/* ==========================================================================
   tokens.css — the design brief, compiled.
   Shedhorn Plumbing, Helena MT. Source: brief.md (approved 2026-09-18),
   quiet-premium family, sidebar-anchor archetype, "The Valve Opens" hero.
   Every value below is the brief's — house-tech-spec §3: this file is the
   only place raw values live.
   ========================================================================== */

:root {

  /* --- Colour — brief §2 -------------------------------------------------
     Derivation order (design-rules §6): dossier §4.5 real-world colour is
     genuinely empty (Wix template defaults, ground 4/provenance) → local
     character (Helena's pine valley) + trade-material echo (oxidised brass
     and copper reads this exact verdigris-pine register) → family norms
     (quiet-premium: restraint, one confident muted accent). Contrast table
     is brief §2; every pair re-verified below by scripts/qa/contrast.mjs. */

  --scheme: light;

  --color-bg: #F6F1E7;                /* parchment ground */
  --color-surface: #EDE6D6;           /* deeper parchment — cards, rail-adjacent panels */
  --color-ink: #1F2A22;               /* pine-black ink — body + headings */
  --color-ink-muted: #4B5A4E;         /* secondary text — 6.51:1 / 5.89:1 */
  --color-accent: #2F5D45;            /* pine/forest — the one colour that means "act" */
  --color-accent-ink: #FFFFFF;        /* 7.57:1 on accent */

  --color-border: #D9D0BC;            /* decorative hairlines only — no contrast floor */
  --color-border-strong: #4B5A4E;     /* = ink-muted; >=3:1 vs bg AND surface, WCAG 1.4.11 */

  --color-focus: #2F5D45;             /* = accent; >=3:1 vs bg AND surface */
  /* --color-focus-on-band: —; commented out. No dark band anywhere in this design (brief §2). */

  --color-selection-bg: #2F5D45;
  --color-selection-ink: #FFFFFF;

  /* Hero ground atmosphere (brief §2's gradient pair, measured at its
     extremes per design-rules §6 — a gradient is not a pairing). Two radial
     gradients over --color-bg; worst-case stop #e6dcc4 (L=0.720) clears
     AA under the eyebrow/h1 text block at 375px with margin (brief §2). */
  --color-hero-atmos-near: #f0ead9;
  --color-hero-atmos-far: #e6dcc4;

  /* --- Typography — brief §3 ----------------------------------------------
     Newsreader (display, variable wght) + Newsreader Italic (emphasis,
     variable wght) + Mulish (body, variable). SIL OFL 1.1, self-hosted.

     DELIVERY NOTE (house-tech-spec §7.1 lever 1; full reasoning in
     README.md's Build notes): the brief's opsz axis, kept live, measured
     68–72 KB/face post-subset — over the font-payload budget, because opsz
     carries continuously-interpolated kerning. Pinned to one instance (24)
     while wght stays genuinely variable: 83.6 KB shipped total. No
     `font-variation-settings` ships anywhere as a result — the opsz axis
     does not exist in the files — so `font-weight` alone sets weight. */

  --font-display: 'Newsreader', 'Newsreader Fallback', Georgia, 'Times New Roman', serif;
  --font-emphasis: 'Newsreader Italic', 'Newsreader Italic Fallback', Georgia, 'Times New Roman', serif;
  --font-body: 'Mulish', 'Mulish Fallback', 'Helvetica Neue', Arial, sans-serif;

  --font-weight-body: 400;
  --font-weight-body-strong: 700;      /* buttons, eyebrow labels (Mulish) */
  --font-weight-display: 500;          /* h1/h2/h3 default (Newsreader) */
  --font-weight-display-strong: 600;   /* section lead-in labels (Newsreader) */

  /* --- Type scale — brief §3, computed across its range at 375/1440 ------- */

  --text-hero: clamp(2rem, 1.5rem + 2.2vw, 3.2rem);       /* 32.25px@375 (slide) → 51.20px@1440 (flat) */
  --text-h2: clamp(1.5rem, 1.3rem + 1vw, 2.1rem);         /* 24.55px@375 → 33.60px@1440 */
  --text-h3: clamp(1.25rem, 1.1rem + 0.6vw, 1.55rem);     /* 20.00px@375 (at floor) → 24.80px@1440 */
  --text-lead: clamp(1.05rem, 0.98rem + 0.35vw, 1.2rem);  /* 16.99px@375 → 19.20px@1440 */
  --text-body: clamp(1rem, 0.96rem + 0.2vw, 1.06rem);     /* 16.11px@375 → 16.96px@1440 */
  --text-small: clamp(0.85rem, 0.82rem + 0.15vw, 0.92rem);/* 13.68px@375 → 14.72px@1440 */
  --text-eyebrow: clamp(0.72rem, 0.68rem + 0.2vw, 0.8rem);/* 11.63px@375 → 12.80px@1440 */

  --leading-tight: 1.05;   /* hero h1 */
  --leading-snug: 1.25;    /* h2/h3/lead/eyebrow */
  --leading-body: 1.6;     /* body copy */

  --tracking-tight: -0.02em;
  --tracking-normal: 0em;
  --tracking-wide: 0.08em; /* eyebrow only — ~0.93px at 11.63px, verified inside legible bounds */

  /* --- Space --------------------------------------------------------------
     House scale. --section-gap is the brief's one inter-section token
     (design-rules §7.1): 64px flat, identical at 375 and 1440 (brief §4). */

  --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;

  --section-gap: var(--space-xl);      /* = 4rem = 64px, flat (brief §4) */

  /* Hero-specific rhythm (brief §4.1's own first-screen arithmetic table —
     these two do not sit on the 3xs…3xl scale, they are the brief's stated
     figures for this hero, so they are named tokens rather than inline
     literals). */
  --space-hero-top: 1.6rem;      /* 25.6px — hero top padding */
  --space-hero-bottom: 1.25rem;  /* 20px — hero bottom padding */

  /* --- Layout --------------------------------------------------------------
     House defaults reproduce the brief's own 335px/375px content-width
     figure without an override: --layout-gutter's floor (1.25rem = 20px)
     is what clamp() actually resolves to at 375px (5vw = 18.75px < floor). */

  --layout-container: 72rem;
  --layout-measure: 62ch;
  --layout-gutter: clamp(1.25rem, 5vw, 3rem);
  --layout-tap-min: 44px;

  /* Sidebar-anchor rail (brief §4: persistent rail, ≥960px) */
  --layout-rail-w: 15rem;
  --layout-rail-breakpoint: 60em; /* 960px */

  /* Fixed geometry site.css consumes as tokens rather than literals
     (house-tech-spec §3) — the sticky-chrome heights (brief §4.1: 56px
     mobile / 72px desktop content height), the signature dial glyph's two
     fixed sizes (brief §6), and a handful of one-off component measures. */
  --header-h-mobile: 3.5rem;    /* 56px */
  --header-h-desktop: 4.5rem;   /* 72px */
  --dial-size: 20px;
  --dial-size-min: 16px;
  --hero-field-w-desktop: 26rem;
  /* QA r1 FIX: was flat, thinned above 768px. Scales with vw past it now. */
  --trust-texture-h: clamp(8rem, calc(100vw / 6), 20rem);
  --contact-divider-size: 5rem;
  --field-textarea-min: 6rem;

  /* --- Radius / shadow / border --------------------------------------------
     quiet-premium restraint (design-rules §3): sharp editorial geometry, no
     drop shadow anywhere (design-rules §4 bans a shadow on every card; this
     site ships none at all — the borrowed devices are typographic/line-based,
     ref-007/ref-011). House radius-sm only, for touch targets; --radius-none
     for the rail/trust panels (flat editorial blocks). */

  --radius-none: 0;
  --radius-sm: 2px;

  --shadow-none: none;

  --border-hairline: 1px;
  --border-thick: 3px;
  --border-style: solid;

  /* --- Motion — brief §6 ---------------------------------------------------
     House reveal system unchanged. The signature move ("the valve opens")
     adds its own tokens: a 2.2s ease-out one-shot rotation, a flow-line draw
     starting at 2.1s, and a slow (~6s) independent joint-glint loop — none of
     these reuse --duration-slow (640ms), which is an order of magnitude too
     fast for a load-triggered hero moment. All four collapse to ~0 under
     prefers-reduced-motion (site.css), same contract as the house tokens. */

  --duration-fast: 140ms;
  --duration-base: 320ms;
  --duration-slow: 640ms;

  --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;

  --duration-signature: 2200ms;        /* valve rotation, −70deg → 0deg, ease-out */
  --duration-signature-delay: 2100ms;  /* flow-line draw starts at 2.1s */
  --duration-signature-draw: 420ms;    /* flow-line draw length, then settles static */
  --duration-glint: 6000ms;            /* joint-glint loop, independent, non-synchronised */

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

/* --------------------------------------------------------------------------
   @font-face — self-hosted woff2, SIL OFL 1.1 (assets/fonts/OFL-*.txt).
   font-display: swap, a metrics-matched fallback (*Fallback families above
   the real ones), and the ONE house declared safe range (house-tech-spec
   §8), identical on all three faces so a mid-sentence split cannot occur.

   COVERAGE GAP (house-tech-spec §8 pattern): U+2010/2011/2012/2015 sit in
   the declared range and are absent from all three source faces alike
   (fontTools cmap read) — never mid-sentence in two faces, so not narrowed.

   FALLBACK METRICS measured with scripts/font-metrics.mjs against the real
   files. This environment has neither Times New Roman nor Helvetica Neue
   installed (fc-match substitutes Liberation Serif/Sans, both purpose-built
   metric clones) — the disclosed-caveat pattern `3-elements-landscaping-
   asheville-nc` recorded. `local()` still targets the real system faces.
   -------------------------------------------------------------------------- */

@font-face {
  font-family: 'Newsreader Fallback';
  src: local('Times New Roman'), local('Liberation Serif'), local('Georgia');
  ascent-override: 72.36%;
  descent-override: 26.09%;
  line-gap-override: 0%;
  size-adjust: 101.58%;
}

@font-face {
  font-family: 'Newsreader Italic Fallback';
  src: local('Times New Roman Italic'), local('Liberation Serif Italic'), local('Georgia Italic');
  font-style: italic;
  ascent-override: 79.03%;
  descent-override: 28.49%;
  line-gap-override: 0%;
  size-adjust: 93%;
}

@font-face {
  font-family: 'Mulish Fallback';
  src: local('Helvetica Neue'), local('Arial'), local('Liberation Sans');
  ascent-override: 96.2%;
  descent-override: 23.93%;
  line-gap-override: 0%;
  size-adjust: 104.47%;
}

@font-face {
  font-family: 'Newsreader';
  src: url('../assets/fonts/newsreader-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;
}

@font-face {
  font-family: 'Newsreader Italic';
  src: url('../assets/fonts/newsreader-italic-variable-latin.woff2') format('woff2');
  font-weight: 400 500;
  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: 'Mulish';
  src: url('../assets/fonts/mulish-variable-latin.woff2') format('woff2');
  font-weight: 400 800;
  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;
}
