/* ==========================================================================
   MUNGARU — design tokens for the TSS floor app
   The Totagars' Co-Operative Sale Society Ltd., Sirsi

   This file is the single source of truth for the app's visual identity.
   Link it FIRST, before any other stylesheet. Spec and measured contrast
   ratios: docs/design/01-identity.md.

   Structure:
     1. Primitives  — raw values, prefixed --_ , never used in app CSS
     2. Semantics   — the light theme, defined on bare :root
     3. Dark theme  — remaps semantics only, twice (media query + attribute)
     4. Kernel      — reset, base type, focus, money utility, reduced motion

   Theme contract: OS preference applies via prefers-color-scheme; an explicit
   data-theme="light"|"dark" on <html> wins in BOTH directions. The two dark
   blocks below are intentionally identical — if you touch one, mirror it.
   Every hex in this file lives in section 1, so no colour is ever defined
   only inside a media query or a [data-theme] block.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. PRIMITIVES (private — reference only from section 2/3 mappings)
   -------------------------------------------------------------------------- */
:root {
  /* Neutrals. Two ramps: "mist" (light, a faint green cast — morning mist
     over the gardens) and "canopy" (green-tinted darks — wet evergreen).
     Pure grey looks dead next to the working ramps; the green cast is small
     enough to stay out of the way of the money greens.
     Pivot: canopy-900 is BOTH the light theme's text ink and the dark
     theme's card surface — the two themes are joined at that value. */
  --_white:       #FFFFFF;
  --_mist-100:    #F2F5F2;  /* light ground */
  --_mist-200:    #E6EBE6;  /* light sunken wells */
  --_mist-300:    #C8D2C9;  /* light hairline rule */
  --_canopy-100:  #E9EEEA;  /* dark ink */
  --_canopy-200:  #B6C2B9;
  --_canopy-300:  #8FA095;
  --_canopy-400:  #79887E;  /* light strong rule — darkest value that still
                               reads as a line, ≥3:1 on mist and white */
  --_canopy-500:  #66756B;  /* dark strong rule — ≥3:1 on both dark surfaces */
  --_canopy-600:  #5A6A60;
  --_canopy-700:  #3F4D45;
  --_canopy-800:  #2A362F;
  --_canopy-850:  #1F2C25;
  --_canopy-900:  #16211B;  /* the pivot */
  --_canopy-950:  #0E1713;  /* dark ground */
  --_canopy-1000: #0A100D;

  /* Rain — the accent. Monsoon-slate blue. Blue because the working colours
     of money own green, red and amber outright; the accent must never be
     mistakable for a money state. */
  --_rain-100: #E2EEF6;
  --_rain-200: #B7DCF2;
  --_rain-300: #8CC4E6;  /* dark-theme accent: 8.8:1+ as text, and as a fill
                            it makes buttons the brightest thing in a dim aisle */
  --_rain-700: #1C5A7F;  /* light-theme accent: white on it is 7.45:1 (AAA) */
  --_rain-800: #164863;  /* pressed fill, light (white on it 9.81:1) */
  --_rain-900: #123B52;
  --_rain-950: #132937;  /* selection wash, dark */

  /* Money ramps. AAA (>=7:1) is the floor for every money-on-background pair,
     verified against ground, surface AND the ramp's own wash in both themes.
     -700 = light-theme text, -300 = dark-theme text, -100/-900 = washes. */
  --_leaf-100:     #E6F6EC;  /* leaf: areca frond green — credit, money in   */
  --_leaf-300:     #7FD9A2;
  --_leaf-700:     #0B5B2F;
  --_leaf-900:     #12301F;
  --_laterite-100: #FCEAE7;  /* laterite: the district's red stone — debit,
                                shortfall, danger. NOT KHATA's lacquer red.  */
  --_laterite-300: #FFA198;
  --_laterite-700: #971D1B;
  --_laterite-900: #3A1714;
  --_husk-100:     #F7F0DE;  /* husk: drying-yard amber — pending (UPI wait),
                                surplus variance, warnings                    */
  --_husk-300:     #F1C46A;
  --_husk-700:     #6E4900;
  --_husk-900:     #332A12;

  /* Chart series. Tuned under simulated protanopia/deuteranopia until the
     worst same-theme pair beats the Okabe-Ito benchmark; hue pairs that
     collapse for red-green blindness are separated by lightness instead.
     Use strictly in order; every mark is >=3:1 on its theme's ground & card. */
  --_chart-1-l: #24587B;  --_chart-1-d: #63ACD8;  /* rain     */
  --_chart-2-l: #A87400;  --_chart-2-d: #EBB54E;  /* husk     */
  --_chart-3-l: #10715A;  --_chart-3-d: #46C79C;  /* leaf     */
  --_chart-4-l: #4A2545;  --_chart-4-d: #F6D2EE;  /* orchid   */
  --_chart-5-l: #8C3312;  --_chart-5-d: #C65D33;  /* laterite */
  --_chart-6-l: #708595;  --_chart-6-d: #75848F;  /* slate    */
}

/* --------------------------------------------------------------------------
   2. SEMANTICS — light theme, the default, on bare :root
   -------------------------------------------------------------------------- */
:root {
  color-scheme: light;

  /* Surfaces. Light theme builds height with shadow on white; the sunken
     well is for things content sits IN (scan tray, search field zone). */
  --bg:             var(--_mist-100);
  --surface:        var(--_white);
  --surface-raised: var(--_white);      /* + shadow; same colour by design */
  --surface-sunken: var(--_mist-200);
  --scrim:          rgb(10 16 13 / 0.55);

  /* Ink. --ink is AAA on every surface above (13.7:1 worst case).
     --ink-faint is AA — helper text only, never money, never mid-task
     reading. */
  --ink:       var(--_canopy-900);
  --ink-mute:  var(--_canopy-700);
  --ink-faint: var(--_canopy-600);

  /* Rules. Hairline divides; strong rule outlines things a user must FIND
     (inputs, table frames) and is measured >=3:1 on the surfaces it borders. */
  --rule:        var(--_mist-300);
  --rule-strong: var(--_canopy-400);

  /* Accent */
  --accent:       var(--_rain-700);
  --on-accent:    var(--_white);
  --accent-press: var(--_rain-800);
  --accent-wash:  var(--_rain-100);   /* selected row / active tab bg.
                                         Never put money figures on this wash:
                                         credit/pending drop below 7:1 here. */
  --focus:        var(--_rain-700);

  /* Money. AAA everywhere it is allowed to sit (see identity doc §2).
     Washes are chip/row tints; each money colour is AAA on its OWN wash. */
  --money-credit:       var(--_leaf-700);
  --money-credit-wash:  var(--_leaf-100);
  --money-debit:        var(--_laterite-700);
  --money-debit-wash:   var(--_laterite-100);
  --money-pending:      var(--_husk-700);
  --money-pending-wash: var(--_husk-100);

  /* Variance: green ONLY at exactly zero. Surplus is a counting error, so
     "over" is amber — the system never congratulates cash that shouldn't
     exist. */
  --variance-zero:  var(--_leaf-700);
  --variance-over:  var(--_husk-700);
  --variance-short: var(--_laterite-700);

  /* General status (non-monetary). Same ramps, so hue meaning stays
     consistent app-wide; every status also gets an icon and a word. */
  --ok:          var(--_leaf-700);
  --on-ok:       var(--_white);
  --ok-wash:     var(--_leaf-100);
  --warn:        var(--_husk-700);
  --warn-wash:   var(--_husk-100);
  --danger:      var(--_laterite-700);
  --danger-wash: var(--_laterite-100);
  --info:        var(--_rain-700);
  --info-wash:   var(--_rain-100);

  /* Charts (Admin/Accounts only — never in cashier or guard flows) */
  --chart-1: var(--_chart-1-l);
  --chart-2: var(--_chart-2-l);
  --chart-3: var(--_chart-3-l);
  --chart-4: var(--_chart-4-l);
  --chart-5: var(--_chart-5-l);
  --chart-6: var(--_chart-6-l);

  /* Elevation. Canopy-tinted, never pure black — reads as depth, not dirt. */
  --shadow-1: 0 1px 2px rgb(14 23 19 / 0.10);
  --shadow-2: 0 2px 6px rgb(14 23 19 / 0.12), 0 1px 2px rgb(14 23 19 / 0.08);
  --shadow-3: 0 8px 24px rgb(14 23 19 / 0.16), 0 2px 6px rgb(14 23 19 / 0.10);

  /* ---- Type ----
     One stack for both scripts, on purpose: no per-language CSS exists, so
     no CSS can rank Kannada below English. system-ui covers Latin everywhere
     and Kannada on Android; the named faces catch iOS and Windows. */
  --font-ui: system-ui, -apple-system, "Segoe UI", Roboto,
             "Noto Sans Kannada", "Kannada Sangam MN", "Nirmala UI", "Tunga",
             "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  /* 16px body floor: read at arm's length while walking; iOS zooms focused
     inputs under 16px (which would wreck every scan); Kannada conjuncts
     close up below 16px before Latin suffers. The floor protects the harder
     script. */
  --fs-meta:    0.8125rem;  /* 13px — meta only; never money, never the sole
                               carrier of Kannada content */
  --fs-body:    1rem;       /* 16px */
  --fs-lead:    1.125rem;   /* 18px — emphasised rows, line-item amounts */
  --fs-title:   1.375rem;   /* 22px */
  --fs-head:    1.75rem;    /* 28px — bill total in the flow */
  --fs-total:   2.25rem;    /* 36px — the amount asked of the customer */
  --fs-display: 3rem;       /* 48px — guard screen, read at a metre */

  /* 400/600/700 only. No 300: thin strokes die in doorway glare. 600 is the
     one emphasis weight (system Kannada faces synthesise heavier weights);
     700 is for money totals and display digits, which are ASCII. */
  --w-regular: 400;
  --w-strong:  600;
  --w-heavy:   700;

  /* Leading is set for Kannada's stacked vowel signs and conjuncts; Latin
     just gets air. Never tighter than these per size class. */
  --lh-body:    1.6;
  --lh-title:   1.35;
  --lh-display: 1.2;

  /* ---- Space / radius / borders ---- */
  --sp-0: 2px;
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 48px;
  --sp-8: 64px;

  --r-xs:   4px;    /* tags */
  --r-sm:   8px;    /* buttons, inputs */
  --r-md:   12px;   /* cards */
  --r-lg:   16px;   /* bottom sheets */
  --r-full: 999px;  /* pills */

  --bw-hair:   1px;
  --bw-strong: 2px;

  /* ---- Touch ----
     Damp/greasy fingers report a smeared centroid and walking adds aim
     error; 48px (~9mm) is the floor so a bad press still lands, 56-64px so
     the rush-hour verbs land WITHOUT looking. The 8px gap makes a smeared
     press resolve to the nearer target, not the wrong one. */
  --tap-min:     48px;  /* every interactive element, no exceptions */
  --tap-primary: 56px;  /* scan / add / charge */
  --tap-anchor:  64px;  /* the single bottom thumb-bar action */
  --tap-gap:     8px;

  /* ---- Motion ----
     Motion is a receipt, not a show: it only confirms a press, a content
     swap (HTMX partials), or a sheet. Durations are short because a queue
     is watching. Easings are named for their job, not their curve. */
  --dur-press: 80ms;    /* pressed-state feedback */
  --dur-swap:  160ms;   /* htmx partial swap fade */
  --dur-sheet: 240ms;   /* bottom sheets, drawers — the longest we ever take */
  --ease-press:  cubic-bezier(0.2, 0, 0, 1);      /* state flips: fast, settled */
  --ease-arrive: cubic-bezier(0.05, 0.7, 0.1, 1); /* entering: decelerate in   */
  --ease-leave:  cubic-bezier(0.3, 0, 0.8, 0.15); /* exiting: get out quickly  */

  /* ---- Layers ---- */
  --z-bar:   10;   /* sticky thumb bar */
  --z-sheet: 20;
  --z-toast: 30;
}

/* --------------------------------------------------------------------------
   3. DARK THEME — remaps semantics only; both blocks are IDENTICAL twins.
   Block A: OS prefers dark and no explicit light choice overrides it.
   Block B: explicit data-theme="dark" wins even when the OS prefers light.
   -------------------------------------------------------------------------- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    /* Height is a surface step in the dark — shadows barely read on #0E1713,
       so raised things get a lighter room, not a bigger shadow. */
    --bg:             var(--_canopy-950);
    --surface:        var(--_canopy-900);
    --surface-raised: var(--_canopy-850);
    --surface-sunken: var(--_canopy-1000);
    --scrim:          rgb(0 0 0 / 0.6);

    --ink:       var(--_canopy-100);
    --ink-mute:  var(--_canopy-200);
    --ink-faint: var(--_canopy-300);

    --rule:        var(--_canopy-800);
    --rule-strong: var(--_canopy-500);

    /* Buttons invert: light fill, dark text — the brightest object in a dim
       aisle is the one the thumb is looking for. */
    --accent:       var(--_rain-300);
    --on-accent:    var(--_canopy-950);
    --accent-press: var(--_rain-200);
    --accent-wash:  var(--_rain-950);
    --focus:        var(--_rain-300);

    --money-credit:       var(--_leaf-300);
    --money-credit-wash:  var(--_leaf-900);
    --money-debit:        var(--_laterite-300);
    --money-debit-wash:   var(--_laterite-900);
    --money-pending:      var(--_husk-300);
    --money-pending-wash: var(--_husk-900);

    --variance-zero:  var(--_leaf-300);
    --variance-over:  var(--_husk-300);
    --variance-short: var(--_laterite-300);

    --ok:          var(--_leaf-300);
    --on-ok:       var(--_canopy-950);
    --ok-wash:     var(--_leaf-900);
    --warn:        var(--_husk-300);
    --warn-wash:   var(--_husk-900);
    --danger:      var(--_laterite-300);
    --danger-wash: var(--_laterite-900);
    --info:        var(--_rain-300);
    --info-wash:   var(--_rain-950);

    --chart-1: var(--_chart-1-d);
    --chart-2: var(--_chart-2-d);
    --chart-3: var(--_chart-3-d);
    --chart-4: var(--_chart-4-d);
    --chart-5: var(--_chart-5-d);
    --chart-6: var(--_chart-6-d);

    /* Kept so components referencing shadows don't break; the surface step
       above is what actually communicates height here. */
    --shadow-1: 0 1px 2px rgb(0 0 0 / 0.45);
    --shadow-2: 0 2px 6px rgb(0 0 0 / 0.50), 0 1px 2px rgb(0 0 0 / 0.35);
    --shadow-3: 0 8px 24px rgb(0 0 0 / 0.55), 0 2px 6px rgb(0 0 0 / 0.40);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;

  /* Height is a surface step in the dark — shadows barely read on #0E1713,
     so raised things get a lighter room, not a bigger shadow. */
  --bg:             var(--_canopy-950);
  --surface:        var(--_canopy-900);
  --surface-raised: var(--_canopy-850);
  --surface-sunken: var(--_canopy-1000);
  --scrim:          rgb(0 0 0 / 0.6);

  --ink:       var(--_canopy-100);
  --ink-mute:  var(--_canopy-200);
  --ink-faint: var(--_canopy-300);

  --rule:        var(--_canopy-800);
  --rule-strong: var(--_canopy-500);

  /* Buttons invert: light fill, dark text — the brightest object in a dim
     aisle is the one the thumb is looking for. */
  --accent:       var(--_rain-300);
  --on-accent:    var(--_canopy-950);
  --accent-press: var(--_rain-200);
  --accent-wash:  var(--_rain-950);
  --focus:        var(--_rain-300);

  --money-credit:       var(--_leaf-300);
  --money-credit-wash:  var(--_leaf-900);
  --money-debit:        var(--_laterite-300);
  --money-debit-wash:   var(--_laterite-900);
  --money-pending:      var(--_husk-300);
  --money-pending-wash: var(--_husk-900);

  --variance-zero:  var(--_leaf-300);
  --variance-over:  var(--_husk-300);
  --variance-short: var(--_laterite-300);

  --ok:          var(--_leaf-300);
  --on-ok:       var(--_canopy-950);
  --ok-wash:     var(--_leaf-900);
  --warn:        var(--_husk-300);
  --warn-wash:   var(--_husk-900);
  --danger:      var(--_laterite-300);
  --danger-wash: var(--_laterite-900);
  --info:        var(--_rain-300);
  --info-wash:   var(--_rain-950);

  --chart-1: var(--_chart-1-d);
  --chart-2: var(--_chart-2-d);
  --chart-3: var(--_chart-3-d);
  --chart-4: var(--_chart-4-d);
  --chart-5: var(--_chart-5-d);
  --chart-6: var(--_chart-6-d);

  /* Kept so components referencing shadows don't break; the surface step
     above is what actually communicates height here. */
  --shadow-1: 0 1px 2px rgb(0 0 0 / 0.45);
  --shadow-2: 0 2px 6px rgb(0 0 0 / 0.50), 0 1px 2px rgb(0 0 0 / 0.35);
  --shadow-3: 0 8px 24px rgb(0 0 0 / 0.55), 0 2px 6px rgb(0 0 0 / 0.40);
}

/* --------------------------------------------------------------------------
   4. KERNEL — reset, base, focus, money, reduced motion
   -------------------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
}

html {
  /* Stop mobile browsers "helpfully" inflating text — the scale is designed. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* We draw our own pressed states with --dur-press; the grey OS flash on
     top of them reads as jank. */
  -webkit-tap-highlight-color: transparent;
}

body {
  font-family: var(--font-ui);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  background: var(--bg);         /* explicit — never inherit a host ground */
  color: var(--ink);
  min-height: 100dvh;
}

img,
svg,
video,
canvas {
  display: block;
  max-width: 100%;
}

/* Form controls inherit the bilingual stack — otherwise Kannada input text
   falls back to a browser default face and the two scripts stop matching. */
button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
}

button {
  background: none;
  border: none;
  cursor: pointer;
  touch-action: manipulation;    /* kill the 300ms double-tap wait on scans */
}

/* Native widgets (checkboxes, radios, progress) pick up the theme accent. */
:root {
  accent-color: var(--accent);
}

/* Focus: one loud ring, same recipe both themes. --focus is measured >=3:1
   against both grounds. Keyboard/scanner-wedge focus only — pointer taps
   don't leave rings behind on a hurried screen. */
:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}
:focus:not(:focus-visible) {
  outline: none;
}

::selection {
  background: var(--accent-wash);
}

/* Money. Non-negotiable: every monetary figure is tabular so columns align
   and totals scan vertically; lining figures so digits sit level with
   Kannada and Latin text alike. Apply to every element that renders an
   amount. Colour comes from the money tokens, never from --ink-mute/faint. */
.money {
  font-variant-numeric: tabular-nums lining-nums;
}

/* Reduced motion: the identity's motion is only ever confirmation, so
   removing it loses nothing. Durations collapse rather than zero out so
   transitionend/animationend handlers (htmx swaps) still fire. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-press: 1ms;
    --dur-swap:  1ms;
    --dur-sheet: 1ms;
  }
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
}
