/* ==========================================================================
   EV Clinic — design tokens.

   White, glass, and the cell mosaic. The dark master-franchise page and this
   are one brand seen from two sides: same three accents, same typography,
   opposite ground.

   The page is built in six layers, and the order is the whole design:

     1  white            #FFFFFF, the ground
     2  cell mosaic      a very pale grid on the same 19px pitch the video
                         backdrop samples at — the brand's own motif, used as
                         structure rather than decoration
     3  colour washes    cold / mint / amber radials at 6-10% alpha
     4  WebGL glass      the hero object, refracting layers 1-3
     5  frosted panels   where the content sits
     6  ink              text and hairlines

   Layers 2 and 3 are not ornament. Frosted glass is only glass if there is
   something behind it to blur; over flat white a backdrop-filter panel is an
   expensive way to draw a grey rectangle. The mosaic and the washes are what
   the glass is made of.

   Two rules govern the colour:

     Accents come in two strengths. The mint and amber that read beautifully
     as a fill fail contrast as text, so each has an -ink variant taken to at
     least 4.5:1. Fills and graphics use the pure colour, type uses -ink.

     These figures are computed, not estimated: run tools/check_contrast.py,
     which measures every token against --paper AND checks that this comment
     still agrees with the file. The first version of this block was wrong on
     all four numbers.

     On white: --mute 5.70:1, --mint-ink 5.69:1, --amber-ink 6.61:1,
     --cold 6.77:1.

     Nothing downstream hard-codes a hex value. Everything reads from here,
     which is what makes the relationship to the dark sibling a matter of
     swapping one file rather than auditing every rule.
   ========================================================================== */

:root{
  /* ------------------------------------------------------------- surfaces */
  --paper:#FFFFFF;

  /* The opaque surface, for everything glass cannot be.
     An SVG `fill` takes a colour and not a backdrop-filter, so the map's
     marker discs and popup grounds are painted rather than frosted. Same for
     a form field, where a translucent input over a moving mosaic is a
     legibility problem rather than an effect. */
  --panel:#FFFFFF;

  --raise:#F5F7FA;        /* bands that separate by ground, not by border */
  --sink:#EDF1F6;         /* pressed states, table stripes, inert wells */
  --line:#E2E8EF;
  --line-soft:#EDF1F6;
  --line-strong:#CBD5E0;

  /* ----------------------------------------------------------------- type */
  --ink:#0E1620;
  --mute:#59687A;         /* 5.70:1 on white */
  --faint:#8895A6;        /* decorative only — never body text */

  /* -------------------------------------------------------------- accents */
  --cold:#2B4BD8;
  --cold-ink:#2B4BD8;
  --mint:#3BE0A0;
  --mint-ink:#0E7553;
  --amber:#FFB020;
  --amber-ink:#875000;

  /* Written as rgb triples so a rule can choose its own alpha without a
     second variable for every opacity. */
  --cold-rgb:43,75,216;
  --mint-rgb:59,224,160;
  --amber-rgb:255,176,32;
  --ink-rgb:14,22,32;
  --white-rgb:255,255,255;

  /* ---------------------------------------------------------------- glass
     One recipe, four variables, so a panel, a header and a popup cannot
     drift apart. See .glass in base.css for how they combine. */
  --glass-top:rgba(255,255,255,.74);
  --glass-bottom:rgba(255,255,255,.52);
  --glass-edge:rgba(255,255,255,.78);      /* the 1px border */
  --glass-sheen:rgba(255,255,255,.92);     /* inset highlight on the top edge */
  --glass-shadow:0 10px 34px rgba(14,22,32,.07);
  --glass-blur:18px;
  --glass-saturate:1.5;

  /* --------------------------------------------------------------- mosaic
     The cell grid. 19px is not arbitrary: it is CELL in evc-backdrop.js, so
     the static mosaic and the video mosaic land on the same lattice and read
     as one surface rather than two overlapping grids. */
  --cell:19px;
  --cell-ink:rgba(14,22,32,.038);
  --cell-dot:rgba(14,22,32,.055);

  /* ------------------------------------------- pipeline and network status
     Weakest to strongest. Shared with the map so a legend chip and a country
     fill cannot disagree. */
  --st-soon:#7C8B9C;
  --st-signed:#2B4BD8;
  --st-boarding:#9A5B00;   /* 5.43:1 — #B26A00 measured 4.24 and failed */
  --st-open:#0E7553;

  /* Franchise classes. */
  --ty-hq:#875000;
  --ty-mothership:#0E7553;
  --ty-legacy:#4A6C88;

  /* ------------------------------------------------------------- the map
     Inverted from the dark sibling: there, land is a lighter shape on a
     near-black sea. Here the sea is the page and land is a shade darker, so
     the continents read as objects lying on the paper rather than as holes
     cut out of it. */
  --map-sea:transparent;
  --map-land:#E7ECF3;
  --map-land-hi:#D7DFE9;
  --map-stroke:#B6C3D1;

  /* ---------------------------------------------------------- typography */
  --display:'Archivo',system-ui,-apple-system,'Segoe UI',sans-serif;
  --body:'IBM Plex Sans',system-ui,-apple-system,'Segoe UI',sans-serif;
  --mono:'IBM Plex Mono',ui-monospace,SFMono-Regular,Menlo,monospace;

  /* ------------------------------------------------------------ geometry */
  --gut:clamp(20px,5vw,64px);
  --evc-gut:var(--gut);                /* the name theme.json refers to */
  --content:760px;
  --wide:1280px;
  --radius:3px;                        /* glass wants a hair more than a box */

  --ease-out:cubic-bezier(.2,.7,.2,1);
  --ease-in-out:cubic-bezier(.4,0,.2,1);

  /* The header's floor. A CONSTANT, and it has to stay one.
     --header-min is what .header-inner's min-height reads. --header-h is a
     measurement of the rendered header, written by JavaScript. They must
     never be the same variable: feeding a measurement back into the rule
     that produces it is a loop with no fixed point. See --header-h below. */
  --header-min:66px;

  /* Set at runtime. Declared here with defaults so a rule that reads one
     before its script has run gets a usable number rather than an invalid
     value that kills the whole declaration.

     --header-h is the MEASURED height of .site-header, published by
     evc-chrome.js. Read it only from things the header's own size cannot
     depend on — scroll-padding-top, and the top edge of the mobile drawer,
     which is position:fixed and therefore out of flow.

     It was once read by .header-inner's min-height, and that shipped. The
     header carries a 1px bottom border, so the measured box was always one
     pixel taller than the inner box it was being fed back into: every
     notification added a pixel, forever, and the whole page walked down the
     screen at roughly sixty pixels a second. tools/probe_header.py exists to
     catch exactly this and is the regression test for it. */
  --header-h:66px;
  --scroll-v:0;
  --bd-cell:19px;
  --bd-opacity:.26;
}

/* ========================================================================
   When glass must stop being glass.

   backdrop-filter is the most expensive thing on this page. Every element
   carrying one becomes its own compositing layer, and on a mid-range phone a
   handful of them turns a smooth scroll into a slideshow. It is also a real
   accessibility problem: translucency over moving content is exactly what
   prefers-reduced-transparency exists to switch off.

   Three escapes, all of which land on the same opaque fallback, so the
   design degrades to flat panels rather than to nothing.
   ======================================================================== */

/* 1. The visitor asked for it. */
@media (prefers-reduced-transparency: reduce){
  :root{
    --glass-top:#FFFFFF;
    --glass-bottom:#FFFFFF;
    --glass-edge:var(--line);
    --glass-sheen:transparent;
    --glass-blur:0px;
    --glass-saturate:1;
  }
}

/* 2. The screen is small, which correlates with the slow GPU. */
@media (max-width: 900px){
  :root{
    --glass-top:rgba(255,255,255,.97);
    --glass-bottom:rgba(255,255,255,.97);
    --glass-blur:0px;
    --glass-saturate:1;
  }
}

/* 3. The browser cannot do it at all. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))){
  :root{
    --glass-top:#FFFFFF;
    --glass-bottom:#FFFFFF;
    --glass-sheen:transparent;
  }
}

/* --------------------------------------------------------------- contrast
   Windows high-contrast and forced-colors: hand the palette back to the OS
   rather than fighting it. A design built from space and hairlines survives
   this better than most, because the structure is in the spacing and the
   type rather than in the colour. */
@media (forced-colors: active){
  :root{
    --paper:Canvas;
    --raise:Canvas;
    --sink:Canvas;
    --ink:CanvasText;
    --mute:CanvasText;
    --faint:CanvasText;
    --line:CanvasText;
    --line-soft:CanvasText;
    --line-strong:CanvasText;
    --glass-top:Canvas;
    --glass-bottom:Canvas;
    --glass-edge:CanvasText;
    --glass-sheen:transparent;
    --glass-shadow:none;
    --glass-blur:0px;
    --cell-ink:transparent;
    --cell-dot:transparent;
  }
}
