/* Mobile-first on purpose - every screen here is used one-handed, in a
   moving car, usually at night. Big tap targets, high contrast, dark
   background so it doesn't blind the driver or the person riding shotgun. */

:root {
  --bg: #16130f;
  --surface: #201b13;
  --surface-raised: #2b2418;
  --border: #3d3524;
  --text: #f2ead9;
  --text-dim: #b8ab8e;
  --accent: #c9a24b; /* seal gold - kept distinct from Spotify's own green so the app doesn't read as Spotify-branded */
  --accent-dim: #a3822f;
  --danger: #ff5470;
  --radius: 14px;
  /* The bottom of the screen stacks two fixed bars - tab nav at the very
     bottom, search above it - referenced from both bars themselves and
     from .screen's padding so scrollable content never hides behind them. */
  --tab-bar-height: 56px;
  --search-bar-height: 62px;
}

/* Always reserve room for the scrollbar, even on tabs short enough not to
   need one. Home and Autopilot usually scroll while Queue, Skipped and
   History often don't, and since the whole layout is centred (and the
   fixed bars are positioned against the viewport), a scrollbar appearing
   narrows the viewport and slides everything sideways by half its width -
   so switching tabs made the entire UI jump left and right. Mobile uses
   overlay scrollbars that take no space, so this only ever shows up on
   desktop, which is exactly where it was spotted. */
html { scrollbar-gutter: stable; }

* { box-sizing: border-box; }

/* Every icon is a monoline stroke drawing that inherits its colour from
   whatever it sits in, so an active tab or a gold award row tints its icon
   for free. Sized in em so it scales with surrounding text unless a more
   specific rule overrides it. */
.icon {
  width: 1.25em;
  height: 1.25em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex-shrink: 0;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  -webkit-tap-highlight-color: transparent;
}

.screen {
  max-width: 480px;
  margin: 0 auto;
  /* bottom padding clears both fixed bars (search + tab nav) stacked below */
  padding: 24px 20px calc(var(--tab-bar-height) + var(--search-bar-height) + env(safe-area-inset-bottom) + 24px);
}

.tab-panel { display: none; }
.tab-panel.active { display: block; }

.screen-center {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding-bottom: 24px;
}

.logo-mark {
  width: 60px;
  height: 60px;
  color: var(--accent);
  margin-bottom: 10px;
}

.logo {
  font-family: 'Fraunces', serif;
  font-weight: 600;
  font-size: 2.5rem;
  margin: 0;
  letter-spacing: 0.01em;
}

.logo-rule {
  width: 46px;
  height: 2px;
  background: var(--accent);
  margin: 10px auto;
}

.tagline {
  color: var(--text-dim);
  font-style: italic;
  margin-top: 4px;
  margin-bottom: 32px;
}

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

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  text-align: left;
}

.card label {
  color: var(--text-dim);
  font-size: 0.85rem;
}

input {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
  font-size: 1.1rem;
  color: var(--text);
  width: 100%;
}

.button {
  display: block;
  text-align: center;
  border: none;
  border-radius: 10px;
  padding: 14px 20px;
  font-size: 1.05rem;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
}

.button-primary {
  background: var(--accent);
  color: #04170a;
}

.button-secondary {
  background: var(--surface-raised);
  color: var(--text);
  border: 1px solid var(--border);
}

/* --- Compact brand lockup at the top of the session pages --- */

.brand-bar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  margin-bottom: 18px;
}

.brand-bar-mark {
  width: 24px;
  height: 24px;
  color: var(--accent);
}

.brand-bar-name {
  font-family: 'Fraunces', serif;
  font-weight: 600;
  font-size: 1.05rem;
}

/* Small, deliberately unobtrusive build tag - not something a guest needs
   to notice, just something to point to when debugging "which version is
   this" after a deploy. Sits below the Up next queue on the Home tab,
   in normal document flow above the fixed tab-bar - never overlapping or
   merged into the bottom nav itself. */
.app-version {
  display: block;
  margin-top: 16px;
  font-size: 0.7rem;
  color: var(--text-dim);
  opacity: 0.6;
  text-align: center;
}

/* --- Session header: room code / QR on the host screen --- */

.session-header {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px;
  text-align: center;
  margin-bottom: 24px;
}

.room-code {
  font-size: 2.4rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  margin: 8px 0;
}

.session-header img {
  width: 140px;
  height: 140px;
  border-radius: 10px;
  margin-top: 8px;
  background: white;
  padding: 6px;
}

.guest-count {
  color: var(--text-dim);
  font-size: 0.9rem;
}

.guest-names {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: center;
  margin-top: 8px;
}

.guest-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 0.8rem;
  color: var(--text);
}

.cohost-badge {
  color: var(--accent);
  width: 14px;
  height: 14px;
}

/* Shared round icon-button look - the guest-chip actions and the larger
   session-header icon buttons (.button-icon, below) both use it, just at
   different sizes. */
.chip-action,
.button-icon {
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-dim);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.chip-action {
  width: 22px;
  height: 22px;
}

/* Filled state doubles as the co-host status indicator, so a guest who's
   already a co-host doesn't need a separate static badge next to this
   button - the button itself shows it. */
.promote-button-active {
  background: rgba(201, 162, 75, 0.18);
  border-color: var(--accent);
  color: var(--accent);
}

.kick-button {
  /* Long-pressing this button is a deliberate gesture, not a request to
     select text or scroll - stop the browser from treating it as either. */
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
}

.chip-action .icon {
  width: 12px;
  height: 12px;
}

/* Shown while a kick-button hold is building toward the long-press
   threshold, so a host can feel the escalation from "mark as left" to
   the harder, banning kick before they reach it. */
.kick-button-pressing {
  background: var(--danger, #c0392b);
  border-color: var(--danger, #c0392b);
  color: #fff;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.guest-names:empty {
  display: none;
}

/* The guest's copy of the join code. Deliberately quieter than the host's
   big room code - it's a reference for reading aloud, not the headline of
   the screen. */
.invite-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

.invite-code-label {
  color: var(--text-dim);
  font-size: 0.82rem;
}

.invite-code {
  color: var(--accent);
  font-weight: 700;
  letter-spacing: 0.14em;
  margin-left: 4px;
}

.invite-button {
  padding: 7px 14px;
  font-size: 0.8rem;
}

.end-session-button {
  margin-top: 14px;
  width: 100%;
}

/* Host-only volume row in the session header. The generic input styling
   above (background, border, padding) is meant for text fields and makes a
   range slider look like a pill - reset it here. */
.volume-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 14px;
}

/* Separate from volume-row itself so the slider can be hidden on devices
   that reject remote volume control (some TVs/speakers) without also
   hiding the device-picker button next to it - a host stuck on one of
   those devices still needs a way to switch away from it. */
.volume-controls {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1;
}

.volume-row input[type='range'] {
  flex: 1;
  background: transparent;
  border: none;
  padding: 0;
  accent-color: var(--accent);
}

.volume-icon {
  color: var(--text-dim);
  width: 17px;
  height: 17px;
}

.button-icon {
  width: 28px;
  height: 28px;
  flex-shrink: 0;
}

.button-icon .icon {
  width: 15px;
  height: 15px;
}

/* The on-demand device list under the volume row. Hidden by default and
   toggled by device-picker-button - see host.js for why it's fetched fresh
   on open rather than kept live. */
.device-list {
  margin-top: 8px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.device-list-status {
  color: var(--text-dim);
  font-size: 0.85rem;
}

.device-option {
  text-align: left;
  padding: 8px 12px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
}

.device-option-active {
  border-color: var(--accent);
  color: var(--accent);
}

/* --- Now playing --- */

.now-playing-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px;
  margin-bottom: 20px;
}

.now-playing {
  display: flex;
  gap: 14px;
  align-items: center;
}

.playback-status {
  font-size: 0.78rem;
  color: var(--text-dim);
  margin-top: 12px;
}

/* --- Now-playing progress bar --- */

.progress-track {
  height: 4px;
  background: var(--surface-raised);
  border-radius: 2px;
  margin-top: 12px;
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  width: 0%;
  background: var(--accent);
  border-radius: 2px;
}

.progress-times {
  display: flex;
  justify-content: space-between;
  color: var(--text-dim);
  font-size: 0.72rem;
  margin-top: 4px;
}

/* --- "Up next" highlight on the queue's first row --- */

.queue-item.up-next {
  border-color: var(--accent-dim);
}

.up-next-label {
  color: var(--accent);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-bottom: 2px;
}

/* --- Offline / reconnecting banner --- */

.connection-banner {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 40; /* above everything, including the name prompt */
  background: var(--danger);
  color: #2b0a11;
  text-align: center;
  font-size: 0.82rem;
  font-weight: 600;
  padding: 6px 12px;
  padding-top: calc(6px + env(safe-area-inset-top));
}

/* --- Queue mode banner (Fair rotation / Majority rule) --- */

.queue-mode-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 8px 12px;
  margin-bottom: 10px;
  font-size: 0.82rem;
  color: var(--text-dim);
}

.queue-mode-bar:empty {
  display: none;
}

.mode-label {
  display: flex;
  align-items: center;
  gap: 7px;
}

.mode-icon {
  width: 16px;
  height: 16px;
  color: var(--accent);
}

.mode-toggle {
  flex-shrink: 0;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 8px;
  padding: 6px 12px;
  font-size: 0.78rem;
  font-weight: 600;
}

/* --- Golden record badge + end-of-session election results --- */

/* Sits inline with the track name, so it's nudged down to sit on the
   text baseline rather than riding above it. */
.golden-badge {
  width: 15px;
  height: 15px;
  margin-left: 6px;
  color: var(--accent);
  vertical-align: -2px;
}

.recap-card {
  width: 100%;
  margin-bottom: 16px;
  gap: 0;
}

.recap-card .section-title {
  margin: 0 0 4px;
}

.recap-row {
  display: flex;
  gap: 12px;
  align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
}

.recap-row:last-of-type {
  border-bottom: none;
}

.recap-icon {
  display: flex;
  flex-shrink: 0;
  color: var(--accent);
}

.recap-icon .icon {
  width: 26px;
  height: 26px;
}

.recap-info {
  min-width: 0;
}

.recap-label {
  color: var(--accent);
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.recap-main {
  font-weight: 600;
}

.recap-sub {
  color: var(--text-dim);
  font-size: 0.82rem;
}

.recap-footer {
  color: var(--text-dim);
  font-size: 0.8rem;
  text-align: center;
  margin-top: 10px;
}

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

.host-controls .button {
  flex: 1;
  padding: 8px 10px;
  font-size: 0.85rem;
}

.host-controls .button:disabled {
  opacity: 0.4;
  pointer-events: none;
}

.now-playing .art,
.queue-item .art {
  width: 56px;
  height: 56px;
  border-radius: 8px;
  background: var(--surface-raised) center/cover no-repeat;
  flex-shrink: 0;
}

.track-info { flex: 1; min-width: 0; }
.track-name { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.track-artist { color: var(--text-dim); font-size: 0.9rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.added-by { color: var(--text-dim); font-size: 0.78rem; margin-top: 2px; }
.skip-progress { color: var(--danger); font-size: 0.78rem; margin-top: 2px; }
.duplicate-badge { color: #e0a83c; font-size: 0.78rem; margin-top: 2px; }

.explicit-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 5px;
  font-size: 0.65rem;
  font-weight: 700;
  line-height: 1.4;
  color: var(--text-dim);
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: 4px;
  vertical-align: middle;
}

.section-title {
  color: var(--text-dim);
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin: 20px 0 10px;
}

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

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

.vote-buttons {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
}

.vote-button {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--surface-raised);
  color: var(--text);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* The most-tapped control in the app - drawn a touch heavier than the
   other icons so it stays obvious at arm's length in a moving car. */
.vote-icon {
  width: 20px;
  height: 20px;
  stroke-width: 2.2;
}

.vote-button.active-up { background: var(--accent-dim); border-color: var(--accent); }
.vote-button.active-down { background: #4a1a26; border-color: var(--danger); }

.net-votes {
  min-width: 22px;
  text-align: center;
  color: var(--text-dim);
  font-size: 0.9rem;
}

.empty-state {
  color: var(--text-dim);
  text-align: center;
  padding: 24px 0;
}

.empty-state-warning {
  color: var(--danger);
}

.skipped-item .readd-button {
  margin-left: auto;
  flex-shrink: 0;
  padding: 8px 14px;
  font-size: 0.85rem;
  white-space: nowrap;
}

.remove-button {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface-raised);
  color: var(--text-dim);
  display: flex;
  align-items: center;
  justify-content: center;
}

.remove-button .icon {
  width: 15px;
  height: 15px;
}

/* --- Fixed bottom stack: tab nav (bottom-most) -> search bar -> results --- */

.tab-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  max-width: 480px; /* same centering trick as .screen, so it lines up with the QR card on a wide viewport instead of stretching edge to edge */
  margin: 0 auto;
  z-index: 15;
  display: flex;
  height: calc(var(--tab-bar-height) + env(safe-area-inset-bottom));
  padding-bottom: env(safe-area-inset-bottom);
  background: var(--surface);
  border-top: 1px solid var(--border);
}

.tab-button {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  background: none;
  border: none;
  color: var(--text-dim);
  font-size: 0.68rem;
  font-weight: 600;
  padding: 6px 2px;
}

.tab-button .tab-icon {
  width: 21px;
  height: 21px;
}

.tab-button.active {
  color: var(--accent);
}

.add-song-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: calc(var(--tab-bar-height) + env(safe-area-inset-bottom));
  max-width: 480px;
  margin: 0 auto;
  z-index: 12;
  background: var(--surface);
  border-top: 1px solid var(--border);
  padding: 10px 16px;
}

.add-song-bar input {
  display: block;
  width: 100%;
}

.search-results {
  position: fixed;
  left: 0;
  right: 0;
  bottom: calc(var(--tab-bar-height) + var(--search-bar-height) + env(safe-area-inset-bottom));
  max-width: 480px;
  margin: 0 auto;
  z-index: 11;
  max-height: 50vh;
  overflow-y: auto;
  background: var(--surface);
  border-top: 1px solid var(--border);
  padding: 8px 16px;
}

.search-results:empty { display: none; }

/* Sits directly under a section title, so it takes no top margin of its
   own - the title's 10px bottom margin is the whole gap, matching how
   the lists sit under their titles on every other tab. */
.tab-blurb {
  color: var(--text-dim);
  font-size: 0.85rem;
  line-height: 1.4;
  margin: 0 0 16px;
}

.export-history-button {
  margin-bottom: 16px;
}

/* --- Host's "add a playlist to the Autopilot Mix" box --- */

.autopilot-admin {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 16px;
}

.autopilot-admin label {
  color: var(--text-dim);
  font-size: 0.85rem;
}

.playlist-results {
  display: flex;
  flex-direction: column;
}

.playlist-results:empty {
  display: none;
}

.search-result {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 4px;
  border-bottom: 1px solid var(--border);
}

.search-result:last-child { border-bottom: none; }

.search-result button {
  margin-left: auto;
  background: var(--accent);
  color: #04170a;
  border: none;
  border-radius: 8px;
  width: 36px;
  height: 36px;
  font-size: 1.2rem;
  font-weight: 700;
}

.name-prompt {
  position: fixed;
  inset: 0;
  z-index: 30; /* above the tab bar and search bar - naming yourself gates using either */
  background: rgba(0, 0, 0, 0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

/* --- Info modal: the (?) help overlay explaining each page, see task #24 --- */

.info-button {
  position: fixed;
  top: calc(env(safe-area-inset-top) + 16px);
  right: 16px;
  z-index: 20;
}

.info-overlay {
  position: fixed;
  inset: 0;
  z-index: 32; /* above the name-prompt (30) - reachable the moment it's dismissed */
  background: rgba(0, 0, 0, 0.7);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.info-overlay.open { display: flex; }

.info-modal.card {
  max-width: 420px;
  width: 100%;
  max-height: 80vh;
  overflow-y: auto;
  text-align: left;
  gap: 14px;
}

.info-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.info-modal-header h2 {
  font-family: 'Fraunces', serif;
  font-weight: 600;
  font-size: 1.1rem;
  margin: 0;
}

.info-modal-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.info-modal-body p {
  margin: 0;
  color: var(--text-dim);
  font-size: 0.9rem;
  line-height: 1.6;
}

.info-modal-body strong {
  color: var(--text);
}

/* --- Toast: brief error messages (duplicate song, self-downvote, etc) --- */

.toast {
  position: fixed;
  left: 50%;
  /* clears the tab bar + search bar + results panel stacked below it */
  bottom: calc(var(--tab-bar-height) + var(--search-bar-height) + env(safe-area-inset-bottom) + 76px);
  transform: translateX(-50%) translateY(10px);
  background: var(--surface-raised);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 10px 16px;
  border-radius: 10px;
  font-size: 0.9rem;
  text-align: center;
  max-width: 90%;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
  z-index: 20;
}

.toast.visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
