/* ============================================================
   Moscoso Express TMS — Design Tokens & Shared Styles
   ============================================================ */

:root {
  /* Brand Colors — neutral gray-based UI (owner, 2026-07-06). The red Moscoso
     mark is the only saturated brand color; the interface itself stays graphite
     so status/alert colors carry all the meaning. */
  --brand-primary:    #2b2f36;   /* Graphite (side rail) */
  --brand-secondary:  #c00000;   /* Moscoso red (logo) */
  --brand-accent:     #4b5563;   /* Neutral slate-gray action color (was action blue) */
  --brand-accent-dark:#374151;   /* accent hover */

  /* Neutrals */
  --gray-50:   #f9fafb;
  --gray-100:  #f3f4f6;
  --gray-200:  #e5e7eb;
  --gray-300:  #d1d5db;
  --gray-400:  #9ca3af;
  --gray-500:  #6b7280;
  --gray-600:  #4b5563;
  --gray-700:  #374151;
  --gray-800:  #1f2937;
  --gray-900:  #111827;

  /* Status Colors */
  --status-info-received:    #6b7280;
  --status-scheduled:        #2563eb;
  --status-en-route-pu:      #7c3aed;
  --status-at-pickup:        #d97706;
  --status-en-route-del:     #0891b2;
  --status-at-delivery:      #ea580c;
  --status-delivered:        #16a34a;
  --status-exception:        #dc2626;

  /* Alert Colors */
  --alert-critical-bg:     #fef2f2;
  --alert-critical-border: #fca5a5;
  --alert-critical-text:   #991b1b;
  --alert-critical-icon:   #dc2626;

  --alert-warning-bg:      #fffbeb;
  --alert-warning-border:  #fcd34d;
  --alert-warning-text:    #92400e;
  --alert-warning-icon:    #d97706;

  --alert-info-bg:         #f3f4f6;
  --alert-info-border:     #d1d5db;
  --alert-info-text:       #374151;
  --alert-info-icon:       #4b5563;

  /* Surfaces */
  --surface-page:      #f4f4f5;
  --surface-card:      #ffffff;
  --surface-nav:       #2b2f36;
  --surface-nav-dark:  #22252b;
  --surface-sidebar:   #f8fafc;
  --surface-input:     #ffffff;   /* form field fill — white on light, raised gray on dark */

  /* Typography */
  --font-sans:  -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --font-mono:  'SF Mono', 'Fira Code', 'Courier New', monospace;

  --text-xs:   11px;
  --text-sm:   12px;
  --text-base: 13px;
  --text-md:   14px;
  --text-lg:   16px;
  --text-xl:   18px;
  --text-2xl:  22px;
  --text-3xl:  28px;

  /* Spacing */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;

  /* Borders */
  --radius-sm:  4px;
  --radius-md:  6px;
  --radius-lg:  8px;
  --radius-xl:  12px;
  --radius-full: 9999px;

  --border-color: #e5e7eb;
  --border-width: 1px;

  /* Shadows */
  --shadow-sm: 0 1px 2px 0 rgba(0,0,0,0.05);
  --shadow-md: 0 4px 6px -1px rgba(0,0,0,0.07), 0 2px 4px -2px rgba(0,0,0,0.05);
  --shadow-lg: 0 10px 15px -3px rgba(0,0,0,0.08), 0 4px 6px -4px rgba(0,0,0,0.05);
  --shadow-xl: 0 20px 25px -5px rgba(0,0,0,0.1), 0 8px 10px -6px rgba(0,0,0,0.04);

  /* Layout — page-width tiers (Decision 072). Replaces three stale, unused
     tokens (--nav-height / --sidebar-width / --panel-width — the top-nav and
     side-panel patterns were retired for the side rail; their literal values
     are now inlined on the two dormant component rules further down). Every
     constrained page centers #pageRoot at one of these caps.
     Warehouses (locations.html) adopted --page-w-wide on 2026-07-16 (its old
     fixed-width opt-out is retired; row-expansion stability now rides on the
     shared .app-col.page-scroll scrollbar-gutter rule in app.css, not a fixed
     width) — it was the last page opting out of the width standard. */
  --page-w-full:     none;    /* full-bleed operational screens — documents the tier (absence of a max-width) */
  --page-w-wide:     1280px;  /* wide data: dense grids / registries (availability, payroll, geofences, equipment, warehouses) */
  --page-w-standard: 1100px;  /* standard content: reports, admin, summaries (reports, settings, alerts) */
  --page-w-narrow:   640px;   /* narrow self-service forms (security) */
}

/* ── DARK THEME (Decision 073) ─────────────────────────────────
   The complete dark token layer: every semantic token above gets a dark value
   here, so any rule that routes through tokens flips automatically. Rules that
   carry literal light colors get color-only [data-theme="dark"] overrides —
   in this file for this file's own components, in app.css for the app shell
   and the frozen board/drawer (whose 17 pre-existing dark rules chose the
   canonical dark alert washes: crit #3F161B · warn #3A2115 · det #382A12 ·
   late #3B1E14 — the alert tokens below align with those choices).
   Gray-scale meaning is preserved, not the values: --gray-900 stays "strongest
   text" (near-white here), --gray-50 stays "subtlest fill" (near-black).
   Red stays reserved for escalation/error only (owner rule) — the focus ring
   and accents remain slate in dark. Light is the default; this block applies
   only when shared.js/signin.html set data-theme="dark" on <html>. */
[data-theme="dark"] {
  color-scheme: dark;             /* native form controls / scrollbars render dark */

  --brand-accent:      #7e8798;   /* slate action color, brightened for dark surfaces */
  --brand-accent-dark: #929caf;   /* hover: lighter (not darker) against dark bg */

  /* Neutrals — inverted meaning-preserving scale */
  --gray-50:   #20252d;
  --gray-100:  #262c35;
  --gray-200:  #313845;
  --gray-300:  #3e4654;
  --gray-400:  #8b94a3;
  --gray-500:  #98a2b3;
  --gray-600:  #aeb6c2;
  --gray-700:  #c3cad4;
  --gray-800:  #dbe0e7;
  --gray-900:  #f2f4f8;

  /* Status colors — brightened to hold contrast on dark surfaces */
  --status-info-received:    #98a2b3;
  --status-scheduled:        #60a5fa;
  --status-en-route-pu:      #a78bfa;
  --status-at-pickup:        #fbbf24;
  --status-en-route-del:     #22d3ee;
  --status-at-delivery:      #fb923c;
  --status-delivered:        #4ade80;
  --status-exception:        #f87171;

  /* Alert trios — aligned with the board's pre-chosen dark washes */
  --alert-critical-bg:     #3F161B;
  --alert-critical-border: #7f2f38;
  --alert-critical-text:   #f4a9a9;
  --alert-critical-icon:   #f87171;

  --alert-warning-bg:      #382A12;
  --alert-warning-border:  #6b5416;
  --alert-warning-text:    #f5cd7a;
  --alert-warning-icon:    #f59e0b;

  --alert-info-bg:         #262c35;
  --alert-info-border:     #3e4654;
  --alert-info-text:       #c3cad4;
  --alert-info-icon:       #98a2b3;

  /* Surfaces — page darkest, card raised above it */
  --surface-page:      #12151a;
  --surface-card:      #1a1f26;
  --surface-nav:       #101519;   /* matches the rail's chosen dark --sb-bg */
  --surface-nav-dark:  #0b0f13;
  --surface-sidebar:   #171d23;
  --surface-input:     #20252d;   /* form field fill on dark — same as --gray-50 raise */

  --border-color: #333b47;

  /* Shadows — heavier/darker so elevation still reads on dark */
  --shadow-sm: 0 1px 2px 0 rgba(0,0,0,0.5);
  --shadow-md: 0 4px 6px -1px rgba(0,0,0,0.55), 0 2px 4px -2px rgba(0,0,0,0.45);
  --shadow-lg: 0 10px 15px -3px rgba(0,0,0,0.6), 0 4px 6px -4px rgba(0,0,0,0.5);
  --shadow-xl: 0 20px 25px -5px rgba(0,0,0,0.65), 0 8px 10px -6px rgba(0,0,0,0.5);
}

/* Dark overrides for THIS file's literal-color components (color-only; the
   html[data-theme] prefix out-specifies page-local <style> rules of equal
   class count, so the dark value wins the cascade without !important). */
html[data-theme="dark"] .btn-outline { background: var(--surface-card); }
html[data-theme="dark"] .stat-card { background: var(--surface-card); }
html[data-theme="dark"] .milestone-dot.pending { background: var(--surface-card); }
html[data-theme="dark"] .search-input,
html[data-theme="dark"] .select-input { background: var(--gray-50); }
/* Focus ring: the light slate rgba(75,85,99,…) vanishes on dark surfaces —
   brighten the slate (NEVER red; red = error only, owner rule). Same
   !important reasoning as the light rule below. */
html[data-theme="dark"] button:focus-visible,
html[data-theme="dark"] select:focus-visible,
html[data-theme="dark"] input:focus-visible,
html[data-theme="dark"] textarea:focus-visible,
html[data-theme="dark"] .dtr-seg-opt:focus-visible {
  border-color: var(--brand-accent) !important;
  box-shadow: 0 0 0 3px rgba(146, 156, 175, 0.38) !important;
}
/* Return pill: graphite-on-near-black needs an edge to read as a control. */
html[data-theme="dark"] .back-to-index { background: var(--gray-100); border: 1px solid var(--border-color); }
html[data-theme="dark"] .back-to-index:hover { background: var(--gray-200); }

/* ── RESET & BASE ──────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: var(--font-sans);
  font-size: var(--text-base);
  color: var(--gray-800);
  background: var(--surface-page);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--brand-accent); text-decoration: none; }
a:hover { text-decoration: underline; }

button {
  font-family: var(--font-sans);
  cursor: pointer;
  border: none;
  outline: none;
}

/* ── FOCUS-VISIBLE FALLBACK (owner ruling, round-5 UI-specialist finding 1) ──
   The resets above (and the per-field `:focus { outline:none }` rules
   scattered through app.css) strip the native ring so mouse clicks stay
   clean, but that left every button/select/input/textarea with ZERO visual
   change on keyboard focus. This layers `:focus-visible` back on top —
   same voice as the side rail's existing `.rail-item:focus-visible` (2px
   solid, 2px offset) — without touching the `outline:none` resets or the
   mouse-click experience. `!important` is needed because several fields
   (e.g. `.dispatch-select:focus`) set `outline:none` at equal-or-higher
   selector specificity than a bare `button:focus-visible`; the fallback
   has to win regardless of source order. Scoped to the amber Detention
   Review popup (#detOverlay) below, since amber already carries a different
   meaning in that panel (the live accruing clock, `.dtr-live`/
   `.dtr-clock-run`) and that ring there would clash with the meaning.

   FOCUS STYLE (owner directive 2026-07-10): the ring was a 2px SOLID MOSCOSO-
   RED outline (--brand-secondary). On data-entry screens that reads as an
   error on the cell you're simply editing, so it was softened on the
   Warehouses page first, then adopted platform-wide here: no hard outline, a
   calm slate accent border, and a soft slate focus ring (box-shadow). Red is
   freed to mean only what it should — escalation/error — everywhere. */
button:focus-visible,
select:focus-visible,
input:focus-visible,
textarea:focus-visible,
.dtr-seg-opt:focus-visible {
  outline: none !important;
  border-color: var(--brand-accent) !important;
  box-shadow: 0 0 0 3px rgba(75, 85, 99, 0.32) !important;
}
#detOverlay button:focus-visible,
#detOverlay select:focus-visible,
#detOverlay input:focus-visible,
#detOverlay textarea:focus-visible,
#detOverlay .dtr-seg-opt:focus-visible {
  outline: none !important;
  border-color: #D97706 !important;
  box-shadow: 0 0 0 3px rgba(217, 119, 6, 0.30) !important;
}

/* ── TOP NAV ───────────────────────────────────────────────── */
.top-nav {
  height: 56px;  /* was var(--nav-height); token retired (Decision 072). Rule dormant — top-nav replaced by the side rail. */
  background: var(--brand-primary);
  display: flex;
  align-items: center;
  padding: 0 var(--space-5);
  gap: var(--space-4);
  position: sticky;
  top: 0;
  z-index: 100;
  box-shadow: var(--shadow-md);
}

.nav-brand {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: white;
  font-size: var(--text-lg);
  font-weight: 700;
  letter-spacing: -0.3px;
  text-decoration: none;
  white-space: nowrap;
}

.nav-brand .brand-dot {
  width: 8px; height: 8px;
  background: var(--brand-secondary);
  border-radius: var(--radius-full);
}

.nav-tabs {
  display: flex;
  gap: 2px;
  margin-left: var(--space-6);
  flex: 1;
}

.nav-tab {
  padding: var(--space-2) var(--space-3);
  color: rgba(255,255,255,0.7);
  font-size: var(--text-sm);
  font-weight: 500;
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: all 0.15s;
  white-space: nowrap;
  background: transparent;
}

.nav-tab:hover { color: white; background: rgba(255,255,255,0.1); }
.nav-tab.active { color: white; background: rgba(255,255,255,0.15); }

.nav-right {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-left: auto;
}

.nav-clock {
  color: rgba(255,255,255,0.8);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
}

.nav-alert-badge {
  background: var(--brand-secondary);
  color: white;
  font-size: var(--text-xs);
  font-weight: 700;
  padding: 2px 7px;
  border-radius: var(--radius-full);
  cursor: pointer;
}

.nav-avatar {
  width: 30px; height: 30px;
  background: rgba(255,255,255,0.2);
  border-radius: var(--radius-full);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-size: var(--text-sm);
  font-weight: 600;
}

/* ── CARDS ─────────────────────────────────────────────────── */
.card {
  background: var(--surface-card);
  border: var(--border-width) solid var(--border-color);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

.card-header {
  padding: var(--space-4) var(--space-5);
  border-bottom: var(--border-width) solid var(--border-color);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.card-title {
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--gray-900);
}

.card-body { padding: var(--space-4) var(--space-5); }

/* ── STATUS CHIPS ──────────────────────────────────────────── */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: var(--radius-full);
  font-size: var(--text-xs);
  font-weight: 600;
  white-space: nowrap;
}

/* Solid, high-contrast fills so chips stay readable regardless of any row
   tint/stripe behind them (urgency lives on the row, status lives on the chip).
   Every text/fill pair is >= 4.5:1 (WCAG AA, ratio noted per line). Yellow keeps
   dark-on-amber because white-on-yellow can't reach 4.5:1. */
.chip-gray      { background: #4b5563; color: #ffffff; }  /* 7.6:1 */
.chip-blue      { background: #1d4ed8; color: #ffffff; }  /* 6.7:1 */
.chip-purple    { background: #6d28d9; color: #ffffff; }  /* 7.1:1 */
.chip-indigo    { background: #4338ca; color: #ffffff; }  /* 7.5:1 */
.chip-yellow    { background: #fcd34d; color: #451a03; }  /* 10.5:1 */
.chip-orange    { background: #c2410c; color: #ffffff; }  /* 5.8:1 */
.chip-red       { background: #b91c1c; color: #ffffff; }  /* 6.4:1 */
.chip-green     { background: #15803d; color: #ffffff; }  /* 5.0:1 */
.chip-teal      { background: #0f766e; color: #ffffff; }  /* 5.5:1 */
.chip-cyan      { background: #0e7490; color: #ffffff; }  /* 5.3:1 */

.chip-dot::before {
  content: '';
  display: inline-block;
  width: 6px; height: 6px;
  border-radius: var(--radius-full);
  background: currentColor;
}

/* ── ALERT ITEMS ───────────────────────────────────────────── */
.alert-item {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  border-left: 3px solid;
  margin-bottom: var(--space-2);
}

.alert-critical { background: var(--alert-critical-bg); border-color: var(--alert-critical-icon); }
.alert-warning  { background: var(--alert-warning-bg);  border-color: var(--alert-warning-icon); }
.alert-info     { background: var(--alert-info-bg);     border-color: var(--alert-info-icon); }

.alert-icon { font-size: 16px; flex-shrink: 0; margin-top: 1px; }
.alert-title { font-size: var(--text-sm); font-weight: 600; color: var(--gray-900); }
.alert-message { font-size: var(--text-xs); color: var(--gray-600); margin-top: 2px; }
.alert-meta { font-size: var(--text-xs); color: var(--gray-400); margin-top: 4px; }

/* ── MILESTONE TIMELINE ────────────────────────────────────── */
.milestone-bar {
  display: flex;
  align-items: center;
  gap: 0;
  width: 100%;
}

.milestone-step {
  flex: 1;
  display: flex;
  align-items: center;
}

.milestone-dot {
  width: 20px; height: 20px;
  border-radius: var(--radius-full);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 10px;
  border: 2px solid;
  position: relative;
  z-index: 1;
}

.milestone-dot.complete  { background: #16a34a; border-color: #16a34a; color: white; }
.milestone-dot.active    { background: #2563eb; border-color: #2563eb; color: white; animation: pulse 1.5s ease-in-out infinite; }
.milestone-dot.pending   { background: white;   border-color: #d1d5db; color: #9ca3af; }

.milestone-line {
  flex: 1;
  height: 2px;
  background: #e5e7eb;
}
.milestone-line.complete { background: #16a34a; }

@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(37,99,235,0.4); }
  50%       { box-shadow: 0 0 0 4px rgba(37,99,235,0); }
}

/* ── BUTTONS ───────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 6px 14px;
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  font-weight: 500;
  cursor: pointer;
  transition: all 0.15s;
  border: var(--border-width) solid transparent;
  white-space: nowrap;
}

.btn-primary  { background: var(--brand-accent); color: white; }
.btn-primary:hover { background: var(--brand-accent-dark); }

.btn-danger   { background: #dc2626; color: white; }
.btn-danger:hover { background: #b91c1c; }

.btn-outline  { background: white; border-color: var(--border-color); color: var(--gray-700); }
.btn-outline:hover { background: var(--gray-50); }

.btn-ghost    { background: transparent; color: var(--gray-600); }
.btn-ghost:hover { background: var(--gray-100); color: var(--gray-800); }

.btn-sm { padding: 4px 10px; font-size: var(--text-xs); }
.btn-lg { padding: 10px 20px; font-size: var(--text-md); }

/* ── TABLES ────────────────────────────────────────────────── */
.tms-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.tms-table th {
  background: var(--gray-50);
  color: var(--gray-500);
  font-size: var(--text-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: var(--space-2) var(--space-3);
  text-align: left;
  border-bottom: 2px solid var(--border-color);
  white-space: nowrap;
}
.tms-table td {
  padding: var(--space-2) var(--space-3);
  border-bottom: var(--border-width) solid var(--border-color);
  vertical-align: middle;
  color: var(--gray-700);
}
.tms-table tr:hover td { background: var(--gray-50); cursor: pointer; }
.tms-table tr:last-child td { border-bottom: none; }

/* ── STAT CARDS ────────────────────────────────────────────── */
.stat-card {
  background: white;
  border: var(--border-width) solid var(--border-color);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.stat-label { font-size: var(--text-xs); color: var(--gray-500); font-weight: 500; text-transform: uppercase; letter-spacing: 0.5px; }
.stat-value { font-size: var(--text-2xl); font-weight: 700; color: var(--gray-900); line-height: 1.2; }
.stat-sub   { font-size: var(--text-xs); color: var(--gray-500); }

.stat-card.critical { border-left: 4px solid var(--alert-critical-icon); }
.stat-card.warning  { border-left: 4px solid var(--alert-warning-icon); }
.stat-card.positive { border-left: 4px solid #16a34a; }

/* ── PANELS / DRAWERS ──────────────────────────────────────── */
.side-panel {
  width: 360px;      /* was var(--panel-width); token retired (Decision 072). Rule dormant. */
  min-width: 360px;
  background: white;
  border-left: var(--border-width) solid var(--border-color);
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
}

.panel-header {
  padding: var(--space-4) var(--space-5);
  border-bottom: var(--border-width) solid var(--border-color);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.panel-close {
  width: 28px; height: 28px;
  background: var(--gray-100);
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 14px;
  color: var(--gray-500);
  border: none;
}
.panel-close:hover { background: var(--gray-200); }

.panel-body {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-4) var(--space-5);
}

/* ── FORM INPUTS ───────────────────────────────────────────── */
.search-input {
  width: 100%;
  padding: 6px 10px 6px 32px;
  border: var(--border-width) solid var(--border-color);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  font-family: var(--font-sans);
  background: white;
  color: var(--gray-800);
  outline: none;
}
.search-input:focus { border-color: var(--brand-accent); box-shadow: 0 0 0 2px rgba(37,99,235,0.15); }

.select-input {
  padding: 6px 10px;
  border: var(--border-width) solid var(--border-color);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  font-family: var(--font-sans);
  background: white;
  color: var(--gray-700);
  cursor: pointer;
  outline: none;
}
.select-input:focus { border-color: var(--brand-accent); }

/* ── SECTION HEADERS ───────────────────────────────────────── */
.section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-3);
}

.section-title {
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--gray-900);
}

.section-label {
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  color: var(--gray-400);
  margin-bottom: var(--space-2);
}

/* ── DATA LABELS ───────────────────────────────────────────── */
.data-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 4px 0;
  gap: var(--space-3);
}

.data-label { font-size: var(--text-xs); color: var(--gray-500); white-space: nowrap; }
.data-value { font-size: var(--text-sm); color: var(--gray-800); font-weight: 500; text-align: right; }

/* ── SCROLLBAR ─────────────────────────────────────────────── */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--gray-300); border-radius: var(--radius-full); }
::-webkit-scrollbar-thumb:hover { background: var(--gray-400); }

/* ── UTILITIES ─────────────────────────────────────────────── */
.flex { display: flex; }
.flex-col { display: flex; flex-direction: column; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-1 { gap: var(--space-1); }
.gap-2 { gap: var(--space-2); }
.gap-3 { gap: var(--space-3); }
.gap-4 { gap: var(--space-4); }
.flex-1 { flex: 1; }
.text-xs { font-size: var(--text-xs); }
.text-sm { font-size: var(--text-sm); }
.text-md { font-size: var(--text-md); }
.text-lg { font-size: var(--text-lg); }
.font-500 { font-weight: 500; }
.font-600 { font-weight: 600; }
.font-700 { font-weight: 700; }
.color-gray { color: var(--gray-500); }
.color-muted { color: var(--gray-400); }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nowrap { white-space: nowrap; }
.w-full { width: 100%; }
.mt-1 { margin-top: var(--space-1); }
.mt-2 { margin-top: var(--space-2); }
.mt-3 { margin-top: var(--space-3); }
.mt-4 { margin-top: var(--space-4); }
.mb-2 { margin-bottom: var(--space-2); }
.mb-3 { margin-bottom: var(--space-3); }
.mb-4 { margin-bottom: var(--space-4); }
.p-3 { padding: var(--space-3); }
.p-4 { padding: var(--space-4); }
.hidden { display: none !important; }
.pointer { cursor: pointer; }

/* ── RETURN LINK ───────────────────────────────────────────── */
.back-to-index {
  position: fixed;
  bottom: 16px;
  right: 16px;
  background: var(--brand-primary);
  color: white;
  padding: 8px 16px;
  border-radius: var(--radius-full);
  font-size: var(--text-xs);
  font-weight: 600;
  text-decoration: none;
  box-shadow: var(--shadow-lg);
  z-index: 9999;
  transition: background 0.15s;
}
.back-to-index:hover { background: #0f2039; text-decoration: none; }
