/* wicw-design — tokens.css — v0.2.0
 *
 * Every colour, size, radius, shadow and duration the WiConnect surfaces use.
 * Consumers vendor this file and base.css together, pinned by VERSION, and
 * never edit them in place (see README.md).
 *
 * DARK IS THE DEFAULT, by decision in portal-rebuild-spec.md §15. The bare
 * :root block below is therefore the DARK palette, and :root[data-theme="light"]
 * redefines it. Nothing follows prefers-color-scheme: a customer who has never
 * touched the toggle gets dark. See README.md §"Following the OS instead".
 *
 * Contrast, measured against the surface each colour is used on (WCAG AA needs
 * 4.5 for body text, 3.0 for large text and UI edges):
 *
 *              dark            light
 *   ink        15.7            15.7
 *   muted       7.1             5.4
 *   accent      8.6             5.1
 *   good        6.3             4.8
 *   alert       5.6             5.2
 *
 * Re-measure before changing any of these. The preview page prints them live.
 */

/* ── Fonts, self-hosted ─────────────────────────────────────────────────────
 *
 * SELF-HOSTED, NOT FROM GOOGLE FONTS. The portal's Content-Security-Policy is
 * `style-src 'self'` and `font-src 'self'`, so a <link> to
 * fonts.googleapis.com is blocked outright and the page silently falls back to
 * the system sans — which is how it shipped on 2026-09-13. Loosening the CSP
 * to admit a third-party origin on the page that takes card details is not a
 * trade worth making for two typefaces.
 *
 * VARIABLE fonts, latin subset: one file per family covering every weight the
 * system uses, 66 KB for both, instead of six static files. The paths are
 * relative to this stylesheet, so a consumer that vendors tokens.css must
 * vendor fonts/ beside it.
 *
 * font-display: swap — text is readable in the fallback while these load,
 * which matters most on the connection of a customer whose internet is the
 * thing they are logging in to complain about.
 */

@font-face {
  font-family: "Archivo";
  src: url("fonts/Archivo-var.woff2") format("woff2-variations"),
       url("fonts/Archivo-var.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "JetBrains Mono";
  src: url("fonts/JetBrainsMono-var.woff2") format("woff2-variations"),
       url("fonts/JetBrainsMono-var.woff2") format("woff2");
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
}

:root {
  /* ── Colour: dark (default) ───────────────────────────────────────────── */

  /* Neutrals carry a blue bias rather than being true grey — a fixed-wireless
     network is a cold-weather, cold-metal subject and a flat grey reads as
     nothing at all. */
  --ground:      #0E141C;  /* page */
  --surface:     #171F2A;  /* cards, table rows, inputs */
  --surface-2:   #1E2836;  /* hover, table header, nested panels */
  --line:        #2A3646;  /* borders, dividers */
  --line-strong: #3A4859;  /* input borders, where an edge must be found */

  --ink:         #E7EDF4;  /* body text */
  --muted:       #93A2B4;  /* labels, secondary text, captions */

  /* The accent is a signal amber — the one warm thing on a cold ground, and
     the only colour that means "you can act on this". It is NOT a status:
     nothing amber on these surfaces means "warning". */
  --accent:      #E8A33C;
  --accent-hov:  #F2B155;
  --accent-ink:  #0E141C;  /* text ON an accent fill */
  --accent-soft: rgba(232, 163, 60, 0.13);

  /* Semantic colours are a separate register from the accent, and are only
     ever used to say what state something is in. Pending is deliberately
     colourless — see base.css .chip-pending. */
  --good:        #34A97A;
  --good-soft:   rgba(52, 169, 122, 0.14);
  --good-ink:    #0E141C;
  --alert:       #EC5F58;
  --alert-soft:  rgba(236, 95, 88, 0.14);
  --alert-ink:   #0E141C;

  --shadow-1: 0 1px 2px rgba(0, 0, 0, .40), 0 2px 8px rgba(0, 0, 0, .26);
  --shadow-2: 0 4px 14px rgba(0, 0, 0, .46), 0 12px 34px rgba(0, 0, 0, .34);

  /* The logo is swapped by pointing --logo-src at a different file. Nothing
     else in the system refers to the mark.

     THE FILES ARE NAMED FOR THEIR BACKGROUND, NOT THEIR INK, which is the
     usual way round and the easy one to get backwards: logo-dark.svg is the
     LIGHT-ink mark (#E8EDF5) for a dark ground, and logo-light.svg is the
     DARK-ink one (#141B27) for a light ground. So this block -- the dark
     palette -- takes logo-dark.svg.

     THE PLATE IS GONE. It existed because the only mark available was dark
     ink on transparent, which is invisible on a dark ground, so it was given
     a light rectangle to sit on. Both inks exist now, each theme uses its own,
     and the wordmark sits directly on the page the way it is meant to. */
  --logo-src:   url("logo-dark.svg");
  --logo-ratio: 412 / 96;
  --logo-plate: transparent;
  --logo-pad:   0;

  /* ── Type ─────────────────────────────────────────────────────────────── */

  /* One variable sans for the interface (spec §15) and one mono for data that
     has to be read character by character: Billing Numbers, invoice numbers,
     transaction and subscription ids. Money uses the sans with tabular
     figures, not the mono — see .money in base.css. */
  --font-ui:   "Archivo", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  /* Body never drops below 16px — iOS Safari zooms any input below it. */
  --fs-xs:   0.75rem;   /* 12 — table sublabels only */
  --fs-sm:   0.875rem;  /* 14 — captions, chips, helper text */
  --fs-base: 1rem;      /* 16 — body, inputs, buttons */
  --fs-md:   1.125rem;  /* 18 — card titles */
  --fs-lg:   1.375rem;  /* 22 — section headings */
  --fs-xl:   1.75rem;   /* 28 — page headings */
  --fs-2xl:  2.25rem;   /* 36 — balances, the one big number */

  --lh-tight: 1.2;
  --lh-snug:  1.35;
  --lh-body:  1.6;

  --tracking-label: 0.07em;  /* uppercase labels only */
  --measure: 66ch;           /* running text never exceeds this */

  /* ── Space, radius, motion ────────────────────────────────────────────── */

  --sp-1: 0.25rem;  --sp-2: 0.5rem;   --sp-3: 0.75rem;  --sp-4: 1rem;
  --sp-5: 1.5rem;   --sp-6: 2rem;     --sp-7: 3rem;     --sp-8: 4rem;

  --r-sm:   4px;
  --r-md:   8px;
  --r-lg:   14px;
  --r-pill: 999px;

  /* Every tap target is at least this tall. Non-negotiable on the payment
     page, which is used one-handed on a phone. */
  --tap: 44px;

  --dur-fast: 120ms;
  --dur:      200ms;
  --dur-slow: 320ms;
  --ease:     cubic-bezier(.2, .7, .3, 1);

  --page-max: 1100px;
  --gutter:   clamp(1rem, 4vw, 2rem);
}

:root[data-theme="light"] {
  --ground:      #EEF2F6;
  --surface:     #FFFFFF;
  --surface-2:   #F5F8FB;
  --line:        #D9E1EA;
  --line-strong: #AFBDCC;

  --ink:         #111922;
  --muted:       #556478;

  /* Amber has to go a long way down to clear 4.5:1 on white. It is the same
     hue, not a different accent. */
  --accent:      #9A5504;
  --accent-hov:  #7F4602;
  --accent-ink:  #FFFFFF;
  --accent-soft: rgba(154, 85, 4, 0.09);

  --good:        #16794F;
  --good-soft:   rgba(22, 121, 79, 0.10);
  --good-ink:    #FFFFFF;
  --alert:       #BE2F28;
  --alert-soft:  rgba(190, 47, 40, 0.09);
  --alert-ink:   #FFFFFF;

  --shadow-1: 0 1px 2px rgba(17, 25, 34, .07), 0 2px 8px rgba(17, 25, 34, .06);
  --shadow-2: 0 4px 14px rgba(17, 25, 34, .10), 0 12px 34px rgba(17, 25, 34, .09);

  /* Dark ink, for the light ground. Named for the background -- see the note
     in the dark block above. */
  --logo-src:   url("logo-light.svg");
  --logo-plate: transparent;
}
