:root {
  /* Surface Colors — Silent Curator cool-toned surfaces.
     Three-tier hierarchy with deliberate spacing so users can tell
     page canvas apart from secondary surfaces apart from raised cards:
       bg        #d7e2ea  — the canvas (darkest of the light tones)
       surface   #e8f0f6  — secondary (status banners, inline inputs)
       raised    #ffffff  — primary cards, modals, sidebar panels
       high      #c9d7e0  — emphasized / selected surfaces
     Previously bg and surface were 5 RGB apart (both near-white) so
     surface-backed elements blended into the page. Now bg is darker
     and surface sits BETWEEN bg and white. */
  --theme-bg: #d7e2ea;
  --theme-bg-rgb: 215 226 234;
  --theme-surface: #e8f0f6;
  --theme-surface-rgb: 232 240 246;
  --theme-surface-raised: #ffffff;
  --theme-surface-raised-rgb: 255 255 255;
  --theme-surface-high: #c9d7e0;
  --theme-surface-high-rgb: 201 215 224;

  /* Border — previously 15% opacity which made cards vanish in light mode.
     Bumped to 40% (and darker base gray) for clearly-defined card edges
     while still feeling soft, not harsh. Dark mode keeps its own override
     in `html.dark` below. */
  --theme-border: rgba(120, 130, 145, 0.25);
  --theme-border-rgb: 120 130 145;
  --theme-border-strong: rgba(120, 130, 145, 0.45);

  /* Text */
  --theme-text: #161d1f;
  --theme-text-rgb: 22 29 31;
  --theme-text-subtle: #3a3d44;
  --theme-text-subtle-rgb: 58 61 68;
  /* Muted darkened from #606874 → #525968 so it clears WCAG AA on the
     new darker page bg (#d7e2ea). Previously 4.27:1; now ~5.1:1. */
  --theme-muted: #525968;
  --theme-muted-rgb: 82 89 104;

  /* Primary — Deep Navy */
  --theme-primary: #051125;
  --theme-primary-rgb: 5 17 37;
  --theme-on-primary: #ffffff;

  /* Primary Container */
  --theme-primary-container: #1b263b;
  --theme-primary-container-rgb: 27 38 59;

  /* Secondary — Teal */
  --theme-secondary: #25686a;
  --theme-secondary-rgb: 37 104 106;

  /* Tertiary — Burnished amber (accessible on light surfaces: 5.1:1 on surface, 5.7:1 on white)
     Note: #e9c176 bright gold is only accessible as TEXT on dark surfaces (see dark mode).
     Use --theme-tertiary for text/borders; --theme-energy for decorative bg fills only. */
  --theme-tertiary: #8b5e00;
  --theme-tertiary-rgb: 139 94 0;

  /* Semantic Colors */
  --theme-success: #25686a;
  --theme-success-rgb: 37 104 106;
  --theme-warning: #b45309;
  --theme-warning-rgb: 180 83 9;
  --theme-danger: #b91c1c;
  --theme-danger-rgb: 185 28 28;
  --theme-on-danger: #ffffff;
  --theme-info: #1d4ed8;
  --theme-info-rgb: 37 99 235;
  --theme-energy: #e9c176; /* decorative fills ONLY — never use as text in light mode */
  --theme-energy-rgb: 233 193 118;

  /* Shadows — Navy-tinted ambient shadows */
  --theme-shadow-sm: 0 2px 8px rgba(5, 17, 37, 0.04);
  --theme-shadow-md: 0 8px 24px rgba(5, 17, 37, 0.06);
  --theme-shadow-lg: 0 20px 40px rgba(5, 17, 37, 0.08);
  --theme-shadow-float: 0 6px 20px rgba(5, 17, 37, 0.06);
  --theme-shadow-drawer: 22px 0 44px rgba(5, 17, 37, 0.08);
  --theme-shadow-soft: 0 6px 18px rgba(5, 17, 37, 0.05);
  --theme-shadow-strong: 0 16px 40px rgba(5, 17, 37, 0.1);

  /* Overlays */
  --theme-overlay-light: rgba(255, 255, 255, 0.05);
  --theme-overlay-dark: rgba(5, 17, 37, 0.04);
  --theme-overlay-scrim: rgba(5, 17, 37, 0.5);
  --theme-overlay: rgba(5, 17, 37, 0.6);

  /* Motion */
  --theme-motion-fast: 0.1s;
  --theme-motion-normal: 0.15s;
  --theme-motion-slow: 0.22s;
  --theme-motion-ease: cubic-bezier(0.25, 1, 0.5, 1);
  --theme-motion-ease-out: ease-out;
  --theme-motion-ease-in: ease-in;

  /* Spacing Tokens.
     `page-x` and `section-y` tighten on small screens so content takes
     the full width on phones. Previous fixed 1.5rem left a huge gutter
     on mobile. CSS clamp scales with viewport. */
  --space-page-x: clamp(0.75rem, 1vw + 0.5rem, 1.5rem);
  --space-section-y: clamp(1rem, 1.5vw + 0.5rem, 2rem);
  --space-card-padding: 1.25rem;
  --space-header-height: 4rem;

  /* Primary alpha variants.
     MUST use modern `rgb(R G B / A)` slash syntax because our
     `--theme-primary-rgb` stores values space-separated (required by
     Tailwind's `rgb(var(--x) / <alpha-value>)` pattern). The older
     `rgba(var(--x), 0.4)` form is invalid when `--x` is `R G B` (space
     separated), producing `rgba(R G B, 0.4)` which Chrome rejects and
     falls back to preflight. That broke every border/bg that used
     these variables (we lost the CSV button border this way). */
  --theme-primary-10: rgb(var(--theme-primary-rgb) / 0.1);
  --theme-primary-12: rgb(var(--theme-primary-rgb) / 0.12);
  --theme-primary-14: rgb(var(--theme-primary-rgb) / 0.14);
  --theme-primary-15: rgb(var(--theme-primary-rgb) / 0.15);
  --theme-primary-16: rgb(var(--theme-primary-rgb) / 0.16);
  --theme-primary-20: rgb(var(--theme-primary-rgb) / 0.2);
  --theme-primary-24: rgb(var(--theme-primary-rgb) / 0.24);
  --theme-primary-28: rgb(var(--theme-primary-rgb) / 0.28);
  --theme-primary-30: rgb(var(--theme-primary-rgb) / 0.3);
  --theme-primary-35: rgb(var(--theme-primary-rgb) / 0.35);
  --theme-primary-40: rgb(var(--theme-primary-rgb) / 0.4);
  --theme-primary-46: rgb(var(--theme-primary-rgb) / 0.46);
}

html.dark {
  /* Surface Colors — Deep navy layered surfaces */
  --theme-bg: #0a1628;
  --theme-bg-rgb: 10 22 40;
  --theme-surface: #111f35;
  --theme-surface-rgb: 17 31 53;
  --theme-surface-raised: #1a2d48;
  --theme-surface-raised-rgb: 26 45 72;
  --theme-surface-high: #0d192b;
  --theme-surface-high-rgb: 13 25 43;

  /* Border — Ghost borders (50% opacity, blue-tinted) */
  --theme-border: rgba(42, 63, 90, 0.5);
  --theme-border-rgb: 42 63 90;
  --theme-border-strong: rgba(90, 108, 130, 0.55);

  /* Text */
  --theme-text: #c8d4dc;
  --theme-text-rgb: 200 212 220;
  --theme-text-subtle: #7a8a95;
  --theme-text-subtle-rgb: 122 138 149;
  --theme-muted: #7489a0;
  --theme-muted-rgb: 116 137 160;

  /* Primary — Gold in dark mode */
  --theme-primary: #e9c176;
  --theme-primary-rgb: 233 193 118;
  --theme-on-primary: #0a1628;

  /* Primary Container */
  --theme-primary-container: #d4a85a;
  --theme-primary-container-rgb: 212 168 90;

  /* Secondary — Bright Teal */
  --theme-secondary: #4dd4b6;
  --theme-secondary-rgb: 77 212 182;

  /* Tertiary — Gold (same) */
  --theme-tertiary: #e9c176;
  --theme-tertiary-rgb: 233 193 118;

  /* Semantic Colors — brighter on dark */
  --theme-success: #4dd4b6;
  --theme-success-rgb: 77 212 182;
  --theme-warning: #fbbf24;
  --theme-warning-rgb: 251 191 36;
  --theme-danger: #f87171;
  --theme-danger-rgb: 248 113 113;
  --theme-on-danger: #0a1628;
  --theme-info: #93c5fd;
  --theme-info-rgb: 147 197 253;
  --theme-energy: #e9c176;
  --theme-energy-rgb: 233 193 118;

  /* Shadows — stronger for dark surfaces */
  --theme-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.25);
  --theme-shadow-md: 0 8px 24px rgba(0, 0, 0, 0.3);
  --theme-shadow-lg: 0 20px 40px rgba(0, 0, 0, 0.35);
  --theme-shadow-float: 0 6px 20px rgba(0, 0, 0, 0.3);
  --theme-shadow-drawer: 22px 0 44px rgba(0, 0, 0, 0.35);
  --theme-shadow-soft: 0 8px 22px rgba(0, 0, 0, 0.2);
  --theme-shadow-strong: 0 16px 40px rgba(0, 0, 0, 0.35);

  /* Overlays — in dark mode, "light" overlay brightens (lifts) elements */
  --theme-overlay-light: rgba(255, 255, 255, 0.03);
  --theme-overlay-dark: rgba(255, 255, 255, 0.05);
  --theme-overlay-scrim: rgba(0, 0, 0, 0.7);
  --theme-overlay: color-mix(in oklch, var(--theme-bg) 82%, black);

  /* Spacing Tokens remain same for both themes */
}

/* Typography scale (same for both themes) */
:root,
html.dark {
  --type-display: clamp(2.5rem, 1.5rem + 2.5vw, 3.5rem);
  --type-title-1: clamp(1.875rem, 1.45rem + 1.2vw, 2.5rem);
  --type-title-2: clamp(1.375rem, 1.15rem + 0.8vw, 1.9rem);
  --type-title-3: clamp(1.125rem, 1rem + 0.45vw, 1.4rem);
  --type-body: 1rem;
  --type-label: 0.875rem;
  --type-caption: 0.75rem;
  --type-micro: 0.6875rem;
}

/* Component tokens */
:root,
html.dark {
  --comp-disabled-opacity: 0.5;
  --comp-focus-ring: 0 0 0 2px rgb(var(--theme-primary-rgb) / 0.2);
  --comp-focus-border: rgb(var(--theme-primary-rgb) / 0.5);
  --comp-radius-interactive: 0.5rem; /* rounded-lg — buttons, inputs, badges */
  --comp-radius-container: 0.75rem; /* rounded-xl — cards, panels, modals */
  --comp-hover-overlay: rgb(var(--theme-primary-rgb) / 0.05);
}

/* Silent Curator — Gradient CTA
   Shadow glows are now primary-derived via `rgb(var(--theme-primary-rgb)/X)`
   instead of hardcoded navy+gold. That lets any future palette or theme
   override propagate to the button halo automatically (Phase 1 audit fix —
   was previously two hardcoded rgba() values that clashed with warm
   palettes and any non-navy primary). Dark mode keeps the extra black
   shadow layer for grounded weight on the deep-navy canvas. */
.bg-gradient-primary {
  background: linear-gradient(
    135deg,
    var(--theme-primary),
    var(--theme-primary-container)
  );
  box-shadow:
    0 1px 2px rgb(var(--theme-primary-rgb) / 0.22),
    0 8px 22px rgb(var(--theme-primary-rgb) / 0.22),
    inset 0 1px 0 rgba(255, 255, 255, 0.12);
}
.bg-gradient-primary:hover {
  box-shadow:
    0 2px 4px rgb(var(--theme-primary-rgb) / 0.28),
    0 12px 30px rgb(var(--theme-primary-rgb) / 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.16);
}
html.dark .bg-gradient-primary {
  box-shadow:
    0 2px 6px rgba(0, 0, 0, 0.3),
    0 8px 22px rgb(var(--theme-primary-rgb) / 0.22),
    inset 0 1px 0 rgba(255, 255, 255, 0.12);
}
html.dark .bg-gradient-primary:hover {
  box-shadow:
    0 4px 10px rgba(0, 0, 0, 0.35),
    0 12px 30px rgb(var(--theme-primary-rgb) / 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.16);
}

/* Silent Curator — Glassmorphism */
.glass {
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}

/* Silent Curator — Ambient shadow utilities */
.shadow-ambient {
  box-shadow: var(--theme-shadow-md);
}
.shadow-ambient-lg {
  box-shadow: var(--theme-shadow-lg);
}

/* Silent Curator — Ghost border */
.border-ghost {
  border-color: var(--theme-border);
}

/* Component helper classes using theme tokens */
.text-primary {
  color: var(--theme-primary) !important;
}
.bg-primary {
  background-color: var(--theme-primary) !important;
}
.border-primary {
  border-color: var(--theme-primary) !important;
}

/* Primary alpha variants now work natively via Tailwind rgb() + <alpha-value> */

button.bg-primary,
a.bg-primary,
input.bg-primary,
[role="button"].bg-primary {
  color: var(--theme-on-primary) !important;
}

/* Semantic danger text — adapts to theme (white on dark-red, navy on light-red) */
.text-on-danger {
  color: var(--theme-on-danger) !important;
}

/* Global interactive element transitions */
button,
a,
input,
select,
textarea,
[role="button"] {
  transition:
    color var(--theme-motion-fast) var(--theme-motion-ease),
    background-color var(--theme-motion-fast) var(--theme-motion-ease),
    border-color var(--theme-motion-fast) var(--theme-motion-ease),
    box-shadow var(--theme-motion-fast) var(--theme-motion-ease),
    opacity var(--theme-motion-fast) var(--theme-motion-ease);
}

/* Icon size utilities — replace inline style="font-size:Npx" */
.icon-12 {
  font-size: 12px;
}
.icon-13 {
  font-size: 13px;
}
.icon-14 {
  font-size: 14px;
}
.icon-15 {
  font-size: 15px;
}
.icon-16 {
  font-size: 16px;
}
.icon-18 {
  font-size: 18px;
}
.icon-20 {
  font-size: 20px;
}
.icon-24 {
  font-size: 24px;
}
.icon-32 {
  font-size: 32px;
}
.icon-48 {
  font-size: 48px;
}

/* Focus-visible ring for keyboard navigation (both themes) */
:focus-visible {
  outline: 2px solid var(--theme-primary);
  outline-offset: 2px;
}

/* ===========================================================================
   UI Audit Hygiene Fixes — migrated from /ui/light sandbox on 2026-04-15.
   Applies globally (both light and dark), affects every page that loads
   theme-tokens.css. See docs/UI_AUDIT_FIXES.md for the full catalog.
   =========================================================================== */

/* Card separation — every main card gets a 1px border so surfaces never melt
   into the page bg. Uses the palette-aware border token. */
.bg-surface.rounded-xl,
.bg-surface-raised.rounded-xl,
section.bg-surface,
#logs-card {
  border: 1px solid var(--theme-border);
}

/* `.card-inset-primary` used to add a 3px inset stripe on the left edge of
   the Scraper Configuration card. With the full 4-side outline above, the
   stripe reads as a redundant outline. Neutralize it back to the ambient
   shadow so the card matches all the others. */
.card-inset-primary {
  box-shadow: var(--theme-shadow-md) !important;
}

/* Toggle OFF track: the production Tailwind class chain uses
   `bg-surface-raised` which is identical to the card color in light mode →
   the track vanishes when the toggle is off. Force it to `surface-high` +
   a ghost outline so ON vs OFF is clearly readable. */
input.sr-only.peer:not(:checked) + div {
  background-color: var(--theme-surface-high) !important;
  box-shadow: inset 0 0 0 1px var(--theme-border-strong);
}
input.sr-only.peer:not(:checked) + div::after {
  background-color: var(--theme-surface-raised) !important;
  box-shadow: 0 0 0 1px var(--theme-border-strong);
}

/* Native checkboxes (not the sr-only Tailwind toggle peer): add a subtle
   inset ring when unchecked so the box reads as a distinct control on
   both light and dark surfaces. */
input[type="checkbox"]:not(.sr-only):not(:checked) {
  box-shadow: inset 0 0 0 1px var(--theme-border-strong);
  border-radius: 4px;
}

/* Disabled buttons — the previous `disabled:opacity-50 disabled:cursor-not-allowed`
   Tailwind pair alone washed accent colors into the card on light palettes.
   Bump opacity slightly and drop any grayscale filter so the accent color
   remains recognizable (users can still tell the button is disabled by the
   opacity drop, cursor change, and interaction blocking). */
button:disabled,
button[disabled],
[aria-disabled="true"] {
  opacity: 0.55 !important;
  filter: none;
}

/* Bulk-action chips (AI Enhance / Shopify / Merge / Delete / Delete All):
   bump the Tailwind `/10` bg and `/20` border to 14% and 40% so the chips
   carry visible accent color even when disabled. Also pin Delete's text
   color to `danger` so it reads correctly when `--theme-danger` is
   overridden per palette. */
#ai-enhance-selected-btn,
#merge-selected-btn {
  background: rgb(var(--theme-info-rgb) / 0.14) !important;
  border-color: rgb(var(--theme-info-rgb) / 0.4) !important;
}
#shopify-upload-btn {
  background: rgb(var(--theme-primary-rgb) / 0.14) !important;
  border-color: rgb(var(--theme-primary-rgb) / 0.4) !important;
}
#delete-selected-btn,
#delete-all-btn {
  background: rgb(var(--theme-danger-rgb) / 0.14) !important;
  border-color: rgb(var(--theme-danger-rgb) / 0.4) !important;
  color: var(--theme-danger) !important;
}

/* `@tailwindcss/forms` inserts its own SVG chevron on every <select> via
   `background-image`, even when the element has `appearance-none` and the
   template overlays a custom Material `expand_more` icon → two stacked
   arrows. Strip the plugin's background-image on any select the developer
   has explicitly set to appearance-none. */
select.appearance-none,
select[class*="appearance-none"] {
  background-image: none !important;
}
