/* ═══════════════════════════════════════════════════════════════════════════
   bytefret — styles/topbar.css
   ───────────────────────────────────────────────────────────────────────────
   Persistent App-Chrome im Header:
     - Topbar (sticky glass-bar, Brand + Actions)
     - Generic button defaults + .btn-primary + .btn-danger + .icon-btn
       (territorial in topbar.css; nutzbar von dialogs/footer via cascade-order)
     - F8 Multi-Song-Library Dropdown
     - A7 Library-Search Input
     - View-Settings-Gear (Refinement B Phase 3)
     - Refinement A Desktop-Edit-Popover (incl. lang-btn)
     - Mobile-Overflow-Toggle / -Menu
     - Mobile-Toolbar-M2 (≤720px 2-row-Grid)

   DEFER nach Phase 7:
     - body.is-read-only-Toolbar-Bundle (Touch-Block-Distribution)
     - Touch-Block topbar-coarse-Overrides
     - Topbar-bezogene Print-Overrides

   Dependencies: base.css (var(--…), reset).
   Cascade: MUSS vor dialogs.css laden (.btn-primary global utility).
   ═══════════════════════════════════════════════════════════════════════════ */


/* ─── Topbar ──────────────────────────────────────────────────────────────── */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem 2rem;
  padding: .9rem 1.75rem;
  background: var(--bg-topbar);
  backdrop-filter: blur(10px) saturate(140%);
  -webkit-backdrop-filter: blur(10px) saturate(140%);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 10;
}

.brand {
  display: flex;
  align-items: center;
  gap: .8rem;
}

.logo {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  display: block;
  /* Color-Diät-Tweak: dezenter Brand-Glow (4px statt original 10px).
     Logo verdient leichte Akzent-Präsenz für Brand-Identität, ohne
     den Notification-Badge-Look des Originals. */
  filter: drop-shadow(0 0 4px var(--accent-glow));
  transition: filter .35s var(--ease), transform .15s var(--ease);
}

.brand:hover .logo,
.brand-link:hover .logo {
  filter: drop-shadow(0 0 6px var(--accent-glow));
  transform: scale(1.04);
}

.brand-text {
  display: flex;
  flex-direction: column;
  line-height: 1;
}

.brand-text h1 {
  margin: 0;
  font-size: 1.4rem;
  font-weight: 600;
  letter-spacing: -.015em;
  color: var(--text);
}

.brand-text small {
  margin-top: .25rem;
  font-size: .68rem;
  color: var(--text-muted);
  letter-spacing: .14em;
  text-transform: uppercase;
}


/* ─── Buttons ─────────────────────────────────────────────────────────────── */
.actions {
  display: flex;
  gap: .65rem;
  align-items: center;
  flex-wrap: wrap;
}

/* ─── F8 — Multi-Song-Library Dropdown ────────────────────────────────────
   Toggle-Button mit aktivem Song-Titel + Chevron, Menu darunter mit
   "+ Neuer Song" und Liste aller Songs. position:relative am Picker
   damit Menu absolute-positioniert relative dazu sitzt. */
.songs-picker {
  position: relative;
  display: inline-flex;
}
.songs-toggle {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .45rem .75rem;
  background: var(--bg-sunken);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  color: inherit;
  font: inherit;
  font-size: .85rem;
  font-weight: 500;
  cursor: pointer;
  transition: background .12s var(--ease), border-color .12s var(--ease);
}
.songs-toggle:hover { border-color: var(--border); }
.songs-toggle .icon { width: 14px; height: 14px; flex: 0 0 auto; }
.songs-toggle .icon-chevron { transition: transform .15s var(--ease); }
.songs-toggle[aria-expanded="true"] .icon-chevron { transform: rotate(180deg); }
.songs-active-title {
  max-width: 12rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.songs-menu {
  position: absolute;
  top: calc(100% + .25rem);
  left: 0;
  min-width: 16rem;
  /* Defensive für schmale Desktop-Browser-Windows (Split-Screen <400px):
     Sonst kann das Menü übers Viewport-Ende schießen, weil min-width:16rem
     (256px) auch bei 300px Viewport-Breite gehalten wird. Coarse-Pointer-
     Variante (siehe ~Z. 2560) hat das Limit schon, hier für Fine-Pointer
     ergänzt. min() greift auf modernen Browsern (>96% Support). */
  max-width: min(24rem, calc(100vw - 2rem));
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0,0,0,.18);
  padding: .35rem;
  z-index: 100;
}
.songs-menu .songs-action {
  display: block;
  width: 100%;
  text-align: left;
  padding: .55rem .75rem;
  background: transparent;
  border: 1px dashed var(--border-soft);
  border-radius: 4px;
  color: var(--accent);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  margin-bottom: .25rem;
  transition: background .1s var(--ease), border-color .1s var(--ease);
}

/* ─── A7 (Stage 9) — Library-Search Input ────────────────────────────────────
   Text-Input oben im Songs-Dropdown, filtert Songs nach Substring-Match in
   title+artist+composer. Default-hidden, JS togglet .is-visible bei
   Library-Size >= 5 (Heuristic-Trade-off: vermeidet UI-Clutter bei kleinen
   Libraries). `width:` (nicht min-width!) für robust-fixed-Geometrie analog
   Stage-8-Audit-Pass-3-Lehre. */
.songs-search-wrapper {
  display: none;
  position: relative;
  padding: .35rem .25rem .5rem;
  margin-bottom: .25rem;
  border-bottom: 1px solid var(--border-soft);
}
.songs-search-wrapper.is-visible {
  display: block;
}
.songs-search {
  width: 100%;
  font: inherit;
  font-size: .9rem;
  padding: .4rem 2rem .4rem .65rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-sunken);
  color: var(--text);
  outline: none;
  transition: border-color .12s var(--ease), background .12s var(--ease);
  /* A7-Audit-Pass-Korrektur 2026-05-11: appearance:none (standard) zusätzlich
     zu -webkit- + -moz-Prefixes (analog pre-existing pattern line 543, 1268).
     iOS default rounded styling unterdrücken. */
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
}
.songs-search:focus-visible {
  border-color: var(--accent);
  background: var(--bg);
}
.songs-search::placeholder {
  color: var(--text-subtle);
  opacity: .5;
}
.songs-search-clear {
  position: absolute;
  right: .6rem;
  top: 50%;
  /* A7-Audit-Pass-Korrektur 2026-05-11: -50% (echte vertical centering)
     statt -25% (Math-Fehler ergibt ~0.475rem Offset nach unten vom Input-
     Center). Standard-Pattern für absolute-mid-vertical. */
  transform: translateY(-50%);
  width: 1.6rem;
  height: 1.6rem;
  padding: 0;
  border: none;
  background: none;
  color: var(--text-subtle);
  cursor: pointer;
  font-size: 1.2rem;
  line-height: 1;
  border-radius: 4px;
  transition: color .12s var(--ease), background .12s var(--ease);
}
.songs-search-clear:hover {
  color: var(--text);
  background: var(--bg-sunken);
}

/* Empty-State bei aktivem Filter ohne Match. role="status" für SR-Live-Region. */
.songs-empty-state {
  padding: .75rem 1rem;
  color: var(--text-subtle);
  font-size: .85rem;
  font-style: italic;
  text-align: center;
  list-style: none;
}
.songs-menu .songs-action:hover {
  background: var(--accent-soft);
  border-color: var(--accent);
}
#songs-list {
  list-style: none;
  margin: .25rem 0 0;
  padding: 0;
  max-height: 60vh;
  overflow-y: auto;
}
.song-item {
  display: flex;
  align-items: stretch;
  border-radius: 4px;
  margin-bottom: 1px;
}
.song-item:hover { background: var(--bg-sunken); }
.song-item.is-active {
  background: var(--accent-soft);
}
.song-item.is-active .song-switch { color: var(--accent-strong, var(--accent)); font-weight: 600; }
.song-switch {
  flex: 1 1 auto;
  text-align: left;
  padding: .5rem .75rem;
  background: transparent;
  border: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  border-radius: 4px;
}
.song-delete {
  flex: 0 0 auto;
  padding: 0 .65rem;
  background: transparent;
  border: none;
  color: var(--text-subtle);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  border-radius: 4px;
  transition: color .12s var(--ease), background .12s var(--ease);
}
.song-delete:hover {
  color: #c44;
  background: rgba(204, 68, 68, .1);
}

/* ─── Refinement B Phase 3 — View-Settings-Gear ─────────────────────────
   Gear-Icon-Button in der Topbar nach Songs-Picker. Click öffnet
   .view-popover mit Bar-Length + Bars-per-Line. position:relative auf
   dem Wrapper macht ihn zum Anchor für das absolute Popover. */
.view-popover-wrap {
  position: relative;
  display: inline-flex;
}
#view-toggle[data-open] {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
}
.view-popover {
  position: absolute;
  top: calc(100% + .35rem);
  left: 50%;
  transform: translateX(-50%) scale(.97);
  transform-origin: top center;
  min-width: 16rem;
  max-width: 90vw;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .18);
  padding: .75rem;
  z-index: 100;
  opacity: 0;
  pointer-events: none;
  transition: opacity .12s var(--ease), transform .12s var(--ease);
}
.view-popover[data-open] {
  opacity: 1;
  transform: translateX(-50%) scale(1);
  pointer-events: auto;
}
.view-popover-title {
  font-size: .68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--text-muted);
  margin: 0 0 .5rem;
  padding: 0 .25rem;
}
.view-row {
  display: flex;
  flex-direction: column;
  gap: .35rem;
  padding: .5rem .25rem;
}
.view-row + .view-row { border-top: 1px solid var(--border-soft); }
.view-row-label {
  font-size: .82rem;
  font-weight: 500;
  color: var(--text);
}
.view-popover select {
  width: 100%;
  background: var(--bg-page);
  color: var(--text);
  border: 1px solid var(--border);
  padding: .4rem .65rem;
  font: inherit;
  font-size: .9rem;
  border-radius: 6px;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'><path d='M3 5l3 3 3-3' stroke='%23A48455' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right .55rem center;
  background-size: 11px;
  padding-right: 1.85rem;
}
:root .view-popover select {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'><path d='M3 5l3 3 3-3' stroke='%238A6F47' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}
.view-popover select:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.view-row-hint {
  font-size: .7rem;
  color: var(--text-subtle);
  line-height: 1.35;
  font-style: italic;
}

/* Refinement A Phase 2 — Reset-↻-Button am aktiven Song. Sitzt zwischen
   .song-switch und .song-delete, gleicher kompakter Touch-Frame, aber
   neutral (kein roter Hover wie .song-delete) — ↻-Icon ist semantisch
   klar destruktiv-genug, der confirmDialog rendert die Sicherheitsstufe. */
.song-reset {
  flex: 0 0 auto;
  padding: 0 .5rem;
  background: transparent;
  border: none;
  color: var(--text-subtle);
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  border-radius: 4px;
  transition: color .12s var(--ease), background .12s var(--ease);
}
.song-reset:hover {
  color: var(--danger-text);
  background: var(--danger-soft);
}
.song-reset svg { display: block; }

/* ─── Refinement A — Desktop-Edit-Popover ──────────────────────────────────
   Toggle "Edit ▾" + Dropdown-Menu mit seltenen Edit-Aktionen, die chrome.js
   per mountPopover() aus der Toolbar ins Menu umhängt. Pattern matched
   .songs-picker (position:relative + absolute Menu). Auf Mobile-Viewport
   (≤720px coarse) wird der Toggle ausgeblendet — dort übernimmt der
   ⋯-Overflow weiterhin. */
.edit-popover {
  position: relative;
  display: inline-flex;
}
.edit-toggle {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .45rem .75rem;
  background: var(--bg-sunken);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  color: inherit;
  font: inherit;
  font-size: .82rem;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition: background .12s var(--ease), border-color .12s var(--ease);
}
.edit-toggle:hover { border-color: var(--border); }
.edit-toggle .icon { width: 14px; height: 14px; flex: 0 0 auto; }
.edit-toggle .icon-chevron { transition: transform .15s var(--ease); }
.edit-toggle[aria-expanded="true"] .icon-chevron { transform: rotate(180deg); }

.edit-menu {
  position: absolute;
  top: calc(100% + .25rem);
  right: 0;
  min-width: 14rem;
  max-width: 22rem;
  max-height: calc(100vh - 5rem);
  overflow-y: auto;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .18);
  padding: .35rem;
  z-index: 100;
  transform-origin: top right;
  transform: scale(.97);
  opacity: 0;
  pointer-events: none;
  transition: opacity .12s var(--ease), transform .12s var(--ease);
}
.edit-menu[data-open] {
  opacity: 1;
  transform: scale(1);
  pointer-events: auto;
}

/* Items im Edit-Menu: full-width Listen-Optik, analog Mobile-Overflow.
   Selektor matched die hineingehängten <button>-Children (remove-bar,
   clear-bar, etc.) — die behalten ihre Original-Listener und ihre
   eigenen Inhalte (Icon + Text-Span). */
.edit-menu button {
  width: 100%;
  height: auto;
  min-height: 36px;
  justify-content: flex-start;
  padding: .5rem .75rem;
  margin: .1rem 0;
  border-radius: 6px;
  background: transparent;
  border: 1px solid transparent;
  color: var(--text);
}
.edit-menu button:hover {
  background: var(--bg-sunken);
  color: var(--accent);
}
/* Toggle-Buttons im Menu: pressed-State darf weiterhin sichtbar sein. */
.edit-menu button[aria-pressed="true"] {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
}
.edit-menu .ovf-section-label {
  font-size: .68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--text-muted);
  padding: .55rem .75rem .2rem;
  user-select: none;
}
.edit-menu .ovf-section-label:first-child {
  padding-top: .15rem;
}
.edit-menu .ovf-sep {
  height: 1px;
  background: var(--border-soft);
  margin: .3rem .25rem;
}

.btn-group {
  display: flex;
  gap: .15rem;
  padding: .25rem;
  background: var(--bg-sunken);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
}

button {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  background: transparent;
  color: var(--text);
  border: 1px solid transparent;
  padding: .42rem .75rem;
  font: inherit;
  font-size: .82rem;
  font-weight: 500;
  cursor: pointer;
  border-radius: 5px;
  transition: background .15s var(--ease), color .15s var(--ease), transform .08s var(--ease), box-shadow .15s var(--ease);
  white-space: nowrap;
  user-select: none;
}

button:hover {
  background: var(--secondary-soft);
  color: var(--text);
}

/* Press-Feedback: translate + dezenter BG-Tint, damit auch Touch-User
   einen haptischen Click spüren. Toggle-Buttons im aria-pressed=true /
   .is-active-State sind ausgenommen, weil deren BG durch den Toggle-State
   bestimmt ist und nicht überschrieben werden soll. */
button:active { transform: translateY(1px); }
button:active:not([aria-pressed="true"]):not(.is-active):not(.btn-danger) {
  background: var(--secondary-soft);
}
button.btn-danger:active {
  background: var(--danger);
  border-color: var(--danger);
  color: #FFFFFF;
}

button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

button:disabled,
button[disabled],
.icon-btn:disabled,
.icon-btn[disabled] {
  opacity: .35;
  cursor: not-allowed;
  pointer-events: none;
}

/* B1 — Dark-Mode disabled-Sichtbarkeit. Original opacity .35 auf bg-elevated
   #221E1A ergibt für default text-color (#F2EBDC) effektiv ~#6B665E ≈ 2.86:1
   Kontrast — Disabled-State ist im Dark-Theme schwer erkennbar. opacity .5
   ergibt effektiv ~#8A857B ≈ 4.4:1 — visible aber weiterhin als „dimmed"
   erkennbar (dimmer als active button). NICHT WCAG-Compliance-Fix:
   WCAG 1.4.3/1.4.11 exempt inactive UI components von Kontrast-Anforderungen.
   Reine UX-Verbesserung. Light-Mode bleibt .35 (cream-bg + dunkler text =
   ~2:1 mit .35; auch nicht WCAG-pflichtig, aber kosmetisch ok).
   Audit-Pass-2 2026-05-10: original color-Override auf text-subtle entfernt
   weil das den Kontrast SCHLECHTER machte (text-subtle ist dunkler als
   default text → blendet näher zum bg). */
[data-theme="dark"] button:disabled,
[data-theme="dark"] button[disabled],
[data-theme="dark"] .icon-btn:disabled,
[data-theme="dark"] .icon-btn[disabled] {
  opacity: .5;
}

button .icon {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

/* Primary — accent-filled. Wird in Modals (confirmDialog Cancel,
   feedbackDialog Send) genutzt — dort ist der Filled-CTA-Look funktional
   richtig (klare Hauptaktion). In der Toolbar (#add-bar) wird das per
   spezifischerem Selektor zu "Soft Tonal" gedämpft (siehe unten). */
button.btn-primary {
  background: var(--accent);
  color: var(--accent-on);
  font-weight: 600;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, .18) inset,
    0 2px 6px var(--accent-glow);
}

button.btn-primary:hover {
  background: var(--accent-hover);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, .22) inset,
    0 4px 14px var(--accent-glow);
}

/* Toolbar-Override: Add-Bar als "Soft Tonal" — pastelliger Pill statt
   filled-Fläche. Logo (Brand-Anker) und Add-Bar (Primary CTA) konkurrieren
   sonst optisch um Aufmerksamkeit auf gleicher Topbar-Ebene. Soft Tonal
   bleibt klar als CTA erkennbar (Akzent-Text + Akzent-Hauch-bg), aber
   tritt visuell hinter das Logo zurück. Hover füllt zu vollem Akzent —
   gibt klares Activation-Feedback. */
.actions #add-bar.btn-primary {
  background: var(--accent-soft);
  color: var(--accent);
  border-color: transparent;
  box-shadow: none;
}
.actions #add-bar.btn-primary:hover {
  background: var(--accent);
  color: var(--accent-on);
  box-shadow: 0 2px 6px var(--accent-glow);
}
.actions #add-bar.btn-primary:active {
  background: var(--accent-hover);
  color: var(--accent-on);
}

/* Danger — destruktive Aktionen (Reset). Gedämpft-roter Text auf transparent;
   das Trash-Icon trägt die destruktive Bedeutung, Farbe ist flüsternder
   Zweit-Cue. Border bleibt aus — kein Outline-Schrei. Hover/Active füllen
   voll rot mit Weiß, damit der Aktionsmoment trotzdem klar destruktiv wirkt. */
button.btn-danger {
  color: var(--danger-text);
  background: transparent;
}
button.btn-danger:hover {
  background: var(--danger);
  border-color: var(--danger);
  color: #FFFFFF;
}
button.btn-danger:focus-visible {
  outline-color: var(--danger);
}

/* Theme-Toggle (icon-only) */
.icon-btn {
  width: 36px;
  height: 36px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-sunken);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  color: var(--text);
  cursor: pointer;
  transition: background .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease), transform .15s var(--ease);
}

.icon-btn:hover {
  background: var(--secondary-soft);
  border-color: var(--border);
  color: var(--accent);
}

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

.icon-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.icon-btn .icon { width: 16px; height: 16px; }

/* Icon-Btn innerhalb btn-group: das Group-Container liefert schon die "Tray"-
   Optik, das innere icon-btn braucht keinen eigenen Background. */
.btn-group > .icon-btn {
  background: transparent;
  border-color: transparent;
}
.btn-group > .icon-btn:hover {
  background: var(--secondary-soft);
  border-color: transparent;
}

/* F6 — Toggle-Button Active-State (aria-pressed=true | is-active class).
   Bisher nur für #toggle-chords genutzt, aber generisch geschrieben für
   weitere Toggles in der Edit-Group. Accent-soft als Background macht den
   "ich bin gerade an"-Status klar erkennbar ohne fancy Animation. */
.btn-group > button.is-active,
.btn-group > button[aria-pressed="true"] {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent-strong, var(--accent));
}

/* A8 (ADR-38) Stage 1 — Repeat-Toolbar-Cluster.
   #repeat-start / #repeat-end: kompakte Toggle-Buttons mit Glyph-Span statt
   SVG-Icon (|: und :| sind reine Text-Glyphs, kein eigenes Icon nötig).
   Aktivierung ist active-bar-gated — disabled wenn keine Bar selektiert. */
#repeat-start, #repeat-end {
  font-family: ui-monospace, SFMono-Regular, "Cascadia Mono", Menlo, Consolas, monospace;
  font-weight: 800;
  letter-spacing: -0.02em;
}
#repeat-start .repeat-glyph,
#repeat-end .repeat-glyph {
  display: inline-block;
  padding: 0 .15rem;
  font-size: 1.05rem;
  line-height: 1;
}
#repeat-start[disabled], #repeat-end[disabled],
#repeat-count[disabled] {
  opacity: 0.4;
  cursor: not-allowed;
}
/* #repeat-count number-input — schmal, neben dem :|-Button.
   Browser-default-spinner ausgeblendet für cleane optics. */
.repeat-count-input {
  height: 36px;
  width: 3.5rem;
  padding: 0 .35rem;
  border: 1px solid var(--secondary-line);
  border-radius: 6px;
  background: var(--bg-sunken);
  color: var(--text);
  font: inherit;
  font-size: .85rem;
  text-align: center;
  -moz-appearance: textfield;
}
.repeat-count-input::-webkit-outer-spin-button,
.repeat-count-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.repeat-count-input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* A8 (ADR-38) Stage 3 — Jump-Marker-Select-Dropdown.
   Native <select> mit zwei optgroups (Anchors + Directives). Active-bar-
   gated analog volta-number-input. Reset zu Placeholder nach Change-Event
   damit User immer neuen Marker setzen kann ohne explicit zu cleanen. */
.jump-marker-select {
  height: 36px;
  padding: 0 .5rem;
  border: 1px solid var(--secondary-line);
  border-radius: 6px;
  background: var(--bg-sunken);
  color: var(--text);
  font: inherit;
  font-size: .85rem;
  cursor: pointer;
  max-width: 11rem;
}
.jump-marker-select:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.jump-marker-select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* visually-hidden für screen-reader-only Labels in den Repeat-Buttons.
   Pattern aus footer.css repliziert, lokal duplikat-tolerant (Cascade
   gewinnt egal welche Datei zuletzt lädt). */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  white-space: nowrap;
  border: 0;
}

/* Sun/moon umschalten je nach Theme — der jeweils ANDERE wird gezeigt */
.icon-btn .ico-sun  { display: none; }
.icon-btn .ico-moon { display: block; }
[data-theme="dark"] .icon-btn .ico-sun  { display: block; }
[data-theme="dark"] .icon-btn .ico-moon { display: none; }

/* Language toggle — Globe + ISO-Code ("EN" / "DE") */
.lang-btn {
  height: 36px;
  padding: 0 .55rem;
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  background: var(--bg-sunken);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  color: var(--text);
  cursor: pointer;
  font: inherit;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .08em;
  transition: background .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease), transform .15s var(--ease);
}

.lang-btn:hover {
  background: var(--secondary-soft);
  border-color: var(--border);
  color: var(--accent);
}

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

.lang-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.lang-btn .icon { width: 14px; height: 14px; flex-shrink: 0; }
.lang-btn .lang-current { line-height: 1; font-variant-numeric: tabular-nums; }


/* ─── Mobile-Overflow-Toggle (≤720px, source: ehemalig styles.css:2206) ─── */
/* ─── Mobile Overflow-Toggle / -Menu — Default versteckt auf Desktop ──────── */
.overflow-toggle { display: none; }
.overflow-menu { display: none; position: absolute; }

/* Refinement A — Edit-Popover auf Mobile-Phone-Viewport (≤720px) hidden;
   dort übernimmt der ⋯-Overflow. iPad (>720px coarse) sieht das Edit-▾.
   chrome.js syncToggleVisibility ergänzt das via hidden-Attribut, CSS ist
   defensiver Fallback für initial-state vor JS-Load. */
@media (max-width: 720px) {
  .edit-popover { display: none; }
}

/* ─── Mobile-Toolbar-M2-Grid (≤720px, source: ehemalig styles.css:2563) ─── */
/* ─── Mobile-Toolbar-M2 (2026-05-09) ────────────────────────────────────────
   Phone (≤720px coarse) bekommt eine bewusste 2-Zeilen-Komposition (iOS
   Notes / Bear / Apple Music Pattern):

     Zeile 1 (Title-Bar): Brand-Logo links · Song-Title zentriert · ⋯ rechts
     Zeile 2 (Action-Strip): Undo+Redo links · Add-Bar rechts

   Tablet (≥721px coarse) revertet die Mobile-spezifischen Änderungen — iPad
   bekommt das volle Desktop-Layout. 44px-Touch-Targets aus dem `pointer:
   coarse`-Block bleiben in beiden Fällen.

   Implementation: `.actions-strip` wraps die History + Edit btn-groups im
   HTML. Default `display: contents` lässt die btn-groups direkte `.actions`-
   Children sein (Desktop-Flex unverändert). Auf Phone wird `.topbar` zu
   einem 3-Spalten-2-Zeilen-CSS-Grid; `.actions` bleibt `display: contents`,
   sodass Songs-Picker, Overflow-Toggle und actions-strip direkt addressiert
   werden können. ─────────────────────────────────────────────────────────── */

/* Default: actions-strip ist transparent für den Layout-Flow. */
.actions-strip { display: contents; }

@media (pointer: coarse) and (max-width: 720px) {
  /* Topbar wird Grid: drei Spalten (auto/1fr/auto), zwei Zeilen. */
  .topbar {
    display: grid;
    grid-template-columns: auto 1fr auto;
    grid-template-rows: auto auto;
    column-gap: .5rem;
    row-gap: .5rem;
    align-items: center;
  }
  /* .actions hat keinen eigenen Layout-Container mehr — alle Children
     werden direkte Grid-Items. */
  .actions { display: contents; }

  /* Zeile 1 — Title-Bar */
  .brand           { grid-column: 1; grid-row: 1; }
  .songs-picker    {
    grid-column: 2;
    grid-row: 1;
    min-width: 0;        /* erlaubt Title-Truncate */
    justify-self: stretch;
  }
  .songs-toggle {
    width: 100%;
    justify-content: flex-start;
  }
  .songs-active-title {
    max-width: none;     /* überschreibt 8rem aus dem coarse-Block */
    flex: 1 1 auto;
    min-width: 0;
  }
  .overflow-toggle {
    grid-column: 3;
    grid-row: 1;
    display: inline-flex;   /* aus dem coarse-Block schon, hier nochmal */
  }

  /* Zeile 2 — Action-Strip: spannt alle 3 Spalten, eigenes Flex drin.
     Recovery (Undo/Redo) und Primary (Add-Bar) gruppiert in der Mitte
     statt an die Extreme gezogen — wirkt sonst lehrer als designed. */
  .actions-strip {
    display: flex;
    grid-column: 1 / -1;
    grid-row: 2;
    align-items: center;
    justify-content: center;
    gap: .75rem;
  }

  /* File-btn-group hat nach DOM-Move zwar keine Button-Children mehr,
     aber Whitespace-Text-Nodes vom HTML-Indent bleiben — :empty matcht
     nicht. :has(button) ist die korrekte Probe. Plus icon-btn-Variante
     für Defensive (z.B. wenn künftig icon-btns drin landen). */
  .actions > .btn-group:not(:has(button)):not(:has(.icon-btn)) {
    display: none;
  }

  /* Theme/Lang sind eh durch DOM-Move ins Overflow verschwunden, aber
     defensive: falls JS nicht läuft, hidden via Media-Query. Selektor
     auf `.actions >` qualifizieren, damit die Buttons IM Overflow-Menü
     (nach Move) nicht auch ungewollt versteckt werden. */
  .actions > #theme-toggle,
  .actions > #lang-toggle,
  .actions > #feedback-btn { display: none; }

  /* Add-Bar + Duplicate-Bar in der Action-Strip beide icon-only auf Phone:
     symmetrisch zu Undo/Redo, kompakt, alle vier Buttons in der zweiten
     Zeile haben dieselbe Form. Tooltips über title-attr bleiben für
     Long-Press-Discovery. */
  #add-bar span,
  #duplicate-bar span { display: none; }
  #add-bar,
  #duplicate-bar {
    width: 44px;
    padding: 0;
    justify-content: center;
  }
}

@media (pointer: coarse) and (min-width: 721px) {
  /* Tablet zurück zum Desktop-Layout. Brand-Text + Wortmarke wieder da,
     kein Overflow-Toggle, alle btn-groups inline. 44px-Touch-Targets
     bleiben (coarse-Block-Erbe). */
  .brand-text       { display: flex; }
  .brand-text small { display: block; }
  .overflow-toggle  { display: none; }
  .btn-group        { flex-wrap: nowrap; }
  .songs-active-title { max-width: 12rem; }
}


/* ═══════════════════════════════════════════════════════════════════════════
   Read-Only-Distribution (Phase 7b) — body.is-read-only Toolbar-Bundle
   ───────────────────────────────────────────────────────────────────────────
   Multi-Komponente-Bundle: alle Toolbar-Buttons + Library + Edit-Toggle +
   Share + Songs + sheet-music-chips → display: none im Read-Only-Modus.
   Plan-Convention: KOMPLETTE Regel in dominanter Komponente (topbar) statt
   Property-Wiederholung in 19 Sub-Files.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Edit-UI komplett hidden im Read-Only: Toolbar-Buttons + Library + Share
   + Music-Chips-Edit (sheet-actions). Keine Edit-Möglichkeit, keine Verwirrung. */

body.is-read-only #add-bar,
body.is-read-only #remove-bar,
body.is-read-only #clear-bar,
body.is-read-only #duplicate-bar,
body.is-read-only #copy-bar,
body.is-read-only #paste-bar,
body.is-read-only #toggle-chords,
body.is-read-only #toggle-sections,
body.is-read-only #toggle-palm-mute,
body.is-read-only #toggle-let-ring,
body.is-read-only #toggle-repeats,
body.is-read-only #repeat-start,
body.is-read-only #repeat-end,
body.is-read-only #repeat-count,
body.is-read-only #toggle-voltas,
body.is-read-only #volta-number,
body.is-read-only #toggle-jump-markers,
body.is-read-only #jump-marker,
body.is-read-only #transpose,
body.is-read-only #edit-toggle,
body.is-read-only #overflow-toggle,
body.is-read-only #share-link,
body.is-read-only #songs-toggle,
body.is-read-only #undo,
body.is-read-only #redo,
body.is-read-only #open-file,
body.is-read-only .sheet-music-chips {
  display: none !important;
}


/* ═══════════════════════════════════════════════════════════════════════════
   Distributed @media-Overrides (Phase 7c) — topbar-bezogene Coarse + Responsive
   ───────────────────────────────────────────────────────────────────────────
   Konvention (Plan v6 P3): Component-spec coarse/responsive Overrides in der
   Komponente. KEINE Centralised-Mobile.css. Audit via grep -rn '@media' styles/.
   ═══════════════════════════════════════════════════════════════════════════ */

@media (max-width: 720px) {
  .brand-text small { display: none; }
  .topbar { padding: .75rem 1rem; gap: .75rem; }
}

@media (pointer: coarse) {
  /* Topbar-Buttons HIG-konform 44×44px (Topbar-Tap hat keinen
     horizontal-scroll-Druck, kann großzügiger sein als die Cells). */
  .icon-btn {
    width: 44px;
    height: 44px;
  }
  .btn-group > button { min-height: 44px; padding: .55rem .85rem; }
  /* Lang-Toggle hat eigene Klasse (nicht .icon-btn), separat hochziehen */
  .lang-btn { height: 44px; padding: 0 .85rem; }

  /* View-Settings-Gear Select-Dropdown (im Popover) — Touch + iOS no-zoom */
  .view-popover select { min-height: 44px; font-size: 1rem; }

  /* A8 (ADR-38) — Repeat-Count, Volta-Number und Jump-Marker-Inputs/Select
     brauchen 44px Touch-Targets auf Coarse-Pointers (WCAG 2.2 SC 2.5.8).
     Browser-Defaults für <input type="number"> + <select> sind ~32px ohne
     explicit min-height. font-size 1rem verhindert iOS-Auto-Zoom beim Focus.
     Audit 2026-05-14. */
  #repeat-count,
  #volta-number,
  #jump-marker {
    min-height: 44px;
    font-size: 1rem;
  }

  /* F8 — Songs-Picker auf Touch: 44px-Targets, schmaleres Toggle-Label damit
     Topbar nicht overflowt, breiteres Menu-Min für Touch-Tap-Komfort. */
  .songs-toggle {
    min-height: 44px;
    padding: .55rem .7rem;
  }
  .songs-active-title { max-width: 8rem; }
  .songs-menu { min-width: 14rem; max-width: calc(100vw - 2rem); }
  .song-switch  { min-height: 44px; }
  .song-delete  { min-width: 44px; min-height: 44px; padding: 0 .85rem; }
  .songs-menu .songs-action { min-height: 44px; padding: .7rem .75rem; }

  /* A7 (Stage 9) — Library-Search auf Touch: WCAG 2.2 SC 2.5.8 (min 24px,
     Apple-HIG 44px) + iOS-Auto-Zoom-Prevention via font-size ≥16px (1rem). */
  .songs-search {
    min-height: 44px;
    font-size: 1rem;
    padding: .55rem 2.75rem .55rem .75rem;
  }
  .songs-search-clear {
    width: 2.5rem;
    height: 2.5rem;
    right: .5rem;
    font-size: 1.4rem;
    /* Audit-Pass-Korrektur: -50% (echte vertical centering) statt -30%. */
    transform: translateY(-50%);
  }

  /* ─── Mobile-Topbar-Refactor — Overflow-Menu ──────────────────────────── */
  /* Brand: nur Logo, kein Wortmarken-Text */
  .brand-text { display: none; }

  /* ⋯-Trigger sichtbar, ans rechte Ende der Topbar */
  .overflow-toggle {
    display: inline-flex;
    margin-left: auto;
  }

  /* Defensive: falls JS-DOM-Move scheitert, wraps die Topbar gracefully
     statt horizontal zu overflowen. */
  .btn-group { flex-wrap: wrap; }

  /* Overflow-Container — Anchor unter dem ⋯-Button (top-right der Topbar).
     position: relative auf .topbar gibt es schon implizit nicht — daher
     positionieren wir relativ zum nächsten relativen Vorfahr. .topbar ist
     position: sticky, was als positioning-context für absolute Children
     fungiert. */
  .overflow-menu {
    top: calc(100% + .35rem);
    right: .75rem;
    min-width: 16rem;
    max-width: 90vw;
    max-height: calc(100vh - 5rem);
    overflow-y: auto;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: 0 8px 24px rgba(0, 0, 0, .18);
    padding: .35rem;
    z-index: 20;
    transform-origin: top right;
    transform: scale(.97);
    opacity: 0;
    transition: opacity .12s var(--ease), transform .12s var(--ease);
    pointer-events: none;
  }
  .overflow-menu[data-open] {
    display: block;
    opacity: 1;
    transform: scale(1);
    pointer-events: auto;
  }

  /* Items im Menu: full-width, links-bündig, großzügig tappbar */
  .overflow-menu button,
  .overflow-menu .icon-btn,
  .overflow-menu .lang-btn {
    width: 100%;
    height: auto;
    min-height: 44px;
    justify-content: flex-start;
    padding: .65rem .9rem;
    margin: .1rem 0;
    border-radius: 6px;
    background: transparent;
    border: 1px solid transparent;
    color: var(--text);
  }
  .overflow-menu button:hover,
  .overflow-menu .icon-btn:hover,
  .overflow-menu .lang-btn:hover {
    background: var(--bg-sunken);
    color: var(--accent);
  }
  /* .btn-primary im Menu auf neutrale Listen-Optik (kein Filled-Look in
     einer Liste). .btn-danger-Selektoren wurden mit A2 entfernt — seit
     Reset ins Songs-Menü gewandert ist, trägt kein Element im Mobile-
     Overflow mehr btn-danger. */
  .overflow-menu button.btn-primary {
    background: transparent;
    color: var(--text);
    box-shadow: none;
    font-weight: 500;
  }

  /* Visuelle Section-Separators (kein neuer i18n-Text) */
  .overflow-menu .ovf-sep {
    height: 1px;
    background: var(--border-soft);
    margin: .3rem .25rem;
  }

  /* Section-Caption-Labels über jeder Gruppe (2026-05-08).
     Klein, uppercase, muted — gibt mobile Usern Orientierung ohne die
     visuelle Ruhe der Liste zu stören. */
  .overflow-menu .ovf-section-label {
    font-size: .68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--text-muted);
    padding: .55rem .9rem .2rem;
    user-select: none;
  }
  /* Erste Section: kein extra Top-Padding, weil Menu schon padding hat */
  .overflow-menu .ovf-section-label:first-child {
    padding-top: .15rem;
  }

  /* iOS Safe-Area-Insets — `viewport-fit=cover` + `status-bar-style:
     black-translucent` rendert die App edge-to-edge unter Notch und
     Home-Indicator. `env(safe-area-inset-*)` liefert die nötigen Pads.
     `max()` schützt das Desktop-Layout (env() ist 0 auf nicht-notched
     Geräten — fallback bleibt auf den ursprünglichen Werten). */
  .topbar {
    padding-top:    max(.75rem, env(safe-area-inset-top));
    padding-left:   max(1rem,   env(safe-area-inset-left));
    padding-right:  max(1rem,   env(safe-area-inset-right));
  }
}
