/**
 * scale-page.css — Scale page v2 styles.
 * ============================================================================
 * Class prefix: `.spg-*` (Scale PaGe).  No element selectors at the page
 * level — every rule keys off a class name to keep the page hermetic.
 *
 * Design tokens (CMS-overridable via CSS custom properties at .spg-root):
 *   --spg-control-gap        gap between control fields
 *   --spg-tab-radius         pill-tab corner radius
 *   --spg-tab-active-bg      active tab background
 *   --spg-tab-active-fg      active tab foreground
 *   --spg-board-bg           board area background (paper-feel)
 */

/* Control-bar contextual visibility (scale page) — mirror of the
   chord-page rules.  `data-active-tab` is written onto the
   ctrl-grid by `_syncControlsActiveTab`; per-cell `data-ctrl-key`
   identifies the knob.  Per user 2026-05-13. */
/* Chords / Suites / Articles tabs — hide voicing-/fingering-related
   cells; KEY & DISPLAY stays.  All + Fingerings tabs leave every
   cell visible (the page's primary surfaces). */
.scp-ctrl-grid[data-active-tab="chords"]   > .scp-ctrl-cell[data-ctrl-key="fingerings"],
.scp-ctrl-grid[data-active-tab="chords"]   > .scp-ctrl-cell[data-ctrl-key="ghosts"],
.scp-ctrl-grid[data-active-tab="suites"]   > .scp-ctrl-cell[data-ctrl-key="fingerings"],
.scp-ctrl-grid[data-active-tab="suites"]   > .scp-ctrl-cell[data-ctrl-key="ghosts"],
.scp-ctrl-grid[data-active-tab="articles"] > .scp-ctrl-cell[data-ctrl-key="fingerings"],
.scp-ctrl-grid[data-active-tab="articles"] > .scp-ctrl-cell[data-ctrl-key="ghosts"] {
  display: none;
}

.spg-root {
  --spg-control-gap:    16px;
  --spg-tab-radius:     6px;
  --spg-tab-active-bg:  var(--accent, #2E5B8A);
  --spg-tab-active-fg:  #fff;
  --spg-board-bg:       var(--surface, #fff);

  display: flex;
  flex-direction: column;
  gap: 24px;
  padding: 24px;
  max-width: 1280px;
  margin: 0 auto;
  color: var(--text, #1a1a18);
  font-family: var(--font-ui, system-ui, sans-serif);
}

/* ── Controls ─────────────────────────────────────────────────────── */
/* `.spg-controls` removed 2026-05-12 — the legacy `_renderControls` chain
   in page-controls.js (and its supporting helpers) were stripped because
   InlineCollectionStrip + ScaleListPane + ScaleSettingsDialog own those
   controls now.  `.spg-field` survives because `_buildSystemTabs` (the
   only surviving legacy method) still emits it. */

.spg-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.spg-field-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-3, #888);
}

.spg-select {
  padding: 6px 10px;
  font-size: 14px;
  border: 1px solid var(--border, #ccc);
  border-radius: 4px;
  background: var(--surface, #fff);
  color: var(--text, #1a1a18);
  min-width: 140px;
}

.spg-tabs {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  background: var(--surface, #fff);
  border: 1px solid var(--border, #ccc);
  border-radius: var(--spg-tab-radius);
}

.spg-tab {
  padding: 5px 10px;
  font-size: 12px;
  font-weight: 500;
  border: none;
  background: transparent;
  color: var(--text-2, #555);
  cursor: pointer;
  border-radius: calc(var(--spg-tab-radius) - 2px);
  transition: background 120ms, color 120ms;
}

.spg-tab:hover {
  background: var(--surface-2, #f0eee9);
}

.spg-tab--active {
  background: var(--spg-tab-active-bg);
  color: var(--spg-tab-active-fg);
}

.spg-tab--active:hover {
  background: var(--spg-tab-active-bg);
}

/* User-custom tabs get a subtle accent so they read as "yours". */
.spg-tab--user {
  font-style: italic;
}

/* Admin-curated tabs get a small dot — F6. */
.spg-tab--admin-curated::before {
  content: '';
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent, #2E5B8A);
  margin-right: 5px;
  vertical-align: middle;
}

/* "+ Add custom" button — distinct from real tabs. */
.spg-tab--add {
  font-weight: 700;
  font-size: 14px;
  padding: 5px 9px;
  color: var(--text-3, #888);
  border-left: 1px dashed var(--border, #ccc);
  margin-left: 4px;
  border-radius: calc(var(--spg-tab-radius) - 2px);
}

.spg-tab--add:hover {
  color: var(--accent, #2E5B8A);
  background: var(--surface-2, #f0eee9);
}

/* ── Custom-fingering editor card ─────────────────────────────────── */

.spg-edit-card {
  --spg-edit-marker-color:  var(--accent, #2E5B8A);
  --spg-edit-marker-label-fg: var(--accent, #2E5B8A);

  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px;
  background: var(--surface, #fff);
  border: 2px dashed var(--accent, #2E5B8A);
  border-radius: 8px;
  margin-top: 16px;
}

.spg-edit-header {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

.spg-edit-name {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-3, #888);
}

.spg-edit-name-input {
  padding: 6px 10px;
  font-size: 14px;
  font-weight: normal;
  text-transform: none;
  letter-spacing: normal;
  border: 1px solid var(--border, #ccc);
  border-radius: 4px;
  background: var(--surface, #fff);
  color: var(--text, #1a1a18);
  min-width: 240px;
}

/* Category cell — same label chrome as Name + select dropdown
   alongside an inline new-folder input. */
.spg-edit-category {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-3, #888);
}
.spg-edit-category-select {
  padding: 6px 10px;
  font-size: 14px;
  font-weight: normal;
  text-transform: none;
  letter-spacing: normal;
  border: 1px solid var(--border, #ccc);
  border-radius: 4px;
  background: var(--surface, #fff);
  color: var(--text, #1a1a18);
  min-width: 200px;
  cursor: pointer;
}
.spg-edit-newfolder {
  display: inline-flex;
  margin-top: 6px;
}
.spg-edit-newfolder-input {
  padding: 6px 10px;
  font-size: 14px;
  font-weight: normal;
  text-transform: none;
  letter-spacing: normal;
  border: 1px solid var(--accent, #e8853c);
  border-radius: 4px;
  background: var(--surface, #fff);
  color: var(--text, #1a1a18);
  min-width: 200px;
}

.spg-edit-hint {
  font-size: 12px;
  color: var(--text-3, #888);
  font-style: italic;
}

.spg-edit-board {
  position: relative;
}

.spg-edit-svg {
  cursor: crosshair;
}

.spg-edit-range-marker {
  stroke: var(--spg-edit-marker-color);
  stroke-width: 2;
  stroke-dasharray: 4 3;
  pointer-events: none;
}

/* Main-board cmd+click range anchor (#22) — same dashed accent language as
   the editor's range markers, drawn directly on the read-only board. */
.spg-range-anchor-line {
  stroke: var(--accent, #2E5B8A);
  stroke-width: 2;
  stroke-dasharray: 4 3;
  pointer-events: none;
}
.spg-range-anchor-label {
  fill: var(--accent, #2E5B8A);
  font-family: var(--font-ui, system-ui, sans-serif);
  font-size: 14px;
  font-weight: 700;
  pointer-events: none;
}

/* Range-pick hint toast (#23) — appears after the first cmd+click so the
   gesture is self-documenting (replaces the discoverability button). */
.spg-range-hint {
  position: fixed;
  left: 50%;
  bottom: 28px;
  transform: translateX(-50%);
  background: var(--accent, #2E5B8A);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  padding: 9px 16px;
  border-radius: 999px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.22);
  z-index: 9500;
  pointer-events: none;
  white-space: nowrap;
}

.spg-edit-range-marker-label {
  fill: var(--spg-edit-marker-label-fg);
  font-family: var(--font-ui, system-ui, sans-serif);
  font-size: 14px;
  font-weight: 700;
}

.spg-edit-footer {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-top: 8px;
  border-top: 1px solid var(--border, #ddd);
}

.spg-edit-default-toggle {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--text-2, #555);
  cursor: pointer;
  user-select: none;
}

.spg-edit-spacer {
  flex: 1;
}

.spg-edit-btn {
  padding: 6px 14px;
  font-size: 13px;
  font-weight: 600;
  border: 1px solid var(--border, #ccc);
  border-radius: 4px;
  cursor: pointer;
  background: var(--surface, #fff);
  color: var(--text, #1a1a18);
  transition: background 120ms, color 120ms;
}

.spg-edit-btn--cancel:hover {
  background: var(--surface-2, #f0eee9);
}

.spg-edit-btn--clear-range:hover:not(:disabled) {
  background: var(--surface-2, #f0eee9);
}
.spg-edit-btn:disabled {
  opacity: 0.45;
  cursor: default;
}

.spg-edit-btn--save {
  background: var(--accent, #2E5B8A);
  border-color: var(--accent, #2E5B8A);
  color: #fff;
}

.spg-edit-btn--save:hover {
  filter: brightness(1.1);
}

/* Phase 15 — Status pill in editor footer.  Draft = muted grey,
   Published = accent.  Single click toggles. */
.spg-edit-btn--status {
  font-weight: 500;
}
.spg-edit-btn--status-draft {
  background: var(--muted-soft, #eceef2);
  color: var(--muted-strong, #5a6068);
  border-color: var(--muted, #b9bcc1);
}
.spg-edit-btn--status-published {
  background: var(--accent, #2E5B8A);
  color: #fff;
  border-color: var(--accent, #2E5B8A);
}
.spg-edit-btn--status:hover {
  filter: brightness(1.05);
}

/* ── Override history panel (admin-only modal) ───────────────────── */
.fly-ovh-overlay {
  position: fixed; inset: 0;
  background: rgba(20, 20, 20, 0.55);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  z-index: 9000;
  padding: 48px 16px;
  overflow-y: auto;
}
.fly-ovh-modal {
  background: var(--surface, #fff);
  color: var(--text, #1a1a18);
  border: 1px solid var(--border, #ccc);
  border-radius: 10px;
  box-shadow: 0 12px 48px rgba(0, 0, 0, 0.25);
  width: min(960px, 100%);
  max-height: calc(100vh - 96px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.fly-ovh-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 20px;
  border-bottom: 1px solid var(--border, #e0ddd5);
}
.fly-ovh-header h3 { margin: 0; font-size: 16px; font-weight: 700; }
.fly-ovh-close {
  background: transparent; border: 0; font-size: 24px; line-height: 1;
  cursor: pointer; color: var(--text-muted, #666);
  padding: 4px 8px;
}
.fly-ovh-close:hover { color: var(--text, #1a1a18); }
.fly-ovh-body {
  padding: 12px 20px 20px;
  overflow-y: auto;
  flex: 1 1 auto;
  min-height: 0;
}
.fly-ovh-empty, .fly-ovh-error {
  padding: 24px 8px;
  color: var(--text-muted, #666);
  font-size: 14px;
}
.fly-ovh-error { color: #c43; }
.fly-ovh-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.fly-ovh-table th,
.fly-ovh-table td {
  text-align: left;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border, #eee);
  vertical-align: middle;
}
.fly-ovh-table th {
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted, #666);
}
.fly-ovh-when  { white-space: nowrap; color: var(--text-muted, #666); }
.fly-ovh-who   { white-space: nowrap; }
.fly-ovh-type  { font-family: monospace; font-size: 12px; }
.fly-ovh-act--save   { color: #297a3b; font-weight: 600; }
.fly-ovh-act--delete { color: #c43;    font-weight: 600; }
.fly-ovh-scope { font-family: monospace; font-size: 12px; max-width: 360px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fly-ovh-actions { white-space: nowrap; text-align: right; }
.fly-ovh-btn {
  padding: 5px 11px;
  font-size: 12px;
  font-weight: 600;
  border: 1px solid var(--accent, #2E5B8A);
  border-radius: 4px;
  background: var(--surface, #fff);
  color: var(--accent, #2E5B8A);
  cursor: pointer;
}
.fly-ovh-btn:hover { background: var(--accent, #2E5B8A); color: #fff; }
.fly-ovh-btn:disabled { opacity: 0.6; cursor: default; }

/* ── Layout shell — single column (scale picker is a popover) ─────── */

.spg-shell-main {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
}

.spg-shell-area {
  position: relative;
}

.spg-shell-panels {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* `.spg-scale-trigger` + `-label` + `-caret` removed 2026-05-12 — the
   trigger button was emitted by `_buildScalePicker`, which was stripped
   from page-controls.js when the legacy controls bar was retired.  The
   ScaleListPane (left pane) now owns scale selection. */

/* ── Scale list popover (overlay) ─────────────────────────────────── */

.spg-popover-scrim {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.18);
  z-index: 90;
}

.spg-popover {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: 320px;
  max-width: 90vw;
  background: var(--surface, #fff);
  border-right: 1px solid var(--border, #ddd);
  box-shadow: 2px 0 12px rgba(0, 0, 0, 0.12);
  z-index: 100;
  display: flex;
  flex-direction: column;
  transform: translateX(-100%);
  transition: transform 180ms ease;
}

.spg-popover--open {
  transform: translateX(0);
}

.spg-popover-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--border, #ddd);
}

.spg-popover-title {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
  color: var(--text, #1a1a18);
}

.spg-popover-close {
  background: none;
  border: none;
  font-size: 16px;
  color: var(--text-2, #666);
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 4px;
}

.spg-popover-close:hover {
  background: var(--surface-2, #f0eee9);
  color: var(--text, #1a1a18);
}

.spg-popover-filter {
  margin: 12px 16px 8px;
  padding: 8px 12px;
  font-size: 14px;
  border: 1px solid var(--accent, #2E5B8A);
  border-radius: 4px;
  background: var(--surface, #fff);
  color: var(--text, #1a1a18);
  outline: none;
}

.spg-popover-filter:focus {
  box-shadow: 0 0 0 2px var(--accent-soft, rgba(46, 91, 138, 0.2));
}

.spg-popover-list {
  flex: 1;
  overflow-y: auto;
  padding: 4px 0 16px;
}

.spg-popover-empty {
  padding: 16px;
  font-size: 13px;
  font-style: italic;
  color: var(--text-3, #999);
}

.spg-popover-group {
  display: flex;
  flex-direction: column;
}

.spg-popover-group-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-3, #999);
  padding: 12px 16px 4px;
}

.spg-popover-item {
  text-align: left;
  padding: 8px 16px;
  font-size: 14px;
  border: none;
  background: transparent;
  color: var(--text, #1a1a18);
  cursor: pointer;
}

.spg-popover-item:hover {
  background: var(--surface-2, #f7f6f3);
}

.spg-popover-item--active {
  background: var(--accent-soft, rgba(46, 91, 138, 0.1));
  color: var(--accent, #2E5B8A);
  font-weight: 600;
}

/* ── FingeringArea: browse + list views ────────────────────────────
   Fretboard width = control-panel width (full main column).  Browse
   buttons hang OUTSIDE that width, sitting in the page gutter to the
   left/right of the column.  Both browse and list modes use the same
   `.spg-area-card` so the visible diagram width is identical between
   modes — only the buttons differ. */

.spg-area {
  position: relative;
  /* No margin — fretboard is the full width of the main column,
     same as the control panel above it.  Buttons overflow outward. */
}

/* ── Layout-stability for the fretboard area (chord + scale page) ─
   The "shake" reported 2026-05-10 had two distinct sources, both
   fixed at the source rather than via CSS height locks:
     1. Panels were re-rendering on every state change → fixed via
        signature gating in the panel base class.
     2. `Fretboard.layout` recomputes integer-rounded `dx`/`dy`/
        `PADT`/`PADB` on every redraw → near-identical `clientWidth`
        values produced different `L.H` between draws.  Fixed by
        caching the layout in VoicingBoard / FingeringBoard; only
        the ResizeObserver path (real width change) recomputes.
   No `height` / `min-height` pinning here — the SVG dimensions are
   now stable per-config, and the card sizes naturally to the SVG.
   Half-window viewports get a proportionally smaller card with no
   trailing empty space. */

.spg-area-boards {
  width: 100%;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* List view COLS — lay the stacked fretboard cards out in 1-4 columns
   (parity with the Collection grid's COLS).  data-fa-cols lives on the
   `.spg-area` root; only List view sets > 1.  Responsive: collapses on
   narrow viewports so boards stay readable.  Per user 2026-06-13. */
.spg-area--list[data-fa-cols="2"] .spg-area-boards,
.spg-area--list[data-fa-cols="3"] .spg-area-boards,
.spg-area--list[data-fa-cols="4"] .spg-area-boards {
  display: grid;
  align-items: start;
}
.spg-area--list[data-fa-cols="2"] .spg-area-boards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.spg-area--list[data-fa-cols="3"] .spg-area-boards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.spg-area--list[data-fa-cols="4"] .spg-area-boards { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 1100px) {
  .spg-area--list[data-fa-cols="3"] .spg-area-boards,
  .spg-area--list[data-fa-cols="4"] .spg-area-boards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 700px) {
  .spg-area--list[data-fa-cols="2"] .spg-area-boards,
  .spg-area--list[data-fa-cols="3"] .spg-area-boards,
  .spg-area--list[data-fa-cols="4"] .spg-area-boards { grid-template-columns: 1fr; }
}

/* List-view COLS stepper (fingerings control cell).  "Cols" label +
   1-4 chip buttons, sitting right beside the View switch. */
.spg-fview-switch .scp-switch-state { min-width: 0; }   /* close the gap before Cols */
.spg-list-cols {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: 6px;
}
.spg-list-cols-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-3, #888);
}
.spg-list-cols-btn {
  min-width: 24px;
  padding: 3px 8px;
  border: 1px solid var(--border, #e0ddd5);
  background: var(--surface, #fff);
  color: var(--text-2, #555);
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  border-radius: 4px;
  cursor: pointer;
}
.spg-list-cols-btn:hover { background: var(--surface-2, #f7f6f3); color: var(--text, #1a1a18); }
.spg-list-cols-btn.active,
.spg-list-cols-btn.active:hover { background: var(--accent, #e8853c); color: #fff; border-color: var(--accent, #e8853c); }

/* Quiet empty-state placeholder — used via renderAreaEmpty()
   (shared/music-page/area-card.js) whenever a fingering system
   legitimately resolves to zero positions.  Mirrors chord-page.css's
   .cpg-area-empty (own class per the CSS-prefix doctrine: scale-page
   owns `.spg-*`).  Never used for developer-facing error text — see
   CLAUDE.md owner rule 2026-07-04. */
.spg-area-empty {
  padding: var(--space-lg) var(--space-sm);
  text-align: center;
  font-style: italic;
  color: var(--text-3, #888);
}

/* Browse toolbar — sits ABOVE the bare fretboard as a transparent
   header.  Auto-wrapping layout: nav and actions are both flex
   items with `flex-wrap: wrap` on the parent, so when the row
   can't fit them side-by-side they reflow onto separate rows.
   No fixed breakpoint — pure constraint-driven detection.  The
   counter text can wrap internally too, soft-breaking at the `›`
   separators on very narrow viewports. */
/* Tokens applied per CLAUDE.md design-tokens doctrine.  The card
   toolbar chrome is shared with chord page via
   assets/js/shared/music-page/area-card.js. */
.spg-area-card-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-xs);
  background: transparent;
  border: none;
  /* Single-row at all widths.  Wrapping the toolbar shifts the
     fretboard down — bad optics.  When the canvas can't hold the
     full layout, the middle counter text truncates instead. */
  flex-wrap: nowrap;
  min-width: 0;
  /* Pin toolbar height so it doesn't change between Browse and List
     views.  Browse view shows Prev / counter / Next buttons (taller);
     List view shows just a label (shorter).  FIXED height — not
     min-height — eliminates 1px sub-pixel drift the user reported
     2026-06-01 ("still moves about 1px").  Height = nav-button
     height + vertical padding.  Route-scoped override uses 10px×2
     padding; base uses tokens.  Both pin all three (height +
     min-height + max-height) to fully lock the box. */
  height:     calc(var(--ctl-h-md) + (var(--space-sm) * 2));
  min-height: calc(var(--ctl-h-md) + (var(--space-sm) * 2));
  max-height: calc(var(--ctl-h-md) + (var(--space-sm) * 2));
  box-sizing: border-box;
}
/* Nav (Prev + counter + Next) keeps Prev / Title / Next on a SINGLE
   horizontal row.  The counter text in the middle is allowed to soft-
   wrap internally so a long title grows tall instead of pushing
   Prev/Next to their own rows.  When the canvas can't fit nav +
   actions side-by-side, only the actions group wraps below — toolbar
   stays at MAX 2 rows.  No `flex-wrap` here on purpose. */
.spg-area-card-toolbar > .spg-area-card-nav {
  flex: 1 1 auto;
  min-width: 0;
}
.spg-area-card-toolbar > .spg-area-card-actions {
  flex: 0 0 auto;
}
/* Counter text stays on ONE line — toolbar must never wrap (wrapping
   shifts the fretboard down).  The middle text is the only flexible
   element; it shrinks and ellipsis-truncates when the toolbar can't
   fit Prev / title / Next / actions side-by-side.  Title is the
   thing that gives, not the buttons. */
.spg-area-card-counter {
  flex: 1 1 0;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Right-side action group — Copy / Export (FretboardActions),
   Add to Collection, and Top.  Mirrors the legacy `panel-bar-right`
   container's role on `.boards-area` cards. */
.spg-area-card-actions {
  display: inline-flex;
  align-items: center;
  gap: var(--space-sm);
  flex: 0 0 auto;
}

/* On-board "− 100% +" zoom control (shared by scale + chord areas). */
.spg-zoom {
  display: inline-flex;
  align-items: center;
  gap: 1px;
}
.spg-zoom-btn,
.spg-zoom-label {
  font: inherit;
  line-height: 1;
  height: var(--ctl-h-sm, 1.7rem);
  border: 1px solid var(--border, #d8d4cc);
  background: var(--surface, #fff);
  color: var(--text, #2a2a26);
  cursor: pointer;
  transition: background var(--t-fast, 120ms);
}
.spg-zoom-btn {
  width: var(--ctl-h-sm, 1.7rem);
  padding: 0;
  font-size: var(--font-base, 1rem);
  font-weight: 700;
}
.spg-zoom-btn:first-child  { border-radius: var(--radius-sm, 4px) 0 0 var(--radius-sm, 4px); }
.spg-zoom-btn:last-child   { border-radius: 0 var(--radius-sm, 4px) var(--radius-sm, 4px) 0; }
.spg-zoom-label {
  min-width: 3.4em;
  padding: 0 var(--space-xs, 6px);
  font-size: var(--font-xs, 0.78rem);
  font-variant-numeric: tabular-nums;
  text-align: center;
  border-left: 0;
  border-right: 0;
}
.spg-zoom-btn:hover:not(:disabled),
.spg-zoom-label:hover { background: var(--surface-2, #f3f1ec); }
.spg-zoom-btn:disabled { opacity: 0.4; cursor: default; }

.spg-area-card-top {
  font-size: var(--font-xs);
  font-weight: var(--weight-medium);
  color: var(--text-3, #888);
  text-decoration: none;
  letter-spacing: 0.02em;
  white-space: nowrap;
  padding: 0 var(--space-xs);
  transition: color var(--t-fast);
}
.spg-area-card-top:hover { color: var(--accent, #e8853c); }

/* ── Collection-mode back link ──────────────────────────────────── */
.spg-collection-back-row {
  padding: var(--space-xs) 0 var(--space-sm);
}
.spg-collection-back-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-size: var(--font-sm);
  font-weight: var(--weight-semibold);
  color: var(--accent, #e8853c);
  text-decoration: none;
  letter-spacing: 0.02em;
}
.spg-collection-back-link:hover { text-decoration: underline; }

/* ── Auto-wrapping panel row: Properties | Modes | Circle ────────
   No fixed breakpoint — `flex-wrap: wrap` + each panel's `min-width`
   makes the layout self-detecting: when the row can't fit all three
   panels at their minimum sizes, the trailing items naturally wrap
   to a new row.  Properties + Modes claim equal flexible space when
   they fit; Circle stays fixed at 240 px (its natural square).  When
   the canvas shrinks past the combined minimums, items reflow.   */
.spg-panel-row {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 16px;
  margin-bottom: 16px;
}
.spg-panel-row .spg-panel-host--inline {
  display: flex;
  /* Default min-width that prevents flex items from squeezing
     below readable size.  Overridden per slot below. */
  min-width: 320px;
}
.spg-panel-row .spg-panel-host--inline > .spg-panel { flex: 1; }
/* Properties → flexible, prefers ~400 px, can shrink to 320 px
   before wrapping. */
.spg-panel-row--top > .spg-panel-host--inline:nth-child(1) {
  flex: 1 1 400px;
  min-width: 320px;
}
/* Modes/Inversions table → flexible, prefers wide, never narrower
   than its readable threshold.  Wraps to its own row when the
   remaining width can't accommodate it. */
.spg-panel-row--top > .spg-panel-host--inline:nth-child(2) {
  flex: 1 1 360px;
  min-width: 320px;
}
/* Circle → fixed natural square, no shrink. */
.spg-panel-row--top > .spg-panel-host--inline:nth-child(3) {
  flex: 0 0 240px;
  min-width: 240px;
}

/* Overlap guard (intermittent panel collision reported ~half-screen width):
   a flex item won't shrink below its content unless min-width is 0, so a wide
   Modes/Inversions table used to spill out (overflow:visible) and overlap the
   neighbouring Scale Circle panel.  Let panels shrink to their flex allotment
   and let the table wrap to fit instead of overflowing. */
.spg-panel-row .spg-panel { min-width: 0; }
.spg-panel--modes table,
.spg-panel--ischord table { width: 100%; }
.spg-panel--modes table th, .spg-panel--modes table td,
.spg-panel--ischord table th, .spg-panel--ischord table td { overflow-wrap: anywhere; }

/* ── Modes panel header — title on left, Perspective on right. */
.spg-modes-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
}
.spg-modes-head .spg-panel-title { margin: 0; }
.spg-modes-perspective .scp-btn-group-btn {
  font-size: 11px;
  padding: 3px 8px;
}

/* ── Scale Explorer table styles, ported for the unified scale page.
     Rules duplicate Scale Explorer's `.info-tbl` / `.modes-tbl`
     verbatim so PROPERTIES + MODES cards render with the exact same
     typography, spacing, hover, and current-row highlight. */
.spg-info-tbl  { width: 100%; border-collapse: collapse; font-size: 13px; }
.spg-info-tbl th {
  text-align: left;
  color: var(--text-2);
  font-weight: 600;
  padding: 5px 12px 5px 0;
  white-space: nowrap;
  width: 130px;
  border-bottom: 1px solid var(--surface-2);
}
.spg-info-tbl td {
  padding: 5px 0;
  font-family: var(--font-mono, 'SF Mono', 'Consolas', monospace);
  font-weight: 500;
  border-bottom: 1px solid var(--surface-2);
}

.spg-modes-tbl { width: 100%; border-collapse: collapse; font-size: 12px; }
.spg-modes-tbl th {
  text-align: left;
  padding: 5px 10px;
  color: var(--text-2);
  font-weight: 600;
  border-bottom: 1px solid var(--border);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.3px;
}
.spg-modes-tbl td { padding: 5px 10px; border-bottom: 1px solid var(--surface-2); }
.spg-modes-tbl .mt-name { font-weight: 600; }
.spg-modes-tbl .mt-name-text {
  display: block;
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.spg-modes-tbl .mt-unnamed { color: var(--text-2); font-style: italic; }
.spg-modes-tbl .mt-formula {
  font-family: var(--font-mono, 'SF Mono', 'Consolas', monospace);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.spg-modes-tbl .mt-notes {
  font-family: var(--font-mono, 'SF Mono', 'Consolas', monospace);
  /* Prefer single-line; the auto-layout table grows to accommodate
     when the panel has the room, and falls back to wrapping only
     when the panel is genuinely narrow. */
  white-space: nowrap;
}
.spg-modes-tbl .mt-pcs {
  font-family: var(--font-mono, 'SF Mono', 'Consolas', monospace);
  color: var(--text-2);
  font-size: 11px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.spg-modes-tbl tbody tr { cursor: pointer; transition: background .1s; }
.spg-modes-tbl tbody tr:hover { background: var(--accent-bg, rgba(232,135,74,0.06)); }
.spg-modes-tbl tr.mt-current  { background: var(--accent-bg-hover, rgba(232,135,74,0.15)); }
.spg-modes-tbl .mt-degree { color: var(--text-2); width: 24px; text-align: center; }
.spg-modes-tbl .mt-aka { font-size: 10px; color: var(--text-3); line-height: 1.3; margin-top: 2px; }
.spg-modes-tbl tr.mt-unnamed { cursor: default; }
.spg-modes-tbl tr.mt-unnamed:hover { background: transparent; }

/* ── Summary Table panel (advanced mode only) ─────────────────────────
   Windowed/scrollable variant of the same .info-tbl typography — a
   capped-height scroll region so 2000+ rows don't blow out the page. */
.spg-summary-table-scroll {
  max-height: 26rem;
  overflow-y: auto;
  border: var(--border-w) solid var(--border, #ddd);
  border-radius: var(--radius-sm);
}
.spg-summary-table { font-size: var(--font-sm); }
.spg-summary-table thead th {
  position: sticky;
  top: 0;
  background: var(--surface, #fff);
  text-align: left;
  padding: var(--space-xs) var(--space-sm);
  color: var(--text-2);
  font-weight: var(--weight-semibold);
  border-bottom: var(--border-w) solid var(--border, #ddd);
}
.spg-summary-table td {
  padding: var(--space-xs) var(--space-sm);
  border-bottom: var(--border-w) solid var(--surface-2);
  font-family: var(--font-mono, 'SF Mono', 'Consolas', monospace);
}
.spg-summary-row:hover { background: var(--accent-bg, rgba(232,135,74,0.06)); }

/* ── ScaleNavigator (advanced mode only, buttons-only) ────────────────
   See scale-navigator.js docblock: no keyboard axis bound — the page's
   Focus-mode arrow keys are already fully claimed by fingering-position
   stepping, so this is intentionally click-only. */
.spg-navigator-host { margin-bottom: var(--space-md); }
.spg-navigator {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  padding: var(--space-sm) var(--space-md);
  background: var(--surface-2, #f7f6f3);
  border: var(--border-w) solid var(--border, #ddd);
  border-radius: var(--radius-md);
}
.spg-navigator-row {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}
.spg-navigator-label {
  font-size: var(--font-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-2);
  margin-right: var(--space-xs);
}
.spg-navigator-btn {
  min-width: 2rem;
  padding: var(--space-xs) var(--space-sm);
  border: var(--border-w) solid var(--border, #ddd);
  border-radius: var(--radius-sm);
  background: var(--surface, #fff);
  cursor: pointer;
}
.spg-navigator-btn:hover:not(:disabled) { background: var(--accent-bg, rgba(232,135,74,0.06)); }
.spg-navigator-btn:disabled { opacity: 0.4; cursor: default; }

.spg-area-card-nav {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex: 1 1 auto;
  min-width: 0;
  flex-wrap: nowrap;
}
.spg-area-card-nav > .spg-area-nav { flex: 0 0 auto; }

/* Static label variant - used in list/overlay mode.  Must TRUNCATE
   (ellipsis) rather than spill: the toolbar is locked to a single
   fixed-height row, so a long label like "Major · Strings 1-2-4 · 6
   positions" was overflowing its (shrunk) flex box and overlapping the
   action buttons (Reset / Make default / … / Export / Import), which on
   the admin bar are many.  min-width:0 + overflow:hidden lets the box
   shrink and the text ellipsize so nav and actions never collide.
   Per user 2026-06-19. */
.spg-area-card-nav--static {
  font-size: var(--font-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-3, #888);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  padding: 0 var(--space-xs);
}

.spg-area-card-counter {
  font-size: var(--font-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-3, #888);
  white-space: nowrap;
  padding: 0 var(--space-xs);
}

.spg-area-nav {
  flex: 0 0 auto;
  height: var(--ctl-h-md);
  padding: 0 var(--space-md);
  border-radius: var(--radius-md);
  border: var(--border-w) solid var(--border, #ccc);
  background: var(--surface, #fff);
  font-family: inherit;
  font-size: var(--font-sm);
  font-weight: var(--weight-medium);
  line-height: 1;
  cursor: pointer;
  color: var(--text-2, #555);
  transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast);
}

.spg-area-nav:hover:not(:disabled) {
  background: var(--surface-2, #f7f6f3);
  color: var(--accent, #e8853c);
  border-color: var(--accent, #e8853c);
}

.spg-area-nav:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.spg-area-nav--hidden { display: none; }

.spg-area--list .spg-area-boards {
  gap: var(--space-xl);
}

/* ── Action bar (edit / delete / fork) above the diagram ──────────── */

.spg-area-wrap {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.spg-area-actions {
  display: flex;
  gap: 8px;
  align-items: center;
}

.spg-area-actions:empty { display: none; }

.spg-area-action {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px;
  font-size: 12px;
  font-weight: 600;
  border: 1px solid var(--border, #ccc);
  border-radius: 4px;
  background: var(--surface, #fff);
  color: var(--text-2, #555);
  cursor: pointer;
}

.spg-area-action:hover {
  background: var(--surface-2, #f0eee9);
  color: var(--text, #1a1a18);
}

.spg-area-action--delete:hover {
  border-color: var(--danger, #b3261e);
  color: var(--danger, #b3261e);
}

.spg-area-action--fork:hover {
  border-color: var(--accent, #2E5B8A);
  color: var(--accent, #2E5B8A);
}

/* App-header gear button — opens the page settings popover.
   Matches chart-v2's gear glyph (⚙) so the affordance is identical
   across pages. */
.scp-app-gear,
.scp-app-help {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--ctl-h-md, 30px);
  height: var(--ctl-h-md, 30px);
  border: var(--border-w, 1px) solid var(--border, #ccc);
  border-radius: var(--radius-md, 6px);
  background: var(--surface, #fff);
  color: var(--text-2, #555);
  cursor: pointer;
  align-self: center;
  flex: 0 0 auto;
  margin-left: var(--space-sm);
  padding: 0;
  font-size: var(--font-base);
  line-height: 1;
}
.scp-app-gear:hover,
.scp-app-help:hover {
  background: var(--surface-2, #f7f6f3);
  color: var(--accent, #e8853c);
  border-color: var(--accent, #e8853c);
}
.scp-app-help {
  /* Slightly bolder so the '?' glyph reads as a distinct affordance
     even at small sizes — mirrors how GitHub / Linear render their
     keyboard-shortcuts buttons. */
  font-weight: var(--weight-bold);
}
/* Tighter gap between the gear and the '?' buttons — they're a
   paired action group (settings + shortcuts) so they should read
   as a cluster, not as two unrelated icons.  Per user
   2026-05-13. */
.scp-app-gear + .scp-app-help {
  margin-left: 4px;
}

/* Bare fretboard — no card chrome, full content width.  The toolbar
   sits flush at the top as a transparent header; the fretboard SVG
   spans the full content area edge-to-edge.  Doctrine: single source
   of truth for fretboard-card chrome.  Both scale and chord pages
   inherit this rule.  When card chrome is needed (Collection view),
   the leaf-card--browse variant carries its own border. */
.spg-area-card {
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 0;
  width: 100%;
}

.spg-area-card .spg-board-card,
.spg-area-card .spg-board {
  padding: 0;
}

.spg-area-card-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-3, #888);
  margin-bottom: 8px;
}

/* ── Generic panel chrome ─────────────────────────────────────────── */

.spg-panel-host {
  display: contents;
}

.spg-panel {
  padding: var(--space-md) var(--space-lg);
  background: var(--surface, #fff);
  border: var(--border-w) solid var(--border, #ddd);
  border-radius: var(--radius-md);
}

.spg-panel-title {
  margin: 0 0 var(--space-sm);
  font-size: var(--font-sm);
  font-weight: var(--weight-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-3, #888);
}

.spg-panel-caption {
  margin: 0 0 var(--space-sm);
  font-size: var(--font-sm);
  color: var(--text-3, #888);
}

.spg-pill-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
}

.spg-pill {
  display: inline-block;
  padding: var(--space-xs) var(--space-md);
  font-size: var(--font-sm);
  font-weight: var(--weight-semibold);
  border-radius: var(--radius-full);
  background: var(--surface-2, #f7f6f3);
  color: var(--text, #1a1a18);
  border: 1px solid var(--border, #ddd);
}

.spg-pill--root {
  background: var(--accent, #2E5B8A);
  color: #fff;
  border-color: var(--accent, #2E5B8A);
}

/* ── Modes list ───────────────────────────────────────────────────── */

.spg-modes-list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.spg-modes-item {
  display: inline-block;
  padding: 5px 10px;
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  border-radius: 4px;
  background: var(--surface-2, #f7f6f3);
  color: var(--text, #1a1a18);
  border: 1px solid var(--border, #ddd);
}

.spg-modes-item:hover {
  background: var(--accent-soft, rgba(46, 91, 138, 0.1));
  color: var(--accent, #2E5B8A);
}

.spg-modes-item--active {
  background: var(--accent, #2E5B8A);
  color: #fff;
  border-color: var(--accent, #2E5B8A);
  pointer-events: none;
}

/* ── Aliases / Usage / IsChord text panels ────────────────────────── */

.spg-pill--alias {
  font-style: italic;
  background: transparent;
  border-style: dashed;
}

.spg-usage-text,
.spg-ischord-text {
  margin: 0;
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-2, #333);
}

.spg-panel--ischord {
  background: var(--accent-soft, rgba(46, 91, 138, 0.06));
  border-color: var(--accent, #2E5B8A);
}

/* ── Inline Collection Strip — now hosted inside FingeringsPopover ── */

.spg-shell-strip { display: none; }

/* Fingerings cell — popover trigger sits to the LEFT of the
   List|Browse view toggle.  Trigger looks like an outlined button
   with a caret; opens a fixed-position panel below the cell. */

.spg-fingerings-row {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.spg-fpop-host { display: inline-flex; }

.spg-fpop-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 5px 18px;        /* wider than the other btn-group buttons */
  min-width: 88px;
  font-size: 12px;
  font-weight: 500;
  border: 1px solid var(--border, #ccc);
  border-radius: 4px;
  background: var(--surface, #fff);
  color: var(--text-2, #333);
  cursor: pointer;
  white-space: nowrap;
  min-height: 28px;
}
.spg-fpop-trigger:hover { background: var(--surface-2, #f0eee9); }
/* When open, trigger matches the panel bg below it so they read as
   one connected surface.  Chain selectors to outrank
   `.scp-btn-group-btn` rules loaded later in scale-collection-page.css. */
.spg-fpop-trigger.spg-fpop-trigger--open,
.scp-btn-group-btn.spg-fpop-trigger--open {
  border-color: var(--accent, #e8853c);
  color: var(--accent, #e8853c);
  background: rgba(232, 133, 60, 0.08);
}
.spg-fpop-trigger.spg-fpop-trigger--open:hover,
.scp-btn-group-btn.spg-fpop-trigger--open:hover {
  background: rgba(232, 133, 60, 0.12);
}
.spg-fpop-trigger-label {
  font-weight: 500;
  /* Reserve enough horizontal room for the widest source label
     ("Narrow Triads") so the trigger doesn't reflow when the
     async `_refreshSources` swap happens.  Without this min-width,
     the button starts at "Computed" width and grows to "Narrow
     Triads" once chord data loads, shifting every cell to its
     right by ~20-30px on every page refresh. */
  display: inline-block;
  min-width: 96px;
}

/* Integrated drop-down row — appears as a full-width sibling
   directly under the controls shell so it reads as part of the same
   bar (no floating box, no shadow, matching surface).  The strip
   inside is given the same horizontal padding as the controls. */

.spg-fpop-panel--integrated {
  /* Soft accent wash — matches the active trigger's bg so the bar
     reads as one continuous surface. */
  background: rgba(232, 133, 60, 0.08);
  border-bottom: 1px solid var(--border, #e0ddd5);
  padding: 8px 16px;
  animation: spg-fpop-slide 70ms ease-out;
}
.spg-fpop-panel--integrated .spg-strip {
  /* Suppress the strip's own card chrome — the panel IS the row. */
  border: none;
  background: transparent;
  padding: 0;
}

/* Centered inner row — strip + browse-full button.  Both centered
   horizontally; gap between them so the button sits as a
   distinct trailing affordance. */
.spg-fpop-inner {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}
.spg-fpop-strip { display: inline-flex; }

.spg-fpop-browse-btn {
  padding: 5px 12px;
  font-size: 12px;
  font-weight: 600;
  border: 1px solid var(--accent, #e8853c);
  border-radius: 4px;
  background: var(--surface, #fff);
  color: var(--accent, #e8853c);
  cursor: pointer;
  white-space: nowrap;
}
.spg-fpop-browse-btn:hover {
  background: var(--accent, #e8853c);
  color: #fff;
}

@keyframes spg-fpop-slide {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}

.spg-strip {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 6px 12px;
  background: var(--surface-2, #f7f6f3);
  border: 1px solid var(--border, #ddd);
  border-radius: 8px;
}

.spg-strip--single { padding: 6px 12px; }

.spg-strip-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

/* Combined single-row layout: system tabs on the left, pills on the
   right (when present) via .spg-strip-browse-spacer (margin-right:auto). */
.spg-strip-row--combined { gap: 8px; }

.spg-strip-pills {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

/* Custom-overflow tab — visually distinct from system tabs and the
   "+ add" tab.  Routes to browse-full Collection mode. */
.spg-strip-tab--more {
  font-style: italic;
  color: var(--accent, #e8853c);
  border-color: var(--accent, #e8853c);
  background: transparent;
}
.spg-strip-tab--more:hover {
  background: var(--accent, #e8853c);
  color: #fff;
}

.spg-strip-row-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-3, #888);
  min-width: 76px;
}

.spg-strip-tabs {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
}

.spg-strip-tab {
  padding: 5px 10px;
  font-size: 12px;
  font-weight: 500;
  border: 1px solid var(--border, #ccc);
  border-radius: 4px;
  background: var(--surface, #fff);
  color: var(--text-2, #555);
  cursor: pointer;
  white-space: nowrap;
}

.spg-strip-tab:hover {
  background: var(--surface-2, #f0eee9);
  color: var(--text-1, #222);
}

.spg-strip-tab--active {
  background: var(--accent, #e8853c);
  border-color: var(--accent, #e8853c);
  color: #fff;
}

/* Active + hover — keep the orange/white treatment so the label
   stays readable.  Without this, the generic :hover above flips the
   background to light beige while the active rule still sets text to
   #fff → white-on-beige (illegible). */
.spg-strip-tab--active:hover {
  background: var(--accent, #e8853c);
  border-color: var(--accent, #e8853c);
  color: #fff;
}

.spg-strip-tab--user {
  font-style: italic;
}

.spg-strip-tab--add {
  font-weight: 700;
  font-size: 14px;
  border-style: dashed;
  color: var(--text-3, #888);
  padding: 4px 10px;
}

.spg-strip-tab--add:hover {
  color: var(--accent, #e8853c);
  border-color: var(--accent, #e8853c);
}

.spg-strip-divider {
  display: inline-block;
  width: 1px;
  height: 18px;
  background: var(--border, #ccc);
  margin: 0 4px;
}

.spg-strip-group-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-3, #888);
}

/* Secondary row — sub-collection pills (suites/charts/articles). */

.spg-strip-row--secondary {
  border-top: 1px dashed var(--border, #ddd);
  padding-top: 8px;
}

.spg-strip-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 4px 3px 10px;
  font-size: 12px;
  background: var(--surface, #fff);
  border: 1px solid var(--border, #ccc);
  border-radius: 999px;
  color: var(--text-2, #555);
}

/* Empty-state styling MUST NOT change any box-model property — only
   visual (color / opacity).  Otherwise a 0→N count transition flips
   classes and reflows the row, shifting siblings.  Per user 2026-05-20.
   Uses opacity so border-style + background + padding + border-width
   are all identical to the filled state.  Composition layer only,
   no layout cost. */
.spg-strip-pill--empty {
  opacity: 0.55;
}

.spg-strip-pill-label {
  font-weight: 500;
}

.spg-strip-pill-count {
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  background: var(--surface-2, #f7f6f3);
  border-radius: 999px;
  padding: 1px 7px;
}

.spg-strip-pill-add {
  background: transparent;
  border: none;
  color: var(--text-3, #888);
  font-size: 14px;
  cursor: pointer;
  padding: 0 4px;
  line-height: 1;
}

.spg-strip-pill-add:hover {
  color: var(--accent, #e8853c);
}

.spg-strip-browse-link {
  font-size: 12px;
  font-weight: 600;
  color: var(--accent, #e8853c);
  text-decoration: none;
  margin-right: auto;     /* push pills to the right */
}

.spg-strip-browse-link:hover {
  text-decoration: underline;
}

/* Strip spacer — preserves the legacy pills-on-the-right layout
   after the browse-full icon button moved into the Collection
   control cell. */
.spg-strip-browse-spacer { margin-right: auto; }

/* `.spg-field--browse-link` + `.spg-browse-collection-link` removed
   2026-05-12 — emitted by `_buildBrowseCollectionLink`, stripped from
   page-controls.js when the legacy controls bar was retired.  The
   right-edge "Browse Collection" affordance now lives in the
   collection-mode toggle inside the ctrl-grid + the strip's
   `.spg-strip-browse-link`. */

/* ── Collection Drawer — REMOVED 2026-05-04 — see CLAUDE.md.
   The block below is left as historical reference; it's safe to
   delete in the next CSS-cleanup sweep. */

.spg-coll-drawer-handle__REMOVED {
  position: fixed;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 12px 6px;
  background: var(--accent, #e8853c);
  color: #fff;
  border: none;
  border-radius: 8px 0 0 8px;
  cursor: pointer;
  z-index: 90;
  font-size: 12px;
  font-weight: 600;
}

.spg-coll-drawer-handle:hover {
  filter: brightness(1.05);
}

.spg-coll-drawer-handle--hidden {
  display: none;
}

.spg-coll-drawer-handle-label {
  writing-mode: vertical-rl;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.spg-coll-drawer-handle-count {
  font-size: 11px;
  background: rgba(255, 255, 255, 0.25);
  border-radius: 999px;
  padding: 1px 7px;
  font-variant-numeric: tabular-nums;
}

.spg-coll-drawer-scrim {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.18);
  z-index: 95;
}

.spg-coll-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 360px;
  max-width: 90vw;
  background: var(--surface, #fff);
  border-left: 1px solid var(--border, #ddd);
  box-shadow: -2px 0 12px rgba(0, 0, 0, 0.12);
  z-index: 100;
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform 180ms ease;
}

.spg-coll-drawer--open {
  transform: translateX(0);
}

.spg-coll-drawer-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  border-bottom: 1px solid var(--border, #ddd);
}

.spg-coll-drawer-title {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
  color: var(--text, #1a1a18);
}

.spg-coll-drawer-close {
  background: none;
  border: none;
  font-size: 20px;
  color: var(--text-2, #555);
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 4px;
  line-height: 1;
}

.spg-coll-drawer-close:hover {
  background: var(--surface-2, #f0eee9);
  color: var(--text, #1a1a18);
}

.spg-coll-drawer-body {
  flex: 1;
  overflow-y: auto;
  padding: 8px 0;
}

.spg-coll-drawer-section-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 14px 16px 6px;
  border-top: 1px solid var(--border, #eee);
}

.spg-coll-drawer-section-head:first-child { border-top: none; }

.spg-coll-drawer-section-name {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-3, #888);
  flex: 1;
}

.spg-coll-drawer-section-count {
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  background: var(--surface-2, #f7f6f3);
  border-radius: 999px;
  padding: 1px 8px;
  color: var(--text-2, #555);
}

.spg-coll-drawer-section-add {
  background: transparent;
  border: 1px solid var(--border, #ccc);
  width: 22px;
  height: 22px;
  border-radius: 4px;
  cursor: pointer;
  color: var(--text-2, #555);
  font-size: 14px;
  line-height: 1;
  padding: 0;
}

.spg-coll-drawer-section-add:hover {
  border-color: var(--accent, #e8853c);
  color: var(--accent, #e8853c);
}

.spg-coll-drawer-list {
  display: flex;
  flex-direction: column;
}

.spg-coll-drawer-row {
  text-align: left;
  padding: 8px 16px;
  font-size: 13px;
  border: none;
  background: transparent;
  color: var(--text, #1a1a18);
  cursor: pointer;
}

.spg-coll-drawer-row:hover {
  background: var(--surface-2, #f7f6f3);
}

.spg-coll-drawer-row--active {
  background: var(--accent-soft, rgba(232, 133, 60, 0.12));
  color: var(--accent, #e8853c);
  font-weight: 600;
}

.spg-coll-drawer-divider {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-3, #888);
  padding: 10px 16px 4px;
}

.spg-coll-drawer-empty {
  margin: 4px 16px 8px;
  font-size: 12px;
  font-style: italic;
  color: var(--text-3, #888);
}

/* Tree rows — recursive nesting via padding-left set inline. */

.spg-coll-drawer-row--tree {
  display: flex;
  align-items: center;
  gap: 8px;
  text-align: left;
  width: 100%;
}

.spg-coll-drawer-chev {
  font-size: 10px;
  color: var(--text-3, #888);
  width: 12px;
  text-align: center;
  flex-shrink: 0;
}

.spg-coll-drawer-tree-icon {
  font-size: 12px;
  color: var(--text-3, #888);
  width: 14px;
  flex-shrink: 0;
}

.spg-coll-drawer-tree-name {
  flex: 1;
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* "+ here" inline-add row, indented to match its scope. */

.spg-coll-drawer-inline-add {
  display: flex;
  gap: 8px;
  padding: 4px 16px 6px;
  flex-wrap: wrap;
}

.spg-coll-drawer-add-link {
  font-size: 11px;
  padding: 2px 8px;
  background: transparent;
  border: 1px dashed var(--border, #ccc);
  border-radius: 4px;
  color: var(--text-3, #888);
  cursor: pointer;
}

.spg-coll-drawer-add-link:hover {
  border-color: var(--accent, #e8853c);
  color: var(--accent, #e8853c);
}

.spg-coll-drawer-section-extra {
  font-size: 11px;
  width: auto;
  padding: 0 8px;
  font-weight: 500;
}

.spg-coll-drawer-footer {
  border-top: 1px solid var(--border, #ddd);
  padding: 12px 16px;
  text-align: center;
}

.spg-coll-drawer-browse-link {
  font-size: 13px;
  font-weight: 500;
  color: var(--accent, #e8853c);
  text-decoration: none;
  cursor: pointer;
}

.spg-coll-drawer-browse-link:hover {
  text-decoration: underline;
}

/* ── Board ────────────────────────────────────────────────────────── */

/* Bare fretboard — no card chrome.  The board is rendered directly
   in the content area (full content width).  Doctrine: NO double
   cards — the .spg-area-card already provided card chrome which we
   stripped, and `.spg-board` was duplicating that role.  Both pages
   inherit this rule (chord page also uses .spg-board). */
.spg-board {
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 0;
}

/* ── ONE WHITE CARD AROUND THE FRETBOARD ──────────────────────────────
   `.spg-area-card` IS the single white card.  Every OTHER wrapper in
   the chain (.boards-area / .spg-area-boards / .spg-board /
   .spg-board-card / .cpg-area / .cpg-area-boards) is transparent so
   we never get double cards.  Doctrine: single source of truth —
   both pages inherit identical chrome. */
:where(#route-scale, #route-chord) .boards-area,
:where(#route-scale, #route-chord) .spg-area-boards,
:where(#route-scale, #route-chord) .spg-board,
:where(#route-scale, #route-chord) .spg-board-card,
:where(#route-scale, #route-chord) .cpg-area,
:where(#route-scale, #route-chord) .cpg-area-boards {
  background: transparent !important;
  border: none !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  padding: 0 !important;
}

/* The card itself — single white chrome.  Width 100% so the card
   spans the full content area. */
:where(#route-scale, #route-chord) .spg-area-card {
  background: var(--surface, #fff) !important;
  border: 1px solid var(--border, #ddd) !important;
  border-radius: 8px !important;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04) !important;
  padding: 0 !important;
  width: 100% !important;
  box-sizing: border-box !important;
  overflow: hidden !important;
}

/* Toolbar inside the card — surface-2 band with bottom separator. */
:where(#route-scale, #route-chord) .spg-area-card-toolbar {
  padding: 10px 16px !important;
  background: var(--surface-2, #f7f6f3) !important;
  border-bottom: 1px solid var(--border, #e0ddd5) !important;
  border-radius: 0 !important;
  margin: 0 !important;
  /* FIXED height (not min-height) so Browse + List views are
     PIXEL-IDENTICAL.  Browse fits the Prev/Next buttons (var(--ctl-h-md)
     tall) inside the 10px×2 padding; List's plain label centers in
     the same height.  Per user 2026-06-01: "still moves about 1px"
     — min-height let sub-pixel rounding cause drift; fixed height
     locks it. */
  height: calc(var(--ctl-h-md) + 20px) !important;
  min-height: calc(var(--ctl-h-md) + 20px) !important;
  max-height: calc(var(--ctl-h-md) + 20px) !important;
  box-sizing: border-box !important;
}

/* ── Advanced mode — page-mode toggle lock chip + list-pane filter toolbar
   (SCALES-ADVANCED-PHASE-A-SPEC-2026-07-03).  Design tokens only, `.spg-*`
   prefix owns this per the binding spec — no `.se-*` rules here. ── */

/* Lock chip sits inline next to the Advanced switch (NOT the whole cell —
   `_buildAdvancedCell` DOM is label / switch / optional chip, the SAME
   vertical label-then-content stack every sibling `.scp-ctrl-cell` uses
   (see `_buildGhostsCell`).  A `display:flex; align-items:center` on the
   CELL itself (the previous rule here) pulled the label onto the same row
   as the switch, breaking that shared vertical rhythm and widening/
   misaligning the cell vs its 2-child siblings — fixed 2026-07-03 by
   scoping the flex row to just the switch+chip pairing via a wrapper-free
   inline-flex on the chip alone; the cell keeps the block/stack layout
   every other ctrl cell uses so column width stays identical with or
   without the chip present. FretlyGate.renderLockChip's own styling is
   `.fg-lock-chip` in feature-gate.css; this only positions it inline
   after the switch. */
.scp-ctrl-cell[data-ctrl-key="advanced"] .fg-lock-chip {
  display: inline-flex;
  align-items: center;
  margin-left: var(--space-xs);
  vertical-align: middle;
  /* PUBLIC-GATING-PASS 2026-07-12: size the pill down to the cell's
     control rhythm (it read oversized next to the ADVANCED switch) and
     centre it on the switch's vertical axis. */
  padding: 1px var(--space-xs, 6px);
  font-size: var(--font-2xs, 10px);
  line-height: 1.4;
}
/* The switch label defaults to baseline alignment, which parks the
   chip ~5px below the switch's vertical centre.  Aligning BOTH inline
   boxes to `middle` snaps the pill onto the toggle's centre axis
   (PUBLIC-GATING-PASS 2026-07-12). */
.scp-ctrl-cell[data-ctrl-key="advanced"] .scp-switch {
  vertical-align: middle;
}

/* Filter/sort toolbar — appended into the scale list panel's `actions`
   slot (fly-panel__header) only while Advanced mode is active. */
.spg-adv-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-xs) 0;
}
.spg-adv-toolbar-row {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}
.spg-adv-check {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--space-xs) / 2);
  font-size: var(--font-xs, 11px);
  color: var(--text-2, #555);
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
.spg-adv-check input {
  margin: 0;
}
.spg-adv-sort {
  font-size: var(--font-xs, 11px);
  height: var(--ctl-h-sm, 24px);
  padding: 0 var(--space-xs);
  border: var(--border-w, 1px) solid var(--border, #c8c4ba);
  border-radius: var(--radius-sm, 4px);
  background: var(--surface, #fff);
  color: var(--text-1, #222);
}

/* ── Advanced-mode Fingerings graft (advanced-fingerings-graft.js) ──────
   Content injected into the `#se-advanced-fingerings-host` card that
   route-scale-explorer.php renders empty by default (SCALES-ADVANCED-
   PHASE-A-SPEC-2026-07-03, 2026-07-03 addendum, Item 5/6). `.spg-*`
   prefixed per doctrine — this is scale-page-owned graft content, not a
   native Explorer control (see that module's docblock for the full
   .se-* vs .spg-* reasoning). The host card itself (`.se-card`) and its
   title (`.se-card-title`) reuse Explorer's OWN existing chrome classes
   (scale-explorer.css) so the graft's outer shell matches its
   Properties/Modes/Circle siblings pixel-for-pixel; only the INNER
   content below is new. */
.spg-adv-fg-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}
.spg-adv-fg-note {
  font-size: var(--font-xs, 11px);
  color: var(--text-2, #777);
  background: var(--surface-2, #f7f6f3);
  border: var(--border-w, 1px) solid var(--border, #e0ddd6);
  border-radius: var(--radius-sm, 4px);
  padding: var(--space-xs) var(--space-sm);
}
.spg-adv-fg-empty {
  padding: var(--space-lg);
  text-align: center;
  color: var(--text-2, #777);
  font-size: var(--font-sm);
}
.spg-adv-fg-boards .spg-area-card {
  background: var(--surface, #fff);
  border: var(--border-w, 1px) solid var(--border, #e0ddd6);
  border-radius: var(--radius-md, 8px);
  overflow: hidden;
}
.spg-adv-fg-boards .spg-area-card-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: var(--space-xs) var(--space-md);
  background: var(--surface-2, #f7f6f3);
  border-bottom: var(--border-w, 1px) solid var(--border, #e0ddd6);
}
.spg-adv-fg-boards .spg-area-card > svg {
  display: block;
  width: 100%;
  height: auto;
  padding: var(--space-sm) var(--space-md);
  box-sizing: border-box;
}
/* Mode Map placement — ADDENDUM 2026-07-03 (4th), owner directive "Put
   mode map in same place as on Scales page": DOM-moved to right after
   Explorer's own `.se-circle-props-row` (Properties/Modes/Circle),
   matching the normal page's panel order — see advanced-fingerings-
   graft.js `_buildPanelsShell`'s placement-decision comment. `.mode-map`
   itself already carries full chrome (mode-map.css, app-wide) — this
   just adds the vertical gap from `.se-circle-props-row` above it. */
.spg-adv-modemap-host {
  margin-top: var(--space-md);
}
.spg-adv-modemap-host:empty {
  margin-top: 0;
}

/* ── Advanced-mode Collection graft (advanced-collection-graft.js) ──────
   Collection SUMMARY card injected into `#se-advanced-collection-host`
   (route-scale-explorer.php, rendered empty by default — see that
   module's docblock). `.spg-*` prefixed per doctrine; the outer `.se-card`
   host + `.se-card-title`/`.se-card-body` classes are Explorer's own
   (scale-explorer.css) so the card shell matches its siblings. Collapsible
   header mirrors the Tablature panel's toggle/caret chrome
   (shared/tab-panel.js `.spg-tab-card-toggle`/`.spg-tab-card-caret`),
   scoped separately since this card lives in `.se-card`, not `.spg-tab-card`. */
.spg-adv-coll-head {
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
}
.spg-adv-coll-toggle {
  display: flex;
  align-items: center;
  gap: 0.45rem;
}
.spg-adv-coll-caret {
  width: 0; height: 0;
  border-left: 5px solid currentColor;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  color: var(--text-3, #888);
  transition: transform 0.15s ease;
  flex: none;
}
.spg-adv-coll-head--open .spg-adv-coll-caret { transform: rotate(90deg); }
.spg-adv-coll-head:hover .spg-adv-coll-caret,
.spg-adv-coll-head:hover .spg-adv-coll-toggle { color: var(--accent, #2E5B8A); }
.spg-adv-coll-browse-link {
  font-size: var(--font-xs, 11px);
  color: var(--text-2, #777);
  text-decoration: none;
  white-space: nowrap;
}
.spg-adv-coll-browse-link:hover { color: var(--accent, #2E5B8A); text-decoration: underline; }
.spg-adv-coll-body {
  padding: var(--space-sm) var(--space-lg, 20px);
}
.spg-adv-coll-sections {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.spg-adv-coll-section {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--radius-sm, 4px);
  color: var(--text-1, #222);
  text-decoration: none;
  font-size: var(--font-sm, 13px);
}
.spg-adv-coll-section:hover {
  background: var(--surface-2, #f7f6f3);
  color: var(--accent, #2E5B8A);
}
.spg-adv-coll-section-count {
  color: var(--text-3, #888);
  font-variant-numeric: tabular-nums;
}

/* Bug fix 2026-07-03 (owner desktop review — "No Collections visible"):
   card is now always rendered; for an unnamed/synthetic selection (or no
   selection yet) the body shows this single muted line instead of the
   six-section summary — see advanced-collection-graft.js _render(). */
.spg-adv-coll-placeholder {
  color: var(--text-2, #777);
  font-size: var(--font-sm, 13px);
  font-style: italic;
}

/* Force the fretboard SVG to fill its card width on both pages.
   `Fretboard.draw` writes a pixel-width attribute on the SVG based
   on the container's clientWidth at first render — if that width
   was small (chord page's wrapped container resolves narrower at
   first paint), the SVG ends up locked at that size.  Override
   with CSS so the SVG always scales to fill the card. */
:where(#route-scale, #route-chord) .spg-area-card > svg,
:where(#route-scale, #route-chord) .spg-area-card .spg-board-svg,
:where(#route-scale, #route-chord) .spg-area-card .cpg-board-svg {
  width: 100% !important;
  height: auto !important;
  display: block;
  padding: 14px 16px;
  box-sizing: border-box;
}

.spg-board-svg {
  display: block;
  width: 100%;
  height: auto;
}

/* G4 — center the MAIN area board in its card when it's narrower than the
   card (zoomed-out / <100% on the scale + chord pages).  fretboard-board.js
   adds `.fb-board--centered` only in that case (board pinned to its exact
   pixel width); without it the board sat left-aligned with dead space on the
   right.  Re-positions only — never rescales the drawing. */
.spg-board-svg.fb-board--centered,
.cpg-board-svg.fb-board--centered {
  margin-left: auto;
  margin-right: auto;
}

.spg-board-svg--error {
  min-height: 60px;
}

.spg-board-error-label {
  fill: var(--danger, #b3261e);
  font-family: var(--font-ui, system-ui, sans-serif);
  font-size: 13px;
}

/* ── Tab-generation card (shared/tab-panel.js) ──────────────────────────
   Read-only ascending/descending tablature derived from a fingering.
   Admin-gated (FretlyDisplayConfig.tabGenerationAvailable); shown per
   pattern card, never for the full fretboard.  Uses the page's .se-card
   shell so it matches Properties / Modes / Scale Circle. */
.spg-tab-card {
  margin-top: 0.75rem;
  background: var(--surface, #fff);
  border: 1px solid var(--border, #e0ddd6);
  border-radius: var(--spg-tab-radius, 8px);
  padding: 0.75rem 1rem;
  /* Subtle lift so it reads as a distinct card even when --surface ≈ the
     page background (light theme). */
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
  /* Two-column layout responds to the CARD's own width (it sits in a
     fixed-ish content column), not the viewport. */
  container-type: inline-size;
}
.spg-tab-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  cursor: pointer;   /* whole title bar toggles the panel */
}
.spg-tab-card-toggle {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0;
  background: none;
  border: 0;
  cursor: pointer;
  color: inherit;
  text-align: left;
}
.spg-tab-card-title { margin: 0; }   /* .spg-panel-title gives uppercase type */
/* Caret sits right next to the title so it reads as one disclosure control. */
.spg-tab-card-caret {
  width: 0; height: 0;
  border-left: 5px solid currentColor;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  color: var(--text-3, #888);
  transition: transform 0.15s ease;
}
.spg-tab-card--open .spg-tab-card-caret { transform: rotate(90deg); }
.spg-tab-card-toggle:hover .spg-tab-card-caret,
.spg-tab-card-toggle:hover .spg-tab-card-title { color: var(--accent, #2E5B8A); }
/* Header tools group: rhythm + column + zoom controls on the right. */
.spg-tab-card-tools { display: flex; align-items: center; gap: 0.75rem; cursor: default; }
/* Segmented controls in the header (rhythm toolbar + column control) —
   the app avoids dropdowns; both reuse the cols-button look. */
.spg-tab-rhythm,
.spg-tab-card-cols { display: flex; gap: 4px; }
.spg-tab-rhythm[hidden],
.spg-tab-card-cols[hidden] { display: none; }
.spg-tab-card-tools .fly-cols-btn {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 7px;
  font-size: 11px;
  border: 1px solid var(--border, #ccc);
  border-radius: var(--r-sm, 5px);
  background: var(--surface, #fff);
  color: var(--text-2, #555);
  cursor: pointer;
}
.spg-tab-card-tools .fly-cols-btn:hover { border-color: var(--accent, #2E5B8A); }
.spg-tab-card-tools .fly-cols-btn.is-active {
  border-color: var(--accent, #2E5B8A);
  color: var(--accent, #2E5B8A);
}
.spg-tab-card-body {
  margin-top: 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  align-items: center;   /* centre the tablature in the card (stacked) */
}
/* No box around the tab — the staff sits directly on the panel.  Owner
   2026-06-19. */
.spg-tab-block { max-width: 100%; min-width: 0; }
/* Two-column layout (admin: tabPanelLayout = 'columns') — Ascending |
   Descending side by side; collapses to stacked on narrow viewports. */
.spg-tab-card-body.spg-tab-cols {
  display: grid;
  /* minmax(0,1fr) clamps each column to half the card so a wide staff scrolls
     inside its column instead of stretching the grid past the card. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 1rem 1.25rem;
  justify-items: center;   /* centre each staff within its column */
}
/* Collapse to a single column only when the card itself is too narrow for
   two readable staves (e.g. mobile), regardless of viewport width. */
@container (max-width: 600px) {
  .spg-tab-card-body.spg-tab-cols { grid-template-columns: 1fr; }
}
/* A lone block (e.g. a single chord voicing on the chord page) spans the full
   width even in columns mode — the column control stays visible for a
   consistent header across pages, without splitting a single tab. */
.spg-tab-card-body.spg-tab-cols .spg-tab-block:only-child { grid-column: 1 / -1; }
/* The JS toggles the body via the `hidden` attribute; the explicit display
   above (flex/grid) would otherwise override the UA `[hidden]` display:none, so
   the panel could never collapse.  This author-level rule restores it (placed
   after the display rules so it wins by source order).  Owner 2026-06-19. */
.spg-tab-card-body[hidden] { display: none; }
.spg-tab-block-label {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-3, #888);
  margin-bottom: 0.35rem;
}
/* Staff header — label on the left, Play/Stop on the right.  When the head
   wraps the label, the label's own bottom margin is folded into the head. */
.spg-tab-block-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.35rem;
}
.spg-tab-block-head .spg-tab-block-label { margin-bottom: 0; }
/* Play/Stop button — reuses the app-wide .btn/.btn--sm tokens; compact icon +
   label, accent when playing. */
.spg-tab-play {
  gap: 0.3rem;
  line-height: 1;
  color: var(--text-2, #555);
}
.spg-tab-play svg { display: block; }
.spg-tab-play.is-playing {
  background: var(--accent, #2E5B8A);
  border-color: var(--accent, #2E5B8A);
  color: #fff;
}
.spg-tab-play.is-playing:hover { background: var(--accent, #2E5B8A); opacity: 0.9; }
/* Subtle cue on the staff currently sounding. */
.spg-tab-block--playing .spg-tab-paper { outline: 1px solid var(--accent, #2E5B8A); outline-offset: 3px; border-radius: 4px; }
/* Inner scroll container — the card surface/border now lives on .spg-tab-block
   so the label is enclosed too.  This just holds the (possibly wide) staff. */
.spg-tab-paper {
  overflow-x: auto;
  /* Centre the staff/diagram within the panel. `safe center` falls back to
     start-alignment when content is wider than the container (zoom > 1), so
     the left edge is never clipped/unscrollable. */
  display: flex;
  justify-content: safe center;
}
/* Tab scales DOWN to fit its container (column or full width) but never
   stretches UP past its natural size — otherwise a short tab (a single chord
   voicing) blows up to fill the whole card.  max-width caps; width stays
   intrinsic. */
.spg-tab-paper svg { display: block; max-width: 100%; height: auto; }
.spg-tab-empty {
  color: var(--text-3, #888);
  font-size: 0.8rem;
}

/* ── CAGED-set authoring wizard (admin) — caged-set-wizard.js ─────────── */
.spg-strip-tab--add-caged { border-style: dashed; opacity: .75; }
.spg-strip-tab--add-caged:hover { opacity: 1; }
.spg-csw-host { margin: 12px 0; padding: 14px; }
.spg-csw-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.spg-csw-title { font-weight: 600; }
.spg-csw-close { background: none; border: none; cursor: pointer; font-size: 15px; color: var(--muted, #888); }
.spg-csw-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.spg-csw-chip { border: 1px solid var(--border, #ccc); border-radius: 14px; background: var(--bg-1, #fff); padding: 3px 12px; cursor: pointer; font-size: 13px; }
.spg-csw-chip.is-active { border-color: var(--accent, #e07a3f); color: var(--accent, #e07a3f); }
.spg-csw-chip.is-done { font-weight: 600; }
.spg-csw-chip--add, .spg-csw-chip--del { border-style: dashed; opacity: .7; }
.spg-csw-foot { display: flex; align-items: center; gap: 10px; margin-top: 12px; }
.spg-csw-status { font-size: 13px; color: var(--muted, #888); margin-right: auto; }
.spg-csw-btn { border: 1px solid var(--border, #ccc); border-radius: 6px; background: var(--bg-1, #fff); padding: 5px 14px; cursor: pointer; font-size: 13px; }
.spg-csw-btn:disabled { opacity: .45; cursor: default; }
.spg-csw-btn--publish { background: var(--accent, #e07a3f); border-color: var(--accent, #e07a3f); color: #fff; }
.spg-csw-preview { margin-top: 14px; }
.spg-csw-preview-key { margin-bottom: 10px; }
.spg-csw-preview-title { font-size: 13px; font-weight: 600; margin-bottom: 6px; }
.spg-csw-preview-gallery { display: flex; flex-wrap: wrap; gap: 8px; }
.spg-csw-preview-empty { font-size: 13px; color: var(--muted, #888); }
.spg-csw-error { margin-top: 8px; font-size: 13px; color: #b00020; }

.spg-strip-tab--draft { border-style: dashed; }
.spg-strip-tab-draft-badge { font-size: 9px; margin-left: 4px; color: var(--accent, #e07a3f); text-transform: uppercase; letter-spacing: .04em; }
.spg-csw-btn--remove { color: #b00020; border-color: #b00020; background: transparent; }
.spg-csw-btn--remove.is-armed { background: #b00020; color: #fff; }
