/* ═══════════════════════════════════════════════════════════
   Capplon Design System — Design Tokens
   Extracted faithfully from the TNonline web UI.
   "Scandinavian Industrial" — warm charcoal + deep teal.

   Every value below is a CSS custom property. Components in
   components/*.css reference these exclusively, so a single
   change here re-themes the whole system.

   This file is CUSTOM PROPERTIES ONLY — no selectors touch an element.
   As of commit a3bf454 the global reset AND Capplon visual-identity
   defaults (typography, page background, link colour, focus ring,
   scrollbar) that used to live at the bottom of this file moved out to a
   companion base.css — READ base.css's header before you decide whether
   that file is optional for you. If you're updating a tokens.css vendored
   before a3bf454, it is very likely not optional for you, and the failure
   mode if you skip it is easy to miss in review: if your product already
   loads some other reset (e.g. a Bootstrap reboot), the generic parts
   (box-sizing) still hold, so nothing looks broken — only the Capplon-
   specific look (font, background, link colour, focus ring) quietly
   reverts to that other reset's defaults, page by page. Load tokens.css
   first regardless of whether you also take base.css.
   ═══════════════════════════════════════════════════════════ */

:root {
    /* ── Primary — deep charcoal with warmth ── */
    --tn-primary: #1A1D23;
    --tn-primary-light: #24272E;
    --tn-primary-dark: #111318;

    /* ── Accent — deep teal, industrial, confident ── */
    --tn-accent: #0D7377;
    --tn-accent-hover: #0A5C5F;
    --tn-accent-active: #084E51;
    --tn-accent-light: #EFFAFA;
    /* Text/icon color to place ON TOP of a solid --tn-accent fill (e.g. a
       primary button's label). White works for every accent this system has
       shipped so far, so this changes nothing today — it exists so an
       alternate, lighter accent (a palette experiment, a future theme) can
       repoint its own button text without every component hardcoding #fff. */
    --tn-accent-contrast: #fff;
    /* The accent as bare RGB channels, for rgba() alpha use — focus rings,
       hover glows, selection tints. CSS can't take an alpha slice of a hex
       custom property, so anything semi-transparent had to hardcode the teal
       and would stay teal when the palette changed. Components use
       rgba(var(--tn-accent-rgb), <alpha>) instead; keep this in sync with
       --tn-accent. */
    --tn-accent-rgb: 13, 115, 119;

    /* ── Corporate brand blue — the capplon.se WEBSITE accent (the "Kontakt"
       pill). Used ONLY by the site header (.tn-site-header) so the funnel's
       chrome matches the marketing site; product UI stays teal (--tn-accent). ── */
    --tn-brand-blue: #2017DF;

    /* ── Status colors — muted, professional ── */
    --tn-success: #2D8B4E;
    --tn-success-light: #F0F9F3;
    --tn-success-text: #276749;
    --tn-warning: #B8860B;
    --tn-warning-light: #FDF8EC;
    --tn-warning-text: #92400E;
    --tn-danger: #C53030;
    --tn-danger-light: #FDF2F2;
    --tn-danger-text: #9B2C2C;
    /* Same literal as --tn-accent above, deliberately, not derived from it
       (no var()) — in THIS base palette, informational UI reads as brand
       teal rather than a separate hue. That's a base-palette decision, not
       an architectural coupling: palettes.css already diverges the two on
       purpose in both directions. A palette that moves --tn-accent to a
       distinct brand color while keeping teal's own identity (philip-light/
       philip-white → blue accent) leaves --tn-info at teal rather than
       following the accent. A palette where the accent line itself becomes
       the "light, brand-forward" hue (philip-dark/dark-blue) overrides
       --tn-info to match it. If you're touching this value: decide which of
       those two shapes applies to what you're changing, and either update
       both together on purpose or leave a comment for why they now differ —
       don't let the next repaint depend on someone remembering this line. */
    --tn-info: #0D7377;
    --tn-info-light: #EFFAFA;

    /* ── Scan direction — ScanEasy's IN/OUT indicator on the scan page.
       Deliberately separate from --tn-success/--tn-danger: those are muted
       system/form feedback colors, while this is a high-visibility
       directional signal that has to read correctly at a glance in a dim
       warehouse aisle. Keeps its own saturated values instead of the muted
       status palette. Scoped to scan-direction UI only — every other
       success/error state still uses --tn-success/--tn-danger. ── */
    --tn-scan-in: #4CAF50;
    --tn-scan-out: #F44336;

    /* ── Text — warm, readable ── */
    --tn-text-primary: #1A1A1A;
    --tn-text-secondary: #5F6368;
    /* Was #9AA0A6 (2.64:1 on card, 2.42:1 on page) — under AA even at the
       large-text allowance. Every palette override already darkens this
       (see palettes.css's philip-white/philip-warm/dark comments) — this
       is the one place the fix hadn't been applied, because it's the
       un-themed default nothing here renders under. Darkened to the
       nearest value that clears 4.5:1 on both --tn-bg-card and
       --tn-bg-page with margin, same method as the palette fixes. */
    --tn-text-muted: #686C72;
    --tn-text-on-dark: #B8BCC2;
    --tn-text-on-dark-bright: #ECEEF0;

    /* ── Backgrounds — warm neutrals ── */
    --tn-bg-page: #F5F5F3;
    --tn-bg-card: #FFFFFF;
    /* Input fill. Defaults to the card colour, so this changes nothing on its
       own — it exists so a theme can TINT surfaces without swallowing the
       controls sitting on them. With a warm/beige card, inputs inheriting that
       fill lose their edge against the panel they're in; this lets them stay
       crisp while the panel warms up. */
    --tn-bg-input: var(--tn-bg-card);
    --tn-bg-hover: #FAFAF8;
    --tn-bg-active: #EFFAFA;

    /* ── Borders — clean, warm ── */
    --tn-border: #E3E3E0;
    --tn-border-light: #F0F0EE;

    /* ── Scrollbar — its own tokens, not borrowed text roles ──
       base.css used to paint the thumb with --tn-text-muted/-secondary
       directly. That's a surface use of a token whose contrast is tuned
       for TEXT — when --tn-text-muted was darkened for AA (see this
       file's own comment on it), the rest/hover separation on the
       scrollbar thumb quietly dropped from 2.29:1 to 1.15:1 as a side
       effect nobody chose (found by colibriauth-coder, 2026-08-14).
       These preserve the original visual values so future text-contrast
       fixes can never again move a scrollbar affordance as a side effect.

       This isn't specific to OUR fix. logeasy-coder reproduced the exact
       same collapse independently in LogEasy's own dark theme (2026-08-14)
       — their own local --tn-text-muted override for dark mode ALSO fed
       the old coupled scrollbar rule, and darkening it for their own
       reasons dropped their rest/hover separation from 2.61:1 to 1.69:1,
       with zero involvement from anything in this repo. Any consumer that
       redefines --tn-text-muted, for any reason, in any theme, hits this
       if the scrollbar is still wired to it — which is the real argument
       for dedicated tokens: it decouples a hazard a product can trigger
       entirely on their own side, not just one this repo could cause.

       OPEN QUESTION, deliberately not resolved here (colibriauth-coder,
       2026-08-14): the thumb against its (transparent) track measures
       2.64:1 on card / 2.42:1 on page — under WCAG 1.4.11's 3:1 floor for
       UI components. Whether an author-styled ::-webkit-scrollbar counts
       as a "component" under 1.4.11 or falls under the native-browser-
       chrome exemption is genuinely contested, not something either of us
       has a citation settling. Two facts ARE settled: this value was
       already under 3:1 before the #55 thread ever started, and it's now
       pinned deliberately rather than able to drift darker by accident.
       Raising it is a visual decision (a more visible scrollbar thumb),
       not an accessibility-floor fix like the rest of this thread — leave
       for a product-owner call, don't bump it as a side effect of
       something else.

       THESE TWO VALUES ARE LIGHT-MODE ONLY. If your product has its own
       dark theme, override --tn-scrollbar-thumb/-hover explicitly there —
       don't assume it inherits something reasonable. logeasy-coder hit
       this taking these tokens as-is into their dark theme (2026-08-14):
       #9AA0A6 rest / #5F6368 hover measured fine against their dark
       surface in isolation (7.04:1 / 3.07:1) but FADES on hover instead
       of lighting up, because these were tuned as a light-recedes-to-
       darker-on-hover pair, and that relationship inverts on a dark
       surface without a deliberate dark-mode override. Not a bug in this
       file; it's what removing the old (accidental) text-token coupling
       exposes once a consumer's dark theme only thought to override text. */
    --tn-scrollbar-thumb: #9AA0A6;
    --tn-scrollbar-thumb-hover: #5F6368;

    /* ── App bars ──
       The height of the fixed top bar, and of the optional second-level bar
       under it. These exist as tokens because every layout that hosts a fixed
       bar has to agree with it: content offset, a sticky sub-nav's `top`, a
       drawer's `padding-top`, a full-height panel's `height`. ScanEasy hardcodes
       its bar height in ELEVEN files (56px / 64px / 3.5rem) and its sub-nav
       assumes 56px under a 64px bar — so every section page sits 8px under the
       header. One value, referenced everywhere, is the fix. */
    --tn-topbar-height: 60px;
    --tn-subbar-height: 52px;

    /* Measured via getBoundingClientRect on the real rendered bar (5
       items, one raised centre action, safe-area-inset at 0). Same
       derivation reasoning as the topbar heights above — one value,
       referenced by both the bar and .tn-bottom-nav-offset, is what
       stops them drifting apart. */
    --tn-bottomnav-height: 63px;

    /* ── Sidebar ── */
    --tn-sidebar-width: 252px;
    --tn-sidebar-bg: #1A1D23;
    --tn-sidebar-hover: rgba(255, 255, 255, 0.06);
    --tn-sidebar-active: rgba(13, 115, 119, 0.25);

    /* ── Shadows — subtle, grounded ── */
    --tn-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04);
    --tn-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
    --tn-shadow-md: 0 2px 8px rgba(0, 0, 0, 0.08);
    --tn-shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.1);

    /* ── Radius — angular, industrial ── */
    --tn-radius-sm: 3px;
    --tn-radius: 6px;
    --tn-radius-lg: 8px;
    --tn-radius-xl: 10px;

    /* ── Z-index scale — the authoritative stacking order for every
       system-level overlay. Before this existed, each overlay component
       hardcoded its own literal with no documented relationship to the
       others, which is how a product regresses a page by lifting one
       overlay above another it was never meant to cover. If you're adding
       a new full-page or floating overlay, place it using this scale —
       don't guess a literal. Values preserve exactly what each existing
       component already used; this only makes the relationship explicit.
       Low to high:
         fixed-nav   — persistent chrome that's always on screen (bottom nav)
         dropdown    — transient, closes on outside click (menus)
         panel       — a drawer/sheet the user explicitly opened and must
                       explicitly close; can coexist under a dropdown or a
                       confirmation modal raised from within it
         modal       — a blocking dialog; goes above a panel because a
                       panel's own "are you sure you want to close?"
                       confirmation must be able to sit on top of it
         scanner     — the fullscreen camera takeover; the one surface
                       that must never be obscured by anything else in the
                       product, including a modal, since it's a hardware
                       capture in progress ── */
    --tn-z-fixed-nav: 1000;
    --tn-z-dropdown: 1100;
    --tn-z-panel: 9000;
    --tn-z-modal: 9999;
    --tn-z-scanner: 10000;

    /* ── Touch targets — minimum interactive sizes for high-friction
       contexts. The 44px baseline (Apple HIG) already anchors list rows
       (lists.css) and phone-width stepper controls (stepper.css);
       --tn-touch-target-lg is for screens where that's not enough — e.g.
       ScanEasy's scan page, operated one-handed while wearing work gloves. ── */
    --tn-touch-target: 44px;
    --tn-touch-target-lg: 48px;

    /* ── Spacing — 8px base ── */
    --tn-space-xs: 4px;
    --tn-space-sm: 8px;
    --tn-space-md: 16px;
    --tn-space-lg: 24px;
    --tn-space-xl: 32px;

    /* ── Page gutter — horizontal padding for page content.
       The single source of truth for "how far content sits from the
       screen edge". Tapers on phones (override below) so the whole UI
       tightens at once, and .tn-bleed-mobile cancels exactly this. ── */
    --tn-page-pad-x: var(--tn-space-lg); /* 24px on desktop */

    /* ── Typography — Figtree: warm geometric, professional ── */
    --tn-font-family: 'Figtree', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --tn-font-mono: 'Cascadia Code', 'Fira Code', ui-monospace, monospace;
    --tn-font-size-xs: 0.75rem;     /* 12px */
    --tn-font-size-sm: 0.8125rem;   /* 13px */
    --tn-font-size-base: 0.9375rem; /* 15px */
    --tn-font-size-lg: 1.0625rem;   /* 17px */
    --tn-font-size-xl: 1.1875rem;   /* 19px */
    --tn-font-size-2xl: 1.375rem;   /* 22px */
    --tn-font-size-3xl: 1.75rem;    /* 28px */

    /* ── Transitions — quick, purposeful ── */
    --tn-transition: 0.15s ease;
    --tn-transition-slow: 0.25s ease;
}

/* On phones the page gutter tightens to 16px (== Bootstrap px-3), so
   content sits closer to the edge and the whole UI feels denser. */
@media (max-width: 640px) {
    :root {
        --tn-page-pad-x: var(--tn-space-md); /* 16px */
    }
}
