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

:root {
  /* Phosphor defaults. applyColorScheme() sets the same values from JS; these
     are what the first paint uses, so there is no flash of another palette. */
  --bg: #061009;
  --surface: #0a1a10;
  --surface-2: #0d2216;
  --surface-3: #12301f;
  --border: #1f5c39;
  --text: #6cf08a;
  --text-muted: #4fbf7a;
  --text-dim: #2c7a4e;

  --accent: #6cf08a;
  --accent-soft: #3ec96a;
  --accent-glow: rgba(108, 240, 138, 0.25);
  --accent-bg: rgba(108, 240, 138, 0.1);

  --rose: #ff9d6c;
  --peach: #ffcf5c;
  --sage: #9ae66e;
  --sky: #5ad2e0;
  --lavender: #9ae66e;
  --mauve: #9ae66e;
  --sand: #ffcf5c;
  --vocal-color: #ff9d6c;

  --drums-color: #6cf08a;
  --chords-color: #5ad2e0;
  --bass-color: #ffcf5c;
  --melody-color: #c8ffd8;

  --grid-cell: #0a1a10;
  --grid-beat: #102a18;
  --grid-alt: #081409;
  --grid-alt-beat: #0e2415;
  --grid-border: #1f5c39;
  --piano-roll-bg: #061009;
  --note-color: #ffcf5c;
  --note-border: #061009;

  --radius: 14px;
  --radius-sm: 8px;
  --radius-xs: 6px;
  --safe-bottom: 0px;
}

html {
  height: 100%;
  height: 100dvh;
}

body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  background: var(--bg);
  color: var(--text);
  height: 100%;
  height: 100dvh;
  overflow: hidden;
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  user-select: none;
}

/* Screens */
.screen {
  display: none;
  position: fixed;
  inset: 0;
  overflow-y: auto;
  scrollbar-width: none;
}
.screen::-webkit-scrollbar { display: none; }
.screen.active { display: flex; }

/* HOME */
.home-container {
  margin: auto;
  padding: 24px;
  width: 100%;
  max-width: 560px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 32px;
  text-align: center;
}

.logo {
  font-size: 2.8rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  line-height: 1.1;
  color: var(--accent);
  text-shadow: 0 0 40px var(--accent-glow);
}

.tagline {
  color: var(--text-muted);
  font-size: 0.9rem;
  margin-top: -16px;
}

.home-actions {
  display: flex;
  flex-direction: column;
  gap: 16px;
  width: 100%;
}

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

.code-input {
  flex: 1;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  padding: 12px 16px;
  font-size: 1.1rem;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  text-align: center;
  outline: none;
  font-family: inherit;
}

.code-input::placeholder {
  letter-spacing: 0.04em;
  text-transform: none;
  font-weight: 400;
  color: var(--text-dim);
}

.code-input:focus { border-color: var(--accent-soft); }

.name-input {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  padding: 10px 16px;
  font-size: 0.9rem;
  text-align: center;
  outline: none;
  width: 200px;
  font-family: inherit;
}
.name-input::placeholder { color: var(--text-dim); }
.name-input:focus { border-color: var(--accent-soft); }

.home-hint {
  color: var(--text-dim);
  font-size: 0.8rem;
  margin-top: -16px;
}

/* Buttons */
.btn-primary {
  background: var(--accent);
  color: #1a1528;
  border: none;
  border-radius: var(--radius-sm);
  padding: 14px 24px;
  font-size: 1rem;
  font-weight: 700;
  cursor: pointer;
  transition: all 0.15s;
  font-family: inherit;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
}
.btn-primary:active { transform: scale(0.96); opacity: 0.9; }
.btn-primary:disabled { opacity: 0.4; cursor: default; transform: none; }

.btn-secondary {
  background: var(--surface-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 12px 20px;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.15s;
  font-family: inherit;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.btn-secondary:active { transform: scale(0.96); }

.btn-text {
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: 0.85rem;
  cursor: pointer;
  padding: 8px;
  font-family: inherit;
}
.btn-text:hover { color: var(--text); }

.btn-icon {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 4px;
  display: flex;
}
.btn-icon:active { color: var(--accent); }

/* LOBBY */
.lobby-container {
  margin: auto;
  padding: 24px;
  width: 100%;
  max-width: 720px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.lobby-header {
  display: flex;
  align-items: center;
  gap: 8px;
}

.lobby-header h2 {
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--text-muted);
}

.room-code {
  font-size: 1.3rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  color: var(--accent);
}

.player-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.player-card {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 12px 16px;
}

.player-avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.1rem;
  font-weight: 700;
  color: #1a1528;
  flex-shrink: 0;
}

.player-name {
  font-weight: 600;
  font-size: 0.95rem;
}

.player-badge {
  margin-left: auto;
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-dim);
}

.host-controls {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 8px;
}

.song-input {
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  padding: 12px 16px;
  font-size: 0.95rem;
  outline: none;
  font-family: inherit;
}
.song-input::placeholder { color: var(--text-dim); }
.song-input:focus { border-color: var(--accent-soft); }

.lobby-tempo {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.lobby-tempo label {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
}

.guest-waiting {
  text-align: center;
  padding: 20px;
  color: var(--text-muted);
  font-size: 0.9rem;
}

/* REVEAL */
.reveal-container {
  margin: auto;
  padding: 24px;
  text-align: center;
  max-width: 620px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

.reveal-label {
  font-size: 0.9rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
}

.reveal-song {
  font-size: 2rem;
  font-weight: 800;
  color: var(--accent);
  word-break: break-word;
}

.reveal-instrument {
  font-size: 1rem;
  color: var(--text-muted);
}
.reveal-instrument strong {
  color: var(--text);
  text-transform: capitalize;
}

.reveal-timer {
  width: 100%;
  height: 4px;
  background: var(--surface-3);
  border-radius: 2px;
  margin-top: 16px;
  overflow: hidden;
}

.reveal-bar {
  height: 100%;
  background: var(--accent);
  border-radius: 2px;
  width: 100%;
  transition: width 5s linear;
}

/* BUILD */
.build-container {
  padding: 20px 24px;
  max-width: 1240px;
  margin: 0 auto;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-height: 100%;
}

.build-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
}

.build-info {
  display: flex;
  align-items: center;
  gap: 8px;
}

.build-song {
  font-size: 0.85rem;
  color: var(--text-muted);
  max-width: 300px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.build-badge {
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 4px 10px;
  border-radius: 20px;
  color: #1a1528;
}

.build-badge[data-inst="drums"] { background: var(--drums-color); }
.build-badge[data-inst="chords"] { background: var(--chords-color); }
.build-badge[data-inst="bass"] { background: var(--bass-color); }
.build-badge[data-inst="melody"] { background: var(--melody-color); }

.build-timer {
  display: flex;
  align-items: center;
  gap: 4px;
  color: var(--text-muted);
  font-size: 0.85rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* Sequencer shared */
.sequencer {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: 0;
}

.seq-controls {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
}

.btn-seq-play {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--accent);
  border: none;
  color: #1a1528;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
}
.btn-seq-play:active { transform: scale(0.92); }

.tempo-mini {
  display: flex;
  align-items: center;
  gap: 6px;
}
.tempo-mini label {
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--text-dim);
  text-transform: uppercase;
}

.bpm-display {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--text-muted);
  letter-spacing: 0.04em;
}

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

.tempo-control input[type="range"] {
  flex: 1;
  -webkit-appearance: none;
  appearance: none;
  height: 4px;
  background: var(--border);
  border-radius: 2px;
  outline: none;
}

.tempo-control input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--accent);
  cursor: pointer;
}

.tempo-display {
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--accent);
  min-width: 36px;
  text-align: right;
}

/* Drum grid */
.drum-grid {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 0 16px;
  overflow-y: auto;
  /* Plain `center` clips the first and last lane once the rows are taller
     than the container — and the clipped part cannot be scrolled to. That
     is exactly what happens on a phone held sideways. `safe center` falls
     back to flex-start instead; the first declaration covers browsers that
     drop the whole thing as invalid. */
  justify-content: flex-start;
  justify-content: safe center;
  scrollbar-width: none;
}
.drum-grid::-webkit-scrollbar { display: none; }

.drum-row {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}

.drum-label {
  width: 56px;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--text-muted);
  text-align: right;
  flex-shrink: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.drum-cell {
  flex: 1;
  aspect-ratio: 1;
  max-width: 48px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.1s;
}

.drum-cell.on {
  background: var(--drums-color);
  border-color: var(--drums-color);
}

.drum-cell.beat { background: var(--surface-2); }

/* Bar ruler. Shares the cell sizing so the ticks stay over their steps. */
.drum-ruler { margin-bottom: 2px; }
.drum-tick {
  flex: 1;
  max-width: 48px;
  height: 14px;
  font-size: 0.6rem;
  line-height: 14px;
  text-align: center;
  color: var(--text-dim);
  user-select: none;
}
.drum-tick.beat { color: var(--text-muted); }
.drum-cell.playing { box-shadow: 0 0 8px var(--accent-glow); }

/* Note grid (bass/melody) */
.note-grid {
  flex: 1;
  overflow: auto;
  scrollbar-width: none;
  position: relative;
}
.note-grid::-webkit-scrollbar { display: none; }

/* A grid holding a piano roll scrolls inside the roll rather than as a whole,
   so the sound picker and the chord bar stay put while the notes scroll under
   them. Without this the grid takes its content's full height and the panels
   above the roll scroll off the top. */
.note-grid.note-grid-roll {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.note-grid.note-grid-roll .piano-roll-wrapper { min-height: 0; }
.note-grid.note-grid-roll .piano-roll { min-height: 0; overflow: auto; }

.note-grid-inner {
  display: grid;
  gap: 2px;
  min-width: 100%;
}

.note-cell {
  height: 32px;
  background: var(--surface);
  border: 1px solid transparent;
  border-radius: 3px;
  cursor: pointer;
  transition: all 0.1s;
}

.note-cell.beat { background: var(--surface-2); }
.note-cell.playing { border-color: rgba(167,139,250,0.3); }

.note-label {
  font-size: 0.6rem;
  font-weight: 600;
  color: var(--text-dim);
  text-align: right;
  padding-right: 4px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  height: 32px;
}

/* Piano Roll */
.piano-roll-wrapper {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 0;
}

.piano-roll {
  flex: 1;
  overflow: auto;
  padding: 0 16px;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--piano-roll-bg);
}
.piano-roll::-webkit-scrollbar { width: 6px; height: 6px; }
.piano-roll::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }

.piano-roll-canvas {
  position: relative;
  user-select: none;
  -webkit-user-select: none;
}

.pr-label {
  position: absolute;
  left: 0;
  width: 52px;
  font-size: 0.65rem;
  font-weight: 600;
  color: var(--text-dim);
  text-align: right;
  padding-right: 4px;
  z-index: 2;
  pointer-events: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.pr-cell {
  position: absolute;
  background: var(--surface);
  border: 1px solid rgba(53, 53, 80, 0.4);
  cursor: crosshair;
}

.pr-cell.pr-beat {
  background: var(--surface-2);
}

.pr-notes-layer {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 3;
}

.pr-note-block {
  position: absolute;
  border-radius: 3px;
  cursor: pointer;
  pointer-events: auto;
  display: flex;
  align-items: center;
  padding-left: 3px;
  font-size: 0.5rem;
  font-weight: 600;
  color: rgba(0,0,0,0.6);
  overflow: hidden;
  white-space: nowrap;
  z-index: 4;
}

.pr-note-block[data-inst="drums"] { background: var(--drums-color); }
.pr-note-block[data-inst="chords"] { background: var(--chords-color); }
.pr-note-block[data-inst="bass"] { background: var(--bass-color); }
.pr-note-block[data-inst="melody"] { background: var(--melody-color); }

.pr-playhead {
  position: absolute;
  top: 0;
  width: 2px;
  height: 100%;
  background: var(--accent);
  z-index: 5;
  pointer-events: none;
  opacity: 0.8;
}

/* Chord selector dropdowns */
.chord-selector-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
  padding: 4px 0;
}

.chord-select {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  padding: 10px 14px;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  outline: none;
  font-family: inherit;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239b8fc0' stroke-width='2.5' stroke-linecap='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 32px;
  min-width: 80px;
}
.chord-select:focus { border-color: var(--accent-soft); }
.chord-select option {
  background: var(--surface);
  color: var(--text);
}

.chord-display {
  font-size: 1.2rem;
  font-weight: 800;
  color: var(--accent);
  min-width: 60px;
  text-align: center;
  letter-spacing: 0.02em;
}

.btn-submit {
  flex-shrink: 0;
  margin-top: auto;
  padding-bottom: calc(14px + var(--safe-bottom));
}

/* LISTEN */
.listen-container {
  margin: auto;
  padding: 24px;
  width: 100%;
  max-width: 820px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  text-align: center;
}

.listen-title {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.listen-song {
  font-size: 1.8rem;
  font-weight: 800;
  color: var(--accent);
  word-break: break-word;
}

.listen-layers {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 8px 0;
}

.layer-card {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 12px 16px;
  text-align: left;
}

.layer-badge {
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 4px 8px;
  border-radius: 12px;
  color: #1a1528;
  flex-shrink: 0;
}

.layer-badge[data-inst="drums"] { background: var(--drums-color); }
.layer-badge[data-inst="chords"] { background: var(--chords-color); }
.layer-badge[data-inst="bass"] { background: var(--bass-color); }
.layer-badge[data-inst="melody"] { background: var(--melody-color); }

.layer-player {
  font-weight: 600;
  font-size: 0.9rem;
}

.layer-status {
  margin-left: auto;
  font-size: 0.75rem;
  color: var(--text-dim);
}

.listen-controls {
  display: flex;
  gap: 12px;
  width: 100%;
}

.listen-controls .btn-primary,
.listen-controls .btn-secondary {
  flex: 1;
}

.listen-actions {
  display: flex;
  gap: 12px;
  align-items: center;
  margin-top: 8px;
}

/* Bass note on color */
.note-cell.on[data-inst="bass"] {
  background: var(--bass-color);
  border-color: var(--bass-color);
}

.note-cell.on[data-inst="melody"] {
  background: var(--melody-color);
  border-color: var(--melody-color);
}

/* Toast */
.toast {
  position: fixed;
  bottom: calc(40px + var(--safe-bottom));
  left: 50%;
  transform: translateX(-50%) translateY(16px);
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 10px 20px;
  border-radius: var(--radius);
  font-size: 0.82rem;
  opacity: 0;
  transition: all 0.25s;
  z-index: 100;
  pointer-events: none;
  white-space: nowrap;
}
.toast.show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* Song Entry */
.songentry-container {
  margin: auto;
  padding: 24px;
  width: 100%;
  max-width: 520px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  text-align: center;
}

.songentry-player {
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--accent);
}

/* Handoff */
.handoff-container {
  margin: auto;
  padding: 24px;
  width: 100%;
  max-width: 520px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  text-align: center;
}

.handoff-label {
  font-size: 0.85rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
}

.handoff-player {
  font-size: 2rem;
  font-weight: 800;
  color: var(--accent);
}

.handoff-instrument {
  font-size: 1rem;
  color: var(--text);
  font-weight: 600;
}

.handoff-hint {
  font-size: 0.85rem;
  color: var(--text-muted);
  font-style: italic;
}

/* Waiting dots animation */
.waiting-dots {
  display: flex;
  gap: 6px;
  justify-content: center;
  margin-top: 8px;
}
.waiting-dots span {
  font-size: 2rem;
  font-weight: 800;
  color: var(--accent);
  animation: waitBounce 1.4s infinite ease-in-out;
}
.waiting-dots span:nth-child(2) { animation-delay: 0.2s; }
.waiting-dots span:nth-child(3) { animation-delay: 0.4s; }
@keyframes waitBounce {
  0%, 80%, 100% { opacity: 0.3; transform: translateY(0); }
  40% { opacity: 1; transform: translateY(-8px); }
}

/* Piano roll grid */
.pr-cell {
  background: var(--grid-cell);
  border: 1px solid var(--grid-border);
}

.pr-cell.pr-beat {
  background: var(--grid-beat);
}

.pr-cell.pr-alt {
  background: var(--grid-alt);
}

.pr-cell.pr-alt.pr-beat {
  background: var(--grid-alt-beat);
}

/* Accidental rows read as the black keys of a keyboard */
.pr-cell.pr-sharp {
  background: var(--grid-alt);
  filter: brightness(0.72);
}

.pr-cell.pr-sharp.pr-beat {
  background: var(--grid-alt-beat);
  filter: brightness(0.72);
}

.pr-label-sharp {
  opacity: 0.6;
}

.pr-note-block {
  background: var(--note-color) !important;
  color: rgba(255,255,255,0.95) !important;
  border: 1px solid var(--note-border);
  box-shadow: 0 1px 4px rgba(0,0,0,0.2);
}

.pr-note-block[data-inst="drums"] { background: var(--drums-color) !important; color: rgba(0,0,0,0.6) !important; border: none; box-shadow: none; }

/* Piano roll resize handle */
.pr-resize-handle {
  position: absolute;
  right: 0;
  top: 0;
  width: 10px;
  height: 100%;
  cursor: ew-resize;
  background: rgba(255,255,255,0.15);
  border-radius: 0 3px 3px 0;
}

/* Chord timeline */
.chord-timeline-wrapper {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 0;
}

.chord-timeline {
  flex: 1;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--piano-roll-bg);
}
.chord-timeline::-webkit-scrollbar { width: 6px; height: 6px; }
.chord-timeline::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }

.chord-timeline-canvas {
  position: relative;
  user-select: none;
  -webkit-user-select: none;
}

.ct-cell {
  position: absolute;
  background: var(--grid-cell);
  border: 1px solid var(--grid-border);
  cursor: crosshair;
}

.ct-cell.ct-beat {
  background: var(--grid-beat);
}

.ct-beat-num {
  position: absolute;
  top: -16px;
  font-size: 0.5rem;
  font-weight: 600;
  color: var(--text-dim);
  text-align: center;
  pointer-events: none;
}

.ct-notes-layer {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 3;
}

.ct-note-block {
  position: absolute;
  background: var(--chords-color);
  border-radius: 3px;
  cursor: pointer;
  pointer-events: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.65rem;
  font-weight: 700;
  color: #1a1528;
  overflow: hidden;
  white-space: nowrap;
  z-index: 4;
}

.ct-note-label {
  pointer-events: none;
}

.ct-handle-right {
  position: absolute;
  right: 0;
  top: 0;
  width: 10px;
  height: 100%;
  cursor: ew-resize;
  background: rgba(0,0,0,0.15);
  border-radius: 0 3px 3px 0;
}

/* Listen to existing layers button */
.btn-listen-existing {
  flex-shrink: 0;
  width: 100%;
}

/* Guess section */
.guess-section {
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex-shrink: 0;
}

.guess-label {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* Listen guesses */
.listen-guesses {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 8px 0;
}

.guesses-title {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  text-align: left;
}

.guess-row {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 14px;
}

.guess-player {
  font-weight: 600;
  font-size: 0.85rem;
  min-width: 60px;
}

.guess-text {
  flex: 1;
  font-size: 0.85rem;
  color: var(--text-muted);
  font-style: italic;
}

.guess-badge {
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 10px;
  flex-shrink: 0;
}

.guess-badge.correct {
  background: var(--sage);
  color: #1a1528;
}

.guess-badge.wrong {
  background: rgba(194, 46, 46, 0.3);
  color: #e88;
}

/* Theme picker */
.theme-picker {
  display: flex;
  gap: 10px;
  justify-content: center;
  margin-top: -16px;
}

.theme-dot {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 2px solid transparent;
  cursor: pointer;
  transition: all 0.15s;
  outline: none;
  box-shadow: 0 2px 8px rgba(0,0,0,0.3);
}
.theme-dot:active { transform: scale(0.9); }
.theme-dot.active {
  border-color: var(--text);
  box-shadow: 0 0 0 2px var(--bg), 0 0 12px var(--accent-glow);
}

/* Listen counter (Song X of Y) */
.listen-counter {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* Desktop enhancements */
@media (min-width: 601px) {
  .chord-pick:hover {
    background: var(--surface-2);
    border-color: var(--accent-soft);
  }
  .drum-cell:hover:not(.on) {
    background: var(--surface-2);
  }
  .btn-primary:hover:not(:disabled) { opacity: 0.9; }
  .btn-secondary:hover { background: var(--surface-3); }
  .theme-dot:hover { transform: scale(1.15); }
  .pr-cell:hover { background: var(--surface-2) !important; }
  .ct-cell:hover { background: var(--surface-2) !important; }
}

/* ============================================================
   MOBILE
   The desktop layout assumes it can show all 32 steps and every
   sound at once. On a phone that squeezed drum cells to ~8px and
   pushed the grid off the bottom of the screen. Here the rule is
   the opposite: tap targets keep their size and the content
   scrolls sideways instead.
   ============================================================ */
@media (max-width: 600px) {
  .home-container { max-width: 400px; }
  .lobby-container { max-width: 440px; }
  .build-container { max-width: 600px; padding: 12px 10px; gap: 10px; }
  .listen-container { max-width: 440px; }
  .songentry-container { max-width: 400px; }
  .handoff-container { max-width: 400px; }
  .reveal-container { max-width: 400px; }
  .build-song { max-width: 120px; }

  /* Drums: fixed 30px cells that swipe, rather than 32 cells crushed
     into 390px. The label gutter stays pinned so you can always tell
     which lane you are on. */
  .drum-grid {
    overflow-x: auto;
    padding: 0;
    scrollbar-width: none;
    scroll-padding-left: 46px;
    overscroll-behavior-x: contain;
  }
  .drum-grid::-webkit-scrollbar { display: none; }
  .drum-row { width: max-content; }
  .drum-grid { justify-content: flex-start; }
  /* Taller than wide: width is the scarce axis on a phone, height is not,
     so the lanes get easier to hit vertically for free. */
  .drum-cell {
    flex: 0 0 28px;
    width: 28px;
    height: 36px;
    max-width: none;
    aspect-ratio: auto;
  }
  .drum-tick {
    flex: 0 0 28px;
    width: 28px;
    max-width: none;
  }
  /* Beat starts get a keyline, so bars stay countable while scrolling */
  .drum-cell.beat { box-shadow: inset 2px 0 0 var(--text-dim); }
  .drum-label {
    position: sticky;
    left: 0;
    z-index: 2;
    width: 46px;
    min-width: 46px;
    font-size: 0.65rem;
    /* Matches the sequencer panel behind it, so cells scrolling under the
       pinned gutter are hidden without drawing a visible band. */
    background: var(--surface);
    padding-right: 4px;
  }

  .piano-roll { padding: 0; }
  .note-cell, .note-label { height: 28px; }

  /* Thumb-sized controls */
  .theme-dot { width: 34px; height: 34px; }

  /* The submit bar is fixed at the bottom, so the toast has to clear it */
  .toast {
    bottom: calc(86px + var(--safe-bottom));
    max-width: calc(100vw - 32px);
    white-space: normal;
    text-align: center;
  }
}

/* Game Options */
.game-options {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
}

.game-options-label {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
}

.option-toggles {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
}

.option-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  padding: 10px 12px;
  cursor: pointer;
  transition: all 0.15s;
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--text-muted);
}

.option-toggle:has(input:checked) {
  border-color: var(--accent-soft);
  background: var(--accent-bg);
  color: var(--accent);
}

.option-toggle input[type="checkbox"] {
  -webkit-appearance: none;
  appearance: none;
  width: 16px;
  height: 16px;
  border: 2px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  cursor: pointer;
  flex-shrink: 0;
  position: relative;
}

.option-toggle input[type="checkbox"]:checked {
  background: var(--accent);
  border-color: var(--accent);
}

.option-toggle input[type="checkbox"]:checked::after {
  content: '';
  position: absolute;
  left: 3px;
  top: 0px;
  width: 5px;
  height: 9px;
  border: solid #1a1528;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

/* SFX color */
.build-badge[data-inst="sfx"] { background: var(--mauve); }
.layer-badge[data-inst="sfx"] { background: var(--mauve); }

/* Vocal color */
.build-badge[data-inst="vocal"] { background: var(--vocal-color); }
.layer-badge[data-inst="vocal"] { background: var(--vocal-color); }

/* Voting screen */
.voting-container {
  margin: auto;
  padding: 24px;
  width: 100%;
  max-width: 760px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  text-align: center;
}

.voting-title {
  font-size: 1.2rem;
  font-weight: 800;
  color: var(--accent);
}

.voting-song {
  font-size: 0.85rem;
  color: var(--text-muted);
}

.voting-options {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.vote-option {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--surface);
  border: 2px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 14px 16px;
  cursor: pointer;
  transition: all 0.15s;
  text-align: left;
}

.vote-option:active { transform: scale(0.98); }

.vote-option.selected {
  border-color: var(--accent);
  background: var(--accent-bg);
}

.vote-option .vote-layer {
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 10px;
  color: #1a1528;
  flex-shrink: 0;
}

.vote-option .vote-player {
  font-weight: 600;
  font-size: 0.9rem;
}

.vote-option .vote-check {
  margin-left: auto;
  width: 20px;
  height: 20px;
  border: 2px solid var(--border);
  border-radius: 50%;
  flex-shrink: 0;
}

.vote-option.selected .vote-check {
  background: var(--accent);
  border-color: var(--accent);
}

.voting-results {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.results-title {
  font-size: 0.95rem;
  font-weight: 700;
  margin: 4px 0 0;
}
.vote-result-label {
  font-size: 0.85rem;
  font-weight: 600;
  min-width: 100px;
}

.vote-result {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 12px 16px;
}

.vote-result.winner {
  border-color: var(--accent);
  background: var(--accent-bg);
}

.vote-result .vote-player { font-weight: 600; font-size: 0.9rem; }

.vote-bar-track {
  flex: 1;
  height: 8px;
  background: var(--surface-3);
  border-radius: 4px;
  overflow: hidden;
}

.vote-bar-fill {
  height: 100%;
  background: var(--accent);
  border-radius: 4px;
  transition: width 0.6s ease;
}

.vote-count {
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--accent);
  min-width: 28px;
  text-align: right;
}

/* Speed round indicator */
.speed-badge {
  background: #e05050;
  color: white;
  font-size: 0.6rem;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 10px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  animation: speedPulse 1s infinite;
}

@keyframes speedPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.6; }
}

/* Buildup reveal controls */
.buildup-controls {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  width: 100%;
  margin-top: 8px;
}
.buildup-status {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text-muted);
  margin: 0;
}

.buildup-btn {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 20px;
  color: var(--text-muted);
  padding: 8px 16px;
  font-size: 0.75rem;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.15s;
  font-family: inherit;
  text-transform: capitalize;
}

.buildup-btn.active {
  background: var(--accent);
  color: #1a1528;
  border-color: var(--accent);
}

.buildup-btn:active { transform: scale(0.94); }

/* Vocal recorder */
.vocal-waveform {
  width: 100%;
  height: 80px;
  border-radius: var(--radius-sm);
  background: var(--surface);
  border: 1px solid var(--border);
}
.vocal-status {
  font-size: 0.8rem;
  color: var(--text-muted);
  font-weight: 500;
}

/* Vocal clip placement timeline */
.vocal-timeline {
  margin-top: 8px;
  overflow-x: auto;
  overflow-y: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--piano-roll-bg);
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
.vocal-timeline::-webkit-scrollbar { height: 6px; }
.vocal-timeline::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }

.vocal-timeline-canvas {
  position: relative;
  height: 48px;
  user-select: none;
  -webkit-user-select: none;
}

.vocal-cell {
  position: absolute;
  top: 0;
  height: 100%;
  background: var(--surface);
  border-right: 1px solid rgba(53, 53, 80, 0.4);
  box-sizing: border-box;
}
.vocal-cell.beat { background: var(--surface-2); }

.vocal-block {
  position: absolute;
  top: 4px;
  height: calc(100% - 8px);
  background: var(--accent);
  color: #1a1528;
  border-radius: var(--radius-xs);
  font-size: 0.7rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: grab;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
  touch-action: none;
  overflow: hidden;
}
.vocal-block:active { cursor: grabbing; }
.btn-rec {
  color: #e05050;
}
.btn-rec.recording {
  animation: recPulse 0.8s infinite;
  color: #ff3333;
}
@keyframes recPulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.6; transform: scale(1.1); }
}

.btn-sm {
  font-size: 0.75rem;
  padding: 6px 12px;
}

/* Grip marks so both drag edges are discoverable — blocks resize from
   either side, and the middle deletes. */
.pr-note-block::before,
.pr-note-block::after,
.ct-note-block::before,
.ct-note-block::after {
  content: '';
  position: absolute;
  top: 22%;
  bottom: 22%;
  width: 2px;
  border-radius: 1px;
  background: rgba(0, 0, 0, 0.4);
  pointer-events: none;
}
.pr-note-block::before,
.ct-note-block::before { left: 3px; }
.pr-note-block::after,
.ct-note-block::after { right: 3px; }

/* ── Shaper ──
   The knob panel under the sound picker on chords, bass and melody. Amber on
   black, with a ring of lit segments round each knob: it reads as a piece of
   hardware bolted under the roll rather than another row of web controls. */
.shaper {
  display: flex;
  flex-direction: column;
  background: #081409;
  border: 1px solid var(--peach);
  border-radius: 2px;
  flex-shrink: 0;
  /* No overflow clipping here: the preset list drops out of the panel and
     would be cut off at the bottom edge. */
}

.shaper-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 3px 10px;
  background: var(--peach);
  color: #061009;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-shadow: none;
}
.shaper.edited .shaper-head::after {
  content: 'EDITED';
  order: 1;
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  opacity: 0.65;
}
.shaper-tools { display: flex; gap: 6px; order: 2; }
.shaper-toggle {
  display: flex;
  align-items: center;
  gap: 7px;
  background: none;
  border: 0;
  padding: 3px 0;
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  cursor: pointer;
  text-shadow: none;
}
.shaper-caret { transition: transform 0.15s ease; font-size: 0.9em; }
.shaper.collapsed .shaper-caret { transform: rotate(-90deg); }
.shaper.collapsed .shaper-preset,
.shaper.collapsed .shaper-source,
.shaper.collapsed .shaper-table,
.shaper.collapsed .shaper-knobs { display: none; }
.shaper-btn {
  background: transparent;
  border: 1px solid rgba(6, 16, 9, 0.5);
  color: #061009;
  font: inherit;
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  padding: 1px 9px;
  min-height: 24px;
  cursor: pointer;
  text-shadow: none;
}
.shaper-btn:hover { background: rgba(6, 16, 9, 0.12); }
.shaper-btn:active { background: rgba(6, 16, 9, 0.22); }

/* Source toggle: presets or wavetable, one at a time. */
.shaper-source {
  display: flex;
  gap: 0;
  padding: 10px 12px 0;
}
.src-btn {
  flex: 1;
  min-height: 34px;
  padding: 4px 10px;
  background: transparent;
  border: 1px solid rgba(255, 207, 92, 0.35);
  color: rgba(255, 207, 92, 0.65);
  font: inherit;
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  cursor: pointer;
}
.src-btn + .src-btn { border-left: 0; }
.src-btn:hover:not(.on) { background: rgba(255, 207, 92, 0.08); }
.src-btn.on {
  background: var(--peach);
  border-color: var(--peach);
  color: #061009;
  text-shadow: none;
}

/* Preset picker: a lit window with a step arrow either side, and a drop-down
   list of every sound for the layer. */
.shaper-preset {
  position: relative;
  display: flex;
  align-items: stretch;
  gap: 8px;
  padding: 10px 12px 0;
}

.preset-step {
  flex: none;
  width: 34px;
  background: transparent;
  border: 1px solid rgba(255, 207, 92, 0.35);
  color: var(--peach);
  font: inherit;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}
.preset-step:hover { background: rgba(255, 207, 92, 0.1); }

.preset-field {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 6px 10px;
  min-height: 36px;
  background: rgba(255, 207, 92, 0.07);
  border: 1px solid var(--peach);
  color: var(--peach);
  font: inherit;
  letter-spacing: 0.08em;
  cursor: pointer;
}
.preset-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.preset-caret { flex: none; opacity: 0.7; font-size: 0.8em; }

.preset-list {
  position: absolute;
  z-index: 30;
  left: 54px;
  right: 54px;
  margin: 0 auto;
  max-width: 340px;
  top: calc(100% + 2px);
  max-height: 232px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  background: #081409;
  border: 1px solid var(--peach);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.6);
}
.preset-option {
  background: transparent;
  border: 0;
  border-bottom: 1px solid rgba(255, 207, 92, 0.16);
  color: var(--peach);
  font: inherit;
  letter-spacing: 0.06em;
  text-align: left;
  padding: 9px 12px;
  min-height: 40px;
  cursor: pointer;
}
/* A class that sets display beats the UA rule for [hidden], so the list needs
   to be told to stay shut. */
.preset-list[hidden] { display: none; }
.preset-option:last-child { border-bottom: 0; }
.preset-option:hover { background: rgba(255, 207, 92, 0.12); }
.preset-option.on { background: var(--peach); color: #061009; text-shadow: none; }

/* Wavetable row: the scan knob beside a screen showing the wave it is on. */
.shaper-table {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 12px 0;
}
.shaper-table .knob-cell { flex: none; width: 74px; }
.wave-scope {
  flex: 1;
  min-width: 0;
  height: 62px;
  border: 1px solid rgba(255, 207, 92, 0.3);
  background: rgba(255, 207, 92, 0.04);
}
.wave-scope svg { display: block; width: 100%; height: 100%; }
.wave-scope .wave-mid {
  stroke: rgba(255, 207, 92, 0.22);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}
.wave-scope .wave-line {
  fill: none;
  stroke: var(--peach);
  stroke-width: 2;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  filter: drop-shadow(0 0 4px rgba(255, 207, 92, 0.6));
}

.shaper-knobs {
  display: flex;
  justify-content: space-between;
  gap: 4px;
  padding: 12px 12px 10px;
}

.knob-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  flex: 1;
  min-width: 0;
}

.knob-name,
.knob-value {
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  color: var(--peach);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.knob-name { opacity: 0.6; }

/* A control the current sound cannot honour. Still turnable — the value is
   kept, so it applies again the moment a sound that uses it is picked. */
.knob-cell.inert { opacity: 0.32; }

/* The knob itself: a dark cap with a pointer line, ringed by segments that
   light up to the current value. --angle is set from JS. */
.knob {
  position: relative;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 2px solid rgba(255, 207, 92, 0.3);
  background: radial-gradient(circle at 50% 40%, var(--surface-3), var(--surface) 72%);
  cursor: grab;
  touch-action: none;
  flex: none;
}
.knob.grabbed { cursor: grabbing; }
.knob:focus-visible { outline: 2px solid var(--peach); outline-offset: 4px; }
.knob::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 4px;
  width: 2px;
  height: 13px;
  margin-left: -1px;
  background: var(--peach);
  transform-origin: 50% 18px;
  transform: rotate(var(--angle, 0deg));
  box-shadow: 0 0 5px rgba(255, 207, 92, 0.9);
}

.knob-seg { position: absolute; inset: -8px; }
.knob-seg i {
  position: absolute;
  left: 50%;
  top: 0;
  width: 2px;
  height: 5px;
  margin-left: -1px;
  background: rgba(255, 207, 92, 0.22);
  transform-origin: 50% 30px;
}
.knob-seg i.on {
  background: var(--peach);
  box-shadow: 0 0 5px rgba(255, 207, 92, 0.8);
}

@media (max-width: 600px) {
  /* Two rows of three rather than six squeezed across a phone. */
  .shaper-knobs {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px 4px;
  }
}

/* The title bar is the whole control when the panel is folded, so on anything
   touched by a finger its buttons get a thumb-sized target rather than the
   desktop's compact one. Keyed on the pointer, not the width: a phone held
   landscape is wider than the mobile breakpoint and still has no mouse. */
@media (max-width: 600px), (pointer: coarse) {
  .shaper-head { padding: 5px 10px; }
  .shaper-toggle,
  .shaper-btn { min-height: 36px; }
  .shaper-btn { padding: 2px 12px; }
}

/* Quick fill (drums only) */
.fill-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  flex-shrink: 0;
}

.fill-bar-label {
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
}

.fill-buttons {
  display: flex;
  gap: 6px;
}

.fill-btn {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  color: var(--text-muted);
  padding: 7px 12px;
  font-size: 0.78rem;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  min-height: 34px;
}
.fill-btn:disabled { opacity: 0.4; cursor: default; }
.fill-btn.active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--bg);
}

.fill-bar-hint {
  font-size: 0.72rem;
  color: var(--text-dim);
}

/* Chord roll controls */
.chord-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  flex-shrink: 0;
}

.chord-bar-label {
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
}

.chord-bar-hint {
  font-size: 0.72rem;
  color: var(--text-dim);
}

.chord-mode-toggle {
  display: flex;
  gap: 6px;
}

.mode-btn {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  color: var(--text-muted);
  padding: 7px 12px;
  font-size: 0.78rem;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  min-height: 34px;
}
.mode-btn.active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--bg);
}

/* Option help text: explained in place rather than behind a tooltip */
.opt-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.opt-name {
  font-size: 0.82rem;
  font-weight: 600;
}
.opt-help {
  font-size: 0.7rem;
  line-height: 1.3;
  color: var(--text-dim);
  font-weight: 400;
  white-space: normal;
}
.option-toggle {
  align-items: flex-start;
}
.option-toggle input[type="checkbox"] { margin-top: 2px; }

/* ============================================================
   PHOSPHOR SKIN
   A CRT terminal that happens to be a sequencer. The whole look is
   one font, square corners, two colours and a glow — no textures and
   no images, so it costs almost nothing and stays consistent on
   screens the other two skins never reached.
   Green is structure, amber is the thing you are placing right now.
   ============================================================ */

:root[data-skin="phosphor"] {
  --ph-green: #6cf08a;
  --ph-bright: #c8ffd8;
  --ph-mid: #3ec96a;
  --ph-dim: #2c7a4e;
  --ph-amber: #ffcf5c;
  --ph-black: #061009;
  --ph-glow: 0 0 6px rgba(108, 240, 138, 0.45);
  --ph-glow-amber: 0 0 6px rgba(255, 207, 92, 0.45);
  /* The four classic monitor phosphors, one per layer. Overriding the
     instrument variables here means badges, note blocks, layer cards and
     the reveal screen all follow without touching their own rules. */
  --drums-color: #6cf08a;
  --chords-color: #5ad2e0;
  --bass-color: #ffcf5c;
  --melody-color: #c8ffd8;
  --mauve: #9ae66e;
  --vocal-color: #ff9d6c;
}

/* VT323 ships one weight, so every bold in the app is synthesised and smears.
   !important is needed because some headings carry an inline font-weight. */
:root[data-skin="phosphor"] body,
:root[data-skin="phosphor"] body * {
  font-weight: 400 !important;
}

:root[data-skin="phosphor"] body {
  font-family: 'VT323', 'Courier New', monospace;
  font-size: 1.22rem;
  letter-spacing: 0.01em;
  background-color: var(--ph-black);
  background-image: none;
  color: var(--ph-green);
  text-shadow: var(--ph-glow);
}

/* Scanlines sit above the content but never eat a tap */
:root[data-skin="phosphor"] .screen.active::after {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 50;
  background: repeating-linear-gradient(to bottom,
    rgba(0, 0, 0, 0.26) 0 1px, transparent 1px 3px);
}

/* Logo: framed like a boot banner rather than glowing loose text */
:root[data-skin="phosphor"] .logo {
  font-family: 'VT323', monospace;
  font-weight: 400;
  font-size: 3.1rem;
  line-height: 1;
  letter-spacing: 0.14em;
  color: var(--ph-bright);
  text-shadow: 0 0 10px rgba(200, 255, 216, 0.4);
  border: 2px solid var(--ph-green);
  padding: 10px 20px;
}

:root[data-skin="phosphor"] .tagline,
:root[data-skin="phosphor"] .home-hint {
  font-family: 'VT323', monospace;
  font-size: 1.05rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ph-mid);
}

:root[data-skin="phosphor"] .listen-title,
:root[data-skin="phosphor"] .voting-title,
:root[data-skin="phosphor"] .reveal-song,
:root[data-skin="phosphor"] .handoff-player,
:root[data-skin="phosphor"] .listen-song,
:root[data-skin="phosphor"] .room-code {
  font-family: 'VT323', monospace;
  font-weight: 400;
  letter-spacing: 0.1em;
  color: var(--ph-bright);
  text-shadow: 0 0 9px rgba(200, 255, 216, 0.35);
}

/* Panels: a single hairline rule, square. Depth comes from the glow */
:root[data-skin="phosphor"] .sequencer,
:root[data-skin="phosphor"] .guess-section,
:root[data-skin="phosphor"] .game-options,
:root[data-skin="phosphor"] .layer-card,
:root[data-skin="phosphor"] .guess-row,
:root[data-skin="phosphor"] .player-chip,
:root[data-skin="phosphor"] .player-card,
:root[data-skin="phosphor"] .vocal-timeline,
:root[data-skin="phosphor"] .option-toggle,
:root[data-skin="phosphor"] .song-input,
:root[data-skin="phosphor"] .name-input,
:root[data-skin="phosphor"] .code-input,
:root[data-skin="phosphor"] .piano-roll,
:root[data-skin="phosphor"] .vocal-waveform {
  border: 1px solid var(--ph-dim);
  border-radius: 0;
  background: rgba(10, 26, 16, 0.6);
  box-shadow: none;
}

:root[data-skin="phosphor"] .song-input,
:root[data-skin="phosphor"] .name-input,
:root[data-skin="phosphor"] .code-input {
  font-family: 'VT323', monospace;
  color: var(--ph-bright);
  caret-color: var(--ph-amber);
  letter-spacing: 0.08em;
}

/* Buttons read as terminal keys: filled = the action, outlined = the rest */
:root[data-skin="phosphor"] .btn-primary {
  font-family: 'VT323', monospace;
  font-weight: 400;
  font-size: 1.25rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  background: var(--ph-green);
  color: var(--ph-black);
  border: 2px solid var(--ph-green);
  border-radius: 0;
  text-shadow: none;
}
:root[data-skin="phosphor"] .btn-primary:active {
  background: var(--ph-bright);
  border-color: var(--ph-bright);
  transform: none;
}

:root[data-skin="phosphor"] .btn-secondary {
  font-family: 'VT323', monospace;
  font-weight: 400;
  font-size: 1.05rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  background: transparent;
  color: var(--ph-green);
  border: 1px solid var(--ph-green);
  border-radius: 0;
}
:root[data-skin="phosphor"] .btn-secondary:active {
  background: rgba(108, 240, 138, 0.16);
  transform: none;
}

:root[data-skin="phosphor"] .btn-text {
  font-family: 'VT323', monospace;
  font-size: 1rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ph-mid);
}

:root[data-skin="phosphor"] .btn-seq-play,
:root[data-skin="phosphor"] .btn-icon {
  border: 1px solid var(--ph-green);
  border-radius: 0;
  color: var(--ph-green);
  background: transparent;
}

/* Drum hits: a lit cell on a dark grid, which is the whole metaphor */
:root[data-skin="phosphor"] .drum-cell {
  background: rgba(10, 26, 16, 0.55);
  border: 1px solid var(--ph-dim);
  border-radius: 0;
}
:root[data-skin="phosphor"] .drum-cell.beat { background: rgba(16, 42, 24, 0.85); }
:root[data-skin="phosphor"] .drum-cell.on,
:root[data-skin="phosphor"] .drum-cell.on.beat {
  background: var(--drums-color);
  border-color: var(--drums-color);
  box-shadow: 0 0 8px rgba(108, 240, 138, 0.5);
}
:root[data-skin="phosphor"] .drum-cell.playing {
  background: var(--ph-bright);
  border-color: var(--ph-bright);
  box-shadow: 0 0 12px rgba(200, 255, 216, 0.7);
}

:root[data-skin="phosphor"] .drum-label,
:root[data-skin="phosphor"] .pr-label {
  font-family: 'VT323', monospace;
  font-weight: 400;
  font-size: 0.95rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ph-mid);
}
:root[data-skin="phosphor"] .pr-label-sharp { color: var(--ph-dim); opacity: 1; }

:root[data-skin="phosphor"] .pr-cell {
  border-color: rgba(31, 92, 57, 0.5);
}
:root[data-skin="phosphor"] .pr-cell.pr-sharp,
:root[data-skin="phosphor"] .pr-cell.pr-sharp.pr-beat { filter: none; }
:root[data-skin="phosphor"] .pr-cell.pr-sharp { background: #040b07; }
:root[data-skin="phosphor"] .pr-cell.pr-sharp.pr-beat { background: #07140d; }

/* Notes keep their layer's phosphor; the skin only squares them and lights them */
:root[data-skin="phosphor"] .pr-note-block,
:root[data-skin="phosphor"] .ct-note-block {
  border-radius: 0 !important;
  border: 1px solid rgba(6, 16, 9, 0.7) !important;
  color: var(--ph-black) !important;
  box-shadow: 0 0 7px rgba(108, 240, 138, 0.3) !important;
  font-family: 'VT323', monospace;
  font-weight: 400;
  text-shadow: none;
}

:root[data-skin="phosphor"] .vocal-block {
  border-radius: 0;
  border: 1px solid var(--ph-amber);
  background: rgba(255, 207, 92, 0.2);
  color: var(--ph-amber);
  font-family: 'VT323', monospace;
  box-shadow: 0 0 8px rgba(255, 207, 92, 0.35);
}

/* Badges are bracketed labels, not filled pills */
:root[data-skin="phosphor"] .build-badge,
:root[data-skin="phosphor"] .layer-badge,
:root[data-skin="phosphor"] .guess-badge {
  font-family: 'VT323', monospace;
  font-weight: 400;
  font-size: 0.95rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  border-radius: 0;
  box-shadow: none;
  color: var(--ph-black);
  text-shadow: none;
}

:root[data-skin="phosphor"] .build-song {
  font-family: 'VT323', monospace;
  font-size: 1.05rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ph-mid);
}

:root[data-skin="phosphor"] .chord-pick,
:root[data-skin="phosphor"] .chord-select,
:root[data-skin="phosphor"] .mode-btn,
:root[data-skin="phosphor"] .fill-btn {
  font-family: 'VT323', monospace;
  font-weight: 400;
  font-size: 1rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border: 1px solid var(--ph-dim);
  border-radius: 0;
  background: transparent;
  color: var(--ph-mid);
}
:root[data-skin="phosphor"] .chord-pick.active,
:root[data-skin="phosphor"] .mode-btn.active,
:root[data-skin="phosphor"] .fill-btn.active {
  background: rgba(108, 240, 138, 0.16);
  border-color: var(--ph-green);
  color: var(--ph-bright);
  box-shadow: none;
}

:root[data-skin="phosphor"] .crystal-pill,
:root[data-skin="phosphor"] .listen-counter,
:root[data-skin="phosphor"] .bpm-display,
:root[data-skin="phosphor"] .build-timer,
:root[data-skin="phosphor"] .vocal-status,
:root[data-skin="phosphor"] .chord-bar-label,
:root[data-skin="phosphor"] .chord-bar-hint,
:root[data-skin="phosphor"] .fill-bar-label,
:root[data-skin="phosphor"] .fill-bar-hint,
:root[data-skin="phosphor"] .knob-name,
:root[data-skin="phosphor"] .knob-value {
  font-family: 'VT323', monospace;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 1rem;
  color: var(--ph-mid);
}

/* The clock is the one number people watch, so it gets the amber */
:root[data-skin="phosphor"] .build-timer {
  color: var(--ph-amber);
  text-shadow: var(--ph-glow-amber);
  font-size: 1.3rem;
}

/* Every slider is a square amber handle on a hairline track */
:root[data-skin="phosphor"] input[type="range"] {
  background: var(--ph-dim);
  border-radius: 0;
  height: 2px;
}
:root[data-skin="phosphor"] input[type="range"]::-webkit-slider-thumb {
  border-radius: 0;
  width: 10px;
  height: 20px;
  background: var(--ph-amber);
}
:root[data-skin="phosphor"] input[type="range"]::-moz-range-thumb {
  border-radius: 0;
  width: 10px;
  height: 20px;
  border: none;
  background: var(--ph-amber);
}

:root[data-skin="phosphor"] .option-toggle input[type="checkbox"] {
  border-radius: 0;
  border: 1px solid var(--ph-mid);
  background: transparent;
}
:root[data-skin="phosphor"] .option-toggle input[type="checkbox"]:checked {
  background: var(--ph-green);
  border-color: var(--ph-green);
}
:root[data-skin="phosphor"] .option-toggle input[type="checkbox"]:checked::after {
  border-color: var(--ph-black);
}

:root[data-skin="phosphor"] .tempo-display,
:root[data-skin="phosphor"] .opt-group-title,
:root[data-skin="phosphor"] .lobby-section-label {
  font-family: 'VT323', monospace;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

:root[data-skin="phosphor"] .opt-name {
  font-size: 1.05rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
:root[data-skin="phosphor"] .opt-help {
  font-family: 'VT323', monospace;
  font-size: 0.95rem;
  letter-spacing: 0.02em;
  color: var(--ph-dim);
}

:root[data-skin="phosphor"] .theme-dot {
  border: 1px solid var(--ph-dim);
  border-radius: 0;
}
:root[data-skin="phosphor"] .theme-dot.active {
  border-color: var(--ph-bright);
  box-shadow: 0 0 8px rgba(108, 240, 138, 0.6);
}

:root[data-skin="phosphor"] .toast {
  font-family: 'VT323', monospace;
  font-size: 1.1rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: var(--ph-green);
  color: var(--ph-black);
  border: 1px solid var(--ph-green);
  border-radius: 0;
  box-shadow: 0 0 14px rgba(108, 240, 138, 0.4);
  text-shadow: none;
}

@media (max-width: 480px) {
  :root[data-skin="phosphor"] .logo { font-size: 2.5rem; padding: 8px 14px; }
}

/* The shaper is the one amber panel in a green room, so it keeps its own
   colour against the skin's blanket green rules. It comes after them on
   purpose: they select on the same specificity and would otherwise win. */
:root[data-skin="phosphor"] .shaper {
  border: 1px solid var(--ph-amber);
  border-radius: 0;
  background: rgba(8, 20, 9, 0.9);
  box-shadow: 0 0 14px rgba(255, 207, 92, 0.1);
}
:root[data-skin="phosphor"] .shaper-head {
  font-family: 'VT323', monospace;
  font-weight: 400;
  font-size: 1.1rem;
  background: var(--ph-amber);
  color: var(--ph-black);
}
:root[data-skin="phosphor"] .shaper-toggle,
:root[data-skin="phosphor"] .shaper-btn {
  font-family: 'VT323', monospace;
  font-size: 1rem;
  color: var(--ph-black);
}
:root[data-skin="phosphor"] .knob-name,
:root[data-skin="phosphor"] .knob-value {
  color: var(--ph-amber);
  font-size: 1rem;
  text-shadow: var(--ph-glow-amber);
}
:root[data-skin="phosphor"] .knob { border-radius: 50%; }
:root[data-skin="phosphor"] .src-btn,
:root[data-skin="phosphor"] .preset-field,
:root[data-skin="phosphor"] .preset-step,
:root[data-skin="phosphor"] .preset-option {
  font-family: 'VT323', monospace;
  font-weight: 400;
  font-size: 1.15rem;
  text-transform: uppercase;
  color: var(--ph-amber);
  border-radius: 0;
}
:root[data-skin="phosphor"] .preset-option.on,
:root[data-skin="phosphor"] .src-btn.on { color: var(--ph-black); }
:root[data-skin="phosphor"] .preset-list { border-radius: 0; }

/* ============================================================
   MOBILE, PART TWO
   These components are defined further down the file than the main
   mobile block, so rules there lost on source order. Nothing here
   overlaps a skin, so it is safe at the end.
   ============================================================ */
@media (max-width: 600px) {
  /* Two columns of option cards leaves ~150px for a title plus two lines
     of help text. One column per option instead. */
  .option-toggles { grid-template-columns: 1fr; }
  .option-toggle input[type="checkbox"] { width: 22px; height: 22px; }

  .chord-bar { gap: 8px; }
  .chord-bar-hint { width: 100%; }
  .mode-btn, .chord-select, .chord-pick, .fill-btn { min-height: 40px; }
  .fill-bar { gap: 6px; }
  /* The hint line already says what these do, so the label can go and give
     the four buttons the width "Sixteenth" needs. */
  .fill-bar-label { display: none; }
  .fill-bar-hint { width: 100%; }
  .fill-buttons { flex: 1; gap: 5px; }
  .fill-btn { flex: 1; padding: 7px 4px; font-size: 0.74rem; }
}

/* All three skins draw a border on .game-options, but the base panel has no
   padding, so the "Game modes" / "Features" label sat on the keyline. */
:root[data-skin] .game-options {
  padding: 10px 12px;
}

/* ============================================================
   SHORT VIEWPORTS (a phone held sideways)
   All 32 steps fit across the width here, so the win is giving the
   grid back the vertical space the chrome would otherwise take.
   ============================================================ */
@media (max-height: 480px) and (orientation: landscape) {
  .build-container { padding: 8px 12px; gap: 8px; }
  .build-container .btn-primary { padding: 9px 24px; }
  .seq-controls { gap: 8px; }
  .btn-seq-play { width: 34px; height: 34px; }
  .drum-ruler { display: none; }
  .home-container, .lobby-container { gap: 16px; padding: 16px 24px; }
}

/* ============================================================
   PHOSPHOR — FEEDBACK
   Picking something should feel like it lit up: the chosen control
   brightens, grows slightly and sits above its neighbours. Hover is
   the same gesture at half strength, and a press pulls it back in.
   ============================================================ */

:root[data-skin="phosphor"] .chord-pick,
:root[data-skin="phosphor"] .mode-btn,
:root[data-skin="phosphor"] .fill-btn,
:root[data-skin="phosphor"] .btn-primary,
:root[data-skin="phosphor"] .btn-secondary,
:root[data-skin="phosphor"] .btn-seq-play,
:root[data-skin="phosphor"] .btn-icon,
:root[data-skin="phosphor"] .drum-cell {
  transition: transform 0.13s ease, background-color 0.13s ease,
              box-shadow 0.13s ease, color 0.13s ease, border-color 0.13s ease;
}

/* The selected one */
:root[data-skin="phosphor"] .chord-pick.active,
:root[data-skin="phosphor"] .mode-btn.active {
  background: rgba(108, 240, 138, 0.18);
  border-color: var(--ph-green);
  color: var(--ph-bright);
  transform: scale(1.06);
  box-shadow: 0 0 12px rgba(108, 240, 138, 0.35),
              inset 0 0 12px rgba(108, 240, 138, 0.12);
  /* Grown controls overlap their neighbours, so lift the lit one on top */
  position: relative;
  z-index: 2;
}

/* Press */
:root[data-skin="phosphor"] .chord-pick:active,
:root[data-skin="phosphor"] .mode-btn:active,
:root[data-skin="phosphor"] .fill-btn:active,
:root[data-skin="phosphor"] .btn-primary:active,
:root[data-skin="phosphor"] .btn-secondary:active,
:root[data-skin="phosphor"] .btn-seq-play:active {
  transform: scale(0.96);
}

/* Hover, on pointing devices only — a phone would latch this after a tap */
@media (hover: hover) and (pointer: fine) {
  :root[data-skin="phosphor"] .chord-pick:hover:not(.active),
  :root[data-skin="phosphor"] .mode-btn:hover:not(.active),
  :root[data-skin="phosphor"] .fill-btn:hover:not(.active):not(:disabled) {
    transform: scale(1.04);
    background: rgba(108, 240, 138, 0.08);
    border-color: var(--ph-mid);
    color: var(--ph-bright);
  }

  :root[data-skin="phosphor"] .btn-primary:hover:not(:disabled) {
    background: var(--ph-bright);
    border-color: var(--ph-bright);
    transform: scale(1.02);
    box-shadow: 0 0 18px rgba(108, 240, 138, 0.4);
    opacity: 1;
  }

  :root[data-skin="phosphor"] .btn-secondary:hover,
  :root[data-skin="phosphor"] .btn-seq-play:hover {
    background: rgba(108, 240, 138, 0.14);
    border-color: var(--ph-bright);
    color: var(--ph-bright);
    transform: scale(1.02);
    box-shadow: 0 0 14px rgba(108, 240, 138, 0.25);
  }

  :root[data-skin="phosphor"] .btn-text:hover { color: var(--ph-bright); }

  :root[data-skin="phosphor"] .drum-cell:hover:not(.on) {
    background: rgba(108, 240, 138, 0.14);
    border-color: var(--ph-mid);
  }
  :root[data-skin="phosphor"] .pr-cell:hover {
    background: rgba(108, 240, 138, 0.14) !important;
  }
}

/* ============================================================
   PHOSPHOR — CRT MOTION
   One band of mistracking rolling down the tube, on the screens where
   there is nothing to do yet — the title screen and the two setup
   screens. It stays out of the way once a round is running. Transform only, so it
   composites on the GPU, and off under prefers-reduced-motion.
   ============================================================ */

@media (prefers-reduced-motion: no-preference) {
  :root[data-skin="phosphor"] #screen-home.active::before,
  :root[data-skin="phosphor"] #screen-lobby.active::before,
  :root[data-skin="phosphor"] #screen-solo.active::before {
    content: '';
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    height: 140px;
    pointer-events: none;
    z-index: 51;
    background: linear-gradient(to bottom,
      transparent 0%,
      rgba(108, 240, 138, 0.04) 42%,
      rgba(200, 255, 216, 0.08) 50%,
      rgba(108, 240, 138, 0.04) 58%,
      transparent 100%);
    animation: ph-vhs-roll 11s linear infinite;
  }
}

@keyframes ph-vhs-roll {
  0% { transform: translateY(-160px); }
  100% { transform: translateY(100vh); }
}

/* Menu music toggle. Fixed rather than in the page flow so it can sit on the
   title, lobby and solo screens without three copies of the markup. */
.music-toggle {
  position: fixed;
  right: 14px;
  bottom: calc(14px + var(--safe-bottom));
  z-index: 60;
  width: 42px;
  height: 42px;
  align-items: center;
  justify-content: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  cursor: pointer;
  transition: transform 0.13s ease, color 0.13s ease, border-color 0.13s ease;
}
.music-toggle .music-off { display: none; }
.music-toggle.muted { color: var(--text-dim); }
.music-toggle.muted .music-on { display: none; }
.music-toggle.muted .music-off { display: block; }
.music-toggle:active { transform: scale(0.94); }

:root[data-skin="phosphor"] .music-toggle {
  border-radius: 0;
  background: rgba(10, 26, 16, 0.85);
  border-color: var(--ph-dim);
  color: var(--ph-mid);
}
:root[data-skin="phosphor"] .music-toggle.muted { color: var(--ph-dim); }

@media (hover: hover) and (pointer: fine) {
  :root[data-skin="phosphor"] .music-toggle:hover {
    color: var(--ph-bright);
    border-color: var(--ph-green);
    transform: scale(1.06);
  }
}

/* Song vote: one row per song, play it then vote for it */
.vote-song {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
}
.vote-song-title {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  text-align: left;
}
.vote-song-name {
  font-size: 0.95rem;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.vote-song-by { font-size: 0.72rem; color: var(--text-dim); }
.vote-song-play,
.vote-song-pick {
  flex-shrink: 0;
  min-height: 38px;
  padding: 8px 14px;
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  border-radius: var(--radius-xs);
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-muted);
  display: flex;
  align-items: center;
  gap: 6px;
}
.vote-song-pick.voted,
.vote-song-play.playing {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--bg);
}
.vote-song-pick:disabled { opacity: 0.35; cursor: default; }
.vote-song-count {
  flex-shrink: 0;
  min-width: 26px;
  text-align: right;
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--accent);
}
.vote-song.winner { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.voting-status { font-size: 0.78rem; color: var(--text-dim); text-align: center; }

:root[data-skin="phosphor"] .vote-song,
:root[data-skin="phosphor"] .vote-song-play,
:root[data-skin="phosphor"] .vote-song-pick {
  border-radius: 0;
  background: rgba(10, 26, 16, 0.6);
  border-color: var(--ph-dim);
  color: var(--ph-mid);
}
:root[data-skin="phosphor"] .vote-song-name { color: var(--ph-bright); }
:root[data-skin="phosphor"] .vote-song-pick.voted,
:root[data-skin="phosphor"] .vote-song-play.playing {
  background: rgba(108, 240, 138, 0.18);
  border-color: var(--ph-green);
  color: var(--ph-bright);
  box-shadow: 0 0 12px rgba(108, 240, 138, 0.35);
}
:root[data-skin="phosphor"] .vote-song.winner { box-shadow: 0 0 14px rgba(108, 240, 138, 0.3); }

@media (hover: hover) and (pointer: fine) {
  :root[data-skin="phosphor"] .vote-song-play:hover:not(.playing),
  :root[data-skin="phosphor"] .vote-song-pick:hover:not(.voted):not(:disabled) {
    border-color: var(--ph-green);
    color: var(--ph-bright);
    transform: scale(1.03);
  }
}

@media (max-width: 600px) {
  .vote-song { gap: 8px; padding: 9px 10px; }
  .vote-song-play, .vote-song-pick { padding: 8px 10px; font-size: 0.75rem; min-height: 40px; }
}

/* Waiting screen: the round's instrument playing to itself. The same grid and
   playhead as the build screen, shrunk, so it reads as "a loop is running". */
.wait-seq {
  position: relative;
  width: 168px;
  display: flex;
  flex-direction: column;
  gap: 5px;
  margin: 4px auto 0;
}
.wait-lane {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 4px;
}
.wait-cell {
  height: 15px;
  border: 1px solid var(--border);
  border-radius: 2px;
}
.wait-cell.on {
  animation: waitHit 1.6s linear infinite;
  animation-delay: var(--d);
}
@keyframes waitHit {
  0%, 7% {
    background: var(--wait-color);
    border-color: var(--wait-color);
    box-shadow: 0 0 8px var(--wait-color);
  }
  24%, 100% { background: transparent; border-color: var(--border); box-shadow: none; }
}
.wait-head {
  position: absolute;
  top: -3px;
  bottom: -3px;
  width: 2px;
  background: var(--text);
  opacity: 0.7;
  animation: waitSweep 1.6s steps(8) infinite;
}
@keyframes waitSweep {
  from { transform: translateX(0); }
  to { transform: translateX(168px); }
}
:root[data-skin="phosphor"] .wait-cell { border-radius: 0; border-color: var(--ph-dim); }
:root[data-skin="phosphor"] .wait-head { background: var(--ph-bright); box-shadow: 0 0 8px var(--ph-bright); }

/* Title screen: the theme's own spectrum, along the lower third. Sits behind
   everything and never takes a tap. */
.home-bars {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: 33vh;
  display: flex;
  align-items: flex-end;
  gap: 7px;
  padding: 0 7px;
  pointer-events: none;
  z-index: 0;
  opacity: 0.22;
  /* Fade the tops out rather than ending them in a hard line across the
     buttons: the bars read as background instead of competing with the menu. */
  -webkit-mask-image: linear-gradient(to top, #000 30%, rgba(0, 0, 0, 0.35) 70%, transparent 100%);
  mask-image: linear-gradient(to top, #000 30%, rgba(0, 0, 0, 0.35) 70%, transparent 100%);
}
.home-bars i {
  flex: 1;
  min-width: 0;
  display: block;
  height: 0;
  background: var(--accent);
  /* The rise and fall is shaped in JS now, so a CSS ease on top would only
     add lag. A hair of linear smoothing covers the gap between frames. */
  transition: height 0.05s linear;
}
:root[data-skin="phosphor"] .home-bars i {
  background: linear-gradient(to top, var(--ph-green), var(--ph-bright));
  box-shadow: 0 0 6px rgba(108, 240, 138, 0.5);
}
.home-container { position: relative; z-index: 1; }

@media (max-width: 600px) {
  .home-bars { gap: 4px; padding: 0 4px; }
}

@media (prefers-reduced-motion: reduce) {
  .home-bars i { transition: none; }
  .wait-cell.on { animation: none; background: var(--wait-color); border-color: var(--wait-color); }
  .wait-head { display: none; }
  .home-bars { display: none; }
}
