/* Live Performance Assistant — single stylesheet */
:root { --bg: #111; --fg: #f4f4f4; --muted: #9a9a9a; --accent: #ffb300; --ok: #2ecc71; --bad: #e74c3c; --info: #4aa3df; --panel: #1e1e1e; --border: #333;
  --nav-h: 0px; --lyrics-size: 2.6rem; }
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; background: var(--bg); color: var(--fg); font-family: -apple-system, "Helvetica Neue", Arial, "PingFang SC", "Microsoft YaHei", sans-serif; -webkit-text-size-adjust: 100%; }
body { overflow-x: hidden; }
.page { padding: 12px max(16px, env(safe-area-inset-right)) 12px max(16px, env(safe-area-inset-left)); max-width: 100%; }  /* clear of an iPhone's notch in landscape */
h1 { font-size: 1.4rem; margin: 0 0 8px; }
h2 { font-size: 1.1rem; margin: 12px 0 6px; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; }
a { color: var(--accent); }
.muted { color: var(--muted); }
.btn { display: inline-block; background: var(--panel); color: var(--fg); border: 2px solid var(--border); border-radius: 10px; padding: 10px 16px; font-size: 1rem; cursor: pointer; text-decoration: none; min-height: 44px; font-family: inherit;
  transition: background-color .08s, transform .08s; -webkit-tap-highlight-color: transparent; user-select: none; }
.btn:active { background: #3a3a3a; transform: scale(.97); }
.btn:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible, [tabindex]:focus-visible { outline: 3px solid var(--info); outline-offset: 2px; }
.btn[disabled] { opacity: .45; cursor: default; }
.btn-big { min-height: 64px; font-size: 1.3rem; padding: 14px 24px; }
.btn-huge { min-height: 120px; font-size: 1.8rem; width: 100%; }
.btn-primary { border-color: var(--accent); color: var(--accent); }
.btn-danger { border-color: var(--bad); color: var(--bad); }
.btn kbd { display: inline-block; font-family: inherit; font-size: .7rem; color: var(--muted); border: 1px solid var(--border); border-radius: 4px; padding: 0 5px; margin-left: 8px; vertical-align: middle; line-height: 1.3; }
.btn.current kbd, .btn-primary kbd { color: inherit; border-color: currentColor; opacity: .7; }

/* ---- role icons (LPA.icon): emoji, sized by the text around them ---- */
.icon { display: inline-block; font-style: normal; font-size: .95em; line-height: 1; margin-right: .35em; flex: none; }
.btn .icon, .field > span .icon { margin-right: .4em; }

/* ---- connection banner (every page that talks to the server) ---- */
.conn-banner { position: fixed; top: 0; left: 0; right: 0; z-index: 50; background: var(--bad); color: #fff; font-weight: bold; font-size: 1.1rem; text-align: center; padding: 10px 16px; box-shadow: 0 2px 8px rgba(0,0,0,.5); }
.conn-banner.connecting { background: #555; }
.conn-banner.own-copy { background: #8a5a00; font-size: 1rem; }
body.offline.own-copy .page { opacity: 1; }
body.offline .page { opacity: .55; }
body.offline .page { padding-top: 56px; }

/* ---- index ---- */
.route-list { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 10px; }
.route-list li { margin: 0; }
.route-card { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 4px; width: 100%; min-height: 84px; text-align: left; }
.route-card .route-device { font-size: .9rem; color: var(--muted); font-weight: normal; }
.route-group { margin: 14px 0 6px; }
.lan-urls { margin: 10px 0; font-size: 1.1rem; }
.lan-urls code { background: var(--panel); padding: 3px 8px; border-radius: 6px; }

/* ---- editor pages (library, events) ---- */
.editor { background: #181818; }
.editor-head { display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap; gap: 8px; position: sticky; top: 0; background: #181818; z-index: 5; padding: 4px 0; }
.editor-cols { display: flex; gap: 20px; flex-wrap: wrap; align-items: flex-start; }
.editor-side { flex: 0 0 280px; max-width: 100%; }
.editor-main { flex: 1 1 500px; min-width: 0; }
.song-list { list-style: none; padding: 0; margin: 0 0 12px; }
.song-item { margin-bottom: 10px; padding: 8px; background: var(--panel); border-radius: 8px; }
.song-title { font-weight: bold; margin-bottom: 4px; }
.btn-small { min-height: 36px; padding: 6px 10px; font-size: .9rem; margin: 2px 4px 2px 0; }
.arr-btn.active { border-color: var(--accent); color: var(--accent); }
.stack { display: flex; flex-direction: column; gap: 6px; }
.stack input, .stack textarea, .field input, .field select, .field textarea, .page-text, .singer-words-text, .flow-script, .flow-script-title, #import-text, .row input, .row select, .row textarea {
  background: #0d0d0d; color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 8px; font-size: 1rem; width: 100%; font-family: inherit; min-height: 40px; }
.row > input, .row > select { width: auto; }
.grid-form { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 8px 12px; margin-bottom: 8px; }
.field { display: flex; flex-direction: column; gap: 2px; font-size: .85rem; color: var(--muted); }
.field input[type=checkbox] { width: auto; align-self: flex-start; transform: scale(1.4); margin: 8px 6px; min-height: 0; }
.row { display: flex; gap: 8px; align-items: flex-end; flex-wrap: wrap; margin: 6px 0; }
.section-box { border: 1px solid var(--border); border-radius: 8px; margin: 8px 0; background: var(--panel); }
.section-box > summary { list-style: none; cursor: pointer; padding: 10px 12px; display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.section-box > summary::-webkit-details-marker { display: none; }
.section-box > summary::before { content: '▸'; color: var(--muted); width: 14px; }
.section-box[open] > summary::before { content: '▾'; }
.section-box > summary .sec-sum-name { font-weight: bold; font-size: 1.05rem; }
.section-box > summary .sec-sum-type { color: var(--accent); font-size: .8rem; text-transform: uppercase; letter-spacing: .05em; }
.section-box > summary .sec-sum-first { color: var(--muted); font-size: .9rem; flex: 1 1 200px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.section-body { padding: 0 12px 10px; border-top: 1px solid var(--border); }
.page-row { display: flex; flex-direction: column; gap: 6px; margin: 6px 0; padding: 6px 8px; border: 1px solid transparent; border-radius: 8px; }
.page-row.open { border-color: var(--border); background: #161616; }
.page-head { display: flex; align-items: center; gap: 8px; }
.page-head .page-num { min-width: 56px; }
.page-head .page-title { display: flex; align-items: center; gap: 8px; min-width: 0; margin-right: auto; }  /* the page's buttons sit on the right */
.page-head .btn { margin: 0; }
.page-edit { display: none; }
.page-row.open .page-edit { display: block; }
.page-row:not(.open) .page-preview { cursor: pointer; }
.page-text { font-family: Menlo, Consolas, monospace; }
.page-preview { padding: 6px 10px; background: #0d0d0d; border-radius: 6px; border: 1px dashed var(--border); font-size: .95rem; min-height: 32px; }
.page-preview .cp-line { margin-bottom: .2em; }
.singer-words { display: flex; flex-direction: column; gap: 4px; }
.singer-words-summary { font-size: .85rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.singer-words.own .singer-words-summary { color: var(--info); }
.page-row.open .singer-words-summary { display: none; }
.singer-words-offer, .singer-words-editor { display: none; }
.page-row.open .singer-words:not(.own):not(.shown) .singer-words-offer { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: .85rem; color: var(--muted); }
.page-row.open .singer-words.own .singer-words-editor, .page-row.open .singer-words.shown .singer-words-editor { display: flex; flex-direction: column; gap: 4px; }
.singer-words-offer .btn { margin: 0; }
.singer-words-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: .85rem; color: var(--muted); }
.singer-words-label { color: var(--info); }
.singer-words-head .btn { margin: 0; }
.singer-words-text { min-height: 56px; resize: vertical; }
.singer-words-text::placeholder { color: #666; font-style: italic; }
.singer-words.own .singer-words-text { border-color: var(--info); }
.singer-preview { margin-bottom: 6px; }
#flow { padding-left: 24px; }
.flow-entry { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin: 4px 0; }
.flow-label { flex: 1 1 160px; }
.flow-script { flex: 1 1 100%; }
.flow-script-title { flex: 1 1 200px; width: auto; }
.message { padding: 8px 10px; background: #2b2b1a; border: 1px solid var(--accent); border-radius: 6px; margin: 8px 0; }
.hidden { display: none !important; }
.revisions { list-style: none; padding: 0; }
.revisions li { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; padding: 4px 0; border-bottom: 1px solid var(--border); }
.readonly { border: 2px dashed var(--accent); padding: 10px; margin-top: 12px; }
.actions { margin: 12px 0; }
.btn.dirty { background: #3a2a00; border-color: var(--accent); color: var(--accent); }
.dirty-note { color: var(--accent); font-size: .9rem; }
h3 { margin: 16px 0 6px; font-size: 1rem; color: var(--accent); }
.collapse-tools { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin: 6px 0; }

/* ---- chordpro rendering ---- */
.cp-line { margin: 0 0 .4em; line-height: 1.2; white-space: normal; }
.cp-pair { display: inline-block; vertical-align: bottom; white-space: nowrap; }
.cp-chord { display: block; color: var(--accent); font-weight: bold; font-size: .85em; min-height: 1.1em; padding-right: .6em; }
.cp-lyric { display: block; }
.cp-lyrics-only .cp-line { font-size: 1.1em; }
/* melody line (简谱): one column per syllable (chord / notes / lyric), bars kept whole when a line wraps */
.mel-line { margin: 0 0 .5em; line-height: 1.2; }
.mel-bar { display: inline-block; vertical-align: bottom; white-space: nowrap; padding: 0 .1em 0 .4em; margin-bottom: .35em; border-right: 1px solid var(--muted); }
.mel-seg { display: inline-block; vertical-align: bottom; padding-right: .4em; }
.mel-chord { display: block; color: var(--accent); font-weight: bold; font-size: .85em; min-height: 1.1em; }
/* 简谱: a chord over the syllables it lasts for (.mel-run). The notes and words set each column's width and a long chord
   name runs on over the next ones, but the run is never narrower than its name, so it stops short of the next chord */
.mel-run { display: inline-block; vertical-align: bottom; }
.mel-run > .mel-chord { white-space: nowrap; padding-right: .45em; }
.mel-page { position: relative; }  /* ties are placed over it */
/* the notes row is tall enough for three beams and a low-octave dot, so every syllable column has the same height */
.mel-notes { display: flex; gap: .3em; align-items: flex-start; min-height: 2.75em; padding-top: .2em; font-variant-numeric: tabular-nums; }
.mel-lyric { display: block; }
.jp-note { display: inline-grid; grid-template-columns: auto 1fr; justify-items: center; line-height: 1; }
.jp-note > * { grid-column: 1; }
.jp-stack > .jp-body + .jp-body { margin-top: .1em; }  /* stacked notes (1+3+5): the numbers one above the other */
.mel-notes.mel-notes-stacked { align-items: flex-end; }  /* ... growing upward: the lowest number level with its neighbours */
.jp-grow { flex: 1 1 auto; }  /* last note of a syllable whose beam runs on into the next one */
.jp-oct { font-size: .45em; height: 1em; line-height: 1; }
.jp-body { display: inline-flex; align-items: flex-start; }
/* beams: one line per halving under the number; .jp-join carries it across the gap to the next number of the beat */
.jp-note > .jp-beam { justify-self: stretch; height: .07em; min-height: 1px; margin-top: .09em; background: currentColor; }
.jp-note > .jp-beam.jp-join { grid-column: 1 / -1; margin-right: -.3em; }
.jp-note.jp-grow > .jp-beam.jp-join { margin-right: -.4em; }
.jp-acc { font-size: .65em; vertical-align: .45em; }
.jp-dot { padding-left: .08em; }
.jp-dash { padding-top: .45em; }
.jp-tie { position: absolute; pointer-events: none; fill: currentColor; }
.jp-note { position: relative; }
.jp-tuplet { position: absolute; top: -1.5em; left: 50%; transform: translateX(-50%); font-size: .5em; font-style: italic; }  /* the 3 of a triplet */
/* repeat signs: a thick line with the two dots of |: and :| at the height of the notes */
.mel-rep { display: inline-block; vertical-align: bottom; font-weight: bold; line-height: 1; padding: 0 .12em 1.75em; }
.mel-rep-start { border-left: .16em solid currentColor; margin: 0 .15em 0 -.4em; }
.mel-rep-end { border-right: .16em solid currentColor; margin-right: -.1em; }
.mel-bar-repeat { border-right-color: transparent; }
.page-singer .mel-chord { display: none; }  /* the singer reads notes and words */
/* 五线谱 (abcjs): engraved in the text colour, chord names in the accent colour */
.staff-run { margin: 0 0 .4em; overflow: hidden; }
.staff-run .abcjs-chord { fill: var(--accent); font-weight: bold; font-family: inherit; }
.staff-run .abcjs-lyric { font-family: inherit; font-weight: normal; }
.cp-grid-row { display: flex; gap: 12px; padding: 6px 8px; border-bottom: 1px solid var(--border); align-items: baseline; }
/* the section's name says where the song is; the page being played is amber, the page after it blue */
.cp-grid-row.current .cp-grid-name { color: var(--accent); font-weight: bold; }
.cp-grid-row.next .cp-grid-name { color: var(--info); font-weight: bold; }
.cp-grid-page { display: flex; flex-direction: column; gap: 4px; padding: 3px 8px; border-radius: 6px; }
.cp-grid-page.current { background: #2a2410; box-shadow: inset 4px 0 0 var(--accent); }
.cp-grid-page.next { background: #14303f; box-shadow: inset 4px 0 0 var(--info); }
.cp-grid-name { flex: 0 0 110px; color: var(--muted); text-transform: uppercase; font-size: .85em; }
.cp-grid-chords { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; }
.cp-grid-line { display: flex; flex-wrap: wrap; gap: 6px 14px; }
.cp-grid-chord { font-weight: bold; font-size: 1.2em; color: var(--accent); }

/* ---- setlist editor ---- */
.setlist { list-style: none; padding: 0; margin: 0; }
.setlist-row { background: var(--panel); border: 1px solid var(--border); border-radius: 8px; margin: 6px 0; padding: 6px 8px; }
.setlist-row.dragging { opacity: .5; }
.setlist-row.drop-target { border-color: var(--accent); }
.setlist-line { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.drag-handle { cursor: grab; color: var(--muted); }
.setlist-line .seq { width: 28px; text-align: right; color: var(--muted); }
.setlist-line .title { flex: 1 1 160px; font-weight: bold; }
.setlist-line .title-link { color: inherit; text-decoration: none; }
.setlist-line .title-link:hover, .setlist-line .title-link:focus-visible { text-decoration: underline; }
.setlist-line .key { width: 40px; color: var(--accent); }
.setlist-line .bpm { width: 70px; }
.setlist-line .dur { width: 50px; }
.setlist-detail { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 6px; font-size: .9rem; }
.field.inline { flex-direction: row; align-items: center; gap: 6px; }
.field.inline input { width: 90px; }
.event-scripts { flex: 1 1 100%; }
.script-item-text { flex: 1 1 100%; }
.script-pos { width: auto !important; min-width: 180px; }
.script-text { flex: 1 1 200px; }
.item-script .setlist-line .title { color: #9bd; font-weight: normal; font-style: italic; }

/* ---- performance views (shared) ---- */
.badge { display: inline-block; padding: 4px 10px; border-radius: 999px; font-size: .85rem; border: 1px solid var(--border); }
.badge-ok, .badge-ready { border-color: var(--ok); color: var(--ok); }
.badge-bad { border-color: var(--bad); color: var(--bad); }
.badge-playing { background: var(--accent); color: #000; border-color: var(--accent); font-weight: bold; }
.badge-paused { background: var(--info); color: #000; border-color: var(--info); font-weight: bold; }
.dot { display: inline-block; width: 12px; height: 12px; border-radius: 50%; margin: 0 4px; vertical-align: middle; }
.dot-ok { background: var(--ok); } .dot-bad { background: var(--bad); }
.panel { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; margin: 10px 0; }
main.perf { display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh; padding-bottom: calc(var(--nav-h) + 12px); }
/* whatever is scrolled into view (focus, a test, a link) stops above the fixed nav bar of the performance pages */
html:has(main.perf) { scroll-padding-bottom: calc(var(--nav-h) + 12px); }
.perf-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; flex-wrap: wrap; border-bottom: 1px solid var(--border); padding-bottom: 6px; }
.perf-title { font-size: 2rem; font-weight: bold; line-height: 1.1; }
.perf-meta { font-size: 1.2rem; display: flex; gap: 14px; align-items: center; flex-wrap: wrap; }
.perf-meta .key-big { font-size: 1.6rem; color: var(--accent); }
.section-label { font-size: 1rem; letter-spacing: .08em; color: var(--accent); text-transform: uppercase; margin: 10px 0 4px; font-weight: bold; }
.section-label.now { display: inline-block; font-size: 1.3rem; background: var(--accent); color: #000; border-radius: 8px; padding: 4px 14px; margin: 10px 0 8px; }
.section-label.now:empty { display: none; }
.section-label.next-now { display: inline-block; font-size: 1.1rem; background: var(--info); color: #000; border-radius: 8px; padding: 4px 12px; margin: 10px 0 8px 10px; vertical-align: top; }
.section-label.next-now:empty { display: none; }
/* song count (pianist): the bar and beat being played beside the page labels, green (amber is the page, blue the
   next one); the bar itself lit in the 简谱 view, and the first full bar of each line numbered */
.count-chip { display: inline-flex; align-items: center; gap: 12px; font-size: 1.3rem; font-weight: bold; font-variant-numeric: tabular-nums;
  border: 2px solid var(--ok); color: var(--ok); border-radius: 8px; padding: 2px 12px; margin: 10px 0 8px 10px; vertical-align: top; min-height: 2.15rem; }
.count-chip[data-phase="count_in"], .count-chip[data-phase="waiting"] { border-color: var(--info); color: var(--info); }
.count-beats { display: inline-flex; gap: 7px; align-items: center; }
.count-dot { width: .62em; height: .62em; border-radius: 50%; border: 2px solid currentColor; opacity: .5; }
.count-dot.accent { width: .85em; height: .85em; }
.count-dot.on { background: currentColor; opacity: 1; }
/* the count: the bar (measure, row) being played faintly tinted, the crotchet (dotted in compound time) or the chord
   being played in a brighter box */
.mel-bar.count-now { background: rgba(46, 204, 113, .09); border-radius: 4px; }
.count-beat { position: absolute; pointer-events: none; border: 2px solid var(--ok); background: rgba(46, 204, 113, .2); border-radius: 6px; }
.cp-line.count-row { background: rgba(46, 204, 113, .09); border-radius: 4px; }
.cp-pair.count-chord, .cp-grid-chord.count-chord { background: rgba(46, 204, 113, .24); box-shadow: 0 0 0 2px var(--ok); border-radius: 6px; }
.staff-run .count-staff-now { fill: rgba(46, 204, 113, .09); stroke: none; }  /* the measure in 五线谱 */
.staff-run .count-staff-beat { fill: rgba(46, 204, 113, .24); stroke: var(--ok); stroke-width: 1.5; }
/* the count-in's last bar (songcount.js lead): the first note lit ahead of it, its bar tinted fainter, its box
   flashing on every click (lit afresh on each): bright on the click, fading to a dashed outline by the next
   (--count-beat: a beat), brighter on the bar's first beat */
@keyframes count-lead { from { background-color: rgba(46, 204, 113, .55); border-style: solid; } to { background-color: rgba(46, 204, 113, .06); } }
@keyframes count-lead-one { from { background-color: var(--ok); border-style: solid; } to { background-color: rgba(46, 204, 113, .06); } }
@keyframes count-lead-staff { from { fill: rgba(46, 204, 113, .55); } to { fill: rgba(46, 204, 113, .06); } }
@keyframes count-lead-staff-one { from { fill: rgba(46, 204, 113, .95); } to { fill: rgba(46, 204, 113, .06); } }
.mel-bar.count-now.count-lead, .cp-line.count-row.count-lead { background: rgba(46, 204, 113, .045); }
/* the count's lead-in (songcount.js lead): bars of rests above the page it starts on, until the end of its first line */
.count-lead-in { margin: 0 0 .15em; }
.staff-run .count-staff-now.count-lead { fill: rgba(46, 204, 113, .045); }
.count-beat.count-lead, .count-chord.count-lead { border-style: dashed; animation: count-lead var(--count-beat, .5s) ease-out forwards; }
.count-beat.count-lead-one, .count-chord.count-lead-one { animation-name: count-lead-one; }
.staff-run .count-staff-beat.count-lead { stroke-dasharray: 4 3; animation: count-lead-staff var(--count-beat, .5s) ease-out forwards; }
.staff-run .count-staff-beat.count-lead-one { animation-name: count-lead-staff-one; }
/* Whole song: the number of a line's first full bar (pianist.js numberBars) in the gap left of the line, on its chord
   row: a zero-width box before the first chord name that ends just before it, so nothing moves. It grows with the text
   only as far as the page's own left gap and the bar's lead-in allow (two digits: up to .256 of the text + 6.4px,
   three: .187 + 4.6px; 9px at the pianist's 60%), and is centred on the chord name: raised by half the difference of
   their heights (digits and capitals are about .72 of the font size). The chord's size reaches it as a
   length (a registered property; without it the number sits on the chords' baseline). */
@property --chord-fs { syntax: '<length>'; inherits: true; initial-value: 0px; }
.mel-chord[data-bar-no] { --chord-fs: 1em; }
.mel-chord[data-bar-no]::before { content: attr(data-bar-no); display: inline-block; box-sizing: border-box; width: 4em; margin-left: -4em; padding-right: .4em;
  text-align: right; font-size: min(.85em, calc(.3em + 6.4px)); color: var(--muted); font-weight: bold; letter-spacing: -.02em; vertical-align: calc((var(--chord-fs) - 1em) * .36); }
.mel-chord.bar-no-3::before { font-size: min(.68em, calc(.22em + 4.6px)); letter-spacing: -.05em; }
/* 五线谱: the same number for each staff line, in the same column, centred on that line's chord names (numberStaff) */
.staff-bar-no { position: absolute; z-index: 2; pointer-events: none; font-size: min(.7225em, calc(.256em + 6.4px)); line-height: 1; font-weight: bold; color: var(--muted);
  letter-spacing: -.02em; white-space: nowrap; transform: translateX(-100%); }
.staff-bar-no.bar-no-3 { font-size: min(.578em, calc(.187em + 4.6px)); letter-spacing: -.05em; }
/* the singer's 简谱 has no chord row: beside the line's first numbers instead (their middle is 1.15em down the bar) */
@property --bar-fs { syntax: '<length>'; inherits: true; initial-value: 0px; }
.mel-bar.bar-no-notes { position: relative; --bar-fs: 1em; }
.mel-bar.bar-no-notes::before { content: attr(data-bar-no); position: absolute; right: calc(100% - var(--bar-fs) * .4 + .4em); top: calc(var(--bar-fs) * 1.15 - .5em);
  font-size: min(.7225em, calc(.256em + 6.4px)); line-height: 1; color: var(--muted); font-weight: bold; letter-spacing: -.02em; white-space: nowrap; }
.mel-bar.bar-no-notes.bar-no-3::before { font-size: min(.578em, calc(.187em + 4.6px)); letter-spacing: -.05em; }
/* 🥁 Count: beside the line's chord row, and the singer's lyrics: beside the line's first row of words. The page's own
   gap is too narrow there (the barline; the words start at its edge), so those lines move in by about one number. */
@property --row-fs { syntax: '<length>'; inherits: true; initial-value: 0px; }
.cv-numbered .cv-line { padding-left: calc(2px + .66em); }
.cp-numbered { padding-left: .42em; }
.cv-chords[data-bar-no], .cp-numbered > .cp-line[data-bar-no] { --row-fs: 1em; }
.cv-chords[data-bar-no]::before { content: attr(data-bar-no); position: absolute; right: calc(100% + 5px); top: calc(var(--row-fs) * .55 - .5em);  /* the chord names' middle */
  font-size: .6em; line-height: 1; color: var(--muted); font-weight: bold; letter-spacing: -.02em; white-space: nowrap; }
.cv-chords.bar-no-3::before { font-size: .5em; letter-spacing: -.05em; }
/* a lyric line's: a zero-width box at the start of its first row of words (wherever a remark or a wrap puts it), raised
   to the words' middle (measured on Chinese characters) */
.cp-numbered > .cp-line[data-bar-no]::before { content: attr(data-bar-no); display: inline-block; box-sizing: border-box; width: 4em; margin-left: -4em; padding-right: 5px;
  text-align: right; font-size: .38em; line-height: 1; color: var(--muted); font-weight: bold; letter-spacing: -.02em; white-space: nowrap;
  vertical-align: calc((var(--row-fs) - 1em) * .35); }
.cp-numbered > .cp-line.bar-no-3::before { font-size: .3em; letter-spacing: -.05em; }
#btn-count.active { background: var(--ok); color: #000; border-color: var(--ok); }
/* the video that keeps a phone's screen on over plain http (LPA.requestWakeLock): one pixel, out of the way */
.keep-awake { position: fixed; left: 0; bottom: 0; width: 1px; height: 1px; opacity: .01; pointer-events: none; z-index: -1; }
/* the singer's and the pianist's own click (myclick.js): green while on, amber while it needs a tap for the sound, a flash on each click */
#btn-my-click.active { border-color: var(--ok); color: var(--ok); }
#btn-my-click.needs-tap { border-color: var(--accent); color: var(--accent); }
#btn-my-click.beat { background: rgba(46, 204, 113, .35); }
.now-count { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 4px 0 8px; }
.count-settings .count-issue { color: var(--accent); margin: 2px 0; }
.count-issue { color: var(--accent); }
.count-chip-head { margin: 0; font-size: 1.05rem; padding: 2px 10px; min-height: 0; }  /* singer iPad header */
/* pianist phone: the bar and beat big, lighting up on every beat (green, the downbeat solid) */
.count-big { display: flex; flex-direction: column; align-items: center; gap: 6px; margin: 8px 0 0; padding: 12px; border-radius: 12px; transition: background-color .12s; }
.count-big .count-page { font-size: 1rem; font-weight: normal; color: var(--fg); }
.count-big .count-where { font-size: 3rem; line-height: 1.1; }
/* /pianist-audio: what the click's sound file does, and this phone's earbud delay (Metronome.FileClick) */
.click-file { margin: 4px 0 0; text-align: center; font-variant-numeric: tabular-nums; }
.click-early { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 12px 0; }
.click-early strong { min-width: 4.5em; text-align: center; font-variant-numeric: tabular-nums; }
.click-early .muted { flex-basis: 100%; font-size: .85rem; }
.count-big .count-beats { gap: 12px; font-size: 1.6rem; }
.count-big.flash { background: rgba(46, 204, 113, .25); }
.count-big.flash.accent { background: var(--ok); color: #000; }
.audio.counting #beat-display { display: none; }
.count-big.click-off::after { content: 'Your click is off · the pages still turn'; font-size: .9rem; font-weight: normal; color: var(--muted); }
.btn-go { border-color: var(--ok); color: var(--ok); }
.btn-hold { position: relative; overflow: hidden; touch-action: none; -webkit-user-select: none; }
.btn-hold .hold-fill { position: absolute; inset: 0; background: rgba(231, 76, 60, .35); transform: scaleX(0); transform-origin: left; }
.btn-hold.holding .hold-fill { transform: scaleX(1); transition: transform 1s linear; }
.btn-hold .lbl { position: relative; }
.auto-turn-badge { margin: 8px 0 0; }
.phone-setlist { list-style: none; margin: 8px 0 0; padding: 0; }
.phone-song { border-top: 1px solid var(--border); }
.phone-song.now .phone-song-head strong { color: var(--accent); }
.phone-song-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; width: 100%; background: none; border: 0; color: inherit;
  font: inherit; text-align: left; padding: 10px 2px; min-height: 52px; cursor: pointer; }
.phone-song-chips { flex: none; }
.phone-song-detail { padding: 0 2px 12px; display: flex; flex-direction: column; gap: 8px; }
.phone-song-detail p { margin: 0; }
/* auto page turn in the setlist editor and on the control laptop */
.chip.chip-ok { border-color: var(--ok); color: var(--ok); }
.chip.chip-off { color: var(--muted); }
.auto-turn { display: inline-flex; align-items: center; gap: 2px; }
.auto-turn-label { display: inline-flex; align-items: center; gap: 4px; cursor: pointer; font-size: .9rem; white-space: nowrap; }
.auto-turn-label input { transform: scale(1.3); margin: 0 6px 0 2px; }
.setlist-warn { list-style: none; margin: 4px 0 0 64px; padding: 0; color: var(--accent); font-size: .85rem; }
.row-item .auto-turn-mark { width: 70px; font-size: .8rem; color: var(--ok); }
/* control laptop: Who can do what (actions down, screens across) */
.perm-wrap { overflow-x: auto; }
.perm-table { border-collapse: collapse; width: 100%; }
.perm-table th, .perm-table td { padding: 8px 10px; border-bottom: 1px solid var(--border); text-align: center; vertical-align: middle; }
.perm-table th[scope=row], .perm-table thead th:first-child { text-align: left; font-weight: normal; }
.perm-table .perm-label { font-weight: bold; }
.perm-table .perm-screen { white-space: nowrap; color: var(--muted); font-size: .85rem; }
.perm-table .perm-none { color: var(--muted); }
.perm-table input[type=checkbox] { width: auto; min-height: 0; margin: 0; padding: 0; transform: scale(1.4); accent-color: var(--accent); cursor: pointer; }
/* control laptop: Event settings (songs down, their click and song count across) */
.es-songs-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; margin-top: 6px; }
.es-songs-head h3 { margin: 0; }
.es-all { display: inline-flex; align-items: center; gap: 6px; }
.es-all .btn { margin: 0; }
.es-wrap { overflow-x: auto; }
.es-table { border-collapse: collapse; width: 100%; }
.es-table th, .es-table td { padding: 6px 8px; border-bottom: 1px solid var(--border); text-align: left; vertical-align: middle; }
.es-table thead th { white-space: nowrap; color: var(--muted); font-size: .85rem; font-weight: normal; }
.es-table th[scope=row] { font-weight: normal; min-width: 150px; }
.es-table tr.current th[scope=row] { color: var(--accent); }
.es-table .es-turn { white-space: nowrap; }
.es-table input[type=number], .es-table select { background: #0d0d0d; color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 6px; font-size: 1rem; font-family: inherit; min-height: 36px; }
.es-table input[type=number] { width: 4.5em; }
.es-table input[type=checkbox] { width: auto; min-height: 0; margin: 0 4px; padding: 0; transform: scale(1.3); accent-color: var(--accent); cursor: pointer; }
.es-table input[type=checkbox]:disabled { cursor: not-allowed; opacity: .4; }
.count-settings input[type=checkbox] { width: auto; min-height: 0; padding: 0; margin: 0 6px; transform: scale(1.4); flex: none; accent-color: var(--accent); }
.count-settings input.count-lead { width: 5.5em; flex: none; }
.flow-remark-singer { display: inline-block; font-size: 1.3rem; font-style: italic; font-weight: 600; color: var(--accent); margin: 10px 0 8px 12px; vertical-align: middle; }
.next-remark { font-style: italic; text-transform: none; letter-spacing: 0; }
.notes { padding: 8px 12px; border-left: 4px solid var(--accent); background: #262200; margin: 8px 0; font-size: 1.1rem; }
.notes-song { font-size: 1rem; }
.page-singer { height: 100vh; height: 100dvh; }
/* singer: the page (or the scrolling song) on the left, the flow column on the right unless it is hidden */
.singer-cols { display: flex; gap: 16px; flex: 1 1 auto; min-height: 0; }
.singer-main { flex: 1 1 auto; min-width: 0; min-height: 0; display: flex; flex-direction: column; position: relative; }
/* the singer's entry countdown (singer.js paintCue): over the foot of the song, never moving it; blue while bars are
   left, green in the last bar, flashing on each click */
.entry-cue { position: absolute; left: 0; right: 10px; bottom: 8px; z-index: 5; padding: 12px 18px 14px; border-radius: 14px;
  background: #0e0e0e; border: 3px solid var(--info); color: var(--info); box-shadow: 0 6px 28px rgba(0, 0, 0, .7);
  display: flex; flex-direction: column; gap: 4px; pointer-events: none; }
.singer-main.cue-center .entry-cue { top: 50%; bottom: auto; transform: translateY(-50%); }
.singer-main.cue-center.cue-on #lyrics > .instrumental { visibility: hidden; }
.entry-cue .cue-top { display: flex; align-items: baseline; gap: 14px; font-weight: bold; font-variant-numeric: tabular-nums; }
.entry-cue .cue-num { font-size: 3.6rem; line-height: 1; }
.entry-cue .cue-unit { font-size: 1.5rem; }
.entry-cue .cue-beats { margin-left: auto; font-size: 1.5rem; align-self: center; }
.entry-cue .cue-where { font-size: 1.25rem; font-weight: bold; }
.entry-cue .cue-words { font-size: 1.7rem; color: var(--fg); line-height: 1.25; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.entry-cue .cue-words:empty { display: none; }
.entry-cue .cue-words strong { color: var(--accent); }
.entry-cue .cue-progress { height: 6px; border-radius: 3px; background: rgba(74, 163, 223, .2); overflow: hidden; margin-top: 4px; }
.entry-cue .cue-fill { height: 100%; width: 0; background: currentColor; }
.entry-cue.cue-last { border-color: var(--ok); color: var(--ok); }
.entry-cue.cue-last .cue-num { font-size: 5rem; }
.entry-cue.cue-last .cue-progress { background: rgba(46, 204, 113, .2); }
/* the pianist's card (pianist.js): counts the band in at the foot of the chart; the dock takes no room and stays
   above the buttons while a long page scrolls */
.cue-dock { position: sticky; bottom: calc(var(--nav-h) + 8px); height: 0; z-index: 5; }
.cue-dock .entry-cue { right: 0; bottom: 0; }
.entry-cue.cue-flash { animation: cue-flash var(--count-beat, .5s) ease-out forwards; }
@keyframes cue-flash { from { background-color: #17552f; } to { background-color: #0e0e0e; } }  /* opaque: the song under it never shows through */
@media (prefers-reduced-motion: reduce) { .entry-cue.cue-flash { animation: none; } }
@media (max-width: 600px) {
  .entry-cue { right: 0; padding: 8px 12px 10px; }
  .entry-cue .cue-num { font-size: 2.6rem; } .entry-cue.cue-last .cue-num { font-size: 3.4rem; }
  .entry-cue .cue-unit, .entry-cue .cue-beats { font-size: 1.15rem; } .entry-cue .cue-where { font-size: 1rem; }
  .entry-cue .cue-words { font-size: 1.25rem; }
}
.singer-side { flex: 0 0 26%; min-width: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.page-singer.flow-hidden .singer-side { display: none; }
.singer-song { flex: 1 1 auto; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; line-height: 1.3; padding-right: 6px; }
/* set in the lyric size (A− / A+), never smaller than readable; the heading's box grows and shrinks with its words */
.singer-song .song-sec-head { cursor: default; font-size: max(.5em, .8rem); min-height: 0; padding: .3em .6em; gap: .6em; }
.singer-song .song-sec-notes { font-size: max(.45em, .75rem); }
.singer-song .script-text { font-size: max(.7em, .9rem); }
.singer-song .instrumental { font-size: max(.55em, .8rem); }
.singer-flow .flow-row { font-size: 1.1rem; -webkit-tap-highlight-color: transparent; }
.singer-flow .flow-row:active { filter: brightness(1.4); }
.singer-flow .flow-row.next { box-shadow: inset 6px 0 0 var(--info); padding-left: 14px; }
.current-page { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 30vh; }
.lyrics { font-size: var(--lyrics-size); line-height: 1.3; flex: 1 1 auto; min-height: 0; overflow: hidden; }
/* a script (spoken) page: framed amber like anything current (blue is for what comes next); its labels keep their
   own colours, so NEXT stays black on blue. A short script's frame ends at its words, a long one still fits. */
.page-script { background: #221c0e; border-radius: 10px; padding: 10px; }  /* no dashed border (the user, 2026-10-15) */
.current-page.page-script { flex: 0 1 auto; }
.script-text { white-space: pre-wrap; font-size: 1.6rem; color: #cfe8ff; }  /* upright: browsers only fake an italic for Chinese */
/* the singer's current page: a script's words at the lyric size (A− / A+), the next song below them a little smaller */
#lyrics .script-text { font-size: 1em; }
#lyrics .next-song-block { margin-top: .6em; font-size: .85em; }
#lyrics .next-song-block .script-text { font-size: .9em; }
.perf-nav { position: fixed; left: 0; right: 0; bottom: 0; display: flex; gap: 10px; padding: 10px max(16px, env(safe-area-inset-right)) calc(8px + env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
  background: var(--bg); border-top: 1px solid var(--border); flex-wrap: wrap; z-index: 20; }
.nav-btn { flex: 1 1 140px; min-height: 72px; font-size: 1.4rem; }
.page-singer .nav-btn { min-height: 88px; font-size: 1.6rem; }
.transpose .btn-small { min-height: 44px; min-width: 44px; font-size: 1.3rem; }
.toggles { display: flex; gap: 6px; flex-wrap: wrap; }
.toggles .btn-small { min-height: 44px; }
/* pianist ✎ Edit: ✎ Chords / ✎ Piano in a menu under it, so the live row has no edit switch to hit by mistake */
.edit-wrap { position: relative; }
.edit-menu { position: absolute; top: calc(100% + 6px); left: 0; z-index: 30; padding: 8px; background: var(--panel);
  border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 8px 24px rgba(0, 0, 0, .5); }
.edit-menu .btn-small { min-height: 48px; font-size: 1.05rem; white-space: nowrap; }
/* Start sits apart from Next ▶, so reaching for the next page never starts the show */
.perf-nav #btn-start-song { margin-left: 18px; }
/* pianist: the page labels and the bar chip, with the side column's toggle at the end of the same row */
.label-row { display: flex; align-items: center; flex-wrap: wrap; }
.pianist-content .song-page, .pianist-content .cp-grid-page { cursor: pointer; }  /* a tap goes to that page */
.label-row #toggle-structure { margin-left: auto; min-height: 44px; }
.toggle[data-value] { border-color: var(--accent); }
.text-size .btn-small { min-height: 44px; min-width: 44px; }
.pianist-cols { display: flex; gap: 16px; flex: 1 1 auto; }
.pianist-main { flex: 1 1 60%; min-width: 0; }
.pianist-side { flex: 0 0 34%; min-width: 0; }
/* structure hidden: the content takes the whole width and short lyric lines flow side by side;
   a blank line (stanza break) always starts a new row */
.page-pianist.structure-hidden .pianist-side { display: none; }
.page-pianist.structure-hidden .pianist-content .cp-line { display: inline-block; vertical-align: top; max-width: 100%; margin-right: 2.2em; }
.page-pianist.structure-hidden .pianist-content .cp-line.cp-line-empty { display: block; margin-right: 0; }
.pianist-content { font-size: 1.6rem; line-height: 1.25; min-height: 30vh; }
.pianist-content .cp-chord { font-size: .9em; }
.flow-row.current { background: var(--accent); color: #000; border-radius: 6px; }
.flow-row.current .muted { color: #333; }
/* Minimal: the flow shorthand alone, top to bottom, in a column only as wide as its widest entry */
.page-pianist.structure-minimal .pianist-side { flex: 0 0 auto; }
.flow-shorthand { display: flex; flex-direction: column; align-items: stretch; gap: 6px; font-weight: bold; font-size: 1.2rem; }
.flow-shorthand .sh { padding: 6px 10px; border: 1px solid var(--border); border-radius: 6px; cursor: pointer; min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }
.flow-shorthand .sh.current { background: var(--accent); color: #000; border-color: var(--accent); }
/* pianist side column: on the last page of a flow entry, the entry that comes next in blue */
.pianist-side .flow-row.next, .pianist-side .flow-row.next[class*="hl-"] { background: var(--info); color: #000; border-radius: 6px; }
.pianist-side .flow-row.next .muted { color: #333; }
.flow-shorthand .sh.next, .flow-shorthand .sh.next[class*="hl-"] { background: var(--info); color: #000; border-color: var(--info); }
.flow-row { display: flex; gap: 8px; padding: 8px 10px; border-bottom: 1px solid var(--border); cursor: pointer; align-items: baseline; min-height: 44px; }
.flow-row-script { color: #9bd; }
.flow-name { flex: 1 1 auto; }
.flow-remark { flex: 0 1 auto; text-align: right; font-weight: 600; font-style: italic; overflow-wrap: anywhere; }
.flow-edit { flex: 0 0 auto; color: var(--muted); }
.flow-row.current .flow-edit { color: #333; }
.flow-row-locked { opacity: .45; cursor: default; }
.structure.marking .flow-full { outline: 2px dashed var(--info); outline-offset: 2px; border-radius: 6px; }
.flow-mark-toggle { margin-top: 10px; min-height: 44px; }
/* ✎ Edit flow (pianist Detail): ☰ drag, ⧉ play again, ✕ take out, + Add section; the part being played stays put */
.flow-tools { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.flow-tools .btn { min-height: 44px; }
.structure.marking .flow-row { align-items: center; padding-top: 2px; padding-bottom: 2px; }
.flow-drag, .flow-btn { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; min-width: 40px; min-height: 40px;
  border-radius: 6px; color: var(--muted); font-size: 1.15rem; background: none; border: 0; padding: 0; cursor: pointer; touch-action: none; }
.flow-btn { touch-action: manipulation; border: 1px solid var(--border); }
.flow-drag { cursor: grab; font-size: 1.3rem; }
.flow-row.current .flow-drag, .flow-row.current .flow-btn, .pianist-side .flow-row.next .flow-drag, .pianist-side .flow-row.next .flow-btn { color: #222; border-color: #222; }
.flow-btn.flow-remove:hover { color: var(--bad); border-color: var(--bad); }
.flow-name-btn { flex: 1 1 auto; min-width: 0; min-height: 40px; display: flex; align-items: center; gap: 6px; padding: 4px 8px;
  text-align: left; font: inherit; color: inherit; background: transparent; border: 1px dashed var(--border); border-radius: 6px; cursor: pointer; }
.flow-name-btn .flow-pencil { flex: 0 0 auto; color: var(--muted); }
.flow-name-stack { display: flex; flex-direction: column; min-width: 0; overflow-wrap: anywhere; }
.flow-name-stack .flow-remark { text-align: left; font-size: .9em; }
.flow-row.current .flow-name-btn, .pianist-side .flow-row.next .flow-name-btn { border-color: #222; }
.flow-row.current .flow-pencil, .pianist-side .flow-row.next .flow-pencil { color: #222; }
.flow-editing .page-pianist .pianist-side { flex-basis: max(34%, 360px); }
.flow-playing { flex: 0 0 auto; min-width: 40px; text-align: center; font-size: .9rem; }
.flow-row.sortable-ghost { opacity: .35; }
.flow-row.sortable-chosen { box-shadow: 0 0 0 2px var(--info); border-radius: 6px; }
/* the pianist's Setlist: one big row per item; the one on stage amber, the next one blue, the ones done dimmed */
.setlist-list { display: flex; flex-direction: column; gap: 6px; }
.setlist-item { display: grid; grid-template-columns: 2.4em 1fr auto; gap: 10px; align-items: center; min-height: 56px; padding: 8px 12px;
  text-align: left; background: var(--panel, #1b1b1b); color: var(--fg); border: 1px solid var(--border); border-radius: 8px; font: inherit; cursor: pointer; }
.setlist-item .setlist-num { text-align: center; font-weight: 700; color: var(--muted); }
.setlist-title { display: flex; flex-direction: column; min-width: 0; }
.setlist-title strong { font-size: 1.1rem; overflow-wrap: anywhere; }
.setlist-item.current { background: var(--accent); color: #000; border-color: var(--accent); }
.setlist-item.current .muted, .setlist-item.current .setlist-num { color: #333; }
.setlist-item.next { box-shadow: inset 6px 0 0 var(--info); }
.setlist-item.done { opacity: .6; }
.setlist-item[disabled] { opacity: .35; cursor: not-allowed; }
.setlist-offline { margin: 0 0 10px; color: var(--warn, #e0a030); font-weight: 600; }
.flow-add-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
.flow-add-list .btn { min-height: 52px; justify-content: flex-start; text-align: left; }
.flow-mark-hint { margin: 4px 0 0; font-size: .9rem; }

/* flow highlight colours (validation.FLOW_COLORS): a colour bar + tint; the current row stays amber */
.hl-red { --hl: #ff5a52; --hl-bg: rgba(255, 90, 82, .24); }
.hl-green { --hl: #3ddc84; --hl-bg: rgba(61, 220, 132, .2); }
.hl-blue { --hl: #4aa3ff; --hl-bg: rgba(74, 163, 255, .26); }
.hl-purple { --hl: #b388ff; --hl-bg: rgba(179, 136, 255, .26); }
.hl-pink { --hl: #ff7ac8; --hl-bg: rgba(255, 122, 200, .24); }
.flow-row[class*="hl-"], .song-sec[class*="hl-"] .song-sec-head { background: var(--hl-bg); box-shadow: inset 6px 0 0 var(--hl); border-radius: 6px; }
.flow-row[class*="hl-"] { padding-left: 14px; }
.flow-row.current[class*="hl-"] { background: var(--accent); }
.flow-shorthand .sh[class*="hl-"] { border-color: var(--hl); background: var(--hl-bg); }
.flow-shorthand .sh.current[class*="hl-"] { background: var(--accent); box-shadow: inset 0 -5px 0 var(--hl); }
.swatches { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.swatch { width: 44px; height: 44px; border-radius: 50%; border: 3px solid transparent; background: var(--hl, none); cursor: pointer; padding: 0; color: var(--muted); font-size: 1rem; font-family: inherit; }
.swatch-none { --hl: initial; border-color: var(--border); }  /* never inherit a highlighted row's colour */
.swatch.active { border-color: #fff; box-shadow: 0 0 0 3px var(--hl, var(--muted)); }
.swatches-small { gap: 6px; }
.swatches-small .swatch { width: 28px; height: 28px; border-width: 2px; font-size: .7rem; }
.swatches-small .swatch.active { box-shadow: 0 0 0 2px var(--hl, var(--muted)); }

/* whole-song view: the full flow with chords + lyrics, scrolling inside the content box */
.pianist-content.style-full { font-size: 1.3rem; }
.pianist-content.song-scroll { max-height: calc(100vh - var(--nav-h) - 230px); max-height: calc(100dvh - var(--nav-h) - 230px); overflow-y: auto; -webkit-overflow-scrolling: touch; padding-right: 6px; scrollbar-width: none; }
.pianist-content.song-scroll::-webkit-scrollbar { display: none; }  /* no bar between the song and the flow column; it still scrolls */
/* current = amber, next = blue; the legend above the content says so */
/* pianist: after the last section, the next song and how it starts */
.next-song-block { margin-top: 18px; padding-top: 8px; border-top: 2px dashed var(--info); }
.next-song-head { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; margin: 0 0 6px; font-size: .75em; }
.next-song-label { background: var(--info); color: #000; border-radius: 6px; padding: 1px 8px; text-transform: uppercase; letter-spacing: .08em; font-weight: bold; }
.next-song-title { font-weight: bold; }
.next-song-meta { color: var(--muted); }
.next-song-block .song-sec-head { cursor: default; }
.singer-song .next-song-head { font-size: max(.45em, .75rem); }  /* the singer's song view is set in its large lyric size */
.page-singer .section-label.next-now { font-size: 1.1rem; }
.singer-labels { display: flex; flex-wrap: wrap; align-items: center; column-gap: 10px; }
.singer-labels .section-label.now, .singer-labels .section-label.next-now, .singer-labels .flow-remark-singer { margin-left: 0; margin-right: 0; }
.page-singer .section-label.next-now.hidden { display: none; }
.song-sec { margin: 0 0 14px; }
.song-sec-head { display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap; padding: 6px 12px; border-radius: 6px; cursor: pointer; font-size: .8em; font-weight: bold; color: var(--accent); min-height: 36px; border-bottom: 1px solid var(--border); }
.song-sec-name { text-transform: uppercase; letter-spacing: .06em; }
.song-sec-remark { font-style: italic; color: var(--fg); }
.song-sec.current .song-sec-head { background: var(--accent); color: #000; border-bottom-color: var(--accent); }
.song-sec.current .song-sec-remark { color: #000; }
.song-sec.next .song-sec-head { background: var(--info); color: #000; border-bottom-color: var(--info); }
.song-sec-tag { font-size: .75em; letter-spacing: .1em; text-transform: uppercase; opacity: .75; }
.song-sec-script .song-sec-head { color: var(--info); }
.song-sec-script .script-text { font-size: 1em; }
.song-sec-notes { font-size: .8em; color: var(--muted); margin: 4px 12px 0; }
.song-page { padding: 6px 12px 2px; border-radius: 6px; border-left: 4px solid transparent; }
.song-page.current { background: #2a2410; border-left-color: var(--accent); }
.song-page.next { background: #14303f; border-left-color: var(--info); }
.song-sec-next-label { background: var(--info); color: #000; border-radius: 6px; padding: 1px 8px; font-size: .85em; letter-spacing: .08em; text-transform: uppercase; }

/* ---- control ---- */
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.page-control { display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh; padding-bottom: 0; }
/* status bar: event, state, show timer, devices */
.control-head { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 14px; padding: 8px 12px; border-radius: 10px; border: 2px solid var(--border); background: var(--panel); }
.control-head.playing { background: #2a2410; border-color: var(--accent); }
.control-head.paused { background: #0f2230; border-color: var(--info); }
.control-head.alert { border-color: var(--bad); }
.control-head select { background: #0d0d0d; color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 6px 8px; font-size: 1rem; font-family: inherit; min-height: 40px; max-width: 100%; }
.show-timer { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 14px; color: var(--muted); font-size: .9rem; }
.show-timer strong { color: var(--fg); font-size: 1.25rem; font-variant-numeric: tabular-nums; }
.show-timer .badge { align-self: center; font-weight: bold; font-variant-numeric: tabular-nums; }
.show-timer .t-clock { font-size: 1.4rem; }
.timer-line2 { flex: 1 1 100%; display: flex; flex-wrap: wrap; gap: 2px 14px; font-size: .85rem; font-variant-numeric: tabular-nums; }
.timer-line2 span:empty { display: none; }
.timer-line2 .over { color: var(--bad); font-weight: bold; }
.devices { list-style: none; padding: 0; margin: 0 0 0 auto; display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: .85rem; }
.device { color: var(--muted); }
.device.connected { color: var(--fg); }
.device.warn .device-note { color: var(--accent); }
.device.dropped { color: var(--bad); font-weight: bold; }
.device .dot { width: 10px; height: 10px; margin: 0 5px 0 0; }
.dot-off { border: 1px solid var(--muted); }
.dot-warn { background: var(--accent); }
/* a musician's device in the list: tap its name to rename it */
.device-rename { background: none; border: 0; padding: 0; margin: 0; font: inherit; color: inherit; cursor: pointer; text-decoration: underline dotted; text-underline-offset: 3px; }

/* ---- who is holding a musician's screen (device_name.js) ---- */
.name-chip { display: inline-flex; align-items: center; font-size: .9rem; max-width: 14em; margin: 0; white-space: nowrap; overflow: hidden; }
.name-chip .icon-svg { margin-right: .3em; flex: none; }
.name-chip.name-unset { color: var(--muted); border-style: dashed; }
.name-line { margin: 12px 0 0; }
.name-line .name-chip { min-height: 44px; font-size: 1rem; }
/* 16px or more, so iOS does not zoom into the field */
.modal-name .field .name-input { font-size: 1.25rem; min-height: 52px; }
.name-recent { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.name-recent .muted { flex: 1 1 100%; font-size: .9rem; }
.name-recent .name-pick { margin: 0; }
.name-error { color: var(--bad); }
/* pianist Display dialog: a size per kind of view, a view per section */
.display-settings h3 { margin: 6px 0 0; }
.display-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; min-height: 44px; }
.display-row .display-name { flex: 1 1 120px; font-weight: bold; }
.display-row .btn { margin: 0; min-height: 40px; min-width: 44px; }
.display-row .size-value { min-width: 52px; text-align: center; font-variant-numeric: tabular-nums; }
.display-row .key-big { min-width: 52px; text-align: center; font-size: 1.6rem; color: var(--accent); }
.display-row.transpose .btn { min-height: 44px; font-size: 1.3rem; }
.section-views-all { justify-content: flex-end; }  /* over the column of section buttons it sets */
/* singer Settings: the song's key, first note, tempo and length, read only */
.song-info { gap: 0; }
.song-info .display-row { min-height: 38px; }
.display-row .display-value { font-variant-numeric: tabular-nums; }
.song-info .display-value .key-big { display: inline-block; min-width: 0; text-align: left; }
/* singer header: the title with its count and connection on the left; Flow, A− / A+ and Settings on the right */
.page-singer .perf-head { align-items: center; }
.toggles .text-size { display: inline-flex; gap: 6px; }
.toggles .text-size .btn-small { margin: 0; }
/* info sent by a musician (pianist ℹ Info): a blue banner on the control, singer and pianist pages for 5 seconds */
.issue-banner { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin: 8px 0; padding: 10px 14px; border-radius: 10px; background: var(--info); color: #000; font-size: 1.25rem; font-weight: bold; animation: issue-pulse 1.6s ease-out infinite; }
.issue-banner.info-fading { animation: issue-pulse 1.6s ease-out infinite, info-fade 5s linear forwards; }
@keyframes info-fade { 0%, 88% { opacity: 1; } 100% { opacity: 0; } }
.btn-info { border-color: var(--info); color: var(--info); }
/* line icons drawn in the page (the pianist's ⚙ Display and 💬 Info buttons): the text's colour and size, on every device */
.icon-svg { width: 1.15em; height: 1.15em; vertical-align: -0.2em; margin-right: .4em; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.issue-banner .issue-text { flex: 1 1 auto; }
.issue-banner .issue-clear { margin: 0 0 0 auto; border-color: #000; color: #000; background: transparent; min-height: 40px; }
.issue-presets { display: flex; flex-wrap: wrap; gap: 8px; }
.issue-presets .issue-preset { margin: 0; min-height: 44px; }
/* the Info dialog: presets by section, and the band block (hold a phrase, slide over who, let go to send) */
.info-sec h3 { margin: 0 0 6px; font-size: .95rem; }
.info-mix { display: grid; grid-template-columns: max-content minmax(0, 240px); justify-content: space-between; gap: 14px; touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.info-phrases, .info-band { display: flex; flex-direction: column; gap: 8px; }
.info-phrase { display: flex; align-items: center; min-height: 52px; padding: 10px 14px; border: 2px solid var(--border); border-radius: 10px; font-size: 1.05rem; white-space: nowrap; cursor: grab; }
.info-phrase.held { border-color: var(--info); color: var(--info); background: rgba(74, 163, 223, .12); }
.info-who { display: flex; align-items: center; min-height: 44px; padding: 8px 12px; border: 2px solid var(--border); border-radius: 10px; }
.info-who.picked { border-color: var(--ok); color: var(--ok); background: rgba(46, 204, 113, .14); }
.info-preview { min-height: 1.5em; margin-top: 8px; }
@keyframes issue-pulse { 0% { box-shadow: 0 0 0 0 rgba(74, 163, 223, .7); } 100% { box-shadow: 0 0 0 14px rgba(74, 163, 223, 0); } }
.device-alert { margin-top: 8px; padding: 10px 14px; border-radius: 10px; background: #3a1d1b; border: 2px solid var(--bad); color: #fff; font-weight: bold; font-size: 1.1rem; }
/* now + setlist */
.control-cols { display: grid; grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr); gap: 12px; align-items: start; }
.control-cols .panel { margin: 10px 0 0; }
.control-setlist h2 { margin-top: 2px; }
.now-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 2px 12px; }
.now-title { font-size: 1.5rem; font-weight: bold; }
.song-timer { margin-left: auto; font-size: 1.4rem; font-variant-numeric: tabular-nums; }
.song-timer.over { color: var(--bad); }
.song-progress { height: 4px; border-radius: 2px; background: var(--border); margin: 6px 0 10px; overflow: hidden; }
.song-progress div { height: 100%; width: 0; background: var(--accent); }
.song-progress.over div { background: var(--bad); }
.now-content { font-size: 1.1rem; max-height: 36vh; overflow: auto; }
/* next / preview pane: dashed and dim is what → brings, blue is what the operator picked (Enter takes it) */
.now-next { margin-top: 10px; padding: 8px 10px; border: 1px dashed var(--border); border-radius: 8px; color: var(--muted); }
.now-next.preview { border: 2px solid var(--info); background: #0f2230; color: var(--fg); }
.now-next.preview .now-next-label { color: var(--info); }
.now-next-head { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 10px; }
.now-next-head .btn { margin: 0; }
.now-next-body { margin-top: 4px; font-size: .95rem; max-height: 20vh; overflow: hidden; }
.now-next-body .script-text { font-size: 1rem; }
.btn-take kbd { color: inherit; border-color: currentColor; opacity: .7; }
.btn-take { margin-left: auto !important; background: var(--info); color: #000; border-color: var(--info); font-weight: bold; }
.now-next:empty { display: none; }
.now-next-label { font-size: .8rem; font-weight: bold; text-transform: uppercase; letter-spacing: .05em; }
.now-next-text { flex: 1 1 200px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jump-buttons { display: flex; flex-wrap: wrap; gap: 6px; }
.jump-btn { min-height: 44px; padding: 6px 12px; }
.jump-btn kbd { margin: 0 6px 0 0; }
.jump-btn.done { color: var(--muted); }
.jump-btn.current { background: var(--accent); color: #000; border-color: var(--accent); font-weight: bold; }
.jump-btn.preview { background: #0f2230; color: var(--info); border-color: var(--info); }
/* transport: always the last thing on screen; the filled button is the next expected action */
.live-controls { position: sticky; bottom: 0; z-index: 10; display: grid; grid-template-columns: 1fr 1.4fr 2fr; gap: 8px; margin: auto -16px 0; padding: 10px 16px calc(10px + env(safe-area-inset-bottom)); background: var(--bg); border-top: 1px solid var(--border); }
.live-controls .btn-big { min-height: 64px; padding: 10px 12px; }
.live-controls .btn-primary { background: var(--accent); color: #000; font-weight: bold; }
.live-controls .btn-primary:active { background: #cc8f00; }
.live-controls #btn-next.at-end { border-style: dashed; color: var(--muted); }
.live-controls .sub { display: block; font-size: .8rem; font-weight: normal; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.live-controls .sub:empty { display: none; }
.control-foot { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0 18px; margin: 10px 0; font-size: .9rem; color: var(--muted); }
.control-foot nav { margin-left: auto; padding: 12px 0; }
.control-drawer > summary { cursor: pointer; padding: 12px 4px; }
.control-drawer[open] { flex: 1 1 100%; background: var(--panel); border: 1px solid var(--border); border-radius: 10px; padding: 0 12px 10px; color: var(--fg); }
.setup-row { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 12px; margin: 8px 0; }
.setup-row .btn { flex: 0 0 220px; }
.setup-row .muted { flex: 1 1 240px; }
.control-setlist-list { list-style: none; padding: 0; margin: 0; max-height: max(240px, calc(100vh - 320px)); overflow-y: auto; }
.row-item { display: flex; gap: 8px; align-items: center; padding: 10px 8px; border-bottom: 1px solid var(--border); cursor: pointer; min-height: 48px; border-radius: 6px; }
.row-item .marker { width: 18px; color: var(--accent); }
.row-item .seq { width: 26px; color: var(--muted); }
.row-item .title { flex: 1 1 auto; }
.row-item .key { width: 36px; color: var(--accent); }
.row-item .bpm { width: 64px; font-size: .9rem; }
.row-item .dur { width: 44px; font-size: .9rem; }
.row-item.current { background: #2a2410; font-weight: bold; }
.row-item.status-done { opacity: .55; }
.row-item.preview { outline: 2px solid var(--info); background: #0f2230; }
.row-item .preview-note { color: var(--info); font-weight: normal; font-size: .85rem; }
.row-item .dur.actual { color: var(--ok); }
.setlist-hint { font-size: .85rem; color: var(--muted); margin: 4px 0; }
.run-head { cursor: pointer; padding: 6px 0; border-bottom: 1px solid var(--border); }
.run-song { margin-top: 6px; font-weight: bold; }
.run-section { padding-left: 12px; white-space: pre; }
.shortcut-help { flex: 1 1 100%; font-size: .85rem; color: var(--muted); }
@media (max-width: 800px) {
  .control-cols { grid-template-columns: minmax(0, 1fr); }
  .control-setlist-list { max-height: none; }
  .devices { margin-left: 0; }
  .live-controls .btn-big { font-size: 1.1rem; }
}
@media (max-width: 560px) {
  .live-controls { grid-template-columns: 1fr 1fr; }
  .live-controls #btn-prev { order: 1; } .live-controls #btn-next { order: 2; }
  .live-controls #btn-start-song, .live-controls #btn-pause { order: 3; grid-column: 1 / -1; }
}

/* ---- audio pages ---- */
.audio { max-width: 640px; margin: 0 auto; }
.indicators { display: flex; gap: 10px; flex-wrap: wrap; margin: 8px 0; }
.ind { font-weight: bold; padding: 6px 10px; border-radius: 6px; background: var(--panel); }
@media (max-width: 600px) {  /* a phone: the pills in one row, so ENABLE AUDIO and the song sit higher */
  .indicators { gap: 6px; margin: 6px 0; }
  .ind { font-size: .75rem; padding: 4px 8px; }
}
.ind-ok { color: var(--ok); } .ind-bad { color: var(--bad); }
.audio-song { font-size: 1.6rem; font-weight: bold; }
.audio-meta { font-size: 1.2rem; margin-top: 4px; }
.beat-display { font-size: 3.2rem; text-align: center; min-height: 5rem; margin-top: 8px; font-variant-numeric: tabular-nums; border-radius: 12px; border: 2px solid var(--border); padding: 10px; transition: background-color .12s; line-height: 1.1; }
.beat-display.accent { color: var(--accent); }
.beat-display.count_in { color: var(--info); }
.beat-display.flash { background: #444; }
.beat-display.flash.accent { background: var(--accent); color: #000; }
.beat-display.flash.count_in { background: var(--info); color: #000; }
.click-buttons { display: flex; flex-direction: column; gap: 12px; margin: 12px 0; }
.click-buttons .btn-huge { min-height: 96px; }
.btn-huge { min-height: 120px; }
.btn-note { min-height: 160px; font-size: 2.4rem; margin: 12px 0; }
.btn-note.playing { background: var(--accent); color: #000; }
.sound-select { display: flex; gap: 10px; }
.sound-select .btn { flex: 1 1 50%; }
.sound.active { border-color: var(--accent); color: var(--accent); }
.check-row { flex-direction: row; align-items: center; gap: 8px; font-size: 1rem; color: var(--fg); margin: 8px 0; }
.check-row input { width: auto; transform: scale(1.4); margin: 0 8px; }
details.settings > summary { cursor: pointer; font-weight: bold; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; padding: 6px 0; }

/* ---- check page ---- */
.checks { list-style: none; padding: 0; font-size: 1.3rem; }
.checks li { padding: 10px 8px; border-bottom: 1px solid var(--border); }
.checks .mark { display: inline-block; width: 32px; font-weight: bold; }
.checks li.ok .mark { color: var(--ok); } .checks li.bad .mark { color: var(--bad); }
.summary { font-size: 1.2rem; font-weight: bold; margin: 10px 0; }
.summary.ok { color: var(--ok); } .summary.bad { color: var(--bad); }
.reminder li { margin: 6px 0; }
.qr-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 12px; }
.qr-card { display: flex; flex-direction: column; align-items: center; justify-content: flex-start; background: var(--panel); color: var(--fg); border: 1px solid var(--border); border-radius: 10px; padding: 10px; text-align: center; font: inherit; cursor: pointer; }
.qr-card:hover { border-color: var(--accent); }
.qr-card:focus-visible { outline: 3px solid var(--info); outline-offset: 2px; }
.qr-card .qr { display: inline-block; background: #fff; padding: 6px; border-radius: 6px; line-height: 0; }
.qr-card .qr svg { width: 150px; height: 150px; }
.qr-card .qr-label { font-weight: bold; margin-top: 6px; }
.qr-card .qr-url { font-size: .8rem; color: var(--muted); word-break: break-all; }
.qr-host { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin: 6px 0 10px; }
dialog.modal.modal-qr { width: min(620px, calc(100vw - 32px)); }
.qr-stage { display: flex; align-items: center; justify-content: center; gap: 8px; }
.qr-big { flex: 1; min-width: 0; text-align: center; }
.qr-big .qr { display: inline-block; background: #fff; padding: 16px; border-radius: 8px; line-height: 0; }
.qr-big .qr svg { --qr: min(400px, calc(100vw - 210px), calc(100vh - 340px)); width: var(--qr); height: var(--qr); min-width: 120px; min-height: 120px; }
.qr-big .qr-label { font-weight: bold; font-size: 1.3rem; margin-top: 10px; }
.qr-big .qr-url { color: var(--muted); word-break: break-all; }
.qr-big .qr-count { margin-top: 4px; }
.qr-nav { flex: none; font-size: 2rem; line-height: 1; min-height: 72px; padding: 10px 14px; }

/* ---- motion ---- */
@media (prefers-reduced-motion: reduce) {
  .btn, .beat-display { transition: none; }
  .issue-banner, .issue-banner.info-fading { animation: none; outline: 3px solid #fff; }
  .beat-display.flash { background: transparent; }
  .beat-display.flash.accent { background: transparent; color: var(--accent); }
  .beat-display.flash.count_in { background: transparent; color: var(--info); }
}

/* ---- narrow screens (phones, portrait) ---- */
@media (max-width: 700px) {
  .pianist-cols { flex-direction: column; }
  .pianist-side, .page-pianist.structure-minimal .pianist-side { flex: 1 1 auto; }
  .flow-shorthand { flex-direction: row; flex-wrap: wrap; }  /* under the music: a row that wraps */
  .perf-title { font-size: 1.5rem; }
  :root { --lyrics-size: 2rem; }
  .lyrics { min-height: 20vh; }
  .pianist-content { font-size: 1.3rem; min-height: 20vh; }
  .pianist-content.style-full { font-size: 1.15rem; }
  .pianist-content.song-scroll { max-height: 55vh; }
  .editor-side { flex: 1 1 100%; position: static; max-height: none; }
  /* an iPhone standing in for an iPad: one row of Prev | Info (its icon) | Next, short labels in the header */
  .perf-nav { flex-wrap: nowrap; gap: 8px; }
  .nav-btn, .nav-btn.nav-main, .page-singer .nav-btn { flex: 1 1 0; min-width: 0; min-height: 64px; font-size: 1.25rem; padding: 6px 8px; }
  .nav-btn.btn-info { flex: 0 0 64px; }
  .perf-head .btn-label, .perf-nav .btn-label, .wide-only { display: none; }
  .perf-head .icon-svg, .perf-nav .icon-svg { margin-right: 0; }
  .perf-head .toggles .btn-small { padding: 6px 10px; }
  .perf-meta { font-size: 1.05rem; gap: 10px; }
  .section-label.now { font-size: 1.1rem; }
  /* the singer's flow becomes a strip of entries across the top */
  .singer-cols { flex-direction: column; gap: 6px; }
  .singer-side { order: -1; flex: 0 0 auto; overflow-x: auto; overflow-y: hidden; }
  .singer-flow { display: flex; gap: 6px; white-space: nowrap; padding-bottom: 4px; }
  .singer-flow .flow-row { flex: 0 0 auto; border: 1px solid var(--border); border-radius: 6px; min-height: 40px; padding: 4px 10px; font-size: 1rem; align-items: center; }
  .singer-flow .flow-remark { display: none; }
}

/* ---- short screens (a phone on its side): the header and the nav as small as they can be, the song the rest ---- */
@media (max-height: 500px) {
  .page { padding-top: 6px; }
  .perf-head { align-items: center; padding-bottom: 4px; gap: 6px; }
  .perf-title { font-size: 1.35rem; }
  .perf-meta { font-size: 1rem; gap: 10px; }
  .perf-head .btn-label, .wide-only { display: none; }
  .perf-head .icon-svg { margin-right: 0; }
  .nav-btn, .page-singer .nav-btn { min-height: 64px; font-size: 1.2rem; padding: 4px 8px; }
  .perf-nav { padding-top: 6px; padding-bottom: calc(6px + env(safe-area-inset-bottom)); }
  .section-label.now { font-size: 1rem; }
  .entry-cue { padding: 6px 12px 8px; gap: 2px; }
  .entry-cue .cue-num { font-size: 2.2rem; } .entry-cue.cue-last .cue-num { font-size: 2.8rem; }
  .entry-cue .cue-unit, .entry-cue .cue-beats { font-size: 1.05rem; } .entry-cue .cue-where { font-size: .95rem; }
  .entry-cue .cue-words { font-size: 1.15rem; }
}

/* ---- editor v2: list pages, modals, toasts, tabs, datatable ---- */
.editor-head .crumbs { display: flex; gap: 6px; align-items: baseline; flex-wrap: wrap; font-size: 1rem; color: var(--muted); min-width: 0; }
.editor-head .crumbs a { color: var(--muted); text-decoration: none; }
.editor-head .crumbs a:hover { color: var(--accent); }
.editor-head .crumbs .sep { opacity: .5; }
.editor-head .crumbs .here { color: var(--fg); font-weight: bold; font-size: 1.25rem; }
.editor-head .head-actions { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.page-list .editor-head h1 { margin: 0; }
.subtle { font-size: .85rem; color: var(--muted); }

.toasts { position: fixed; left: 50%; bottom: 20px; transform: translateX(-50%); z-index: 100; display: flex; flex-direction: column; gap: 8px; align-items: center; pointer-events: none; max-width: calc(100vw - 32px); }
.toast { pointer-events: auto; padding: 10px 16px; border-radius: 10px; background: #2a2a2a; border: 1px solid var(--border); color: var(--fg); box-shadow: 0 4px 16px rgba(0,0,0,.5); font-size: 1rem; cursor: pointer; animation: toast-in .15s ease-out; }
.toast-ok { border-color: var(--ok); }
.toast-error { border-color: var(--bad); background: #3a1d1b; }
.toast-info { border-color: var(--info); }
.toast-action { margin-left: 12px; min-height: 36px; }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

dialog.modal { background: var(--panel); color: var(--fg); border: 1px solid var(--border); border-radius: 12px; padding: 0; width: min(520px, calc(100vw - 32px)); max-height: calc(100vh - 40px); overflow: hidden; box-shadow: 0 12px 40px rgba(0,0,0,.6); }
dialog.modal-wide { width: min(880px, calc(100vw - 32px)); }
dialog.modal::backdrop { background: rgba(0,0,0,.6); }
/* 2px less than the dialog: its border is inside its max-height; only .modal-body scrolls */
.modal-form { display: flex; flex-direction: column; max-height: calc(100vh - 42px); }
.modal-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 12px 16px; border-bottom: 1px solid var(--border); }
.modal-head h2 { margin: 0; color: var(--fg); text-transform: none; letter-spacing: 0; font-size: 1.15rem; }
.modal-x { min-height: 32px; margin: 0; }
.modal-body { padding: 14px 16px; overflow: auto; display: flex; flex-direction: column; gap: 10px; }
.modal-body p { margin: 0; line-height: 1.4; }
.modal-foot { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--border); }
.modal-body .field input, .modal-body .field select, .modal-body .field textarea, .modal-body input[type=search] { background: #0d0d0d; color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 8px; font-size: 1rem; width: 100%; font-family: inherit; min-height: 40px; }
.modal-body .field.inline { flex-direction: row; align-items: center; }
.modal-body .field.inline input[type=checkbox] { width: auto; transform: scale(1.3); margin: 4px 8px; }
.pick-list { list-style: none; margin: 0; padding: 0; max-height: 50vh; overflow: auto; border: 1px solid var(--border); border-radius: 8px; }
.pick-list li { display: flex; gap: 10px; align-items: center; padding: 8px 10px; border-bottom: 1px solid var(--border); flex-wrap: wrap; }
.pick-list li:last-child { border-bottom: 0; }
.pick-list .pick-title { flex: 1 1 160px; font-weight: bold; }
.pick-list .pick-sub { color: var(--muted); font-size: .9rem; }
.pick-list select { width: auto !important; min-width: 140px; }
.pick-list input[type=checkbox] { flex: 0 0 auto; width: 18px; height: 18px; min-height: 0; padding: 0; margin: 0 2px; }
.pick-list li.picked { background: #26230f; }

.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin: 10px 0 12px; flex-wrap: wrap; }
.tab { background: none; border: 0; border-bottom: 3px solid transparent; color: var(--muted); padding: 10px 16px; font-size: 1rem; cursor: pointer; font-family: inherit; min-height: 44px; display: inline-flex; gap: 8px; align-items: center; }
.tab:hover { color: var(--fg); }
.tab.active { color: var(--accent); border-bottom-color: var(--accent); font-weight: bold; }
.tab-badge { background: var(--bad); color: #fff; border-radius: 999px; padding: 1px 7px; font-size: .75rem; font-weight: bold; }
.tab-panel { padding-bottom: 80px; }

.dt-toolbar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin: 8px 0 10px; }
.dt-search { flex: 1 1 220px; max-width: 360px; background: #0d0d0d; color: var(--fg); border: 1px solid var(--border); border-radius: 8px; padding: 8px 12px; font-size: 1rem; min-height: 44px; font-family: inherit; }
.dt-toggle { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); cursor: pointer; }
.dt-toggle input { transform: scale(1.3); margin: 4px 6px; }
.dt-spacer { flex: 1 1 auto; }
.dt-scroll { max-width: 100%; overflow-x: auto; border-radius: 10px; }
.dt-table { width: 100%; border-collapse: collapse; background: var(--panel); border-radius: 10px; overflow: hidden; }
.dt-table th, .dt-table td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.dt-table th { color: var(--muted); font-size: .8rem; text-transform: uppercase; letter-spacing: .05em; font-weight: normal; background: #232323; }
.dt-sort { background: none; border: 0; color: inherit; font: inherit; cursor: pointer; padding: 0; text-transform: inherit; letter-spacing: inherit; white-space: nowrap; }
.dt-sort.active { color: var(--accent); }
.dt-row { cursor: default; }
.dt-row.clickable, .dt-table.has-expand .dt-row { cursor: pointer; }
.dt-row:hover { background: #262626; }
.dt-row.open { background: #26230f; }
.dt-row.deleted td { opacity: .6; }
.dt-chev { width: 32px; padding-right: 0 !important; }
.dt-expand { background: none; border: 0; color: var(--muted); font-size: 1.1rem; cursor: pointer; padding: 4px 8px; min-height: 36px; min-width: 36px; }
.dt-expand-row > td { padding: 0 12px 12px 44px; background: #1a1a1a; }
.dt-actions { white-space: nowrap; text-align: right; }
.dt-actions-h { text-align: right; }
.dt-actions .btn { margin: 2px 0 2px 4px; }
.dt-num { text-align: right; white-space: nowrap; }
.dt-empty td { color: var(--muted); text-align: center; padding: 28px; }
.dt-foot { display: flex; gap: 8px; align-items: center; margin: 10px 0; flex-wrap: wrap; }
.dt-page { color: var(--muted); font-size: .9rem; }
.dt-loading { color: var(--muted); padding: 6px 0; }
.dt-title { font-weight: bold; }
.dt-sub { display: block; color: var(--muted); font-size: .85rem; font-weight: normal; }
.sub-table { width: 100%; border-collapse: collapse; margin: 6px 0 2px; }
.sub-table th, .sub-table td { padding: 6px 10px; border-bottom: 1px solid var(--border); text-align: left; font-size: .95rem; }
.sub-table th { color: var(--muted); font-size: .75rem; text-transform: uppercase; letter-spacing: .05em; font-weight: normal; }
.sub-table tr:last-child td { border-bottom: 0; }
.sub-table .dt-actions .btn { min-height: 34px; padding: 4px 10px; }
.sub-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 6px; }
.sub-head h3 { margin: 0; }
.chip { display: inline-block; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--border); font-size: .8rem; color: var(--muted); margin-left: 6px; vertical-align: middle; }
.chip-live { border-color: var(--ok); color: var(--ok); }
.chip-del { border-color: var(--bad); color: var(--bad); }
.chip-warn { border-color: var(--accent); color: var(--accent); }

/* song tags: colours come from the tag itself (inline fg/bg) */
.tag { display: inline-block; padding: 2px 10px; border-radius: 999px; border: 1px solid rgba(255, 255, 255, .18); font-size: .8rem; font-weight: 600; line-height: 1.5; white-space: nowrap; font-family: inherit; }
.tag-list, .tag-picker { display: flex; flex-wrap: wrap; gap: 4px 6px; align-items: center; }
.tag-list { display: inline-flex; vertical-align: middle; }
.tag-arr { border: 1px dashed currentColor; }  /* on a song row: carried by an arrangement, not the song */
.tag-toggle { cursor: pointer; min-height: 32px; padding: 4px 12px; font-size: .9rem; opacity: .6; }
.tag-toggle:hover { opacity: .85; }
.tag-toggle[aria-pressed="true"] { opacity: 1; box-shadow: 0 0 0 2px var(--panel), 0 0 0 4px var(--fg); }
.tag-toggle[aria-pressed="true"]::before { content: '✓ '; }
.tag-toggle:focus-visible { outline: 3px solid var(--info); outline-offset: 4px; }
.color-row { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 12px; }
.modal-body .field input[type=color] { padding: 3px; height: 44px; cursor: pointer; }
.tag-preview { padding: 12px; background: #181818; border: 1px solid var(--border); border-radius: 6px; }
.tag-preview .tag { font-size: 1rem; }
.tag-contrast { color: var(--accent); }
.tag-contrast:empty { display: none; }

.sortable-ghost { opacity: .35; }
.sortable-chosen { border-color: var(--accent) !important; }
.drag-handle { cursor: grab; color: var(--muted); font-size: 1.2rem; padding: 4px 6px; touch-action: none; user-select: none; }
.drag-handle:active { cursor: grabbing; }

/* arrangement editor v2 */
.editor-layout { display: flex; gap: 20px; align-items: flex-start; }
.editor-body { flex: 1 1 500px; min-width: 0; }
.form-section { margin: 0 0 18px; }
.form-section > h3 { margin: 0 0 8px; }
details.advanced { border: 1px solid var(--border); border-radius: 8px; padding: 8px 12px; background: var(--panel); margin: 10px 0; }
details.advanced > summary { cursor: pointer; color: var(--accent); font-weight: bold; }
.field-error input, .field-error select, .field-error textarea { border-color: var(--bad) !important; }
.field .err { color: var(--bad); font-size: .8rem; }
.error-list { margin: 8px 0; padding: 8px 12px; border: 1px solid var(--bad); border-radius: 8px; background: #3a1d1b; }
.error-list ul { margin: 4px 0 0 18px; padding: 0; }
/* editor: saved elsewhere meanwhile, both sides changed these places */
.conflict-list { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 8px; }
.conflict-value { font-size: .9rem; overflow-wrap: anywhere; }
.sec-head .field { flex: 0 1 170px; min-width: 120px; }
.sec-head .field.sec-note { flex: 1 1 200px; }
.sec-head .add-page { margin: 0 0 2px; min-height: 40px; }
/* section details read as text until "✎ Edit section" (.editing) shows their controls */
.sec-head .sec-value { display: flex; align-items: center; min-height: 40px; padding: 0 2px; font-size: 1rem; color: var(--fg); overflow-wrap: anywhere; }
.sec-head .sec-value.empty { color: var(--muted); }
.sec-head:not(.editing) .field > input, .sec-head:not(.editing) .field > select, .sec-head.editing .sec-value { display: none; }
.sec-head .sec-edit-toggle { margin: 0 0 2px auto; min-height: 40px; }
/* the section tools stay under the header while the sections scroll */
.section-head-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; position: sticky; top: var(--editor-head-h, 44px); z-index: 4; margin: 0 0 8px; padding: 6px 0; background: #181818; border-bottom: 1px solid var(--border); }
/* the dock: chord / note palette and the note matrix. A sheet at the bottom of a touch screen (refreshDock);
   with a mouse, a column right of the sections */
.editor-dock { position: fixed; left: 0; right: 0; bottom: 0; z-index: 6; max-height: 50vh; overflow: auto; display: flex; flex-direction: column; padding: 0 16px; background: var(--panel); border-top: 1px solid var(--border); border-radius: 12px 12px 0 0; box-shadow: 0 -6px 18px rgba(0, 0, 0, .55); }
.editor-dock > .chord-palette { padding: 8px 0; gap: 6px 14px; }
.editor-dock > .note-matrix { padding: 8px max(0px, calc((100vw - 652px) / 2)); }  /* the grid no wider than 620px */
.chord-palette { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
/* touch keys (library_editor.js touchKeys): the sheet's top row on a phone or tablet, ⌨ for the on-screen keyboard and
   arrows for the cursor; held, an arrow repeats, so it must not scroll the sheet or start a text selection */
.touch-keys { display: flex; align-items: center; gap: 6px; position: sticky; top: 0; z-index: 1; padding: 8px 0 6px; background: var(--panel); border-bottom: 1px solid var(--border); }
.touch-keys .btn { margin: 0; min-height: 44px; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.touch-kbd { touch-action: manipulation; white-space: nowrap; }
.touch-kbd[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); background: #3a2a00; }
.touch-arrows { display: flex; gap: 6px; margin-left: auto; }
.touch-arrow { min-width: 48px; font-size: 1.25rem; font-weight: bold; touch-action: none; }
.dock-sheet .mx-hint { display: none; }
.dock-sheet .mx-cell { min-height: 38px; }
/* on the sheet the note rows join the palette's own rows, so Join / Split stands beside "Notes by", as with the matrix */
.dock-sheet .chord-palette .palette-notes { display: contents; }
.dock-sheet .chord-palette > .palette-lines { order: 1; }
.dock-sheet .palette-notes > .palette-row:not(.palette-mode) { order: 2; flex-basis: 100%; }
@media (hover: hover) and (pointer: fine) and (min-width: 901px) {
  .editor-dock { flex: 0 0 clamp(340px, 30vw, 420px); position: sticky; top: calc(var(--editor-head-h, 44px) + 8px); z-index: auto; max-height: calc(100vh - var(--editor-head-h, 44px) - 16px); gap: 10px; padding: 0; background: none; border: 0; border-radius: 0; box-shadow: none; }
  .editor-dock > .chord-palette, .editor-dock > .note-matrix { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; padding: 10px; }
  .editor-dock > .chord-palette { flex-direction: column; align-items: stretch; gap: 10px; }
  .editor-dock .chord-palette > .palette-lines { order: -1; }  /* Join / Split above the chords and the notes */
  /* the chords one under another; the note lengths and the notes as two columns side by side */
  .editor-dock .chord-palette .palette-chords { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
  .editor-dock .chord-palette .palette-notes { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 10px; align-items: start; }
  .editor-dock .palette-notes > .palette-mode, .editor-dock .palette-notes > .note-hint { grid-column: 1 / -1; }
  .editor-dock .palette-notes > .palette-row:not(.palette-mode):not(.note-hint) { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
  .editor-dock .note-len-btn { flex-direction: row; justify-content: space-between; gap: 8px; min-width: 0; }
  .editor-dock .note-len-custom { flex-wrap: wrap; }
  .editor-dock .note-len-custom > .subtle:first-child { flex-basis: 100%; }
  .editor-dock #note-len-num, .editor-dock #note-len-den { flex: 1 1 0; min-width: 0; width: auto; }
  .editor-dock #note-octave .seg-btn { flex: 1 1 0; padding-left: 4px; padding-right: 4px; }
  .editor-dock .mx-grid { grid-template-columns: minmax(64px, 1.5fr) repeat(8, minmax(26px, 1fr)); }
  /* the chord palette as three columns of narrow buttons: the key's chords | what to add | the bass; the dock's spare
     width goes into the room between them, a rule in the middle of it, so a press or a slide lands in the right one */
  .editor-dock .cx { display: grid; grid-template-columns: minmax(0, 80px) 1px minmax(0, 80px) 1px minmax(0, 62px); column-gap: 18px; justify-content: space-between; align-items: start; touch-action: none; user-select: none; -webkit-user-select: none; }
  .editor-dock .cx-col, .editor-dock .cx-list { display: flex; flex-direction: column; flex-wrap: nowrap; align-items: stretch; gap: 6px; min-width: 0; }
  .editor-dock .cx-head { font-size: .8rem; margin: 0 0 1px 2px; }
  .editor-dock .cx-rule { display: block; align-self: stretch; background: var(--border); }
  .editor-dock .cx-hint { display: block; min-height: 2.6em; font-size: .9rem; }
  .editor-dock .cx .chord-btn { min-width: 0; min-height: 46px; padding: 4px 6px; font-size: 1.1rem; cursor: grab; }
}
.chord-palette .chord-btn { margin: 0; min-width: 52px; font-weight: bold; color: var(--accent); }
.chord-palette .palette-group { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
/* chord palette (library_editor.js chordPalette): on the sheet too the key's chords | Add | Bass, always three columns of
   buttons one under another, side by side (a slide leaves a chord through its right side onto the others), a rule in
   the room between; Join / Split beside them when there is room. Held, a chord shows its fans */
.dock-sheet .chord-palette { align-items: flex-start; }
.dock-sheet .chord-palette > .palette-chords { flex: 1 1 420px; max-width: 600px; }
.dock-sheet .chord-palette .palette-chords > .cx { flex: 1 1 100%; }
.cx { display: grid; grid-template-columns: minmax(0, 1fr) 1px minmax(0, 1fr) 1px minmax(0, 1fr); column-gap: 24px; align-items: start; }
.cx-col, .cx-list { display: flex; flex-direction: column; flex-wrap: nowrap; align-items: stretch; gap: 4px; min-width: 0; }
.cx-head { font-size: .8rem; margin-left: 2px; }
.cx-rule { align-self: stretch; background: var(--border); }
.cx-hint { display: none; }
/* seven buttons high, so a little lower than in the desktop dock: the sheet stays within half the screen */
.dock-sheet .cx .chord-btn, .dock-sheet .cx .cx-mod { min-width: 0; min-height: 38px; margin: 0; padding: 2px 6px; }
.dock-sheet .cx .cx-mod { line-height: 1.05; }
@media (max-width: 520px) {  /* a phone */
  .cx { column-gap: 12px; }
  .dock-sheet .cx .chord-btn, .dock-sheet .cx .cx-mod { min-height: 36px; padding: 1px 4px; }
  .dock-sheet .cx .cx-mod .cx-gives { font-size: .7rem; }
}
.cx .chord-btn, .cx-mod { transition: opacity .1s; touch-action: none; user-select: none; -webkit-user-select: none; }
.cx .chord-btn.held { position: relative; z-index: 2; border-color: var(--info); color: var(--info); background: #102331; box-shadow: 0 0 0 4px rgba(74, 163, 223, .18); cursor: grabbing; }
.cx .chord-btn.last { border-color: #6b5200; background: #2a2000; }
.cx.holding .chord-btn:not(.held) { opacity: .25; }  /* while one is held the others do nothing: they step back */
.cx-mod { display: flex; flex-direction: column; align-items: center; justify-content: center; min-width: 0; min-height: 46px; margin: 0; padding: 2px 4px; line-height: 1.15; }
.cx-mod .cx-name { font-weight: bold; }
.cx-mod .cx-gives { font-size: .75rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.cx-mod.picked { border-color: var(--ok); color: var(--ok); background: rgba(46, 204, 113, .14); }
.cx-mod.picked .cx-gives { color: var(--ok); }
.cx-mod.pending { border-color: var(--ok); }  /* rested on: picked in a moment */
.cx-mod.inv .cx-gives { color: var(--info); }  /* the chord's 3rd, 5th … in the bass */
.cx-mod.changed .cx-name { color: #8fd0ff; }   /* the chord's own note, not the key's (E → Eb) */
.cx-mod.off { opacity: .32; cursor: not-allowed; }
.cx.bending .cx-bass .cx-mod:not(.fanned) { opacity: .25; }  /* and the other bass notes while one is bent */
.cx .nope { animation: cx-nope .35s; }
@keyframes cx-nope { 25% { transform: translateX(-3px); } 75% { transform: translateX(3px); } }
.cx-hint b { color: var(--accent); }
/* a note button or matrix cell held to be bent: the others step back, so its fans read over them */
.pitch-btn, .mx-cell { transition: opacity .1s; }
.bending > .pitch-btn:not(.held), .mx-grid.bending .mx-cell:not(.held) { opacity: .25; }
.pitch-btn.held, .mx-cell.held { position: relative; z-index: 2; }
/* fans (fans.js): drawn over the whole window while a chord, a bass or a note is held */
.fans { position: fixed; left: 0; top: 0; width: 100vw; height: 100vh; z-index: 1000; pointer-events: none; display: none; }
.fans.on { display: block; animation: fans-in .15s ease-out; }
.fans text { font-family: inherit; font-weight: bold; }
@keyframes fans-in { from { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .fans.on { animation: none; } }
.note-len-btn { margin: 0; display: inline-flex; flex-direction: column; align-items: center; gap: 1px; min-width: 62px; padding: 4px 8px; line-height: 1.15; }
.len-sample { font-family: Menlo, Consolas, monospace; font-weight: bold; color: var(--accent); white-space: nowrap; }
.note-len-btn .len-name { font-size: .7rem; color: var(--muted); white-space: nowrap; }
.note-len-btn[aria-pressed="true"] { border-color: var(--accent); background: #3a2a00; }
.note-len-btn[aria-pressed="true"] .len-name { color: var(--fg); }
.note-len-custom { display: inline-flex; align-items: center; gap: 6px; }
.note-len-input { width: 112px; min-height: 36px; background: #0d0d0d; color: var(--fg); border: 2px solid var(--border); border-radius: 8px; padding: 4px 8px; font-size: 1rem; font-family: inherit; }
.note-len-custom.active .note-len-input { border-color: var(--accent); }
#note-len-num { width: 64px; }
#note-len-den { width: 70px; }
.chord-palette .palette-notes { flex-direction: column; align-items: flex-start; }
.palette-row { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
/* note buttons: held and swiped for accidentals, so the page must not scroll under the finger */
.pitch-btn { margin: 0; min-width: 46px; min-height: 42px; font-weight: bold; font-size: 1.05rem; touch-action: none; user-select: none; -webkit-user-select: none; }
.pitch-btn.bent { border-color: var(--accent); color: var(--accent); background: #3a2a00; }
.pitch-btn:not(.pitch-rest) { display: inline-flex; align-items: center; justify-content: center; gap: .4em; padding-top: 0; padding-bottom: 0; }
.pitch-btn .pitch-name { font-weight: normal; font-size: .8rem; color: var(--muted); }
.pitch-btn.bent .pitch-name { color: inherit; }
.pitch-rest { color: var(--muted); }
.note-tool { margin: 0; min-width: 46px; min-height: 42px; }
.note-tools { display: inline-flex; gap: 6px; }
.note-tools .note-tool { flex: 1 1 0; }
.palette-row .seg .seg-btn { min-height: 40px; }
.pitch-readout { min-width: 2.2em; font-weight: bold; font-size: 1.1rem; color: var(--accent); }
/* on a phone, or an iPad on its side, the bottom sheet needs the room */
@media (max-width: 700px), (pointer: coarse) and (max-height: 820px) { .section-head-row { position: static; } }
.note-len-input.invalid { border-color: var(--bad); }
/* the note palette's other face: Buttons here, or the matrix beside the sections */
.palette-notes.matrix > .palette-row:not(.palette-mode) { display: none; }
.mx-tools { display: flex; flex-wrap: wrap; gap: 6px 8px; align-items: center; margin-bottom: 8px; }
.mx-tools .seg .seg-btn { min-height: 36px; min-width: 40px; }
.mx-tool { margin: 0; min-width: 40px; }
.mx-tool[aria-pressed="true"] { border-color: var(--accent); background: #3a2a00; color: var(--accent); }
.mx-close { margin-left: auto; }
.mx-meter { display: flex; gap: 8px; align-items: center; margin-bottom: 8px; }
.mx-meter-bar { display: flex; gap: 5px; flex: 1 1 auto; }
.mx-beat { display: flex; gap: 1px; flex: 1 1 0; }
.mx-slot { flex: 1 1 0; height: 10px; background: #2f2f2f; }
.mx-beat .mx-slot:first-child { border-radius: 3px 0 0 3px; }
.mx-beat .mx-slot:last-child { border-radius: 0 3px 3px 0; }
.mx-slot.used { background: var(--fg); }
.mx-meter-text { white-space: nowrap; font-variant-numeric: tabular-nums; }
.mx-meter-text.mx-bad { color: var(--bad); }
.mx-grid { display: grid; grid-template-columns: minmax(84px, 1.7fr) repeat(8, minmax(30px, 1fr)); gap: 4px; }
.mx-col-head { text-align: center; color: var(--muted); font-size: .8rem; }
.mx-row-head { display: flex; flex-direction: column; justify-content: center; min-width: 0; padding: 2px 5px; border: 2px solid transparent; border-radius: 8px; background: none; color: var(--fg); font: inherit; text-align: left; cursor: pointer; line-height: 1.15; }
.mx-row-head .mx-n { font-size: .8rem; }
.mx-row-head .mx-b { font-size: .7rem; color: var(--muted); white-space: nowrap; }
.mx-row-head[aria-pressed="true"] { border-color: var(--accent); background: #3a2a00; }
/* cells are held and swiped for accidentals like the note buttons, so the page must not scroll under the finger */
.mx-cell { display: flex; align-items: center; justify-content: center; gap: .2em; min-width: 0; min-height: 44px; margin: 0; padding: 2px; border: 2px solid var(--border); border-radius: 8px; background: #262626; color: var(--fg); font: inherit; cursor: pointer; touch-action: none; user-select: none; -webkit-user-select: none; }
.mx-cell:hover, .mx-cell.bent { border-color: var(--accent); background: #3a2a00; }
.mx-cell:active { transform: scale(.95); }
.mx-cell.armed { border-color: #6b5200; }
.mx-cell.over { border-style: dashed; }
.mx-cell.mx-rest { color: var(--muted); }
.mx-cell .len-sample { font-size: .68rem; white-space: normal; text-align: center; }
.mx-g { display: inline-flex; flex-direction: column; align-items: stretch; font-weight: bold; font-size: 1.05rem; line-height: 1; }
.mx-g .mx-o { font-size: .5em; height: .8em; text-align: center; }
.mx-g .mx-u { height: 1px; margin-top: 2px; background: currentColor; }
.mx-dash { color: var(--muted); font-size: .75rem; letter-spacing: .05em; white-space: nowrap; }
.mx-hint { margin-top: 8px; }
@media (max-width: 520px) { .mx-dash { display: none; } .mx-grid { grid-template-columns: 72px repeat(8, minmax(28px, 1fr)); gap: 3px; } .mx-row-head .mx-n { font-size: .72rem; } .note-matrix .mx-cell { min-height: 32px; } .mx-tools, .mx-meter { margin-bottom: 5px; } .mx-row-head { padding: 0 3px; line-height: 1.05; } .mx-row-head .mx-b { display: none; } .mx-row-head[data-len='auto'] .mx-b, .mx-row-head[data-len='custom'] .mx-b { display: inline; } }
.section-box > summary .drag-handle { margin-left: -4px; }
.section-box > summary .sec-sum-use { color: var(--muted); font-size: .8rem; }
.section-box > summary .sec-sum-use.unused { color: var(--accent); }
.section-box > summary .sec-tools { margin-left: auto; display: flex; gap: 4px; }
.section-box > summary .sec-tools .btn { min-height: 32px; padding: 2px 8px; margin: 0; font-size: .85rem; }
.page-text { min-height: 90px; resize: vertical; }
.page-row .page-tools { display: none; gap: 4px; }
.page-row.open .page-tools { display: flex; align-items: center; }
.page-row .page-tools .btn { margin: 0; }
.page-row .page-remove { display: inline-flex; align-items: center; justify-content: center; }
.page-row .page-transpose { min-height: 36px; padding: 4px 6px; background: #0d0d0d; color: var(--fg); border: 1px solid var(--border); border-radius: 6px; font-size: .9rem; font-family: inherit; }
/* a section or page in a key of its own (transposed away from the song's or its section's) */
.key-badge { display: inline-block; padding: 1px 8px; border: 1px solid var(--info); border-radius: 999px; color: var(--info); font-size: .75rem; font-weight: bold; letter-spacing: .03em; white-space: nowrap; line-height: 1.4; }
.song-sec-head .key-badge { color: inherit; border-color: currentColor; }
.page-view > .key-badge, .song-page > .key-badge, .song-cue-page > .key-badge { margin: 2px 0 4px; }
.cp-grid-name .key-badge { margin-left: 6px; vertical-align: middle; }
.page-row .page-remove:hover { color: var(--bad); border-color: var(--bad); }
.flow-chips { display: flex; gap: 6px; flex-wrap: wrap; margin: 8px 0; align-items: center; }
.flow-chips .chip-btn { min-height: 36px; padding: 4px 12px; font-size: .9rem; margin: 0; }
#flow { list-style: none; padding: 0; }
.flow-entry { background: var(--panel); border: 1px solid var(--border); border-radius: 8px; padding: 6px 10px; }
.flow-entry .flow-seq { color: var(--muted); width: 26px; text-align: right; }
.flow-entry .flow-type { color: var(--accent); font-size: .75rem; text-transform: uppercase; letter-spacing: .05em; }
.flow-entry.flow-script .flow-label { color: #9bd; font-style: italic; }
.flow-entry.flow-missing { border-color: var(--bad); }
.flow-entry .flow-marks { display: flex; flex-wrap: wrap; gap: 4px 12px; flex: 1 1 200px; min-width: 0; font-size: .95rem; }
.flow-entry .flow-mark { font-style: italic; overflow-wrap: anywhere; }
.flow-entry .flow-mark-pianist { color: var(--fg); }
.flow-entry .flow-mark-singer { color: var(--accent); }
.flow-entry[class*="hl-"] { background: var(--hl-bg); border-color: var(--hl); box-shadow: inset 5px 0 0 var(--hl); }
.pop-wrap { position: relative; display: inline-flex; }
.popover { position: absolute; top: calc(100% + 6px); right: 0; z-index: 30; padding: 10px 12px; background: var(--panel); border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 6px 24px rgba(0,0,0,.6); max-width: calc(100vw - 32px); }
.flow-entry .flow-tools { margin-left: auto; }
.flow-entry .flow-tools .btn { min-height: 34px; padding: 2px 8px; margin: 0; }
.flow-menu { font-size: 1.2rem; line-height: 1; min-width: 40px; }
.flow-menu[aria-expanded="true"] { border-color: var(--accent); color: var(--accent); }
.flow-menu-pop { display: flex; flex-direction: column; gap: 10px; min-width: 260px; }
.flow-menu-pop .field { color: var(--muted); }
.flow-menu-pop .swatches { flex-wrap: nowrap; }
.flow-menu-pop .flow-remove { align-self: stretch; }
/* arrangement editor header: Save at the top right, the rarer actions under More ▾ */
.editor-head .head-actions #save { margin: 2px 0; }
.editor-head #save[disabled] { border-color: var(--border); color: var(--muted); opacity: .6; }  /* nothing to save */
.editor-head .save-hint { color: var(--muted); font-size: .85rem; }
.editor-head #more[aria-expanded="true"] { border-color: var(--accent); color: var(--accent); }
.more-wrap > .popover { left: 0; right: auto; }  /* Save stands to the right of More */
.more-menu { display: flex; flex-direction: column; gap: 6px; min-width: 160px; }
.more-menu .btn { margin: 0; text-align: left; }
/* row "more" menus (ui.moreMenu): fixed to the viewport so the table's scroll box does not clip them */
.popover-fixed { position: fixed; left: auto; z-index: 40; }
.btn-more { font-size: 1.15rem; line-height: 1; min-width: 40px; letter-spacing: .05em; }
.btn-more[aria-expanded="true"] { border-color: var(--accent); color: var(--accent); }
.more-menu .btn-danger { margin-top: 4px; }
/* library rows: the title opens the song, key / BPM / length read at a glance */
.dt-title-cell { display: block; }
a.song-link { color: var(--fg); text-decoration: none; }
a.song-link:hover, a.song-link:focus-visible { color: var(--accent); text-decoration: underline; }
td.col-fact, th.col-fact { white-space: nowrap; }
.fact-more { color: var(--muted); font-size: .8em; }
.rev-list { list-style: none; padding: 0; margin: 0; }
.rev-list li { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; padding: 8px 4px; border-bottom: 1px solid var(--border); }
.rev-list li.current { background: #26230f; }
.rev-list .rev-name { font-weight: bold; min-width: 90px; }
.rev-list .rev-meta { color: var(--muted); font-size: .9rem; flex: 1 1 200px; }
.rev-list .rev-tools { display: flex; gap: 4px; }
.rev-view h4 { margin: 10px 0 4px; color: var(--accent); }
.rev-view .rev-head { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.import-drop { border: 2px dashed var(--border); border-radius: 8px; padding: 14px; text-align: center; color: var(--muted); }
.import-drop input[type=file] { display: block; margin: 8px auto 0; }
/* setlist import: each arrangement, found in the library or added to it */
.import-report { list-style: none; padding: 0; margin: 0; }
.import-report li { display: flex; gap: 8px; align-items: center; justify-content: space-between; flex-wrap: wrap; padding: 6px 4px; border-bottom: 1px solid var(--border); }
/* sheet import: the uploaded picture beside what was read from it */
dialog.modal-sheet { width: min(1280px, calc(100vw - 32px)); }
.sheet-review { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr); gap: 16px; align-items: start; }
.sheet-scan { position: sticky; top: 0; }
.sheet-scan img { width: 100%; border-radius: 6px; background: #fff; }
.sheet-read { display: flex; flex-direction: column; gap: 8px; min-width: 0; overflow-x: auto; }
.sheet-warnings { margin: 0; padding: 8px 10px 8px 26px; border: 1px solid #7a5a00; border-radius: 6px; background: #2a2000; color: #ffd66b; font-size: .9rem; }
.sheet-warnings:empty { display: none; }
.sheet-section-name { background: transparent; color: inherit; border: 1px dashed var(--border); border-radius: 6px; padding: 4px 8px; font: inherit; width: min(100%, 320px); }
@media (max-width: 900px) { .sheet-review { grid-template-columns: 1fr; } .sheet-scan { position: static; } }
.key-pick { display: flex; gap: 6px; align-items: center; }
.key-pick select { flex: 1 1 auto; }

.seg { display: inline-flex; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.seg .seg-btn { border: 0; border-radius: 0; margin: 0; min-height: 32px; padding: 4px 10px; font-size: .85rem; }
.seg .seg-btn.active { background: var(--accent); color: #000; }
.btn.active { border-color: var(--accent); color: var(--accent); }
.play-note { min-width: 44px; margin: 0; }
.help-example pre { margin: 0 0 4px; padding: 8px 10px; background: #0d0d0d; border-radius: 6px; font-family: Menlo, Consolas, monospace; white-space: pre-wrap; }
.help-example .page-preview { grid-column: auto; }
.help p { margin: 0; }
.rev-diff { border: 1px solid var(--accent); border-radius: 8px; padding: 8px 12px; margin: 8px 0; background: #26230f; }
.rev-diff ul { margin: 4px 0 0 18px; padding: 0; }
.rev-view h4 .chip { margin-left: 8px; }

/* setlist editor v2 */
.setlist-summary { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; margin: 6px 0 12px; }
.meter { flex: 1 1 200px; height: 8px; background: #0d0d0d; border-radius: 999px; overflow: hidden; border: 1px solid var(--border); }
.meter > div { height: 100%; background: var(--ok); }
.meter.over > div { background: var(--bad); }
.setlist-row { cursor: default; }
.setlist-row .setlist-line { min-height: 44px; }
.setlist-row .setlist-sub { color: var(--muted); font-size: .85rem; margin: 2px 0 0 54px; }
.setlist-row.item-deleted { border-color: var(--bad); }
.setlist-row .item-tools { margin-left: auto; display: flex; gap: 4px; }
.setlist-row .item-tools .btn { margin: 0; }
.script-list { list-style: none; padding: 0; margin: 0; }
.script-list li { display: flex; gap: 8px; align-items: center; padding: 6px 0; border-bottom: 1px solid var(--border); }
.script-list .script-where { color: var(--accent); font-size: .85rem; white-space: nowrap; }
.script-list .script-txt { flex: 1 1 auto; }
.script-list .script-name { color: #9bd; }
.rev-view .view-script { white-space: pre-wrap; font-style: italic; color: #9bd; }

@media (max-width: 900px) {
  .col-minor { display: none; }
  .dt-actions { white-space: normal; }
  .sub-table th, .sub-table td { padding: 6px 6px; }
}
@media (max-width: 700px) {
  .editor-layout { flex-direction: column; }
  .dt-table thead { display: none; }
  .dt-table, .dt-table tbody, .dt-table tr, .dt-table td { display: block; width: 100%; }
  .dt-table tr.dt-row { border-bottom: 2px solid var(--border); padding: 6px 0; }
  .dt-table td { border: 0; padding: 4px 12px; display: flex; gap: 10px; }
  .dt-table td[data-label]::before { content: attr(data-label); color: var(--muted); font-size: .75rem; text-transform: uppercase; letter-spacing: .05em; flex: 0 0 90px; padding-top: 3px; }
  .dt-table td.dt-chev { display: none; }
  .dt-table td.dt-actions { text-align: left; white-space: normal; flex-wrap: wrap; gap: 0; }
  .dt-table td.dt-actions::before { content: ''; flex-basis: 0; }
  .dt-expand-row > td { padding: 4px 12px 12px; display: block; }
  .dt-expand-row > td::before { content: none; }
  /* key / BPM / length side by side on one line of the card; empty cells (no artist, no tags) take no line */
  .dt-table td.col-fact { display: inline-flex; width: auto; padding-right: 4px; vertical-align: top; }
  .dt-table td.col-fact::before { flex: 0 0 auto; }
  .page-library .dt-table td:empty { display: none; }
  .dt-table td.col-minor { display: none; }  /* .dt-table td above would show them again */
  .dt-table tr.arr-row { border-bottom: 1px solid var(--border); padding: 6px 0; }
  .dt-table tr.arr-row:last-child { border-bottom: 0; }
  .setlist-row .setlist-sub { margin-left: 0; }
  .tab { padding: 10px 12px; }
}

/* structured chords in the editor: parse errors and bar warnings on a page, the convert banner, the Numbers/Letters toggle */
.page-error { color: var(--bad); font-size: .85em; margin-bottom: 4px; }
.page-warning { color: var(--accent); font-size: .85em; margin-bottom: 4px; }  /* a bar saved before bar lengths were checked */
.page-warning-bar { padding-left: 1.4em; }
.convert-banner { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.section-head-row .seg { display: inline-flex; }
.section-head-row .tool-pair { display: inline-flex; gap: 8px; align-items: center; }  /* a label wraps with its buttons */

/* ---- slideshow (projector): lyrics over a picture or a drifting gradient ---- */
@property --g1 { syntax: '<color>'; inherits: true; initial-value: #0b1026; }
@property --g2 { syntax: '<color>'; inherits: true; initial-value: #1d2a5a; }
@property --g3 { syntax: '<color>'; inherits: true; initial-value: #2a1446; }
.page-slideshow { position: fixed; inset: 0; padding: 0; margin: 0; max-width: none; overflow: hidden; background: #000; color: #fff; --overlay: .45; --g1: #0b1026; --g2: #1d2a5a; --g3: #2a1446; }
.page-slideshow.idle { cursor: none; }
.page-slideshow .bg { position: absolute; inset: 0; }
.bg-gradient { background: linear-gradient(135deg, var(--g1), var(--g2), var(--g3), var(--g1)); background-size: 300% 300%; animation: ss-drift 40s ease-in-out infinite; transition: --g1 2s ease, --g2 2s ease, --g3 2s ease; }
.bg-image { background-size: cover; background-position: center; opacity: 0; transition: opacity 1.2s ease; animation: ss-kenburns 50s ease-in-out infinite alternate; will-change: opacity, transform; }
.bg-image.show { opacity: 1; }
.bg-image.fit-contain { background-size: contain; background-repeat: no-repeat; background-color: #000; animation: none; }  /* "show it whole": centred, black bars */
.bg-image.bg-html, .bg-image.bg-video { animation: none; }  /* they move by themselves; no slow zoom */
.bg-image video { position: absolute; inset: 0; width: 100%; height: 100%; display: block; object-fit: cover; object-position: center; pointer-events: none; background: #000; }
.bg-image.fit-contain video { object-fit: contain; }  /* "show it whole": centred, black bars */
.bg-image iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; display: block; pointer-events: none; background: #000; }  /* never takes the mouse: double-click and idle cursor stay with the page */
.bg-overlay { position: absolute; inset: 0; background: #000; opacity: 0; transition: opacity .6s ease; }
.page-slideshow.has-image .bg-overlay { opacity: var(--overlay); }
.slide { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; padding: 5vh 6vw; text-align: center; }
.slide-lyrics { max-width: 100%; max-height: 100%; overflow: hidden; font-weight: 600; line-height: 1.25; text-shadow: 0 2px 14px rgba(0,0,0,.85), 0 0 3px rgba(0,0,0,.9); overflow-wrap: anywhere; }
.slide-lyrics .cp-line { margin: 0 0 .25em; line-height: 1.25; }
.slide-lyrics .cp-lyrics-only .cp-line { font-size: 1em; }
.slide-lyrics.fade { animation: ss-fade .35s ease; }
.slide-card { text-shadow: 0 2px 14px rgba(0,0,0,.85); animation: ss-fade .6s ease; }
.slide-song { font-size: min(9vh, 7vw); font-weight: 700; line-height: 1.15; }
.slide-artist { font-size: min(4vh, 3vw); color: rgba(255,255,255,.8); margin-top: 1.5vh; }
.slide-artist:empty { display: none; }
.slide-black { position: absolute; inset: 0; background: #000; opacity: 0; transition: opacity .4s ease; pointer-events: none; z-index: 5; }
.page-slideshow.blackout .slide-black { opacity: 1; }
.slide-hint { position: absolute; left: 0; right: 0; bottom: 12px; text-align: center; font-size: .85rem; color: rgba(255,255,255,.55); transition: opacity .5s; z-index: 6; }
.page-slideshow.idle .slide-hint, .page-slideshow.blackout .slide-hint, .page-slideshow.preview .slide-hint { display: none; }
body.offline .page-slideshow { opacity: .55; }
@keyframes ss-drift { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } }
@keyframes ss-kenburns { from { transform: scale(1); } to { transform: scale(1.08); } }
@keyframes ss-fade { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .bg-gradient, .bg-image, .slide-lyrics.fade, .slide-card { animation: none; }
}
/* control: slideshow drawer */
.overlay-field { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.overlay-field input[type=range] { width: 180px; accent-color: var(--accent); }
.overlay-field output { min-width: 3ch; font-variant-numeric: tabular-nums; }
/* slideshow backgrounds: thumbnails (a picture, or an HTML page that plays while hovered) */
.bg-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 6px; }
.bg-row-name { min-width: 0; max-width: 260px; overflow-wrap: anywhere; }
.bg-thumb { display: inline-block; position: relative; overflow: hidden; flex: none; vertical-align: middle; width: 160px; height: 90px; border-radius: 6px; border: 1px solid var(--border); background: #000; }
.bg-thumb img, .bg-thumb video { display: block; width: 100%; height: 100%; object-fit: cover; }
.bg-thumb-video .bg-thumb-label { inset: auto 6px 6px auto; padding: 1px 6px; border-radius: 4px; background: rgba(0, 0, 0, .6); font-size: .72rem; }
.bg-thumb-video.playing .bg-thumb-label { display: flex; }
.bg-thumb-video.unplayable { outline: 2px solid var(--bad); outline-offset: -2px; }
.bg-thumb .bg-frame { position: absolute; left: 0; top: 0; border: 0; transform-origin: 0 0; pointer-events: none; }
.bg-thumb-small { width: 112px; height: 63px; }
.bg-thumb-default { opacity: .55; border: 1px dashed var(--muted); }
.bg-thumb-none { display: inline-flex; align-items: center; justify-content: center; font-size: .8rem; color: var(--muted); background: linear-gradient(135deg, #0b1026, #1d2a5a, #2a1446); }
.bg-thumb-html { background: linear-gradient(135deg, #141a33, #2a1446); }
.bg-thumb-label { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: .8rem; letter-spacing: .05em; color: rgba(255, 255, 255, .75); }
.bg-thumb-html.playing .bg-thumb-label { display: none; }
/* backgrounds page */
.bg-settings { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); gap: 12px; align-items: start; }
.bg-panel h2:first-child { margin-top: 0; }
.bg-preview { position: relative; width: 100%; aspect-ratio: 16 / 9; background: #000; border-radius: 8px; overflow: hidden; border: 1px solid var(--border); }
.bg-preview iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; pointer-events: none; }
.bg-switch { display: flex; align-items: center; gap: 8px; font-size: 1rem; cursor: pointer; }
.bg-switch input { transform: scale(1.4); margin: 4px 8px 4px 4px; }
.page-backgrounds .dt-table td.bg-cell { width: 130px; }
.bg-library { margin: 14px 0 8px; }
.bg-lib-toolbar .btn { margin: 0; }
.bg-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; }
.bg-card { display: flex; flex-direction: column; gap: 4px; min-width: 0; padding: 8px; background: var(--panel); border: 1px solid var(--border); border-radius: 10px; color: var(--fg); font: inherit; text-align: left; }
.bg-card .bg-thumb { width: 100%; height: auto; aspect-ratio: 16 / 9; margin-bottom: 2px; }
.bg-card.deleted { opacity: .6; }
.bg-card-name { font-weight: bold; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bg-card-meta, .bg-card-usage { font-size: .8rem; }
.bg-card-usage { color: var(--muted); }
.bg-card-usage.used { color: var(--ok); }
.bg-card-warn { font-size: .8rem; color: var(--accent); line-height: 1.3; }
.bg-card-warn.bad { color: var(--bad); }
.bg-card-warn:empty { display: none; }
.bg-card-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 2px; margin-top: 2px; }
.bg-card-actions .btn { display: inline-flex; align-items: center; }
.bg-empty { grid-column: 1 / -1; }
.bg-fit-preview { aspect-ratio: 16 / 9; background: #000; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.bg-fit-preview img, .bg-fit-preview video { display: block; width: 100%; height: 100%; }
.bg-starters-label { font-size: .85rem; margin-bottom: -4px; }
.bg-starters { display: grid; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); gap: 8px; }
.bg-starter { display: flex; gap: 10px; align-items: flex-start; padding: 8px; border: 1px solid var(--border); border-radius: 8px; cursor: pointer; color: var(--fg); font-size: .9rem; line-height: 1.35; }
.bg-starter:has(input:checked) { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.bg-starter-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.bg-starter-name { display: flex; align-items: center; gap: 6px; }
.modal-body .bg-starter input[type=radio] { width: auto; min-height: 0; margin: 0; padding: 0; transform: scale(1.2); flex: none; accent-color: var(--accent); }
/* library picker (a dialog) */
dialog.modal-bg-picker { width: min(980px, calc(100vw - 32px)); }
.bg-pick-tools { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-bottom: 10px; }
.bg-pick-tools .btn { margin: 0; }
.modal-body input.bg-pick-search { flex: 1 1 220px; width: auto; }
.bg-pick-grid { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); }
.bg-pick { cursor: pointer; }
.bg-pick:hover, .bg-pick:focus-visible { border-color: var(--accent); }
.bg-pick.current { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.bg-pick-empty { grid-column: 1 / -1; }
.bg-pick .bg-card-name { white-space: normal; }
/* the background + dimming dialog: a preview of the choice with its dimming, and the dimming control */
.bg-choose-top { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: 12px; align-items: start; margin-bottom: 12px; }
.bg-choose-preview, .ev-card-preview { position: relative; aspect-ratio: 16 / 9; background: #000; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; container-type: inline-size; }
.bg-choose-preview .bg-choose-thumb, .ev-card-preview .bg-choose-thumb { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; border-radius: 0; }
.bg-choose-shade { position: absolute; inset: 0; background: #000; pointer-events: none; transition: opacity .2s; }
.bg-choose-lyrics { position: absolute; inset: 5% 6%; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; color: #fff; font-weight: 600; line-height: 1.25; font-size: 6cqw; text-shadow: 0 2px 14px rgba(0,0,0,.85), 0 0 3px rgba(0,0,0,.9); pointer-events: none; }
.bg-choose-badge { position: absolute; left: 6px; top: 6px; max-width: calc(100% - 12px); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: .75rem; color: #fff; background: rgba(0, 0, 0, .65); padding: 2px 7px; border-radius: 4px; }
.bg-choose-dim { display: flex; flex-direction: column; gap: 8px; }
.bg-choose-dim .overlay-field input[type=range] { width: 100%; flex: 1 1 auto; }
.bg-choose-dim input[type=range]:disabled { opacity: .45; }
/* a flow entry's own background (arrangement editor, Flow tab) */
.bg-thumb-tiny { width: 48px; height: 27px; border-radius: 4px; }
.bg-thumb-tiny .bg-thumb-label { font-size: .55rem; letter-spacing: 0; }
.bg-thumb-video.bg-thumb-tiny .bg-thumb-label { display: none; }
.flow-bg { display: inline-flex; align-items: center; gap: 6px; min-height: 36px; padding: 3px 8px; margin: 0; flex: none; }
.flow-bg .flow-bg-text { font-size: .8rem; color: var(--muted); }
.flow-bg.own { border-color: var(--info); }
.flow-bg.own .flow-bg-text { color: var(--fg); }
.flow-bg.missing .flow-bg-text { color: var(--bad); }
/* the event screen (event editor) */
.ev-screen h2 { margin-top: 0; }
.ev-screen-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); gap: 14px; align-items: start; }
.ev-card-words { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 0 6%; color: #fff; text-shadow: 0 2px 14px rgba(0,0,0,.85); pointer-events: none; }
.ev-card-title { font-size: 5cqw; font-weight: 700; line-height: 1.15; }
.ev-card-sub { font-size: 2.4cqw; color: rgba(255, 255, 255, .8); margin-top: 1.5cqw; }
.ev-card-sub:empty { display: none; }
.dim-now { color: var(--fg); }
@media (max-width: 800px) { .bg-choose-top, .ev-screen-grid { grid-template-columns: 1fr; } }
@media (max-width: 800px) { .bg-settings { grid-template-columns: 1fr; } }
/* HTML background editor */
.bg-ed { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 12px; align-items: start; }
.bg-ed-tools { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; margin: 6px 0 8px; }
.bg-ed-tools .btn { margin: 0; display: inline-flex; align-items: center; }
.bg-ed-name { margin-bottom: 4px; }
.bg-ed-textarea { display: block; width: 100%; min-height: 56vh; resize: vertical; background: #0d0d0d; color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 8px; font-family: Menlo, Consolas, monospace; font-size: .85rem; line-height: 1.45; tab-size: 2; white-space: pre; overflow: auto; }
.bg-ed-status { font-size: .85rem; margin: 4px 0; min-height: 1.2em; }
.bg-ed-error { color: var(--bad); }
.bg-ed-h { margin: 10px 0 6px; font-size: 1rem; }
.bg-ed-warnings { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.bg-ed-warn { display: flex; gap: 4px 8px; align-items: baseline; flex-wrap: wrap; padding: 6px 8px; border: 1px solid var(--border); border-left: 3px solid var(--accent); border-radius: 0 6px 6px 0; font-size: .9rem; line-height: 1.35; }
.bg-ed-warn.level-tip { border-left-color: var(--info); }
.bg-ed-warn-tag { font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; color: var(--accent); }
.bg-ed-warn.level-tip .bg-ed-warn-tag { color: var(--info); }
.bg-ed-line { background: none; border: 0; padding: 0; color: var(--info); text-decoration: underline; cursor: pointer; font: inherit; }
.bg-ed-warn-msg { flex: 1 1 260px; }
.bg-ed-ok { color: var(--ok); font-size: .9rem; }
.bg-ed-preview { position: sticky; top: 52px; }
.bg-ed-check { display: inline-flex; gap: 6px; align-items: center; font-size: .9rem; cursor: pointer; }
.bg-ed-check input { transform: scale(1.2); }
.bg-ed-screen { position: relative; width: 100%; aspect-ratio: 16 / 9; background: #000; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.bg-ed-stage { position: absolute; left: 0; top: 0; width: 1920px; height: 1080px; transform-origin: 0 0; overflow: hidden; }
.bg-ed-frame { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; display: block; pointer-events: none; background: #000; }
.bg-ed-dim { position: absolute; inset: 0; background: #000; opacity: .45; pointer-events: none; transition: opacity .3s; }
.bg-ed-lyrics { position: absolute; inset: 5% 6%; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; color: #fff; font-weight: 600; line-height: 1.25; text-shadow: 0 2px 14px rgba(0,0,0,.85), 0 0 3px rgba(0,0,0,.9); pointer-events: none; }
.bg-ed-lyrics > div { margin: 0 0 .25em; }
.bg-ed-guides { position: absolute; inset: 0; pointer-events: none; }
.bg-ed-guides .gl-v { position: absolute; left: 50%; top: 0; bottom: 0; margin-left: -2px; border-left: 4px dashed rgba(255, 179, 0, .85); }
.bg-ed-guides .gl-h { position: absolute; top: 50%; left: 0; right: 0; margin-top: -2px; border-top: 4px dashed rgba(255, 179, 0, .85); }
.bg-ed-guides .gl-safe { position: absolute; inset: 5% 6%; border: 4px dashed rgba(74, 163, 223, .75); }
#prompt-text { width: 100%; background: #0d0d0d; color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 8px; font-family: Menlo, Consolas, monospace; font-size: .8rem; }
@media (max-width: 1000px) { .bg-ed { grid-template-columns: 1fr; } .bg-ed-preview { position: static; } .bg-ed-textarea { min-height: 40vh; } }
/* check: an optional device that is not connected is neither ✓ nor ✗ */
.checks li.skip .mark { color: var(--muted); }

/* ---- show summary (after End on the last item) ---- */
.summary-overlay { position: fixed; inset: 0; z-index: 60; background: rgba(0, 0, 0, .78); display: flex; align-items: flex-start; justify-content: center; padding: 24px 16px; overflow-y: auto; }
.summary-card { width: 100%; max-width: 680px; background: var(--panel); border: 1px solid var(--border); border-radius: 12px; padding: 16px 18px; box-shadow: 0 10px 40px rgba(0, 0, 0, .6); }
.summary-card h2 { margin: 0 0 2px; color: var(--accent); }
.summary-table { width: 100%; border-collapse: collapse; margin: 12px 0 6px; font-size: 1.05rem; }
.summary-table th, .summary-table td { padding: 6px 8px; border-bottom: 1px solid var(--border); text-align: left; vertical-align: baseline; }
.summary-table th { color: var(--muted); font-weight: normal; font-size: .85rem; }
.summary-table .num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.summary-table tr.skipped td { color: var(--muted); }
.summary-table tfoot td { font-weight: bold; border-bottom: 0; }
.summary-table tr.summary-total td { font-size: 1.25rem; border-top: 2px solid var(--border); }
.summary-table .over { color: var(--bad); }
.summary-table .under { color: var(--ok); }
.summary-tag { margin-left: 8px; font-size: .75rem; color: var(--muted); border: 1px solid var(--border); border-radius: 4px; padding: 0 5px; }
.summary-actions { display: flex; justify-content: flex-end; }
@media (max-width: 480px) { .summary-table { font-size: .95rem; } .summary-table th, .summary-table td { padding: 5px 4px; } }

/* ---- script items: pages with singer / pianist / projector views (event editor) ---- */
.script-music { gap: 8px; }
.script-music .field { flex: 1 1 80px; }
.script-pages { display: flex; flex-direction: column; gap: 10px; }
.script-page { border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px; display: flex; flex-direction: column; gap: 6px; background: #161616; }
.script-page-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.script-page-tools { display: flex; gap: 4px; }
.script-page-tools .btn { margin: 0; }
.field textarea.script-pianist { font-family: Menlo, Consolas, monospace; }
.view-pianist-raw { white-space: pre-wrap; font-family: Menlo, Consolas, monospace; color: var(--muted); }
/* a script page on the pianist's screen: the music, the words under it */
.script-sec > .script-words { padding: 0 12px 8px 16px; color: var(--muted); }  /* above the page, lined up with its text (border 4 + padding 12) */

/* ---- own screen (event setting): this device is not on the live page ---- */
.own-nav-bar { position: fixed; left: 50%; transform: translateX(-50%); bottom: calc(var(--nav-h) + 10px); z-index: 25; display: flex; align-items: center; gap: 12px;
  max-width: calc(100vw - 32px); padding: 8px 10px 8px 16px; background: #14303f; border: 2px solid var(--info); border-radius: 12px; box-shadow: 0 6px 24px rgba(0, 0, 0, .6); }
.own-nav-text { font-size: 1rem; white-space: pre-wrap; overflow: hidden; text-overflow: ellipsis; }
.own-nav-bar .btn { margin: 0; white-space: nowrap; min-height: 48px; font-size: 1.05rem; }
@media (max-width: 600px) { .own-nav-bar { left: 16px; right: 16px; transform: none; max-width: none; } .own-nav-text { font-size: .85rem; } }

/* ---- arrangement editor: Preview panel (the real device pages of this song, unsaved edits included) ---- */
.preview-panel { position: fixed; top: 52px; right: 16px; z-index: 40; width: min(760px, calc(100vw - 32px)); min-width: 320px; max-width: calc(100vw - 32px);
  background: var(--panel); border: 1px solid var(--border); border-radius: 12px; box-shadow: 0 12px 40px rgba(0, 0, 0, .65); padding: 8px; resize: horizontal; overflow: hidden; }
.preview-panel-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.preview-panel-head .btn { margin: 0; }
.preview-note { flex: 1 1 auto; font-size: .8rem; }
.preview-note.preview-error { color: var(--bad); }
.preview-stage { position: relative; overflow: hidden; border-radius: 8px; background: #000; }
.preview-frame { position: absolute; top: 0; left: 0; border: 0; transform-origin: 0 0; background: var(--bg); }
.preview-frame.hidden { display: none; }
/* under the projector: Previous / Next through this song's pages, and where it is */
.preview-nav { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.preview-nav .btn { margin: 0; }
.preview-where { flex: 1 1 auto; text-align: center; font-size: .9rem; }
/* a device page inside that preview: nothing that would reach the show */
body.preview-mode #btn-issue { display: none; }

/* ---- scrolling song views: the marks are two layers that slide to their pages (LPA.placeMarks) ---- */
.marks-slide { position: relative; }
.marks-slide > :not(.mark-layer) { position: relative; z-index: 1; }
.marks-slide .song-page.current, .marks-slide .song-page.next,
.marks-slide .cp-grid-page.current, .marks-slide .cp-grid-page.next { background: transparent; border-left-color: transparent; box-shadow: none; }
.mark-layer { position: absolute; z-index: 0; top: 0; left: 0; width: 0; height: 0; border-radius: 6px; border-left: 4px solid transparent; box-sizing: border-box; pointer-events: none; opacity: 0;
  transition: top var(--slide, 1500ms) cubic-bezier(.25, .8, .25, 1), left var(--slide, 1500ms) cubic-bezier(.25, .8, .25, 1),
    width var(--slide, 1500ms) cubic-bezier(.25, .8, .25, 1), height var(--slide, 1500ms) cubic-bezier(.25, .8, .25, 1), opacity calc(var(--slide, 1500ms) / 2) ease; }
.mark-layer.still { transition: none; }
.mark-now { background: #2a2410; border-left-color: var(--accent); }
.mark-next { background: #14303f; border-left-color: var(--info); }
/* a heading's amber goes in the first half of the slide and the next heading's comes in the second: never two amber
   headings at once (the delay holds for the heading becoming current; the one it leaves fades at once) */
.marks-slide .song-sec-head { transition: background-color calc(var(--slide, 1500ms) / 2) ease, color calc(var(--slide, 1500ms) / 2) ease, border-color calc(var(--slide, 1500ms) / 2) ease; }
.marks-slide .song-sec.current .song-sec-head { transition-delay: calc(var(--slide, 1500ms) / 2); }
.marks-slide .cp-grid-name { transition: color var(--slide, 1500ms) ease; }
@media (prefers-reduced-motion: reduce) { .mark-layer, .marks-slide .song-sec-head, .marks-slide .cp-grid-name { transition: none; } }
/* the page just played / the page that comes next, when it is elsewhere in the song: its lines copied in next to the
   current page (LPA.followPage, which also keeps the view still while they come and go: no scroll anchoring of the
   browser's own) */
.pianist-content.song-scroll, .singer-song { overflow-anchor: none; }
.song-cue { margin: 0 0 14px; opacity: .6; }
.song-cue-label { padding: 0 12px 2px; font-size: .6em; font-weight: bold; color: var(--muted); text-transform: uppercase; letter-spacing: .06em; }
.song-cue-clip { overflow: hidden; border-left: 4px dashed var(--muted); border-radius: 6px; }
.song-cue-page { padding: 6px 12px 2px; }
.song-cue-next { margin: 6px 0 14px; opacity: .85; }  /* what comes next, drawn elsewhere: its first lines under the current page */
/* the page left behind, out of sight (LPA.rollInto); .song-cue twice so .marks-slide > * does not make it relative (in
   the flow: blank room above the song, 2026-10-15) */
.song-cue.song-cue-ghost { position: absolute; top: -10000px; left: 0; width: 100%; margin: 0; visibility: hidden; }
.song-cue-space, .song-cue-fill { margin: 0; opacity: 1; }  /* room above the page just rolled into (its first line where the cue's was), and below a short one */
.song-cue-next .song-cue-label { color: var(--info); }
.song-cue-next .song-cue-clip { border-left-color: var(--info); background: #14303f; }  /* tinted as the next page is (.mark-next) */
.singer-song .song-cue-label { font-size: max(.4em, .7rem); }
/* Next onto the page the blue cue copies (LPA.liftCue / LPA.rollTo): copies laid over the box, on the page colour,
   that stay put while the song rolls in under them */
.roll-glass { position: fixed; z-index: 20; overflow: hidden; pointer-events: none; margin: 0; padding: 0; min-height: 0; max-height: none; }
.roll-glass > .roll-item { position: absolute; margin: 0; box-sizing: border-box; }
.roll-glass.roll-out, .roll-glass.roll-in { will-change: transform, opacity; }  /* the box as it was, and the next item coming up (LPA.turnOver) */

/* ---- drummer: the count view (countview.js), drum bars and the drum grid (drums.js) ---- */
:root { --drum: #b48cff; }
.icon-drum { margin-right: 4px; }
.cv-page { display: flex; flex-direction: column; }
/* a line's bars share it by how long they last (flex-grow), each at least as wide as its words need (fitBars); the
   bar line on the left is a shadow, so a bar that wraps onto a second row still has one */
.cv-line { display: flex; flex-wrap: wrap; row-gap: .4em; padding-left: 2px; margin: .15em 0 .5em; min-width: 0; }
.cv-bar { position: relative; flex: 1 1 0; border-right: 2px solid var(--muted); box-shadow: -2px 0 0 var(--muted); min-width: 0; padding: 0 0 .1em; }
.cv-drum { display: none; }
.cv-line.has-drum .cv-drum, .cv-editable .cv-line .cv-drum { display: block; min-height: 4.4em; border-bottom: 1px dashed #3a3a3a; padding: 0 .15em; overflow: hidden; }
.cv-drum-label { font-size: .58em; color: var(--drum); line-height: 1.25; padding: .15em .25em 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cv-drum-staff { color: var(--fg); line-height: 0; min-height: 3em; }
.cv-chords { position: relative; height: 1.25em; }
.cv-chord { position: absolute; top: .1em; padding-left: .25em; color: var(--accent); font-weight: bold; font-size: .8em; white-space: nowrap; }
.cv-beats { position: relative; height: 1.4em; }
.cv-beat { position: absolute; top: 0; padding-left: .2em; font-size: 1.1em; font-weight: bold; line-height: 1.2; color: #5a5a5a; }
.cv-beat.cv-one { color: #808080; }
.cv-words { position: relative; height: 1.75em; }
.cv-word { position: absolute; top: .05em; padding-left: .25em; white-space: nowrap; }
.cv-hold { position: absolute; top: 1.42em; height: 3px; border-radius: 2px; background: #575757; }
.cv-hold-on { background: #444; }
.cv-text { margin: .1em 0 .45em; }
.cv-blank { height: .5em; }
.cv-bar.cv-now { background: rgba(46, 204, 113, .1); }
.cv-beat.cv-on { color: var(--ok); }
/* the count-in's last bar (countview.js lead): the first note's beat number flashing on every click, fading by the
   next (--count-beat: a beat), brighter on the bar's first beat; its bar tinted fainter */
@keyframes cv-lead { from { color: #fff; text-shadow: 0 0 .3em var(--ok); } to { color: rgba(46, 204, 113, .45); text-shadow: none; } }
@keyframes cv-lead-one { from { color: #fff; text-shadow: 0 0 .3em var(--ok), 0 0 .7em var(--ok); transform: scale(1.2); } to { color: rgba(46, 204, 113, .45); text-shadow: none; transform: none; } }
.cv-bar.cv-now.cv-lead { background: rgba(46, 204, 113, .045); }
.cv-beat.cv-on.cv-lead { animation: cv-lead var(--count-beat, .5s) ease-out forwards; }
.cv-beat.cv-on.cv-lead-one { animation-name: cv-lead-one; }
.cv-drum-strip { display: flex; flex-wrap: wrap; gap: .5em; margin: 0 0 .35em; }
.cv-drum-strip .cv-drum-cell { width: min(100%, 20em); border: 1px dashed #3a3a3a; border-radius: 6px; padding: 0 .3em .2em; }
.cv-editable .cv-bar, .cv-editable .cv-drum-strip .cv-drum-cell { cursor: pointer; }
.cv-editable .cv-bar:hover, .cv-editable .cv-bar:focus-visible, .cv-editable .cv-drum-cell:hover { outline: 2px solid var(--drum); outline-offset: -2px; }
.cv-drum-add-hint { display: block; font-size: .58em; color: var(--drum); padding: .3em .25em; opacity: .75; }
.cv-drum-add { font-size: .7em; align-self: flex-start; margin: 0; }

/* the drum grid editor */
.drum-editor-box { display: flex; flex-direction: column; gap: 8px; }
.de-tools { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: center; }
.de-tools .btn, .de-tools .seg .seg-btn { margin: 0; }
.de-tools input, .de-tools select { min-height: 36px; background: #0d0d0d; color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 4px 8px; font: inherit; font-size: .9rem; }
.de-tools .de-label { width: 200px; }
.de-link { font-size: .85rem; color: var(--drum); }
.de-warn { font-size: .85rem; color: var(--accent); }
.de-body { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); gap: 14px; align-items: start; }
@media (max-width: 1100px) { .de-body { grid-template-columns: minmax(0, 1fr); } }
.dg { display: grid; gap: 3px 2px; user-select: none; -webkit-user-select: none; overflow-x: auto; }
.dg-count { text-align: center; font-size: .72rem; color: var(--muted); padding-bottom: 2px; }
.dg-count.beat { color: var(--fg); font-weight: bold; font-size: .85rem; }
.dg-inst { font-size: .82rem; display: flex; align-items: center; gap: 6px; padding-right: 6px; white-space: nowrap; }
.dg-inst i { font-style: normal; color: var(--muted); width: 1em; text-align: center; }
.dg-cell { min-height: 28px; border: 0; border-radius: 4px; background: #252525; color: var(--fg); font: inherit; font-size: .82rem; padding: 0; cursor: pointer; touch-action: manipulation; }
.dg-cell.alt { background: #2f2f2f; }
.dg-cell:hover { outline: 1px solid var(--drum); }
.dg-cell.on { background: #d8d8d8; color: #000; font-weight: bold; }
.dg-cell.acc { background: var(--accent); color: #000; font-weight: bold; }
.drum-touch .dg-cell { min-height: 38px; font-size: 1rem; }
.drum-touch .dg-inst { font-size: .95rem; }
.de-staff { background: #0d0d0d; border: 1px dashed var(--border); border-radius: 6px; padding: 8px; color: var(--fg); min-width: 0; }
.de-staff .subtle { display: block; margin-bottom: 4px; }
.de-staff-draw { line-height: 0; }
dialog.modal-drums { width: min(1100px, 96vw); max-width: 96vw; }
.modal-drums .modal-body { max-height: 74vh; overflow-y: auto; }

/* the arrangement editor: a page's drum bars, one chip per bar of the page */
.drums { display: flex; flex-direction: column; gap: 6px; }
.drums-summary { font-size: .85rem; color: var(--drum); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.page-row.open .drums-summary { display: none; }
.page-row:not(.open) .drums-open { display: none; }
.drums-open { padding: 8px; border-radius: 8px; background: #121212; display: flex; flex-direction: column; gap: 8px; }
.drums-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: .85rem; color: var(--muted); }
.drums-head .drums-label { color: var(--drum); }
.drums-head .btn { margin: 0; }
.drum-line { display: grid; grid-template-columns: repeat(var(--n, 4), minmax(0, 1fr)); gap: 6px; }
.drum-chip { display: flex; flex-direction: column; align-items: stretch; gap: 2px; text-align: left; min-height: 64px; padding: 5px 8px; background: var(--panel); color: var(--fg); border: 1px dashed var(--border); border-radius: 8px; font: inherit; cursor: pointer; min-width: 0; }
.drum-chip:hover { border-color: var(--drum); }
.drum-chip.has { border-style: solid; border-color: #4a3d66; }
.drum-chip.sel { border: 2px solid var(--drum); background: #1d1726; }
.drum-chip.orphan { border-color: var(--bad); }
.dc-no { font-size: .75rem; color: var(--muted); display: flex; gap: 8px; }
.dc-no b { color: var(--accent); }
.dc-words { font-size: .9rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dc-add { font-size: .8rem; color: var(--drum); margin-top: auto; }
.dc-label { font-size: .75rem; color: var(--drum); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dc-thumb { color: var(--fg); line-height: 0; overflow: hidden; }
.drum-panel { border: 1px solid #4a3d66; border-radius: 8px; padding: 8px 10px; background: #161320; display: flex; flex-direction: column; gap: 8px; }
.drum-panel-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.drum-panel-head strong { color: var(--drum); }
.drum-panel-head .btn { margin: 0; }
.drum-panel-head .spacer { margin-left: auto; }
.sec-sum-drums { color: var(--drum); font-size: .8rem; }
.sec-sum-remarks { color: var(--muted); font-size: .8rem; }

/* the drummer iPad */
.page-drummer .pianist-content { font-size: 1.5rem; }
.page-drummer #btn-edit-drums.active { background: var(--drum); color: #000; border-color: var(--drum); }
.drum-edit-hint { margin: 4px 0 8px; color: var(--drum); font-size: .95rem; }
.page-drummer.drum-editing .pianist-content .song-page { cursor: default; }

/* the drum library page */
.drum-lib { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 12px; }
.drum-card { border: 1px solid var(--border); border-radius: 10px; background: var(--panel); padding: 10px 12px; display: flex; flex-direction: column; gap: 6px; }
.drum-card.deleted { opacity: .6; }
.drum-card-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.drum-card-head strong { font-size: 1.05rem; }
.drum-card-staff { line-height: 0; color: var(--fg); min-height: 60px; }
.drum-card-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.drum-card-actions .btn { margin: 0; }
.drum-lib-tools { display: flex; gap: 8px 12px; flex-wrap: wrap; align-items: center; margin: 8px 0 12px; }
.drum-lib-tools .btn { margin: 0; }
.drum-lib-tools input, .drum-lib-tools select { min-height: 36px; background: #0d0d0d; color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 4px 8px; font: inherit; }
.drum-lib-tools .check-row { display: inline-flex; align-items: center; gap: 6px; margin: 0; }
.drum-lib-tools .check-row input { width: auto; min-height: 0; margin: 0; transform: scale(1.2); }

/* the drum grid: press and slide paints a row; Select picks steps of a row; a triplet's three cells under a "3" */
.dg-cell { touch-action: none; }
.dg-tuplet { display: flex; gap: 2px; position: relative; min-width: 0; border-top: 2px solid var(--drum); padding-top: 2px; margin-top: -4px; }
.dg-tuplet::before { content: '3'; position: absolute; top: -9px; left: 50%; transform: translateX(-50%); font-size: .62rem; font-weight: bold; line-height: 1; color: var(--drum); background: #161320; padding: 0 2px; }
.dg-tuplet .dg-cell { flex: 1 1 0; min-width: 0; font-size: .7rem; }
.dg-cell.sel { outline: 2px solid var(--info); outline-offset: -2px; box-shadow: inset 0 0 0 40px rgba(74, 163, 223, .22); }
.de-selecting .dg-cell { cursor: cell; }
.de-select { display: flex; align-items: center; gap: 8px 12px; flex-wrap: wrap; font-size: .9rem; padding: 6px 8px; border: 1px dashed var(--info); border-radius: 6px; }
.de-select .btn { margin: 0; }
.de-select-what { color: var(--info); }
.de-select-why { color: var(--accent); font-size: .85rem; }
.de-select .de-tuplet:not([disabled]) { border-color: var(--drum); color: var(--drum); font-weight: bold; }

/* chords only, in time (melody.js renderChordsTimed): the 简谱 layout without its numbers; each note, held crotchet and rest
   keeps an empty slot, so the beats have room and the count boxes the crotchet being played */
.mel-timed .mel-notes { min-height: 0; height: 0; padding: 0; gap: .2em; }
.mel-timed .mel-slot { display: inline-block; width: 1em; height: 0; }
.mel-timed .mel-bar { padding-top: .1em; padding-bottom: .1em; }

/* the drum grid: the tools (how a press plays a step), undo / redo, Select steps */
.drum-editor-box:focus { outline: none; }
.de-tools-marks .seg { flex-wrap: wrap; }
.de-tools-marks .seg .seg-btn { min-height: 34px; }
.de-select-toggle.active { background: var(--info); color: #000; border-color: var(--info); }
.de-tools .de-undo, .de-tools .de-redo { min-width: 40px; font-size: 1.05rem; }
.de-paint-seg.de-off .seg-btn.active { background: transparent; }
.de-selecting .de-paint-seg .seg-btn { opacity: .55; }
.dg-cell.ghost { background: #4a4a4a; color: var(--fg); }
.dg-cell.art { background: #d8d8d8; color: #000; font-weight: bold; }
.dg-cell.dg-off { opacity: .35; cursor: not-allowed; }

/* ---- bar remarks (remarks.js): hold a bar or a line; pills above their bars in the role's colour ---- */
.remarks-on .song-page, .remarks-on .remark-page { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
/* the box opens under the finger still holding the bar, and iPadOS's own long press goes on there: it selected the
   box's title (the next taps only cleared that). Only the remark's text can be selected. */
dialog.modal-remark { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
dialog.modal-remark input { -webkit-touch-callout: default; -webkit-user-select: text; user-select: text; }
.remark-holding { animation: remark-hold .5s linear forwards; }
@keyframes remark-hold { from { box-shadow: inset 0 0 0 0 rgba(255, 179, 0, 0); } to { box-shadow: inset 0 -6em 0 0 rgba(255, 179, 0, .22); } }
.remark-hold { position: absolute; pointer-events: none; border-radius: 4px; z-index: 2; }
.has-remark, .has-staff-remarks { position: relative; }
/* a remark is as big as the words (the lyrics) and plain like them; the line it is on gets room above it */
.mel-line.has-remarks, .cv-line.has-remarks { margin-top: 1.65em; }
.mel-line.has-remarks-2, .cv-line.has-remarks-2 { margin-top: 3.2em; }
.bar-remark { position: absolute; top: -1.5em; left: .25em; z-index: 3; font-size: 1em; line-height: 1.3; white-space: nowrap; max-width: 24em;
  overflow: hidden; text-overflow: ellipsis; border-radius: 999px; padding: 0 .45em; border: 1px solid; font-weight: normal; pointer-events: none; }
.bar-remark + .bar-remark { top: -3em; }
.remark-layer { position: absolute; inset: 0; pointer-events: none; z-index: 3; }
.staff-remark { transform: translateY(-50%); }  /* as big as the staff's words (remarks.js placeStaff) */
.mel-staff .abcjs-annotation { opacity: 0; }  /* the room the bar remarks are laid over */
.line-remark { display: inline-block; vertical-align: baseline; margin-left: .5em; font-size: 1em; line-height: 1.3; border-radius: 999px; padding: 0 .45em;
  border: 1px solid; font-weight: normal; white-space: nowrap; max-width: 24em; overflow: hidden; text-overflow: ellipsis; }
.r-PIANIST { color: var(--accent); background: #2b2410; border-color: #6b5a1e; }
.r-DRUMMER { color: var(--drum); background: #221a33; border-color: #4a3d66; }
.r-SINGER { color: var(--info); background: #12242f; border-color: #285670; }
.bar-remark.pass, .line-remark.pass { border-style: dashed; }
.remark-who { color: var(--muted); font-size: .9rem; }
.remark-input { font-size: 1.15rem !important; width: 100%; }
.remark-picks { display: flex; flex-wrap: wrap; gap: 6px; }
.remark-picks .btn { margin: 0; }
.scope-seg { flex-wrap: wrap; }
.scope-seg .seg-btn { min-height: 40px; }
.scope-hint { font-size: .85rem; color: var(--muted); }
/* the arrangement editor: every role's bar remarks under a page */
.remarks { display: flex; flex-direction: column; gap: 6px; }
.remarks-summary { font-size: .85rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.page-row.open .remarks-summary { display: none; }
.page-row:not(.open) .remarks-open { display: none; }
.remarks-open { padding: 8px; border-radius: 8px; background: #121212; display: flex; flex-direction: column; gap: 8px; }
.remarks-label { color: var(--fg); }
.remark-chip { display: flex; flex-direction: column; align-items: stretch; gap: 3px; min-height: 64px; padding: 5px 8px; background: var(--panel); border: 1px dashed var(--border); border-radius: 8px; min-width: 0; }
.remark-chip.has { border-style: solid; }
.remark-chip.orphan { border-color: var(--bad); }
.remark-lines { display: flex; flex-direction: column; gap: 6px; }
.remark-lines .remark-chip { flex-direction: row; flex-wrap: wrap; align-items: center; min-height: 0; gap: 6px 10px; }
.remark-lines .remark-chip .dc-words { flex: 1 1 12em; }
.remark-tag { font: inherit; font-size: .78rem; font-weight: bold; border-radius: 999px; padding: 1px 8px; border: 1px solid; align-self: flex-start; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: pointer; text-align: left; }
.remark-tag.pass { border-style: dashed; }
.remark-chip .remark-add { align-self: flex-start; margin: auto 0 0; font-size: .75rem; min-height: 26px; padding: 2px 8px; }
.remark-lines .remark-chip .remark-add { margin: 0; }
.remark-roles .seg-btn[disabled] { opacity: .45; }

/* ---- /library filter card: an accordion over the songs table (library.js) ---- */
.fcard { background: var(--panel); border: 1px solid var(--border); border-radius: 12px; margin: 0 0 12px; }
.fcard-head { display: flex; align-items: center; gap: 8px 10px; flex-wrap: wrap; padding: 6px 8px 6px 4px; }
.fcard-toggle { display: inline-flex; align-items: center; gap: 8px; background: none; border: 0; color: var(--fg); font: inherit; font-weight: bold; cursor: pointer; padding: 8px 10px; min-height: 44px; border-radius: 8px; }
.fcard-toggle:hover { background: #262626; }
.fcard-chev { display: inline-block; transition: transform .15s; color: var(--muted); }
.fcard.open .fcard-chev { transform: rotate(90deg); }
.fcard-badge { background: var(--accent); color: #000; border-radius: 999px; padding: 0 8px; font-size: .8rem; line-height: 1.6; }
.fcard-badge:empty { display: none; }
.fcard-pills { display: flex; flex-wrap: wrap; gap: 6px; flex: 1 1 260px; min-width: 0; align-items: center; }
.fpill { display: inline-flex; align-items: center; gap: 4px; background: #262626; border: 1px solid var(--border); border-radius: 999px; padding: 2px 4px 2px 10px; font-size: .85rem; max-width: 100%; }
.fpill > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fpill b { color: var(--muted); font-weight: normal; }
.fpill .x { background: none; border: 0; color: var(--muted); cursor: pointer; font-size: 1rem; line-height: 1; padding: 4px 7px; border-radius: 999px; }
.fpill .x:hover { color: var(--fg); background: #3a3a3a; }
.fcard-count { color: var(--muted); font-size: .9rem; white-space: nowrap; }
.fcard-clear { background: none; border: 0; color: var(--accent); cursor: pointer; font: inherit; font-size: .9rem; padding: 6px 8px; text-decoration: underline; min-height: 36px; }
.fcard-clear[hidden], .ff-reset[hidden] { display: none; }
.fcard-body { display: none; border-top: 1px solid var(--border); padding: 14px 14px 16px; }
.fcard.open .fcard-body { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px 18px; }
.fcard-body .ff-wide { grid-column: span 2; }
.fcard-body .ff-full { grid-column: 1 / -1; }
@media (max-width: 1000px) { .fcard.open .fcard-body { grid-template-columns: repeat(2, minmax(0, 1fr)); } .fcard-body .ff-wide { grid-column: 1 / -1; } }
@media (max-width: 640px) { .fcard.open .fcard-body { grid-template-columns: minmax(0, 1fr); } .fcard-body .ff-wide, .fcard-body .ff-full { grid-column: auto; } }
.ff { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.ff-label { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: .75rem; text-transform: uppercase; letter-spacing: .05em; min-height: 28px; }
.ff-label a, .ff-reset { margin-left: auto; background: none; border: 0; color: var(--muted); cursor: pointer; font: inherit; font-size: .8rem; text-transform: none; letter-spacing: 0; text-decoration: underline; padding: 2px 4px; }
.ff-label a + .ff-reset { margin-left: 4px; }
.ff-label a:hover, .ff-reset:hover { color: var(--accent); }
.ff-note { color: var(--muted); font-size: .8rem; margin: 0; }

/* select2-style picker (ui.picker) */
.ms { position: relative; }
.ms-box { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; min-height: 44px; padding: 5px 34px 5px 8px; background: #0d0d0d; border: 1px solid var(--border); border-radius: 8px; cursor: text; position: relative; }
.ms.open .ms-box, .ms-box:focus-within { border-color: var(--info); }
.ms-box::after { content: '\25BE'; position: absolute; right: 12px; top: 50%; transform: translateY(-50%); color: var(--muted); pointer-events: none; }
.ms-input { flex: 1 1 80px; min-width: 60px; background: none; border: 0; color: var(--fg); font: inherit; font-size: 1rem; padding: 4px 2px; outline: none; min-height: 0; }
.ms-input:focus-visible { outline: none; }
.ms-input-hidden { position: absolute; opacity: 0; width: 1px; min-width: 0; pointer-events: none; }
.ms-input::placeholder { color: #6d6d6d; }
.ms-chip { display: inline-flex; align-items: center; gap: 2px; border-radius: 999px; padding: 1px 2px 1px 10px; font-size: .85rem; font-weight: 600; border: 1px solid rgba(255,255,255,.18); max-width: 100%; }
.ms-chip.plain { background: #2b2b2b; color: var(--fg); font-weight: normal; }
.ms-chip > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ms-remove { background: none; border: 0; color: inherit; opacity: .7; cursor: pointer; font-size: 1rem; line-height: 1; padding: 2px 7px; border-radius: 999px; }
.ms-remove:hover { opacity: 1; background: rgba(0,0,0,.2); }
.ms-drop { position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 30; background: var(--panel); border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 8px 28px rgba(0,0,0,.6); max-height: 300px; overflow-y: auto; padding: 4px; display: none; }
.ms.open .ms-drop { display: block; }
.ms-opt { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-radius: 6px; cursor: pointer; min-height: 40px; }
.ms-opt.hl { background: #2d2d2d; }
.ms-opt.on .ms-check { visibility: visible; }
.ms-opt.zero { opacity: .45; }
.ms-check { visibility: hidden; color: var(--accent); width: 1em; flex: none; }
.ms-opt-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ms-opt-sub { color: var(--muted); font-size: .8rem; margin-left: 6px; }
.ms-count { color: var(--muted); font-size: .8rem; flex: none; }
.ms-empty { color: var(--muted); padding: 10px; font-size: .9rem; }

/* two-choice toggles under a picker */
.seg2 { display: inline-flex; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; align-self: flex-start; }
.seg2 button { background: none; border: 0; color: var(--muted); font: inherit; font-size: .85rem; padding: 6px 12px; cursor: pointer; min-height: 34px; }
.seg2 button + button { border-left: 1px solid var(--border); }
.seg2 button[aria-pressed="true"] { background: #26230f; color: var(--accent); }
.seg2[aria-disabled="true"] { opacity: .45; pointer-events: none; }

/* key buttons */
.key-chips { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 6px; }
@media (max-width: 760px) { .key-chips { grid-template-columns: repeat(6, minmax(0, 1fr)); } }
.key-chip { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; min-height: 48px; background: #0d0d0d; border: 1px solid var(--border); border-radius: 8px; color: var(--fg); font: inherit; font-weight: bold; cursor: pointer; padding: 4px 0; }
.key-chip small { color: var(--muted); font-weight: normal; font-size: .7rem; }
.key-chip:hover { border-color: #555; }
.key-chip[aria-pressed="true"] { border-color: var(--accent); background: #26230f; color: var(--accent); }
.key-chip[aria-pressed="true"] small { color: var(--accent); }
.key-chip.zero { opacity: .35; }

/* two-handled range (ui.dualRange) */
.range { display: flex; flex-direction: column; gap: 8px; }
.range-read { display: flex; justify-content: space-between; align-items: baseline; }
.range-read b { font-size: 1.05rem; }
.range-read .muted { font-size: .8rem; }
.dual { position: relative; height: 30px; }
.dual .track, .dual .fill { position: absolute; top: 13px; height: 4px; border-radius: 2px; }
.dual .track { left: 0; right: 0; background: #3a3a3a; }
.dual .fill { background: var(--accent); }
.dual input[type=range] { position: absolute; left: 0; width: 100%; top: 4px; margin: 0; padding: 0; height: 22px; min-height: 0; border: 0; background: none; pointer-events: none; -webkit-appearance: none; appearance: none; }
.dual input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; pointer-events: auto; width: 24px; height: 24px; border-radius: 50%; background: var(--fg); border: 3px solid var(--accent); cursor: pointer; }
.dual input[type=range]::-moz-range-thumb { pointer-events: auto; width: 20px; height: 20px; border-radius: 50%; background: var(--fg); border: 3px solid var(--accent); cursor: pointer; }
.dual input[type=range]::-webkit-slider-runnable-track { background: none; }
.presets { display: flex; flex-wrap: wrap; gap: 6px; }
.preset { background: #0d0d0d; border: 1px solid var(--border); color: var(--fg); border-radius: 999px; padding: 4px 12px; font: inherit; font-size: .85rem; cursor: pointer; min-height: 32px; }
.preset[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); background: #26230f; }

/* ---- pianist iPad ✎ Chords (pianist_chords.js): every chord dashed and tapped, the chord panel in columns ---- */
.chord-edit-hint { margin: 4px 0 8px; color: var(--accent); font-size: .95rem; }
#btn-edit-chords.active { border-color: var(--accent); color: #000; background: var(--accent); }
.pc-chip { display: inline-block; padding: 0 .18em; margin-left: -.18em; border-radius: 6px; outline: 1.5px dashed rgba(255, 179, 0, .6); outline-offset: 1px; cursor: pointer; }
.song-page.current .pc-chip { outline-color: rgba(255, 179, 0, .9); }
.pc-chip.pc-pending { outline: 2px solid var(--info); color: #8fd0ff; background: #102331; animation: pc-pulse 1.2s ease-in-out infinite; }
.pc-chip.pc-gone { color: var(--muted); text-decoration: line-through; }
@keyframes pc-pulse { 50% { box-shadow: 0 0 0 5px rgba(74, 163, 223, .25); } }
.pc-ch { cursor: pointer; border-radius: 3px; position: relative; }
.pc-ch:hover { background: rgba(255, 179, 0, .16); }
.pc-ch:hover::before { content: '+'; position: absolute; left: 0; top: -1.15em; font-size: .7em; font-weight: bold; color: var(--accent); }
.mel-bar.pc-bar { position: relative; }
.mel-chord .pc-chip { position: relative; z-index: 2; }
.pc-page .jp-note { cursor: pointer; }
.pc-page .jp-note:hover { background: rgba(255, 179, 0, .14); border-radius: 4px; }
.pc-beat { position: absolute; z-index: 1; display: flex; align-items: center; justify-content: center; box-sizing: border-box; border: 1.5px dashed rgba(255, 179, 0, .35);
  border-radius: 6px; color: rgba(255, 179, 0, .6); font-size: .6em; font-weight: bold; cursor: pointer; }
.pc-beat:hover { background: rgba(255, 179, 0, .14); }
.pc-beat.pc-pending { border: 2px solid var(--info); color: #8fd0ff; background: #102331; animation: pc-pulse 1.2s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .pc-chip.pc-pending, .pc-beat.pc-pending { animation: none; } }

/* the panel: the editor's dock, its columns one list down each (Starts on | the key's chords | Add | Bass); a sheet up
   from the bottom of an iPad or a phone (body.chord-panel-sheet: a touch screen or under 900 px) with the columns side
   by side, at the right of a laptop with the song beside it (body.chord-panel-docked) */
:root { --chord-panel-w: 380px; --chord-sheet-h: 0px; }
.chord-panel { position: fixed; top: 0; right: 0; bottom: 0; width: var(--chord-panel-w); z-index: 60; background: var(--panel); border-left: 3px solid var(--info);
  box-shadow: -10px 0 30px rgba(0, 0, 0, .5); padding: 12px 14px 14px; display: none; flex-direction: column; gap: 10px; overflow-y: auto; box-sizing: border-box;
  touch-action: none; user-select: none; -webkit-user-select: none; }
.chord-panel.on { display: flex; animation: pc-in .15s ease-out; }
@keyframes pc-in { from { transform: translateX(24px); opacity: 0; } }
body.chord-panel-docked main.page-pianist { padding-right: calc(var(--chord-panel-w) + 16px); }  /* the song moves over: nothing under the panel */
body.chord-panel-docked .perf-nav { right: var(--chord-panel-w); }
body.chord-panel-docked .toasts { left: calc((100% - var(--chord-panel-w)) / 2); }
body.chord-panel-sheet .pianist-content { padding-bottom: var(--chord-sheet-h); }
body.chord-panel-sheet .toasts { bottom: calc(20px + var(--chord-sheet-h)); }
.pc-where { color: var(--muted); font-size: .9rem; }
.pc-readout { font-size: 1.5rem; font-weight: bold; line-height: 1.2; }
.pc-readout s { color: var(--muted); font-weight: normal; }
.pc-readout b { color: #8fd0ff; }
.pc-error { color: var(--bad); font-size: .85rem; }
.chord-panel .pc-cols { display: flex; flex-wrap: nowrap; align-items: flex-start; justify-content: space-between; gap: 0; }
.pc-col { display: flex; flex-direction: column; gap: 6px; width: 80px; min-width: 0; }
.pc-col.pc-col-bass { width: 62px; }
.pc-col.pc-col-at { width: 52px; }
.pc-rule { align-self: stretch; width: 1px; background: var(--border); }
.pc-col-name { font-size: .8rem; color: var(--muted); margin: 0 0 1px 2px; white-space: nowrap; }
.pc-col .chord-btn { margin: 0; min-height: 46px; padding: 4px 6px; font-size: 1.1rem; font-weight: bold; touch-action: none; cursor: grab; }
.pc-col .chord-btn.picked { border-color: var(--info); color: #8fd0ff; background: #102331; }
.pc-col .cx-mod { min-height: 46px; margin: 0; }
.pc-col .cx-mod .cx-name { font-size: 1rem; }
.pc-col .pc-and { min-height: 34px; }
.pc-col .pc-and .cx-name { color: var(--muted); }
.pc-col .pc-and.picked .cx-name { color: var(--ok); }
.chord-panel .cx-hint { display: block; font-size: .8rem; line-height: 1.35; }
.pc-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: auto; }
.pc-actions .btn { margin: 0; min-height: 48px; }
.pc-actions .pc-nc.picked { border-color: var(--info); color: #8fd0ff; background: #102331; }
.pc-actions .btn-danger.active { background: rgba(231, 76, 60, .18); }
body.chord-panel-sheet .chord-panel { top: auto; left: 0; width: auto; max-height: 64vh; border-left: 0; border-top: 3px solid var(--info); border-radius: 14px 14px 0 0;
  box-shadow: 0 -10px 30px rgba(0, 0, 0, .6); padding-bottom: calc(14px + env(safe-area-inset-bottom)); }
body.chord-panel-sheet .chord-panel.on { animation-name: pc-up; }
@keyframes pc-up { from { transform: translateY(48px); opacity: 0; } }
body.chord-panel-sheet .chord-panel .pc-cols { justify-content: flex-start; gap: 0 4px; }
body.chord-panel-sheet .pc-col, body.chord-panel-sheet .pc-col.pc-col-bass, body.chord-panel-sheet .pc-col.pc-col-at { width: auto; flex: 1 1 0; }
body.chord-panel-sheet .pc-col.pc-col-at { flex: .7 1 0; }
/* the buttons first, in reach, and kept in sight when the sheet scrolls */
body.chord-panel-sheet .pc-actions { grid-template-columns: repeat(4, 1fr); order: -1; margin: -12px -14px 0; padding: 10px 14px 8px; position: sticky; top: -12px; z-index: 3; background: var(--panel); }
@media (min-width: 960px) {
  /* an iPad on its side: what is changing at the left, the columns in the middle, the buttons at the right, so the
     sheet is no taller than its longest column and the song keeps the top half of the screen */
  body.chord-panel-sheet .chord-panel.on { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); grid-template-rows: auto auto auto 1fr; gap: 6px 32px; align-items: start; }
  body.chord-panel-sheet .chord-panel > * { grid-column: 1; }
  body.chord-panel-sheet .pc-where { grid-row: 1; }
  body.chord-panel-sheet .pc-readout { grid-row: 2; }
  body.chord-panel-sheet .pc-error { grid-row: 3; }
  body.chord-panel-sheet .chord-panel .cx-hint { grid-row: 4; align-self: end; max-width: 300px; }
  body.chord-panel-sheet .chord-panel .pc-cols { grid-column: 2; grid-row: 1 / -1; gap: 0 18px; }
  body.chord-panel-sheet .pc-col, body.chord-panel-sheet .pc-col.pc-col-bass, body.chord-panel-sheet .pc-col.pc-col-at { flex: none; width: 92px; gap: 5px; }
  body.chord-panel-sheet .pc-col.pc-col-bass { width: 72px; }
  body.chord-panel-sheet .pc-col.pc-col-at { width: 60px; }
  body.chord-panel-sheet .pc-col .chord-btn, body.chord-panel-sheet .pc-col .cx-mod { min-height: 40px; }
  body.chord-panel-sheet .pc-col .pc-and { min-height: 32px; }
  body.chord-panel-sheet .pc-actions { grid-column: 3; grid-row: 1 / -1; align-self: end; justify-self: end; width: 100%; max-width: 300px; grid-template-columns: 1fr 1fr;
    order: 0; margin: 0; padding: 0; top: auto; bottom: 0; }
}

/* ---- pianist: piano bars (pianobars.js, pianist_piano.js): a bar of notes above the chords of a bar, and the ✎ Piano sheet ---- */
:root { --piano: #4fd1c5; --piano-sheet-h: 0px; }
.page-pianist #btn-edit-piano.active { background: var(--piano); color: #000; border-color: var(--piano); }
.piano-edit-hint { margin: 4px 0 8px; color: var(--piano); font-size: .95rem; }
.page-pianist.piano-editing .pianist-content .song-page { cursor: default; }
/* the card above its bar (.mel-bar) or its chord (.cp-pair): the host grows at the top, the chords and words stay put */
.pb-host { position: relative; }
.pb-card { position: absolute; left: 0; top: 0; z-index: 2; box-sizing: border-box; width: 100%; min-width: 7em; color: var(--fg); background: #0f1e1c; border: 1px solid #27514c;
  border-radius: 6px; padding: .12em .45em .2em .4em; font-size: .62em; line-height: 1.15; white-space: nowrap; text-align: left; font-weight: normal; }  /* as wide as its bar: its time at the bar's pace */
.pb-card .pb-label { color: var(--piano); font-size: .78em; line-height: 1.2; margin-bottom: .05em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pb-card .pb-empty { color: var(--muted); font-size: .9em; padding: .4em 0; }
.pb-draw { color: var(--fg); }
.pb-draw .mel-page { position: relative; }
.pb-draw .mel-chord, .pb-draw .mel-lyric { display: none; }
.pb-draw .mel-line { margin: 0; line-height: 1.2; }
.pb-draw .mel-bar { display: block; border-right: 0; margin-bottom: 0; padding: 0; }
.pb-draw .mel-run { display: flex; width: 100%; align-items: flex-end; }  /* the notes spread over the bar by their lengths (drawBar sets each column's share); columns level at the bottom, as the page's */
.pb-draw .mel-seg { min-width: max-content; padding-right: .3em; }
.pb-draw .mel-notes { min-height: 2.3em; padding-top: .15em; }
.pb-draw .staff-run { margin: 0; overflow: visible; }
.pb-draw-staff { overflow: hidden; width: 100%; }  /* the run inside is wider by the clef, key and time signature cut off at its left (trimStaff) */
.pb-card.pb-pending { border: 2px solid var(--info); background: #102331; animation: pb-pulse 1.2s ease-in-out infinite; }
@keyframes pb-pulse { 50% { box-shadow: 0 0 0 5px rgba(74, 163, 223, .25); } }
@media (prefers-reduced-motion: reduce) { .pb-card.pb-pending { animation: none; } }
/* ✎ Piano on: every bar (every chord) takes a tap; the ones without a piano bar say so */
.pb-plus { position: absolute; left: 0; top: 0; z-index: 1; box-sizing: border-box; font-size: .5em; line-height: 1.5; color: var(--piano); opacity: .75; border: 1.5px dashed rgba(79, 209, 197, .55);
  border-radius: 6px; padding: 0 .6em; white-space: nowrap; cursor: pointer; font-weight: normal; }
.piano-editing .pb-host, .piano-editing .pb-card { cursor: pointer; }
.piano-editing .pb-host:hover > .pb-plus, .piano-editing .pb-plus:hover { background: rgba(79, 209, 197, .14); opacity: 1; }
.piano-editing .pb-card:not(.pb-pending) { border-style: dashed; }
.piano-editing .pb-card:not(.pb-pending):hover { border-color: var(--piano); background: #122a27; }
/* 五线谱: the cards and the + boxes lie over the engraving, each above its measure, in the room the page was engraved with */
.pb-layer { position: absolute; left: 0; top: 0; right: 0; bottom: 0; pointer-events: none; }
.pb-layer > * { pointer-events: auto; }
.pb-layer .pb-card, .pb-layer .pb-plus { min-width: 0; }
.pb-card .mel-chord[data-bar-no]::before, .pb-card .mel-bar.bar-no-notes::before { display: none; }  /* no bar numbers inside a card */

/* the editor's input (PianoBars.Editor): what is being written (.pb-info: the two previews one under the other, the
   typed line, the meter) and the keys (.pb-input: the tools in one row of small groups, the keyboard under them) */
.pb-editor { display: contents; }
.pb-info { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.pb-info .pc-where { font-size: .9rem; display: flex; flex-wrap: wrap; gap: 2px 8px; align-items: center; }
.pb-where .pb-editing { color: #8fd0ff; }
.pb-where .btn { margin: 0; min-height: 30px; padding: 2px 8px; font-size: .8rem; }
.pb-label-row { display: flex; gap: 8px; align-items: center; }
.pb-label-row span { color: var(--muted); font-size: .85rem; white-space: nowrap; }
.pb-label-row input { flex: 1 1 auto; min-width: 0; background: #0d0d0d; color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 4px 8px; font: inherit; font-size: .95rem; min-height: 36px; }
.pb-preview { min-width: 0; background: #0d0d0d; border: 1px dashed var(--border); border-radius: 6px; padding: 4px 8px; overflow-x: auto; overflow-y: hidden; }
.pb-preview .subtle { display: block; font-size: .72rem; margin-bottom: 2px; }
.pb-preview .pb-draw { font-size: 1.25rem; }
.pb-preview .pb-draw .mel-notes { min-height: 2.4em; }
.pb-preview .pb-draw-staff { overflow: visible; }
.pb-preview .pb-empty { color: var(--muted); font-size: .9rem; padding: 10px 0; }
/* a note tapped is the one the keys change: blue in the previews, the typed line and the card on the page */
.pb-preview .jp-note, .pb-card.pb-pending .jp-note { cursor: pointer; border-radius: 4px; }
.pb-preview .jp-note:hover { background: rgba(74, 163, 223, .15); }
.jp-note.pb-sel { background: rgba(74, 163, 223, .28); outline: 2px solid var(--info); outline-offset: 1px; }
.pb-card .jp-note.pb-sel { outline-width: 1.5px; }
.pb-preview .abcjs-note, .pb-preview .abcjs-rest { cursor: pointer; }
.abcjs-note.pb-sel path, .abcjs-rest.pb-sel path { fill: var(--info); }
.pb-text { display: flex; gap: 8px; align-items: center; font-size: .9rem; }
.pb-text code { flex: 1 1 auto; min-width: 0; overflow-x: auto; white-space: nowrap; background: #0d0d0d; border-radius: 6px; padding: 5px 8px; color: var(--fg); }
.pb-text code .pb-cursor { color: var(--info); }
.pb-text code .pb-tok { padding: 0 1px; border-radius: 3px; }
.pb-text code .pb-tok.pb-sel { background: rgba(74, 163, 223, .28); outline: 1px solid var(--info); }
.pb-text .btn { margin: 0; }
.pb-text input { flex: 1 1 auto; min-width: 0; font-family: ui-monospace, Consolas, monospace; background: #0d0d0d; color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 4px 8px; min-height: 36px; }
.pb-meter { display: flex; align-items: center; gap: 8px; font-size: .82rem; color: var(--muted); }
.pb-meter-cells { display: flex; gap: 2px; flex: 0 0 auto; width: 160px; height: 10px; }
.pb-meter-cells span { flex: 1 1 0; background: #2a2a2a; border-radius: 2px; position: relative; overflow: hidden; }
.pb-meter-cells span i { position: absolute; left: 0; top: 0; bottom: 0; background: var(--piano); }
.pb-meter.full { color: var(--ok); }
.pb-meter.over { color: var(--bad); }
.pb-error { color: var(--bad); font-size: .85rem; }
.pb-input { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.pb-tools { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: flex-end; }
.pb-group { display: flex; flex-direction: column; gap: 3px; }
.pb-group-name { font-size: .72rem; color: var(--muted); margin-left: 2px; white-space: nowrap; }
.pb-group-btns { display: flex; gap: 3px; }
.pb-group .btn { margin: 0; min-height: 44px; min-width: 44px; padding: 2px 3px; font-size: 1rem; line-height: 1.05; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0; touch-action: manipulation; }
.pb-group .btn small { font-size: .6rem; color: var(--muted); font-weight: normal; }
.pb-group .btn .sym { font-size: 1.2rem; line-height: 1; }
.pb-group .btn.picked { border-color: var(--info); color: #8fd0ff; background: #102331; }  /* picked: a look of its own, not btn-primary (Save's) */
.pb-group .btn.picked small { color: #8fd0ff; }
.pb-group .btn[disabled] { opacity: .35; }
.pb-keysbox { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.pb-keysbox .pb-col-name { display: flex; gap: 10px; align-items: center; font-size: .78rem; color: var(--muted); }
.pb-keysbox .seg .seg-btn { min-height: 26px; padding: 0 8px; font-size: .78rem; margin: 0; }
.pb-keys { position: relative; height: 120px; display: flex; gap: 2px; }
.pb-key { position: relative; border: 1px solid #333; border-radius: 0 0 6px 6px; font: inherit; cursor: pointer; display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
  padding-bottom: 6px; gap: 2px; -webkit-tap-highlight-color: transparent; touch-action: manipulation; user-select: none; -webkit-user-select: none; }
.pb-key.pb-white { flex: 1 1 0; background: #f1f1f1; color: #222; min-width: 0; }
.pb-key.pb-white:active { background: #cfe9e6; }
.pb-key.pb-black { position: absolute; top: 0; width: 6.2%; height: 62%; background: #1a1a1a; color: #eee; border-color: #000; z-index: 2; }
.pb-key.pb-black:active { background: #2f4d49; }
.pb-key .pb-key-deg { font-weight: bold; font-size: 1.15rem; line-height: 1.1; display: flex; flex-direction: column; align-items: center; }
.pb-key .pb-key-deg .pb-dots { font-size: .55rem; line-height: .6; height: .5rem; }
.pb-key .pb-key-name { font-size: .68rem; opacity: .7; }
.pb-key.pb-black .pb-key-deg { font-size: .9rem; }
.pb-key.pb-out .pb-key-deg { font-weight: normal; opacity: .6; }
.pb-key.pb-root { box-shadow: inset 0 0 0 3px var(--piano); }
.pb-key.pb-black.pb-root { box-shadow: inset 0 0 0 2px var(--piano); }
.pb-nums { display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px; height: 120px; }
.pb-nums .btn { margin: 0; min-height: 0; font-size: 1.3rem; font-weight: bold; padding: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; touch-action: manipulation; }
.pb-nums .btn .pb-dots { font-size: .6rem; line-height: .6; height: .5rem; }
.pb-nums .btn.pb-mod { font-size: 1rem; font-weight: normal; }
.pb-nums .btn.picked { border-color: var(--info); color: #8fd0ff; background: #102331; }
.pb-keys-hint { font-size: .78rem; color: var(--muted); line-height: 1.3; }
/* the buttons: one row */
.pb-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.pb-actions .btn { margin: 0; min-height: 42px; }
.pb-actions select { min-height: 42px; background: #0d0d0d; color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 4px 8px; font: inherit; font-size: .95rem; }
.pb-actions .pb-actions-gap { flex: 1 1 auto; }

/* the pianist iPad's sheet: up from the bottom, the buttons in one row on top (in sight while it scrolls), then what is
   written at the left and the keys at the right (one under the other on a narrow screen) */
.piano-sheet { position: fixed; left: 0; right: 0; bottom: 0; z-index: 60; display: none; flex-direction: column; gap: 8px; box-sizing: border-box; max-height: 76vh; overflow-y: auto; background: var(--panel);
  border-top: 3px solid var(--info); border-radius: 14px 14px 0 0; box-shadow: 0 -10px 30px rgba(0, 0, 0, .6); padding: 10px 16px calc(14px + env(safe-area-inset-bottom)); user-select: none; -webkit-user-select: none; }
.piano-sheet input { user-select: text; -webkit-user-select: text; }
.piano-sheet.on { display: flex; animation: pb-up .15s ease-out; }
@keyframes pb-up { from { transform: translateY(48px); opacity: 0; } }
.piano-sheet .pb-actions { position: sticky; top: -10px; z-index: 3; background: var(--panel); margin: -10px -16px 0; padding: 10px 16px 6px; }
.piano-sheet .pb-body { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px 22px; align-items: start; }
@media (min-width: 900px) { .piano-sheet .pb-body { grid-template-columns: minmax(300px, 400px) minmax(0, 1fr); } }
body.piano-sheet-on .pianist-content { padding-bottom: var(--piano-sheet-h); }
body.piano-sheet-on .toasts { bottom: calc(20px + var(--piano-sheet-h)); }

/* the arrangement editor: a page's piano bars, a chip per bar (or per chord), the open one edited below (library_editor.js) */
.pianos { display: flex; flex-direction: column; gap: 6px; }
.piano-line { display: grid; grid-template-columns: repeat(var(--n, 4), minmax(0, 1fr)); gap: 6px; }
.piano-summary { font-size: .85rem; color: var(--piano); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.page-row.open .piano-summary { display: none; }
.page-row:not(.open) .piano-open { display: none; }
.piano-open { padding: 8px; border-radius: 8px; background: #121212; display: flex; flex-direction: column; gap: 8px; }
.piano-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: .85rem; color: var(--muted); }
.piano-head .piano-label { color: var(--piano); }
.piano-chip { display: flex; flex-direction: column; align-items: stretch; gap: 2px; text-align: left; min-height: 64px; padding: 5px 8px; background: var(--panel); color: var(--fg); border: 1px dashed var(--border); border-radius: 8px; font: inherit; cursor: pointer; min-width: 0; }
.piano-chip:hover { border-color: var(--piano); }
.piano-chip.has { border-style: solid; border-color: #2d5f59; }
.piano-chip.sel { border: 2px solid var(--piano); background: #10211f; }
.piano-chip.orphan { border-color: var(--bad); }
.piano-chip .dc-add, .piano-chip .dc-label { color: var(--piano); }
.piano-chip .dc-thumb { color: var(--fg); overflow: hidden; font-size: 1.1rem; line-height: 1.2; }
.piano-chip .dc-thumb .pb-draw .mel-notes { min-height: 2.1em; }
.piano-panel { border: 1px solid #2d5f59; border-radius: 8px; padding: 8px 10px; background: #0f1a19; display: flex; flex-direction: column; gap: 10px; }
.piano-panel-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.piano-panel-head strong { color: var(--piano); }
.piano-panel-head .btn { margin: 0; }
.piano-panel-head .spacer { margin-left: auto; }
.piano-panel select { background: #0d0d0d; color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 4px 8px; font: inherit; font-size: .9rem; min-height: 36px; }
.piano-panel .pb-editor { display: grid; grid-template-columns: minmax(280px, 400px) minmax(0, 1fr); gap: 10px 20px; align-items: start; }
@media (max-width: 1100px) { .piano-panel .pb-editor { grid-template-columns: minmax(0, 1fr); } }
.sec-sum-piano { color: var(--piano); font-size: .8rem; }

/* ---- guitarist and bassist iPads (strings.js, guitar.js) ---- */
:root { --strings: #f0a35e; }
.icon-guitar, .icon-bass { margin-right: 4px; }
.page-strings .pianist-content { font-size: 1.5rem; }
.page-strings #btn-capo.active, .page-strings #btn-numbers.active { background: var(--strings); color: #000; border-color: var(--strings); }
.page-strings #btn-numbers { min-width: 3.4em; font-variant-numeric: tabular-nums; }
/* a chord as "big, small": the guitarist's shape with the chord heard beside it; the bassist's note with its chord above */
.ch-sub { font-size: .6em; font-weight: normal; color: var(--muted); margin-left: .3em; }
.ch-tap { cursor: pointer; }
.view-bass .cv-chords { height: 2.5em; }
.view-bass .cv-chord { display: flex; flex-direction: column-reverse; align-items: flex-start; top: 0; font-size: 1.45em; line-height: 1.05; }
.view-bass .cp-chord { display: flex; flex-direction: column-reverse; align-items: flex-start; font-size: 1.25em; line-height: 1.05; }
.view-bass .ch-sub { font-size: .45em; margin: 0; }
/* chord boxes: each shape of a section once, above it; a tapped chord's box big in a dialog */
.chord-boxes { display: flex; flex-wrap: wrap; gap: .2em .5em; margin: .1em 0 .4em; }
.chord-box { display: flex; flex-direction: column; align-items: center; cursor: pointer; }
.chord-box-name { font-size: .55em; font-weight: bold; color: var(--accent); line-height: 1.2; }
.chord-box-bass { font-size: .42em; color: var(--muted); }
.chord-boxes .chord-box-svg { width: 2.6em; height: auto; }
.chord-box-big { display: flex; flex-direction: column; align-items: center; }
.chord-box-big .chord-box { cursor: default; font-size: 2.4rem; }
.chord-box-big .chord-box-svg { width: 200px; height: auto; }
.chord-box-svg .cb-string, .chord-box-svg .cb-fret { stroke: #8a8a8a; stroke-width: 1; }
.chord-box-svg .cb-nut { stroke: var(--fg); stroke-width: 3; }
.chord-box-svg .cb-dot, .chord-box-svg .cb-barre { fill: var(--fg); }
.chord-box-svg .cb-open { fill: none; stroke: var(--fg); stroke-width: 1; }
.chord-box-svg .cb-mute { fill: var(--fg); font-family: sans-serif; }
.chord-box-svg .cb-base { fill: var(--muted); font-family: sans-serif; }

/* ---- sign in, the home page's who-bar, the admin page (auth.py, /admin) ---- */
.page-login { display: flex; align-items: center; justify-content: center; min-height: 100vh; box-sizing: border-box; }
.login-card { background: var(--panel); border: 1px solid var(--border); border-radius: 12px; padding: 24px; width: min(420px, 100%); display: flex; flex-direction: column; gap: 12px; }
.login-card h1 { margin: 0; font-size: 1.4rem; }
.login-card p { margin: 0; }
.login-error { color: var(--bad); font-weight: bold; }
.login-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.inline-form { display: inline; margin: 0; }
.who-bar { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; color: var(--muted); margin: 0 0 10px; }
.who-bar .btn { margin: 0; }
.password-form { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; background: var(--panel); border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; margin: 0 0 12px; }
.password-form .btn { margin: 0; }
.page-admin .panel h2 { margin: 0 0 6px; font-size: 1.15rem; }
.admin-row { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; margin-top: 8px; }
.admin-row .btn { margin: 0; }
.admin-row .check-row { margin: 0; }
.users-table tr.disabled td { opacity: .55; }
.users-table .row-actions { display: flex; gap: 4px; flex-wrap: wrap; }
.users-table .row-actions .btn { margin: 0; }
.users-table td.bad, .restore-summary .bad { color: var(--bad); }
.restore-summary { background: #111; border: 1px solid var(--border); border-radius: 10px; padding: 8px 12px; margin-top: 8px; }
.restore-summary p { margin: 4px 0; }
.backups { margin-top: 10px; }
.backups li { margin: 6px 0; }
.backups .btn { margin: 0 0 0 6px; }
