:root {
  --bg-dark: #0b0d14;
  --bg-panel: #131722;
  --bg-panel-alt: #1a2030;
  --bg-card: #20273c;
  --accent-cyan: #00f2fe;
  --accent-blue: #4facfe;
  --accent-purple: #9b51e0;
  --accent-yellow: #f5a623;
  --accent-red: #ff3366;
  --accent-green: #00e676;
  --text-main: #f0f4f8;
  --text-dim: #8b9bb4;
  --border-subtle: #263147;
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;
}

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

body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  background-color: var(--bg-dark);
  color: var(--text-main);
  height: 100vh;
  overflow: hidden;
  user-select: none;
}

.app-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
}

/* Navbar */
.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 24px;
  background-color: var(--bg-panel);
  border-bottom: 1px solid var(--border-subtle);
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
}

.logo-icon {
  font-size: 24px;
  background: linear-gradient(135deg, var(--accent-cyan), var(--accent-purple));
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-md);
  box-shadow: 0 4px 14px rgba(0, 242, 254, 0.3);
}

.brand-text h1 {
  font-size: 20px;
  font-weight: 800;
  letter-spacing: 1px;
  background: linear-gradient(90deg, #ffffff, var(--accent-cyan));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.brand-text .badge {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 1.5px;
  color: var(--accent-cyan);
  background: rgba(0, 242, 254, 0.1);
  padding: 2px 6px;
  border-radius: 4px;
  border: 1px solid rgba(0, 242, 254, 0.2);
}

.nav-controls {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* Buttons */
.btn {
  padding: 8px 16px;
  border-radius: var(--radius-sm);
  font-weight: 600;
  font-size: 13px;
  cursor: pointer;
  border: none;
  transition: all 0.2s ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}

.btn-primary {
  background: linear-gradient(135deg, #00c6ff, #0072ff);
  color: #fff;
  box-shadow: 0 4px 12px rgba(0, 114, 255, 0.3);
}

.btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(0, 114, 255, 0.5);
}

.btn-secondary {
  background: var(--bg-card);
  color: var(--text-main);
  border: 1px solid var(--border-subtle);
}

.btn-secondary:hover {
  background: var(--bg-panel-alt);
}

.btn-upload {
  background: rgba(155, 81, 224, 0.15);
  color: #c084fc;
  border: 1px solid rgba(155, 81, 224, 0.4);
}

.btn-upload:hover {
  background: rgba(155, 81, 224, 0.3);
}

.btn-icon {
  background: var(--bg-card);
  color: var(--text-main);
  font-size: 16px;
  width: 36px;
  height: 36px;
  padding: 0;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-subtle);
}

/* Main Layout */
.main-content {
  display: flex;
  flex: 1;
  /* No hardcoded height. The navbar is 69px, not the 65px this used to assume, so the old
     calc() pushed this box past the viewport and clipped the bottom of the sidebar. Flex
     already knows the remaining space; min-height:0 lets the sidebar scroll inside it. */
  min-height: 0;
}

/* Sidebar */
.sidebar {
  width: 310px;
  background-color: var(--bg-panel);
  border-right: 1px solid var(--border-subtle);
  display: flex;
  flex-direction: column;
  /* The sidebar itself no longer scrolls - only its body does, so the action bar below
     stays put instead of being pushed off the bottom by a long algorithm list. */
  overflow: hidden;
}

.sidebar-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.sidebar-actions {
  flex-shrink: 0;
  display: flex;
  gap: 10px;
  padding: 14px 20px;
  background: var(--bg-panel);
  border-top: 1px solid var(--border-subtle);
  /* Lifts the bar off the list scrolling underneath it. */
  box-shadow: 0 -10px 20px -12px rgba(0, 0, 0, 0.9);
}

.sidebar-actions .btn {
  flex: 1;
  justify-content: center;
}

.panel-section h3 {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--text-dim);
  margin-bottom: 8px;
}

.form-select {
  width: 100%;
  padding: 10px 12px;
  background: var(--bg-card);
  color: var(--text-main);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  font-size: 13px;
  outline: none;
}

.form-select:focus {
  border-color: var(--accent-cyan);
}

.algo-desc {
  font-size: 11px;
  color: var(--text-dim);
  margin-top: 6px;
  line-height: 1.4;
  min-height: 28px;
}

/* Pseudocode Box */
.pseudocode-box {
  margin-top: 10px;
  background: #080a0f;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.pseudocode-header {
  background: var(--bg-card);
  padding: 4px 8px;
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  color: var(--accent-cyan);
  border-bottom: 1px solid var(--border-subtle);
}

.pseudocode-code {
  display: block;
  padding: 8px 10px;
  font-family: 'Fira Code', monospace;
  font-size: 10px;
  line-height: 1.45;
  color: #c9d1d9;
  max-height: 160px;
  overflow-y: auto;
  white-space: pre-wrap;
  tab-size: 2;
}

/* Visualizer Grid Buttons */
.visualizer-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}

.vis-btn {
  background: var(--bg-card);
  color: var(--text-main);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  padding: 10px 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.vis-btn .icon {
  font-size: 18px;
}

.vis-btn .label {
  font-size: 11px;
  font-weight: 600;
}

.vis-btn:hover {
  background: var(--bg-panel-alt);
  border-color: rgba(0, 242, 254, 0.4);
}

.vis-btn.active {
  background: rgba(0, 242, 254, 0.12);
  border-color: var(--accent-cyan);
  color: var(--accent-cyan);
}

/* Sliders */
.slider-row {
  margin-bottom: 12px;
}

.slider-row label {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: var(--text-dim);
  margin-bottom: 6px;
}

.size-header-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 6px;
}

.size-number-input {
  width: 80px;
  padding: 3px 6px;
  font-family: 'Fira Code', monospace;
  font-size: 12px;
  font-weight: 700;
  text-align: right;
  color: var(--accent-cyan);
  background: var(--bg-card);
  border: 1px solid var(--border-subtle);
  border-radius: 4px;
  outline: none;
}

.size-number-input:focus {
  border-color: var(--accent-cyan);
  box-shadow: 0 0 8px rgba(0, 242, 254, 0.3);
}

.size-presets {
  display: flex;
  gap: 4px;
  margin-top: 6px;
}

.btn-size-preset {
  flex: 1;
  padding: 3px 0;
  font-size: 10px;
  font-weight: 600;
  font-family: 'Fira Code', monospace;
  background: var(--bg-card);
  color: var(--text-dim);
  border: 1px solid var(--border-subtle);
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.15s ease;
}

.btn-size-preset:hover {
  background: var(--bg-panel-alt);
  color: var(--accent-cyan);
  border-color: var(--accent-cyan);
}

input[type=range] {
  width: 100%;
  accent-color: var(--accent-cyan);
}

.buttons-row {
  display: flex;
  gap: 10px;
  margin-top: auto;
}

.buttons-row .btn {
  flex: 1;
  padding: 12px;
}

/* Center Stage */
.stage {
  flex: 1;
  display: flex;
  flex-direction: column;
  background-color: var(--bg-dark);
  position: relative;
  overflow: hidden;
}

/* HUD bar */
.hud-bar {
  display: flex;
  justify-content: space-around;
  padding: 12px 20px;
  background: rgba(19, 23, 34, 0.85);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border-subtle);
}

.hud-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}

.hud-label {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  color: var(--text-dim);
}

.hud-value {
  font-family: 'Fira Code', monospace;
  font-size: 16px;
  font-weight: 600;
  color: var(--text-main);
}

.text-yellow { color: var(--accent-yellow); }
.text-red { color: var(--accent-red); }
.text-blue { color: var(--accent-cyan); }

/* Color Legend Bar */
.color-legend {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 14px;
  padding: 6px 16px;
  background: rgba(14, 18, 27, 0.95);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border-subtle);
  font-size: 11px;
  z-index: 5;
}

.legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.legend-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  display: inline-block;
  flex-shrink: 0;
}

.legend-label {
  color: #a0aec0;
  font-weight: 500;
  letter-spacing: 0.2px;
}

.dot-pivot { background: #ffffff; border: 1.5px solid #d946ef; box-shadow: 0 0 8px rgba(255, 255, 255, 0.9), 0 0 12px rgba(217, 70, 239, 0.8); }
.dot-compare { background: #ffe600; box-shadow: 0 0 6px rgba(255, 230, 0, 0.8); }
.dot-partition-left { background: #00a6ff; box-shadow: 0 0 6px rgba(0, 166, 255, 0.8); }
.dot-partition-right { background: #ff5500; box-shadow: 0 0 6px rgba(255, 85, 0, 0.8); }
.dot-swap { background: #ff0055; box-shadow: 0 0 6px rgba(255, 0, 85, 0.8); }
.dot-sorted { background: #00e676; box-shadow: 0 0 6px rgba(0, 230, 118, 0.8); }
.dot-default { background: #3d7bfd; }


/* Viewport */

.viewport-container {
  flex: 1;
  position: relative;
  width: 100%;
  height: 100%;
}

.three-container, .canvas2d {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.camera-hint {
  position: absolute;
  top: 14px;
  right: 14px;
  background: rgba(19, 23, 34, 0.75);
  padding: 6px 12px;
  border-radius: 20px;
  font-size: 11px;
  color: var(--text-dim);
  border: 1px solid var(--border-subtle);
  pointer-events: none;
  transition: opacity 0.3s ease;
}

/* Status Banner */
.status-banner {
  padding: 8px 20px;
  background: var(--bg-panel);
  border-top: 1px solid var(--border-subtle);
  display: flex;
  align-items: center;
  gap: 10px;
}

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: var(--accent-green);
  box-shadow: 0 0 8px var(--accent-green);
}

.status-text {
  font-family: 'Fira Code', monospace;
  font-size: 12px;
  color: var(--text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Playback bar */
.playback-bar {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 24px;
  background: var(--bg-panel);
  border-top: 1px solid var(--border-subtle);
}

.btn-ctrl {
  background: var(--bg-card);
  color: var(--text-main);
  border: 1px solid var(--border-subtle);
  border-radius: 50%;
  width: 38px;
  height: 38px;
  font-size: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s ease;
}

.btn-ctrl:hover {
  background: var(--bg-panel-alt);
  border-color: var(--accent-cyan);
}

.btn-play {
  width: 44px;
  height: 44px;
  background: linear-gradient(135deg, var(--accent-cyan), var(--accent-blue));
  border: none;
  color: #000;
  font-weight: bold;
}

.btn-play:hover {
  transform: scale(1.05);
}

.scrubber {
  flex: 1;
}

.scrubber-label {
  font-family: 'Fira Code', monospace;
  font-size: 12px;
  color: var(--text-dim);
  min-width: 40px;
  text-align: right;
}

.section-header-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.count-badge {
  font-size: 10px;
  font-weight: 700;
  color: var(--accent-cyan);
  background: rgba(0, 242, 254, 0.12);
  padding: 2px 8px;
  border-radius: 12px;
  border: 1px solid rgba(0, 242, 254, 0.3);
}

.btn-preset {
  font-size: 10px;
  font-weight: 600;
  padding: 4px 8px;
  background: var(--bg-card);
  color: var(--text-dim);
  border: 1px solid var(--border-subtle);
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.15s ease;
}

.btn-preset:hover {
  background: var(--bg-panel-alt);
  color: var(--text-main);
  border-color: var(--accent-blue);
}

/* Multi-algo Checkbox List */
.multi-algo-checkbox-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-height: 220px;
  overflow-y: auto;
  padding-right: 4px;
}

.algo-checkbox-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  background: var(--bg-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: all 0.15s ease;
}

.algo-checkbox-item:hover {
  border-color: rgba(0, 242, 254, 0.4);
  background: rgba(0, 242, 254, 0.05);
}

.algo-checkbox-item.checked {
  border-color: var(--accent-cyan);
  background: rgba(0, 242, 254, 0.1);
}

.algo-checkbox-item input[type="checkbox"] {
  accent-color: var(--accent-cyan);
  cursor: pointer;
}

.algo-checkbox-item .algo-item-name {
  font-size: 12px;
  font-weight: 600;
  flex: 1;
  color: var(--text-main);
}

/* Multi-Sort Comparison Grid */
.multi-sort-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
  gap: 12px;
  width: 100%;
  height: 100%;
  overflow-y: auto;
  padding: 12px;
}

.multi-sort-card {
  background: var(--bg-panel);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
  min-height: 240px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
  transition: border-color 0.2s ease, transform 0.2s ease;
}

.multi-sort-card.finished {
  border-color: var(--accent-green);
  box-shadow: 0 0 20px rgba(0, 230, 118, 0.25);
}

.multi-sort-card.winner {
  border-color: #ffd600;
  box-shadow: 0 0 24px rgba(255, 214, 0, 0.4);
}

.multi-card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 12px;
  background: var(--bg-card);
  border-bottom: 1px solid var(--border-subtle);
}

.multi-card-title {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.multi-card-title-main {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 700;
  font-size: 13px;
  color: var(--text-main);
}

.multi-card-complexity-tags {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
}

.comp-chip {
  font-family: 'Fira Code', monospace;
  font-size: 9.5px;
  font-weight: 600;
  padding: 1px 5px;
  border-radius: 4px;
  letter-spacing: 0.2px;
}

.comp-chip.comp-best {
  background: rgba(0, 230, 118, 0.12);
  color: #00e676;
  border: 1px solid rgba(0, 230, 118, 0.25);
}

.comp-chip.comp-avg {
  background: rgba(245, 166, 35, 0.12);
  color: #f5a623;
  border: 1px solid rgba(245, 166, 35, 0.25);
}

.comp-chip.comp-worst {
  background: rgba(255, 51, 102, 0.12);
  color: #ff3366;
  border: 1px solid rgba(255, 51, 102, 0.25);
}

.multi-card-badge {
  font-size: 10px;
  font-weight: 700;
  padding: 2px 6px;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.1);
}

.multi-card-badge.status-running {
  background: rgba(0, 242, 254, 0.15);
  color: var(--accent-cyan);
  border: 1px solid rgba(0, 242, 254, 0.3);
}

.multi-card-badge.status-done {
  background: rgba(0, 230, 118, 0.15);
  color: var(--accent-green);
  border: 1px solid rgba(0, 230, 118, 0.3);
}

.multi-card-metrics {
  display: flex;
  gap: 10px;
  font-family: 'Fira Code', monospace;
  font-size: 11px;
}

.multi-card-metrics .metric-pill {
  color: var(--text-dim);
}

.multi-card-metrics .metric-val {
  font-weight: 600;
  color: var(--text-main);
}

.multi-card-canvas-wrap {
  flex: 1;
  position: relative;
  width: 100%;
  min-height: 180px;
}

.multi-card-canvas-wrap canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.multi-card-rank-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  font-size: 12px;
  font-weight: 800;
  background: rgba(10, 14, 22, 0.85);
  padding: 3px 8px;
  border-radius: 12px;
  border: 1px solid #ffd600;
  color: #ffd600;
  z-index: 10;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
  animation: popIn 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

@keyframes popIn {
  0% { transform: scale(0.5); opacity: 0; }
  100% { transform: scale(1); opacity: 1; }
}

/* Floating Algorithm Detail Popover */
.algo-detail-popover {
  position: fixed;
  z-index: 9999;
  width: 440px;
  max-width: calc(100vw - 40px);
  max-height: 520px;
  background: rgba(13, 18, 28, 0.95);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid rgba(0, 242, 254, 0.4);
  border-radius: var(--radius-lg);
  box-shadow: 0 16px 48px rgba(0, 0, 0, 0.7), 0 0 24px rgba(0, 242, 254, 0.18);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  pointer-events: none;
  opacity: 0;
  transform: scale(0.96) translateY(6px);
  transition: opacity 0.2s cubic-bezier(0.16, 1, 0.3, 1), transform 0.2s cubic-bezier(0.16, 1, 0.3, 1);
}

.algo-detail-popover.visible {
  opacity: 1;
  transform: scale(1) translateY(0);
}

.popover-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  background: rgba(22, 29, 44, 0.9);
  border-bottom: 1px solid var(--border-subtle);
}

.popover-title-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.popover-icon {
  font-size: 18px;
}

.popover-title {
  font-size: 15px;
  font-weight: 800;
  color: #fff;
  letter-spacing: 0.3px;
}

.popover-badge {
  font-size: 10px;
  font-weight: 700;
  color: var(--accent-cyan);
  background: rgba(0, 242, 254, 0.15);
  padding: 2px 8px;
  border-radius: 6px;
  border: 1px solid rgba(0, 242, 254, 0.3);
}

.popover-body {
  padding: 14px 16px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.popover-desc {
  font-size: 12px;
  line-height: 1.55;
  color: var(--text-dim);
}

.popover-pseudocode-wrap {
  background: rgba(8, 11, 18, 0.85);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  padding: 10px;
  max-height: 240px;
  overflow-y: auto;
}

.popover-pseudocode-label {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  color: var(--accent-blue);
  margin-bottom: 6px;
}

.popover-pseudocode-wrap pre {
  margin: 0;
  font-family: 'Fira Code', monospace;
  font-size: 11px;
  line-height: 1.45;
  color: #a5d6a7;
  white-space: pre-wrap;
}

.multi-sort-card:hover {
  border-color: rgba(0, 242, 254, 0.6);
  transform: translateY(-2px);
  cursor: pointer;
}

/* ==========================================================================
   Multi-language support: implementation picker, Language Race, conformance
   ========================================================================== */

/* --- Single mode: implementation picker ---------------------------------- */

.language-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 10px;
}

.language-row-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #7c8aa5;
  white-space: nowrap;
}

.form-select-sm {
  flex: 1;
  padding: 6px 8px;
  font-size: 12px;
}

/* --- Language Race: chip selector ---------------------------------------- */

.language-chip-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}

.language-chip {
  --lang-color: #7c8aa5;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 12px 6px 9px;
  border: 1px solid rgba(124, 138, 165, 0.35);
  border-radius: 999px;
  background: rgba(10, 14, 22, 0.6);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, opacity 0.15s ease;
  user-select: none;
}

/* Visually hidden, but still rendered and focusable - see the visually-hidden rule in the
   keyboard access section below. Setting display:none here would take the whole selector
   out of the tab order. */

.language-chip-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--lang-color);
  opacity: 0.35;
  transition: opacity 0.15s ease, box-shadow 0.15s ease;
}

.language-chip-name {
  font-size: 12px;
  font-weight: 600;
  color: #9fb0c9;
}

.language-chip.checked {
  border-color: var(--lang-color);
  background: color-mix(in srgb, var(--lang-color) 12%, rgba(10, 14, 22, 0.6));
}

.language-chip.checked .language-chip-dot {
  opacity: 1;
  box-shadow: 0 0 8px var(--lang-color);
}

.language-chip.checked .language-chip-name {
  color: #e8eef7;
}

/* A missing toolchain is a fact about this machine, not a broken feature: show it,
   dimmed and explained by its tooltip, rather than hiding it. */
.language-chip.unavailable {
  opacity: 0.4;
  cursor: not-allowed;
  border-style: dashed;
}

.language-chip.unavailable .language-chip-name {
  text-decoration: line-through;
}

.race-hint {
  margin-top: 14px;
  font-size: 11px;
  line-height: 1.55;
  color: #6b7a94;
}

/* --- Conformance banner --------------------------------------------------- */

.divergence-banner {
  padding: 9px 14px;
  margin-bottom: 10px;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.01em;
}

.divergence-banner.conformant {
  background: rgba(0, 230, 118, 0.09);
  border: 1px solid rgba(0, 230, 118, 0.35);
  color: #6ee7a8;
}

.divergence-banner.diverged {
  background: rgba(255, 51, 102, 0.1);
  border: 1px solid rgba(255, 51, 102, 0.45);
  color: #ff7a9c;
}

/* --- Race tiles ----------------------------------------------------------- */

.lang-dot {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  flex-shrink: 0;
}

.comp-chip.comp-time {
  background: rgba(0, 242, 254, 0.12);
  border-color: rgba(0, 242, 254, 0.4);
  color: #7fe6f5;
  font-variant-numeric: tabular-nums;
}

.comp-chip.comp-build {
  background: rgba(124, 138, 165, 0.12);
  border-color: rgba(124, 138, 165, 0.35);
  color: #9fb0c9;
}

.comp-chip.comp-error {
  background: rgba(255, 51, 102, 0.12);
  border-color: rgba(255, 51, 102, 0.4);
  color: #ff7a9c;
}

.multi-card-badge.status-error {
  background: rgba(255, 51, 102, 0.15);
  color: #ff7a9c;
  border: 1px solid rgba(255, 51, 102, 0.4);
}

.multi-sort-card.unavailable {
  opacity: 0.45;
  border-style: dashed;
}

.multi-sort-card.diverged {
  border-color: rgba(255, 51, 102, 0.6);
  box-shadow: 0 0 0 1px rgba(255, 51, 102, 0.25), 0 0 22px rgba(255, 51, 102, 0.18);
}

/* ==========================================================================
   Control restructure: Vary / Subject / Conditions / View
   ========================================================================== */

/* --- Shared field vocabulary --------------------------------------------- */

.field-group {
  margin-top: 14px;
}

.field-label {
  display: block;
  margin-bottom: 6px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #7c8aa5;
}

/* Constraints are explained here rather than enforced silently by rewriting a value
   the user just typed. */
.field-hint {
  margin-top: 6px;
  font-size: 11px;
  line-height: 1.5;
  color: #6b7a94;
}

.form-input {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--border-subtle);
  border-radius: 6px;
  background: rgba(10, 14, 22, 0.75);
  color: #e8eef7;
  font-family: inherit;
  font-size: 12px;
}

.form-input::placeholder {
  color: #5c6a82;
}

/* --- Vary: segmented control --------------------------------------------- */

/* One control for one axis, rather than three buttons that look like three features. */
.segmented {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--border-subtle);
  border-radius: 8px;
  background: rgba(10, 14, 22, 0.75);
}

.segmented-option {
  padding: 7px 4px;
  border: none;
  border-radius: 5px;
  background: transparent;
  color: #8b9ab3;
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}

.segmented-option:hover {
  color: #cfdaea;
  background: rgba(124, 138, 165, 0.12);
}

.segmented-option.active {
  background: linear-gradient(135deg, #00f2fe, #4facfe);
  color: #04121c;
}

/* --- Subject: algorithm list --------------------------------------------- */

.list-actions {
  display: flex;
  gap: 6px;
  margin-top: 8px;
}

/* Families were already encoded in the old preset buttons; showing them as headings
   makes that structure visible instead of hiding it behind a shortcut. */
.algo-group-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  margin: 12px 0 4px;
  padding: 4px 2px;
  border: none;
  border-bottom: 1px solid var(--border-subtle);
  background: transparent;
  color: #7c8aa5;
  font-family: inherit;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: left;
  cursor: pointer;
}

.algo-group-header:hover {
  color: #00f2fe;
  border-bottom-color: rgba(0, 242, 254, 0.4);
}

.algo-group-header .group-count {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: #5c6a82;
}

.algo-group:first-child .algo-group-header {
  margin-top: 4px;
}

/* --- Conditions: seed ----------------------------------------------------- */

.seed-row {
  display: flex;
  gap: 8px;
}

.seed-input {
  flex: 1;
  font-variant-numeric: tabular-nums;
}

.btn-inline {
  flex-shrink: 0;
  padding: 8px 10px;
  border: 1px solid var(--border-subtle);
  border-radius: 6px;
  background: rgba(10, 14, 22, 0.75);
  color: #9fb0c9;
  font-family: inherit;
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease;
}

.btn-inline:hover {
  border-color: #00f2fe;
  color: #00f2fe;
}

/* --- View: styles the current mode cannot render are removed, not faked --- */

.vis-btn[hidden] {
  display: none !important;
}

/* --- Busy state ----------------------------------------------------------- */

/* A race can take seconds and a first C build a noticeable part of one. Saying so beats
   an unchanged button that invites a second click. */
.btn[aria-busy="true"],
.btn:disabled {
  opacity: 0.6;
  cursor: progress;
  filter: saturate(0.6);
}

/* --- Divergence banner is now a control ----------------------------------- */

.divergence-banner {
  display: block;
  width: 100%;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}

.divergence-banner[hidden] {
  display: none !important;
}

.divergence-banner.conformant {
  cursor: default;
}

.divergence-banner.diverged:hover {
  background: rgba(255, 51, 102, 0.16);
}

/* --- Keyboard access ------------------------------------------------------ */

/* The chip inputs were display:none, which took them out of the tab order entirely and
   made the whole selector mouse-only. Hide them visually but keep them focusable. */
.language-chip input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.language-chip:focus-within {
  outline: 2px solid #00f2fe;
  outline-offset: 2px;
}

.segmented-option:focus-visible,
.btn-inline:focus-visible,
.vis-btn:focus-visible,
.btn-preset:focus-visible,
.algo-group-header:focus-visible,
.divergence-banner:focus-visible,
.form-input:focus-visible,
.form-select:focus-visible {
  outline: 2px solid #00f2fe;
  outline-offset: 2px;
}

.algo-checkbox-item:focus-within {
  outline: 2px solid #00f2fe;
  outline-offset: 1px;
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ==========================================================================
   Race track
   --------------------------------------------------------------------------
   When implementations conform, their step sequences are identical and the four
   array animations are the same picture four times over. Execution speed is the only
   thing that actually differs, so it gets its own view rather than a static number.
   ========================================================================== */

.race-track {
  padding: 10px 14px 12px;
  margin-bottom: 10px;
  border: 1px solid var(--border-subtle);
  border-radius: 8px;
  background: rgba(10, 14, 22, 0.55);
}

.race-track[hidden] {
  display: none !important;
}

.race-track-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 8px;
}

.race-track-title {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #7c8aa5;
}

.race-clock {
  font-family: 'Fira Code', ui-monospace, monospace;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: #00f2fe;
}

.race-lanes {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.race-lane {
  --lane-color: #7c8aa5;
  display: grid;
  grid-template-columns: 86px 1fr 104px;
  align-items: center;
  gap: 10px;
}

.race-lane-name {
  font-size: 11px;
  font-weight: 600;
  color: #9fb0c9;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.race-lane-track {
  position: relative;
  height: 10px;
  border-radius: 5px;
  background: rgba(124, 138, 165, 0.14);
  overflow: hidden;
}

.race-lane-fill {
  height: 100%;
  width: 0;
  border-radius: 5px;
  background: var(--lane-color);
  box-shadow: 0 0 10px -1px var(--lane-color);
}

.race-lane-time {
  font-family: 'Fira Code', ui-monospace, monospace;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  text-align: right;
  color: #6b7a94;
  white-space: nowrap;
}

.race-lane.finished .race-lane-time {
  color: #e8eef7;
  font-weight: 600;
}

.race-lane.leader .race-lane-name {
  color: var(--lane-color);
}

.race-lane.unavailable {
  opacity: 0.4;
}

.race-lane.unavailable .race-lane-track {
  background-image: repeating-linear-gradient(
    -45deg,
    rgba(124, 138, 165, 0.18) 0 4px,
    transparent 4px 8px
  );
}

.race-lane.diverged .race-lane-fill {
  background: repeating-linear-gradient(
    -45deg,
    var(--lane-color) 0 6px,
    rgba(255, 51, 102, 0.85) 6px 12px
  );
}

/* ------------------------------------------------------------------------------------
   Phones and narrow screens.

   The desktop layout puts a 310px sidebar beside the stage, which on a phone leaves the
   visualizer a sliver. Here the page scrolls normally instead: the stage comes first at
   a fixed share of the screen, the settings follow, and Run stays pinned to the bottom.
   ------------------------------------------------------------------------------------ */
@media (max-width: 760px) {
  body {
    height: auto;
    overflow-x: hidden;
    overflow-y: auto;
  }

  .app-container {
    height: auto;
    min-height: 100dvh;
  }

  .navbar {
    padding: 8px 12px;
    position: sticky;
    top: 0;
    z-index: 30;
  }

  .brand { gap: 8px; }
  .logo-icon { width: 32px; height: 32px; font-size: 18px; }
  .brand-text h1 { font-size: 17px; }
  .brand-text .badge { display: none; }
  .btn-upload { padding: 6px 10px; font-size: 12px; }

  .main-content {
    flex-direction: column;
    min-height: auto;
  }

  .stage {
    order: 1;
    flex: none;
    height: 62svh;
    min-height: 380px;
    /* Keeps the sticky navbar from covering the top of the stage when Run scrolls to it. */
    scroll-margin-top: 52px;
  }

  .sidebar {
    order: 2;
    width: auto;
    border-right: none;
    border-top: 1px solid var(--border-subtle);
    overflow: visible;
  }

  .sidebar-scroll {
    overflow: visible;
    padding: 16px 14px;
  }

  .sidebar-actions {
    position: sticky;
    bottom: 0;
    z-index: 20;
    padding: 10px 14px calc(10px + env(safe-area-inset-bottom));
  }

  .pseudocode-code { max-height: 120px; }

  .hud-bar {
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 4px 10px;
    padding: 6px 10px;
  }
  .hud-label { font-size: 8px; letter-spacing: 0.4px; }
  .hud-value { font-size: 12px; }

  .color-legend {
    gap: 4px 10px;
    padding: 4px 8px;
    font-size: 10px;
  }

  /* Mouse instructions mean nothing on a touchscreen. */
  .camera-hint { display: none !important; }

  .status-banner { padding: 6px 10px; }
  .status-text { font-size: 11px; }

  .playback-bar {
    gap: 8px;
    padding: 8px 10px calc(8px + env(safe-area-inset-bottom));
  }
  .btn-ctrl { width: 36px; height: 36px; flex-shrink: 0; }
  .scrubber { min-width: 0; }

  .multi-sort-grid {
    grid-template-columns: 1fr;
    padding: 8px;
    gap: 8px;
  }
}
