/* ============================================================================
   satelite.css — O CSS COMUM DAS PÁGINAS SATÉLITE
   (carregado por __SAT_CSS_LINK__ em TODA satélite, ANTES do css/<x>-page.css)

   ─────────────────────────────────────────────────────────────────────────────
   O QUE É
   Este arquivo estiliza EXATAMENTE as classes que a BASE dos brinquedos cria em
   tempo de execução — `RhythmToy` e seus descendentes (`StaffToy`, `IntervalToy`):

       .toy · .toy-card (+ --wide/--tall/.is-playing/::before/:not(.toy))
       .toy-stage (+ svg) · .toy-controls · .toy-btn (+ --primary/is-on/foco)
       .toy-field (+ label/range/select/number/text/checkbox) · .toy-readout
       .toy-hit · .toy-stage [role="slider"]

   Se a classe nasce no JS da base, a regra dela mora AQUI. Se a classe é do
   template de uma página (`rp-`/`lp-`/`ip-`), ela mora no CSS daquela página.
   Essa é a linha divisória inteira, e ela é fácil de aplicar: procure a classe
   no `js/classes/tools/`; se estiver lá, é comum.

   ─────────────────────────────────────────────────────────────────────────────
   POR QUE EXISTE (auditoria de 07/set/2026)
   As duas primeiras satélites (ritmo 30/ago, leitura 31/ago) nasceram como dois
   arquivos independentes, por decisão consciente: a primeira já estava em prod e
   não se tocava numa frente nova. Um mês depois, a medição:

     • 57% das regras do `ritmo-page.css` eram byte a byte iguais às do
       `leitura-page.css`, trocado só o prefixo;
     • o bloco `.toy-*` — que NÃO tem prefixo, porque a classe é da base e é a
       MESMA nas duas páginas — já havia DIVERGIDO em 12 seletores. Duas cópias
       da mesma verdade divergem na primeira correção, e foi o que aconteceu:
       cada conserto feito na leitura ficou na leitura.

   Com a meta declarada de 20 a 30 satélites, isso seria 30 cópias divergindo de
   um bloco que o JS da base já obriga a ser único. Um arquivo, um `<link>`,
   versão pelo conteúdo (`?v=<hash>`); ausente, o token sai vazio e nada quebra.

   🔴 REGRA, e é a única deste arquivo:
      NENHUM `css/<x>-page.css` VOLTA A DEFINIR `.toy-*`.
      A exceção — e é a única forma legítima — é uma regra da PÁGINA que qualifica
      um `.toy-*` com o prefixo dela (ex.: `.lp-section--notas .toy-btn.is-on`,
      a seção das sete cores da leitura). Ali quem manda é a página, e a
      especificidade maior já diz isso. O gate genérico das satélites cobra a
      regra pelos dois lados.

   ─────────────────────────────────────────────────────────────────────────────
   AS DIVERGÊNCIAS, E QUEM VENCEU
   Onde ritmo e leitura discordavam no corpo da MESMA regra, venceu a LEITURA —
   ela é a mais nova e cada divergência dela foi um CONSERTO, não uma preferência:

   1. `.toy-card` SEM `overflow: hidden` (o ritmo tinha). O `hidden` cortava, em
      silêncio, o anel de foco de teclado dos alvos inflados (`StaffToy.hit`) e
      dos punhos de arrasto que encostam na borda do palco. Quem passou a
      respeitar o raio do cartão é a barra de cor, no `::before` (que ganhou
      `border-radius` próprio).
   2. `.toy-card:not(.toy) { min-height: 13rem }` — reserva de altura enquanto o
      brinquedo não montou. Só a leitura tinha. Os brinquedos montam por
      `IntersectionObserver`; sem a reserva, cada cartão abaixo da dobra é um
      talo de ~70px que vira ~350px de repente e empurra a página debaixo do dedo
      de quem está rolando.
   3. `.toy-readout` com `min-width` E `:empty { display: none }` — só a leitura.
      O readout nasce vazio e só é escrito ao tocar: com fundo e largura mínima,
      isso desenhava um blob cinza do tamanho de um botão ao lado dos controles,
      e blob do tamanho de botão a pessoa tenta apertar.
   4. `.toy-hit` e `.toy-stage [role="slider"]` (foco visível dentro do SVG) —
      só a leitura tinha, porque só ela tinha alvos dentro do palco. Alvo
      transparente sem anel de foco é um botão que só existe para o mouse.
   5. `@media (max-width:768px) .toy-card` com padding lateral `--space-3` (a
      leitura) em vez de `--space-4` (o ritmo): no celular o cartão é quem tem
      largura para dar, e largura é legibilidade da pauta.

   O que NÃO virou regra fixa foram as MEDIDAS que cada página mediu para si —
   elas viraram VARIÁVEIS (abaixo). O ritmo precisa de 48,2rem no palco largo
   porque a grade do GrooveBox pede 770px; a leitura precisa de 38rem no palco
   normal porque pauta espremida é o único jeito de estragar aquela página.
   Regra igual, número da página: é o que deixa unificar sem apagar medição.

   ─────────────────────────────────────────────────────────────────────────────
   AS VARIÁVEIS (a página declara; aqui só existe o padrão de segurança)

     --sec / --sec-soft      a cor da SEÇÃO corrente. Quem declara é sempre a
                             página (`.rp-section--x { --sec: … }`) — este arquivo
                             só CONSOME. É o fio condutor visual da rolagem.
     --sat-card              largura do cartão de brinquedo        (padrão 48rem)
     --sat-card-wide         idem, no `--wide`                     (padrão 56rem)
     --sat-stage             largura do palco SVG                  (padrão 38rem)
     --sat-stage-wide        idem, dentro de `.toy-card--wide`     (padrão 46rem)
     --sat-stage-tall        largura do palco no `--tall`          (padrão 34rem)
     --sat-stage-tall-h      teto de ALTURA no `--tall`            (padrão 26rem)

   🔴 Os padrões acima são os da leitura (a página com mais brinquedos), e existem
   só para uma satélite nova nascer razoável sem declarar nada. Toda página em
   produção declara os seus no escopo do `<main>`, e é lá que se muda.

   ─────────────────────────────────────────────────────────────────────────────
   O QUE ESTE ARQUIVO NÃO FAZ
   • Não desenha o miolo de brinquedo nenhum (viewBox, cabeça de nota, tecla): é
     do arquivo do brinquedo.
   • Não pinta notação — nem `fill` nem `stroke` de nada que a base desenhe. Fora
     do modo Kids a cor é reservada a ESTADO (`StaffToy.INK` é preto de propósito).
   • Não usa `font-family: 'Bravura'`. A fonte musical pesa 945 KB e nenhuma
     página estática a baixa; a notação das satélites são contornos no bundle.
   • Não declara `--sec`, `--sec-soft`, nem cor de página nenhuma.
   ========================================================================== */

/* ===========================================================================
   1. O CARTÃO DO BRINQUEDO
   `.toy-card` = a caixa que a PÁGINA escreve no template; `.toy` = a marca que
   o `RhythmToy` põe ao montar. Os dois são o MESMO elemento: o template escreve
   <figure class="toy-card" data-toy="…"> e `mount()` acrescenta `.toy`.
   =========================================================================== */
.toy-card {
    position: relative;
    max-width: var(--sat-card, 48rem);
    margin: 0 auto;
    padding: var(--space-6) var(--space-5) var(--space-5);
    background: var(--color-surface);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-card);
    transition: box-shadow var(--transition-normal);
    /* 🔴 Sem `overflow: hidden` (divergência 1 do cabeçalho): os brinquedos têm
       alvos tocáveis INFLADOS até 44px (`StaffToy.hit`) e punhos de arrasto que
       encostam na borda do palco — `hidden` cortaria o anel de foco de teclado
       deles em silêncio. Quem respeita o raio é a barra, no `::before`. */
}
.toy-card--wide { max-width: var(--sat-card-wide, 56rem); }

/* 🔴 Reserva de altura ENQUANTO o brinquedo não montou. Os brinquedos montam por
   `IntersectionObserver` (o custo só nasce ao entrar na tela), então sem isto
   cada cartão abaixo da dobra é um talo de ~70px que vira ~350px de repente e
   empurra a página debaixo do dedo de quem está rolando. Não é espelho do
   viewBox de ninguém — é uma reserva genérica, e some no instante em que o
   brinquedo monta (`.toy`). */
.toy-card:not(.toy) { min-height: 13rem; }

/* Barra de cor no topo: o brinquedo pertence visivelmente à seção. O raio é
   repetido AQUI em vez de sair de um `overflow: hidden` no cartão (ver acima). */
.toy-card::before {
    content: "";
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 4px;
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
    background: linear-gradient(90deg, var(--sec), var(--sec-soft));
}

/* Tocando: o cartão ganha um anel na cor da seção. É o único feedback de estado
   que a PÁGINA dá — o resto é do brinquedo. */
.toy-card.is-playing {
    box-shadow: var(--shadow-card-hover), 0 0 0 3px var(--sec-soft);
}

/* ===========================================================================
   2. O PALCO SVG
   🔴 Os tetos são POR PÁGINA (variáveis), porque foram medidos por página:
   pauta espremida estraga a satélite da leitura, e a grade do GrooveBox pede
   771px de largura na do ritmo. Aqui só a regra.
   =========================================================================== */
.toy-stage {
    max-width: var(--sat-stage, 38rem);
    margin: 0 auto;
    /* Escotilha de emergência: brinquedo que peça largura mínima rola AQUI
       DENTRO — nunca na página. */
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
}
/* No cartão largo o palco também cresce — com teto: solto, num monitor de 1100
   ele media 808px e o espaço de pauta chegava a 27px, quatro vezes o da
   partitura impressa. Pauta gigante não é mais legível, é só grande. */
.toy-card--wide .toy-stage { max-width: var(--sat-stage-wide, 46rem); }
/* `--tall` é uma DICA de proporção para o brinquedo alto (duas pautas e a
   chave), não um espelho do viewBox de ninguém: o viewBox é do agente do
   brinquedo e muda durante a construção. Por isso são dois tetos independentes —
   um de largura, que sempre vale, e um de ALTURA, que só entra em ação no caso
   patológico (aí o desenho encolhe centrado, em vez de virar uma parede). */
.toy-card--tall .toy-stage { max-width: var(--sat-stage-tall, 34rem); }
.toy-card--tall .toy-stage svg { max-height: var(--sat-stage-tall-h, 26rem); }

/* 🔴 O viewBox é de cada brinquedo — nada de altura fixa aqui. */
.toy-stage svg {
    display: block;
    width: 100%;
    height: auto;
    overflow: visible;                 /* halo/anel que escapa do viewBox */
}

/* ===========================================================================
   3. A BARRA DE CONTROLES
   🔴 `flex-wrap` NÃO é enfeite: quatro botões de 44px numa linha de 390 estouram,
   e o `overflow-x` do body corta em SILÊNCIO (nenhum erro, nenhuma barra — o
   conteúdo some pela direita). Aqui ela quebra em duas linhas.
   =========================================================================== */
.toy-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--space-2) var(--space-3);
    margin-top: var(--space-5);
    min-width: 0;
}
.toy-controls > * { min-width: 0; max-width: 100%; }
.toy-controls:empty { margin-top: 0; }

/* 🔴 44×44px de alvo, SEMPRE — e isso é compromisso de LARGURA também, inclusive
   quando o rótulo é uma letra só (♯, ♭, ▲, ▼, e nos intervalos `3M`/`M3`). */
.toy-btn {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 2.75rem;
    min-width: 2.75rem;
    padding: 0 var(--space-4);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    background: var(--color-surface);
    color: var(--color-text);
    font-family: inherit;
    font-size: 0.9375rem;
    font-weight: var(--font-semibold);
    line-height: 1.2;
    text-align: center;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: border-color var(--transition-fast), background var(--transition-fast),
                color var(--transition-fast), transform var(--transition-fast);
}
.toy-btn:hover { border-color: var(--sec); color: var(--sec); }
.toy-btn:active { transform: scale(0.97); }
/* `StaffToy.choice()` marca os DOIS (aria-pressed + .is-on) — as regras andam
   juntas de propósito, para o estado nunca depender de um só. */
.toy-btn[aria-pressed="true"], .toy-btn.is-on {
    background: var(--sec-soft);
    border-color: var(--sec);
    color: var(--sec);
}

.toy-btn--primary {
    background: var(--sec);
    border-color: var(--sec);
    color: #fff;
    padding: 0 var(--space-6);
    box-shadow: 0 4px 12px rgb(0 0 0 / 0.12);
}
.toy-btn--primary:hover {
    background: var(--sec); border-color: var(--sec); color: #fff; filter: brightness(1.08);
}

/* Anel de foco do botão. Os elementos de MOLDURA de cada página (chips, CTAs)
   repetem esta forma no CSS delas — o seletor deles tem prefixo e não caberia
   aqui. */
.toy-btn:focus-visible {
    outline: 3px solid var(--sec);
    outline-offset: 2px;
}

/* ===========================================================================
   4. ALVOS E PUNHOS DENTRO DO SVG
   🔴 `.toy-hit` é um retângulo TRANSPARENTE (`StaffToy.hit` o infla até 44px de
   tela). Transparente e sem foco visível é um botão que só existe para o mouse.
   `outline` em nó SVG ainda é irregular entre navegadores, então o anel vem
   TAMBÉM por `stroke` — que num retângulo invisível não conflita com desenho
   nenhum e aparece em todos eles.
   =========================================================================== */
.toy-hit { cursor: pointer; }
.toy-hit:focus-visible {
    outline: 3px solid var(--sec);
    outline-offset: 2px;
    stroke: var(--sec);
    stroke-width: 2;
    stroke-dasharray: 5 4;
}
/* O punho de arrastar vira `role="slider"` e anda pelas setas (`StaffToy.drag`).
   Aqui só o anel: mexer em fill/stroke repintaria o desenho do brinquedo. */
.toy-stage [role="slider"]:focus-visible {
    outline: 3px solid var(--sec);
    outline-offset: 3px;
}

/* ===========================================================================
   5. CAMPO ROTULADO
   A base monta <label.toy-field><span.toy-field-label> + o nó. O nó costuma ser
   um <input type="range"> ou um <select>: ele manda o campo ocupar a linha.
   =========================================================================== */
.toy-field {
    flex: 1 1 14rem;
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 0;
    max-width: 22rem;
}
.toy-field-label {
    font-size: var(--text-xs);
    font-weight: var(--font-semibold);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-text-muted);
}

/* Slider com 44px de área de toque, mas trilho fino: a altura é do DEDO, não do
   desenho. */
.toy-field input[type="range"] {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: 2.75rem;
    margin: 0;
    background: transparent;
    cursor: pointer;
}
.toy-field input[type="range"]::-webkit-slider-runnable-track {
    height: 6px; border-radius: 3px; background: var(--color-border);
}
.toy-field input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 24px; height: 24px; margin-top: -9px;
    border-radius: 50%;
    background: var(--sec);
    border: 3px solid var(--color-surface);
    box-shadow: var(--shadow-md);
}
.toy-field input[type="range"]::-moz-range-track {
    height: 6px; border-radius: 3px; background: var(--color-border);
}
.toy-field input[type="range"]::-moz-range-thumb {
    width: 18px; height: 18px;
    border-radius: 50%;
    background: var(--sec);
    border: 3px solid var(--color-surface);
    box-shadow: var(--shadow-md);
}

.toy-field select,
.toy-field input[type="number"],
.toy-field input[type="text"] {
    min-height: 2.75rem;
    max-width: 100%;
    padding: 0 var(--space-3);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    color: var(--color-text);
    font-family: inherit;
    font-size: var(--text-base);      /* <16px faz o iOS dar zoom no foco */
}
.toy-field input[type="checkbox"] { width: 1.5rem; height: 1.5rem; accent-color: var(--sec); }

/* Campo que é um slider ganha a linha inteira: um trilho espremido entre botões
   não se arrasta com o polegar. */
.toy-field:has(input[type="range"]) { flex: 1 1 100%; max-width: 26rem; }

/* ===========================================================================
   6. LEITURA VIVA (o nome da nota, o BPM, o intervalo)
   🔴 O conteúdo muda com o IDIOMA — `Dó`/`C`/`Do`, `5J`/`P5` — então a pílula é
   larga o bastante para a palavra maior e curta o bastante para não empurrar a
   linha de controles.
   =========================================================================== */
.toy-readout {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 2.25rem;
    min-width: 3.5rem;
    padding: 0 var(--space-4);
    border-radius: var(--radius-full);
    background: var(--sec-soft);
    color: var(--color-text);
    font-weight: var(--font-bold);
    font-size: 0.9375rem;
    font-variant-numeric: tabular-nums;   /* o número não "dança" ao mudar */
    white-space: nowrap;
}
/* 🔴 Readout VAZIO não é pílula (divergência 3 do cabeçalho). */
.toy-readout:empty { display: none; }

/* ===========================================================================
   7. RESPONSIVO
   =========================================================================== */
@media (max-width: 768px) {
    /* 🔴 O desenho pede LARGURA e o cartão é quem tem para dar. Padding lateral
       menor no celular = mais px por espaço de pauta (ou por tecla), que é a
       legibilidade inteira destas páginas. O padding de cima e de baixo não
       muda: é ele que separa o desenho da barra de cor e dos controles. */
    .toy-card { padding: var(--space-5) var(--space-3) var(--space-4); }
}

@media (max-width: 480px) {
    /* 🔴 Aqui é onde a largura vira o risco. Num aparelho de 390 (ou de 320), a
       barra de controles TEM de quebrar: campo ocupa a linha inteira e o rótulo
       do botão não estica além do cartão. O piso de 44px continua valendo —
       quem encolhe é o PADDING, nunca o `min-height`/`min-width`. */
    .toy-field { flex: 1 1 100%; max-width: 100%; }
    .toy-controls { gap: var(--space-2); }
    .toy-btn { padding: 0 var(--space-3); font-size: 0.875rem; }
    .toy-btn--primary { padding: 0 var(--space-5); }
}

/* ===========================================================================
   8. MOVIMENTO REDUZIDO
   O `styles.css` já zera transições globalmente; aqui garantimos que o único
   movimento que a BASE produz no toque também pare. Brinquedo parado continua
   com o ▶ funcionando: quem cuida disso é o `RhythmToy` (invariante 6).
   =========================================================================== */
@media (prefers-reduced-motion: reduce) {
    .toy-btn:active { transform: none; }
}
