/* ==========================================================================
   LumiStore Web Admin — Slim Neutral Design System (macOS finish)

   The rose-tinted "liquid glass" skin is gone. What replaced it, and why:
   cool zinc neutrals with near-black text (every figure legible at a glance),
   flat white surfaces with hairline borders instead of tinted gradients (a
   pink wash under grey text is what made the old console read as blurry), the
   platform's own font (nothing to download, and the console looks native on
   the machine it is open on), and colour reserved for the brand accent and
   for status -- so when something IS red, it means something.

   Most of the old class names survive (glass-card, glass-input, btn-primary):
   the login page, core.js's modals and the first-paint skeletons all wear
   them, so the restyle happens here once rather than in every template.
   ========================================================================== */

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

:root {
  /* The platform's own faces: SF on a Mac, Segoe on Windows. Eight webfont
     downloads used to sit ahead of first paint on an HTTP/1.1 server; now
     zero do, and the console looks native wherever it is opened. */
  --font-sans: -apple-system, BlinkMacSystemFont, 'SF Pro Text', ui-sans-serif, system-ui, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --font-mono: ui-monospace, 'SF Mono', SFMono-Regular, 'Cascadia Mono', 'Segoe UI Mono', Menlo, Consolas, monospace;
  
  /* Brand Crimson / Rose Scale */
  --brand-50: #fff1f2;
  --brand-100: #ffe4e6;
  --brand-200: #fecdd3;
  --brand-300: #fda4af;
  --brand-400: #fb7185;
  --brand-500: #e11d48;
  --brand-600: #e50914;
  --brand-700: #be123c;
  --brand-800: #9f1239;
  --brand-900: #881337;
  
  /* Cool Neutral Surfaces (zinc, with a blue cast on the ground) */
  --pearl-bg: #f3f6fb;
  --pearl-surface: #f4f4f5;
  --pearl-elevated: #ffffff;
  
  /* The neutral scale, remapped cool and DARKER at the text steps.
     Half the console's text is text-stone-500/600 -- warm greys around 45%
     lightness on a pink wash, which is where "nothing is crystal clear" came
     from. These sit one shade darker than the standard scale, so the same
     markup gains a contrast step everywhere at once. tailwind.config.js
     remaps the compiled stone-* utilities to the same values. */
  --stone-950: #09090b;
  --stone-900: #101012;
  --stone-800: #1d1d20;
  --stone-700: #2e2e33;
  --stone-600: #44444b;
  --stone-500: #5b5b64;
  --stone-400: #82828c;
  --stone-300: #d4d4d8;
  --stone-200: #e4e4e7;
  --stone-100: #f4f4f5;
  --stone-50: #fafafa;
  
  /* Semantic Accent Palette */
  --emerald-600: #059669;
  --emerald-700: #047857;
  --emerald-800: #065f46;
  --emerald-50: #ecfdf5;
  
  --amber-600: #d97706;
  --amber-700: #b45309;
  --amber-800: #92400e;
  --amber-50: #fffbeb;
  
  --rose-600: #e11d48;
  --rose-700: #be123c;
  --rose-800: #9f1239;
  --rose-50: #fff1f2;

  --blue-600: #2563eb;
  --blue-700: #1d4ed8;
  --blue-50: #eff6ff;

  --indigo-600: #4f46e5;
  --indigo-700: #4338ca;
  --indigo-50: #eef2ff;
  
  /* Flat surfaces, hairline borders, neutral mac-subtle shadows. The old
     values were white-on-white gradients with rose-tinted glows; every border
     was either invisible (white on white) or pink. These are visible and
     colourless, which is what lets the content own the colour. */
  --liquid-glass-bg: #ffffff;
  --liquid-glass-panel: #ffffff;
  --liquid-glass-elevated: #ffffff;

  /* One step darker than zinc-200: hairlines vanished against the blue
     ground, and a card without an edge is a white blob. */
  --liquid-glass-border: #cfcfd6;
  --liquid-glass-border-subtle: #d7d7dd;
  --liquid-glass-border-hover: #a9a9b3;

  --liquid-glass-shadow-sm:
    0 1px 2px rgba(0, 0, 0, 0.05);

  --liquid-glass-shadow:
    0 1px 2px rgba(0, 0, 0, 0.05),
    0 1px 3px rgba(0, 0, 0, 0.04);

  --liquid-glass-shadow-hover:
    0 4px 12px rgba(0, 0, 0, 0.08),
    0 1px 3px rgba(0, 0, 0, 0.05);

  --liquid-glass-shadow-modal:
    0 24px 60px -12px rgba(0, 0, 0, 0.22),
    0 8px 20px -6px rgba(0, 0, 0, 0.10);

  /* Animation Easings */
  --ease-spring: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-smooth: cubic-bezier(0.4, 0, 0.2, 1);
}

html, body {
  height: 100%;
  font-family: var(--font-sans);
  background-color: var(--pearl-bg);
  /* Near-black body ink: the single biggest legibility change in the file. */
  color: var(--stone-900);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* Butter-Smooth Hardware Acceleration */
* {
  -webkit-tap-highlight-color: transparent;
}

button, a, input, select, textarea {
  transition: transform 0.15s var(--ease-smooth), opacity 0.15s ease, background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, color 0.15s ease;
}

button:focus-visible, input:focus-visible, select:focus-visible,
textarea:focus-visible, a:focus-visible, [role="button"]:focus-visible {
  outline: 3px solid rgba(225, 29, 72, 0.45);
  outline-offset: 2px;
}

button:disabled, [aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.55;
  pointer-events: none;
}

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

.brand-logo-img {
  width: 32px !important;
  height: 32px !important;
  max-width: 32px !important;
  max-height: 32px !important;
  object-fit: contain !important;
}

.brand-logo-login {
  width: 64px !important;
  height: 64px !important;
  max-width: 64px !important;
  max-height: 64px !important;
  object-fit: contain !important;
}

/* --------------------------------------------------------------------------
   Ambient Multi-Mesh Floor Lighting (GPU-Cached Static Refraction)
   -------------------------------------------------------------------------- */
.circuit-light-bg {
  /* Cool blue washes under the console. The content cards are opaque, so
     these never sit under body text -- they live in the page gaps and BEHIND
     the glass chrome, which is what makes the glass read as glass instead of
     as a slightly grey rectangle. Blue on purpose against the red accent:
     ambience and brand stay two different jobs. */
  background-color: var(--pearl-bg);
  background-image:
    radial-gradient(1200px 700px at 8% -10%, rgba(59, 130, 246, 0.38), transparent 62%),
    radial-gradient(1000px 560px at 96% 0%, rgba(14, 165, 233, 0.30), transparent 58%),
    radial-gradient(900px 560px at 35% 60%, rgba(96, 165, 250, 0.18), transparent 62%),
    radial-gradient(1200px 700px at 62% 114%, rgba(99, 102, 241, 0.30), transparent 62%);
  background-attachment: fixed;
}

/* The floor orbs are retired with the tint: painting three 500px blurred
   radials under every page bought nothing but GPU work and a pink cast. */
.ambient-glow { display: none; }

/* --------------------------------------------------------------------------
   Liquid Glass chrome

   Apple's treatment, applied where Apple applies it: the CHROME — the rail,
   the header, dialogs and drawers are translucent, blurred and slightly
   saturated, so the console reads as layers of glass over the content. The
   content surfaces themselves (cards, tables) stay opaque on purpose: body
   text over live blur is exactly the fog this redesign removed.
   -------------------------------------------------------------------------- */
[data-sidebar='sidebar']:not([data-mobile='true']) {
  background: hsl(var(--sidebar-background) / 0.55);
  -webkit-backdrop-filter: blur(20px) saturate(1.7);
  backdrop-filter: blur(20px) saturate(1.7);
}

/* The phone drawer stays SOLID: it slides over a dimmed page, and glass over
   a scrim reads as a murky grey wash -- which is exactly how it shipped for
   one screenshot before this rule. iOS sheets are near-opaque for the same
   reason. */
[data-sidebar='sidebar'][data-mobile='true'] {
  background: hsl(var(--sidebar-background));
}

/* --------------------------------------------------------------------------
   Liquid Glass Components (Polished, Ultra-Fast 60fps GPU Composited)
   -------------------------------------------------------------------------- */
.glass-panel {
  /* Chrome surfaces (header-like bars): translucent with blur, the one place
     the mac vibrancy effect earns its cost. */
  background: rgba(255, 255, 255, 0.82);
  -webkit-backdrop-filter: saturate(1.6) blur(14px);
  backdrop-filter: saturate(1.6) blur(14px);
  border-color: var(--liquid-glass-border-subtle);
}

.glass-card {
  background: var(--pearl-elevated);
  border: 1px solid var(--liquid-glass-border);
  box-shadow: var(--liquid-glass-shadow);
  border-radius: 0.75rem;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
  position: relative;
  contain: paint;
}

.glass-card-elevated {
  background: var(--pearl-elevated);
  border: 1px solid var(--liquid-glass-border);
  box-shadow: var(--liquid-glass-shadow);
  border-radius: 0.75rem;
  contain: paint;
}

.glass-card:hover {
  border-color: var(--liquid-glass-border-hover);
}

.glass-card-interactive {
  cursor: pointer;
  will-change: transform, box-shadow;
  transform: translateZ(0);
}

.glass-card-interactive:hover {
  border-color: var(--liquid-glass-border-hover);
  transform: translateY(-1px);
  box-shadow: var(--liquid-glass-shadow-hover);
}

.glass-card-interactive:active {
  transform: translateY(0) scale(0.99);
}

/* Glass Sheen Specular Overlay */
.glass-sheen {
  position: relative;
  overflow: hidden;
}

.glass-sheen::after {
  /* The specular overlay is retired: a white gradient over white content
     only ever lowered contrast. The class stays for the markup that wears it. */
  content: none;
}

/* --------------------------------------------------------------------------
   Shimmer & Skeleton Loading Engine (Zero Cumulative Layout Shift)
   -------------------------------------------------------------------------- */
@keyframes shimmerWave {
  0% { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}

.skeleton {
  background: linear-gradient(90deg, rgba(244, 244, 245, 0.9) 25%, rgba(228, 228, 231, 0.9) 50%, rgba(244, 244, 245, 0.9) 75%);
  background-size: 200% 100%;
  animation: shimmerWave 1.8s ease-in-out infinite;
  border-radius: 0.5rem;
  display: block;
}

.skeleton-text {
  height: 0.875rem;
  width: 100%;
  margin-bottom: 0.5rem;
}

.skeleton-circle {
  border-radius: 9999px;
}

/* --------------------------------------------------------------------------
   Form Controls (Sleek Glass Inputs, Dropdowns & Selects)
   -------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
   Form Controls (Sleek Glass Inputs, Dropdowns & Selects)
   -------------------------------------------------------------------------- */
.glass-input {
  background: var(--pearl-elevated);
  border: 1px solid var(--stone-300);
  color: var(--stone-900);
  font-family: inherit;
  font-size: 0.8125rem;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
  outline: none;
  border-radius: 0.5rem;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.glass-input:focus {
  border-color: var(--brand-500);
  box-shadow: 0 0 0 3px rgba(225, 29, 72, 0.15);
}

.glass-input::placeholder {
  color: var(--stone-400);
}

/* --------------------------------------------------------------------------
   Button System (Tactile, Silky & Micro-Interactive)
   -------------------------------------------------------------------------- */
.glass-btn {
  background: var(--pearl-elevated);
  border: 1px solid var(--stone-300);
  color: var(--stone-700);
  font-family: inherit;
  font-size: 0.8125rem;
  font-weight: 600;
  box-shadow: var(--liquid-glass-shadow-sm);
  cursor: pointer;
  outline: none;
  border-radius: 0.5rem;
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  transition: transform 0.12s ease-out, box-shadow 0.15s ease, border-color 0.15s ease, background-color 0.15s ease, color 0.15s ease;
  position: relative;
}

.glass-btn:hover {
  background: var(--stone-100);
  border-color: var(--liquid-glass-border-hover);
  color: var(--stone-900);
}

.glass-btn:active {
  transform: scale(0.98);
}

.glass-btn:disabled {
  background: var(--stone-100);
  border-color: var(--stone-200);
  color: var(--stone-400);
  box-shadow: none;
  transform: none;
}

.btn-primary {
  /* Solid brand, no gradient, no glow: the accent carries the weight now that
     nothing else on the page is pink. */
  background: var(--brand-500);
  color: #ffffff;
  font-family: inherit;
  font-size: 0.8125rem;
  font-weight: 600;
  border: 1px solid transparent;
  border-radius: 0.5rem;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
  cursor: pointer;
  outline: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  transition: transform 0.12s ease-out, background-color 0.15s ease, box-shadow 0.15s ease, opacity 0.15s ease;
  position: relative;
}

.btn-primary:hover {
  background: var(--brand-700);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.18);
}

.btn-primary:active {
  transform: scale(0.98);
}

.btn-primary:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
}

.btn-secondary {
  background: #ffffff;
  border: 1px solid rgba(225, 29, 72, 0.2);
  border-top: 1px solid #ffffff;
  color: var(--stone-700);
  font-family: inherit;
  font-size: 0.875rem;
  font-weight: 600;
  border-radius: 0.75rem;
  padding: 0.5rem 1rem;
  cursor: pointer;
  outline: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  box-shadow: var(--liquid-glass-shadow-sm);
  transition: transform 0.15s var(--ease-spring), border-color 0.15s ease, background-color 0.15s ease, color 0.15s ease;
}

.btn-secondary:hover {
  background: #fff1f2;
  border-color: rgba(225, 29, 72, 0.38);
  color: var(--brand-600);
  transform: translateY(-1px);
}

.btn-secondary:active {
  transform: scale(0.975);
}

.btn-danger {
  background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
  color: #ffffff;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-top: 1px solid rgba(255, 255, 255, 0.6);
  font-family: inherit;
  font-size: 0.875rem;
  font-weight: 700;
  border-radius: 0.75rem;
  padding: 0.5rem 1rem;
  cursor: pointer;
  outline: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  box-shadow: 0 4px 14px rgba(220, 38, 38, 0.3);
  transition: transform 0.15s var(--ease-spring), box-shadow 0.15s ease;
}

.btn-danger:hover {
  background: linear-gradient(135deg, #f87171 0%, #ef4444 100%);
  box-shadow: 0 6px 20px rgba(220, 38, 38, 0.42);
  transform: translateY(-1px);
}

.btn-danger:active {
  transform: scale(0.975);
}

.btn-success {
  background: linear-gradient(135deg, #10b981 0%, #059669 100%);
  color: #ffffff;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-top: 1px solid rgba(255, 255, 255, 0.6);
  font-family: inherit;
  font-size: 0.875rem;
  font-weight: 700;
  border-radius: 0.75rem;
  padding: 0.5rem 1rem;
  cursor: pointer;
  outline: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  box-shadow: 0 4px 14px rgba(5, 150, 105, 0.3);
  transition: transform 0.15s var(--ease-spring), box-shadow 0.15s ease;
}

.btn-success:hover {
  background: linear-gradient(135deg, #34d399 0%, #10b981 100%);
  box-shadow: 0 6px 20px rgba(5, 150, 105, 0.42);
  transform: translateY(-1px);
}

.btn-success:active {
  transform: scale(0.975);
}

/* --------------------------------------------------------------------------
   Segmented Filter Controls & Preset Pills
   -------------------------------------------------------------------------- */
.filter-pill {
  padding: 0.45rem 0.9rem;
  border-radius: 0.75rem;
  font-size: 0.8125rem;
  font-weight: 700;
  cursor: pointer;
  outline: none;
  border: 1px solid transparent;
  background: transparent;
  color: var(--stone-600);
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  white-space: nowrap;
}

.filter-pill:hover {
  color: var(--brand-600);
  background: rgba(255, 241, 242, 0.8);
}

.filter-pill.active {
  background: var(--brand-500);
  color: #ffffff;
  border-color: rgba(255, 255, 255, 0.3);
  box-shadow: 0 3px 12px rgba(225, 29, 72, 0.32), inset 0 1px 1px rgba(255, 255, 255, 0.4);
}

/* --------------------------------------------------------------------------
   Navigation Buttons & Sidebar Refinements
   -------------------------------------------------------------------------- */
.nav-btn {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.65rem 0.85rem;
  border-radius: 0.85rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--stone-600);
  background: transparent;
  border: 1px solid transparent;
  cursor: pointer;
  text-align: left;
  outline: none;
  position: relative;
  transition: transform 0.15s var(--ease-spring), background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.nav-btn svg, .nav-btn i {
  width: 1.25rem;
  height: 1.25rem;
  flex-shrink: 0;
  transition: transform 0.15s var(--ease-spring), color 0.15s ease;
}

.nav-btn:hover {
  color: var(--brand-600);
  background: rgba(255, 241, 242, 0.92);
  transform: translateX(2px);
}

.nav-btn:hover svg, .nav-btn:hover i {
  transform: scale(1.1);
  color: var(--brand-600);
}

.nav-btn.active {
  color: var(--brand-600);
  background: linear-gradient(135deg, rgba(255, 228, 230, 0.98) 0%, rgba(255, 241, 242, 0.88) 100%);
  border: 1px solid rgba(225, 29, 72, 0.28);
  border-top: 1px solid #ffffff;
  box-shadow: 0 3px 12px -1px rgba(225, 29, 72, 0.2), inset 0 1px 1px #ffffff;
  font-weight: 700;
}

.nav-btn.active::before {
  content: '';
  position: absolute;
  left: 0;
  top: 18%;
  bottom: 18%;
  width: 4px;
  border-radius: 0 4px 4px 0;
  background: var(--brand-500);
  box-shadow: 0 0 12px rgba(225, 29, 72, 0.7);
}

/* Sidebar Collapsed State */
#main-sidebar.collapsed {
  width: 5rem;
}
#main-sidebar.collapsed .sidebar-label {
  display: none;
}
#main-sidebar.collapsed .nav-btn {
  justify-content: center;
  padding-left: 0;
  padding-right: 0;
}

/* --------------------------------------------------------------------------
   High-Contrast Legible Tables (Frosted Glass Table)
   -------------------------------------------------------------------------- */
.glass-table {
  border-collapse: separate;
  border-spacing: 0;
  width: 100%;
}

.glass-table th {
  background: rgba(255, 245, 245, 0.96);
  border-bottom: 1.5px solid rgba(225, 29, 72, 0.16);
  font-size: 0.75rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--brand-900);
  padding: 0.85rem 1rem;
  text-align: left;
  position: sticky;
  top: 0;
  z-index: 10;
}

.glass-table td {
  padding: 0.85rem 1rem;
  border-bottom: 1px solid rgba(225, 29, 72, 0.07);
  font-size: 0.875rem;
  color: var(--stone-800);
  transition: background-color 0.1s ease;
}

.glass-table tbody tr {
  transition: background-color 0.1s ease;
}

.glass-table tbody tr:hover {
  background: rgba(255, 241, 242, 0.75);
}

.glass-table tbody tr:last-child td {
  border-bottom: none;
}

/* --------------------------------------------------------------------------
   Status Badges (Jewel Tone Glass Pills)
   -------------------------------------------------------------------------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.25rem 0.7rem;
  border-radius: 9999px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.025em;
  text-transform: uppercase;
  border-width: 1px;
  border-style: solid;
  line-height: 1.25;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
}

.badge-dot {
  width: 0.45rem;
  height: 0.45rem;
  border-radius: 9999px;
}

.badge-success {
  background: var(--emerald-50);
  border-color: rgba(5, 150, 105, 0.32);
  color: var(--emerald-700);
}
.badge-success .badge-dot {
  background: var(--emerald-600);
  box-shadow: 0 0 6px rgba(5, 150, 105, 0.6);
}

.badge-warning {
  background: var(--amber-50);
  border-color: rgba(217, 119, 6, 0.32);
  color: var(--amber-700);
}
.badge-warning .badge-dot {
  background: var(--amber-600);
  box-shadow: 0 0 6px rgba(217, 119, 6, 0.6);
}

.badge-danger {
  background: var(--rose-50);
  border-color: rgba(225, 29, 72, 0.32);
  color: var(--rose-700);
}
.badge-danger .badge-dot {
  background: var(--rose-600);
  box-shadow: 0 0 6px rgba(225, 29, 72, 0.6);
}

.badge-info {
  background: #f0f9ff;
  border-color: rgba(14, 165, 233, 0.32);
  color: #0369a1;
}
.badge-info .badge-dot {
  background: #0284c7;
  box-shadow: 0 0 6px rgba(2, 132, 199, 0.6);
}

.badge-neutral {
  background: var(--stone-100);
  border-color: rgba(120, 113, 108, 0.25);
  color: var(--stone-600);
}
.badge-neutral .badge-dot {
  background: var(--stone-500);
}

/* --------------------------------------------------------------------------
   Modals & Drawers (Ultra-Smooth Spring Animation)
   -------------------------------------------------------------------------- */
.glass-modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.75rem;
  overflow-y: auto;
  background: rgba(0, 0, 0, 0.35);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  animation: fadeIn 0.12s var(--ease-smooth);
}

.glass-modal {
  width: 100%;
  max-height: calc(100vh - 2.5rem);
  display: flex;
  flex-direction: column;
  background: color-mix(in srgb, var(--pearl-elevated) 88%, transparent);
  -webkit-backdrop-filter: blur(24px) saturate(1.6);
  backdrop-filter: blur(24px) saturate(1.6);
  border: 1px solid var(--liquid-glass-border);
  box-shadow: var(--liquid-glass-shadow-modal);
  border-radius: 0.75rem;
  /* Scrolls itself rather than clipping. The max-height above is what keeps a
     modal on screen, and with overflow:hidden a form taller than the viewport
     simply lost its bottom -- Save included -- on a phone in landscape or any
     short window. Modals that carry their own flex-1 scrolling body absorb the
     overflow before this ever engages, so they are unaffected. */
  overflow-y: auto;
  overscroll-behavior: contain;
  margin: auto;
  animation: modalScaleUp 0.18s var(--ease-spring);
  transform: translateZ(0);
}

/* Slide-in Side Drawer */
.glass-drawer-backdrop {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: rgba(24, 21, 20, 0.45);
  display: flex;
  justify-content: flex-end;
  animation: fadeIn 0.12s var(--ease-smooth);
}

.glass-drawer {
  width: 100%;
  max-width: 580px;
  height: 100%;
  background: #ffffff;
  border-left: 1px solid rgba(225, 29, 72, 0.18);
  box-shadow: -12px 0 45px rgba(225, 29, 72, 0.2);
  display: flex;
  flex-direction: column;
  animation: drawerSlideIn 0.2s var(--ease-spring);
  transform: translateZ(0);
}

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes modalScaleUp {
  from { opacity: 0; transform: scale(0.97) translateY(6px); }
  to { opacity: 1; transform: scale(1) translateY(0); }
}

@keyframes drawerSlideIn {
  from { opacity: 0; transform: translateX(100%); }
  to { opacity: 1; transform: translateX(0); }
}

/* --------------------------------------------------------------------------
   Toast Notifications (Floating Liquid Glass)
   -------------------------------------------------------------------------- */
.glass-toast {
  pointer-events: auto;
  background: #ffffff;
  border: 1px solid rgba(225, 29, 72, 0.22);
  border-top: 1px solid #ffffff;
  box-shadow: 0 14px 34px -4px rgba(225, 29, 72, 0.22), inset 0 1px 1px #ffffff;
  border-radius: 0.95rem;
  animation: toastSlideIn 0.2s var(--ease-spring);
  position: relative;
  overflow: hidden;
  transform: translateZ(0);
}

@keyframes toastSlideIn {
  from { opacity: 0; transform: translateX(16px) scale(0.97); }
  to { opacity: 1; transform: translateX(0) scale(1); }
}

/* --------------------------------------------------------------------------
   Command Palette (Quick Actions & Navigation)
   -------------------------------------------------------------------------- */
.command-palette {
  background: #ffffff;
  border: 1px solid rgba(225, 29, 72, 0.2);
  border-top: 2px solid #ffffff;
  box-shadow: var(--liquid-glass-shadow-modal);
  border-radius: 1.25rem;
  overflow: hidden;
  transform: translateZ(0);
}

.command-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  border-radius: 0.75rem;
  cursor: pointer;
  transition: background-color 0.1s ease, color 0.1s ease;
}

.command-item:hover, .command-item.selected {
  background: rgba(255, 241, 242, 0.9);
  color: var(--brand-600);
}

.command-kbd {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  line-height: 1;
  padding: 0.2rem 0.35rem;
  background: var(--stone-100);
  border: 1px solid var(--stone-300);
  border-radius: 0.3rem;
  color: var(--stone-600);
  /* A keycap is one token: it must neither wrap ("Ctrl / K" on two lines) nor
     be squeezed by the flex row it sits in -- both of which it did inside the
     header's search field. */
  white-space: nowrap;
  flex-shrink: 0;
}

/* --------------------------------------------------------------------------
   Custom Scrollbars (Sleek Rose Tinted Glass)
   -------------------------------------------------------------------------- */
.custom-scrollbar::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}
.custom-scrollbar::-webkit-scrollbar-track {
  background: transparent;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, 0.18);
  border-radius: 9999px;
}
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
  background: rgba(0, 0, 0, 0.32);
}

/* --------------------------------------------------------------------------
   Lucide Vector Icon Utility & Animations
   -------------------------------------------------------------------------- */
.lucide-icon, svg.icon-svg {
  display: inline-block;
  vertical-align: middle;
  stroke-width: 2px;
  stroke: currentColor;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.icon-sm { width: 1rem; height: 1rem; }
.icon-md { width: 1.25rem; height: 1.25rem; }
.icon-lg { width: 1.5rem; height: 1.5rem; }
.icon-xl { width: 2rem; height: 2rem; }

/* Pulse dot animation for Live Telemetry (GPU Composited) */
@keyframes pulseDot {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.35; transform: scale(0.85); }
}

.telemetry-pulse {
  animation: pulseDot 2s infinite;
}

/* Syntax Validator Box for Vault Bulk Import */
.syntax-preview-box {
  border: 1px solid rgba(225, 29, 72, 0.18);
  background: #fafaf9;
  border-radius: 0.85rem;
  padding: 0.75rem 1rem;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  max-height: 180px;
  overflow-y: auto;
}

/* View Fade Entrance */
.view-enter {
  animation: viewFade 0.12s ease-out;
}

@keyframes viewFade {
  from { opacity: 0.85; }
  to { opacity: 1; }
}

/* --------------------------------------------------------------------------
   Reduced Motion Preferences
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
    transition-duration: 0.01ms !important;
  }
}

/* --------------------------------------------------------------------------
   Atomic utilities intentionally REMOVED.

   This file used to hand-reimplement ~46 Tailwind utilities (.flex, .hidden,
   .fixed, .relative, .gap-*, .w-full, .font-bold ...) as a fallback for when
   the Tailwind CDN failed to load. Now that Tailwind is compiled and served
   from /static/vendor/tailwind.css, those copies were actively harmful:
   styles.css loads AFTER the Tailwind bundle, so at equal specificity the
   copies won the cascade and silently defeated every responsive variant.

   Two concrete regressions this caused:
     * `.fixed { position: fixed }` overrode `lg:static`, so #main-sidebar
       stayed fixed at all widths and overlapped the main content on desktop.
     * `.hidden { display: none !important }` overrode `md:flex` / `sm:inline`,
       permanently hiding the Ctrl+K quick-jump button and several button labels.

   Add new styling as semantic component classes (.nav-btn, .pager, .badge-*)
   or as design tokens above -- never as a bare utility that shadows Tailwind.
   -------------------------------------------------------------------------- */
.permission-hidden { display: none !important; }

/* ==========================================================================
   AMBIENT LIGHTING — theme-aware brand glow
   ========================================================================== */
.ambient-orb-1 { background: radial-gradient(circle, rgba(225, 29, 72, 0.18) 0%, transparent 70%); opacity: 0.40; }
.ambient-orb-2 { background: radial-gradient(circle, rgba(255, 77, 109, 0.15) 0%, transparent 70%); opacity: 0.35; }
.ambient-orb-3 { background: radial-gradient(circle, rgba(254, 205, 211, 0.35) 0%, transparent 70%); opacity: 0.25; }

[data-theme="dark"] .ambient-orb-1 { background: radial-gradient(circle, rgba(225, 29, 72, 0.30) 0%, transparent 70%); opacity: 0.55; }
[data-theme="dark"] .ambient-orb-2 { background: radial-gradient(circle, rgba(190, 18, 60, 0.26) 0%, transparent 70%); opacity: 0.45; }
[data-theme="dark"] .ambient-orb-3 { background: radial-gradient(circle, rgba(79, 70, 229, 0.18) 0%, transparent 70%); opacity: 0.40; }

/* ==========================================================================
   COMPACT PROFESSIONAL TYPE SCALE
   Per brand brief: 12px dense metadata/tables, 13-14px controls, 16-20px heads.
   ========================================================================== */
:root {
  --fs-meta: 11.5px;   /* dense table metadata, badges, timestamps */
  --fs-table: 12px;    /* table body */
  --fs-ui: 13px;       /* form controls, buttons, menu items */
  --fs-body: 14px;     /* primary reading text */
  --fs-h3: 16px;       /* card / panel headings */
  --fs-h2: 18px;       /* section headings */
  --fs-h1: 20px;       /* page heading */
  --row-py: 7px;       /* compact table row padding */
}

.glass-table thead th {
  font-size: var(--fs-meta);
  letter-spacing: 0.045em;
}
.glass-table tbody td {
  font-size: var(--fs-table);
  padding-top: var(--row-py);
  padding-bottom: var(--row-py);
}
.glass-input,
select.glass-input,
textarea.glass-input { font-size: var(--fs-ui); }
.nav-btn { font-size: var(--fs-ui); }
#page-title { font-size: var(--fs-h1); }

/* Screen-reader-only helper for icon-only controls and select labels. */
.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;
}

/* ==========================================================================
   PAGINATION
   ========================================================================== */
.pager {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 12px;
  padding: 10px 14px; margin-top: 2px;
  border-top: 1px solid var(--liquid-glass-border-subtle);
}
.pager-meta {
  display: flex; align-items: center; gap: 6px;
  font-size: var(--fs-meta); color: var(--stone-500);
}
.pager-size { display: inline-flex; align-items: center; margin-left: 6px; }
.pager-select { padding: 3px 22px 3px 8px !important; font-size: var(--fs-meta) !important; border-radius: 8px !important; }
.pager-controls { display: flex; align-items: center; gap: 6px; }

.pager-btn {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 5px 9px; border-radius: 9px;
  font-size: var(--fs-meta); font-weight: 700;
  color: var(--stone-600);
  background: var(--liquid-glass-bg);
  border: 1px solid var(--liquid-glass-border-subtle);
  cursor: pointer;
}
.pager-btn:hover:not(:disabled) {
  color: var(--brand-600);
  border-color: var(--liquid-glass-border-hover);
  box-shadow: var(--liquid-glass-shadow-sm);
}
.pager-btn:disabled { opacity: 0.4; cursor: not-allowed; }

.pager-num {
  min-width: 28px; height: 28px; padding: 0 6px;
  border-radius: 8px;
  font-family: var(--font-mono); font-size: var(--fs-meta); font-weight: 700;
  color: var(--stone-600);
  background: transparent;
  border: 1px solid transparent;
  cursor: pointer;
}
.pager-num:hover { background: var(--brand-50); color: var(--brand-600); }
.pager-num-active {
  background: linear-gradient(135deg, var(--brand-600), var(--brand-500));
  color: #fff;
  border-color: var(--brand-700);
  box-shadow: 0 2px 8px -2px rgba(225, 29, 72, 0.45);
}
.pager-num-active:hover { background: linear-gradient(135deg, var(--brand-700), var(--brand-600)); color: #fff; }

/* ==========================================================================
   DARK THEME — "Obsidian & Crimson"
   The markup is Tailwind-utility driven, so a token swap alone is not enough:
   the utility classes actually used in app.js/index.html are remapped here to
   their dark equivalents. This keeps one source of truth for the palette and
   avoids sprinkling `dark:` variants across ~4,900 lines of template strings.
   ========================================================================== */
[data-theme="dark"] {
  /* Cool zinc dark, same recipe as light: flat surfaces, hairline borders,
     high-contrast ink, no warm cast and no rose-tinted shadows. */
  --pearl-bg: #0a0a0b;
  --pearl-surface: #121214;
  --pearl-elevated: #17171a;

  --surface-1: #121214;
  --surface-2: #17171a;
  --surface-3: #1f1f23;
  --ink-strong: #fafafa;
  --ink: #e6e6e9;
  --ink-muted: #a7a7b0;
  --ink-faint: #74747e;
  --hairline: rgba(250, 250, 250, 0.09);

  --stone-950: #fafafa;
  --stone-900: #f1f1f3;
  --stone-800: #dedee2;
  --stone-700: #c2c2c8;
  --stone-600: #a7a7b0;
  --stone-500: #8d8d97;
  --stone-400: #6e6e78;
  --stone-300: #33333a;
  --stone-200: #26262c;
  --stone-100: #1d1d22;
  --stone-50: #151518;

  --liquid-glass-bg: #17171a;
  --liquid-glass-panel: rgba(18, 18, 20, 0.82);
  --liquid-glass-elevated: #1c1c20;

  --liquid-glass-border: rgba(250, 250, 250, 0.14);
  --liquid-glass-border-subtle: rgba(250, 250, 250, 0.11);
  --liquid-glass-border-hover: rgba(250, 250, 250, 0.28);

  --liquid-glass-shadow-sm:
    0 1px 2px rgba(0, 0, 0, 0.5);
  --liquid-glass-shadow:
    0 1px 2px rgba(0, 0, 0, 0.5),
    0 2px 6px rgba(0, 0, 0, 0.4);
  --liquid-glass-shadow-hover:
    0 6px 16px rgba(0, 0, 0, 0.55),
    0 2px 6px rgba(0, 0, 0, 0.4);
  --liquid-glass-shadow-modal:
    0 26px 60px -12px rgba(0, 0, 0, 0.8);

  /* Brand tints need to *emit* light on dark rather than wash out. */
  --brand-50: rgba(225, 29, 72, 0.14);
  --brand-100: rgba(225, 29, 72, 0.20);
  --emerald-50: rgba(5, 150, 105, 0.15);
  --amber-50: rgba(217, 119, 6, 0.15);
  --rose-50: rgba(225, 29, 72, 0.14);
  --blue-50: rgba(37, 99, 235, 0.15);
  --indigo-50: rgba(79, 70, 229, 0.15);

  color-scheme: dark;
}

[data-theme="dark"] html,
[data-theme="dark"] body {
  background-color: var(--pearl-bg);
  color: var(--ink);
}
[data-theme="dark"] .circuit-light-bg {
  background-color: var(--pearl-bg);
  background-image:
    radial-gradient(1200px 700px at 8% -10%, rgba(59, 130, 246, 0.38), transparent 62%),
    radial-gradient(1000px 560px at 96% 0%, rgba(56, 189, 248, 0.20), transparent 58%),
    radial-gradient(900px 560px at 35% 60%, rgba(59, 130, 246, 0.14), transparent 62%),
    radial-gradient(1200px 700px at 62% 114%, rgba(99, 102, 241, 0.28), transparent 62%);
}

/* ---- Text utility remap -------------------------------------------------- */
[data-theme="dark"] .text-stone-900 { color: var(--ink-strong) !important; }
[data-theme="dark"] .text-stone-800 { color: var(--ink) !important; }
[data-theme="dark"] .text-stone-700 { color: #c2c2c8 !important; }
[data-theme="dark"] .text-stone-600 { color: var(--ink-muted) !important; }
[data-theme="dark"] .text-stone-500 { color: #9b9ba4 !important; }
[data-theme="dark"] .text-stone-400 { color: var(--ink-faint) !important; }
[data-theme="dark"] .text-black { color: var(--ink-strong) !important; }

/* Semantic text lightened for AA contrast on dark surfaces. */
[data-theme="dark"] .text-brand-600,
[data-theme="dark"] .text-brand-700,
[data-theme="dark"] .text-brand-800,
[data-theme="dark"] .text-brand-900 { color: #ff8fa3 !important; }
[data-theme="dark"] .text-emerald-600,
[data-theme="dark"] .text-emerald-700,
[data-theme="dark"] .text-emerald-800 { color: #4ade9a !important; }
[data-theme="dark"] .text-rose-600,
[data-theme="dark"] .text-rose-700,
[data-theme="dark"] .text-rose-800 { color: #ff8fa3 !important; }
[data-theme="dark"] .text-amber-600,
[data-theme="dark"] .text-amber-700,
[data-theme="dark"] .text-amber-800,
[data-theme="dark"] .text-amber-900 { color: #fcd34d !important; }
[data-theme="dark"] .text-blue-600,
[data-theme="dark"] .text-blue-700,
[data-theme="dark"] .text-blue-800 { color: #7dacff !important; }
[data-theme="dark"] .text-purple-600,
[data-theme="dark"] .text-purple-700,
[data-theme="dark"] .text-purple-800 { color: #c4a8ff !important; }

/* ---- Surface utility remap ---------------------------------------------- */
[data-theme="dark"] .bg-white,
[data-theme="dark"] .bg-white\/98,
[data-theme="dark"] .bg-white\/90,
[data-theme="dark"] .bg-white\/80,
[data-theme="dark"] .bg-white\/75 { background-color: var(--surface-2) !important; }
[data-theme="dark"] .bg-stone-50,
[data-theme="dark"] .bg-stone-50\/90,
[data-theme="dark"] .bg-stone-50\/80 { background-color: var(--surface-1) !important; }
[data-theme="dark"] .bg-stone-100 { background-color: var(--surface-3) !important; }
[data-theme="dark"] .bg-stone-200 { background-color: #302a2a !important; }
[data-theme="dark"] .bg-stone-900\/35 { background-color: rgba(0, 0, 0, 0.65) !important; }

/* Semantic tints: translucent so the glass depth still reads. */
[data-theme="dark"] .bg-brand-50,
[data-theme="dark"] .bg-rose-50,
[data-theme="dark"] .bg-rose-50\/70,
[data-theme="dark"] .bg-rose-50\/40 { background-color: rgba(225, 29, 72, 0.13) !important; }
[data-theme="dark"] .bg-rose-100 { background-color: rgba(225, 29, 72, 0.22) !important; }
[data-theme="dark"] .bg-emerald-50,
[data-theme="dark"] .bg-emerald-50\/70 { background-color: rgba(5, 150, 105, 0.15) !important; }
[data-theme="dark"] .bg-emerald-100 { background-color: rgba(5, 150, 105, 0.25) !important; }
[data-theme="dark"] .bg-amber-50 { background-color: rgba(217, 119, 6, 0.15) !important; }
[data-theme="dark"] .bg-amber-100 { background-color: rgba(217, 119, 6, 0.25) !important; }

/* Solid accent fills stay saturated — they carry white text. */
[data-theme="dark"] .bg-brand-500 { background-color: var(--brand-500) !important; }
[data-theme="dark"] .bg-emerald-500 { background-color: #059669 !important; }
[data-theme="dark"] .bg-emerald-600 { background-color: #047857 !important; }

/* ---- Border utility remap ---------------------------------------------- */
[data-theme="dark"] .border-stone-200,
[data-theme="dark"] .border-stone-200\/80,
[data-theme="dark"] .border-stone-300 { border-color: var(--hairline) !important; }
[data-theme="dark"] .border-emerald-200,
[data-theme="dark"] .border-emerald-300 { border-color: rgba(5, 150, 105, 0.42) !important; }
[data-theme="dark"] .border-rose-200,
[data-theme="dark"] .border-rose-300 { border-color: rgba(225, 29, 72, 0.42) !important; }
[data-theme="dark"] .border-amber-400 { border-color: rgba(217, 119, 6, 0.55) !important; }

/* ---- Component-level dark polish --------------------------------------- */
[data-theme="dark"] #main-sidebar { background: rgba(20, 17, 17, 0.96) !important; }
[data-theme="dark"] .glass-input {
  background: rgba(12, 10, 10, 0.62);
  border-color: var(--hairline);
  color: var(--ink);
}
[data-theme="dark"] .glass-input::placeholder { color: var(--ink-faint); }
[data-theme="dark"] .glass-input:focus {
  border-color: var(--liquid-glass-border-hover);
  background: rgba(12, 10, 10, 0.85);
}
/* Native dropdown lists render with the OS palette unless told otherwise. */
[data-theme="dark"] select.glass-input option { background-color: var(--surface-2); color: var(--ink); }

[data-theme="dark"] .glass-btn { color: var(--ink-muted); }
[data-theme="dark"] .glass-btn:hover { color: #ff8fa3; }
[data-theme="dark"] .glass-table tbody tr:hover { background: rgba(225, 29, 72, 0.07); }
[data-theme="dark"] .glass-table thead th { color: var(--ink-muted); }
[data-theme="dark"] .badge-neutral { background: var(--surface-3); color: var(--ink-muted); border-color: var(--hairline); }
[data-theme="dark"] .pager-num:hover { background: rgba(225, 29, 72, 0.16); color: #ff8fa3; }
[data-theme="dark"] .command-kbd { background: var(--surface-3); color: var(--ink-muted); border-color: var(--hairline); }
[data-theme="dark"] .custom-scrollbar::-webkit-scrollbar-thumb { background: rgba(250, 250, 250, 0.16); }
[data-theme="dark"] .custom-scrollbar::-webkit-scrollbar-thumb:hover { background: rgba(250, 250, 250, 0.30); }
[data-theme="dark"] .brand-logo-img,
[data-theme="dark"] .brand-logo-login { filter: none; }
[data-theme="dark"] button:focus-visible,
[data-theme="dark"] input:focus-visible,
[data-theme="dark"] select:focus-visible,
[data-theme="dark"] textarea:focus-visible,
[data-theme="dark"] a:focus-visible,
[data-theme="dark"] [role="button"]:focus-visible {
  outline-color: rgba(255, 143, 163, 0.70);
}

/* Toast surfaces are set inline by app.js; force dark equivalents. */
[data-theme="dark"] .glass-toast { backdrop-filter: blur(18px); }

/* ==========================================================================
   DARK THEME — component surfaces
   The component classes above hardcode their own light backgrounds
   (rgba(255,255,255,.98), #ffffff, pink gradients) rather than reading the
   --liquid-glass-* tokens, so overriding the tokens alone left the whole
   content area light. Each surface is therefore restated here.
   ========================================================================== */

/* Page backdrop: the light build paints four pink radial gradients on top of
   its background-color, which showed through as a washed-out veil. */
[data-theme="dark"] .circuit-light-bg {
  background-color: var(--pearl-bg);
  background-image:
    radial-gradient(circle at 50% 0%, rgba(225, 29, 72, 0.16) 0%, transparent 46%),
    radial-gradient(circle at 95% 15%, rgba(190, 18, 60, 0.13) 0%, transparent 38%),
    radial-gradient(circle at 5% 75%, rgba(79, 70, 229, 0.10) 0%, transparent 42%),
    radial-gradient(circle at 50% 100%, rgba(225, 29, 72, 0.10) 0%, transparent 52%);
}

[data-theme="dark"] .glass-panel {
  background: rgba(24, 20, 20, 0.94);
  border-color: var(--liquid-glass-border-subtle);
}

[data-theme="dark"] .glass-card {
  background: rgba(32, 27, 27, 0.90);
  border: 1px solid var(--hairline);
  border-top: 1.5px solid rgba(255, 255, 255, 0.07);
  box-shadow: var(--liquid-glass-shadow);
}
[data-theme="dark"] .glass-card-elevated {
  background: var(--surface-3);
  border: 1px solid var(--hairline);
  border-top: 1.5px solid rgba(255, 255, 255, 0.08);
}
[data-theme="dark"] .glass-card:hover { border-top-color: rgba(255, 255, 255, 0.12); }
[data-theme="dark"] .glass-card-interactive:hover {
  border-color: rgba(225, 29, 72, 0.55);
  border-top-color: rgba(255, 255, 255, 0.14);
}

/* Specular sheen must subtract far less light on a dark surface. */
[data-theme="dark"] .glass-sheen::after {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.055) 0%, rgba(255, 255, 255, 0) 100%);
}

[data-theme="dark"] .skeleton {
  background: linear-gradient(90deg, rgba(38, 33, 33, 0.9) 25%, rgba(225, 29, 72, 0.14) 50%, rgba(38, 33, 33, 0.9) 75%);
  background-size: 200% 100%;
}

[data-theme="dark"] .glass-input {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--hairline);
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  color: var(--ink);
}
[data-theme="dark"] .glass-input:focus {
  background: rgba(12, 10, 10, 0.92);
  border-color: var(--brand-500);
  box-shadow: 0 0 0 3px rgba(225, 29, 72, 0.30), inset 0 1px 1px rgba(255, 255, 255, 0.04);
}

[data-theme="dark"] .glass-btn {
  background: linear-gradient(135deg, rgba(40, 35, 35, 0.95) 0%, rgba(30, 26, 26, 0.90) 100%);
  border: 1px solid var(--hairline);
  border-top: 1px solid rgba(255, 255, 255, 0.07);
  color: var(--ink-muted);
}
[data-theme="dark"] .glass-btn:hover {
  background: linear-gradient(135deg, rgba(225, 29, 72, 0.24) 0%, rgba(225, 29, 72, 0.14) 100%);
  border-color: rgba(225, 29, 72, 0.55);
  color: #ff8fa3;
}

[data-theme="dark"] .btn-secondary {
  background: var(--surface-3);
  border: 1px solid var(--hairline);
  border-top: 1px solid rgba(255, 255, 255, 0.07);
  color: var(--ink);
}
[data-theme="dark"] .btn-secondary:hover {
  background: rgba(225, 29, 72, 0.20);
  border-color: rgba(225, 29, 72, 0.55);
  color: #ff8fa3;
}

[data-theme="dark"] .filter-pill:hover { background: rgba(225, 29, 72, 0.18); color: #ff8fa3; }

[data-theme="dark"] .nav-btn { color: var(--ink-muted); }
[data-theme="dark"] .nav-btn:hover { background: rgba(225, 29, 72, 0.16); color: #ff8fa3; }
[data-theme="dark"] .nav-btn.active {
  background: linear-gradient(135deg, rgba(225, 29, 72, 0.30) 0%, rgba(225, 29, 72, 0.16) 100%);
  border: 1px solid rgba(225, 29, 72, 0.50);
  color: #ff8fa3;
}

[data-theme="dark"] .glass-table th {
  background: rgba(225, 29, 72, 0.10);
  border-bottom: 1.5px solid rgba(225, 29, 72, 0.30);
  color: var(--ink-muted);
}
[data-theme="dark"] .glass-table tbody tr:hover { background: rgba(225, 29, 72, 0.09); }
[data-theme="dark"] .glass-table tbody tr { border-color: var(--hairline); }

[data-theme="dark"] .glass-modal {
  background: var(--surface-2);
  border: 1px solid var(--hairline);
  color: var(--ink);
}
[data-theme="dark"] .glass-drawer {
  background: var(--surface-2);
  border-left: 1px solid var(--liquid-glass-border-subtle);
  color: var(--ink);
}
[data-theme="dark"] .glass-toast {
  background: var(--surface-3);
  border: 1px solid var(--liquid-glass-border-subtle);
  border-top: 1px solid rgba(255, 255, 255, 0.07);
}
[data-theme="dark"] .command-palette {
  background: var(--surface-2);
  border: 1px solid var(--liquid-glass-border-subtle);
  border-top: 2px solid rgba(225, 29, 72, 0.40);
}
[data-theme="dark"] .command-item:hover,
[data-theme="dark"] .command-item.selected { background: rgba(225, 29, 72, 0.18); color: #ff8fa3; }
[data-theme="dark"] .command-kbd {
  background: rgba(12, 10, 10, 0.70);
  border: 1px solid var(--hairline);
  color: var(--ink-muted);
}
[data-theme="dark"] .syntax-preview-box {
  background: rgba(12, 10, 10, 0.70);
  border-color: var(--hairline);
  color: var(--ink);
}
[data-theme="dark"] .pager { border-top-color: var(--liquid-glass-border-subtle); }
[data-theme="dark"] .pager-btn { color: var(--ink-muted); }

/* The login card sits on the same backdrop and must follow the theme too. */
[data-theme="dark"] #view-login .glass-card { background: var(--surface-2); }

/* Badges hardcode `color: var(--<hue>-700)` — a dark ink that becomes illegible
   once the tint behind it is itself dark. Restate ink + tint together so each
   pairing clears WCAG AA (>=4.5:1) in dark mode. */
[data-theme="dark"] .badge-success {
  background: rgba(5, 150, 105, 0.20);
  border-color: rgba(16, 185, 129, 0.45);
  color: #6ee7b7;
}
[data-theme="dark"] .badge-warning {
  background: rgba(217, 119, 6, 0.20);
  border-color: rgba(245, 158, 11, 0.45);
  color: #fcd34d;
}
[data-theme="dark"] .badge-danger {
  background: rgba(225, 29, 72, 0.20);
  border-color: rgba(244, 63, 94, 0.45);
  color: #fda4af;
}
[data-theme="dark"] .badge-info {
  background: rgba(2, 132, 199, 0.20);
  border-color: rgba(56, 189, 248, 0.45);
  color: #7dd3fc;
}
[data-theme="dark"] .badge-neutral {
  background: rgba(245, 240, 238, 0.09);
  border-color: var(--hairline);
  color: #cfc9c5;
}

/* ==========================================================================
   DARK THEME — inline code, native form chrome
   ========================================================================== */

/* Tailwind's preflight leaves <code> inheriting colour. On the dark surface the
   order codes rendered as near-black on near-black and were unreadable. Give
   them an explicit chip treatment in both themes so IDs are always scannable. */
code {
  font-family: var(--font-mono);
  font-size: 0.92em;
  padding: 0.08em 0.34em;
  border-radius: 5px;
  background: rgba(225, 29, 72, 0.07);
  border: 1px solid rgba(225, 29, 72, 0.14);
  color: var(--brand-700);
  white-space: nowrap;
}
[data-theme="dark"] code {
  background: rgba(225, 29, 72, 0.17);
  border-color: rgba(225, 29, 72, 0.34);
  color: #ffa8b6;
}

/* Native <select> keeps the OS widget colours unless appearance is reset, so the
   dark theme showed a light dropdown. Reset it and draw our own chevron. */
select.glass-input {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2378716c' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.5rem center;
  background-size: 0.85em;
  padding-right: 1.85rem;
}
[data-theme="dark"] select.glass-input {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23a8a29e' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
}
/* The pager's compact select still needs room for the chevron. */
.pager-select { padding-right: 1.6rem !important; }

/* Date inputs render a dark-on-dark calendar glyph in some engines. */
[data-theme="dark"] input[type="date"]::-webkit-calendar-picker-indicator {
  filter: invert(0.85);
  cursor: pointer;
}

/* `.glass-table td` pins `color: var(--stone-800)` (a near-black ink) directly on
   the cell. On the dark surface that measured 1.14:1 — effectively invisible for
   any cell whose text is not wrapped in its own coloured element. */
[data-theme="dark"] .glass-table td { color: var(--ink); }
[data-theme="dark"] .glass-table th { color: #ffa8b6; }
[data-theme="dark"] .glass-table td,
[data-theme="dark"] .glass-table tbody tr:last-child td { border-bottom-color: var(--hairline); }

/* ==========================================================================
   Movement bands (Fast & Slow Moving Goods)

   These were composed at runtime as `bg-${tone}-100 text-${tone}-700`, which
   only works if that exact utility is in the vendored subset. Two of the five
   tones -- sky and slate -- are not in it, so "Steady" and "Too new" rendered
   with no colour at all while the other three looked right. Semantic classes
   instead: one place to read, and nothing left to fall through.
   ========================================================================== */

.band-pill {
  display: inline-block;
  padding: 0.25rem 0.5rem;
  border-radius: 9999px;
  font-size: 0.75rem;
  font-weight: 700;
  line-height: 1.2;
  white-space: nowrap;
}

.band-fast   { background: #d1fae5; color: #047857; }
.band-steady { background: #dbeafe; color: #1d4ed8; }
.band-slow   { background: #fef3c7; color: #b45309; }
.band-dead   { background: #ffe4e6; color: #be123c; }
.band-new    { background: #f5f5f4; color: #57534e; }

.band-figure { font-weight: 800; font-size: 1.5rem; line-height: 1.2; font-variant-numeric: tabular-nums; }
.band-figure.band-fast,
.band-figure.band-steady,
.band-figure.band-slow,
.band-figure.band-dead,
.band-figure.band-new { background: none; }

.band-figure.band-fast   { color: #059669; }
.band-figure.band-steady { color: #2563eb; }
.band-figure.band-slow   { color: #d97706; }
.band-figure.band-dead   { color: #e11d48; }
.band-figure.band-new    { color: #78716c; }

/* No ring-* utilities exist in the vendored subset, so the cards had no hover
   feedback at all despite being buttons. */
.band-card {
  /* A real card. It used to be a transparent-bordered text block that leaned
     on the page's old glass ground for its shape; on the flat ground it
     rendered as five floating captions. */
  text-align: left;
  cursor: pointer;
  background: var(--pearl-elevated);
  border: 1px solid var(--liquid-glass-border);
  box-shadow: var(--liquid-glass-shadow);
  transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.12s ease-out;
}
.band-card:hover { border-color: var(--liquid-glass-border-hover); box-shadow: var(--liquid-glass-shadow-hover); transform: translateY(-1px); }
.band-card:active { transform: scale(0.98); }
.band-card:disabled { cursor: default; transform: none; }
.band-card:focus-visible { outline: 2px solid var(--brand-500); outline-offset: 2px; }
.band-card[aria-pressed="true"] {
  border-color: var(--brand-500);
  box-shadow: 0 0 0 1px var(--brand-500), var(--liquid-glass-shadow);
}

[data-theme="dark"] .band-fast   { background: rgba(5, 150, 105, 0.25); color: #6ee7b7; }
[data-theme="dark"] .band-steady { background: rgba(37, 99, 235, 0.25); color: #93c5fd; }
[data-theme="dark"] .band-slow   { background: rgba(217, 119, 6, 0.25); color: #fcd34d; }
[data-theme="dark"] .band-dead   { background: rgba(225, 29, 72, 0.25); color: #fda4af; }
[data-theme="dark"] .band-new    { background: rgba(120, 113, 108, 0.3); color: #d6d3d1; }

[data-theme="dark"] .band-figure.band-fast   { color: #34d399; }
[data-theme="dark"] .band-figure.band-steady { color: #60a5fa; }
[data-theme="dark"] .band-figure.band-slow   { color: #fbbf24; }
[data-theme="dark"] .band-figure.band-dead   { color: #fb7185; }
[data-theme="dark"] .band-figure.band-new    { color: #a8a29e; }

/* ==========================================================================
   Utilities the CMS asks for that the vendored subset never compiled

   The Tailwind build in vendor/ is a fixed subset, not a JIT compiler, so a
   class that was not in it when it was generated is inert: the element renders
   unstyled and nothing anywhere reports it. An audit of every class used
   against every class defined turned up sixty of these.

   The one that showed everywhere was `tabular-nums`, asked for twenty-six
   times and never delivered, so every money and quantity column in the admin
   had proportional digits that did not line up down the column.

   Colours are written against the existing tokens rather than fresh hex, so
   they follow the theme, and each gets its dark counterpart -- a light-only
   colour is how text ends up unreadable on the dark surface.
   ========================================================================== */

/* -- numerals ------------------------------------------------------------ */

.tabular-nums { font-variant-numeric: tabular-nums; }

/* -- text and flow ------------------------------------------------------- */

.whitespace-nowrap { white-space: nowrap; }
.break-all { word-break: break-all; }
.underline { text-decoration-line: underline; }
.normal-case { text-transform: none; }
.tracking-widest { letter-spacing: 0.1em; }
.leading-snug { line-height: 1.375; }
.object-cover { object-fit: cover; }
.border-dashed { border-style: dashed; }

/* -- spacing the markup asks for ----------------------------------------- */

.mb-0\.5 { margin-bottom: 0.125rem; }
.mr-1 { margin-right: 0.25rem; }
.py-6 { padding-top: 1.5rem; padding-bottom: 1.5rem; }

/* -- scroll bounds on the modals and inner tables ------------------------ */

.max-h-52 { max-height: 13rem; }
.max-h-56 { max-height: 14rem; }
.max-h-96 { max-height: 24rem; }
.max-h-\[70vh\] { max-height: 70vh; }
.max-h-\[85vh\] { max-height: 85vh; }
.max-w-\[10rem\] { max-width: 10rem; }

/* -- shadows ------------------------------------------------------------- */

.shadow-2xs { box-shadow: 0 1px 1px rgba(15, 12, 14, 0.04); }
.shadow-xs { box-shadow: 0 1px 2px rgba(15, 12, 14, 0.06); }
.shadow-glass-hover { box-shadow: var(--liquid-glass-shadow-hover); }

/* -- neutrals ------------------------------------------------------------ */

.text-stone-300 { color: var(--stone-300); }
.border-stone-50 { border-color: var(--stone-50); }
.border-stone-100 { border-color: var(--stone-100); }
.border-stone-200\/70 { border-color: color-mix(in srgb, var(--stone-200) 70%, transparent); }
.border-stone-300\/60 { border-color: color-mix(in srgb, var(--stone-300) 60%, transparent); }
.bg-stone-50\/60 { background-color: color-mix(in srgb, var(--stone-50) 60%, transparent); }
.hover\:bg-stone-50\/60:hover { background-color: color-mix(in srgb, var(--stone-50) 60%, transparent); }
.bg-slate-100 { background-color: var(--stone-100); }

/* -- red, which this theme spells rose ----------------------------------- */

.text-red-600 { color: var(--rose-600); }
.text-red-700 { color: var(--rose-700); }
.border-red-300 { border-color: color-mix(in srgb, var(--rose-600) 35%, transparent); }
.hover\:bg-red-50:hover { background-color: var(--rose-50); }

/* -- blue ---------------------------------------------------------------- */

.bg-blue-100 { background-color: color-mix(in srgb, var(--blue-600) 16%, white); }
.bg-blue-600 { background-color: var(--blue-600); }
.border-blue-200 { border-color: color-mix(in srgb, var(--blue-600) 25%, transparent); }
.border-blue-700 { border-color: var(--blue-700); }
.text-blue-900 { color: color-mix(in srgb, var(--blue-700) 80%, black); }
.text-sky-700 { color: var(--blue-700); }

/* -- amber --------------------------------------------------------------- */

.bg-amber-600 { background-color: var(--amber-600); }
.hover\:bg-amber-700:hover { background-color: var(--amber-700); }
.border-amber-300 { border-color: color-mix(in srgb, var(--amber-600) 35%, transparent); }
.border-amber-400\/40 { border-color: color-mix(in srgb, var(--amber-600) 40%, transparent); }

/* -- violet, used only by the discount presets --------------------------- */

.bg-violet-50 { background-color: #f5f3ff; }
.hover\:bg-violet-100:hover { background-color: #ede9fe; }
.text-violet-600 { color: #7c3aed; }
.text-violet-700 { color: #6d28d9; }
.text-violet-800 { color: #5b21b6; }
.border-violet-500\/30 { border-color: rgba(139, 92, 246, 0.3); }

.hover\:border-emerald-400:hover { border-color: color-mix(in srgb, var(--emerald-600) 60%, transparent); }

/* -- the Telegram preview in the product editor --------------------------
   Three classes the markup has always asked for and no stylesheet has ever
   defined, so the panel that is meant to show the customer's view rendered as
   plain stacked divs. */

.telegram-simulator {
  background: linear-gradient(180deg, #dfe9f3 0%, #c7d8ea 100%);
  border: 1px solid rgba(15, 12, 14, 0.08);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7), var(--liquid-glass-shadow-sm);
}

.telegram-bubble {
  background: #ffffff;
  border-radius: 0.85rem 0.85rem 0.85rem 0.2rem;
  box-shadow: 0 1px 2px rgba(15, 12, 14, 0.12);
}

.telegram-btn {
  background: rgba(255, 255, 255, 0.92);
  color: #2b7bbd;
  border: 1px solid rgba(43, 123, 189, 0.22);
  cursor: default;
}

.discount-preset {
  border: 1px solid rgba(139, 92, 246, 0.3);
  transition: background-color 0.15s ease, border-color 0.15s ease;
}

/* -- dark counterparts ---------------------------------------------------
   Every colour above needs one, or the light value survives onto the dark
   surface and the contrast collapses. */

[data-theme="dark"] .text-stone-300 { color: var(--ink-muted); }
[data-theme="dark"] .border-stone-50,
[data-theme="dark"] .border-stone-100 { border-color: var(--hairline); }
[data-theme="dark"] .border-stone-200\/70,
[data-theme="dark"] .border-stone-300\/60 { border-color: var(--hairline); }
[data-theme="dark"] .bg-stone-50\/60,
[data-theme="dark"] .hover\:bg-stone-50\/60:hover { background-color: rgba(255, 255, 255, 0.05); }
[data-theme="dark"] .bg-slate-100 { background-color: rgba(255, 255, 255, 0.08); }

[data-theme="dark"] .text-red-600 { color: #fda4af; }
[data-theme="dark"] .text-red-700 { color: #fecdd3; }
[data-theme="dark"] .hover\:bg-red-50:hover { background-color: rgba(225, 29, 72, 0.18); }

[data-theme="dark"] .bg-blue-100 { background-color: rgba(37, 99, 235, 0.25); }
[data-theme="dark"] .text-blue-900 { color: #bfdbfe; }
[data-theme="dark"] .text-sky-700 { color: #93c5fd; }
[data-theme="dark"] .border-blue-200 { border-color: rgba(37, 99, 235, 0.4); }

[data-theme="dark"] .bg-violet-50 { background-color: rgba(139, 92, 246, 0.18); }
[data-theme="dark"] .hover\:bg-violet-100:hover { background-color: rgba(139, 92, 246, 0.28); }
[data-theme="dark"] .text-violet-600 { color: #c4b5fd; }
[data-theme="dark"] .text-violet-700 { color: #ddd6fe; }
[data-theme="dark"] .text-violet-800 { color: #ede9fe; }

[data-theme="dark"] .telegram-simulator {
  background: linear-gradient(180deg, #1f2a37 0%, #16202b 100%);
  border-color: var(--hairline);
}
[data-theme="dark"] .telegram-bubble { background: #26313d; color: var(--ink); }
[data-theme="dark"] .telegram-btn {
  background: rgba(255, 255, 255, 0.08);
  color: #7db6e6;
  border-color: rgba(125, 182, 230, 0.25);
}

.hover\:border-amber-400:hover { border-color: color-mix(in srgb, var(--amber-600) 55%, transparent); }

.italic { font-style: italic; }

/* ------------------------------------------------------------------------
   Two class names the console has always asked for and never had.

   Neither was defined here or in the Tailwind build, so both have been
   silently doing nothing -- `shadow-glow-red` on the primary action of nine
   separate screens, which is the one button on each that was meant to stand
   out. Nothing reports a class that does not exist, which is why this went
   unnoticed; tests/js/tailwind_classes_check.cjs now does.

   Written against --brand-500 rather than a literal, so the blue store glows
   blue instead of inheriting this one's red.
   ------------------------------------------------------------------------ */
.shadow-glow-red {
  /* Kept as a name, retired as a glow: under the neutral design the primary
     action carries a plain 1px shadow like every other raised control. */
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
}

.shadow-glow-red:hover {
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.18);
}

/* The decorative orb layer. Its own paint is confined so three large blurred
   gradients cannot force the page to repaint on every scroll. */
.ambient-glow {
  contain: paint;
}

/* ==========================================================================
   Responsive & Interaction Layer

   Added after an audit found the console had exactly one media query in this
   file (reduced-motion) and ~95 responsive utilities across 12,000 lines of
   page code, while 33 tables fell back to a bare horizontal scroll. On a
   375px phone the audit table cut its last column off entirely, with nothing
   on screen to say the column existed.

   Everything here keys off classes the pages ALREADY use, so all twenty-four
   screens get it without a markup change -- including the ones still written
   in vanilla JS.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Wide tables on narrow screens

   Two problems, both visible in that screenshot: cells wrapped mid-value
   ("2026-09-12 14:22:01" over two lines, "Admin #1" over two), and there was
   no sign the table continued past the right edge.

   Cells stop wrapping, so a row is one line and horizontal scroll does the
   job it is there for; and the scroller grows edge shadows that appear only
   when there is more in that direction. The `local`/`scroll` attachment pair
   is what makes that automatic -- the cover gradients travel with the
   content, the shadows stay pinned, so a fully-scrolled edge shows nothing.
   -------------------------------------------------------------------------- */
.overflow-x-auto,
.overflow-auto {
  -webkit-overflow-scrolling: touch;
  /* A flick that runs out of table should not then scroll the page sideways. */
  overscroll-behavior-x: contain;
  background:
    linear-gradient(to right, var(--surface-2, #ffffff) 30%, rgba(255, 255, 255, 0)) left center / 36px 100% no-repeat local,
    linear-gradient(to left, var(--surface-2, #ffffff) 30%, rgba(255, 255, 255, 0)) right center / 36px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%, rgba(68, 64, 60, 0.16), rgba(68, 64, 60, 0)) left center / 14px 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, rgba(68, 64, 60, 0.16), rgba(68, 64, 60, 0)) right center / 14px 100% no-repeat scroll;
}

@media (max-width: 767px) {
  /* Touch targets.

     The console's chrome is tuned for a mouse: the rail trigger, the header's
     icon buttons and the per-row action buttons are all 32px boxes, which is
     comfortable with a cursor and a coin-flip with a thumb. 44px is the floor
     both platform guidelines give, and this raises only the hit area -- the
     icons, the padding and the desktop density are untouched, because the
     media query already scopes the whole thing to phones.

     Height only for the row-action buttons: they sit in a wrapped flex row
     inside a stacked card, and forcing a min-width there would push two
     buttons onto separate lines for no benefit. */
  header [data-sidebar='trigger'],
  header button.size-8,
  header a.size-8 {
    min-height: 44px;
    min-width: 44px;
  }
  /* Not a switch: it is a button too, and its pill is a fixed 24px by 44px --
     a 44px floor on its height made it taller than wide, which its rounded
     corners drew as a blob. */
  .stacked-table td button:not([role='switch']),
  .stacked-table td a[role='button'] {
    min-height: 44px;
  }

  /* `:not(.stacked-table)` matters: this rule was written for the era when
     every table on a phone was a sideways scroll, and nowrap is what made the
     columns readable inside it. A stacked table has no sideways scroll to be
     readable inside -- each cell is a full-width line -- and nowrap there
     stops long values wrapping, which forces the card wider than the screen
     and brings the horizontal scrollbar back on the six pages whose rows
     carry a sentence: the empty-state cell alone was 479px inside a 325px
     card. */
  .glass-table th,
  .glass-table td,
  .overflow-auto table:not(.stacked-table) th,
  .overflow-auto table:not(.stacked-table) td {
    white-space: nowrap;
    padding-left: 0.7rem;
    padding-right: 0.7rem;
  }
  /* The one column that should still wrap: a truncated payload is already
     capped by its own max-width and reads better clipped than stretched. */
  .glass-table td.truncate {
    white-space: nowrap;
  }
}

/* --------------------------------------------------------------------------
   Touch targets

   The console's dense buttons are 24-28px tall, which is fine for a mouse and
   below every platform minimum for a finger. Raised only for coarse pointers,
   so the desktop density the owner works in all day is untouched.
   -------------------------------------------------------------------------- */
@media (pointer: coarse) {
  .glass-btn,
  .btn-primary,
  .pager-btn,
  .pager-num,
  .glass-input,
  .pager-select {
    min-height: 38px;
  }
  .pager {
    justify-content: center;
  }
}

/* --------------------------------------------------------------------------
   Interaction feedback

   A press that does not acknowledge itself reads as a click that missed --
   which on a slow connection is exactly when an operator clicks again, and
   why a non-idempotent POST got sent twice.
   -------------------------------------------------------------------------- */
.glass-btn:active,
.btn-primary:active,
.pager-btn:not(:disabled):active,
.pager-num:active {
  transform: translateY(1px) scale(0.994);
}

/* Keyboard focus was invisible on every control in the console. `:where()`
   keeps this at zero specificity so any component with its own focus style
   still wins. */
:where(button, a, select, input, textarea, [role='button'], [tabindex]):focus-visible {
  outline: 2px solid var(--brand-500);
  outline-offset: 2px;
}

/* --------------------------------------------------------------------------
   View transitions

   The direct children are animated rather than #view-content itself: the
   container persists across navigations (both the vanilla pages and React
   replace its contents, not the element), so an animation on the container
   would play once on load and never again.

   The global prefers-reduced-motion block above already reduces this to
   0.01ms, so there is nothing extra to opt out of.
   -------------------------------------------------------------------------- */
@keyframes view-enter {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

#view-content > * {
  animation: view-enter 0.24s var(--ease-spring) both;
}

/* --------------------------------------------------------------------------
   Stacked tables

   Every list in this console is a table, and most of them are eight or nine
   columns wide. On a phone that is a card you have to drag sideways to read:
   the order code is visible and the status and the actions are not, so the
   two things an operator opened the page to do are both off-screen.

   Below `md` a table marked `stacked-table` stops being a table. Each row
   becomes a card and each cell becomes one "label: value" line, the label
   coming from the cell's own `data-label` -- which is why the header can be
   hidden without losing what the columns meant.

   One markup, two layouts. The alternative -- a <Card> list for mobile beside
   a <Table> for desktop -- is the same screen written twice, and the second
   copy is the one that stops getting fixed.

   A cell with no `data-label` (an actions column, a checkbox) keeps the whole
   line to itself, which is what those want anyway.
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {
  /* `display: none`, not the visually-hidden clip trick. Making the rows
     `display: block` below already strips the table's semantics from the
     accessibility tree, so a clipped header row carries nothing a screen
     reader would use -- it only leaves an 833px-wide row inside a 1px box for
     every layout probe to trip over. The column names live on the cells now. */
  .stacked-table thead { display: none; }

  .stacked-table,
  .stacked-table tbody,
  .stacked-table tr,
  .stacked-table td {
    display: block;
    width: 100%;
  }

  .stacked-table tr {
    margin-bottom: 0.625rem;
    padding: 0.25rem 0;
    border: 1px solid hsl(var(--border));
    border-radius: 0.875rem;
    background: hsl(var(--card));
  }

  .stacked-table tr:last-child { margin-bottom: 0; }

  .stacked-table td {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    column-gap: 0.75rem;
    row-gap: 0.2rem;
    /* Beats the `max-w-[180px]` / `w-32` utilities some cells carry for the
       desktop layout: a fixed column width is meaningless once the cell is a
       full-width line, and left unchecked it truncates text that now fits. */
    max-width: 100%;
    padding: 0.4rem 0.85rem;
    border: 0;
    text-align: right;
  }

  /* `margin-right: auto` rather than `flex: 1` so the label takes only the
     width of its own text. Growing it instead squeezed every neighbour: a
     status badge next to a long label collapsed to a coloured sliver with its
     text clipped away entirely. */
  .stacked-table td::before {
    content: attr(data-label);
    flex: 0 1 auto;
    margin-right: auto;
    min-width: 0;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: hsl(var(--muted-foreground));
    text-align: left;
  }

  /* Cells that hold a stack of paragraphs -- a name over an id, a figure over
     its discount -- keep them stacked. One line each, not run together. */
  .stacked-table td > p:not(:only-child),
  .stacked-table td > div:not(:only-child) {
    flex-basis: 100%;
  }

  /* No label, no line to share: actions and checkboxes take the full width.
     `data-label=""` counts as no label -- it is how a cell says it is
     deliberately unlabelled rather than accidentally so, which the contract
     suite can then tell apart from an oversight. */
  .stacked-table td:not([data-label])::before,
  .stacked-table td[data-label='']::before { content: none; }

  .stacked-table td:not([data-label]),
  .stacked-table td[data-label=''] {
    justify-content: stretch;
    padding-top: 0.55rem;
    text-align: left;
  }

  /* The empty and loading rows span the table; they are not "label: value". */
  .stacked-table td[colspan] {
    justify-content: center;
    text-align: center;
  }

  .stacked-table td[colspan]::before { content: none; }

  /* A skeleton ROW, stacked, is the one shape this layout gets wrong on its
     own. Half the pages write their loading state as one <TableCell> per
     column rather than a single colSpan row -- which is right on a desktop,
     and on a phone turns six placeholder rows into forty-two full-width grey
     bars: a wall of loading taller than the data it stands in for.
     Three lines per card is the same density the loaded card has.

     Done here rather than in ten page files because it is a property of the
     stacked layout, not of any one page, and because a page that writes its
     skeleton the obvious way should not have to know about this. */
  /* Descendant, not child: some pages wrap the placeholder in a div to stack
     two bars, and those cells are part of the same wall. */
  .stacked-table td:has(.skeleton) {
    padding-top: 0.3rem;
    padding-bottom: 0.3rem;
  }

  .stacked-table td:has(.skeleton):nth-child(n + 4) { display: none; }

  /* `truncate` is a desktop column's answer to a long value: clip it to the
     width of its column. A stacked cell has no column to be too wide for, and
     clipping there loses the end of a transaction hash with nothing to scroll
     -- so it wraps instead. Same reasoning as the max-width override above. */
  .stacked-table td {
    overflow-wrap: anywhere;
  }

  .stacked-table td.truncate,
  .stacked-table td .truncate {
    overflow: visible;
    white-space: normal;
    text-overflow: clip;
  }
}

/* ==========================================================================
   A <details> used as a dropdown

   Radix has no popover in this build and the multi-select the templates
   column needs is not a <select>: it picks SEVERAL, and a native select that
   closes on every pick is the wrong control for that. <details> is already a
   disclosure widget in the browser, so it needs no dependency and no
   outside-click handler -- only its marker removing, which is the browser's
   idea of the control rather than ours.

   Tailwind's `list-none` is not in the vendored subset, so this cannot be
   done in markup.
   ========================================================================== */
.dropdown-summary {
  list-style: none;
}

.dropdown-summary::-webkit-details-marker {
  display: none;
}
