/* =============================================================================
   Win-DSL ISP Billing: design tokens  (tokens.css, spec v1.0, 2026-10-17)
   -----------------------------------------------------------------------------
   Drop-in CSS custom properties for the vanilla-JS SPA "ISP Billing Win-DSL".
   Source of truth: mockups/assets/fn.css (redesign proposal) + audit ia-map.md §6.6/§7.

   HOW TO LOAD (phase 1)
     <link rel="stylesheet" href="/tokens.css?v=…">       after style.css
     <link rel="stylesheet" href="/components.css?v=…">   after tokens.css
   tokens.css also re-points the LEGACY variable names used by style.css and by
   the ~383 inline style="" attributes in app.js/net.js/console.js
   (see the "Legacy compatibility" block at the end of this file), so the old UI
   picks up the AA-safe colours right away. Delete both legacy :root blocks in
   style.css (lines 1-7 and 184-191) in the same change.

   NAMING
     --color-*   colour (primitives: --color-blue-600 …; semantic roles: --color-text …)
     --text-*    font size        --leading-*  line height     --weight-*  font weight
     --space-*   4-px spacing     --radius-*   corner radius   --shadow-*  elevation
     --z-*       stacking order   --focus-*    focus ring      --target-*  touch targets
     --control-h-*  control heights   --dur-* / --ease-*  motion
   Rule: components use SEMANTIC tokens only (never primitives, never hex).

   AA-CHECKED PAIRS
     Every text/background pair is listed in "Allowed pairs" below and verified by
     spec/tools/check-contrast.py (WCAG 2.x relative luminance). Use a colour only in
     the pairing listed; e.g. --color-text-subtle is allowed on WHITE only (4.83),
     not on --color-surface-sunken (4.39).

   RTL-SAFE (LOGICAL PROPERTIES) GUIDANCE  — Arabic RTL is the primary layout
     DO   margin-inline-start / -end, padding-inline, padding-block,
          inset-inline-start / -end, border-inline-start, border-start-start-radius,
          text-align: start | end, float: inline-start, justify-content: flex-start
     DON'T left/right/margin-left/padding-right/text-align:left|right/border-left,
          box-shadow: inset -3px 0 … (box-shadow is PHYSICAL; use border-inline-start
          or a ::before at inset-inline-start), translateX(±n) for slide-ins without
          a [dir] override, background-position: left/right.
     Icons: arrows/chevrons/"back"/"next" carry .fn-icon--dir and mirror in RTL
          ([dir=rtl] .fn-icon--dir { scale: -1 1 }). Never mirror logos, clocks,
          checkmarks, media "play", or charts.
     Numbers, IDs, IPs, MACs, logins, phone numbers, money: wrap in .fn-num / <bdi>
          (direction:ltr; unicode-bidi:isolate) so "#T-1042" or "10.20.4.21" never reorder.
     Charts keep time left→right in both directions (mockups/README caveat; confirm with users).
     Breakpoints cannot read custom properties; the literal values are documented
     here and must be used verbatim in @media:  mobile ≤ 760px · rail 761-1180px · desktop ≥ 1181px.
   ========================================================================== */

:root {
  /* ---------- Colour primitives (keep brand #2563eb family) ---------- */
  --color-blue-50: #eff6ff;
  --color-blue-100: #dbeafe;
  --color-blue-200: #bfdbfe;
  --color-blue-500: #3b82f6;
  --color-blue-600: #2563eb;
  --color-blue-700: #1d4ed8;
  --color-blue-800: #1e40af;
  --color-blue-900: #1e3a8a;

  --color-gray-0: #ffffff;
  --color-gray-25: #f5f7fb;
  --color-gray-50: #f1f4f9;
  --color-gray-100: #f3f4f6;
  --color-gray-200: #e5e7eb;
  --color-gray-300: #d1d5db;
  --color-gray-450: #7c8594;
  --color-gray-500: #6b7280;
  --color-gray-600: #4b5563;
  --color-gray-700: #374151;
  --color-gray-900: #111827;

  --color-green-50: #dcfce7;
  --color-green-600: #16a34a;
  --color-green-700: #15803d;
  --color-green-800: #166534;

  --color-amber-50: #fef3c7;
  --color-amber-400: #f59e0b;
  --color-amber-600: #d97706;
  --color-amber-700: #b45309;
  --color-amber-800: #92400e;
  --color-amber-950: #422006;

  --color-red-50: #fee2e2;
  --color-red-300: #fca5a5;
  --color-red-600: #dc2626;
  --color-red-700: #b91c1c;
  --color-red-800: #991b1b;

  --color-cyan-50: #cffafe;
  --color-cyan-600: #0891b2;
  --color-cyan-700: #0e7490;
  --color-cyan-800: #155e75;

  --color-violet-50: #ede9fe;
  --color-violet-600: #7c3aed;
  --color-violet-700: #6d28d9;
  --color-violet-800: #5b21b6;

  /* ---------- Semantic: surfaces & text ---------- */
  --color-bg: var(--color-gray-25);              /* page background */
  --color-surface: var(--color-gray-0);          /* cards, sidebar, inputs, sheets */
  --color-surface-sunken: var(--color-gray-50);  /* table header, command bar, segmented track */
  --color-surface-hover: var(--color-gray-100);
  --color-text: var(--color-gray-900);           /* 17.74 on surface */
  --color-text-secondary: var(--color-gray-700); /* 10.31 labels, nav */
  --color-text-muted: var(--color-gray-600);     /* 7.56 helper text (was #6b7280) */
  --color-text-subtle: var(--color-gray-500);    /* 4.83 placeholder, WHITE ONLY */
  --color-text-on-brand: var(--color-gray-0);
  --color-text-on-solid: var(--color-gray-0);
  --color-text-disabled: var(--color-gray-500);  /* exempt (WCAG 1.4.3), still 4.39 on neutral-bg */

  /* ---------- Semantic: borders ---------- */
  --color-border: var(--color-gray-200);         /* card edges, row dividers (decorative) */
  --color-border-strong: var(--color-gray-300);  /* secondary button edge, separators */
  --color-border-control: var(--color-gray-450); /* inputs, checkboxes, selects: 3.72:1 (WCAG 1.4.11) */

  /* ---------- Semantic: brand ---------- */
  --color-brand: var(--color-blue-600);          /* primary fill; white text 5.17 */
  --color-brand-hover: var(--color-blue-700);    /* white text 6.70 */
  --color-brand-text: var(--color-blue-700);     /* links / tertiary on white 6.70 */
  --color-brand-soft: var(--color-blue-50);      /* active nav, selected row */
  --color-brand-bg: var(--color-blue-100);       /* brand badge, active bottom-bar pill */
  --color-brand-on: var(--color-blue-800);       /* text on brand-bg 7.15 */

  /* ---------- Semantic: status (fg = on white, bg = soft fill, on = text on bg, solid = fill) ---------- */
  --color-ok-fg: var(--color-green-700);
  --color-ok-bg: var(--color-green-50);
  --color-ok-on: var(--color-green-800);
  --color-ok-solid: var(--color-green-700);

  --color-warn-fg: var(--color-amber-700);
  --color-warn-bg: var(--color-amber-50);
  --color-warn-on: var(--color-amber-800);
  --color-warn-solid: var(--color-amber-400);
  --color-warn-solid-on: var(--color-amber-950); /* dark text on amber, NEVER white */
  --color-warn-solid-hover: var(--color-amber-600); /* dark text 4.57 */

  --color-bad-fg: var(--color-red-700);
  --color-bad-bg: var(--color-red-50);
  --color-bad-on: var(--color-red-800);
  --color-bad-solid: var(--color-red-600);
  --color-bad-border: var(--color-red-300);      /* decorative edge of danger-outline / overdue KPI */

  --color-info-fg: var(--color-cyan-700);
  --color-info-bg: var(--color-cyan-50);
  --color-info-on: var(--color-cyan-800);
  --color-info-solid: var(--color-cyan-700);

  --color-violet-fg: var(--color-violet-700);
  --color-violet-bg: var(--color-violet-50);
  --color-violet-on: var(--color-violet-800);

  --color-neutral-bg: var(--color-gray-100);
  --color-neutral-on: var(--color-gray-700);

  --color-toast-bg: var(--color-gray-900);
  --color-scrim: rgba(17, 24, 39, .45);
  --gradient-brand: linear-gradient(150deg, var(--color-blue-600), var(--color-blue-900)); /* logo tile, login screen */

  /* ---------- Focus ---------- */
  --color-focus: var(--color-blue-700);

  /* ---------- Charts (graphics need 3:1; replaces the hard-coded const C in console.js) ---------- */
  --color-chart-1: var(--color-blue-600);
  --color-chart-2: var(--color-green-700);
  --color-chart-3: var(--color-red-600);
  --color-chart-4: var(--color-amber-600);
  --color-chart-5: var(--color-violet-600);
  --color-chart-6: var(--color-cyan-600);
  --color-chart-7: var(--color-gray-500);
  --color-chart-axis: var(--color-gray-500);     /* axis labels 4.83 (audit: #9ca3af = 2.54) */
  --color-chart-grid: var(--color-gray-200);
}

/* ===== Allowed pairs (verified by tools/check-contrast.py, ratio : 1) ==========
   text           / surface #fff      17.74   text          / bg #f5f7fb   16.54
   text-secondary / surface           10.31   text-muted    / surface       7.56
   text-muted     / bg                 7.05   text-muted    / sunken        6.86
   text-subtle    / surface (only)     4.83   brand-text    / surface       6.70
   brand-text     / brand-soft         6.16   brand-on      / brand-bg      7.15
   white / brand #2563eb               5.17   white / brand-hover           6.70
   ok-fg / surface                     5.02   ok-on / ok-bg                 6.49
   white / ok-solid                    5.02   warn-fg / surface             5.02
   warn-on / warn-bg                   6.37   warn-solid-on / warn-solid    6.79
   bad-fg / surface                    6.47   bad-on / bad-bg               6.80
   white / bad-solid                   4.83   info-fg / surface             5.36
   info-on / info-bg                   6.49   violet-fg / surface           7.10
   violet-on / violet-bg               7.57   neutral-on / neutral-bg       9.37
   white / toast-bg                   17.74   chart-axis / surface          4.83
   border-control / surface (3:1)      3.72   focus / surface (3:1)         6.70
   Forbidden (fail AA): white on warn-solid (2.15) · text-subtle on sunken (4.39)
   · border / border-strong as the ONLY boundary of an input (1.24 / 1.47).
   ========================================================================== */

:root {
  /* ---------- Typography: 7-step scale, IBM Plex Sans Arabic ---------- */
  --font-sans-ar: "IBM Plex Sans Arabic", Tahoma, "Segoe UI", sans-serif;
  --font-sans-en: "IBM Plex Sans", "IBM Plex Sans Arabic", "Segoe UI", Tahoma, sans-serif; /* self-host IBM Plex Sans too (audit §1: not loaded today) */
  --font-mono: ui-monospace, "SFMono-Regular", Consolas, monospace;
  --font-sans: var(--font-sans-ar);

  --text-xs: 0.75rem;    /* 12  caption, field hint, counters. Minimum size anywhere */
  --text-sm: 0.875rem;   /* 14  body-sm, table cells, buttons, tabs */
  --text-md: 1rem;       /* 16  body (was 15px) */
  --text-lg: 1.125rem;   /* 18  h3, mobile primary button */
  --text-xl: 1.25rem;    /* 20  h2, mobile page title */
  --text-2xl: 1.5rem;    /* 24  h1 desktop page title */
  --text-3xl: 2rem;      /* 32  display / big KPI ("cash in hand") */
  --text-kpi: 1.75rem;   /* 28  KPI value (mockups); mobile uses --text-2xl */

  --leading-tight: 1.2;  /* display, KPI */
  --leading-heading: 1.35;
  --leading-body: 1.6;
  --leading-compact: 1.45; /* table cells, badges */

  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;
  /* No text-transform:uppercase and no letter-spacing on Arabic (audit #25). */

  /* ---------- Spacing: 4-px scale (replaces 6/9/10/14/18/22/26 ad-hoc values) ---------- */
  --space-0: 0;
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;

  /* ---------- Radius: 4 levels + pill ---------- */
  --radius-sm: 6px;      /* tag, kbd, small badge corners */
  --radius-md: 10px;     /* inputs, buttons, nav items, menu */
  --radius-lg: 14px;     /* cards, list rows, menus */
  --radius-xl: 20px;     /* dialogs, bottom sheets (top corners) */
  --radius-full: 999px;  /* badges, pills, avatar */

  /* ---------- Elevation: 3 levels ---------- */
  --shadow-1: 0 1px 2px rgba(16, 24, 40, .06);                                 /* cards */
  --shadow-2: 0 1px 3px rgba(16, 24, 40, .08), 0 4px 12px rgba(16, 24, 40, .06); /* menus, popovers, sticky bars */
  --shadow-3: 0 12px 32px rgba(16, 24, 40, .16);                               /* dialogs, sheets, toasts */

  /* ---------- Z-index (one scale; old: bottom-nav 40, modal 50, toast 60) ---------- */
  --z-base: 0;
  --z-raised: 1;          /* row-link overlay, sticky table header */
  --z-sticky: 10;         /* sticky page header / action bar */
  --z-sidebar: 20;
  --z-bottombar: 30;
  --z-dropdown: 40;       /* menus, command-bar results, tooltips inside page */
  --z-scrim: 50;
  --z-dialog: 60;         /* dialogs & sheets (native <dialog> uses top layer; keep for fallback) */
  --z-toast: 70;          /* toasts above dialogs so dialog results are announced and visible */
  --z-tooltip: 80;

  /* ---------- Focus ring: 2px gap + 2px #1d4ed8 on every interactive element ---------- */
  --focus-width: 2px;
  --focus-offset: 2px;
  --focus-outline: var(--focus-width) solid var(--color-focus);
  --focus-ring: 0 0 0 2px var(--color-surface), 0 0 0 4px var(--color-focus); /* box-shadow form, for elements whose outline is clipped */

  /* ---------- Touch targets & control sizes ---------- */
  --target-min: 44px;            /* any interactive element, any device */
  --target-touch: 48px;          /* mobile list rows, bottom-bar items, menu items on coarse pointers */
  --target-primary-mobile: 56px; /* the ONE primary action per mobile screen (thumb zone) */
  --control-h-sm: 32px;          /* desktop dense tables only; grows to 44 on (pointer: coarse) */
  --control-h-md: 40px;          /* desktop default; grows to 48 on (pointer: coarse) */
  --control-h-lg: 48px;
  --control-h-xl: 56px;
  --input-h: 44px;

  /* ---------- Layout ---------- */
  --sidebar-w: 264px;
  --sidebar-rail-w: 72px;
  --topbar-h: 68px;
  --bottombar-h: 64px;           /* + env(safe-area-inset-bottom) */
  --content-max: 1440px;
  --page-pad-x: var(--space-6);  /* 16px on mobile (set in components.css) */
  --dialog-w-sm: 420px;
  --dialog-w-md: 560px;
  --dialog-w-lg: 720px;
  --icon-sm: 16px;
  --icon-md: 20px;
  --icon-lg: 24px;
  --icon-stroke: 1.75;

  /* ---------- Motion ---------- */
  --dur-fast: 120ms;
  --dur-base: 200ms;
  --dur-slow: 300ms;
  --ease-out: cubic-bezier(.2, .8, .2, 1);
  --ease-in-out: cubic-bezier(.4, 0, .2, 1);
}

/* English / LTR switches family through the lang attribute (no reload; see SPEC §8). */
:root:lang(en) { --font-sans: var(--font-sans-en); }

@media (prefers-reduced-motion: reduce) {
  :root { --dur-fast: 0ms; --dur-base: 0ms; --dur-slow: 0ms; }
}

/* Windows High Contrast / forced colours: make sure focus and boundaries survive. */
@media (forced-colors: active) {
  :root { --color-focus: Highlight; --color-border-control: CanvasText; }
}

/* =============================================================================
   Legacy compatibility (PHASE 1 ONLY: remove in phase 4 once style.css is retired)
   Re-points the variable names used in style.css and in inline styles in JS.
   Mapping table: old token → value in v15.43 → new token (behaviour change)
   -----------------------------------------------------------------------------
   --bg          #f4f6fa → --color-bg #f5f7fb
   --panel       #fff    → --color-surface
   --ink         #1f2937 → --color-text #111827 (darker)
   --muted       #6b7280 → --color-text-muted #4b5563 (4.47 → 7.05 on bg)
   --line        #e5e7eb → --color-border (dividers) | --color-border-control for inputs
   --brand       #2563eb → --color-brand (unchanged)
   --brand-2     #1d4ed8 → --color-brand-hover (fills) | --color-brand-text (links)
   --brand-soft  #eff6ff → --color-brand-soft
   --accent      #f59e0b → --color-warn-solid + text --color-warn-solid-on (white text forbidden)
   --accent-soft #fffbeb → --color-warn-bg #fef3c7 (text --color-warn-on)
   --ok          #16a34a → --color-ok-fg #15803d (text) | --color-ok-solid (fills)
   --ok-soft     #dcfce7 → --color-ok-bg; pill text must be --color-ok-on
   --bad         #dc2626 → --color-bad-fg #b91c1c (text) | --color-bad-solid #dc2626 (fills)
   --bad-soft    #fee2e2 → --color-bad-bg; pill text --color-bad-on
   --warn        #d97706 → --color-warn-fg #b45309
   --warn-soft   #fef3c7 → --color-warn-bg; pill text --color-warn-on
   --purple      #7c3aed → --color-violet-fg #6d28d9
   --purple-soft #ede9fe → --color-violet-bg
   --teal        #0891b2 → --color-info-fg #0e7490
   --teal-soft   #cffafe → --color-info-bg
   --r           12px    → --radius-lg 14px (cards) | --radius-md 10px (controls)
   --shadow      2-layer → --shadow-1
   (modal) 0 20px 50px   → --shadow-3
   chart #9ca3af gray    → --color-chart-axis / --color-chart-7 #6b7280
   const C {…} hexes     → --color-chart-1 … -7
   #7a4a10 / #92400e     → --color-warn-on (rate chip)
   #e8a33a/#fff4e0/#5c3200 (.trialbar) → --color-warn-solid / --color-warn-bg / --color-warn-on
   #fff1f1 (rtoday rows) → --color-bad-bg      #eef0f3/#ccc/#ddd → --color-border(-strong)
   #f0ede6 / #fbfaf7 / #efede8 / #fcfbf8 (legacy cream) → --color-border / --color-surface-hover / --color-neutral-bg / --color-surface-sunken
   15px / 1.55 base      → --text-md 16px / --leading-body 1.6
   12.5 / 10.5 / 11 px   → --text-xs 12px (minimum)
   13 px                 → --text-sm 14px  ·  19/22 px h1 → --text-2xl (desktop) / --text-xl (mobile)
   z 40 / 50 / 60        → --z-bottombar / --z-dialog / --z-toast
   ========================================================================== */
:root {
  --bg: var(--color-bg);
  --panel: var(--color-surface);
  --ink: var(--color-text);
  --muted: var(--color-text-muted);
  --line: var(--color-border);
  --brand: var(--color-brand);
  --brand-2: var(--color-brand-hover);
  --brand-soft: var(--color-brand-soft);
  --accent: var(--color-warn-solid);
  --accent-soft: var(--color-warn-bg);
  --ok: var(--color-ok-fg);
  --ok-soft: var(--color-ok-bg);
  --bad: var(--color-bad-fg);
  --bad-soft: var(--color-bad-bg);
  --warn: var(--color-warn-fg);
  --warn-soft: var(--color-warn-bg);
  --purple: var(--color-violet-fg);
  --purple-soft: var(--color-violet-bg);
  --teal: var(--color-info-fg);
  --teal-soft: var(--color-info-bg);
  --r: var(--radius-lg);
  --shadow: var(--shadow-1);
}
/* Phase-1 patches for legacy selectors whose pairs still fail with aliases alone: */
.btn.accent { color: var(--color-warn-solid-on); }                    /* 2.15 → 6.79 */
.p-ok { color: var(--color-ok-on); } .p-warn { color: var(--color-warn-on); } .p-bad { color: var(--color-bad-on); }
.p-mut { background: var(--color-neutral-bg); color: var(--color-neutral-on); }
.tst.ok { background: var(--color-ok-solid); } .tst.bad { background: var(--color-bad-solid); }
.chart text { fill: var(--color-chart-axis); }
.small, .kpi .s, .kt .l, .kt .s, .strip .si .l, .mx .l, .bars .bl, .bars .bv, .bottom-nav a, .nav-h, .tag, .kbd { font-size: var(--text-xs); }
.nav-h, .strip .si .l, .mx .l, .tag { text-transform: none; letter-spacing: 0; }
input, select, textarea { border-color: var(--color-border-control); }
