/* ═══════════════════════════════════════════════════════════════════
   theory.css — Interactive Chromatic Theory Explorer
   Two-row layout: static interval row + draggable notes row
   ═══════════════════════════════════════════════════════════════════ */

.theory-page {
  padding: var(--sp-4, 16px) var(--sp-3, 12px);
  max-width: 100%;
  margin: 0 auto;
}

/* ══════════════════════════════════════════════════════════════════
   INTERVAL ROW  (static, top)
   ══════════════════════════════════════════════════════════════════ */
/* ── Labeled rows (label + row content) ─────────────────────────── */
.theory-labeled-row {
  display: flex;
  align-items: center;
  gap: 10px;             /* breathing room between label "Notes" and the row */
}
.theory-row-label {
  flex-shrink: 0;
  width: 92px;           /* fits "INTERVALS" (9 char @ 0.72rem) inside the toggle pill */
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-3, #aaa);
  text-align: center;
  line-height: 1.3;
}
.theory-row-label--toggle {
  cursor: pointer;
  display: inline-block;
  padding: 4px 10px;
  border-radius: var(--r-sm, 6px);
  border: 1px solid transparent;
  background: transparent;
  transition: color 0.15s, background 0.15s, border-color 0.15s;
  color: var(--text-muted, #888);
}
.theory-row-label--toggle:hover {
  background: var(--surface-2, #f5f4f0);
  border-color: var(--border);
}
/* Active state — row is visible */
.theory-row-label--toggle.label-active {
  color: var(--text);
  background: var(--surface-2, #f5f4f0);
  border-color: var(--border);
}
/* Inactive state — row is hidden */
.theory-row-label--toggle.label-inactive {
  color: var(--text-3, #bbb);
  opacity: 0.55;
}
.theory-row-label--toggle.label-inactive:hover {
  opacity: 0.85;
}
/* Hidden row — keep spacing, just hide content */
.theory-labeled-row.row-hidden .theory-interval-row,
.theory-labeled-row.row-hidden .theory-notes-wrap {
  visibility: hidden;
}

.theory-row-divider {
  height: 0;
  /* Clean solid hairline reads as finished (was a faint dashed line that
     looked like placeholder CSS).  Per user 2026-06-19. */
  border-top: 1px solid var(--border, #e3ddd6);
  margin: 14px 0 10px;
  /* Align with the row content: side-control 36 + gap 10 + label 92 + gap 10 = 148px */
  margin-left: 148px;
}

.theory-interval-row {
  display: flex;
  flex: 1;
  gap: 3px;
  /* Pad left/right so cells align with the notes row's cells.
     Notes row layout: scroll-btn 38px + .theory-notes-wrap gap 10px = 48px. */
  padding-left: 48px;
  padding-right: 48px;
  user-select: none;
  -webkit-user-select: none;
}

.theory-int-cell {
  flex: 1;
  min-width: 0;
  text-align: center;
  padding: 12px 2px;
  border: 1.5px solid var(--border);
  border-radius: var(--r-sm, 6px);
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, font-size 0.15s;
  background: var(--surface);

  /* Interval label styling — big, readable.  Sized down responsively
     instead of truncated (#4/b5, #5/b6 must stay legible). */
  font-size: 0.95rem;
  font-weight: 600;
  font-family: var(--font-mono, 'DM Mono', monospace);
  color: var(--text-muted, #888);
  line-height: 1.2;
  white-space: nowrap;
  overflow: visible;
}
.theory-int-cell:hover {
  border-color: var(--text-muted, #888);
}

.theory-int-cell.root {
  border-color: var(--accent, #e8874a);
  border-width: 2px;
  color: var(--text);
}

.theory-int-cell.selected {
  background: rgba(91, 143, 217, 0.15);
  border-color: #5b8fd9;
  color: var(--text);
}
[data-theme="dark"] .theory-int-cell.selected {
  background: rgba(91, 143, 217, 0.22);
}

.theory-int-cell.root-selected {
  background: rgba(232, 135, 74, 0.18);
  border-color: #e8874a;
  color: var(--text);
}
[data-theme="dark"] .theory-int-cell.root-selected {
  background: rgba(232, 135, 74, 0.28);
}

/* Octave root — much fainter tint so it reads as "same note, one octave up"
   rather than competing for attention with the true root. */
.theory-int-cell.octave-root {
  background: rgba(232, 135, 74, 0.06);
  border-color: rgba(232, 135, 74, 0.35);
  color: var(--text-muted, #888);
}
[data-theme="dark"] .theory-int-cell.octave-root {
  background: rgba(232, 135, 74, 0.10);
  border-color: rgba(232, 135, 74, 0.40);
}

/* Hidden unselected cells — invisible but preserve layout space */
.theory-int-cell.unsel-hidden,
.theory-note-cell.unsel-hidden {
  visibility: hidden;
}

/* ══════════════════════════════════════════════════════════════════
   NOTES ROW  (draggable, below intervals)
   ══════════════════════════════════════════════════════════════════ */
/* Label-stack — stacks the row label + spelling-toggle button vertically
   inside the same 92px column the regular `.theory-row-label` would
   occupy on its own.  Keeps the cells columns perfectly aligned across
   intervals, notes, and the stack-explorer rows below. */
.theory-label-stack {
  flex-shrink: 0;
  width: 92px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 4px;
}
.theory-label-stack .theory-row-label {
  width: 100%;             /* fill the stack's column */
}

.theory-naming-toggle {
  font: inherit;
  font-family: var(--font-mono, 'DM Mono', monospace);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--text-muted, #888);
  background: var(--surface-2, #f5f4f0);
  border: 1px solid var(--border);
  border-radius: var(--r-sm, 6px);
  padding: 3px 8px;
  width: 100%;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.theory-naming-toggle:hover {
  border-color: var(--accent, #e8874a);
  color: var(--text);
}
.theory-naming-toggle.naming-sharp {
  background: rgba(91, 143, 217, 0.15);
  border-color: #5b8fd9;
  color: #5b8fd9;
}
.theory-naming-toggle.naming-flat {
  background: rgba(232, 135, 74, 0.15);
  border-color: var(--accent, #e8874a);
  color: var(--accent, #e8874a);
}

.theory-notes-wrap {
  display: flex;
  flex: 1;
  align-items: center;
  gap: 10px;             /* visible breathing room beside the scroll arrows */
  user-select: none;
  -webkit-user-select: none;
}

.theory-scroll-btn {
  flex-shrink: 0;
  width: 38px;
  height: 52px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm, 6px);
  background: var(--surface);
  color: var(--text);
  font-size: 1.35rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s, border-color 0.15s;
}
.theory-scroll-btn:hover {
  background: var(--surface-hover, rgba(0,0,0,0.04));
  border-color: var(--accent, #e8874a);
}
[data-theme="dark"] .theory-scroll-btn:hover {
  background: rgba(255,255,255,0.06);
}

.theory-notes-row {
  display: flex;
  flex: 1;
  gap: 3px;
  cursor: grab;
  touch-action: pan-y;
}
.theory-notes-row.grabbing {
  cursor: grabbing;
}

.theory-note-cell {
  flex: 1;
  min-width: 0;
  text-align: center;
  padding: 12px 2px;
  border: 1.5px solid var(--border);
  border-radius: var(--r-sm, 6px);
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, transform 0.1s, font-size 0.15s;
  background: var(--surface);

  /* Note name styling — prominent.  Don't truncate; the responsive
     ladder below shrinks the type at narrow widths instead. */
  font-size: 1.0rem;
  font-weight: 600;
  color: var(--text);
  line-height: 1.15;
  white-space: nowrap;
  overflow: visible;
}
.theory-note-cell:hover {
  border-color: var(--text-muted, #888);
  transform: translateY(1px);
}

.theory-note-cell.root {
  border-color: var(--accent, #e8874a);
  border-width: 2px;
}

.theory-note-cell.selected {
  background: rgba(91, 143, 217, 0.15);
  border-color: #5b8fd9;
}
[data-theme="dark"] .theory-note-cell.selected {
  background: rgba(91, 143, 217, 0.22);
}

.theory-note-cell.root-selected {
  background: rgba(232, 135, 74, 0.18);
  border-color: #e8874a;
}
[data-theme="dark"] .theory-note-cell.root-selected {
  background: rgba(232, 135, 74, 0.28);
}

.theory-note-cell.octave-root {
  background: rgba(232, 135, 74, 0.06);
  border-color: rgba(232, 135, 74, 0.35);
  color: var(--text-muted, #888);
}
[data-theme="dark"] .theory-note-cell.octave-root {
  background: rgba(232, 135, 74, 0.10);
  border-color: rgba(232, 135, 74, 0.40);
}

/* ══════════════════════════════════════════════════════════════════
   DETECTION RESULTS
   ══════════════════════════════════════════════════════════════════ */
.theory-detection {
  margin-top: var(--sp-5, 24px);
  margin-bottom: 0;
  /* No fixed height — let it expand to fit the modes list. */
  text-align: center;
}

.theory-detect-empty {
  color: var(--text-muted, #888);
  font-size: 0.92rem;
  margin: 0;
  padding: var(--sp-2, 8px) 0;
  text-align: center;
}

.theory-detect-item {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 14px;
  margin: 3px 4px;
  border-radius: var(--r-sm, 6px);
  font-size: 0.92rem;
  line-height: 1.4;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text);
}

.theory-detect-label {
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 2px 7px;
  border-radius: 3px;
  line-height: 1.3;
}
.theory-detect-interval .theory-detect-label {
  background: rgba(91,143,217,0.15);
  color: #5b8fd9;
}
.theory-detect-chord .theory-detect-label {
  background: rgba(232,135,74,0.15);
  color: #e8874a;
}
.theory-detect-scale .theory-detect-label {
  background: rgba(74,190,130,0.15);
  color: #4abe82;
}
.theory-detect-semi {
  color: var(--text-muted, #888);
  font-size: 0.82rem;
}

/* Mode grouping under parent scale */
.theory-detect-group {
  display: inline-block;
  vertical-align: top;
  margin: 3px 0;
  border: 1px solid var(--border);
  border-radius: var(--r-sm, 6px);
  background: var(--surface);
  overflow: hidden;
}
.theory-detect-group > .theory-detect-item {
  border: none;
  border-radius: 0;
  margin: 0;
  display: flex;
  background: transparent;
}
.theory-detect-modes {
  padding: 0 6px 6px;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.theory-detect-mode {
  font-size: 0.85rem;
  padding: 3px 10px;
}
.theory-detect-mode .theory-detect-label {
  background: rgba(74,190,130,0.10);
  color: #4abe82;
  font-size: 0.68rem;
}

/* ══════════════════════════════════════════════════════════════════
   SELECTORS ROW  (key + scale + chord pickers)
   ══════════════════════════════════════════════════════════════════ */
/* ══════════════════════════════════════════════════════════════════
   SELECTOR TOOLBAR  (Key / Scale / Chord — uses shared .toolbar)
   ══════════════════════════════════════════════════════════════════ */
.theory-selector-bar .form-group {
  /* Even columns — flex-basis 0 so every control gets the same width instead
     of the left (Key/Scale/Chord) cluster reading wider than the right.
     Per user 2026-06-19. */
  flex: 1 1 0;
  min-width: 128px;
  max-width: 200px;
}

/* The Key/Scale/Chord/Notes popover triggers (from enhanceNativeSelect) had
   NO base styling on this page — they rendered as raw browser buttons (grey,
   2px outset border, ~20px tall).  Match them EXACTLY to the Display/Intervals/
   In-between boxes (.ghost-toggle) so the whole bar is one uniform set of
   clean boxes.  Per user 2026-06-19. */
.theory-selector-bar .fly-select-trigger {
  box-sizing: border-box;
  width: 100%;
  height: var(--ctl-h-lg, 36px);
  padding: 0 10px;
  font-family: var(--font);
  font-size: var(--font-sm);
  font-weight: var(--weight-medium);
  line-height: 1.2;
  color: var(--text);
  text-align: left;
  background: var(--surface-2);
  background-image: none;
  border: var(--border-w, 1px) solid var(--border);
  border-radius: var(--radius-sm, var(--r-sm, 4px));
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.theory-selector-bar .fly-select-trigger:hover { border-color: var(--text-3); }
.theory-selector-bar .fly-select-trigger:focus-visible {
  outline: none;
  border-color: var(--accent, #e8874a);
  box-shadow: 0 0 0 2px rgba(232, 135, 74, 0.2);
}

/* ══════════════════════════════════════════════════════════════════
   INTERVAL CARD  (wraps interval rows + detection + controls)
   ══════════════════════════════════════════════════════════════════ */
.theory-interval-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--sp-4) var(--sp-5);
  margin-bottom: var(--panel-gap);
  box-shadow: var(--shadow);
}

/* ══════════════════════════════════════════════════════════════════
   TOGGLES & CLEAR inside toolbar
   ══════════════════════════════════════════════════════════════════ */
.theory-toggle-group {
  display: flex;
  align-items: center;
  gap: var(--sp-3, 12px);
  align-self: flex-end;
  padding-bottom: 7px; /* baseline-align with form-control height */
}

/* The three view toggles reuse the shared .scp-switch component (defined in
   scale-collection-page.css, loaded app-wide) so they match the scale/chord
   toolbar toggles instead of using bare native checkboxes.  The shared
   component hides its checkbox with `display:none`, which drops it from the
   tab order; this scoped override keeps the checkbox keyboard-focusable
   (Space toggles, visible focus ring on the track) WITHOUT forking a new
   toggle CSS family — per the no-duplication rule we consume the existing
   component and only layer accessibility on top. */
.theory-toggle-group .scp-switch { position: relative; }
.theory-toggle-group .scp-switch input {
  display: inline-block;   /* override shared display:none so it stays focusable */
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  margin: 0;
  padding: 0;
  opacity: 0;
  pointer-events: none;
}
.theory-toggle-group .scp-switch input:focus-visible + .scp-switch-track {
  outline: 2px solid var(--accent, #e8874a);
  outline-offset: 2px;
}

.theory-clear-btn {
  margin-left: auto;
  align-self: flex-end;
  height: var(--ctl-h-md, 34px);
  padding: 0 var(--space-lg);
  font-size: var(--font-sm);
  font-weight: var(--weight-medium);
  border: var(--border-w, 1px) solid var(--border);
  border-radius: var(--r-sm, var(--radius-md, 6px));
  background: var(--surface-2);
  color: var(--text-muted, #888);
  cursor: pointer;
  transition: background var(--t-fast, 0.15s), color var(--t-fast, 0.15s), border-color var(--t-fast, 0.15s);
}
.theory-clear-btn:hover {
  background: var(--surface-hover, rgba(0,0,0,0.04));
  color: var(--text);
  border-color: var(--text-muted, #888);
}

/* ══════════════════════════════════════════════════════════════════
   VISUALISATION CONTAINERS
   ══════════════════════════════════════════════════════════════════ */
.theory-visuals {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4, 16px);
}

/* Labels hidden — toggled by checkboxes, no need for text labels */
.theory-vis-label {
  display: none;
}

/* Shared card style for all visualisation wrappers */
.theory-fb-wrap,
.theory-piano-wrap,
.theory-circle-wrap {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg, 14px);
  box-shadow: var(--shadow);
  padding: var(--sp-3, 12px) var(--sp-4, 16px);
}

/* Fretboard */
.theory-fb-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* Bottom row: piano left, circle right.
   align-items: stretch so the two cards always have the same height when
   side-by-side.  flex-wrap so the circle drops below the piano as soon as
   the viewport can't comfortably hold both. */
.theory-bottom-row {
  display: flex;
  gap: var(--sp-4, 16px);
  align-items: stretch;
  flex-wrap: wrap;
}

/* Piano — fills available space on the left */
.theory-piano-wrap {
  flex: 1;
  min-width: 0;
  overflow: hidden;
}
.theory-piano-wrap svg {
  display: block;
  width: 100%;
  height: auto;
}

/* Scale circle — square, right side */
.theory-circle-wrap {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
}
.theory-circle-wrap svg {
  display: block;
}

/* ── Both-spelling override ─────────────────────────────────────────
   When the spelling toggle is set to "both" the cell labels become
   ~5 chars wide (#4/b5, C#/Db) and need extra horizontal room.
   Shrink the type and tighten letter-spacing whenever the row carries
   the .naming-both class.  Stacks on top of the responsive ladder
   below so the smallest viewports get the smallest type. */
.theory-interval-row.naming-both .theory-int-cell  { font-size: 0.78rem; letter-spacing: -0.01em; }
.theory-notes-row.naming-both    .theory-note-cell { font-size: 0.84rem; letter-spacing: -0.01em; }

/* ══════════════════════════════════════════════════════════════════
   RESPONSIVE — interval/notes cells shrink instead of truncating
   ══════════════════════════════════════════════════════════════════ */
/* Cells render 12 across plus a 92px label + 48px scroll-button-band on
   each side.  At each breakpoint where the longest token (`#4/b5`,
   `G#/Ab`, `A#/Bb`) would otherwise overflow the cell width, step the
   font down.  Letter-spacing tightens at the smallest steps. */
@media (max-width: 1100px) {
  .theory-int-cell  { font-size: 0.85rem; padding: 11px 1px; }
  .theory-note-cell { font-size: 0.92rem; padding: 11px 1px; }
  .theory-interval-row.naming-both .theory-int-cell  { font-size: 0.7rem;  letter-spacing: -0.02em; }
  .theory-notes-row.naming-both    .theory-note-cell { font-size: 0.74rem; letter-spacing: -0.02em; }
}
@media (max-width: 950px) {
  .theory-int-cell  { font-size: 0.78rem; padding: 10px 1px; letter-spacing: -0.01em; }
  .theory-note-cell { font-size: 0.85rem; padding: 10px 1px; letter-spacing: -0.01em; }
  .theory-interval-row.naming-both .theory-int-cell  { font-size: 0.62rem; letter-spacing: -0.03em; }
  .theory-notes-row.naming-both    .theory-note-cell { font-size: 0.66rem; letter-spacing: -0.03em; }
}
@media (max-width: 820px) {
  .theory-int-cell  { font-size: 0.7rem;  padding: 9px 1px;  letter-spacing: -0.02em; }
  .theory-note-cell { font-size: 0.78rem; padding: 9px 1px;  letter-spacing: -0.02em; }
  .theory-interval-row.naming-both .theory-int-cell  { font-size: 0.55rem; letter-spacing: -0.04em; }
  .theory-notes-row.naming-both    .theory-note-cell { font-size: 0.58rem; letter-spacing: -0.04em; }
}
@media (max-width: 720px) {
  .theory-int-cell  { font-size: 0.62rem; padding: 8px 0;    letter-spacing: -0.03em; }
  .theory-note-cell { font-size: 0.70rem; padding: 8px 0;    letter-spacing: -0.03em; }
  .theory-interval-row.naming-both .theory-int-cell  { font-size: 0.48rem; letter-spacing: -0.05em; }
  .theory-notes-row.naming-both    .theory-note-cell { font-size: 0.52rem; letter-spacing: -0.05em; }
}

@media (max-width: 640px) {
  .theory-labeled-row { gap: 6px; }
  .theory-row-label {
    width: 70px;
    font-size: 0.58rem;
  }
  .theory-row-label--toggle {
    padding: 3px 6px;
  }
  .theory-side-control { width: 30px; }
  .theory-naming-toggle { font-size: 0.7rem; padding: 3px 4px; height: 26px; }
  .theory-row-divider {
    /* Mobile: side 30 + gap 6 + label 70 + gap 6 = 112px */
    margin-left: 112px;
  }
  .theory-interval-row {
    /* scroll-btn 32px + .theory-notes-wrap gap 6px = 38px on mobile */
    padding-left: 38px;
    padding-right: 38px;
  }
  .theory-int-cell {
    padding: 8px 1px;
    font-size: 0.82rem;
  }
  .theory-note-cell {
    padding: 10px 1px;
    font-size: 0.88rem;
  }
  .theory-notes-wrap { gap: 6px; }
  .theory-scroll-btn { width: 32px; height: 46px; font-size: 1.15rem; }
  .theory-bottom-row { flex-direction: column; }
  .theory-circle-wrap svg { width: 250px !important; height: 250px !important; }
  .theory-interval-card { padding: var(--sp-3); }
  .theory-toggle-group { flex-basis: 100%; }
}
