/* =============================================================================
   BimmerExpert — Design Tokens
   Dark-first. Single source of truth for colour, type, space, motion, layout.
   Every downstream stylesheet reads from here. Do not hard-code a hex anywhere
   else in the project.

   Fonts are SELF-HOSTED from site/assets/fonts/ by the @font-face block at the
   foot of this file. Nothing in this project calls a third party at runtime,
   which is what makes the footer's "no cookies, no third-party analytics" line
   and privacy.html clause 7 true. Do not reintroduce the Google Fonts <link>:
   it transmits the visitor's IP to Google and falsifies both claims.

   -----------------------------------------------------------------------------
   CONTRAST AUDIT — every ratio below was computed against the WCAG 2.x
   relative-luminance formula, not estimated. Surfaces are abbreviated:
     SNK #05070A  GND #0E1116  S1 #141922  S2 #1B222D  S3 #232C39  S4 #2E3948

   TEXT ON SURFACES (worst case across all six surfaces shown as MIN)
     --text-primary   #F2F5F9   SNK 18.44  GND 17.29  S1 16.11  S2 14.62  S3 12.88  S4 10.70   MIN 10.70  AAA
     --text-secondary #B7C2D0   SNK 11.18  GND 10.48  S1  9.77  S2  8.86  S3  7.81  S4  6.49   MIN  6.49  AAA
     --text-muted     #9AA7B8   SNK  8.25  GND  7.74  S1  7.21  S2  6.54  S3  5.76  S4  4.79   MIN  4.79  AA body
     --text-brand     #7AAEFF   SNK  8.96  GND  8.40  S1  7.82  S2  7.10  S3  6.26  S4  5.20   MIN  5.20  AA body
     --text-cyan      #5FE3F5   SNK 13.25  GND 12.42  S1 11.57  S2 10.50  S3  9.25  S4  7.68   MIN  7.68  AAA
     --text-danger    #FF7A8C   SNK  8.08  GND  7.58  S1  7.06  S2  6.41  S3  5.64  S4  4.69   MIN  4.69  AA body

   THE BLUE-TEXT RULE — READ THIS.
     Raw brand blue #2E7DFF as TEXT: GND 4.95, S1 4.61, S2 4.18, S3 3.68, S4 3.06.
     It passes on the page ground and clears large-text 3:1 everywhere, but it
     FAILS 4.5:1 body text on S2, S3 and S4. Therefore #2E7DFF is a FILL and a
     LARGE-DISPLAY colour only. For any blue text at body size — links, inline
     emphasis, small labels — use --text-brand (#7AAEFF), which clears 4.5:1 on
     every surface in the system (MIN 5.20).

   LABELS ON FILLED ACCENTS
     --text-inverse #05080C on --brand        #2E7DFF   5.25   AA
     --text-inverse #05080C on --brand-hover  #4E92FF   6.57   AA
     --text-inverse #05080C on --brand-active #2A73F0   4.60   AA
     --text-inverse #05080C on --cyan         #22D3EE  11.10   AAA
     --text-inverse #05080C on --success      #3DDC97  11.35   AAA
     --text-inverse #05080C on --warning      #F5B544  11.06   AAA
     #FFFFFF        on --red    #E4022A   4.84   AA
     Note: white on #2E7DFF is only 3.82 and is NOT used. Brand buttons carry an
     ink label, not a white one. The active/pressed blue was chosen as #2A73F0
     precisely because a darker press value drops the ink label below 4.5:1.

   RESERVED RED
     --red #E4022A as TEXT: GND 3.91 — fails body, clears 3:1 large/non-text.
     Red is the logo stripe and one hot alert state (filled, white label, 4.84).
     Inline error copy uses --text-danger (#FF7A8C, MIN 4.69). Never a button.

   NON-TEXT / UI BOUNDARIES (WCAG 1.4.11 needs 3:1)
     --border-control       #798598  SNK 5.40 GND 5.06 S1 4.72 S2 4.28 S3 3.77 S4 3.13   MIN 3.13  PASS
     --border-control-hover #8A97A9  SNK 6.80 GND 6.38 S1 5.94 S2 5.39 S3 4.75 S4 3.94   MIN 3.94  PASS
     Hairline / default / strong borders are decorative separators at 1.13-1.79
     against their own surface. They carry no information on their own and are
     never the sole boundary of an interactive control — that is what
     --border-control exists for.

   FOCUS RING
     --focus #22D3EE vs SNK 10.84  GND 10.46  S1 9.75  S2 8.85  S3 7.79  S4 6.47.
     Cyan alone fails against a blue button (2.12 vs #2E7DFF) and against red
     (2.68), so the ring must never be drawn ON the control's own fill. It is an
     `outline` with a 2px `outline-offset`, which puts the cyan on the SURFACE
     BEHIND the control — where the numbers above apply and the worst case is
     6.47:1, twice the 3:1 that WCAG 1.4.11 asks for.
     This was a two-layer box-shadow ring until the assembled page was reviewed.
     A box-shadow ring is defeated by any later same-specificity rule that also
     sets box-shadow, and .btn--primary's --glow-brand did exactly that: every
     primary CTA on the site rendered its resting state when focused. outline is
     contested by nothing, and no future section stylesheet can take it away.

   ADJACENT SURFACE SEPARATION (elevation is visible, not guessed)
     SNK->GND 1.066   GND->S1 1.073   S1->S2 1.102   S2->S3 1.135   S3->S4 1.204

   SCRIM
     --scrim rgb(5 7 10 / .74) over light content composites to #434548;
     --text-primary on that composite is 8.80:1.
   ========================================================================== */

:root {
  color-scheme: dark;

  /* ---------------------------------------------------------------------------
     1. SURFACES — six steps, cool graphite, one hue family (~214deg).
     Elevation goes UP from the page ground. Sunken is for wells and code blocks.
     --------------------------------------------------------------------------- */
  --surface-sunken:   #05070A;  /* inset wells, code/log blocks, input troughs */
  --surface-0:        #0E1116;  /* page ground — the brief's ink                */
  --surface-1:        #141922;  /* section bands, resting cards on the ground   */
  --surface-2:        #1B222D;  /* raised card, table header, hovered surface-1 */
  --surface-3:        #232C39;  /* popover, dropdown, sticky header when solid  */
  --surface-4:        #2E3948;  /* modal, top layer, hovered surface-3          */
  --scrim:            rgb(5 7 10 / 0.74);   /* behind modals and the mobile nav */
  --scrim-soft:       rgb(5 7 10 / 0.55);   /* image legibility wash            */

  /* Header glass: use with backdrop-filter: blur(var(--blur-glass)). */
  --surface-glass:    rgb(14 17 22 / 0.78);
  --blur-glass:       14px;

  /* ---------------------------------------------------------------------------
     2. TEXT
     --------------------------------------------------------------------------- */
  --text-primary:     #F2F5F9;  /* headlines, body on any surface               */
  --text-secondary:   #B7C2D0;  /* supporting paragraphs, card body             */
  --text-muted:       #9AA7B8;  /* captions, meta, footer, disabled-adjacent    */
  --text-inverse:     #05080C;  /* label on any filled accent EXCEPT red        */
  --text-on-red:      #FFFFFF;  /* the only white-on-fill pairing in the system */
  --text-brand:       #7AAEFF;  /* blue TEXT — links, inline emphasis           */
  --text-cyan:        #5FE3F5;  /* technical highlights in running copy         */
  --text-danger:      #FF7A8C;  /* inline form errors                           */

  /* ---------------------------------------------------------------------------
     3. BORDERS
     Alpha borders composite correctly over any surface, which is why the three
     decorative ones are alpha and the two control ones are solid and measured.
     --------------------------------------------------------------------------- */
  --border-hairline:  rgb(255 255 255 / 0.06); /* grid lines, table rules       */
  --border-default:   rgb(255 255 255 / 0.10); /* card and panel edges          */
  --border-strong:    rgb(255 255 255 / 0.18); /* section dividers, emphasis    */
  --border-control:   #798598;                 /* inputs, selects, checkboxes   */
  --border-control-hover: #8A97A9;
  --border-brand:     rgb(46 125 255 / 0.32);  /* tinted panel edge             */
  --border-cyan:      rgb(34 211 238 / 0.28);  /* technical callout edge        */
  --hairline:         1px;

  /* ---------------------------------------------------------------------------
     4. BRAND — electric blue
     --------------------------------------------------------------------------- */
  --brand:            #2E7DFF;
  --brand-hover:      #4E92FF;
  --brand-active:     #2A73F0;
  --brand-subtle:     rgb(46 125 255 / 0.12);  /* tinted badge / panel fill     */
  --brand-subtle-strong: rgb(46 125 255 / 0.18);
  --brand-subtle-solid:  #121E32;  /* opaque equivalent of --brand-subtle on -0 */
  --brand-ring:       rgb(46 125 255 / 0.40);

  /* ---------------------------------------------------------------------------
     5. ACCENT — cyan. Technical highlights, hairline accents, focus, data.
     --------------------------------------------------------------------------- */
  --cyan:             #22D3EE;
  --cyan-subtle:      rgb(34 211 238 / 0.10);
  --cyan-subtle-solid:#10242C;
  --cyan-ring:        rgb(34 211 238 / 0.35);

  /* ---------------------------------------------------------------------------
     6. RESERVED RED — logo stripe and ONE hot/alert state. Never a button,
        never a link, never a decorative accent bar, never a divider.
     --------------------------------------------------------------------------- */
  --red:              #E4022A;
  --red-subtle:       rgb(228 2 42 / 0.12);
  --red-subtle-solid: #280F18;

  /* ---------------------------------------------------------------------------
     7. STATUS — minimal, for the enquiry form.
     --------------------------------------------------------------------------- */
  --success:          #3DDC97;
  --success-subtle:   rgb(61 220 151 / 0.12);
  --success-solid:    #142925;
  --warning:          #F5B544;
  --warning-subtle:   rgb(245 181 68 / 0.12);
  --warning-solid:    #2A251C;
  --danger:           var(--red);            /* the one hot state */
  --danger-subtle:    var(--red-subtle);
  --danger-solid:     var(--red-subtle-solid);

  /* ---------------------------------------------------------------------------
     8. FOCUS — two-layer ring, legible on every surface and every filled accent.
     --------------------------------------------------------------------------- */
  --focus:            #22D3EE;
  /* The ring is an OUTLINE, not a box-shadow. A box-shadow ring is defeated by
     any later (0,1,0) rule that also sets box-shadow — .btn--primary's
     --glow-brand did exactly that, and every primary button on the site had no
     focus indicator at all. outline is contested by nothing, and outline-offset
     shows the surface behind the control so the cyan always reads. */
  --focus-width:      2px;
  --focus-gap:        2px;

  /* ---------------------------------------------------------------------------
     9. TYPOGRAPHY — families and fallbacks that survive with no network.
     --------------------------------------------------------------------------- */
  --ff-display: "Space Grotesk", "Segoe UI Variable Display", "Segoe UI",
                -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue",
                Arial, sans-serif;
  --ff-body:    "Inter", -apple-system, BlinkMacSystemFont,
                "Segoe UI Variable Text", "Segoe UI", Roboto, "Helvetica Neue",
                Arial, "Noto Sans", sans-serif, "Apple Color Emoji",
                "Segoe UI Emoji";
  --ff-mono:    "JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono",
                "Cascadia Mono", "Segoe UI Mono", "Roboto Mono", Menlo, Consolas,
                "Liberation Mono", monospace;

  --fw-regular:  400;
  --fw-medium:   500;
  --fw-semibold: 600;
  --fw-bold:     700;

  /* Fluid sizes: min at 360px viewport, max at 1440px, linear between. */
  --fs-display: clamp(2.5rem,    1.75rem   + 3.333vw, 4.75rem);   /* 40 -> 76   */
  --fs-h1:      clamp(1.875rem,  1.5rem    + 1.667vw, 3rem);      /* 30 -> 48   */
  --fs-h2:      clamp(1.5rem,    1.2917rem + 0.926vw, 2.125rem);  /* 24 -> 34   */
  --fs-h3:      clamp(1.25rem,   1.1667rem + 0.37vw,  1.5rem);    /* 20 -> 24   */
  --fs-lead:    clamp(1.0625rem, 0.9896rem + 0.324vw, 1.2813rem); /* 17 -> 20.5 */
  --fs-body:    clamp(1rem,      0.9792rem + 0.093vw, 1.0625rem); /* 16 -> 17   */
  --fs-small:   clamp(0.875rem,  0.8646rem + 0.046vw, 0.9063rem); /* 14 -> 14.5 */
  --fs-micro:   clamp(0.75rem,   0.7396rem + 0.046vw, 0.7813rem); /* 12 -> 12.5 */
  --fs-eyebrow: clamp(0.7188rem, 0.6979rem + 0.093vw, 0.7813rem); /* 11.5 -> 12.5 */
  --fs-stat:    clamp(2.25rem,   1.75rem   + 2.222vw, 3.75rem);   /* 36 -> 60   */

  --lh-display:  1.05;  /* tight, but clears Space Grotesk's descender box */
  --lh-heading:  1.14;
  --lh-snug:     1.28;
  --lh-lead:     1.5;
  --lh-body:     1.65;
  --lh-tight:    1.2;
  --lh-flat:     1;

  --ls-display: -0.03em;
  --ls-h1:      -0.022em;
  --ls-h2:      -0.015em;
  --ls-h3:      -0.008em;
  --ls-lead:    -0.005em;
  --ls-body:     0em;
  --ls-eyebrow:  0.14em;   /* mono, uppercase */
  --ls-mono:     0.02em;   /* mono, sentence case */

  /* Longest comfortable line lengths. Body prose must not exceed --measure. */
  --measure:       68ch;
  --measure-tight: 46ch;   /* lead paragraphs and headline blocks */

  /* ---------------------------------------------------------------------------
     10. SPACING — 4px base.
     --------------------------------------------------------------------------- */
  --space-0:  0;
  --space-1:  0.25rem;  /*   4 */
  --space-2:  0.5rem;   /*   8 */
  --space-3:  0.75rem;  /*  12 */
  --space-4:  1rem;     /*  16 */
  --space-5:  1.25rem;  /*  20 */
  --space-6:  1.5rem;   /*  24 */
  --space-8:  2rem;     /*  32 */
  --space-10: 2.5rem;   /*  40 */
  --space-12: 3rem;     /*  48 */
  --space-16: 4rem;     /*  64 */
  --space-20: 5rem;     /*  80 */
  --space-24: 6rem;     /*  96 */
  --space-32: 8rem;     /* 128 */

  /* ---------------------------------------------------------------------------
     11. RADII — precision instrument, not a consumer app. Small and consistent.
     --------------------------------------------------------------------------- */
  --radius-0:     0;
  --radius-xs:    2px;   /* tags, hairline chips        */
  --radius-sm:    4px;   /* inputs, small buttons       */
  --radius-md:    6px;   /* buttons, form controls      */
  --radius-lg:    10px;  /* cards, panels               */
  --radius-xl:    14px;  /* feature panels, media frame */
  --radius-2xl:   20px;  /* the hero media frame only   */
  --radius-pill:  999px; /* badges, eyebrow pills       */
  --radius-round: 50%;

  /* ---------------------------------------------------------------------------
     12. SHADOWS — dark UI. Black blur alone disappears on a dark ground, so
     every step pairs depth with a 1px top light-bleed that draws the edge.
     Glows are rationed: brand glow on the primary CTA and nothing else.
     --------------------------------------------------------------------------- */
  --shadow-0: none;
  --shadow-1:
    inset 0 1px 0 0 rgb(255 255 255 / 0.045),
    0 1px 2px 0 rgb(0 0 0 / 0.55);
  --shadow-2:
    inset 0 1px 0 0 rgb(255 255 255 / 0.05),
    0 4px 12px -2px rgb(0 0 0 / 0.60),
    0 2px 4px -2px rgb(0 0 0 / 0.50);
  --shadow-3:
    inset 0 1px 0 0 rgb(255 255 255 / 0.06),
    0 12px 32px -8px rgb(0 0 0 / 0.70),
    0 4px 10px -4px rgb(0 0 0 / 0.50);
  --shadow-4:
    inset 0 1px 0 0 rgb(255 255 255 / 0.07),
    0 28px 64px -16px rgb(0 0 0 / 0.78),
    0 8px 20px -8px rgb(0 0 0 / 0.60);

  --glow-brand:
    0 0 0 1px rgb(46 125 255 / 0.34),
    0 10px 34px -10px rgb(46 125 255 / 0.45);
  --glow-cyan:
    0 0 0 1px rgb(34 211 238 / 0.30),
    0 10px 30px -12px rgb(34 211 238 / 0.38);
  --glow-alert:
    0 0 0 1px rgb(228 2 42 / 0.40),
    0 10px 30px -12px rgb(228 2 42 / 0.45);

  /* ---------------------------------------------------------------------------
     13. MOTION — three durations, two easings. Motion answers an action;
     it does not decorate a scroll.
     --------------------------------------------------------------------------- */
  --dur-fast:  120ms;  /* hover, focus, colour change         */
  --dur-base:  220ms;  /* open/close, expand, tab change      */
  --dur-slow:  420ms;  /* the single orchestrated hero reveal  */
  --ease-out:   cubic-bezier(0.2, 0.8, 0.2, 1);   /* entrances, decisive */
  --ease-inout: cubic-bezier(0.4, 0, 0.2, 1);     /* moves and resizes   */

  /* ---------------------------------------------------------------------------
     14. LAYOUT
     --------------------------------------------------------------------------- */
  --container:        1200px;  /* default content column       */
  --container-wide:   1360px;  /* hero, full-bleed media bands */
  --container-narrow: 780px;   /* prose, FAQ, legal            */
  --gutter:          clamp(1.25rem, 0.8333rem + 1.852vw, 2.5rem); /*  20 -> 40  */
  --section-y:       clamp(4rem,    2.6667rem + 5.926vw, 8rem);   /*  64 -> 128 */
  --section-y-tight: clamp(2.5rem,  1.6667rem + 3.704vw, 5rem);   /*  40 -> 80  */
  --block-gap:       clamp(2rem,    1.5rem    + 2.222vw, 3.5rem); /*  32 -> 56  */
  --header-h:     4.5rem;      /* 72 */
  --grid-columns: 12;
  --grid-gap:     var(--space-6);
  --grid-gap-lg:  var(--space-8);

  /* ---------------------------------------------------------------------------
     15. Z-INDEX
     --------------------------------------------------------------------------- */
  --z-base:   0;
  --z-raised: 10;
  --z-sticky: 100;   /* site header            */
  --z-scrim:  200;   /* unused; reserved for a future dialog scrim */
  --z-modal:  300;   /* reserved for future dialogs.  NOT the mobile nav:
                        .site-menu sits at calc(--z-sticky - 1) on purpose, so
                        the header stays painted over the open panel. */
  --z-toast:  400;   /* form success / failure */
}

/* -----------------------------------------------------------------------------
   The only three rules in this file. Everything above is a token.
   ----------------------------------------------------------------------------- */

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: var(--focus-width) solid var(--focus);
  outline-offset: var(--focus-gap);
  border-radius: var(--radius-sm);
}

::selection {
  background: var(--brand);
  color: var(--text-inverse);
}

/* -----------------------------------------------------------------------------
   Reduced motion. Durations collapse at the token level rather than each
   animation being disabled one at a time, so every component built on these
   tokens inherits the setting for free.
   ----------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-fast: 1ms;
    --dur-base: 1ms;
    --dur-slow: 1ms;
  }
}


/* =============================================================================
   16. WEB FONTS — self-hosted, no third-party request.

   All three families are variable fonts under the SIL Open Font License, so one
   file per family per subset covers every weight the design uses; the
   font-weight range on each face is what tells the browser so. Only the latin
   and latin-ext subsets ship — the site is English-only (<html lang="en">).

   font-display: swap keeps first paint on the fallback stack in §9, which is
   matched per family, so the page is correct before these arrive and correct if
   they never do (a file:// double-click may decline to load them; over http they
   always load).

   These six files replace the Google Fonts <link> that used to sit in <head>.
   That link sent every visitor's IP to Google on every request, which made both
   the footer cookie line and privacy.html clause 7 false.
   ============================================================================= */

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../fonts/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../fonts/inter-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url("../fonts/jetbrains-mono-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url("../fonts/jetbrains-mono-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 600 700;
  font-display: swap;
  src: url("../fonts/space-grotesk-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 600 700;
  font-display: swap;
  src: url("../fonts/space-grotesk-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
