/* ============================================================
   Design tokens — the single source of truth for the whole app.
   Load order: tokens.css -> aero.css (skin) -> ux.css (components).

   Rule: no template and no other stylesheet may hardcode a colour,
   a spacing value or a font size. If a value is missing here, add it
   here. That is what makes a redesign a one-file change instead of a
   34-file archaeology dig.
   ============================================================ */

:root {
    /* ---------- Spacing scale (4px base) ----------
       Everything lays out on this ladder so vertical rhythm is
       consistent across screens that were written months apart. */
    --sp-0: 0;
    --sp-1: 2px;
    --sp-2: 4px;
    --sp-3: 6px;
    --sp-4: 8px;
    --sp-5: 12px;
    --sp-6: 16px;
    --sp-7: 20px;
    --sp-8: 24px;
    --sp-9: 32px;
    --sp-10: 40px;

    /* ---------- Type scale ----------
       --fs-body is 14px, not 12px. The old FSL screen used 12px
       monospace for numeric entry; operators reading it for 8 hours
       is an eye-strain complaint waiting to happen. Numbers keep a
       tabular font so columns of money line up digit-for-digit. */
    --fs-micro: 11px;
    --fs-small: 12px;
    --fs-body: 14px;
    --fs-lead: 15px;
    --fs-h3: 17px;
    --fs-h2: 20px;
    --fs-h1: 24px;
    --fs-kpi: 26px;

    --lh-tight: 1.25;
    --lh-body: 1.5;

    --fw-normal: 400;
    --fw-medium: 500;
    --fw-semi: 600;
    --fw-bold: 700;

    --font-ui: 'Segoe UI', 'Inter', Tahoma, Geneva, Verdana, sans-serif;
    /* Tabular numerals: money columns must align. */
    --font-num: 'Segoe UI', 'Inter', ui-monospace, 'Cascadia Mono',
                'Consolas', monospace;

    /* ---------- Radius & elevation ---------- */
    --r-sm: 3px;
    --r-md: 6px;
    --r-lg: 10px;
    --r-pill: 999px;

    --el-1: 0 1px 2px rgba(16, 32, 56, 0.10);
    --el-2: 0 2px 8px rgba(16, 32, 56, 0.12);
    --el-3: 0 8px 24px rgba(16, 32, 56, 0.18);
    --el-4: 0 18px 50px rgba(16, 32, 56, 0.28);
    --el-inset-top: inset 0 1px 0 rgba(255, 255, 255, 0.9);

    /* ---------- Aero surface palette (the look, kept) ---------- */
    --aero-bg-top: #d9e4f1;
    --aero-bg-bottom: #b8c6df;

    --aero-glass: rgba(255, 255, 255, 0.62);
    --aero-glass-strong: rgba(255, 255, 255, 0.86);
    --aero-glass-nav: rgba(255, 255, 255, 0.42);
    --aero-glass-border: rgba(255, 255, 255, 0.82);
    --aero-glass-highlight: rgba(255, 255, 255, 1);

    --aero-btn-top: #4da3ff;
    --aero-btn-bottom: #0069d9;
    --aero-btn-border: #00509e;

    --aero-silver-top: #f6f9fc;
    --aero-silver-bottom: #d5deea;
    --aero-silver-border: #8ea1b8;

    /* ---------- Text ----------
       Contrast fixed: --text-muted was #94a3b8 on glass (2.4:1, fails
       WCAG AA badly). It is now #4a5a70, which clears 4.5:1 against
       every surface in this app. */
    --text: #16202e;
    --text-soft: #33425b;
    --text-muted: #4a5a70;
    --text-link: #0b47a1;
    --text-on-dark: #ffffff;

    /* Text shadow is decoration only — never used to create contrast. */
    --text-emboss: 0 1px 0 rgba(255, 255, 255, 0.75);

    /* ---------- Focus ----------
       One visible focus ring, used by every interactive element.
       The old CSS had none, which made keyboard use guesswork. */
    --focus-ring: 0 0 0 2px #ffffff, 0 0 0 4px #1f6feb;
    --focus-color: #1f6feb;

    /* ---------- Semantic intent ----------
       Each intent has a -fg (text), -bg (fill), -border and -tint.
       Status pills, alerts, badges and KPI deltas all read from these,
       so "warning yellow" cannot drift between screens. */
    --ok-fg: #0a3622;      --ok-bg: #d1e7dd;   --ok-border: #146c43;  --ok-tint: rgba(20, 108, 67, 0.10);
    --warn-fg: #5c4204;    --warn-bg: #fff3cd; --warn-border: #b8860b; --warn-tint: rgba(184, 134, 11, 0.12);
    --bad-fg: #58151c;     --bad-bg: #f8d7da;  --bad-border: #b02a37;  --bad-tint: rgba(176, 42, 55, 0.10);
    --info-fg: #052c65;    --info-bg: #cfe2ff; --info-border: #0a58ca; --info-tint: rgba(10, 88, 202, 0.10);
    --neutral-fg: #3d4756; --neutral-bg: #e9edf2; --neutral-border: #98a5b5; --neutral-tint: rgba(61, 71, 86, 0.08);

    /* Money direction — revenue vs cost, used identically everywhere. */
    --money-in: #0f6b3f;
    --money-out: #a3232f;

    /* ---------- Brand ----------
       Sampled from the GML logo (#00435f is both the diamond mark and the
       wordmark). Used for chart series that mean "the company" rather than
       one side of a comparison, and matched by `BRAND` in company.py so a
       printed invoice and an on-screen chart are the same blue. */
    --gml-blue: #00435f;
    --gml-blue-soft: #4d8ba6;
    --gml-blue-tint: rgba(0, 67, 95, 0.10);

    /* ---------- Categorical chart hues ----------
       For series that are *identities* — sea freight, air freight, a
       customer — where no slice is better or worse than another.

       Deliberately not the money-in/money-out pair, and not --gml-blue.
       Painting "Air Freight Export" green and "Overland Import" red
       borrows the one colour distinction this app has trained people to
       read as profit and loss, and asserts something about the business
       units that is not true.

       The order is the safety mechanism, so it is fixed and never
       cycled: the hues were checked pairwise under simulated protanopia
       and deuteranopia, and every neighbouring pair clears the
       separation floor — including --cat-6 against --cat-1, because in a
       ring the last slice touches the first. Reordering this list
       silently breaks that.

       --cat-1 is GML's own blue with its lightness and chroma raised.
       #00435f itself measures L 0.36 / chroma 0.08, below the readable
       band for a filled area, and next to a real hue it reads as
       near-grey. --gml-blue stays in use everywhere it means "the
       company" rather than "one category among several".

       A chart with more categories than this does not get a seventh
       hue — the tail folds into --cat-rest. Past six, adjacent classes
       blur and the legend becomes a table pretending to be a picture.
       Four of these sit below 3:1 against the glass, which is allowed
       only because every slice is directly labelled with its own name
       and figure; a chart that drops those labels may not use this
       ramp. */
    --cat-1: #0a6d97;
    --cat-2: #eb6834;
    --cat-3: #1baf7a;
    --cat-4: #4a3aa7;
    --cat-5: #eda100;
    --cat-6: #e87ba4;
    /* The remainder — "the other four business units", "23 more". The only
       neutral in the ramp, on purpose: "everything else" is not an identity
       and must not look like one.

       It is this dark rather than a mid-grey because a mid-grey is a
       desaturated blue, and under simulated protanopia every mid-grey
       tried here collapsed into --cat-1 (worst pair ΔE 4.0–5.9, floor 6).
       At this lightness it clears every hue in the ramp with ΔE ≥ 15.9. */
    --cat-rest: #2f3b47;

    /* ---------- Layout ---------- */
    --nav-h: 52px;
    --page-max: 1600px;
    --row-h: 36px;          /* comfortable density */
    --row-pad-y: var(--sp-4);
    --cell-pad-x: var(--sp-5);

    --dur-fast: 90ms;
    --dur: 150ms;
    --dur-slow: 240ms;
    --ease: cubic-bezier(0.2, 0.6, 0.2, 1);

    --z-content: 1;
    --z-sticky: 20;
    --z-nav: 100;
    --z-dropdown: 200;
    --z-toast: 800;
    --z-dialog: 900;
    --z-palette: 1000;
}

/* ---------- Density: compact ----------
   Operators scanning 200-row FSL logs asked for more rows per screen;
   managers reading the dashboard want breathing room. One toggle in
   the navbar flips this on <html> and persists per user. */
:root[data-density="compact"] {
    --row-h: 26px;
    --row-pad-y: var(--sp-2);
    --cell-pad-x: var(--sp-4);
    --fs-body: 13px;
    --fs-small: 11.5px;
}

/* ---------- Respect the user's motion preference ----------
   Nothing in this app needs to move. Animation is a nicety; for
   someone with vestibular sensitivity it is a symptom trigger. */
@media (prefers-reduced-motion: reduce) {
    :root {
        --dur-fast: 0ms;
        --dur: 0ms;
        --dur-slow: 0ms;
    }
    *, *::before, *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }
}

/* ---------- Print ----------
   Invoices, bills, SOAs and PODs are printed and filed. Glass, blur
   and gradients waste toner and blur scans; strip them to plain ink. */
@media print {
    :root {
        --aero-glass: #fff;
        --aero-glass-strong: #fff;
        --aero-glass-nav: #fff;
        --aero-glass-border: #999;
        --text-emboss: none;
    }
    .global-nav, .ux-toasts, .ux-palette, .no-print,
    .ux-actionbar, .ux-filterbar, .ux-shortcut-hint { display: none !important; }
    body { background: #fff !important; }
}
