/* ==========================================================================
   tokens.css — Culp Landscaping (Athens, GA). Compiled from the approved
   brief (runs/culp-landscaping-athens-ga/brief.md — warm-craft /
   boxwood/clay-cream/light / tag-stack). Every value below cites a brief
   section; nothing here is a model default (house-tech-spec §3).
   ========================================================================== */

:root {

  /* --- Colour (brief §4.1/§4.2) -------------------------------------------
     Derivation (design-rules §6): step 1 (real colours) empty — dossier §4.5
     has none to depart from. Step 2 (local character): accent = Georgia
     Piedmont red clay. Step 3 (semantic anchor): dominant hue = boxwood, a
     real clipped-hedge shrub common to Piedmont residential landscaping.

     R4 (brief §0 #4): base.css hardcodes .btn--primary{background:
     var(--color-accent)}. The tile's own naming put boxwood green on
     --color-accent, which would have shipped a green CTA — never scored,
     never intended. --color-accent below carries clay rust instead; no hex
     changes, only the token NAME each hex is bound to. */

  --scheme: light;

  --color-bg:            #FBF3E7;  /* kraft-cream ground */
  --color-surface:       #F3E6D2;  /* raised panels: tag-cards, form fields, FAQ items */
  --color-ink:           #2B2420;  /* body/heading text on bg/surface */
  --color-ink-muted:     #6B5D4F;  /* secondary text on bg/surface */
  --color-accent:        #A84A2A;  /* clay rust — "the one colour that means act" (R4) */
  --color-accent-ink:    #FBF3E7;  /* cream text ON accent (button labels) */

  /* Brief-specific: the dominant registry hue, decorative/atmosphere ONLY —
     never a text colour, never a button colour, never a required-role token
     (brief §4.2). Hero atmosphere, sprig, service-tag-row accent texture. */
  --color-boxwood:       #4A5B34;
  --color-boxwood-light: #6B7F4C;  /* hero gradient's lightest green stop */

  /* R3 (brief §0): border-strong measures 2.72:1 against surface — below the
     3:1 control floor — so it is reserved for controls on --color-bg ONLY
     (nav-toggle, 3.04:1). Tag-card/tag-hole borders are decorative, not
     controls, and use --color-border instead. */
  --color-border:        #E4D5B8;  /* decorative hairlines, tag-card borders, tag-hole */
  --color-border-strong: #9C8A6E;  /* CONTROL boundaries on --color-bg only (nav-toggle) */

  --color-focus:         #2B2420;  /* :focus-visible ring — 13.86:1 vs bg, 12.40:1 vs surface */
  --color-selection-bg:  #A84A2A;
  --color-selection-ink: #FBF3E7;

  /* No --color-focus-on-band: no dark band on this site carries a focusable
     element (brief §4.2) — the hero field is decorative; every control sits
     on --color-bg/--color-surface. Left undeclared rather than unused. */
  /* --color-focus-on-band: …; */


  /* --- Typography (brief §2) -----------------------------------------------
     Two families, four static woff2 instances, SIL OFL 1.1 (assets/fonts/
     OFL.txt). R2: no font-variation-settings — weight via font-weight only. */

  --font-display: 'Domine', 'Domine Fallback', Georgia, 'Times New Roman', serif;
  --font-body:    'Karla', 'Karla Fallback', Arial, 'Helvetica Neue', sans-serif;

  --font-weight-display:     700;   /* the only weight Domine ships */
  --font-weight-body:        400;
  --font-weight-body-strong: 700;   /* buttons, block-titles, tag titles */

  /* Brief §2.6 calls for --tracking-wide (eyebrow/kicker/button) only; no
     heading tracking is specified, so --tracking-tight (read by base.css's
     h1-h4 rule) is a neutral 0, not an invented negative value. */
  --tracking-tight: 0em;
  --tracking-wide:  0.08em;  /* eyebrow, kicker — matches the tile's own value (brief §2.7) */

  /* --- Fluid scale (brief §2.7), computed at 320/375/768/1440 ------------- */
  --text-hero:    clamp(1.5rem, 5.28vw, 4.5rem);
  --text-h2:      clamp(1.7rem, 4.4vw, 2.5rem);
  --text-h3:      clamp(1.15rem, 2.7vw, 1.45rem);
  --text-lead:    clamp(1.05rem, 2.1vw, 1.25rem);
  --text-body:    clamp(1rem, 1.3vw, 1.0625rem);
  --text-small:   0.85rem;   /* FIXED, not fluid — same value at every width */
  --text-eyebrow: 0.75rem;   /* FIXED, not fluid — same value at every width */

  --leading-tight: 1.08;   /* H1 only */
  --leading-snug:  1.3;    /* h2/h3, lead */
  --leading-body:  1.6;    /* prose, FAQ answers, season-strip copy, footer */
  --leading-caps:  1.4;    /* eyebrow, kicker, button label */

  /* --- Space (brief §3) ----------------------------------------------------
     One scale, 3xs → 3xl. --space-3xl continues the brief's own progression
     (×1.5 from --space-lg on) — the brief's table stops at 2xl, but the
     textarea min-height reads 3xl (house-tech-spec §3's required step);
     every other brief in this ledger resolves the same arithmetic to 144px. */
  --space-3xs: 4px;  --space-2xs: 8px;  --space-xs: 12px; --space-sm: 16px;
  --space-md: 24px;  --space-lg: 40px;  --space-xl: 64px; --space-2xl: 96px;
  --space-3xl: 144px;

  /* design-rules §7.1's ONE inter-section token: .section's padding-block and
     the hero's padding-block-end. 64px below 768, 96px at ≥768 (media override
     below). */
  --section-gap: var(--space-xl);

  /* --- Layout (brief §3) -----------------------------------------------------
     --layout-gutter is what .container reads; resolves to one of the brief's
     two named gutter tokens at the brief's own breakpoint (override below). */
  --layout-container:          72rem;         /* 1152px */
  --layout-measure:            62ch;
  --layout-gutter-below-768:   var(--space-md);  /* 24px */
  --layout-gutter-at-768-plus: var(--space-lg);  /* 40px */
  --layout-gutter:             var(--layout-gutter-below-768);
  --layout-tap-min:            44px;
  --header-height:             56px;  /* brief §5.3 step 1: fixed height <=56px + 1px border, at every breakpoint */

  /* --- Radius / shadow / border (brief §3) -----------------------------------
     Both scoped, not uniform (design-rules §4 bans that default): radius on
     buttons/tag-cards/tag-hole only (ref-010's letterpress craft); shadow on
     tag-cards only (the "hung/pinned object" lift). Else radius-none/shadow-none. */
  --radius-sm:   2px;
  --radius-none: 0;
  --shadow-sm:   0 6px 14px rgb(43 36 32 / .12);
  --shadow-none: none;

  --border-hairline: 1px;
  --border-thick:    3px;   /* house default — unchanged; :focus-visible ring width only, not a brief design value */
  --border-style:    solid;

  /* --- Motion (brief §8) — house reveal defaults, unchanged (brief doesn't
     override them). */
  --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 satellite motion (brief §7.4), unchanged from tiles/tile-c.html.
     Twine draws once; tag settles once (overshoot) then sways continuously;
     sprig sways independently, un-synced timing. Tokenised, not raw in
     site.css. */
  --duration-twine-draw:  1s;
  --duration-tag-settle:  1.4s;
  --delay-tag-settle:     0.5s;
  --ease-tag-settle:      cubic-bezier(.34, 1.4, .4, 1);   /* overshoot, brief §7.4 */
  --duration-tag-sway:    6.4s;
  --delay-tag-sway:       1.9s;
  --duration-sprig-sway:  7.6s;

  --tag-settle-start-rotate: -16deg;
  --tag-settle-start-y:      -14px;
  --tag-rest-rotate:         -3deg;
  --tag-sway-rotate:          3deg;
  --sprig-rest-rotate:       -4deg;
  --sprig-sway-rotate:        4deg;

  /* transform-origin for tag/sprig, in the field SVG's own viewBox user-units
     (shared viewBox 0 0 320 190, unchanged from tiles/tile-c.html). */
  --tag-transform-origin:   165px 38px;
  --sprig-transform-origin: 250px 145px;

  /* Hero field (brief §7.3): fixed height, only position yields. 240px below
     768, 360px at ≥768 (media override below). */
  --field-height: 240px;

  /* Services tag-row (brief §7.3): fixed-size cards, independently rotated,
     matching tiles/tile-c.html's own dimension/angles. */
  --tag-card-w:  190px;
  --tag-rotate-1: -2deg;
  --tag-rotate-2: 1.4deg;
  --tag-rotate-3: -1deg;

  /* Hero first-screen arithmetic (brief §7.1 @375px, §7.2 @1440px): every gap
     between DOM-order elements is its own token. Values below are the 375px
     column; the media override resolves 1440px. */
  --hero-pad-top:          var(--space-md);   /* 24px → 96px */
  --hero-gap-eyebrow-h1:   var(--space-xs);   /* 12px → 24px */
  --hero-gap-h1-cta:       var(--space-sm);   /* 16px → 24px */
  --hero-gap-cta-field:    var(--space-md);   /* 24px → 40px */
  --hero-gap-field-lead:   var(--space-sm);   /* 16px → 24px */
  --hero-gap-lead-facts:   var(--space-xs);   /* 12px → 16px */
  --cta-height:            44px;              /* brief §7.1/§7.2: 44px below 768, 50px at ≥768 */

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

@media (min-width: 48em) {
  :root {
    --layout-gutter: var(--layout-gutter-at-768-plus);
    --section-gap:   var(--space-2xl);
    --field-height:  360px;

    --hero-pad-top:        var(--space-2xl); /* 96px */
    --hero-gap-eyebrow-h1: var(--space-md);  /* 24px */
    --hero-gap-h1-cta:     var(--space-md);  /* 24px */
    --hero-gap-cta-field:  var(--space-lg);  /* 40px */
    --hero-gap-field-lead: var(--space-md);  /* 24px */
    --hero-gap-lead-facts: var(--space-sm);  /* 16px */
    --cta-height:          50px;
  }
}

/* --------------------------------------------------------------------------
   @font-face — Domine 700 and Karla 400/700/400-italic, self-hosted, SIL OFL
   1.1 (assets/fonts/OFL.txt), static instances only (brief §2.1-§2.2; R2: no
   font-variation-settings). Fetched from Google Fonts' "latin" subset woff2s
   (Karla's variable file instanced to static 400/700 with fonttools
   varLib.instancer first), then re-subset to house-tech-spec §8's declared
   safe range with fonttools/pyftsubset, identical across all four files.

   Coverage gap (house-tech-spec §8): U+2010-2012, U+2015, U+2032-2033 are in
   the declared range and absent from all four source instances (fontTools
   cmap read) — same gap on every face, so no mid-sentence fallback split is
   possible, and none of these appear in this site's copy (only dash used is
   the plain hyphen U+002D, which every face carries).
   -------------------------------------------------------------------------- */

@font-face {
  font-family: 'Domine';
  src: url('../assets/fonts/domine-700-latin.woff2') format('woff2');
  font-weight: 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;
}

@font-face {
  font-family: 'Karla';
  src: url('../assets/fonts/karla-400-latin.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: 'Karla';
  src: url('../assets/fonts/karla-700-latin.woff2') format('woff2');
  font-weight: 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;
}

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

/* --------------------------------------------------------------------------
   Metrics-matched fallbacks (brief §2.5; house-tech-spec §8). Donors per the
   brief: Georgia for Domine, Arial for Karla — neither redistributable nor
   present here, so each is measured against its own open metric-compatible
   clone: Gelasio for Georgia, Liberation Sans for Arial (same substitution
   precedent as sites/franklins-lawn-care-macon-ga). Computed with
   scripts/font-metrics.mjs against the shipped, subset woff2 files.
   Acceptance test: Lighthouse CLS 0.000 (README.md has the full table).
   -------------------------------------------------------------------------- */

@font-face {
  font-family: 'Domine Fallback';
  src: local('Georgia');
  font-weight: 700;
  font-style: normal;
  size-adjust: 95.95%;
  ascent-override: 93.8%;
  descent-override: 25.01%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Karla Fallback';
  src: local('Arial');
  font-weight: 400;
  font-style: normal;
  size-adjust: 103.53%;
  ascent-override: 88.57%;
  descent-override: 24.34%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Karla Fallback';
  src: local('Arial'), local('Arial Bold');
  font-weight: 700;
  font-style: normal;
  size-adjust: 100.06%;
  ascent-override: 91.64%;
  descent-override: 25.18%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Karla Fallback';
  src: local('Arial Italic'), local('Arial');
  font-weight: 400;
  font-style: italic;
  size-adjust: 93.62%;
  ascent-override: 97.95%;
  descent-override: 26.92%;
  line-gap-override: 0%;
}
