/* ===========================================================================
   IDHOME design tokens — v2 (post-redesign)

   Direction: Restrained (Linear × Stripe Dashboard).
     - Tinted neutrals (cool blue undertone, low chroma 0.005–0.015)
     - One user-selectable accent ≤10% of surface
     - prefers-color-scheme auto with manual override
     - User-configurable: theme, accent, font family, density

   Data-attribute switches (read by inline script in base.html before
   first paint to prevent FOUC):

     html[data-theme="auto"|"light"|"dark"]   (default "auto")
     html[data-accent="brand-red"|"indigo"|"emerald"|"slate"]  (default "brand-red")
     html[data-font="plex"|"line"|"noto"]     (default "plex")
     html[data-density="comfortable"|"compact"]  (default "comfortable")

   All tokens use OKLCH. Shadows kept low-key (Restrained); rely on borders
   and surface separation instead of drop shadows for hierarchy.

   Class namespace: `ui-*`. All component styles live in
   components.css and app-shell.css; this file is tokens only.
   =========================================================================== */

/* ---------- 1. Color primitives — light theme (default) ---------- */

:root,
html[data-theme="light"] {
  /* Neutral ramp — cool blue undertone (hue 250). Chroma kept ≤0.014 so
     neutrals never read as colored. */
  --bg:           oklch(98.5% 0.005 250);
  --bg-elev:      #ffffff;
  --bg-sunken:    oklch(96% 0.006 250);

  --surface:      #ffffff;
  --surface-2:    oklch(97.5% 0.006 250);
  --surface-3:    oklch(95% 0.008 250);

  --border:       oklch(91% 0.008 250);
  --border-strong: oklch(83% 0.010 250);
  --divider:      oklch(94% 0.007 250);

  /* Text ramp — verified ≥4.5:1 against --bg.
     text: 16.4:1 · text-secondary: 7.8:1 · text-muted: 4.8:1 */
  --text:           oklch(22% 0.014 250);
  --text-secondary: oklch(42% 0.012 250);
  --text-muted:     oklch(55% 0.010 250);
  --text-disabled:  oklch(72% 0.008 250);
  --text-inverse:   #ffffff;

  /* Sidebar is dark in both themes — distinct from content surface.
     Slightly cooler than light neutrals. */
  --nav-bg:         oklch(20% 0.018 252);
  --nav-bg-hover:   oklch(26% 0.020 252);
  --nav-bg-active:  oklch(30% 0.022 252);
  --nav-text:       oklch(85% 0.008 252);
  --nav-text-muted: oklch(62% 0.010 252);
  --nav-text-active: #ffffff;
  --nav-border:     oklch(28% 0.018 252);

  /* Status colors — paired soft (background) + strong (text on soft).
     Hue spacing chosen so adjacent badges remain distinguishable. */
  --success:        oklch(54% 0.15 158);
  --success-soft:   oklch(95% 0.04 158);
  --warning:        oklch(70% 0.16 75);
  --warning-strong: oklch(46% 0.16 75);
  --warning-soft:   oklch(96% 0.06 75);
  --danger:         oklch(55% 0.21 25);
  --danger-soft:    oklch(95% 0.05 25);
  /* `--on-danger` — text/icon colour for use directly on `--danger`
     fills (primary destructive buttons). White-on-red works in both
     themes so the value doesn't need a dark-mode override below. */
  --on-danger:      oklch(99% 0 0);
  --info:           oklch(56% 0.16 240);
  --info-soft:      oklch(95% 0.04 240);

  /* Shadows — kept low. Restrained design uses borders + surface for
     hierarchy; shadows reserved for transient elements (popover, modal). */
  --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.04);
  --shadow-md: 0 2px 6px rgba(15, 23, 42, 0.06), 0 1px 3px rgba(15, 23, 42, 0.04);
  --shadow-lg: 0 8px 24px rgba(15, 23, 42, 0.08), 0 2px 6px rgba(15, 23, 42, 0.04);
  --shadow-xl: 0 24px 48px rgba(15, 23, 42, 0.12);

  /* Scrollbar — themed thumb + transparent track for content surfaces.
     Sidebar overrides these with dark-friendly variants in app-shell.css. */
  --sb-thumb:       oklch(80% 0.010 250);
  --sb-thumb-hover: oklch(65% 0.012 250);
  --sb-track:       transparent;
  --sb-size:        10px;
}

/* ---------- 2. Dark theme override ---------- */

html[data-theme="dark"] {
  --bg:           oklch(13% 0.012 252);
  --bg-elev:      oklch(16% 0.014 252);
  --bg-sunken:    oklch(10% 0.010 252);

  --surface:      oklch(17% 0.014 252);
  --surface-2:    oklch(20% 0.016 252);
  --surface-3:    oklch(24% 0.018 252);

  --border:       oklch(28% 0.016 252);
  --border-strong: oklch(36% 0.018 252);
  --divider:      oklch(24% 0.014 252);

  --text:           oklch(96% 0.006 250);
  --text-secondary: oklch(74% 0.010 250);
  --text-muted:     oklch(58% 0.010 250);
  --text-disabled:  oklch(42% 0.010 250);

  --nav-bg:         oklch(10% 0.010 252);
  --nav-bg-hover:   oklch(15% 0.014 252);
  --nav-bg-active:  oklch(20% 0.018 252);
  --nav-text:       oklch(78% 0.008 252);
  --nav-text-muted: oklch(56% 0.010 252);
  --nav-border:     oklch(20% 0.014 252);

  /* Dark status softs — chroma reduced so they don't glow on dark bg. */
  --success-soft:   oklch(24% 0.06 158);
  --warning-soft:   oklch(26% 0.07 75);
  --warning-strong: oklch(82% 0.16 75);
  --danger-soft:    oklch(26% 0.08 25);
  --info-soft:      oklch(24% 0.06 240);

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.30);
  --shadow-md: 0 2px 6px rgba(0, 0, 0, 0.35), 0 1px 3px rgba(0, 0, 0, 0.25);
  --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.45), 0 2px 6px rgba(0, 0, 0, 0.25);
  --shadow-xl: 0 24px 48px rgba(0, 0, 0, 0.55);

  --sb-thumb:       oklch(38% 0.014 252);
  --sb-thumb-hover: oklch(52% 0.014 252);
}

/* ---------- 3. Auto theme — follow OS prefers-color-scheme ----------
   Applied only when no explicit data-theme is set (the inline script
   in base.html leaves data-theme unset when the user picked 'auto'). */

html[data-theme="auto"] {
  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  html[data-theme="auto"] {
    --bg:           oklch(13% 0.012 252);
    --bg-elev:      oklch(16% 0.014 252);
    --bg-sunken:    oklch(10% 0.010 252);
    --surface:      oklch(17% 0.014 252);
    --surface-2:    oklch(20% 0.016 252);
    --surface-3:    oklch(24% 0.018 252);
    --border:       oklch(28% 0.016 252);
    --border-strong: oklch(36% 0.018 252);
    --divider:      oklch(24% 0.014 252);
    --text:           oklch(96% 0.006 250);
    --text-secondary: oklch(74% 0.010 250);
    --text-muted:     oklch(58% 0.010 250);
    --text-disabled:  oklch(42% 0.010 250);
    --nav-bg:         oklch(10% 0.010 252);
    --nav-bg-hover:   oklch(15% 0.014 252);
    --nav-bg-active:  oklch(20% 0.018 252);
    --nav-text:       oklch(78% 0.008 252);
    --nav-text-muted: oklch(56% 0.010 252);
    --nav-border:     oklch(20% 0.014 252);
    --success-soft:   oklch(24% 0.06 158);
    --warning-soft:   oklch(26% 0.07 75);
    --warning-strong: oklch(82% 0.16 75);
    --danger-soft:    oklch(26% 0.08 25);
    --info-soft:      oklch(24% 0.06 240);
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.30);
    --shadow-md: 0 2px 6px rgba(0, 0, 0, 0.35), 0 1px 3px rgba(0, 0, 0, 0.25);
    --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.45), 0 2px 6px rgba(0, 0, 0, 0.25);
    --shadow-xl: 0 24px 48px rgba(0, 0, 0, 0.55);
    --sb-thumb:       oklch(38% 0.014 252);
    --sb-thumb-hover: oklch(52% 0.014 252);
  }
}

/* ---------- 4. Accent — user selectable via data-accent ----------
   Default brand-red (IDHOME identity). Each accent ships a solid value,
   a hover variant, and a soft tint used by `.ui-badge.accent`, selected
   nav, etc. */

:root,
html[data-accent="brand-red"] {
  --accent:        oklch(56% 0.21 25);   /* approx #E30613 */
  --accent-hover:  oklch(48% 0.21 25);
  --accent-soft:   oklch(95% 0.05 25);
  --accent-ring:   oklch(56% 0.21 25 / 0.30);
  --accent-on:     #ffffff;
}

html[data-accent="indigo"] {
  --accent:        oklch(54% 0.18 268);
  --accent-hover:  oklch(46% 0.18 268);
  --accent-soft:   oklch(95% 0.04 268);
  --accent-ring:   oklch(54% 0.18 268 / 0.30);
  --accent-on:     #ffffff;
}

html[data-accent="emerald"] {
  --accent:        oklch(50% 0.14 165);
  --accent-hover:  oklch(42% 0.14 165);
  --accent-soft:   oklch(94% 0.04 165);
  --accent-ring:   oklch(50% 0.14 165 / 0.30);
  --accent-on:     #ffffff;
}

html[data-accent="slate"] {
  --accent:        oklch(28% 0.012 250);
  --accent-hover:  oklch(20% 0.012 250);
  --accent-soft:   oklch(93% 0.006 250);
  --accent-ring:   oklch(28% 0.012 250 / 0.30);
  --accent-on:     #ffffff;
}

/* Accent softs need a dark-theme override (saturation-bumped + chroma-
   reduced so they read as tinted background, not glow). */
html[data-theme="dark"] {
  --accent-soft: color-mix(in oklab, var(--accent) 22%, oklch(20% 0.016 252));
}
@media (prefers-color-scheme: dark) {
  html[data-theme="auto"] {
    --accent-soft: color-mix(in oklab, var(--accent) 22%, oklch(20% 0.016 252));
  }
}

/* ---------- 5. Typography — font family switch via data-font ----------
   Defaults to IBM Plex Sans Thai. Web fonts loaded in base.html via
   Google Fonts; system fallbacks cover the transition period. */

:root,
html[data-font="plex"] {
  --font-sans: "IBM Plex Sans Thai", "IBM Plex Sans Thai Looped",
               "Sukhumvit Set", "Noto Sans Thai", system-ui, -apple-system,
               "Segoe UI", sans-serif;
}

html[data-font="line"] {
  --font-sans: "LINE Seed Sans TH", "Sukhumvit Set", "IBM Plex Sans Thai",
               system-ui, -apple-system, sans-serif;
}

html[data-font="noto"] {
  --font-sans: "Noto Sans Thai", "Sukhumvit Set", "IBM Plex Sans Thai",
               system-ui, -apple-system, sans-serif;
}

:root {
  /* Mono pairs with the chosen sans. Plex Mono goes with Plex Sans Thai;
     for LINE/Noto we fall back to JetBrains Mono. */
  --font-mono: "JetBrains Mono", "IBM Plex Mono", ui-monospace,
               SFMono-Regular, Menlo, monospace;
}

html[data-font="plex"] {
  --font-mono: "IBM Plex Mono", "JetBrains Mono", ui-monospace,
               SFMono-Regular, Menlo, monospace;
}

/* ---------- 6. Type scale — fixed rem, 1.18 ratio (product register) ---- */

:root {
  /* comfortable default */
  --font-xs:    11px;   /* legal / overline */
  --font-sm:    12.5px; /* secondary, small labels */
  --font-base:  13.5px; /* body, table cells, inputs */
  --font-md:    15px;   /* h3, lead */
  --font-lg:    17px;   /* h2 */
  --font-xl:    21px;   /* h1 */
  --font-2xl:   28px;   /* hero / dashboard title */

  --leading-tight: 1.2;
  --leading-snug:  1.35;
  --leading-base:  1.55;
  --leading-loose: 1.7;

  --tracking-tight:  -0.012em;
  --tracking-normal:  0;
  --tracking-wide:    0.04em;
  --tracking-overline: 0.08em;
}

html[data-density="compact"] {
  --font-xs:    10.5px;
  --font-sm:    12px;
  --font-base:  12.5px;
  --font-md:    14px;
  --font-lg:    16px;
  --font-xl:    19px;
  --font-2xl:   24px;
}

/* ---------- 7. Spacing scale — 4px base ---------- */

:root {
  --space-1:  4px;
  --space-2:  8px;
  --space-3:  12px;
  --space-4:  16px;
  --space-5:  20px;
  --space-6:  24px;
  --space-8:  32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;
  --space-20: 80px;

  /* Semantic spacing aliases */
  --gap-sm: var(--space-2);
  --gap:    var(--space-4);
  --gap-lg: var(--space-6);
  --gap-xl: var(--space-8);

  --pad-sm: var(--space-3);
  --pad:    var(--space-4);
  --pad-lg: var(--space-6);
}

html[data-density="compact"] {
  --gap-sm: var(--space-2);
  --gap:    var(--space-3);
  --gap-lg: var(--space-4);
  --gap-xl: var(--space-6);

  --pad-sm: var(--space-2);
  --pad:    var(--space-3);
  --pad-lg: var(--space-4);
}

/* ---------- 8. Radii — Linear-sharp (6px base) ---------- */

:root {
  --r-xs:   3px;
  --r-sm:   5px;
  --r:      6px;     /* default — Linear-flavor */
  --r-md:   8px;
  --r-lg:   10px;
  --r-xl:   14px;
  --r-pill: 999px;
}

/* ---------- 9. Heights ---------- */

:root {
  --h-input:   38px;
  --h-input-lg: 44px;
  --h-input-sm: 30px;
  --h-row:     44px;
  --h-row-compact: 36px;
}

/* Touch-target floor on phones / small tablets. Bumping the token here
   cascades to every consumer (.ui-btn, .ui-input, .ui-select, .ui-input-
   with-icon, .ui-daterange-input, etc.) so the whole form vocabulary
   grows together — no per-component overrides needed. The defaults at
   the top stay desktop-density. */
@media (max-width: 720px) {
  :root {
    --h-input:    44px;     /* Apple HIG 44pt */
    --h-input-lg: 52px;     /* primary CTA — release complete, login */
    --h-input-sm: 36px;     /* table-action / inline chips */
  }
}

html[data-density="compact"] {
  --h-input: 34px;
  --h-input-sm: 28px;
  --h-row: 36px;
}

/* ---------- 10. Z-stack ---------- */

:root {
  --z-base:        1;
  --z-sticky:      10;
  --z-fab:         30;
  --z-drawer-bg:   35;
  --z-drawer:      40;
  --z-dropdown:    50;
  --z-modal-bg:    60;
  --z-modal:       70;
  --z-toast:       80;
  --z-tooltip:     90;
}

/* ---------- 11. Motion ---------- */

:root {
  --dur-fast:   100ms;
  --dur-base:   150ms;   /* Linear-grade transitions */
  --dur-slow:   250ms;
  --ease-out:   cubic-bezier(0.16, 1, 0.30, 1);  /* ease-out-expo-ish */
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-fast: 0.01ms;
    --dur-base: 0.01ms;
    --dur-slow: 0.01ms;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------- 12. Base reset ---------- */

*,
*::before,
*::after { box-sizing: border-box; }

html {
  font-size: 16px;
  -webkit-text-size-adjust: 100%;
  height: auto;
  min-height: 100%;
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--font-base);
  line-height: var(--leading-base);
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: "cv11", "ss01", "kern";
  font-kerning: normal;
  height: auto;
  min-height: 100vh;
  /* Prevent accidental text selection on UI chrome; content cells
     re-enable below. */
  user-select: none;
}

input, textarea, select, button {
  font: inherit;
  color: inherit;
}

/* Allow selection in content surfaces (form fields, table cells,
   monospace identifiers users actually copy). */
input, textarea, select,
.mono, code, pre,
.ui-table tbody td:not(.ui-cell-actions),
.ui-kv .v,
[data-selectable] {
  user-select: text;
}

a {
  color: var(--accent);
  text-decoration: none;
  text-underline-offset: 2px;
  transition: color var(--dur-fast) var(--ease-out);
}
a:hover { color: var(--accent-hover); text-decoration: underline; }
a:focus-visible {
  outline: 2px solid var(--accent-ring);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}

h1, h2, h3, h4 { margin: 0; line-height: var(--leading-tight); }
p { margin: 0; }

code, .mono, [data-mono] {
  font-family: var(--font-mono);
  font-variant-ligatures: none;
}

::selection { background: var(--accent-soft); color: var(--text); }

/* Form field native overrides — fix the Safari/Chrome default chrome
   so our inputs don't flicker between native and themed look. */
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; }

/* ---------- 13. Utility primitives (sparing) ---------- */

.mono     { font-family: var(--font-mono); }
.muted    { color: var(--text-muted); }
.tnum     { font-variant-numeric: tabular-nums; }
.nowrap   { white-space: nowrap; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ---------- 14. Scrollbars ----------

   Modern browsers default to invisible or inconsistent scrollbars:
   - macOS hides them entirely outside scroll gestures (overlay style)
   - Chrome/Edge on Windows ships a chunky default chrome
   - Firefox uses platform defaults too

   We standardise across the portal: thin scrollbars, themed thumb,
   transparent track. Two layers:
     1. Firefox + modern Chromium read `scrollbar-width` + `scrollbar-color`
     2. WebKit/older Chromium read `::-webkit-scrollbar*` pseudo-elements

   Defaults apply to html, body, and any descendant. Sidebar nav and
   in-app-shell scroll containers override the thumb color so the
   dark sidebar gets a contrast-correct scrollbar. */

* {
  scrollbar-width: thin;
  scrollbar-color: var(--sb-thumb) var(--sb-track);
}

*::-webkit-scrollbar {
  width: var(--sb-size);
  height: var(--sb-size);
}
*::-webkit-scrollbar-track {
  background: var(--sb-track);
}
*::-webkit-scrollbar-thumb {
  background: var(--sb-thumb);
  border-radius: 999px;
  /* 2px transparent border via background-clip = visual padding without
     reducing the hit area below recommended touch targets. */
  border: 2px solid transparent;
  background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover {
  background: var(--sb-thumb-hover);
  background-clip: padding-box;
}
*::-webkit-scrollbar-corner { background: transparent; }

/* Lucide icons — set sensible inline behavior so swapping
   `<i class="bi bi-...">` for `<i data-lucide="...">` is drop-in. */
[data-lucide] {
  display: inline-block;
  vertical-align: -2px;
  width: 1em;
  height: 1em;
  stroke-width: 2;
  flex-shrink: 0;
}

/* The Lucide init script swaps each <i data-lucide> for an inline <svg>.
   These rules apply once the swap has happened. */
svg.lucide {
  display: inline-block;
  vertical-align: -2px;
  width: 1em;
  height: 1em;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
  flex-shrink: 0;
}
