/* ============================================================
   Enotale v2 — Theme layer (HAND-MAINTAINED — safe from token-build)
   ============================================================

   Everything the token GENERATOR cannot emit lives here, and only here:
     · the Google Fonts @import
     · the token-system base resets (box-sizing, html, body)
     · [data-theme="dark" | "light"] token remaps
     · the eight [data-theme="visitka-*"] tenant palettes
     · @media (prefers-reduced-motion: reduce)

   WHY THIS FILE EXISTS
   `scripts/token-build` regenerates design-system/tokens.css wholesale from
   tokens/*.json. Every one of the blocks above used to live inside tokens.css and
   was therefore deleted on every regeneration — silently, because a missing
   @import degrades to a system font and a missing [data-theme] block degrades to
   the light palette. The prototype shipped in Times New Roman for 51 days
   (2026-06-15 → 2026-08-04) before anyone caught it. See
   core-data/findings/dangling-tokens-2026-08-04.md.

   With this split, tokens.css is 100 % generated and this file is 100 % hand-
   written. Neither one is ever both.

   LOAD ORDER — tokens.css FIRST, then this file. `:root` and `[data-theme="x"]`
   have equal specificity (0,1,0), so the theme remap only wins on source order.
   Both are loaded UNLAYERED, before the layered prototype.css bundle.

   DO NOT add plain token definitions here. A new token belongs in tokens/*.json.
   ============================================================ */

/* Fonts — Cormorant Garamond (display) + Geologica (UI), self-hosted.
   @font-face blocks live in design-system/base/fonts.css (css-manifest layer:base),
   concatenated into assets/css/core.css before this file is loaded.
   Woff2 files at assets/fonts/{family}/. See assets/fonts/README.md for provenance.
   The Google Fonts @import was removed 2026-09-13 to eliminate the third-party
   request and the associated GDPR IP-logging exposure. */

/* ============================================================
   BASE RESETS (token-system infrastructure — not component CSS)
   ============================================================ */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

body {
  margin: 0;
  font-family: var(--font-ui);
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-text-primary);
  background-color: var(--color-surface-primary);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* NOTE: the responsive img/video reset lives in @layer base (base.css), NOT here.
   tokens.css is loaded UNLAYERED, so an `img,video{height:auto}` rule here would
   beat layered component rules (e.g. .header-public__logo-img{height:68px}) and
   break fixed-size images. Keep image resets in the base layer. */

/* The :root token block that used to sit here now lives in the generated
   design-system/tokens.css, which loads immediately before this file. */

/* ============================================================
   DARK MODE — semantic token overrides
   Components reference semantic tokens — dark mode swaps the
   semantic values without touching component CSS.
   ============================================================ */

/* D-06 ruling 2026-09-13: OS preference now honoured by the inline script
   (src/_includes/partials/theme-init.njk); the [data-theme="dark"] block below
   is the ONLY active dark token set (96 declarations, 87 unique tokens). data-theme on <html> is the
   single cascade mechanism — [data-theme="dark"] wins everywhere.
   History: the @media (prefers-color-scheme: dark) { :root:not([data-theme]) { … } }
   block (171 lines) was unreachable since base.njk always emits an explicit
   data-theme; the two hand-synced blocks had drifted — --color-status-success
   was present in [data-theme="dark"] but missing from the @media block (72 vs 71
   tokens). Block deleted this session; OS preference lives in the init script. */
/* ================================================================
   HAND-MAINTAINED THEME BLOCKS — edit these directly in this file.

   The original of this note ended "do NOT run scripts/token-build",
   which was true only while these blocks lived inside tokens.css.
   Since the 2026-08-04 split, token-build regenerates tokens.css and
   never touches this file — see the header at the top. Corrected
   2026-08-04; the (now-deleted) @media block had already carried the correction
   and this one did not, which is the drift this file is most prone to.
   ================================================================ */

/* Explicit data-theme attribute — allows JS toggle independent of OS preference */
[data-theme="dark"] {
  --color-surface-primary: #1A1410;
  --color-surface-alt: #221D17;
  --color-surface-raised: #2A2319;
  --color-surface-sunk: #15110E;
  --color-surface-overlay: rgba(26, 20, 16, 0.92);
  --color-text-primary: #EDE4D4;
  --color-text-muted: #A89880;
  --color-text-subtle: #7A6E62;
  --color-text-on-accent: #FFFFFF;
  --color-text-on-surface-sunk: #EDE4D4;
  --color-text-link: #CB807C;
  --color-text-link-visited: #A89880;
  --color-border-default: #3D3227;
  --color-border-strong: #5C4E3E;
  --color-border-focus: #5C4E3E;
  /* Serving-glass plate: on dark the vessel is drawn light and already reads
     against the card — no plate needed. DD 2026-08-21.
     Wine lifts — two wines fail 3:1 on BOTH grounds (cream bowl + dark page):
       wine-red  #6B1F2A: bowl 9.98:1, dark page 1.61:1 → #B8474F  bowl 4.57 · page 3.52 ✓
       wine-rose #9B3D4A: bowl 5.86:1, dark page 2.74:1 → #C06A75  bowl 3.33 · page 4.83 ✓
     wine-white #A68643 (bowl 3.03 · page 5.31) and wine-orange #B8782A (3.21 · 5.00) hold. */
  --glass-plate: transparent;
  --glass-wine-red: #B8474F;
  --glass-wine-rose: #C06A75;
  --color-accent-primary: #8B2D3D;
  --color-accent-primary-hover: #A83548;
  --color-accent-primary-text: #FFFFFF;
  --color-accent-link: #CB807C;
  --color-accent-gold: #C9A96A;
  --color-accent-gold-hover: #D4BC82;
  /* Status tokens — dark surface overrides (C1 fix; D-03 2026-08-04)
     These four are the MARK tokens — the colour a status is drawn IN as an
     sla-dot, chart stroke, icon or figure text on a surface. They are NOT pill
     fills; the pill tones are pinned separately below.

     Ratios are quoted against the WORST of the six dark surfaces. The previous
     version of this note quoted only surface-primary and surface-sunk, which is
     how --color-status-error shipped at 3.91:1 on stat-attention while the
     comment claimed 4.63:1. Lifted #CC5F55 -> #D87A71.

     token                     value    worst surface     ratio
     --color-status-success    #7AB566  stat-attention    6.32:1 ✓
     --color-status-warning    #D4924A  stat-attention    5.87:1 ✓
     --color-status-error      #D87A71  stat-attention    5.09:1 ✓  (was 3.91 ✗)
     --color-status-info       #7DA3C4  stat-attention    5.80:1 ✓
     --color-status-warning-text: #D4924A — same lifted amber; 5.87:1 worst. */
  --color-status-success: #7AB566;
  --color-status-warning: #D4924A;
  --color-status-error: #D87A71;
  --color-status-info: #7DA3C4;
  --color-status-warning-text: #D4924A;
  --color-status-success-subtle: #1A2918;
  --color-accent-secondary: #7DA3C4;
  --color-accent-secondary-subtle: #1A2430;
  --color-accent-primary-subtle: #2A1616;
  --color-border-warning: var(--color-status-warning);
  --color-surface-warning: #302214;
  --shadow-card: 0 1px 3px rgba(0, 0, 0, 0.2);
  --shadow-modal: 0 8px 40px rgba(0, 0, 0, 0.4);
  /* Focus ring: outer band corrected 2026-09-07 (S260907-033440670) — moved
     off --color-accent-primary (2.21:1 on dark page, fails WCAG 1.4.11)
     to --color-accent-link (6.01:1 on #1A1410). */
  --shadow-focus: 0 0 0 2px #1A1410, 0 0 0 4px #CB807C;
  --shadow-focus-strong: 0 0 0 2px #CB807C, 0 0 0 4px #1A1410;
  --shadow-floating: var(--shadow-modal);
  --shadow-focus-ring: var(--shadow-focus);
  --shadow-focus-ring-strong: var(--shadow-focus-strong);
  --modal-overlay-bg: rgba(0, 0, 0, 0.7);

  /* ================================================================
     COMPONENT TOKEN DARK OVERRIDES — WCAG AA interactive text
     accent-primary (#8B2D3D) is too dark for text on dark surfaces
     (~2.21:1 on #1A1410). Interactive text tokens remap to accent-link.

     D-03 (2026-08-04): accent-link's dark value was #C4706C, and this note
     claimed it "passes ≥4.5:1 on all dark surfaces". It did not. The claim was
     verified against the two surfaces named below and generalised to four:

         #C4706C on surface-sunk    #15110E = 5.26:1  ✓  (checked)
         #C4706C on surface-primary #1A1410 = 5.11:1  ✓  (checked)
         #C4706C on surface-alt     #221D17 = 4.68:1  ✓  (never checked)
         #C4706C on surface-raised  #2A2319 = 4.35:1  ✗  (never checked)

     surface-raised is the card and table-row surface, so the miss was not
     marginal in practice: 108 failing link instances over 29 admin pages, more
     than any defect but the nav marker. Lifted to #CB807C, which clears the
     worst of the four rather than the best:

         #CB807C on surface-raised  #2A2319 = 5.11:1  ✓  worst case
         #CB807C on surface-alt     #221D17 = 5.51:1  ✓
         #CB807C on surface-primary #1A1410 = 6.01:1  ✓
         #CB807C on surface-sunk    #15110E = 6.19:1  ✓

     Quote the worst surface, not a convenient one, when adding a dark value.
     ================================================================ */
  /* D-02: accent AS TEXT. accent-primary is the FILL and stays deep here so its
     white ink reads; text must lift instead. See color.text.accent in
     semantic.json — light value is identical to accent-primary, so this token
     only ever differs in dark. #CB807C on surface-raised #2A2319 = 5.11:1. */
  --color-text-accent: var(--color-accent-link);

  /* D-08: the secondary button. Transparent fill, so its accent-primary ink AND
     its accent-primary 1px border both sit straight on the page: 2.02:1 for the
     label (needs 4.5:1) and 1.88:1 for the outline (needs even the 3:1 graphical
     floor for a control boundary). It was unreadable AND unbounded in dark —
     106 instances over 30 pages, and it is the CTA on most public pages.
     Both remap to accent-link, 5.11:1 worst-surface each. The PRIMARY button is
     untouched: it is a fill with white ink and already passes. */
  --button-secondary-text: var(--color-accent-link);
  --button-secondary-text-hover: var(--color-accent-link);
  --button-secondary-border: var(--color-accent-link);
  --button-secondary-border-hover: var(--color-accent-link);
  /* Same control shape as button-secondary, missed by D-08; 2.20:1 label and 2.20:1 border on #1A1410 → 6.01/5.51/5.11:1 on the three dark surfaces. */
  --file-upload-trigger-text: var(--color-accent-link);
  --file-upload-trigger-text-hover: var(--color-accent-link);
  --file-upload-trigger-border: var(--color-accent-link);
  --file-upload-trigger-border-hover: var(--color-accent-link);

  --nav-link-hover: var(--color-accent-link);
  --nav-link-active: var(--color-accent-link);
  --button-ghost-text-hover: var(--color-accent-link);

  /* Gallery dark overrides — rgba values have no semantic alias; overridden explicitly. */
  --gallery-scrim-bg: rgba(0, 0, 0, 0.92);
  --gallery-nav-btn-bg: rgba(0, 0, 0, 0.80);
  --gallery-nav-btn-bg-hover: rgba(0, 0, 0, 0.92);

  /* Stat-card variant surfaces (added 2026-08-04).
     These two were minted in the W1 stat-card v2 wave (c335d1b) — DURING the 51 days when
     the [data-theme] blocks did not exist, so nobody could see they had no dark value. In
     dark they kept the light parchment wash (#F1E4CF / #ECDCCE) with dark-mode text on top:
     the "за в риск" card on the winery dashboard was a light rectangle with near-invisible
     label copy. Derived the same way as the light values — accent at 14% composited on
     --color-surface-primary #1A1410 instead of on parchment.
     Contrast on these washes with --color-text-primary #EDE4D4: 11.9:1 and 12.6:1. */
  --color-surface-stat-attention: #302214;
  --color-surface-stat-critical: #2A1616;

  /* ================================================================
     STATUS-PILL TONES — DARK  (D-01, added 2026-08-04)
     ================================================================
     THE GOVERNING RULE, now written down: design-system/color.md →
     "Mark vs Fill — the two-role rule". A colour used both as something you
     draw WITH and something you draw ON is two tokens, and they cannot share
     a value across themes. Read that first; what follows is the case that
     produced it, kept here because the numbers are the argument.

     THE DEFECT. --color-status-{success,warning,error,info} serve TWO
     incompatible roles. As a MARK (sla-dot fill, icon, figure text drawn
     straight onto the page) they must be light enough to pass ≥4.5:1 AS
     foreground on #1A1410 — which is why the dark block above lifts them to
     #7AB566 / #D4924A / #CC5F55 / #7DA3C4. As a pill FILL they carry white or
     ink ON TOP, and lifting the fill destroyed that pair. The dark remap did
     not merely fail to cover the pills — it BROKE pills that were correct in
     light:
         success   light #FFFFFF on moss   6.07:1 ✓ → dark #FFFFFF on #7AB566 2.43:1 ✗
         progress  light #FFFFFF on slate  6.11:1 ✓ → dark #FFFFFF on #7DA3C4 2.66:1 ✗
         action    light #1F1712 on amber  4.84:1 ✓ → dark #EDE4D4 on #D4924A 2.08:1 ✗
         critical  light #FFFFFF on oak    8.89:1 ✓ → dark #FFFFFF on #CC5F55 3.94:1 ✗
     Measured on the ADMIN surface alone: 185 failing instances over 45 pages.

     THE FIX, and why it is not a chip redesign. A fill is self-contained: it
     brings its own background, so it does not need lifting for the dark page
     behind it. The FILL tones therefore pin to the same deep primitives they
     use in light, and their ink pins with them (both must pin — leaving fg as
     --color-text-primary would flip it to cream and re-break amber). The MARK
     tokens above are left lifted, because for sla-dots and figure text they
     are correct.

     The TINT tones cannot pin: their light values (#EFE6D2, #D8E6F0, #EEE0C0)
     are pale washes that would sit on a dark page as bright rectangles — the
     stat-card bug again. They invert to dark tints of the same hue, inked with
     the lifted mark colour.

     This split is deliberate and load-bearing. The light system distinguishes
     the nine tones on TWO axes — hue (semantic) and weight (pale tint vs
     saturated fill). Converting every tone to a tint in dark would have read
     as tidier and collapsed info into progress and waiting into action. Both
     axes survive here.

         tone      dark bg            dark ink       ratio
         neutral   surface-raised     text-primary   12.31:1  tint
         info      #2C2E30            #7DA3C4         5.13:1  tint
         waiting   #3B2B1A            #D4924A         5.18:1  tint
         action    #8A5A1F            white           5.89:1  fill  (see amber note)
         progress  slate-blue         white           6.11:1  fill
         success   moss               white           6.07:1  fill
         warning   #8A5A1F            white           5.89:1  fill  (see amber note)
         critical  blood-oak          white           8.89:1  fill

     THE AMBER NOTE. Four of the five fills pin cleanly; amber-bark does not,
     and it is the one place a value here is not simply the light one. Pinning
     is sound because a fill brings its own background — but "brings its own
     background" says nothing about how loud that background is against the
     page, and amber is the outlier on that axis:

         fill        luminance   in LIGHT, distance    in DARK, distance
                                 from parchment .83    from page .0076
         blood-oak      .068          .76 (loudest)        .061 (softest)
         slate-blue     .122          .71                  .114
         moss           .123          .71                  .115
         amber-bark     .238          .59 (softest)        .230 (loudest)

     The ordering does not merely shift, it inverts — an unavoidable consequence
     of light-page contrast being driven by DISTANCE from a bright page and
     dark-page contrast by ABSOLUTE luminance. No pinned palette preserves both
     hue and relative weight across the flip, so the target is the achievable
     one: no tone accidentally shouting. Amber deepens to #8A5A1F (luminance
     .128, in line with moss .123 and slate .122) and its ink flips to white,
     5.89:1. In light amber is untouched.

     Worth being explicit that this is the one judgement call in the block
     rather than a measurement: amber at #B8782A/ink PASSES AA in dark at
     4.84:1. It was changed because a 4779 px² chip twice as luminous as its
     siblings makes "action" read as an alarm next to "critical", which is
     backwards. If that reads wrong on the real screens, reverting these two
     pairs to var(--color-amber-bark)/var(--color-ink) restores AA-passing
     behaviour and costs nothing else.
         terminal  transparent        text-muted      6.49:1  outline (no override needed —
                                                              both sides already flip)

     The two tints are raw hex because no primitive exists for them: each is
     its mark colour composited at 18 % over --color-surface-primary #1A1410.
     That matches how every other dark value in this file is written.

     These sixteen supersede the two ad-hoc [data-theme="dark"] rules that used
     to live at the foot of status-pill.css (info → surface-sunk, waiting →
     stat-attention) and their "TODO W3: add dark-mode tint overrides" note.
     Fixing it at the token layer covers all 40-odd @deprecated aliases at once;
     the CSS-rule approach only ever covered the two tones someone had noticed.
     ================================================================ */
  --status-pill-tone-neutral-bg: var(--color-surface-raised);
  --status-pill-tone-neutral-fg: var(--color-text-primary);
  --status-pill-tone-info-bg: #2C2E30;
  --status-pill-tone-info-fg: #7DA3C4;
  --status-pill-tone-waiting-bg: #3B2B1A;
  --status-pill-tone-waiting-fg: #D4924A;
  --status-pill-tone-action-bg: #8A5A1F;
  --status-pill-tone-action-fg: var(--color-white);
  --status-pill-tone-progress-bg: var(--color-slate-blue);
  --status-pill-tone-progress-fg: var(--color-white);
  --status-pill-tone-success-bg: var(--color-moss);
  --status-pill-tone-success-fg: var(--color-white);
  --status-pill-tone-warning-bg: #8A5A1F;
  --status-pill-tone-warning-fg: var(--color-white);
  --status-pill-tone-critical-bg: var(--color-blood-oak);
  --status-pill-tone-critical-fg: var(--color-white);

  /* ================================================================
     CHART TOKENS — DARK  (D-04, added 2026-08-04)
     ================================================================
     Charts were the one subsystem whose dark values lived in the COMPONENT
     layer rather than here: bar-chart, trend-chart, rank-bar, sparkline and
     chart-frame each carried an @media (prefers-color-scheme: dark) block
     that swapped --color-chart-series-N for --color-chart-series-N-dark.

     Every one of those blocks was media-query-only. None had a
     [data-theme="dark"] counterpart, so the in-app theme toggle left every
     chart in
     the product rendering light-mode series colours on a dark page. A reader
     whose OS is set to light and who flipped the switch saw it; a reader
     whose OS is dark did not, which is why it survived.

     All five blocks are deleted and their swaps live here instead. The chart
     components are now purely token-referencing like every other component,
     and pick up both mechanisms for free.

     The chrome tokens below had no dark value in any layer:
       axis-label      walnut #6B5D4E → 2.43:1 on surface-raised. Follows
                       --color-text-muted (#A89880, 5.52:1 worst) instead —
                       walnut IS text-muted's light value, so this is the
                       mapping the token should always have had.
       grid            paper-fold → border-default. Decorative rule lines.
       threshold-line  amber-bark → the lifted warning mark.
     --color-chart-mark-gap (parchment) is left alone deliberately: grep
     finds no consumer in any component, so giving it a dark value would be
     inventing a contract. It wants deleting or wiring, not patching.
     ================================================================ */
  --color-chart-series-1: var(--color-chart-series-1-dark);
  --color-chart-series-2: var(--color-chart-series-2-dark);
  --color-chart-series-3: var(--color-chart-series-3-dark);
  --color-chart-ramp-1: var(--color-chart-ramp-1-dark);
  --color-chart-ramp-2: var(--color-chart-ramp-2-dark);
  --color-chart-ramp-3: var(--color-chart-ramp-3-dark);
  --color-chart-ramp-4: var(--color-chart-ramp-4-dark);
  --color-chart-axis-label: var(--color-text-muted);
  --color-chart-grid: var(--color-border-default);
  --color-chart-threshold-line: var(--color-status-warning);

  /* Illustration — wine-spill pool. wine-burgundy #6B1F2A is 1.61:1 on #1A1410 — fails
     ≥3:1 graphical floor. Lifted to brick-red #C84040 (no blue excess; unmistakably
     wine, not rose-pink #CB807C).
     #C84040 on surface-raised #2A2319 = 3.15:1 ✓ (worst dark surface — verified) */
  --color-illustration-wine-spill: #C84040;

  /* Toast text on brightened dark status fills — 2026-09-14 (D1 wave).
     The four --toast-*-text tokens inherit white (#FFFFFF) from light mode.
     CONSUMER: toast.css itself reads the generic --toast-text (text-primary on toast-bg,
     fine in dark); the per-tone pair --toast-{tone}-bg/-text is what the APP consumes —
     enotale-winery onboarding-banner.blade.php paints var(--toast-info-bg)/var(--toast-info-text)
     (the «under AA on the brightened info fill» in the devs' letter of 2026-09-13).
     In dark, fills are lifted (info #7DA3C4, success #7AB566, warning #D4924A,
     error #D87A71), and white no longer passes:
       info 2.66:1  success 2.43:1  warning 2.62:1  error 3.03:1 (all fail AA 4.5:1).
     Fix: remap text to surface-primary (#1A1410 in dark — verified above):
       info 6.87:1  success 7.49:1  warning 6.96:1  error 6.03:1 (all pass AA) */
  --toast-info-text:    var(--color-surface-primary);
  --toast-success-text: var(--color-surface-primary);
  --toast-warning-text: var(--color-surface-primary);
  --toast-error-text:   var(--color-surface-primary);
}

[data-theme="light"] {
  /* Resets to light — takes effect when a user switches back from a stored dark
     choice, or when the page explicitly forces light (landing.njk).
     Until 2026-08-05 this block reset only 29 of the 72 tokens the dark block
     sets. See THE SECOND HALF at the foot of this block for what the other 43
     were doing, and why they are now here. */
  --color-surface-primary: var(--color-parchment);
  --color-surface-alt: var(--color-paper-light);
  --color-surface-raised: var(--color-pure-paper);
  --color-surface-sunk: var(--color-paper-fold);
  --color-text-primary: var(--color-ink);
  --color-text-muted: var(--color-walnut);
  --color-text-subtle: var(--color-oak);
  --color-text-on-accent: var(--color-white);
  --color-text-link: var(--color-rose-ink);
  --color-border-default: var(--color-paper-edge);
  --color-border-strong: var(--color-inked-edge);
  --color-border-focus: var(--color-inked-edge);
  --color-accent-primary: var(--color-wine-burgundy);
  --color-accent-primary-hover: var(--color-deep-lees);
  --color-accent-gold: var(--color-antique-gold);
  --color-accent-gold-hover: var(--color-tarnished-gold);
  /* Status tokens — restore light-mode values (symmetry with dark block above)
     --color-status-success: var(--color-moss)         | 5.35:1 on parchment
     --color-status-warning: var(--color-amber-bark)   | 3.21:1 on parchment (fills/graphical only)
     --color-status-error:   var(--color-blood-oak)    | 7.83:1 on parchment
     --color-status-info:    var(--color-slate-blue)   | 5.39:1 on parchment
     --color-status-warning-text: #7A4E0E              | 6.33:1 on parchment (text use) */
  --color-status-success: var(--color-moss);
  --color-status-warning: var(--color-amber-bark);
  --color-status-error: var(--color-blood-oak);
  --color-status-info: var(--color-slate-blue);
  --color-status-warning-text: #7A4E0E;
  --shadow-card: 0 1px 2px rgba(31, 23, 18, 0.04);
  --shadow-modal: 0 8px 32px rgba(31, 23, 18, 0.12);
  --shadow-focus: 0 0 0 2px #F7F0E1, 0 0 0 4px #6B1F2A;
  --shadow-focus-strong: 0 0 0 2px #6B1F2A, 0 0 0 4px #F7F0E1;
  --shadow-floating: var(--shadow-modal);
  --shadow-focus-ring: var(--shadow-focus);
  --shadow-focus-ring-strong: var(--shadow-focus-strong);
  --modal-overlay-bg: rgba(31, 23, 18, 0.5);

  /* ================================================================
     THE SECOND HALF  (D-06, added 2026-08-05)
     ================================================================
     The 43 declarations below are the rest of what the dark block sets.
     Nothing here is a new value: each is its own `:root` definition from
     tokens.css, re-stated at this selector.

     WHY THAT IS NOT DUPLICATION. `:root` and `[data-theme="light"]` both
     match <html>, and the attribute wins on source order — so on the ROOT
     element these 43 were already correct without this block, which is why
     their absence was invisible for as long as it was. The absence bites on
     any OTHER element. `:root` does not match a <div>, so a scoped
     `<div data-theme="light">` inside a dark page inherited 43 dark values
     it had explicitly asked not to have. The block was a partial reset that
     read as a complete one.

     WHAT MADE IT VISIBLE: /dizayn-sistema/resheniya/ puts a light panel and
     a dark panel side by side on one page so four open decisions can be seen
     in both themes at once. Before this, the light panel of that page showed
     dark status pills, dark chart series and the dark accent — the instrument
     built to settle the amber question would have misreported the amber
     question. A comparison surface is only worth as much as its scoping.

     WHY IT IS SAFE, checked rather than assumed. Eighteen tokens are
     referenced by these declarations. Ten are primitives or literals the dark
     block never touches. The other eight — accent-primary, accent-primary-
     hover, text-primary, text-on-accent and the four status tones — are all
     reset ABOVE in this same block, so they resolve to light values at any
     nesting depth. Zero references resolve through a token this block leaves
     dark. Re-check that closure before adding a declaration here.

     THE RULE THIS ESTABLISHES: the light block and the dark block must
     declare the SAME SET of tokens. A token added to one and not the other
     is a scoping defect, and it will not show up on the root element, which
     is where anyone would look for it.
     ================================================================ */

  /* Accent + link */
  --color-accent-link: var(--color-rose-ink);
  --color-accent-primary-text: var(--color-white);
  --color-text-accent: var(--color-accent-primary);
  --color-text-link-visited: var(--color-walnut);
  --color-text-on-surface-sunk: var(--color-ink);
  --nav-link-active: var(--color-accent-primary);
  --nav-link-hover: var(--color-accent-primary);

  /* Buttons */
  --button-secondary-text: var(--color-accent-primary);
  --button-secondary-text-hover: var(--color-accent-primary-hover);
  --button-secondary-border: var(--color-accent-primary);
  --button-secondary-border-hover: var(--color-accent-primary-hover);
  --button-ghost-text-hover: var(--color-accent-primary);
  /* The file-upload trigger is the same control shape as button-secondary and
     was missed by D-08; its four dark values were added above on 2026-08-05.
     These four exist because of THE RULE stated at the head of this block, and
     they are its first test: the dark blocks got them first and this block was
     one review away from not getting them at all. Values are the tokens.css
     light values, restated so a nested [data-theme="light"] panel resolves
     them — :root does not match a <div>. */
  --file-upload-trigger-text: var(--color-accent-primary);
  --file-upload-trigger-text-hover: var(--color-accent-primary-hover);
  --file-upload-trigger-border: var(--color-accent-primary);
  --file-upload-trigger-border-hover: var(--color-accent-primary-hover);

  /* Charts */
  --color-chart-series-1: #8B2D3D;
  --color-chart-series-2: #1F5F94;
  --color-chart-series-3: #B8782A;
  --color-chart-ramp-1: #C79E9E;
  --color-chart-ramp-2: #B27C82;
  --color-chart-ramp-3: #9E5A64;
  --color-chart-ramp-4: #8B2D3D;
  --color-chart-axis-label: var(--color-walnut);
  --color-chart-grid: var(--color-paper-fold);
  --color-chart-threshold-line: var(--color-amber-bark);

  /* Stat surfaces + gallery */
  --color-surface-stat-attention: var(--color-stat-attention-tint);
  --color-surface-stat-critical: var(--color-stat-critical-tint);
  --gallery-nav-btn-bg: rgba(31, 23, 18, 0.72);
  --gallery-nav-btn-bg-hover: rgba(31, 23, 18, 0.90);
  --gallery-scrim-bg: rgba(31, 23, 18, 0.88);

  /* Illustration — wine-spill pool. Restated here per THE RULE (D-06): the light
     block and the dark block must declare the SAME SET of tokens. This resolves to
     the :root value (wine-burgundy #6B1F2A) for any scoped [data-theme="light"] panel. */
  --color-illustration-wine-spill: var(--color-wine-burgundy);

  /* Status-pill tones — the light side of D-01. The fills pin to the deep
     primitives and carry their own ink; the two tints are pale washes. */
  --status-pill-tone-neutral-bg: var(--color-badge-status-draft-bg);
  --status-pill-tone-neutral-fg: var(--color-badge-status-draft-fg);
  --status-pill-tone-info-bg: #D8E6F0;
  --status-pill-tone-info-fg: var(--color-status-info);
  --status-pill-tone-waiting-bg: #EEE0C0;
  --status-pill-tone-waiting-fg: var(--color-text-primary);
  --status-pill-tone-action-bg: var(--color-status-warning);
  --status-pill-tone-action-fg: var(--color-text-primary);
  --status-pill-tone-progress-bg: var(--color-status-info);
  --status-pill-tone-progress-fg: var(--color-text-on-accent);
  --status-pill-tone-success-bg: var(--color-status-success);
  --status-pill-tone-success-fg: var(--color-text-on-accent);
  --status-pill-tone-warning-bg: var(--color-status-warning);
  --status-pill-tone-warning-fg: var(--color-text-primary);
  --status-pill-tone-critical-bg: var(--color-status-error);
  --status-pill-tone-critical-fg: var(--color-text-on-accent);

  /* Serving-glass plate and the two wine lifts — the light half of the pair the
     dark block above sets. Same values `:root` carries in tokens.css, restated
     here for the D-07 rule at the head of this file: the light and dark blocks
     must declare the same SET of tokens. Omitting them is harmless on <html>,
     where `:root` already supplies the light value and wins on source order, and
     wrong on a nested [data-theme="light"] panel, which `:root` does not match —
     a light panel inside a dark page would draw the glass on the dark plate.
     Added 2026-08-20 when the parity check found these three dark-only. */
  --glass-plate: transparent;
  --glass-contour: var(--color-paper-fold);
  --glass-wine-red: var(--color-wine-burgundy);
  --glass-wine-rose: var(--color-rose-ink);
}

/* === VISITKA palette packs (Wave-5) — winery microsite themes; hand-maintained, applied via data-theme="visitka-{name}" on the visitka one-pager wrapper. Mapping + AA verification: core-data/drafts/visitka-palettes.md === */

/* Мавруд — класически, тъмен (default fallback) */
[data-theme="visitka-mavrud"] {
  --color-surface-primary: #F5EDD8;
  --color-surface-alt: #FAF4E3;
  --color-surface-raised: #FAF4E3;
  --color-surface-sunk: #EDE0C4;
  --color-text-primary: #1C1410;
  --color-text-muted: #6A5B4B;
  --color-text-on-accent: #FFFFFF;
  --color-accent-primary-text: #FFFFFF;
  --color-accent-primary: #6B1F2A;
  --color-border-default: #D6C9A8;
  --color-border-strong: #D6C9A8;
}

/* Варовик — минималист, сив-зелен */
[data-theme="visitka-varovik"] {
  --color-surface-primary: #F2F0EC;
  --color-surface-alt: #FAFAF8;
  --color-surface-raised: #FAFAF8;
  --color-surface-sunk: #E8E5DF;
  --color-text-primary: #1A1C1E;
  --color-text-muted: #5A6068;
  --color-text-on-accent: #FFFFFF;
  --color-accent-primary-text: #FFFFFF;
  --color-accent-primary: #2B6472;
  --color-border-default: #CFCBC2;
  --color-border-strong: #CFCBC2;
}

/* Керемида — топъл теракот */
[data-theme="visitka-keremida"] {
  --color-surface-primary: #F4EDE5;
  --color-surface-alt: #FAF6F1;
  --color-surface-raised: #FAF6F1;
  --color-surface-sunk: #E8DDD3;
  --color-text-primary: #1A1410;
  --color-text-muted: #6B5A50;
  --color-text-on-accent: #FFFFFF;
  --color-accent-primary-text: #FFFFFF;
  --color-accent-primary: #B04C2A;
  --color-border-default: #D4C4B8;
  --color-border-strong: #D4C4B8;
}

/* Трева — природен зелен */
[data-theme="visitka-treva"] {
  --color-surface-primary: #EFECE4;
  --color-surface-alt: #F7F5EE;
  --color-surface-raised: #F7F5EE;
  --color-surface-sunk: #E2DDD2;
  --color-text-primary: #1A1C16;
  --color-text-muted: #5A6050;
  --color-text-on-accent: #FFFFFF;
  --color-accent-primary-text: #FFFFFF;
  --color-accent-primary: #3D6130;
  --color-border-default: #CCCABF;
  --color-border-strong: #CCCABF;
}

/* Розе — деликатен розов */
[data-theme="visitka-roze"] {
  --color-surface-primary: #F8F0EC;
  --color-surface-alt: #FEF8F5;
  --color-surface-raised: #FEF8F5;
  --color-surface-sunk: #EDE0D8;
  --color-text-primary: #1C1410;
  --color-text-muted: #70554E;
  --color-text-on-accent: #FFFFFF;
  --color-accent-primary-text: #FFFFFF;
  --color-accent-primary: #943848;
  --color-border-default: #D8C8C0;
  --color-border-strong: #D8C8C0;
}

/* Хума — тъмен (инвертиран) */
[data-theme="visitka-huma"] {
  --color-surface-primary: #1C1510;
  --color-surface-alt: #251C15;
  --color-surface-raised: #251C15;
  --color-surface-sunk: #2F231A;
  --color-text-primary: #F2E8D8;
  --color-text-muted: #A8917C;
  --color-text-subtle: #A8917C;
  --color-text-on-accent: #1C1510;
  --color-accent-primary-text: #1C1510;
  --color-accent-primary: #C49050;
  --color-border-default: #3D3028;
  --color-border-strong: #3D3028;
}

/* Праг — неутрален, деловит */
[data-theme="visitka-prag"] {
  --color-surface-primary: #F7F5F2;
  --color-surface-alt: #FDFCFB;
  --color-surface-raised: #FDFCFB;
  --color-surface-sunk: #EAE7E2;
  --color-text-primary: #1A1917;
  --color-text-muted: #6B6560;
  --color-text-on-accent: #FFFFFF;
  --color-accent-primary-text: #FFFFFF;
  --color-accent-primary: #2C2824;
  --color-border-default: #D8D4CE;
  --color-border-strong: #D8D4CE;
}

/* Туш — студен, съвременен */
[data-theme="visitka-tush"] {
  --color-surface-primary: #F3F4F5;
  --color-surface-alt: #FAFBFB;
  --color-surface-raised: #FAFBFB;
  --color-surface-sunk: #E5E7E9;
  --color-text-primary: #181A1C;
  --color-text-muted: #60686F;
  --color-text-on-accent: #FFFFFF;
  --color-accent-primary-text: #FFFFFF;
  --color-accent-primary: #1E3A52;
  --color-border-default: #D0D4D7;
  --color-border-strong: #D0D4D7;
}

/* ============================================================
   REDUCED MOTION — wrap all transitions/animations in components
   via this query. Component CSS must check this.
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  :root {
    --duration-fast: 0ms;
    --duration-base: 0ms;
    --duration-moderate: 0ms;
    --duration-slow: 0ms;
    --motion-duration-fast: 0ms;
    --motion-duration-base: 0ms;
    --motion-duration-enter: 0ms;
    --motion-duration-page: 0ms;
    --card-product-fold-duration: 0ms;
    --button-transition-duration: 0ms;
    --modal-enter-duration: 0ms;
  }
}
