/* ═══════════════════════════════════════════════════════════════════════════
   01-tokens.css — the shared palette. BYTE-IDENTICAL in both portals.

   Design tokens follow the CognizantAINexus billing deck so the family reads as
   one. Nothing portal-specific belongs here: the teal-vs-blue identity lives in
   02-accent.css, which is the only stylesheet the two portals are allowed to
   disagree on.

   Verify parity by comparing this file, and 03-base.css, between the two
   portals with cmp — they must match byte for byte.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Tells the browser which way its OWN chrome should render: select dropdown
     lists, date pickers, number spinners, scrollbars and the like. Without it
     those stay light while the page goes dark, which is the giveaway that a
     dark theme was painted on rather than declared.

     Keyed to [data-theme] and NOT to a prefers-color-scheme media query on
     purpose: app.js always writes data-theme itself (from localStorage, else
     the OS preference), and the stylesheets never consult the OS directly. A
     media query here would contradict the page for anyone on a dark OS who
     toggles to light. */
  color-scheme: light;
  --dark-blue:#1A3C6E; --mid-blue:#2E6DB4; --light-blue:#D6E4F7;
  --teal:#0D7E83; --teal-light:#E0F4F5;
  /* --orange and --green are contrast-corrected, not the brand-deck hues:
     --orange was #E86D0A (~2.9:1 on --orange-light) and --green was #1B8754
     (~3.6:1), against the 4.5:1 needed for the 11px bold text these are used
     for — too small to qualify for the large-text exemption. Affects every
     badge, callout, banner and result in both portals. Hues are unchanged, only
     lightness, so orange still reads as orange. Both are also used as solid
     fills and borders (.btn-ok hover, the connection dot, meter-fill's full
     state, banner/module left borders, the activation code's valid-state
     border), where darkening is neutral or an improvement — white-on-colour
     only gets better. Dark mode needs the opposite correction — see below. */
  --orange:#A85000;  /* ~5.0:1 on --orange-light */
  --orange-light:#FFF3E0;
  --green:#167346;   /* ~5.2:1 on --green-light */
  --green-light:#E6F4ED;
  --red:#C0392B; --red-light:#FDECEA;
  --purple:#6C3483; --purple-light:#F3EFFE;
  /* --dark-blue, --mid-blue, --teal, --red and --purple deliberately have NO
     dark-theme override, and adding them is not the five-line change it looks
     like. Each is used in two incompatible roles: as INK (.lic-chip and
     .badge-fulfilled set color:var(--dark-blue); .badge-locked sets
     color:var(--red)) and as a FILL (.footer sets
     background:var(--dark-blue); .btn-danger:hover sets
     background:var(--red)). Lightening them for dark mode is right for the
     ink and wrong for the fill — it would turn the footer into a light band
     and put white text on pale red. Closing this properly means splitting the
     roles into separate ink/surface tokens, which is its own change with its
     own review, not a token-block edit. Until then the handful of
     [data-theme="dark"] patches below each cover one ink site. */
  --bg-page:#F4F6F9; --bg-surface:#FFF; --bg-surface2:#F4F6F9;
  --border:#E8ECF2; --text:#1A1A2E; --text-muted:#3D4F66; --text-faint:#5E7088;
  --heading:#1A3C6E;
  /* Text that sits ON a solid token fill. It is the PAGE colour, not white, so
     it inverts with the theme automatically: near-white on a dark fill in
     light mode, near-black on a light fill in dark mode. Every
     `background:<token>; color:#fff` pair needed this, because a token that
     lightens for dark mode turns white text into 2:1 mush. */
  --on-fill:var(--bg-page);
  /* The footer is a navy BAND, not blue ink, and it must stay dark in both
     themes so its white text keeps working. It used --dark-blue, which is
     also the ink for .lic-chip and .badge-fulfilled — the exact role clash
     that blocked dark-theme overrides. Separating the surface from the ink is
     what unblocks them. */
  --footer-bg:#1A3C6E;
  --shadow-sm:0 1px 4px rgba(0,0,0,.08); --shadow-md:0 4px 16px rgba(0,0,0,.12);
  /* Corner radii. --radius-sm is 8px, up from 6px: the single most visible
     value in this scale, since it is on every button, input, token box,
     result and toast. --radius-pill replaced three separate pill idioms
     (999px, 20px, and .modal-input's 10px); the 20px sites were already
     rendering as full pills because a browser clamps border-radius to half
     the box, and every one of them is a short box (a 10px meter, a ~21px
     badge, an 8px scrollbar thumb). */
  --radius-xs:4px; --radius-sm:8px; --radius-md:12px; --radius-lg:16px;
  --radius-pill:999px;

  /* Motion. Five ad-hoc durations (.15/.18/.2/.25/.35s) collapse onto three
     steps; .18s already matched --dur exactly. --ease is plain `ease` for now,
     which is what every one of these already resolved to — it exists so the
     curve becomes one edit later rather than nine. The spinner's .8s loop and
     its reduced-motion 1.6s are not on this scale: they are a continuous
     animation, not a state transition. */
  --dur-fast:120ms; --dur:180ms; --dur-slow:280ms; --ease:ease;

  /* Elevation, split into geometry and tint. The offsets and blurs are
     identical in both portals, so they belong here; only the colour differs,
     and it lives in 02-accent.css as a --shadow-*-tint. Note this is four
     levels, not the three the plan assumed, and client-portal tinted its bar,
     card and button shadows with three DIFFERENT blues — so a single
     --shadow-tint could not have expressed it without changing pixels. The
     button level was retired in 6b when button hover stopped casting a
     shadow, leaving three. */
  --elev-bar:0 8px 26px; --elev-card:0 8px 28px;
  --elev-card-hover:0 12px 30px;

  /* Type stacks. Two mono stacks used to be in circulation — one with
     'Cascadia Mono' and one without — applied to sites with no principled
     reason to differ (.token-box vs code, .code-value vs .pem). They are now
     one token. This also retires a latent bug: .lic-id asked for var(--mono),
     which was never defined anywhere and silently fell back. */
  --font-sans:'Segoe UI',system-ui,sans-serif;
  --font-mono:ui-monospace,'Cascadia Mono',Consolas,monospace;

  /* Type scale. Every half-pixel size is gone, rounded UP onto a step, because
     10.5/11.5/12.5/13.5px rasterise inconsistently across device pixel ratios
     and were the clearest fingerprint of ad-hoc styling. 39 declarations moved
     by +0.5px; nothing shrank except .sso-gate-title (19px -> 18px).

     Two deliberate departures from the planned scale, both evidence-led: there
     is no --text-lg:16px or --text-3xl:28px, because no rule in either portal
     used 16px or 28px. --text-lg is 15px, the size actually in use (body,
     .code-input, .empty h3, .meter-label strong). Inventing a 16px step would
     have moved body's size — which every unstyled element inherits — to
     satisfy a number nothing asked for. */
  --text-2xs:10px; --text-xs:11px;  --text-sm:12px; --text-base:13px;
  --text-md:14px;  --text-lg:15px;  --text-xl:18px; --text-2xl:22px;
  --text-hero:clamp(1.15rem,2vw,1.55rem);

  /* Spacing. Ten steps, not the 26 distinct values that were in circulation.
     Numbered rather than named in px, so the scale can be retuned without
     every consumer reading as a lie. */
  --space-1:2px;  --space-2:4px;  --space-3:8px;  --space-4:12px;
  --space-5:16px; --space-6:20px; --space-7:24px; --space-8:32px;
  --space-9:40px; --space-10:48px;

  /* Stacking order, a 1:1 map of the values already in use. --z-dropdown and
     --z-toast are deliberately the same number, because they already were:
     an open identity menu and a toast currently tie, so which one wins is
     decided by DOM order rather than by intent. Naming them separately makes
     that resolvable later without moving anything now. */
  --z-sticky:50; --z-dropdown:200; --z-toast:200; --z-modal:300;
}
[data-theme="dark"] {
  color-scheme: dark;
  --bg-page:#0D1117; --bg-surface:#161B22; --bg-surface2:#1C2330;
  --border:#3A4558; --text:#E6EDF6; --text-muted:#B9C6D9; --text-faint:#96A8C2;
  --heading:#7EB3F0; --light-blue:#1E3A5F; --teal-light:#0A2E31;
  /* The light surfaces become near-black here, so --orange/--green are
     LIGHTENED rather than darkened. Easy to miss: correcting only the light
     theme would have made dark mode worse. */
  --orange:#FFB067;  /* ~9.4:1 on the dark --orange-light */
  --orange-light:#2A1A00;
  --green:#5FD39B;   /* ~8.8:1 on the dark --green-light */
  --green-light:#0A2417;
  --red-light:#2A0F0C; --purple-light:#1E1035;
  /* The five that had no dark value until now. They were blocked because each
     served as both INK and FILL, and lightening is right for ink and wrong for
     fill. That is resolved: fills take color:var(--on-fill), which inverts, and
     the footer took its own --footer-bg. So these can finally lighten.

     Each value is the one the retired [data-theme="dark"] patches had already
     arrived at by hand — #FF9B93 came from .conn.is-bad, #C4A0F5 from
     .badge-suspended and .banner-suspended, #DCECFF from .lic-chip and
     .badge-fulfilled. Six patches become five declarations. */
  --dark-blue:#DCECFF; --mid-blue:#7EB3F0; --teal:#5FCFD9;
  --red:#FF9B93; --purple:#C4A0F5;
  --shadow-sm:0 1px 4px rgba(0,0,0,.4); --shadow-md:0 4px 16px rgba(0,0,0,.5);
}

/* ── Reduced motion, at the token layer ──────────────────────────────────────
   Zeroing the duration tokens is what the motion scale is for: it disables
   every tokenised transition and animation at once, instead of naming
   selectors one at a time and missing some. 03-base.css keeps its own
   prefers-reduced-motion block for the things that are NOT durations — the
   hover lift and the pressed scale are transforms, and the page loader's
   spinner is a continuous animation that is slowed rather than stopped.

   This does extend reduced-motion coverage to rules the enumerated block
   missed: body and .tabs background, .tab colour, .subtab, .drop, and
   client-portal's .meter-fill width and .lic-chevron rotation. Those animate
   today even when a user has asked for reduced motion. */
@media (prefers-reduced-motion: reduce) {
  :root { --dur-fast:0ms; --dur:0ms; --dur-slow:0ms; }
}
