/**
 * ADA Systems - the theme.
 *
 * Every colour, radius, space, shadow and size in the site comes from here, and
 * nothing else declares them. Before this file there were twelve stylesheets
 * each with their own :root block - --primary was defined in eight places, .btn
 * in eleven - so changing a button on one page left the same button untouched on
 * the next one. That is the problem this file exists to end.
 *
 * Two rules keep it that way:
 *
 *   1. No other stylesheet declares a custom property. If a page needs a value
 *      that is not here, the value belongs here, named for what it means.
 *   2. Rules elsewhere reference tokens, never literals. A hex code or a pixel
 *      radius written into a page stylesheet is the old problem coming back.
 *
 * Loaded first by every layout, so everything after it can read these.
 */

:root {
    /* ==========================================
       COLOUR - light (the default)
       ========================================== */

    /* Brand */
    --primary: #2563eb;
    --primary-dark: #1e40af;
    --primary-light: #3b82f6;
    --primary-soft: rgba(37, 99, 235, 0.1);

    /* Status. --error is the older name for --danger and is kept because both
       are used across the stylesheets; they must never drift apart. */
    --success: #10b981;
    --success-strong: #059669;
    --success-soft: rgba(16, 185, 129, 0.12);
    --warning: #f59e0b;
    --warning-strong: #b45309;
    --warning-soft: rgba(245, 158, 11, 0.12);
    --danger: #ef4444;
    --danger-strong: #b91c1c;
    --danger-soft: rgba(239, 68, 68, 0.12);
    --error: var(--danger);
    --info: #0ea5e9;
    --info-strong: #0369a1;
    --info-soft: rgba(14, 165, 233, 0.12);
    --accent: var(--success);

    /* The quiet form of a status: a tinted panel with its own readable text and
       border. A warning chip, a danger button that is not shouting, an info
       callout - all of them are these three, not a fresh pair of hex codes. */
    --success-surface: #ecfdf5;
    --success-line: #a7f3d0;
    --on-success-surface: #065f46;
    --warning-surface: #fef3c7;
    --warning-line: #fde68a;
    --on-warning-surface: #92400e;
    --danger-surface: #fef2f2;
    --danger-line: #fecaca;
    --on-danger-surface: #b91c1c;
    --info-surface: #eff6ff;
    --info-line: #bfdbfe;
    --on-info-surface: #1e40af;

    /* Accents. Not statuses - these are the twelve colours the hub tiles are
       coded by, so a person finds "Geofencing" by its pink before they read it.
       One hue each. The coloured halo under a tile is computed from it with
       color-mix, so a colour is one dial rather than five hex codes.

       These were about seventy hex codes spread through fleet-hub.css, and they
       had already drifted: the purple tile's shadow was #7c3aed while its icon
       started at #6366f1 and its hover shadow was #4f46e5. One hue now. */
    --accent-blue: #3b82f6;
    --accent-purple: #6366f1;
    --accent-cyan: #0ea5e9;
    --accent-orange: #f59e0b;
    --accent-green: #22c55e;
    --accent-pink: #ec4899;
    --accent-emerald: #10b981;
    --accent-slate: #64748b;
    --accent-indigo: #6366f1;
    --accent-amber: #f59e0b;
    --accent-red: #ef4444;
    --accent-teal: #14b8a6;

    /* The purples the application actually draws with. --accent-purple is the
       flat one a tile is coded by; these four are the gradient stops and the
       hover shades that were written by hand in a dozen stylesheets - the
       violet on a save button, the deep purple under it, the indigo on a
       focus ring. They were #8b5cf6, #7c3aed, #5b21b6 and #4f46e5, typed out
       between them about eighty times. */
    --accent-violet: #8b5cf6;
    --accent-purple-strong: #7c3aed;
    --accent-purple-deep: #5b21b6;
    --accent-indigo-strong: #4f46e5;

    /* Fuel card brands. Not ours to restyle - this is Shell's yellow and
       Esso's blue - and they stay put in both themes for the same reason a
       logo does. They are here because they were typed into two stylesheets
       and a brand colour is still a value that belongs in one place. */
    --brand-shell: #fbcb09;
    --brand-shell-ink: #dd1d21;
    --brand-esso: #003087;
    --brand-allstar: #e31937;
    --brand-bp: #009a4e;

    /* How far an accent is pulled towards the text colour when it has to BE
       text - a tile's title. The raw hue fails badly: amber on white is 2.15:1,
       where readable text needs 4.5:1. At 62% the worst of the twelve is 4.60:1,
       measured. That is close to the line on purpose - Vlad wanted the colour
       more visible - and it is as far as it goes: 64% drops orange to 4.38 and
       the title stops being readable text. Recompute before turning it. */
    --accent-ink-mix: 62%;

    /* Text */
    --text-dark: #111827;
    --text-gray: #6b7280;
    --text-light: #9ca3af;
    --text-on-brand: #ffffff;

    /* Surfaces */
    --bg-body: #f3f4f6;
    --bg-light: #f9fafb;
    --bg-white: #ffffff;
    --bg-hover: #f3f4f6;
    --bg-sunken: #eef0f3;

    /* Lines */
    --border: #e5e7eb;
    --border-strong: #d1d5db;

    /* The site footer. It is deliberately not --bg-white: on the public pages
       it reads as the ground the page sits on, a shade past the body. These
       lived in components.css as six !important rules in raw hex, fighting
       app.css for the same element. */
    --footer-bg: #f8fafc;
    --footer-border: rgba(0, 0, 0, 0.08);

    /* Chrome */
    --header-bg: #ffffff;
    --header-border: rgba(148, 163, 184, 0.4);

    /* The hairline ring around a hub tile, under its coloured halo. */
    --hub-ring: rgba(148, 163, 184, 0.15);
    --hub-ring-hover: rgba(148, 163, 184, 0.2);

    /* The dark wash behind a modal, and the same with a blur applied. */
    /* Paper. A QR code is read by reflectance and the standard is built on dark
       modules over a light field, so the plate behind one stays white in both
       themes - it is not a surface that follows the theme. */
    --qr-paper: #ffffff;

    --scrim: rgba(15, 23, 42, 0.8);
    --scrim-blurred: rgba(15, 23, 42, 0.6);

    /* Tints of the text colour used ON a brand surface - a modal's header
       icon, its close button, its subtitle. */
    --on-brand-wash: rgba(255, 255, 255, 0.2);
    --on-brand-wash-strong: rgba(255, 255, 255, 0.28);
    --on-brand-muted: rgba(255, 255, 255, 0.8);

    /* Shadows: the colour, so a rule can compose its own offsets, plus the
       three ready-made elevations most of the site uses. */
    --shadow: rgba(15, 23, 42, 0.08);
    --shadow-lg: rgba(15, 23, 42, 0.12);
    --elevation-1: 0 1px 2px var(--shadow);
    --elevation-2: 0 4px 12px var(--shadow);
    --elevation-3: 0 12px 32px var(--shadow-lg);

    /* The coloured lift under a primary button. It is part of how the admin and
       fleet pages read, so it is kept - as a token, not as a hex code repeated
       in eleven stylesheets. */
    --shadow-primary: 0 10px 25px rgba(37, 99, 235, 0.35);
    --shadow-primary-hover: 0 12px 28px rgba(37, 99, 235, 0.45);

    /* ==========================================
       RADIUS

       Rectangular with rounded corners, deliberately - not pills. There is no
       pill token and there should not be one: if a button needs to look like a
       capsule it is not this button. --radius-round stays for things that are
       actually circles, which is avatars, status dots and icon bubbles.
       ========================================== */
    --radius-xs: 4px;
    --radius-sm: 6px;
    --radius-md: 8px;
    --radius-lg: 12px;
    --radius-xl: 16px;
    --radius-2xl: 20px;
    --radius-3xl: 24px;
    --radius-4xl: 28px;
    --radius-round: 50%;

    /* ==========================================
       SPACE - a 4px scale
       ========================================== */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 20px;
    --space-6: 24px;
    --space-7: 28px;
    --space-9: 36px;
    --space-8: 32px;
    --space-10: 40px;
    --space-12: 48px;
    --space-14: 56px;
    --space-15: 60px;
    --space-16: 64px;
    --space-20: 80px;

    /* ==========================================
       TYPE
       ========================================== */
    --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

    --text-2xs: 8px;
    --text-xs: 11px;
    --text-sm: 12px;
    --text-base: 14px;
    --text-md: 16px;
    --text-lg: 18px;
    --text-xl: 22px;
    --text-2xl: 24px;
    --text-3xl: 30px;

    /* Display sizes. The landing and feature pages run well past the reading
       scale - a hero numeral is 112px - and every one of those was typed
       into a rule. Same ramp, further up. */
    --text-4xl: 36px;
    --text-5xl: 40px;
    --text-6xl: 48px;
    --text-7xl: 56px;
    --text-8xl: 64px;
    --text-9xl: 80px;
    --text-display: 112px;

    --weight-normal: 400;
    --weight-medium: 500;
    --weight-semibold: 600;
    --weight-bold: 700;
    --weight-extrabold: 800;
    --weight-black: 900;

    --leading-none: 1;
    --leading-tight: 1.25;
    --leading-snug: 1.4;
    --leading-base: 1.5;
    --leading-normal: 1.6;
    --leading-relaxed: 1.7;
    --leading-loose: 2;

    /* Letter spacing. Uppercase labels were tracked out by hand at 0.03em,
       0.04em, 0.05em, 0.06em, 0.08em, 0.1em, 0.3px, 0.5px and 1px - nine
       spellings of "a little wider", across sixty-odd rules. */
    --tracking-tight: -0.01em;
    --tracking-normal: 0;
    --tracking-wide: 0.03em;
    --tracking-wider: 0.05em;
    --tracking-widest: 0.1em;

    /* Breakpoints cannot be custom properties - a media query is resolved
       before var() exists - so this is the list rather than the mechanism.
       768 carries 42 rules and 1024 another 14; the rest are a single grid
       stepping down - .settings-grid goes three columns, two, one at 700,
       1100 and 1400 - which is a design, not a mess, so they stay.

       What was a mess, and is fixed: the same selector reflowing at different
       widths in different files. .form-grid stacked at 768 in management.css
       and at 900 on the device create page; .form-row at 480, 640 and 768 in
       three files; .col-hide-mobile hid at 640 on one report and 768 on the
       other three. One object should not behave differently depending on
       which page you are on.

           phone    480px
           tablet   768px
           laptop   1024px
           desktop  1280px

       Pick from those for anything new. */

    /* ==========================================
       CONTROLS

       Buttons, inputs and selects share these, which is what makes a button sit
       level with the field next to it instead of a pixel or two off.
       ========================================== */
    --control-height-xs: 26px;
    --control-height-sm: 32px;
    --control-height-md: 38px;
    --control-height-lg: 46px;

    --control-pad-xs: 0 var(--space-2);
    --control-pad-sm: 0 var(--space-3);
    --control-pad-md: 0 var(--space-4);
    --control-pad-lg: 0 var(--space-6);

    /* Every status badge is at least this wide, so a column of them is a
       column and not ragged text. Measured: ONLINE came out 61px against
       OFFLINE's 66px - one letter, and it showed. Long words still grow. */
    --badge-min-width: 72px;

    --control-radius: var(--radius-md);
    --control-border: 1px solid var(--border);

    /* Focus: one ring everywhere, so keyboard users get the same signal on a
       button, a field and a link. */
    --focus-ring: 0 0 0 3px var(--primary-soft);
    --focus-ring-danger: 0 0 0 3px var(--danger-soft);

    /* ==========================================
       MOTION
       ========================================== */
    --transition-fast: 0.12s ease;
    --transition: 0.2s ease;
    --transition-slow: 0.3s ease;
    --transition-slowest: 0.5s ease;

    /* ==========================================
       LAYERS - kept in one list so a modal cannot end up under a sticky header
       ========================================== */
    --z-sticky: 100;
    --z-header: 200;
    --z-dropdown: 300;
    --z-modal: 1000;
    --z-toast: 1100;

    /* Above the page but under a dialog: the map's floating controls, which
       had picked 500 for themselves. And the fullscreen layer, where the map
       and geofencing had written 2147483647 - the largest number there is,
       which wins by being big rather than by meaning anything. */
    --z-overlay: 400;
    --z-fullscreen: 2000;
}

/* ==========================================
   COLOUR - dark

   Only the colours move. Radius, space, type and control sizes are the same in
   both themes, which is why they are declared once above.
   ========================================== */
html.dark {
    --primary: #3b82f6;
    --primary-dark: #2563eb;
    --primary-light: #60a5fa;
    --primary-soft: rgba(59, 130, 246, 0.18);

    --success: #34d399;
    --success-strong: #10b981;
    --success-soft: rgba(52, 211, 153, 0.18);
    --warning: #fbbf24;
    --warning-strong: #f59e0b;
    --warning-soft: rgba(251, 191, 36, 0.18);
    --danger: #f87171;
    --danger-strong: #ef4444;
    --danger-soft: rgba(248, 113, 113, 0.18);
    --info: #38bdf8;
    --info-strong: #0ea5e9;
    --info-soft: rgba(56, 189, 248, 0.18);

    /* Tinted panels go dark by dropping the tint to a low-alpha wash over the
       dark surface, rather than by picking a second set of pastels. */
    --success-surface: rgba(52, 211, 153, 0.12);
    --success-line: rgba(52, 211, 153, 0.3);
    --on-success-surface: #6ee7b7;
    --warning-surface: rgba(251, 191, 36, 0.12);
    --warning-line: rgba(251, 191, 36, 0.3);
    --on-warning-surface: #fcd34d;
    --danger-surface: rgba(248, 113, 113, 0.12);
    --danger-line: rgba(248, 113, 113, 0.3);
    --on-danger-surface: #fca5a5;
    --info-surface: rgba(56, 189, 248, 0.12);
    --info-line: rgba(56, 189, 248, 0.3);
    --on-info-surface: #7dd3fc;

    /* Dark reverses it: --text-dark is now near-white, so the accent is pulled
       towards white instead. At 76% the worst is 4.76:1, and slate is the one
       that runs out first. */
    --accent-ink-mix: 76%;

    --text-dark: #f9fafb;
    --text-gray: #9ca3af;
    --text-light: #6b7280;
    --text-on-brand: #ffffff;

    --bg-body: #0f172a;
    --bg-light: #1e293b;
    --bg-white: #1e293b;
    --bg-hover: #263449;
    --bg-sunken: #172033;

    --border: #334155;
    --border-strong: #475569;

    --footer-bg: #030712;
    --footer-border: rgba(255, 255, 255, 0.08);

    --header-bg: #1e293b;
    --header-border: #334155;

    --scrim: rgba(0, 0, 0, 0.78);
    --scrim-blurred: rgba(0, 0, 0, 0.6);

    --shadow: rgba(0, 0, 0, 0.3);
    --shadow-lg: rgba(0, 0, 0, 0.4);
}

/* ==========================================
   SURFACES BEYOND THE APP

   Two palettes that are deliberately not the app's, declared here so there is
   still one place to change them.

   THE PUBLIC PAGES - the landing page, features, pricing, compliance, legal,
   contact, the app download page and the API docs. Dark by default with a cyan
   accent and glass panels, inverted for light. That inversion is why this block
   uses html:not(.dark) rather than html.dark like the rest of the file: these
   pages were written dark-first and are left that way.

   It was the same palette written five times over, under five prefixes -
   --legal-*, --contact-*, --app-*, --doc-* and the landing pair's own names -
   with byte-identical values in legal, contact and app-download.

   THE ADA TEST TOOL - green-accented and dark, a separate surface with its own
   identity, read across six stylesheets.
   ========================================== */

:root {
    /* Public pages - dark, the default for them */
    --public-bg: #030712;
    --public-bg-secondary: #0a0f1a;
    --public-glass: rgba(255, 255, 255, 0.03);
    --public-glass-hover: rgba(255, 255, 255, 0.06);
    --public-border: rgba(255, 255, 255, 0.08);
    --public-text: #f8fafc;
    --public-text-secondary: #94a3b8;
    --public-text-muted: #64748b;
    --public-accent: #06b6d4;
    --public-accent-secondary: #8b5cf6;
    --public-accent-tertiary: #10b981;
    --public-accent-warning: #f59e0b;
    --public-accent-danger: #ef4444;
    --public-glow: rgba(6, 182, 212, 0.4);
    --public-glow-secondary: rgba(139, 92, 246, 0.4);
    --public-grid: rgba(255, 255, 255, 0.02);
    --public-highlight: rgba(245, 158, 11, 0.1);
    --public-highlight-border: rgba(245, 158, 11, 0.3);
    --public-code-bg: #0a0f1a;

    /* The HTTP verbs on the API docs page - a colour per method. */
    --method-get: #10b981;
    --method-post: #3b82f6;
    --method-put: #f59e0b;
    --method-patch: #a855f7;
    --method-delete: #ef4444;

    /* The ADA Test tool */
    --ada-primary: #22c55e;
    --ada-primary-dark: #16a34a;
    --ada-primary-glow: rgba(34, 197, 94, 0.4);
    --ada-accent: #3b82f6;
    --ada-success: #22c55e;
    --ada-error: #ef4444;
    --ada-warning: #f59e0b;
    --ada-info: #0ea5e9;
    --ada-bg-primary: #0f172a;
    --ada-bg-secondary: #1e293b;
    --ada-bg-tertiary: #334155;
    --ada-bg-card: #1e293b;
    --ada-bg-hover: #334155;
    --ada-bg-input: #0f172a;
    --ada-bg-subtle: rgba(255, 255, 255, 0.03);
    --ada-border: #334155;
    --ada-border-light: #475569;
    --ada-text-primary: #f1f5f9;
    --ada-text-secondary: #94a3b8;
    --ada-text-muted: #64748b;
    --ada-shadow: rgba(0, 0, 0, 0.3);
    --ada-shadow-glow: rgba(34, 197, 94, 0.15);
}

/* The public pages in light. Everything not listed keeps its dark value on
   purpose - the accents are the same in both. */
html:not(.dark) {
    --public-bg: #f8fafc;
    --public-bg-secondary: #f1f5f9;
    --public-glass: rgba(255, 255, 255, 0.7);
    --public-glass-hover: rgba(255, 255, 255, 0.9);
    --public-border: rgba(0, 0, 0, 0.08);
    --public-text: #0f172a;
    --public-text-secondary: #475569;
    --public-text-muted: #64748b;
    --public-glow: rgba(6, 182, 212, 0.2);
    --public-glow-secondary: rgba(139, 92, 246, 0.2);
    --public-grid: rgba(0, 0, 0, 0.03);
    --public-code-bg: #f1f5f9;
}

/* The ADA Test tool in light. It used html.light rather than html:not(.dark),
   so the tool stayed dark until the theme was switched explicitly - kept as it
   was, because changing it would change what the tool looks like by default. */
html.light {
    --ada-bg-primary: #f5f5f5;
    --ada-bg-secondary: #ffffff;
    --ada-bg-tertiary: #fafafa;
    --ada-bg-card: #ffffff;
    --ada-bg-hover: #f0f0f0;
    --ada-bg-input: #ffffff;
    --ada-bg-subtle: rgba(0, 0, 0, 0.03);
    --ada-border: #e5e5e5;
    --ada-border-light: #d4d4d4;
    --ada-text-primary: #171717;
    --ada-text-secondary: #525252;
    --ada-text-muted: #737373;
    --ada-shadow: rgba(0, 0, 0, 0.1);
    --ada-shadow-glow: rgba(34, 197, 94, 0.2);
}

/* Someone who asked their system not to animate gets no animation, including
   the transitions the tokens above hand out. */
@media (prefers-reduced-motion: reduce) {
    :root {
        --transition-fast: 0s;
        --transition: 0s;
        --transition-slow: 0s;
        --transition-slowest: 0s;
    }
}
