/* ================================================================
   ROOT VARIABLES — DARK THEME (default)
   ================================================================ */
:root {
  --bg-primary: #0b0b12;
  --bg-secondary: #11111e;
  --bg-card: rgba(255, 255, 255, 0.04);
  --bg-card-hover: rgba(255, 255, 255, 0.08);
  --border-glass: rgba(255, 255, 255, 0.06);
  --border-glass-strong: rgba(255, 255, 255, 0.12);
  --text-primary: #f0f0f5;
  --text-secondary: #a8a8bf;
  --text-muted: #6a6a82;
  --shadow-card: 0 8px 32px rgba(0, 0, 0, 0.5);
  --shadow-glow: 0 0 60px rgba(139, 92, 246, 0.15);
  --shadow-glow-light: 0 0 40px rgba(139, 92, 246, 0.08);
  --glow-accent: rgba(245, 158, 11, 0.25);
  --canvas-bg: #0d0d18;
  --canvas-fret-line: rgba(255, 255, 255, 0.04);
  --canvas-string: rgba(255, 255, 255, 0.06);
  --canvas-string-label: rgba(255, 255, 255, 0.15);
  --canvas-nut: rgba(255, 255, 255, 0.08);
  --canvas-dot: rgba(255, 255, 255, 0.06);
  --canvas-label-bg: #121212;
  --canvas-label-text: #ffffff;
  --canvas-piano-white: #e8e4dc;
  --canvas-piano-black: #1a1a22;
  --canvas-piano-stroke: rgba(0, 0, 0, 0.06);
  --canvas-piano-label: rgba(0, 0, 0, 0.4);
  --canvas-piano-black-label: rgba(255, 255, 255, 0.5);
  --canvas-piano-c-label: rgba(245, 158, 11, 0.15);
  --canvas-piano-bg-start: #0d0d18;
  --canvas-piano-bg-end: #0a0a12;
  --select-bg: #1a1a2a;
  --select-text: #e8e8f0;
  --select-border: rgba(255, 255, 255, 0.1);
  --select-hover-bg: #22223a;
  --settings-bg: rgba(20, 20, 35, 0.92);
  --global-board-bg: rgba(0, 0, 0, 0.4);
  --fret-progress-track: rgba(255, 255, 255, 0.04);
  --fret-numbers-color: rgba(255, 255, 255, 0.25);
  --header-status-bg: rgba(255, 255, 255, 0.03);
  --accent-1: #f59e0b;
  --accent-2: #8b5cf6;
  --accent-3: #ec4899;
  --accent-grad: linear-gradient(135deg, #f59e0b 0%, #8b5cf6 60%, #ec4899 100%);
  --radius-lg: 20px;
  --radius-md: 14px;
  --radius-sm: 10px;
  --transition: 0.35s cubic-bezier(0.22, 1, 0.36, 1);
  --icon-size: 20px;
}

[data-theme="light"] {
  --bg-primary: #f0f0f8;
  --bg-secondary: #e4e4f0;
  --bg-card: rgba(0, 0, 0, 0.03);
  --bg-card-hover: rgba(0, 0, 0, 0.06);
  --border-glass: rgba(0, 0, 0, 0.06);
  --border-glass-strong: rgba(0, 0, 0, 0.12);
  --text-primary: #1a1a2a;
  --text-secondary: #4a4a6a;
  --text-muted: #8a8aaa;
  --shadow-card: 0 8px 32px rgba(0, 0, 0, 0.07);
  --shadow-glow: 0 0 60px rgba(139, 92, 246, 0.08);
  --shadow-glow-light: 0 0 40px rgba(139, 92, 246, 0.05);
  --glow-accent: rgba(245, 158, 11, 0.2);
  --canvas-bg: #f5f5fa;
  --canvas-fret-line: rgba(0, 0, 0, 0.06);
  --canvas-string: rgba(0, 0, 0, 0.08);
  --canvas-string-label: rgba(0, 0, 0, 0.25);
  --canvas-nut: rgba(0, 0, 0, 0.10);
  --canvas-dot: rgba(0, 0, 0, 0.06);
  --canvas-label-bg: #f0f0f0;
  --canvas-label-text: #1a1a2a;
  --canvas-piano-white: #f5f0e8;
  --canvas-piano-black: #c8c8d0;
  --canvas-piano-stroke: rgba(0, 0, 0, 0.08);
  --canvas-piano-label: rgba(0, 0, 0, 0.30);
  --canvas-piano-black-label: rgba(0, 0, 0, 0.50);
  --canvas-piano-c-label: rgba(245, 158, 11, 0.20);
  --canvas-piano-bg-start: #f0f0f8;
  --canvas-piano-bg-end: #e8e8f2;
  --select-bg: #e8e8f2;
  --select-text: #1a1a2a;
  --select-border: rgba(0, 0, 0, 0.10);
  --select-hover-bg: #dddde8;
  --settings-bg: rgba(240, 240, 248, 0.94);
  --global-board-bg: rgba(255, 255, 255, 0.40);
  --fret-progress-track: rgba(0, 0, 0, 0.04);
  --fret-numbers-color: rgba(0, 0, 0, 0.25);
  --header-status-bg: rgba(0, 0, 0, 0.02);
}

/* ----- Reset & base styles ----- */
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100vh; overflow: hidden; }
body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  background: var(--bg-primary);
  color: var(--text-primary);
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 8px 16px 8px 16px;
  position: relative;
  transition: background var(--transition), color var(--transition);
  background-image: radial-gradient(ellipse at 20% 50%, rgba(139, 92, 246, 0.08) 0%, transparent 60%),
                    radial-gradient(ellipse at 80% 20%, rgba(236, 72, 153, 0.06) 0%, transparent 50%),
                    radial-gradient(ellipse at 50% 100%, rgba(245, 158, 11, 0.04) 0%, transparent 40%);
}
body::before {
  content: '';
  position: fixed;
  top: -50%;
  left: -50%;
  width: 200%;
  height: 200%;
  background: radial-gradient(ellipse at 30% 40%, rgba(139, 92, 246, 0.03) 0%, transparent 50%),
              radial-gradient(ellipse at 70% 60%, rgba(236, 72, 153, 0.02) 0%, transparent 40%);
  animation: bgShift 30s ease-in-out infinite alternate;
  z-index: 0;
  pointer-events: none;
  transition: opacity var(--transition);
}
[data-theme="light"] body::before { opacity: 0.3; }
@keyframes bgShift {
  0% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(3%, 2%) scale(1.05); }
  100% { transform: translate(-2%, -3%) scale(0.95); }
}

/* ----- Icons & buttons ----- */
.icon-svg {
  width: var(--icon-size); height: var(--icon-size);
  stroke: currentColor; stroke-width: 1.75;
  fill: none; stroke-linecap: round; stroke-linejoin: round;
  flex-shrink: 0; transition: var(--transition);
}
.icon-svg.sm { --icon-size: 16px; }
.icon-svg.lg { --icon-size: 28px; }
.icon-svg.xl { --icon-size: 36px; }
.icon-svg.accent { color: var(--accent-1); }
.icon-svg.muted { color: var(--text-muted); }
.icon-svg.secondary { color: var(--text-secondary); }
.icon-svg.filled { fill: currentColor; stroke: none; }

.icon-btn {
  background: transparent; border: none;
  color: var(--text-secondary); cursor: pointer;
  padding: 4px 6px; line-height: 1;
  border-radius: var(--radius-sm);
  transition: var(--transition);
  display: flex; align-items: center; justify-content: center;
}
.icon-btn:hover { color: var(--text-primary); background: var(--bg-card-hover); transform: translateY(-1px); }

/* ----- Nav Button (generic themed action/toggle button) ----- */
.nav-btn {
  appearance: none;
  -webkit-appearance: none;
  font-family: inherit;
  background: var(--bg-card);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  padding: 6px 14px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: var(--transition);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
.nav-btn:hover {
  border-color: var(--border-glass-strong);
  color: var(--text-primary);
  background: var(--bg-card-hover);
  transform: translateY(-1px);
}
.nav-btn.active-mode {
  background: var(--accent-grad);
  border-color: transparent;
  color: #fff;
}
.nav-btn.active-mode:hover {
  transform: translateY(-1px);
  filter: brightness(1.05);
}

/* ----- Header ----- */
.header {
  width: 100%; max-width: 1300px;
  /* Grid (not flex) so the mobile breakpoint can place header-status on its
     own row below header-left/header-actions via grid-template-areas,
     independent of source order — flex's `order` property doesn't reliably
     repaint here when the media query toggles. */
  display: grid;
  grid-template-columns: auto 1fr auto;
  grid-template-areas: "left status actions";
  align-items: center;
  margin-bottom: 6px;
  gap: 10px;
  position: relative;
  z-index: 10;
  padding: 8px 16px;
  background: var(--bg-card);
  backdrop-filter: blur(20px);
  border-radius: var(--radius-lg);
  border: 1px solid var(--border-glass);
  box-shadow: var(--shadow-card), var(--shadow-glow);
  transition: background var(--transition), border var(--transition), box-shadow var(--transition);
}
.header-left { grid-area: left; min-width: 0; }
.header-status { grid-area: status; min-width: 0; }
.header-actions { grid-area: actions; }
.header-left {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  flex: 0 1 auto;
}
.brand-wrapper {
  display: flex;
  align-items: center; gap: 10px;
  cursor: pointer; transition: var(--transition);
  text-decoration: none; color: var(--text-primary);
}
.brand-wrapper:hover { transform: scale(1.02); opacity: 0.9; }
.brand-icon { width: 36px; height: 36px; flex-shrink: 0; }
.brand-name {
  font-family: 'Nunito', 'Inter', sans-serif;
  font-size: 20px; font-weight: 900;
  background: var(--accent-grad);
  -webkit-background-clip: text; -webkit-text-fill-color: transparent;
  background-clip: text;
  letter-spacing: -0.5px; line-height: 1;
  /* Stays invisible until the JS in app.html's <head> confirms Nunito has
     actually loaded, so it paints once already in its final font instead
     of visibly swapping (and appearing to shrink) from a fallback font a
     moment after first paint. */
  opacity: 0;
  transition: opacity 0.15s ease;
}
.brand-name.fonts-ready { opacity: 1; }
.brand-name .monkey { -webkit-text-fill-color: var(--accent-1); }

.header-status {
  flex: 1 1 auto;
  /* Fixed cap, not a percentage: as a grid item (see .header) this resolves
     against the 1fr track's own leftover-space size, not the header's full
     width, so a 50% cap here was clamping the pill far tighter than the
     original flex layout ever did at ordinary desktop widths. */
  max-width: 640px;
  background: var(--header-status-bg);
  padding: 4px 16px;
  border-radius: 40px;
  border: 1px solid var(--border-glass);
  font-size: 11px;
  color: var(--text-secondary);
  text-align: center;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 28px;
  overflow: hidden;
  white-space: nowrap;
  backdrop-filter: blur(8px);
  transition: var(--transition);
  margin: 0 10px;
}
.header-status strong { color: var(--accent-1); font-weight: 600; }
.header-status .error { color: #f87171; }
.header-status .success { color: #34d399; }

.header-actions {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
  align-items: center;
  position: relative;
}
.header-actions .icon-btn { font-size: 20px; padding: 6px 10px; }

/* Getting Started / Recently Played / Theme / Settings share a wrapper so
   the mobile breakpoint can turn them into a single "More" dropdown without
   touching their own markup or click handlers. `display:contents` makes the
   wrapper invisible to the flex layout on desktop - its children become
   direct flex items of .header-actions again, so the explicit `order`
   below is what keeps them in their original visual position regardless of
   where the wrapper sits in the DOM. */
.header-more-group { display: contents; }
#tutorialBtn { order: 1; }
#recentlyPlayedBtn { order: 2; }
#creditChip { order: 3; }
#themeToggleBtn { order: 4; }
#profileBtn { order: 5; }
#settingsBtn { order: 6; }
#moreBtn { display: none; order: 7; }
/* Settings never had a text label (it's a plain icon-btn) - keep it that
   way on desktop; the mobile "More" panel turns it back on further down. */
#settingsBtn .label-text { display: none; }

.header-btn {
  background: var(--bg-card);
  border: 1px solid var(--border-glass);
  border-radius: 30px;
  color: var(--text-secondary);
  cursor: pointer;
  padding: 4px 10px;
  font-size: 13px;
  transition: var(--transition);
  display: flex;
  align-items: center;
  gap: 4px;
  font-family: 'Inter', sans-serif;
  font-weight: 500;
  min-height: 30px;
  line-height: 1;
}
.header-btn:hover {
  border-color: var(--border-glass-strong);
  color: var(--text-primary);
  background: var(--bg-card-hover);
  transform: translateY(-1px);
}
.header-btn .icon-svg { --icon-size: 16px; }
.header-btn .label-text { font-size: 11px; font-weight: 500; }

.theme-toggle-btn {
  background: var(--bg-card);
  border: 1px solid var(--border-glass);
  border-radius: 30px;
  color: var(--text-secondary);
  cursor: pointer;
  padding: 4px 10px;
  font-size: 16px;
  transition: var(--transition);
  display: flex;
  align-items: center;
  gap: 4px;
  font-family: 'Inter', sans-serif;
  font-weight: 500;
  min-height: 30px;
  line-height: 1;
}
.theme-toggle-btn:hover {
  border-color: var(--border-glass-strong);
  color: var(--text-primary);
  background: var(--bg-card-hover);
  transform: translateY(-1px);
}
.theme-toggle-btn .icon-svg { --icon-size: 16px; }
.theme-toggle-btn .label-text { font-size: 11px; font-weight: 500; }

.profile-btn {
  background: var(--bg-card);
  border: 1px solid var(--border-glass);
  border-radius: 50%;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-secondary);
  cursor: pointer;
  transition: var(--transition);
  padding: 0;
}
.profile-btn:hover {
  border-color: var(--border-glass-strong);
  color: var(--text-primary);
  background: var(--bg-card-hover);
  transform: translateY(-1px);
}
.profile-btn .icon-svg { --icon-size: 18px; }

.profile-dropdown {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  background: var(--bg-secondary);
  border: 1px solid var(--border-glass-strong);
  border-radius: var(--radius-md);
  padding: 16px;
  min-width: 200px;
  box-shadow: var(--shadow-card), var(--shadow-glow);
  backdrop-filter: blur(20px);
  display: none;
  z-index: 300;
  flex-direction: column;
  gap: 10px;
}
.profile-dropdown.open { display: flex; }
.profile-dropdown .user-name { font-weight: 600; font-size: 14px; color: var(--text-primary); }
.profile-dropdown .user-email { font-size: 12px; color: var(--text-muted); }
.profile-dropdown .divider { border-top: 1px solid var(--border-glass); margin: 4px 0; }
.profile-dropdown .logout-btn {
  background: transparent;
  border: 1px solid var(--border-glass);
  color: #f87171;
  padding: 6px 12px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: 13px;
  font-family: 'Inter', sans-serif;
  font-weight: 600;
  transition: var(--transition);
  width: 100%;
}
.profile-dropdown .logout-btn:hover {
  background: rgba(248, 113, 113, 0.1);
  border-color: #f87171;
}

.recently-played-dropdown {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  background: var(--bg-secondary);
  border: 1px solid var(--border-glass-strong);
  border-radius: var(--radius-md);
  padding: 12px 0;
  min-width: 220px;
  max-height: 300px;
  overflow-y: auto;
  box-shadow: var(--shadow-card), var(--shadow-glow);
  backdrop-filter: blur(20px);
  display: none;
  z-index: 300;
  flex-direction: column;
}
.recently-played-dropdown.open { display: flex; }
.recently-played-dropdown .download-item {
  padding: 8px 16px;
  font-size: 13px;
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  gap: 10px;
  transition: var(--transition);
  cursor: default;
}
.recently-played-dropdown .download-item:hover { background: var(--bg-card-hover); }
.recently-played-dropdown .download-item .icon-svg { --icon-size: 16px; color: var(--accent-1); }
.recently-played-dropdown .download-item .title { color: var(--text-primary); }
.recently-played-dropdown .download-item .size { font-size: 11px; color: var(--text-muted); margin-left: auto; }
.recently-played-dropdown .empty-msg {
  padding: 20px 16px;
  color: var(--text-muted);
  font-size: 13px;
  text-align: center;
}
.delete-saved-btn {
  color: var(--text-muted);
  transition: color 0.15s, transform 0.15s;
}
.delete-saved-btn:hover {
  color: #f87171;
  transform: scale(1.15);
}

/* ----- Settings Overlay ----- */
.settings-overlay {
  position: fixed; top: 0; left: 0;
  width: 100%; height: 100%;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(8px);
  z-index: 200;
  display: none;
  justify-content: center; align-items: center;
  animation: fadeInOverlay 0.25s ease;
}
.settings-overlay.open { display: flex; }
@keyframes fadeInOverlay { from { opacity: 0; } to { opacity: 1; } }
#settings-panel {
  background: var(--settings-bg);
  backdrop-filter: blur(30px);
  border: 1px solid var(--border-glass-strong);
  border-radius: var(--radius-lg);
  padding: 28px 32px;
  width: 420px; max-width: 90vw;
  max-height: 90vh;
  overflow-y: auto;
  box-shadow: 0 24px 80px rgba(0,0,0,0.6), var(--shadow-glow);
  display: flex; flex-direction: column; gap: 20px;
  transition: background var(--transition), border var(--transition);
  position: relative;
}
#settings-panel .close-btn {
  position: absolute; top: 12px; right: 16px;
  background: transparent; border: none;
  color: var(--text-muted); cursor: pointer;
  font-size: 22px; transition: var(--transition);
  line-height: 1;
}
#settings-panel .close-btn:hover { color: var(--text-primary); transform: rotate(90deg); }
#settings-panel label {
  font-size: 13px; font-weight: 500;
  color: var(--text-secondary);
  display: flex; flex-direction: column; gap: 6px;
  letter-spacing: 0.3px;
}
#settings-panel label span { font-weight: 600; color: var(--text-primary); }
#settings-panel select {
  background: var(--select-bg) !important;
  color: var(--select-text) !important;
  border: 1px solid var(--select-border) !important;
  border-radius: var(--radius-sm) !important;
  padding: 8px 12px !important;
  font-size: 13px !important;
  font-family: 'Inter', sans-serif !important;
  cursor: pointer !important;
  outline: none !important;
  transition: var(--transition) !important;
  appearance: auto !important;
  min-height: 38px !important;
}
#settings-panel select:hover {
  border-color: var(--accent-1) !important;
  background: var(--select-hover-bg) !important;
}

.preset-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  gap: 8px;
  margin-top: 4px;
}
.preset-btn {
  background: var(--bg-card);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  padding: 6px 8px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: var(--transition);
  text-align: center;
  font-family: 'Inter', sans-serif;
}
.preset-btn:hover {
  border-color: var(--accent-1);
  color: var(--text-primary);
  background: var(--bg-card-hover);
}
.preset-btn.active {
  border-color: var(--accent-1);
  background: rgba(245,158,11,0.08);
  color: var(--accent-1);
}
.preset-btn .preset-name { display: block; font-weight: 700; font-size: 13px; }
.preset-btn .preset-notes { display: block; font-size: 10px; color: var(--text-muted); margin-top: 2px; }

.string-tuning-list {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px 16px;
  background: var(--bg-card);
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-glass);
}
.string-tuning-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.string-tuning-item .string-index {
  font-weight: 600;
  color: var(--text-secondary);
  font-size: 12px;
  min-width: 24px;
}
.string-tuning-item select {
  background: var(--select-bg) !important;
  color: var(--select-text) !important;
  border: 1px solid var(--select-border) !important;
  border-radius: var(--radius-sm) !important;
  padding: 2px 6px !important;
  font-size: 11px !important;
  font-weight: 500 !important;
  font-family: 'Inter', sans-serif !important;
  cursor: pointer !important;
  outline: none !important;
  transition: var(--transition) !important;
  appearance: auto !important;
  min-height: 26px !important;
  width: 72px;
}
.string-tuning-item select:hover {
  border-color: var(--accent-1) !important;
  background: var(--select-hover-bg) !important;
}

.settings-section-title {
  font-size: 14px;
  font-weight: 700;
  color: var(--text-primary);
  margin-top: 4px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.settings-section-title .icon-svg { --icon-size: 18px; color: var(--accent-1); }

/* ----- Dropdowns (global) ----- */
#instrumentSelect, #scale-root, #scale-type, #chordRootSelect,
#scaleRootSelect, #scaleTypeSelect, .hub-input-group select,
#settings-panel select, #bottom-bar select,
.pb-field select, .pb-section-label, .cp-filters select, .pb-fx-add select,
.pb-voicing-select {
  background: var(--select-bg) !important;
  color: var(--select-text) !important;
  border: 1px solid var(--select-border) !important;
  border-radius: var(--radius-sm) !important;
  padding: 4px 10px !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  font-family: 'Inter', sans-serif !important;
  cursor: pointer !important;
  outline: none !important;
  transition: var(--transition) !important;
  appearance: auto !important;
  min-height: 30px !important;
}
#instrumentSelect:hover, #scale-root:hover, #scale-type:hover,
#chordRootSelect:hover, #scaleRootSelect:hover, #scaleTypeSelect:hover,
.hub-input-group select:hover, #settings-panel select:hover,
#bottom-bar select:hover,
.pb-field select:hover, .pb-section-label:hover, .cp-filters select:hover, .pb-fx-add select:hover,
.pb-voicing-select:hover {
  border-color: var(--accent-1) !important;
  background: var(--select-hover-bg) !important;
}
#instrumentSelect option, #scale-root option, #scale-type option,
#chordRootSelect option, #scaleRootSelect option, #scaleTypeSelect option,
.hub-input-group select option, #settings-panel select option,
#bottom-bar select option,
.pb-field select option, .pb-section-label option, .cp-filters select option, .pb-fx-add select option,
.pb-voicing-select option {
  background: var(--select-bg) !important;
  color: var(--select-text) !important;
}

/* ----- Page Container ----- */
#page-container {
  width: 100%; max-width: 1300px;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  position: relative;
  z-index: 1;
  gap: 6px;
}

/* ----- Global Board ----- */
#global-board {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  border-radius: var(--radius-md);
  overflow: hidden;
  border: 1px solid var(--border-glass);
  background: var(--global-board-bg);
  backdrop-filter: blur(4px);
  box-shadow: var(--shadow-card), inset 0 1px 0 rgba(255,255,255,0.04);
  max-height: 500px; opacity: 1;
  transition: background var(--transition), border var(--transition), max-height 0.35s ease, opacity 0.25s ease, margin 0.35s ease, border-width 0.35s ease;
}
#global-board.collapsed {
  max-height: 0;
  opacity: 0;
  border-width: 0;
  margin: 0;
  pointer-events: none;
}
#fretboard-canvas-wrapper {
  background: transparent; width: 100%;
  overflow: hidden; flex-shrink: 0;
  position: relative;
}
#fretboard-canvas-wrapper canvas {
  display: block; width: 100%; height: auto;
  background: var(--canvas-bg);
  aspect-ratio: 4 / 1;
  transition: background var(--transition);
}
#fret-numbers {
  display: flex; justify-content: space-between;
  padding: 2px 80px 4px 80px;
  width: 100%;
  font-size: 11px;
  color: var(--fret-numbers-color);
  font-weight: 500;
  font-family: 'Inter', monospace;
  background: var(--global-board-bg);
  user-select: none;
  letter-spacing: 0.5px;
  transition: color var(--transition), background var(--transition);
}
#fret-numbers span { text-align: center; width: 1px; }

/* ----- Visual Controls ----- */
#visual-controls {
  display: flex; justify-content: space-evenly; align-items: center;
  gap: 12px; width: 100%; max-width: 900px;
  margin: 8px auto 4px auto;
  flex-shrink: 0; flex-wrap: wrap;
}
#visual-controls.collapsed .control-item {
  max-height: 0; max-width: 0; min-height: 0;
  opacity: 0;
  padding: 0; margin: 0; border-width: 0;
  overflow: hidden;
  pointer-events: none;
}
/* ----- Collapse-all toggle (sits next to Stems; stays visible so the
   panel can be re-expanded once the control-items above have shrunk away) ----- */
.visual-collapse-btn {
  background: var(--bg-card);
  backdrop-filter: blur(16px);
  border: 1px solid var(--border-glass);
  border-radius: 50%;
  width: 32px; height: 32px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; color: var(--text-secondary);
  box-shadow: var(--shadow-card);
  flex-shrink: 0;
  transition: var(--transition);
}
.visual-collapse-btn:hover {
  border-color: var(--border-glass-strong);
  background: var(--bg-card-hover);
  color: var(--text-primary);
  transform: translateY(-1px);
}
.visual-collapse-btn .icon-svg {
  transition: transform 0.35s ease;
}
.visual-collapse-btn.collapsed .icon-svg {
  transform: rotate(180deg);
}
.control-item {
  background: var(--bg-card);
  backdrop-filter: blur(16px);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-md);
  padding: 8px 18px;
  display: flex; align-items: center; gap: 10px;
  font-size: 13px; color: var(--text-secondary);
  box-shadow: var(--shadow-card);
  max-height: 120px; max-width: 480px; opacity: 1;
  transition: var(--transition), max-height 0.35s ease, max-width 0.35s ease, opacity 0.25s ease, margin 0.35s ease, padding 0.35s ease, min-height 0.35s ease, border-width 0.35s ease;
  flex: 0 1 auto; min-height: 44px;
  /* backdrop-filter creates a new stacking context regardless of position,
     which traps any child popover's z-index inside it - without an explicit
     position+z-index here too, the whole control-item (popover included)
     loses to later same-level page content like #page-home's hero text. */
  position: relative;
  z-index: 2;
}
.control-item:hover {
  border-color: var(--border-glass-strong);
  background: var(--bg-card-hover);
  transform: translateY(-1px);
}
.control-item .label {
  font-weight: 600; font-size: 11px;
  text-transform: uppercase; letter-spacing: 0.5px;
  color: var(--text-muted);
}
.control-item .chord-name {
  color: var(--accent-1); font-weight: 700;
  min-width: 28px; text-align: center; font-size: 15px;
}
.eye-btn {
  background: transparent; border: none;
  cursor: pointer; color: var(--text-muted);
  transition: var(--transition);
  padding: 0 4px; line-height: 1;
  border-radius: 6px; display: flex; align-items: center;
}
.eye-btn.active { color: var(--accent-1); }
.eye-btn:hover { transform: scale(1.15); color: var(--text-primary); }
.color-dot {
  display: inline-block; width: 14px; height: 14px;
  border-radius: 50%;
  border: 2px solid var(--border-glass);
  padding: 0;
  cursor: pointer; transition: var(--transition);
  box-shadow: 0 0 12px rgba(0,0,0,0.3);
}
.color-dot:hover { transform: scale(1.15); }
.color-wrapper {
  position: relative;
  display: inline-block;
  line-height: 0;
  width: 14px;
  height: 14px;
}

/* ----- Themed color swatch popover (replaces the native <input type=color>
   dialog, which can't be styled to match the site) ----- */
.color-popover {
  position: absolute;
  top: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--bg-secondary);
  border: 1px solid var(--border-glass-strong);
  border-radius: var(--radius-md);
  padding: 10px;
  box-shadow: var(--shadow-card), var(--shadow-glow);
  backdrop-filter: blur(20px);
  display: none;
  z-index: 300;
  width: max-content;
}
.color-popover.open { display: block; }
.color-swatch-grid {
  display: grid;
  grid-template-columns: repeat(6, 20px);
  gap: 6px;
}
.color-swatch {
  width: 20px; height: 20px;
  border-radius: 50%;
  border: 2px solid transparent;
  padding: 0;
  cursor: pointer;
  transition: var(--transition);
}
.color-swatch:hover { transform: scale(1.15); }
.color-swatch.active { border-color: var(--text-primary); }
.color-custom-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border-glass);
  font-size: 12px;
  color: var(--text-muted);
  cursor: pointer;
}
.color-picker {
  width: 28px;
  height: 20px;
  padding: 0;
  border: 1px solid var(--border-glass-strong);
  border-radius: 6px;
  cursor: pointer;
  background: none;
}
.color-picker::-webkit-color-swatch-wrapper { padding: 2px; }
.color-picker::-webkit-color-swatch { border: none; border-radius: 4px; }

/* ----- Backing-track analysis mode toggle ----- */
.analysis-mode-toggle {
  display: flex;
  border: 1px solid var(--border-glass-strong, var(--border-glass));
  border-radius: var(--radius-sm);
  overflow: hidden;
  flex-shrink: 0;
}
.analysis-mode-btn {
  background: transparent;
  border: none;
  color: var(--text-muted);
  font-size: 12px;
  font-weight: 600;
  padding: 6px 14px;
  cursor: pointer;
  transition: var(--transition);
}
.analysis-mode-btn.active {
  background: var(--accent-grad);
  color: #fff;
}
.analysis-mode-btn:not(.active):hover {
  background: var(--bg-card-hover, var(--bg-card));
  color: var(--text-primary);
}

/* Stem Separation opt-in - a standalone toggle (not part of the Fast/Accurate
   group above) since it only applies alongside Accurate mode. */
.stems-toggle-btn {
  background: transparent;
  border: 1px solid var(--border-glass-strong, var(--border-glass));
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  font-size: 12px;
  font-weight: 600;
  padding: 6px 14px;
  cursor: pointer;
  transition: var(--transition);
  flex-shrink: 0;
}
.stems-toggle-btn.active {
  background: var(--accent-grad);
  border-color: transparent;
  color: #fff;
}
.stems-toggle-btn:not(.active):hover {
  background: var(--bg-card-hover, var(--bg-card));
  color: var(--text-primary);
}
/* Locked = not entitled at the viewer's current tier. Still clickable -
   opens the Plans modal instead of toggling. */
.stems-toggle-btn.locked {
  opacity: 0.55;
}

/* ----- Stem controls ----- */
.stem-control { gap: 8px; }
.stem-btn-group { display: flex; align-items: center; gap: 2px; }
.stem-slot { position: relative; display: flex; }
.stem-btn {
  background: transparent; border: none;
  cursor: pointer; color: var(--accent-1);
  transition: var(--transition);
  padding: 4px; line-height: 1;
  border-radius: 6px; display: flex; align-items: center;
}
.stem-btn:hover:not(:disabled) { transform: scale(1.15); color: var(--text-primary); }
.stem-btn.muted { color: var(--text-muted); opacity: 0.5; }
.stem-btn.muted:hover:not(:disabled) { color: var(--text-secondary); }
/* Not-yet-available (no advanced-mode song loaded), not an error - a plain
   cursor reads as "inactive" rather than the browser's "forbidden" symbol. */
.stem-btn:disabled { color: var(--text-muted); opacity: 0.25; cursor: default; }

.stem-volume-popover {
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%) translateY(-6px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  background: var(--bg-secondary, #1a1a24);
  border: 1px solid var(--border-glass-strong);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-card);
  padding: 10px 8px 8px;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.15s ease, visibility 0.15s;
  z-index: 20;
  white-space: nowrap;
}
.stem-slot:hover .stem-volume-popover,
.stem-slot:focus-within .stem-volume-popover {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}
.stem-volume-popover .stem-volume-value {
  font-size: 10px; font-weight: 600;
  color: var(--text-secondary);
}
/* Rotating a normal horizontal <input type=range> is the most reliable way
   to get a vertical slider cross-browser (native vertical-slider styling is
   inconsistent). The wrapper is sized to the slider's *rotated* footprint
   (its own box is still 70x4 for layout purposes) and centers it so the
   rotation doesn't overlap neighboring content. rotate(-90deg) puts max at
   the top and min at the bottom, matching a physical fader/mixer.  */
.stem-slider-track {
  width: 24px;
  height: 74px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.stem-volume-slider {
  width: 70px;
  height: 4px;
  transform: rotate(-90deg);
  cursor: pointer;
  accent-color: var(--accent-1);
}
.stem-btn:disabled ~ .stem-volume-popover,
.stem-slot:has(.stem-btn:disabled) .stem-volume-popover {
  display: none;
}

/* ----- Pages Wrapper & Timeline ----- */
#pages-wrapper {
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  position: relative;
  display: flex;
  flex-direction: column;
}
#pages-wrapper #pages {
  flex: 1 1 auto;
  overflow: hidden;
}
#pages-wrapper.hidden #pages {
  display: none;
}
#pages-wrapper.hidden #chord-timeline {
  display: flex;
}

#pages {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
  margin-top: 4px;
  display: block;
}
.page {
  display: none;
  flex-direction: column;
  width: 100%;
  height: 100%;
  overflow-y: auto;
  padding: 4px 2px 8px 2px;
  animation: pageFadeIn 0.4s ease;
}
.page.active { display: flex; }
@keyframes pageFadeIn {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

#chord-timeline {
  display: none;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 12px;
  padding: 12px 16px 16px 16px;
  background: var(--bg-card);
  backdrop-filter: blur(8px);
  border-radius: var(--radius-md);
  border: 1px solid var(--border-glass);
  margin-top: 4px;
  overflow: hidden;
  min-height: 160px;
  width: 100%;
}
.timeline-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-shrink: 0;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border-glass);
}
.timeline-header .title {
  font-weight: 700;
  font-size: 15px;
  color: var(--text-primary);
  display: flex;
  align-items: center;
  gap: 10px;
}
.timeline-header .title .badge {
  font-size: 10px;
  font-weight: 600;
  color: var(--accent-1);
  background: rgba(245, 158, 11, 0.12);
  padding: 2px 10px;
  border-radius: 30px;
  letter-spacing: 0.3px;
}
.timeline-header .time-display {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}
.timeline-header .time-display .current {
  color: var(--text-primary);
}
.timeline-scroll {
  flex: 1;
  overflow-x: auto;
  overflow-y: hidden;
  position: relative;
  padding: 8px 0 4px 0;
  min-height: 80px;
  scroll-behavior: smooth;
}
.timeline-scroll::-webkit-scrollbar {
  height: 4px;
}
.timeline-scroll::-webkit-scrollbar-track {
  background: var(--bg-card);
  border-radius: 10px;
}
.timeline-scroll::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.1);
  border-radius: 10px;
}
[data-theme="light"] .timeline-scroll::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, 0.1);
}
.timeline-track {
  position: relative;
  display: flex;
  align-items: stretch;
  /* The populated (chord blocks) state already fills the full row width via
     percentage widths, so this only affects the empty state - a single
     shrink-to-fit .timeline-empty child that would otherwise pin to the
     left edge instead of sitting centered in the track. */
  justify-content: center;
  height: 100%;
  min-height: 64px;
  border-radius: var(--radius-sm);
  background: var(--bg-secondary);
  overflow: hidden;
  border: 1px solid var(--border-glass);
}
.progression-span {
  flex: 0 0 auto;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 4px 8px;
  position: relative;
  transition: opacity 0.25s ease;
  min-width: 44px;
  opacity: 0.6;
}
.progression-chord-name {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: -0.2px;
  text-shadow: 0 0 8px rgba(0, 0, 0, 0.3);
  white-space: nowrap;
}
.progression-dots {
  display: flex;
  align-items: flex-end;
  gap: 4px;
  height: 14px;
}
.progression-dot {
  width: 7px;
  height: 7px;
  flex-shrink: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.18);
  opacity: 1;
  transition: background-color 0.3s ease, opacity 0.3s ease;
}
[data-theme="light"] .progression-dot {
  background: rgba(0, 0, 0, 0.15);
}
.progression-span.current {
  z-index: 2;
  opacity: 1;
}
.progression-dot.past {
  background: var(--chord-color);
  opacity: 0.5;
}
/* A single, fixed-duration bounce (not tied to BPM - that made faster songs
   feel like the dot was stuttering/repeating rather than doing one clean
   motion) - iteration-count defaults to 1, so this plays once per beat. */
.progression-dot.current {
  background: var(--chord-color);
  box-shadow: 0 0 10px var(--chord-color);
  animation: progressionDotBounce 0.45s ease-in-out;
}
@keyframes progressionDotBounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-6px); }
}
.timeline-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  min-height: 100px;
  color: var(--text-muted);
  gap: 8px;
  font-size: 14px;
}
.timeline-empty .icon-svg {
  --icon-size: 36px;
  color: var(--text-muted);
  opacity: 0.3;
}
.timeline-empty strong {
  color: var(--text-secondary);
}

/* ----- Home Page ----- */
#page-home {
  align-items: center; justify-content: flex-start;
  gap: 28px; padding: 20px 10px;
  overflow-y: auto;
}
.home-title {
  font-size: 42px; font-weight: 900;
  font-family: 'Nunito', 'Inter', sans-serif;
  text-align: center;
  background: var(--accent-grad);
  -webkit-background-clip: text; -webkit-text-fill-color: transparent;
  background-clip: text;
  letter-spacing: -1px; line-height: 1.1;
  display: flex; align-items: center; gap: 14px;
  flex-shrink: 0;
}
.home-title .logo-big { width: 52px; height: 52px; flex-shrink: 0; }
.home-subtitle {
  font-size: 16px; color: var(--text-secondary);
  text-align: center; max-width: 540px;
  font-weight: 400; line-height: 1.6;
  flex-shrink: 0;
}
.home-subtitle strong { color: var(--accent-1); font-weight: 600; }
.home-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 18px;
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
  flex-shrink: 0;
}
.home-tile {
  background: var(--bg-card); backdrop-filter: blur(16px);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-md);
  padding: 24px 18px; text-align: center;
  cursor: pointer; transition: var(--transition);
  text-decoration: none; color: var(--text-primary);
  display: flex; flex-direction: column;
  align-items: center; gap: 8px;
  box-shadow: var(--shadow-card);
  min-height: 140px;
}
.home-tile:hover {
  border-color: var(--border-glass-strong);
  transform: translateY(-4px) scale(1.01);
  box-shadow: 0 12px 48px rgba(0,0,0,0.5), var(--shadow-glow);
  background: var(--bg-card-hover);
}
[data-theme="light"] .home-tile:hover {
  box-shadow: 0 12px 48px rgba(0,0,0,0.08), var(--shadow-glow-light);
}
.home-tile .icon-svg { --icon-size: 32px; color: var(--accent-1); transition: var(--transition); }
.home-tile:hover .icon-svg { transform: scale(1.1); color: var(--accent-2); }
.home-tile .name { font-size: 16px; font-weight: 700; color: var(--text-primary); letter-spacing: -0.2px; }
.home-tile .desc { font-size: 12px; color: var(--text-muted); line-height: 1.4; font-weight: 400; }

.home-grid-secondary-label {
  font-size: 13px; font-weight: 600; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 0.5px;
  width: 100%; max-width: 900px; margin: 4px auto -6px;
}
.home-grid-secondary .home-tile { min-height: 116px; padding: 18px 14px; opacity: 0.85; }
.home-grid-secondary .home-tile:hover { opacity: 1; }
.home-grid-secondary .home-tile .icon-svg { --icon-size: 26px; }
.home-grid-secondary .home-tile .name { font-size: 14px; }

/* ----- Home: returning-visitor "Continue" strip (Website/JS/app.js renderHomeContinue) ----- */
.home-continue-label {
  font-size: 13px; font-weight: 600; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 0.5px;
  width: 100%; max-width: 900px; margin: 0 auto 8px;
}
.home-continue-row {
  display: flex; flex-wrap: wrap; gap: 12px;
  width: 100%; max-width: 900px; margin: 0 auto 8px;
}
.home-continue-chip {
  display: flex; align-items: center; gap: 10px;
  background: var(--bg-card); backdrop-filter: blur(16px);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-md);
  padding: 12px 16px;
  cursor: pointer; transition: var(--transition);
  text-align: left; flex: 1; min-width: 220px;
  box-shadow: var(--shadow-card);
}
.home-continue-chip:hover {
  border-color: var(--border-glass-strong);
  transform: translateY(-2px);
  background: var(--bg-card-hover);
}
.home-continue-chip .icon-svg { --icon-size: 22px; color: var(--accent-1); flex-shrink: 0; }
.home-continue-chip .hc-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.home-continue-chip .hc-title {
  font-size: 13px; font-weight: 700; color: var(--text-primary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.home-continue-chip .hc-sub { font-size: 11px; color: var(--text-muted); }

/* ----- Home: progressive disclosure reveal button (Website/JS/app.js updateHomeDisclosure) ----- */
.home-more-tools-btn {
  display: block; margin: 4px auto 0;
  background: none; border: 1px solid var(--border-glass);
  border-radius: 999px;
  padding: 8px 20px;
  font-size: 13px; font-weight: 600; color: var(--text-muted);
  cursor: pointer; transition: var(--transition);
}
.home-more-tools-btn:hover {
  color: var(--accent-1); border-color: var(--accent-1);
}
/* The 3 label+grid pairs used to be direct children of #page-home (a flex
   column with gap:28px), so each got that gap automatically. Wrapping them
   in this container for the progressive-disclosure toggle took them out of
   that flex context - without its own matching layout here, they collapsed
   into normal block flow with almost no space between them. */
#homeSecondaryGroups {
  display: flex; flex-direction: column; gap: 28px;
  width: 100%; align-items: center;
}

/* ----- Onboarding: first-visit guided intro ----- */
.onboarding-intro {
  width: 100%; max-width: 640px; margin: 0 auto;
  display: flex; justify-content: center;
}
.onboarding-box {
  width: 100%;
  background: var(--bg-card); backdrop-filter: blur(16px);
  border: 1px solid var(--border-glass-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card), var(--shadow-glow);
  padding: 32px; text-align: center;
}
.onboarding-box h2 {
  font-family: 'Nunito', sans-serif; font-size: 22px;
  color: var(--text-primary); margin-bottom: 6px;
}
.onboarding-box > p {
  font-size: 14px; color: var(--text-secondary); margin-bottom: 22px;
}
.onboarding-step + .onboarding-step { margin-top: 0; }
.onboarding-choices { display: flex; flex-direction: column; gap: 12px; }
.onboarding-choice.wide {
  background: none; border: 1px dashed var(--border-glass-strong);
  justify-content: center; text-align: center;
}
.onboarding-choice.wide .oc-title { font-weight: 600; font-size: 13px; color: var(--text-secondary); }
.onboarding-instrument-choices { flex-direction: row; }
.onboarding-instrument-choices .onboarding-choice { justify-content: center; text-align: center; }
#onboardingStepSequence .onboarding-choice { justify-content: center; text-align: center; }
#onboardingSequenceLabel { font-weight: 700; color: var(--accent-1); }
.onboarding-choice {
  display: flex; align-items: center; gap: 14px;
  width: 100%; text-align: left;
  background: var(--bg-card-hover); border: 1px solid var(--border-glass);
  border-radius: var(--radius-md); padding: 14px 16px;
  cursor: pointer; transition: var(--transition);
  font-family: 'Inter', sans-serif;
}
.onboarding-choice:hover {
  border-color: var(--border-glass-strong);
  transform: translateY(-2px);
  box-shadow: 0 8px 32px rgba(0,0,0,0.35);
}
.onboarding-choice.primary {
  background: var(--accent-grad);
  border: none;
}
.onboarding-choice .oc-icon {
  font-size: 20px; flex-shrink: 0; width: 28px; text-align: center;
  color: var(--accent-1);
}
.onboarding-choice.primary .oc-icon { color: #fff; }
.onboarding-choice .oc-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.onboarding-choice .oc-title { font-weight: 700; font-size: 15px; color: var(--text-primary); }
.onboarding-choice.primary .oc-title { color: #fff; }
.onboarding-choice .oc-desc { font-weight: 400; font-size: 12px; color: var(--text-muted); }
.onboarding-choice.primary .oc-desc { color: rgba(255,255,255,0.85); }
.onboarding-skip {
  display: inline-block; margin-top: 20px;
  font-size: 13px; color: var(--text-muted); cursor: pointer;
}
.onboarding-skip:hover { color: var(--text-secondary); text-decoration: underline; }

.onboarding-soft-banner {
  position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
  display: flex; align-items: center; gap: 14px;
  background: var(--bg-secondary); border: 1px solid var(--border-glass-strong);
  border-radius: var(--radius-md); box-shadow: var(--shadow-card), var(--shadow-glow);
  padding: 12px 14px 12px 18px; max-width: 92vw; z-index: 900;
}
.onboarding-soft-banner span { font-size: 13px; color: var(--text-primary); }
.onboarding-soft-cta {
  background: var(--accent-grad); border: none; border-radius: var(--radius-sm);
  color: #fff; font-weight: 700; font-size: 13px; padding: 8px 14px;
  cursor: pointer; white-space: nowrap; transition: var(--transition);
}
.onboarding-soft-cta:hover { transform: scale(1.03); }
.onboarding-soft-dismiss {
  background: none; border: none; color: var(--text-muted);
  font-size: 18px; line-height: 1; cursor: pointer; padding: 0 2px;
}
.onboarding-soft-dismiss:hover { color: var(--text-primary); }
@media (max-width: 640px) {
  .onboarding-soft-banner { flex-wrap: wrap; bottom: 12px; }
}

/* ----- Chord Progressions Library ----- */
.cp-content { display: flex; flex-direction: column; gap: 12px; padding: 4px 2px; }
.cp-filters { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.cp-filters select, .cp-filters input {
  background: var(--bg-card); border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm); color: var(--text-secondary);
  padding: 6px 10px; font-size: 13px; font-family: inherit;
}
.cp-filters input#cpSearch { flex: 1 1 160px; min-width: 140px; }
.cp-meta {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 12px; color: var(--text-muted);
}
.cp-pagination { display: flex; align-items: center; gap: 8px; }
.cp-pagination .nav-btn { padding: 4px 10px; font-size: 12px; }
.cp-pagination .nav-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.cp-results {
  display: flex; flex-direction: column;
  border: 1px solid var(--border-glass); border-radius: var(--radius-md);
  background: var(--bg-card); overflow: hidden;
}
.cp-row {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px; border-bottom: 1px solid var(--border-glass);
  font-size: 13px;
}
.cp-row:last-child { border-bottom: none; }
.cp-row .cp-play-btn {
  flex-shrink: 0; width: 28px; height: 28px; border-radius: 50%;
  background: var(--bg-card-hover); border: 1px solid var(--border-glass);
  color: var(--accent-1); display: flex; align-items: center; justify-content: center;
  cursor: pointer; transition: var(--transition);
}
.cp-row .cp-play-btn:hover { border-color: var(--accent-1); }
.cp-row .cp-play-btn.playing { background: var(--accent-grad); border-color: transparent; color: #fff; }
.cp-row .cp-play-btn .icon-svg { --icon-size: 14px; }
.cp-row .cp-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cp-row .cp-name { color: var(--text-primary); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cp-row .cp-tags { color: var(--text-muted); font-size: 11px; display: flex; gap: 6px; flex-wrap: wrap; }
.cp-row .cp-tags span { background: var(--bg-card-hover); border-radius: 20px; padding: 1px 8px; }
.cp-empty, .cp-loading { padding: 20px; text-align: center; color: var(--text-muted); font-size: 13px; }
.cp-attribution { font-size: 11px; color: var(--text-muted); text-align: center; padding: 4px 0; }
.cp-attribution a { color: var(--accent-1); text-decoration: none; }
.cp-attribution a:hover { text-decoration: underline; }

/* ----- Songs: liked/learned (personal) + difficulty (community vote) ----- */
.song-actions { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.song-rating { display: flex; flex-direction: column; align-items: flex-start; gap: 1px; }
.song-stars { display: flex; gap: 1px; }
.song-star {
  background: none; border: none; cursor: pointer; padding: 2px;
  line-height: 1; font-size: 15px; color: var(--text-muted); transition: var(--transition);
}
.song-star:hover { color: #f5b400; transform: scale(1.1); }
.song-star.filled { color: #f5b400; }
/* Once you've voted, your own stars pick up the accent color instead of gold,
   so "this is what I said" reads differently from "this is the crowd average". */
.song-stars.mine .song-star.filled { color: var(--accent-1); }
.song-rating-meta { font-size: 10px; color: var(--text-muted); white-space: nowrap; }
.song-learned-btn, .song-like-btn {
  display: flex; align-items: center; gap: 4px;
  background: var(--bg-card-hover); border: 1px solid var(--border-glass);
  border-radius: 20px; padding: 4px 10px; font-size: 11px; font-weight: 600;
  color: var(--text-muted); cursor: pointer; transition: var(--transition); white-space: nowrap;
}
.song-learned-btn .icon-svg, .song-like-btn .icon-svg { --icon-size: 12px; }
.song-learned-btn:hover, .song-like-btn:hover { border-color: var(--accent-1); color: var(--text-primary); }
.song-learned-btn.active { background: var(--accent-grad); border-color: transparent; color: #fff; }
.song-like-btn.active {
  background: rgba(255, 77, 109, 0.12); border-color: transparent; color: #ff4d6d;
}
.song-like-btn.active .icon-svg { fill: currentColor; }

/* ----- Progressions: Build/Browse tabs ----- */
.cp-tabs { display: flex; gap: 6px; margin-bottom: 4px; }
.cp-tabs button {
  flex: 0 0 auto; padding: 7px 16px; font-size: 13px; font-weight: 600;
  background: var(--bg-card); border: 1px solid var(--border-glass);
  color: var(--text-secondary); border-radius: var(--radius-sm); cursor: pointer;
  transition: all 0.15s ease;
}
.cp-tabs button:hover { color: var(--text-primary); background: var(--bg-card-hover); }
.cp-tabs button.active { background: var(--accent-grad); border-color: transparent; color: #fff; }
.cp-pane { display: none; flex-direction: column; gap: 12px; }
.cp-pane.active { display: flex; }

/* ----- Progression Builder ----- */
.pb-toolbar { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.pb-name {
  flex: 1 1 180px; min-width: 140px; padding: 8px 12px;
  background: var(--bg-card); border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm); color: var(--text-primary); font-size: 14px; font-weight: 600;
}
.pb-name:focus { outline: none; border-color: var(--accent-1); }
.pb-field { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.3px; font-weight: 600; }
.pb-field input, .pb-field select {
  padding: 7px 10px; background: var(--bg-card); border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm); color: var(--text-primary); font-size: 13px; font-weight: 500; text-transform: none; letter-spacing: 0;
}
.pb-field input#pbBpm { width: 64px; }
.pb-field-sound select { min-width: 130px; }
.pb-field input:focus, .pb-field select:focus { outline: none; border-color: var(--accent-1); }
.pb-key-field, .pb-octave-field { display: inline-flex; align-items: center; gap: 5px; }
.pb-key-field select { padding: 7px 8px; }
.pb-key-transpose-btn {
  padding: 7px 10px;
  background: var(--bg-card-hover); border: 1px solid var(--border-glass); border-radius: var(--radius-sm);
  color: var(--text-secondary); font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.3px;
  cursor: pointer; transition: var(--transition);
}
.pb-key-transpose-btn:hover { color: var(--text-primary); border-color: var(--accent-1); }
.pb-octave-btn {
  width: 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--bg-card-hover); border: 1px solid var(--border-glass); border-radius: var(--radius-sm);
  color: var(--text-secondary); font-size: 15px; font-weight: 700;
  cursor: pointer; transition: var(--transition);
}
.pb-octave-btn:hover { color: var(--text-primary); border-color: var(--accent-1); }
.pb-octave-value {
  min-width: 16px; text-align: center;
  font-size: 13px; font-weight: 700; color: var(--text-primary);
  text-transform: none;
}

.pb-tracks { display: flex; flex-direction: column; gap: 8px; }
.pb-track { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; background: var(--bg-card); border: 1px solid var(--border-glass); border-radius: var(--radius-sm); padding: 8px 12px; }
.pb-track-toggle {
  display: inline-flex; align-items: center; gap: 7px; min-width: 92px; padding: 6px 12px;
  background: var(--bg-card-hover); border: 1px solid var(--border-glass); border-radius: var(--radius-sm);
  color: var(--text-muted); font-size: 13px; font-weight: 700; cursor: pointer; transition: all 0.15s ease;
}
.pb-track-toggle:hover { color: var(--text-primary); border-color: var(--border-glass-strong); }
.pb-track-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--text-muted); transition: all 0.15s ease; }
.pb-track-toggle.on { color: var(--text-primary); border-color: rgba(245, 158, 11, 0.5); background: rgba(245, 158, 11, 0.1); }
.pb-track-toggle.on .pb-track-dot { background: var(--accent-1); box-shadow: 0 0 8px var(--glow-accent); }
.pb-track .pb-field select { min-width: 128px; }

/* ----- Volume faders ----- */
.pb-vol-field { gap: 5px; }
.pb-vol { width: 84px; height: 4px; -webkit-appearance: none; appearance: none; background: var(--border-glass-strong); border-radius: 3px; outline: none; cursor: pointer; }
.pb-vol::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 14px; height: 14px; border-radius: 50%; background: var(--accent-1); border: 2px solid var(--bg-panel, #1a1a2a); box-shadow: 0 0 6px var(--glow-accent); cursor: pointer; }
.pb-vol::-moz-range-thumb { width: 14px; height: 14px; border: none; border-radius: 50%; background: var(--accent-1); box-shadow: 0 0 6px var(--glow-accent); cursor: pointer; }

/* ----- Master track row ----- */
.pb-track-master { justify-content: flex-start; }
.pb-master-label { font-size: 13px; font-weight: 700; color: var(--text-primary); }
.pb-field-spacer { flex: 1; }

/* ----- Effects rack (Chords / Bass) ----- */
.pb-fx-toggle {
  display: inline-flex; align-items: center; padding: 7px 12px;
  background: var(--bg-card-hover); border: 1px solid var(--border-glass); border-radius: var(--radius-sm);
  color: var(--text-muted); font-size: 12px; font-weight: 700; letter-spacing: 0.3px; cursor: pointer; transition: all 0.15s ease;
}
.pb-fx-toggle:hover { color: var(--text-primary); border-color: var(--border-glass-strong); }
.pb-fx-toggle[aria-pressed="true"] { color: var(--text-primary); border-color: rgba(139, 92, 246, 0.5); background: rgba(139, 92, 246, 0.12); }
.pb-fx-wrap { display: flex; flex-direction: column; gap: 10px; background: var(--bg-card); border: 1px solid var(--border-glass); border-radius: var(--radius-md); padding: 12px; }
.pb-fx-head { display: flex; align-items: center; }
.pb-fx-title { font-size: 13px; font-weight: 700; color: var(--text-primary); }
.pb-fx-rack { display: flex; flex-direction: column; gap: 6px; }
.pb-fx-empty { font-size: 12px; color: var(--text-muted); padding: 4px 2px; }
.pb-fx-slot {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: var(--bg-card-hover); border: 1px solid var(--border-glass); border-radius: var(--radius-sm); padding: 7px 10px;
}
.pb-fx-slot-label { flex: 0 0 auto; min-width: 92px; font-size: 12px; font-weight: 700; color: var(--text-primary); }
.pb-fx-knob { display: flex; align-items: center; gap: 6px; font-size: 10px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.3px; font-weight: 600; }
.pb-fx-knob input { width: 72px; height: 4px; -webkit-appearance: none; appearance: none; background: var(--border-glass-strong); border-radius: 3px; cursor: pointer; }
.pb-fx-knob input::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 12px; height: 12px; border-radius: 50%; background: var(--accent-2, #8b5cf6); cursor: pointer; }
.pb-fx-knob input::-moz-range-thumb { width: 12px; height: 12px; border: none; border-radius: 50%; background: var(--accent-2, #8b5cf6); cursor: pointer; }
.pb-fx-slot-spacer { flex: 1; }
.pb-fx-slot-btns { display: flex; align-items: center; gap: 3px; }
.pb-fx-slot-btn {
  width: 22px; height: 22px; padding: 0; display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid var(--border-glass); border-radius: 5px; color: var(--text-muted); font-size: 12px; cursor: pointer;
}
.pb-fx-slot-btn:hover { color: var(--text-primary); border-color: var(--border-glass-strong); }
.pb-fx-slot-btn:disabled { opacity: 0.3; cursor: not-allowed; }
.pb-fx-slot-remove:hover { color: #ef4444; border-color: rgba(239, 68, 68, 0.5); }
.pb-fx-add { display: flex; align-items: center; gap: 8px; }

/* ----- Drum step-sequencer grid ----- */
.pb-drumgrid-wrap { display: flex; flex-direction: column; gap: 8px; background: var(--bg-card); border: 1px solid var(--border-glass); border-radius: var(--radius-md); padding: 12px; }
.pb-drumgrid-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pb-drumgrid-title { font-size: 13px; font-weight: 700; color: var(--text-primary); }
.pb-drumgrid-sub { font-size: 11px; color: var(--text-muted); }
.pb-drumgrid-spacer { flex: 1; }
.pb-swing-field input { width: 70px; height: 4px; -webkit-appearance: none; appearance: none; background: var(--border-glass-strong); border-radius: 3px; cursor: pointer; }
.pb-swing-field input::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 13px; height: 13px; border-radius: 50%; background: var(--accent-2, #8b5cf6); cursor: pointer; }
.pb-swing-field input::-moz-range-thumb { width: 13px; height: 13px; border: none; border-radius: 50%; background: var(--accent-2, #8b5cf6); cursor: pointer; }
.pb-drumgrid { display: flex; flex-direction: column; gap: 5px; overflow-x: auto; }
.pb-grid-row { display: flex; align-items: center; gap: 8px; }
.pb-grid-label { flex: 0 0 58px; font-size: 11px; font-weight: 600; color: var(--text-secondary); text-align: right; }
.pb-grid-cells { display: flex; gap: 3px; }
.pb-grid-cell {
  width: 26px; height: 24px; flex: 0 0 auto; padding: 0;
  background: var(--bg-card-hover); border: 1px solid var(--border-glass); border-radius: 5px; cursor: pointer;
  transition: background 0.1s ease, border-color 0.1s ease;
}
.pb-grid-cell.beat { border-left: 2px solid var(--border-glass-strong); }
.pb-grid-cell:hover { border-color: var(--accent-1); }
.pb-grid-cell.on { background: var(--accent-grad); border-color: transparent; }
.pb-grid-cell.playhead { box-shadow: inset 0 0 0 2px rgba(245, 158, 11, 0.6); }
.pb-drumgrid.preset .pb-grid-cell { cursor: pointer; opacity: 0.92; }
.pb-drumgrid.preset .pb-grid-label { color: var(--text-muted); }


.pb-sections { display: flex; flex-direction: column; gap: 10px; }
.pb-section { background: var(--bg-card); border: 1px solid var(--border-glass); border-radius: var(--radius-md); padding: 12px; }
.pb-section-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; flex-wrap: wrap; }
.pb-section-label {
  padding: 5px 10px; background: var(--bg-card-hover); border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm); color: var(--text-primary); font-size: 13px; font-weight: 700;
}
.pb-section-label:focus { outline: none; border-color: var(--accent-1); }
.pb-section-custom { font-size: 13px; font-weight: 700; color: var(--accent-1); }
.pb-section-spacer { flex: 1; }
.pb-stepper { display: inline-flex; align-items: center; gap: 4px; }
.pb-step-lbl { font-size: 10px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.3px; margin-right: 2px; }
.pb-step {
  width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center;
  background: var(--bg-card-hover); border: 1px solid var(--border-glass); border-radius: 6px;
  color: var(--text-primary); font-size: 16px; line-height: 1; cursor: pointer;
}
.pb-step:hover { border-color: var(--accent-1); }
.pb-step-count { min-width: 18px; text-align: center; font-size: 13px; font-weight: 700; color: var(--text-primary); }
.pb-section-total { font-size: 11px; font-weight: 600; color: var(--text-muted); }
.pb-section-btn { padding: 5px 10px; background: var(--bg-card-hover); border: 1px solid var(--border-glass); border-radius: var(--radius-sm); color: var(--text-secondary); font-size: 12px; font-weight: 600; cursor: pointer; }
.pb-section-btn:hover { color: var(--text-primary); border-color: var(--border-glass-strong); }
.pb-section-del:hover { color: #ef4444; }
.pb-section-btn:disabled { opacity: 0.4; cursor: not-allowed; }

.pb-bars { display: flex; gap: 8px; flex-wrap: wrap; }
.pb-bar {
  position: relative; width: 74px; height: 62px; display: flex; align-items: center; justify-content: center;
  background: var(--bg-card-hover); border: 1px dashed var(--border-glass-strong); border-radius: var(--radius-sm);
  color: var(--text-muted); cursor: pointer; transition: all 0.12s ease; padding: 0;
}
.pb-bar:hover { border-color: var(--accent-1); color: var(--text-primary); }
.pb-bar.filled { border-style: solid; background: rgba(245, 158, 11, 0.1); border-color: rgba(245, 158, 11, 0.5); }
.pb-bar.active { box-shadow: 0 0 0 2px var(--accent-1), 0 0 16px var(--glow-accent); border-color: var(--accent-1); }
.pb-bar-num { position: absolute; top: 3px; left: 6px; font-size: 9px; color: var(--text-muted); font-weight: 600; }
.pb-bar-inner { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; }
.pb-bar-chord { font-size: 16px; font-weight: 700; color: var(--text-primary); }
.pb-bar-empty { font-size: 22px; font-weight: 300; color: var(--text-muted); }
.pb-bar-len { font-size: 9px; font-weight: 600; color: var(--accent-1); text-transform: uppercase; letter-spacing: 0.2px; }
.pb-bar.mute-drums::before, .pb-bar.mute-bass::after {
  content: ''; position: absolute; bottom: 4px; width: 6px; height: 6px; border-radius: 50%;
  background: #ef4444; box-shadow: 0 0 4px rgba(239, 68, 68, 0.7);
}
.pb-bar.mute-drums::before { right: 5px; }
.pb-bar.mute-bass::after { right: 14px; }

.pb-add-section-row { display: flex; }
.pb-add-section {
  padding: 8px 16px; background: var(--bg-card); border: 1px dashed var(--border-glass-strong);
  border-radius: var(--radius-sm); color: var(--text-secondary); font-size: 13px; font-weight: 600; cursor: pointer;
}
.pb-add-section:hover { color: var(--accent-1); border-color: var(--accent-1); }
.pb-hint { font-size: 12px; color: var(--text-muted); line-height: 1.5; }

/* ----- Chord editor popover ----- */
.pb-editor {
  position: absolute; z-index: 2000; width: 300px; max-width: calc(100vw - 16px);
  background: var(--bg-elevated, var(--bg-card)); backdrop-filter: blur(18px);
  border: 1px solid var(--border-glass-strong); border-radius: var(--radius-md);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4); padding: 12px; display: flex; flex-direction: column; gap: 10px;
}
.pb-editor-roots { display: grid; grid-template-columns: repeat(6, 1fr); gap: 4px; }
.pb-root-btn { padding: 6px 0; background: var(--bg-card-hover); border: 1px solid var(--border-glass); border-radius: 6px; color: var(--text-primary); font-size: 12px; font-weight: 600; cursor: pointer; }
.pb-root-btn:hover { border-color: var(--accent-1); }
.pb-root-btn.active { background: var(--accent-grad); border-color: transparent; color: #fff; }
.pb-type-group { display: flex; flex-direction: column; gap: 5px; }
.pb-type-title { font-size: 10px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.3px; }
.pb-type-row { display: flex; flex-wrap: wrap; gap: 4px; }
.pb-type-btn { padding: 5px 9px; background: var(--bg-card-hover); border: 1px solid var(--border-glass); border-radius: 6px; color: var(--text-primary); font-size: 12px; font-weight: 600; cursor: pointer; }
.pb-type-btn:hover { border-color: var(--accent-1); }
.pb-type-btn.active { background: var(--accent-grad); border-color: transparent; color: #fff; }
.pb-editor-voicing { display: flex; flex-direction: column; gap: 8px; padding-top: 4px; border-top: 1px solid var(--border-glass); }
.pb-voicing-group { display: flex; align-items: center; gap: 8px; }
.pb-voicing-label { flex: 0 0 54px; font-size: 10px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.3px; }
.pb-voicing-row { display: flex; gap: 4px; flex: 1; }
.pb-voicing-btn { flex: 1; padding: 5px 6px; background: var(--bg-card-hover); border: 1px solid var(--border-glass); border-radius: 6px; color: var(--text-secondary); font-size: 11px; font-weight: 600; cursor: pointer; }
.pb-voicing-btn:hover { border-color: var(--accent-1); color: var(--text-primary); }
.pb-voicing-btn.active { background: var(--accent-grad); border-color: transparent; color: #fff; }
/* Color/border/padding/font for .pb-voicing-select come from the shared
   "Dropdowns (global)" rule above (incl. its <option> background) so this
   popover's Length/Pattern dropdowns match the rest of the app's theme
   instead of falling back to the browser's default (light) popup styling. */
.pb-voicing-select { flex: 1; }
.pb-voicing-pattern-row { display: flex; align-items: center; gap: 8px; flex: 1; }
.pb-voicing-applyall { display: flex; align-items: center; gap: 5px; font-size: 10px; color: var(--text-muted); white-space: nowrap; cursor: pointer; }
.pb-voicing-applyall input { cursor: pointer; accent-color: var(--accent-2, #8b5cf6); }
.pb-voicing-knob input { flex: 1; height: 4px; -webkit-appearance: none; appearance: none; background: var(--border-glass-strong); border-radius: 3px; cursor: pointer; }
.pb-voicing-knob input::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 13px; height: 13px; border-radius: 50%; background: var(--accent-2, #8b5cf6); cursor: pointer; }
.pb-voicing-knob input::-moz-range-thumb { width: 13px; height: 13px; border: none; border-radius: 50%; background: var(--accent-2, #8b5cf6); cursor: pointer; }
.pb-editor-mute { display: flex; gap: 6px; padding-top: 2px; border-top: 1px solid var(--border-glass); }
.pb-editor-mute-btn { flex: 1; padding: 6px 8px; background: var(--bg-card-hover); border: 1px solid var(--border-glass); border-radius: var(--radius-sm); color: var(--text-muted); font-size: 11px; font-weight: 600; cursor: pointer; }
.pb-editor-mute-btn:hover { color: var(--text-primary); border-color: var(--border-glass-strong); }
.pb-editor-mute-btn.active { color: #fff; background: rgba(239, 68, 68, 0.85); border-color: transparent; }
.pb-editor-foot { display: flex; justify-content: space-between; gap: 8px; margin-top: 2px; }
.pb-editor-clear { padding: 6px 12px; background: none; border: 1px solid var(--border-glass); border-radius: var(--radius-sm); color: var(--text-muted); font-size: 12px; font-weight: 600; cursor: pointer; }
.pb-editor-clear:hover { color: #ef4444; border-color: #ef4444; }
.pb-editor-done { padding: 6px 16px; background: var(--accent-grad); border: none; border-radius: var(--radius-sm); color: #fff; font-size: 12px; font-weight: 700; cursor: pointer; }

/* ----- Downloads Page ----- */
.dl-content { display: flex; flex-direction: column; gap: 12px; padding: 4px 2px; }
.dl-results {
  display: flex; flex-direction: column;
  border: 1px solid var(--border-glass); border-radius: var(--radius-md);
  background: var(--bg-card); overflow: hidden;
}
.dl-results .download-item {
  padding: 12px 16px;
  font-size: 13px;
  color: var(--text-secondary);
  border-bottom: 1px solid var(--border-glass);
  transition: var(--transition);
}
.dl-results .download-item:last-child { border-bottom: none; }
.dl-results .download-item:hover { background: var(--bg-card-hover); }
.dl-results .download-item .title { color: var(--text-primary); }
.dl-results .empty-msg { padding: 32px 16px; color: var(--text-muted); font-size: 13px; text-align: center; }
.dl-source-badge {
  flex-shrink: 0;
  font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.03em;
  color: var(--accent-2);
  background: rgba(139,92,246,0.1);
  border: 1px solid rgba(139,92,246,0.2);
  border-radius: 30px;
  padding: 2px 8px;
}


/* ----- Coming Soon ----- */
.coming-soon {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 16px;
  padding: 40px 20px;
  color: var(--text-secondary);
}
.coming-soon .icon-svg {
  --icon-size: 64px;
  color: var(--text-muted);
  opacity: 0.3;
}
.coming-soon h2 {
  font-size: 28px;
  font-weight: 800;
  color: var(--text-primary);
  letter-spacing: -0.5px;
}
.coming-soon p {
  font-size: 16px;
  max-width: 400px;
  line-height: 1.6;
}
.coming-soon .badge {
  display: inline-block;
  background: var(--accent-grad);
  color: #fff;
  font-weight: 700;
  font-size: 13px;
  padding: 6px 24px;
  border-radius: 40px;
  letter-spacing: 0.5px;
  box-shadow: 0 4px 20px rgba(245, 158, 11, 0.25);
  margin-top: 8px;
}

/* ----- Lessons Page ----- */
.lessons-content {
  flex: 1;
  overflow-y: auto;
  padding: 4px 2px 24px;
  display: flex;
  flex-direction: column;
  gap: 28px;
}
.lessons-hero { padding: 4px 2px 0; }
.lessons-hero-sub {
  font-size: 14px;
  color: var(--text-secondary);
  line-height: 1.6;
  max-width: 640px;
}
.lessons-hero-sub strong { color: var(--accent-1); font-weight: 600; }

.lessons-section { display: flex; flex-direction: column; gap: 14px; }
.lessons-section-head { display: flex; flex-direction: column; gap: 3px; }
.lessons-section-head h3 {
  font-size: 18px;
  font-weight: 800;
  color: var(--text-primary);
  letter-spacing: -0.3px;
}
.lessons-section-sub { font-size: 12px; color: var(--text-muted); }

/* Chapter accordions (both the Theory Path and Instrument Tracks) */
.chapter-list { display: flex; flex-direction: column; gap: 10px; }
.lesson-chapter {
  background: var(--bg-card);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-md);
  overflow: hidden;
  transition: var(--transition);
}
.lesson-chapter:hover { border-color: var(--border-glass-strong); }
.lesson-chapter.open { border-color: var(--border-glass-strong); background: var(--bg-card-hover); }

.lesson-chapter-head {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  background: none;
  border: none;
  text-align: left;
  cursor: pointer;
  color: inherit;
  font: inherit;
}
.lesson-chapter-head:hover { background: var(--bg-card-hover); }

.chapter-num {
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  font-size: 15px;
  color: #fff;
  background: var(--accent-grad);
  box-shadow: 0 4px 14px rgba(245, 158, 11, 0.2);
}
.chapter-badge {
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(245, 158, 11, 0.12);
  border: 1px solid rgba(245, 158, 11, 0.25);
}
.chapter-badge .icon-svg { --icon-size: 20px; color: var(--accent-1); }

.chapter-headtext { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.chapter-title { font-size: 15px; font-weight: 700; color: var(--text-primary); letter-spacing: -0.2px; }
.chapter-desc { font-size: 12px; color: var(--text-muted); line-height: 1.45; }
.chapter-tags { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; flex-shrink: 0; justify-content: flex-end; }

.lesson-chevron {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; flex-shrink: 0;
}
.lesson-chevron .chev {
  width: 18px; height: 18px;
  fill: none; stroke: var(--text-muted); stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.lesson-chevron .chev-open { display: none; }
.lesson-chapter.open .lesson-chevron .chev-closed { display: none; }
.lesson-chapter.open .lesson-chevron .chev-open { display: inline; stroke: var(--accent-1); }

/* Expanded body: sub-lesson list (and module groups for instruments) */
.lesson-chapter-body { padding: 4px 16px 14px 64px; }
.sub-group + .sub-group { margin-top: 12px; }
.sub-group-title {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--accent-2);
  margin: 6px 0 6px;
}
.sub-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.sub-lesson {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 6px 0;
  border-top: 1px solid var(--border-glass);
  font-size: 13px;
  color: var(--text-secondary);
}
.sub-list > .sub-lesson:first-child { border-top: none; }
.sub-index {
  flex-shrink: 0;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
  min-width: 30px;
  font-variant-numeric: tabular-nums;
}
.sub-title { flex: 1; line-height: 1.4; }
.sub-soon { flex-shrink: 0; color: var(--accent-1); opacity: 0.5; font-size: 14px; }
a.sub-link { color: var(--text-primary); text-decoration: none; font-weight: 600; }
a.sub-link:hover { color: var(--accent-1); text-decoration: underline; }
.sub-live {
  flex-shrink: 0; font-size: 9px; font-weight: 700; letter-spacing: 0.4px; text-transform: uppercase;
  color: #10b981; background: rgba(16,185,129,0.14); border: 1px solid rgba(16,185,129,0.35);
  padding: 2px 7px; border-radius: 30px;
}

/* Level tags + shared meta pills */
.level-tag {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: 30px;
  border: 1px solid transparent;
}
.level-tag.beginner { color: #10b981; background: rgba(16, 185, 129, 0.12); border-color: rgba(16, 185, 129, 0.3); }
.level-tag.intermediate { color: #3b82f6; background: rgba(59, 130, 246, 0.12); border-color: rgba(59, 130, 246, 0.3); }
.level-tag.advanced { color: #8b5cf6; background: rgba(139, 92, 246, 0.14); border-color: rgba(139, 92, 246, 0.32); }
.level-tag.expert { color: #ec4899; background: rgba(236, 72, 153, 0.14); border-color: rgba(236, 72, 153, 0.32); }
.lesson-count { font-size: 11px; color: var(--text-muted); font-weight: 500; }

@media (max-width: 700px) {
  .lesson-chapter-head { flex-wrap: wrap; gap: 10px 12px; }
  .chapter-headtext { flex-basis: calc(100% - 100px); }
  .chapter-tags { width: 100%; justify-content: flex-start; padding-left: 48px; }
  .lesson-chapter-body { padding-left: 24px; }
}

/* ----- Tools Page ----- */
#page-tools .tools-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  flex: 1;
  overflow-y: auto;
  padding: 8px 4px;
}
#page-tools .tools-grid > div {
  background: var(--bg-card);
  backdrop-filter: blur(16px);
  border-radius: var(--radius-md);
  border: 1px solid var(--border-glass);
  padding: 16px 18px;
  box-shadow: var(--shadow-card);
  transition: background var(--transition), border var(--transition);
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: 200px;
}
#page-tools .tools-grid > div h3 {
  font-size: 15px;
  font-weight: 700;
  color: var(--text-primary);
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
}
#page-tools .tools-grid > div h3 .icon-svg { color: var(--accent-1); }

.metro-controls {
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
}
.metro-controls label { font-size: 14px; font-weight: 500; color: var(--text-secondary); }
.metro-controls input[type="number"] {
  width: 72px; padding: 6px;
  font-size: 20px; font-weight: 700;
  background: var(--bg-card);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  text-align: center;
  font-family: 'Inter', sans-serif;
}
.metro-controls .start-stop-btn {
  padding: 6px 20px;
  background: var(--accent-grad);
  border: none;
  border-radius: var(--radius-sm);
  color: #fff;
  font-weight: bold;
  font-size: 16px;
  cursor: pointer;
  font-family: 'Inter', sans-serif;
  transition: var(--transition);
}
.metro-controls .start-stop-btn:hover {
  transform: scale(1.02);
  box-shadow: 0 4px 20px rgba(139, 92, 246, 0.3);
}
.metro-pulse-area {
  display: flex; gap: 12px; align-items: center;
}
.metro-pulse {
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--text-muted);
  transition: background 0.1s, box-shadow 0.1s;
  box-shadow: 0 0 20px transparent;
}
.metro-beat-count {
  font-size: 18px; font-weight: 700;
  color: var(--text-secondary);
  min-width: 28px; text-align: center;
}
.metro-time-sigs {
  display: flex; gap: 6px; flex-wrap: wrap;
}
.metro-time-sigs .nav-btn {
  min-width: 40px; text-align: center;
}

/* ----- Tuner ----- */
.tuner-display {
  text-align: center;
  padding: 4px 0;
}
.tuner-note {
  font-size: 52px;
  font-weight: 800;
  letter-spacing: 2px;
  color: var(--text-primary);
  transition: color 0.15s;
  line-height: 1.2;
}
.tuner-note.in-tune { color: #34d399; }
.tuner-note.sharp { color: var(--accent-1); }
.tuner-detail {
  display: flex;
  justify-content: center;
  gap: 18px;
  font-size: 14px;
  color: var(--text-secondary);
  margin-top: 2px;
}
.tuner-detail .freq { font-weight: 500; }
.tuner-detail .cents { font-weight: 500; min-width: 60px; }
.tuner-detail .cents.flat { color: #6a9fd8; }
.tuner-detail .cents.sharp { color: var(--accent-1); }
.tuner-detail .cents.in-tune { color: #34d399; }

.tuner-meter {
  position: relative;
  height: 6px;
  background: rgba(255,255,255,0.08);
  border-radius: 40px;
  margin: 12px 0 8px;
  overflow: visible;
}
.tuner-meter .track-bg {
  position: absolute;
  inset: 0;
  border-radius: 40px;
  background: linear-gradient(to right, #6a9fd8 0%, #6a9fd8 42%, #34d399 45%, #34d399 55%, var(--accent-1) 58%, var(--accent-1) 100%);
  opacity: 0.25;
}
.tuner-meter .needle {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 4px;
  height: 20px;
  background: var(--text-primary);
  border-radius: 4px;
  box-shadow: 0 0 20px rgba(245, 158, 11, 0.2);
  transition: left 0.08s ease-out;
  will-change: left;
}
.tuner-meter .needle.in-tune {
  background: #34d399;
  box-shadow: 0 0 30px rgba(52, 211, 153, 0.4);
}
.tuner-meter .center-mark {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 2px;
  height: 12px;
  background: rgba(255,255,255,0.15);
  border-radius: 2px;
}

.hz-control {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin-top: 6px;
}
.hz-control label {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-muted);
}
.hz-control input[type="range"] {
  width: 120px;
  height: 3px;
  -webkit-appearance: none;
  appearance: none;
  background: rgba(255,255,255,0.1);
  border-radius: 4px;
  outline: none;
}
.hz-control input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--accent-1);
  cursor: pointer;
  border: 2px solid var(--bg-primary);
  box-shadow: 0 0 12px rgba(245, 158, 11, 0.2);
}
.hz-control .hz-value {
  font-size: 16px;
  font-weight: 600;
  color: var(--text-primary);
  min-width: 52px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.hz-control .hz-value small { font-size: 11px; font-weight: 400; color: var(--text-muted); }

.tuner-actions {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin-top: 8px;
}
.tuner-actions .mic-btn {
  background: var(--bg-card);
  border: 1px solid var(--border-glass);
  border-radius: 30px;
  color: var(--text-secondary);
  padding: 6px 20px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  transition: var(--transition);
  font-family: 'Inter', sans-serif;
}
.tuner-actions .mic-btn:hover {
  border-color: var(--border-glass-strong);
  color: var(--text-primary);
  background: var(--bg-card-hover);
}
.tuner-actions .mic-btn.active {
  background: rgba(52, 211, 153, 0.12);
  border-color: #34d399;
  color: #34d399;
}
.tuner-actions .mic-btn.active i {
  animation: pulse 1.2s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.3; }
}

/* ----- Backing Track ----- */
#page-backing-track .backing-content {
  flex: 1; display: flex; flex-direction: column;
  gap: 10px; padding: 8px 2px; overflow-y: auto;
}
.local-upload-area {
  background: var(--bg-card); backdrop-filter: blur(16px);
  border-radius: var(--radius-md);
  border: 1px solid var(--border-glass);
  padding: 14px 20px;
  box-shadow: var(--shadow-card);
  transition: background var(--transition), border var(--transition);
  display: flex; flex-direction: column; gap: 8px;
}
.local-upload-area .upload-row {
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
}
.local-upload-area .upload-row input[type="file"] {
  flex: 1; min-width: 150px;
  background: var(--bg-card);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm);
  padding: 6px 10px;
  color: var(--text-primary);
  font-family: 'Inter', sans-serif;
  font-size: 12px;
  transition: var(--transition);
}
.local-upload-area .upload-row input[type="file"]:hover { border-color: var(--border-glass-strong); }
.local-upload-area .upload-row input[type="file"]::file-selector-button {
  background: var(--bg-card);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm);
  padding: 4px 12px;
  color: var(--text-secondary);
  font-family: 'Inter', sans-serif;
  font-size: 12px;
  cursor: pointer;
  transition: var(--transition);
}
.local-upload-area .upload-row input[type="file"]::file-selector-button:hover {
  background: var(--bg-card-hover);
  color: var(--text-primary);
  border-color: var(--border-glass-strong);
}
.local-upload-area .local-status {
  font-size: 12px;
  color: var(--text-secondary);
  min-height: 20px;
  text-align: center;
}
.local-upload-area .local-status .error { color: #f87171; }
.local-upload-area .local-status .success { color: #34d399; }

#server-track-area {
  background: var(--bg-card);
  border-radius: var(--radius-md);
  padding: 12px;
  border: 1px solid var(--border-glass);
}
#server-track-area .track-header {
  display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;
}
#server-track-area .track-header span { font-weight: 600; font-size: 14px; color: var(--text-primary); }
#server-track-area .track-header .count { font-size: 11px; color: var(--text-muted); }
#track-list {
  max-height: 150px; overflow-y: auto;
  display: flex; flex-direction: column; gap: 4px;
}
#track-list .track-item {
  display: flex; justify-content: space-between; align-items: center;
  padding: 6px 10px;
  background: var(--bg-card-hover);
  border-radius: var(--radius-sm);
  border-left: 3px solid var(--accent-1);
  cursor: pointer;
  transition: var(--transition);
}
#track-list .track-item:hover { background: var(--bg-card-hover); border-color: var(--accent-2); }
#track-list .track-item .info { display: flex; flex-direction: column; overflow: hidden; }
#track-list .track-item .info .title { font-weight: 600; font-size: 13px; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#track-list .track-item .info .meta { font-size: 10px; color: var(--text-muted); }
#track-list .track-item .play-btn {
  background: var(--accent-grad); border: none;
  color: #fff; padding: 4px 12px;
  border-radius: 30px; font-size: 11px; font-weight: 600;
  cursor: pointer; flex-shrink: 0;
  transition: var(--transition);
}
#track-list .track-item .play-btn:hover { transform: scale(1.05); box-shadow: 0 4px 16px rgba(139,92,246,0.3); }

#admin-upload-area {
  display: none;
  background: var(--bg-card);
  border-radius: var(--radius-md);
  padding: 12px;
  border: 1px solid var(--accent-1);
}
#admin-upload-area .admin-title { font-weight: 600; font-size: 13px; color: var(--accent-1); }
#admin-upload-area .admin-row { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
#admin-upload-area .admin-row input, #admin-upload-area .admin-row select {
  flex: 1; min-width: 80px;
  padding: 6px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-glass);
  background: var(--bg-card);
  color: var(--text-primary);
  font-size: 12px;
  font-family: 'Inter', sans-serif;
}
#admin-upload-area .admin-row input[type="file"] { flex: 2; min-width: 120px; padding: 4px; font-size: 11px; }
#admin-upload-area .admin-row .upload-btn {
  background: var(--accent-grad); border: none;
  color: #fff; padding: 6px 16px;
  border-radius: var(--radius-sm);
  cursor: pointer; font-weight: 600; font-size: 12px;
  transition: var(--transition);
}
#admin-upload-area .admin-row .upload-btn:hover { transform: scale(1.02); }
#admin-upload-status { font-size: 11px; color: var(--text-muted); margin-top: 4px; text-align: center; }

.analysis-output {
  background: var(--bg-card); backdrop-filter: blur(16px);
  border-radius: var(--radius-md);
  border: 1px solid var(--border-glass);
  padding: 14px 20px;
  display: flex; flex-wrap: wrap; gap: 10px 28px;
  align-items: center;
  box-shadow: var(--shadow-card);
}
.analysis-output .ao-item { display: flex; flex-direction: column; gap: 2px; }
.analysis-output .ao-label {
  font-size: 11px; color: var(--text-muted);
  font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.5px;
}
.analysis-output .ao-value { font-size: 15px; color: var(--text-primary); font-weight: 700; }
.analysis-output .ao-sub { font-size: 11px; color: var(--text-muted); font-weight: 500; }
.analysis-output .ao-sub:empty { display: none; }
.ao-edit-btn {
  margin-left: auto;
  background: none;
  border: 1px solid var(--border-glass);
  border-radius: 30px;
  color: var(--text-secondary);
  font-size: 12px; font-weight: 600;
  padding: 5px 12px;
  cursor: pointer;
  transition: var(--transition);
}
.ao-edit-btn:hover { border-color: var(--accent-1); color: var(--accent-1); }

.analysis-edit-panel {
  background: var(--bg-card); backdrop-filter: blur(16px);
  border-radius: var(--radius-md);
  border: 1px solid var(--border-glass-strong);
  padding: 14px 20px;
  display: flex; flex-direction: column; gap: 12px;
  box-shadow: var(--shadow-card);
}
.analysis-edit-panel .ae-row { display: flex; flex-wrap: wrap; gap: 20px; }
.analysis-edit-panel .ae-field {
  display: flex; flex-direction: column; gap: 4px;
  font-size: 11px; color: var(--text-muted);
  font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px;
}
.analysis-edit-panel .ae-field select,
.analysis-edit-panel .ae-field input {
  font-size: 14px; font-weight: 600; text-transform: none; letter-spacing: normal;
  color: var(--text-primary);
  background: var(--bg-secondary);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm);
  padding: 6px 8px;
}
.analysis-edit-panel .ae-key-inputs { display: flex; gap: 6px; }
.analysis-edit-panel .ae-bpm-input { width: 80px; }
.analysis-edit-panel .ae-chords-label {
  font-size: 11px; color: var(--text-muted);
  font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px;
  display: block; margin-bottom: 6px;
}
.analysis-edit-panel .ae-chords {
  display: flex; flex-wrap: wrap; gap: 8px;
  max-height: 160px; overflow-y: auto;
}
.analysis-edit-panel .ae-chord-row {
  display: flex; flex-direction: column; gap: 2px;
  min-width: 64px;
}
.analysis-edit-panel .ae-chord-row .ae-chord-time { font-size: 10px; color: var(--text-muted); }
.analysis-edit-panel .ae-chord-row input {
  width: 100%; box-sizing: border-box;
  font-size: 13px; font-weight: 600;
  color: var(--text-primary);
  background: var(--bg-secondary);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm);
  padding: 4px 6px;
}
.analysis-edit-panel .ae-actions { display: flex; gap: 10px; }
.analysis-edit-panel .ae-actions .nav-btn { padding: 7px 18px; font-weight: 600; }

.progression-display {
  background: var(--bg-card); backdrop-filter: blur(16px);
  border-radius: var(--radius-md);
  border: 1px solid var(--border-glass);
  padding: 14px 20px;
  display: flex; flex-wrap: wrap; gap: 10px 18px;
  align-items: center;
  box-shadow: var(--shadow-card);
  transition: background var(--transition), border var(--transition);
}
.progression-display .label {
  font-size: 11px; color: var(--text-muted);
  font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.5px;
}
.progression-display .chord-list { display: flex; gap: 8px; flex-wrap: wrap; }
.progression-display .chord-tag {
  background: rgba(245,158,11,0.06);
  padding: 3px 14px; border-radius: 30px;
  font-size: 13px; font-weight: 600;
  color: var(--accent-1);
  border: 1px solid rgba(245,158,11,0.1);
  transition: var(--transition);
}
.progression-display .chord-tag:hover { background: rgba(245,158,11,0.12); transform: scale(1.02); }
.progression-display .chord-tag.current {
  background: var(--accent-grad);
  color: #fff;
  border-color: transparent;
  box-shadow: 0 0 16px var(--glow-accent);
}
/* ----- AI Teacher ----- */
#page-ai-teacher .ai-layout {
  display: flex; flex: 1; gap: 14px;
  min-height: 0; flex-wrap: wrap;
}
#page-ai-teacher .ai-chat {
  flex: 2; min-width: 220px;
  background: var(--bg-card); backdrop-filter: blur(16px);
  border-radius: var(--radius-md);
  border: 1px solid var(--border-glass);
  display: flex; flex-direction: column;
  padding: 14px; gap: 10px;
  max-height: 100%;
  min-height: 0;
  box-shadow: var(--shadow-card);
  transition: background var(--transition), border var(--transition);
}
#page-ai-teacher .ai-chat .messages {
  flex: 1; overflow-y: auto;
  display: flex; flex-direction: column; gap: 8px;
  padding: 4px 2px;
  min-height: 60px; max-height: 400px;
}
#page-ai-teacher .ai-chat .msg {
  padding: 10px 16px; border-radius: var(--radius-md);
  max-width: 88%;
  font-size: 13px; line-height: 1.6;
  animation: msgFadeIn 0.3s ease;
  box-shadow: 0 2px 8px rgba(0,0,0,0.2);
  display: flex; align-items: flex-start; gap: 8px;
}
@keyframes msgFadeIn {
  from { opacity: 0; transform: translateY(6px) scale(0.98); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
#page-ai-teacher .ai-chat .msg .icon-svg { --icon-size: 16px; flex-shrink: 0; margin-top: 1px; }
#page-ai-teacher .ai-chat .msg.user {
  background: rgba(139,92,246,0.15);
  align-self: flex-end;
  color: var(--text-primary);
  border: 1px solid rgba(139,92,246,0.15);
}
#page-ai-teacher .ai-chat .msg.user .icon-svg { color: var(--accent-2); }
#page-ai-teacher .ai-chat .msg.ai {
  background: rgba(245,158,11,0.06);
  align-self: flex-start;
  color: var(--text-secondary);
  border: 1px solid rgba(245,158,11,0.06);
  border-left: 3px solid var(--accent-1);
}
#page-ai-teacher .ai-chat .msg.ai .icon-svg { color: var(--accent-1); }
#page-ai-teacher .ai-chat .msg.ai .ai-lesson-link-line {
  display: block; margin-top: 4px;
}
#page-ai-teacher .ai-chat .msg.ai .ai-lesson-link-line a {
  color: var(--accent-1); font-weight: 600; text-decoration: underline; cursor: pointer;
}
#page-ai-teacher .ai-chat .msg.ai .ai-lesson-link-line a:hover { opacity: 0.85; }
#page-ai-teacher .ai-chat .msg.ai .action-tag {
  display: inline-block;
  background: rgba(245,158,11,0.1);
  padding: 0 10px; border-radius: 20px;
  font-size: 11px; color: var(--accent-1);
  margin-top: 4px; font-weight: 500;
}

/* AI Teacher — generated practice plan checklist card */
#page-ai-teacher .ai-chat .ai-plan-card { display: flex; flex-direction: column; gap: 8px; width: 100%; }
#page-ai-teacher .ai-chat .ai-plan-title { font-weight: 700; color: var(--text-primary); font-size: 13px; }
#page-ai-teacher .ai-chat .ai-plan-list { display: flex; flex-direction: column; gap: 8px; margin: 0; padding-left: 18px; }
#page-ai-teacher .ai-chat .ai-plan-list li { padding-left: 2px; }
#page-ai-teacher .ai-chat .ai-plan-item-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-weight: 600; color: var(--text-primary); }
#page-ai-teacher .ai-chat .ai-plan-item-desc { font-size: 12px; color: var(--text-secondary); margin-top: 2px; }
#page-ai-teacher .ai-chat .ai-plan-log-link {
  align-self: flex-start; color: var(--accent-1); font-weight: 600;
  text-decoration: underline; cursor: pointer; font-size: 12px; margin-top: 2px;
}
#page-ai-teacher .ai-chat .ai-plan-log-link:hover { opacity: 0.85; }

/* AI Teacher — quizMe multiple-choice card (reuses .eg-choice styling) */
#page-ai-teacher .ai-chat .ai-quiz-card { display: flex; flex-direction: column; gap: 10px; width: 100%; }
#page-ai-teacher .ai-chat .ai-quiz-question { font-weight: 700; color: var(--text-primary); font-size: 13px; }
#page-ai-teacher .ai-chat .ai-quiz-choices { justify-content: flex-start; }
#page-ai-teacher .ai-chat .ai-quiz-choices .eg-choice { padding: 8px 12px; font-size: 12px; }
#page-ai-teacher .ai-chat .ai-quiz-feedback { font-size: 12px; font-weight: 600; color: var(--text-secondary); }
#page-ai-teacher .ai-chat .ai-quiz-feedback.ok { color: #34d399; }
#page-ai-teacher .ai-chat .ai-quiz-feedback.bad { color: #f87171; }
#page-ai-teacher .ai-chat .input-row {
  display: flex; gap: 10px; flex-shrink: 0;
}
#page-ai-teacher .ai-chat .input-row input {
  flex: 1;
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm);
  padding: 8px 14px;
  color: var(--text-primary);
  font-size: 13px;
  font-family: 'Inter', sans-serif;
  outline: none;
  transition: var(--transition);
}
#page-ai-teacher .ai-chat .input-row input:focus {
  border-color: var(--accent-2);
  box-shadow: 0 0 30px rgba(139,92,246,0.08);
  background: rgba(255,255,255,0.06);
}
#page-ai-teacher .ai-chat .input-row input::placeholder { color: var(--text-muted); font-weight: 400; }
#page-ai-teacher .ai-chat .input-row button {
  background: var(--accent-grad); border: none;
  color: #fff; padding: 8px 22px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-weight: 600; font-size: 13px;
  font-family: 'Inter', sans-serif;
  transition: var(--transition);
  box-shadow: 0 4px 16px rgba(139,92,246,0.2);
  display: flex; align-items: center; gap: 6px;
}
#page-ai-teacher .ai-chat .input-row button:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 8px 32px rgba(139,92,246,0.3);
}
#page-ai-teacher .ai-chat .input-row button:disabled { opacity: 0.4; cursor: not-allowed; transform: none; }
#page-ai-teacher .ai-status {
  font-size: 11px; color: var(--text-muted);
  padding: 2px 2px;
  display: flex; align-items: center; gap: 8px;
  font-weight: 500;
  flex-shrink: 0;
}
#page-ai-teacher .ai-status .dot {
  display: inline-block; width: 8px; height: 8px;
  border-radius: 50%;
  background: #34d399;
  box-shadow: 0 0 12px rgba(52,211,153,0.3);
  transition: var(--transition);
}
#page-ai-teacher .ai-status .dot.offline { background: var(--text-muted); box-shadow: none; }
#page-ai-teacher .ai-status .dot.thinking {
  background: var(--accent-1);
  animation: pulseDot 1s ease-in-out infinite;
  box-shadow: 0 0 20px rgba(245,158,11,0.3);
}
@keyframes pulseDot {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.4; transform: scale(0.8); }
}

/* ----- Library ----- */
#page-library .library-content {
  flex: 1; display: flex; flex-direction: column;
  gap: 12px; padding: 8px 2px; overflow-y: auto;
}
#page-library .library-hub-integrated {
  background: var(--bg-card); backdrop-filter: blur(16px);
  border-radius: var(--radius-md);
  border: 1px solid var(--border-glass);
  padding: 16px 20px;
  flex: 1; overflow-y: auto;
  box-shadow: var(--shadow-card);
  display: flex; flex-direction: column; gap: 14px;
  transition: background var(--transition), border var(--transition);
}
#page-library .library-hub-integrated h3 {
  font-size: 15px; font-weight: 700;
  color: var(--text-primary);
  display: flex; align-items: center; gap: 8px;
  margin: 0;
}
#page-library .library-hub-integrated h3 .icon-svg { color: var(--accent-1); }
#page-library .library-hub-integrated .hub-tabs {
  display: flex; gap: 6px;
  border-bottom: 1px solid var(--border-glass);
  padding-bottom: 10px;
}
#page-library .library-hub-integrated .hub-tabs button {
  background: transparent; border: none;
  color: var(--text-muted);
  padding: 6px 16px;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  cursor: pointer;
  font-size: 13px; font-weight: 500;
  font-family: 'Inter', sans-serif;
  transition: var(--transition);
}
#page-library .library-hub-integrated .hub-tabs button.active {
  color: var(--accent-1);
  background: rgba(245,158,11,0.06);
  border-bottom: 2px solid var(--accent-1);
}
#page-library .library-hub-integrated .hub-tabs button:hover { color: var(--text-primary); }
#page-library .library-hub-integrated .hub-pane {
  display: none; flex-direction: column; gap: 12px;
}

/* ----- Chord Finder ----- */
.finder-controls {
  margin-bottom: 8px;
}
.finder-selection {
  font-size: 14px;
  color: var(--text-secondary);
  margin: 6px 0;
}
.finder-selection #finder-notes-display {
  font-weight: 600;
  color: var(--accent-1);
}
.finder-results {
  margin-top: 10px;
  max-height: 200px;
  overflow-y: auto;
  background: var(--bg-card);
  border-radius: var(--radius-sm);
  padding: 8px 12px;
  border: 1px solid var(--border-glass);
}
.finder-result-item {
  padding: 6px 10px;
  border-bottom: 1px solid var(--border-glass);
  font-size: 14px;
  display: flex;
  justify-content: space-between;
}
.finder-result-item:last-child {
  border-bottom: none;
}
.finder-result-item .chord-name {
  font-weight: 700;
  color: var(--accent-1);
}
.finder-result-item .chord-intervals {
  color: var(--text-muted);
  font-size: 12px;
}

/* ----- Chord Finder ----- */
.finder-controls {
  margin-bottom: 8px;
}
.finder-selection {
  font-size: 14px;
  color: var(--text-secondary);
  margin: 6px 0;
}
.finder-selection #finder-notes-display {
  font-weight: 600;
  color: var(--accent-1);
}
.finder-results {
  margin-top: 10px;
  max-height: 200px;
  overflow-y: auto;
  background: var(--bg-card);
  border-radius: var(--radius-sm);
  padding: 8px 12px;
  border: 1px solid var(--border-glass);
}
.finder-result-item {
  padding: 6px 10px;
  border-bottom: 1px solid var(--border-glass);
  font-size: 14px;
  display: flex;
  justify-content: space-between;
}
.finder-result-item:last-child {
  border-bottom: none;
}
.finder-result-item .chord-name {
  font-weight: 700;
  color: var(--accent-1);
}
.finder-result-item .chord-intervals {
  color: var(--text-muted);
  font-size: 12px;
}
#page-library .library-hub-integrated .hub-pane.active { display: flex; }
#page-library .library-hub-integrated .hub-list {
  display: flex; flex-wrap: wrap; gap: 6px;
  max-height: 180px; overflow-y: auto; padding: 4px 0;
}
#page-library .library-hub-integrated .hub-list button {
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--border-glass);
  color: var(--text-secondary);
  padding: 4px 14px; border-radius: 30px;
  cursor: pointer;
  font-size: 12px; font-weight: 500;
  font-family: 'Inter', sans-serif;
  transition: var(--transition);
  flex-shrink: 0;
}
#page-library .library-hub-integrated .hub-list button:hover {
  border-color: var(--border-glass-strong);
  color: var(--text-primary);
  background: rgba(255,255,255,0.06);
}
#page-library .library-hub-integrated .hub-list button.active-item {
  border-color: var(--accent-1);
  background: rgba(245,158,11,0.08);
  color: var(--accent-1);
}
#page-library .library-hub-integrated .hub-info {
  background: rgba(255,255,255,0.02);
  border-radius: var(--radius-sm);
  padding: 12px 16px;
  font-size: 13px;
  color: var(--text-secondary);
  min-height: 40px;
  border: 1px solid var(--border-glass);
  line-height: 1.6;
  transition: background var(--transition), border var(--transition);
}
#page-library .library-hub-integrated .hub-info strong { color: var(--text-primary); }
#page-library .library-hub-integrated .hub-input-group {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
}
#page-library .library-hub-integrated .hub-input-group button {
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--border-glass);
  color: var(--text-secondary);
  padding: 4px 14px; border-radius: 30px;
  cursor: pointer;
  font-size: 12px; font-weight: 500;
  font-family: 'Inter', sans-serif;
  transition: var(--transition);
  white-space: nowrap;
  display: flex; align-items: center; gap: 4px;
  min-height: 32px;
}
#page-library .library-hub-integrated .hub-input-group button:hover {
  border-color: var(--border-glass-strong);
  color: var(--text-primary);
  background: rgba(255,255,255,0.06);
}
#page-library .library-hub-integrated .hub-input-group button.active-mode {
  border-color: var(--accent-1);
  background: rgba(245,158,11,0.08);
  color: var(--accent-1);
}
#page-library .library-hub-integrated .chord-type-buttons {
  display: flex; flex-wrap: wrap; gap: 4px;
  max-height: 140px; overflow-y: auto; padding: 4px 0;
}
#page-library .library-hub-integrated .chord-type-buttons button {
  background: rgba(255,255,255,0.03);
  border: 1px solid var(--border-glass);
  color: var(--text-secondary);
  padding: 2px 12px; border-radius: 30px;
  cursor: pointer;
  font-size: 12px;
  font-family: 'Inter', sans-serif;
  transition: var(--transition);
  flex-shrink: 0;
}
#page-library .library-hub-integrated .chord-type-buttons button:hover {
  border-color: var(--border-glass-strong);
  color: var(--text-primary);
}
#page-library .library-hub-integrated .chord-type-buttons button.active-item {
  border-color: var(--accent-1);
  background: rgba(245,158,11,0.08);
  color: var(--accent-1);
}
.voicing-position-tabs {
  display: flex; flex-wrap: wrap; gap: 4px;
  max-height: 90px; overflow-y: auto; padding: 4px 0;
}
.voicing-position-tabs button {
  background: rgba(255,255,255,0.03);
  border: 1px solid var(--border-glass);
  color: var(--text-secondary);
  padding: 2px 12px;
  border-radius: 30px;
  cursor: pointer;
  font-size: 12px;
  font-family: 'Inter', sans-serif;
  transition: var(--transition);
  flex-shrink: 0;
}
.voicing-position-tabs button:hover {
  border-color: var(--border-glass-strong);
  color: var(--text-primary);
}
.voicing-position-tabs button.active-item {
  border-color: var(--accent-1);
  background: rgba(245,158,11,0.08);
  color: var(--accent-1);
}
.voicing-buttons {
  display: flex; flex-wrap: wrap; gap: 4px;
  margin-top: 6px;
  max-height: 140px; overflow-y: auto; padding: 4px 0;
}
.voicing-buttons button {
  background: rgba(255,255,255,0.03);
  border: 1px solid var(--border-glass);
  color: var(--text-secondary);
  padding: 2px 10px;
  border-radius: 30px;
  cursor: pointer;
  font-size: 11px;
  font-family: 'Inter', sans-serif;
  transition: var(--transition);
  flex-shrink: 0;
}
.voicing-buttons button:hover {
  border-color: var(--border-glass-strong);
  color: var(--text-primary);
}
.voicing-buttons button.active-item {
  border-color: var(--accent-1);
  background: rgba(245,158,11,0.08);
  color: var(--accent-1);
}
.interval-buttons {
  display: flex; flex-wrap: wrap; gap: 4px;
  margin-top: 4px;
}
.interval-buttons button {
  background: rgba(255,255,255,0.03);
  border: 1px solid var(--border-glass);
  color: var(--text-secondary);
  padding: 2px 10px;
  border-radius: 30px;
  cursor: pointer;
  font-size: 11px;
  font-family: 'Inter', sans-serif;
  transition: var(--transition);
  flex-shrink: 0;
}
.interval-buttons button:hover {
  border-color: var(--border-glass-strong);
  color: var(--text-primary);
}
.interval-buttons button.active-item {
  border-color: var(--accent-1);
  background: rgba(245,158,11,0.08);
  color: var(--accent-1);
}

#player { display: none; }

/* ----- Login Modal ----- */
#loginModal {
  display: none;
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.7);
  backdrop-filter: blur(12px);
  z-index: 1000;
  justify-content: center; align-items: center;
}
#loginModal.show { display: flex; }
#loginModal .login-box {
  background: var(--bg-secondary);
  padding: 32px;
  border-radius: var(--radius-lg);
  max-width: 380px; width: 90%;
  box-shadow: var(--shadow-card), var(--shadow-glow);
  border: 1px solid var(--border-glass-strong);
  position: relative;
}
#loginModal .login-box h2 {
  font-family: 'Nunito', sans-serif;
  margin-bottom: 16px;
  color: var(--text-primary);
}
#loginModal .login-box input {
  width: 100%; padding: 10px; margin-bottom: 10px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-glass);
  background: var(--bg-card);
  color: var(--text-primary);
  font-family: 'Inter', sans-serif;
  font-size: 14px;
  transition: var(--transition);
}
#loginModal .login-box input:focus {
  border-color: var(--accent-2);
  outline: none;
  box-shadow: 0 0 20px rgba(139,92,246,0.1);
}
#loginModal .login-box .pw-field {
  position: relative;
  margin-bottom: 10px;
}
#loginModal .login-box .pw-field input {
  padding-right: 40px;
  margin-bottom: 0;
}
#loginModal .login-box .pw-toggle {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: 36px;
  display: flex; align-items: center; justify-content: center;
  background: none; border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 0;
}
#loginModal .login-box .pw-toggle:hover { color: var(--text-primary); }
#loginModal .login-box .pw-toggle .icon-svg { width: 18px; height: 18px; }
#loginModal .login-box .auth-btn {
  width: 100%; padding: 10px;
  background: var(--accent-grad);
  border: none;
  border-radius: var(--radius-sm);
  color: #fff;
  font-weight: 700; font-size: 16px;
  cursor: pointer;
  font-family: 'Inter', sans-serif;
  transition: var(--transition);
}
#loginModal .login-box .auth-btn:hover {
  transform: scale(1.02);
  box-shadow: 0 4px 20px rgba(139,92,246,0.3);
}
#loginModal .login-box .toggle-text {
  margin-top: 12px; font-size: 13px;
  color: var(--text-secondary);
  text-align: center;
}
#loginModal .login-box .toggle-text a {
  color: var(--accent-1);
  cursor: pointer;
  font-weight: 600;
}
#loginModal .login-box .toggle-text a:hover { text-decoration: underline; }
#loginModal .login-box .auth-error {
  color: #f87171; font-size: 13px;
  margin-top: 8px; text-align: center;
  min-height: 20px;
}
#loginModal .login-box .auth-error.success {
  color: #34d399;
}
/* Retriggered (class removed/reflowed/re-added) on every setError() call, even
   when the message text is unchanged - two identical "Invalid credentials"
   errors in a row otherwise look like the Log In click did nothing. */
#loginModal .login-box .auth-error.flash {
  animation: authErrorFlash 0.4s ease;
}
@keyframes authErrorFlash {
  0% { transform: translateX(0); }
  25% { transform: translateX(-5px); }
  50% { transform: translateX(5px); }
  75% { transform: translateX(-3px); }
  100% { transform: translateX(0); }
}
#loginModal .login-box .auth-subtext {
  color: var(--text-secondary);
  font-size: 13px;
  line-height: 1.5;
  margin-bottom: 14px;
}
#loginModal .login-box .auth-subtext strong {
  color: var(--text-primary);
}
#loginModal .login-box .auth-subtext-muted {
  color: var(--text-muted);
  font-size: 12px;
  margin-top: -6px;
}
#loginModal .login-box .auth-subtext a {
  color: var(--accent-1);
  font-weight: 600;
  text-decoration: none;
}
#loginModal .login-box .auth-subtext a:hover { text-decoration: underline; }

/* ----- Launch gate modal (Website/JS/launch-gate.js) -----
   Same look as #loginModal above, kept as its own rule set (rather than a
   combined selector) since it only needs a subset - no password fields. */
#launchGateModal {
  display: none;
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.7);
  backdrop-filter: blur(12px);
  z-index: 1001;
  justify-content: center; align-items: center;
}
#launchGateModal.show { display: flex; }
#launchGateModal .login-box {
  background: var(--bg-secondary);
  padding: 32px;
  border-radius: var(--radius-lg);
  max-width: 380px; width: 90%;
  box-shadow: var(--shadow-card), var(--shadow-glow);
  border: 1px solid var(--border-glass-strong);
  position: relative;
}
#launchGateModal .login-box h2 {
  font-family: 'Nunito', sans-serif;
  margin-bottom: 16px;
  color: var(--text-primary);
}
#launchGateModal .login-box input[type="email"] {
  width: 100%; padding: 10px; margin-bottom: 10px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-glass);
  background: var(--bg-card);
  color: var(--text-primary);
  font-family: 'Inter', sans-serif;
  font-size: 14px;
  transition: var(--transition);
}
#launchGateModal .login-box input[type="email"]:focus {
  border-color: var(--accent-2);
  outline: none;
  box-shadow: 0 0 20px rgba(139,92,246,0.1);
}
#launchGateModal .login-box .preorder-row {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--text-secondary);
  margin-bottom: 14px; cursor: pointer;
}
#launchGateModal .login-box .preorder-row input { margin: 0; }
#launchGateModal .login-box .auth-btn {
  width: 100%; padding: 10px;
  background: var(--accent-grad);
  border: none;
  border-radius: var(--radius-sm);
  color: #fff;
  font-weight: 700; font-size: 16px;
  cursor: pointer;
  font-family: 'Inter', sans-serif;
  transition: var(--transition);
}
#launchGateModal .login-box .auth-btn:hover {
  transform: scale(1.02);
  box-shadow: 0 4px 20px rgba(139,92,246,0.3);
}
#launchGateModal .login-box .auth-btn:disabled { opacity: 0.6; cursor: default; transform: none; }
#launchGateModal .login-box .auth-error {
  color: #f87171; font-size: 13px;
  margin-top: 8px; text-align: center;
  min-height: 20px;
}
#launchGateModal .login-box .auth-subtext {
  color: var(--text-secondary);
  font-size: 13px;
  line-height: 1.5;
  margin-bottom: 14px;
}
#launchGateModal .login-box .auth-subtext strong {
  color: var(--text-primary);
}

/* ----- Scrollbars ----- */
::-webkit-scrollbar { width: 4px; height: 4px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.08); border-radius: 10px; }
::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.15); }
[data-theme="light"] ::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.08); }
[data-theme="light"] ::-webkit-scrollbar-thumb:hover { background: rgba(0,0,0,0.15); }
* { scrollbar-width: thin; scrollbar-color: rgba(255,255,255,0.08) transparent; }
[data-theme="light"] * { scrollbar-color: rgba(0,0,0,0.08) transparent; }

/* ----- Bottom Bar ----- */
#bottom-bar {
  width: 100%;
  max-width: 1300px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 18px;
  background: var(--bg-card);
  backdrop-filter: blur(20px);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card), var(--shadow-glow);
  flex-shrink: 0;
  gap: 10px;
  margin-top: 6px;
  transition: background var(--transition), border var(--transition), box-shadow var(--transition);
  min-height: 48px;
  flex-wrap: nowrap;
  position: relative;
}
#bottom-left {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
#bottom-left label {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  color: var(--text-muted);
  font-weight: 500;
  white-space: nowrap;
}
#bottom-left label span {
  color: var(--text-secondary);
  font-weight: 600;
}
#bottom-left select {
  background: var(--select-bg) !important;
  color: var(--select-text) !important;
  border: 1px solid var(--select-border) !important;
  border-radius: var(--radius-sm) !important;
  padding: 2px 6px !important;
  font-size: 11px !important;
  font-weight: 500 !important;
  font-family: 'Inter', sans-serif !important;
  cursor: pointer !important;
  outline: none !important;
  transition: var(--transition) !important;
  appearance: auto !important;
  min-height: 26px !important;
}
#bottom-left select#scale-root {
  min-width: 48px;
  max-width: 60px;
}
#bottom-left select#scale-type {
  min-width: 110px;
  max-width: 140px;
}
#bottom-left select:hover {
  border-color: var(--accent-1) !important;
  background: var(--select-hover-bg) !important;
}
#bpm-display {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-secondary);
  padding: 0 6px;
  min-width: 46px;
  text-align: center;
  white-space: nowrap;
}

/* ----- Controls (centered) ----- */
#controls {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  gap: 4px;
  background: transparent;
  padding: 0 4px;
  border-radius: var(--radius-sm);
  z-index: 1;
}
#controls .icon-btn {
  background: transparent;
  border: none;
  color: var(--text-secondary);
  cursor: pointer;
  padding: 4px 4px;
  border-radius: var(--radius-sm);
  transition: var(--transition);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  min-width: 28px;
  min-height: 28px;
}
#controls .icon-btn:hover:not(:disabled) {
  color: var(--text-primary);
  background: var(--bg-card-hover);
  transform: translateY(-1px);
}
#controls .icon-btn:disabled {
  opacity: 0.25;
  cursor: not-allowed;
  transform: none !important;
}
#controls .icon-btn .icon-svg {
  --icon-size: 18px;
}
#playBtn .icon-svg {
  --icon-size: 26px;
}
#chord-display {
  background: rgba(245, 158, 11, 0.08);
  border: 1px solid rgba(245, 158, 11, 0.15);
  border-radius: 30px;
  padding: 0 14px;
  font-size: 15px;
  font-weight: 700;
  color: var(--accent-1);
  min-width: 54px;
  text-align: center;
  font-family: 'Inter', sans-serif;
  letter-spacing: -0.3px;
  transition: var(--transition);
  line-height: 28px;
  height: 28px;
  white-space: nowrap;
}
.hide-modules-btn {
  background: var(--bg-card);
  border: 1px solid var(--border-glass);
  border-radius: 30px;
  color: var(--text-secondary);
  cursor: pointer;
  padding: 0 12px;
  font-size: 11px;
  font-weight: 500;
  font-family: 'Inter', sans-serif;
  transition: var(--transition);
  display: flex;
  align-items: center;
  gap: 4px;
  height: 28px;
  line-height: 1;
  white-space: nowrap;
}
.hide-modules-btn:hover {
  border-color: var(--border-glass-strong);
  color: var(--text-primary);
  background: var(--bg-card-hover);
  transform: translateY(-1px);
}
.hide-modules-btn .icon-svg {
  --icon-size: 14px;
}
.hide-modules-btn #hideModulesLabel {
  font-size: 10px;
  font-weight: 600;
}
#bottom-right {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
#bottom-right button {
  background: var(--bg-card);
  border: 1px solid var(--border-glass);
  border-radius: 30px;
  color: var(--text-secondary);
  cursor: pointer;
  padding: 0 14px;
  font-size: 11px;
  font-weight: 500;
  font-family: 'Inter', sans-serif;
  transition: var(--transition);
  display: flex;
  align-items: center;
  gap: 4px;
  height: 28px;
  line-height: 1;
  white-space: nowrap;
}
#bottom-right button:hover {
  border-color: var(--border-glass-strong);
  color: var(--text-primary);
  background: var(--bg-card-hover);
  transform: translateY(-1px);
}
#bottom-right button .icon-svg {
  --icon-size: 14px;
}

/* ----- Back Button (themed) ----- */
.back-btn {
  appearance: none;
  -webkit-appearance: none;
  font-family: inherit;
  background: var(--bg-card);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  padding: 4px 8px;
  cursor: pointer;
  transition: var(--transition);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  line-height: 1;
  min-width: 32px;
  min-height: 32px;
}
.back-btn:hover {
  border-color: var(--border-glass-strong);
  color: var(--text-primary);
  background: var(--bg-card-hover);
  transform: translateY(-1px) scale(1.02);
}
.back-btn .icon-svg {
  --icon-size: 18px;
}

/* ----- Responsive ----- */
@media (max-width: 820px) {
  #bottom-bar { flex-wrap: wrap; justify-content: center; gap: 6px 12px; padding: 6px 14px; border-radius: 30px; min-height: 44px; }
  #bottom-left label span { display: none; }
  #bottom-left select#scale-root { min-width: 40px; max-width: 50px; }
  #bottom-left select#scale-type { min-width: 90px; max-width: 110px; }
  #bpm-display { font-size: 11px; min-width: 38px; }
  #controls .icon-btn { font-size: 16px; min-width: 24px; min-height: 24px; }
  #controls .icon-btn .icon-svg { --icon-size: 16px; }
  #playBtn .icon-svg { --icon-size: 22px; }
  #chord-display { font-size: 13px; min-width: 44px; padding: 0 10px; line-height: 24px; height: 24px; }
  .hide-modules-btn { font-size: 10px; padding: 0 10px; height: 24px; }
  .hide-modules-btn #hideModulesLabel { font-size: 9px; }
  #bottom-right button { font-size: 10px; padding: 0 10px; height: 24px; }
  #bottom-right button .icon-svg { --icon-size: 13px; }
}
@media (max-width: 540px) {
  /* 2 rows instead of 3: Key/Scale/BPM share row 1 with the overlay toggle
     (pushed to the far right), and the playback transport gets its own
     full-width row below instead of every group getting a whole row to
     itself with empty space on either side. */
  #bottom-bar { flex-wrap: wrap; align-items: center; gap: 4px; padding: 6px 10px; border-radius: 24px; min-height: auto; }
  #bottom-left { flex: 1 1 auto; justify-content: flex-start; gap: 4px; }
  #bottom-right { flex: 0 0 auto; margin-left: auto; }
  #controls { flex: 1 1 100%; gap: 2px; position: relative; left: auto; top: auto; transform: none; width: 100%; justify-content: center; }
  #bottom-left label span { display: none; }
  #bottom-left select#scale-root { min-width: 36px; max-width: 44px; font-size: 9px !important; padding: 1px 3px !important; min-height: 22px !important; }
  #bottom-left select#scale-type { min-width: 80px; max-width: 100px; font-size: 9px !important; padding: 1px 3px !important; min-height: 22px !important; }
  #controls .icon-btn { font-size: 14px; min-width: 22px; min-height: 22px; padding: 2px; }
  #controls .icon-btn .icon-svg { --icon-size: 14px; }
  #playBtn .icon-svg { --icon-size: 20px; }
  #chord-display { font-size: 12px; min-width: 38px; padding: 0 8px; line-height: 20px; height: 20px; }
  .hide-modules-btn { font-size: 9px; padding: 0 8px; height: 22px; }
  .hide-modules-btn #hideModulesLabel { font-size: 8px; }
  #bottom-right button { font-size: 9px; padding: 0 8px; height: 22px; }
  #bottom-right button .icon-svg { --icon-size: 12px; }
}
@media (max-width: 768px) {
  .header { padding: 6px 12px; border-radius: var(--radius-md); }
  /* Header collapses to 2 rows: brand/instrument + action icons share row 1,
     status pill moves to its own full-width row below. Desktop's grid-area
     assignment on .header-left/.header-status/.header-actions is unaffected
     by this — only the template (columns/areas) changes per breakpoint. */
  .header {
    grid-template-columns: 1fr auto;
    grid-template-areas: "left actions" "status status";
    row-gap: 4px;
  }
  .brand-name { display: none; }
  .header-actions { gap: 4px; }
  .header-btn .label-text { display: none; }
  .header-btn { padding: 4px 8px; }
  .header-status { max-width: 100%; font-size: 10px; padding: 2px 12px; min-height: 24px; }
  #instrumentSelect { font-size: 10px; padding: 2px 8px; height: 26px; max-width: 130px; }
  #bottom-left label { font-size: 10px; }
  #bottom-left select { font-size: 10px; }
  #bpm-display { font-size: 10px; padding: 2px 10px; min-width: 44px; }
  #bottom-right button { font-size: 10px; padding: 3px 12px; height: 26px; }
  #controls .icon-btn { font-size: 18px; }
  #playBtn .icon-svg { --icon-size: 24px; }
  #chord-display { min-width: 50px; font-size: 15px; padding: 1px 8px; }
  #visual-controls { gap: 8px; }
  .control-item { font-size: 11px; padding: 4px 12px; min-height: 36px; }
  .eye-btn .icon-svg { --icon-size: 16px; }
  #page-ai-teacher .ai-layout { flex-direction: column; }
  #page-ai-teacher .ai-chat { min-height: 200px; }
  .tool-nav .page-title { font-size: 14px; }
  .theme-toggle-btn .label-text { display: none; }
  .theme-toggle-btn { padding: 4px 8px; }
  #settings-panel { width: 280px; padding: 24px 20px; }
  /* Bumped from 26px now that the header row only carries Credits/Profile/
     More - there's room for a real touch target, not just a smaller icon. */
  .profile-btn { width: 40px; height: 40px; }
  .profile-btn .icon-svg { --icon-size: 20px; }
  #page-tools .tools-grid { grid-template-columns: 1fr; }

  /* "More" dropdown: Getting Started / Recently Played / Theme / Settings.
     Same recipe as .profile-dropdown (position/colors/shadow/open toggle)
     so it reads as the same kind of menu, just anchored under a different
     button. */
  .header-more-group {
    display: none;
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    background: var(--bg-secondary);
    border: 1px solid var(--border-glass-strong);
    border-radius: var(--radius-md);
    padding: 8px;
    min-width: 200px;
    max-width: calc(100vw - 24px);
    box-shadow: var(--shadow-card), var(--shadow-glow);
    backdrop-filter: blur(20px);
    z-index: 300;
    flex-direction: column;
    gap: 2px;
  }
  .header-more-group.open { display: flex; }
  .header-more-group .header-btn,
  .header-more-group .theme-toggle-btn,
  .header-more-group .icon-btn {
    width: 100%;
    min-height: 44px;
    padding: 10px 12px;
    border: none;
    border-radius: 8px;
    justify-content: flex-start;
    gap: 10px;
  }
  .header-more-group .label-text { display: inline !important; font-size: 13px; }
  .header-more-group .icon-svg { --icon-size: 18px; }

  /* Its own ~44px circular trigger, matching Profile's shape language. */
  #moreBtn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    min-width: 44px;
    min-height: 44px;
    padding: 0;
    border-radius: 50%;
  }
  #moreBtn.open {
    border-color: var(--border-glass-strong);
    color: var(--text-primary);
    background: var(--bg-card-hover);
  }
}
@media (max-width: 480px) {
  body { padding: 4px 8px; }
  .header { gap: 6px; }
  .header-status { font-size: 9px; padding: 2px 10px; min-height: 22px; max-width: 100%; }
  #instrumentSelect { max-width: 92px; font-size: 9px; }
  .header-actions { gap: 3px; }
  .header-actions .icon-btn { padding: 4px 6px; }
  #settings-panel { width: 90vw; padding: 20px 16px; }
  #chord-display { min-width: 40px; font-size: 14px; padding: 1px 6px; }
  /* Profile stays the 40px size set at 768px - the header row only has
     Credits/Profile/More left at this width, so there's no need to shrink
     it further just because the viewport got narrower. */
  .string-tuning-list { grid-template-columns: 1fr; }
}

/* ----- Downloads dropdown with progress ----- */
.download-item .cancel-download-btn {
  background: none;
  border: none;
  color: #f87171;
  cursor: pointer;
  font-size: 14px;
  padding: 0 4px;
  transition: transform 0.2s;
}
.download-item .cancel-download-btn:hover {
  transform: scale(1.2);
}
.download-item .title {
  font-weight: 600;
  font-size: 13px;
  color: var(--text-primary);
}
.download-item .status {
  font-size: 11px;
  color: var(--text-muted);
}
.download-item .progress-bar {
  width: 100%;
  height: 4px;
  background: var(--bg-card);
  border-radius: 2px;
  margin-top: 4px;
  overflow: hidden;
}
.download-item .progress-bar .fill {
  height: 100%;
  background: var(--accent-grad);
  border-radius: 2px;
  transition: width 0.3s ease;
}

/* Downloads dropdown with progress */
.download-item .progress-bar {
  width: 100%;
  height: 4px;
  background: var(--bg-card);
  border-radius: 2px;
  margin-top: 4px;
  overflow: hidden;
}
.download-item .progress-bar .fill {
  height: 100%;
  background: var(--accent-grad);
  border-radius: 2px;
  transition: width 0.3s ease;
}
.cancel-download-btn {
  background: none;
  border: none;
  color: #f87171;
  cursor: pointer;
  font-size: 14px;
  padding: 0 4px;
  transition: transform 0.2s;
}
.cancel-download-btn:hover {
  transform: scale(1.2);
}
/* ============================================================
   RESPONSIVE LAYOUT — phones & small tablets
   The desktop UI is a fixed-viewport "app shell": html/body are locked to
   100vh with overflow hidden and each panel scrolls internally. On a phone
   that leaves almost no room for page content once the header, board,
   controls and bars are stacked, and the 4:1 fretboard gets crushed to an
   unreadable sliver. Below 768px we switch to natural document scroll and
   make the wide fretboard horizontally swipeable at a legible size.
   ============================================================ */
@media (max-width: 768px) {
  /* Unlock the viewport height so the whole document scrolls as one. Only
     <html> scrolls: putting overflow on <body> as well would make it a second,
     non-window scroll container and swallow normal page scrolling. */
  html { height: auto; overflow-x: hidden; overflow-y: auto; }
  body { height: auto; min-height: 100dvh; overflow: visible; padding: 6px 8px 12px; }

  #page-container { flex: 0 0 auto; max-width: 100%; }
  #pages-wrapper { flex: 0 0 auto; overflow: visible; }
  #pages-wrapper #pages,
  #pages { height: auto; overflow: visible; }
  .page { height: auto; overflow: visible; }

  /* Fretboard: keep the 4:1 ratio but never shrink below a legible width;
     the wrapper scrolls it horizontally and the fret-number strip scrolls
     in lockstep (matching min-width keeps the two aligned). */
  #global-board { overflow: visible; }
  #fretboard-canvas-wrapper {
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    border-radius: inherit;
  }
  #fretboard-canvas-wrapper canvas { min-width: 680px; }
  #fret-numbers { min-width: 680px; padding-left: 46px; padding-right: 34px; }

  /* Hero + tiles: 2 columns instead of a fixed 4 that ran off-screen. */
  #page-home { gap: 18px; padding: 12px 6px; }
  #homeSecondaryGroups { gap: 18px; }
  .home-title { font-size: 30px; gap: 10px; letter-spacing: -0.5px; }
  .home-title .logo-big { width: 38px; height: 38px; }
  .home-subtitle { font-size: 14px; }
  .home-grid { grid-template-columns: repeat(2, 1fr); gap: 12px; max-width: 100%; }
  .home-tile { min-height: 118px; padding: 18px 12px; }
  .home-tile .name { font-size: 15px; }
  .home-tile .desc { font-size: 11px; }

  /* Continue strip: the default 220px chip min-width forces one per row on
     a phone even though two fit fine once it's this tight. */
  .home-continue-chip { min-width: 150px; padding: 10px 12px; }

  /* First-visit guided intro: same "trim the box, not the content" move
     the homepage popup's own ≤480px override already makes. */
  .onboarding-box { padding: 20px 16px; }
  .onboarding-choice { padding: 12px 14px; }

  /* Board controls: Chord/Pentatonic/Modal always stay on one row (their
     text shrinks/truncates before they're allowed to wrap); Stems, being a
     4th and much wider item, gets its own row underneath. */
  #visual-controls { gap: 6px; margin: 6px auto 2px; row-gap: 6px; }
  .control-item { justify-content: center; }
  .control-item:not(.stem-control) { flex: 1 1 0; min-width: 0; padding: 6px 8px; gap: 6px; font-size: 10px; }
  .control-item:not(.stem-control) .label { font-size: 8.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .control-item .chord-name { font-size: 12px; min-width: 20px; }
  .stem-control { flex: 1 1 100%; }

  /* Backing-track upload row: a clean vertical stack instead of the file
     picker + mode toggle wrapping onto one line and stranding the Load
     button alone on the next. */
  .local-upload-area .upload-row { flex-direction: column; align-items: stretch; }
  .local-upload-area .upload-row input[type="file"] { width: 100%; }
  .local-upload-area .upload-row .analysis-mode-toggle { width: 100%; }
  .local-upload-area .upload-row .analysis-mode-btn { flex: 1; }
  .local-upload-area .upload-row .stems-toggle-btn { width: 100%; }
  .local-upload-area .upload-row #localLoadBtn,
  .local-upload-area .upload-row #localCancelBtn { width: 100%; justify-content: center; }
}

/* Narrow phones: a touch more scroll room, tiles stay two-up. */
@media (max-width: 430px) {
  #fretboard-canvas-wrapper canvas,
  #fret-numbers { min-width: 620px; }
  .home-title { font-size: 26px; }
}

/* ============================================================
   MOBILE LANDSCAPE — phones only (short viewport, wide aspect).
   Gated on height, not width: a rotated phone is anywhere from
   568-932px wide, but what actually matters is that it's short
   (<=500px tall). The header stays fixed to the TOP edge (same
   as every other breakpoint - only its internal layout changes),
   restructured as a 3-column/2-row grid: logo | select | actions
   on row 1 (select and the header's action buttons in line with
   each other), then the notifier spanning the full width on row
   2 beneath both. The logo is a direct grid item (promoted out of
   its .header-left wrapper via `display:contents`, since a nested
   wrapper couldn't independently span rows) spanning both rows -
   its height equals the header's full combined height. The
   playback bar is a separate, simpler fixed dock pinned to the
   bottom edge - it doesn't need to coordinate with the logo at
   all since the logo lives up top.
   ============================================================ */
@media (orientation: landscape) and (max-height: 500px) and (max-width: 950px) {
  :root {
    --mm-ls-logo-w: 50px;
    --mm-ls-row1: 38px;
    --mm-ls-notifier: 26px;
    --mm-ls-bb-h: 40px;
  }

  html { height: auto; overflow-x: hidden; overflow-y: auto; }
  body {
    height: auto;
    min-height: 100dvh;
    overflow: visible;
    padding: calc(var(--mm-ls-row1) + var(--mm-ls-notifier) + env(safe-area-inset-top) + 10px)
      calc(8px + env(safe-area-inset-right))
      calc(var(--mm-ls-bb-h) + env(safe-area-inset-bottom) + 10px)
      calc(8px + env(safe-area-inset-left));
  }

  #page-container { flex: 0 0 auto; max-width: 100%; }
  #pages-wrapper { flex: 0 0 auto; overflow: visible; }
  #pages-wrapper #pages,
  #pages { height: auto; overflow: visible; }
  .page { height: auto; overflow: visible; }

  /* ---- Header: fixed to the top, restructured as a grid ---- */
  .header {
    position: fixed;
    left: 0; right: 0; top: 0; bottom: auto;
    width: 100%;
    max-width: none;
    /* Box extends the extra safe-area amount and absorbs it as top
       padding, rather than offsetting the whole box down via `top` -
       that way the header's own background/border reaches the true top
       edge (covering behind a notch/status bar) instead of leaving a
       gap that shows the page background through. */
    height: calc(var(--mm-ls-row1) + var(--mm-ls-notifier) + env(safe-area-inset-top));
    margin: 0;
    display: grid;
    grid-template-columns: var(--mm-ls-logo-w) auto 1fr;
    grid-template-rows: var(--mm-ls-row1) var(--mm-ls-notifier);
    grid-template-areas: "logo select actions" "logo status status";
    row-gap: 0; column-gap: 8px;
    align-items: stretch;
    padding: env(safe-area-inset-top) calc(8px + env(safe-area-inset-right)) 0 env(safe-area-inset-left);
    border-radius: 0;
    border-left: none; border-right: none; border-top: none;
    box-shadow: none;
    backdrop-filter: none;
    z-index: 60;
  }
  /* Unwraps header-left so its children (logo, select) become direct grid
     items of .header - a nested wrapper couldn't independently span rows. */
  .header-left { display: contents; }
  .brand-wrapper {
    grid-area: logo;
    width: 100%; height: 100%;
    justify-content: center;
  }
  .brand-name { display: none; }
  .brand-icon { width: 24px; height: 24px; }
  #instrumentSelect {
    grid-area: select;
    align-self: center;
    max-width: 140px; height: 26px !important; font-size: 10px !important;
    padding: 0 6px !important; min-height: 26px !important;
  }
  .header-actions {
    grid-area: actions;
    align-self: center;
    justify-content: flex-end;
    flex-wrap: nowrap;
    gap: 3px;
    overflow-x: auto;
  }
  /* This row spans nearly the full screen width here (only the logo
     column is lost), so unlike the narrower <=768px portrait breakpoint
     there's always room to keep Tutorial/Recently Played/Theme/Settings
     inline instead of collapsing them behind a "More" button - this rule
     comes after that breakpoint's in source order, so it wins whenever
     both apply (a narrow phone rotated to landscape). */
  .header-more-group { display: contents; }
  #moreBtn { display: none; }
  /* Width/justify-content/gap reset: the pre-existing <=768px breakpoint
     styles these buttons for the vertical dropdown PANEL (width:100%,
     10px icon-label gap) with no `.open` guard, so it's active whenever
     a phone is narrow enough in landscape too (<=768px wide) - unreset,
     each button fights for 100% of this row instead of sizing to its
     icon. */
  .header-more-group .header-btn,
  .header-more-group .theme-toggle-btn,
  .header-more-group .icon-btn {
    width: auto;
    min-height: 26px;
    height: 26px;
    padding: 4px 6px;
    justify-content: center;
    gap: 0;
  }
  .header-more-group .label-text,
  .theme-toggle-btn .label-text { display: none !important; }
  .header-more-group .icon-svg { --icon-size: 15px; }
  .profile-btn { width: 24px; height: 24px; }
  .profile-btn .icon-svg { --icon-size: 14px; }
  #creditChip { height: 22px; padding: 0 8px; font-size: 10px; }

  /* ---- Notifier: full width, below the select + action buttons ---- */
  .header-status {
    grid-area: status;
    width: 100%; max-width: none;
    height: var(--mm-ls-notifier);
    min-height: var(--mm-ls-notifier);
    margin: 0;
    background: transparent;
    border: none;
    border-top: 1px solid var(--border-glass);
    border-radius: 0;
    box-shadow: none;
    backdrop-filter: none;
    justify-content: center;
    padding: 0 4px;
    font-size: 10px;
  }
  .header-status .icon-svg { --icon-size: 12px; }

  /* ---- Playback bar: independent fixed dock at the bottom edge ---- */
  #bottom-bar {
    position: fixed;
    left: 0; right: 0; top: auto; bottom: 0;
    width: 100%;
    max-width: none;
    /* Same reasoning as the header: box extends the extra safe-area
       amount and absorbs it as bottom padding, rather than offsetting
       the whole box up via `bottom` - keeps the bar's own background
       flush against the true bottom edge (covering behind the home
       indicator) instead of a gap showing the page background through. */
    height: calc(var(--mm-ls-bb-h) + env(safe-area-inset-bottom));
    min-height: calc(var(--mm-ls-bb-h) + env(safe-area-inset-bottom));
    margin: 0;
    border-radius: 0;
    border: none;
    border-top: 1px solid var(--border-glass);
    box-shadow: none;
    padding: 0 calc(8px + env(safe-area-inset-right)) env(safe-area-inset-bottom) calc(8px + env(safe-area-inset-left));
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    grid-template-rows: var(--mm-ls-bb-h);
    align-items: center;
    gap: 6px;
    z-index: 60;
    overflow-x: auto;
    overflow-y: hidden;
  }
  /* A 3-column grid (not flex justify-content:space-between) so #controls
     sits in its own content-sized middle column and stays genuinely
     centered regardless of how much wider #bottom-left is than
     #bottom-right - space-between centers only when both flanks match. */
  #bottom-left, #bottom-right, #controls {
    position: static;
    left: auto; top: auto; transform: none;
    display: flex;
    align-items: center;
    gap: 4px;
  }
  /* Explicit grid-column AND grid-row, not source order/auto-placement:
     the DOM has #bottom-left then #bottom-right then #controls, but
     visually the transport belongs in the middle with chord+eye-toggle
     on the right, same as every other breakpoint. Auto-placement would
     otherwise put #bottom-right in the middle column just because it
     comes second in the markup, and (observed in testing) pushed
     #controls into an implicit second row instead of row 1 - pinning
     grid-row:1 on all three avoids relying on placement order at all. */
  #bottom-left { grid-column: 1; grid-row: 1; justify-self: start; }
  #controls { grid-column: 2; grid-row: 1; justify-self: center; }
  #bottom-right { grid-column: 3; grid-row: 1; justify-self: end; }
  #bottom-left label span { display: none; }
  #bottom-left select { min-height: 28px !important; font-size: 10px !important; padding: 0 5px !important; }
  #bottom-left select#scale-root { min-width: 36px; max-width: 40px; }
  #bottom-left select#scale-type { min-width: 68px; max-width: 78px; }
  #bpm-display { font-size: 10px; min-width: 32px; }
  #chord-display { height: 26px; line-height: 26px; font-size: 11px; min-width: 34px; padding: 0 8px; }
  #toggleOverlayBtn, .hide-modules-btn { height: 28px; padding: 0 8px; }
  #toggleOverlayBtn .btn-label,
  .hide-modules-btn #hideModulesLabel { display: none; }
  #controls .icon-btn { min-width: 32px; min-height: 32px; font-size: 16px; padding: 2px; }
  #controls .icon-btn .icon-svg { --icon-size: 17px; }
  #controls #playBtn { min-width: 38px; min-height: 38px; }
  #controls #playBtn .icon-svg { --icon-size: 20px; }

  .onboarding-soft-banner {
    bottom: calc(var(--mm-ls-bb-h) + env(safe-area-inset-bottom) + 14px);
  }
}

/* ============================================================
   MOBILE PORTRAIT — pin the header and playback bar to the true
   top/bottom edges instead of scrolling with the page, and slim
   both down to a single compact row apiece instead of the old
   wrap-heavy layout (header collapsing extra buttons behind a
   "More" toggle, bottom bar wrapping to two rows below 540px).
   Same techniques as the landscape dock above: explicit row
   heights so it isn't fragile against content/font changes, a
   3-column grid for the bottom bar so the transport stays
   genuinely centered, and each box's own height absorbing the
   safe-area inset as padding so it's flush with the true edge
   instead of leaving a gap.
   ============================================================ */
@media (orientation: portrait) and (max-width: 768px) {
  :root {
    --mm-pt-row1: 40px;
    --mm-pt-notifier: 26px;
    --mm-pt-bb-h: 44px;
  }

  html { height: auto; overflow-x: hidden; overflow-y: auto; }
  body {
    height: auto;
    min-height: 100dvh;
    overflow: visible;
    padding-top: calc(var(--mm-pt-row1) + var(--mm-pt-notifier) + env(safe-area-inset-top) + 10px);
    padding-bottom: calc(var(--mm-pt-bb-h) + env(safe-area-inset-bottom) + 10px);
  }

  #page-container { flex: 0 0 auto; max-width: 100%; }
  #pages-wrapper { flex: 0 0 auto; overflow: visible; }
  #pages-wrapper #pages,
  #pages { height: auto; overflow: visible; }
  .page { height: auto; overflow: visible; }

  /* ---- Header: single compact row (logo+select+actions), notifier below ---- */
  .header {
    position: fixed;
    left: 0; right: 0; top: 0; bottom: auto;
    width: 100%;
    max-width: none;
    height: calc(var(--mm-pt-row1) + var(--mm-pt-notifier) + env(safe-area-inset-top));
    margin: 0;
    /* auto/1fr, not 1fr/auto: .header-left's content (logo+select) is
       small and fixed, .header-actions' six buttons need the rest of the
       width. Both also need min-width:0 below - a grid track otherwise
       refuses to shrink below its content's natural width, which was
       blowing the "left" column out to just 2px to make room for
       actions' full unshrunk content instead of letting actions itself
       degrade to internal horizontal scroll. */
    grid-template-columns: auto 1fr;
    grid-template-rows: var(--mm-pt-row1) var(--mm-pt-notifier);
    grid-template-areas: "left actions" "status status";
    row-gap: 0; column-gap: 6px;
    padding: calc(env(safe-area-inset-top)) calc(10px + env(safe-area-inset-right)) 0 calc(10px + env(safe-area-inset-left));
    border-radius: 0;
    border-left: none; border-right: none; border-top: none;
    z-index: 60;
  }
  .header-left { min-width: 0; gap: 6px; }
  .brand-icon { width: 26px; height: 26px; }
  #instrumentSelect { max-width: 100px; height: 26px !important; font-size: 10px !important; padding: 0 6px !important; min-height: 26px !important; }
  .header-actions { min-width: 0; align-self: center; justify-content: flex-end; flex-wrap: nowrap; gap: 2px; overflow-x: auto; }
  /* Same reasoning as the landscape dock: this row has enough width for
     all six action buttons inline, so there's no need to collapse
     Tutorial/Recently Played/Theme/Settings behind a "More" button - this
     rule is later in the stylesheet than the plain <=768px breakpoint
     that does the collapsing, so it wins. */
  .header-more-group { display: contents; }
  #moreBtn { display: none; }
  /* Width/justify-content/gap/border-radius reset: the pre-existing
     <=768px breakpoint styles these buttons for the vertical dropdown
     PANEL (width:100%, left-aligned label, 10px icon-label gap) - that
     rule has no `.open` guard, so it's active unconditionally, not just
     while the panel is open. Left unreset, each button fights for 100%
     of this row instead of sizing to its icon. */
  .header-more-group .header-btn,
  .header-more-group .theme-toggle-btn,
  .header-more-group .icon-btn {
    width: auto;
    min-height: 26px;
    height: 26px;
    padding: 4px 5px;
    justify-content: center;
    gap: 0;
    border-radius: var(--radius-sm, 6px);
  }
  .header-more-group .label-text,
  .theme-toggle-btn .label-text { display: none !important; }
  .header-more-group .icon-svg { --icon-size: 15px; }
  .profile-btn { width: 24px; height: 24px; }
  .profile-btn .icon-svg { --icon-size: 14px; }
  #creditChip { height: 22px; padding: 0 7px; font-size: 10px; }
  .header-status {
    grid-area: status;
    width: 100%; max-width: none;
    height: var(--mm-pt-notifier);
    min-height: var(--mm-pt-notifier);
    margin: 0;
    background: transparent;
    border: none;
    border-top: 1px solid var(--border-glass);
    border-radius: 0;
    box-shadow: none;
    backdrop-filter: none;
    justify-content: center;
    padding: 0 2px;
    font-size: 10px;
  }
  .header-status .icon-svg { --icon-size: 12px; }

  /* ---- Playback bar: single row, transport centered ---- */
  #bottom-bar {
    position: fixed;
    left: 0; right: 0; top: auto; bottom: 0;
    width: 100%;
    max-width: none;
    margin: 0;
    height: calc(var(--mm-pt-bb-h) + env(safe-area-inset-bottom));
    min-height: calc(var(--mm-pt-bb-h) + env(safe-area-inset-bottom));
    padding: 0 calc(10px + env(safe-area-inset-right)) env(safe-area-inset-bottom) calc(10px + env(safe-area-inset-left));
    display: grid;
    /* `auto 1fr auto`, not `1fr auto 1fr`. Symmetric side tracks are what
       centre the transport exactly, but they also force both flanks to the
       SAME width - and the two flanks are not the same size. #bottom-left
       (key select + scale select + tempo) needs ~99px; #bottom-right (chord
       readout + overlay toggle) needs ~70px. At 375px each 1fr track resolved
       to 91px, so the right flank sat on 21px it didn't need while the left
       flank was 8px short and cut the tempo readout in half - measured, not
       assumed. Sizing the flanks to their content and letting the MIDDLE track
       absorb the slack fits everything at 375 with room to spare.
       The trade: the transport is now centred in the leftover space rather
       than in the viewport, so it sits a few px right of true centre once the
       flanks differ. Accepted deliberately - an unreadable tempo is a real
       problem, a barely-perceptible offset is not. The middle track keeps
       `1fr` (= minmax(auto, 1fr)) and #controls deliberately has no
       `min-width: 0`, so the track can never shrink below the transport's own
       min-content width: under extreme narrowness the bar overflows into its
       own overflow-x scroll rather than squeezing the play button. */
    grid-template-columns: auto 1fr auto;
    grid-template-rows: var(--mm-pt-bb-h);
    align-items: center;
    gap: 4px;
    border-radius: 0;
    border-left: none; border-right: none; border-bottom: none;
    box-shadow: none;
    z-index: 60;
    overflow-x: auto;
    overflow-y: hidden;
  }
  #bottom-left, #bottom-right, #controls {
    flex: 0 0 auto;
    position: static;
    left: auto; top: auto; transform: none;
    display: flex;
    align-items: center;
    gap: 3px;
  }
  /* #bottom-left/#bottom-right sit in "1fr" tracks and need min-width:0 to
     actually be allowed to shrink below their content's natural width
     (same grid quirk fixed on the header above) - their own overflow-x
     is the fallback if they still don't fit at the very narrowest
     widths, instead of blowing out the whole bar's layout. #controls
     (transport) stays a fixed "auto" track since it shouldn't compress. */
  #bottom-left { grid-column: 1; grid-row: 1; justify-self: start; min-width: 0; max-width: 100%; overflow-x: auto; }
  #controls { grid-column: 2; grid-row: 1; justify-self: center; }
  #bottom-right { grid-column: 3; grid-row: 1; justify-self: end; min-width: 0; max-width: 100%; overflow-x: auto; }
  #bottom-left label span { display: none; }
  /* The left flank's own width budget, tightened to what it actually needs.
     With the flanks now content-sized (see #bottom-bar's grid comment above),
     whatever this group asks for is what it gets - so asking for less is the
     lever that decides how narrow a phone still shows a complete tempo.
     Measured natural widths: root select 24, scale select 42, tempo ~25 with
     its padding, plus two 2px gaps = 95px. That clears 360px (a very common
     Android width, where the flank resolves to 96px) with a pixel to spare,
     where the previous 28/48 maxes came to 105 and cut the tempo off.
     The selects lose 4px and 6px of slack respectively - both are native
     <select>s whose text was already ellipsised at this size, so nothing
     legible is lost. Below ~340px the group genuinely cannot fit and falls
     back to its own overflow-x scroll, unchanged. */
  #bottom-left { gap: 2px; }
  #bottom-left select { min-height: 26px !important; font-size: 9px !important; padding: 0 2px !important; }
  #bottom-left select#scale-root { min-width: 24px; max-width: 24px; }
  #bottom-left select#scale-type { min-width: 42px; max-width: 42px; }
  /* padding is trimmed here, not just font-size/min-width. The wider
     `@media (max-width: 768px)` rule above sets `padding: 2px 10px`, and this
     block used to override only the other two properties - so at 375px the
     readout ended up 22px wide with 20px of that being horizontal padding,
     leaving ~2px for "♩ 120" to render in. Measured on device widths: the
     tempo was unreadable at 375 and fully outside its container at 320. */
  #bpm-display { font-size: 9px; min-width: 25px; padding: 2px 2px; }
  #chord-display { height: 26px; line-height: 26px; font-size: 10px; min-width: 30px; padding: 0 6px; }
  #toggleOverlayBtn, .hide-modules-btn { height: 28px; padding: 0 6px; }
  #toggleOverlayBtn .btn-label,
  .hide-modules-btn #hideModulesLabel { display: none; }
  #controls .icon-btn { min-width: 28px; min-height: 28px; font-size: 14px; padding: 2px; }
  #controls .icon-btn .icon-svg { --icon-size: 15px; }
  #controls #playBtn { min-width: 34px; min-height: 34px; }
  #controls #playBtn .icon-svg { --icon-size: 18px; }

  .onboarding-soft-banner {
    bottom: calc(var(--mm-pt-bb-h) + env(safe-area-inset-bottom) + 14px);
  }
}

/* ================================================================
   PRACTICE LOG
   ================================================================ */
.pl-wrap {
  --pl-cell: 14px;
  --pl-gap: 3px;
  width: 100%;
  max-width: 760px;
  margin: 0 auto;
  padding: 8px 10px 24px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* stat tiles */
.pl-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.pl-stat {
  background: var(--bg-card);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-md);
  padding: 14px 12px;
  text-align: center;
}
.pl-stat-val { font-size: 24px; font-weight: 800; color: var(--text-primary); letter-spacing: -0.5px; line-height: 1.1; }
.pl-stat-val .pl-fire { font-size: 18px; }
.pl-stat-val .pl-unit { font-size: 12px; font-weight: 600; color: var(--text-muted); margin-left: 3px; }
.pl-stat-label { font-size: 11px; color: var(--text-muted); margin-top: 5px; text-transform: uppercase; letter-spacing: 0.5px; }

/* cards */
.pl-card {
  background: var(--bg-card);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-md);
  padding: 16px;
}
.pl-card-title { font-size: 14px; font-weight: 700; color: var(--text-primary); }
.pl-card-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 12px; }
.pl-card-sub { font-size: 11px; color: var(--text-muted); }

/* weekly goal */
.pl-goal-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 10px; }
.pl-goal-nums { font-size: 13px; color: var(--text-secondary); }
.pl-goal-nums strong { color: var(--accent-1); font-weight: 800; }
.pl-link { background: none; border: none; color: var(--accent-2); font-size: 12px; cursor: pointer; padding: 0 0 0 8px; font-weight: 600; }
.pl-link:hover { text-decoration: underline; }
.pl-progress { height: 10px; background: rgba(255, 255, 255, 0.06); border-radius: 999px; overflow: hidden; }
.pl-progress-fill { height: 100%; width: 0; background: var(--accent-grad); border-radius: 999px; transition: width 0.5s cubic-bezier(0.22, 1, 0.36, 1); }
.pl-goal-msg { font-size: 12px; color: var(--text-muted); margin-top: 8px; }

/* log form */
.pl-form .pl-card-title { margin-bottom: 2px; }
.pl-field { margin-top: 12px; }
.pl-label { display: block; font-size: 12px; font-weight: 600; color: var(--text-secondary); margin-bottom: 6px; }
.pl-optional { font-weight: 400; color: var(--text-muted); font-size: 11px; }
.pl-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.pl-durations { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.pl-moods { display: flex; gap: 6px; }
.pl-chip, .pl-dur, .pl-mood {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border-glass-strong);
  color: var(--text-secondary);
  padding: 6px 12px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s, border-color 0.2s, color 0.2s;
}
.pl-chip { border-radius: 999px; }
.pl-dur { border-radius: var(--radius-sm); }
.pl-mood { font-size: 16px; padding: 4px 10px; border-radius: var(--radius-sm); line-height: 1; }
.pl-chip:hover, .pl-dur:hover, .pl-mood:hover { border-color: var(--accent-2); color: var(--text-primary); }
.pl-chip.selected, .pl-dur.selected { background: var(--accent-2); border-color: var(--accent-2); color: #fff; }
.pl-mood.selected { background: rgba(245, 158, 11, 0.18); border-color: var(--accent-1); }
.pl-custom {
  width: 84px; padding: 6px 10px; border-radius: var(--radius-sm);
  background: var(--select-bg); border: 1px solid var(--select-border);
  color: var(--text-primary); font-size: 12px;
}
.pl-input {
  width: 100%; padding: 9px 12px; border-radius: var(--radius-sm);
  background: var(--select-bg); border: 1px solid var(--select-border);
  color: var(--text-primary); font-size: 13px; font-family: inherit;
}
.pl-custom:focus, .pl-input:focus { outline: none; border-color: var(--accent-2); }
.pl-textarea { resize: vertical; min-height: 40px; line-height: 1.5; }
.pl-form-actions { display: flex; align-items: center; gap: 14px; margin-top: 16px; flex-wrap: wrap; }
.pl-submit {
  background: var(--accent-grad); color: #fff; border: none;
  border-radius: var(--radius-sm); padding: 10px 22px; font-size: 13px; font-weight: 700;
  cursor: pointer; transition: transform 0.15s, box-shadow 0.2s;
}
.pl-submit:hover { transform: translateY(-1px); box-shadow: 0 6px 20px rgba(139, 92, 246, 0.35); }
.pl-form-msg { font-size: 12px; font-weight: 600; }
.pl-form-msg.ok { color: #34d399; }
.pl-form-msg.err { color: #f87171; }

/* calendar heatmap */
.pl-legend { display: flex; align-items: center; gap: 4px; font-size: 10px; color: var(--text-muted); }
.pl-heatmap-scroll { overflow-x: auto; padding-bottom: 2px; }
.pl-heatmap-inner { display: inline-block; min-width: 100%; }
.pl-hm-months { display: grid; grid-auto-flow: column; grid-auto-columns: var(--pl-cell); column-gap: var(--pl-gap); margin-bottom: 5px; }
.pl-hm-month { font-size: 10px; color: var(--text-muted); white-space: nowrap; }
.pl-heatmap { display: grid; grid-template-rows: repeat(7, var(--pl-cell)); grid-auto-flow: column; grid-auto-columns: var(--pl-cell); gap: var(--pl-gap); }
.pl-hm-cell { display: inline-block; width: var(--pl-cell); height: var(--pl-cell); border-radius: 3px; background: rgba(255, 255, 255, 0.05); vertical-align: middle; }
.pl-hm-cell.lvl0 { background: rgba(255, 255, 255, 0.05); }
.pl-hm-cell.lvl1 { background: rgba(245, 158, 11, 0.30); }
.pl-hm-cell.lvl2 { background: rgba(245, 158, 11, 0.52); }
.pl-hm-cell.lvl3 { background: rgba(245, 158, 11, 0.74); }
.pl-hm-cell.lvl4 { background: rgba(245, 158, 11, 0.98); }
.pl-hm-cell.future { visibility: hidden; }
.pl-legend .pl-hm-cell { width: 11px; height: 11px; }

/* where your time goes */
.pl-breakdown { display: flex; flex-direction: column; gap: 8px; }
.pl-bd-row { display: grid; grid-template-columns: 92px 1fr auto; align-items: center; gap: 10px; }
.pl-bd-label { font-size: 12px; color: var(--text-secondary); font-weight: 600; }
.pl-bd-bar { height: 8px; background: rgba(255, 255, 255, 0.06); border-radius: 999px; overflow: hidden; }
.pl-bd-fill { height: 100%; background: var(--accent-2); border-radius: 999px; }
.pl-bd-val { font-size: 11px; color: var(--text-muted); white-space: nowrap; }

/* history */
.pl-empty { font-size: 13px; color: var(--text-muted); padding: 6px 2px; }
.pl-session-list { display: flex; flex-direction: column; }
.pl-session { display: flex; align-items: flex-start; gap: 10px; padding: 12px 0; border-top: 1px solid var(--border-glass); }
.pl-session:first-child { border-top: none; }
.pl-session-main { flex: 1; min-width: 0; }
.pl-session-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pl-badge { font-size: 11px; font-weight: 700; color: var(--accent-1); background: rgba(245, 158, 11, 0.12); border-radius: 6px; padding: 2px 8px; }
.pl-session-dur { font-size: 13px; font-weight: 700; color: var(--text-primary); }
.pl-session-mood { font-size: 14px; }
.pl-session-date { font-size: 11px; color: var(--text-muted); margin-left: auto; }
.pl-session-worked { font-size: 13px; color: var(--text-secondary); margin-top: 4px; overflow-wrap: anywhere; }
.pl-session-notes { font-size: 12px; color: var(--text-muted); margin-top: 3px; font-style: italic; overflow-wrap: anywhere; }
.pl-session-actions { display: flex; flex-direction: column; gap: 2px; flex-shrink: 0; }
.pl-session-edit,
.pl-session-del { background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 13px; padding: 4px 6px; border-radius: 6px; }
.pl-session-edit:hover { color: var(--accent-2); background: rgba(139, 92, 246, 0.1); }
.pl-session-del:hover { color: #f87171; background: rgba(248, 113, 113, 0.1); }
.pl-session-source { font-size: 10px; font-weight: 700; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.4px; border: 1px solid var(--border-glass); border-radius: 999px; padding: 1px 7px; }
.pl-session-chips { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 6px; }
.pl-chip-sm { font-size: 11px; font-weight: 600; color: var(--text-secondary); background: rgba(255, 255, 255, 0.06); border-radius: 999px; padding: 2px 9px; }
.pl-chip-removable { border: none; cursor: pointer; }
.pl-chip-removable:hover { color: #f87171; background: rgba(248, 113, 113, 0.12); }
[data-theme="light"] .pl-chip-sm { background: rgba(0, 0, 0, 0.05); }

/* most practiced */
.pl-most-practiced { display: flex; flex-direction: column; gap: 6px; }
.pl-mp-row { display: flex; align-items: center; gap: 10px; }
.pl-mp-tag { font-size: 10px; font-weight: 700; color: var(--accent-1); text-transform: uppercase; letter-spacing: 0.4px; width: 78px; flex-shrink: 0; }
.pl-mp-label { font-size: 13px; color: var(--text-primary); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pl-mp-count { font-size: 12px; font-weight: 700; color: var(--text-muted); flex-shrink: 0; }

/* edit-mode activity chips inside the form */
.pl-edit-activities { margin-top: 10px; }

/* light theme: swap the white-on-dark fills for dark-on-light */
[data-theme="light"] .pl-chip,
[data-theme="light"] .pl-dur,
[data-theme="light"] .pl-mood { background: rgba(0, 0, 0, 0.04); }
[data-theme="light"] .pl-progress,
[data-theme="light"] .pl-bd-bar { background: rgba(0, 0, 0, 0.08); }
[data-theme="light"] .pl-hm-cell.lvl0 { background: rgba(0, 0, 0, 0.06); }

@media (max-width: 560px) {
  .pl-stats { grid-template-columns: repeat(2, 1fr); }
  .pl-bd-row { grid-template-columns: 76px 1fr auto; }
}

/* ================================================================
   EAR TRAINING GAME
   ================================================================ */
.eg-wrap {
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
  padding: 8px 10px 24px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* controls */
.eg-controls { display: flex; flex-wrap: wrap; gap: 16px; }
.eg-control { display: flex; flex-direction: column; gap: 6px; }
.eg-control-label { font-size: 11px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; }
.eg-seg { display: inline-flex; background: rgba(255, 255, 255, 0.04); border: 1px solid var(--border-glass-strong); border-radius: var(--radius-sm); padding: 3px; gap: 3px; }
.eg-seg button {
  background: none; border: none; color: var(--text-secondary);
  padding: 6px 12px; font-size: 12px; font-weight: 600; cursor: pointer;
  border-radius: 7px; transition: background 0.2s, color 0.2s;
}
.eg-seg button:hover { color: var(--text-primary); }
.eg-seg button.active { background: var(--accent-2); color: #fff; }

/* stats */
.eg-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.eg-stat {
  background: var(--bg-card); border: 1px solid var(--border-glass);
  border-radius: var(--radius-md); padding: 12px 10px; text-align: center;
  display: flex; flex-direction: column; gap: 3px;
}
.eg-stat-val { font-size: 22px; font-weight: 800; color: var(--text-primary); letter-spacing: -0.5px; line-height: 1.1; }
.eg-stat-label { font-size: 10px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; }

/* stage */
.eg-card { background: var(--bg-card); border: 1px solid var(--border-glass); border-radius: var(--radius-md); padding: 20px 16px; }
.eg-stage { display: flex; flex-direction: column; align-items: center; gap: 14px; text-align: center; }
.eg-play {
  background: var(--accent-grad); color: #fff; border: none;
  border-radius: var(--radius-sm); padding: 14px 30px; font-size: 15px; font-weight: 700;
  cursor: pointer; transition: transform 0.15s, box-shadow 0.2s; min-width: 200px;
}
.eg-play:hover { transform: translateY(-1px); box-shadow: 0 8px 24px rgba(139, 92, 246, 0.4); }
.eg-play:active { transform: translateY(0); }
.eg-prompt { font-size: 14px; font-weight: 600; color: var(--text-secondary); }
.eg-choices { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; width: 100%; }
.eg-choice {
  display: inline-flex; align-items: center; gap: 7px;
  background: rgba(255, 255, 255, 0.04); border: 1px solid var(--border-glass-strong);
  color: var(--text-primary); border-radius: var(--radius-sm);
  padding: 10px 16px; font-size: 13px; font-weight: 600; cursor: pointer;
  transition: background 0.15s, border-color 0.15s, transform 0.1s;
}
.eg-choice:hover:not(:disabled) { border-color: var(--accent-2); transform: translateY(-1px); }
.eg-choice:disabled { cursor: default; opacity: 0.85; }
.eg-choice-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 5px; font-size: 10px; font-weight: 700;
  background: rgba(255, 255, 255, 0.08); color: var(--text-muted);
}
.eg-choice.correct { background: rgba(52, 211, 153, 0.18); border-color: #34d399; color: #6ee7b7; }
.eg-choice.wrong { background: rgba(248, 113, 113, 0.16); border-color: #f87171; color: #fca5a5; }
.eg-choice.correct .eg-choice-num, .eg-choice.wrong .eg-choice-num { background: rgba(0, 0, 0, 0.2); }
.eg-feedback { font-size: 15px; font-weight: 700; min-height: 20px; }
.eg-feedback.ok { color: #34d399; }
.eg-feedback.bad { color: #f87171; }
.eg-next {
  background: rgba(255, 255, 255, 0.06); border: 1px solid var(--border-glass-strong);
  color: var(--text-primary); border-radius: var(--radius-sm);
  padding: 9px 24px; font-size: 13px; font-weight: 700; cursor: pointer; transition: background 0.2s;
}
.eg-next:hover { background: rgba(255, 255, 255, 0.12); }
.eg-earn { font-size: 13px; font-weight: 700; color: var(--accent-1); min-height: 16px; }
.eg-hint { font-size: 11px; color: var(--text-muted); margin-top: 2px; }
.eg-hint strong { color: var(--text-secondary); }

/* light theme fills */
[data-theme="light"] .eg-seg,
[data-theme="light"] .eg-choice { background: rgba(0, 0, 0, 0.04); }
[data-theme="light"] .eg-next { background: rgba(0, 0, 0, 0.05); }
[data-theme="light"] .eg-choice-num { background: rgba(0, 0, 0, 0.08); }

@media (max-width: 560px) {
  .eg-stats { grid-template-columns: repeat(4, 1fr); gap: 6px; }
  .eg-stat-val { font-size: 18px; }
  .eg-controls { gap: 12px; }
}

/* ================================================================
   CREDITS — header chip, profile tier line, plans modal
   ================================================================ */
.credit-chip {
  background: rgba(245, 158, 11, 0.12);
  border: 1px solid rgba(245, 158, 11, 0.30);
  border-radius: 30px;
  color: var(--accent-1);
  cursor: pointer;
  padding: 4px 12px 4px 9px;
  font-size: 13px;
  font-weight: 700;
  display: flex;
  align-items: center;
  gap: 5px;
  min-height: 30px;
  line-height: 1;
  font-family: 'Inter', sans-serif;
  transition: var(--transition);
}
.credit-chip:hover { background: rgba(245, 158, 11, 0.20); transform: translateY(-1px); }
.credit-chip .icon-svg { --icon-size: 15px; fill: currentColor; stroke: none; }
/* Reserves room for a real balance so filling in the "—" placeholder once
   the credits fetch resolves doesn't nudge the chip's own width (and with it
   the rest of the header row) a second time, smaller than the chip's
   whole display:none->visible reveal but still visible if left unreserved. */
#creditBalance { min-width: 2ch; text-align: right; }
.credit-chip.low { background: rgba(248, 113, 113, 0.14); border-color: rgba(248, 113, 113, 0.4); color: #f87171; }

.profile-dropdown .profile-tier { font-size: 11px; color: var(--accent-1); font-weight: 600; margin-top: 2px; }
.profile-dropdown .dropdown-link {
  background: none; border: none; text-align: left;
  color: var(--text-secondary); font-size: 13px; font-weight: 500;
  padding: 6px 0; cursor: pointer; font-family: 'Inter', sans-serif;
}
.profile-dropdown .dropdown-link:hover { color: var(--text-primary); }

.ai-cost-hint { font-size: 11px; color: var(--text-muted); margin-top: 6px; text-align: center; }
.ai-cost-hint strong { color: var(--accent-1); }
.ai-cost-hint a { color: var(--accent-2); cursor: pointer; text-decoration: none; }
.ai-cost-hint a:hover { text-decoration: underline; }

.plans-overlay {
  display: none; position: fixed; inset: 0;
  background: rgba(0, 0, 0, 0.7); backdrop-filter: blur(12px);
  z-index: 1100; justify-content: center; align-items: center; padding: 20px;
}
.plans-overlay.open { display: flex; }
.plans-box {
  background: var(--bg-secondary);
  border: 1px solid var(--border-glass-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card), var(--shadow-glow);
  padding: 28px; width: 100%; max-width: 880px;
  max-height: 88vh; overflow-y: auto; position: relative;
}
.plans-close {
  position: absolute; top: 14px; right: 16px;
  background: none; border: none; color: var(--text-muted);
  font-size: 18px; cursor: pointer; line-height: 1;
}
.plans-close:hover { color: var(--text-primary); }
.plans-title { font-family: 'Nunito', sans-serif; font-weight: 800; font-size: 22px; color: var(--text-primary); }
.plans-sub { font-size: 13px; color: var(--text-secondary); margin-top: 6px; line-height: 1.5; }
.plans-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin: 18px 0; }
.plan-card {
  background: var(--bg-card); border: 1px solid var(--border-glass);
  border-radius: var(--radius-md); padding: 16px 12px; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
}
/* Deliberately unstyled - the "Current plan" button is the signal, not the
   card border. A colored border here would compete with .recommended
   below for the eye, defeating its whole point. */
/* Isolation effect: one tier (Pro) reads as visually distinct from its
   neighbors so new signups have an obvious default instead of three
   equally-weighted options. */
.plan-card.recommended { border-color: var(--accent-2); box-shadow: inset 0 0 0 1px var(--accent-2), 0 0 18px rgba(139, 92, 246, 0.3); }
.plan-badge-recommended {
  font-size: 9px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.5px;
  background: var(--accent-2); color: #fff; border-radius: 999px; padding: 3px 10px;
  margin-bottom: 2px;
}
/* Stacks alongside .plan-badge-recommended when a tier is both the
   recommended pick and beta-discounted, rather than the two competing for
   the same slot. */
.plan-badges { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px; margin-bottom: 2px; }
.plan-badges .plan-badge-recommended, .plan-badges .plan-badge-beta { margin-bottom: 0; }
.plan-badge-beta {
  font-size: 9px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.5px;
  background: #10b981; color: #fff; border-radius: 999px; padding: 3px 10px;
}
.plan-name { font-family: 'Nunito', sans-serif; font-weight: 800; font-size: 15px; color: var(--text-primary); }
.plan-tagline { font-size: 10.5px; color: var(--text-muted); line-height: 1.3; margin-top: -1px; }
.plan-credits { font-size: 22px; font-weight: 800; color: var(--accent-1); letter-spacing: -0.5px; }
.plan-per { font-size: 10px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; }
.plan-price { font-size: 13px; color: var(--text-secondary); margin-top: 4px; font-weight: 600; }
.plan-price-was { font-size: 11px; color: var(--text-muted); text-decoration: line-through; margin-top: 4px; }
.plan-price.plan-price-beta { color: #10b981; font-size: 14px; margin-top: 0; }
.plan-features {
  list-style: none; margin: 10px 0 0; padding: 10px 0 0; width: 100%;
  border-top: 1px solid var(--border-glass);
  display: flex; flex-direction: column; gap: 5px;
}
.plan-features li { font-size: 10.5px; line-height: 1.35; color: var(--text-secondary); }
.plan-btn {
  margin-top: 10px; width: 100%;
  background: rgba(255, 255, 255, 0.05); border: 1px solid var(--border-glass-strong);
  color: var(--text-muted); border-radius: var(--radius-sm);
  padding: 7px 8px; font-size: 11px; font-weight: 700; cursor: default;
}
.plan-btn.is-current { background: var(--accent-1); border-color: var(--accent-1); color: #fff; }
.plans-costs { border-top: 1px solid var(--border-glass); padding-top: 14px; }
.plans-costs-title { font-size: 12px; font-weight: 700; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 8px; }
.plans-costs-list { display: flex; flex-direction: column; gap: 6px; }
.plans-cost-row { display: flex; justify-content: space-between; font-size: 13px; color: var(--text-secondary); }
.plans-cost-val { color: var(--accent-1); font-weight: 700; }
.plans-foot { font-size: 12px; color: var(--text-muted); margin-top: 16px; text-align: center; }

[data-theme="light"] .plan-btn { background: rgba(0, 0, 0, 0.05); }

/* Interactive upgrade/manage buttons (billing enabled) — distinct from the
   disabled "Coming soon" state which keeps the muted default look above. */
.plan-btn:not(:disabled) { cursor: pointer; color: var(--text-primary); }
.plan-btn.plan-btn-buy { background: var(--accent-1); border-color: var(--accent-1); color: #fff; }
/* The recommended tier's buy button uses the site's signature gradient
   instead of flat amber, tying the "this is the one to pick" card back to
   the same accent used for the brand mark and other primary CTAs. */
.plan-btn.plan-btn-buy-featured { background: var(--accent-grad); border-color: transparent; color: #fff; }
.plan-btn:not(:disabled):hover { filter: brightness(1.08); }

/* Monthly / Yearly interval toggle */
.plans-interval {
  display: inline-flex; gap: 4px; margin: 14px 0 2px;
  background: var(--bg-card); border: 1px solid var(--border-glass);
  border-radius: var(--radius-md); padding: 4px;
}
.pi-opt {
  background: none; border: none; color: var(--text-secondary);
  font-size: 12px; font-weight: 700; padding: 6px 14px;
  border-radius: var(--radius-sm); cursor: pointer;
}
.pi-opt.active { background: var(--accent-2); color: #fff; }
.pi-badge {
  font-size: 9px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.4px;
  background: var(--accent-1); color: #fff; border-radius: 999px; padding: 1px 6px; margin-left: 4px;
}
.pi-opt.active .pi-badge { background: rgba(255, 255, 255, 0.25); }

/* Pay-as-you-go credit top-up */
.plans-topup { border-top: 1px solid var(--border-glass); padding-top: 14px; margin-top: 16px; }
.topup-sub { font-size: 12px; color: var(--text-muted); margin: 4px 0 12px; line-height: 1.5; }
.topup-slider { width: 100%; accent-color: var(--accent-1); cursor: pointer; }
.topup-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 10px; }
.topup-readout { font-size: 14px; color: var(--text-secondary); font-weight: 600; }
.topup-dollars { color: var(--accent-1); font-weight: 800; font-size: 16px; }
.topup-btn {
  background: var(--accent-1); border: 1px solid var(--accent-1); color: #fff;
  border-radius: var(--radius-sm); padding: 9px 18px; font-size: 13px; font-weight: 700; cursor: pointer;
  white-space: nowrap;
}
.topup-btn:hover { filter: brightness(1.08); }
.topup-btn:disabled { opacity: 0.6; cursor: default; }

@media (max-width: 620px) {
  .plans-grid { grid-template-columns: repeat(2, 1fr); }
}

/* ================================================================
   ACCESSIBILITY FOUNDATION (Phase 1.2)
   ================================================================ */

/* ---- Skip link ---- */
/* Off-screen until focused, then a real, high-contrast, prominent link -
   the standard pattern for letting a keyboard user bypass the header's
   ~8 tab stops (logo, instrument select, tutorial/recently-played/credits/
   theme/profile/settings buttons) and land straight in the page content. */
.skip-link {
  position: absolute;
  top: -40px;
  left: 8px;
  z-index: 10000;
  background: var(--accent-2, #8b5cf6);
  color: #fff;
  padding: 10px 18px;
  border-radius: var(--radius-sm, 8px);
  font-weight: 700;
  font-size: 14px;
  text-decoration: none;
  transition: top 0.15s ease;
}
.skip-link:focus {
  top: 8px;
}

/* ---- :focus-visible ----
   A general, branded keyboard-focus indicator, plus targeted overrides for
   every place the stylesheet already suppresses outline (mostly custom
   <select> styling and a handful of :focus{outline:none} form fields) -
   :focus-visible only matches keyboard/programmatic focus, never a mouse
   click, so this restores a visible indicator for keyboard users without
   bringing back the "outline flashes on every click" look those rules were
   written to avoid. Placed last so it wins the cascade for :focus-visible
   specifically, including against the !important rules below (matched with
   !important of its own where needed) - none of the original rules are
   modified, this only adds what was missing. */
:focus-visible {
  outline-width: 2px;
  outline-style: solid;
  outline-color: var(--accent-2, #8b5cf6);
  outline-offset: 2px;
  border-radius: 2px;
}

/* Custom <select> styling across the app forces outline:none !important
   with no replacement - restore one, matching that !important so it wins. */
#instrumentSelect:focus-visible, #scale-root:focus-visible, #scale-type:focus-visible,
#chordRootSelect:focus-visible, #scaleRootSelect:focus-visible, #scaleTypeSelect:focus-visible,
.hub-input-group select:focus-visible, #settings-panel select:focus-visible,
#bottom-bar select:focus-visible, #bottom-left select:focus-visible,
.pb-field select:focus-visible, .pb-section-label:focus-visible,
.cp-filters select:focus-visible, .pb-fx-add select:focus-visible,
.pb-voicing-select:focus-visible, .string-tuning-item select:focus-visible {
  outline-width: 2px !important;
  outline-style: solid !important;
  outline-color: var(--accent-2, #8b5cf6) !important;
  outline-offset: 2px !important;
}

/* Individual :focus{outline:none} form fields and controls - same fix,
   no !important needed since none of these used it originally. */
.pb-vol:focus-visible,
#page-ai-teacher .ai-chat .input-row input:focus-visible,
#loginModal .login-box input:focus-visible,
#launchGateModal .login-box input[type="email"]:focus-visible,
.pb-name:focus-visible,
.pb-field input:focus-visible,
.pl-custom:focus-visible, .pl-input:focus-visible {
  outline-width: 2px;
  outline-style: solid;
  outline-color: var(--accent-2, #8b5cf6);
  outline-offset: 2px;
}

/* .home-tile is a role="button" div (see app.html + JS/a11y.js's
   makeActivatable) - it has no native focus ring of its own, and its
   padding means a default outline would sit flush against the icon/text
   rather than around the whole card, so give it a slightly larger offset
   and match the card's own border-radius instead of the generic 2px one. */
.home-tile:focus-visible {
  outline-width: 2px;
  outline-style: solid;
  outline-color: var(--accent-2, #8b5cf6);
  outline-offset: 3px;
  border-radius: var(--radius-sm, 12px);
}

/* ---- Reduced motion ----
   Large/continuous/auto-playing motion is disabled outright (the 30s
   infinite background shift, pulsing status dots, the fade-in page/message
   transitions); short state-change transitions (hover, theme toggle, modal
   open) are cut to near-zero rather than fully removed, since some of them
   also drive a *visibility* change (display/opacity) that user testing
   patterns rely on completing rather than never happening. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .skip-link {
    transition: none;
  }
}
