/* =====================================================================
 * gt7-kit.css — canonical design tokens + component classes
 *
 * Single source of truth shared between gt7-ui-kit.html and the live app
 * pages. Mirror any addition/change in BOTH places — the kit file inlines
 * an identical copy of these blocks for its standalone preview, and the
 * app pages link this file directly so they always pick up the latest
 * token values without a duplication step.
 *
 * Sections:
 *   1. Tokens (:root)
 *   2. Buttons (.btn, .btn-*, .icon-btn-*)
 *   3. Inputs (.input, .select, .textarea, .check, .radio, .switch, .slider)
 *   4. Pills + badges + tags + delta pills + severity badges
 *   5. Toggle group (.toggle-group .tog)
 *   6. Cards + glass cards + stat cards
 *   7. Tabs (.tabs .tab)
 *   8. Table (.table)
 *   9. Modal (.modal-mock)
 *  10. Toasts (.toast)
 *  11. Empty state (.empty)
 *  12. Progress + spinner + skeleton (loaders)
 *  13. Live-stat-row + lap-chip helpers
 *  14. Pagination buttons (.page-btn for Sessions list)
 * ===================================================================== */

/* ─── 1. Tokens ─────────────────────────────────────────────────── */
/* Source of truth: the admin Design panel (admin.html #panel-design).
 * Any colour added there must be mirrored here, in gt7-ui-kit.html's
 * inline :root block, and in gt7-redesign-mockup.html's :root block.
 * Surfaces (background / card / card-2) follow the digit-edge brand
 * "Elevation" scale; channel accents are the official telemetry
 * palette; tire bands are the six anchor colours that the live
 * gt7-tire-bands.js gradient interpolates between.
 */
:root {
  /* Surfaces — brand Elevation scale */
  --background: #09162d;   /* Navy        — page bg */
  --elev-1:    #0d1c38;    /* Elevation 1 — popovers, table strips */
  --elev-2:    #112344;    /* Elevation 2 — card bg */
  --card:      #0d1c38;    /* alias of --elev-1 (primary card surface) */
  --card-2:    #112344;    /* alias of --elev-2 (raised card surface) */
  --popover:   #112344;
  --muted:     #0d1c38;
  --foreground:  #e2e8f0;
  --muted-fg:    #64748b;
  --slate-300:   #cbd5e1;
  --slate-400:   #94a3b8;

  /* Brand colours (digit-edge) */
  --brand-blue:  #409ed7;
  --brand-red:   #cd202d;
  --brand-amber: #ffb432;
  --brand-green: #2fc980;
  --brand-purple:#6052c8;

  /* Primary + state aliases */
  --primary:      var(--brand-blue);
  --primary-fg:   #ffffff;
  --destructive:  var(--brand-red);
  --border:        rgba(64,158,215,0.15);
  --border-strong: rgba(64,158,215,0.30);
  --ring:          rgba(64,158,215,0.4);

  /* Telemetry channel colours — canonical from Design panel */
  --c-throttle: #2fc980;   /* same as brand-green */
  --c-brake:    #cd202d;   /* same as brand-red */
  --c-steer:    #409ed7;   /* same as brand-blue (was a378bfa, now standardised) */
  --c-speed:    #ffb432;   /* same as brand-amber */
  --c-gear:     #6052c8;   /* same as brand-purple */
  --c-yellow:   #e1ca17;   /* secondary speed/rpm yellow accent */
  --c-delta:    #a855f7;   /* purple delta line (chart-only) */
  /* Legacy aliases — keep so existing class rules don't break */
  --c-green: var(--c-throttle);
  --c-red:   var(--c-brake);
  --c-blue:  var(--c-steer);

  /* Severity badges */
  --sev-high: #ef4444;
  --sev-mid:  var(--brand-amber);
  --sev-low:  #94a3b8;

  /* Tire-temp bands — 6 anchors; gt7-tire-bands.js interpolates between */
  --tire-cold:        #1d85f6;  /* < 60 °C */
  --tire-sub-optimal: #06b6d4;  /* 60–75 */
  --tire-optimal:     #21c45d;  /* 75–85 */
  --tire-warm:        #e1ca17;  /* 85–95 */
  --tire-hot:         #f97316;  /* 95–110 */
  --tire-overheating: #ef4343;  /* 110+ */

  /* Radii — sharp & geometric */
  --r-sm: 2px;
  --r-md: 6px;
  --r-lg: 10px;
  --r-xl: 14px;

  /* Spacing scale (4 px grid) */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
}

/* Tire-band utility classes — drop one of these on any element and it
 * inherits the matching anchor colour via `currentColor`. The tire card,
 * gauge ring, and tag chip in the mockup all reference these. */
.is-cold        { --tire-band: var(--tire-cold);        color: var(--tire-cold); }
.is-sub-optimal { --tire-band: var(--tire-sub-optimal); color: var(--tire-sub-optimal); }
.is-optimal     { --tire-band: var(--tire-optimal);     color: var(--tire-optimal); }
.is-warm        { --tire-band: var(--tire-warm);        color: var(--tire-warm); }
.is-hot         { --tire-band: var(--tire-hot);         color: var(--tire-hot); }
.is-overheating { --tire-band: var(--tire-overheating); color: var(--tire-overheating); }

/* Numeric / "mono" text — Inter + tabular-nums.
 * The app deliberately uses Inter for both prose and numbers (its Tailwind
 * config maps font-mono to Inter), and `font-variant-numeric: tabular-nums`
 * gives every digit the same advance width so lap-time columns align
 * cleanly without switching to a true monospace face. JetBrains Mono /
 * Consolas were tried earlier in the kit + mockup but mismatched the live
 * app's typography. Anchor the canonical look here so the kit, mockup,
 * and the live pages all render identical numbers.
 *
 * Use `.mono` on any element whose digits should align column-by-column
 * (table cells, lap-time chips, ID strings). It inherits font-family from
 * the page so prose stays Inter; only the digit metrics change.
 */
.mono,
code,
kbd,
samp {
  font-family: 'Inter', system-ui, sans-serif;
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* ─── 2. Buttons ────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: var(--r-md);
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: all 0.15s;
  border: 1px solid transparent;
  background: transparent;
  color: var(--foreground);
  white-space: nowrap;
  /* Explicit line-height so every .btn computes the same height. Without
     it, icon-ONLY buttons (e.g. the Library globe link) size from the
     material-icons line box (14px) instead of the text line box (~18px)
     and come out 4px shorter than their text siblings in the same row. */
  line-height: 18px;
  /* And an explicit height, so a page's own font size or line height
     cannot make its buttons 2px taller than the next page's: 36px, the
     height of a field. */
  height: 36px; padding-top: 0; padding-bottom: 0; box-sizing: border-box;
}
.btn .material-icons { font-size: 14px; line-height: 18px; }
.btn:disabled { opacity: 0.4; cursor: not-allowed; }
.btn-primary { background: var(--primary); color: var(--primary-fg); }
.btn-primary:hover:not(:disabled) { background: #409ed7; }
.btn-primary:active:not(:disabled) { background: #2d8cc3; }
/* The button beside the primary one. There were two of these - a filled
   .btn-secondary and this - and no rule for choosing, so a page got
   whichever its author had copied. One name now. */
.btn-outline { border-color: var(--border-strong); color: var(--foreground); }
.btn-outline:hover:not(:disabled) { background: rgba(64,158,215,0.08); border-color: var(--primary); }
.btn-ghost { color: var(--slate-400); }
.btn-ghost:hover:not(:disabled) { background: rgba(255,255,255,0.05); color: var(--foreground); }
.btn-danger { background: var(--destructive); color: white; }
.btn-danger:hover:not(:disabled) { background: #ff5b5b; }
.btn-success { background: var(--c-green); color: white; }
.btn-success:hover:not(:disabled) { background: #2dd66e; }
.btn-sm { padding: 0 10px; height: 26px; font-size: 11px; line-height: 16px; }
.btn-sm .material-icons { font-size: 12px; line-height: 16px; }
.btn-lg { padding: 0 20px; height: 44px; font-size: 14px; line-height: 20px; }
.btn-lg .material-icons { font-size: 16px; line-height: 20px; }

/* Icon buttons */
.icon-btn-sq {
  width: 28px; height: 28px;
  border-radius: var(--r-md);
  background: transparent;
  border: 1px solid var(--border);
  color: var(--slate-400);
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: all 0.15s;
}
.icon-btn-sq:hover { background: rgba(255,255,255,0.05); color: var(--foreground); border-color: var(--border-strong); }
.icon-btn-sq:disabled { opacity: 0.4; cursor: not-allowed; }
.icon-btn-sq .material-icons { font-size: 14px; }
.icon-btn-sq.is-active { background: rgba(64,158,215,0.18); border-color: var(--primary); color: var(--primary); }

.icon-btn-bare {
  width: 24px; height: 24px;
  border-radius: 4px;
  background: transparent;
  border: none;
  color: var(--muted-fg);
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: all 0.15s;
}
.icon-btn-bare:hover { background: rgba(255,255,255,0.05); color: var(--foreground); }
.icon-btn-bare .material-icons { font-size: 14px; }

/* ─── 3. Inputs ───────────────────────────────────────────────────
 * The selector lists below intentionally pair the TAG with the CLASS
 * (e.g. `input.input`, `select.select`) instead of using just `.input`
 * etc. The pages load Tailwind's `forms` plugin from the CDN, which
 * ships a preflight stylesheet that targets every `<input>` with
 * `[type='text']:not([type='button']):not(...)` etc. and paints them
 * white. That preflight beats a bare `.input` rule on specificity, so
 * the inputs in Settings (and anywhere else using `.input` on a text
 * field) rendered as white boxes against the dark page. Adding the
 * tag part bumps the specificity above the preflight without needing
 * `!important`, so the dark card-2 background sticks. */
input.input, select.select, textarea.textarea,
.input, .select, .textarea {
  width: 100%;
  padding: 8px 12px;
  /* A field is as tall as a button (36px), so a row of both lines up. */
  height: 36px;
  box-sizing: border-box;
  padding-top: 0; padding-bottom: 0; line-height: 34px;
  background: var(--card-2);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  color: var(--foreground);
  font-family: inherit;
  font-size: 12px;
  outline: none;
  transition: all 0.15s;
}
textarea.textarea, .textarea { height: auto; padding-top: 8px; padding-bottom: 8px; line-height: 1.45; }
input.input:focus, select.select:focus, textarea.textarea:focus,
.input:focus, .select:focus, .textarea:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--ring);
}
input.input::placeholder, textarea.textarea::placeholder,
.input::placeholder, .textarea::placeholder { color: var(--muted-fg); }
.textarea { min-height: 80px; resize: vertical; font-family: inherit; }
/* `<input type="date">` honours OS-level form-control theming via the
 * `color-scheme` property. Without this Chrome paints the day/month/year
 * spinners + the dropdown calendar with light-mode native styling, which
 * shows as a white box-within-the-box on top of our dark .input
 * background. `color-scheme: dark` flips those native pieces to a
 * dark palette so the whole control reads as one cohesive dark field. */
input[type="date"].input,
input[type="time"].input,
input[type="datetime-local"].input,
input[type="month"].input,
input[type="week"].input {
  color-scheme: dark;
}
/* The calendar picker icon ships as a black SVG which disappears on
 * a dark background. Invert it so it reads as a light grey chevron
 * that matches the placeholder colour. */
input[type="date"].input::-webkit-calendar-picker-indicator,
input[type="time"].input::-webkit-calendar-picker-indicator,
input[type="datetime-local"].input::-webkit-calendar-picker-indicator {
  filter: invert(0.7) brightness(0.9);
  cursor: pointer;
  opacity: 0.7;
}
input[type="date"].input::-webkit-calendar-picker-indicator:hover,
input[type="time"].input::-webkit-calendar-picker-indicator:hover,
input[type="datetime-local"].input::-webkit-calendar-picker-indicator:hover {
  opacity: 1;
}
/* Every native piece the system draws - the list a select opens, a
   number field's spinner, the date picker, the scrollbars - takes its
   light or dark from color-scheme, and nothing set it: Chromium painted a
   white list under a dark field. On <html>, so every control on every
   page gets it at once (the Light theme sets light). The options take
   the field's colours where the platform honours them. */
html { color-scheme: dark; }
select option { background: var(--card-2); color: var(--foreground); }
/* At select.select too, so the right padding beats the field rule's
   (select.select { padding: 0 12px }) and the text stays clear of the chevron. */
select.select, .select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 32px;
}
/* A control sitting in a row of buttons rather than in a form column.
   The width:100% above is right for a form and wrong in a toolbar, where it
   takes the whole line and pushes every control after it onto the next one.
   Written at two classes so it beats the width utilities regardless of which
   stylesheet the page loads last - the bug this fixes was exactly that. */
.input.input-inline, .select.input-inline, .textarea.input-inline { width: auto; }

/* A picker button (the Library's and Telemetry's Track / Car): a field
   that opens a list. One width whatever name it shows - the name is cut
   with an ellipsis and the chevron stays put, so the fields beside it do
   not move when a longer track is picked. */
.tev-filter-track-btn, .tev-filter-car-btn { width: 220px; min-width: 0; flex: none; }
.tev-filter-track-btn > span:first-child, .tev-filter-car-btn > span:first-child { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tev-filter-track-btn > .material-icons, .tev-filter-car-btn > .material-icons { flex: none; }

/* The segmented control: one choice out of a few, side by side. The
   kit's field (36px, the inner fill, the hairline) holding 28px segments;
   the chosen one is button blue with white text - the same mark as the
   Recording page's Telemetry | Video tabs, so "on" looks the same
   everywhere. The Leaderboard's filters are the reference. */
.seg { display: inline-flex; align-items: center; height: 36px; box-sizing: border-box; background: var(--card-2); border: 1px solid var(--border); border-radius: var(--r-md); padding: 3px; gap: 2px; }
.seg button {
  font: inherit; font-size: 12px; font-weight: 600; color: var(--slate-400); background: transparent;
  border: none; border-radius: 4px; height: 28px; padding: 0 12px; cursor: pointer; white-space: nowrap;
}
.seg button:hover { color: var(--foreground); }
.seg button.on { background: var(--primary); color: var(--primary-fg); }
/* A lap time, wherever it stands - the Library's Best lap, the loaded lap
   in the Telemetry bar, a recording's best: the page's face, 13px,
   semibold, tabular figures. One style, so the same time never looks
   like two. */
.gt7-time { font-family: inherit; font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; letter-spacing: 0; }

/* The side rail: a page's sections down the left, the Admin's rail for
   everyone - the Manual's chapters, the Overlays' kinds and link options.
   Sticky under the bar, as tall as the window, groups with a small label,
   items 34px with an icon, the current one in the primary tint. */
.gt7-siderail { width: 220px; flex: 0 0 220px; position: sticky; top: var(--gt7-header-h, 3.5rem); align-self: flex-start; height: calc(100vh - var(--gt7-header-h, 3.5rem)); display: flex; flex-direction: column; background: var(--card); border-right: 1px solid var(--border); z-index: 30; min-width: 0; }
.gt7-siderail-groups { flex: 1 1 auto; overflow-y: auto; overflow-x: hidden; padding: 10px 0 8px; scrollbar-width: none; }
.gt7-siderail-groups::-webkit-scrollbar { display: none; }
.gt7-siderail-group { padding: 4px 0 2px; }
.gt7-siderail-group + .gt7-siderail-group { border-top: 1px solid rgba(255,255,255,0.05); margin-top: 4px; }
.gt7-siderail-lbl { height: 16px; padding: 0 20px; margin: 4px 0 2px; font-size: 10px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--muted-fg); white-space: nowrap; overflow: hidden; }
.gt7-siderail-item { display: flex; align-items: center; gap: 12px; width: calc(100% - 16px); margin: 1px 8px; padding: 0 10px 0 12px; height: 34px; border-radius: 8px; border: 1px solid transparent; background: transparent; color: var(--slate-400); font: inherit; font-size: 13px; font-weight: 600; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; text-decoration: none; }
.gt7-siderail-item .material-icons { font-size: 20px; flex-shrink: 0; }
.gt7-siderail-item:hover { color: var(--foreground); background: rgba(255,255,255,0.04); }
.gt7-siderail-item.active { color: var(--primary); background: rgba(64,158,215,0.12); border-color: rgba(64,158,215,0.35); }
/* A field in the rail: the label over the control, the control full width. */
.gt7-siderail-field { display: flex; flex-direction: column; gap: 4px; margin: 4px 16px 8px; font-size: 11px; color: var(--slate-400); }
.gt7-siderail-field > .material-icons { display: none; }
.gt7-siderail-field > span { font-size: 10px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--muted-fg); }
.gt7-siderail-field .select { max-width: none !important; width: 100%; }
.gt7-siderail-check { display: flex; align-items: center; gap: 8px; margin: 4px 16px 8px; font-size: 12px; color: var(--slate-400); cursor: pointer; }
.gt7-siderail-check > .material-icons { font-size: 16px; color: var(--muted-fg); }
@media (max-width: 900px) { .gt7-siderail { position: static; height: auto; width: 100%; flex-basis: auto; } }

/* A filter strip: the controls of a list, on a card, 36px each, 8px apart.
   The Library's sessions filters and the Leaderboard's are this. */
.filter-strip { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 12px 16px; }
.filter-strip .f-label { font-size: 10px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--muted-fg); margin-left: 4px; }
.filter-strip .select.input-inline, .filter-strip .input.input-inline { width: 180px; }

.input-with-icon { position: relative; }
.input-with-icon .input { padding-left: 32px; }
.input-with-icon .input-icon {
  position: absolute;
  left: 10px; top: 50%;
  transform: translateY(-50%);
  color: var(--muted-fg);
  pointer-events: none;
}
.input-with-icon .input-icon .material-icons { font-size: 14px; }
.label { display: block; font-size: 10px; font-weight: 600; color: var(--muted-fg); letter-spacing: 0.08em; text-transform: uppercase; margin-bottom: 6px; }
.help { font-size: 11px; color: var(--muted-fg); margin-top: 4px; }

/* Every checkbox and radio is the kit's, wherever it stands. Tailwind's
   forms plugin (compiled in) already takes the native look off them,
   but left a white box and its own blue; this is the field's fill, the
   hairline, the app's primary when on, and the ring in the app's colour.
   Where a page wraps one in .check / .radio the rules below draw the
   mark themselves; elsewhere the plugin's tick and dot stay. */
input[type="checkbox"], input[type="radio"] {
  width: 16px; height: 16px; flex-shrink: 0; margin: 0;
  background-color: var(--card-2); border: 1px solid var(--border-strong); color: var(--primary);
  border-radius: 4px; cursor: pointer;
  --tw-ring-color: var(--ring); --tw-ring-offset-color: var(--background);
}
input[type="radio"] { border-radius: 50%; }
input[type="checkbox"]:checked, input[type="radio"]:checked { background-color: var(--primary); border-color: var(--primary); }
input[type="checkbox"]:disabled, input[type="radio"]:disabled { opacity: 0.45; cursor: not-allowed; }
/* A number field's spinner, a colour field's swatch, a file field's
   button: the app's, not the system's. */
input[type="number"]::-webkit-inner-spin-button, input[type="number"]::-webkit-outer-spin-button { opacity: 0.6; }
input[type="color"] { appearance: none; -webkit-appearance: none; width: 36px; height: 36px; padding: 3px; background: var(--card-2); border: 1px solid var(--border); border-radius: var(--r-md); cursor: pointer; }
input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
input[type="color"]::-webkit-color-swatch { border: 0; border-radius: 4px; }
input[type="file"]::file-selector-button { font: inherit; font-size: 12px; font-weight: 600; color: var(--foreground); background: var(--card-2); border: 1px solid var(--border); border-radius: var(--r-md); padding: 6px 12px; margin-right: 10px; cursor: pointer; }
input[type="file"]::file-selector-button:hover { border-color: var(--border-strong); }
/* A range without the kit's class is the kit's slider all the same. */
input[type="range"] { -webkit-appearance: none; appearance: none; height: 4px; background: var(--muted); border-radius: 2px; outline: none; }
input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 14px; height: 14px; background: var(--primary); border-radius: 50%; cursor: pointer; border: 2px solid var(--background); }
.check { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: 12px; }
.check input { appearance: none; width: 16px; height: 16px; border: 1px solid var(--border-strong); border-radius: 4px; background: var(--card-2); position: relative; cursor: pointer; flex-shrink: 0; }
.check input:checked { background: var(--primary); border-color: var(--primary); }
.check input:checked::after { content: ''; position: absolute; top: 2px; left: 5px; width: 4px; height: 8px; border: solid white; border-width: 0 2px 2px 0; transform: rotate(45deg); }

.radio { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: 12px; }
.radio input { appearance: none; width: 16px; height: 16px; border: 1px solid var(--border-strong); border-radius: 50%; background: var(--card-2); position: relative; cursor: pointer; flex-shrink: 0; }
.radio input:checked { border-color: var(--primary); }
.radio input:checked::after { content: ''; position: absolute; top: 3px; left: 3px; width: 8px; height: 8px; border-radius: 50%; background: var(--primary); }

.switch {
  position: relative;
  width: 36px; height: 20px;
  background: var(--card-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  transition: all 0.15s;
  flex-shrink: 0;
}
.switch::after {
  content: '';
  position: absolute;
  top: 2px; left: 2px;
  width: 14px; height: 14px;
  background: var(--slate-400);
  border-radius: 50%;
  transition: all 0.2s;
}
.switch.on { background: var(--primary); border-color: var(--primary); }
.switch.on::after { left: 18px; background: white; }

.slider {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 4px;
  background: var(--muted);
  border-radius: 2px;
  outline: none;
}
.slider::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 14px; height: 14px;
  background: var(--primary);
  border-radius: 50%;
  cursor: pointer;
  border: 2px solid var(--background);
}

/* ─── 4. Pills / badges / tags ──────────────────────────────────── */
.pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 12px;
  border-radius: var(--r-lg);
  border: 1px solid var(--border);
  background: transparent;
  color: var(--muted-fg);
  font-size: 11px; font-weight: 600;
  cursor: pointer;
  transition: all 0.15s;
  white-space: nowrap;
}
.pill .pill-dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
.pill:hover { color: var(--foreground); }
.pill.pill-delta.active    { color: var(--c-delta);  border-color: rgba(168,85,247,0.4); background: rgba(168,85,247,0.1); }
.pill.pill-speed.active    { color: var(--c-speed);    border-color: rgba(255,180,50,0.4); background: rgba(255,180,50,0.1); }
.pill.pill-throttle.active { color: var(--c-throttle); border-color: rgba(47,201,128,0.4); background: rgba(47,201,128,0.1); }
.pill.pill-brake.active    { color: var(--c-brake);    border-color: rgba(205,32,45,0.4);  background: rgba(205,32,45,0.1); }
.pill.pill-steer.active    { color: var(--c-steer);    border-color: rgba(64,158,215,0.4); background: rgba(64,158,215,0.1); }
.pill.pill-gear.active     { color: var(--c-gear);     border-color: rgba(96,82,200,0.4);  background: rgba(96,82,200,0.1); }

.delta-pill {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 10px;
  border-radius: var(--r-md);
  border: 1px solid;
  font-size: 11px; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.delta-pill .label { color: var(--muted-fg); font-size: 10px; }
.delta-pill.loss    { border-color: rgba(239,67,67,0.3); background: rgba(239,67,67,0.1); color: var(--destructive); }
.delta-pill.gain    { border-color: rgba(33,196,93,0.3); background: rgba(33,196,93,0.1); color: var(--c-green); }
.delta-pill.neutral { border-color: var(--border);       background: transparent;        color: var(--muted-fg); }

.badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 10px; font-weight: 600;
  letter-spacing: 0.04em;
  border: 1px solid;
}
.badge .dot-pulse { width: 6px; height: 6px; border-radius: 50%; animation: kit-pulse 1.6s ease-in-out infinite; }
@keyframes kit-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }
.badge-connected    { color: var(--c-green);    background: rgba(33,196,93,0.1); border-color: rgba(33,196,93,0.3); }
.badge-recording    { color: var(--destructive);background: rgba(239,67,67,0.1); border-color: rgba(239,67,67,0.3); }
.badge-disconnected { color: var(--muted-fg);   background: var(--muted);        border-color: var(--border); }
.badge-warning      { color: var(--sev-mid);    background: rgba(245,158,11,0.1); border-color: rgba(245,158,11,0.3); }
/* Purple variant — paired with `.badge` for the screenshot CTA and
 * any other small action that should read as a pill rather than a
 * square icon button. Matches the brand purple from --c-gear /
 * --brand-purple so it tonally fits next to the green "Connected"
 * badge. */
.badge-purple       { color: var(--brand-purple); background: rgba(96,82,200,0.1); border-color: rgba(96,82,200,0.3); }
/* Clickable badges (buttons / anchors that adopt `.badge` styling)
 * pick up a subtle hover lift — backgrounds intensify by a small
 * factor without changing colour. Lets the screenshot pill feel
 * interactive without losing its "this is a status chip" look. */
button.badge, a.badge { cursor: pointer; transition: background 0.15s ease, border-color 0.15s ease; }
button.badge-purple:hover, a.badge-purple:hover { background: rgba(96,82,200,0.18); border-color: rgba(96,82,200,0.5); }
button.badge-connected:hover, a.badge-connected:hover { background: rgba(33,196,93,0.18); border-color: rgba(33,196,93,0.5); }

.sev-badge {
  display: inline-flex; align-items: center;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 10px; font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.sev-badge.high   { color: var(--sev-high); background: rgba(239,68,68,0.18); }
.sev-badge.medium { color: var(--sev-mid);  background: rgba(245,158,11,0.18); }
.sev-badge.low    { color: var(--sev-low);  background: rgba(148,163,184,0.18); }

.tag {
  display: inline-flex;
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 10px; font-weight: 700;
  letter-spacing: 0.06em;
}
.tag-best    { background: rgba(64,158,215,0.2); color: var(--primary); }
.tag-invalid { background: var(--muted);         color: var(--muted-fg); }

/* ─── 5. Toggle group ───────────────────────────────────────────── */
.toggle-group {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  overflow: hidden;
}
.toggle-group .tog {
  padding: 4px 12px;
  font-size: 10px; font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--muted-fg);
  background: transparent;
  border: none;
  border-right: 1px solid var(--border);
  cursor: pointer;
  transition: all 0.15s;
  text-transform: capitalize;
  font-family: inherit;
}
.toggle-group .tog:last-child { border-right: none; }
.toggle-group .tog:hover { color: var(--foreground); }
.toggle-group .tog.active { background: rgba(64,158,215,0.15); color: var(--primary); }

/* ─── 6. Cards ──────────────────────────────────────────────────── */
.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.card-glass {
  background: rgba(64,158,215,0.04);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(64,158,215,0.18);
  border-radius: var(--r-lg);
  padding: 16px;
}
.card-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 16px;
  border-bottom: 1px solid var(--border);
}
.card-header-title {
  font-size: 10px; font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--slate-400);
}
.card-body { padding: 16px; }

.stat-card { padding: 16px; }
.stat-label { font-size: 10px; color: var(--muted-fg); letter-spacing: 0.1em; text-transform: uppercase; margin-bottom: 6px; }
.stat-value { font-size: 32px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
.stat-unit  { font-size: 12px; color: var(--muted-fg); margin-left: 4px; }
.stat-delta { font-size: 11px; margin-top: 4px; font-weight: 600; }

/* Apex card — the elevated, lightly-glassy panel used on the Home modules +
 * hero and the Overlays catalogue. A clearly DEFINED surface (visibly lighter
 * than the page bg) with a hairline border, a top-edge highlight (::before),
 * and a real drop shadow so it reads as a card, not a faint outline. Anchors
 * with this class (clickable tiles) brighten + deepen on hover. */
.apex-glass {
  background: linear-gradient(135deg, rgba(20, 38, 71, 0.9) 0%, rgba(13, 28, 56, 0.94) 100%);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 10px;
  position: relative;
  overflow: hidden;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.30);
}
.apex-glass::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.12), transparent);
  pointer-events: none;
}
a.apex-glass { transition: border-color 0.15s ease, box-shadow 0.15s ease; }
a.apex-glass:hover { border-color: rgba(93, 189, 240, 0.40); box-shadow: 0 8px 22px rgba(0, 0, 0, 0.42); }

/* ─── 7. Tabs ───────────────────────────────────────────────────── */
.tabs {
  display: flex; gap: 0;
  border-bottom: 1px solid var(--border);
}
.tab {
  padding: 10px 16px;
  font-size: 12px; font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--muted-fg);
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  cursor: pointer;
  transition: all 0.15s;
  font-family: inherit;
}
.tab:hover { color: var(--foreground); border-bottom-color: var(--border); }
.tab.active { color: var(--primary); border-bottom-color: var(--primary); }

/* ─── 8. Tables ─────────────────────────────────────────────────── */
/* A table is .gt7-table, in gt7-shell.css. There was a .table here too,
   describing the same object and disagreeing about every part of it: 10px
   headers against 11px, 12px cells against 13px, 14px of side padding
   against 12, a blue-tinted hairline against a white one, a grey hover
   against a blue one. It was worn by one element in either repo — the
   swatch that existed to show it off — so it is gone rather than
   reconciled. */
.row-indicator { display: inline-block; width: 3px; height: 16px; background: var(--primary); border-radius: 0 2px 2px 0; vertical-align: middle; }

.page-btn {
  min-width: 28px; height: 28px;
  padding: 0 6px;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  background: transparent;
  color: var(--foreground);
  font-family: inherit;
  font-size: 11px; font-weight: 600;
  cursor: pointer;
  transition: background 120ms, border-color 120ms;
}
.page-btn:hover { background: rgba(255,255,255,0.04); border-color: rgba(64,158,215,0.35); }
.page-btn-active { background: var(--primary); border-color: var(--primary); color: white; }
.page-btn-active:hover { background: var(--primary); }

/* ─── 9. Modal ──────────────────────────────────────────────────── */
.modal-mock {
  max-width: 480px;
  background: var(--card);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-xl);
  box-shadow: 0 16px 48px rgba(0,0,0,0.5);
  overflow: hidden;
}
.modal-head { display: flex; align-items: center; justify-content: space-between; padding: 16px 20px; border-bottom: 1px solid var(--border); }
.modal-title { font-size: 14px; font-weight: 600; }
.modal-body { padding: 20px; color: var(--muted-fg); font-size: 13px; line-height: 1.6; }
.modal-foot { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 20px; border-top: 1px solid var(--border); }

/* ─── 10. Toasts ────────────────────────────────────────────────── */
.toast {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 12px 16px;
  background: var(--card);
  border: 1px solid var(--border);
  border-left-width: 3px;
  border-radius: var(--r-md);
  box-shadow: 0 4px 16px rgba(0,0,0,0.3);
  min-width: 320px;
}
.toast .material-icons { font-size: 18px; flex-shrink: 0; margin-top: 1px; }
.toast-title { font-size: 12px; font-weight: 600; margin: 0 0 2px; }
.toast-msg   { font-size: 11px; color: var(--muted-fg); margin: 0; }
.toast.success { border-left-color: var(--c-green); }
.toast.success .material-icons { color: var(--c-green); }
.toast.error   { border-left-color: var(--destructive); }
.toast.error   .material-icons { color: var(--destructive); }
.toast.warning { border-left-color: var(--sev-mid); }
.toast.warning .material-icons { color: var(--sev-mid); }
.toast.info    { border-left-color: var(--primary); }
.toast.info    .material-icons { color: var(--primary); }

/* ─── 11. Empty state ───────────────────────────────────────────── */
.empty {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  text-align: center;
  padding: 40px 24px;
  color: var(--muted-fg);
  border: 1px dashed rgba(100,116,139,0.4);
  border-radius: var(--r-lg);
}
.empty .material-icons { font-size: 36px; margin-bottom: 8px; color: var(--slate-400); }
.empty p { font-size: 12px; margin: 0; max-width: 280px; line-height: 1.6; }

/* ─── 12. Loaders ───────────────────────────────────────────────── */
.progress { width: 100%; height: 4px; background: var(--muted); border-radius: 2px; overflow: hidden; }
.progress-bar { height: 100%; background: var(--primary); border-radius: 2px; }

.spinner {
  width: 18px; height: 18px;
  border: 2px solid var(--muted);
  border-top-color: var(--primary);
  border-radius: 50%;
  animation: kit-spin 0.8s linear infinite;
  display: inline-block;
}
@keyframes kit-spin { to { transform: rotate(360deg); } }

.skeleton {
  background: linear-gradient(90deg, var(--muted) 0%, rgba(64,158,215,0.08) 50%, var(--muted) 100%);
  background-size: 200% 100%;
  animation: kit-shimmer 1.6s linear infinite;
  border-radius: 4px;
}
@keyframes kit-shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }

/* ─── 13. Helpers ───────────────────────────────────────────────── */
.live-stat-row {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px;
  background: var(--card-2);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  font-size: 11px;
}
.live-stat-row .label { color: var(--muted-fg); }
.live-stat-row .value { font-weight: 600; }

.lap-chip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 12px;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  background: var(--card-2);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}
.lap-chip .label { color: var(--muted-fg); }

/* =====================================================================
 * 15. Container colour unification layer
 *
 * The app's pages were written with scattered Tailwind utility-class
 * backgrounds (bg-slate-800/50, bg-slate-900/80, bg-black/30, etc.)
 * that produce subtly different shades on different pages. This
 * section overrides those common Tailwind utilities with the kit's
 * canonical surface tokens (--card / --card-2) and border token
 * (--border) so every panel across the app reads as the same Navy
 * Elevation scale defined in the admin Design panel.
 *
 * Naming note: Tailwind generates classes like `.bg-slate-800\/50`
 * — the forward slash is escaped in CSS. The Play CDN injects
 * these styles at runtime, sometimes AFTER this stylesheet loads,
 * so the overrides below use `!important` to win the cascade. The
 * Tailwind utilities aren't marked important, so a regular
 * `!important` is enough — no need to escalate further.
 *
 * What we DON'T override:
 *   • Channel + chart colours (text-chart-green, text-chart-red,
 *     etc.) — those carry telemetry semantics.
 *   • Brand-tinted accents kept deliberately for affordance:
 *     bg-primary/5  (very-faint hint cards), bg-primary/10
 *     (active sidebar item), bg-primary/15-20 (active tab/toggle).
 *   • Status badges and severity badges — kit classes (.badge-*,
 *     .sev-badge-*) own those colours.
 * ===================================================================== */

/* Neutral card surfaces — slate-800-family (most common) → --card-2
 * (the raised Elevation 2 surface). Catches `bg-slate-800/40`,
 * `bg-slate-800/50`, `bg-slate-800/60` which all collapse to the
 * same intent: "raised content card on the page bg." */
.bg-slate-800\/40,
.bg-slate-800\/50,
.bg-slate-800\/60,
.bg-slate-800\/80,
.bg-slate-800\/95 { background-color: var(--card-2) !important; }

/* Deeper slate-900 family → --card (Elevation 1). These are the
 * tones used for inputs, info-bar wells, lap-list rows, and any
 * other "container sitting against the bg" surface. */
.bg-slate-900\/30,
.bg-slate-900\/40,
.bg-slate-900\/50,
.bg-slate-900\/60,
.bg-slate-900\/80,
.bg-slate-900\/95 { background-color: var(--card) !important; }

/* Black-tinted overlays (bg-black/30/40/50) were used for inset
 * canvas wraps and panel wells. They lived BETWEEN the page bg and
 * --card visually, so we ramp them to --card — slightly above the
 * page surface, matching the Elevation scale. */
.bg-black\/20,
.bg-black\/30,
.bg-black\/40,
.bg-black\/50 { background-color: var(--card) !important; }

/* Background-dark already resolves to #09162d in the Tailwind config,
 * which equals --background. Just here for completeness in case the
 * config drifts. */
.bg-background-dark,
.dark\:bg-background-dark { background-color: var(--background) !important; }

/* Border tokens — every "primary tint, low alpha" border collapses
 * to --border (rgba(64,158,215,0.15)) so the divider treatment is
 * uniform. */
.border-primary\/5,
.border-primary\/10,
.border-primary\/15,
.border-primary\/20 { border-color: var(--border) !important; }

/* Slate borders → kit border too. Catches the outline-button border
 * (border-slate-600/60), filter dividers (border-slate-500/40),
 * and friends. Hover states already have their own brand-tinted
 * border in the kit classes, so the static state can safely
 * unify here. */
.border-slate-500\/40,
.border-slate-600\/40,
.border-slate-600\/60,
.border-slate-700\/50 { border-color: var(--border) !important; }

/* Slate-700 icon-button backgrounds (the "w-6 h-6 rounded bg-slate-
 * 700/60" icon-square style used as inline action buttons in the
 * Coach and Driving toolbars) → --card-2 so they sit on the same
 * surface scale as the .icon-btn-sq kit class. */
.bg-slate-700\/40,
.bg-slate-700\/60,
.bg-slate-700\/80 { background-color: var(--card-2) !important; }
