/* ==========================================================================
   tokens.css — the design brief, compiled (house-tech-spec §3).
   Source: runs/triple-c-repair-texarkana-ar/brief.md §2–§6, carried against
   the approved C2 tile (tiles/tile-c.html) for the values the brief itself
   says are "carried from the tile" (radius, border, no-shadow register).
   Every value below traces to one of those two documents; nothing here was
   chosen at build time.
   ========================================================================== */

:root {

  /* --- Colour — brief §2.1. Derivation order (design-rules §6): step 1
     (real-world colour) is EMPTY — dossier §4.5 records no van/uniform/
     signage colour to sample and no brand_color in front-matter. Step 2
     (local character) is also EMPTY (§4.5: no distinguishing local/regional
     visual signal). Step 3 (family norms, pushed for distinctiveness and
     away from blue — playbooks/hvac.md §6.1's collision note + dossier §4.6's
     top competitor already running blue/orange) supplies the palette below.
     One deliberate mode, light. --- */

  --scheme: light;

  --color-bg:          #F5F1E9;  /* Warm Ivory — page ground */
  --color-surface:     #EDE7DA;  /* raised panels, chips, cards */
  --color-ink:         #211F1D;  /* Graphite Ink — body + heading text */
  --color-ink-muted:   #56534E;  /* Slate Warm — secondary text, 6.80:1 vs bg */
  --color-accent:      #6E6A63;  /* Duct Graphite — text-safe at large sizes only
                                     (4.77:1 vs bg / 4.37:1 vs surface — brief §2.1
                                     gate: large-text/decorative-rule use only,
                                     never body-sized text) */
  --color-accent-ink:  #F5F1E9;  /* text sitting ON --color-ink (primary CTA label) */

  /* Brief-specific colours (brief §2.1) */
  --color-accent-deep:   #9A5A1E;  /* Pilot Amber, deepened — text-safe, 4.84:1 vs
                                       bg. The ONE emphasised proof word/number,
                                       and the focus ring. */
  --color-accent-bright: #C97B2E;  /* Pilot Amber — 2.93:1 vs bg, FAILS even the
                                       large-text 3:1 floor on purpose. Illustration
                                       fill only (the hero's amber dial-needle
                                       touch); never set as text at any size. */

  /* Brief §2.1's gradient-over-text check: the hero's two atmosphere
     gradients, rgba forms of --color-accent and --color-accent-bright at the
     brief's own stated alpha values. Declared as tokens (not inline in
     site.css) so no raw colour literal sits outside this file. */
  --color-atmo-graphite: rgba(110, 106, 99, 0.16);  /* = --color-accent @16% */
  --color-atmo-amber:    rgba(201, 123, 46, 0.14);  /* = --color-accent-bright @14% */

  /* House-required structural colours (consumed by base.css) */
  --color-border: #DCD5C4;            /* DECORATIVE hairlines only — index-list
                                          rules, footer rule, field borders. No
                                          contrast floor: a divider is not a
                                          control (skeleton §3 note). */

  /* Control boundary, WCAG 1.4.11 (>=3:1 vs bg AND surface): brief §2.1
     re-uses --color-accent (4.77:1 / 4.37:1) for this exact role. */
  --color-border-strong: #6E6A63;     /* = --color-accent */

  --color-focus: #9A5A1E;             /* = --color-accent-deep, 4.84:1 vs bg /
                                          4.42:1 vs surface (brief §2.1) */

  /* No dark band anywhere on this site (brief §2.1: soft atmosphere gradients
     over --color-bg only; every other section sits on flat bg or surface), so
     --color-focus-on-band stays unset per the skeleton's own convention. */
  /* --color-focus-on-band: …; */

  --color-selection-bg:   #211F1D;
  --color-selection-ink:  #F5F1E9;

  /* --- Typography — brief §2.2. Two families, both SIL OFL 1.1, both
     self-hosted (assets/fonts/OFL.txt carries the notices). Instrument Serif
     ships ONE weight (400) and is used only in italic — italic is a
     font-style, never named alongside font-weight in
     font-variation-settings (house-tech-spec §8's `wght`-trap rule; this site
     sets no font-variation-settings at all). Work Sans is the single variable
     body/UI face, wght 400/600 via font-weight only. --- */

  --font-display: 'Instrument Serif', 'Instrument Serif Italic Fallback', 'Instrument Serif Italic Fallback 2', Georgia, serif;
  --font-body:    'Work Sans', 'Work Sans Fallback', Arial, sans-serif;

  --font-weight-display:      400;  /* Instrument Serif's only weight */
  --font-weight-body:         400;
  --font-weight-body-strong:  600;  /* eyebrow, CTA labels, nav, index-rail active state */

  /* --- Fluid type scale — brief §2.3, computed fresh across 320→1440 (the
     tile's own hero clamp is corrected here — see brief §2.3's own note on
     why). --text-eyebrow and --text-small are FIXED (no clamp): the brief's
     own table computes them flat at every width. --- */

  --text-eyebrow: 0.8125rem;                                  /* 13px, fixed */
  --text-small:   0.9375rem;                                  /* 15px, fixed */
  --text-body:    clamp(1rem, 0.95rem + 0.25vw, 1.1rem);      /* 16 -> 17.6px */
  --text-lead:    clamp(1.2rem, 1.1rem + 0.5vw, 1.5rem);      /* 19.2 -> 24px */
  --text-h3:      clamp(1.6rem, 1.35rem + 1.2vw, 2.1rem);     /* 25.6 -> 33.6px */
  --text-h2:      clamp(2.0rem, 1.65rem + 1.9vw, 2.8rem);     /* 32 -> 44.8px */
  --text-hero:    clamp(2.1rem, 1.8rem + 2.44vw, 4rem);       /* 33.6 -> 64px */

  /* Brief §2.3: leading-tight for hero/h2/h3 display type in general;
     leading-snug used ONCE, for the hero H1's own two-line wrap only — 1.05
     would crowd the italic descenders on that specific block. */
  --leading-tight: 1.05;
  --leading-snug:  1.25;
  --leading-body:  1.6;

  --tracking-tight:  0em;      /* Instrument Serif italic carries no tracking
                                   adjustment on this site — no brief/tile
                                   instruction to depart from neutral */
  --tracking-normal: 0em;
  --tracking-wide:   0.08em;   /* eyebrows, CTA labels, index rail (tile-c.html) */

  /* --- Space — house scale, unmodified (brief §3.2 keeps the house default
     step). --- */

  --space-3xs: 0.25rem;
  --space-2xs: 0.5rem;
  --space-xs: 0.75rem;
  --space-sm: 1rem;
  --space-md: 1.5rem;
  --space-lg: 2.5rem;
  --space-xl: 4rem;
  --space-2xl: 6rem;
  --space-3xl: 9rem;

  /* Inter-section rhythm — brief §3.2: --section-gap = --space-xl (64px),
     unchanged from the tile. Every intra-section gap on the page stays
     strictly below 2 x this (brief §3.2 verifies the largest, 40px). */
  --section-gap: var(--space-xl);

  /* --- Layout — house defaults plus the brief §3.1 sticky-chrome constants.
     --- */

  --layout-container: 72rem;
  --layout-measure: 62ch;
  --layout-gutter: clamp(1.25rem, 5vw, 3rem);
  --layout-tap-min: 44px;             /* WCAG touch-target floor; also the
                                          preview expiry bar's own height
                                          (css/preview.css --expiry-height) */

  /* Brief §3.1's own sticky-chrome arithmetic constants — fixed pixel values
     because the fold gate depends on the exact number, not a scale step. */
  --layout-header-height: 4rem;       /* 64px target, incl. border-bottom */
  --sticky-chrome: calc(var(--expiry-height, 0px) + var(--layout-header-height) + var(--border-hairline));
                                       /* target 44 + 64 + hairline ≈ 108px —
                                          §3.4's rail sticky offset reads this */

  --control-height:      3rem;        /* 48px — primary CTA (brief §3.1's own
                                          "48px button" figure) */
  --control-height-icon: var(--layout-tap-min); /* 44px — tel icon-button,
                                          nav-toggle */

  --hero-pad-top:    1.5rem; /* 24px, brief §3.1 */
  --hero-pad-bottom: 2rem;   /* 32px, brief §3.1 */

  /* Hero field: locked to the shipped raster's own ratio (brief §3.1 states
     200px @375 as a re-computable target, §7.2 rule 3) rather than an
     independent height, so object-fit: cover crops nothing at any width and
     the §6.1 anchor's measured overlay position stays exact everywhere.
     Renders ≈187px tall @375 (375×667 is the binding fold case, not 1440). */
  --hero-field-ratio: 1500 / 837;

  --breakpoint-rail: 641px;  /* brief §3.4's own sidebar-rail breakpoint —
                                literal px inside a @media condition is the
                                one house-permitted escape hatch
                                (base.css header note 1) */

  --rail-column: 12rem;          /* brief §3.4's sidebar-rail column width,
                                     ≥641px */
  --hero-title-measure: 18ch;    /* the hero H1's own 2-line wrap cap */
  --index-num-width: 1.75em;     /* "Systems we work on" list's own leading
                                     numeral column */
  --process-num-width: 1.4em;    /* process-row numeral column, carried from
                                     tile-c.html's own ".process-row .n" rule */

  /* The two dust motes' own drift amounts (brief §6), as percentages of the
     hero field's own box — the overlay's viewBox is percentage-normalised
     (0 0 100 100), so a CSS transform percentage resolves against it
     directly, carried in spirit from tile-c.html's dust-drift keyframe. */
  --mote-drift-x: 1.5%;
  --mote-drift-y: -1.25%;

  /* --- Radius / shadow / border — carried from the approved C2 tile
     (tiles/tile-c.html) exactly: 2px on interactive/chip elements, no radius
     elsewhere, no shadow anywhere (flat editorial register — design-rules §4
     bans a drop shadow on every card, and this family uses none at all). --- */

  --radius-none: 0;
  --radius-sm: 2px;
  --radius-md: 2px;
  --radius-lg: 2px;
  --radius-pill: 2px;

  --shadow-none: none;
  --shadow-sm: none;
  --shadow-md: none;
  --shadow-lg: none;

  --border-hairline: 1px;
  --border-thick: 2px;      /* tile-c.html's own rule/tick/active-marker weight */
  --border-style: solid;

  /* --- Motion — brief §6. base.css's reveal engine consumes --duration-slow
     and --ease-out directly; this site points --duration-slow at the brief's
     own reveal duration (320ms) rather than the house default. --- */

  --duration-fast: 140ms;
  --duration-base: 320ms;
  --duration-slow: 320ms;      /* = brief's reveal duration; base.css's reveal
                                   transition reads THIS token */

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);

  --reveal-shift: 1.25rem;
  --reveal-stagger: 90ms;      /* brief §6's own stagger, across the 8-item
                                   services list, the 3 process rows, the
                                   review cards */

  /* The signature — "the duct-line draws, then the dial settles" (brief §6).
     One-shot draw on load, then two independent, non-synced ambient loops. */
  --duration-draw: 1.8s;
  --delay-draw: 0.2s;
  --loop-dial: 6.9s;
  --loop-dust: 9.6s;
  --delay-dust-b: 3.2s;   /* the second dust mote's own phase offset, so its
                              9.6s loop never visibly syncs with the first */
  --motion-draw-length: 59;   /* the overlay duct-line's own measured path
                                  length in the 0-100 viewBox (path
                                  M30,40 Q58,52 78,72 ≈ 58.0 units) —
                                  stroke-dasharray/stroke-dashoffset unit */

  /* --- Z layers ------------------------------------------------------------ */
  --z-base: 0;
  --z-header: 100;
  --z-nav-panel: 200;
  --z-skip-link: 300;
}

/* Brief §6 reduced-motion: the signature-move tokens need their own collapse
   (base.css only collapses its own three); the settled visual state is set
   in site.css at matching specificity, no !important (spec §12). */
@media (prefers-reduced-motion: reduce) {
  :root {
    --duration-draw: 0.01ms;
    --delay-draw: 0s;
    --loop-dial: 0.01ms;
    --loop-dust: 0.01ms;
  }
}

/* --------------------------------------------------------------------------
   @font-face — self-hosted woff2, SIL OFL 1.1 (assets/fonts/OFL.txt), subset
   to the house declared safe range (house-tech-spec §8), byte-identical on
   both faces (brief §2.2).

   COVERAGE GAP (house-tech-spec §8's "found on first use" clause), checked by
   a fontTools cmap read against the shipped, post-subset woff2 files: both
   faces lack U+2010-2012/2015 (the documented, both-lack-it case, inert by
   construction). Instrument Serif Italic ALSO lacks U+2032/2033 (prime
   marks), which Work Sans carries — the "different matter" §8 calls a FIX if
   ever rendered in two faces on one line. It is not: copy.md's shipped
   strings contain no prime mark anywhere. Flagged rather than silently
   shipped; the range is not narrowed for a gap nothing on the page hits.
   -------------------------------------------------------------------------- */

@font-face {
  font-family: 'Instrument Serif';
  src: url('../assets/fonts/instrument-serif-italic-latin.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
  unicode-range:
    U+0020-007E, U+00A0, U+00A9, U+00AE, U+2122, U+00B0, U+00B7,
    U+00BF, U+00C0-00FF, U+2010-2015, U+2018-201A, U+201C-201E,
    U+2026, U+2032-2033;
}

@font-face {
  font-family: 'Work Sans';
  src: url('../assets/fonts/work-sans-variable-latin.woff2') format('woff2');
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
  unicode-range:
    U+0020-007E, U+00A0, U+00A9, U+00AE, U+2122, U+00B0, U+00B7,
    U+00BF, U+00C0-00FF, U+2010-2015, U+2018-201A, U+201C-201E,
    U+2026, U+2032-2033;
}

/* --------------------------------------------------------------------------
   Metrics-matched fallbacks (house-tech-spec §7/§8) — MEASURED with
   scripts/font-metrics.mjs (Fontaine's method) against each donor's real
   installed instance, never guessed.

   TWO TIERS for Instrument Serif Italic, the house's own documented shape
   (auto-evolution-north-logan-ut / alex-landscaping): Georgia is the correct
   donor for most real traffic, tried first via 'Instrument Serif Italic
   Fallback', measured against Gelasio (Georgia's open metric twin, since
   Georgia itself is not inspectable on this build box — `fc-match Georgia`
   -> DejaVu Serif). A second tier, 'Instrument Serif Italic Fallback 2',
   calibrated against DejaVu Serif (genuinely installed here; it has no
   italic instance, so the upright file is the donor for the italic override
   too, matching the house precedent), covers Linux/Android/CI before falling
   to an unmatched generic serif.

   Work Sans needs one tier: `fc-match Arial` resolves to Liberation Sans on
   this box, Arial's own metric twin, measured per weight (400, 600) since
   the variable font's glyph widths shift slightly per instance.
   -------------------------------------------------------------------------- */

@font-face {
  font-family: 'Instrument Serif Italic Fallback';
  src: local('Georgia');
  font-style: italic;
  font-weight: 400;
  size-adjust: 79.35%;
  ascent-override: 124.76%;
  descent-override: 39.07%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Instrument Serif Italic Fallback 2';
  src: local('DejaVu Serif');
  font-style: italic;
  font-weight: 400;
  size-adjust: 69.42%;
  ascent-override: 142.62%;
  descent-override: 44.66%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Work Sans Fallback';
  src: local('Arial'), local('Liberation Sans');
  font-weight: 400;
  font-style: normal;
  size-adjust: 113.41%;
  ascent-override: 82%;
  descent-override: 21.43%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Work Sans Fallback';
  src: local('Arial'), local('Liberation Sans');
  font-weight: 600;
  font-style: normal;
  size-adjust: 113.25%;
  ascent-override: 82.12%;
  descent-override: 21.46%;
  line-gap-override: 0%;
}
