/* ==========================================================================
   tokens.css — the design brief, compiled.

   THIS FILE IS THE ONLY PLACE RAW VALUES LIVE.
   Every hex colour, font name, size literal and timing value on the site is
   declared here and consumed as var(--token) everywhere else. That contract
   (house-tech-spec §3) is what makes the tweaks bar work, keeps uniqueness in
   *values* while consistency lives in *structure*, and lets a purchased site
   be re-themed by editing one file.

   Compiled from runs/bonneville-lawn-care-idaho-falls-id/brief.md. Every
   value below either restates a brief §2/§3 value or carries forward an
   unchanged house default the brief explicitly kept (type scale §3, reveal
   geometry §7, section-gap §4) — nothing here is improvised.
   ========================================================================== */

:root {

  /* --- Colour ------------------------------------------------------------
     Brief §2. Derivation order: real-world colour (none recorded, dossier
     §4.5 blocked at every tier) → local character (Idaho Falls high-desert
     agricultural belt) → family norms (fresh-organic). Every pairing below
     is in the brief's contrast table, computed WCAG relative luminance. */

  --scheme: light;

  --color-bg: #f9f1e6;                /* warm-cream */
  --color-surface: #fffaf3;
  --color-ink: #2c2118;
  --color-ink-muted: #6b5a48;         /* 5.90:1 on bg, 6.36:1 on surface */
  --color-accent: #b1502f;            /* adobe-clay — dominant hue */
  --color-accent-ink: #ffffff;        /* 5.18:1 on accent */

  /* House-required structural colours (consumed by base.css) */
  --color-border: #e9dcc9;
  --color-focus: #b1502f;             /* 4.62:1 vs bg AND surface — clears 3:1 ring floor */

  /* No dark band exists anywhere on this site (brief §2, §9) — left unset
     per tokens.css's own instruction. */
  /* --color-focus-on-band: …; */
  --color-selection-bg: #b1502f;
  --color-selection-ink: #ffffff;

  /* Brief-specific colours (§2). Sage is a decorative-fill-only secondary —
     it never carries text at full saturation (solid sage on white fails the
     4.5:1 body floor at 4.35:1, brief §2's binding rule). --color-sage-tint
     is the one place sage carries text-adjacent area (season-card fill,
     12.71:1 / 5.34:1 — both AA). */
  --color-sage: #6b7f5e;              /* decorative fill ONLY — leaf/seed marks, icon strokes. NEVER text. */
  --color-sage-tint: #e4e9dd;         /* season-card + field chip background */


  /* --- Typography --------------------------------------------------------
     Brief §3: Gantari (display, variable 400–800) + Hanken Grotesk (body,
     variable 400–700). Both self-hosted, subset to the house declared safe
     range (house-tech-spec §8), OFL 1.1. No italic instance ships — emphasis
     is colour + weight only (brief §3). Metrics-matched fallbacks below. */

  --font-display: 'Gantari', 'Gantari Fallback', 'Arial', 'Helvetica Neue', sans-serif;
  --font-body: 'Hanken Grotesk', 'Hanken Grotesk Fallback', 'Arial', 'Helvetica Neue', sans-serif;

  --font-weight-body: 400;
  --font-weight-body-strong: 600;
  --font-weight-display: 700;

  /* --- Type scale --------------------------------------------------------
     Brief §3: "House scale, carried forward unchanged — no dossier or
     playbook line argues for a different scale." Identical to the skeleton
     default; restated here (not omitted) because tokens.css is the single
     place values live. */

  --text-hero: clamp(2.6rem, 9vw, 5rem);
  --text-h2: clamp(1.9rem, 5vw, 3rem);
  --text-h3: clamp(1.3rem, 3vw, 1.75rem);
  --text-lead: clamp(1.125rem, 2.2vw, 1.375rem);
  --text-body: clamp(1rem, 1.4vw, 1.0625rem);
  --text-small: 0.9375rem;
  --text-eyebrow: 0.8125rem;

  --leading-tight: 1.05;
  --leading-snug: 1.25;
  --leading-body: 1.6;

  --tracking-tight: -0.02em;
  --tracking-normal: 0em;
  --tracking-wide: 0.1em;             /* brief §3 — checked against Hanken Grotesk's metrics at this size */

  /* --- Space -------------------------------------------------------------
     House scale, unchanged — brief §4 argues no departure. */

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

  /* Brief §4: --section-gap = --space-xl = 4rem = 64px, fixed at every
     breakpoint. Two call sites only (.section padding-block, hero's
     padding-block-end) — no other rule sets vertical rhythm. */
  --section-gap: var(--space-xl);

  /* --- Layout ------------------------------------------------------------ */

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

  /* Brief §4 point 1: header fixed at 56px content + 1px border-bottom, at
     every breakpoint — not a step on the space scale, so it is named here
     rather than approximated by one. Brief §5: hero field (the LCP image +
     atmosphere band the plate sits over) is the hero's own full content
     height at each of the brief's two breakpoints, computed as
     (hero bottom − hero top) from the §5 arithmetic tables: 515−101=414px
     below 48em, 734−101=633px at 48em and up. */
  --layout-header-height: 56px;
  --hero-field-height: 414px;
  --hero-field-height-md: 633px;

  /* Brief §5's own H1 budget arithmetic: container max-width 11ch below
     48em, 48rem at 48em and up — the narrow column that makes the H1 stack
     to its intentional ≤3 lines at both breakpoints. --hero-plate-width,
     --season-card-min and --process-image-* are Builder execution values
     (component widths, not brief-cited numbers) named here rather than left
     as bare literals in site.css, per the token contract (house-tech-spec
     §3). */
  --hero-h1-max-mobile: 11ch;
  --hero-h1-max-desktop: 48rem;
  --hero-plate-width: 28rem;
  --season-card-min: 15rem;
  --process-image-min: 14rem;
  --process-image-max: 20rem;
  --nav-panel-max-width: min(80vw, 16rem);

  /* --- Radius / shadow / border -------------------------------------------
     House scale. fresh-organic's "rounded" family norm (brief, family line)
     is expressed by WHICH step site.css applies to which component — cards
     and chips take --radius-lg, controls take --radius-sm — not by minting
     new radius values (design-rules §4: multiple steps exist so the brief
     is selective, not so everything rounds uniformly). */

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

  --shadow-none: none;
  --shadow-sm: 0 1px 2px rgb(44 33 24 / 0.06);
  --shadow-md: 0 6px 24px rgb(44 33 24 / 0.09);
  --shadow-lg: 0 24px 60px rgb(44 33 24 / 0.14);

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

  /* --- Motion --------------------------------------------------------------
     House defaults. Brief §7's reveal geometry (--reveal-shift 1.25rem,
     --reveal-stagger 90ms) equals these house values already — restated,
     not overridden. */

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

  /* --- Hero atmosphere (brief §1/§2/§7) ------------------------------------
     The clay + sage radial gradients cited in brief §2's gradient-vs-flat
     measurement, and the two leaf/seed satellite marks of the living-hero
     signature move (brief §7/§8). Brief-specific tokens, not house ones. */
  --hero-gradient-clay: radial-gradient(60% 45% at 88% 6%, rgb(177 80 47 / 0.22) 0%, transparent 70%);
  --hero-gradient-sage: radial-gradient(50% 40% at 100% 90%, rgb(107 127 94 / 0.16) 0%, transparent 70%);

  /* --- Z layers -----------------------------------------------------------
     Hero stack (field < atmosphere < plate), house pattern: the image is the
     LCP element and sits lowest, the two gradients/satellite marks sit above
     it, and the opaque text plate sits highest so R4's flat-pair contrast
     table is what a reader actually sees. */
  --z-base: 0;
  --z-atmosphere: 1;
  --z-plate: 2;
  --z-header: 100;
  --z-nav-panel: 200;
  --z-skip-link: 300;
}

/* --------------------------------------------------------------------------
   @font-face — self-hosted woff2, latin subset, font-display: swap. Both
   OFL 1.1 (licence files in assets/fonts/), both subset to the house
   declared safe range (house-tech-spec §8), identical unicode-range on both.

   Coverage gap (recorded per §8, not silently shipped, full detail in
   README.md): U+2010/2011/2012/2015/2032/2033 are absent from BOTH shipped
   faces equally — never a mid-sentence split — and none render in this
   site's copy.
   -------------------------------------------------------------------------- */

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

@font-face {
  font-family: 'Hanken Grotesk';
  src: url('../assets/fonts/hanken-grotesk-variable-latin.woff2') format('woff2');
  font-weight: 400 700;
  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 §8, brief §3) -------------
   local('Arial') / local('Liberation Sans') — same metric donor, not a
   second one. size-adjust measured via canvas.measureText() in headless
   Chromium against the real shipped woff2 (FontFace API); overrides are
   each real face's own hhea metrics ÷ size-adjust. Matched at each face's
   PRIMARY usage weight — Gantari 700 (display), Hanken Grotesk 400 (body,
   by far the greatest character volume) — with that weight declared
   explicitly so the browser never synthesizes bold onto an unmatched 400
   face. Full derivation in README.md. */

@font-face {
  font-family: 'Gantari Fallback';
  src: local('Arial'), local('Liberation Sans');
  font-weight: 700;
  size-adjust: 95.4%;
  ascent-override: 99.6%;
  descent-override: 26.2%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Hanken Grotesk Fallback';
  src: local('Arial'), local('Liberation Sans');
  font-weight: 400;
  size-adjust: 101.3%;
  ascent-override: 98.8%;
  descent-override: 29.9%;
  line-gap-override: 0%;
}
