/* ══════════════════════════════════════════════════════
   VISIST.AI  ·  Annotation Portal  ·  Premium UI v3
   ══════════════════════════════════════════════════════ */

/* ─── Tokens ──────────────────────────────────────────── */
:root {
  /* Palette */
  --green: #2ecc71;
  --green-dark: #1aa659;
  --green-glow: rgba(46, 204, 113, 0.25);
  --green-dim: rgba(46, 204, 113, 0.12);

  --teal: #00d4b8;
  --teal-dim: rgba(0, 212, 184, 0.15);

  --blue: #3b9eff;
  --blue-dim: rgba(59, 158, 255, 0.15);
  --blue-glow: rgba(59, 158, 255, 0.22);

  --amber: #f5a623;
  --danger: #ff5f5f;
  --success: #2ecc71;

  /* Backgrounds */
  --bg: #010b13;
  --bg-1: #041018;
  --bg-2: #061420;
  --bg-3: #081a28;

  /* Glass surfaces */
  --surface: rgba(8, 22, 38, 0.75);
  --surface-2: rgba(10, 26, 44, 0.85);
  --surface-hover: rgba(12, 30, 52, 0.9);

  /* Borders */
  --border: rgba(255, 255, 255, 0.07);
  --border-lit: rgba(255, 255, 255, 0.13);
  --border-green: rgba(46, 204, 113, 0.35);

  /* Text */
  --t1: #f0f8ff;
  --t2: #8eafc5;
  --t3: #4e6a80;

  /* Spacing */
  --gap: 0.9rem;

  /* Radius */
  --r-sm: 8px;
  --r-md: 14px;
  --r-lg: 22px;
  --r-xl: 30px;

  /* Transitions */
  --ease: cubic-bezier(0.4, 0, 0.2, 1);
  --spring: cubic-bezier(0.34, 1.56, 0.64, 1);
}

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

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: 'Inter', system-ui, sans-serif;
  color: var(--t1);
  background: var(--bg);
  min-height: 100vh;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

/* ─── Animated Background ─────────────────────────────── */

/* Base gradient */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -5;
  pointer-events: none;
  background:
    radial-gradient(ellipse 80vw 60vh at 80% -5%, rgba(46, 204, 113, 0.1) 0%, transparent 60%),
    radial-gradient(ellipse 70vw 60vh at -5% 90%, rgba(59, 158, 255, 0.09) 0%, transparent 60%),
    radial-gradient(ellipse 50vw 50vh at 50% 50%, rgba(0, 212, 184, 0.045) 0%, transparent 60%),
    linear-gradient(170deg, #010b13 0%, #041018 60%, #010e18 100%);
}

/* Noise grain */
.noise {
  position: fixed;
  inset: 0;
  z-index: -4;
  pointer-events: none;
  opacity: 0.025;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E");
  background-size: 200px 200px;
}

/* Subtle grid */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -3;
  pointer-events: none;
  background-image:
    linear-gradient(rgba(100, 160, 200, 0.03) 1px, transparent 1px),
    linear-gradient(90deg, rgba(100, 160, 200, 0.03) 1px, transparent 1px);
  background-size: 56px 56px;
}

/* Orbs */
.orb {
  position: fixed;
  border-radius: 50%;
  pointer-events: none;
  z-index: -2;
  animation: orb-float 20s var(--ease) infinite;
}

.orb-1 {
  width: 560px;
  height: 560px;
  background: radial-gradient(circle, rgba(46, 204, 113, 0.18) 0%, transparent 70%);
  filter: blur(90px);
  top: -180px;
  right: -120px;
  animation-duration: 22s;
}

.orb-2 {
  width: 480px;
  height: 480px;
  background: radial-gradient(circle, rgba(59, 158, 255, 0.14) 0%, transparent 70%);
  filter: blur(80px);
  left: -140px;
  bottom: -150px;
  animation-duration: 26s;
  animation-delay: -8s;
}

.orb-3 {
  width: 320px;
  height: 320px;
  background: radial-gradient(circle, rgba(0, 212, 184, 0.1) 0%, transparent 70%);
  filter: blur(70px);
  right: 15%;
  bottom: 25%;
  animation-duration: 18s;
  animation-delay: -5s;
}

@keyframes orb-float {

  0%,
  100% {
    transform: translate(0, 0) scale(1);
  }

  30% {
    transform: translate(25px, -30px) scale(1.07);
  }

  65% {
    transform: translate(-20px, 18px) scale(0.95);
  }
}

/* ─── Shell ───────────────────────────────────────────── */
.shell {
  width: min(99vw, 1760px);
  margin: 1.1rem auto 2.5rem;
  padding: 0 0.85rem;
  display: grid;
  gap: var(--gap);
}

/* ─── Glass Panel Mixin ───────────────────────────────── */
.panel,
.hero,
.auth-card,
.how-card,
.stat-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  backdrop-filter: blur(24px) saturate(1.4);
  -webkit-backdrop-filter: blur(24px) saturate(1.4);
  box-shadow:
    0 4px 24px rgba(0, 0, 0, 0.45),
    0 1px 0 rgba(255, 255, 255, 0.05) inset;
  position: relative;
  overflow: hidden;
}

/* Top sheen */
.panel::before,
.hero::before,
.auth-card::before,
.how-card::before,
.stat-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent 0%, rgba(255, 255, 255, 0.12) 50%, transparent 100%);
  pointer-events: none;
}

/* ═══════════════════════════════
   HERO  HEADER
═══════════════════════════════ */
.hero {
  margin-bottom: 0.4rem;
  padding: 0.4rem 0.6rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  border-top: 2px solid transparent;
  background:
    linear-gradient(var(--surface), var(--surface)) padding-box,
    linear-gradient(90deg, var(--green), #00d4b8 45%, var(--blue)) border-box;
}

/* Brand cluster */
.hero-brand {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-shrink: 0;
}

.brand-logo {
  height: 36px;
  width: auto;
  filter: drop-shadow(0 0 10px rgba(46, 204, 113, 0.35));
  transition: filter 0.3s var(--ease);
}

.brand-logo:hover {
  filter: drop-shadow(0 0 16px rgba(46, 204, 113, 0.55));
}

.brand-divider {
  width: 1px;
  height: 32px;
  background: linear-gradient(180deg, transparent, rgba(255, 255, 255, 0.15), transparent);
}

.brand-text {
  display: flex;
  flex-direction: column;
  gap: 0.06rem;
}

.brand-label {
  font-size: 1rem;
  font-weight: 700;
  color: var(--t1);
  letter-spacing: -0.01em;
}

.brand-sub {
  font-size: 0.7rem;
  font-weight: 500;
  color: var(--t3);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* Center tagline */
.hero-center {
  flex: 1;
  text-align: center;
}

.hero-tagline {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--t3);
}

/* Nav cluster */
.hero-nav {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-shrink: 0;
}

.nav-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.42rem;
  padding: 0.46rem 0.9rem;
  border-radius: var(--r-sm);
  border: 1px solid var(--border-lit);
  background: rgba(12, 28, 48, 0.7);
  color: var(--t2);
  font-family: 'Inter', sans-serif;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s var(--ease);
}

.nav-btn:hover {
  background: rgba(18, 40, 66, 0.9);
  border-color: rgba(255, 255, 255, 0.2);
  color: var(--t1);
  transform: translateY(-1px);
}

.nav-btn.danger:hover {
  border-color: rgba(255, 95, 95, 0.5);
  color: #ff8a8a;
  background: rgba(80, 18, 18, 0.5);
}

/* Session pill — dot via ::before so JS textContent doesn't break it */
.session-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.42rem 0.9rem;
  border-radius: 999px;
  border: 1px solid var(--border-lit);
  background: rgba(8, 22, 38, 0.8);
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--t2);
  white-space: nowrap;
  transition: border-color 0.3s var(--ease), color 0.3s var(--ease);
}

.session-pill::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--t3);
  flex-shrink: 0;
  transition: all 0.4s var(--ease);
  box-shadow: 0 0 0 0 transparent;
}

/* Active state — set via JS class */
.session-pill.is-logged-in {
  border-color: rgba(46, 204, 113, 0.35);
  color: var(--t1);
}

.session-pill.is-logged-in::before {
  background: var(--green);
  box-shadow: 0 0 0 3px rgba(46, 204, 113, 0.18);
  animation: pulse-dot 2s ease infinite;
}

@keyframes pulse-dot {

  0%,
  100% {
    box-shadow: 0 0 0 3px rgba(46, 204, 113, 0.18);
  }

  50% {
    box-shadow: 0 0 0 5px rgba(46, 204, 113, 0.05);
  }
}

/* ═══════════════════════════════
   AUTH  VIEW
═══════════════════════════════ */
.auth-layout {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: var(--gap);
}

/* Auth card */
.auth-card {
  padding: 2rem 2rem 1.8rem;
  display: flex;
  flex-direction: column;
  gap: 0;
}

.auth-logo-wrap {
  margin-bottom: 1.6rem;
}

.auth-logo {
  height: 32px;
  width: auto;
  filter: drop-shadow(0 0 8px rgba(46, 204, 113, 0.3));
}

.auth-title {
  font-size: 1.85rem;
  font-weight: 800;
  color: var(--t1);
  letter-spacing: -0.03em;
  line-height: 1.1;
}

.auth-subtitle {
  font-size: 0.88rem;
  color: var(--t2);
  margin-top: 0.4rem;
  margin-bottom: 1.6rem;
  line-height: 1.5;
}

/* Step track */
.step-track {
  display: flex;
  align-items: center;
  gap: 0;
  margin-bottom: 1.8rem;
}

.step-node {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
}

.step-circle {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 2px solid var(--border-lit);
  background: rgba(12, 28, 48, 0.8);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--t3);
  transition: all 0.3s var(--ease);
}

.step-node.active .step-circle {
  border-color: var(--green);
  background: rgba(46, 204, 113, 0.12);
  color: var(--green);
  box-shadow: 0 0 0 4px rgba(46, 204, 113, 0.1), 0 0 20px rgba(46, 204, 113, 0.2);
}

.step-label {
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--t3);
  transition: color 0.3s;
}

.step-node.active .step-label {
  color: var(--green);
}

.step-connector {
  flex: 1;
  height: 2px;
  background: linear-gradient(90deg, var(--border-lit), var(--border));
  margin: 0 0.6rem;
  margin-bottom: 1.1rem;
  border-radius: 999px;
}

/* Form fields */
.field-group {
  margin-bottom: 1.1rem;
}

.field-label {
  display: flex;
  align-items: center;
  gap: 0.38rem;
  font-size: 0.76rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--t2);
  margin-bottom: 0.55rem;
}

.field-row {
  display: flex;
  gap: 0.55rem;
  flex-wrap: wrap;
}

/* Input prefix (for +91) */
.input-wrap {
  position: relative;
  flex: 1;
  min-width: 180px;
  display: flex;
  align-items: center;
}

.input-prefix {
  position: absolute;
  left: 0.82rem;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--t3);
  pointer-events: none;
  z-index: 1;
}

.input-wrap input {
  padding-left: 2.6rem;
}

/* Inputs & selects */
input,
select {
  font-family: 'Inter', sans-serif;
  font-size: 0.9rem;
  border: 1px solid var(--border-lit);
  border-radius: var(--r-sm);
  background: rgba(4, 14, 26, 0.9);
  color: var(--t1);
  padding: 0.66rem 0.9rem;
  width: 100%;
  outline: none;
  transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease), background 0.2s var(--ease);
}

input:focus,
select:focus {
  border-color: var(--green);
  box-shadow: 0 0 0 3px rgba(46, 204, 113, 0.15);
  background: rgba(6, 20, 36, 0.95);
}

input::placeholder {
  color: var(--t3);
  font-weight: 400;
}

input.otp-input {
  font-family: 'JetBrains Mono', monospace;
  font-size: 1.2rem;
  letter-spacing: 0.35em;
  text-align: center;
}

select {
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%234e6a80' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.85rem center;
  padding-right: 2.4rem;
}

/* Primary button */
.btn-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  padding: 0.66rem 1.4rem;
  border-radius: var(--r-sm);
  border: none;
  font-family: 'Inter', sans-serif;
  font-size: 0.9rem;
  font-weight: 700;
  color: #fff;
  background: linear-gradient(135deg, var(--green-dark), var(--green));
  cursor: pointer;
  white-space: nowrap;
  position: relative;
  overflow: hidden;
  box-shadow: 0 4px 20px rgba(46, 204, 113, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15);
  transition: all 0.2s var(--ease);
}

.btn-primary::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.1) 0%, transparent 60%);
  pointer-events: none;
}

.btn-primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 30px rgba(46, 204, 113, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.2);
  filter: brightness(1.08);
}

.btn-primary:active {
  transform: translateY(0);
}

/* Login note */
.login-note {
  min-height: 1.4rem;
  color: var(--green);
  font-size: 0.86rem;
  font-weight: 600;
  margin-top: 0.5rem;
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

/* Local Studio entry (LOCAL_S3_BYPASS) — an alternative to logging in */
.local-studio-entry {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin-top: 1.2rem;
  padding: 0.85rem 1rem;
  border-radius: var(--r-md);
  border: 1px solid var(--border-lit);
  border-left: 3px solid var(--teal);
  background: rgba(0, 212, 184, 0.06);
  color: var(--t2);
  font-size: 0.82rem;
  line-height: 1.4;
  text-decoration: none;
  transition: all 0.2s var(--ease);
}

.local-studio-entry:hover {
  background: rgba(0, 212, 184, 0.11);
  border-color: rgba(0, 212, 184, 0.4);
  transform: translateY(-1px);
}

.local-studio-entry svg {
  color: var(--teal);
  flex-shrink: 0;
}

.local-studio-entry strong {
  color: var(--t1);
  font-weight: 700;
}

/* How it works card */
.how-card {
  padding: 1.8rem;
  display: flex;
  flex-direction: column;
  gap: 1.4rem;
}

.how-header {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  color: var(--teal);
}

.how-header svg {
  flex-shrink: 0;
}

.how-header h3 {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--t1);
}

.how-steps {
  list-style: none;
  display: grid;
  gap: 1.1rem;
}

.how-steps li {
  display: flex;
  gap: 0.95rem;
  align-items: flex-start;
  padding: 0.85rem 1rem;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  background: rgba(4, 14, 26, 0.6);
  font-size: 0.88rem;
  color: var(--t2);
  line-height: 1.5;
  transition: all 0.22s var(--ease);
}

.how-steps li:hover {
  border-color: var(--border-green);
  background: rgba(46, 204, 113, 0.05);
  transform: translateX(4px);
}

.how-steps li strong {
  color: var(--t1);
  font-weight: 700;
}

.how-icon {
  width: 34px;
  height: 34px;
  border-radius: var(--r-sm);
  background: rgba(46, 204, 113, 0.12);
  border: 1px solid rgba(46, 204, 113, 0.25);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--green);
  flex-shrink: 0;
}

.how-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.5rem 0.9rem;
  border-radius: 999px;
  border: 1px solid var(--border-green);
  background: rgba(46, 204, 113, 0.07);
  color: var(--green);
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  align-self: flex-start;
}

/* Disabled blocks */
.disabled-block {
  opacity: 0.35;
  pointer-events: none;
  filter: blur(0.5px);
  transition: all 0.3s var(--ease);
}

/* ═══════════════════════════════
   STATS  GRID
═══════════════════════════════ */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--gap);
}

.stat-card {
  padding: 1.2rem 1.3rem;
  display: flex;
  align-items: center;
  gap: 1rem;
  cursor: default;
  transition: all 0.25s var(--ease);
}

.stat-card:hover {
  transform: translateY(-3px);
  border-color: var(--border-lit);
  box-shadow: 0 12px 36px rgba(0, 0, 0, 0.5);
}

.stat-icon {
  width: 48px;
  height: 48px;
  flex-shrink: 0;
  border-radius: var(--r-md);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.25s var(--ease);
}

.stat-card:hover .stat-icon {
  transform: scale(1.08);
}

/* Per-card accent */
.stat-annotator .stat-icon {
  background: rgba(59, 158, 255, 0.12);
  border: 1px solid rgba(59, 158, 255, 0.2);
  color: var(--blue);
}

.stat-done .stat-icon {
  background: rgba(46, 204, 113, 0.12);
  border: 1px solid rgba(46, 204, 113, 0.2);
  color: var(--green);
}

.stat-pending .stat-icon {
  background: rgba(245, 166, 35, 0.12);
  border: 1px solid rgba(245, 166, 35, 0.2);
  color: var(--amber);
}

.stat-working .stat-icon {
  background: rgba(0, 212, 184, 0.12);
  border: 1px solid rgba(0, 212, 184, 0.2);
  color: var(--teal);
}

.stat-annotator {
  border-top: 2px solid rgba(59, 158, 255, 0.35);
}

.stat-done {
  border-top: 2px solid rgba(46, 204, 113, 0.35);
}

.stat-pending {
  border-top: 2px solid rgba(245, 166, 35, 0.35);
}

.stat-working {
  border-top: 2px solid rgba(0, 212, 184, 0.35);
}

.stat-info {
  display: flex;
  flex-direction: column;
  gap: 0.12rem;
  min-width: 0;
}

.stat-label {
  font-size: 0.73rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--t3);
}

.stat-value {
  font-size: 1.9rem;
  font-weight: 800;
  line-height: 1;
  color: var(--t1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.stat-meta {
  font-size: 0.78rem;
  color: var(--t3);
}

/* ═══════════════════════════════
   WORKSPACE  GRID
═══════════════════════════════ */
.workspace {
  display: grid;
  grid-template-columns: 390px 1fr;
  gap: var(--gap);
}

.right-col {
  display: grid;
  gap: var(--gap);
  grid-template-rows: auto 1fr;
}

.panel {
  padding: 1.15rem 1.25rem;
}

.tasks-panel {
  grid-row: span 2;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

/* Panel head */
.panel-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.8rem;
}

.panel-title {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--t1);
}

.panel-title svg {
  color: var(--green);
  flex-shrink: 0;
}

.count-badge {
  font-size: 0.75rem;
  font-weight: 700;
  padding: 0.2rem 0.65rem;
  border-radius: 999px;
  background: rgba(46, 204, 113, 0.1);
  border: 1px solid rgba(46, 204, 113, 0.22);
  color: var(--green);
}

.panel-badge {
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--amber);
  background: rgba(245, 166, 35, 0.08);
  border: 1px solid rgba(245, 166, 35, 0.2);
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
}

/* ─── Toolbar ─── */
.toolbar {
  display: grid;
  gap: 0.55rem;
}

/* Search field */
.search-wrap {
  position: relative;
  display: flex;
  align-items: center;
}

.search-icon {
  position: absolute;
  left: 0.78rem;
  color: var(--t3);
  pointer-events: none;
  z-index: 1;
}

.search-input {
  padding-left: 2.2rem;
}

.sort-select {
  min-width: unset;
}

/* Filter chips */
.filter-chips {
  display: flex;
  gap: 0.38rem;
  flex-wrap: wrap;
}

.chip {
  border: 1px solid var(--border-lit);
  background: rgba(12, 24, 42, 0.7);
  color: var(--t3);
  border-radius: 999px;
  padding: 0.32rem 0.75rem;
  cursor: pointer;
  font-family: 'Inter', sans-serif;
  font-size: 0.77rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  transition: all 0.2s var(--ease);
}

.chip:hover {
  background: rgba(18, 38, 62, 0.8);
  border-color: rgba(255, 255, 255, 0.15);
  color: var(--t1);
}

.chip.active {
  border-color: rgba(46, 204, 113, 0.5);
  background: rgba(46, 204, 113, 0.1);
  color: var(--green);
  box-shadow: 0 0 12px rgba(46, 204, 113, 0.1);
}

/* Action row */
.action-row {
  display: flex;
  gap: 0.45rem;
  flex-wrap: wrap;
}

/* Small buttons */
.btn-sm {
  display: inline-flex;
  align-items: center;
  gap: 0.38rem;
  padding: 0.44rem 0.82rem;
  border-radius: var(--r-sm);
  border: 1px solid var(--border-lit);
  background: rgba(12, 26, 44, 0.7);
  color: var(--t2);
  font-family: 'Inter', sans-serif;
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s var(--ease);
  white-space: nowrap;
}

.btn-sm:hover {
  background: rgba(18, 38, 62, 0.9);
  border-color: var(--border-lit);
  color: var(--t1);
  transform: translateY(-1px);
}

.btn-sm.accent {
  background: linear-gradient(135deg, rgba(26, 166, 89, 0.25), rgba(46, 204, 113, 0.15));
  border-color: rgba(46, 204, 113, 0.35);
  color: var(--green);
}

.btn-sm.accent:hover {
  background: linear-gradient(135deg, rgba(26, 166, 89, 0.4), rgba(46, 204, 113, 0.25));
  box-shadow: 0 4px 16px rgba(46, 204, 113, 0.2);
}

/* ─── Task List ─── */
.task-list {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  display: grid;
  align-content: start;
  gap: 0.4rem;

  scrollbar-width: thin;
  scrollbar-color: rgba(46, 204, 113, 0.2) transparent;
}

.task-list::-webkit-scrollbar {
  width: 4px;
}

.task-list::-webkit-scrollbar-track {
  background: transparent;
}

.task-list::-webkit-scrollbar-thumb {
  background: rgba(46, 204, 113, 0.2);
  border-radius: 2px;
}

/* ─── Pagination bar ─── */
.task-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.55rem 0.2rem 0.1rem;
  border-top: 1px solid var(--border);
  margin-top: 0.2rem;
}

.pager-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.38rem 0.75rem;
  border-radius: var(--r-sm);
  border: 1px solid var(--border-lit);
  background: rgba(12, 26, 44, 0.75);
  color: var(--t2);
  font-family: 'Inter', sans-serif;
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s var(--ease);
  white-space: nowrap;
}

.pager-btn:hover:not(:disabled) {
  background: rgba(18, 38, 62, 0.9);
  border-color: rgba(46, 204, 113, 0.4);
  color: var(--green);
  transform: translateY(-1px);
}

.pager-btn.disabled,
.pager-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
  pointer-events: none;
}

.pager-info {
  font-size: 0.78rem;
  font-weight: 700;
  font-family: 'JetBrains Mono', monospace;
  color: var(--t3);
  letter-spacing: 0.04em;
}

.task-card {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 0.75rem 0.9rem;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  background: rgba(6, 18, 34, 0.7);
  cursor: pointer;
  text-align: left;
  width: 100%;
  font-family: 'Inter', sans-serif;
  color: var(--t1);
  transition: all 0.2s var(--ease);
  position: relative;
  overflow: visible;
}

/* Left accent bar */
.task-card::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: transparent;
  transition: all 0.2s var(--ease);
  border-radius: 0 2px 2px 0;
}

.task-card:hover {
  border-color: var(--border-lit);
  background: rgba(10, 26, 46, 0.85);
  transform: translateX(3px);
}

.task-card:hover::before {
  background: linear-gradient(180deg, var(--blue), var(--teal));
  box-shadow: 2px 0 10px rgba(59, 158, 255, 0.3);
}

.task-card.selected {
  border-color: rgba(46, 204, 113, 0.4);
  background: rgba(6, 36, 28, 0.7);
  transform: translateX(3px);
}

.task-card.selected::before {
  background: linear-gradient(180deg, var(--green), var(--teal));
  box-shadow: 2px 0 12px rgba(46, 204, 113, 0.4);
}

.task-main {
  display: flex;
  flex: 1 1 12rem;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}

.task-name {
  font-weight: 700;
  font-size: 0.88rem;
  color: var(--t1);
  white-space: normal;
  overflow-wrap: anywhere;
  word-break: break-word;
}

.task-sub {
  font-size: 0.72rem;
  color: var(--t3);
  font-family: 'JetBrains Mono', monospace;
  white-space: normal;
  overflow-wrap: anywhere;
  word-break: break-word;
}

/* Badges */
.badge {
  border-radius: 999px;
  padding: 0.2rem 0.58rem;
  font-size: 0.67rem;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  border: 1px solid var(--border);
  background: rgba(18, 36, 58, 0.8);
  color: var(--t3);
  white-space: nowrap;
  flex-shrink: 0;
}

.badge.done {
  background: rgba(26, 100, 65, 0.55);
  border-color: rgba(46, 204, 113, 0.45);
  color: #5dffa5;
}

/* Terminal failure — deliberately red so it never reads as a success state. */
.badge.failed {
  background: rgba(90, 20, 20, 0.6);
  border-color: rgba(255, 95, 95, 0.5);
  color: #ff9d9d;
}

/* Destructive action that isn't a delete: outlined rather than filled. */
.btn-sm.danger-outline {
  border-color: rgba(255, 95, 95, 0.4);
  color: #ff9d9d;
}

.btn-sm.danger-outline:hover {
  background: rgba(80, 18, 18, 0.5);
  border-color: rgba(255, 95, 95, 0.6);
  color: #ffb3b3;
}

.badge.pending {
  background: rgba(90, 58, 18, 0.55);
  border-color: rgba(245, 166, 35, 0.45);
  color: #ffcc70;
}

.badge.working {
  background: rgba(15, 52, 100, 0.55);
  border-color: rgba(59, 158, 255, 0.45);
  color: #80caff;
}

/* ─── Videos list ─── */
.videos-list {
  display: grid;
  gap: 0.75rem;
}

.video-item {
  border: 1px solid var(--border);
  background: rgba(4, 14, 28, 0.82);
  border-radius: var(--r-md);
  padding: 0.9rem;
  display: grid;
  gap: 0.65rem;
  transition: all 0.2s var(--ease);
}

.video-item:hover {
  border-color: var(--border-lit);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.35);
}

.video-name {
  font-weight: 700;
  font-size: 0.84rem;
  color: var(--teal);
  font-family: 'JetBrains Mono', monospace;
}

video {
  width: 100%;
  max-width: 100%;
  border-radius: var(--r-sm);
  border: 1px solid var(--border-lit);
  background: #020810;
  display: block;
}

.video-actions {
  display: flex;
  justify-content: flex-end;
}

.download-btn {
  min-width: 175px;
  background: linear-gradient(135deg, var(--green-dark), var(--green));
  box-shadow: 0 4px 16px rgba(46, 204, 113, 0.25);
}

.download-btn:hover {
  box-shadow: 0 6px 24px rgba(46, 204, 113, 0.4);
}

/* ─── Upload / Dropzone ─── */
.dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  padding: 1.8rem 1.5rem;
  border: 2px dashed rgba(46, 204, 113, 0.25);
  border-radius: var(--r-md);
  background: rgba(3, 10, 20, 0.6);
  cursor: pointer;
  text-align: center;
  color: var(--t3);
  transition: all 0.25s var(--ease);
  margin-bottom: 0.8rem;
}

.dropzone:hover {
  border-color: rgba(46, 204, 113, 0.5);
  background: rgba(46, 204, 113, 0.04);
  color: var(--t2);
  transform: scale(1.005);
}

.dropzone svg {
  color: var(--green);
  opacity: 0.6;
  transition: all 0.25s;
}

.dropzone:hover svg {
  opacity: 1;
  transform: translateY(-3px);
}

.dropzone-text {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--t2);
}

.dropzone-text strong {
  color: var(--green);
}

.dropzone-hint {
  font-size: 0.77rem;
  color: var(--t3);
}

/* Hide native file input, the label activates it */
input[type="file"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.upload-actions {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin-bottom: 0.8rem;
}

.btn-upload {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.62rem 1.2rem;
  border-radius: var(--r-sm);
  border: none;
  font-family: 'Inter', sans-serif;
  font-size: 0.88rem;
  font-weight: 700;
  color: #fff;
  background: linear-gradient(135deg, var(--green-dark), var(--green));
  cursor: pointer;
  position: relative;
  overflow: hidden;
  box-shadow: 0 4px 18px rgba(46, 204, 113, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.12);
  transition: all 0.2s var(--ease);
  flex: 1;
  justify-content: center;
}

.btn-upload::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.1) 0%, transparent 55%);
  pointer-events: none;
}

.btn-upload:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 28px rgba(46, 204, 113, 0.45);
  filter: brightness(1.08);
}

.btn-upload.ghost {
  background: rgba(12, 26, 44, 0.8);
  border: 1px solid var(--border-green);
  color: var(--green);
  box-shadow: none;
}

.btn-upload.ghost:hover {
  background: rgba(46, 204, 113, 0.1);
  box-shadow: 0 4px 16px rgba(46, 204, 113, 0.15);
}

/* ─── Button busy state (validate / upload in flight) ─── */
.btn-spinner {
  width: 13px;
  height: 13px;
  flex-shrink: 0;
  border-radius: 50%;
  border: 2px solid currentColor;
  border-top-color: transparent;
  animation: btn-spin 0.65s linear infinite;
}

@keyframes btn-spin {
  to {
    transform: rotate(360deg);
  }
}

/* Anything in a busy state must not look or behave clickable. Applies to every
   control the busy helper touches: buttons, task cards, rally chips. */
[aria-busy="true"] {
  cursor: progress;
  opacity: 0.8;
  transform: none;
}

[aria-busy="true"]:hover {
  transform: none;
  filter: none;
  box-shadow: none;
}

/* Cards/chips normally space their contents apart — while busy the spinner and
   label should read as one unit. */
.task-card[aria-busy="true"],
.rally-chip[aria-busy="true"],
.picker-list .task-card[aria-busy="true"] {
  justify-content: center;
  gap: 0.5rem;
}

.btn-upload:disabled,
.btn-sm:disabled,
.mini-btn:disabled {
  cursor: not-allowed;
}

/* ─── Progress bar ─── */
.progress-wrap {
  display: grid;
  gap: 0.4rem;
  margin-bottom: 0.8rem;
}

.progress-header {
  display: flex;
  justify-content: space-between;
  font-size: 0.8rem;
  font-weight: 600;
}

.progress-label {
  color: var(--t2);
}

.progress-pct {
  color: var(--green);
  font-family: 'JetBrains Mono', monospace;
}

.progress-track {
  height: 8px;
  background: rgba(20, 44, 68, 0.7);
  border-radius: 999px;
  overflow: hidden;
  border: 1px solid var(--border);
}

.progress-fill {
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, var(--green-dark), var(--green), var(--teal));
  border-radius: 999px;
  transition: width 160ms ease;
  box-shadow: 0 0 10px rgba(46, 204, 113, 0.5);
}

/* ─── Result header row ─── */
.result-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.42rem;
}

.result-label {
  font-size: 0.73rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--t3);
}

/* ─── Result & Log boxes ─── */
.result-box,
#messages {
  margin: 0;
  border-radius: var(--r-sm);
  border: 1px solid var(--border);
  background: rgba(1, 7, 16, 0.9);
  color: #8ec9d9;
  padding: 0.88rem;
  white-space: pre-wrap;
  overflow: auto;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.78rem;
  line-height: 1.75;
  scrollbar-width: thin;
  scrollbar-color: rgba(46, 204, 113, 0.15) transparent;
}

.result-box {
  min-height: 120px;
}

#messages {
  min-height: 100px;
}

.result-box::-webkit-scrollbar,
#messages::-webkit-scrollbar {
  width: 4px;
  height: 4px;
}

.result-box::-webkit-scrollbar-thumb,
#messages::-webkit-scrollbar-thumb {
  background: rgba(46, 204, 113, 0.2);
  border-radius: 2px;
}

/* Log panel */
.log-panel #messages {
  resize: vertical;
  max-height: 200px;
}

/* ─── Hidden ─── */
.hidden {
  display: none !important;
}

.muted {
  color: var(--t3);
}

/* ═══════════════════════════════
   MINI  PLAYER
═══════════════════════════════ */
.mini-player {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  width: 320px;
  background: rgba(3, 12, 24, 0.97);
  border: 1px solid rgba(46, 204, 113, 0.3);
  border-radius: var(--r-md);
  padding: 0.65rem;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.04);
  z-index: 100;
  backdrop-filter: blur(30px);
  animation: slide-up 0.35s var(--spring);
}

@keyframes slide-up {
  from {
    transform: translateY(20px) scale(0.97);
    opacity: 0;
  }

  to {
    transform: translateY(0) scale(1);
    opacity: 1;
  }
}

.mini-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.45rem;
}

.mini-title-row {
  display: flex;
  align-items: center;
  gap: 0.42rem;
  color: var(--t2);
  font-size: 0.8rem;
  font-weight: 700;
  min-width: 0;
}

.mini-title-row svg {
  color: var(--green);
  flex-shrink: 0;
}

#mini-title {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mini-close {
  border: 1px solid var(--border-lit);
  background: rgba(25, 45, 70, 0.7);
  color: var(--t2);
  width: 24px;
  height: 24px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.72rem;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-family: 'Inter', sans-serif;
  transition: all 0.2s var(--ease);
}

.mini-close:hover {
  background: rgba(100, 20, 20, 0.6);
  border-color: rgba(255, 95, 95, 0.45);
  color: #ffaaaa;
}

.mini-player video {
  width: 100%;
  border-radius: var(--r-sm);
  border: 1px solid var(--border-lit);
}

/* ═══════════════════════════════
   TOAST
═══════════════════════════════ */
.toast {
  position: fixed;
  right: 1.25rem;
  top: 1.25rem;
  min-width: 200px;
  max-width: 340px;
  background: rgba(6, 20, 38, 0.97);
  color: var(--t1);
  border: 1px solid var(--border-lit);
  border-radius: var(--r-sm);
  padding: 0.75rem 1.1rem;
  box-shadow: 0 12px 36px rgba(0, 0, 0, 0.45);
  z-index: 250;
  font-size: 0.86rem;
  font-weight: 600;
  backdrop-filter: blur(20px);
  animation: toast-slide 0.3s var(--spring);
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.toast::before {
  content: '●';
  font-size: 0.5rem;
  flex-shrink: 0;
  color: var(--t3);
}

@keyframes toast-slide {
  from {
    transform: translateX(110%);
    opacity: 0;
  }

  to {
    transform: translateX(0);
    opacity: 1;
  }
}

.toast.ok {
  background: rgba(6, 40, 28, 0.97);
  border-color: rgba(46, 204, 113, 0.45);
}

.toast.ok::before {
  color: var(--green);
  filter: drop-shadow(0 0 4px var(--green));
}

.toast.err {
  background: rgba(50, 12, 12, 0.97);
  border-color: rgba(255, 95, 95, 0.45);
}

.toast.err::before {
  color: var(--danger);
  filter: drop-shadow(0 0 4px var(--danger));
}

/* ═══════════════════════════════
   RESPONSIVE
═══════════════════════════════ */
@media (max-width: 1280px) {
  .workspace {
    grid-template-columns: 350px 1fr;
  }
}

@media (max-width: 1100px) {
  .auth-layout {
    grid-template-columns: 1fr;
  }

  .stats-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .workspace {
    grid-template-columns: 1fr;
  }

  .tasks-panel {
    grid-row: auto;
    min-height: auto;
  }
}

@media (max-width: 760px) {
  .hero {
    flex-wrap: wrap;
  }

  .hero-center {
    order: 3;
    flex-basis: 100%;
    text-align: left;
  }

  .hero-nav {
    flex-wrap: wrap;
  }

  .stats-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .upload-actions {
    flex-direction: column;
  }
}

@media (max-width: 520px) {
  .stats-grid {
    grid-template-columns: 1fr;
  }

  .shell {
    padding: 0 0.5rem;
  }

  .mini-player {
    width: calc(100vw - 1.25rem);
    right: 0.625rem;
  }
}

/* ═══════════════════════════════
   ANIMATIONS  ON  LOAD
═══════════════════════════════ */
@keyframes fade-rise {
  from {
    opacity: 0;
    transform: translateY(18px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.hero {
  animation: fade-rise 0.5s var(--ease) 0.05s both;
}

.auth-layout {
  animation: fade-rise 0.55s var(--ease) 0.14s both;
}

.stats-grid {
  animation: fade-rise 0.55s var(--ease) 0.12s both;
}

.workspace {
  animation: fade-rise 0.55s var(--ease) 0.22s both;
}

.log-panel {
  animation: fade-rise 0.55s var(--ease) 0.3s both;
}

/* ══════════════════════════════════════════════════════
   ANNOTATION  STUDIO  (annotate.html)
   ══════════════════════════════════════════════════════ */

/* Portal → studio launch button (shares .btn-sm look with an accent) */
.btn-sm.studio {
  background: linear-gradient(135deg, rgba(15, 52, 100, 0.4), rgba(59, 158, 255, 0.18));
  border-color: rgba(59, 158, 255, 0.4);
  color: #9fd0ff;
}

.btn-sm.studio:hover {
  background: linear-gradient(135deg, rgba(15, 52, 100, 0.6), rgba(59, 158, 255, 0.3));
  box-shadow: 0 4px 16px rgba(59, 158, 255, 0.22);
  color: #cfe6ff;
}

/* Header link styled as a nav button */
a.nav-btn {
  text-decoration: none;
}

/* ─── Import view ─── */
.import-panel {
  animation: fade-rise 0.5s var(--ease) both;
}

.import-hint {
  margin-top: 0.6rem;
  font-size: 0.82rem;
}

/* ─── Picker view ─── */
.picker-grid {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  gap: var(--gap);
  animation: fade-rise 0.5s var(--ease) both;
}

.picker-list {
  display: grid;
  gap: 0.4rem;
  align-content: start;
  max-height: 480px;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(46, 204, 113, 0.2) transparent;
}

.picker-list::-webkit-scrollbar {
  width: 4px;
}

.picker-list::-webkit-scrollbar-thumb {
  background: rgba(46, 204, 113, 0.2);
  border-radius: 2px;
}

.picker-list a {
  color: var(--teal);
}

/* ─── Studio grid ─── */
.studio-grid {
  display: grid;
  /* Fill the shell (itself ≤1760px) so the player can grow on wide screens. */
  grid-template-columns: minmax(0, 1fr);
  justify-content: center;
  gap: var(--gap);
  align-items: start;
  animation: fade-rise 0.5s var(--ease) both;
}

/* Hit Annotation: vertical rally list on the left, video + controls on the right. */
.studio-grid.mode-hits {
  /* Narrow rally list and a tight gap — the width goes to the video instead. */
  grid-template-columns: 128px minmax(0, 1fr);
  column-gap: 0.5rem;
}

/* Main column. Segmentation: player (≤1100px) on the left with the rally +
   clips/submit panels in a column to its RIGHT, so every button is on screen
   without scrolling. Hit mode reuses the exact same split — player on the
   left, hit-adding controls in a column to its right; playback controls
   (play/pause/seek) stay under the video in both modes. */
.studio-main {
  display: grid;
  /* Player takes every pixel the side column doesn't; the side column is the
     270–300px it always was, so its buttons keep their size and wrapping. */
  grid-template-columns: minmax(0, 1fr) minmax(270px, 300px);
  gap: var(--gap);
  align-content: start;
  align-items: start;
  min-width: 0;
}

.mode-hits .player-panel {
  grid-column: 1;
}

.mode-hits #hits-panel {
  grid-column: 2;
  /* 10px narrower column, 10px less padding: the buttons get exactly the
     inner width they had before, and the video gets the 10px. */
  padding-left: 15px;
  padding-right: 15px;
}

.mode-hits .studio-main {
  grid-template-columns: minmax(0, 1fr) minmax(260px, 290px);
}

.studio-grid:not(.mode-hits) .player-panel {
  grid-column: 1;
  grid-row: 1 / span 2;
}

.studio-grid:not(.mode-hits) #rally-panel,
.studio-grid:not(.mode-hits) #finish-panel {
  grid-column: 2;
}

/* Keep the side column's buttons reachable: the rally table scrolls
   internally instead of pushing Generate/Validate/Submit below the fold. */
.studio-grid:not(.mode-hits) #rally-panel .table-wrap {
  max-height: 30vh;
  overflow-y: auto;
}

/* Hit mode: the shortcuts hint is redundant once the toggles are visible
   beside the video, so it stays hidden. The stage itself no longer gets a
   height cap — now that the hit-adding controls live in their own column
   instead of stacking below the video, the player can fill its (now wider)
   column just like the segmentation player does. */
.mode-hits .shortcuts-hint {
  display: none;
}

/* Hide the long SOP explainer inside the hit form in hit mode — the toggles
   are self-explanatory and this buys the vertical room to keep everything
   (player + form + Add Hit + rally list) on one laptop screen. */
.mode-hits #hits-panel > .muted {
  display: none;
}

/* Trim the vertical rhythm in hit mode so player + form + buttons clear a
   standard laptop viewport without scrolling. */
.mode-hits .player-panel {
  padding-top: 0.75rem;
  padding-bottom: 0.75rem;
}

.mode-hits .tool-version {
  margin-bottom: 0.4rem;
}

.mode-hits .frame-slider {
  margin: 0.4rem 0 0.25rem;
}

.mode-hits .frame-readout {
  margin-bottom: 0.35rem;
}

.mode-hits .transport {
  margin-bottom: 0.2rem;
}

/* Slimmer header + tighter shell in hit mode (body.studio-hits set by JS) so
   player + controls + rally list clear a real laptop viewport without scroll. */
/* Hit annotation drops the page header entirely (logo, "Back to Portal",
   session pill) — every pixel goes to the work area. Rally segmentation keeps
   it, so the way back to the portal is still one click away from there. */
body.studio-hits .hero {
  display: none;
}

body.studio-hits .shell {
  margin-top: 0.6rem;
  gap: 0.6rem;
  /* The freed height can't enlarge a 16:9 picture by itself — its size is set
     by the column's WIDTH. Taking 20% of the freed ~65px as video height means
     ~23px more width, so the outer window margins give up that much. */
  padding-left: 0.125rem;
  padding-right: 0.125rem;
}

.mode-hits #hits-panel {
  padding-top: 0.65rem;
  padding-bottom: 0.65rem;
}

/* Tighten the column gap and title block in hit mode. */
.mode-hits .studio-main {
  gap: 0.5rem;
}

.mode-hits .player-panel .panel-head {
  margin-bottom: 0.35rem;
}

/* The video runs edge to edge across its panel: no gap between the picture's
   frame and the panel's sides. The negative margin cancels the panel's own
   side padding (0.6rem, see .player-panel); the stage's side borders and
   corner rounding go too, since they'd just be a second edge against the
   panel's. */
.mode-hits .player-panel .stage {
  /* width:100% is the panel's content box, so the stage must also be widened by
     the padding it reaches into — margins alone would only shift it left. */
  width: calc(100% + 1.2rem);
  margin-left: -0.6rem;
  margin-right: -0.6rem;
  border-left-width: 0;
  border-right-width: 0;
  border-radius: 0;
}

.mode-hits .hit-form-grid {
  gap: 0.3rem 0.9rem;
  margin-bottom: 0.45rem;
}

/* Compact toggles in hit mode so the whole form takes fewer rows. */
.mode-hits .toggle-btn {
  padding: 0.28rem 0.5rem;
  font-size: 0.74rem;
}

.mode-hits .form-label {
  font-size: 0.68rem;
  min-width: unset;
}

.mode-hits .player-hit-bar {
  margin-bottom: 0.35rem;
  padding: 0.35rem 0.6rem;
}

/* Keep the hits table from pushing the export/prev-next row off-screen. */
.mode-hits #hits-table-wrap {
  max-height: 22vh;
  overflow-y: auto;
}

/* The wrap scrolls, so pin the header or it scrolls out of sight. */
#hits-table-wrap thead th,
#rally-table-wrap thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--bg-2);
}

/* Briefly flag the row that was just saved — hits are ordered by frame, so a
   new one can land anywhere in the list. */
.studio-table tr.just-saved td {
  background: rgba(46, 204, 113, 0.18);
  transition: background 0.6s var(--ease);
}

/* ─── Import failure (kept on the panel, with recovery actions) ─── */
.import-error {
  margin-top: 0.9rem;
  padding: 0.9rem 1rem;
  border: 1px solid rgba(255, 95, 95, 0.4);
  border-left: 3px solid var(--danger);
  border-radius: var(--r-md);
  background: rgba(50, 12, 12, 0.35);
}

.import-error-msg {
  color: #ff9d9d;
  font-weight: 600;
  font-size: 0.88rem;
  margin-bottom: 0.35rem;
}

.import-error .muted {
  font-size: 0.82rem;
  line-height: 1.5;
  margin-bottom: 0.7rem;
}

.import-error .mark-row {
  margin-bottom: 0;
}

.player-panel {
  min-width: 0;
  /* Tighter left/right padding so the video fills more of the panel width. */
  padding-left: 0.6rem;
  padding-right: 0.6rem;
}

.video-meta {
  font-size: 0.78rem;
  color: var(--t3);
  font-family: 'JetBrains Mono', monospace;
  margin-bottom: 0.25rem;
}

/* Studio: fps / frames / resolution sit on the title line, giving the row of
   height to the video. When space runs out the details shorten first, then
   the file name. (The verify page keeps its own line.) */
#studio-view .player-panel .panel-title,
#verify-view .player-panel .panel-title {
  min-width: 0;
}

#studio-view #video-title,
#verify-view #video-title {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

#studio-view .panel-head .video-meta,
#verify-view .panel-head .video-meta {
  margin: 0 0 0 0.25rem;
  font-size: 0.74rem;
  font-weight: 400;
  min-width: 0;
  flex-shrink: 10;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Version tag under the file name — shown in both segmentation & annotation. */
.tool-version {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--teal);
  margin-bottom: 0.7rem;
}

/* ─── Stage (video + exact frame overlay) ─── */
.stage {
  position: relative;
  width: 100%;
  background: #020810;
  border-radius: var(--r-md);
  border: 1px solid var(--border-lit);
  overflow: hidden;
  aspect-ratio: 16 / 9;
  /* On wide screens a 16:9 box would push the playback controls below the
     fold; cap the height and let object-fit letterbox the extra width. */
  max-height: calc(100vh - 12rem);   /* the details line moved into the title row */
}

.stage video,
.stage .exact-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  border: none;
  border-radius: 0;
  background: transparent;
}

.stage .exact-frame {
  pointer-events: none;
  z-index: 2;
}

/* ─── Frame slider + readout ─── */
.frame-slider {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 6px;
  margin: 0.8rem 0 0.4rem;
  padding: 0;
  border: none;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--green-dim), rgba(20, 44, 68, 0.7));
  cursor: pointer;
}

.frame-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--green), var(--teal));
  border: 2px solid #041018;
  box-shadow: 0 0 10px rgba(46, 204, 113, 0.5);
  cursor: pointer;
}

.frame-slider::-moz-range-thumb {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--green);
  border: 2px solid #041018;
  cursor: pointer;
}

.frame-readout {
  text-align: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.8rem;
  color: var(--t2);
  margin-bottom: 0.7rem;
}

.frame-readout b {
  color: var(--green);
}

/* ─── Transport bar ─── */
.transport {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  /* Spread the controls across the full (now wider) video width. */
  justify-content: space-between;
  gap: 0.4rem;
}

.play-btn {
  min-width: 92px;
  justify-content: center;
}

.goto-wrap {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

.input-frame {
  width: 92px;
  padding: 0.4rem 0.55rem;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.8rem;
}

.input-xs {
  width: 58px;
}

.check-label {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.78rem;
  color: var(--t2);
  white-space: nowrap;
  cursor: pointer;
}

.check-label input {
  width: auto;
}

.shortcuts-hint {
  text-align: center;
  margin-top: 0.5rem;
  font-size: 0.76rem;
}

/* ─── Mark / form rows ─── */
.mark-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.6rem;
}

.formrow {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.55rem;
  flex-wrap: wrap;
}

.form-label {
  font-size: 0.73rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--t2);
  min-width: 78px;
}

/* Hit form laid out horizontally, spread across the full player width, so
   playback + annotation controls fit one laptop screen without scrolling. */
.hit-form-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 0.55rem 1.4rem;
  margin-bottom: 0.6rem;
}

.hit-form-grid .formrow {
  margin-bottom: 0;
  flex: 0 1 auto;
}

.hit-form-grid .formrow .form-label {
  min-width: unset;
}

.hit-form-grid .formrow-wide {
  flex-basis: 100%;
}

/* Spread the hit-panel action rows to the player's edges. */
#hits-panel .export-row {
  justify-content: space-between;
}

.export-row {
  margin-top: 0.7rem;
  padding-top: 0.7rem;
  border-top: 1px solid var(--border);
}

a.btn-sm {
  text-decoration: none;
}

/* ─── Toggle groups (hit form) ─── */
.toggle-group {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}

.toggle-btn {
  border: 1px solid var(--border-lit);
  background: rgba(12, 24, 42, 0.7);
  color: var(--t2);
  border-radius: var(--r-sm);
  padding: 0.36rem 0.6rem;
  cursor: pointer;
  font-family: 'Inter', sans-serif;
  font-size: 0.78rem;
  font-weight: 600;
  transition: all 0.18s var(--ease);
  white-space: nowrap;
}

.toggle-btn:hover {
  background: rgba(18, 38, 62, 0.85);
  color: var(--t1);
  border-color: rgba(255, 255, 255, 0.18);
}

.toggle-btn.on {
  border-color: rgba(46, 204, 113, 0.55);
  background: rgba(46, 204, 113, 0.14);
  color: var(--green);
  box-shadow: 0 0 12px rgba(46, 204, 113, 0.12);
}

/* ─── Studio tables ─── */
.table-wrap {
  overflow-x: auto;
  margin-top: 0.5rem;
  scrollbar-width: thin;
  scrollbar-color: rgba(46, 204, 113, 0.2) transparent;
}

.studio-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8rem;
}

.studio-table thead th {
  text-align: left;
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--t3);
  padding: 0.45rem 0.55rem;
  border-bottom: 1px solid var(--border-lit);
  white-space: nowrap;
}

.studio-table tbody td {
  padding: 0.45rem 0.55rem;
  border-bottom: 1px solid var(--border);
  color: var(--t1);
  font-family: 'JetBrains Mono', monospace;
  white-space: nowrap;
}

.studio-table tbody tr:hover {
  background: rgba(10, 26, 46, 0.6);
}

.studio-table tbody tr.editing {
  background: rgba(15, 52, 100, 0.35);
}

.clip-cell.ok {
  color: #5dffa5;
}

.clip-cell.err {
  color: #ff8a8a;
}

.row-actions {
  display: flex;
  gap: 0.3rem;
}

.mini-btn {
  border: 1px solid var(--border-lit);
  background: rgba(12, 26, 44, 0.7);
  color: var(--t2);
  border-radius: 6px;
  padding: 0.26rem 0.5rem;
  cursor: pointer;
  font-family: 'Inter', sans-serif;
  font-size: 0.74rem;
  font-weight: 600;
  transition: all 0.18s var(--ease);
  white-space: nowrap;
}

.mini-btn:hover {
  background: rgba(18, 38, 62, 0.9);
  color: var(--t1);
  transform: translateY(-1px);
}

.mini-btn.accent {
  border-color: rgba(46, 204, 113, 0.4);
  color: var(--green);
}

.mini-btn.danger:hover {
  border-color: rgba(255, 95, 95, 0.5);
  color: #ff8a8a;
  background: rgba(80, 18, 18, 0.5);
}

/* ─── Rally winner (GT) ─── */
/* Read-only winner badge in the rally table (set in the add-rally form). */
.win-tag {
  display: inline-block;
  min-width: 1.2rem;
  text-align: center;
  border: 1px solid rgba(46, 204, 113, 0.5);
  background: rgba(46, 204, 113, 0.14);
  color: var(--green);
  border-radius: 6px;
  padding: 0.08rem 0.4rem;
  font-weight: 800;
  font-size: 0.74rem;
}

/* GT winner row in the hit-annotation panel */
.gt-winner-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.6rem;
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--border);
  border-left: 3px solid var(--amber);
  border-radius: var(--r-sm);
  background: rgba(245, 166, 35, 0.06);
}

.gt-winner-note {
  font-size: 0.74rem;
  color: var(--t3);
  font-family: 'JetBrains Mono', monospace;
}

/* ─── SOP issue list ─── */
.issue-list {
  display: grid;
  gap: 0.35rem;
  margin-bottom: 0.7rem;
}

.issue {
  font-size: 0.8rem;
  padding: 0.5rem 0.7rem;
  border-radius: var(--r-sm);
  border: 1px solid var(--border);
  background: rgba(4, 14, 26, 0.7);
  line-height: 1.45;
}

.issue b {
  text-transform: uppercase;
  font-size: 0.7rem;
  letter-spacing: 0.05em;
}

.issue.ok {
  border-color: rgba(46, 204, 113, 0.4);
  background: rgba(6, 40, 28, 0.5);
  color: #5dffa5;
}

.issue.err {
  border-color: rgba(255, 95, 95, 0.4);
  background: rgba(50, 12, 12, 0.4);
  color: #ff9d9d;
}

.issue.warn {
  border-color: rgba(245, 166, 35, 0.4);
  background: rgba(60, 40, 10, 0.4);
  color: #ffcc70;
}

.clip-status {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.76rem;
  margin-bottom: 0.7rem;
}

.clip-status-warn {
  color: #ffcc70;
  font-weight: 600;
}

/* ─── Submit block ─── */
.submit-wrap {
  margin-top: 0.7rem;
  padding-top: 0.8rem;
  border-top: 1px solid var(--border-green);
}

.submit-wrap .btn-upload {
  width: 100%;
  margin-bottom: 0.5rem;
}

/* ─── Stage note (clip preparation / load errors) ─── */
.stage-note {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.8rem;
  text-align: center;
  padding: 1.2rem;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--t2);
  background: rgba(2, 8, 16, 0.82);
  backdrop-filter: blur(4px);
}

.stage-note.err {
  color: #ff9d9d;
}

.stage-note-action {
  flex-shrink: 0;
}

/* ─── Rally rail (jump between rallies while annotating) ─── */
/* Vertical rally list — a sticky panel to the left of the video in Hit mode. */
.rally-rail {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  position: sticky;
  top: 0.9rem;
  max-height: calc(100vh - 1.8rem);
  padding: 0.55rem;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  backdrop-filter: blur(24px) saturate(1.4);
  -webkit-backdrop-filter: blur(24px) saturate(1.4);
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.45), 0 1px 0 rgba(255, 255, 255, 0.05) inset;
}

.rally-rail-head {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--t1);
  letter-spacing: -0.01em;
  padding-bottom: 0.15rem;
}

.rally-rail-head svg {
  color: var(--green);
  flex-shrink: 0;
}

.rally-rail-strip {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  overflow-y: auto;
  overflow-x: hidden;
  padding-right: 0.15rem;
  scrollbar-width: thin;
  scrollbar-color: rgba(46, 204, 113, 0.2) transparent;
}

.rally-rail-strip::-webkit-scrollbar {
  width: 4px;
}

.rally-rail-strip::-webkit-scrollbar-thumb {
  background: rgba(46, 204, 113, 0.2);
  border-radius: 2px;
}

.rally-chip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem;
  width: 100%;
  border: 1px solid var(--border-lit);
  background: rgba(12, 24, 42, 0.7);
  color: var(--t2);
  border-radius: var(--r-sm);
  padding: 0.34rem 0.5rem;
  cursor: pointer;
  font-family: 'Inter', sans-serif;
  font-size: 0.74rem;
  font-weight: 700;
  transition: all 0.18s var(--ease);
  text-align: left;
}

.rally-chip small {
  font-size: 0.66rem;
  font-weight: 700;
  font-family: 'JetBrains Mono', monospace;
  color: var(--t3);
  background: rgba(4, 14, 26, 0.8);
  border-radius: 999px;
  padding: 0.1rem 0.44rem;
  flex-shrink: 0;
}

.rally-chip:hover {
  background: rgba(18, 38, 62, 0.85);
  color: var(--t1);
  border-color: rgba(255, 255, 255, 0.18);
}

.rally-chip.on {
  border-color: rgba(46, 204, 113, 0.55);
  background: rgba(46, 204, 113, 0.14);
  color: var(--green);
  box-shadow: 0 0 12px rgba(46, 204, 113, 0.12);
}

.rally-chip.on small {
  color: var(--green);
}

/* ─── Quick add-stroke bar (under the frame readout) ─── */
.player-hit-bar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.7rem;
  flex-wrap: wrap;
  margin-bottom: 0.7rem;
  padding: 0.55rem 0.7rem;
  border: 1px dashed rgba(46, 204, 113, 0.3);
  border-radius: var(--r-md);
  background: rgba(46, 204, 113, 0.04);
}

.quick-add-btn {
  flex: 0 1 auto;
  padding: 0.5rem 1rem;
  font-size: 0.82rem;
}

.quick-add-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.quick-hit-summary {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.74rem;
  color: var(--t3);
  white-space: nowrap;
}

/* ─── Studio responsive ─── */
@media (max-width: 1200px) {
  .studio-grid,
  .studio-grid.mode-hits {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Collapse the segmentation side column back under the player. */
  .studio-main,
  .mode-hits .studio-main {
    grid-template-columns: 1fr;
  }

  .studio-grid:not(.mode-hits) .player-panel {
    grid-row: auto;
  }

  .studio-grid:not(.mode-hits) #rally-panel,
  .studio-grid:not(.mode-hits) #finish-panel {
    grid-column: auto;
  }

  .studio-grid:not(.mode-hits) #rally-panel .table-wrap {
    max-height: none;
  }

  /* Collapse the hit-mode player + hit-controls columns back into a stack. */
  .mode-hits .player-panel,
  .mode-hits #hits-panel {
    grid-column: auto;
  }

  /* Rally list drops above the video and stops sticking on narrow screens. */
  .rally-rail {
    position: static;
    max-height: 120px;
  }

  .picker-grid {
    grid-template-columns: 1fr;
  }
}
/* ─── Verification page (/verify) ───────────────────────────────────────
   Reuses the studio's stage / transport / toggle / table styles; only what is
   specific to reviewing inference results lives here. */

/* Distinguishes verification tasks on the dashboard and in the page header. */
.badge.verify {
  background: rgba(0, 90, 84, 0.55);
  border-color: rgba(0, 212, 184, 0.45);
  color: #5ff2dc;
}

.vf-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 400px;
  gap: var(--gap);
  align-items: start;
  animation: fade-rise 0.5s var(--ease) both;
}

.vf-side {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
  min-width: 0;
}

/* Detections are drawn on a canvas stacked over the video and the exact-frame
   JPEG. It never takes clicks unless the verifier is placing a position. */
.vf-overlay {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 3;
  pointer-events: none;
}

.vf-overlay.placing {
  pointer-events: auto;
  cursor: crosshair;
}

.vf-timeline {
  position: relative;
  height: 14px;
  margin-top: 0.55rem;
}

.vf-tick {
  position: absolute;
  top: 0;
  width: 5px;
  height: 14px;
  margin-left: -2px;
  border-radius: 2px;
  border: none;
  padding: 0;
  cursor: pointer;
  opacity: 0.85;
}

.vf-tick:hover,
.vf-tick.selected {
  opacity: 1;
  transform: scaleY(1.25);
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.55);
  z-index: 2;
}

.vf-frame-context {
  color: var(--t3);
  margin-left: 0.5rem;
}

/* Review status colours — shared by ticks, dots and badges. */
.st-unreviewed { --st: var(--amber); }
.st-accepted   { --st: var(--green); }
.st-corrected  { --st: var(--blue); }
.st-rejected   { --st: var(--danger); }
.st-added      { --st: var(--teal); }

.vf-tick { background: var(--st, var(--t3)); }

/* Status as a dot in the narrow item list; the name is in the title and for
   screen readers. */
.vf-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--st, var(--t3));
  vertical-align: middle;
}

.vf-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.vf-cell-type {
  max-width: 96px;
  overflow: hidden;
  text-overflow: ellipsis;
}

.badge.vf-badge {
  color: var(--st, var(--t3));
  border-color: var(--st, var(--border));
  background: rgba(10, 22, 38, 0.8);
}

/* Autosave indicator */
.vf-save {
  font-size: 0.72rem;
  font-weight: 700;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  color: var(--t3);
  white-space: nowrap;
}
.vf-save.is-saved  { color: #5dffa5; border-color: rgba(46, 204, 113, 0.35); }
.vf-save.is-dirty  { color: #ffcc70; border-color: rgba(245, 166, 35, 0.45); }
.vf-save.is-saving { color: #80caff; border-color: rgba(59, 158, 255, 0.45); }
.vf-save.is-error  { color: #ff9d9d; border-color: rgba(255, 95, 95, 0.5); }

.vf-progress { margin: 0.2rem 0 0.5rem; }
.vf-summary { margin: 0 0 0.6rem; }

.vf-result {
  margin-top: 0.4rem;
  padding: 0.6rem 0.75rem;
  border-radius: var(--r-sm);
  border: 1px solid rgba(46, 204, 113, 0.4);
  background: rgba(26, 100, 65, 0.3);
  color: #b6ffd6;
  font-size: 0.82rem;
  line-height: 1.45;
  white-space: pre-line;
}

.vf-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin-bottom: 0.4rem;
}

.vf-chips .chip {
  padding: 0.22rem 0.55rem;
  font-size: 0.7rem;
}

/* The list scrolls inside its panel so the Review and Edit panels stay on
   screen while working down a long match. */
.vf-items {
  max-height: 32vh;
  overflow-y: auto;
}

.vf-items .studio-table tbody tr {
  cursor: pointer;
}

.vf-items .studio-table tbody tr.selected {
  background: rgba(15, 52, 100, 0.45);
  box-shadow: inset 3px 0 0 var(--st, var(--blue));
}

.vf-items .studio-table tbody tr.st-rejected td:not(.vf-cell-act) {
  text-decoration: line-through;
  opacity: 0.6;
}

.vf-items .studio-table tbody td {
  padding: 0.35rem 0.45rem;
}

.vf-cell-act {
  text-align: right;
}

.vf-add-row {
  margin: 0.5rem 0 0;
}

.vf-actions {
  margin-bottom: 0.5rem;
}

.vf-pos {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.78rem;
  color: var(--t1);
}

.vf-notice-msg {
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--t1);
  margin: 0.3rem 0 0.7rem;
}

.vf-notice-detail {
  font-size: 0.74rem;
  max-height: 160px;
  overflow: auto;
  padding: 0.6rem;
  border-radius: var(--r-sm);
  background: rgba(2, 8, 16, 0.7);
  border: 1px solid var(--border);
  color: var(--t2);
  white-space: pre-wrap;
}

/* Top-down court (positions are court metres, not video pixels). */
.vf-court {
  display: block;
  width: 100%;
  height: 330px;
  border-radius: var(--r-sm);
  background: rgba(2, 8, 16, 0.55);
}

.vf-legend {
  font-size: 0.72rem;
  margin: 0.4rem 0 0;
}

/* Rally headers group their strokes in the review list. */
.vf-items .studio-table tbody tr.vf-rally-row td {
  background: rgba(20, 44, 74, 0.55);
  font-size: 0.78rem;
  border-top: 1px solid var(--border-lit);
}

.vf-items .studio-table tbody tr.vf-context {
  opacity: 0.55;
}

/* Rallies on the timeline: a bar spanning start→end, under the stroke ticks. */
.vf-span {
  position: absolute;
  top: 4px;
  height: 6px;
  border: none;
  padding: 0;
  border-radius: 3px;
  cursor: pointer;
  opacity: 0.45;
  background: var(--st, var(--t3));
}

.vf-span:hover,
.vf-span.selected {
  opacity: 0.8;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.5);
}

.vf-tick { z-index: 1; }

.vf-info {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.72rem;
  line-height: 1.5;
  color: var(--t2);
  white-space: pre-wrap;
  margin: 0.5rem 0 0.3rem;
  padding: 0.5rem 0.6rem;
  border-radius: var(--r-sm);
  background: rgba(2, 8, 16, 0.5);
  border: 1px solid var(--border);
}

.vf-info:empty {
  display: none;
}

/* Stroke type: the model's two predictions as cards, plus "Neither". */
/* Label above, cards across the whole panel — the side column is too narrow
   for three cards beside a label. */
.vf-choice-row {
  flex-direction: column;
  align-items: stretch;
  gap: 0.3rem;
}

.vf-choice-body {
  min-width: 0;
}

.vf-choices {
  display: grid;
  grid-template-columns: 1fr 1fr 0.8fr;
  gap: 0.35rem;
}

.vf-choice {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  text-align: left;
  padding: 0.4rem 0.5rem;
  border-radius: var(--r-sm);
  border: 1px solid var(--border-lit);
  background: rgba(12, 24, 42, 0.7);
  color: var(--t2);
  font-family: 'Inter', sans-serif;
  cursor: pointer;
  min-width: 0;
  width: auto;
  max-width: none;
}

.vf-choice:hover {
  border-color: rgba(255, 255, 255, 0.2);
  color: var(--t1);
}

.vf-choice.on {
  border-color: rgba(46, 204, 113, 0.6);
  background: rgba(46, 204, 113, 0.14);
  color: var(--green);
}

.vf-choice-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 0.3rem;
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  opacity: 0.85;
  flex-wrap: wrap;
}

.vf-choice-name {
  font-size: 0.8rem;
  font-weight: 700;
  white-space: normal;
  overflow-wrap: anywhere;
  word-break: break-word;
}

/* Model confidence for that prediction. */
.vf-conf {
  display: block;
  height: 4px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.1);
  overflow: hidden;
}

.vf-conf > span {
  display: block;
  height: 100%;
  background: currentColor;
  opacity: 0.8;
}

.vf-choice-list {
  margin-top: 0.4rem;
}

@media (max-width: 1100px) {
  .vf-grid {
    grid-template-columns: 1fr;
  }

  .vf-items {
    max-height: 260px;
  }
}

/* ─── Verification: studio layout (rally page / strokes page) ─── */
/* Strokes page timeline is zoomed to the open rally: a bar for the rally,
   stroke ticks on it, and a playhead (dimmed outside the rally). */
.vf-zoom-bar {
  position: absolute;
  left: 0;
  right: 0;
  top: 4px;
  height: 6px;
  border-radius: 3px;
  background: rgba(59, 158, 255, 0.18);
}

.vf-playhead {
  position: absolute;
  top: -2px;
  width: 2px;
  height: 18px;
  margin-left: -1px;
  background: #e8f1ff;
  pointer-events: none;
  z-index: 3;
}

.vf-playhead.outside {
  opacity: 0.25;
}

/* A rally whose strokes are all verified. */
.rally-chip.vf-chip-done small {
  color: var(--green);
}

.vf-empty {
  color: var(--t3);
  font-size: 0.85rem;
  margin: 0.4rem 0;
}

#verify-view .vf-items {
  max-height: 34vh;
  overflow-y: auto;
}

#verify-view #finish-panel .export-row,
#verify-view #hits-panel .export-row {
  display: block;
}

#verify-view #hits-panel #submit-btn {
  width: 100%;
  margin-top: 0.4rem;
}

/* Verification: items the verifier deleted stay listed (restorable), struck through. */
.st-deleted { --st: var(--danger); }
.vf-items .studio-table tbody tr.st-deleted td:not(.row-actions):not(:first-child) {
  text-decoration: line-through;
  opacity: 0.55;
}
.vf-span.st-deleted { opacity: 0.35; }
#verify-view .issue[data-rally] { cursor: pointer; }

/* Verification: keyboard shortcuts under the transport controls, on both pages
   (the studio's hit mode hides its hint; this one stays). */
#verify-view .vf-shortcuts {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.3rem 0.9rem;
  margin-top: 0.45rem;
  font-size: 0.72rem;
  color: var(--t3);
}

#verify-view .vf-shortcuts i {
  font-style: normal;
}

#verify-view .vf-shortcuts kbd {
  display: inline-block;
  min-width: 1.35em;
  padding: 0.05rem 0.32rem;
  margin-right: 0.15rem;
  border: 1px solid var(--border-lit);
  border-bottom-width: 2px;
  border-radius: 4px;
  background: rgba(12, 24, 42, 0.8);
  color: var(--t1);
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.68rem;
  text-align: center;
}

/* Verification strokes page: the form and the list can swap places (the icon at
   the panel's right edge, level with the Shot buttons). Flipped = list on top,
   form below. The icon is pinned (--flip-top is measured in JS from the normal
   layout), so it stays put when the blocks swap; the narrow gutter keeps it
   clear of every button and table cell in both layouts. */
#verify-view .vf-flip {
  position: relative;
  display: flex;
  flex-direction: column;
  padding-right: 36px;
}

/* Order, not column-reverse: the Verify / Delete row always sits directly under
   whichever block is on top — form, row, list; or list, row, form. */
#verify-view .vf-flip > #stroke-form,
#verify-view .vf-flip > #stroke-empty { order: 1; }
#verify-view .vf-flip > #stroke-actions { order: 2; }
#verify-view .vf-flip > #stroke-list { order: 3; }
#verify-view .vf-flip.flipped > #stroke-list { order: 1; }
#verify-view .vf-flip.flipped > #stroke-form,
#verify-view .vf-flip.flipped > #stroke-empty { order: 3; }

#verify-view .vf-flip-btn {
  position: absolute;
  right: 0;
  top: var(--flip-top, 9rem);
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.3rem 0.45rem;
}

#verify-view .vf-flip.flipped .vf-flip-btn {
  border-color: rgba(46, 204, 113, 0.5);
  color: var(--green);
}

/* "Add missed stroke/rally": the "@ frame N" part always sits on its own line, so
   the button's size doesn't change as the frame number grows while the video plays. */
#verify-view .vf-add-text {
  display: block;
  text-align: center;
  white-space: nowrap;
}

#verify-view .vf-add-line {
  display: block;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* The zoomed strokes-page bar is scrubbable; touch drags must not scroll the page. */
body.studio-hits #verify-view .vf-timeline {
  cursor: pointer;
  touch-action: none;
  user-select: none;
}
