/* =============================================================================
   songbook.css — the playing surface
   -----------------------------------------------------------------------------
   Chrome is built against the ratified taste corpus (records/skills/taste:
   color-type-layout.md standing laws + control-surfaces-spec.md), because the
   first pass invented its own conventions and hit four NEVERs:

     · bordered-rect control groups  → "a table in word" (e-08). Now: tight
       clusters, hairline separators, no boxes around controls.
     · dotted underline on the editable chord name → blueprint semantics belong
       to containers, never editable text (e-07). Now: a spine mark.
     · ghost buttons in control rows (e-06/07). Now: filled accent primary,
       tint-well secondary, ink third.
     · filled-pill chips rank LAST (e-06). Now: spine-chips, square r2.
     · didactic empty-state prose → "i hate text that tries to TEACH me"
       (YOU-SAID, STRONG, e-13). Now: empty states show the SHAPE of what will
       be there, and no string in this file instructs.

   Ambient constants: r2 corners (2px) · 3px uniform spine as the accent
   language · accent carries STATE, never surface · small-caps labels · mono
   tabular numerals · shell/dense spacing (clusters pad 9 / gap 7) · elevation
   present (blur-12 @ 20%) on floating surfaces only.

   The chart geometry: the horizontal axis is musical time, bars are equal grid
   columns, and ONE unbroken run of six-line systems carries the whole song.
   Sections are labels above the staff, not containers — nothing restarts at a
   section boundary. The six lines are drawn full width on every system whether
   or not anything sits on them; a chord marks itself with its name above them
   and its shape ON them as fret digits, and tab and melody are digits on those
   same lines. Lyrics sit underneath. Density shrinks text, never notation.

   Edit mode (`.sb.editing`) only ADDS: resize handles, a snap grid, grab
   cursors, and a loud selection. It never moves anything, so the chart you
   edit is pixel-for-pixel the chart you play from.
============================================================================= */

.songbook-mount { display: flex; flex-direction: column; height: 100%; min-height: 0; }

.sb {
  --line:   color-mix(in srgb, var(--fg) 15%, transparent);
  --line-2: color-mix(in srgb, var(--fg) 30%, transparent);
  --chip:   color-mix(in srgb, var(--fg) 6%, transparent);
  --well:   color-mix(in srgb, var(--accent) 12%, transparent);
  --well-2: color-mix(in srgb, var(--accent) 19%, transparent);
  --shadow: 0 4px 12px color-mix(in srgb, #000 20%, transparent);
  --lyr: 12.5px;
  --r: 2px;
  /* Staff geometry. These three MUST match ROW / NAME_H / FOOT_H in
     songbook.js — the script places every digit in px against them. */
  --row: 11px;      /* == ROW in songbook.js */
  --name-h: 22px;   /* == NAME_H in songbook.js */
  --foot-h: 16px;   /* == FOOT_H in songbook.js */
  --staff-h: 55px;  /* == STAFF_H (ROW * 5) */
  display: flex; flex-direction: column; gap: 9px;
  height: 100%; min-height: 0;
}
/* Only the staff gives up space. Everything above it keeps its own height —
   without this, adding a row (the edit bar) squeezes the rows above it until
   their contents overflow up into the header. */
.sb > * { flex: 0 0 auto; }
.sb > .sb-systems { flex: 1 1 0; }

/* A song he has not published, seen by anyone else. States the fact; the pill
   in the header is where it changes. */
.sb-private {
  display: flex; flex-direction: column; gap: 3px; padding: 40px 0;
  color: var(--fg-mute); font-size: 12.5px;
}
.sb-private b { font-size: 16px; color: var(--fg-dim); font-weight: 700; }

/* The publish switch. Green is the signed-in signal this site already uses for
   "live", so a published song wears it and a private one stays neutral. */
.sb-live {
  font-family: inherit; font-weight: 700; font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; line-height: 1; height: 24px; padding: 0 9px;
  border: 0; border-radius: var(--r); cursor: pointer;
  background: var(--chip); color: var(--fg-mute);
  transition: background 150ms ease, color 150ms ease;
}
.sb-live:hover { background: color-mix(in srgb, var(--fg) 12%, transparent); }
.sb-live.on {
  background: color-mix(in srgb, var(--c-mint-1, #059669) 20%, transparent);
  color: var(--c-mint-1, #059669);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-mint-1, #059669) 45%, transparent);
}

/* ------------------------------------------------------------ compact mode */
/* Playing is the normal state of this page, and the chrome above the staff was
   taking about a third of the height. Compact folds all of it into one line:
   the song, the transport, the detail dial. Nothing is lost — the toggle is
   right there and the setting persists. */
.sb.compact { gap: 5px; }
.sb.compact .sb-head {
  align-items: center; gap: 12px; padding-bottom: 5px;
}
.sb.compact .sb-id { flex-direction: row; align-items: baseline; gap: 9px; min-width: 0; }
.sb.compact .sb-id h1 { font-size: 14px; }
.sb.compact .sb-id .who { font-size: 11px; }
.sb.compact .sb-id .meta { display: none; }
.sb.compact .sb-act { gap: 6px; }
/* The shell above the songbook is part of the same budget. */
body[data-sb-compact] .app-topbar { height: 32px; }
body[data-sb-compact] .page-song { padding: 4px 16px 6px; }

/* Placed EARLY on purpose: `[data-tip]` ties `.sb-lyric` on specificity, so if it
   came later it would win and turn absolutely-positioned elements static. */
/* Tooltip: surface-bordered float, 230ms hover delay. Describes; never instructs. */
[data-tip] { position: relative; }
[data-tip]::after {
  content: attr(data-tip); position: absolute; bottom: calc(100% + 7px); left: 50%;
  transform: translateX(-50%); opacity: 0; pointer-events: none; white-space: nowrap;
  z-index: 20; background: var(--bg-elev); color: var(--fg); font-size: 10.5px;
  font-weight: 500; letter-spacing: 0; text-transform: none;
  padding: 4px 8px; border-radius: var(--r); border: 1px solid var(--line-2);
  box-shadow: var(--shadow); transition: opacity .15s ease;
}
[data-tip]:hover::after { opacity: 1; transition-delay: 230ms; }
.sb-bar[data-tip]::after { bottom: auto; top: calc(100% + 5px); }

/* Small-caps label — the corpus's label voice, used for every control name. */
.sb-lab {
  font-size: 9.5px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--fg-mute);
}

/* ------------------------------------------------------- head: identity + act */
.sb-head {
  display: flex; align-items: flex-start; gap: 20px; flex-wrap: wrap;
  padding-bottom: 9px; border-bottom: 1px solid var(--line);
}
.sb-id { display: flex; flex-direction: column; gap: 1px; min-width: 170px; }
.sb-id h1 { margin: 0; font-size: 19px; font-weight: 700; letter-spacing: -.012em; }
.sb-id .who { font-size: 12.5px; color: var(--fg-dim); }
.sb-id .meta {
  font: 600 10px/1.5 var(--mono); letter-spacing: .05em; color: var(--fg-mute);
  display: flex; gap: 7px; align-items: center; flex-wrap: wrap;
}
.sb-id .meta .soft { color: color-mix(in srgb, var(--fg) 34%, transparent); }

.sb-act { display: flex; align-items: center; gap: 7px; margin-left: auto; flex-wrap: wrap; }

/* Primary: A3 soft-depth — faint top gradient, small lift, filled accent, h26.
   Press is symmetric 220/220 ease and activation strips the fill to an outline
   ("fill means go"). */
.sb-primary {
  font-family: inherit; font-weight: 700; font-size: 11.5px; line-height: 1; height: 26px; padding: 0 14px; border: 0;
  border-radius: var(--r); cursor: pointer; display: inline-flex;
  align-items: center; gap: 7px; color: var(--accent-fg);
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--accent) 88%, #fff), var(--accent));
  box-shadow: 0 1.5px 4px color-mix(in srgb, #000 22%, transparent);
  transition: all 220ms cubic-bezier(.4, 0, .2, 1);
}
.sb-primary:hover { filter: brightness(1.04); }
.sb-primary.live {
  background: transparent; color: var(--accent);
  box-shadow: inset 0 0 0 1.5px var(--accent);
}
.sb-primary .cnt {
  font: 700 11px/1 var(--mono); font-variant-numeric: tabular-nums;
  min-width: 8px;
}

/* Secondary: tint well — borderless, accent @12% ground, accent text. */
.sb-tw {
  font-family: inherit; font-weight: 600; font-size: 11px; line-height: 1; height: 24px; padding: 0 10px; border: 0;
  border-radius: var(--r); cursor: pointer;
  background: var(--well); color: var(--accent);
  transition: background 150ms ease;
  display: inline-flex; align-items: center; gap: 6px;
}
.sb-tw:hover { background: var(--well-2); }
.sb-tw.quiet { background: var(--chip); color: var(--fg-dim); }
.sb-tw.quiet:hover { background: color-mix(in srgb, var(--fg) 11%, transparent); }
.sb-tw.on { background: var(--accent); color: var(--accent-fg); }

/* Ink third — the lowest tier, for kebabs and dismissals. */
.sb-ink {
  font-family: inherit; font-weight: 600; font-size: 12px; line-height: 1; height: 22px; min-width: 22px; padding: 0 5px;
  border: 0; background: none; color: var(--fg-mute); cursor: pointer;
  border-radius: var(--r);
}
.sb-ink:hover { background: var(--chip); color: var(--fg); }

button:focus-visible, input:focus-visible {
  outline: none; background: color-mix(in srgb, var(--accent) 10%, transparent);
}

.sb [hidden] { display: none !important; }

/* The live loop, described where it lives. Spine-chip, square r2. */
.sb-loopchip {
  display: inline-flex; align-items: center; gap: 7px; height: 24px;
  padding: 0 8px 0 7px; background: var(--chip);
  border-left: 3px solid var(--accent); border-radius: 0 var(--r) var(--r) 0;
  font: 700 10.5px/1 var(--mono); color: var(--fg-dim);
  font-variant-numeric: tabular-nums;
}
.sb-loopchip b { color: var(--fg); font-weight: 700; }

/* Segmented dense strip — the depth dial. */
.sb-seg { display: inline-flex; border: 1.5px solid var(--line-2); border-radius: var(--r); overflow: hidden; }
.sb-seg button {
  font-family: inherit; font-weight: 600; font-size: 11px; line-height: 1; height: 24px; padding: 0 11px; border: 0;
  background: transparent; color: var(--fg-dim); cursor: pointer;
  border-right: 1px solid var(--line);
  transition: background 150ms ease, color 150ms ease;
}
.sb-seg button:last-child { border-right: 0; }
.sb-seg button:hover { background: var(--chip); color: var(--fg); }
.sb-seg button.on { background: var(--accent); color: var(--accent-fg); }

/* -------------------------------------------------------------- setup row */
.sb-setup {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  padding: 0 0 1px;
}
.sb-unit { display: inline-flex; align-items: center; gap: 6px; padding-right: 7px; }
.sb-unit + .sb-unit { border-left: 1px solid var(--line); padding-left: 12px; }

/* Stepper, to spec: 1.5px frame, mono tabular value in a bordered centre cell.
   Hold-to-repeat arms at 174ms and accelerates 300 → 80ms; click has instant
   attack and a 150ms release, and re-clicking inside the window re-flashes. */
.sb-step { display: inline-flex; border: 1.5px solid var(--line-2); border-radius: var(--r); overflow: hidden; }
.sb-step button {
  font-family: inherit; font-weight: 700; font-size: 13px; line-height: 1; width: 24px; height: 23px; border: 0;
  background: var(--bg-elev); color: var(--accent); cursor: pointer;
  transition: background 150ms ease;
}
.sb-step button:hover { background: var(--well); }
.sb-step button[disabled] { color: var(--fg-mute); opacity: .4; cursor: default; background: var(--bg-elev); }
.sb-step button.hit { background: var(--well-2); transition: none; }
.sb-step .v {
  font: 700 11.5px/23px var(--mono); font-variant-numeric: tabular-nums;
  padding: 0 9px; min-width: 44px; text-align: center;
  border-left: 1px solid var(--line); border-right: 1px solid var(--line);
  color: var(--fg);
}
/* Numbers travel. */
.sb-step .v i { display: inline-block; font-style: normal; transition: transform 174ms cubic-bezier(.4,0,.2,1), opacity 174ms ease; }
.sb-step .v.up i   { animation: sbUp 260ms cubic-bezier(.4,0,.2,1); }
.sb-step .v.down i { animation: sbDown 260ms cubic-bezier(.4,0,.2,1); }
@keyframes sbUp   { 0% { transform: translateY(6px); opacity: .3 } 100% { transform: none; opacity: 1 } }
@keyframes sbDown { 0% { transform: translateY(-6px); opacity: .3 } 100% { transform: none; opacity: 1 } }

/* ------------------------------------------------------------------ shapes */
/* Every voicing the song uses, once and legible. The chart itself then carries
   names, with a grip only where a chord first appears in a section. */
.sb-shapes { display: flex; gap: 14px; align-items: flex-end; flex-wrap: wrap; padding: 2px 0 1px; }
.sb-shape { display: inline-flex; align-items: flex-end; gap: 6px; }
.sb-shape .sb-grip { width: 30px; height: 30px; }
.sb-shape .sb-grip::before { height: 30px; background: repeating-linear-gradient(to bottom,
    color-mix(in srgb, var(--fg) 34%, transparent) 0 1px, transparent 1px 5.8px); }
.sb-shape b { font-size: 12.5px; font-weight: 700; color: var(--fg); }

/* ---------------------------------------------------------------- practice */
.sb-practice { display: flex; gap: 9px; align-items: center; flex-wrap: wrap; font-size: 11px; color: var(--fg-dim); }
.sb-pstat { display: inline-flex; gap: 5px; align-items: baseline; }
.sb-pstat b { font: 700 12px var(--mono); font-variant-numeric: tabular-nums; color: var(--fg); }
.sb-weak {
  font: 600 10.5px/1 var(--mono); padding: 3px 8px; cursor: pointer;
  border: 0; border-left: 3px solid var(--c-amber-1, #d97706);
  border-radius: 0 var(--r) var(--r) 0; background: var(--chip); color: var(--fg-dim);
  font-variant-numeric: tabular-nums;
}
.sb-weak:hover { background: var(--well); color: var(--accent); }
.sb-weak i { font-style: normal; opacity: .7; margin-left: 6px; }

/* Empty state = the SHAPE of what will be there. A ghost of the real row,
   never a lesson about how to fill it. */
.sb-practice.ghost { user-select: none; pointer-events: none; }
.sb-practice.ghost .gh {
  display: inline-block; height: 17px; border-radius: 0 var(--r) var(--r) 0;
  background: color-mix(in srgb, var(--fg) 4%, transparent);
  border-left: 3px solid color-mix(in srgb, var(--fg) 9%, transparent);
}

/* -------------------------------------------------------------------- ears */
.sb-ears {
  display: flex; gap: 14px; align-items: center; flex-wrap: wrap;
  padding: 8px 11px; background: var(--bg-elev);
  border-left: 3px solid var(--accent); border-radius: 0 var(--r) var(--r) 0;
}
.sb-ereadout { font-size: 12px; color: var(--fg-dim); display: flex; gap: 9px; align-items: center; }
.sb-ereadout b { font: 700 17px var(--mono); font-variant-numeric: tabular-nums; color: var(--fg); }
.sb-ereadout b.intune { color: var(--c-mint-1, #059669); }
.sb-cents { font: 500 11px var(--mono); color: var(--fg-mute); }
.sb-meter {
  position: relative; width: 128px; height: 14px; border-radius: var(--r);
  background: var(--bg); border: 1.5px solid var(--line-2);
  box-shadow: inset 0 2px 4px color-mix(in srgb, #000 16%, transparent);
}
.sb-meter i {
  position: absolute; top: -2px; width: 8px; height: 16px; border-radius: var(--r);
  background: linear-gradient(180deg, var(--bg-elev), var(--chip));
  border: 1.5px solid var(--line-2); transform: translateX(-50%);
  box-shadow: 0 1.5px 3px color-mix(in srgb, #000 25%, transparent);
  transition: left .08s linear;
}
.sb-meter::before {
  content: ""; position: absolute; left: 50%; top: 2px; bottom: 2px; width: 1px;
  background: var(--line-2);
}
.sb-match { font-size: 11.5px; }
.sb-match.ok { color: var(--c-mint-1, #059669); }
.sb-match.near { color: var(--c-amber-1, #d97706); }
.sb-match.off { color: var(--fg-mute); }

/* --------------------------------------------------------- the edit surface */
/* Two docked rows, present only while editing: the TOOLS (snap, bar grid,
   history, and what a bar RANGE does) and the INSPECTOR (the selected mark).
   Docked, not floating — the old popover opened wherever the mark happened to
   be, which put it off the bottom of a page that does not scroll, so nothing
   below the first line could be edited at all. A strip cannot be misplaced. */
.sb-editbar, .sb-insp {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  padding: 5px 9px; background: var(--bg-elev);
  border-left: 3px solid var(--accent); border-radius: 0 var(--r) var(--r) 0;
}
.sb-insp { border-left-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.sb-insp.empty { border-left-color: var(--line-2); }
.sb-editbar .sb-tw[disabled], .sb-insp .sb-tw[disabled] { opacity: .34; pointer-events: none; }
.sb-range { margin-left: auto; }
.sb-where {
  font: 500 10.5px var(--mono); color: var(--fg-mute);
  font-variant-numeric: tabular-nums; margin-left: auto;
}
.sb-where b { color: var(--fg); font-weight: 700; margin-right: 6px; }
.sb-unit.grow { flex: 1 1 220px; min-width: 160px; }
.sb-in {
  font: 500 12px var(--sans, inherit); padding: 3px 7px; border-radius: var(--r);
  border: 1.5px solid var(--line-2); background: var(--bg); color: var(--fg);
  min-width: 120px;
}
.sb-in.grow { width: 100%; }

/* Pick the cut. The line reads as itself with a mark between every word, and
   each mark is the button. */
.sb-cuts {
  display: inline-flex; align-items: center; flex-wrap: wrap;
  font-size: 12px; color: var(--fg); line-height: 1.5;
  background: var(--bg); padding: 2px 6px; border-radius: var(--r);
  border: 1.5px solid var(--line-2); max-width: 100%;
}
.sb-cut {
  border: 0; background: none; cursor: pointer; padding: 0 2px; margin: 0 1px;
  font: 700 12px/1 var(--mono); color: color-mix(in srgb, var(--fg) 26%, transparent);
  border-radius: 1px;
}
.sb-cut:hover { background: var(--accent); color: var(--accent-fg); }

/* What the last grid operation actually did. States it, then goes quiet. */
.sb-said {
  margin-left: auto; font-size: 10.5px; color: var(--accent);
  background: var(--well); padding: 3px 8px; border-radius: var(--r);
}

/* The chord picker. A chord is a constrained value — you pick one, you never
   type one — so the song's own chords are buttons and "More" is the library. */
.sb-pick { display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.sb-pk {
  font: 700 11.5px/1 var(--mono); height: 24px; padding: 0 9px; border: 0;
  border-radius: var(--r); cursor: pointer;
  background: var(--chip); color: var(--fg);
  transition: background 120ms ease;
}
.sb-pk:hover { background: color-mix(in srgb, var(--fg) 13%, transparent); }
.sb-pk.on { background: var(--accent); color: var(--accent-fg); }
.sb-pk.hit { font-size: 12px; }

/* The full chord library, opened from More. Its own name: `sb-grid` collided
   with the snap grid on the staff and the two rules overwrote each other. */
.sb-cgrid {
  display: flex; flex-direction: column; gap: 3px; padding: 7px 9px;
  background: var(--bg-elev); border-left: 3px solid var(--line-2);
  border-radius: 0 var(--r) var(--r) 0; max-height: 24vh; overflow-y: auto;
}
.sb-growrow { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.sb-growrow .sb-lab { min-width: 22px; }

/* The strum pattern, written once for the song instead of papered over every
   bar. A repeating figure is notated once — that is what a chart does. */
.sb-strum { display: inline-flex; align-items: center; gap: 3px; padding: 0 2px; }
.sb-strum i { font-style: normal; font-size: 12px; line-height: 1; color: color-mix(in srgb, var(--fg) 62%, transparent); }
.sb-strum i.up { color: color-mix(in srgb, var(--fg) 38%, transparent); }
.sb-strum i.mute { color: var(--fg-mute); }

/* ----------------------------------------------------------------- systems */
/* ONE continuous run of systems, bar 1 to the last bar. Sections are labels
   riding above the staff, never containers that restart it. */
.sb-systems {
  position: relative; flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden;
  padding-right: 4px;
}
.sb-system { margin-top: 13px; }
.sb-system:first-child { margin-top: 4px; }

/* Section labels: spine-chips at the exact beat the section starts. */
.sb-secs { position: relative; height: 15px; }
.sb-seclab {
  position: absolute; top: 0; transform: translateX(-1px);
  font: 700 9.5px/1 var(--sans, inherit); letter-spacing: .11em; text-transform: uppercase;
  height: 15px; padding: 0 6px 0 5px; border: 0; cursor: pointer; white-space: nowrap;
  background: var(--chip); color: var(--fg);
  border-left: 3px solid color-mix(in srgb, var(--fg) 40%, transparent);
  border-radius: 0 var(--r) var(--r) 0;
  display: inline-flex; align-items: center; gap: 5px; z-index: 2;
}
/* Near the right edge the chip grows the other way; the spine swaps sides so it
   still sits exactly on the beat the section starts. */
.sb-seclab.flip {
  transform: translateX(calc(-100% + 2px));
  border-left: 0; border-right: 3px solid color-mix(in srgb, var(--fg) 40%, transparent);
  border-radius: var(--r) 0 0 var(--r);
}
.sb-seclab.flip[data-mark="good"]  { border-right-color: var(--c-mint-1, #059669); }
.sb-seclab.flip[data-mark="shaky"] { border-right-color: var(--c-amber-1, #d97706); }
.sb-seclab.flip[data-mark="wrong"] { border-right-color: var(--c-rose-1, #e11d48); }
.sb-seclab:hover { background: color-mix(in srgb, var(--fg) 11%, transparent); }
.sb-seclab.looped { background: var(--well-2); color: var(--accent); }
.sb-seclab i { font-style: normal; font: 700 8.5px var(--mono); opacity: .8; }
.sb-seclab u { text-decoration: none; font: 500 8.5px var(--mono); color: var(--fg-mute); letter-spacing: 0; text-transform: none; }
.sb-seclab[data-kind="chorus"]     { color: var(--c-amber-1, #d97706); }
.sb-seclab[data-kind="verse"]      { color: var(--c-cyan-1, #0891b2); }
.sb-seclab[data-kind="pre-chorus"] { color: var(--c-violet-1, #7c3aed); }
.sb-seclab[data-kind="bridge"]     { color: var(--c-mint-1, #059669); }
/* The spine carries the section's standing — accent is state, nothing else. */
.sb-seclab[data-mark="good"]  { border-left-color: var(--c-mint-1, #059669); }
.sb-seclab[data-mark="shaky"] { border-left-color: var(--c-amber-1, #d97706); }
.sb-seclab[data-mark="wrong"] { border-left-color: var(--c-rose-1, #e11d48); }


/* The section bands. While playing, the grid under a section wears that
   section's colour from its marker to the next one — where you are in the
   arrangement without reading a word. Kept faint on purpose: it has six string
   lines, fret digits and lyrics sitting on top of it. Hidden while editing,
   where the chord boxes own the background instead. */
.sb-tints { position: absolute; inset: 0; pointer-events: none; z-index: 0; }
.sb-tint { position: absolute; top: 0; bottom: 0; }
.sb-tint[data-kind="verse"]      { background: color-mix(in srgb, var(--c-cyan-1, #0891b2) 9%, transparent); }
.sb-tint[data-kind="pre-chorus"] { background: color-mix(in srgb, var(--c-violet-1, #7c3aed) 9%, transparent); }
.sb-tint[data-kind="chorus"]     { background: color-mix(in srgb, var(--c-amber-1, #d97706) 9%, transparent); }
.sb-tint[data-kind="bridge"]     { background: color-mix(in srgb, var(--c-mint-1, #059669) 9%, transparent); }
.sb-tint[data-kind="solo"]       { background: color-mix(in srgb, var(--c-rose-1, #e11d48) 9%, transparent); }
.sb-tint[data-kind="intro"],
.sb-tint[data-kind="outro"]      { background: color-mix(in srgb, var(--fg) 4%, transparent); }
.sb.editing .sb-tints { display: none; }

/* The stage: bars, lines, marks — one coordinate system, x is musical time. */
.sb-stage { position: relative; }
.sb-bars {
  position: absolute; inset: 0; display: grid;
  grid-template-columns: repeat(var(--n), 1fr);
}
.sb-bar { position: relative; min-width: 0; cursor: pointer; }
.sb-bar.past { cursor: default; background: color-mix(in srgb, var(--fg) 2.5%, transparent); }
.sb-bar.in-loop { background: color-mix(in srgb, var(--accent) 10%, transparent); }
.sb-bar:hover:not(.past) { background: color-mix(in srgb, var(--fg) 4%, transparent); }
.sb-barnum {
  position: absolute; bottom: 0; left: 2px; font: 500 8px var(--mono);
  color: var(--fg-mute); opacity: .55; pointer-events: none;
  font-variant-numeric: tabular-nums;
}

/* Six lines, full width, every system, whether or not anything sits on them. */
.sb-lines { position: absolute; inset: 0; pointer-events: none; }
.sb-str {
  position: absolute; left: 0; right: 0; height: 1px;
  background: color-mix(in srgb, var(--fg) 26%, transparent);
}
/* ------------------------------------------------------------- the measure */
/* A tape measure, not a grid: the graduation you count by is the longest,
   heaviest and labelled one, and each finer division steps down in length,
   weight and tone. Four bars > one bar > beat > snap. */
.sb-t1 {                                   /* four bars */
  position: absolute; top: 0; bottom: 0; width: 3px; margin-left: -1px;
  background: color-mix(in srgb, var(--fg) 62%, transparent); border-radius: 1px;
}
.sb-t2 {                                   /* one bar */
  position: absolute; top: 0; bottom: calc(var(--foot-h) - 9px); width: 1px;
  background: color-mix(in srgb, var(--fg) 34%, transparent);
}
.sb-t3 {                                   /* beat */
  position: absolute; bottom: calc(var(--foot-h) - 9px); height: 5px; width: 1px;
  background: color-mix(in srgb, var(--fg) 22%, transparent);
}
.sb-t4 {                                   /* the snap division, while editing */
  position: absolute; bottom: calc(var(--foot-h) - 9px); height: 2.5px; width: 1px;
  background: color-mix(in srgb, var(--fg) 13%, transparent);
}
/* Beat and snap ticks also rise faintly through the staff, so a chord can be
   read against them without the lines themselves becoming a cage. */
.sb-t3::after, .sb-t4::after {
  content: ""; position: absolute; left: 0; width: 1px;
  top: calc(-1 * (var(--staff-h) + 5px)); height: 5px;
  background: color-mix(in srgb, var(--fg) 16%, transparent);
}
.sb-t4::after { opacity: .55; }

/* The numbers, in the same hierarchy: the four-bar mark is set bold and dark,
   the intermediate bars small and quiet, both on the same baseline. */
.sb-majnum, .sb-barnum {
  position: absolute; bottom: -2px; padding-left: 5px;
  font-style: normal; font-variant-numeric: tabular-nums;
  white-space: nowrap; pointer-events: none;
}
.sb-majnum { font: 700 11px/1 var(--mono); letter-spacing: .04em; color: var(--fg); }
.sb-barnum { font: 500 8.5px/1 var(--mono); color: var(--fg-mute); opacity: .75; }

.sb-secline {
  position: absolute; top: calc(var(--name-h) - 4px); bottom: calc(var(--foot-h) - 3px);
  width: 3px; margin-left: -1px;
  background: color-mix(in srgb, var(--fg) 34%, transparent);
  border-left: 1px solid var(--bg); border-right: 1px solid var(--bg);
  box-sizing: content-box;
}

/* The marks. The container never eats a click — only the glyphs do, so the
   staff underneath stays reachable for adding. */
.sb-marks { position: absolute; inset: 0; pointer-events: none; }
/* A chord OWNS a space: from its beat to the end of its length, floor to the
   ruler. Without that it was a loose name and a loose column of digits sitting
   on top of whatever bar line happened to be behind them. */
.sb-ch {
  position: absolute; top: 0; bottom: var(--foot-h); pointer-events: none;
  border-radius: var(--r);
}
.sb.editing .sb-ch {
  background: color-mix(in srgb, var(--fg) 5%, transparent);
  box-shadow: inset 1px 0 0 color-mix(in srgb, var(--fg) 30%, transparent);
}
.sb.editing .sb-ch.hit {
  width: 15px; margin-left: -1px;
  background: color-mix(in srgb, var(--fg) 8%, transparent);
}
.sb.editing .sb-ch.cont { background: color-mix(in srgb, var(--fg) 3%, transparent); box-shadow: none; }
.sb.editing .sb-ch.sel { background: color-mix(in srgb, var(--accent) 17%, transparent);
  box-shadow: inset 1.5px 0 0 var(--accent); }
.sb-cn {
  position: absolute; top: 0; left: 0; pointer-events: auto; cursor: pointer;
  font-size: 12.5px; font-weight: 700; letter-spacing: -.01em; line-height: 1.25;
  color: var(--fg); white-space: nowrap;
  padding: 0 3px; border-radius: var(--r); background: var(--bg);
}
/* No room to the right: the name grows LEFT from the beat it marks, so it stays
   on screen instead of being pinned to the far end of a long chord's box. */
.sb-cn.flip { left: 0; transform: translateX(-100%); padding-right: 5px; }
/* A chord still sounding at the top of the next row says so, the same way a
   carried lyric does. */
.sb-cn.carry { color: var(--fg-mute); font-weight: 600; }
.sb-cn.carry::before { content: "("; }
.sb-cn.carry::after { content: ")"; }
/* The duration, drawn between the name and its shape so neither is crowded. */
.sb-dur {
  position: absolute; left: 0; right: 0; top: calc(var(--name-h) - 9px); height: 2px;
  pointer-events: none;
  border-left: 1px solid color-mix(in srgb, var(--fg) 45%, transparent);
  background: linear-gradient(to right,
    color-mix(in srgb, var(--fg) 22%, transparent), transparent 92%);
}
.sb-ch.cont .sb-dur { border-left: 0; opacity: .45; }
/* Provenance by SPINE, never by underline (e-07). */




.sb-ch.own .sb-cn::after { content: "•"; color: var(--accent); margin-left: 3px; font-size: 10px; }

/* The chord's shape, ON the lines: one digit per string where it is fretted. */
.sb-frets { position: absolute; inset: 0; pointer-events: none; }
.sb-frets i {
  position: absolute; left: 2px; transform: translateY(-50%); pointer-events: auto;
  font: 700 9px/1 var(--mono); font-style: normal; color: var(--fg);
  background: var(--bg); padding: 1px 2px; min-width: 7px; text-align: center;
  cursor: pointer; border-radius: 1px;
}
.sb-frets i.x { color: var(--fg-mute); font-weight: 500; opacity: .55; }


/* Tab digits and melody notes share those same six lines. */
.sb-tn, .sb-mn {
  position: absolute; transform: translate(-50%, -50%); pointer-events: auto;
  font: 700 9.5px/1 var(--mono); font-style: normal; color: var(--fg);
  background: var(--bg); padding: 1px 2px; cursor: pointer;
}

.sb-mn { color: var(--c-cyan-1, #0891b2); }


/* A percussive hit is a chord named × — same element, same handles, same drag.
   Only the glyphs differ: × down the strings instead of a name over a shape. */
.sb-ch.hit .sb-frets i.x {
  color: color-mix(in srgb, var(--fg) 80%, transparent); opacity: 1; font-weight: 700;
}
.sb-cn.hitmark { font: 700 13px/1 var(--mono); color: var(--fg-dim); }

/* The ghost: where the next click lands, before you commit to it. */
.sb-ghost {
  position: absolute; pointer-events: none; z-index: 5;
  font: 700 12px/1 var(--mono); color: var(--accent); opacity: .75;
}
.sb-ghost.chord {
  top: 0; height: 100%; width: 0;
  border-left: 1px dashed color-mix(in srgb, var(--accent) 70%, transparent);
  padding-left: 2px;
}
.sb-ghost.tab {
  height: 12px; font-size: 9.5px; transform: translateX(-50%);
  background: var(--bg); padding: 1px 2px; border-radius: var(--r);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 60%, transparent);
}

.sb-lyr { position: relative; min-height: 18px; margin-top: 3px; overflow: hidden; }
.sb-lyric {
  position: absolute; top: 0; font-size: var(--lyr); line-height: 1.34;
  color: var(--fg); padding-right: 10px; overflow-wrap: break-word; hyphens: none;
}

/* Which lines he has placed is worth seeing WHILE placing them and nowhere
   else — reading a chart is reading words, not provenance, and inserting one
   bar re-times every line after it, which would otherwise spine the whole song. */

/* A line he has SIZED is a block of a stated width. It wraps inside that width
   and stops there, which is what makes two dense lines stop reading as one
   ambiguous run of text. */
.sb-lyric.sized { padding-right: 4px; }
/* A line that ran past the end of its row continues at the start of the next
   one, which begins at the very next bar — so it lines up there the same way a
   line in the interior lines up with the bar it lands on. The two halves are
   one line: selecting either lights up both. */
.sb-lyric.head { padding-right: 2px; }
.sb-lyric.tail { padding-left: 0; }
.sb-lyric.head::after {
  content: "\2013"; color: var(--fg-mute); opacity: .55; margin-left: 2px;
}
/* An empty line still has to be grabbable while he types into it. */
.sb.editing .sb-lyric:empty::before,
.sb.editing .sb-lyric > i:only-child::before {
  content: "…"; color: var(--fg-mute);
}
.sb-lgrab { display: none; }
/* While aligning, every block SHOWS its edges — persistently, not on hover.
   Where a line starts and stops is the thing being set, so it has to be
   visible without hunting for it. A wrapped half marks only the edge it really
   owns: the head's right edge and the tail's left edge are a wrap, not a
   boundary, and the en-dash already says so. */
.sb.editing .sb-lyric {
  background: color-mix(in srgb, var(--fg) 4%, transparent);
  box-shadow: inset 2px 0 0 color-mix(in srgb, var(--accent) 60%, transparent),
              inset -2px 0 0 color-mix(in srgb, var(--accent) 35%, transparent);
}
.sb.editing .sb-lyric.head { box-shadow: inset 2px 0 0 color-mix(in srgb, var(--accent) 60%, transparent); }
.sb.editing .sb-lyric.tail { box-shadow: inset -2px 0 0 color-mix(in srgb, var(--accent) 35%, transparent); }
.sb.editing .sb-lyric.sel {
  box-shadow: inset 2px 0 0 var(--accent), inset -2px 0 0 var(--accent);
}

.sb.editing .sb-lgrab {
  display: block; position: absolute; right: -2px; top: 0; bottom: 0; width: 6px;
  cursor: ew-resize; background: linear-gradient(to right, transparent,
    color-mix(in srgb, var(--accent) 45%, transparent));
  opacity: .4; transition: opacity 120ms ease;
}
/* The other edge. Both lock to the snap grid, so a line's start and its end are
   each placeable on a stated beat. */
.sb.editing .sb-lgrab.start {
  right: auto; left: -2px;
  background: linear-gradient(to left, transparent,
    color-mix(in srgb, var(--accent) 45%, transparent));
}
.sb.editing .sb-lyric:hover .sb-lgrab, .sb-lyric.sel .sb-lgrab { opacity: 1; }
/* The body of a block moves it; only the 6px edges resize. */
.sb.editing .sb-lyric { cursor: grab; }
.sb.editing .sb-lyric:active { cursor: grabbing; }


/* ------------------------------------------------------------- edit mode */
/* Handles appear only while editing, and the selection is the loudest thing on
   the staff — you are always looking at the one thing the keys will move. */
.sb-grab { display: none; }
.sb.editing .sb-cn, .sb.editing .sb-tn[data-id], .sb.editing .sb-lyric,
.sb.editing .sb-frets i { cursor: grab; }
.sb.editing .sb-cn:hover, .sb.editing .sb-tn[data-id]:hover {
  background: color-mix(in srgb, var(--accent) 22%, var(--bg));
}
.sb.editing .sb-lyric:hover { background: color-mix(in srgb, var(--accent) 12%, transparent); }
.sb.editing .sb-grab {
  display: block; position: absolute; right: -3px; top: calc(var(--name-h) - 12px);
  width: 7px; height: 7px;
  pointer-events: auto; cursor: ew-resize; border-radius: 50%;
  background: color-mix(in srgb, var(--fg) 30%, transparent);
}
.sb.editing .sb-grab:hover { background: var(--accent); }
.sb-ch.sel .sb-cn, .sb-tn.sel, .sb-lyric.sel {
  background: var(--accent); color: var(--accent-fg); border-radius: var(--r);
}
.sb-ch.sel .sb-dur { background: var(--accent); border-left-color: var(--accent); }
.sb-ch.sel .sb-frets i { box-shadow: 0 0 0 1px var(--accent); }
/* The marquee. Drag across the staff and everything inside comes with you. */
.sb-marquee {
  position: fixed; z-index: 55; pointer-events: none;
  border: 1px solid var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border-radius: var(--r);
}
.dragging { opacity: .85; cursor: grabbing !important; z-index: 6; }
.dragging.dup { opacity: .6; }
.sb-seclab.sel { background: var(--accent); color: var(--accent-fg); }
.sb.editing .sb-bar { cursor: copy; }
/* The bar number is its own target while editing: the bar's own menu lives
   there (insert one before it, take it out). */
/* While editing, the graduations are also the range handles. */
.sb.editing .sb-barnum, .sb.editing .sb-majnum {
  pointer-events: auto; cursor: pointer; padding: 1px 4px 1px 5px;
  border-radius: var(--r);
}
.sb.editing .sb-barnum:hover, .sb.editing .sb-majnum:hover {
  background: var(--accent); color: var(--accent-fg); opacity: 1;
}
.sb.editing .sb-secs { cursor: copy; }

/* The palette. Load a chord (or the hit stamp) and every click on a bar drops
   it in — the loaded one says so on itself and in the edit bar. */
.sb-shapes.sb-loaded .sb-shape { cursor: pointer; padding: 2px 5px; border-radius: var(--r); }
.sb-shapes.sb-loaded .sb-shape:hover { background: var(--chip); }
.sb-shape.armed { background: var(--well-2); box-shadow: inset 0 0 0 1.5px var(--accent); }
.sb-shape.armed b { color: var(--accent); }
.sb-xs {
  position: absolute; left: 0; font: 700 7px/1 var(--mono); font-style: normal;
  color: color-mix(in srgb, var(--fg) 60%, transparent);
}
.sb-armed {
  display: inline-flex; align-items: center; gap: 6px; height: 24px;
  padding: 0 4px 0 8px; background: var(--well-2); color: var(--accent);
  border-radius: var(--r); font-size: 10.5px;
}
.sb-armed b { font: 700 12px var(--mono); }

/* Length row inside a chord, and the string toggles inside a hit. */
.sb-seg.lens button, .sb-seg.wrap button { padding: 0 8px; height: 22px; font-size: 10.5px; }
.sb-seg.wrap { flex-wrap: wrap; }
.sb-xtog {
  font: 700 12px var(--mono); padding: 4px 0; width: 100%; cursor: pointer;
  border: 1.5px solid var(--line-2); border-radius: var(--r);
  background: var(--bg); color: var(--fg-mute);
}
.sb-xtog.on { background: var(--accent); color: var(--accent-fg); border-color: var(--accent); }

/* The grip strip: constant at every density — compression shrinks text, never
   notation. This is where a grip is worth reading at full size. */
.sb-grip { position: relative; width: 26px; height: 26px; flex: none; margin-top: 1px; }
.sb-grip::before {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 100%; height: 26px;
  background: repeating-linear-gradient(to bottom,
    color-mix(in srgb, var(--fg) 34%, transparent) 0 1px, transparent 1px 5px);
}
.sb-dot { position: absolute; width: 4.5px; height: 4.5px; border-radius: 50%; background: var(--fg); box-shadow: 0 0 0 1px var(--bg); }
.sb-dot.open { background: transparent; border: 1.2px solid var(--fg-dim); width: 3.5px; height: 3.5px; }

.sb-playhead {
  position: absolute; top: 0; left: 0; width: 2px; pointer-events: none; z-index: 4;
  background: var(--accent); box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 45%, transparent);
  will-change: transform;
}

.sb-notes {
  font-size: 11.5px; line-height: 1.55; color: var(--fg-dim);
  padding: 8px 0 0; border-top: 1px solid var(--line); max-width: 90ch;
}
.sb-notes b { color: var(--fg-mute); margin-right: 7px; font-size: 9.5px; text-transform: uppercase; letter-spacing: .12em; font-weight: 700; }

/* ------------------------------------------------------- floating surfaces */
.sb-pop {
  position: absolute; z-index: 60; min-width: 208px; padding: 9px;
  border-radius: var(--r); border: 1.5px solid var(--line-2);
  background: var(--bg-elev); box-shadow: var(--shadow);
  display: flex; flex-direction: column; gap: 7px;
}
.sb-pop.wide { width: min(560px, 92vw); position: fixed; }
.sb-pop.menu { padding: 4px; gap: 0; min-width: 186px; }
.sb-pophead {
  font-size: 9.5px; text-transform: uppercase; letter-spacing: .12em; font-weight: 700;
  color: var(--fg-mute); display: flex; justify-content: space-between; gap: 9px;
}
.sb-pophead i { font-style: normal; text-transform: none; letter-spacing: 0; font-weight: 500; }
.sb-menuitem {
  display: flex; align-items: center; gap: 8px; width: 100%;
  font-family: inherit; font-weight: 600; font-size: 11.5px; line-height: 1;
  height: 27px; padding: 0 9px; border: 0; background: none;
  color: var(--fg-dim); cursor: pointer; text-align: left; border-radius: var(--r);
  border-left: 3px solid transparent;
}
.sb-menuitem:hover { background: var(--chip); color: var(--fg); }
.sb-menuitem.on { color: var(--fg); border-left-color: var(--accent); background: var(--chip); }
.sb-menuitem .k { margin-left: auto; font: 500 9.5px var(--mono); color: var(--fg-mute); }
.sb-menugroup { font-size: 9px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--fg-mute); padding: 8px 9px 3px; }
.sb-menusep { height: 1px; background: var(--line); margin: 4px 0; }

.sb-popin {
  font: 700 14px var(--mono); padding: 6px 8px; border-radius: var(--r);
  border: 1.5px solid var(--line-2); background: var(--bg); color: var(--fg);
}
.sb-popin.text { font: 500 13px var(--sans, inherit); }
.sb-pop.wide-in { min-width: 320px; }
/* A note that states a fact about what you are looking at. Never a lesson. */
.sb-popnote { font-size: 10.5px; line-height: 1.45; color: var(--fg-mute); }
.sb-popgrid {
  display: grid; grid-template-columns: auto 1fr; gap: 5px 9px; align-items: center;
}
.sb-popnum {
  font: 700 12px var(--mono); font-variant-numeric: tabular-nums;
  padding: 4px 7px; border-radius: var(--r); width: 100%;
  border: 1.5px solid var(--line-2); background: var(--bg); color: var(--fg);
}
.sb-popfrets { display: flex; flex-direction: column; gap: 4px; }
.sb-fretin { display: grid; grid-template-columns: repeat(6, 1fr); gap: 4px; }
.sb-fretin input {
  font: 700 12px var(--mono); text-align: center; padding: 4px 0; width: 100%;
  border: 1.5px solid var(--line-2); border-radius: var(--r);
  background: var(--bg); color: var(--fg);
}
.sb-poprow { display: flex; gap: 6px; }
.sb-poprow .sb-tw, .sb-poprow .sb-primary { flex: 1; justify-content: center; height: 26px; }
.sb-srcs { display: flex; flex-direction: column; gap: 4px; max-height: 46vh; overflow: auto; }
.sb-src {
  display: flex; gap: 9px; align-items: baseline; font-size: 11px; padding: 5px 7px;
  background: var(--chip); border-left: 3px solid var(--line-2); border-radius: 0 var(--r) var(--r) 0;
}
.sb-src.used { border-left-color: color-mix(in srgb, var(--fg) 45%, transparent); }
.sb-src.rej { opacity: .68; }
.sb-src b { font: 700 10.5px var(--mono); color: var(--fg); }
.sb-src span { font-size: 9px; text-transform: uppercase; letter-spacing: .1em; color: var(--fg-mute); }
.sb-src i { font-style: normal; color: var(--fg-dim); font-size: 10.5px; }


@media (max-width: 760px) {
  .sb-act { margin-left: 0; }
  .sb-id h1 { font-size: 16px; }
}
