/* ==========================================================================
   KineCrew design tokens
   --------------------------------------------------------------------------
   Set the palette on <html>:  <html data-palette="shift">

     shift      Sales floor, daylight. Default.
     backroom   Night shift, stock room, dim cab. Dark.
     ledger     Dense reporting. Warm-neutral ground, smaller base.
     highvis    Glare, older eyes, gloves. Max contrast, larger base.

   Rules this file encodes:
     - Brand color names the product. State color runs the store.
     - Exactly one state is allowed to be loud: `late`.
     - State is hue AND silhouette. Never ship a chip that leans on hue
       alone -- it has to survive grayscale and the deuteranopia check.
     - Every number is tabular.

   Every ink-on-fill pair clears 4.5:1 and every glyph clears 3:1 against
   its own fill, in all four palettes.

   Full spec + live preview: docs/design-system.html
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. STRUCTURE -- identical in every palette
   -------------------------------------------------------------------------- */
:root{
  --sp-1:4px;  --sp-2:8px;  --sp-3:12px; --sp-4:16px;
  --sp-5:24px; --sp-6:32px; --sp-7:48px; --sp-8:72px; --sp-9:112px;

  --r-chip:3px; --r:6px; --r-lg:10px; --r-pill:999px;

  --lift-1:0 1px 2px rgba(8,20,32,.06), 0 1px 1px rgba(8,20,32,.04);
  --lift-2:0 2px 4px rgba(8,20,32,.06), 0 8px 20px rgba(8,20,32,.07);

  --base:16px;
  --w-ui:400; --w-ui-strong:600;

  /* Type roles -- the "Utility" pairing */
  --f-display:'Archivo', system-ui, sans-serif;
  --f-ui:'Public Sans', system-ui, sans-serif;
  --f-data:'IBM Plex Mono', ui-monospace, monospace;
  --tr-display:-.028em; --w-display:700;
}

/* --------------------------------------------------------------------------
   2. PALETTES
   -------------------------------------------------------------------------- */

/* SHIFT -- light. Sales floor in daylight. */
:root,
[data-palette="shift"]{
  --bg:#F4F7FA; --surface:#FFFFFF; --raised:#FFFFFF; --sunk:#EDF1F6;
  --line:#DCE3EB; --line-strong:#C0CDDA;
  --text:#0E1720; --text-2:#445565; --text-3:#617181;
  --brand:#0B4FA6; --brand-2:#12A7C9; --brand-ink:#FFFFFF; --focus:#12A7C9; --nav:#093F84; --wx-warm:#B4531B; --wx-cool:#2A6E9E;

  --st-idle-solid:#7F8C99;     --st-idle-fill:#EFF2F5;     --st-idle-ink:#4E5C69;
  --st-open-solid:#52708F;     --st-open-fill:#ECF1F6;     --st-open-ink:#33495F;
  --st-done-solid:#0E7A5B;     --st-done-fill:#E4F4EE;     --st-done-ink:#0A5742;
  --st-hold-solid:#B0700A;     --st-hold-fill:#FBF0DC;     --st-hold-ink:#7C4D04;
  --st-late-solid:#D23B2A;     --st-late-fill:#FCEAE7;     --st-late-ink:#962417;
  --st-rejected-solid:#8B3C77; --st-rejected-fill:#F8EAF4; --st-rejected-ink:#66284F;

  /* Priority is a separate axis from state: it says how much it matters,
     not what happened. Kept quiet so the state chip stays the loud thing. */
  --pri-high:#D23B2A; --pri-medium:#B0700A; --pri-low:#52708F;
}

/* BACKROOM -- dark. Night shift, stock room, a wall monitor at 2am. */
[data-palette="backroom"]{
  --bg:#11161C; --surface:#191F27; --raised:#212934; --sunk:#0C1117;
  --line:#2B3540; --line-strong:#3D4B59;
  --text:#E7EEF5; --text-2:#A5B5C4; --text-3:#7A8B9B;
  --brand:#3EA8E0; --brand-2:#4FD6E8; --brand-ink:#06131F; --focus:#4FD6E8; --nav:#0F1720; --wx-warm:#E8894F; --wx-cool:#6BB6E0;

  --st-idle-solid:#7C8A98;     --st-idle-fill:#232B34;     --st-idle-ink:#B4C0CB;
  --st-open-solid:#6E97C4;     --st-open-fill:#1B2732;     --st-open-ink:#A8C4DE;
  --st-done-solid:#2EC08A;     --st-done-fill:#102820;     --st-done-ink:#6EDCB0;
  --st-hold-solid:#E0A032;     --st-hold-fill:#2A2011;     --st-hold-ink:#F1C671;
  --st-late-solid:#FF6A55;     --st-late-fill:#2E1815;     --st-late-ink:#FF9F8E;
  --st-rejected-solid:#C87BB4; --st-rejected-fill:#271A24; --st-rejected-ink:#E0A6D2;

  --pri-high:#FF6A55; --pri-medium:#E0A032; --pri-low:#6E97C4;

  --lift-1:0 1px 2px rgba(0,0,0,.4);
  --lift-2:0 2px 4px rgba(0,0,0,.35), 0 10px 24px rgba(0,0,0,.45);
}

/* LEDGER -- light, dense. Forty locations in one table. */
[data-palette="ledger"]{
  --bg:#F1F3EE; --surface:#FBFBF8; --raised:#FFFFFF; --sunk:#E7EAE2;
  --line:#D7DCD1; --line-strong:#B5BCAD;
  --text:#191C17; --text-2:#4A5049; --text-3:#696F67;
  --brand:#16394F; --brand-2:#0E7C8F; --brand-ink:#FFFFFF; --focus:#0E7C8F; --nav:#143446; --wx-warm:#A04A18; --wx-cool:#255F87;

  --st-idle-solid:#81877F;     --st-idle-fill:#EAEBE5;     --st-idle-ink:#4C524A;
  --st-open-solid:#4A6B84;     --st-open-fill:#E7EDF0;     --st-open-ink:#2C4557;
  --st-done-solid:#146B4E;     --st-done-fill:#E2EFE6;     --st-done-ink:#0D5038;
  --st-hold-solid:#9C6606;     --st-hold-fill:#F5EBD8;     --st-hold-ink:#6E4703;
  --st-late-solid:#C0392B;     --st-late-fill:#F7E7E3;     --st-late-ink:#8B2216;
  --st-rejected-solid:#7D3A6B; --st-rejected-fill:#F2E8EF; --st-rejected-ink:#5B2A4D;

  --pri-high:#C0392B; --pri-medium:#9C6606; --pri-low:#4A6B84;

  --base:15px;
}

/* HIGH-VIS -- light, maximum contrast. Sun on the screen, gloves on. */
[data-palette="highvis"]{
  --bg:#FFFFFF; --surface:#FFFFFF; --raised:#FFFFFF; --sunk:#F0F0F0;
  --line:#C4C4C4; --line-strong:#8A8A8A;
  --text:#000000; --text-2:#2B2B2B; --text-3:#484848;
  --brand:#003E8A; --brand-2:#006E9E; --brand-ink:#FFFFFF; --focus:#003E8A; --nav:#00306B; --wx-warm:#8F3D0C; --wx-cool:#00477F;

  --st-idle-solid:#6B6B6B;     --st-idle-fill:#ECECEC;     --st-idle-ink:#333333;
  --st-open-solid:#0B4FA6;     --st-open-fill:#E2ECF8;     --st-open-ink:#073C80;
  --st-done-solid:#006B4F;     --st-done-fill:#DCEFE6;     --st-done-ink:#00543D;
  --st-hold-solid:#9A6A00;     --st-hold-fill:#FBEFD2;     --st-hold-ink:#6B4900;
  --st-late-solid:#C1121F;     --st-late-fill:#FBE2E2;     --st-late-ink:#8B0A14;
  --st-rejected-solid:#6A2C91; --st-rejected-fill:#EFE4F6; --st-rejected-ink:#4C1E69;

  --pri-high:#C1121F; --pri-medium:#9A6A00; --pri-low:#0B4FA6;

  --base:17.5px; --w-ui:450; --w-ui-strong:700;
  --lift-1:none; --lift-2:0 0 0 1px #8A8A8A;
}

/* verified reuses done's hue -- the silhouette carries the difference */
:root{
  --st-verified-solid:var(--st-done-solid);
  --st-verified-fill:var(--st-done-fill);
  --st-verified-ink:var(--st-done-ink);
}

/* --------------------------------------------------------------------------
   3. BASELINE
   -------------------------------------------------------------------------- */
/* Tailwind's type and spacing utilities are rem-based, so the root font size
   is the lever that actually makes Ledger denser and High-Vis larger.
   Changing body's font-size alone would not reach `text-sm`, `p-4` etc. */
html{font-size:var(--base)}

body{
  background:var(--bg);
  color:var(--text);
  font-family:var(--f-ui);
  font-variant-numeric:tabular-nums;   /* times, counts, temps and money line up */
}
/* Every heading takes the display face. Element selectors, so all 103
   templates pick this up without touching their markup -- the templates set
   size and weight with Tailwind classes and never set font-family, so there
   is nothing here to fight. */
h1,h2,h3,h4,h5,h6,.font-display{
  font-family:var(--f-display);
  letter-spacing:var(--tr-display);
}
h1,h2,h3,.font-display{font-weight:var(--w-display)}
/* h4-h6 are used as small section labels here, so they stay lighter than a
   page title even though they share the face. */
h4,h5,h6{font-weight:600; letter-spacing:-.012em}

/* Anything countable: times, temperatures, counts, percentages, money.
   Never prose. */
.font-data,.tabular,.stat{font-family:var(--f-data); font-variant-numeric:tabular-nums}
.stat{letter-spacing:-.02em; font-weight:600}

:focus-visible{outline:2px solid var(--focus); outline-offset:2px}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important; transition-duration:.01ms!important}
}

/* --------------------------------------------------------------------------
   4. THE STATE CHIP -- hue + silhouette, never hue alone
   Rendered by {% state_chip %}; see accounts/templatetags/ui_tags.py
   -------------------------------------------------------------------------- */
.chip{
  display:inline-flex; align-items:center; gap:6px; flex:none;
  padding:3px 9px 3px 7px; border-radius:var(--r-chip);
  background:var(--chip-bg); color:var(--chip-ink);
  border:1px solid color-mix(in srgb, var(--chip-solid) 26%, transparent);
  font-size:12.5px; font-weight:var(--w-ui-strong); line-height:1.35;
  white-space:nowrap; text-decoration:none;
}
.chip svg{width:14px; height:14px; flex:none; color:var(--chip-solid); --knock:var(--chip-bg)}

.chip-idle    {--chip-bg:var(--st-idle-fill);     --chip-ink:var(--st-idle-ink);     --chip-solid:var(--st-idle-solid)}
.chip-open    {--chip-bg:var(--st-open-fill);     --chip-ink:var(--st-open-ink);     --chip-solid:var(--st-open-solid)}
.chip-done    {--chip-bg:var(--st-done-fill);     --chip-ink:var(--st-done-ink);     --chip-solid:var(--st-done-solid)}
.chip-verified{--chip-bg:var(--st-done-fill);     --chip-ink:var(--st-done-ink);     --chip-solid:var(--st-done-solid)}
.chip-hold    {--chip-bg:var(--st-hold-fill);     --chip-ink:var(--st-hold-ink);     --chip-solid:var(--st-hold-solid)}
.chip-late    {--chip-bg:var(--st-late-fill);     --chip-ink:var(--st-late-ink);     --chip-solid:var(--st-late-solid)}
.chip-rejected{--chip-bg:var(--st-rejected-fill); --chip-ink:var(--st-rejected-ink); --chip-solid:var(--st-rejected-solid)}

/* the loud treatment belongs to the chip only */
.chip.chip-late{border-color:var(--st-late-solid); font-weight:700}

.chip-sm{font-size:11.5px; padding:2px 7px 2px 5px}
.chip-sm svg{width:12px; height:12px}

/* --------------------------------------------------------------------------
   5. PRIORITY RAIL
   Priority says how much a task matters; state says what happened to it.
   A rail keeps priority scannable without tinting the whole card, which is
   what forced status badges to white-on-ring in the first place.
   -------------------------------------------------------------------------- */
/* Drawn as a pseudo-element rather than a border-left: Tailwind's `divide-*`
   and `border-*` utilities set border-color on all four sides, which silently
   repaints a border-based rail on every row after the first. */
.rail{position:relative}
.rail::before{
  content:""; position:absolute; left:0; top:0; bottom:0; width:4px;
  background:var(--rail, var(--line-strong));
  border-top-left-radius:inherit; border-bottom-left-radius:inherit;
  pointer-events:none;
}
.rail-high  {--rail:var(--pri-high)}
.rail-medium{--rail:var(--pri-medium)}
.rail-low   {--rail:var(--pri-low)}

/* --------------------------------------------------------------------------
   6. SURFACES -- for templates converted to the token layer
   -------------------------------------------------------------------------- */
.surface{background:var(--surface); color:var(--text)}
.surface-sunk{background:var(--sunk)}
.hairline{border-color:var(--line)}

/* Two-tier dividers for grouped lists (e.g. the checklist list's Overdue /
   In Progress / Completed sections): the line between groups should read
   heavier than the line between rows within a group. */
.divide-section{border-top:2px solid var(--line-strong)}
.divide-y-soft > * + *{border-top:1px solid color-mix(in srgb, var(--line) 45%, var(--surface))}


/* --------------------------------------------------------------------------
   7. LEGACY UTILITY BRIDGE
   Most templates still style themselves with raw Tailwind neutrals and
   pastels. Rather than edit all 103, these map those utilities onto the
   current palette, so the whole app follows the user's choice -- not just
   the handful of screens converted to tokens.

   The `:root ` prefix is doing real work: the Tailwind CDN injects its
   utilities into the document AFTER this stylesheet, so a bare `.bg-white`
   here would lose the tie on source order. `:root .bg-white` wins on
   specificity instead, which keeps !important out of the file.

   This section should SHRINK as templates move to the token layer.
   -------------------------------------------------------------------------- */

/* Surfaces */
:root .bg-white{background-color:var(--surface)}
:root .bg-gray-50,
:root .bg-gray-100,
:root .bg-slate-50,
:root .bg-primary-50{background-color:var(--sunk)}
/* gray-200 is used for progress-bar tracks and toggle-off states, so it has
   to stay visible against BOTH the surface and the sunk ground -- --raised is
   the same white as the card in the light palettes and made tracks vanish. */
:root .bg-gray-200,
:root .bg-gray-300{background-color:var(--line)}

/* Text */
:root .text-gray-900,
:root .text-gray-800{color:var(--text)}
:root .text-gray-700,
:root .text-gray-600{color:var(--text-2)}
:root .text-gray-500,
:root .text-gray-400{color:var(--text-3)}

/* One edge language: a hairline in the palette's own line colour */
:root .border-gray-100,
:root .border-gray-200,
:root .border-gray-300{border-color:var(--line)}
:root .divide-gray-100 > * + *,
:root .divide-gray-200 > * + *{border-color:var(--line)}
:root .ring-gray-900\/5,
:root .ring-gray-100,
:root .ring-gray-200,
:root .ring-gray-300,
:root .ring-primary-100{--tw-ring-color:var(--line)}

/* Form controls */
/* Checkboxes and radios are excluded: painting a background on a native
   control can suppress the browser's own checkmark, and the checklist fill
   screen depends on those being unmistakable. */
:root input:not([type="checkbox"]):not([type="radio"]),
:root select,
:root textarea{background-color:var(--surface); color:var(--text); border-color:var(--line-strong)}
:root input::placeholder,
:root textarea::placeholder{color:var(--text-3)}

/* Legacy semantic tints map onto the state ramp, so an unconverted screen
   says the same thing as a converted one -- and stops glowing pastel in the
   dark palette. Fill and ink always move together so contrast holds. */
:root .bg-red-50,
:root .bg-red-100{background-color:var(--st-late-fill)}
:root .text-red-600,
:root .text-red-700,
:root .text-red-800{color:var(--st-late-ink)}

:root .bg-green-50,
:root .bg-green-100{background-color:var(--st-done-fill)}
:root .text-green-600,
:root .text-green-700,
:root .text-green-800{color:var(--st-done-ink)}

:root .bg-yellow-50,
:root .bg-yellow-100,
:root .bg-amber-50,
:root .bg-amber-100{background-color:var(--st-hold-fill)}
:root .text-yellow-600,
:root .text-yellow-700,
:root .text-yellow-800,
:root .text-amber-700,
:root .text-amber-800{color:var(--st-hold-ink)}

:root .bg-blue-50,
:root .bg-blue-100{background-color:var(--st-open-fill)}
:root .text-blue-600,
:root .text-blue-700,
:root .text-blue-800{color:var(--st-open-ink)}

/* --------------------------------------------------------------------------
   8. FLATTENING THE GRADIENTS
   Decorative gradients were the most dated thing in the interface, and they
   dodged the palette entirely -- a pastel tile stayed pastel on a dark
   ground because a gradient sets background-image, not background-color.
   -------------------------------------------------------------------------- */

/* Pastel icon tiles (bg-gradient-to-br from-*-100 to-*-50) */
:root .bg-gradient-to-br{background-image:none; background-color:var(--sunk)}

/* The brand-gradient primary button, used in 44 places. Solid brand instead,
   with brand-ink for the label: white text would drop to ~2.5:1 on the
   lighter brand blue the dark palette uses. */
:root .bg-gradient-to-r.from-primary-600{
  background-image:none;
  background-color:var(--brand);
  color:var(--brand-ink);
}
:root .bg-gradient-to-r.from-primary-600:hover{filter:brightness(1.08)}

/* --------------------------------------------------------------------------
   9. NAVIGATION
   The sidebar's active and hover states were pinned to static Tailwind blues,
   which drift off-hue once the nav ground follows the palette. Scoped to
   .nav-surface so nothing else in the app is affected.
   -------------------------------------------------------------------------- */
.nav-surface{background:var(--nav)}
.nav-surface .bg-primary-800{background-color:rgb(255 255 255 / .12)}
.nav-surface a:hover{background-color:rgb(255 255 255 / .07)}
.nav-surface .border-accent-300{border-color:var(--brand-2)}
.nav-surface .text-accent-300{color:var(--brand-2)}
.nav-surface .text-primary-100{color:rgb(255 255 255 / .76)}
.nav-surface .text-primary-200,
.nav-surface .text-primary-300{color:rgb(255 255 255 / .55)}

/* --------------------------------------------------------------------------
   10. THE SETTING PILL
   Active / Inactive is not a stage. It has no direction and no order of
   loudness, so it stays out of the state ramp -- otherwise a green check
   would mean both "this checklist is finished" and "this account is switched
   on", and the ramp stops being worth reading at a glance.

   Shape carries the distinction: state chips are square-cut (3px), settings
   are fully rounded.

   Active is also the quiet one. In a list of forty locations where thirty-nine
   are on, marking the norm spends ink to say nothing; the one that is OFF is
   what somebody is scanning for.
   -------------------------------------------------------------------------- */
.pill{
  display:inline-flex; align-items:center; gap:6px; flex:none;
  padding:2px 10px 2px 8px; border-radius:var(--r-pill);
  font-size:12px; font-weight:var(--w-ui-strong); line-height:1.45;
  white-space:nowrap; border:1px solid transparent;
}
.pill::before{content:""; width:7px; height:7px; border-radius:50%; flex:none}

/* on -- the expected state, minimal ink */
.pill-on{color:var(--text-3)}
.pill-on::before{background:var(--text-3)}

/* off -- the exception worth spotting; marked, but not an error */
.pill-off{color:var(--text); background:var(--sunk); border-color:var(--line-strong)}
.pill-off::before{background:transparent; box-shadow:inset 0 0 0 2px var(--text-2)}

/* --------------------------------------------------------------------------
   11. WEATHER
   Weather is neither brand nor state, so it gets its own two values rather
   than borrowing from the state ramp -- warm red there means overdue, and a
   hot day is not an overdue day. Used in exactly one place: the direction of
   the year-on-year comparison on the dashboard.
   -------------------------------------------------------------------------- */
/* Applied to the arrow only. Tinting the whole phrase put a near-red block of
   text beside the Overdue chips, and the ramp allows exactly one loud thing. */
.wx-warm{color:var(--wx-warm)}
.wx-cool{color:var(--wx-cool)}
.wx-arrow{display:inline-block; width:0; height:0; vertical-align:.08em; margin-right:.28em}
.wx-arrow-up{border-left:.3em solid transparent; border-right:.3em solid transparent; border-bottom:.42em solid currentColor}
.wx-arrow-down{border-left:.3em solid transparent; border-right:.3em solid transparent; border-top:.42em solid currentColor}
