/* ============================================================================
   ACG design tokens
   The single source of every raw value. Per rules/01 sections 1 to 6.

   TOKEN LAW: no raw hex, no raw px spacing, no font-size, and no duration may
   appear in any component or page CSS. If a value is not here, it does not
   exist. scripts/check-design-lint.sh fails the build on any violation.

   Clamps interpolate between the 390px mobile size and the 1440px desktop size
   on a 1.25 ratio at a 16px base. Formula: slope = (max-min)/(1440-390)*100vw,
   intercept = min - slope/100*390.
   ============================================================================ */

:root {
  /* -- 1. Type scale ------------------------------------------------------ */
  /* Six sizes maximum render on any one page. No intermediate sizes. */
  --fs-display: clamp(36px, 27.09px + 2.286vw, 60px); /* H1, hero only. One per page. */
  --fs-h2:      clamp(28px, 23.54px + 1.143vw, 40px);
  --fs-h3:      clamp(22px, 19.77px + 0.571vw, 28px);
  --fs-h4:      clamp(18px, 17.26px + 0.190vw, 20px);
  --fs-lead:    clamp(18px, 17.26px + 0.190vw, 20px); /* Max 2 per page. */
  --fs-body:    clamp(16px, 15.63px + 0.095vw, 17px);
  --fs-sm:      15px;
  --fs-mono:    13px;

  --lh-display: 1.02;  --tr-display: -0.024em;  --fw-display: 600;
  --lh-h2:      1.08;  --tr-h2:      -0.020em;  --fw-h2:      600;
  --lh-h3:      1.16;  --tr-h3:      -0.014em;  --fw-h3:      600;
  --lh-h4:      1.25;  --tr-h4:      -0.008em;  --fw-h4:      600;
  --lh-lead:    1.5;   --tr-lead:    0;         --fw-lead:    400;
  --lh-body:    1.6;   --tr-body:    0;         --fw-body:    400;
  --lh-sm:      1.5;   --tr-sm:      0;         --fw-sm:      400;
  --lh-mono:    1.4;   --tr-mono:    0.04em;    --fw-mono:    500;

  /* Uppercase is permitted ONLY on mono labels, at this tracking, nowhere else. */
  --tr-mono-upper: 0.06em;

  /* 45 to 75 characters is the readability band. 68ch sits mid-band at --fs-body. */
  --measure: 68ch;

  /* -- 2. Font stacks ----------------------------------------------------- */
  --font-sans: "Inter Tight", "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;

  /* -- 3. Color ----------------------------------------------------------- */
  /* Brand */
  --navy-900: #08182f;
  --navy-800: #0e284f; /* brand primary. 14.63:1 on white */
  --navy-700: #173a69;
  --navy-600: #20497f;
  --navy-100: #e8ecf3;
  --navy-050: #f3f6fa;

  --red-600:  #c41019; /* 6.11:1 on white. The ONLY red permitted for text */
  --red-500:  #e11320; /* surfaces and rules only. 3.01:1 on navy: never text there */
  --red-300:  #ff6b73; /* 5.30:1 on navy. The only red permitted on a navy section */

  /* Neutrals */
  --ink-900:  #12161c;
  --ink-700:  #3a4351;
  --ink-500:  #5a6a80; /* 5.51:1 on white. Nothing lighter is permitted */
  --line-200: #dfe4ec;
  --line-300: #c6cdd8;
  --paper:    #ffffff;
  --paper-alt:#f5f6f8;

  /* Secondary text on a navy section. 6.88:1 */
  --on-navy-secondary: #a8b3c0;
  --on-navy-rule: rgba(255, 255, 255, .16);

  /* -- 3b. Surfaces ------------------------------------------------------
     Added 2026-09-09 after a measurement that changed the plan.

     The component library was built light: sections defaulted to --paper with
     --ink-900 text. Then it was applied to three pages and I sampled the rest of
     the site. Every page type renders dark: the county pages, the city pages,
     the blog, the homepage, about, portfolio, all near-black at rgb(5,10,18) or
     rgb(5,7,12). Those three converted pages were the only light ones on a
     1,527-page site.

     So the system was making the site LESS uniform, not more. Dark is the
     established brand language and the components move to it, not the reverse.
     Naming the surfaces means components stop hard-coding --paper and a future
     theme change is one block, not a sweep.

     Contrast measured against --surface #050a12:
       --on-surface       #e8ecf3  16.6:1
       --on-surface-muted #a8b3c0   8.9:1
       --red-300          #ff6b73   6.5:1  the only red permitted as text here */
  --surface:          #050a12;  /* the page. matches the live body colour */
  --surface-raised:   #0e284f;  /* a card or panel lifted off the page */
  --surface-alt:      #0a1220;  /* alternating band, one step off --surface */
  --on-surface:       #e8ecf3;
  --on-surface-muted: #a8b3c0;
  --surface-rule:     rgba(255, 255, 255, .12);

  /* Form states. TEXT ONLY. No other hues exist. */
  --ok:   #146c43;
  --warn: #8a5a00;

  /* -- 4. Spacing. 8pt closed set ----------------------------------------- */
  /* The only permitted margin, padding and gap values. */
  --s-1: 4px;   --s-2: 8px;   --s-3: 12px;  --s-4: 16px;
  --s-6: 24px;  --s-8: 32px;  --s-10: 40px; --s-12: 48px;
  --s-16: 64px; --s-20: 80px; --s-24: 96px; --s-32: 128px;

  /* -- 5. Grid and layout ------------------------------------------------- */
  --w-content: 1280px;
  --w-prose:   720px;
  --w-page:    1600px;
  --gutter-desk: 32px;
  --gutter-mob:  20px;

  /* -- 5b. Photographic scrim ---------------------------------------------
     rules/01 mandates this exact gradient wherever text sits over photography,
     and check-design-lint.sh bans gradients everywhere except this file. Both
     are right. The scrim is a measured, named design value, so it lives here as
     a token rather than being pasted into a component or the ban being softened.
     Do not adjust these stops by eye. The 4.5:1 contrast claim is measured
     against the .78 floor. */
  --scrim-photo: linear-gradient(to top,
                   rgba(8, 24, 47, .78) 0%,
                   rgba(8, 24, 47, .35) 45%,
                   transparent 75%);

  /* -- 6. Radius, elevation, motion --------------------------------------- */
  /* Glazing is a square-edged, mullion-and-frame product. 999px is banned. */
  --r-0: 0;
  --r-1: 2px;
  --r-2: 4px; /* maximum, on buttons, inputs, cards, tags only */

  /* Borders, not shadows. These two exist only for genuinely floating layers. */
  --e-1: 0 1px 2px rgba(8, 24, 47, .08), 0 0 0 1px rgba(8, 24, 47, .04);
  --e-2: 0 12px 32px -8px rgba(8, 24, 47, .18);

  /* Nothing animates longer than 260ms. */
  --dur-fast: 120ms;
  --dur-base: 180ms;
  --dur-slow: 260ms;
  --ease-out:   cubic-bezier(.2, .8, .25, 1);
  --ease-inout: cubic-bezier(.4, 0, .2, 1);
}

/* Every numeric run is tabular. Applies to spec tables, pricing, IDs,
   license/UEI/CAGE numbers. */
:root {
  font-feature-settings: "tnum" 1, "cv05" 1;
}

/* Display type balances; prose is set for even ragging. */
h1, h2, h3, h4 { text-wrap: balance; }
p, li, blockquote { text-wrap: pretty; max-width: var(--measure); }

/* Required, and verified by committed screenshot rather than asserted. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-fast: 1ms;
    --dur-base: 1ms;
    --dur-slow: 1ms;
  }
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
    transform: none !important;
  }
}
