/* browse.css — The Browse destination's chrome: Settings page, buttons, both pane
   heads, the chords bar, sheets, the content panels and the tune list.

   Cut from the single style.css on 2026-08-02. The <link> order in
   index.html IS the cascade order these were split at; reordering the
   tags changes which rule wins. */

/* -------------------------------------------------------- Settings page */

.set-group {
  font-family: var(--font-cond);
  font-size: 1rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent-ink);
  margin: 1.2rem 0 0.2rem;
}

.set-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.55rem 0;
  border-bottom: 1px dotted var(--border);
}
.set-row-label { display: flex; flex-direction: column; min-width: 0; }
.set-row-label > span { font-size: 0.92rem; }
.set-row-hint { font-size: 0.74rem; color: var(--muted); }
.set-value { color: var(--muted); font-size: 0.78rem; text-align: right; }

.set-row .seg-group { flex: none; }
.set-row .seg-btn { flex: none; padding: 0.35rem 0.7rem; font-size: 0.8rem; }

.set-select {
  font: inherit;
  font-size: 0.85rem;
  color: var(--fg);
  background: var(--panel2);
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  padding: 0.35rem 0.5rem;
  cursor: pointer;
}

.set-slider {
  flex: none;
  width: 12rem;
  max-width: 100%;
  accent-color: var(--accent-ink);
}

.set-stepper { display: inline-flex; align-items: center; gap: 0.4rem; }
.set-stepper button {
  width: 1.9rem;
  height: 1.9rem;
  background: none;
  border: 1px solid var(--border);
  border-radius: 0.45rem;
  color: var(--fg);
  font: inherit;
  cursor: pointer;
}
.set-stepper button:hover { border-color: var(--accent); }
.set-stepper-val {
  min-width: 3.4rem;
  text-align: center;
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

.set-btn-row { display: flex; gap: 0.4rem; }

/* Two panes side by side: a fixed list pane (collapsible) and a detail pane
   that fills the rest. Below the 860px seam the two become a single-screen
   switch (list OR detail), driven by body.show-detail. */
.shell {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: row;
  position: relative; /* anchors the sheets + backdrop */
  overflow: hidden;
}

#listPane {
  flex: none;
  width: 320px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--border);
  overflow: hidden;
  transition: width 0.18s ease;
}

body.list-collapsed #listPane { width: 0; border-right: none; }

/* The whole pane is the scroller: the header + tabs ride at the top of the flow
   and scroll away with the chords (the title row is never pinned), while only
   the footer control bar stays stuck to the bottom of the viewport. */
#detailPane {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overflow-x: hidden;
  position: relative;
}

/* --------------------------------------------------- icon / pill buttons */

/* 36×36 square icon button with a 10px radius — the mockup's chrome control. */
.icon-btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  width: 2.25rem;
  height: 2.25rem;
  background: none;
  border: 1px solid var(--border);
  border-radius: 0.6rem;
  color: var(--fg);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
}

.icon-btn:hover { border-color: var(--muted); }
.icon-btn svg { width: 1.05rem; height: 1.05rem; }
.icon-btn.on { border-color: var(--accent); color: var(--accent-ink); }

/* Small count badge (active filters) top-right of the filters button. */
.badge {
  position: absolute;
  top: -0.35rem;
  right: -0.35rem;
  min-width: 1rem;
  height: 1rem;
  padding: 0 0.25rem;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: 0.62rem;
  font-weight: 700;
  line-height: 1rem;
  text-align: center;
}
.badge[hidden] { display: none; }

/* Pill toggle (a switch) used in the Filters / Settings sheets. */
.toggle-btn {
  flex: none;
  width: 2.5rem;
  height: 1.5rem;
  padding: 0;
  border-radius: 0.75rem;
  border: 1px solid var(--border);
  background: var(--panel);
  cursor: pointer;
  position: relative;
}
.toggle-btn .knob {
  position: absolute;
  top: 1px;
  left: 1px;
  width: 1.2rem;
  height: 1.2rem;
  border-radius: 50%;
  background: var(--muted);
  transition: left 0.15s ease, background 0.15s ease;
}
.toggle-btn.on { background: var(--accent); border-color: var(--accent); }
.toggle-btn.on .knob { left: calc(100% - 1.3rem); background: #fff; }

/* -------------------------------------------------------- list pane head */

.list-head {
  flex: none;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 0.8rem 0.8rem 0.55rem;
}

/* Collapse ☰ · search · filters, one row. The wordmark lives in the rail. */
.list-head-top {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

#search {
  flex: 1;
  min-width: 0;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 0.6rem;
  background: var(--panel);
  color: var(--fg);
  font-size: 0.95rem;
}

#search:focus { outline: 1px solid var(--muted); }

/* "N of M tunes" under the search row. */
.list-count {
  font-size: 0.72rem;
  color: var(--muted);
  margin-top: -0.2rem;
}

/* Active-playlist chip in the list header. */
.active-pl-chip {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.active-pl-chip[hidden] { display: none; }

#playlistBtn {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: left;
  background: var(--chip-bg);
  border: 1px solid var(--accent-ink);
  border-radius: 999px;
  color: var(--accent-ink);
  font-size: 0.8rem;
  padding: 0.3rem 0.7rem;
  cursor: pointer;
}
#playlistBtn::before { content: "▶ "; }

#playlistClear {
  flex: none;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 0.78rem;
  cursor: pointer;
}
#playlistClear:hover { color: var(--fg); }

#tuneList {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 0 0.35rem 1.4rem;
}

/* ---------------------------------------------------- detail pane head */

.detail-head {
  flex: none;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6rem 0.6rem 0.4rem;
}

/* Fixed-width gutters on both sides keep the title centered whether or not a
   back / sidebar button is present. */
.dh-side {
  flex: none;
  width: 2.25rem;
  display: flex;
  align-items: center;
}

/* Back (mobile) and sidebar-open (desktop, collapsed) are shown by JS via
   body classes; hidden by default. */
#backBtn, #sidebarOpenBtn { display: none; font-size: 1.3rem; }
/* Sidebar-reopen button: wide screens only, when the list is collapsed. The
   back button is narrow-only (added in the responsive block). */
body.list-collapsed #sidebarOpenBtn { display: inline-flex; }

.detail-title {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.05rem;
}
.detail-title .dt-title {
  font-family: var(--font-cond);
  font-weight: 700;
  font-size: 1.5rem;
  line-height: 1.05;
  letter-spacing: 0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* composer · year · form */
.detail-title .dt-meta {
  font-size: 0.8rem;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Chords · Melody · Similar underline tabs (shown by JS when a tune has more
   than one destination). */
.detail-tabs {
  flex: none;
  display: flex;
  gap: 0;
  padding: 0 0.8rem 0.15rem;
}
.detail-tabs[hidden] { display: none; }
.detail-tabs .tab {
  flex: 0 0 auto;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  color: var(--muted);
  font: inherit;
  font-size: 0.85rem;
  font-weight: 500;
  padding: 0.4rem 1rem;
  cursor: pointer;
}
.detail-tabs .tab[hidden] { display: none; }
.detail-tabs .tab.active {
  color: var(--fg);
  font-weight: 600;
  border-bottom-color: var(--accent);
}

#tuneView {
  /* Grow to fill the pane so a short tune still pushes the footer to the bottom,
     but let a tall tune overflow and drive the pane's scroll (not a nested one). */
  flex: 1 0 auto;
  min-height: 0;
  overflow-y: visible;
  padding: 0.6rem 1.4rem 2rem;
  position: relative;
}

#tunePane {
  min-width: 0;
  container-type: inline-size;
}

/* ------------------------------------------------------- detail footer */

/* The chords bar: one thin strip at the foot of the detail pane holding the
   four things that have to stay reachable while reading — zoom, key, and the
   ♪ (player) and ⋯ (settings) menus, which open above it. Sticky, so it stays
   put while the chart scrolls, and positioned, so the menus can anchor to it. */
#detailFooter {
  flex: none;
  position: sticky;
  bottom: 0;
  z-index: 20;
  background: var(--bg);
  border-top: 1px solid var(--border);
}
#detailFooter[hidden] { display: none; }
/* An open menu lifts the whole bar above the sheets and the scan overlay. */
#detailFooter.menu-open { z-index: 60; }

.chords-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.32rem 0.9rem;
  /* Above the scrim (44), below the menus (46): the scrim swallows the rest of
     the app, but ♪ and ⋯ stay live — tapping the open one closes it, and
     tapping the other switches. */
  position: relative;
  z-index: 45;
}

.cb-zoom { display: inline-flex; gap: 0.35rem; }
.cb-right { display: inline-flex; align-items: center; gap: 0.4rem; }

/* ♪ and ⋯. Same box; ♪ is the only thing on the bar that carries transport
   state, so a take running behind a closed menu is still visible. */
.cb-btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  padding: 0;
  border-radius: 0.55rem;
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--fg);
  font-size: 1.15rem;
  line-height: 1;
  cursor: pointer;
}
.cb-btn:hover { border-color: var(--muted); }
#tuneMenuBtn { font-size: 1.2rem; }
/* ♪: menu open, or a take running. */
#playerBtn.on,
#playerBtn.playing {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
/* ⋯: open. A quieter state — nothing is happening, a panel is just showing. */
#tuneMenuBtn.on {
  background: var(--chip-bg);
  border-color: var(--accent);
  color: var(--accent-ink);
}

/* ---- the transport on the bar: ⏮ ▶ ♩=BPM.

   A take is controllable without opening anything, and the readout doubles as
   the menu's button — so ♪ would be a second way to do the same thing, and it
   is dropped here. Below the phone seam there is no room for any of it: the
   transport folds into the top of the menu and ♪ comes back. */
.cb-transport {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding-right: 0.5rem;
  margin-right: 0.1rem;
  border-right: 1px solid var(--border);
}
#playerBtn { display: none; }

.cb-play.playing {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
/* The glyph is a triangle with air on its left; nudge it back onto the centre. */
.cb-play:not(.playing) { padding-left: 0.1rem; }
.cb-play:disabled { opacity: 0.5; cursor: progress; }

.cb-tempo {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  height: 2.1rem;
  padding: 0 0.6rem;
  background: none;
  border: 1px solid var(--border);
  border-radius: 0.55rem;
  color: var(--muted);
  font: inherit;
  font-size: 0.82rem;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
}
.cb-tempo:hover { border-color: var(--muted); }
.cb-tempo .cb-note {
  font-family: var(--font-cond);
  font-size: 1rem;
  color: var(--fg);
}
.cb-tempo.on {
  background: var(--chip-bg);
  border-color: var(--accent);
  color: var(--accent-ink);
}

@media (max-width: 859px) {
  .cb-transport { display: none; }
  #playerBtn { display: inline-flex; }
}

/* The footer summary chips (key/tempo/family/starts-on) are retired: that info
   now lives in the collapsible Details/Tags sections and the Key is the centre
   dropdown below. The bottom bar is a clean three-zone control strip. */
#footerChips { display: none; }
.footer-chips .fchip {
  font-size: 0.75rem;
  color: var(--muted);
  background: var(--chip-bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.2rem 0.55rem;
  white-space: nowrap;
}
.footer-chips .fchip.key { color: var(--accent-ink); border-color: var(--accent-ink); }

/* Playlist step buttons: only on the bar while a playlist is active, so the
   three design groups are what the bar normally shows. Narrow enough not to
   push the key selector off centre. */
.footer-nav { display: inline-flex; gap: 0.25rem; margin-right: 0.15rem; }
.footer-nav[hidden] { display: none; }
.footer-nav .step-btn {
  flex: none;
  width: 1.6rem;
  height: 2.1rem;
  padding: 0;
  background: none;
  border: 1px solid var(--border);
  border-radius: 0.45rem;
  color: var(--muted);
  font-size: 0.95rem;
  line-height: 1;
  cursor: pointer;
}
.footer-nav .step-btn:disabled { opacity: 0.35; cursor: default; }

/* --------------------------------------------------- sheets & backdrop */

#sheetBackdrop {
  position: absolute;
  inset: 0;
  z-index: 45;
  background: rgba(0, 0, 0, 0.45);
}
#sheetBackdrop[hidden] { display: none; }

.sheet-panel {
  position: absolute;
  z-index: 50;
  background: var(--bg);
  border: 1px solid var(--border);
  overflow-y: auto;
  padding: 0.9rem 1.1rem 1.2rem;
  /* Desktop: floating card, top-right of the shell. */
  top: 0.9rem;
  right: 0.9rem;
  width: 23rem;
  max-height: 86%;
  border-radius: 1rem;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.35);
}
.sheet-panel[hidden] { display: none; }

.sheet-grip { display: none; }

.sheet-title {
  font-family: var(--font-cond);
  font-weight: 700;
  font-size: 1.2rem;
  margin-bottom: 0.8rem;
}

/* "N of M tunes" under the Filters title — how much the filters cut away. */
.sheet-count {
  font-size: 0.82rem;
  color: var(--muted);
  margin: -0.55rem 0 0.7rem;
}

.sheet-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.8rem;
  padding: 0.5rem 0.1rem;
}
.sheet-row[hidden] { display: none; } /* display:flex would otherwise win */
.sheet-row-label { font-size: 0.92rem; }

/* Divider between the current-tune options and the global settings. */
.sheet-divider {
  height: 1px;
  background: var(--border);
  margin: 0.9rem 0 0.2rem;
}

/* The current tune's title, heading its options block in the Settings sheet. */
.sheet-section-head {
  font-size: 1rem;
  font-weight: 700;
  text-transform: none;
  letter-spacing: 0;
  color: var(--fg);
  margin-bottom: 0.6rem;
}

.sheet-field { margin-top: 0.7rem; }
.sheet-field-label {
  display: block;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin-bottom: 0.35rem;
}
.sheet-field select {
  width: 100%;
  font: inherit;
  font-size: 0.9rem;
  color: var(--fg);
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  padding: 0.4rem 0.5rem;
}

.sheet-action {
  width: 100%;
  text-align: left;
  background: none;
  border: 1px dashed var(--border);
  border-radius: 0.6rem;
  color: var(--fg);
  font-size: 0.88rem;
  padding: 0.55rem 0.6rem;
  cursor: pointer;
}
.sheet-action:hover { border-color: var(--muted); }

/* Segmented control (theme picker, view picker). */
.seg-group { display: flex; gap: 0.4rem; }
.seg-btn {
  flex: 1;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  color: var(--fg);
  font: inherit;
  font-size: 0.85rem;
  padding: 0.45rem 0;
  cursor: pointer;
}
.seg-btn.active,
.seg-btn.on { background: var(--accent); border-color: var(--accent); color: #fff; }

/* Pill option buttons in the tune sheet (view / similar rows reuse existing). */
.opt-pill {
  background: none;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--fg);
  font: inherit;
  font-size: 0.82rem;
  padding: 0.35rem 0.75rem;
  cursor: pointer;
}
.opt-pill.active { border-color: var(--accent); color: var(--accent-ink); background: var(--chip-bg); }


/* --------------------------------------- content panels (chords/melody) */

/* Toolbar with the Chords / Melody switches, under the tune head (§5.4). */
.panel-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.6rem 1.4rem;
  margin: 0.2rem auto 1rem;
}

.switch {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  cursor: pointer;
  font-size: 0.9rem;
  user-select: none;
}

.switch input { position: absolute; opacity: 0; pointer-events: none; }

.switch .knob {
  width: 2.1rem;
  height: 1.15rem;
  border-radius: 0.6rem;
  background: var(--panel);
  border: 1px solid var(--border);
  position: relative;
  transition: background 0.15s ease;
  flex: none;
}

.switch .knob::after {
  content: "";
  position: absolute;
  top: 1px;
  left: 2px;
  width: 0.95rem;
  height: 0.95rem;
  border-radius: 50%;
  background: var(--muted);
  transition: transform 0.15s ease, background 0.15s ease;
}

.switch input:checked + .knob { background: var(--accent); border-color: var(--accent); }
.switch input:checked + .knob::after { transform: translateX(0.9rem); background: #fff; }
.switch input:focus-visible + .knob { outline: 2px solid var(--muted); }

/* Transpose key picker: a compact native <select> so it stays small and gets
   the OS picker on phones. Sits in the panel bar beside the Chords/Melody
   switches. */
.transpose {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.9rem;
  user-select: none;
}

.key-select {
  font: inherit;
  font-size: 0.85rem;
  color: var(--fg);
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  padding: 0.15rem 0.4rem;
  cursor: pointer;
  max-width: 9.5rem;
}

.key-select:focus-visible { outline: 2px solid var(--muted); }

/* In the chords bar the key is the middle of three groups and has to stay
   there, so it is sized to its own label ("F ●", "D-") and never grows. */
.chords-bar .transpose { flex: none; }
.chords-bar .key-select {
  font-size: 0.82rem;
  border-radius: 0.45rem;
  padding: 0.24rem 0.2rem 0.24rem 0.45rem;
}

/* Panels stack vertically (mobile portrait); on wide screens two visible
   panels sit side by side — chords left, melody right (§5.4). */
.panels {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.panel {
  min-width: 0;
  position: relative;
  container-type: inline-size;
}

@media (min-width: 860px) {
  .panels.dual { flex-direction: row; align-items: flex-start; gap: 2rem; }
  .panels.dual .panel { flex: 1 1 50%; }

  /* A lone chord panel (no melody sheet) still occupies about half the
     container — the same footprint it has beside the melody — so the grid
     fills a readable half-width column instead of stranding the chords in a
     wide, sparse one. On phones/portrait (< 900px) panels stack full width.
     The book-layout view is the exception: its 8-boxes-per-row lattice gets
     the full pane (the lattice itself caps at 58em and centres). */
  .panels:not(.dual) .panel.chords { width: 50%; align-self: center; }
  .panels:not(.dual) .panel.chords.show-boxes:not(.show-scan) { width: 100%; }
  /* Melody hidden + the user zoomed in: let the lone chords grid spread to the
     full pane width instead of the readable half-column (set in JS by fitAll). */
  .panels:not(.dual) .panel.chords.zoom-wide { width: 100%; }
}

.panel img.scan {
  display: block;
  max-width: 100%;
  margin: 0 auto;
  border-radius: 2px;
  cursor: zoom-in;
}

/* Toggle on a panel with a rendered form (chord grid or abcjs lead sheet):
   rendered ⇄ original scan. Both live in the DOM; .show-scan flips which one
   is visible. The button sits in its own tools row above the content — never
   overlapping the scan — and its icon shows what it switches TO (photo ⇄
   grid/notes). */
.panel-tools {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 0.35rem;
}

/* Empty stand-in matching a real tools row's height, so a toolless melody panel
   lines its top up with the chords panel's grid (see renderTune). */
.panel-tools.tools-spacer { min-height: 1.7rem; }

.panel .scan-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 1.7rem;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 0.4rem;
  color: var(--fg);
  cursor: pointer;
  opacity: 0.9;
}

.panel .scan-toggle svg {
  width: 1rem;
  height: 1rem;
  fill: currentColor;
}

.panel .scan-toggle:hover { opacity: 1; }
.panel .scan-toggle.on { border-color: var(--accent); color: var(--accent); }

/* Debug aid: the crop's filename, in small print under the scan. */
.panel .scan-name {
  font-family: ui-monospace, Consolas, monospace;
  font-size: 0.62rem;
  color: var(--muted);
  text-align: center;
  margin-top: 0.2rem;
  word-break: break-all;
}

/* Only when the panel holds a rendered form does the scan start hidden. */
.panel.has-render img.scan,
.panel.has-render .scan-name { display: none; }
.panel.has-render.show-scan img.scan { display: block; }
.panel.has-render.show-scan .scan-name { display: block; }
/* The extras stay in scan view, as they do in book layout: Links, Listen and
   the rest describe the tune, not the way its chords are drawn. Hiding them
   here made a remembered "scan" look like missing enrichment data. */
.panel.show-scan .grid,
.panel.show-scan .variants,
.panel.show-scan .abc-sheet { display: none; }

/* Book-layout view (.show-boxes): the 8-boxes-per-row lattice replaces the
   4-bar grid and its variants; the extras stay. Scan view wins over it. */
.panel .boxgrid { display: none; }
.panel.show-boxes:not(.show-scan) .boxgrid { display: block; }
.panel.show-boxes .grid,
.panel.show-boxes .variants { display: none; }

/* Segmented view switch (grid / book layout / scan) in the panel tools row. */
.view-seg { display: inline-flex; gap: 0.25rem; }

/* Harmonic-analysis controls (spelling switch + overlay toggle) sit on the LEFT
   of the tools row, aligned with the grid/book-layout content — margin-right:auto
   pushes them left while the view switch stays right. The spelling pills (C · C⁄ii
   · ii) are a one-hot group, kept close together; a gap sets the independent
   overlay (_¬) toggle apart. Hidden in scan view — they don't apply to the photo. */
.analysis-tools {
  display: inline-flex;
  align-items: center;
  margin-right: auto;
}
.analysis-tools .analysis-toggle { margin-left: 0.6rem; }
.panel.show-scan .analysis-tools { display: none; }

/* "⇆ Melody" split toggle (renderTune): a pill in the chords tools row that
   puts the lead sheet beside the grid. Desktop only — on phones the Chords /
   Melody tabs already switch between them. */
.melody-toggle { display: none; }
.melody-toggle svg { width: 0.95rem; height: 0.95rem; fill: currentColor; }
.melody-toggle .mt-glyph { font-size: 0.9rem; line-height: 1; }
@media (min-width: 860px) {
  .melody-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    margin-right: 0.5rem;
    background: none;
    border: 1px solid var(--border);
    border-radius: 0.4rem;
    color: var(--muted);
    font-size: 0.72rem;
    line-height: 1.2;
    padding: 0.25rem 0.55rem;
    cursor: pointer;
    white-space: nowrap;
  }
  .melody-toggle:hover { color: var(--fg); border-color: var(--accent); }
  .melody-toggle.on {
    background: var(--chip-bg);
    border-color: var(--accent);
    color: var(--accent-ink);
  }
}

/* ------------------------------------------ melody lead sheet (abcjs) */

/* abcjs draws with fill/stroke: currentColor, so the sheet follows the
   theme through the CSS color property. */
.abc-sheet {
  color: var(--fg);
  max-width: 52em;
  margin: 0 auto;
}

.abc-sheet svg { max-width: 100%; height: auto; }

/* Zoomed past 100% (the footer's − / + on the Melody tab): the staves are wider
   than the pane, so this box pans sideways instead of the page. The scroller is
   .abc-scroll and not the .panel — a scrolling flex item loses its automatic
   minimum size, and the column would then collapse the sheet's height. */
.panel.melody.zoomed .abc-scroll { overflow-x: auto; }

/* The note under the melody synth's cursor (melody_play.js). */
.abc-sheet .abcjs-note.abc-playing,
.abc-sheet .abcjs-rest.abc-playing,
.abc-sheet .abc-playing path { fill: var(--accent); }

/* abcjs's own transport widget, loaded only so the synth has somewhere to
   write its tempo — the app's ▶ and ♩= buttons are the UI. Off-screen rather
   than display:none, which abcjs's layout code does not expect. */
.melody-synth-host {
  position: absolute;
  left: -9999px;
  top: 0;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Under the staves: what the engraving is showing that the verified file does
   not (a variant's chords). */
.abc-note {
  color: var(--muted);
  font-size: 0.8rem;
  margin: 0.4rem 0 0;
  text-align: center;
}

.abc-error {
  color: #c96e6e;
  font-size: 0.85rem;
  margin: 0.5rem 0;
}

/* ------------------------------------------- fullscreen scan (overlay) */

/* Click on the image toggles .magnified; click on the backdrop / ✕ closes. */
#scanOverlay {
  display: flex;
  align-items: center;
  justify-content: center;
  position: fixed;
  inset: 0;
  z-index: 50;
  background: rgba(0, 0, 0, 0.82);
  padding: 1rem;
  cursor: zoom-out;
}

#scanOverlay[hidden] { display: none; }

#scanOverlay img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  cursor: zoom-in;
  background: #fff;
}

#overlayClose {
  position: fixed;
  top: 0.6rem;
  right: 0.9rem;
  z-index: 51;
  width: 2.2rem;
  height: 2.2rem;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.5);
  color: #fff;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}

/* Magnified: image at up to natural size (capped at 2.5× the viewport on
   small screens), panned by scrolling. */
#scanOverlay.magnified {
  overflow: auto;
  align-items: flex-start;
  justify-content: flex-start;
  padding: 0;
}

#scanOverlay.magnified img {
  max-width: 250vw;
  max-height: none;
  object-fit: initial;
  cursor: zoom-out;
}

/* --------------------------------------------------- grid zoom controls */

/* Grid zoom lives in the detail footer's control row. */
#gridZoom {
  display: inline-flex;
  gap: 0.35rem;
}

#gridZoom button {
  width: 1.9rem;
  height: 1.9rem;
  border-radius: 50%;
  background: var(--panel);
  color: var(--fg);
  border: 1px solid var(--border);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  opacity: 0.85;
}

#gridZoom button:hover:not(:disabled) { opacity: 1; }
/* Nothing zoomable in view (a scan, or the Similar tab). */
#gridZoom button:disabled { opacity: 0.35; cursor: default; }

/* ----------------------------------------------------------- tune list */

.tune-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 0.55rem;
  margin: 0.1rem 0;
  border-radius: 0.7rem;
  cursor: pointer;
  border: 1px solid transparent;
}

.tune-item:hover { background: var(--panel); }
.tune-item.active { background: var(--panel); }
.tune-item.current { background: var(--chip-bg); border-color: var(--accent); }

/* Key chip on the right of each row. */
.tune-item .row-key {
  flex: none;
  font-size: 0.72rem;
  color: var(--accent-ink);
  background: var(--chip-bg);
  border-radius: 0.5rem;
  padding: 0.15rem 0.45rem;
  white-space: nowrap;
}

/* Availability icons (§5.2): two fixed slots — chord grille | melody — so
   the columns stay aligned; gray = scan only, green = digitized. */
.tune-item .icons {
  display: inline-flex;
  gap: 0.25rem;
  flex: none;
}

.tune-item .icon {
  width: 0.8rem;
  height: 0.8rem;
  display: inline-block;
}

.tune-item .icon svg {
  width: 100%;
  height: 100%;
  display: block;
  fill: var(--icon-off);
}

.tune-item .icon.ok svg { fill: var(--ok); }

.tune-item .txt { min-width: 0; }
.tune-item .t { display: block; font-size: 0.92rem; }
.tune-item .c { display: block; font-size: 0.78rem; color: var(--muted); }

.list-empty {
  padding: 1.5rem 0.75rem;
  color: var(--muted);
  font-size: 0.9rem;
  text-align: center;
}
.list-empty button {
  display: block;
  margin: 0.6rem auto 0;
  background: none;
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  color: var(--fg);
  font: inherit;
  font-size: 0.85rem;
  padding: 0.35rem 0.75rem;
  cursor: pointer;
}
.list-empty button:hover { border-color: var(--accent); }

/* --------------------------------------------------- harmonic chips */

/* Chip rows for the collapsible "Tags" section (opening degree + section-key
   modulations, fingerprint family + tags). The old always-visible summary
   block that centred these below the grid has been retired. */
.harm-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.4rem;
}

.harm-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 0.35rem;
  padding: 0.16rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--chip-bg);
  font-size: 0.78rem;
  line-height: 1.3;
  white-space: nowrap;
}

.harm-chip .harm-label {
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.harm-chip .harm-val { color: var(--fg); }

/* Main key: the headline chip — accent border + accent label. */
.harm-chip.key {
  border-color: var(--accent-ink);
}

.harm-chip.key .harm-label { color: var(--accent-ink); }
.harm-chip.key .harm-val { font-weight: 600; }

/* Section key = a per-section modulation; amber to set it apart. */
.harm-chip.section {
  border-color: var(--mod-ink);
}

.harm-chip.section .harm-label { color: var(--mod-ink); }

/* Fingerprint family + tags: quieter, second row. */
.harm-tags .harm-chip {
  font-size: 0.72rem;
  padding: 0.13rem 0.5rem;
  background: transparent;
  color: var(--muted);
}

.harm-chip.family {
  border-style: dashed;
  font-weight: 600;
}

.harm-chip.family .harm-val { color: var(--fg); }
.harm-chip.tag .harm-val { color: var(--muted); }

/* Per-section prose analysis inside the collapsible extras. */
.harm-sections {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.3rem 0.7rem;
  margin: 0.5rem 0 0.25rem;
}

.harm-sections dt {
  font-weight: 700;
  color: var(--fg);
  font-family: var(--font-cond);
}

.harm-sections dd { margin: 0; }

.harm-modnote { color: var(--fg); }

