/* Cadência — tokens de design.
   Direção aprovada em design_handoff_cadencia/README.md (tema claro).
   Os apelidos no fim do bloco existem para este commit não quebrar as regras
   que ainda usam os nomes antigos. Removem-se no commit 5, depois da varredura. */

:root {
  /* Cor */
  --fundo: #F4F2ED;
  --superficie: #FFFFFF;
  --superficie-2: #FBFAF7;
  --tinta: #16181B;
  --tinta-media: #4A4F53;
  --tinta-fraca: #6B6F73;
  --tinta-fantasma: #8B9095;
  --fio: rgba(22, 24, 27, .09);
  --fio-forte: rgba(22, 24, 27, .26);
  --dominio: #0E6B5C;
  --dominio-fraco: #E9F0EC;
  --agora: #E8703A;
  --trilho: #EAE7E0;
  --trilho-vazio: #EFEDE7;

  /* Sobre o bloco escuro do teclado e do transporte */
  --escuro-texto: #FFFFFF;
  --escuro-icone: #C9CDD0;
  --escuro-legenda: #9AA0A4;
  --escuro-tecla-preta: #1B1E21;
  --escuro-fio: rgba(255, 255, 255, .08);
  --escuro-fio-btn: rgba(255, 255, 255, .16);
  --escuro-fio-btn-hover: rgba(255, 255, 255, .40);
  --escuro-hover: rgba(255, 255, 255, .09);

  /* Capas, enquanto não houver imagem */
  --capa-1: #DCE5DF;
  --capa-2: #E4E1D6;
  --capa-3: #DEE2E9;
  --capa-4: #E8DFD9;

  /* Tipografia.
     As duas famílias entram no commit 2, com @font-face local — até lá as
     pilhas de reserva (Georgia e system-ui) é que respondem. */
  --fonte-titulo: 'Newsreader', Georgia, 'Times New Roman', serif;
  --fonte-ui: 'Instrument Sans', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
  --fonte-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;

  /* Forma */
  --raio-xg: 18px;
  --raio-g: 16px;
  --raio-m: 14px;
  --raio-btn: 12px;
  --raio-p: 11px;
  --raio-i: 10px;
  --raio-alt: 8px;
  --raio-barra: 3px;

  /* Sombra */
  --sombra-1: 0 1px 2px rgba(22, 24, 27, .06);
  --sombra-2: 0 4px 14px rgba(22, 24, 27, .24);

  /* Movimento */
  --transition-fast: 120ms ease;
  --transition-normal: 200ms ease;
  --transition-slow: 320ms ease;

  /* Apelidos temporários — remover no commit 5 */
  --bg-primary: var(--fundo);
  --bg-secondary: var(--superficie);
  --bg-tertiary: var(--trilho);
  --surface-score: var(--superficie);
  --text-primary: var(--tinta);
  --text-secondary: var(--tinta-fraca);
  --text-on-light: var(--tinta);
  --accent-blue: var(--dominio);
  --accent-green: var(--dominio);
  --accent-red: var(--agora);
  --accent-blue-glow: rgba(14, 107, 92, .22);
  --radius-sm: var(--raio-i);
  --radius-md: var(--raio-btn);
  --radius-lg: var(--raio-xg);
  --shadow-card: var(--sombra-2);
  --shadow-key: var(--sombra-1);
  --font-ui: var(--fonte-ui);
  --font-mono: var(--fonte-mono);
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --transition-fast: 0ms;
    --transition-normal: 0ms;
    --transition-slow: 0ms;
  }
}

/* Global Reset & Base */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  width: 100vw;
  min-height: 100vh;
  overflow-x: hidden;
  overflow-y: auto;
  background-color: var(--bg-primary);
  color: var(--text-primary);
  font-family: var(--font-ui);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  scroll-behavior: smooth;
  user-select: none;
}

/* Layout */
#app-container {
  display: flex;
  flex-direction: column;
  width: 100%;
  min-height: 100%;
  position: relative;
}

#main-view {
  display: flex;
  flex-direction: column;
  flex-grow: 1;
  width: 100%;
  min-height: 100%;
}

#piano-container {
  flex: 0 0 auto;
  width: 100%;
  min-height: 100px;
  height: 15vh;
  max-height: 160px;
  position: relative;
}

#piano-canvas {
  display: block;
  width: 100%;
  height: 100%;
}

#feedback-container {
  flex: 0 0 auto;
  height: 56px;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
}

#score-container {
  flex: 0 0 auto;
  margin: 0 16px 16px 16px;
  background-color: var(--surface-score);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
  overflow-y: hidden;
  overflow-x: auto;
  padding: 8px;
  color: var(--text-on-light);
  min-height: 200px;
}

#osmd-container {
  width: max-content;
  height: 100%;
}

#controls-bar {
  flex: 0 0 auto;
  min-height: 64px;
  background-color: var(--bg-secondary);
  position: relative;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  padding: 12px 24px;
  gap: 16px;
  box-shadow: 0 -2px 10px rgba(0,0,0,0.3);
}

/* Progress Bar */
#progress-container {
  width: 100%;
  height: 4px;
  background-color: var(--bg-tertiary);
  position: absolute;
  top: 0;
  left: 0;
}

#progress-bar {
  height: 100%;
  background-color: var(--accent-blue);
  width: 0%;
  transition: width 0.1s linear;
}

/* Controls Bar Elements */
.transport-group, .tempo-group, .hand-group, .measure-group {
  display: flex;
  align-items: center;
  gap: 12px;
}

/*
 * 52px, e não 36. O destino é um iPad: a mão volta do teclado e acerta o botão
 * sem que o olho saia da partitura. A Apple recomenda 44pt como mínimo; a
 * folga extra é para o dedo que chega de lado.
 */
.control-btn {
  background: var(--bg-tertiary);
  border: none;
  border-radius: var(--radius-md);
  width: 52px;
  height: 52px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-primary);
  font-size: 18px;
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}

.control-btn:hover {
  background: hsl(230, 15%, 28%);
}

.control-btn:active, .control-btn.active {
  background: var(--accent-blue);
  color: #fff;
}

/* Custom Range Slider */
input[type=range] {
  -webkit-appearance: none;
  width: 120px;
  background: transparent;
}

input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none;
  height: 16px;
  width: 16px;
  border-radius: 50%;
  background: var(--accent-blue);
  cursor: pointer;
  margin-top: -6px;
}

input[type=range]::-webkit-slider-runnable-track {
  width: 100%;
  height: 4px;
  cursor: pointer;
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
}

#bpm-display {
  min-width: 3ch;
  font-family: var(--font-mono);
}

/* Select */
select {
  background-color: var(--bg-tertiary);
  color: var(--text-primary);
  border: none;
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  font-family: var(--font-ui);
  font-size: 14px;
  cursor: pointer;
  outline: none;
}

/* Measure Indicator */
.mono-font {
  font-family: var(--font-mono);
  font-size: 14px;
  min-width: 90px;
  text-align: center;
}

/* A tela de entrada foi removida: o app abre no catálogo. O que ela tinha de
   próprio (o cartão, o ícone, a pilha de ações) saiu junto — os botões .btn
   continuam, porque servem ao aviso de erro e à tela de falha do catálogo. */

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 56px;
  padding: 16px 26px;
  border-radius: var(--radius-md);
  font-weight: 600;
  font-size: 16px;
  cursor: pointer;
  transition: all var(--transition-fast);
  border: 1px solid transparent;
  font-family: var(--font-ui);
  text-align: center;
}

/* Latão, e não azul: é o acento do app inteiro desde a barra do player. Uma
   tela de entrada com outra cor de destaque parece de outro programa. */
.btn-primary {
  background-color: var(--brass);
  color: var(--brass-ink);
}

.btn-primary:hover {
  filter: brightness(1.08);
}

.btn-secondary {
  background-color: transparent;
  border-color: var(--bg-tertiary);
  color: var(--text-primary);
}

.btn-secondary:hover {
  background-color: var(--bg-tertiary);
}

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

/* Audio Unlock Overlay */
#audio-unlock-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 90;
}

.pulse-anim {
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0% { transform: scale(1); box-shadow: 0 0 0 0 rgba(100, 181, 246, 0.7); }
  70% { transform: scale(1.05); box-shadow: 0 0 0 15px rgba(100, 181, 246, 0); }
  100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(100, 181, 246, 0); }
}

/* Loading Indicator */
#loading-indicator {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.7);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  z-index: 110;
  color: #fff;
}

.spinner {
  width: 48px;
  height: 48px;
  border: 4px solid var(--bg-tertiary);
  border-top-color: var(--accent-blue);
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-bottom: 16px;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* Feedback Animations */
@keyframes feedback-pop-in {
  0% { transform: scale(0); opacity: 0; }
  60% { transform: scale(1.3); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

@keyframes feedback-fade-out {
  0% { opacity: 1; }
  100% { opacity: 0; }
}

@keyframes feedback-shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-6px); }
  40% { transform: translateX(6px); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(4px); }
}

/* O sinal de acerto e erro fica sobre a linha do agora, no alto da partitura:
   é onde o olho de quem toca já está. A faixa própria que existia entre o
   teclado e a partitura sumiu — ninguém olhava para lá. */
.feedback-wrapper {
  position: absolute;
  left: calc(16px + (100% - 32px) * var(--linha-frac));
  top: 26px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 10px;
  pointer-events: none;
  z-index: 4;
}

.feedback-icon {
  font-size: 32px;
  font-weight: bold;
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.35));
}

/*
 * Sem `feedback-fade-out` embutido na animação. Quem decide quando o sinal sai
 * é o JS, porque a resposta depende do modo: no Modo de espera o X fica até a
 * nota certa chegar, já que foi ele quem parou a música.
 */
.feedback-correct {
  animation: feedback-pop-in var(--transition-fast) ease-out forwards;
}

.feedback-wrong {
  animation: feedback-pop-in var(--transition-fast) ease-out forwards,
             feedback-shake 300ms ease-in-out;
}

.feedback-fadeout {
  animation: feedback-fade-out var(--transition-normal) ease-in forwards;
}

.feedback-streak {
  background: rgba(0, 0, 0, 0.7);
  color: #fff;
  padding: 5px 13px;
  border-radius: 16px;
  font-family: var(--font-mono);
  font-weight: bold;
  font-size: 17px;
}

/* A faixa antiga do feedback não guarda mais nada. Some, em vez de reservar
   56px de altura — no iPad em pé essa altura faz falta à partitura. */
#feedback-container {
  height: 0;
  overflow: visible;
}

/* Utility Classes */
.hidden {
  display: none !important;
}

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

.fade-in {
  animation: fadeIn var(--transition-normal) forwards;
}

.fade-out {
  animation: fadeOut var(--transition-normal) forwards;
}

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes fadeOut {
  from { opacity: 1; }
  to { opacity: 0; }
}

/* Telas estreitas — iPad em pé, sobretudo.
 *
 * Aqui havia um `.control-btn { width: 32px }`, que encolhia o alvo de toque
 * justamente no aparelho onde se toca com o dedo. Era remendo para a barra
 * caber: ela carregava tudo, precisava de 1030px e estourava. Agora o que não
 * se usa tocando mora nos menus, a barra cabe, e o botão pode ter o tamanho
 * que a mão precisa. O que sobra aqui é só apertar o espaçamento.
 */
@media (max-width: 1024px) {
  #controls-bar {
    padding: 10px 12px;
    gap: 8px;
  }

  #app-bar {
    padding: 10px 12px;
    gap: 8px;
  }

  .mono-font {
    font-size: 12px;
  }
}

/* Library Overlay */
/* `fixed`, e não `absolute`: em `absolute` a sobreposição herdava a altura do
   conteúdo da página, que é menor que a tela, e as abas do catálogo paravam
   799px abaixo do topo numa tela de 1024 — com faixa morta embaixo delas. */
#library-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(18, 20, 31, 0.95);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  z-index: 105;
  display: flex;
  justify-content: center;
  align-items: center;
}

/* ==========================================================================
   O catálogo — Início, Músicas e Busca
   ========================================================================== */

.catalogo {
  width: 100%;
  max-width: 1100px;
  height: 100%;
  max-height: 100%;
  background: var(--bg-primary);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.catalogo-topo {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 18px 20px 10px;
}

.catalogo-topo h2 {
  font-size: 26px;
  font-weight: 600;
}

.catalogo-acoes {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 10px;
}

.catalogo-carregar {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 52px;
  padding: 12px 18px;
  border-radius: var(--radius-md);
  border: 1px solid var(--brass);
  background: transparent;
  color: var(--brass);
  font-family: var(--font-ui);
  font-size: 14px;
  cursor: pointer;
}

.catalogo-carregar:hover {
  background: hsla(35, 65%, 60%, 0.12);
}

.catalogo-carregar:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 3px;
}

.catalogo-carregar span {
  font-size: 17px;
  line-height: 1;
}

.catalogo-corpo {
  flex: 1 1 auto;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 0 20px 20px;
}

.catalogo-secao {
  margin-top: 22px;
}

.catalogo-secao h3 {
  font-size: 13px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-secondary);
  margin-bottom: 12px;
}

.catalogo-lista {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 12px;
}

/* O cartão é um <button>: responde a toque, teclado e leitor de tela. */
.library-card {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  min-height: 98px;
  padding: 12px 14px;
  text-align: left;
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  font-family: var(--font-ui);
  cursor: pointer;
  transition: border-color var(--transition-fast), background var(--transition-fast);
}

.library-card:hover {
  background: var(--bg-tertiary);
  border-color: var(--brass);
}

.library-card:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 3px;
}

.card-capa {
  flex: 0 0 auto;
  /* 3:2, que e a proporcao das fotos: assim elas entram sem corte violento.
     110pt de largura pedem 220px numa tela de dois pixels por ponto, e as
     capas sao baixadas a 400px justamente por isso. */
  width: 110px;
  height: 74px;
  border-radius: var(--radius-sm);
  background: linear-gradient(140deg, hsl(230, 20%, 26%), hsl(230, 25%, 14%));
  color: var(--brass);
  font-size: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.card-texto {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  flex: 1 1 auto;
}

.card-title {
  font-size: 15px;
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.card-composer {
  font-size: 12.5px;
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.card-difficulty {
  flex: 0 0 auto;
  font-size: 10px;
  letter-spacing: 1px;
  color: var(--brass);
}

/* Filtros */
.filtro-bloco {
  margin-top: 16px;
}

.filtro-rotulo {
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-secondary);
  margin-bottom: 8px;
}

.filtro-faixa {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.filtro-pilula {
  min-height: 44px;
  padding: 10px 16px;
  border-radius: 999px;
  border: 1px solid var(--bg-tertiary);
  background: var(--bg-secondary);
  color: var(--text-secondary);
  font-family: var(--font-ui);
  font-size: 13px;
  cursor: pointer;
}

.filtro-pilula.on {
  color: var(--brass);
  border-color: var(--brass);
  background: hsla(35, 65%, 60%, 0.12);
}

.filtro-pilula:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 2px;
}

/* Campo de busca */
.catalogo-campo-busca {
  width: 100%;
  margin-top: 8px;
  padding: 15px 16px;
  border-radius: var(--radius-md);
  border: 1px solid var(--bg-tertiary);
  background: var(--bg-secondary);
  color: var(--text-primary);
  font-family: var(--font-ui);
  font-size: 16px;
}

.catalogo-campo-busca:focus {
  outline: none;
  border-color: var(--brass);
}

.library-empty {
  color: var(--text-secondary);
  text-align: center;
  padding: 48px 20px;
}

/* Abas, embaixo, onde o polegar alcanca */
.catalogo-abas {
  flex: 0 0 auto;
  display: flex;
  border-top: 1px solid var(--bg-tertiary);
  background: var(--bg-secondary);
}

.catalogo-aba {
  flex: 1;
  min-height: 60px;
  padding: 10px 4px 12px;
  border: none;
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font-ui);
  font-size: 11px;
  cursor: pointer;
}

.catalogo-aba .glifo {
  display: block;
  font-size: 20px;
  margin-bottom: 3px;
}

.catalogo-aba.on {
  color: var(--brass);
}

.catalogo-aba:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: -3px;
}

/* Piano Roll Container */
#piano-roll-container {
  width: 100%;
  height: 100%;
  background-color: var(--bg-primary);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

#piano-roll-container canvas {
  display: block;
  width: 100%;
  height: 100%;
}

/* ==========================================================================
   Interface de toque — barra superior, linha do agora e menus
   ========================================================================== */

:root {
  --brass: hsl(35, 65%, 60%);
  --brass-ink: hsl(230, 30%, 12%);
  /*
   * Onde a linha do agora fica, em fração da largura visível da partitura.
   * O usuário escolhe entre 0.5 (meio) e 0.35 (um terço, sobra leitura à
   * frente). O followCursor() do renderer lê exatamente este mesmo número —
   * se os dois discordarem, a linha deixa de cair sobre a nota que soa.
   */
  --linha-frac: 0.5;
}

/* Barra superior --------------------------------------------------------- */
#app-bar {
  flex: 0 0 auto;
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  min-height: 72px;
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--bg-tertiary);
}

#app-bar .bar-right {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 10px;
}

.icon-btn {
  width: 52px;
  height: 52px;
  border-radius: var(--radius-md);
  border: 1px solid var(--bg-tertiary);
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  font-size: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: color var(--transition-fast), border-color var(--transition-fast);
}

.icon-btn:hover { color: var(--text-primary); }

.icon-btn.on {
  color: var(--brass);
  border-color: var(--brass);
}

/* Mão apagada: a nota continua na tela, mas o app não a toca nem a cobra. */
.hand-btn:not(.on) { opacity: 0.45; }

.fab {
  position: absolute;
  left: 50%;
  top: 10px;
  transform: translateX(-50%);
  width: 72px;
  height: 72px;
  border-radius: 50%;
  border: none;
  background: var(--brass);
  color: var(--brass-ink);
  font-size: 26px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 4;
  box-shadow: 0 10px 26px -8px hsla(35, 65%, 50%, 0.7);
}

.fab:hover { filter: brightness(1.08); }

.icon-btn:focus-visible,
.fab:focus-visible,
.control-btn:focus-visible,
.menu-item:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 3px;
}

/* Partitura e a linha do agora -------------------------------------------- */
#score-stage {
  position: relative;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-height: 200px;
}

#score-stage #score-container {
  flex: 1 1 auto;
}

/* O 16px é a margem lateral do #score-container: a linha tem de cair sobre a
   caixa que rola, não sobre a largura da tela. */
#play-line {
  position: absolute;
  left: calc(16px + (100% - 32px) * var(--linha-frac));
  top: 0;
  bottom: 16px;
  width: 3px;
  transform: translateX(-50%);
  background: var(--brass);
  box-shadow: 0 0 0 10px hsla(35, 65%, 60%, 0.12);
  pointer-events: none;
  z-index: 3;
}

#play-line::before {
  content: "";
  position: absolute;
  left: 50%;
  top: -1px;
  transform: translateX(-50%);
  border-left: 9px solid transparent;
  border-right: 9px solid transparent;
  border-top: 11px solid var(--brass);
}

/* No modo MIDI não há partitura para alinhar, então a linha sai. */
#score-stage.modo-midi #play-line { display: none; }

/* Fichas de estado -------------------------------------------------------- */
.chip {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--text-primary);
  background: var(--bg-tertiary);
  border-radius: 999px;
  padding: 9px 14px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

#measure-indicator.chip,
#bpm-display.chip {
  min-width: 0;
}

.stats {
  display: flex;
  gap: 8px;
}

.tally {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

.dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  display: inline-block;
}

.dot-good { background: var(--accent-green); }
.dot-bad  { background: var(--accent-red); }
.dot-none { background: var(--text-secondary); }

/* Menus suspensos --------------------------------------------------------- */
/*
 * O que não se toca durante a execução mora aqui. Foi assim que a barra
 * deixou de precisar de 1030px e de sumir no iPad em pé.
 */
.popover {
  position: absolute;
  top: 74px;
  right: 16px;
  z-index: 20;
  width: min(330px, calc(100vw - 32px));
  padding: 8px;
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
}

.menu-label {
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-secondary);
  padding: 12px 14px 6px;
}

.menu-item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 52px;
  padding: 14px;
  border: none;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text-primary);
  font-family: var(--font-ui);
  font-size: 15px;
  text-align: left;
  cursor: pointer;
}

.menu-item:hover { background: var(--bg-tertiary); }

.menu-item.sel {
  color: var(--brass);
  background: hsla(35, 65%, 60%, 0.12);
  font-weight: 600;
}

.menu-item input[type="checkbox"] {
  width: 20px;
  height: 20px;
  accent-color: var(--brass);
  cursor: pointer;
}

.menu-item .glyph {
  width: 24px;
  text-align: center;
  flex: 0 0 auto;
}

.menu-sep {
  height: 1px;
  background: var(--bg-tertiary);
  margin: 6px 10px;
}

.menu-slider {
  padding: 10px 14px 14px;
}

.menu-slider label {
  display: block;
  font-size: 13px;
  color: var(--text-secondary);
  margin-bottom: 8px;
}

.menu-slider input[type="range"] { width: 100%; }

/* ==========================================================================
   Aviso de erro — o que era alert() do navegador
   ========================================================================== */

#erro-aviso {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(10, 13, 20, 0.72);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.erro-cartao {
  width: min(460px, 100%);
  padding: 28px;
  border-radius: var(--radius-lg);
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  box-shadow: var(--shadow-card);
}

.erro-marca {
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-red);
  margin-bottom: 10px;
}

#erro-titulo {
  font-size: 22px;
  font-weight: 600;
  margin-bottom: 10px;
  overflow-wrap: anywhere;
}

/*
 * O motivo aparece inteiro, e em fonte de código: quase sempre é uma resposta
 * de rede ou uma queixa do OSMD, e é exatamente esse texto que serve para
 * procurar o defeito depois. Resumir aqui seria esconder a única pista.
 */
.erro-detalhe {
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-secondary);
  background: var(--bg-primary);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  max-height: 180px;
  overflow-y: auto;
  overflow-wrap: anywhere;
  user-select: text;
}

.erro-acoes {
  display: flex;
  justify-content: flex-end;
  margin-top: 20px;
}

/* Saída da tela de falha do catálogo: sem a tela de entrada, é o único
   caminho que resta quando o library.json não carrega. */
.catalogo-saida {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 360px;
  margin: 0 auto;
}

/* ==========================================================================
   Marcador de trecho — escolher compassos com o dedo
   ========================================================================== */

/* A camada vive dentro do conteúdo que rola, e não sobre a janela: assim a
   faixa acompanha a partitura em vez de ficar parada na tela. */
#osmd-container {
  position: relative;
}

#marcador-camada {
  position: absolute;
  top: 0;
  bottom: 0;
  z-index: 2;
  pointer-events: none;
}

/* Cinza, como texto marcado — e não a cor de acento. O destaque aqui é dizer
   "é isto que vai repetir", não chamar atenção para si. */
.marcador-faixa {
  position: absolute;
  inset: 0;
  background: rgba(30, 41, 59, 0.13);
  border-left: 2px solid rgba(30, 41, 59, 0.3);
  border-right: 2px solid rgba(30, 41, 59, 0.3);
}

/* As alças e o ✕ vivem presos à janela, e não à partitura que rola: com um
   trecho maior que a tela, a ponta do fim ficava fora do campo visível e não
   havia como alcançá-la. Quando a ponta some, a alça encosta na borda. */
.marcador-alca,
.marcador-limpar {
  position: absolute;
  transform: translate(-50%, -50%);
  z-index: 6;
  padding: 0;
  cursor: pointer;
  touch-action: none;
}

.marcador-alca {
  width: 44px;
  height: 76px;
  border: none;
  border-radius: 10px;
  background: #FFFFFF;
  color: var(--brass);
  font-size: 19px;
  line-height: 1;
  cursor: ew-resize;
  box-shadow: 0 2px 10px rgba(15, 23, 42, 0.28);
}

/* Presa na borda: a ponta do trecho está fora da tela. O tom mais forte diz
   que aquela alça não está sobre a ponta, e sim esperando por ela. */
.marcador-alca-presa {
  background: var(--brass);
  color: var(--brass-ink);
}

.marcador-limpar {
  width: 52px;
  height: 52px;
  border: 2px solid rgba(255, 255, 255, 0.9);
  border-radius: 50%;
  background: rgba(30, 41, 59, 0.55);
  color: #FFFFFF;
  font-size: 19px;
}

.marcador-alca:focus-visible,
.marcador-limpar:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 3px;
}

/* Ficha "quem toca agora" e a nota explicativa do acompanhamento.
   As duas existem porque o silêncio do Modo Seguir é proposital e invisível —
   e porque num iPad não há ponteiro para pousar sobre um `title`. */
#quem-toca {
  background: transparent;
  border: 1px solid var(--bg-tertiary);
  color: var(--text-secondary);
  font-family: var(--font-ui);
  font-size: 12px;
}

#quem-toca.chip-silencio {
  border-style: dashed;
}

.menu-nota {
  padding: 0 14px 12px 50px;
  margin-top: -6px;
  font-size: 12px;
  line-height: 1.45;
  color: var(--text-secondary);
}

/* ---------------------------------------------------------------------------
   O que o normalizador mexeu na peca.
   Fica sob a barra de cima, discreta, sem bloquear a partitura: e informacao,
   e nao obstaculo. Mas visivel — o silencio e que seria o defeito.
   --------------------------------------------------------------------------- */
#ajustes-aviso {
  /* Embaixo, e nao em cima: o teclado desenhado e area de trabalho, e a ficha
     tapava as teclas. Aqui ela fica no caminho de ninguem e continua visivel. */
  position: fixed;
  bottom: 12px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 40;
  max-width: min(680px, calc(100vw - 32px));
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 8px 10px 8px 14px;
  border-radius: 10px;
  background: hsl(38, 92%, 95%);
  border: 1px solid hsl(38, 70%, 78%);
  color: hsl(30, 45%, 22%);
  box-shadow: 0 6px 20px hsla(30, 40%, 20%, 0.18);
  font-size: 0.92rem;
  flex-wrap: wrap;
}

#ajustes-aviso.hidden { display: none; }

#btn-ajustes-resumo {
  flex: 1 1 auto;
  min-width: 0;
  text-align: left;
  background: none;
  border: none;
  padding: 2px 0;
  color: inherit;
  font: inherit;
  cursor: pointer;
  text-decoration: underline dotted;
  text-underline-offset: 3px;
}

#btn-ajustes-fechar {
  flex: 0 0 auto;
  background: none;
  border: none;
  color: inherit;
  font-size: 1.3rem;
  line-height: 1;
  padding: 0 4px;
  cursor: pointer;
  opacity: 0.65;
}
#btn-ajustes-fechar:hover { opacity: 1; }

#ajustes-lista {
  flex: 1 1 100%;
  margin: 6px 0 2px;
  padding-left: 18px;
  max-height: 40vh;
  overflow-y: auto;
}
#ajustes-lista.hidden { display: none; }
#ajustes-lista li { margin-bottom: 6px; line-height: 1.4; }
#ajustes-lista li .ajuste-regra {
  font-weight: 600;
  opacity: 0.7;
  margin-right: 4px;
}

/* A limitacao do motor entra na lista, mas mais quieta que a intervencao:
   uma diz "mexi na sua peca", a outra diz "o app nao vai tao longe". */
#ajustes-lista li.ajuste-limitacao { color: var(--tinta-fraca, #6b6b6b); opacity: 0.85; }
#ajustes-lista li.ajuste-limitacao .ajuste-regra { font-weight: 500; }

/* ---------------------------------------------------------------------------
   A capa do cartao.
   Duas camadas: o campo desenhado, que nunca falha, e a fotografia por cima
   quando existir. A pauta de cinco linhas e a inicial do compositor sao o
   desenho — sobrios de proposito, porque sao miniaturas e um catalogo de mil
   quadrinhos berrantes e ilegivel.
   --------------------------------------------------------------------------- */
.card-capa {
  position: relative;
  overflow: hidden;
  background: linear-gradient(140deg, var(--capa-a, hsl(230,20%,26%)), var(--capa-b, hsl(230,25%,14%)));
  isolation: isolate;
}

/* A pauta. */
.card-capa::before {
  content: "";
  position: absolute;
  inset: 30% 12% 30% 12%;
  background: repeating-linear-gradient(
    to bottom,
    hsla(0, 0%, 100%, 0.28) 0 1px,
    transparent 1px 25%
  );
  z-index: 1;
}

/* A fotografia, quando existir, cobre tudo — e escurece um pouco, para a
   inicial continuar legivel sobre qualquer foto. */
.card-capa-foto {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 3;
  /* Sem texto por cima, a foto nao precisa mais ser escurecida. Fica so um
     leve recuo de saturacao, para o catalogo nao virar vitrine. */
  filter: saturate(0.88);
}
/* Com foto, a pauta desenhada some: ela e o motivo da capa vazia, e por cima
   de uma fotografia vira sujeira. */
.card-capa:has(.card-capa-foto)::before { opacity: 0; }

/* Filtro com muitos valores: lista de escolha em vez de faixa de pastilhas.
   145 compositores nao cabem numa faixa; numa lista cabem, e o sistema ja a
   desenha bem no iPad. */
.filtro-escolha {
  width: 100%;
  max-width: 420px;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  color: var(--text-primary);
  font-family: var(--font-ui);
  font-size: 14px;
}
.filtro-escolha:focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; }

/* O botao que pede o proximo bloco de cartoes. E um botao de verdade, e nao
   uma sentinela invisivel: se o observador nao rodar — aba em segundo plano,
   pagina sem compositar quadros — o dedo continua tendo o que tocar. */
.catalogo-mais {
  display: block;
  width: 100%;
  margin-top: 12px;
  padding: 12px;
  border-radius: var(--radius-sm);
  background: var(--bg-secondary);
  border: 1px dashed var(--bg-tertiary);
  color: var(--text-secondary);
  font-family: var(--font-ui);
  font-size: 14px;
  cursor: pointer;
}
.catalogo-mais:hover { border-color: var(--brass); color: var(--text-primary); }
.catalogo-mais:focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; }

/* Botão de excluir partitura pessoal do usuário */
.card-delete-btn {
  background: transparent;
  border: none;
  color: var(--text-secondary);
  font-size: 16px;
  padding: 8px 12px;
  cursor: pointer;
  border-radius: var(--radius-sm);
  transition: all var(--transition-fast);
  margin-left: auto;
  min-width: 44px;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.card-delete-btn:hover {
  color: var(--accent-red);
  background: hsla(0, 75%, 55%, 0.15);
}

/* Onboarding Modal */
.onboarding-overlay {
  position: fixed;
  inset: 0;
  background: rgba(8, 10, 15, 0.85);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.onboarding-overlay.hidden {
  display: none !important;
}

.onboarding-card {
  background: var(--bg-secondary);
  border: 1px solid var(--bg-tertiary);
  border-radius: var(--radius-lg);
  max-width: 480px;
  width: 100%;
  padding: 28px;
  box-shadow: var(--shadow-card);
  animation: modalFadeIn 0.3s ease-out;
}

@keyframes modalFadeIn {
  from { opacity: 0; transform: translateY(16px) scale(0.97); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

.onboarding-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 24px;
}

.onboarding-dots {
  display: flex;
  gap: 8px;
}

.onboarding-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--bg-tertiary);
  transition: background var(--transition-fast);
}

.onboarding-dot.active {
  background: var(--accent-blue);
  width: 24px;
  border-radius: 10px;
}

.onboarding-skip {
  background: transparent;
  border: none;
  color: var(--text-secondary);
  font-size: 14px;
  font-family: var(--font-ui);
  cursor: pointer;
  padding: 6px 10px;
  border-radius: var(--radius-sm);
}
.onboarding-skip:hover {
  color: var(--text-primary);
}

.onboarding-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 16px;
}

.onboarding-icon {
  font-size: 48px;
  line-height: 1;
}

.onboarding-body h2 {
  font-size: 22px;
  font-weight: 600;
  color: var(--text-primary);
}

.onboarding-desc {
  font-size: 15px;
  line-height: 1.5;
  color: var(--text-secondary);
}

.onboarding-actions {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 100%;
  margin-top: 12px;
}

.onboarding-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
  margin-top: 8px;
}

.onboarding-btn {
  width: 100%;
  min-height: 48px;
  font-size: 15px;
  font-weight: 500;
}

/* Practice Summary Overlay ------------------------------------------------ */
.summary-overlay {
  position: fixed;
  inset: 0;
  background: rgba(10, 12, 18, 0.85);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 1000;
  animation: fadeIn 0.25s ease-out;
}

.summary-card {
  background: var(--bg-surface, #1e2433);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: var(--radius-lg, 16px);
  width: 100%;
  max-width: 440px;
  padding: 28px 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.5);
}

.summary-stars {
  font-size: 38px;
  margin-bottom: 8px;
  display: flex;
  gap: 6px;
  justify-content: center;
}

.summary-star {
  color: rgba(255, 255, 255, 0.15);
  transition: color 0.3s ease, transform 0.3s ease;
}

.summary-star.filled {
  color: #fbbf24;
  text-shadow: 0 0 12px rgba(251, 191, 36, 0.6);
  transform: scale(1.1);
}

.summary-header h2 {
  font-size: 24px;
  font-weight: 700;
  color: #fff;
  margin: 0 0 4px 0;
}

.summary-piece-name {
  font-size: 14px;
  color: var(--text-secondary);
  margin: 0 0 20px 0;
}

.summary-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
  width: 100%;
  margin-bottom: 18px;
}

.summary-stat-item {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: var(--radius-md, 10px);
  padding: 12px 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

.summary-stat-item.highlight {
  grid-column: span 2;
  background: rgba(245, 158, 11, 0.12);
  border-color: rgba(245, 158, 11, 0.3);
}

.summary-stat-item .stat-value {
  font-size: 22px;
  font-weight: 700;
  color: #fff;
}

.summary-stat-item .stat-label {
  font-size: 12px;
  color: var(--text-secondary);
}

.text-green { color: #10b981 !important; }
.text-red { color: #ef4444 !important; }

.summary-streak {
  background: linear-gradient(135deg, rgba(239, 68, 68, 0.15), rgba(245, 158, 11, 0.15));
  border: 1px solid rgba(245, 158, 11, 0.3);
  color: #fef3c7;
  padding: 10px 16px;
  border-radius: var(--radius-md);
  font-size: 14px;
  margin-bottom: 20px;
  width: 100%;
  box-sizing: border-box;
}

.summary-actions {
  display: flex;
  gap: 12px;
  width: 100%;
}

.summary-btn {
  flex: 1;
  min-height: 48px;
  font-size: 15px;
  font-weight: 600;
  border-radius: var(--radius-md);
}


/* ============================================================
   Ícones desenhados
   ============================================================
   Antes os ícones eram caracteres, e cada aparelho os desenhava com a fonte
   que tinha: no iPad, ✋ e 🤚 saíam como emoji coloridos ao lado de glifos
   monocromáticos, com pesos que não combinavam. Agora são SVG do próprio app.

   O tamanho vem do `font-size` do botão (o SVG mede 1em), então toda a régua
   de tamanhos que já existia continua valendo, sem uma segunda tabela. */
.icone {
  width: 1em;
  height: 1em;
  /* `inline-block` e nao `block`: o mesmo icone precisa servir dentro de um
     botao em flex E no meio de um titulo, sem quebrar a linha. */
  display: inline-block;
  vertical-align: -0.125em;
  flex: none;
  /* O traço não pode engrossar junto com o ícone quando ele cresce. */
  vector-effect: non-scaling-stroke;
}

/* A mão é um desenho só, espelhado. Duas cópias seriam duas chances de ficarem
   diferentes na próxima vez que alguém mexer numa delas. */
#btn-hand-left .icone { transform: scaleX(-1); }

/* Dentro de um item de menu o ícone fica ao lado do texto, e precisa da mesma
   caixa que o `.glyph` de antes ocupava, senão o menu perde o alinhamento. */
.menu-item .glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.25em;
}
