/* Chant Sight-Singing Trainer — minimal, desktop + tablet */

*,
*::before,
*::after {
  box-sizing: border-box;
}

/* Author display: rules must not un-hide [hidden] (e.g. .btn { display: flex }) */
[hidden] {
  display: none !important;
}

:root {
  --bg: #1a1b1e;
  --surface: #25262b;
  --border: #3a3b40;
  --text: #e8e8ea;
  /* Blue-tinted neutrals borrowed from the “How to use” card, so chrome text
     reads as one family instead of flat gray. */
  --muted: #a8b4cc;
  --label: #d7e5ff; /* control labels */
  --label-hi: #eef2ff; /* hover / emphasis */
  --accent: #4c8bf5;
  --accent-soft: rgba(76, 139, 245, 0.2);
  --danger: #e05a5a;
  --ok: #3db87a;
  --toolbar-h: auto;
  /* Height of the bottom page bar, excluding the iOS safe-area inset.
     Anything docking above the bar (see .diag-ui) measures from this. */
  --page-bar-h: 4rem;
  --radius: 8px;
  --font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

html,
body {
  margin: 0;
  height: 100%;
  font-family: var(--font);
  color: var(--text);
  background: var(--bg);
  -webkit-tap-highlight-color: transparent;
}

body {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
  overflow: hidden;
}

/* —— Toolbar —— */
.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.1rem;
  padding: 0.75rem 1rem;
  /**
   * Reads as a raised plane rather than a flat block: a barely-there vertical
   * gradient, a 1px top highlight catching "light" from above, a darker seam
   * where it meets the score, and a soft cast shadow onto the page below.
   */
  background: linear-gradient(180deg, #2b2c33 0%, #25262b 62%, #232429 100%);
  border-bottom: 1px solid #15161a;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.055),
    0 3px 10px -2px rgba(0, 0, 0, 0.42);
  flex-shrink: 0;
  z-index: 20; /* above stage so Diagnose dropdown overlays the PDF */
  user-select: none;
  overflow: visible;
}

.toolbar-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.5rem;
}

/**
 * Group separators: a hairline that fades out at both ends rather than a hard
 * rule butting into the bar edges. Absolutely positioned so it stays out of
 * flex flow and can't affect the toolbar fit measurement.
 */
.toolbar-group + .toolbar-group {
  position: relative;
  padding-left: 0.9rem;
  margin-left: 0.15rem;
  border-left: none;
}

.toolbar-group + .toolbar-group::before {
  content: "";
  position: absolute;
  left: 0;
  top: 8%;
  bottom: 8%;
  width: 1px;
  background: linear-gradient(
    to bottom,
    transparent,
    var(--border) 22%,
    var(--border) 78%,
    transparent
  );
  pointer-events: none;
}

/* Pin Play Music to the far right of the toolbar (desktop bar) */
.toolbar-play-music {
  margin-left: auto;
  border-left: none !important;
  padding-left: 0 !important;
}

/* —— Upload / Settings label (responsive text in one button) —— */
/* Desktop & wide: always “Upload & Settings” */
.us-label-full {
  display: inline;
}
.us-label-upload,
.us-label-settings {
  display: none;
}

/* Drop-hint mirrors the toolbar label */
.hint-us-full {
  display: inline;
}
.hint-us-upload,
.hint-us-settings {
  display: none;
}

/**
 * Inside Upload & Settings: sound/mic/save/load stay grayed until a PDF is
 * loaded so users focus on Upload PDF first.
 */
.upload-save-after-pdf {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
}

.upload-save-after-pdf.is-awaiting-pdf {
  opacity: 0.42;
  filter: grayscale(0.55);
  cursor: not-allowed;
  user-select: none;
}

.upload-save-after-pdf.is-awaiting-pdf .btn,
.upload-save-after-pdf.is-awaiting-pdf .file-btn,
.upload-save-after-pdf.is-awaiting-pdf .switch,
.upload-save-after-pdf.is-awaiting-pdf input {
  pointer-events: none;
  cursor: not-allowed;
}

.upload-first-hint {
  margin: 0.15rem 0 0.25rem;
}

body.has-pdf .upload-first-hint {
  display: none;
}

/**
 * Tools wrapper: on desktop the toggle is hidden and the panel is an
 * inline flex row of Match / Transpose / Tempo / Assess / Play.
 * On phone the toggle is shown and the panel becomes a dropdown.
 */
.tools-menu {
  position: relative;
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  min-width: 0;
  gap: 0.75rem 1.1rem;
}

/* Hidden unless body.compact-toolbar — never show Tools on a full-width bar */
.tools-toggle {
  display: none !important;
}

.tools-panel {
  display: flex;
  flex: 1 1 auto;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.1rem;
  min-width: 0;
  /* Not a floating panel on desktop */
  position: static;
  padding: 0;
  margin: 0;
  border: none;
  background: transparent;
  box-shadow: none;
}

.btn,
.file-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  min-height: 3.4rem;
  padding: 0.6rem 1.2rem;
  font: inherit;
  font-size: 1.35rem;
  font-weight: 600;
  color: var(--label);
  background: var(--bg);
  /* Default: light-gray outline (~30% darker than previous #9a9ba5) */
  border: 1.5px solid #6c6d76;
  border-radius: var(--radius);
  cursor: pointer;
  white-space: nowrap;
  touch-action: manipulation;
}

.btn:hover,
.file-btn:hover {
  border-color: #85868f;
  background: #2c2d32;
  color: var(--label-hi);
}

.btn:active,
.file-btn:active {
  transform: translateY(1px);
}

.btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/**
 * Pre-score preview: controls stay visible but grayed and inert until a PDF
 * has notes ready. Used on Match Pitch, Transpose, Tempo, Assess, Play All.
 */
.btn.is-awaiting-score:disabled,
.btn.is-awaiting-score[disabled] {
  opacity: 0.42;
  filter: grayscale(0.55);
  cursor: not-allowed;
  pointer-events: none;
}

.tempo-controls.is-awaiting-score,
.transpose-controls-bar.is-awaiting-score {
  opacity: 0.42;
  filter: grayscale(0.55);
  cursor: not-allowed;
  user-select: none;
}

.tempo-controls.is-awaiting-score input,
.transpose-controls-bar.is-awaiting-score input,
.tempo-controls.is-awaiting-score label,
.transpose-controls-bar.is-awaiting-score label,
.transpose-controls-bar.is-awaiting-score .transpose-menu-toggle {
  pointer-events: none;
  cursor: not-allowed;
}

/* Score menu: file picker styled like a full-width menu button */
.file-btn-block {
  display: flex;
  width: 100%;
  box-sizing: border-box;
  min-height: 2.6rem;
  padding: 0.45rem 0.75rem;
  font-size: 1rem;
  text-align: center;
}

.score-menu .play-menu-panel {
  min-width: 15rem;
}

.btn[aria-pressed="true"],
.btn.is-on {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: #c5d8ff;
}

#mic-btn.is-on {
  background: rgba(61, 184, 122, 0.18);
  border-color: var(--ok);
  color: #9ee0bc;
}

/* —— Live pitch debug (pitch.js) —— */
.pitch-readout {
  display: inline-flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.3rem;
  min-width: 9rem;
  padding: 0.4rem 0.7rem;
  background: #121316;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.pitch-readout.has-pitch {
  border-color: #3a6a4a;
}

.pitch-note {
  font-size: 1.3rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-align: center;
  color: var(--muted);
  line-height: 1.2;
  white-space: nowrap;
}

.pitch-readout.has-pitch .pitch-note {
  color: #9ee0bc;
}

.pitch-bar {
  position: relative;
  height: 12px;
  border-radius: 6px;
  background: linear-gradient(
    90deg,
    rgba(224, 90, 90, 0.45) 0%,
    rgba(61, 184, 122, 0.35) 45%,
    rgba(61, 184, 122, 0.35) 55%,
    rgba(224, 90, 90, 0.45) 100%
  );
  overflow: hidden;
}

.pitch-bar-center {
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  width: 1px;
  background: rgba(255, 255, 255, 0.55);
  transform: translateX(-50%);
}

.pitch-needle {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 5px;
  margin-left: -2.5px;
  left: 50%;
  background: #fff;
  border-radius: 1px;
  box-shadow: 0 0 4px rgba(0, 0, 0, 0.5);
  transition: left 40ms linear;
}

.mic-error {
  flex-shrink: 0;
  padding: 0.6rem 1rem;
  font-size: 1.1rem;
  color: #ffc9c9;
  background: rgba(224, 90, 90, 0.18);
  border-bottom: 1px solid rgba(224, 90, 90, 0.45);
}

/* —— Primary highlight (blue): Upload first; Match Pitch after score loads —— */
.btn-primary,
.file-btn.btn-primary {
  background: var(--accent-soft);
  border-color: var(--accent);
  border-width: 1.5px;
  color: #d7e5ff;
}

.btn-primary {
  min-width: 7rem;
}

.btn-primary:hover,
.file-btn.btn-primary:hover {
  background: rgba(76, 139, 245, 0.3);
  border-color: var(--accent);
  color: #eef4ff;
}

/**
 * After score is ready:
 * Assess — soft light-yellow outline + matching label color
 * Play Music — solid medium/dark gray (low-emphasis secondary control)
 */
#diag-btn.btn-assess-ready:not(.is-on):not([aria-pressed="true"]) {
  border-color: rgba(250, 235, 160, 0.9);
  border-width: 1.5px;
  background: rgba(250, 235, 160, 0.06);
  /* Same light yellow as the border */
  color: rgba(250, 235, 160, 0.95);
}

#diag-btn.btn-assess-ready:not(.is-on):not([aria-pressed="true"]):hover {
  border-color: rgba(255, 245, 190, 0.98);
  background: rgba(250, 235, 160, 0.12);
  color: rgba(255, 245, 190, 0.98);
}

/* Play Music — subdued solid gray (not green, not primary) */
#play-btn.btn-play-music:not(.is-playing) {
  border: 1.5px solid #4a4b52;
  background: #3a3b42;
  color: #c4c5cc;
}

#play-btn.btn-play-music:not(.is-playing) .play-icon {
  color: #c4c5cc;
}

#play-btn.btn-play-music:not(.is-playing):hover {
  border-color: #5c5d66;
  background: #45464e;
  color: #d8d9e0;
}

/* Active run / mode (Match On / Pause) — red, not blue */
#begin-btn.is-playing,
#match-pitch-btn.is-playing,
#play-btn.is-playing {
  background: rgba(224, 90, 90, 0.2);
  border-color: var(--danger);
  border-width: 1.5px;
  color: #ffc9c9;
}

/* —— Score / Sound menus (dropdown) —— */
.play-menu {
  position: relative;
  display: inline-flex;
  flex-direction: column;
  align-items: stretch;
}

.play-menu-toggle .caret {
  font-size: 0.85em;
  opacity: 0.85;
  margin-left: 0.15rem;
}

.play-menu-toggle.is-open {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.play-menu-panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 30;
  min-width: 16rem;
  padding: 0.75rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
}

.play-menu-panel .btn-block {
  width: 100%;
}

/* —— Play Music (far right) —— */
.play-controls {
  position: relative;
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem 0.65rem;
}

/* —— Assess menu (Assess selection + Find your range) —— */
.assess-menu {
  position: relative;
  display: inline-flex;
  flex-direction: column;
  align-items: stretch;
}

.assess-menu-panel {
  min-width: 12.5rem;
}

.assess-menu-panel .btn-block {
  width: 100%;
  justify-content: flex-start;
  text-align: left;
}

/* Range actions inside Transpose ▾ menu */
.range-chip-item {
  display: inline-block;
  padding: 0.35rem 0.6rem;
  font: inherit;
  font-size: 0.82rem;
  font-weight: 700;
  text-align: center;
  color: var(--text);
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 6px;
  cursor: pointer;
}

.range-chip-item:hover {
  background: rgba(76, 139, 245, 0.18);
  border-color: rgba(120, 150, 200, 0.45);
}

/* Measured range block inside Transpose ▾ panel */
.range-in-tip {
  margin: 0.45rem 0 0;
  padding: 0.5rem 0 0;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
}

.range-in-tip[hidden] {
  display: none !important;
}

.range-in-tip-title {
  margin: 0 0 0.25rem;
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #a8b4cc;
}

.range-in-tip-summary {
  margin: 0 0 0.4rem;
  font-size: 0.88rem;
  font-weight: 700;
  line-height: 1.35;
  color: var(--text);
}

.range-in-tip-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}

/* Transpose ▾ dropdown */
.transpose-menu {
  position: relative;
  flex: 0 0 auto;
}

.transpose-menu-toggle {
  min-width: 0;
  min-height: 2.1rem;
  padding: 0.25rem 0.55rem;
  font-size: 0.92rem;
  font-weight: 650;
  white-space: nowrap;
}

.transpose-menu-toggle.has-range {
  border-color: #4c8bf5;
  box-shadow: 0 0 0 1px rgba(76, 139, 245, 0.35);
}

.transpose-menu-panel {
  left: 0;
  right: auto;
  min-width: 12.5rem;
  max-width: min(18rem, 90vw);
  padding: 0.4rem;
  z-index: 60;
}

.transpose-menu-panel .btn-block {
  width: 100%;
  justify-content: flex-start;
  text-align: left;
  font-size: 0.9rem;
}

/* Match Pitch active = Stop (same idea as Play is-playing) */
#match-pitch-btn.is-on,
#match-pitch-btn.is-playing,
#match-pitch-btn[aria-pressed="true"] {
  background: rgba(224, 90, 90, 0.2);
  border-color: rgba(240, 120, 120, 0.85);
  color: #ffd0d0;
  font-weight: 750;
}

.range-in-tip-hr {
  margin: 0.55rem 0 0;
  border: none;
  border-top: 1px solid rgba(180, 130, 40, 0.35);
}

/* Subtle cue that a measured range is stored (still open tip for details) */
.info-eye.has-range {
  border-color: #4c8bf5;
  background: rgba(76, 139, 245, 0.18);
  box-shadow: 0 0 0 2px rgba(76, 139, 245, 0.25);
}

.info-eye.has-range .info-eye-glyph {
  color: #e8f0ff;
}

/* Find your range: centered full-screen shell; large HBD card stays put */
.range-overlay {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.25rem 1.25rem 1.5rem;
  background: rgba(10, 12, 16, 0.62);
  box-sizing: border-box;
  pointer-events: auto;
}

.range-overlay[hidden] {
  display: none !important;
}

.range-overlay-panel {
  max-width: min(40rem, 100%);
  text-align: center;
}

/* One large stage for intro → 3-2-1 → listening (never shrinks) */
.range-session-stage {
  width: min(44rem, 96vw);
  max-height: min(92vh, 52rem);
  display: flex;
  flex-direction: column;
  align-items: stretch;
}

.range-session-stage[hidden] {
  display: none !important;
}

/* Always-large lyrics card — stays sizeable through countdown + listening */
.range-piece-sheet {
  position: relative;
  text-align: left;
  flex: 1 1 auto;
  min-height: min(62vh, 28rem);
  padding: 1.45rem 1.6rem 1.25rem;
  background: rgba(248, 248, 250, 0.98);
  border: 1.5px solid #6c6d76;
  border-radius: 14px;
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.55);
  color: #1a1b1e;
  box-sizing: border-box;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  transition: box-shadow 160ms ease, border-color 160ms ease;
}

.range-piece-sheet.is-clickable {
  cursor: pointer;
  border-color: #4c8bf5;
  box-shadow:
    0 18px 48px rgba(0, 0, 0, 0.55),
    0 0 0 3px rgba(76, 139, 245, 0.35);
}

.range-piece-sheet.is-clickable:hover {
  box-shadow:
    0 20px 52px rgba(0, 0, 0, 0.58),
    0 0 0 4px rgba(76, 139, 245, 0.5);
}

.range-piece-sheet.is-listening {
  border-color: #3db87a;
  box-shadow:
    0 18px 48px rgba(0, 0, 0, 0.55),
    0 0 0 3px rgba(61, 184, 122, 0.3);
}

/* Bold 3-2-1 flashing over the Happy Birthday card itself */
.range-sheet-countdown {
  position: absolute;
  inset: 0;
  z-index: 6;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  font-size: clamp(5.5rem, 22vmin, 13rem);
  font-weight: 900;
  line-height: 1;
  letter-spacing: -0.04em;
  color: rgba(28, 78, 200, 0.92);
  text-shadow:
    0 2px 0 rgba(255, 255, 255, 0.95),
    0 8px 28px rgba(0, 0, 0, 0.35),
    0 0 48px rgba(76, 139, 245, 0.45);
  background: rgba(248, 248, 250, 0.28);
  border-radius: 14px;
}

.range-sheet-countdown[hidden] {
  display: none !important;
}

.range-sheet-countdown.is-tick {
  animation: range-countdown-pop 280ms ease-out;
}

@keyframes range-countdown-pop {
  from {
    transform: scale(1.4);
    opacity: 0.2;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}

.range-piece-title {
  margin: 0 0 0.35rem;
  font-size: clamp(1.45rem, 3.4vw, 1.85rem);
  font-weight: 800;
  color: #121316;
  text-align: center;
  flex: 0 0 auto;
}

.range-piece-lyrics {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  flex: 1 1 auto;
  font-size: clamp(1.15rem, 2.8vw, 1.45rem);
  font-weight: 650;
  line-height: 1.5;
  letter-spacing: 0.01em;
}

.range-piece-line {
  margin: 0;
  padding: 0.45rem 0.65rem;
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.045);
}

.range-piece-line .range-friend {
  color: #1a4a9a;
  font-weight: 800;
  text-decoration: underline;
  text-underline-offset: 0.12em;
}

.range-piece-friend-note {
  margin: 0.35rem 0 0;
  font-size: 0.98rem;
  font-weight: 600;
  line-height: 1.35;
  color: #3a3b42;
  text-align: center;
  flex: 0 0 auto;
}

.range-sheet-prompt {
  margin: 0.35rem 0 0;
  padding: 0.65rem 0.75rem;
  font-size: clamp(1rem, 2.2vw, 1.15rem);
  font-weight: 700;
  line-height: 1.4;
  text-align: center;
  color: #1a2a4a;
  background: rgba(76, 139, 245, 0.12);
  border-radius: 8px;
  flex: 0 0 auto;
}

.range-sheet-prompt[hidden] {
  display: none !important;
}

.range-sheet-listen-bar {
  margin: 0.4rem 0 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.75rem 1rem;
  flex: 0 0 auto;
}

.range-sheet-listen-bar[hidden] {
  display: none !important;
}

.range-listening-label {
  margin: 0;
  font-size: 1.15rem;
  font-weight: 700;
  color: #1a5a3a;
}

/* Stop on the light Happy Birthday card — solid dark fill, pure white label */
#range-stop-btn.btn,
#range-stop-btn.btn-primary {
  min-width: 6.5rem;
  min-height: 2.6rem;
  padding: 0.45rem 1.15rem;
  font-size: 1.1rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  color: #ffffff;
  background: #163a7a;
  border: 2px solid #0d2858;
  box-shadow: 0 2px 0 rgba(0, 0, 0, 0.18);
}

#range-stop-btn.btn:hover,
#range-stop-btn.btn-primary:hover {
  color: #ffffff;
  background: #1f4d9e;
  border-color: #0d2858;
}

.range-overlay-card {
  padding: 1.25rem 1.4rem;
  background: var(--surface);
  border: 1.5px solid #6c6d76;
  border-radius: 12px;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.5);
  color: var(--text);
  text-align: left;
  max-width: min(28rem, 100%);
}

.range-overlay-card p {
  margin: 0 0 0.75rem;
  font-size: 1.05rem;
  line-height: 1.45;
}

.range-overlay-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem;
  justify-content: flex-end;
  margin-top: 0.85rem;
}

.range-results-body p {
  margin: 0 0 0.65rem;
}

/* Multi-voice / chord page notice (near Play All) */
.harmony-hint {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  left: auto;
  z-index: 45;
  max-width: min(22rem, 92vw);
  padding: 0.55rem 0.75rem;
  font-size: 0.88rem;
  font-weight: 600;
  line-height: 1.35;
  color: #1a1408;
  background: rgba(250, 220, 120, 0.97);
  border: 1px solid rgba(180, 130, 40, 0.55);
  border-radius: 8px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.35);
  white-space: normal;
  pointer-events: none;
}

.harmony-hint[hidden] {
  display: none !important;
}

body.compact-toolbar .harmony-hint {
  right: auto;
  left: 0;
  max-width: min(18rem, 88vw);
}

.play-controls .play-icon,
.play-controls .pause-icon {
  font-size: 0.85em;
  line-height: 1;
  opacity: 0.95;
}

/* Filename at top of Upload & Settings (not clickable) */
.file-status-in-menu {
  display: block;
  margin: 0 0 0.45rem;
  padding: 0.4rem 0.55rem;
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--text);
  background: rgba(0, 0, 0, 0.2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  pointer-events: none;
  user-select: text;
  max-width: 100%;
  box-sizing: border-box;
}

/* Tempo / Transpose on the main toolbar bar */
.tempo-controls,
.tempo-controls-block {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  min-width: 11rem;
  max-width: 15rem;
  min-height: 3.4rem;
  padding: 0.35rem 0.6rem;
  border: 1.5px solid #6c6d76;
  border-radius: var(--radius);
  background: rgba(0, 0, 0, 0.15);
  box-sizing: border-box;
}

/**
 * Transpose: menu ▾ · track (no numeric readout — value on title / aria).
 * Track: four equal half-octave bands (−18…−12 | −12…−6 | −6…0 | 0…+6);
 * default 0 sits at 75%.
 */
.tempo-controls.transpose-controls-bar {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 0.4rem;
  flex: 0 0 auto;
  box-sizing: border-box;
  width: 18.5rem;
  min-width: 16.5rem;
  max-width: 20rem;
  padding: 0.35rem 0.55rem 0.5rem;
  overflow: visible;
}

.tempo-controls.transpose-controls-bar .transpose-menu {
  flex: 0 0 auto;
}

.tempo-controls.transpose-controls-bar .transpose-slider-wrap {
  flex: 1 1 auto;
  min-width: 0;
  width: auto;
}

/* Circled i + hover tip for Transpose help */
.info-eye {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.45rem;
  height: 1.45rem;
  flex-shrink: 0;
  border: 1.5px solid #8a8b95;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.06);
  cursor: help;
  outline: none;
}

.info-eye-glyph {
  font-size: 0.9rem;
  font-weight: 800;
  font-style: italic;
  font-family: Georgia, "Times New Roman", serif;
  line-height: 1;
  color: #d7d8de;
  opacity: 0.95;
}

.info-eye-tip {
  display: none;
  position: absolute;
  left: 0;
  top: calc(100% + 10px);
  z-index: 80;
  width: min(22rem, 78vw);
  min-height: 3rem;
  padding: 0.65rem 0.75rem;
  font-size: 0.88rem;
  font-weight: 600;
  line-height: 1.4;
  color: #1a1408;
  background: rgba(255, 248, 220, 0.99);
  border: 1px solid rgba(180, 130, 40, 0.55);
  border-radius: 8px;
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.4);
  text-align: left;
  white-space: normal;
  /* none by default; enabled when open so Re-measure / Clear work */
  pointer-events: none;
  box-sizing: border-box;
}

.info-eye-tip strong {
  color: #3a2a08;
}

.info-eye:hover .info-eye-tip,
.info-eye:focus .info-eye-tip,
.info-eye:focus-visible .info-eye-tip,
.info-eye:focus-within .info-eye-tip {
  display: block;
  pointer-events: auto;
}

/* Long track: ticks inset to match range thumb travel (half of 18px thumb) */
.transpose-slider-wrap {
  position: relative;
  min-width: 0;
  padding: 0 0 0.65rem;
  box-sizing: border-box;
}

.transpose-slider-wrap input[type="range"] {
  display: block;
  width: 100%;
  min-width: 0;
  margin: 0;
  height: 1.65rem;
}

.transpose-ticks {
  position: absolute;
  /* Align with browser range thumb centers (≈ half thumb width) */
  left: 9px;
  right: 9px;
  top: 1.4rem;
  height: 0.55rem;
  pointer-events: none;
}

.transpose-ticks .tick {
  position: absolute;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* Major: full-octave marks (−1 oct at left, written pitch at 2/3) */
.transpose-ticks .tick-octave i {
  display: block;
  width: 2.5px;
  height: 9px;
  background: #f0f1f5;
  border-radius: 1px;
}

/* Minor: half-octave marks (shorter) */
.transpose-ticks .tick-half i {
  display: block;
  width: 1.5px;
  height: 5px;
  margin-top: 2px;
  background: #9a9ba5;
  border-radius: 1px;
}

.tempo-controls .tempo-label,
.tempo-label {
  flex: 0 0 auto;
  font-size: 1.35rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text);
}

.tempo-controls input[type="range"] {
  flex: 1;
  min-width: 5.5rem;
  width: 100%;
  height: 1.65rem;
  accent-color: var(--accent, #4c8bf5);
  cursor: pointer;
}

.transpose-slider-wrap input[type="range"] {
  flex: none;
  min-width: 0;
  width: 100%;
  height: 1.65rem;
  accent-color: var(--accent, #4c8bf5);
  cursor: pointer;
}

/* Fatter track (WebKit / Firefox) */
.tempo-controls input[type="range"]::-webkit-slider-runnable-track,
.transpose-slider-wrap input[type="range"]::-webkit-slider-runnable-track {
  height: 10px;
  border-radius: 5px;
  background: #4a4b52;
}
.tempo-controls input[type="range"]::-webkit-slider-thumb,
.transpose-slider-wrap input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 18px;
  height: 18px;
  margin-top: -4px;
  border-radius: 50%;
  background: #8ab0f0;
  border: 1.5px solid #c5d8ff;
  cursor: pointer;
}
.tempo-controls input[type="range"]::-moz-range-track,
.transpose-slider-wrap input[type="range"]::-moz-range-track {
  height: 10px;
  border-radius: 5px;
  background: #4a4b52;
}
.tempo-controls input[type="range"]::-moz-range-thumb,
.transpose-slider-wrap input[type="range"]::-moz-range-thumb {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #8ab0f0;
  border: 1.5px solid #c5d8ff;
  cursor: pointer;
}

.tempo-controls .tempo-val,
.tempo-val {
  flex: 0 0 2.25rem;
  text-align: right;
  font-size: 1rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

/* Green “ready” status at the bottom of Upload & Settings menu */
.score-ready-box {
  margin-top: 0.35rem;
  padding: 0.55rem 0.7rem;
  font-size: 0.95rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1.3;
  text-align: center;
  color: #b6f0d0;
  background: rgba(61, 184, 122, 0.22);
  border: 1.5px solid rgba(61, 184, 122, 0.5);
  border-radius: var(--radius);
  text-shadow: 0 0 8px rgba(61, 184, 122, 0.25);
}

.upload-save-menu .play-menu-panel {
  min-width: 17rem;
}

.menu-section-title {
  font-size: 0.85rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0.15rem 0 0.1rem;
}

.sound-mic-section {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.45rem 0.5rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.03);
}

.sound-mic-section.is-mic-on {
  border-color: rgba(61, 184, 122, 0.55);
  background: rgba(61, 184, 122, 0.08);
}

.file-status {
  font-size: 1.1rem;
  color: var(--text);
  max-width: 16rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
}

/* Legacy class names used in Score/Sound menus */
.tempo-row {
  display: flex;
  width: 100%;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.tempo-row label {
  flex: 0 0 auto;
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--text);
}

.tempo-row input[type="range"] {
  flex: 1;
  min-width: 5.5rem;
  accent-color: var(--accent, #3db87a);
}

.tempo-val {
  flex: 0 0 2.25rem;
  text-align: right;
  font-size: 0.9rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

.play-menu-hint {
  margin: 0;
  font-size: 0.8rem;
  color: var(--muted);
  line-height: 1.35;
}

/* Sound status panel still floats under Upload & Settings */

/* Match Turn Sound On button scale: same min-height / font weight */
.mic-switch-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.85rem;
  min-height: 2.4rem;
  padding: 0.35rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.04);
  box-sizing: border-box;
}

.mic-switch-text {
  display: flex;
  flex-direction: row;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.35rem 0.55rem;
  min-width: 0;
}

.mic-switch-title {
  font-size: 1rem;
  font-weight: 800;
  color: var(--text);
  line-height: 1.2;
}

.mic-switch-state {
  font-size: 1rem;
  color: var(--muted);
  font-weight: 800;
  line-height: 1.2;
}

.mic-switch-state.is-on {
  color: #9ee0bc;
}

/* On/off switch — sized with the row / Turn Sound On button */
.switch {
  position: relative;
  display: inline-block;
  width: 3.6rem;
  height: 2rem;
  flex-shrink: 0;
  cursor: pointer;
}

.switch input {
  opacity: 0;
  width: 0;
  height: 0;
  position: absolute;
}

.switch-slider {
  position: absolute;
  inset: 0;
  background: #3a3f4a;
  border: 1px solid var(--border);
  border-radius: 999px;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.switch-slider::before {
  content: "";
  position: absolute;
  width: 1.5rem;
  height: 1.5rem;
  left: 0.22rem;
  top: 50%;
  transform: translateY(-50%);
  background: #e8ecf2;
  border-radius: 50%;
  transition: transform 0.15s ease;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}

.switch input:checked + .switch-slider {
  background: #1f6b4a;
  border-color: #3db87a;
}

.switch input:checked + .switch-slider::before {
  transform: translate(1.45rem, -50%);
}

.switch input:focus-visible + .switch-slider {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.visually-hidden {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/* Turn Sound On — same visual weight as Microphone row */
.btn-sound {
  background: #1f6b4a;
  border-color: #3db87a;
  color: #e8fff3;
  font-weight: 800;
  font-size: 1rem;
  min-height: 2.4rem;
  padding: 0.35rem 0.9rem;
  box-shadow: 0 0 0 1px rgba(61, 184, 122, 0.35);
}

.btn-sound:hover {
  background: #268a5c;
  border-color: #6dca9a;
  color: #fff;
}

.btn-sound.is-ok {
  background: rgba(60, 140, 100, 0.45);
  border-color: #6dca9a;
  color: #d8ffe8;
}

.btn-sound.is-fail {
  background: rgba(160, 50, 50, 0.45);
  border-color: rgba(240, 100, 100, 0.75);
  color: #ffe0e0;
  animation: sound-pulse 1.2s ease-in-out infinite;
}

@keyframes sound-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(240, 100, 100, 0.35); }
  50% { box-shadow: 0 0 0 4px rgba(240, 100, 100, 0.15); }
}

/* Sound message: floats under Sound & Mic toggle (like Diagnose box), not full-width */
.sound-mic-menu {
  position: relative;
}

.sound-status-panel {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 42;
  margin-top: 0;
  width: max(17rem, 100%);
  min-width: 16rem;
  max-width: min(22rem, 90vw);
  padding: 0.75rem 2rem 0.75rem 0.85rem;
  border: 1px solid rgba(200, 80, 80, 0.55);
  border-radius: 0 0 10px 10px;
  background: rgba(180, 50, 50, 0.97);
  color: #fff0f0;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.35);
  font-size: 1.05rem;
  font-weight: 600;
  line-height: 1.4;
  text-align: left;
  pointer-events: auto;
}

.sound-status-panel.is-ok {
  background: rgba(40, 110, 75, 0.97);
  border-color: rgba(80, 180, 120, 0.55);
  color: #e8fff3;
}

.sound-status-panel.is-neutral {
  background: rgba(45, 50, 60, 0.97);
  border-color: rgba(120, 130, 150, 0.45);
  color: #e8ecf2;
}

.sound-status-panel[hidden] {
  display: none !important;
}

.sound-status-panel .diag-collapse {
  border-color: rgba(255, 255, 255, 0.35);
  background: rgba(255, 255, 255, 0.2);
  color: #fff;
}

.sound-status-panel .diag-collapse:hover {
  background: rgba(255, 255, 255, 0.35);
}

.sound-status-body {
  margin: 0;
  max-width: none;
}

.hint {
  font-size: 0.95rem;
  color: var(--muted);
  max-width: 8rem;
  line-height: 1.2;
}

/* —— Bottom bar: help + processing status + page nav —— */
.page-bar {
  flex-shrink: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 0.75rem 1.1rem;
  /* Extra side inset so Prev/Next don’t sit flush on phone screen edges */
  padding: 0.55rem max(1.25rem, calc(12px + env(safe-area-inset-right, 0px)))
    0.55rem max(1.25rem, calc(12px + env(safe-area-inset-left, 0px)));
  /* Mirror of the toolbar, lit from above: highlight on the top edge, the
     gradient running the other way, shadow cast upward onto the score. */
  background: linear-gradient(180deg, #282930 0%, #25262b 45%, #212228 100%);
  border-top: 1px solid #15161a;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.05),
    0 -3px 10px -2px rgba(0, 0, 0, 0.4);
  user-select: none;
  min-height: var(--page-bar-h);
}

.help-btn {
  flex: 0 0 auto;
  /* Slightly tight box around “?” so page nav can sit inset without crowding */
  width: 3.15rem;
  min-width: 3.15rem;
  min-height: 3.15rem;
  padding: 0;
  font-size: 1.35rem;
  font-weight: 800;
  border: 1.5px solid #6c6d76;
  background: var(--bg);
  color: var(--label);
  box-sizing: border-box;
}

.help-btn:hover {
  border-color: #85868f;
  background: #2c2d32;
  color: var(--label-hi);
}

/* First-load How to use — larger, front-and-center */
.howto-modal {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.25rem;
  background: rgba(8, 10, 14, 0.72);
  box-sizing: border-box;
}

.howto-modal[hidden] {
  display: none !important;
}

.howto-modal-card {
  position: relative;
  width: min(40rem, 96vw);
  max-height: min(88vh, 44rem);
  overflow: auto;
  padding: 1.5rem 1.65rem 1.4rem;
  background: var(--surface);
  /* Quiet gray edge (same family as help modal / other cards — not blue) */
  border: 1.5px solid #6c6d76;
  border-radius: 14px;
  box-shadow: 0 20px 56px rgba(0, 0, 0, 0.55);
  color: var(--text);
}

.howto-app-name {
  margin: 0 2.25rem 0.25rem 0;
  font-size: clamp(1.65rem, 4vw, 2.1rem);
  font-weight: 800;
  letter-spacing: 0.01em;
  line-height: 1.15;
  color: #eef2ff;
}

.howto-app-sub {
  margin: 0 2.25rem 1rem 0;
  font-size: clamp(0.98rem, 2.2vw, 1.12rem);
  font-weight: 600;
  line-height: 1.35;
  color: #a8b4cc;
}

/* Screen-size advisory — deliberately unbolded so it reads as a note, not a
   warning competing with the title. */
.howto-app-note {
  margin: 0 2.25rem 1rem 0;
  font-size: clamp(0.92rem, 2vw, 1rem);
  font-weight: 400;
  line-height: 1.4;
  color: var(--muted);
}

.howto-modal-card h2.howto-section-title,
.howto-section-title {
  margin: 0 2.25rem 0.85rem 0;
  font-size: clamp(1.2rem, 2.8vw, 1.45rem);
  font-weight: 800;
  color: #d7e5ff;
}

.howto-body {
  font-size: clamp(1.02rem, 2.2vw, 1.12rem);
  line-height: 1.5;
}

.howto-list {
  margin: 0 0 1rem;
  padding-left: 1.35rem;
}

.howto-list li {
  margin: 0 0 0.7rem;
}

.howto-list li:last-child {
  margin-bottom: 0;
}

.howto-list strong {
  color: #d7e5ff;
}

/* Inline Liturgical Calendar control inside How to use — same blue as main lit-cal-btn */
.howto-inline-btn.lit-cal-btn {
  display: inline-flex;
  align-items: center;
  vertical-align: baseline;
  margin: 0 0.1rem;
  min-height: 0;
  min-width: 0;
  padding: 0.12rem 0.5rem;
  font-size: inherit;
  font-weight: 650;
  line-height: 1.3;
  white-space: nowrap;
  /* Match .lit-cal-btn blue (explicit so generic .btn doesn’t win) */
  border: 1.5px solid #6a7a9a;
  border-radius: var(--radius, 8px);
  color: #c8d4ee;
  background: rgba(76, 139, 245, 0.12);
  cursor: pointer;
}

.howto-inline-btn.lit-cal-btn:hover {
  border-color: #8aa0c8;
  background: rgba(76, 139, 245, 0.22);
  color: #e8eefc;
}

.howto-inline-btn.lit-cal-btn:focus-visible {
  outline: 2px solid #4c8bf5;
  outline-offset: 2px;
}

.howto-foot {
  margin: 1rem 0 0;
  padding-top: 0.75rem;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--muted, #9a9ba5);
}

/* Mini “?” box matching the footer Help button look */
.howto-help-glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.35rem;
  height: 1.35rem;
  margin: 0 0.12rem;
  padding: 0;
  font-size: 0.95rem;
  font-weight: 800;
  line-height: 1;
  vertical-align: -0.15em;
  color: var(--text);
  background: var(--bg, #1a1b1e);
  border: 1.5px solid #6c6d76;
  border-radius: var(--radius, 8px);
  box-sizing: border-box;
}

/* Help modal overlay */
.help-modal {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.25rem;
  background: rgba(0, 0, 0, 0.55);
  box-sizing: border-box;
}

.help-modal[hidden] {
  display: none !important;
}

.help-modal-card {
  position: relative;
  width: min(36rem, 100%);
  max-height: min(80vh, 40rem);
  overflow: auto;
  padding: 1.15rem 1.35rem 1.25rem;
  background: var(--surface);
  border: 1.5px solid #6c6d76;
  border-radius: 12px;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.5);
  color: var(--text);
}

.help-modal-card h2 {
  margin: 0 2rem 0.75rem 0;
  font-size: 1.35rem;
  font-weight: 800;
}

.help-body {
  font-size: 1rem;
  line-height: 1.45;
}

.help-body p {
  margin: 0 0 0.75rem;
}

/* Liturgical calendar button (welcome + Upload & Settings) */
.lit-cal-btn {
  font-size: 1.05rem;
  font-weight: 650;
  border-color: #6a7a9a;
  color: #c8d4ee;
  background: rgba(76, 139, 245, 0.12);
}

.lit-cal-btn:hover {
  border-color: #8aa0c8;
  background: rgba(76, 139, 245, 0.22);
  color: #e8eefc;
}

.lit-cal-btn-welcome {
  pointer-events: auto;
  margin-top: 1.15rem;
  min-height: 2.75rem;
  padding: 0.5rem 0.9rem;
  font-size: clamp(0.95rem, 1.8vw, 1.1rem);
  white-space: normal;
  text-align: center;
  line-height: 1.3;
  max-width: 100%;
}

/* Liturgical calendar modal (live MCI sidebar) */
.lit-cal-modal {
  position: fixed;
  inset: 0;
  z-index: 110;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.25rem;
  background: rgba(0, 0, 0, 0.55);
  box-sizing: border-box;
}

.lit-cal-modal[hidden] {
  display: none !important;
}

.lit-cal-modal-card {
  position: relative;
  width: min(34rem, 100%);
  max-height: min(82vh, 42rem);
  overflow: auto;
  padding: 1.15rem 1.35rem 1.25rem;
  background: var(--surface);
  border: 1.5px solid #6c6d76;
  border-radius: 12px;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.5);
  color: var(--text);
}

.lit-cal-modal-card h2 {
  margin: 0 2rem 0.55rem 0;
  font-size: 1.3rem;
  font-weight: 800;
}

.lit-cal-source {
  margin: 0 0 0.75rem;
  font-size: 0.92rem;
  line-height: 1.4;
  color: var(--muted);
}

.lit-cal-source a {
  color: #8ab0f0;
}

.lit-cal-status {
  margin: 0.5rem 0;
  font-size: 1rem;
  color: var(--muted);
}

.lit-cal-status.is-error {
  color: #e8a0a0;
}

.lit-cal-body {
  display: flex;
  flex-direction: column;
  gap: 1.15rem;
}

.lit-cal-section-title {
  margin: 0 0 0.45rem;
  font-size: 1.1rem;
  font-weight: 800;
  color: var(--text);
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.3rem;
}

.lit-cal-entry {
  margin: 0 0 0.55rem;
  font-size: 0.98rem;
  line-height: 1.4;
  color: var(--muted);
}

.lit-cal-entry strong {
  color: var(--text);
  font-weight: 700;
}

.lit-cal-entry a {
  color: #8ab0f0;
  text-decoration: underline;
  text-underline-offset: 0.12em;
  word-break: break-word;
}

.lit-cal-entry a:hover {
  color: #b0c8f8;
}

.lit-cal-more {
  margin: 0.35rem 0 0;
  font-size: 0.95rem;
}

.lit-cal-more a {
  color: #8ab0f0;
}

.help-body p:last-child {
  margin-bottom: 0;
}

.help-body strong {
  color: #d7e5ff;
}

.help-section-heading {
  margin: 1rem 0 0.45rem;
  font-size: 1.1rem;
  font-weight: 800;
  color: #d7e5ff;
}

.help-credits-heading {
  margin: 1.15rem 0 0.45rem;
  font-size: 1.15rem;
  font-weight: 800;
  color: var(--text);
}

.help-credits {
  margin: 0;
  padding-top: 0.15rem;
  color: var(--muted);
  font-size: 0.98rem;
}

.help-credits strong {
  color: #d7e5ff;
}

/* Yellow while extracting (ready status moved into Upload & Settings menu) */
.page-bar .extract-banner {
  flex: 1 1 auto;
  min-width: 0;
  max-width: min(52%, 28rem);
  margin: 0;
  padding: 0.55rem 0.95rem;
  font-size: 1.15rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-align: left;
  text-transform: uppercase;
  line-height: 1.25;
  border: 1.5px solid rgba(230, 190, 70, 0.55);
  border-radius: var(--radius);
  color: #1a1408;
  background: rgba(240, 200, 70, 0.92);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem 0.65rem;
  box-sizing: border-box;
}

.page-bar .extract-banner .extract-banner-text {
  flex: 1 1 auto;
  min-width: 0;
}

.page-bar .extract-banner.is-mixed-case {
  text-transform: none;
  letter-spacing: 0.01em;
  font-size: 0.95rem;
  font-weight: 700;
  line-height: 1.35;
}

.page-bar .extract-banner.is-error {
  color: #ffc9c9;
  background: rgba(224, 90, 90, 0.18);
  border-color: rgba(224, 90, 90, 0.4);
  letter-spacing: 0.03em;
  font-size: 1rem;
}

.page-bar .extract-banner.is-warn {
  color: #1a1408;
  background: rgba(240, 180, 60, 0.9);
  border-color: rgba(200, 140, 30, 0.55);
  letter-spacing: 0.02em;
  font-size: 0.95rem;
  font-weight: 700;
  text-transform: none;
}

.extract-diag-copy-btn {
  flex: 0 0 auto;
  margin: 0;
  padding: 0.3rem 0.55rem;
  font: inherit;
  font-size: 0.82rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  text-transform: none;
  color: #1a1408;
  background: rgba(255, 255, 255, 0.88);
  border: 1.5px solid rgba(80, 55, 10, 0.4);
  border-radius: 6px;
  cursor: pointer;
  white-space: nowrap;
}

.extract-diag-copy-btn:hover {
  background: #fff;
  border-color: rgba(80, 55, 10, 0.65);
}

.extract-banner.is-error .extract-diag-copy-btn {
  color: #1a1408;
  background: rgba(255, 240, 240, 0.95);
  border-color: rgba(180, 80, 80, 0.55);
}

.extract-diag-copy-btn[hidden] {
  display: none !important;
}

/* Page controls: Prev / page number / Next — same enlarged size */
.page-bar-controls {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin-left: auto;
  /* Small nudge inward from the screen edge (~10–14px + safe area) */
  margin-right: max(10px, 0.65rem);
}

/* Phone / narrow: Next inset from bezel; keep air between Help and page nav */
@media (max-width: 720px) {
  :root {
    --page-bar-h: 3.4rem;
  }
  /**
   * Phone: the bar is only as tall as its controls, and the home indicator
   * strip is paid for exactly once via env() rather than being padded around.
   * Previously the bar kept its 4rem desktop height AND sat under the
   * indicator, so it cost ~34px of screen and still crowded the buttons.
   */
  .page-bar {
    gap: 0.45rem 0.55rem;
    min-height: var(--page-bar-h);
    padding-top: 0.3rem;
    padding-bottom: calc(0.3rem + env(safe-area-inset-bottom, 0px));
    padding-left: max(0.75rem, calc(10px + env(safe-area-inset-left, 0px)));
    padding-right: max(0.75rem, calc(10px + env(safe-area-inset-right, 0px)));
  }
  /* ~8–10px narrower “?” control → room so Prev doesn’t kiss Help */
  .help-btn {
    width: 2.85rem;
    min-width: 2.85rem;
    min-height: 2.85rem;
    font-size: 1.25rem;
  }
  .page-bar-controls {
    margin-right: max(10px, 0.65rem);
    gap: 0.4rem;
    /* Don’t let nav steal flex space from Help */
    flex-shrink: 1;
    min-width: 0;
  }
  .page-bar-btn {
    min-width: 5.5rem;
    min-height: 3rem;
    padding: 0.45rem 0.75rem;
    font-size: 1.1rem;
  }
  .page-bar .page-label {
    min-width: 0;
    min-height: 3rem;
    padding: 0.45rem 0.4rem;
    font-size: 1rem;
    gap: 0.25rem;
  }
}

.page-bar-btn {
  min-height: 3.4rem;
  min-width: 6.5rem;
  padding: 0.55rem 1.1rem;
  font-size: 1.25rem;
  font-weight: 600;
}

/**
 * Page readout: prose, not a third button. Muted “Page … of …” with the
 * numerals carrying the bright color, so the eye lands on the count.
 */
.page-bar .page-label {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  min-height: 3.4rem;
  min-width: 7rem;
  box-sizing: border-box;
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  text-align: center;
  padding: 0.55rem 0.9rem;
  background: none;
  border: none;
  border-radius: 0;
}

.page-label-num {
  font-weight: 700;
  color: var(--label-hi);
}

/* —— Diagnostic mode: yellow dropdown under the Diagnose button —— */
.diag-wrap {
  position: relative;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
}

/* Assess active: soft light yellow (not dark “warning” gold) */
#diag-btn.is-on,
#diag-btn[aria-pressed="true"] {
  background: rgba(250, 235, 160, 0.14);
  border-color: rgba(255, 245, 200, 0.95);
  border-width: 1.5px;
  color: #fff6d0;
}

/* Toolbar Assess ▾ lights yellow while assess mode is on */
#assess-menu-toggle.is-on,
#assess-menu-toggle.is-assess-on,
#assess-menu-toggle[aria-pressed="true"] {
  background: rgba(250, 220, 70, 0.92);
  border-color: rgba(220, 175, 20, 0.95);
  border-width: 1.5px;
  color: #1a1408;
  font-weight: 800;
  box-shadow: 0 0 0 2px rgba(250, 220, 70, 0.35);
}

#assess-menu-toggle.is-on:hover,
#assess-menu-toggle.is-assess-on:hover {
  background: rgba(255, 230, 90, 0.98);
  border-color: rgba(200, 150, 10, 0.98);
  color: #1a1408;
}

/* Floats over the PDF; does not push page content down */
.diag-ui {
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  z-index: 50;
  margin-top: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  pointer-events: none; /* children re-enable */
}

.diag-ui > * {
  pointer-events: auto;
}

.diag-panel {
  position: relative;
  z-index: 1;
  /* ~2.5× a typical Diagnose button width */
  width: max(16rem, 250%);
  min-width: 16rem;
  max-width: min(22rem, 90vw);
  padding: 0.75rem 2rem 0.75rem 0.85rem;
  border: 1px solid rgba(180, 130, 40, 0.55);
  border-radius: 0 0 10px 10px;
  background: rgba(240, 200, 70, 0.97);
  color: #1a1408;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.35);
  font-size: 1.05rem;
  font-weight: 600;
  line-height: 1.4;
}

.diag-banner {
  background: transparent;
  border: none;
  padding: 0;
  color: inherit;
  text-align: left;
  font-size: inherit;
  font-weight: inherit;
}

.diag-banner.is-listening {
  color: #0d4a2c;
}

.diag-banner-text {
  max-width: none;
  margin: 0;
}

.diag-collapse {
  position: absolute;
  top: 0.3rem;
  right: 0.3rem;
  width: 1.65rem;
  height: 1.65rem;
  padding: 0;
  border: 1px solid rgba(80, 55, 10, 0.35);
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.35);
  color: #1a1408;
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
}

.diag-collapse:hover {
  background: rgba(255, 255, 255, 0.55);
}

/* Collapsed: small yellow tab under the action dock (not over Sing/Finish) */
.diag-tab {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.25rem;
  height: 1.45rem;
  margin-top: 0;
  padding: 0 0.55rem;
  border: 1px solid rgba(180, 130, 40, 0.65);
  border-top: none;
  border-radius: 0 0 8px 8px;
  background: rgba(240, 200, 70, 0.97);
  color: #1a1408;
  font-size: 0.95rem;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
}

.diag-tab:hover {
  background: #f5d060;
}

.diag-tab[hidden],
.diag-panel[hidden],
.diag-ui[hidden],
.diag-action-dock[hidden] {
  display: none !important;
}

/* Status + Sing / Finish — always below instructions, never under the ▾ tab */
.diag-action-dock {
  position: relative;
  z-index: 3;
  width: max(16rem, 250%);
  min-width: 16rem;
  max-width: min(22rem, 90vw);
  margin-top: 0.2rem;
  padding: 0.55rem 2rem 0.6rem 0.65rem;
  border: 1px solid rgba(180, 130, 40, 0.55);
  border-radius: 10px;
  background: rgba(255, 248, 220, 0.98);
  color: #1a1408;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.3);
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  align-items: stretch;
}

.diag-action-dock.is-listening {
  background: rgba(210, 245, 225, 0.98);
  border-color: rgba(40, 140, 90, 0.45);
}

.diag-status-line {
  font-size: 0.92rem;
  font-weight: 700;
  line-height: 1.35;
  text-align: left;
  color: #1a1408;
}

.diag-action-dock .diag-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  justify-content: center;
  margin: 0;
}

.diag-action-dock .diag-actions .btn,
.diag-panel .diag-actions .btn {
  min-height: 2.35rem;
  font-size: 0.95rem;
  padding: 0.3rem 0.75rem;
  background: rgba(255, 255, 255, 0.75);
  color: #1a1408;
  border-color: rgba(80, 55, 10, 0.35);
}

.diag-action-dock .diag-actions .btn-primary {
  background: rgba(40, 120, 80, 0.2);
  border-color: rgba(40, 120, 80, 0.55);
  color: #0d4a2c;
  font-weight: 800;
}

/* Results: fixed top-right so they don’t cover Assess menu or notes under it */
.diag-report-panel {
  position: fixed;
  top: 4.35rem;
  right: 0.75rem;
  left: auto;
  z-index: 75;
  margin-top: 0;
  width: min(22rem, 92vw);
  min-width: 0;
  max-width: min(22rem, 92vw);
  max-height: min(48vh, 24rem);
  overflow: auto;
  padding: 0.55rem 0.65rem 0.75rem;
  border: 1px solid rgba(180, 150, 80, 0.5);
  border-radius: 10px;
  background: rgba(28, 30, 36, 0.98);
  color: var(--text);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
  font-size: 0.95rem;
  font-weight: 500;
  line-height: 1.45;
  text-align: left;
  box-sizing: border-box;
}

.diag-report-panel[hidden] {
  display: none !important;
}

/* Compact summary chip (does not block staff or Assess ▾) */
.diag-report-panel.is-minimized {
  top: 4.35rem;
  right: 0.75rem;
  display: flex;
  align-items: center;
  gap: 0.2rem;
  width: auto;
  max-width: min(18rem, 80vw);
  max-height: none;
  overflow: hidden;
  padding: 0.35rem 0.45rem;
  border-radius: 999px;
  background: rgba(40, 42, 50, 0.96);
  border-color: rgba(230, 190, 80, 0.55);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
}

.diag-report-chrome {
  position: absolute;
  top: 0.3rem;
  right: 0.3rem;
  display: flex;
  gap: 0.25rem;
  z-index: 2;
}

.diag-report-panel.is-minimized .diag-report-chrome {
  position: static;
  margin-left: 0.15rem;
  flex: 0 0 auto;
}

.diag-minimize {
  width: 1.65rem;
  height: 1.65rem;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.1);
  color: var(--text);
  font-size: 1.15rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
}

.diag-minimize:hover {
  background: rgba(255, 255, 255, 0.2);
}

.diag-report-panel .diag-collapse {
  position: static;
  border-color: rgba(255, 255, 255, 0.22);
  background: rgba(255, 255, 255, 0.1);
  color: var(--text);
}

.diag-report-panel .diag-collapse:hover {
  background: rgba(255, 255, 255, 0.2);
}

.diag-report-panel:not(.is-minimized) {
  padding-top: 2.1rem;
}

.diag-report-mini {
  display: none;
  align-items: center;
  gap: 0.4rem;
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  padding: 0.15rem 0.35rem;
  border: none;
  background: transparent;
  color: #ffe9b8;
  font: inherit;
  font-size: 0.88rem;
  font-weight: 700;
  text-align: left;
  cursor: pointer;
}

.diag-report-panel.is-minimized .diag-report-mini {
  display: inline-flex;
}

.diag-report-mini-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.diag-report-mini-expand {
  flex: 0 0 auto;
  opacity: 0.75;
  font-size: 0.85rem;
}

.diag-report {
  margin: 0;
  padding: 0;
  background: transparent;
  border: none;
  max-height: none;
  overflow: visible;
  color: inherit;
}

.diag-report-panel.is-minimized .diag-report {
  display: none !important;
}

.diag-report-panel.is-minimized .diag-minimize {
  display: none;
}

.diag-report h3 {
  margin: 0 0 0.4rem;
  font-size: 1.08rem;
  font-weight: 700;
  color: #ffe9b8;
}

.diag-report .diag-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  margin: 0.35rem 0 0.6rem;
  font-variant-numeric: tabular-nums;
}

.diag-report .stat-ok { color: #9ee0bc; }
.diag-report .stat-near { color: #e6c04a; }
.diag-report .stat-wrong { color: #f08080; }
.diag-report .stat-missing { color: #9a9ba0; }

.diag-report ul {
  margin: 0.25rem 0 0;
  padding-left: 1.2rem;
}

.diag-report .diag-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.65rem;
}

.diag-report .diag-actions .btn {
  min-height: 2.4rem;
  font-size: 1rem;
  padding: 0.35rem 0.85rem;
}

.diag-report-panel .diag-actions .btn {
  background: rgba(255, 255, 255, 0.1);
  color: var(--text);
  border-color: rgba(255, 255, 255, 0.2);
}

/* Missing-score nag: a loaded PDF with no notes looks fine but does nothing. */
.score-banner {
  flex-shrink: 0;
  padding: 0.6rem 1rem;
  font-size: 1.1rem;
  font-weight: 600;
  color: #ffe9b8;
  background: rgba(230, 170, 60, 0.16);
  border-bottom: 1px solid rgba(230, 170, 60, 0.45);
}

/* Fallback if extract-banner is ever shown outside .page-bar */
.extract-banner {
  font-weight: 800;
  text-transform: uppercase;
}

.extract-test-banner {
  flex-shrink: 0;
  padding: 0.5rem 0.75rem;
  font-size: 0.85rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  white-space: pre-wrap;
  color: #e8e8ea;
  background: #121316;
  border-bottom: 1px solid var(--border);
  max-height: 14rem;
  overflow: auto;
}

.extract-test-banner.is-pass {
  color: #9ee0bc;
  border-bottom-color: rgba(61, 184, 122, 0.5);
}

.extract-test-banner.is-fail {
  color: #ffc9c9;
  border-bottom-color: rgba(224, 90, 90, 0.5);
}

/* Big translucent 3-2-1 over the sheet. */
.countdown {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  font-size: clamp(8rem, 28vmin, 22rem);
  font-weight: 800;
  line-height: 1;
  color: rgba(76, 139, 245, 0.45);
  text-shadow: 0 0 40px rgba(0, 0, 0, 0.55);
}

.countdown[hidden] {
  display: none;
}

.countdown.is-tick {
  animation: countdown-pop 260ms ease-out;
}

@keyframes countdown-pop {
  from {
    transform: scale(1.35);
    opacity: 0.15;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}

.selftest-banner {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 99;
  padding: 10px 16px;
  font: 600 16px system-ui, sans-serif;
  background: #1c2a44;
  color: #cfe0ff;
}

/* Filename next to Upload & Save (see also toolbar-files rules above) */
.toolbar-files .file-status {
  font-size: 1.1rem;
  color: var(--text);
  max-width: 16rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
}

.slider-label {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 1.2rem;
  color: var(--muted);
}

.slider-label input[type="range"] {
  width: 10rem;
  height: 2.2rem;
  accent-color: var(--accent);
  cursor: pointer;
}

.slider-label span {
  min-width: 4.2rem;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  font-size: 1.2rem;
}

.current-note {
  min-width: 4rem;
  max-width: 14rem;
  padding: 0.3rem 0.65rem;
  font-size: 1.15rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1.25;
  text-align: center;
  color: #e8e4d8;
  background: #121316;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Lyric under the current note (not piano names like G4) */
.current-lyric {
  font-style: italic;
}

.page-label {
  font-size: 1.2rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  min-width: 4.5rem;
  text-align: center;
}

#prev-page,
#next-page {
  min-width: 3.4rem;
  font-size: 2rem;
  line-height: 1;
  padding-left: 0.7rem;
  padding-right: 0.7rem;
}

/* —— Stage / PDF view —— */
.stage {
  flex: 1;
  min-height: 0;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  position: relative;
  background: #111214;
}

.drop-hint {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: stretch;
  justify-content: stretch;
  padding: 0;
  color: var(--muted);
  pointer-events: none;
  z-index: 1;
}

/* Two columns: 60% instructions | 40% MCI reference */
.drop-hint-split {
  position: relative;
  display: flex;
  flex-direction: row;
  align-items: stretch;
  width: 100%;
  height: 100%;
  min-height: 0;
}

.drop-hint-col {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem 1.75rem;
  box-sizing: border-box;
  min-width: 0;
}

.drop-hint-col-main {
  flex: 0 0 60%;
  width: 60%;
}

.drop-hint-col-mci {
  flex: 0 0 40%;
  width: 40%;
}

/* Thin vertical rule only through the middle 60% of stage height */
.drop-hint-divider {
  position: absolute;
  left: 60%;
  top: 20%;
  bottom: 20%;
  width: 0;
  border-left: 1px solid rgba(154, 155, 165, 0.45);
  transform: translateX(-0.5px);
  pointer-events: none;
}

.drop-hint-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  max-width: 36rem;
}

.drop-hint-main {
  margin: 0 0 0.65rem;
  font-size: clamp(1.45rem, 3.2vw, 1.95rem);
  font-weight: 700;
  line-height: 1.35;
  color: var(--muted);
  letter-spacing: 0.01em;
}

.drop-hint-main strong {
  color: var(--text);
  font-weight: 800;
}

.drop-hint-sub {
  margin: 0 0 0.85rem;
  font-size: clamp(1.15rem, 2.4vw, 1.4rem);
  font-weight: 600;
  line-height: 1.4;
  color: var(--muted);
}

.drop-hint-note {
  margin: 0;
  font-size: clamp(0.95rem, 1.8vw, 1.1rem);
  font-weight: 500;
  line-height: 1.45;
  color: var(--muted);
  opacity: 0.88;
  max-width: 28rem;
}

/* Right column: same structure, softer weight / dimmer so left stays primary */
.drop-hint-card-mci {
  max-width: 22rem;
}

.drop-hint-mci-line {
  margin: 0 0 0.4rem;
  font-size: clamp(1.05rem, 2.1vw, 1.35rem);
  font-weight: 500;
  line-height: 1.4;
  color: #6a6b74;
  letter-spacing: 0.01em;
}

.drop-hint-mci-spacer {
  margin: 0.35rem 0 0.55rem;
  line-height: 0.6;
  height: 0.6em;
  opacity: 0;
}

.drop-hint-mci-link-wrap {
  margin: 0.15rem 0 0;
  max-width: 100%;
}

.drop-hint-mci-link {
  pointer-events: auto;
  display: inline-block;
  font-size: clamp(0.95rem, 1.7vw, 1.1rem);
  font-weight: 500;
  line-height: 1.4;
  color: #5a6a8a;
  text-decoration: underline;
  text-underline-offset: 0.15em;
  word-break: break-all;
}

.drop-hint-mci-link:hover {
  color: #7a8cb0;
}

/**
 * Thin horizontal rule under sheet-music link (same stroke as the vertical
 * column divider). Only the middle ~50% of the right-column card width.
 */
.drop-hint-mci-hrule {
  width: 50%;
  max-width: 11rem;
  height: 0;
  margin: 1.15rem auto 0;
  border: none;
  border-top: 1px solid rgba(154, 155, 165, 0.45);
  pointer-events: none;
  align-self: center;
}

.drop-hint code {
  font-size: 0.9em;
  color: var(--text);
}

@media (max-width: 720px) {
  .drop-hint-split {
    flex-direction: column;
  }
  .drop-hint-col-main,
  .drop-hint-col-mci {
    flex: 1 1 auto;
    width: 100%;
  }
  /**
   * Horizontal rule between the stacked columns.
   * Centred by width + auto margins, not by left/right: on a relatively
   * positioned box those are offsets rather than insets, so `right` is
   * ignored and `left` just pushes the full-width rule off the screen edge.
   */
  .drop-hint-divider {
    position: relative;
    left: auto;
    right: auto;
    top: auto;
    bottom: auto;
    width: 70%;
    max-width: 70%;
    height: 0;
    border-left: none;
    border-top: 1px solid rgba(154, 155, 165, 0.45);
    transform: none;
    margin: 0.25rem auto;
  }
}

.stage.is-dragover {
  outline: 2px dashed var(--accent);
  outline-offset: -8px;
  background: #151820;
}

.canvas-wrap {
  position: relative;
  margin: 0 auto;
  /* width set in JS to match PDF CSS width */
  line-height: 0;
}

/*
 * "Keep going, the page turns itself" cue. Fixed rather than in-flow so it
 * never disturbs the canvas geometry the overlay maths depends on; JS pins it
 * to the stage's own box so it clears the page bar whatever height that is.
 * pointer-events:none matters — click-to-seek must still reach the sheet.
 */
.page-advance-hint {
  position: fixed;
  z-index: 40;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.55rem 1.15rem;
  border-radius: 999px;
  background: rgba(30, 31, 36, 0.94);
  border: 1px solid var(--border);
  color: var(--text);
  font-size: 1.05rem;
  font-weight: 600;
  white-space: nowrap;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.5);
  pointer-events: none;
  opacity: 0;
  transition: opacity 180ms ease, transform 180ms ease;
}

.page-advance-hint.is-visible {
  opacity: 1;
}

.page-advance-hint[hidden] {
  display: none;
}

.page-advance-hint::after {
  content: "↓";
  font-size: 1.15em;
  line-height: 1;
  color: var(--accent);
}

@media (prefers-reduced-motion: reduce) {
  .page-advance-hint {
    transition: none;
  }
}

#page,
#overlay {
  display: block;
  /* CSS size set in JS; bitmap size uses devicePixelRatio */
  width: 100%;
  height: auto;
}

#overlay {
  position: absolute;
  left: 0;
  top: 0;
  pointer-events: none;
}

/* The wrapper takes the taps (the overlay above it is pointer-events:none). */
.canvas-wrap {
  cursor: pointer;
}

/**
 * Compact / phone toolbar: Upload (+ Settings label) + Tools ▾ only.
 * Applied when body.compact-toolbar is set by JS (actual wrap) or narrow
 * screens — not only a fixed pixel breakpoint.
 */
body.compact-toolbar .toolbar {
  flex-wrap: nowrap;
  justify-content: flex-start;
  gap: 0.5rem;
  padding: 0.55rem 0.65rem;
}

body.compact-toolbar .toolbar-group + .toolbar-group {
  border-left: none;
  padding-left: 0;
  margin-left: 0;
}

body.compact-toolbar .toolbar-group + .toolbar-group::before {
  content: none;
}

/* Compact labels: “Upload” until a PDF is loaded, then “Settings” */
body.compact-toolbar .us-label-full,
body.compact-toolbar .hint-us-full {
  display: none;
}

body.compact-toolbar:not(.has-pdf) .us-label-upload {
  display: inline;
}
body.compact-toolbar:not(.has-pdf) .us-label-settings {
  display: none;
}
body.compact-toolbar.has-pdf .us-label-upload {
  display: none;
}
body.compact-toolbar.has-pdf .us-label-settings {
  display: inline;
}

body.compact-toolbar:not(.has-pdf) .hint-us-upload {
  display: inline;
}
body.compact-toolbar:not(.has-pdf) .hint-us-settings {
  display: none;
}
body.compact-toolbar.has-pdf .hint-us-upload {
  display: none;
}
body.compact-toolbar.has-pdf .hint-us-settings {
  display: inline;
}

body.compact-toolbar .toolbar-files {
  flex: 0 0 auto;
}

/* Tools sits beside Upload/Settings on the left (not pushed to the far right) */
body.compact-toolbar .tools-menu {
  flex: 0 0 auto;
  margin-left: 0;
  gap: 0;
}

body.compact-toolbar .tools-toggle {
  display: inline-flex !important;
}

body.compact-toolbar .tools-toggle.is-awaiting-score:disabled,
body.compact-toolbar .tools-toggle.is-awaiting-score[disabled] {
  opacity: 0.42;
  filter: grayscale(0.55);
  cursor: not-allowed;
}

body.compact-toolbar .tools-toggle.is-open {
  border-color: var(--accent);
  background: var(--accent-soft);
}

/* Dropdown list of all practice controls (opens under Tools, aligned left) */
body.compact-toolbar .tools-panel {
  display: none;
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: auto;
  z-index: 40;
  flex: none;
  flex-direction: column;
  flex-wrap: nowrap;
  align-items: stretch;
  gap: 0.55rem;
  min-width: min(92vw, 18.5rem);
  max-width: min(96vw, 22rem);
  max-height: min(70vh, 32rem);
  overflow-x: hidden;
  overflow-y: auto;
  padding: 0.75rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
}

body.compact-toolbar .tools-menu.is-open .tools-panel {
  display: flex;
}

body.compact-toolbar .tools-panel .toolbar-group {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  width: 100%;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  border: none;
}

body.compact-toolbar .tools-panel .toolbar-play-music {
  margin-left: 0;
}

body.compact-toolbar .tools-panel .btn,
body.compact-toolbar .tools-panel .file-btn {
  width: 100%;
  justify-content: center;
}

body.compact-toolbar .tools-panel .tempo-controls,
body.compact-toolbar .tools-panel .transpose-controls-bar {
  width: 100%;
  max-width: none;
  min-width: 0;
}

body.compact-toolbar .tools-panel .play-controls {
  width: 100%;
}

body.compact-toolbar .tools-panel .diag-wrap {
  width: 100%;
  align-items: stretch;
}

body.compact-toolbar .tools-panel #diag-btn {
  width: 100%;
}

/* ——————————————————————————————————————————————————————————
   Phone: Assess docks above the page bar

   Hanging off the Assess button, the yellow instruction panel covered the
   staff — including the very noteheads it was asking the user to tap. Docked
   to the bottom edge it stays permanently visible and out of the way, and the
   score keeps the whole middle of the screen.
   —————————————————————————————————————————————————————————— */
body.compact-toolbar .diag-ui,
body.compact-toolbar .tools-panel .diag-ui {
  position: fixed;
  top: auto;
  left: 0;
  right: 0;
  bottom: calc(var(--page-bar-h) + env(safe-area-inset-bottom, 0px));
  transform: none;
  z-index: 60;
  align-items: stretch;
  max-height: 42vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}

body.compact-toolbar .diag-panel,
body.compact-toolbar .diag-action-dock {
  width: 100%;
  min-width: 0;
  max-width: none;
  box-sizing: border-box;
  border-radius: 0;
  border-left: none;
  border-right: none;
  font-size: 0.95rem;
  line-height: 1.35;
}

body.compact-toolbar .diag-panel {
  padding: 0.5rem 2.25rem 0.5rem 0.85rem;
  box-shadow: none;
}

body.compact-toolbar .diag-action-dock {
  margin-top: 0;
  padding: 0.45rem 0.85rem calc(0.5rem + env(safe-area-inset-bottom, 0px) * 0);
  box-shadow: 0 -6px 18px rgba(0, 0, 0, 0.35);
}

body.compact-toolbar .diag-status-line {
  font-size: 0.88rem;
}

/* ——————————————————————————————————————————————————————————
   Phone: reduced toolbar

   Three icon controls only — gear (upload + settings), Match Pitch, Play.
   Transpose and Tempo are relocated into the gear sheet by mobile.js; assess
   features are hidden entirely and explained under Help. Labels are collapsed
   with font-size:0 rather than removed, because follow.js rewrites the text of
   these buttons as their state changes.
   —————————————————————————————————————————————————————————— */

/* Assess is desktop-only */
body.compact-toolbar .toolbar-note,
body.compact-toolbar #assess-menu,
body.compact-toolbar #diag-ui,
body.compact-toolbar #diag-tab,
body.compact-toolbar .tools-toggle,
body.compact-toolbar #harmony-hint,
/* The "app will turn the page" notice competes with the sheets for the same
   strip of screen and is redundant when the page bar is one thumb away. */
body.compact-toolbar .page-advance-hint {
  display: none !important;
}

/* Gear */
body.compact-toolbar #upload-save-toggle {
  min-width: 3.2rem;
  padding: 0.5rem 0.75rem;
  font-size: 0;
}

body.compact-toolbar #upload-save-toggle::before {
  content: "\2699";
  font-size: 1.75rem;
  line-height: 1;
}

body.compact-toolbar #upload-save-toggle .us-label,
body.compact-toolbar #upload-save-toggle .caret {
  display: none;
}

/* Match Pitch → eighth note; becomes a stop square while matching */
body.compact-toolbar #match-pitch-btn {
  min-width: 3.2rem;
  padding: 0.5rem 0.75rem;
  font-size: 0;
}

body.compact-toolbar #match-pitch-btn::before {
  content: "\266A";
  font-size: 1.8rem;
  line-height: 1;
}

body.compact-toolbar #match-pitch-btn[aria-pressed="true"]::before,
body.compact-toolbar #match-pitch-btn.is-on::before {
  content: "\25A0";
  font-size: 1.4rem;
}

/* Play → ▶ / ⏸ only. The glyph spans are re-sized back up. */
body.compact-toolbar #play-btn {
  min-width: 3.2rem;
  padding: 0.5rem 0.75rem;
  font-size: 0;
}

body.compact-toolbar #play-btn .play-icon,
body.compact-toolbar #play-btn .pause-icon {
  font-size: 1.6rem;
  line-height: 1;
}

/**
 * Match Pitch and Play sit on the bar itself. With Transpose and Tempo moved
 * into the gear sheet and Assess hidden, what is left of the Tools panel is
 * two icon buttons — so it stops being a dropdown and becomes part of the bar.
 */
body.compact-toolbar .tools-panel {
  display: flex;
  position: static;
  flex: 0 0 auto;
  flex-direction: row;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0.5rem;
  width: auto;
  min-width: 0;
  max-width: none;
  max-height: none;
  overflow: visible;
  padding: 0;
  margin: 0;
  background: none;
  border: none;
  border-radius: 0;
  box-shadow: none;
}

body.compact-toolbar .tools-panel .toolbar-group {
  flex-direction: row;
  flex-wrap: nowrap;
  align-items: center;
  width: auto;
  gap: 0.5rem;
}

body.compact-toolbar .tools-panel .btn {
  width: auto;
}

/**
 * Phone bar proportions. With only three icon controls left, the desktop
 * 3.4rem control height and 0.55rem bar padding are more than the bar needs —
 * this trims both to a medium size that is still a comfortable tap target
 * (≈44px, Apple's minimum) and gives the score back the difference.
 */
body.compact-toolbar .toolbar {
  gap: 0.5rem;
  padding: 0.35rem 0.6rem;
}

body.compact-toolbar .toolbar .btn,
body.compact-toolbar .toolbar .file-btn {
  min-height: 2.75rem;
  font-size: 1.05rem;
  padding: 0.4rem 0.85rem;
}

body.compact-toolbar #upload-save-toggle,
body.compact-toolbar #match-pitch-btn,
body.compact-toolbar #play-btn {
  min-width: 2.9rem;
  min-height: 2.75rem;
  padding: 0.35rem 0.6rem;
}

body.compact-toolbar #upload-save-toggle::before {
  font-size: 1.45rem;
}

body.compact-toolbar #match-pitch-btn::before {
  font-size: 1.5rem;
}

body.compact-toolbar #match-pitch-btn[aria-pressed="true"]::before,
body.compact-toolbar #match-pitch-btn.is-on::before {
  font-size: 1.15rem;
}

body.compact-toolbar #play-btn .play-icon,
body.compact-toolbar #play-btn .pause-icon {
  font-size: 1.35rem;
}

body.compact-toolbar .toolbar-play-music {
  margin-left: auto;
}

/* Relocated sliders (see mobile.js) */
.mobile-tools-mount,
.mobile-assess-note {
  display: none;
}

body.compact-toolbar .mobile-tools-mount {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.6rem;
  width: 100%;
  margin-top: 0.35rem;
}

body.compact-toolbar .mobile-tools-mount .tempo-controls,
body.compact-toolbar .mobile-tools-mount .transpose-controls-bar {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  max-width: none;
}

body.compact-toolbar .mobile-tools-mount input[type="range"] {
  flex: 1 1 auto;
  width: auto;
  min-width: 0;
}

/* Transpose keeps its slider; its ▾ menu is redundant at this size */
body.compact-toolbar .mobile-tools-mount #transpose-menu {
  display: none;
}

body.compact-toolbar .mobile-tools-mount .transpose-controls-bar::before {
  content: "Transpose";
  flex: 0 0 5.5rem;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--label);
}

body.compact-toolbar .mobile-assess-note {
  display: block;
  margin-top: 0.9rem;
  padding-top: 0.75rem;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}

/* ——————————————————————————————————————————————————————————
   Phone: menus as bottom sheets

   A dropdown anchored under its button has nowhere to go on a 6.9" screen —
   it either runs off the right edge or covers the score. Pinning menus to the
   bottom edge instead gives them the full width, puts them under the thumb,
   and lets them scroll internally rather than pushing the layout around.
   —————————————————————————————————————————————————————————— */
body.compact-toolbar .play-menu-panel {
  position: fixed;
  top: auto;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 80;
  width: 100%;
  min-width: 0;
  max-width: none;
  max-height: min(78vh, 40rem);
  overflow-x: hidden;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  box-sizing: border-box;
  /* Top inset clears the grab handle; bottom clears the home indicator. */
  padding: 1.6rem 1rem calc(1rem + env(safe-area-inset-bottom, 0px));
  background: var(--surface);
  border: none;
  border-top: 1px solid #4a5670;
  border-radius: 16px 16px 0 0;
  box-shadow: 0 -12px 32px rgba(0, 0, 0, 0.5);
  overscroll-behavior: contain;
}

/* Dimming scrim. pointer-events:none so a tap still reaches the element
   behind it and the existing outside-click handler closes the menu. */
body.compact-toolbar .play-menu-panel::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: rgba(8, 10, 14, 0.5);
  pointer-events: none;
}

/* Grab handle, so the sheet reads as a sheet */
body.compact-toolbar .play-menu-panel::after {
  content: "";
  position: absolute;
  top: 0.45rem;
  left: 50%;
  transform: translateX(-50%);
  width: 2.5rem;
  height: 4px;
  border-radius: 2px;
  background: #565963;
}

body.compact-toolbar .play-menu-panel > *:first-child {
  margin-top: 0.5rem;
}

/* A menu opened from inside another sheet stacks above it */
body.compact-toolbar .assess-menu-panel,
body.compact-toolbar .transpose-menu-panel {
  z-index: 82;
}

/* Full-width, thumb-sized rows inside a sheet */
body.compact-toolbar .play-menu-panel .btn,
body.compact-toolbar .play-menu-panel .file-btn {
  width: 100%;
  min-height: 3rem;
  justify-content: center;
}

body.compact-toolbar .slider-label input[type="range"] {
  width: 4.25rem;
}

body.compact-toolbar .current-note {
  font-size: 0.95rem;
  min-width: 3rem;
  max-width: 8rem;
}

body.compact-toolbar .file-status {
  display: none;
}

/**
 * Measure pass: full desktop bar — Tools button hidden, all practice controls
 * laid out as they would on a wide screen so we can test fit.
 */
body.toolbar-measuring .tools-toggle {
  display: none !important;
}
/* Separators are absolutely positioned, but drop them in the measure pass so
   fit is computed on the controls alone. */
body.toolbar-measuring .toolbar-group + .toolbar-group::before {
  content: none !important;
}
body.toolbar-measuring .toolbar {
  flex-wrap: wrap !important;
  overflow: visible !important;
}
body.toolbar-measuring .tools-menu {
  flex: 1 1 auto !important;
  min-width: 0 !important;
  overflow: visible !important;
  margin-left: 0 !important;
}
body.toolbar-measuring .tools-panel {
  display: flex !important;
  position: static !important;
  flex: 1 1 auto !important;
  flex-direction: row !important;
  flex-wrap: wrap !important;
  align-items: center !important;
  gap: 0.75rem 1.1rem !important;
  width: auto !important;
  min-width: 0 !important;
  max-width: none !important;
  max-height: none !important;
  overflow: visible !important;
  padding: 0 !important;
  margin: 0 !important;
  border: none !important;
  background: transparent !important;
  box-shadow: none !important;
}
/* For scrollWidth: natural one-row width of the tool strip */
body.toolbar-measuring .tools-panel-measure-row {
  display: flex !important;
  flex-direction: row !important;
  flex-wrap: nowrap !important;
  width: max-content !important;
  min-width: max-content !important;
  gap: 0.75rem 1.1rem !important;
  align-items: center !important;
}
body.toolbar-measuring .tools-panel .toolbar-group {
  flex-direction: row !important;
  flex-wrap: nowrap !important;
  width: auto !important;
  flex: 0 0 auto !important;
}
body.toolbar-measuring .tools-panel .btn,
body.toolbar-measuring .tools-panel .file-btn {
  width: auto !important;
  flex: 0 0 auto !important;
}
body.toolbar-measuring .tools-panel .tempo-controls,
body.toolbar-measuring .tools-panel .transpose-controls-bar {
  width: auto !important;
  max-width: 15rem !important;
  flex: 0 0 auto !important;
}
body.toolbar-measuring .tools-panel .toolbar-play-music {
  margin-left: auto !important;
}

/* =====================================================================
   Phone layout (2026-08-10): minimal chrome, maximum sheet.
   - file-status chip hidden (was an unreadable thin box)
   - page nav = small fixed arrows in the bottom corners
   - help "?" moves to the top-right; toolbar keeps clear of it
   ===================================================================== */
/* Phones in portrait (narrow) OR any touch device in short landscape —
   an iPhone in landscape is ~850–930px wide, far past a 720px query. */
@media (max-width: 720px), ((pointer: coarse) and (max-height: 540px)) {
  /* The filename readout renders as an unreadable thin sliver on phones —
     hide it there (id covers the current in-menu variant). */
  #file-status,
  .file-status,
  .file-status-in-menu {
    display: none !important;
  }

  /* Small corner arrows; disabled state grays out (Prev at page 1). */
  #prev-page,
  #next-page {
    position: fixed;
    bottom: calc(env(safe-area-inset-bottom, 0px) + 10px);
    z-index: 60;
    min-width: 44px;
    width: 44px;
    height: 44px;
    padding: 0;
    border-radius: 22px;
    font-size: 1.5rem;
    line-height: 1;
    opacity: 0.82;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
  }
  #prev-page {
    left: calc(env(safe-area-inset-left, 0px) + 10px);
  }
  #next-page {
    right: calc(env(safe-area-inset-right, 0px) + 10px);
  }
  #prev-page:disabled,
  #next-page:disabled {
    opacity: 0.22;
  }
  #prev-page .pg-word,
  #next-page .pg-word {
    display: none;
  }
  .page-label {
    display: none;
  }
  .page-bar-controls {
    min-height: 0;
  }

  /* Help to the top-right; reserve toolbar space so nothing sits under it. */
  #help-btn {
    position: fixed;
    top: calc(env(safe-area-inset-top, 0px) + 8px);
    right: calc(env(safe-area-inset-right, 0px) + 8px);
    z-index: 61;
    width: 40px;
    height: 40px;
    min-height: 40px;
    padding: 0;
    border-radius: 20px;
    opacity: 0.9;
  }
  .toolbar {
    padding-right: 54px;
  }
}

.howto-build {
  margin: 2px 0 0;
  font-size: 0.72rem;
  opacity: 0.55;
  text-align: center;
}

/* —— 2026-08-10b: aesthetics + phone page indicator —— */

/* A touch more breathing room inside the How-to card */
.howto-modal-card {
  padding: 1.9rem 2.1rem 1.7rem;
}
.howto-body {
  padding: 0 0.15rem;
}

/* Build number: small spacer after the “press × or Escape” line */
.howto-build {
  margin-top: 14px;
}

@media (max-width: 720px), ((pointer: coarse) and (max-height: 540px)) {
  /* X/Y indicator floats bottom-center between the corner arrows */
  .page-label {
    display: block !important;
    position: fixed;
    bottom: calc(env(safe-area-inset-bottom, 0px) + 20px);
    left: 50%;
    transform: translateX(-50%);
    z-index: 60;
    min-width: 0;
    font-size: 0.95rem;
    padding: 3px 12px;
    border-radius: 12px;
    background: rgba(10, 10, 14, 0.55);
    opacity: 0.85;
  }
}

/* —— 2026-08-11: phone sheet comfort + footer removal —— */

/* Bottom sheets: real side padding (text ran to the screen edge), a lower
   ceiling so the sheet never towers over the page (worst in landscape),
   and slightly smaller type. Content scrolls — longer is fine. */
body.compact-toolbar .play-menu-panel {
  max-height: min(60vh, 30rem);
  padding: 1.9rem 1.7rem calc(1.5rem + env(safe-area-inset-bottom, 0px));
  font-size: 0.93rem;
}
body.compact-toolbar .play-menu-panel .play-menu-hint {
  font-size: 0.85rem;
}
/* Bigger, more obvious grab handle (it is now tappable + draggable) */
body.compact-toolbar .play-menu-panel::after {
  width: 3.4rem;
  height: 5px;
  top: 0.55rem;
}

@media (max-width: 720px), ((pointer: coarse) and (max-height: 540px)) {
  /* Landscape is short: keep the sheet to half the screen */
  body.compact-toolbar .play-menu-panel {
    max-height: 55vh;
  }

  /* Bottom bar gone entirely — the floating arrows, X/Y pill and fixed
     help button replace it. Fixed-position children still render, so we
     collapse the bar's box rather than display:none the container. */
  .page-bar {
    padding: 0 !important;
    min-height: 0 !important;
    height: 0 !important;
    border: 0 !important;
    background: transparent !important;
    box-shadow: none !important;
    overflow: visible;
  }
  /* Extraction status floats just above the corner arrows when present */
  #extract-banner {
    position: fixed;
    left: 50%;
    transform: translateX(-50%);
    bottom: calc(env(safe-area-inset-bottom, 0px) + 62px);
    z-index: 58;
    max-width: 92vw;
    border-radius: 10px;
  }
}

/* —— 2026-08-12: sheet transpose sizing, sheet Reset, SE status bar —— */

/* Sheet transpose: a medium-short bar whose ticks align exactly with the
   thumb travel — the control keeps its own compact row, and the slider wrap
   is a fixed centred width instead of inheriting the toolbar's 18.5rem box. */
body.compact-toolbar #mobile-tools-mount .transpose-controls-bar {
  width: 100%;
  max-width: none;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.45rem 0.6rem;
  padding: 0.35rem 0;
}
body.compact-toolbar #mobile-tools-mount .transpose-slider-wrap {
  flex: 0 0 auto;
  width: 13rem;
  max-width: calc(100% - 1rem);
  margin: 0 auto;
}
body.compact-toolbar #mobile-tools-mount .transpose-slider-wrap input[type="range"] {
  width: 100%;
  min-width: 0;
}

/* Sheet-only Reset button (created by mobile.js) */
.mobile-transpose-reset {
  display: none;
}
body.compact-toolbar #mobile-tools-mount .mobile-transpose-reset {
  display: flex;
  width: 100%;
  min-height: 2.7rem;
  justify-content: center;
  margin-top: 0.15rem;
}

/* iPhone SE / status-bar clearance: keep the app toolbar below the system
   clock + carrier text when the page is drawn edge-to-edge
   (viewport-fit=cover). env() is 0 wherever the browser already offsets. */
@media (max-width: 720px), ((pointer: coarse) and (max-height: 540px)) {
  .toolbar {
    padding-top: calc(0.55rem + env(safe-area-inset-top, 0px)) !important;
  }
}
