/* ===== Tempo Tracer (golf swing analyzer): base theme =====
   Deep green, cream and gold on a dark background, so the navy and red
   club lines stay easy to see. Colours live here as variables. */

:root {
  --bg: #0c1511;
  --bg-2: #101c16;
  --panel: #14231b;
  --panel-2: #1a2d22;
  --line: #24392d;
  --line-2: #2f4a3a;
  --cream: #f1ead6;
  --text: #e4e3d6;
  --muted: #98a597;
  --gold: #c9a54a;
  --gold-2: #e0c06c;
  --green: #2a6b48;
  --green-2: #348357;
  --navy: #1f3fa8;
  --red: #b3121f;
  --danger: #ff8a80;
  --ok: #9fd3a8;
  --radius: 12px;
  --serif: "Playfair Display", Georgia, serif;
  --sans: Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

html {
  min-height: 100%;
  background:
    radial-gradient(1200px 600px at 20% -10%, #17301f 0%, transparent 60%) no-repeat,
    var(--bg);
}
body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--sans);
  font-size: 14px;
  color: var(--text);
  background: transparent;
  display: flex;
  flex-direction: column;
}

/* ===== Mode visibility ===== */
body.user-mode .admin-only { display: none !important; }
/* The public website has no Admin mode at all (see PUBLIC_SITE in app.js) */
body.public-site .mode-switch { display: none !important; }

/* ===== Footer (privacy line) ===== */
/* Small version tag at the end of the footer line */
.site-version {
  display: inline-block;
  margin-left: 10px;
  padding: 1px 7px;
  border: 1px solid currentColor;
  border-radius: 999px;
  font-size: 0.68rem;
  letter-spacing: .04em;
  opacity: .7;
  vertical-align: 1px;
}
.site-footer {
  padding: 14px 24px 22px;
  text-align: center;
  font-size: 0.78rem;
  color: var(--muted);
}

/* ===== Your swing (in the top bar): file name, Analyze, Add swing ===== */
.swing-bar { display: flex; align-items: center; gap: 12px; margin-left: auto; min-width: 0; }
.swing-bar .btn { flex: none; padding: 8px 16px; }
@media (max-width: 760px) {
  .topbar { flex-wrap: wrap; }
  .swing-bar { order: 3; flex: 1 1 100%; margin-left: 0; }
}

/* ===== Top bar ===== */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 24px;
  background: linear-gradient(180deg, #123020, #0f2419);
  border-bottom: 1px solid #c9a54a33;
}
.brand { display: flex; align-items: center; gap: 12px; color: var(--gold); }
/* The clubhouse logo is wide (96 × 67), so it's sized by height */
.brand-mark { width: auto; height: 56px; flex: none; margin: -6px 0; } /* bigger, without making the top bar taller */
/* The logo only shows in a full-size window (the user's choice); in a
   smaller window it's hidden and just the name shows. */
@media (max-width: 1279px) {
  .brand-mark { display: none; }
}
.brand-mark .lf { fill: var(--panel); }             /* walls, roof, trees: filled */
.brand-mark .brand-accent { stroke: var(--gold); }  /* smokestack bands and smoke */
.brand-mark .la { fill: var(--gold); }              /* the bell */
.brand h1 {
  margin: 0;
  font-family: var(--serif);
  font-weight: 700;
  font-size: 1.45rem;
  letter-spacing: 0.02em;
  color: var(--cream);
}
/* A line in the accent colour under the name (red in Scorecard), where the
   tagline used to be */
.brand h1::after {
  content: "";
  display: block;
  height: 2px;
  margin-top: 5px;
  background: var(--gold);
}

.mode-switch {
  display: flex;
  background: #0a1510;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  padding: 3px;
}
.mode-btn {
  font: 600 0.82rem var(--sans);
  letter-spacing: 0.04em;
  border: 0;
  border-radius: 999px;
  padding: 6px 16px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
}
.mode-btn.active { background: var(--gold); color: #1b1607; }
.mode-btn:not(.active):hover { color: var(--cream); }
body.admin-mode .topbar { border-bottom-color: #ff8a8055; }

/* ===== Layout: video left, sidebar right ===== */
.layout {
  flex: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: 20px;
  padding: 20px 24px 28px;
  align-items: start;
  max-width: 1500px;
  width: 100%;
  margin: 0 auto;
}
@media (max-width: 960px) {
  .layout { grid-template-columns: minmax(0, 1fr); padding: 16px; }
}
@media (max-width: 600px) {
  .topbar { padding: 12px 16px; }
  .brand h1 { font-size: 1.15rem; }
  .dropzone { min-height: 50vh; }
  /* On a phone every video fills the full width (swings stack, so the
     boxes line up exactly and you scroll down from one to the next) */
  .viewer-row, .viewer-row.comparing { align-items: stretch; }
  .viewer-row .players > .player, .viewer-row.comparing .players > .player { width: 100%; max-width: 100%; }
  .stage { align-self: stretch !important; width: 100%; }
  .stage video { width: 100%; height: auto; max-height: none; }
}

.viewer { display: flex; flex-direction: column; gap: 12px; min-width: 0; }

/* ===== Welcome / drop zone ===== */
.dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 60vh;
  padding: 32px 20px;
  border: 1.5px dashed #c9a54a66;
  border-radius: var(--radius);
  background: linear-gradient(180deg, #13241b, #0e1a14);
  text-align: center;
  cursor: pointer;
  transition: border-color .15s, background .15s;
}
.dropzone:hover, .dropzone.over { border-color: var(--gold); background: linear-gradient(180deg, #172c20, #10201a); }
.dropzone input { display: none; }
.dropzone svg { width: 54px; height: 54px; color: var(--gold); margin-bottom: 6px; }
.dz-title { font-family: var(--serif); font-size: 1.6rem; color: var(--cream); }
.dz-sub { color: var(--muted); }
.dz-tips {
  list-style: none;
  margin: 18px 0 6px;
  padding: 14px 18px;
  border-top: 1px solid var(--line);
  color: var(--text);
  display: grid;
  gap: 6px;
  text-align: left;
}
.dz-tips li::before { content: "\26F3"; margin-right: 8px; }
.dz-private { color: var(--muted); font-size: 0.8rem; }

/* ===== Videos ("players") =====
 * Each player is a column: a name bar with its "Show" menu, the video, and
 * its own playback controls. The stage box shrinks to the video's exact
 * size, so there are no black bars and the canvas on top lines up with the
 * video. Beside the main player is either the "Add swing" slot or the
 * second swing's player. */
.viewer-row {
  display: flex;
  gap: 20px;
  align-items: stretch;
  min-width: 0;
}
.viewer-row[hidden] { display: none; }
/* One video: centred, hugging its own size. The big empty "Add swing" box
   is gone; the "+ Add swing" button in the top bar does that job. */
.viewer-row { justify-content: center; }
.compare-slot { display: none !important; }

.player { display: flex; flex-direction: column; gap: 8px; flex: 0 1 auto; min-width: 0; }
.player[hidden] { display: none; }
/* The bar and controls take the video's width but don't widen the column
   (width 0 + min-width 100%), so the column is exactly as wide as the video. */
.player > .player-head, .player > .controls { width: 0; min-width: 100%; }
.player > .stage { align-self: flex-start; max-width: 100%; }

.player-head { display: flex; align-items: center; gap: 10px; font-size: 0.85rem; min-height: 30px; }
.compare-tempo { color: var(--gold); font-weight: 700; white-space: nowrap; font-variant-numeric: tabular-nums; }

.stage {
  position: relative;
  flex: 0 1 auto;
  min-width: 0;
  line-height: 0;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  overflow: hidden;
  box-shadow: 0 10px 30px #0008;
  background: #000;
}
.stage.editing { cursor: crosshair; }
/* The video can be dragged off the tracer (see "Pull the video off" in app.js) */
#stage:not(.editing) video { cursor: grab; }
.stage video { display: block; max-width: 100%; max-height: 72vh; }

/* While analyzing: the held frame, a see-through dark shade over it, and
   the progress box in the middle */
.analyze-shade {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: grid;
  place-items: center;
  line-height: normal;
}
.analyze-shade[hidden] { display: none; }
.analyze-shade canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.analyze-shade::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: rgba(8, 12, 24, 0.6);
}
.shade-box {
  position: relative;
  z-index: 2;
  width: min(80%, 320px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  color: #fff;
  text-align: center;
}
.shade-label { font: 700 1.05rem var(--sans); letter-spacing: .04em; }
.shade-box progress { width: 100%; height: 10px; }
.shade-text { font-size: 0.82rem; opacity: .85; font-variant-numeric: tabular-nums; }
.shade-box .btn { padding: 6px 18px; background: transparent; color: #fff; border-color: #ffffff88; }
.shade-box .btn:hover { border-color: #fff; }

/* Toggle bar across the top of each video: what to draw on it */
.toggle-bar {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
}
.toggle-bar .switch { flex: none; gap: 8px; font-size: 0.82rem; }
.toggle-bar .switch > span { flex: none; }
.toggle-bar .switch input[type="checkbox"] { width: 30px; height: 17px; }
.toggle-bar .switch input[type="checkbox"]::after { top: 2.5px; left: 2.5px; width: 12px; height: 12px; }
.toggle-bar .switch input[type="checkbox"]:checked::after { transform: translateX(13px); }
.compare-x {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  border: 1px solid var(--line-2); background: transparent; color: var(--muted);
  font-size: 1.1rem; line-height: 1; cursor: pointer;
}
.compare-x:hover { color: var(--cream); border-color: var(--gold); }

/* The "Add swing" slot: clickable once a swing is analyzed */
.compare-slot {
  flex: 1 1 0;
  min-width: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 20px;
  border: 1.5px dashed #c9a54a33;
  border-radius: var(--radius);
  background: linear-gradient(180deg, #13241b66, #0e1a1466);
  text-align: center;
  color: var(--muted);
  cursor: pointer;
  transition: border-color .15s, background .15s;
}
.compare-slot[hidden] { display: none; }
.compare-slot svg { width: 46px; height: 46px; color: #c9a54a88; margin-bottom: 4px; }
.compare-slot input, .add-swing input { display: none; }
.compare-slot:hover:not(.waiting) { border-color: var(--gold); }
.compare-slot.waiting { cursor: default; }
.compare-slot.waiting .cs-title { opacity: .5; }
.cs-title { font-family: var(--serif); font-size: 1.25rem; color: var(--cream); opacity: .75; }
.cs-sub { font-size: 0.82rem; }
.add-swing { cursor: pointer; }

/* Two swings side by side, each at most half the row */
.viewer-row.comparing { justify-content: center; }
.viewer-row.comparing .players > .player { max-width: calc(50% - 10px); }
/* Swing 1 (already analyzed) stays on the LEFT; the swing you add and
   analyze next (the main player) shows on the right. */
.viewer-row.comparing .players > .compare-view { order: -1; }

/* Two swings side by side get IDENTICAL frames: each is half the row wide and
   the same height (sized to the screen, leaving room for the controls). The
   video sits centred inside its frame without being stretched, and the drawing
   canvas is fitted the same way, so the lines stay on the picture. A tall clip
   and a wide clip just get dark bars on different sides. */
@media (min-width: 1101px) {
  .viewer-row.comparing .players > .player { flex: 1 1 0; max-width: none; }
  .viewer-row.comparing .player > .player-head,
  .viewer-row.comparing .player > .controls { width: auto; min-width: 0; }
  .viewer-row.comparing .player > .stage {
    align-self: stretch;
    width: 100%;
    height: clamp(340px, calc(100vh - 195px), 900px);
  }
  .viewer-row.comparing .stage video,
  .viewer-row.comparing .stage canvas { width: 100%; height: 100%; max-height: none; object-fit: contain; }
}

/* Not enough room side by side (wide clips, small windows): drop the empty
   slot, and stack two swings. */
@media (max-width: 1100px) {
  .compare-slot { display: none; }
  .viewer-row { justify-content: center; }
  .viewer-row.comparing { flex-direction: column; align-items: center; }
  .viewer-row.comparing .players > .player { max-width: 100%; }
}

/* Legend: one slim row under the videos (hidden until a video is loaded) */
.legend-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 24px; padding: 4px 0; }
.viewer-row[hidden] ~ .legend-row { display: none; }
.stage canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* ===== Playback bar (one per player) =====
   Row 1: the slider with Address / Top / Impact markers.
   Row 2: previous, play, next, then the time and speed on the right.
   Under it, the swing's tempo section (see "Tempo" below). */
.controls {
  display: flex;
  flex-direction: column;
  gap: 4px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 6px 12px 10px;
}
.controls-row { display: flex; align-items: center; gap: 10px; }
.controls-row .frame-label { margin-left: auto; }
.link-switch { flex: none; gap: 8px; font-size: 0.8rem; }
.icon-btn, .play-btn {
  display: grid;
  place-items: center;
  border: 0;
  cursor: pointer;
  color: var(--cream);
}
.icon-btn { width: 38px; height: 38px; border-radius: 10px; background: var(--panel-2); }
.icon-btn:hover:not(:disabled) { background: var(--line-2); }
.icon-btn svg { width: 22px; height: 22px; }
.play-btn { width: 48px; height: 48px; border-radius: 50%; background: var(--gold); color: #1b1607; }
.play-btn:hover:not(:disabled) { background: var(--gold-2); }
.play-btn svg { width: 24px; height: 24px; }
.play-btn .i-pause, .play-btn.playing .i-play { display: none; }
.play-btn.playing .i-pause { display: block; }
.icon-btn:disabled, .play-btn:disabled { opacity: .4; cursor: not-allowed; }

.scrub { position: relative; flex: 1; padding-top: 14px; }
.markers { position: absolute; left: 9px; right: 9px; top: 0; height: 14px; pointer-events: none; }
.marker {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  white-space: nowrap;
  line-height: 1;
}
.marker::after {
  content: "";
  display: block;
  width: 2px;
  height: 8px;
  margin: 2px auto 0;
  background: currentColor;
  border-radius: 1px;
}
.marker.mk-address { color: var(--cream); }
.marker.mk-top { color: #6f8cff; }
.marker.mk-impact { color: #ff5a64; }

input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 6px;
  border-radius: 3px;
  background: var(--line-2);
  outline: none;
  margin: 8px 0;
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: var(--cream);
  border: 3px solid var(--gold);
  cursor: pointer;
}
input[type="range"]::-moz-range-thumb {
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--cream);
  border: 3px solid var(--gold);
  cursor: pointer;
}
.frame-label {
  min-width: 64px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--cream);
  font-weight: 600;
}
.frame-label small { display: block; color: var(--muted); font-weight: 400; font-size: 0.72rem; }

/* ===== Status line ===== */
.status {
  margin: 0;
  padding: 10px 14px;
  border-radius: 10px;
  background: #0f1d16;
  border: 1px solid var(--line);
  color: var(--ok);
  font-size: 0.88rem;
  line-height: 1.45;
}
.status.error { color: var(--danger); border-color: #ff8a8044; }
/* User mode: no message line ("Video loaded: … frames") unless something
   went wrong. Admin mode still shows every message. */
body.user-mode .status:not(.error) { display: none; }

/* File name in "Your swing": click it to pick a different video */
.video-name { display: flex; align-items: baseline; gap: 8px; cursor: pointer; font-size: 0.85rem; min-width: 0; }
.video-name input { display: none; }
.video-name[hidden] { display: none; }
.vn-change { color: var(--gold); font-size: 0.78rem; text-decoration: underline; text-underline-offset: 2px; flex: none; }
.video-name:hover .vn-change { color: var(--gold-2); }

/* Key moments as three small jump buttons under the tempo */
.moments-mini { grid-template-columns: repeat(3, 1fr); gap: 6px; margin-top: 2px; }
.moments-mini .moment {
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
  padding: 6px 8px;
  font-size: 0.74rem;
  position: relative;
}
.moments-mini .m-dot { position: absolute; top: 8px; right: 8px; width: 7px; height: 7px; }
.moments-mini .m-name { color: var(--muted); }
.moments-mini .m-time { font-size: 0.9rem; font-weight: 600; color: var(--cream); }

/* ===== Sidebar cards ===== */
.sidebar { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.results-group { display: contents; }
.card {
  background: linear-gradient(180deg, var(--panel), #12201a);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.card.admin-only { border-color: #ff8a8030; }
.card h2 {
  margin: 0 0 2px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold);
}
.card.admin-only h2::after {
  content: "ADMIN";
  margin-left: 8px;
  padding: 1px 6px;
  border-radius: 4px;
  font-size: 0.6rem;
  color: #ffb3ab;
  background: #ff8a8022;
}
.muted { color: var(--muted); }
.small { font-size: 0.8rem; margin: 0; line-height: 1.45; }

/* ===== Buttons ===== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: 1px solid transparent;
  border-radius: 10px;
  padding: 10px 14px;
  font: 600 0.9rem var(--sans);
  cursor: pointer;
  text-decoration: none;
  transition: background .15s, border-color .15s;
}
.btn-gold { background: var(--gold); color: #1b1607; flex: 1; }
.btn-gold:hover:not(:disabled) { background: var(--gold-2); }
.btn-ghost { background: var(--panel-2); color: var(--cream); border-color: var(--line-2); }
.btn-ghost:hover:not(:disabled) { border-color: var(--gold); }
.btn:disabled { background: #222c26; color: #6b766d; border-color: transparent; cursor: not-allowed; }
.btn-sm { padding: 7px 10px; font-size: 0.8rem; flex: 1; }
.btn-full { width: 100%; }
.btn-row { display: flex; gap: 8px; flex-wrap: wrap; }
.file-btn input { display: none; }
.file-btn:has(input:disabled) { opacity: .5; cursor: not-allowed; }

/* ===== Progress ===== */
progress {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 8px;
  border: 0;
  border-radius: 4px;
  background: var(--line);
  overflow: hidden;
}
progress::-webkit-progress-bar { background: var(--line); border-radius: 4px; }
progress::-webkit-progress-value { background: linear-gradient(90deg, var(--green-2), var(--gold)); border-radius: 4px; }
progress::-moz-progress-bar { background: linear-gradient(90deg, var(--green-2), var(--gold)); }

/* ===== Key moments ===== */
.moments { display: grid; gap: 6px; }
.moment {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--line-2);
  background: var(--panel-2);
  color: var(--cream);
  font: 500 0.92rem var(--sans);
  cursor: pointer;
  text-align: left;
}
.moment:hover:not(:disabled) { border-color: var(--gold); }
.moment.current { border-color: var(--gold); background: #2a3a24; }
.moment:disabled { opacity: .5; cursor: default; }
.m-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; }
.m-address { background: var(--cream); }
.m-top { background: var(--navy); box-shadow: 0 0 0 2px #6f8cff55; }
.m-impact { background: var(--red); box-shadow: 0 0 0 2px #ff5a6455; }
.m-name { flex: 1; }
.m-time { color: var(--muted); font-variant-numeric: tabular-nums; font-size: 0.82rem; }

/* ===== Tempo section under each video =====
   The ratio and the two times on top, the bar, then the key moments
   (click to jump there) and a short note. */
.player-tempo {
  width: 0; min-width: 100%;  /* as wide as the video, never wider */
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 12px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.pt-top { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.pt-top .tempo-times { flex: 0 1 260px; }
.player-tempo .tempo-ratio small { margin-top: 4px; }
.player-tempo .small { font-size: 0.74rem; }

/* ===== Tempo (pieces) ===== */
.tempo { display: flex; flex-direction: column; gap: 10px; }
.tempo-ratio { display: flex; flex-direction: column; }
.tempo-value { font-family: var(--serif); font-size: 2.3rem; font-weight: 700; color: var(--cream); line-height: 1.05; }
.tempo-ratio small { margin-top: 6px; color: var(--muted); font-size: 0.72rem; letter-spacing: .08em; text-transform: uppercase; }
.tempo-bar { display: flex; height: 8px; border-radius: 4px; overflow: hidden; background: var(--line); }
.tb-back { background: var(--navy); transition: width .3s; }
.tb-down { background: var(--red); transition: width .3s; }
.tempo-times { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.tempo-times > div { display: flex; flex-direction: column; gap: 2px; padding: 8px 10px; border-radius: 8px; background: var(--panel-2); }
.tt-label { font-size: 0.74rem; color: var(--muted); display: flex; align-items: center; gap: 6px; }
.tt-val { font-size: 1.15rem; font-weight: 600; color: var(--cream); font-variant-numeric: tabular-nums; }
.tempo-value.empty, .tt-val.empty { color: #4d5d52; font-family: var(--sans); font-weight: 400; }

/* small colour swatches */
.sw { display: inline-block; flex: none; width: 18px; height: 4px; border-radius: 2px; }
.sw-back { background: var(--navy); }
.sw-down { background: var(--red); }
.sw-grad { background: linear-gradient(90deg, var(--navy) 55%, var(--red)); }
.sw-hands { background: #ff3b30; }
.sw-ai { background: #00ffff; }
.sw-body { background: linear-gradient(90deg, #4cc9f0 50%, #ff4d8d 50%); }
.sw-found { background: linear-gradient(90deg, #1faa59 55%, #ff8c00); }
.sw-dot-navy { width: 10px; height: 10px; border-radius: 50%; background: var(--navy); border: 1.5px solid #fff; }

/* ===== Toggle switches (styled checkboxes) ===== */
.switch {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  color: var(--text);
  line-height: 1.3;
}
.switch > span { flex: 1; }
.switch input[type="checkbox"] {
  -webkit-appearance: none;
  appearance: none;
  flex: none;
  width: 36px;
  height: 20px;
  margin: 0;
  border-radius: 999px;
  background: #33433a;
  position: relative;
  cursor: pointer;
  transition: background .15s;
}
.switch input[type="checkbox"]::after {
  content: "";
  position: absolute;
  top: 3px; left: 3px;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: #cfd4cc;
  transition: transform .15s, background .15s;
}
.switch input[type="checkbox"]:checked { background: var(--green-2); }
.switch input[type="checkbox"]:checked::after { transform: translateX(16px); background: var(--cream); }
.switch input[type="checkbox"]:disabled { opacity: .45; cursor: not-allowed; }
.switch input[type="checkbox"]:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* ===== Theme picker (Admin) ===== */
.theme-picker { display: grid; gap: 6px; }
.theme-chip {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 7px 10px; text-align: left; cursor: pointer;
  font: inherit; color: var(--text); background: transparent;
  border: 1px solid var(--line-2); border-radius: var(--radius);
}
.theme-chip > span:nth-child(2) { flex: 1; }
.theme-chip small { color: var(--muted); }
.theme-chip:hover { border-color: var(--gold); }
.theme-chip.active { border-color: var(--gold); box-shadow: inset 0 0 0 1px var(--gold); font-weight: 600; }
.swatch { flex: none; width: 30px; height: 18px; border-radius: 4px; border: 1px solid #ffffff40;
  background: linear-gradient(90deg, var(--b) 55%, var(--a) 55%); }

/* ===== Fields ===== */
.settings-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 22px; }
.field { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.field > span { color: var(--text); }
input[type="number"], select {
  padding: 6px 8px;
  border-radius: 8px;
  border: 1px solid var(--line-2);
  background: #0f1b15;
  color: var(--cream);
  font: inherit;
}
input[type="number"] { width: 80px; }
.controls select { padding: 6px 6px; }
.slider-row { display: flex; align-items: center; gap: 10px; }
.slider-row input[type="range"] { flex: 1; }
.pill {
  min-width: 26px;
  text-align: center;
  padding: 2px 6px;
  border-radius: 6px;
  background: var(--panel-2);
  color: var(--cream);
  font-size: 0.8rem;
}

/* ===== Legend ===== */
.legend span { display: flex; align-items: center; gap: 10px; font-size: 0.82rem; color: #c3c9bf; }
.legend i.ln { display: inline-block; width: 24px; height: 4px; border-radius: 2px; flex: none; }
.legend i.dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; flex: none; margin: 0 7px; }

/* ===== Tracker stats (admin) ===== */
.stats { display: flex; flex-direction: column; gap: 10px; font-size: 0.8rem; }
.stats h3 {
  margin: 4px 0 0;
  font-size: 0.68rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
}
.stats dl {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 3px 10px;
  margin: 0;
}
.stats dt { color: var(--muted); }
.stats dd { margin: 0; text-align: right; color: var(--cream); font-variant-numeric: tabular-nums; }
.stats dd.warn { color: #ffcc66; }
.stats dd.bad { color: var(--danger); }
.stats .frames-list {
  font-family: ui-monospace, Consolas, monospace;
  font-size: 0.74rem;
  color: #c3c9bf;
  word-break: break-word;
}
.stats .bar { display: flex; height: 6px; border-radius: 3px; overflow: hidden; background: var(--line); }
.stats .bar span { display: block; }
