/* ============================================================
   PBE Tools — Design Tokens v2 ("operating console")
   Loaded BEFORE style.css: defines the palette the whole
   platform inherits (all 68 tool pages reference these tokens).
   style.css must NOT redefine any name declared here.
   Aesthetic: graphite base, PBE blue as the only signal accent.
   Gold (--accent-gold) is reserved for premium/QR identity and
   primary actions; PBE blue = links, accents, active states.
   ============================================================ */

/* Self-hosted Inter variable (latin subset) — replaces the Google Fonts request.
   The 100-900 range covers every weight the UI uses, including 800. */
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url('/assets/fonts/inter-var-latin.woff2') format('woff2-variations');
    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;
}

:root {
    /* ── PBE accent ramp (brand blue #3D5A80 from the PBE site) ──
       Raw #3D5A80 manages only ~2.7:1 on the graphite bg, so it is a
       FILL/BORDER color; accent text/icons on dark use --pb-blue-text. */
    --pb-blue: #3D5A80;
    --pb-blue-strong: #4A6E9E;              /* hover/active fills */
    /* Accent text & icons on dark. #5E88B8 was 5.27:1 on the page ground but only
       4.21:1 inside a tinted callout (the green tip card, #0E291C once
       composited) — and a link in a tip box is exactly where this token gets
       used. #6B93C0 clears 4.85:1 on that worst surface and 5.7-6.1:1 elsewhere. */
    --pb-blue-text: #6B93C0;
    --pb-blue-soft: rgba(61, 90, 128, 0.14);
    --pb-focus-ring: 0 0 0 3px rgba(94, 136, 184, 0.55);

    --pb-bg: #0B0D10;
    --pb-surface: #11151A;
    --pb-surface-2: #171C22;
    --pb-border: rgba(255, 255, 255, 0.07);
    --pb-success: #22C55E;
    --pb-warn: #F59E0B;
    --pb-danger: #EF4444;

    /* ── Raw palette remap (legacy names keep working everywhere) ── */
    --bg-dark: #0B0D10;
    --surface-dark: #11151A;
    --surface-dark-elevated: #171C22;

    /* PBE blue is the system accent; gold reserved for premium/QR + primary actions */
    --accent-gold: #D4AF37;
    --primary-cta: var(--pb-blue);
    --primary-cta-hover: var(--pb-blue-strong);
    --secondary-cta: var(--pb-blue-text);
    --secondary-cta-hover: var(--pb-blue);
    --border-glow: rgba(61, 90, 128, 0.28);
    --border-glass: rgba(255, 255, 255, 0.07);

    --accent-gold-glow: rgba(212, 175, 55, 0.12);

    /* ── Gold interaction layer (from the live v1 site, style.css?v=4.3.0) ──
       Division of labour, deliberately: BLUE stays the informational accent
       (links, active nav, focus rings — the a11y-critical ones), GOLD is the
       interaction-energy layer (primary fills, hover lifts, glows, premium).
       --gold* are FILL colours and keep their raw values in BOTH themes; gold
       as TEXT must use --accent-gold, which light theme darkens to #85661B
       because #D4AF37 on white is about 2:1. */
    --gold: #D4AF37;
    --gold-light: #F3C63F;              /* gradient top / hover sweep */
    --gold-deep: #B5952F;               /* pressed */
    --gold-ink: #060913;                /* text ON a gold fill */
    --gold-grad: linear-gradient(135deg, var(--gold) 0%, var(--gold-light) 100%);
    --gold-grad-hover: linear-gradient(135deg, var(--gold-light) 0%, var(--gold) 100%);

    --glow-gold-sm: 0 4px 14px rgba(212, 175, 55, 0.20);
    --glow-gold-md: 0 6px 20px rgba(212, 175, 55, 0.35);
    --glow-gold-lg: 0 0 30px rgba(212, 175, 55, 0.10);
    --glow-gold-halo: 0 0 20px rgba(212, 175, 55, 0.15);
    --glow-gold-tab: 0 4px 12px rgba(212, 175, 55, 0.25);
    --gold-border: rgba(212, 175, 55, 0.25);
    --gold-border-hover: rgba(212, 175, 55, 0.30);

    /* Motion: one lift value per surface class, so hover feels uniform */
    --lift-hover: translateY(-1px);
    --lift-card: translateY(-4px);
    --card-hover-shadow: var(--shadow-2), var(--glow-gold-halo);

    --accent-cyan: #22D3EE;
    --accent-cyan-glow: rgba(34, 211, 238, 0.12);
    --accent-purple: #8B5CF6;
    --accent-purple-glow: rgba(139, 92, 246, 0.12);
    --accent-success: #22C55E;
    --accent-danger: #EF4444;
    --accent-green: #22C55E;
    --accent-green-bg: rgba(34, 197, 94, 0.15);
    --accent-red: #EF4444;
    --accent-red-bg: rgba(239, 68, 68, 0.15);
    /* AI accent used as TEXT, most often on its own --accent-ai-bg tint. #8B5CF6
       measured 3.99:1 against that tint (#1E1933 once composited) — the tint is
       the worst case, lighter than any page or card surface. #9B72F8 clears
       4.96:1 there and 5.3-5.7:1 everywhere else, and keeps the same hue. */
    --accent-ai: #9B72F8;
    --accent-ai-bg: rgba(139, 92, 246, 0.15);

    /* ── Semantic aliases ───────────────────────────────── */
    --bg-color: var(--bg-dark);
    --card-bg: var(--surface-dark);
    --surface-elevated: var(--surface-dark-elevated);
    --nav-bg: rgba(9, 11, 15, 0.88);
    --border-color: var(--border-glass);

    --text-primary: #E8EAED;
    --text-secondary: #9AA3AF;
    /* Was #6B7280, which measured 3.74:1 against the lightest dark surface
       (#101623 tool cards) — below the 4.5:1 AA floor for body text, and the
       single cause of 82 failing nodes. #848C96 clears 5.32:1 on that surface
       and 6.19:1 on the page ground, while staying clearly dimmer than
       --text-secondary so the three-step hierarchy still reads. */
    --text-muted: #848C96;

    /* ── Elevation scale (3 steps, theme-aware) ─────────── */
    --shadow-1: 0 1px 2px 0 rgba(0, 0, 0, 0.4);
    --shadow-2: 0 4px 16px rgba(0, 0, 0, 0.35);
    --shadow-3: 0 12px 32px rgba(0, 0, 0, 0.5);
    --shadow-sm: var(--shadow-1);
    --shadow-md: var(--shadow-2);

    /* ── Shape scale ────────────────────────────────────── */
    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-lg: 12px;
    --radius-xl: 16px;
    --radius-pill: 9999px;
    --radius-card: var(--radius-lg);
    --radius-input: var(--radius-md);

    /* ── Layout widths ──────────────────────────────────── */
    --width-page: 1200px;
    --width-content: 860px;
    --width-reading: 720px;

    /* ── Chrome ─────────────────────────────────────────── */
    --nav-height: 64px;
    --z-nav: 1000;
    --z-modal: 3000;
    --z-palette: 4000;
    --z-toast: 5000;

    /* ── Type ───────────────────────────────────────────── */
    --font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
}

/* Dark theme (default) — explicit so the toggle wins in both directions.
   Theme classes live on <html> (set pre-paint by the early script). */
html.theme-dark {
    color-scheme: dark;
    --bg-color: var(--bg-dark);
    --card-bg: var(--surface-dark);
    --surface-elevated: var(--surface-dark-elevated);
    --text-primary: #E8EAED;
    --text-secondary: #9AA3AF;
    --border-color: rgba(255, 255, 255, 0.07);
    --nav-bg: rgba(9, 11, 15, 0.88);
    --shadow-1: 0 1px 2px 0 rgba(0, 0, 0, 0.4);
    --shadow-2: 0 4px 16px rgba(0, 0, 0, 0.35);
    --shadow-3: 0 12px 32px rgba(0, 0, 0, 0.5);
}

/* Light theme — clean graphite-on-paper counterpart.
   Light surfaces are light enough that raw #3D5A80 passes as accent text (6.6:1).
   Dark-tuned accent colors get darker "ink" variants here: #D4AF37 gold as text
   on white is ~2:1, and the bright cyan/green/amber fail badly — same hues,
   deeper values, so chips/badges/statuses stay on-brand AND readable. */
html.theme-light {
    color-scheme: light;
    --secondary-cta: var(--pb-blue);
    --secondary-cta-hover: var(--pb-blue-strong);
    --pb-blue-text: var(--pb-blue);
    --bg-color: #F5F6F8;
    --card-bg: #FFFFFF;
    --surface-elevated: #FFFFFF;
    --nav-bg: rgba(255, 255, 255, 0.92);
    --border-color: #E4E8EC;
    --text-primary: #0D1117;
    --text-secondary: #57606A;
    /* Was #6E7781: 4.55:1 on a white card but only 4.20:1 on the page ground
       (#F5F6F8), so the same token passed or failed depending on surface —
       18 failing nodes. #646C74 clears 4.93:1 on the ground and 5.33:1 on cards. */
    --text-muted: #646C74;
    --shadow-1: 0 1px 2px 0 rgba(0, 0, 0, 0.06);
    --shadow-2: 0 4px 12px rgba(0, 0, 0, 0.08);
    --shadow-3: 0 12px 28px rgba(0, 0, 0, 0.12);
    /* Gold used as TEXT on the light ground. #8C6D1F measured 4.493:1 against
       #F5F6F8 — a miss by 0.007, which axe reports as a real failure. #85661B
       clears 4.96:1 on the page ground and 5.37:1 on a white card, and is
       visually indistinguishable at body-text size. */
    --accent-gold: #85661B;
    --accent-gold-glow: rgba(140, 109, 31, 0.12);
    /* Gold FILLS stay raw (#D4AF37/#F3C63F read correctly as fills on white);
       only the shadows change, because dark-tuned alphas vanish on a light page. */
    --glow-gold-sm: 0 4px 12px rgba(212, 175, 55, 0.28);
    --glow-gold-md: 0 6px 18px rgba(212, 175, 55, 0.42);
    --glow-gold-lg: 0 0 24px rgba(212, 175, 55, 0.18);
    --glow-gold-halo: 0 0 18px rgba(212, 175, 55, 0.22);
    --glow-gold-tab: 0 4px 12px rgba(212, 175, 55, 0.30);
    --card-hover-shadow: var(--shadow-2), var(--glow-gold-halo);
    --accent-cyan: #0E7490;
    --accent-cyan-glow: rgba(14, 116, 144, 0.10);
    --accent-purple: #7C3AED;
    --accent-purple-glow: rgba(124, 58, 237, 0.10);
    --accent-ai: #7C3AED;
    --accent-ai-bg: #EDE9FE;
    /* Semantic colours get used as TEXT on their own pale tint (status pills like
       "Live" / "Critical"), and that tint is the worst case — lighter than any
       card or page surface. Measured on the old values:
         #15803D on #D1FAE5 = 4.42:1   (the "Live" badges on /about)
         #DC2626 on #FEE2E2 = 3.95:1, and 4.47:1 even on the page ground
       Both missed the 4.5:1 floor. These clear 5.31:1 and 5.10:1 on their tints
       and stay the same hues. */
    --accent-success: #147236;
    --accent-green: #147236;
    --accent-green-bg: #D1FAE5;
    --accent-danger: #BE1C1C;
    --accent-red: #BE1C1C;
    --accent-red-bg: #FEE2E2;
    --pb-warn: #B45309;
    --pb-success: #147236;
    --pb-danger: #BE1C1C;
}

/* ── Global refinements ─────────────────────────────────── */
body {
    font-family: var(--font-family);
    letter-spacing: -0.011em;
    /* Native-app feel: kill rubber-banding and tap flashes on mobile */
    overscroll-behavior-y: none;
    -webkit-tap-highlight-color: transparent;
    -webkit-text-size-adjust: 100%;
}

/* Controls get fast taps; scrolling stays untouched */
button, a, [role="button"], input[type="submit"], label[for] {
    touch-action: manipulation;
}

/* Chrome is not selectable content — inputs, results and prose stay selectable */
nav, .btn-primary, .btn-secondary, .category-tab, .qr-pill, .badge,
.mobile-nav, .mega-menu, footer nav {
    user-select: none;
    -webkit-user-select: none;
}

/* Tabular numerals wherever results are displayed */
#output-section,
.result-value,
[data-numeric],
.stat-value,
output {
    font-variant-numeric: tabular-nums;
    font-feature-settings: 'tnum' 1;
}

/* ── Reduced motion ─────────────────────────────────────────
   The platform had NO prefers-reduced-motion handling: ~30 transitions and the
   skeleton / spin / badge-pulse / palette-in keyframes all ran unconditionally.
   Users who ask the OS for less motion have vestibular reasons for it.
   Transitions collapse to near-zero rather than 0s so transitionend still fires
   for any code that waits on it; decorative loops stop entirely. The .spin
   loader keeps turning (slowly) because a frozen spinner reads as "hung". */
@media (prefers-reduced-motion: reduce) {
    :root {
        --anim-fast: 1ms linear;
        --anim-normal: 1ms linear;
        --lift-hover: none;
        --lift-card: none;
    }

    *, *::before, *::after {
        animation-duration: 1ms !important;
        animation-delay: 0ms !important;
        transition-duration: 1ms !important;
        transition-delay: 0ms !important;
        scroll-behavior: auto !important;
    }

    /* Decorative infinite loops: stop outright */
    .skeleton,
    .division-badge {
        animation: none !important;
    }

    /* Progress feedback must still read as "working" */
    .spin {
        animation: spin 1.6s linear infinite !important;
    }

    /* No hover lift, but keep the colour/shadow change so hover is still legible */
    .tool-card.human-card:hover,
    .btn-primary:hover {
        transform: none !important;
    }
}

/* Focus visibility for keyboard users, on-brand */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
    outline: none;
    box-shadow: var(--pb-focus-ring);
}
