/* ==========================================================================
   PRODUCT TOOLS HUB DESIGN TOKENS - THE ZIVA BRAND, LOCKED

   These are the final Ziva brand values, locked 2026-08-09 and applied by
   work order ZB-1. The provisional GFP placeholder values that carried
   T0.1 and T0.5 are gone; every screen inherits the Ziva brand from this
   file and nothing else.

   TOKEN NAMES ARE STRUCTURAL IDENTIFIERS, NOT COLOR DESCRIPTIONS. The
   names below (including "gold" and "navy") are the permanent T0.1
   identifiers that every screen in tools/ references; ZB-1 changed VALUES
   only, so a name may no longer describe its color. Read them as roles:
     --color-gold-*  = the brand accent family (now the Ziva clay family)
     --color-ink-navy / --color-surface-navy = the dark ink and the dark
       band surface (now the Ziva warm ink)
   Renaming would touch every screen for zero behavior change; the roles,
   scales, and structure are unchanged per the work order.

   ZB-1 additions (new names, because the locked brand defines values that
   had no home): --color-surface-band, --color-hairline,
   --color-chart-series-1, --color-chart-series-2, --weight-light.

   The single source of design values for the public tools hub. Every
   screen in tools/ takes its spacing, type, color, radii, shadows, and
   motion from the named values below and hardcodes nothing. The
   conformance check (scripts/tools_token_check.py) fails the build if a
   raw hex color or a raw pixel value appears anywhere in tools/ outside
   this file.

   Sources of truth this file encodes:
   - The locked Ziva brand (2026-08-09), applied by work order ZB-1:
     clay accent family, warm cream surfaces, warm ink, forest/marigold/
     crimson status hues, two warm-neutral chart series, Spectral
     headings with Geist body and figures.
   - docs/build-standards.md section 4: motion durations and easing.
   - docs/design/ziva-contrast.md: the full measured contrast table for
     every pairing these tokens create, with the failures that await
     Goldy's ruling. Two fallbacks from that measurement are encoded
     here, neither an invented color, both flagged in the ZB-1 pull
     request:
       the watch chip INK is the warm ink, not marigold, because
       marigold misses the 4.5:1 text floor on every light surface
       (marigold survives as the watch chip OUTLINE, a graphic held
       to the 3:1 dot threshold);
       status chip FILLS are the card surface, because the locked
       palette defines no pastel status fills; the outline, glyph,
       and word carry the status.

   Colors are defined in oklch() rather than hex. The source hex each value
   was converted from is noted in a comment beside it for traceability.
   Conversions were computed by code (sRGB to OKLab, Ottosson matrices),
   not transcribed by eye.

   Standing rule, figures in columns: any column of figures uses tabular
   numerals so digits align. The token is --font-numeric-figures and the
   utility class .u-tabular-figures applies it. No column of numbers ships
   without it.
   ========================================================================== */

:root {

  /* ------------------------------------------------------------------
     COLOR, ground and ink
     Light-first: warm cream ground, white cards, warm ink for text.
     The dark ink is never a full-page wall.
     ------------------------------------------------------------------ */
  --color-ground:        oklch(97.24% 0.0096 72.66);   /* Ziva cream, from #FAF5EF */
  --color-surface-card:  oklch(100.00% 0.0000 89.88);  /* white card, from #FFFFFF;
                                                          white is not in the locked
                                                          color list and is kept as
                                                          the neutral card surface */
  --color-surface-band:  oklch(94.36% 0.0159 73.68);   /* Ziva band, a quiet section
                                                          background one step below
                                                          the cream, from #F3EBE1 */
  --color-hairline:      oklch(89.89% 0.0207 74.65);   /* Ziva neutral hairline for
                                                          borders on surfaces, from
                                                          #E6DCCF */
  --color-ink-navy:      oklch(26.30% 0.0120 44.58);   /* Ziva warm ink (name is the
                                                          T0.1 identifier), from
                                                          #2A2320 */
  --color-ink-body:      oklch(26.30% 0.0120 44.58);   /* body text ink, same value
                                                          as --color-ink-navy per
                                                          Goldy's standing ruling
                                                          (2026-08-06), from #2A2320 */
  --color-ink-muted:     oklch(51.30% 0.0158 60.34);   /* Ziva muted ink, secondary
                                                          text ONLY (captions, quiet
                                                          notes), never body
                                                          paragraphs, from #6E655E */
  --color-surface-navy:  oklch(26.30% 0.0120 44.58);   /* the dark band surface,
                                                          from #2A2320 */

  /* ------------------------------------------------------------------
     COLOR, the brand clay family (token names keep the T0.1 "gold"
     identifiers; the values are the locked Ziva clay family)
     The brand accent is rationed. THE DECOUPLING RULE: this family
     never appears as a chart series color or a status color; the brand
     color never encodes data (enforced by the conformance gate).
     ------------------------------------------------------------------ */
  --color-gold-base:      oklch(52.78% 0.1291 36.48);  /* brand deep clay, from #A84B31 */
  --color-gold-mid:       oklch(80.24% 0.0581 35.98);  /* brand hairline, from #E1B2A5 */
  --color-gold-bright:    oklch(87.17% 0.0324 37.13);  /* brand tint (shares the
                                                          tint value; the locked
                                                          family has four members
                                                          for five T0.1 slots),
                                                          from #E9CEC6 */
  --color-gold-highlight: oklch(87.17% 0.0324 37.13);  /* brand tint, from #E9CEC6 */
  --color-gold-deep:      oklch(47.27% 0.1142 36.30);  /* brand pressed, from #90402A */

  /* Brand color that must be READ uses the deep clay, which measures
     4.5:1 or better on the cream, the band, and the card surfaces
     (see docs/design/ziva-contrast.md). */
  --color-gold-text-body:  oklch(52.78% 0.1291 36.48); /* body-size accent text, from #A84B31 */
  --color-gold-text-large: oklch(52.78% 0.1291 36.48); /* large text accent, from #A84B31 */
  --color-gold-interface:  oklch(52.78% 0.1291 36.48); /* interface accent, from #A84B31 */

  /* THE GRADIENT IS RETIRED (Goldy's ruling, corrections round two,
     2026-08-12). The gradient headline was GFP's signature device and
     is not part of the locked Ziva identity: no gradient appears
     anywhere in the Ziva tools. The token was removed rather than
     re-tinted, which also retires the two failing contrast
     measurements on the dark band, because those measured the
     gradient's stops. Headlines now render in ONE solid color, named
     below.

     The shipped headline color is the deep clay, the brand color that
     must be read (4.5:1 or better on cream, band, and card). Goldy
     rules by eye between solid deep clay and solid ink on the
     side-by-side in the specimen; until she rules, this is the
     shipped value. */
  --color-headline: oklch(52.78% 0.1291 36.48);  /* brand deep clay, from #A84B31 */

  /* ------------------------------------------------------------------
     COLOR, traffic-light status trio

     THE LOCKED ZIVA CHIP SYSTEM (Goldy's ruling, corrections round
     two, 2026-08-12). Outlined pills are retired. There are exactly
     two status treatments and no others:

       1. THE QUIET DEFAULT, used for every status that simply reports:
          an inline DOT carrying the status hue, followed by the status
          WORD set in the warm ink. The dot is a graphic, held to the
          3:1 dot threshold against the surface behind it; the word is
          text, held to the 4.5:1 floor, which the warm ink clears with
          enormous room on every light surface. This is why the watch
          state needs no special case: every status word is already ink
          (see the marigold ruling below), so marigold is never asked
          to be text.

       2. THE ONE ITEM THAT MUST STOP THE EYE: the left-rule white
          callout card. A white card with a thick rule down its left
          edge in the status hue. The rule is a graphic at the same 3:1
          threshold. Used sparingly, at most once per view, or it stops
          being a stop.

     The *-ink and *-outline tokens below keep their locked values and
     their T0.1 names. The dot uses the *-outline value (it is the same
     graphic role), and the *-ink values remain the named home for each
     status hue as text where a status hue may legitimately be read.
     ------------------------------------------------------------------ */
  --color-status-good-fill:     oklch(100.00% 0.0000 89.88); /* card surface, from #FFFFFF */
  --color-status-good-ink:      oklch(48.60% 0.0708 153.02); /* status forest, from #3E6B4C */
  --color-status-good-outline:  oklch(48.60% 0.0708 153.02); /* status forest, from #3E6B4C */

  --color-status-watch-fill:    oklch(100.00% 0.0000 89.88); /* card surface, from #FFFFFF */
  --color-status-watch-ink:     oklch(26.30% 0.0120 44.58);  /* the warm ink, NOT
                                                                 marigold: marigold
                                                                 misses the 4.5:1 text
                                                                 floor on every light
                                                                 surface; fallback per
                                                                 the ZB-1 work order,
                                                                 awaiting Goldy's
                                                                 ruling, from #2A2320 */
  --color-status-watch-outline: oklch(65.04% 0.1241 82.72);  /* status marigold as a
                                                                 graphic outline, from
                                                                 #B48720 */

  --color-status-action-fill:    oklch(100.00% 0.0000 89.88); /* card surface, from #FFFFFF */
  --color-status-action-ink:     oklch(45.66% 0.1558 18.74);  /* status crimson, from #9B2233 */
  --color-status-action-outline: oklch(45.66% 0.1558 18.74);  /* status crimson, from #9B2233 */

  /* ------------------------------------------------------------------
     COLOR, chart series
     Two warm neutrals for data. THE DECOUPLING RULE, other direction:
     chart colors are never the brand clay family, so the brand color
     never encodes data (enforced by the conformance gate).
     ------------------------------------------------------------------ */
  --color-chart-series-1: oklch(36.34% 0.0190 43.90);  /* from #473B36 */
  --color-chart-series-2: oklch(47.62% 0.0263 42.38);  /* from #6A5851 */

  /* ------------------------------------------------------------------
     COLOR, the Ziva chart language (docs/design/ziva-chart-language.md,
     codified 2026-08-12, installed by corrections 2026-08-13)

     Six meaning states for charts that carry meaning. Token names
     describe MEANING, never hue; the family names in the source doc are
     internal vocabulary and never appear in customer-facing copy.
     Tinted states carry a fill plus an outline of the same family
     (data shapes are outlined at --border-data); solid states carry one
     value and NEVER an outline. Severity escalates by LOSING the tint
     (attention tint to severe solid), never by changing hue.

     THE TWO SANCTIONED CLAY DATA JOBS (the chart language's own ruling,
     which refines the ZB-1 decoupling rule): the clay tint pair below
     means cost / subtraction / money that left, with no judgment, and
     the solid clay pace bar has exactly one data job, pace toward a
     goal. Everywhere else the decoupling rule still holds: brand clay
     never appears as a chart series color, a status color, or any
     other chart meaning color. The conformance gate enforces exactly
     this carve-out and nothing wider.
     ------------------------------------------------------------------ */
  --color-chart-good-fill:         oklch(92.17% 0.0183 155.80); /* good / positive /
                                                          stayed, from #DCE9E0 */
  --color-chart-good-outline:      oklch(48.60% 0.0708 153.02); /* from #3E6B4C */
  --color-chart-watch-fill:        oklch(91.53% 0.0473 88.30);  /* watch / thin /
                                                          broke even, from #F0E2C0 */
  --color-chart-watch-outline:     oklch(65.04% 0.1241 82.72);  /* from #B48720 */
  --color-chart-attention-fill:    oklch(87.05% 0.0366 7.22);   /* attention /
                                                          past-due, from #EBCBD0 */
  --color-chart-attention-outline: oklch(45.66% 0.1558 18.74);  /* from #9B2233 */
  --color-chart-severe:            oklch(45.66% 0.1558 18.74);  /* severe: SOLID, no
                                                          outline, no tint,
                                                          from #9B2233 */
  --color-chart-cost-fill:         oklch(87.17% 0.0324 37.13);  /* cost / subtraction /
                                                          money that left, no
                                                          judgment, from #E9CEC6 */
  --color-chart-cost-outline:      oklch(52.78% 0.1291 36.48);  /* from #A84B31 */
  --color-chart-anchor:            oklch(26.30% 0.0120 44.58);  /* neutral reference,
                                                          SOLID, never a
                                                          judgment, from #2A2320 */

  /* The pace bar: solid clay's one data job, on its own quiet track. */
  --color-chart-pace:                oklch(52.78% 0.1291 36.48); /* from #A84B31 */
  --color-chart-pace-track:          oklch(94.36% 0.0159 73.68); /* from #F3EBE1 */
  --color-chart-pace-track-hairline: oklch(89.89% 0.0207 74.65); /* from #E6DCCF */

  /* Chart label inks. Primary and secondary carry every ordinary label;
     the on-watch ink is for text sitting ON the watch fill; the
     positive ink is for a positive outcome value; the cost text ink is
     for chips only. */
  --color-chart-label-primary:   oklch(26.30% 0.0120 44.58);  /* from #2A2320 */
  --color-chart-label-secondary: oklch(51.30% 0.0158 60.34);  /* from #6E655E */
  --color-chart-label-on-watch:  oklch(35.62% 0.0674 89.64);  /* from #4A3A08 */
  --color-chart-label-positive:  oklch(36.97% 0.0662 156.59); /* from #1D4A31 */
  --color-chart-label-cost:      oklch(33.95% 0.0857 34.44);  /* chips only,
                                                          from #5C2417 */

  /* Waterfall connectors: dashed, quiet, warmer than a hairline. */
  --color-chart-connector: oklch(80.72% 0.0208 69.94);  /* from #C9BEB2 */

  /* Chart geometry from the same doc: data shapes are 1.5, radii scale
     with the shape, connectors dash 4 4 (dash lengths are plain numbers
     in SVG user units, so they need no token). */
  --border-data:            1.5px;  /* every data shape's outline weight */
  --radius-chart-bar:       3px;    /* small vertical bars */
  --radius-chart-bar-wide:  5px;    /* horizontal bars */
  --radius-chart-bar-client: 4px;   /* client bars */

  /* The dotted-underline-to-solid hover is the signal for "this opens",
     used by drill-downs, input finders, and the Tools+ link. */
  --underline-signal: 2px;

  /* ------------------------------------------------------------------
     SPACING SCALE
     A 4-based rem scale. Screens compose from these names only.
     ------------------------------------------------------------------ */
  --space-2xs: 0.25rem;
  --space-xs:  0.5rem;
  --space-sm:  0.75rem;
  --space-md:  1rem;
  --space-lg:  1.5rem;
  --space-xl:  2rem;
  --space-2xl: 3rem;
  --space-3xl: 4rem;
  --space-4xl: 6rem;

  /* ------------------------------------------------------------------
     TYPE SCALE
     Spectral carries headings: Light (300) for large marketing-style
     headlines, Regular (400) for section headings and warm subheads.
     GEIST carries body, interface, and ALL figures, hero figures
     included, with tabular figures on numeric content. Body text is
     never set in Spectral; headlines are never set in Geist. Both faces
     are self-hosted under tools/design/fonts/ (SIL OFL, obtained from
     the google/fonts repository) and loaded by fonts/fonts.css; no font
     CDN is ever linked.

     GEIST REPLACED IBM PLEX SANS on 2026-08-12, Goldy's ruling from the
     type board (docs/review/zb1-type-board.html): seven sans faces under
     one constant Spectral headline, judged by eye. Spectral was kept
     unchanged by the same ruling. Geist is a variable font covering
     100-900, so every weight below is a real weight, not a synthetic
     one, and its digits are equal-width under tabular figures.
     ------------------------------------------------------------------ */
  --font-display: "Spectral", Georgia, serif;
  --font-serif:   "Spectral", Georgia, serif;
  --font-sans:    "Geist", "Helvetica Neue", Arial, sans-serif;

  /* The small end of the scale is fixed: body copy does not shrink on a
     phone, it just reflows. */
  --text-caption:    0.75rem;
  --text-small:      0.875rem;
  --text-body:       1rem;
  --text-lead:       1.125rem;
  --text-title-sm:   1.375rem;

  /* RESPONSIVE DISPLAY SCALE (Goldy's finding, corrections round two,
     2026-08-12). The four large steps clamp between a mobile minimum
     and the desktop size they have always had. At 1440 each one still
     resolves to exactly its old fixed value, so nothing about the
     desktop render changes; at 390 each drops to its floor so a
     headline no longer stacks one word per line and a figure no longer
     breaks across three lines. The middle term is a rem base plus a vw
     term, so the size tracks the viewport smoothly instead of jumping
     at a breakpoint.

     Sizes shrinking is only half the fix. A FIGURE NEVER WRAPS
     MID-NUMBER at any size: .u-figure below holds numeric display text
     on one line, because "$12," on one line and "480" on the next is
     not a smaller number, it is a wrong one. */
  --text-title:      clamp(1.5rem,  1.35rem + 0.6vw, 1.75rem);
  --text-headline:   clamp(1.75rem, 1.40rem + 1.5vw, 2.25rem);
  --text-display:    clamp(2rem,    1.50rem + 2.2vw, 3rem);
  --text-display-xl: clamp(2.5rem,  1.80rem + 3.0vw, 3.75rem);   /* the result
                                                     number, large and
                                                     unmissable */

  --leading-tight:  1.15;
  --leading-snug:   1.35;
  --leading-body:   1.6;

  --weight-light:    300;   /* Spectral Light, large headlines only (ZB-1) */
  --weight-regular:  400;
  --weight-medium:   500;
  --weight-semibold: 600;
  --weight-bold:     700;

  /* Standing rule: any column of figures uses tabular numerals. */
  --font-numeric-figures: tabular-nums;

  /* ------------------------------------------------------------------
     RADII AND BORDERS
     Soft radii, 8 to 14, per the design system. The hairline frame is
     the signature card frame: thin, inset, never chunky.
     ------------------------------------------------------------------ */
  --radius-sm:   8px;
  --radius-md:   12px;
  --radius-lg:   14px;
  --radius-pill: 999px;

  --border-hairline: 1px;
  --border-chip:     1.5px;   /* retained: the outgoing outlined-pill weight,
                                 still used by the specimen's comparison
                                 strip so Goldy can see what was replaced */
  --border-rule:     4px;     /* the left rule on the callout card, the one
                                 treatment allowed to stop the eye */
  --size-status-dot: 0.625rem;  /* the inline status dot in the quiet default */

  --focus-ring-width:  2px;
  --focus-ring-offset: 2px;
  --color-focus-ring:  oklch(26.30% 0.0120 44.58);  /* warm ink, from #2A2320 */

  /* ------------------------------------------------------------------
     SHADOW ELEVATION SCALE
     Layered ink-tinted shadows so lift reads warm, not sooty.
     ------------------------------------------------------------------ */
  --shadow-1: 0 1px 2px oklch(26.30% 0.0120 44.58 / 0.06),
              0 1px 1px oklch(26.30% 0.0120 44.58 / 0.04);
  --shadow-2: 0 2px 4px oklch(26.30% 0.0120 44.58 / 0.07),
              0 4px 12px oklch(26.30% 0.0120 44.58 / 0.06);
  --shadow-3: 0 4px 8px oklch(26.30% 0.0120 44.58 / 0.08),
              0 12px 28px oklch(26.30% 0.0120 44.58 / 0.10);

  /* ------------------------------------------------------------------
     MOTION
     Durations per docs/build-standards.md section 4. Micro 100 to 150,
     interface 150 to 250, modals 200 to 300, and 300 is a hard
     ceiling. Exits run about 20 percent faster than entrances. Only
     transform and opacity ever animate. Ease-out is the default and
     ease-in never drives interface motion. A numeric value never
     animates: no counting up, correct in its first frame.
     ------------------------------------------------------------------ */
  --duration-micro:          120ms;
  --duration-interface:      200ms;
  --duration-modal:          260ms;
  --duration-micro-exit:     100ms;
  --duration-interface-exit: 160ms;
  --duration-modal-exit:     210ms;
  /* Chart builds keep these even when reduce zeros the ones above. */
  --duration-build:          260ms;
  --duration-build-fade:     200ms;

  --ease-out:      cubic-bezier(0.2, 0, 0, 1);
  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
}

/* Standing rule made usable: apply to any column of figures. */
.u-tabular-figures {
  font-variant-numeric: var(--font-numeric-figures);
}

/* ALIGNMENT (Goldy's ruling, 2026-08-12). Text aligns left by default,
   everywhere. Centering is a deliberate exception applied through THIS
   one named class, so the intent is visible in the markup instead of
   scattered as ad-hoc styles. Columns of figures right-align so place
   values line up; that takes precedence inside numeric table columns.
   Text is never justified. */
.u-center       { text-align: center; }
.u-align-figures { text-align: right; }

/* A FIGURE NEVER WRAPS MID-NUMBER (Goldy's finding, 2026-08-12). Any
   numeric display value carries this class: it stays on one line at
   every viewport width, and the responsive display scale above is what
   makes that fit rather than overflow. */
.u-figure {
  white-space: nowrap;
  font-variant-numeric: var(--font-numeric-figures);
}

/* ------------------------------------------------------------------
   THE LOCKED ZIVA CHIP SYSTEM, shipped (Goldy's ruling, 2026-08-12).
   Two treatments, no pills.
   ------------------------------------------------------------------ */

/* 1. The quiet default: an inline dot plus the status word in ink. */
.status {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-xs);
  font-size: var(--text-small);
  font-weight: var(--weight-medium);
  color: var(--color-ink-body);
}
.status-dot {
  flex: none;
  width: var(--size-status-dot);
  height: var(--size-status-dot);
  border-radius: var(--radius-pill);
  /* Nudged to sit on the text baseline rather than float above it. */
  transform: translateY(calc(var(--size-status-dot) / -8));
}
.status-good  .status-dot { background: var(--color-status-good-outline); }
.status-watch .status-dot { background: var(--color-status-watch-outline); }
.status-action .status-dot { background: var(--color-status-action-outline); }

/* 2. The one item that must stop the eye: the left-rule white callout. */
.callout {
  background: var(--color-surface-card);
  border-left: var(--border-rule) solid var(--color-hairline);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-1);
  padding: var(--space-md) var(--space-lg);
}
.callout-good   { border-left-color: var(--color-status-good-outline); }
.callout-watch  { border-left-color: var(--color-status-watch-outline); }
.callout-action { border-left-color: var(--color-status-action-outline); }
.callout .status { font-weight: var(--weight-semibold); }

/* Interface motion can go still. Chart-build durations stay, so a
   machine with Windows animations off still sees the visual arrive. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --duration-micro:          0ms;
    --duration-interface:      0ms;
    --duration-modal:          0ms;
    --duration-micro-exit:     0ms;
    --duration-interface-exit: 0ms;
    --duration-modal-exit:     0ms;
  }
}
