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

   Aquatic Gardens & Landscaping (Mankato, MN). Every value below is taken
   from the approved brief (runs/aquatic-gardens-and-landscaping-mankato-mn/
   brief.md §§2-5, §8) — nothing here is improvised. Contrast pairs are
   re-derived independently in brief §4 and match what is declared below.

   THIS FILE IS THE ONLY PLACE RAW VALUES LIVE (house-tech-spec §3).
   ========================================================================== */

:root {

  /* --- Colour --------------------------------------------------------------
     Derivation order: design-rules §6 — brief §3.1. Step 1 (the business's
     real-world colours) is EMPTY (dossier front-matter brand_color is unset);
     millrace-slate carries the local river-valley character AND the founding
     water-feature specialty instead (brief §3.1 steps 2-4). One deliberate
     mode: light. */

  --scheme: light;

  --color-bg:          #F6F2EA;        /* parchment-stone — page ground */
  --color-surface:     #FFFFFF;        /* card/chip ground, form fields */
  --color-ink:         #1A2429;        /* deep slate-charcoal */
  --color-ink-muted:   #4A5860;        /* muted slate-grey */
  --color-accent:      #35505C;        /* DOMINANT — millrace-slate, hsl(200°, 29%, 28%) */
  --color-accent-ink:  #F7F3EA;        /* text ON accent fill */

  /* Hero atmosphere — the generated asset's grading target and the CSS field
     backdrop it sits against. NOT general UI tokens (brief §3.2). */
  --color-atmos-deep:  #1B2C33;        /* darkest gradient/asset extreme */
  --color-atmos-mid:   #2C4650;        /* mid gradient stop */

  /* House-required structural colours */
  --color-border:          #7C8A90;    /* slate-mist — every hairline, divider, field border */
  --color-hairline-accent: #B08A4E;    /* gold rule — decorative-only, credentials-list divider (ref-007) */
  --color-focus:           #1A2429;    /* :focus-visible ring */

  /* No dark band on this site (brief §5.1 rule 6: "one light register
     throughout") — --color-focus-on-band is intentionally not declared. */

  --color-selection-bg: #35505C;
  --color-selection-ink: #F7F3EA;


  /* --- Typography ------------------------------------------------------------
     Libre Caslon Text (display) / Mulish (body) — both OFL 1.1, self-hosted,
     brief §2. Metrics-matched fallbacks below carry the swap so CLS stays
     0.000 (house-tech-spec §8). */

  --font-display: 'Libre Caslon Text', 'Libre Caslon Text Fallback', 'Georgia', 'Times New Roman', serif;
  --font-body:    'Mulish', 'Mulish Fallback', 'Helvetica Neue', Arial, sans-serif;

  --font-weight-body:        400;
  --font-weight-body-strong: 600;
  --font-weight-display:     400;   /* both roman and italic instances are static 400 (brief §2.3) */

  /* --- Type scale — brief §2.9, computed across its range at §2.10 -------- */

  --text-display: clamp(2.0rem, 1.3rem + 3.0vw, 4.25rem);
  --text-h2:      clamp(1.375rem, 1.10rem + 1.0vw, 2.0rem);
  --text-lead:    clamp(1.0625rem, 1.0rem + 0.25vw, 1.3125rem);
  --text-body:    1rem;      /* 16px, fixed at every width */
  --text-eyebrow: 0.75rem;   /* 12px, fixed at every width */
  --text-micro:   0.6875rem; /* 11px, fixed at every width */

  /* text-small: the skeleton's small-print role (nav links, field labels,
     footer). Not itemised in brief §2.9's table because the brief's own
     scale stops at --text-micro; this site has no separate "small" size
     distinct from eyebrow, so nav/label/footer text shares --text-eyebrow's
     12px value rather than introducing an unbriefed sixth step. */
  --text-small: var(--text-eyebrow);

  --leading-tight:   1.08;  /* h1 — see house-tech-spec §8's CLS acceptance test */
  --leading-snug:    1.20;  /* h3 section heads, thanks.html heading */
  --leading-lead:    1.55;
  --leading-body:    1.62;
  --leading-eyebrow: 1.35;  /* fixed 20px row height used in the fold arithmetic, brief §5.5 */

  --tracking-wide: 0.16em;  /* eyebrows, uppercase labels */

  /* Libre Caslon Text is a book-proportioned serif and needs no tightening —
     the C2-winning tile sets its own h1 at letter-spacing: 0 throughout
     (tiles/tile-a.html, .h1 rule) and this carries that forward exactly. */
  --tracking-tight:  0em;
  --tracking-normal: 0em;

  /* --- Space -----------------------------------------------------------------
     Brief §3.3's scale exactly. --space-3xl is not itemised in the brief (its
     scale stops at 2xl, matching the tile) but remains required house
     structure for the form's textarea min-height; kept at the skeleton's
     value since no brief value replaces it. */

  --space-3xs: 0.25rem;  /* 4px */
  --space-2xs: 0.5rem;   /* 8px */
  --space-xs:  0.75rem;  /* 12px */
  --space-sm:  1rem;     /* 16px */
  --space-md:  1.5rem;   /* 24px */
  --space-lg:  2.5rem;   /* 40px */
  --space-xl:  4rem;     /* 64px */
  --space-2xl: 6rem;     /* 96px */
  --space-3xl: 9rem;     /* unbriefed — house default, textarea min-height only */

  --section-gap: var(--space-xl);   /* = 64px, at EVERY width — brief §5.4 */

  /* --- Layout ------------------------------------------------------------
     --layout-gutter's clamp already reproduces brief §5.3's stated gutters
     exactly: 20px @375 (clamp floor), 32px @640 (5vw), 48px @≥1024 (clamp
     ceiling) — unchanged from the skeleton default. --layout-container caps
     at 800px only from 1440 up (brief §5.3); below that the container is
     unconstrained by a hard cap (site.css applies the cap in a @media
     (min-width: 90em) block, since a custom property cannot vary by
     breakpoint any other way). */

  --layout-container: none;           /* uncapped below 1440 */
  --layout-container-wide: 50rem;     /* 800px, ≥1440 — brief §5.3. site.css
                                          switches which token .container
                                          reads at 90em; this token is never
                                          reassigned, only referenced */
  --layout-measure: 62ch;
  --layout-gutter: clamp(1.25rem, 5vw, 3rem);
  --layout-tap-min: 44px;

  /* Header wordmark — brief §6 sticky-chrome: 13px @<1024, 16px @≥1024. A
     two-step (not fluid) size; site.css switches which token
     .site-header__brand reads at @media (min-width: 64em). */
  --text-wordmark: 0.8125rem;         /* 13px, < 1024 */
  --text-wordmark-lg: 1rem;           /* 16px, ≥ 1024 */

  /* --- Hero field height — brief §5.2: fixed, unchanged, every width ----- */
  --hero-field-height: 300px;

  /* --- Fold-arithmetic tokens — brief §5.3, §5.5. Values that are exact
     pixel figures the brief states directly (not derivable from the space
     scale) get their own token here rather than a raw literal in site.css.
     Where a brief figure equals an existing scale step, that step is reused
     instead of a duplicate token (noted per line). */
  --eyebrow-row-height: 20px;                  /* fixed at every width */
  --header-height: 57px;                       /* 56px box + 1px border, brief §6 */

  --hero-pad-start: 20px;                      /* < 1024 */
  --hero-pad-start-lg: var(--space-xl);        /* ≥ 1024 — 64px */
  --hero-gap-eyebrow-h1: var(--space-xs);      /* < 1024 — 12px */
  --hero-gap-eyebrow-h1-lg: var(--space-md);   /* ≥ 1024 — 24px */
  --hero-gap-h1-cta: 20px;                     /* < 1024 */
  --hero-gap-h1-cta-lg: var(--space-md);       /* ≥ 1024 — 24px */
  --hero-field-margin-top: 18px;               /* < 1024 */
  --hero-field-margin-top-lg: var(--space-md); /* ≥ 1024 — 24px */

  --cta-height: 52px;                          /* < 1024 */
  --cta-height-lg: 56px;                       /* ≥ 1024 */

  /* thanks.html's own fold arithmetic (brief §5.5): heading -> lead and
     lead -> CTA are both this gap, at every width. */
  --thanks-gap: 18px;                          /* < 1024 */
  --thanks-gap-lg: var(--space-md);            /* ≥ 1024 — 24px */

  /* --- Radius / shadow / border -------------------------------------------
     Brief §3.2: --radius-none and --shadow-none carry every call site on
     this site (cards, buttons, inputs, chips — zero rounded corners, no
     shadow anywhere, a considered zero). --radius-sm/md/lg/pill and
     --shadow-sm/md/lg keep their SKELETON values verbatim, per brief §3.2's
     own instruction, with zero call sites in this site's own site.css —
     they satisfy the house-required token group and base.css's two
     structural (non-decorative) uses (skip-link, :focus-visible) and are
     otherwise unused here. */

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

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

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

  /* --- Motion --------------------------------------------------------------
     House reveal-system durations: unused on this site (brief §8.1 — no
     scroll-triggered reveal system runs; body sections are static on load),
     kept at skeleton defaults only because base.css's reduced-motion kill
     switch still references them for the shared reveal primitives.

     The still-surface signature's own timings — brief §8.2. */

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

  --duration-ripple: 5000ms;   /* full one-shot sequence, plays once */
  --duration-reed:   8500ms;   /* infinite loop */
  --duration-leaf:   11000ms;  /* infinite loop */

  --ease-out:    cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-ripple: cubic-bezier(.2, .6, .2, 1);
  --ease-loop:   ease-in-out;

  /* Still-surface signature geometry — brief §8.2's exact keyframe table,
     carried forward from the C2-winning tile unchanged. One-off values with
     no scale relationship to the space tokens, so each gets its own name
     rather than a raw literal in site.css (spec §3). */
  --ripple-border-width: 2px;
  --ripple-start-size:   10px;
  --ripple-start-offset: -5px;    /* = -(ripple-start-size / 2) */
  --ripple-end-size:     220px;
  --ripple-end-offset:   -110px;  /* = -(ripple-end-size / 2) */
  --ripple-core-size:    6px;
  --ripple-core-offset:  -3px;    /* = -(ripple-core-size / 2) */
  --reed-width:  3px;
  --reed-height: 70px;
  --leaf-width:  20px;
  --leaf-height: 12px;
  --leaf-drift-x: 6px;
  --leaf-drift-y: -3px;
  --leaf-rest-x:  3px;   /* reduced-motion parked position, brief §8.3 */
  --leaf-rest-y:  -1px;
  --plate-label-max-width: 12.5rem;
  --tracking-plate: .02em;         /* tile's own .plate-lbl letter-spacing */
  --section-image-max-width: 28rem;

  --reveal-shift: 1.25rem;
  --reveal-stagger: 90ms;

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

/* --------------------------------------------------------------------------
   @font-face — self-hosted woff2, brief §2. Subset to house-tech-spec §8's
   declared safe range and declares that same range in unicode-range (brief
   §2.5). Fetched from Google Fonts (Libre Caslon Text v5, Mulish v18) and
   subset with fontTools on 2026-08-27; see README.md for the coverage-gap
   record and the measured metrics-matched fallback numbers.
   -------------------------------------------------------------------------- */

@font-face {
  font-family: 'Libre Caslon Text';
  src: url('../assets/fonts/librecaslontext-400.woff2') format('woff2');
  font-weight: 400;
  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: 'Libre Caslon Text';
  src: url('../assets/fonts/librecaslontext-400italic.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: 'Mulish';
  src: url('../assets/fonts/mulish-400.woff2') format('woff2');
  font-weight: 400;
  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: 'Mulish';
  src: url('../assets/fonts/mulish-600.woff2') format('woff2');
  font-weight: 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 §8, brief §2.4). Measured from
   the shipped woff2 files' hhea/OS-2 tables against the published capsize
   metrics for the donor system faces (Georgia; Helvetica Neue). See
   README.md for the full derivation. */

@font-face {
  font-family: 'Libre Caslon Text Fallback';
  src: local('Georgia'), local('Times New Roman');
  size-adjust: 120.79%;
  ascent-override: 80.3%;
  descent-override: 21.52%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Libre Caslon Text Fallback';
  src: local('Georgia'), local('Times New Roman');
  font-style: italic;
  size-adjust: 118.36%;
  ascent-override: 81.96%;
  descent-override: 21.97%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Mulish Fallback';
  src: local('Helvetica Neue'), local('Arial');
  size-adjust: 116.25%;
  ascent-override: 86.45%;
  descent-override: 21.51%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Mulish Fallback';
  src: local('Helvetica Neue'), local('Arial');
  font-weight: 600;
  size-adjust: 118.15%;
  ascent-override: 85.06%;
  descent-override: 21.16%;
  line-gap-override: 0%;
}
