/* =====================================================================
   VOIP.SO — typefaces, self-hosted.

   Nothing here reaches the network. The files in /public/fonts/ are the
   Google Fonts latin and latin-ext subsets of the two variable faces,
   downloaded once and committed; the site makes zero requests to
   fonts.googleapis.com or fonts.gstatic.com at runtime. Both are SIL
   Open Font Licence 1.1 — see public/fonts/LICENSE.txt.

   `font-display: swap` keeps text readable during the swap period, which
   matters more here than avoiding a flash: the fonts are same-origin and
   preloaded, so the period is short.

   Two subsets per family rather than one merged file. latin is ~90 KB and
   covers every page; latin-ext is only fetched when a page actually
   contains a character in its range — the accented country names on
   /coverage, mostly.
   ===================================================================== */

@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 800;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url('/fonts/archivo-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: 'Archivo';
  font-style: normal;
  font-weight: 400 800;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url('/fonts/archivo-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: 'Martian Mono';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('/fonts/martian-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: 'Martian Mono';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('/fonts/martian-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;
}

/* =====================================================================
   VOIP.SO — design tokens
   The authoritative values live in DESIGN.md. Every contrast ratio noted
   here was computed, not estimated.
   ===================================================================== */

:root {
  /* ---- Brand ------------------------------------------------------- */
  --brand-700: oklch(0.4700 0.2300 262.00);   /* #0047CC  pressed         */
  --brand-600: oklch(0.5366 0.2575 262.47);   /* #0057FF  primary         */
  --brand-500: oklch(0.6231 0.1880 259.81);   /* #3B82F6  hover on dark   */
  --brand-400: oklch(0.7137 0.1434 254.62);   /* #60A5FA  text on dark    */
  --brand-300: oklch(0.8000 0.1100 250.00);
  --signal:    oklch(0.7623 0.1519 229.99);   /* #00C2FF  live only       */

  /* Flat fallbacks for the few places a gradient stop or shadow needs
     a colour that older engines can interpolate reliably. */
  --brand-600-rgb: 0 87 255;
  --signal-rgb: 0 194 255;

  /* ---- Neutrals (tinted toward the brand hue, ~257–266) ------------ */
  --ink-950: oklch(0.1288 0.0406 264.70);
  --ink-900: oklch(0.2077 0.0398 265.75);
  --ink-800: oklch(0.2795 0.0368 260.03);
  --ink-700: oklch(0.3717 0.0392 257.29);
  --ink-600: oklch(0.4455 0.0374 257.28);
  --ink-500: oklch(0.5450 0.0407 257.42);   /* 4.54:1 on --bg-sunken */
  --ink-400: oklch(0.6300 0.0380 257.00);
  --ink-300: oklch(0.7107 0.0351 256.79);
  --ink-200: oklch(0.8690 0.0198 252.89);
  --ink-100: oklch(0.9288 0.0126 255.51);
  --ink-050: oklch(0.9650 0.0070 250.00);
  --paper:   oklch(0.9842 0.0034 247.86);
  --surface: oklch(1 0 0);

  /* ---- Semantic ---------------------------------------------------- */
  --success-fill: oklch(0.6271 0.1699 149.21);
  --success-text: oklch(0.5170 0.1371 150.07);   /* 5.23:1 white · 4.64:1 on wash */
  --success-dark: oklch(0.8003 0.1821 151.71);   /* 10.25:1 on ink-900 */
  --success-wash: oklch(0.9550 0.0400 150.00);

  --warning-fill: oklch(0.7686 0.1647 70.08);
  --warning-text: oklch(0.5490 0.1455 49.00);    /* 5.16:1 white · 4.61:1 on wash */
  --warning-dark: oklch(0.8369 0.1644 84.43);
  --warning-wash: oklch(0.9650 0.0450 80.00);

  --danger-fill:  oklch(0.5771 0.2152 27.33);
  --danger-text:  oklch(0.5054 0.1905 27.52);    /* 6.47:1 on white  */
  --danger-dark:  oklch(0.7106 0.1661 22.22);
  --danger-wash:  oklch(0.9600 0.0300 25.00);

  --info-fill:    oklch(0.6542 0.1099 194.03);
  --info-text:    oklch(0.5000 0.1193 242.75);   /* 5.93:1 on white  */
  --info-dark:    oklch(0.7535 0.1390 232.66);
  --info-wash:    oklch(0.9600 0.0250 235.00);

  /* ---- Surface roles: light (portal / admin) ----------------------- */
  --bg:            var(--paper);
  --bg-raised:     var(--surface);
  --bg-sunken:     var(--ink-050);
  --bg-nav:        var(--ink-900);
  --text:          var(--ink-900);
  --text-body:     var(--ink-600);
  --text-muted:    var(--ink-500);
  --text-inverse:  var(--paper);
  --border:        var(--ink-100);
  --border-strong: var(--ink-200);
  --accent:        var(--brand-600);
  --accent-text:   var(--brand-600);

  /* ---- Typography -------------------------------------------------- */
  --font-sans: 'Archivo', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-mono: 'Martian Mono', ui-monospace, 'SF Mono', 'Cascadia Mono', Menlo, monospace;

  /* Brand register — fluid, display capped at 4.5rem so long telecom
     nouns ("Infrastructure") cannot overflow a narrow grid. */
  --fs-display: clamp(2.5rem, 1.6rem + 4.4vw, 4.5rem);
  --fs-h1:      clamp(2rem, 1.4rem + 2.8vw, 3.25rem);
  --fs-h2:      clamp(1.5rem, 1.2rem + 1.5vw, 2.25rem);
  --fs-h3:      clamp(1.25rem, 1.1rem + 0.7vw, 1.5rem);
  --fs-lead:    clamp(1.0625rem, 1rem + 0.4vw, 1.25rem);
  --fs-body:    1.0625rem;
  --fs-sm:      0.9375rem;
  --fs-xs:      0.8125rem;

  /* Product register — fixed, ratio ~1.15. A heading that shrinks
     inside a sidebar looks broken, so no clamp here. */
  --ui-h1:   1.5rem;
  --ui-h2:   1.25rem;
  --ui-h3:   1.0625rem;
  --ui-body: 0.9375rem;
  --ui-sm:   0.875rem;
  --ui-xs:   0.8125rem;

  --lh-tight: 1.15;
  --lh-snug:  1.35;
  --lh-body:  1.6;
  --lh-dark:  1.7;   /* light type on dark reads lighter; give it room */

  --ls-display: -0.03em;   /* floor; never tighter */
  --ls-heading: -0.02em;
  --ls-body:     0;
  --ls-caps:     0.06em;

  --measure: 68ch;

  /* ---- Space ------------------------------------------------------- */
  --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;
  --sp-9: 6rem;     --sp-10: 8rem;

  --section-y:       clamp(3.5rem, 2rem + 6vw, 7rem);
  --section-y-tight: clamp(2.5rem, 1.5rem + 4vw, 4.5rem);

  /* ---- Structure --------------------------------------------------- */
  --w-page: 1200px;
  --w-wide: 1440px;
  --w-narrow: 780px;

  --r-sm: 4px;  --r-md: 6px;  --r-lg: 10px;  --r-full: 999px;

  --border-w: 1px;

  /* ---- Elevation ---------------------------------------------------
     Shadows are tinted with the brand hue rather than pure black, so
     they sit in the same colour world as the surfaces they lift off. */
  --shadow-sm: 0 1px 2px rgb(15 23 42 / 0.06);
  --shadow-md: 0 2px 4px rgb(15 23 42 / 0.06), 0 4px 12px rgb(15 23 42 / 0.05);
  --shadow-lg: 0 4px 8px rgb(15 23 42 / 0.06), 0 12px 32px rgb(15 23 42 / 0.10);
  --shadow-focus: 0 0 0 3px rgb(var(--brand-600-rgb) / 0.22);

  /* ---- Z-index: semantic only, no 999 ------------------------------ */
  --z-base: 0;
  --z-dropdown: 100;
  --z-sticky: 200;
  --z-backdrop: 300;
  --z-modal: 400;
  --z-toast: 500;
  --z-tooltip: 600;

  /* ---- Motion ------------------------------------------------------ */
  --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
  --ease-out-expo:  cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out:    cubic-bezier(0.65, 0, 0.35, 1);

  --dur-instant: 80ms;
  --dur-fast:    150ms;
  --dur-base:    220ms;
  --dur-slow:    360ms;
  --dur-hero:    1400ms;
}

/* ---- Dark surface role set -----------------------------------------
   Scoped to the sections that are actually dark, never to <html>. The
   public site interleaves dark and light bands in one document, so a
   global dark class would push light-on-light text into the light bands
   and make them unreadable.

   The component selectors are listed here rather than left to authors
   remembering a utility class: a dark band that forgets `.on-dark` is a
   contrast failure waiting to ship. */
.on-dark,
.site-header,
.hero,
.band--dark,
.band--panel,
.site-footer,
.portal-rail {
  --bg:            var(--ink-950);
  --bg-raised:     var(--ink-900);
  --bg-sunken:     var(--ink-950);
  --text:          var(--paper);
  --text-body:     var(--ink-200);
  --text-muted:    var(--ink-300);
  --text-inverse:  var(--ink-950);
  --border:        color-mix(in oklch, var(--ink-700) 70%, transparent);
  --border-strong: var(--ink-700);
  /* brand-600 is only 3.24:1 on ink-900 — text on dark must use 400. */
  --accent-text:   var(--brand-400);
  --success-text:  var(--success-dark);
  --warning-text:  var(--warning-dark);
  --danger-text:   var(--danger-dark);
  --info-text:     var(--info-dark);
  --shadow-sm: 0 1px 2px rgb(2 6 23 / 0.4);
  --shadow-md: 0 2px 4px rgb(2 6 23 / 0.4), 0 4px 12px rgb(2 6 23 / 0.35);
  --shadow-lg: 0 4px 8px rgb(2 6 23 / 0.45), 0 12px 32px rgb(2 6 23 / 0.5);
}

/* Fallback for engines without oklch(). Values are the sRGB equivalents
   of the tokens above, so the palette degrades to the same colours
   rather than to browser defaults. */
@supports not (color: oklch(0.5 0.1 260)) {
  :root {
    --brand-700: #0047cc; --brand-600: #0057ff; --brand-500: #3b82f6;
    --brand-400: #60a5fa; --brand-300: #93c5fd; --signal: #00c2ff;
    --ink-950: #020617; --ink-900: #0f172a; --ink-800: #1e293b;
    --ink-700: #334155; --ink-600: #475569; --ink-500: #617188;
    --ink-400: #7c8ba1; --ink-300: #94a3b8; --ink-200: #cbd5e1;
    --ink-100: #e2e8f0; --ink-050: #f1f5f9; --paper: #f8fafc; --surface: #ffffff;
    --success-fill: #16a34a; --success-text: #0f7d3a; --success-dark: #4ade80; --success-wash: #f0fdf4;
    --warning-fill: #f59e0b; --warning-text: #b25104; --warning-dark: #fbbf24; --warning-wash: #fffbeb;
    --danger-fill: #dc2626;  --danger-text: #b91c1c;  --danger-dark: #f87171;  --danger-wash: #fef2f2;
    --info-fill: #0ea5a4;    --info-text: #0369a1;    --info-dark: #38bdf8;    --info-wash: #f0f9ff;
  }
}
