/* ==========================================================================
   SPARTAN HOMES — DESIGN TOKENS
   Custom home builder · Lake Anna / Spotsylvania VA
   Load order: tokens.css → base.css → components.css → animations.css
   No external requests. All fonts are local woff2.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. FONTS (local, font-display: swap)

   NOTE FOR MAINTAINERS:
   assets/fonts/raleway.woff2 is the Raleway *Italic* variable font
   (wght 100–900, italicAngle -12). It is declared below as the italic face
   only — using it for upright body copy would slant the entire site.
   Upright UI/body copy therefore runs on Open Sans (upright VF, wght 300–800),
   which is also a brand font.

   TO RESTORE UPRIGHT RALEWAY: drop an upright Raleway VF at
   assets/fonts/raleway-upright.woff2, uncomment the @font-face below,
   and set --font-sans to "Raleway", "Open Sans", ...  Nothing else changes.
   -------------------------------------------------------------------------- */

/* Display serif — headings only */
@font-face {
  font-family: "Vidaloka";
  src: url("../assets/fonts/vidaloka.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* Cinzel — chiseled Roman caps, matched to the "SPARTAN" logo wordmark.
   Headings render in caps forms (Cinzel has no true lowercase — lowercase
   input renders as small caps, the classic inscriptional look).
   The site requests display headings at several weights (light 300 for hero/
   section titles, 400 for h1–h4). Cinzel ships no light cut, so each loaded
   file is mapped across a weight RANGE — any request resolves to bold Cinzel,
   which is what matches the logo's weight. */
@font-face {
  font-family: "Cinzel";
  src: url("../assets/fonts/cinzel-700.woff2") format("woff2");
  font-weight: 300 700;      /* headings render BOLD to sit closer to the logo's weight */
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Cinzel";
  src: url("../assets/fonts/cinzel-900.woff2") format("woff2");
  font-weight: 701 900;      /* the big display titles get the heaviest (black) cut */
  font-style: normal;
  font-display: swap;
}

/* Freshman (William Boyd) — the collegiate wedge-serif that matches the "SPARTAN"
   logo wordmark. Primary heading face; Cinzel stays as the fallback. */
@font-face {
  font-family: "Freshman";
  src: url("../assets/fonts/freshman.woff2") format("woff2");
  font-weight: 400 900;
  font-style: normal;
  font-display: swap;
}

/* Body / UI — upright variable */
@font-face {
  font-family: "Open Sans";
  src: url("../assets/fonts/opensans.woff2") format("woff2-variations"),
       url("../assets/fonts/opensans.woff2") format("woff2");
  font-weight: 300 800;
  font-style: normal;
  font-display: swap;
}

/* Raleway — ITALIC variable face (pull quotes, emphasis) */
@font-face {
  font-family: "Raleway";
  src: url("../assets/fonts/raleway.woff2") format("woff2-variations"),
       url("../assets/fonts/raleway.woff2") format("woff2");
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
}

/*
@font-face {
  font-family: "Raleway";
  src: url("../assets/fonts/raleway-upright.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
*/

:root {
  /* ------------------------------------------------------------------
     2. RAW PALETTE — built out from the 7 brand colors into usable ramps
     Brand: #F49C22 #FCF5EA #251B07 #CB4124 #D99F2A #FFFFFF #8C8577
     ------------------------------------------------------------------ */

  /* Warm neutral (cream → sand → stone). Surfaces, borders, muted type. */
  --c-white:      #ffffff;
  --c-sand-50:    #fefbf6;
  --c-sand-100:   #fcf5ea; /* BRAND cream */
  --c-sand-200:   #f6ecdc;
  --c-sand-300:   #ebdfca;
  --c-sand-400:   #dbcbae;
  --c-sand-500:   #bfb094; /* hairline on cream */
  --c-sand-600:   #a49b88;
  --c-sand-700:   #8c8577; /* BRAND warm grey */
  --c-sand-800:   #6a6356;
  --c-sand-900:   #4c463a;

  /* Ink — near-black brown. Body copy, dark sections. */
  --c-ink-500:    #6f5c37;
  --c-ink-600:    #55431f;
  --c-ink-700:    #3b2d11;
  --c-ink-800:    #251b07; /* BRAND ink */
  --c-ink-900:    #1a1305;
  --c-ink-950:    #0f0b03;

  /* Amber — the signature orange. ACCENT ONLY. Never a background wash. */
  --c-amber-100:  #fdeacd;
  --c-amber-200:  #fbd79f;
  --c-amber-300:  #f9c46f;
  --c-amber-400:  #f6ae45;
  --c-amber-500:  #f49c22; /* BRAND orange */
  --c-amber-600:  #e08a13;
  --c-amber-700:  #b96e0c;
  --c-amber-800:  #8d5308;

  /* Gold — the quieter metallic. Rules, badges, ornaments. */
  --c-gold-400:   #e6b855;
  --c-gold-500:   #d99f2a; /* BRAND gold */
  --c-gold-600:   #b8831c;

  /* Rust — sparing secondary accent (alerts, "veteran-owned", underlines). */
  --c-rust-400:   #de6b52;
  --c-rust-500:   #cb4124; /* BRAND rust */
  --c-rust-600:   #a5311a;

  /* Green — NGBS certification only. Never decorative. */
  --c-leaf-500:   #4a7c46;
  --c-leaf-600:   #3a6337;

  /* ------------------------------------------------------------------
     3. SEMANTIC TOKENS — LIGHT (default) CONTEXT
     Contrast rules baked in (measured, not asserted):
       ink-800 on cream .......... 14.8:1  ✅
       sand-800 on cream .......... 5.4:1  ✅ (muted body)
       amber-500 on cream ......... 2.2:1  ❌ NEVER text — decoration only
       amber-700 on cream ......... 3.66:1 ❌ FAILS AA for normal text.
                                           Graphics/icons only (3:1 threshold).
       amber-800 on cream ......... 5.75:1 ✅ THIS is the accent text color on
                                           light. Use --accent-ink-on-light.
       ink-800 on amber-500 ....... 6.9:1  ✅ (this is why buttons are dark-on-orange)
       amber-500 on ink-800 ....... 6.9:1  ✅ (accent text is legal on dark)
     ------------------------------------------------------------------ */

  --surface:            var(--c-sand-100);  /* page background: warm cream   */
  --surface-raised:     var(--c-white);     /* cards on cream                */
  --surface-sunken:     var(--c-sand-300);  /* wells, alternating bands      */
  --surface-inverse:    var(--c-ink-900);   /* dramatic dark sections        */
  --surface-inverse-2:  var(--c-ink-800);
  --surface-scrim:      rgba(15, 11, 3, 0.55);

  --ink:                var(--c-ink-800);   /* primary type                  */
  --ink-strong:         var(--c-ink-950);
  --ink-muted:          var(--c-sand-900);  /* secondary type                */
  --ink-subtle:         var(--c-sand-800);  /* captions, meta                */
  --ink-inverse:        var(--c-sand-100);  /* type on dark                  */
  --ink-inverse-muted:  rgba(252, 245, 234, 0.72);
  --ink-inverse-subtle: rgba(252, 245, 234, 0.54);

  --line:               rgba(37, 27, 7, 0.14); /* hairline on cream          */
  --line-strong:        rgba(37, 27, 7, 0.28);
  --line-inverse:       rgba(252, 245, 234, 0.16);
  --line-inverse-strong:rgba(252, 245, 234, 0.34);

  --accent:             var(--c-amber-500);
  --accent-hover:       var(--c-amber-400);
  --accent-press:       var(--c-amber-600);
  --accent-ink:         var(--c-ink-900);  /* type that sits ON accent       */
  --accent-soft:        rgba(244, 156, 34, 0.14);
  --accent-quiet:       var(--c-gold-500);
  /* Accent-COLOURED TYPE on a light surface. 5.75:1 on cream. Always use this
     for eyebrows/meta/links — never --accent or --c-amber-700, both of which
     fail AA at text sizes. */
  --accent-ink-on-light: var(--c-amber-800);

  --danger:             var(--c-rust-500);
  --certified:          var(--c-leaf-500);

  --focus-ring:         var(--c-amber-500);
  --focus-ring-inverse: var(--c-amber-400);
  --selection-bg:       var(--c-amber-500);
  --selection-fg:       var(--c-ink-900);

  /* ------------------------------------------------------------------
     4. TYPE
     ------------------------------------------------------------------ */
  --font-display: "Freshman", "Cinzel", "Trajan Pro", "Iowan Old Style",
                  "Palatino Linotype", Palatino, Georgia, "Times New Roman", serif;
  --font-sans:    "Open Sans", "Segoe UI", Helvetica, Arial, sans-serif;
  --font-ui:      var(--font-sans);
  --font-italic:  "Raleway", var(--font-sans); /* italic face — quotes/emphasis */

  /* Fluid scale. Root ≈ 16px @390 → 17px @1440. Ratio ~1.24 mobile, ~1.33 desk. */
  --step--2: clamp(0.694rem, 0.680rem + 0.06vw, 0.729rem);
  --step--1: clamp(0.833rem, 0.806rem + 0.12vw, 0.900rem);
  --step-0:  clamp(1.000rem, 0.955rem + 0.19vw, 1.106rem);
  --step-1:  clamp(1.200rem, 1.129rem + 0.30vw, 1.369rem);
  --step-2:  clamp(1.440rem, 1.332rem + 0.46vw, 1.700rem);
  --step-3:  clamp(1.728rem, 1.568rem + 0.68vw, 2.110rem);
  --step-4:  clamp(2.074rem, 1.841rem + 0.99vw, 2.630rem);
  --step-5:  clamp(2.488rem, 2.155rem + 1.42vw, 3.290rem);
  --step-6:  clamp(2.986rem, 2.516rem + 2.01vw, 4.120rem);
  --step-7:  clamp(3.583rem, 2.928rem + 2.80vw, 5.160rem);
  --step-8:  clamp(4.300rem, 3.393rem + 3.87vw, 6.480rem);

  --lh-tight:   1.02;  /* display                    */
  --lh-snug:    1.16;  /* large headings — Cinzel caps need a touch more leading
                          than mixed-case so two-line titles don't read cramped */
  --lh-heading: 1.24;  /* small headings             */
  --lh-body:    1.65;  /* paragraphs                 */
  --lh-loose:   1.75;  /* long-form / lede           */

  --ls-display: 0.02em;   /* Cinzel Roman caps want open tracking, not tightening */
  --ls-heading: 0.015em;
  --ls-body:    0;
  --ls-ui:      0.01em;
  --ls-eyebrow: 0.18em;  /* small caps / eyebrows    */
  --ls-caps:    0.08em;

  --wt-light:     300;
  --wt-regular:   400;
  --wt-medium:    500;
  --wt-semibold:  600;
  --wt-bold:      700;

  /* Short measure is a luxury cue. 65ch is the hard ceiling for body copy;
     ledes are shorter still so a centred section head never runs long. */
  --measure:        62ch;
  --measure-narrow: 48ch;
  --measure-lede:   52ch;  /* type islands stay narrow & centred — a luxury cue */

  /* ------------------------------------------------------------------
     5. SPACE (4px base, geometric-ish)
     ------------------------------------------------------------------ */
  --space-3xs: 0.25rem;  /*  4 */
  --space-2xs: 0.5rem;   /*  8 */
  --space-xs:  0.75rem;  /* 12 */
  --space-sm:  1rem;     /* 16 */
  --space-md:  1.5rem;   /* 24 */
  --space-lg:  2rem;     /* 32 */
  --space-xl:  3rem;     /* 48 */
  --space-2xl: 4rem;     /* 64 */
  --space-3xl: 6rem;     /* 96 */
  --space-4xl: 8rem;     /* 128 */
  --space-5xl: 12rem;    /* 192 */

  /* ONE vertical rhythm. Every band on every page uses --section-y.
     --section-y-tight exists only for bands that sit directly against a
     full-bleed image. Nothing else may invent its own padding. */
  --section-y:       clamp(5rem, 3rem + 6.5vw, 9rem);
  --section-y-tight: clamp(3.25rem, 2.25rem + 3.5vw, 5.5rem);
  --gutter:          clamp(1.25rem, 0.9rem + 1.8vw, 2.5rem);

  /* Space between a .section-head and the content it introduces */
  --head-gap:        clamp(2.5rem, 1.6rem + 3vw, 4.5rem);
  /* The single gap value every grid in the system uses */
  --grid-gap:        clamp(1.25rem, 0.75rem + 1.6vw, 2.25rem);

  /* ------------------------------------------------------------------
     6. LAYOUT — ONE RAIL.
     Every section's content sits inside .container. Same max-width, same
     gutter, top to bottom. That single fact is most of "symmetrical".
     ------------------------------------------------------------------ */
  --container:        80rem;   /* 1280 — THE rail                     */
  --container-narrow: 46rem;   /* 736  — faq, form, quote             */
  --container-text:   36rem;   /* 576                                 */

  --header-h:      4.5rem;   /* 72  */
  --header-h-lg:   5.5rem;   /* 88  */
  --header-h-slim: 4rem;     /* 64 — scrolled state */
  --callbar-h:     4rem;     /* 64 — mobile sticky call bar */

  --z-base:      0;
  --z-raised:    10;
  --z-sticky:    100;
  /* The mobile drawer sits BELOW the header on purpose: the header carries the
     close (X) button, and the drawer's own padding-block-start clears it.
     If --z-nav ever goes above --z-header again, the drawer becomes a trap. */
  --z-nav:       150;
  --z-header:    200;
  --z-callbar:   250;
  --z-lightbox:  400;

  /* ------------------------------------------------------------------
     7. RADII — restrained. Luxury reads square, not rounded.
     ------------------------------------------------------------------ */
  --radius-xs:   2px;
  --radius-sm:   3px;
  --radius-md:   4px;
  --radius-lg:   6px;
  --radius-xl:   10px;
  --radius-pill: 999px;
  --radius-card: var(--radius-md);

  /* ------------------------------------------------------------------
     8. SHADOWS — warm-tinted, never grey/blue
     ------------------------------------------------------------------ */
  --shadow-xs:  0 1px 2px rgba(37, 27, 7, 0.06);
  --shadow-sm:  0 2px 6px rgba(37, 27, 7, 0.07),
                0 1px 2px rgba(37, 27, 7, 0.05);
  --shadow-md:  0 8px 24px -8px rgba(37, 27, 7, 0.14),
                0 2px 6px -2px rgba(37, 27, 7, 0.08);
  --shadow-lg:  0 24px 48px -16px rgba(37, 27, 7, 0.22),
                0 6px 14px -6px rgba(37, 27, 7, 0.1);
  --shadow-xl:  0 40px 80px -24px rgba(15, 11, 3, 0.34),
                0 12px 24px -12px rgba(15, 11, 3, 0.16);
  --shadow-accent: 0 10px 30px -10px rgba(244, 156, 34, 0.5);
  --shadow-inset-line: inset 0 0 0 1px var(--line);

  /* ------------------------------------------------------------------
     9. MOTION — smooth, slow, expensive
     ------------------------------------------------------------------ */
  --ease:          cubic-bezier(0.16, 1, 0.3, 1);   /* the house curve */
  --ease-out:      cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out:   cubic-bezier(0.65, 0, 0.35, 1);
  --ease-in:       cubic-bezier(0.5, 0, 0.75, 0);
  --ease-linear:   linear;

  --dur-instant: 120ms;
  --dur-fast:    240ms;
  --dur-base:    400ms;
  --dur-slow:    600ms;
  --dur-slower:  800ms;
  --dur-slowest: 1100ms;

  --reveal-dur:    900ms;
  --reveal-rise:   28px;
  --reveal-stagger: 90ms;

  --img-zoom: 1.03;   /* gentle hover scale */

  /* ------------------------------------------------------------------
     10. EFFECTS / SCRIMS — the readability guarantee.

   Every one of these is specified against the WORST CASE: a pure-white
   subject (#fff — a white farmhouse in noon sun, a blown-out sky). The
   numbers below are measured, not vibes. Cream type is #FCF5EA, L≈0.912.

   Two layers are ALWAYS used together on a hero:
     --scrim-flat   a uniform tint  (raises the floor everywhere)
     --scrim-hero   a vertical ramp (buries the type zone)
   Composite alpha a = 1 − (1−a_flat)(1−a_ramp).

   Over white, at the four ramp stops with --scrim-flat (0.30):
     ramp 0.90 @  0%  → a=0.930 → cream on it ≈ 15.2:1   (stat bar)
     ramp 0.72 @ 35%  → a=0.804 → cream on it ≈ 10.6:1   (headline + lede)
     ramp 0.46 @ 62%  → a=0.622 →              ≈  5.9:1   (eyebrow)
     ramp 0.34 @ 85%  → a=0.538 →              ≈  4.7:1   (no type — sky)
     ramp 0.50 @100%  → a=0.650 →              ≈  6.4:1   (header edge)
   Floor across the ENTIRE hero is 4.7:1. There is nowhere to put cream
   type on this thing that fails AA. That is the point.

   DO NOT lighten these without re-running the arithmetic against #fff.
   ------------------------------------------------------------------ */
  --scrim-flat: rgba(15, 11, 3, 0.30);

  --scrim-hero: linear-gradient(
      to top,
      rgba(15, 11, 3, 0.90) 0%,
      rgba(15, 11, 3, 0.72) 35%,
      rgba(15, 11, 3, 0.46) 62%,
      rgba(15, 11, 3, 0.34) 85%,
      rgba(15, 11, 3, 0.50) 100%);

  /* Full-bleed break with a centred pull-quote: the type lands dead centre, so
     the ramp is DARKEST at the middle (under the text) and eases toward the
     edges where the photo can breathe. flat 0.46 + ramp 0.60 at centre → a≈0.78
     (~10:1); edges → a≈0.70 (~7:1). Even across the width, so a bright roofline
     on one side can no longer wash the quote out. */
  --scrim-bleed: linear-gradient(
      to top,
      rgba(15, 11, 3, 0.44) 0%,
      rgba(15, 11, 3, 0.60) 50%,
      rgba(15, 11, 3, 0.44) 100%);
  --scrim-bleed-flat: rgba(15, 11, 3, 0.46);

  /* A photo used as a SECTION background (the lead form). Type sits all over it,
     but the fields carry their own surface — so the scrim only has to protect
     the cream labels/heads, not bury the photograph. 0.62 keeps the interior
     shot visibly luxurious while cream on it still clears ~5.5:1 over the worst
     (a bright window). Do not push back toward opaque — that destroys the photo. */
  --scrim-section: rgba(15, 11, 3, 0.62);

  /* Caption / label riding the bottom of a gallery tile. Bottom-anchored, and
     captions land on white farmhouses, so 0.92 at the baseline. */
  --scrim-caption: linear-gradient(
      to top,
      rgba(15, 11, 3, 0.92) 0%,
      rgba(15, 11, 3, 0.65) 42%,
      rgba(15, 11, 3, 0) 100%);

  --rule-accent: 2px solid var(--accent);

  /* Aspect ratios. Consistency WITHIN a grid is most of what makes it look
     expensive — so a grid picks ONE of these and every tile obeys it. */
  --aspect-card:     4 / 3;
  --aspect-wide:    16 / 9;
  --aspect-photo:    3 / 2;
  --aspect-portrait: 3 / 4;
  --aspect-square:   1 / 1;
}

/* --------------------------------------------------------------------------
   11. INVERSE CONTEXT
   Put .on-dark (or .section--dark) on any container to flip the semantic
   tokens. Everything downstream — type, rules, buttons, cards, forms —
   re-derives automatically. This is the ONLY switch page builders need.
   -------------------------------------------------------------------------- */
.on-dark,
.section--dark,
.site-footer {
  --surface:        var(--c-ink-900);
  --surface-raised: rgba(252, 245, 234, 0.05);
  --surface-sunken: var(--c-ink-950);
  /* On ink, full-strength amber is 6.9:1 — legal, and it's the right hue. */
  --accent-ink-on-light: var(--c-amber-500);
  --ink:            var(--c-sand-100);
  --ink-strong:     var(--c-white);
  --ink-muted:      rgba(252, 245, 234, 0.74);
  --ink-subtle:     rgba(252, 245, 234, 0.56);
  --line:           var(--line-inverse);
  --line-strong:    var(--line-inverse-strong);
  --focus-ring:     var(--focus-ring-inverse);
  --shadow-md:      0 8px 24px -8px rgba(0, 0, 0, 0.5);
  --shadow-lg:      0 24px 48px -16px rgba(0, 0, 0, 0.55);
  color: var(--ink);
  background-color: var(--surface);
}

/* Media (photography) always sits on ink, regardless of context */
.on-media {
  --ink:        var(--c-sand-100);
  --ink-strong: var(--c-white);
  --ink-muted:  rgba(252, 245, 234, 0.8);
  --line:       rgba(252, 245, 234, 0.26);
  --focus-ring: var(--focus-ring-inverse);
  --accent-ink-on-light: var(--c-amber-500);
  color: var(--ink);
}

/* --------------------------------------------------------------------------
   12. REDUCED MOTION — collapse every duration at the token level
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-instant: 1ms;
    --dur-fast:    1ms;
    --dur-base:    1ms;
    --dur-slow:    1ms;
    --dur-slower:  1ms;
    --dur-slowest: 1ms;
    --reveal-dur:  1ms;
    --reveal-rise: 0px;
    --reveal-stagger: 0ms;
    --img-zoom:    1;
  }
}
