/*
 * shared/styles/variables.css — THE design-token system (doc 10 §12; GLB-5; PC-52).
 *
 * Every visual constant in the app is a CSS custom property defined here — components NEVER
 * hardcode colors/sizes/shadows; they reference var(--…). Served two ways:
 *   1. GET /__assets/base.css (framework route, lib/create-sub-server.js) — concatenated with
 *      base.css so tokens + reset paint before hydration on every page, incl. static auth pages.
 *   2. Imported by shared/entry-client.js → extracted into the hashed prod CSS bundle (Q-3
 *      styled first paint).
 *
 * THEMES: light is the :root default; dark overrides ride BOTH the OS signal
 * (prefers-color-scheme) and the explicit [data-theme="dark"] attribute — and
 * [data-theme="light"] wins back over the OS signal, so a user toggle always beats the OS.
 *
 * RTL: no directional tokens exist (no --margin-left-*). Components use CSS logical properties
 * (margin-inline-start, inset-inline-end, …) against dir="rtl" on <html> — doc 14.
 */

:root {
  /* ── neutral scale (light) ────────────────────────────────────────────────── */
  --color-neutral-0: #ffffff;
  --color-neutral-50: #f7f8fa;
  --color-neutral-100: #eef0f3;
  --color-neutral-200: #e2e5ea;
  --color-neutral-300: #ccd2d9;
  --color-neutral-400: #9aa2ad;
  --color-neutral-500: #6b7480;
  --color-neutral-600: #5b636e;
  --color-neutral-700: #3d434b;
  --color-neutral-800: #272c31;
  --color-neutral-900: #1c2024;

  /* ── semantic surfaces + text ─────────────────────────────────────────────── */
  --color-bg: var(--color-neutral-0);            /* page background */
  --color-surface: var(--color-neutral-50);      /* cards, sidebar, panels */
  --color-surface-raised: var(--color-neutral-0);/* popovers, modals, menus */
  --color-surface-sunken: var(--color-neutral-100);
  --color-border: var(--color-neutral-200);
  --color-border-strong: var(--color-neutral-300);
  --color-text: var(--color-neutral-900);
  --color-text-muted: var(--color-neutral-600);
  --color-text-faint: var(--color-neutral-400);
  --color-text-inverse: var(--color-neutral-0);

  /* ── brand + state colors (AA on their contrast pair) ─────────────────────── */
  --color-primary: #2563eb;
  --color-primary-hover: #1d4ed8;
  --color-primary-active: #1e40af;
  --color-primary-soft: #dbeafe;                 /* soft chip/hover wash */
  --color-primary-contrast: #ffffff;

  --color-danger: #dc2626;
  --color-danger-hover: #b91c1c;
  --color-danger-soft: #fee2e2;
  --color-danger-contrast: #ffffff;

  --color-success: #16a34a;
  --color-success-soft: #dcfce7;
  --color-success-contrast: #ffffff;

  --color-warning: #d97706;
  --color-warning-soft: #fef3c7;
  --color-warning-contrast: #ffffff;

  --color-info: #0891b2;
  --color-info-soft: #cffafe;
  --color-info-contrast: #ffffff;

  /* focus ring + selection */
  --color-focus-ring: #2563eb;
  --color-selection-bg: #dbeafe;

  /* impersonation banner (distinct amber — doc 10 §4.2) */
  --color-impersonation-bg: #fef3c7;
  --color-impersonation-text: #92400e;

  /* ── typography ───────────────────────────────────────────────────────────── */
  --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  --font-size-base: 16px;      /* html root; everything else in rem */
  --font-size-xs: 0.75rem;
  --font-size-sm: 0.875rem;
  --font-size-md: 1rem;
  --font-size-lg: 1.125rem;
  --font-size-xl: 1.25rem;
  --font-size-2xl: 1.5rem;
  --font-size-3xl: 1.875rem;
  --font-size-display: 2.25rem;  /* the dialer readout ONLY (DESIGN-PLAN law 2) */
  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;
  --line-height-base: 1.5;
  --line-height-tight: 1.25;
  --line-height-loose: 1.75;

  /* ── spacing ramp (4px base) ──────────────────────────────────────────────── */
  --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 + elevation ───────────────────────────────────────────────────── */
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 12px;
  --radius-full: 9999px;
  --shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.06);
  --shadow-md: 0 4px 8px -2px rgba(16, 24, 40, 0.1), 0 2px 4px -2px rgba(16, 24, 40, 0.06);
  --shadow-lg: 0 12px 16px -4px rgba(16, 24, 40, 0.12), 0 4px 6px -2px rgba(16, 24, 40, 0.05);
  --shadow-overlay: 0 20px 24px -4px rgba(16, 24, 40, 0.16), 0 8px 8px -4px rgba(16, 24, 40, 0.06);

  /* ── z-index layers (one ladder — components never invent values) ─────────── */
  --z-base: 0;
  --z-sticky: 100;       /* sticky table headers, save bars */
  --z-nav: 200;          /* top nav + sidebar */
  --z-dropdown: 300;     /* dropdown/select menus (teleported) */
  --z-overlay: 400;      /* modal backdrop */
  --z-modal: 410;        /* modal dialog */
  --z-toast: 500;        /* toasts above everything */

  /* ── motion ───────────────────────────────────────────────────────────────── */
  --transition-fast: 120ms ease;
  --transition-base: 200ms ease;
  --transition-slow: 320ms ease;

  /* ── layout chrome sizes (doc 10 §4.2/§12) ────────────────────────────────── */
  --nav-height: 56px;
  --status-height: 28px;
  --sidebar-width: 240px;
  --sidebar-width-rail: 56px;  /* tablet icon rail; the MOBILE off-canvas re-asserts
                                  min(var(--sidebar-width), 80vw) — never this (PC-53) */
  --content-max-width: 1440px;

  /* form controls */
  --control-height: 36px;
  --control-height-sm: 28px;

  /* ── touch targets + control sizes (UX-SPEC-1 §1; DESIGN-PLAN law 1/3) ────────── */
  --tap-min: 44px;                 /* minimum interactive target below 48rem */
  --tap-min-lg: 56px;              /* dial keys, primary phone actions */
  --control-height-lg: 44px;       /* comfortable admin row / mobile field height */

  /* ── icon sizes (shared/components/Icon.vue — never a raw px in an SFC) ───────── */
  --icon-size-sm: 16px;
  --icon-size-md: 20px;
  --icon-size-lg: 24px;

  /* ── focus ring geometry (the colour is --color-focus-ring above) ────────────── */
  --focus-ring-width: 2px;
  --focus-ring-offset: 2px;

  /* ── table density (re-declared under [data-density="compact"] below) ────────── */
  --density-row-y: var(--space-3);
  --density-cell-x: var(--space-3);

  /* ── elevation alias: the call bar / any docked bar rides the overlay shadow ─── */
  --elevation-bar: var(--shadow-overlay);

  /* ── neutral wash for hover on a transparent control (Tabs, .btn-secondary) ────
        UX-SPEC-6 #26: 8%/10% moved the surface by 1.10:1 (light) / 1.25:1 (dark) — hover was
        effectively invisible, and hover is the affordance a non-technical user leans on hardest
        ("did that row react to me?"). 14%/16% reads on a phone without becoming a selected
        state (a real selection still paints --color-primary-soft). Dark twin in BOTH blocks. */
  --color-surface-hover: rgba(107, 116, 128, 0.14);   /* neutral-500 @ 14% — dark twin below */

  /* ── the scrim behind a modal / the mobile nav drawer ──────────────────────────
        UX-SPEC-6 #17: was a raw rgb(0 0 0 / 0.4) literal in DashboardLayout with no dark
        answer. Retuned by measurement, not by taste — a drawer's edge against what it covers
        is a UI boundary and owes 3:1 (WCAG 1.4.11). At 0.40 the light drawer (--color-surface)
        read 2.68:1 against the scrimmed page; at 0.50 it is 3.41:1. Dark needs a HEAVIER one
        for a different reason: its page ground is already near-black, so the scrim's whole job
        there is pushing the page's TEXT back — 0.40 dimmed it by dL* 34, 0.66 by dL* 59. */
  --color-scrim: rgba(12, 14, 16, 0.50);

  /* ── AA floors (DESIGN-PLAN law 1: 4.5:1 for text, 3:1 for a UI edge, in BOTH themes).
        Measured 2026-09-07 against every ground the kit paints on (bg / surface /
        surface-sunken / the matching -soft):
          --color-border-strong on white is 1.43:1 — fine as a decorative rule, far under the
            3:1 an INTERACTIVE edge owes, so a form field gets --color-control-border instead;
          --color-success on a card is 3.10:1 and --color-danger on --color-danger-soft is
            3.95:1 — both under 4.5:1 as TEXT, so state text uses the -text pair below.
        The base --color-<state> tokens keep their values (they are fills and edges, and the
        whole app leans on them); these are the text-safe partners, worst case 5.1:1. ──────── */
  --color-control-border: var(--color-neutral-500);   /* alias: dark is inherited, see the note above */
  --color-danger-text: #b91c1c;
  --color-success-text: #166534;
  --color-warning-text: #92400e;
  --color-info-text: #155e75;

  /* ── the SOLID-FILL partners for the state scale (UX-SPEC-6 #1/#2/#15/#16) ─────
        --color-danger (#dc2626) carries white at 4.83:1, so a solid red control was always
        legal. The other three never were: white on --color-success is 3.30:1, on --color-info
        3.68:1, on --color-warning 3.19:1 — all under the 4.5:1 a BUTTON LABEL owes. That is
        how the green Call and Answer buttons — the two controls this product exists for —
        shipped as a pale wash on a phone in daylight.
        The base tokens keep their values (dots, edges, washes and the whole app lean on them);
        these are the darker partners a SOLID control fills with. Measured 2026-09-07 against
        --color-*-contrast (#ffffff in light): 5.02 / 5.36 / 5.02. Both dark blocks alias these
        straight back to the base token — dark already clears the floor at 10.5:1 and must keep
        its bright fills, since a dark theme's solid control is light-on-dark. ─────────────── */
  --color-success-strong: #15803d;
  --color-info-strong: #0e7490;
  --color-warning-strong: #b45309;

  /* ── call semantics (DESIGN-PLAN law 1): ALIASES onto the state scale, so the
        dark theme is inherited automatically — the aliased token is re-declared in
        both dark blocks, and a var() on :root resolves against :root's dark value.
        Never duplicate these in the dark blocks.
        UX-SPEC-6 #1/#2/#15/#16: the three that paint a SOLID control (Call, Answer, .ph-badge)
        or read as TEXT (.transfer-line) ride the -strong partners above, so one token pair
        fixes every one of them in both themes. --color-call-end stays on --color-danger,
        which already clears 4.5:1. ──────────────────────────────────────────────── */
  --color-call-answer: var(--color-success-strong);
  --color-call-answer-contrast: var(--color-success-contrast);
  --color-call-end: var(--color-danger);
  --color-call-end-contrast: var(--color-danger-contrast);
  --color-call-ringing: var(--color-warning-strong);
  --color-call-ringing-soft: var(--color-warning-soft);
  --color-call-live: var(--color-info-strong);
  --color-call-live-soft: var(--color-info-soft);

  color-scheme: light;
}

/* ── dark theme ──────────────────────────────────────────────────────────────── */

/* OS signal (default when no explicit user choice is stamped) */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --color-neutral-0: #101315;
    --color-neutral-50: #14171a;
    --color-neutral-100: #1c2024;
    --color-neutral-200: #2b3138;
    --color-neutral-300: #3a414a;
    --color-neutral-400: #6b7480;
    --color-neutral-500: #8b94a0;
    --color-neutral-600: #9aa2ad;
    --color-neutral-700: #c3c9d1;
    --color-neutral-800: #dde1e6;
    --color-neutral-900: #e8eaed;

    --color-bg: #101315;
    --color-surface: #171b1e;
    --color-surface-raised: #1e2328;
    --color-surface-sunken: #0c0e10;

    --color-primary: #60a5fa;
    --color-primary-hover: #93c5fd;
    --color-primary-active: #3b82f6;
    --color-primary-soft: #1e3a5f;
    --color-primary-contrast: #0b1220;

    --color-danger: #f87171;
    --color-danger-hover: #fca5a5;
    --color-danger-soft: #45201f;
    --color-danger-contrast: #1a0b0b;

    --color-success: #4ade80;
    --color-success-soft: #14351f;
    --color-success-contrast: #06180c;

    --color-warning: #fbbf24;
    --color-warning-soft: #3d2e0a;
    --color-warning-contrast: #1c1503;

    --color-info: #22d3ee;
    --color-info-soft: #0a323a;
    --color-info-contrast: #051418;

    --color-focus-ring: #60a5fa;
    --color-selection-bg: #1e3a5f;

    /* neutral wash — a light-neutral at 16% reads on a dark ground (UX-SPEC-6 #26: 10% moved
       the surface by 1.25:1, which is not a visible hover on a phone) */
    --color-surface-hover: rgba(200, 208, 218, 0.16);

    /* the scrim: a dark UI needs a HEAVIER one than light — 0.45 black over #101315 barely
       separates the drawer from the page it covers (UX-SPEC-6 #17) */
    --color-scrim: rgba(0, 0, 0, 0.66);

    /* AA text partners for the state scale on a dark ground (>= 5.1:1 everywhere the kit paints) */
    --color-danger-text: #f87171;
    --color-success-text: #4ade80;
    --color-warning-text: #fbbf24;
    --color-info-text: #22d3ee;

    /* Solid-fill partners: dark keeps its BRIGHT fills — a dark theme's solid control is
       dark-text-on-light-fill, and #06180c on #4ade80 is already 10.54:1. Darkening here would
       BREAK it. So the -strong tokens alias straight back to the base (UX-SPEC-6 #1/#2/#15/#16). */
    --color-success-strong: var(--color-success);
    --color-info-strong: var(--color-info);
    --color-warning-strong: var(--color-warning);

    --color-impersonation-bg: #3d2e0a;
    --color-impersonation-text: #fcd34d;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 4px 8px -2px rgba(0, 0, 0, 0.5), 0 2px 4px -2px rgba(0, 0, 0, 0.4);
    --shadow-lg: 0 12px 16px -4px rgba(0, 0, 0, 0.55), 0 4px 6px -2px rgba(0, 0, 0, 0.4);
    --shadow-overlay: 0 20px 24px -4px rgba(0, 0, 0, 0.6), 0 8px 8px -4px rgba(0, 0, 0, 0.45);

    color-scheme: dark;
  }
}

/* explicit user choice — always beats the OS signal */
:root[data-theme="dark"] {
  --color-neutral-0: #101315;
  --color-neutral-50: #14171a;
  --color-neutral-100: #1c2024;
  --color-neutral-200: #2b3138;
  --color-neutral-300: #3a414a;
  --color-neutral-400: #6b7480;
  --color-neutral-500: #8b94a0;
  --color-neutral-600: #9aa2ad;
  --color-neutral-700: #c3c9d1;
  --color-neutral-800: #dde1e6;
  --color-neutral-900: #e8eaed;

  --color-bg: #101315;
  --color-surface: #171b1e;
  --color-surface-raised: #1e2328;
  --color-surface-sunken: #0c0e10;

  --color-primary: #60a5fa;
  --color-primary-hover: #93c5fd;
  --color-primary-active: #3b82f6;
  --color-primary-soft: #1e3a5f;
  --color-primary-contrast: #0b1220;

  --color-danger: #f87171;
  --color-danger-hover: #fca5a5;
  --color-danger-soft: #45201f;
  --color-danger-contrast: #1a0b0b;

  --color-success: #4ade80;
  --color-success-soft: #14351f;
  --color-success-contrast: #06180c;

  --color-warning: #fbbf24;
  --color-warning-soft: #3d2e0a;
  --color-warning-contrast: #1c1503;

  --color-info: #22d3ee;
  --color-info-soft: #0a323a;
  --color-info-contrast: #051418;

  --color-focus-ring: #60a5fa;
  --color-selection-bg: #1e3a5f;

  /* neutral wash — a light-neutral at 16% reads on a dark ground (UX-SPEC-6 #26: 10% moved
     the surface by 1.25:1, which is not a visible hover on a phone) */
  --color-surface-hover: rgba(200, 208, 218, 0.16);

  /* the scrim: a dark UI needs a HEAVIER one than light — 0.45 black over #101315 barely
     separates the drawer from the page it covers (UX-SPEC-6 #17) */
  --color-scrim: rgba(0, 0, 0, 0.66);

  /* AA text partners for the state scale on a dark ground (>= 5.1:1 everywhere the kit paints) */
  --color-danger-text: #f87171;
  --color-success-text: #4ade80;
  --color-warning-text: #fbbf24;
  --color-info-text: #22d3ee;

  /* Solid-fill partners: dark keeps its BRIGHT fills — a dark theme's solid control is
     dark-text-on-light-fill, and #06180c on #4ade80 is already 10.54:1. Darkening here would
     BREAK it. So the -strong tokens alias straight back to the base (UX-SPEC-6 #1/#2/#15/#16). */
  --color-success-strong: var(--color-success);
  --color-info-strong: var(--color-info);
  --color-warning-strong: var(--color-warning);

  --color-impersonation-bg: #3d2e0a;
  --color-impersonation-text: #fcd34d;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 4px 8px -2px rgba(0, 0, 0, 0.5), 0 2px 4px -2px rgba(0, 0, 0, 0.4);
  --shadow-lg: 0 12px 16px -4px rgba(0, 0, 0, 0.55), 0 4px 6px -2px rgba(0, 0, 0, 0.4);
  --shadow-overlay: 0 20px 24px -4px rgba(0, 0, 0, 0.6), 0 8px 8px -4px rgba(0, 0, 0, 0.45);

  color-scheme: dark;
}

/* ── density mode (UX-SPEC-1 §1; DESIGN-PLAN law 5) ───────────────────────────────
   Comfortable is the DEFAULT (the tokens above). A surface opts a subtree into the
   dense variant with data-density="compact" on any ancestor — tables read these two
   tokens, never a literal padding. */
:root[data-density="compact"],
[data-density="compact"] {
  --density-row-y: var(--space-1);
  --density-cell-x: var(--space-2);
}
