/* Player público.
 *
 * Nenhuma cor literal mora aqui. Todas vêm de `theme-tokens.css`, que é gerado
 * de `data/themes/*.theme.json` — trocar `data-theme` no elemento raiz troca a
 * página inteira, e o mesmo tema vai para o palco e para o vídeo exportado.
 *
 * A transparência continua existindo, mas como alfa aplicado a um token, via
 * `color-mix`. Guardar `rgba(114,231,197,.45)` seria guardar o acento de novo,
 * em outro lugar, sem ninguém conferindo que os dois combinam.
 */

:root {
  /* Apelidos locais. Não são cores novas: são leituras do token com o alfa que
     esta tela usa, nomeadas pelo papel que exercem. */
  --panel-veil: color-mix(in srgb, var(--phsp-panel) 88%, transparent);
  --topbar-veil: color-mix(in srgb, var(--phsp-ink) 82%, transparent);
  --overlay: color-mix(in srgb, var(--phsp-stage-backdrop-top) 80%, transparent);
  --hairline: color-mix(in srgb, var(--phsp-line) 55%, transparent);
  --accent-soft: color-mix(in srgb, var(--phsp-accent) 45%, transparent);
  --accent-faint: color-mix(in srgb, var(--phsp-accent) 18%, transparent);
  --accent-glow: color-mix(in srgb, var(--phsp-accent) 22%, transparent);
  --alt-soft: color-mix(in srgb, var(--phsp-accent-alt) 30%, transparent);
  --alt-faint: color-mix(in srgb, var(--phsp-accent-alt) 8%, transparent);
  --shadow: 0 30px 90px color-mix(in srgb, var(--phsp-shadow) 58%, transparent);
  --text-dim: color-mix(in srgb, var(--phsp-text-primary) 78%, var(--phsp-text-muted));
}

* { box-sizing: border-box; }

html, body { margin: 0; min-height: 100%; background: var(--phsp-ink); }

body {
  color: var(--phsp-text-primary);
  font-family: var(--phsp-text-family);
  font-size: var(--phsp-minimum-size);
  background:
    radial-gradient(circle at 78% 5%, var(--accent-faint), transparent 30rem),
    linear-gradient(140deg, var(--phsp-ink) 0%, var(--phsp-panel) 48%, var(--phsp-ink) 100%);
}

button, input, select { font: inherit; }
button { color: inherit; }

/* Foco visível em todo controle. Estava ausente: o contorno padrão do navegador
   some sobre fundo escuro, e navegar por teclado virava adivinhação. */
:where(a, button, select, input, [tabindex]):focus-visible {
  outline: 2px solid var(--phsp-focus-ring);
  outline-offset: 2px;
}

.shell { min-height: 100vh; padding: 18px clamp(14px, 2vw, 34px) 32px; }

.topbar {
  max-width: 1680px;
  margin: 0 auto 16px;
  min-height: 76px;
  display: grid;
  grid-template-columns: minmax(170px, .7fr) minmax(320px, 1.6fr) minmax(240px, .9fr);
  align-items: center;
  gap: 24px;
  padding: 10px 18px;
  border: 1px solid var(--phsp-line);
  background: var(--topbar-veil);
  backdrop-filter: blur(20px);
}

.brand { color: inherit; text-decoration: none; display: inline-flex; align-items: center; width: fit-content; }
.brand .phsp-piano-logo { display: block; width: 72px; height: 72px; object-fit: contain; }
.brand span:last-child { display: grid; line-height: 1; }
.brand strong { font-family: var(--phsp-display-family); font-size: 21px; letter-spacing: .12em; }
.brand small { margin-top: 6px; font-size: 11px; letter-spacing: .3em; color: var(--phsp-accent); }
.brand-mark { width: 46px; height: 46px; border: 1px solid var(--accent-soft); display: flex; align-items: center; justify-content: center; gap: 3px; }
.brand-mark i { width: 2px; border-radius: 4px; background: var(--phsp-accent); }
.brand-mark i:nth-child(1), .brand-mark i:nth-child(5) { height: 11px; }
.brand-mark i:nth-child(2), .brand-mark i:nth-child(4) { height: 21px; }
.brand-mark i:nth-child(3) { height: 29px; }

.track-heading { min-width: 0; }
.eyebrow { color: var(--phsp-accent); font-size: 11px; letter-spacing: .22em; font-weight: 700; }
.track-heading p { margin: 7px 0 0; color: var(--phsp-text-muted); font-size: 12px; }

/* Seletor de faixa. É o título da tela e o controle ao mesmo tempo: o catálogo
   tem seis faixas prontas, e a porta de entrada mostrava uma só. */
.track-picker { display: grid; gap: 3px; min-width: 0; }
.track-picker select {
  width: 100%; min-width: 0; padding: 2px 4px;
  border: 0; border-bottom: 1px solid var(--phsp-line); outline: 0;
  background: transparent; color: var(--phsp-text-primary);
  font-family: var(--phsp-display-family); font-size: clamp(24px, 2.1vw, 36px); font-weight: 500;
  text-overflow: ellipsis; cursor: pointer;
}
.track-picker select:hover { border-bottom-color: var(--phsp-accent); }
.track-picker option { color: var(--phsp-text-primary); background: var(--phsp-panel); font-family: var(--phsp-text-family); font-size: 13px; }

.header-actions { display: flex; justify-content: flex-end; align-items: center; gap: 10px; }
.studio-link { padding: 10px 12px; color: var(--phsp-accent-alt); border: 1px solid var(--alt-soft); text-decoration: none; font-size: 11px; text-transform: uppercase; letter-spacing: .08em; }
.studio-link:hover { border-color: var(--phsp-accent-alt); background: var(--alt-faint); }

/* Seletor de tema. Fica na barra superior porque é escolha do dono da tela, não
   ajuste escondido: quem abre em sala com luz acesa precisa achá-lo. */
.theme-picker { display: flex; align-items: center; gap: 7px; }
.theme-picker label { color: var(--phsp-text-muted); font-size: 11px; text-transform: uppercase; letter-spacing: .1em; }
.theme-picker select { color: var(--phsp-text-primary); background: var(--phsp-surface); border: 1px solid var(--phsp-line); padding: 8px 9px; font-size: 12px; }

.sync-badge { border: 1px solid var(--accent-soft); padding: 10px 12px; font-size: 11px; color: var(--text-dim); text-transform: uppercase; letter-spacing: .08em; }
.sync-badge b { display: inline-block; width: 7px; height: 7px; margin-right: 7px; border-radius: 50%; background: var(--phsp-accent); }
.icon-button { width: 39px; height: 39px; border: 1px solid var(--phsp-line); background: var(--phsp-surface); cursor: pointer; }
.icon-button:hover { border-color: var(--phsp-accent); color: var(--phsp-accent); }
.info-button { width: 44px; height: 44px; display: inline-grid; place-items: center; border-radius: 50%; }
.info-button span { font-family: var(--phsp-display-family); font-size: 20px; font-style: italic; font-weight: 700; line-height: 1; transform: translateX(-1px); }
.info-button[aria-expanded="true"] { border-color: var(--phsp-accent); background: var(--accent-glow); color: var(--phsp-accent); }

main { max-width: 1680px; margin: auto; }
/* Palco e controles são IRMÃOS numa coluna, e não camadas sobrepostas.
   Enquanto as barras eram `position: absolute` presas ao rodapé do cartão, elas
   cobriam a faixa das teclas por inteiro — a linha do teclado fica em 72% da
   altura do palco, e as barras ocupavam de 17px a ~172px do rodapé. O aluno via
   a barra da nota cair e não via a tecla afundar. */
.player-card { display: flex; flex-direction: column; border: 1px solid var(--alt-soft); background: var(--phsp-stage-backdrop-top); box-shadow: var(--relevo-erguido); isolation: isolate; }
/* O piso em pixels não é enfeite: com o deck ocupando altura própria, `64vh`
   numa tela baixa — telefone deitado, janela encolhida — deixaria o palco menor
   que a própria faixa de teclas. E numa janela de altura zero, `vh` zera e o
   palco some inteiro. `max()` garante que o teclado continue legível. Os três
   limites são exatamente 10% maiores que o perfil anterior. */
.stage { position: relative; min-height: max(352px, min(64vh, 726px)); overflow: hidden; }
.player-deck { display: flex; flex-direction: column; gap: 8px; padding: 10px; border-top: 1px solid var(--hairline); background: var(--phsp-panel); }
.cover-layer, .stage-wash { position: absolute; inset: 0; pointer-events: none; }
.cover-layer { z-index: -3; background-position: center 28%; background-size: cover; filter: saturate(.72) contrast(1.05); transform: scale(1.05); animation: cover-breathe 24s ease-in-out infinite alternate; }
.cover-layer::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, var(--overlay), var(--phsp-stage-backdrop-bottom) 94%); }
.stage-wash { z-index: -2; background: radial-gradient(ellipse at 50% 74%, var(--accent-faint), transparent 42%); }
@keyframes cover-breathe { from { transform: scale(1.04) translate3d(-.3%, 0, 0); } to { transform: scale(1.11) translate3d(.5%, -1%, 0); } }

#pianoCanvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; transition: opacity .24s ease; }
/* A barra fica SOBRE o palco, que é onde a nota nasce. Como ela não pode sair
   dali sem perder a relação com o que controla, ela recua: em repouso é
   discreta, e ao aproximar o ponteiro ou receber foco volta ao contraste
   cheio. Nunca abaixo de 0.72 — controle que some de vez vira adivinhação. */
.visual-mode-toolbar {
  position: absolute; z-index: 8; top: 14px; left: 50%; transform: translateX(-50%);
  display: flex; align-items: center; gap: 4px; padding: 4px;
  border: 1px solid var(--hairline); background: color-mix(in srgb, var(--overlay) 92%, transparent);
  box-shadow: var(--relevo-contato); backdrop-filter: blur(14px);
  opacity: .72; transition: opacity 160ms ease;
}
.visual-mode-toolbar:hover,
.visual-mode-toolbar:focus-within,
.visual-mode-toolbar:has(details[open]) { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .visual-mode-toolbar { transition: none; } }

/* Ajustes recolhidos: Modelo e Ambiente saem da barra e viram um painel que só
   aparece quando pedido. */
.stage-settings { position: relative; }
.stage-settings > summary {
  display: flex; align-items: center; gap: 6px; padding: 6px 10px;
  border: 1px solid transparent; color: var(--phsp-text-muted);
  font-size: 12px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  cursor: pointer; list-style: none; white-space: nowrap;
}
.stage-settings > summary::-webkit-details-marker { display: none; }
.stage-settings > summary:hover { color: var(--phsp-text-primary); border-color: var(--accent-soft); }
.stage-settings > summary:focus-visible { outline: 2px solid var(--phsp-accent); outline-offset: 2px; }
.stage-settings[open] > summary { color: var(--phsp-text-primary); border-color: var(--accent-soft); }
.stage-settings-panel {
  position: absolute; z-index: 12; top: calc(100% + 6px); right: 0;
  display: grid; gap: 10px; min-width: 220px; padding: 12px;
  border: 1px solid var(--hairline); background: var(--overlay);
  box-shadow: var(--relevo-contato); backdrop-filter: blur(16px);
}
/* Em retrato o painel ancora à esquerda para não sair pela borda da tela. */
@media (max-width: 640px) {
  .stage-settings-panel { right: auto; left: 0; min-width: min(78vw, 260px); }
  .stage-settings-label { display: none; }
}
.visual-mode-toolbar button, .piano3d-controls button {
  min-height: 30px; border: 1px solid transparent; background: transparent;
  color: var(--phsp-text-muted); font: inherit; font-size: 12px; letter-spacing: .04em;
  cursor: pointer; touch-action: manipulation; -webkit-tap-highlight-color: transparent;
}
.visual-mode-toolbar button:hover, .piano3d-controls button:hover { border-color: var(--accent-soft); color: var(--phsp-text-primary); }
.visual-mode-toolbar button.is-active, .piano3d-controls button.is-active,
.piano3d-controls button[aria-pressed="true"] {
  border-color: var(--phsp-accent); background: var(--accent-glow); color: var(--phsp-text-primary);
}
.visual-mode-toolbar button:focus-visible, .piano3d-controls button:focus-visible,
.piano3d-canvas:focus-visible { outline: 2px solid var(--phsp-accent-alt); outline-offset: 2px; }
.visual-mode-toolbar button[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }
.immersive-toggle { display: inline-flex; align-items: center; gap: 6px; border-left-color: var(--hairline) !important; }
.immersive-toggle > span:first-child { font-size: 16px; line-height: 1; }
/* Estado pronto não ocupa a barra. Carregamento e falha reaparecem porque são
   ação necessária, e não telemetria decorativa. */
#piano3dStatus[data-state="loading"], #piano3dStatus[data-state="error"] {
  position: static; width: auto; height: auto; margin: 0; padding: 0 7px; overflow: visible;
  clip-path: none; color: var(--phsp-text-muted); font-size: 12px; white-space: nowrap;
}
#piano3dStatus[data-state="error"] { color: var(--phsp-accent-alt); }
.environment-picker {
  min-height: 34px; display: grid; grid-template-columns: auto minmax(132px, 1fr); align-items: center;
  column-gap: 7px; padding-left: 9px; border-left: 1px solid var(--hairline);
  color: var(--phsp-text-muted); cursor: pointer;
}
.environment-picker > span { font-size: 12px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; }
.environment-picker select {
  min-width: 0; padding: 5px 24px 5px 7px; border: 1px solid var(--phsp-line);
  background: var(--phsp-surface); color: var(--phsp-text-primary); font-size: 12px; cursor: pointer;
}
.environment-picker small {
  grid-column: 2; margin-top: -2px; color: var(--phsp-accent); font-size: 12px;
  letter-spacing: .06em; white-space: nowrap;
}
.piano-variant-picker {
  min-height: 34px; display: grid; grid-template-columns: auto minmax(84px, 1fr); align-items: center;
  column-gap: 7px; padding-left: 9px; border-left: 1px solid var(--hairline);
  color: var(--phsp-text-muted); cursor: pointer;
}
.piano-variant-picker > span { font-size: 12px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; }
.piano-variant-picker select {
  min-width: 0; padding: 5px 24px 5px 7px; border: 1px solid var(--phsp-line);
  background: var(--phsp-surface); color: var(--phsp-text-primary); font-size: 12px; cursor: pointer;
}
.piano-variant-picker select:focus-visible { outline: 2px solid var(--phsp-accent-alt); outline-offset: 2px; }
.piano3d-host {
  position: absolute; z-index: 2; inset: 0; overflow: hidden;
  background:
    radial-gradient(ellipse at 50% 82%, color-mix(in srgb, var(--phsp-accent) 16%, transparent), transparent 46%),
    linear-gradient(180deg, var(--phsp-stage-black-key-face) 0%, var(--phsp-stage-black-key-shade) 62%, var(--phsp-stage-black-key-edge) 100%);
}
.piano3d-host[hidden] { display: none; }
.piano3d-canvas {
  width: 100%; height: 100%; display: block; border: 0; cursor: crosshair;
  touch-action: none; overscroll-behavior: contain;
  -webkit-tap-highlight-color: transparent; -webkit-touch-callout: none;
  -webkit-user-select: none; user-select: none;
}
.piano3d-canvas[data-interaction="explore"] { cursor: grab; }
.piano3d-canvas[data-interaction="explore"]:active { cursor: grabbing; }
.piano3d-controls {
  position: absolute; z-index: 9; left: 12px; right: 12px; bottom: calc(10px + env(safe-area-inset-bottom, 0px));
  display: flex; align-items: center; justify-content: center; gap: 6px; pointer-events: none;
}
.piano3d-controls[hidden] { display: none; }
.piano3d-controls > *, .piano3d-controls .piano3d-control-group { pointer-events: auto; }
.piano3d-controls .piano3d-control-group {
  display: flex; gap: 2px; padding: 3px; border: 1px solid var(--hairline);
  background: color-mix(in srgb, var(--overlay) 92%, transparent); backdrop-filter: blur(12px);
}
.piano3d-secondary-controls { display: contents; }
.piano3d-control-label {
  display: inline-flex; align-items: center; padding: 0 6px 0 4px; color: var(--phsp-accent);
  font-size: 12px; font-weight: 700; letter-spacing: .16em;
}
.piano3d-cinematic-presets { border-color: var(--alt-soft) !important; }
.piano3d-cinematic-presets button[aria-pressed="true"] {
  box-shadow: inset 0 -2px 0 var(--phsp-accent-alt), 0 0 12px var(--accent-glow);
}
.piano3d-visualizer-presets { border-color: var(--accent-soft) !important; }
.piano3d-visualizer-presets button[aria-pressed="true"] {
  box-shadow: inset 0 -2px 0 var(--phsp-accent), 0 0 12px var(--accent-glow);
}
.piano3d-controls button:disabled { opacity: .46; cursor: not-allowed; }
.piano3d-pedals button { padding-inline: 8px; }
.piano3d-key-travel { align-items: center; padding-inline: 6px !important; }
.piano3d-key-travel[hidden] { display: none !important; }
.piano3d-key-travel input[type="range"] {
  width: 96px; margin: 0 2px; accent-color: var(--phsp-accent); cursor: ew-resize;
}
.piano3d-key-travel output {
  min-width: 38px; color: var(--ink); font-size: 12px; font-variant-numeric: tabular-nums;
  text-align: right;
}
.piano3d-key-travel button { min-width: 30px; padding-inline: 6px; }
.stage.is-3d #pianoCanvas { opacity: 0; pointer-events: none; }
.stage.is-3d .piano-touch-surface { visibility: hidden; pointer-events: none; }
.stage.is-3d .cover-layer, .stage.is-3d .stage-wash { opacity: 0; }
.piano-touch-surface {
  position: absolute; z-index: 3; inset: 72% 0 0; cursor: pointer;
  touch-action: none; -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none; user-select: none;
}
/* Mesmo antes de baixar o 3D, o ambiente escolhido deixa uma assinatura leve
   no palco 2D. São somente tokens do tema; o recinto real continua sendo o
   runtime Unity, e esta camada nunca tenta imitar o modelo comprado. */
.stage[data-environment="studio"] .stage-wash {
  background: radial-gradient(ellipse at 50% 74%, var(--accent-faint), transparent 42%);
}
.stage[data-environment="theatre"] .stage-wash {
  background:
    radial-gradient(ellipse at 50% 95%, var(--alt-soft), transparent 38%),
    linear-gradient(90deg, var(--overlay), transparent 18% 82%, var(--overlay));
}
.stage[data-environment="cathedral"] .stage-wash {
  background:
    repeating-linear-gradient(90deg, transparent 0 11%, var(--accent-faint) 11.4% 11.8%, transparent 12.2% 22%),
    radial-gradient(ellipse at 50% 22%, var(--alt-soft), transparent 52%);
}
.stage[data-environment="cave"] .stage-wash {
  background:
    radial-gradient(ellipse at 48% 77%, var(--accent-faint), transparent 30%),
    radial-gradient(ellipse at 12% 44%, var(--overlay), transparent 48%),
    radial-gradient(ellipse at 88% 38%, var(--overlay), transparent 46%);
}
.stage[data-environment="stadium"] .stage-wash {
  background:
    radial-gradient(circle at 7% 8%, var(--accent-soft), transparent 13%),
    radial-gradient(circle at 93% 8%, var(--accent-soft), transparent 13%),
    radial-gradient(ellipse at 50% 92%, var(--alt-faint), transparent 58%);
}
.stage-meta { position: absolute; z-index: 7; left: 22px; right: 22px; top: 18px; display: flex; justify-content: space-between; align-items: center; pointer-events: none; }
.mode-label { font-size: 11px; letter-spacing: .18em; padding: 8px 10px; background: var(--overlay); border-left: 2px solid var(--phsp-accent-alt); }
.live-metrics { display: flex; gap: 14px; padding: 8px 10px; background: var(--overlay); font-size: 11px; color: var(--phsp-text-muted); }
.live-metrics b { color: var(--phsp-text-primary); font-weight: 600; }

/* ── Palco imersivo ────────────────────────────────────────────────────────
   A mesma superfície abriga 2D e 3D. O Fullscreen API é preferido; a classe
   `is-immersive` também é o fallback para WebKit/iPhone que recuse fullscreen
   em elementos arbitrários. Nos dois caminhos a composição e a saída são
   idênticas, e o renderer escolhe 16:9/9:16 pelas dimensões reais do palco. */
.immersive-heading, .immersive-format { display: none; }
.player-card.is-immersive:not(:fullscreen) {
  position: fixed; z-index: 1000; inset: 0; width: 100vw; height: 100dvh;
}
.player-card:is(:fullscreen, .is-immersive) {
  width: 100vw; height: 100dvh; max-width: none; margin: 0; border: 0;
  background: var(--phsp-stage-backdrop-top); box-shadow: none;
}
.player-card:is(:fullscreen, .is-immersive) .stage {
  flex: 1 1 auto; height: auto; min-height: 0;
}
.player-card:is(:fullscreen, .is-immersive) .player-deck {
  position: relative; z-index: 20; flex: 0 0 auto; gap: 0;
  padding: 8px max(12px, env(safe-area-inset-right)) max(8px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left));
  border-top-color: var(--accent-soft); background: color-mix(in srgb, var(--phsp-panel) 94%, transparent);
  backdrop-filter: blur(18px);
}
.player-card:is(:fullscreen, .is-immersive) .section-bar,
.player-card:is(:fullscreen, .is-immersive) .voice-toolbar { display: none; }
.player-card:is(:fullscreen, .is-immersive) .transport {
  min-height: 50px; grid-template-columns: 46px 48px minmax(120px, 1fr) 48px auto auto auto;
  border: 0; background: transparent;
}
.player-card:is(:fullscreen, .is-immersive) .immersive-heading {
  position: absolute; z-index: 8; top: max(18px, env(safe-area-inset-top)); left: max(20px, env(safe-area-inset-left));
  display: grid; max-width: min(28vw, 390px); pointer-events: none;
  text-shadow: 0 1px 20px var(--phsp-stage-backdrop-top);
}
.immersive-heading .immersive-kicker { color: var(--phsp-accent); font-size: 12px; font-weight: 700; letter-spacing: .24em; }
.immersive-heading strong { margin-top: 4px; overflow: hidden; color: var(--phsp-text-primary); font-family: var(--phsp-display-family); font-size: clamp(20px, 2.2vw, 34px); font-weight: 500; text-overflow: ellipsis; white-space: nowrap; }
.immersive-heading small { margin-top: 3px; overflow: hidden; color: var(--phsp-text-muted); font-size: 12px; text-overflow: ellipsis; white-space: nowrap; }
.player-card:is(:fullscreen, .is-immersive) .immersive-format {
  position: absolute; z-index: 10; top: max(18px, env(safe-area-inset-top)); right: max(20px, env(safe-area-inset-right));
  display: block; padding: 7px 9px; border: 1px solid var(--hairline); background: var(--overlay);
  color: var(--phsp-accent); font-size: 12px; font-weight: 700; letter-spacing: .12em; pointer-events: none;
}
.player-card:is(:fullscreen, .is-immersive) .visual-mode-toolbar { top: max(16px, env(safe-area-inset-top)); }
.player-card:is(:fullscreen, .is-immersive) .stage-meta { top: 74px; }
.has-immersive-player, .has-immersive-player body { overflow: hidden; overscroll-behavior: none; }

/* ── tela cheia que fica cheia de verdade ────────────────────────────────────
   Antes, "tela cheia" mantinha barra de modo, cabeçalho, formato, metadados e
   transporte por cima da música. Em retrato de celular a barra comia o terço
   de cima, justo onde a nota nasce.

   Agora o cromo recolhe sozinho depois de 2,6 s tocando e volta a qualquer
   toque. O palco NÃO some junto: só o que é controle sai de cena.

   `visibility` entra junto de `opacity` porque elemento apenas transparente
   continua clicável — o aluno tocaria um botão que não vê. */
.player-card:is(:fullscreen, .is-immersive)[data-immersive-chrome="oculto"] :is(
  .visual-mode-toolbar,
  .immersive-heading,
  .immersive-format,
  .stage-meta,
  .player-deck
) {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}
.player-card:is(:fullscreen, .is-immersive) :is(
  .visual-mode-toolbar,
  .immersive-heading,
  .immersive-format,
  .stage-meta,
  .player-deck
) {
  transition: opacity 240ms ease, visibility 240ms;
}
@media (prefers-reduced-motion: reduce) {
  .player-card:is(:fullscreen, .is-immersive) :is(
    .visual-mode-toolbar, .immersive-heading, .immersive-format, .stage-meta, .player-deck
  ) { transition: none; }
}
/* Com o cromo recolhido o palco ocupa a altura inteira: o deck deixa de
   reservar espaço, em vez de ficar como uma faixa vazia no rodapé. */
.player-card:is(:fullscreen, .is-immersive)[data-immersive-chrome="oculto"] .player-deck {
  position: absolute; inset: auto 0 0 0;
}

/* Barra de seções. É o que transforma o player em ferramenta de estudo:
   repetir um trecho é o gesto que o aluno mais faz, e ele exigia o Studio. */
/* Escada de estudo: cada degrau abre o player já montado para aquele exercício.
   Numerada porque a ordem carrega informação — mão separada antes das duas
   juntas é a sequência que a trilha prescreve, não uma lista qualquer. */
.escada { display: grid; gap: 6px; margin: 0; padding-left: 20px; }
.escada li::marker { color: var(--phsp-accent); font-weight: 700; font-size: 12px; }
.escada-passo {
  display: grid; gap: 2px; padding: 8px 10px;
  border: 1px solid var(--hairline); background: var(--overlay);
  color: var(--phsp-text-primary); text-decoration: none;
}
.escada-passo:hover { border-color: var(--accent-soft); }
.escada-passo:focus-visible { outline: 2px solid var(--phsp-accent); outline-offset: 2px; }
.escada-passo b { font-size: 13px; font-weight: 600; }
.escada-passo small { color: var(--phsp-text-muted); font-size: 12px; }

/* Exercício vindo do curso: um dock compacto, acima dos controles comuns. A
   tela só o mostra depois de resolver unit/exercise contra o dado canônico. */
.course-practice-dock {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto;
  gap: 14px; align-items: center; margin-bottom: 12px; padding: 13px 15px;
  border: 1px solid var(--phsp-accent); border-radius: 16px;
  background: var(--phsp-panel); color: var(--phsp-text-primary);
}
.course-practice-dock[hidden] { display: none; }
.course-practice-dock.is-complete { border-color: var(--phsp-accent-alt); }
.course-practice-dock.is-preview { border-style: dashed; }
.course-practice-back {
  min-height: 44px; padding: 11px 12px; border-radius: 12px;
  color: var(--phsp-accent); text-decoration: none; font-size: 13px; font-weight: 750;
}
.course-practice-back:hover { background: var(--phsp-surface); }
.course-practice-copy { min-width: 0; display: grid; gap: 1px; }
.course-practice-copy strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 15px; }
.course-practice-copy > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--phsp-text-muted); font-size: 12px; }
.course-practice-rounds { min-width: 54px; text-align: center; display: grid; }
.course-practice-rounds b { font-family: var(--phsp-mono-family); color: var(--phsp-accent); font-size: 18px; }
.course-practice-rounds span { color: var(--phsp-text-muted); font-size: 12px; }
.course-practice-nav { display: flex; gap: 5px; }
.course-practice-nav a {
  width: 44px; height: 44px; display: grid; place-items: center;
  border: 1px solid var(--phsp-line); border-radius: 12px; color: var(--phsp-text-primary); text-decoration: none;
}
.course-practice-nav a:hover { border-color: var(--phsp-accent); }
.course-practice-nav a[aria-disabled="true"] { opacity: .35; pointer-events: none; }

@media (max-width: 680px) {
  .course-practice-dock { grid-template-columns: auto 1fr auto; gap: 8px; }
  .course-practice-copy { grid-column: 2 / -1; grid-row: 1; }
  .course-practice-back { grid-column: 1; grid-row: 1; padding-inline: 8px; }
  .course-practice-rounds { grid-column: 1 / 2; grid-row: 2; }
  .course-practice-nav { grid-column: 2 / -1; grid-row: 2; justify-content: flex-end; }
}

.focus-sound-note {
  font-size: 12px; color: var(--phsp-text-muted); line-height: 1.35;
  flex: 1 1 14ch; min-width: 0;
}

.section-bar { display: flex; align-items: center; gap: 9px; padding: 8px 10px; background: var(--overlay); border: 1px solid var(--hairline); }
.section-bar-label { color: var(--phsp-text-muted); font-size: 11px; font-weight: 700; letter-spacing: .2em; }
.section-chips { flex: 1; min-width: 0; display: flex; gap: 5px; overflow-x: auto; scrollbar-width: none; }
.section-chips::-webkit-scrollbar { display: none; }
.section-chip { flex: 0 0 auto; min-height: 32px; display: inline-flex; align-items: center; gap: 7px; padding: 6px 10px; border: 1px solid var(--phsp-line); background: var(--panel-veil); color: var(--text-dim); cursor: pointer; font-size: 11px; transition: border-color .18s ease, background .18s ease; }
.section-chip:hover { border-color: var(--accent-soft); }
.section-chip b { color: var(--phsp-text-muted); font-size: 11px; font-variant-numeric: tabular-nums; font-weight: 400; }
.section-chip.is-active { border-color: var(--phsp-accent); background: var(--accent-glow); color: var(--phsp-text-primary); }
/* Dentro do chip ativo o fundo clareia, e o texto secundário deixa de passar em
   tema claro: o horário fica em 3,91:1. Sobre leito de acento, texto é o
   primário do tema. */
.section-chip.is-active b { color: var(--phsp-text-primary); }
/* Estado ativo nunca é só cor: o símbolo de repetição diz o mesmo para quem não
   distingue os dois tons e para quem lê por leitor de tela. */
.section-chip.is-active::before { content: "⟲"; color: var(--phsp-accent); font-size: 13px; }
.section-empty { margin: 0; padding: 4px 2px; color: var(--phsp-text-muted); font-size: 11px; }
.loop-state { flex: 0 0 auto; max-width: 34%; overflow: hidden; color: var(--phsp-accent); font-size: 11px; text-overflow: ellipsis; white-space: nowrap; }
.loop-range { position: absolute; top: -3px; height: 9px; border-left: 2px solid var(--phsp-accent); border-right: 2px solid var(--phsp-accent); background: var(--accent-faint); pointer-events: none; }

.voice-toolbar { display: flex; align-items: center; gap: 7px; padding: 8px 10px; background: var(--overlay); border: 1px solid var(--hairline); }
.voice-toolbar-label { margin-right: 3px; color: var(--phsp-text-muted); font-size: 11px; font-weight: 700; letter-spacing: .2em; }
.focus-chip { min-height: 32px; display: inline-flex; align-items: center; gap: 7px; padding: 6px 10px; border: 1px solid var(--phsp-line); background: var(--panel-veil); color: var(--text-dim); cursor: pointer; font-size: 11px; transition: border-color .18s ease, background .18s ease, transform .18s ease; }
.focus-chip:hover { transform: translateY(-1px); border-color: var(--accent-soft); }
.focus-chip.is-active { border-color: var(--phsp-accent); background: var(--accent-glow); color: var(--phsp-text-primary); }
/* Estado ativo nunca é só cor: a marca ✓ diz o mesmo para quem não distingue os
   dois tons e para quem lê por leitor de tela. */
.focus-chip.is-active::before { content: "✓"; font-size: 11px; color: var(--phsp-accent); }
.focus-chip b { color: var(--phsp-text-muted); font-size: 11px; font-variant-numeric: tabular-nums; }
/* ── a mão, desenhada uma vez ──────────────────────────────────────────────
   O rótulo era a palavra "Mão esquerda". Uma mão desenhada é lida antes de ser
   lida: o aluno reconhece a forma sem atravessar o texto, e a criança que ainda
   não lê reconhece do mesmo jeito.
   A esquerda é a MESMA figura espelhada — não um segundo desenho, que
   divergiria do primeiro no primeiro ajuste. */
.glyph-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.hand-glyph { width: 19px; height: 19px; flex: 0 0 auto; color: var(--phsp-voices-right); }
.hand-glyph.is-left { transform: scaleX(-1); color: var(--phsp-voices-left); }
.hand-pair { display: inline-flex; align-items: center; gap: 1px; }
/* Duas mãos juntas ficam largas demais na barra; encolhem e se aproximam. */
.hand-pair .hand-glyph { width: 15px; height: 15px; }
/* A melodia é uma mão só, na cor da melodia, com o brilho que a distingue de
   "mão direita" — que também é uma mão só. */
.hand-melody { display: inline-flex; }
.hand-melody .hand-glyph { color: var(--phsp-voices-melody); filter: drop-shadow(0 0 4px var(--accent-glow)); }

/* ── modo aprendizado ──────────────────────────────────────────────────────
   Fica na barra das mãos porque é a mesma decisão: COMO atravessar a peça
   desta vez. */
/* 12px é o piso do tema, e as duas declarações novas nascem nele em vez de
   engrossar a dívida que a catraca de tipografia está encolhendo. */
.learn-toggle { min-height: 32px; display: inline-flex; align-items: center; gap: 7px; padding: 6px 11px; border: 1px solid var(--phsp-line); background: var(--panel-veil); color: var(--text-dim); cursor: pointer; font-size: 12px; letter-spacing: .04em; transition: border-color .18s ease, background .18s ease, transform .18s ease; }
.learn-toggle:hover { transform: translateY(-1px); border-color: var(--accent-soft); }
.learn-toggle-dot { width: 9px; height: 9px; border-radius: 50%; border: 2px solid var(--phsp-text-muted); }
.learn-toggle[aria-pressed="true"] { border-color: var(--phsp-accent-alt); background: var(--accent-glow); color: var(--phsp-text-primary); }
.learn-toggle[aria-pressed="true"] .learn-toggle-dot { border-color: var(--phsp-accent-alt); background: var(--phsp-accent-alt); }

/* O aviso no palco. Só existe com o modo ligado, e diz a nota ESPERADA — nunca
   se a anterior foi bem tocada. O produto mede alcance de objetivo, e não
   qualidade de execução; um "quase" aqui seria uma nota de desempenho. */
.learn-prompt { position: absolute; z-index: 5; left: 50%; bottom: 12px; transform: translateX(-50%); display: flex; align-items: baseline; gap: 10px; padding: 9px 16px; background: var(--overlay); border: 1px solid var(--phsp-accent-alt); backdrop-filter: blur(14px); pointer-events: none; }
.learn-prompt[hidden] { display: none; }
.learn-prompt-note { color: var(--phsp-text-primary); font-size: 19px; font-weight: 600; letter-spacing: .02em; }
.learn-prompt-hint { color: var(--phsp-text-muted); font-size: 12px; }
.learn-prompt::after { content: "✓"; position: absolute; right: -15px; top: 50%; width: 27px; height: 27px; display: grid; place-items: center; border: 1px solid var(--phsp-accent); border-radius: 50%; background: var(--phsp-bg-primary); color: var(--phsp-accent); font-size: 16px; font-weight: 700; opacity: 0; transform: translateY(-50%) scale(.55); box-shadow: 0 0 0 0 var(--accent-glow); }
.learn-prompt.is-hit { border-color: var(--phsp-accent); animation: learn-hit 320ms ease; }
.learn-prompt.is-hit::after { animation: learn-hit-seal 320ms ease-out; }
@keyframes learn-hit { 0% { transform: translateX(-50%) scale(1); } 40% { transform: translateX(-50%) scale(1.06); } 100% { transform: translateX(-50%) scale(1); } }
@keyframes learn-hit-seal { 0% { opacity: 0; transform: translateY(-50%) scale(.55); box-shadow: 0 0 0 0 var(--accent-glow); } 35%, 72% { opacity: 1; transform: translateY(-50%) scale(1); box-shadow: 0 0 0 8px transparent; } 100% { opacity: 0; transform: translateY(-50%) scale(.88); } }
/* A faixa das teclas é sempre tocável; o modo de estudo continua decidindo
   apenas se uma tecla também libera o portão da música. */
.stage.is-learning .piano-touch-surface { cursor: crosshair; }
@media (prefers-reduced-motion: reduce) {
  .learn-prompt.is-hit { animation: none; }
  .learn-prompt.is-hit::after { animation: none; opacity: 1; transform: translateY(-50%) scale(1); }
  .learn-toggle:hover, .focus-chip:hover { transform: none; }
  #pianoCanvas { transition: none; }
}
.transport { min-height: 54px; display: grid; grid-template-columns: 46px 44px 1fr 44px auto auto auto auto; align-items: center; gap: 10px; padding: 6px 10px; background: var(--overlay); border: 1px solid var(--hairline); }
/* O botão de tocar é o único controle que precisa parecer apertável: ele tem
   luz em cima, sombra de contato embaixo, e AFUNDA quando pressionado. Um botão
   que só muda de cor no clique não dá retorno tátil nenhum. */
.play-button {
  width: 42px; height: 42px; border-radius: 50%; border: 0;
  background: radial-gradient(120% 120% at 34% 22%, color-mix(in srgb, var(--phsp-accent) 74%, var(--phsp-panel)), var(--phsp-accent) 62%);
  color: var(--phsp-ink); cursor: pointer; font-size: 15px;
  box-shadow: 0 0 0 7px var(--accent-faint), var(--relevo-contato), var(--relevo-corpo);
  transition: transform 140ms cubic-bezier(.2, .7, .3, 1), box-shadow 140ms ease;
}
.play-button:hover { transform: translateY(-1px) scale(1.04); box-shadow: 0 0 0 9px var(--accent-faint), var(--relevo-corpo), var(--relevo-halo); }
.play-button:active { transform: translateY(1px) scale(.98); box-shadow: 0 0 0 5px var(--accent-faint), var(--relevo-afundado); }
.time { font-variant-numeric: tabular-nums; font-size: 12px; color: var(--text-dim); text-align: center; }
.timeline-label { position: relative; height: 22px; display: flex; align-items: center; }
#timeline { position: relative; z-index: 2; width: 100%; height: 18px; margin: 0; opacity: .001; cursor: pointer; }
.timeline-label::before { content: ""; position: absolute; left: 0; right: 0; height: 3px; background: var(--phsp-line); }
.timeline-fill { position: absolute; left: 0; width: 0%; height: 3px; background: linear-gradient(90deg, var(--phsp-accent), var(--phsp-accent-alt)); pointer-events: none; }
.timeline-fill::after { content: ""; position: absolute; right: -5px; top: -4px; width: 11px; height: 11px; border-radius: 50%; background: var(--phsp-text-primary); }
.timeline-status { position: absolute; z-index: 5; left: 50%; bottom: 20px; transform: translateX(-50%); width: max-content; max-width: min(70vw, 420px); padding: 5px 8px; border: 1px solid var(--phsp-line); background: var(--phsp-surface-strong); color: var(--phsp-text-primary); font-size: 12px; line-height: 1.25; text-align: center; box-shadow: var(--phsp-shadow-soft); pointer-events: none; }
.timeline-status[data-state="loading"] { color: var(--phsp-accent); }
.timeline-status[data-state="error"] { color: var(--phsp-warning); }
.speed-control, .sound-control { display: flex; gap: 8px; align-items: center; color: var(--phsp-text-muted); font-size: 11px; text-transform: uppercase; letter-spacing: .1em; }
.speed-control select, .sound-control select { color: var(--phsp-text-primary); background: var(--phsp-surface); border: 1px solid var(--phsp-line); padding: 7px 9px; }
.pedal-toggle {
  display: inline-flex; align-items: center; gap: 7px; min-height: 32px; padding: 6px 9px;
  border: 1px solid var(--phsp-line); background: var(--phsp-surface); color: var(--phsp-text-muted);
  font: inherit; font-size: 12px; letter-spacing: .08em; text-transform: uppercase; cursor: pointer;
  touch-action: manipulation; -webkit-tap-highlight-color: transparent;
}
.pedal-toggle b { color: var(--phsp-text-primary); font-size: 12px; }
.pedal-toggle[aria-pressed="true"] { border-color: var(--phsp-accent-alt); box-shadow: inset 0 -3px 0 var(--phsp-accent-alt); }
.pedal-toggle[aria-pressed="true"] b { color: var(--phsp-accent-alt); }

/* ── Guia compacto do player ──────────────────────────────────────────────
   O palco é a aplicação. Tutorial, progresso, calibração e metadados vivem
   neste painel sob demanda, sem disputar altura com a música. */
.player-info-dialog {
  width: min(920px, calc(100vw - 32px)); max-height: min(86dvh, 820px); margin: auto; padding: 0;
  border: 1px solid var(--phsp-line); background: var(--phsp-panel); color: var(--phsp-text-primary);
  box-shadow: 0 28px 90px color-mix(in srgb, var(--phsp-stage-backdrop-bottom) 72%, transparent); overflow: hidden;
}
.player-info-dialog:not([open]) { display: none; }
.player-info-dialog::backdrop { background: color-mix(in srgb, var(--phsp-stage-backdrop-bottom) 76%, transparent); backdrop-filter: blur(8px); }

/* ── partitura protegida pelo PHSP One ─────────────────────────────── */
.score-button { cursor: pointer; }
.score-dialog {
  width: min(1180px, calc(100vw - 28px));
  max-width: none;
  max-height: calc(100dvh - 28px);
  padding: 0;
  border: 1px solid var(--phsp-line);
  color: var(--phsp-text-primary);
  background: var(--phsp-panel);
  box-shadow: var(--shadow);
}
.score-dialog:not([open]) { display: none; }
.score-dialog::backdrop { background: color-mix(in srgb, var(--phsp-stage-backdrop-bottom) 64%, transparent); backdrop-filter: blur(7px); }
.score-sheet { min-height: min(760px, calc(100dvh - 32px)); }
.score-head { display: flex; align-items: center; justify-content: space-between; gap: 20px; padding: 18px 20px; border-bottom: 1px solid var(--phsp-line); background: linear-gradient(115deg, var(--phsp-panel), var(--phsp-surface)); }
.score-identity { display: flex; align-items: center; gap: 16px; min-width: 0; }
.score-identity img { width: 76px; height: 76px; object-fit: cover; border-radius: 14px; box-shadow: 0 8px 22px color-mix(in srgb, var(--phsp-shadow) 36%, transparent); }
.score-identity h2 { margin: 3px 0; font-size: clamp(22px, 3vw, 36px); }
.score-identity p { margin: 0; color: var(--phsp-text-muted); }
.score-close { width: 44px; height: 44px; border: 1px solid var(--phsp-line); background: var(--phsp-panel); color: var(--phsp-text-primary); font-size: 28px; cursor: pointer; }
.score-body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(260px, 320px); gap: 0; min-height: 650px; }
.score-preview { position: relative; min-width: 0; padding: 18px; overflow: auto; background: var(--phsp-surface); }
.score-preview > img,
.score-preview > iframe { display: block; width: 100%; min-height: 610px; border: 0; background: var(--phsp-panel); box-shadow: 0 12px 34px color-mix(in srgb, var(--phsp-shadow) 38%, transparent); }
.score-preview > img { height: auto; min-height: 0; object-fit: contain; }
.score-preview > [hidden] { display: none; }
.score-page-state { position: sticky; left: 16px; bottom: 16px; display: inline-flex; margin-top: 12px; padding: 8px 12px; border-radius: 999px; color: var(--phsp-text-primary); background: var(--overlay); font-size: 12px; letter-spacing: .06em; text-transform: uppercase; }
.score-access-panel { display: flex; flex-direction: column; align-items: stretch; gap: 12px; padding: 32px 24px; border-left: 1px solid var(--phsp-line); background: var(--phsp-panel); }
.score-access-panel h3 { margin: 0; font-size: 24px; }
.score-access-panel p { margin: 0; line-height: 1.55; }
.score-lock { color: var(--phsp-accent); font-size: 42px; }
.score-status { padding: 12px; border-left: 3px solid var(--phsp-accent); background: var(--accent-faint); }
.score-primary,
.score-secondary,
.score-link { min-height: 44px; padding: 11px 14px; border: 1px solid var(--phsp-line); text-align: center; text-decoration: none; font: inherit; cursor: pointer; }
.score-primary { color: var(--phsp-panel); background: var(--phsp-text-primary); }
.score-secondary { color: var(--phsp-text-primary); background: var(--accent-faint); }
.score-link { border-color: transparent; color: var(--phsp-text-muted); background: transparent; }
.score-access-panel small { margin-top: auto; color: var(--phsp-text-muted); line-height: 1.45; }

@media (max-width: 760px) {
  .score-dialog { width: 100vw; max-height: 100dvh; border: 0; }
  .score-sheet { min-height: 100dvh; }
  .score-head { padding: 12px; }
  .score-identity img { width: 56px; height: 56px; }
  .score-identity h2 { font-size: 20px; }
  .score-body { display: flex; flex-direction: column; min-height: 0; }
  .score-preview { padding: 10px; max-height: 58dvh; }
  .score-preview > iframe { min-height: 54dvh; }
  .score-access-panel { padding: 18px; border-top: 1px solid var(--phsp-line); border-left: 0; }
  .score-access-panel small { display: none; }
}
.player-info-sheet { max-height: min(86dvh, 820px); display: flex; flex-direction: column; overflow: hidden; }
.player-info-head {
  position: sticky; z-index: 2; top: 0; display: flex; justify-content: space-between; gap: 24px;
  padding: 22px 24px 18px; border-bottom: 1px solid var(--hairline);
  background: color-mix(in srgb, var(--phsp-panel) 94%, transparent); backdrop-filter: blur(16px);
}
.player-info-head h2 { max-width: 640px; margin: 6px 0 3px; font-family: var(--phsp-display-family); font-size: clamp(24px, 3vw, 36px); font-weight: 500; line-height: 1.08; }
.player-info-head p { margin: 0; color: var(--phsp-text-muted); font-size: 12px; }
.player-info-close {
  flex: 0 0 auto; width: 44px; height: 44px; border: 1px solid var(--phsp-line); border-radius: 50%;
  background: var(--phsp-surface); color: var(--phsp-text-primary); cursor: pointer; font: inherit; font-size: 25px; line-height: 1;
}
.player-info-close:hover { border-color: var(--phsp-accent); color: var(--phsp-accent); }
.player-info-content { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: 1.08fr .92fr; gap: 10px; padding: 12px; overflow-y: auto; overscroll-behavior: contain; }
.player-info-card { min-width: 0; padding: 18px; border: 1px solid var(--hairline); background: var(--panel-veil); }
.player-info-card--wide { grid-column: 1 / -1; }
.player-info-card h3 { margin: 6px 0 12px; font-family: var(--phsp-display-family); font-size: 22px; font-weight: 500; }
.player-info-card p { margin: 0 0 13px; color: var(--phsp-text-muted); font-size: 12px; line-height: 1.5; }
.player-info-steps { counter-reset: player-step; display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin: 0; padding: 0; list-style: none; }
.player-info-steps li { counter-increment: player-step; min-width: 0; padding: 12px; border-left: 2px solid var(--phsp-line); background: color-mix(in srgb, var(--phsp-surface) 58%, transparent); }
.player-info-steps li::before { content: "0" counter(player-step); display: block; margin-bottom: 15px; color: var(--phsp-accent); font-family: var(--phsp-mono-family); font-size: 12px; }
.player-info-steps b, .player-info-steps span { display: block; }
.player-info-steps b { margin-bottom: 4px; font-size: 12px; }
.player-info-steps span { color: var(--phsp-text-muted); font-size: 12px; line-height: 1.4; }
.info-live-status { display: flex; align-items: center; gap: 8px; margin-top: 10px; padding: 9px 11px; border: 1px solid var(--accent-faint); color: var(--phsp-text-muted); font-size: 12px; }
.info-live-status > span:first-child { color: var(--phsp-accent); text-shadow: 0 0 8px var(--phsp-accent); }
.info-live-status b { color: var(--phsp-text-primary); font-size: 12px; }
.info-live-status #samplerStatus[data-state="error"] { color: var(--phsp-accent-alt); }
.shortcut-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 12px; margin: 0; }
.shortcut-grid div { display: grid; grid-template-columns: 70px 1fr; gap: 8px; padding: 8px 0; border-top: 1px solid var(--hairline); }
.shortcut-grid dt { color: var(--phsp-accent); font-family: var(--phsp-mono-family); font-size: 12px; font-weight: 700; }
.shortcut-grid dd { margin: 0; color: var(--phsp-text-muted); font-size: 12px; }
.device-offset-value { display: block; margin: 2px 0 6px; color: var(--phsp-text-primary); font-family: var(--phsp-display-family); font-size: 30px; font-weight: 500; }
.stepper { display: flex; align-items: center; gap: 5px; }
.stepper button { min-height: 38px; border: 1px solid var(--phsp-line); background: var(--phsp-surface); padding: 9px 13px; cursor: pointer; font-size: 12px; }
.stepper button:hover { border-color: var(--phsp-accent); color: var(--phsp-accent); }
.quality-row { display: flex; justify-content: space-between; margin-top: 9px; padding-top: 8px; border-top: 1px solid var(--hairline); font-size: 11px; color: var(--phsp-text-muted); }
.quality-row b { margin: 0; font-family: inherit; font-size: 11px; color: var(--phsp-text-primary); }
.quality-row .accent { color: var(--phsp-accent); }
.quality-row .pending { color: var(--phsp-accent-alt); }
.midi-downloads { display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px; margin-top: 10px; }
.midi-downloads a { padding: 7px 5px; color: var(--text-dim); border: 1px solid var(--accent-faint); background: var(--panel-veil); text-align: center; text-decoration: none; font-size: 11px; letter-spacing: .04em; }
.midi-downloads a:hover { color: var(--phsp-accent); border-color: var(--accent-soft); }

/* Estado vazio e estado de erro. Nenhuma lista e nenhum painel deste produto
   fica mudo quando não há dado: silêncio faz o usuário achar que quebrou. */
.empty-state { padding: 22px 20px; border: 1px dashed var(--phsp-line); background: var(--panel-veil); color: var(--phsp-text-muted); font-size: 12px; line-height: 1.5; }
.empty-state strong { display: block; margin-bottom: 6px; color: var(--phsp-text-primary); font-size: 13px; }
.error-state { border-color: var(--phsp-warning); color: var(--phsp-warning); }

.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

@media (max-width: 1280px) {
  .piano3d-controls { justify-content: flex-start; overflow-x: auto; scrollbar-width: none; }
  .piano3d-controls::-webkit-scrollbar { display: none; }
  .piano3d-controls .piano3d-control-group, .piano3d-controls > button { flex: 0 0 auto; }
}

@media (max-width: 900px) {
  .shell { padding: 8px; }
  .topbar { grid-template-columns: auto 1fr auto; gap: 12px; min-height: 68px; padding: 8px 10px; }
  .sync-badge, .studio-link, .theme-picker label { display: none; }
  .brand .phsp-piano-logo { width: 52px; height: 52px; }
  .track-picker .eyebrow { display: none; }
  .track-picker select { font-size: 22px; }
  .track-heading p { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 50vw; }
  /* No telefone o palco encolhe para o deck caber inteiro sem rolagem — mas
     nunca abaixo do que deixa a faixa das teclas legível. */
  .stage { min-height: 50.6vh; }
  .player-deck { gap: 6px; padding: 6px; }
  .live-metrics span:nth-child(3), .mode-label { display: none; }
  .stage-meta { left: 10px; right: 10px; top: 10px; justify-content: flex-end; }
  .visual-mode-toolbar { top: 7px; left: 7px; transform: none; }
  .stage.is-3d .stage-meta { top: 48px; }
  .piano3d-controls { justify-content: flex-start; overflow-x: auto; scrollbar-width: none; }
  .piano3d-controls::-webkit-scrollbar { display: none; }
  .piano3d-controls .piano3d-control-group, .piano3d-controls > button { flex: 0 0 auto; }
  .piano3d-control-label { padding-inline: 4px; }
  .transport { grid-template-columns: 44px 37px 1fr 37px auto auto; gap: 5px; }
  /* No estreito a reação sobe para a linha implícita junto do resto; o par
     curti/não curti continua inteiro porque é um par, e quebrar um par no meio
     deixaria "curti" sozinho numa linha. */
  .reacoes { flex-wrap: nowrap; }
  .section-bar-label, .loop-state { display: none; }
  .voice-toolbar { overflow-x: auto; scrollbar-width: none; }
  .voice-toolbar::-webkit-scrollbar { display: none; }
  .voice-toolbar-label { display: none; }
  .focus-chip, .learn-toggle { flex: 0 0 auto; padding: 6px 8px; }
  .speed-control { display: none; }
  .sound-control > span { display: none; }
  .sound-control select { max-width: 112px; padding-inline: 5px; }
  .pedal-toggle { padding-inline: 7px; }
  .pedal-toggle span { display: none; }
  .player-info-content { grid-template-columns: 1fr; }
  .player-info-card--wide { grid-column: 1; }
  .player-info-steps { grid-template-columns: 1fr 1fr; }
}

@media (orientation: portrait) {
  .player-card:is(:fullscreen, .is-immersive)[data-immersive-aspect="portrait"] .immersive-heading {
    top: max(12px, env(safe-area-inset-top)); left: max(12px, env(safe-area-inset-left)); max-width: calc(100% - 112px);
  }
  .player-card:is(:fullscreen, .is-immersive)[data-immersive-aspect="portrait"] .immersive-heading .immersive-kicker,
  .player-card:is(:fullscreen, .is-immersive)[data-immersive-aspect="portrait"] .immersive-heading small { display: none; }
  .player-card:is(:fullscreen, .is-immersive)[data-immersive-aspect="portrait"] .immersive-heading strong { font-size: 20px; }
  .player-card:is(:fullscreen, .is-immersive)[data-immersive-aspect="portrait"] .immersive-format {
    top: max(12px, env(safe-area-inset-top)); right: max(12px, env(safe-area-inset-right)); padding: 6px 8px;
  }
  .player-card:is(:fullscreen, .is-immersive)[data-immersive-aspect="portrait"] .visual-mode-toolbar {
    top: max(52px, calc(env(safe-area-inset-top) + 42px)); left: 7px; right: 7px; transform: none;
    justify-content: center; max-width: none;
  }
  .player-card:is(:fullscreen, .is-immersive)[data-immersive-aspect="portrait"] .stage-meta { top: 104px; }
  .player-card:is(:fullscreen, .is-immersive)[data-immersive-aspect="portrait"] .player-deck { padding-top: 5px; }
  .player-card:is(:fullscreen, .is-immersive)[data-immersive-aspect="portrait"] .transport {
    grid-template-columns: 44px 38px minmax(80px, 1fr) 38px auto; gap: 5px; padding: 4px;
  }
  .player-card:is(:fullscreen, .is-immersive)[data-immersive-aspect="portrait"] .sound-control,
  .player-card:is(:fullscreen, .is-immersive)[data-immersive-aspect="portrait"] .speed-control { display: none; }
}

@media (orientation: landscape) and (max-height: 560px) {
  .player-card:is(:fullscreen, .is-immersive) .immersive-heading small { display: none; }
  .player-card:is(:fullscreen, .is-immersive) .immersive-heading strong { font-size: 20px; }
  .player-card:is(:fullscreen, .is-immersive) .stage-meta { top: 58px; }
  .player-card:is(:fullscreen, .is-immersive) .player-deck { padding-block: 4px; }
  .player-card:is(:fullscreen, .is-immersive) .transport { min-height: 44px; padding-block: 2px; }
}

@media (max-width: 600px) {
  .piano3d-controls {
    left: 7px; right: 7px; display: grid; grid-template-columns: minmax(0, 1fr) auto;
    align-items: end; justify-content: stretch; gap: 4px; overflow: visible;
  }
  .piano3d-camera-primary { grid-column: 1; grid-row: 1; justify-self: start; }
  #piano3dInteraction { grid-column: 2; grid-row: 1; align-self: stretch; padding-inline: 7px; }
  .piano3d-visualizer-presets { grid-column: 1 / -1; grid-row: 2; justify-self: start; }
  .piano3d-secondary-controls {
    grid-column: 1 / -1; grid-row: 3; display: flex; max-width: 100%; gap: 4px;
    overflow-x: auto; overscroll-behavior-inline: contain; scrollbar-width: thin;
    pointer-events: auto; padding-bottom: 2px;
  }
  .piano3d-secondary-controls .piano3d-control-group,
  .piano3d-secondary-controls > button { flex: 0 0 auto; pointer-events: auto; }
  .piano3d-control-label { display: none; }
  .piano3d-controls button { min-height: 34px; padding-inline: 6px; }
  .piano3d-key-travel input[type="range"] { width: 88px; }
}

@media (prefers-reduced-motion: reduce) {
  .cover-layer { animation: none; }
  .play-button, .focus-chip { transition: none; }
  .play-button:hover, .focus-chip:hover { transform: none; }
  /* A sombra fica: ela não é movimento, é espessura, e é o que faz o painel
     continuar parecendo objeto para quem desliga a animação. */
}

@media (max-width: 520px) {
  /* No player normal, transporte e seletores viram uma pequena mesa de três
     linhas. A timeline conserva largura útil e nenhum nome de opção força a
     página além dos 360 px. O modo imersivo tem sua própria grade acima. */
  .player-card:not(:fullscreen):not(.is-immersive) .transport {
    grid-template-columns: 44px 38px minmax(0, 1fr) 38px;
    grid-template-rows: auto auto auto;
    gap: 6px 5px;
    padding: 7px;
  }
  .player-card:not(:fullscreen):not(.is-immersive) .transport > * { min-width: 0; }
  .player-card:not(:fullscreen):not(.is-immersive) #playButton { grid-column: 1; grid-row: 1; }
  .player-card:not(:fullscreen):not(.is-immersive) #currentTime { grid-column: 2; grid-row: 1; }
  .player-card:not(:fullscreen):not(.is-immersive) .timeline-label {
    grid-column: 3; grid-row: 1; width: 100%; min-width: 0;
  }
  .player-card:not(:fullscreen):not(.is-immersive) #duration { grid-column: 4; grid-row: 1; }
  .player-card:not(:fullscreen):not(.is-immersive) .reaction-slot {
    grid-column: 1 / 4; grid-row: 2; min-height: 34px;
  }
  .player-card:not(:fullscreen):not(.is-immersive) .pedal-toggle {
    grid-column: 4; grid-row: 2; justify-self: stretch;
  }
  .player-card:not(:fullscreen):not(.is-immersive) .sound-control {
    grid-column: 1 / -1; grid-row: 3; width: 100%; min-width: 0;
  }
  .player-card:not(:fullscreen):not(.is-immersive) .sound-control select {
    width: 100%; max-width: none; min-width: 0;
  }
  .focus-chip b { display: none; }
  .focus-chip span { max-width: 76px; }
  .midi-downloads { grid-template-columns: 1fr; }
  .visual-mode-toolbar button { padding-inline: 7px; }
  .visual-mode-toolbar { right: 7px; max-width: calc(100vw - 14px); overflow-x: auto; scrollbar-width: none; }
  .visual-mode-toolbar::-webkit-scrollbar { display: none; }
  .piano-variant-picker { grid-template-columns: minmax(76px, 1fr); padding-left: 6px; }
  .piano-variant-picker > span, .piano-variant-picker small { display: none; }
  .piano-variant-picker select { grid-column: 1; max-width: 92px; }
  .environment-picker { grid-template-columns: minmax(118px, 1fr); padding-left: 6px; }
  .environment-picker > span, .environment-picker small { display: none; }
  .environment-picker select { grid-column: 1; max-width: 132px; }
  .immersive-toggle [data-immersive-label] { display: none; }
}

@media (max-width: 520px) {
  .player-info-dialog { width: calc(100vw - 12px); max-height: calc(100dvh - 12px); }
  .player-info-sheet { max-height: calc(100dvh - 12px); }
  .player-info-head { padding: 17px 16px 14px; }
  .player-info-head h2 { font-size: 25px; }
  .player-info-head p { display: none; }
  .player-info-content { padding: 6px; gap: 6px; }
  .player-info-card { padding: 15px; }
  .player-info-steps { grid-template-columns: 1fr; }
  .shortcut-grid { grid-template-columns: 1fr; }
}

/* ── Objetivos da unidade ───────────────────────────────────────────────────
   O painel de progresso do curso. Mede alcance de objetivo, nunca qualidade de
   execução — o produto não avalia execução e não tem como avaliar.

   Duas decisões de desenho que carregam regra e não gosto:

   · o denominador aparece do lado do número, sempre. "3 de 4" diz onde a pessoa
     está; um número de pontos sozinho não diz nada, porque ninguém sabe qual é
     o total. Por isso o medidor tem exatamente quatro marcas, e não uma barra
     contínua de porcentagem;

   · o estado de cada objetivo é dito em forma E em texto. Um selo aceso e um
     apagado que só diferem na cor são o mesmo selo para quem não distingue os
     dois — então o alcançado ganha preenchimento, e o rótulo acessível diz
     "alcançado" ou "ainda não". */
.goals-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.goals-head strong { font-family: var(--phsp-mono-family); font-size: 20px; font-variant-numeric: tabular-nums; color: var(--phsp-text-primary); }

.goals-meter { display: flex; gap: 5px; margin: 10px 0 14px; }
.goals-meter i { flex: 1; height: 4px; background: var(--phsp-line); }
.goals-meter i.is-done { background: var(--phsp-accent); }

.goals-list { list-style: none; display: grid; gap: 8px; margin: 0; padding: 0; }
.goal { display: flex; align-items: flex-start; gap: 10px; padding: 8px 0; border-top: 1px solid var(--hairline); }
.goal:first-child { border-top: 0; }
.goal-mark { flex: none; width: 14px; height: 14px; margin-top: 3px; border: 1.5px solid var(--phsp-line); border-radius: 50%; }
.goal.is-done .goal-mark { border-color: var(--phsp-accent); background: var(--phsp-accent); }
.goal-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.goal-body b { font-size: 13px; font-weight: 600; color: var(--phsp-text-muted); }
.goal.is-done .goal-body b { color: var(--phsp-text-primary); }
.goal-body small { font-size: 11.5px; line-height: 1.45; color: var(--phsp-text-muted); }

.goals-badges { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.badge-chip { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; padding: 3px 9px; color: var(--phsp-accent); border: 1px solid var(--phsp-accent); }

.goals-foot { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--hairline); font-size: 11px; line-height: 1.5; color: var(--phsp-text-muted); }
.goals-empty { font-size: 12px; line-height: 1.5; color: var(--phsp-text-muted); }

/* Download da partitura livre — PDF e MIDI para membro PHSP One.
 *
 * Mora no painel de informação, abaixo dos MIDIs derivados. Quem abre o player
 * quer tocar; o download é para quem foi procurar, e por isso ele não disputa
 * espaço com o transporte. */
.free-score-download { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--accent-faint); }
.free-score-download[hidden] { display: none; }
.free-score-title { display: block; font-size: 12px; letter-spacing: .08em; color: var(--text-dim); text-transform: uppercase; }
.free-score-status { margin: 6px 0 9px; font-size: 12px; line-height: 1.45; color: var(--text-dim); }
.free-score-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.free-score-actions button {
  padding: 8px 6px; font-size: 12px; letter-spacing: .04em;
  border: 1px solid var(--accent-faint); background: var(--panel-veil);
  color: var(--text-dim); cursor: pointer;
}
.free-score-actions button:hover:not(:disabled) { border-color: var(--accent); color: var(--text); }
.free-score-actions button:disabled { opacity: .6; cursor: progress; }
/* O crédito fica junto do botão, não escondido: sob Creative Commons
 * Attribution ele é condição da licença, e acompanha também o arquivo. */
.free-score-credit { display: block; margin-top: 8px; font-size: 12px; line-height: 1.4; color: var(--text-dim); opacity: .85; }

/* Contexto da obra e reações.
 *
 * O contexto é texto de verdade — quem escreveu, por que está livre, o que
 * exige da mão. Serve à pessoa e ao buscador com a mesma frase, e por isso não
 * fica escondido atrás de "leia mais". */
.track-context { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--accent-faint); }
.track-context[hidden] { display: none; }
.track-context p { margin: 0 0 7px; font-size: 12px; line-height: 1.55; color: var(--text-dim); }
.track-context p:first-child { color: var(--text); font-weight: 600; }

.reaction-slot { display: inline-flex; align-items: center; }
.reacoes { position: relative; display: inline-flex; align-items: center; gap: 3px; }
.reacoes[hidden] { display: none; }
.reacao {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-width: 30px; min-height: 30px; padding: 3px 6px;
  border: 1px solid transparent; background: transparent; color: var(--text-dim);
  cursor: pointer; line-height: 1;
}
.reacao:hover { background: var(--panel-veil); border-color: var(--accent-faint); }
/* O emoji é texto, não imagem: herda o tamanho e nunca precisa de rede. */
.reacao-emoji { font-size: 17px; line-height: 1; display: block; }
.reacao-rotulo { font-size: 12px; line-height: 1.2; letter-spacing: .02em; }
.reacao-marcada { border-color: var(--phsp-accent); background: var(--accent-glow); color: var(--phsp-text-primary); }
.reacao-marcada .reacao-emoji { transform: scale(1.12); }
.reacao-mais { min-width: 26px; min-height: 30px; padding: 0 5px; border: 1px solid transparent; background: transparent; color: var(--phsp-text-muted); cursor: pointer; font-size: 14px; letter-spacing: .1em; }
.reacao-mais:hover, .reacao-mais[aria-expanded="true"] { background: var(--panel-veil); border-color: var(--accent-faint); }

/* O painel abre PARA CIMA: a barra de transporte mora no rodapé do palco, e um
   painel que descesse ficaria fora da tela. */
.reacoes-painel {
  position: absolute; z-index: 12; right: 0; bottom: calc(100% + 8px);
  width: max(260px, 100%); padding: 11px 12px;
  border: 1px solid var(--phsp-line); background: var(--phsp-panel); box-shadow: var(--shadow);
}
.reacoes-painel[hidden] { display: none; }
.reacoes-fila { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4px; }
.reacoes-fila .reacao { justify-content: flex-start; border-color: var(--hairline); }
.reacoes-nota { margin: 9px 0 0; font-size: 12px; line-height: 1.45; color: var(--phsp-text-muted); }
@media (prefers-reduced-motion: no-preference) {
  .reacao, .reacao-emoji { transition: transform 120ms ease, background-color 120ms ease, border-color 120ms ease; }
}

/* ── acordes ───────────────────────────────────────────────────────────────
   O botão vive na barra das mãos porque responde à mesma pergunta que ela: o
   que exatamente eu vou tocar aqui. O ícone tem faces e sombra em vez de ser
   chapado — três retângulos planos leriam como "linhas", e não como três teclas
   afundadas ao mesmo tempo, que é o que um acorde é. */
.chord-toggle { min-height: 32px; display: inline-flex; align-items: center; gap: 7px; padding: 6px 11px; border: 1px solid var(--phsp-line); background: var(--panel-veil); color: var(--text-dim); cursor: pointer; font-size: 12px; letter-spacing: .04em; transition: border-color .18s ease, background .18s ease, transform .18s ease; }
.chord-toggle:hover { transform: translateY(-1px); border-color: var(--accent-soft); }
.chord-toggle[aria-expanded="true"] { border-color: var(--phsp-accent); background: var(--accent-glow); color: var(--phsp-text-primary); }
.chord-glyph { width: 19px; height: 19px; flex: 0 0 auto; color: var(--phsp-accent); filter: drop-shadow(0 1px 1px color-mix(in srgb, var(--phsp-bg-primary) 70%, transparent)); }
@media (prefers-reduced-motion: reduce) { .chord-toggle:hover { transform: none; } }

.chord-dialog {
  width: min(1080px, calc(100vw - 28px));
  max-width: none;
  max-height: calc(100dvh - 28px);
  padding: 0;
  border: 1px solid var(--phsp-line);
  color: var(--phsp-text-primary);
  background: var(--phsp-panel);
  box-shadow: var(--shadow);
}
.chord-dialog:not([open]) { display: none; }
.chord-dialog::backdrop { background: color-mix(in srgb, var(--phsp-stage-backdrop-bottom) 64%, transparent); backdrop-filter: blur(7px); }
.chord-sheet { display: flex; flex-direction: column; max-height: calc(100dvh - 28px); }
.chord-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 18px 20px 14px; border-bottom: 1px solid var(--hairline); }
.chord-head h2 { margin: 2px 0 6px; font-size: 19px; }
/* O resumo carrega a cobertura da leitura. Ele é a única coisa nesta janela que
   diz o que a leitura NÃO conseguiu nomear, e por isso não é letra miúda
   decorativa: fica no cabeçalho, junto do título. */
.chord-summary { margin: 0; color: var(--phsp-text-muted); font-size: 12px; line-height: 1.5; max-width: 74ch; }
.chord-close { width: 34px; height: 34px; flex: 0 0 auto; border: 1px solid var(--phsp-line); background: var(--panel-veil); color: var(--phsp-text-primary); font-size: 18px; cursor: pointer; }
.chord-close:hover { border-color: var(--accent-soft); }

.chord-body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(300px, 380px); gap: 0; overflow: hidden; }
.chord-picker { display: flex; flex-direction: column; min-height: 0; padding: 14px 16px 16px; overflow-y: auto; }
.chord-tabs { display: inline-flex; gap: 6px; margin-bottom: 12px; }
.chord-tabs button { padding: 7px 14px; border: 1px solid var(--phsp-line); background: var(--panel-veil); color: var(--text-dim); font-size: 12px; letter-spacing: .04em; cursor: pointer; }
.chord-tabs button[aria-pressed="true"] { border-color: var(--phsp-accent); background: var(--accent-glow); color: var(--phsp-text-primary); }
.chord-list { display: flex; flex-wrap: wrap; gap: 7px; align-content: flex-start; }
.chord-list[hidden], .chord-dictionary[hidden] { display: none; }
.chord-chip { min-width: 74px; display: inline-flex; flex-direction: column; align-items: flex-start; gap: 2px; padding: 7px 10px; border: 1px solid var(--phsp-line); background: var(--panel-veil); color: var(--phsp-text-primary); cursor: pointer; text-align: left; transition: border-color .16s ease, background .16s ease; }
.chord-chip:hover { border-color: var(--accent-soft); }
.chord-chip[aria-pressed="true"] { border-color: var(--phsp-accent); background: var(--accent-glow); }
.chord-chip b { font-size: 14px; letter-spacing: .01em; }
.chord-chip small { color: var(--phsp-text-muted); font-size: 12px; font-variant-numeric: tabular-nums; }
/* Ambiguidade não é erro, é o estado real da evidência: as mesmas teclas
   admitem mais de um nome. A marca avisa antes do clique. */
.chord-chip[data-ambiguo="sim"] b::after { content: " ~"; color: var(--phsp-text-muted); }
.chord-roots { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 12px; }
.chord-root { min-width: 42px; padding: 6px 8px; border: 1px solid var(--phsp-line); background: var(--panel-veil); color: var(--text-dim); font-size: 12px; cursor: pointer; }
.chord-root[aria-pressed="true"] { border-color: var(--phsp-accent); background: var(--accent-glow); color: var(--phsp-text-primary); }
.chord-empty { margin: 0; color: var(--phsp-text-muted); font-size: 12px; line-height: 1.55; max-width: 60ch; }

.chord-detail { display: flex; flex-direction: column; gap: 11px; min-height: 0; padding: 16px; border-left: 1px solid var(--hairline); background: var(--overlay); overflow-y: auto; }
.chord-detail-head { display: flex; flex-direction: column; gap: 2px; }
.chord-detail-symbol { font-size: 26px; letter-spacing: .01em; }
.chord-detail-label { color: var(--phsp-text-muted); font-size: 12px; }
.chord-keyboard { width: 100%; height: auto; }
/* A harmonia acompanha o palco, inclusive quando os controles se recolhem. */
.live-chord {
  position: absolute; z-index: 7; top: 14px; left: 14px; width: 188px;
  padding: 10px; border: 1px solid var(--phsp-line); border-radius: 12px;
  background: color-mix(in srgb, var(--phsp-surface) 94%, transparent);
  color: var(--phsp-text-primary); box-shadow: var(--phsp-shadow-soft);
  backdrop-filter: blur(12px);
}
.live-chord-heading { display: grid; gap: 2px; }
.live-chord-tabs { display: flex; gap: 3px; margin: -3px -3px 7px; border-bottom: 1px solid var(--phsp-line); }
.live-chord-tabs button { flex: 1; min-height: 28px; border: 0; border-radius: 7px 7px 0 0; background: transparent; color: var(--phsp-text-muted); font: inherit; font-size: 12px; cursor: pointer; }
.live-chord-tabs button[aria-pressed="true"] { background: var(--phsp-accent); color: var(--phsp-surface); }
.live-chord-tabs button:focus-visible { outline: 2px solid var(--phsp-accent); outline-offset: 2px; }
.live-chord[data-instrument="guitar"] .live-chord-keys { height: 86px; }
.chord-guitar { display: block; width: 140px; height: 86px; max-width: 100%; margin: auto; }
.live-chord-instrument-note { display: block; font-size: 12px; line-height: 1.2; margin: 4px 0 7px; color: var(--phsp-text-muted); }
.live-chord-instrument-note[hidden] { display: none; }
.player-card:not(:fullscreen):not(.is-immersive) .stage:has(.live-chord[data-instrument="guitar"]) { min-height: max(440px, min(64vh, 726px)); }
.live-chord-heading strong { font-size: 22px; line-height: 1.15; overflow-wrap: anywhere; }
.live-chord-heading span { font-size: 12px; line-height: 1.2; color: var(--phsp-text-muted); }
.live-chord-keys { height: 51px; margin: 7px 0; }
.live-chord-keys .chord-keyboard { display: block; height: 100%; }
.live-chord-actions { display: flex; gap: 5px; }
.live-chord-actions button { flex: 1; min-height: 30px; padding: 3px; font: inherit; font-size: 12px; cursor: pointer; border: 1px solid var(--phsp-line); border-radius: 5px; background: var(--phsp-surface); color: var(--phsp-text-primary); }
.live-chord-actions button:hover:not(:disabled) { background: var(--phsp-accent); color: var(--phsp-surface); }
.live-chord-actions button:focus-visible { outline: 2px solid var(--phsp-accent); outline-offset: 2px; }
.live-chord-actions button:disabled { opacity: .45; cursor: default; }
.player-card:is(:fullscreen, .is-immersive):has(.live-chord) .immersive-heading { display: none; }
@media (max-width: 1050px) {
  .live-chord, .player-card:is(:fullscreen, .is-immersive) .live-chord { top: 62px; left: 8px; width: 156px; padding: 8px; }
  .live-chord-keys { height: 40px; margin: 5px 0; }
  .live-chord-heading strong { font-size: 19px; }
  .live-chord-actions button { min-height: 34px; }
}
.player-card:is(:fullscreen, .is-immersive)[data-immersive-aspect="portrait"] .live-chord { top: 104px; }
@media (min-width: 1051px) {
  .stage:has(.live-chord) .stage-meta { left: 220px; }
}
@media (max-height: 500px) and (min-width: 600px) {
  .player-card:is(:fullscreen, .is-immersive) .live-chord[data-instrument="guitar"] {
    display: grid; grid-template-columns: 140px 140px; column-gap: 8px; width: 306px; top: 60px; padding: 8px;
  }
  .live-chord[data-instrument="guitar"] .live-chord-tabs,
  .live-chord[data-instrument="guitar"] .live-chord-heading,
  .live-chord[data-instrument="guitar"] .live-chord-instrument-note { grid-column: 1; }
  .player-card:is(:fullscreen, .is-immersive) .live-chord[data-instrument="guitar"] .live-chord-keys { grid-column: 2; grid-row: 1 / span 3; margin: 0; }
  .live-chord[data-instrument="guitar"] .live-chord-actions { grid-column: 1 / span 2; }
}
.chord-key { stroke: var(--phsp-stage-key-outline); stroke-width: .8; }
.chord-key--branca { fill: var(--phsp-stage-white-key-face); }
.chord-key--preta { fill: var(--phsp-stage-black-key-face); }
.chord-key--branca.chord-key--acesa { fill: var(--phsp-accent); }
.chord-key--preta.chord-key--acesa { fill: color-mix(in srgb, var(--phsp-accent) 78%, var(--phsp-stage-black-key-shade)); }
.chord-detail-notes { margin: 0; color: var(--phsp-text-primary); font-size: 12px; letter-spacing: .02em; }
.chord-detail-warn, .chord-detail-evidence { margin: 0; color: var(--phsp-text-muted); font-size: 12px; line-height: 1.5; }
.chord-detail-actions { display: flex; gap: 7px; }
.chord-play { padding: 8px 16px; border: 1px solid var(--phsp-accent); background: var(--accent-glow); color: var(--phsp-text-primary); font-size: 12px; letter-spacing: .04em; cursor: pointer; }
.chord-play--suave { border-color: var(--phsp-line); background: var(--panel-veil); color: var(--text-dim); }
.chord-play:hover { border-color: var(--accent-soft); }
.chord-detail-when { margin: 4px 0 0; color: var(--phsp-text-muted); font-size: 12px; }
.chord-moments { display: flex; flex-wrap: wrap; gap: 5px; }
.chord-moment { padding: 5px 9px; border: 1px solid var(--phsp-line); background: var(--panel-veil); color: var(--phsp-text-primary); font-size: 12px; font-variant-numeric: tabular-nums; cursor: pointer; }
.chord-moment:hover { border-color: var(--phsp-accent); }

/* No celular a janela vira uma coluna: a lista em cima, o acorde escolhido
   embaixo. Duas colunas de 300px não cabem em 375px de largura. */
@media (max-width: 860px) {
  .chord-body { grid-template-columns: minmax(0, 1fr); }
  .chord-detail { border-left: 0; border-top: 1px solid var(--hairline); }
}


/* ── o dossiê da obra ──────────────────────────────────────────────────────
   Embaixo do palco, na página, e não atrás de um botão. Enquanto esteve dentro
   do diálogo do "i", o texto que explica a obra existia só para quem clicasse —
   e buscador nenhum clica. */
.obra-dossie { margin-top: 18px; padding: 18px 20px 20px; background: var(--overlay); border: 1px solid var(--hairline); }
.dossie-cabeca h2 { margin: 3px 0 4px; font-size: 21px; line-height: 1.25; }
.dossie-autoria { margin: 0; color: var(--phsp-text-muted); font-size: 13px; }
.dossie-compositor { display: inline-block; margin-top: 7px; color: var(--phsp-accent); text-decoration: none; font-size: 13px; }
.dossie-compositor:hover { text-decoration: underline; }
.dossie-compositor[hidden] { display: none; }
.dossie-corpo { display: grid; grid-template-columns: minmax(0, 1fr) minmax(240px, 300px); gap: 22px; margin-top: 15px; }
.dossie-texto .track-context { margin-top: 0; padding-top: 0; border-top: 0; }
.dossie-texto .track-context p { font-size: 13px; line-height: 1.65; max-width: 68ch; }
.dossie-procedencia { margin: 12px 0 0; padding-top: 10px; border-top: 1px solid var(--accent-faint); color: var(--phsp-text-muted); font-size: 12px; line-height: 1.5; }
.dossie-procedencia[hidden] { display: none; }
.dossie-medidas h3 { margin: 0 0 9px; font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--text-dim); }
@media (max-width: 860px) {
  .dossie-corpo { grid-template-columns: minmax(0, 1fr); gap: 16px; }
}
/* Em tela cheia o palco é o produto inteiro: o dossiê é leitura, e leitura não
   disputa espaço com a peça sendo tocada. */
.player-card:is(:fullscreen, .is-immersive) ~ .obra-dossie { display: none; }

/* Piano HQ — marfim, vidro fosco e verde, conforme referência da varanda. */
.player-card:has(.stage.is-3d) {
  --hq-panel: color-mix(in srgb, var(--phsp-panel) 96%, transparent);
  --hq-border: color-mix(in srgb, var(--phsp-text-primary) 12%, transparent);
  --hq-shadow: 0 8px 28px color-mix(in srgb, var(--phsp-shadow) 14%, transparent), inset 0 1px 0 color-mix(in srgb, var(--phsp-panel) 55%, transparent);
}
.stage.is-3d :is(.visual-mode-toolbar, .live-chord, .live-metrics, .mode-label, .immersive-format, .stage-settings-panel),
.stage.is-3d .piano3d-controls :is(.piano3d-control-group, #piano3dInteraction, #piano3dResetCamera) {
  background: var(--hq-panel); border: 1px solid var(--hq-border); border-radius: 18px;
  box-shadow: var(--hq-shadow); backdrop-filter: blur(18px); color: var(--phsp-text-primary);
}
.stage.is-3d .visual-mode-toolbar { gap: 3px; padding: 5px; opacity: 1; border-radius: 22px; }
.stage.is-3d .visual-mode-toolbar :is(button, summary) {
  min-height: 40px; padding: 8px 15px; border-radius: 17px;
  font-size: 13px; font-weight: 650; text-transform: none; letter-spacing: 0;
}
.stage.is-3d :is(.visual-mode-toolbar, .piano3d-controls) button[aria-pressed="true"],
.stage.is-3d .live-chord-tabs button[aria-pressed="true"] {
  color: var(--phsp-panel); background: var(--phsp-accent); border-color: transparent; box-shadow: none;
}
.stage.is-3d :is(button, summary):focus-visible {
  outline: 3px solid var(--phsp-accent); outline-offset: 3px;
}
.stage.is-3d :is(.visual-mode-toolbar, .piano3d-controls) button:hover:not(:disabled):not([aria-pressed="true"]) {
  color: var(--phsp-text-primary); background: color-mix(in srgb, var(--phsp-text-primary) 8%, transparent); border-color: transparent;
}
.stage.is-3d .stage-settings-panel { top: calc(100% + 12px); padding: 18px; min-width: 250px; }
.stage.is-3d .environment-picker select { border-radius: 10px; padding: 9px; min-height: 40px; }
.stage.is-3d .live-chord { width: 216px; padding: 13px; top: 18px; left: 18px; border-radius: 20px; }
.stage.is-3d .live-chord-tabs { border: 0; gap: 4px; margin-bottom: 10px; }
.stage.is-3d .live-chord-tabs button { border-radius: 12px; min-height: 34px; font-weight: 600; }
.stage.is-3d .live-chord-heading strong { font-size: 27px; letter-spacing: -.025em; }
.stage.is-3d .live-chord-heading span { font-size: 12px; margin-top: 3px; }
.stage.is-3d .live-chord-keys { height: 58px; margin: 12px 0; }
.stage.is-3d .live-chord-actions { gap: 8px; }
.stage.is-3d .live-chord-actions button { border-radius: 10px; min-height: 36px; font-weight: 600; }
.stage.is-3d .stage-meta { top: 88px; left: 252px; right: 18px; gap: 12px; }
.stage.is-3d .mode-label { border-radius: 999px; padding: 10px 14px; color: var(--phsp-accent); font-weight: 700; letter-spacing: .055em; }
.stage.is-3d .live-metrics { border-radius: 999px; padding: 10px 15px; gap: 12px; font-size: 12px; }
.stage.is-3d .live-metrics > span + span { border-left: 1px solid var(--hq-border); padding-left: 12px; }
.player-card:is(:fullscreen, .is-immersive) .stage.is-3d .immersive-format { border-radius: 999px; top: 20px; padding: 11px 15px; letter-spacing: .03em; }
.stage.is-3d .piano3d-controls { gap: 8px; flex-wrap: wrap; bottom: 14px; overflow: visible; }
.stage.is-3d .piano3d-controls .piano3d-control-group { padding: 6px; gap: 3px; align-items: center; }
.stage.is-3d .piano3d-controls button { min-height: 34px; border-radius: 11px; padding: 6px 9px; letter-spacing: 0; }
.stage.is-3d .piano3d-control-label { letter-spacing: .065em; font-size: 12px; padding: 0 8px; }
.stage.is-3d .piano3d-key-travel input[type="range"] { width: 90px; }
.player-card:has(.stage.is-3d) .player-deck { padding: 13px 20px; background: var(--hq-panel); border-top: 1px solid var(--hq-border); }
.player-card:has(.stage.is-3d) .transport { border: 0; background: transparent; gap: 12px; }
.player-card:has(.stage.is-3d) .play-button { width: 52px; height: 52px; font-size: 20px; background: var(--phsp-accent); color: var(--phsp-panel); box-shadow: 0 0 0 6px color-mix(in srgb, var(--phsp-accent) 12%, transparent); }
.player-card:has(.stage.is-3d) :is(.sound-control select, .speed-control select, .pedal-toggle) { border-radius: 10px; min-height: 36px; border-color: var(--hq-border); }
.player-card:has(.stage.is-3d) :is(.timeline-label::before, .timeline-fill) { height: 4px; border-radius: 3px; }
.player-card:has(.stage.is-3d) .timeline-fill { background: var(--phsp-accent); }
.player-card:has(.stage.is-3d) .timeline-fill::after { width: 14px; height: 14px; top: -5px; background: var(--phsp-accent); }
@media (max-width: 1200px) {
  .stage.is-3d .piano3d-controls { flex-wrap: nowrap; justify-content: flex-start; overflow-x: auto; padding: 3px 2px; scrollbar-width: thin; }
  .stage.is-3d .piano3d-controls > *, .stage.is-3d .piano3d-control-group { flex-shrink: 0; }
  .stage.is-3d .stage-meta .mode-label { display: none; }
  .stage.is-3d .stage-meta { justify-content: flex-end; }
}
@media (max-width: 900px) {
  .stage.is-3d .live-chord { width: 174px; top: 86px; left: 12px; padding: 10px; }
  .stage.is-3d .live-chord-keys { height: 43px; margin: 8px 0; }
  .stage.is-3d .live-chord-heading strong { font-size: 23px; }
  .stage.is-3d .stage-meta { left: auto; top: 90px; right: 12px; }
  .stage.is-3d .live-metrics { gap: 5px; padding: 8px 10px; font-size: 12px; }
  .stage.is-3d .live-metrics > span + span { padding-left: 5px; }
  .stage.is-3d .live-metrics #midiRange { display: none; }
  .player-card:is(:fullscreen, .is-immersive)[data-immersive-aspect="portrait"] .stage.is-3d .visual-mode-toolbar { top: 14px; left: 12px; right: 12px; }
  .player-card:is(:fullscreen, .is-immersive) .stage.is-3d .immersive-format { display: none; }
}
@media (max-width: 600px) {
  .stage.is-3d .visual-mode-toolbar :is(button, summary) { padding: 7px 10px; min-height: 38px; font-size: 12px; }
  .stage.is-3d .piano3d-controls { display: flex; left: 8px; right: 8px; bottom: 8px; gap: 6px; }
  .stage.is-3d .piano3d-controls .piano3d-secondary-controls { display: contents; }
  .stage.is-3d .piano3d-controls .piano3d-control-group { border-radius: 14px; padding: 4px; }
  .stage.is-3d .piano3d-controls button { min-height: 38px; }
  .player-card:has(.stage.is-3d) .player-deck { padding: 10px 12px; }
  .player-card:has(.stage.is-3d) .transport { gap: 7px; }
  .player-card:has(.stage.is-3d) .play-button { width: 40px; height: 40px; }
}

.midi-membro-fila { display: flex; flex-wrap: wrap; gap: 7px; }

.stage.is-3d .live-chord[data-instrument="guitar"] .live-chord-keys { height: 86px; }
@media (pointer: coarse) {
  .stage.is-3d :is(.visual-mode-toolbar, .live-chord, .piano3d-controls) button,
  .stage.is-3d .visual-mode-toolbar summary { min-height: 44px; min-width: 44px; }
}
/* The reader uses the original SVG, independent of the GPU texture resolution. */
.score-stand-reader{width:min(94vw,960px);max-height:94dvh;border:1px solid var(--phsp-line);border-radius:20px;padding:0;background:var(--phsp-panel);color:var(--phsp-text-primary);box-shadow:0 20px 90px color-mix(in srgb,var(--phsp-shadow) 40%,transparent);overflow:auto}
.score-stand-reader::backdrop{background:var(--overlay);backdrop-filter:blur(6px)}
.score-stand-reader header{position:sticky;top:0;z-index:2;display:flex;align-items:center;gap:16px;padding:16px 20px;background:var(--phsp-surface);border-bottom:1px solid var(--phsp-line)}
.score-stand-reader header strong{flex:1}.score-stand-reader button,.score-stand-reader a{padding:10px 14px;border:1px solid var(--phsp-line);border-radius:10px;background:var(--phsp-panel);color:var(--phsp-accent);font:inherit;cursor:pointer}
.score-stand-reading-page{position:relative;width:100%;background:var(--phsp-stage-white-key-face)}.score-stand-reading-page img{display:block;width:100%;height:auto}
.score-stand-reading-page [data-stand-cursor]{position:absolute;width:3px;transform:translateX(-50%);background:var(--phsp-warning);box-shadow:0 0 8px color-mix(in srgb,var(--phsp-warning) 65%,transparent);pointer-events:none}
.score-stand-reader footer{position:sticky;bottom:0;background:var(--phsp-surface);padding:20px;border-top:1px solid var(--phsp-line);text-align:center}.score-stand-reader footer p{margin:8px 0 16px}.score-stand-reader footer a{display:inline-block;margin:4px;text-decoration:none}
.score-stand-reader [data-stand-empty]{padding:28px}.score-stand-reader [hidden]{display:none!important}
.score-reader-zoom{position:sticky;left:0;top:69px;z-index:2;display:flex;align-items:center;gap:8px;padding:8px 16px;background:var(--phsp-panel);border-bottom:1px solid var(--phsp-line)}
.score-reader-zoom output{min-width:50px;text-align:center;font-variant-numeric:tabular-nums}.score-reader-zoom span{font-size:12px;color:var(--phsp-text-muted)}
.score-stand-reader header{left:0}.score-stand-reading-page{touch-action:none;cursor:grab}.score-stand-reading-page:active{cursor:grabbing}
.walk-overlay{position:absolute;inset:0;z-index:12;pointer-events:none;color:var(--phsp-text-primary)}
.walk-overlay[hidden],.walk-overlay [hidden]{display:none!important}
.walk-overlay button,.walk-stick{pointer-events:auto;touch-action:none}
.walk-guide{position:absolute;left:50%;transform:translateX(-50%);bottom:78px;display:flex;align-items:center;gap:12px;max-width:calc(100% - 280px);padding:8px 12px;border-radius:24px;background:color-mix(in srgb,var(--phsp-panel) 83%,transparent);border:1px solid color-mix(in srgb,var(--phsp-line) 50%,transparent);backdrop-filter:blur(14px);font-size:12px;text-align:center}
.walk-guide button{border:0;background:transparent;color:var(--phsp-accent);font:inherit;white-space:nowrap;min-height:36px;cursor:pointer}
.walk-stick{position:absolute;bottom:96px;width:112px;height:112px;border-radius:50%;border:1px solid color-mix(in srgb,var(--phsp-panel) 70%,transparent);background:radial-gradient(circle,color-mix(in srgb,var(--phsp-panel) 9%,transparent),color-mix(in srgb,var(--phsp-panel) 33%,transparent));backdrop-filter:blur(6px);box-shadow:inset 0 1px 6px color-mix(in srgb,var(--phsp-panel) 40%,transparent),0 4px 22px color-mix(in srgb,var(--phsp-shadow) 14%,transparent);user-select:none;cursor:grab}
.walk-stick-move{left:max(22px,env(safe-area-inset-left))}.walk-stick-look{right:max(22px,env(safe-area-inset-right))}
.walk-stick>span{position:absolute;inset:0;display:grid;place-items:center;font-size:42px;color:color-mix(in srgb,var(--phsp-panel) 80%,var(--phsp-accent));opacity:.75}
.walk-stick i{position:absolute;left:34px;top:34px;width:42px;height:42px;border:1px solid color-mix(in srgb,var(--phsp-panel) 85%,transparent);border-radius:50%;background:color-mix(in srgb,var(--phsp-panel) 52%,transparent);box-shadow:0 3px 10px color-mix(in srgb,var(--phsp-shadow) 16%,transparent);will-change:transform}
.walk-stick.is-held{border-color:var(--phsp-accent)}.walk-stick b{position:absolute;top:122px;left:0;right:0;text-align:center;font-size:11px;font-weight:700;letter-spacing:.15em;color:var(--phsp-text-primary);background:color-mix(in srgb,var(--phsp-panel) 78%,transparent);border-radius:12px;padding:4px}
.walk-seat,.walk-stand{position:absolute;transform:translate(-50%,-50%);padding:13px 22px;border:1px solid color-mix(in srgb,var(--phsp-panel) 75%,transparent);border-radius:30px;background:color-mix(in srgb,var(--phsp-panel) 89%,transparent);color:var(--phsp-accent);box-shadow:0 6px 28px color-mix(in srgb,var(--phsp-shadow) 23%,transparent);backdrop-filter:blur(14px);font:inherit;font-weight:700;cursor:pointer}
.walk-seat small,.walk-stand small{margin-left:10px;border:1px solid var(--phsp-line);border-radius:5px;padding:2px 5px}.walk-stand{left:50%;bottom:135px}
.stage.is-walking .piano3d-controls{display:none!important}
.stage.is-3d [data-walk-toggle]{background:var(--phsp-panel);color:var(--phsp-accent);border:1px solid var(--phsp-line);border-radius:20px;padding:8px 14px}
.walk-guide{bottom:18px}.walk-stick{bottom:74px}
@media(max-width:700px){.walk-guide{bottom:72px;max-width:calc(100% - 24px);font-size:11px;padding:4px 10px}.walk-stick{bottom:139px;width:98px;height:98px}.walk-stick i{left:27px;top:27px}.walk-stick b{top:103px}.walk-stick-move{left:14px}.walk-stick-look{right:14px}.walk-stand{bottom:174px}.score-reader-zoom{gap:5px;top:63px;padding:6px}.score-reader-zoom span{display:none}}
@media(max-width:600px){.score-stand-reader header{gap:8px;padding:12px;font-size:12px}.score-stand-reader footer{padding:12px;font-size:13px}}
@media(max-width:700px){.walk-guide{bottom:16px}.walk-guide [data-walk-help]{display:none}.walk-stick{bottom:87px}.walk-stand{bottom:140px}}
