/*  ══════════════════════════════════════════════════════════════════════════
    simulador-3d/sim3d.css — A CASCA DAS PÁGINAS DE SIMULADOR.

    Tudo o que está FORA da janela 3D e é igual em todas elas: a trilha, o
    título, a explicação, o guia de cartões e a lista do hub.

    ─── POR QUE ESTE ARQUIVO EXISTE ───

    Havia duas escritas do mesmo desenho. O simulador de camisa tinha
    `.sim-guia` no fim do `mockup.css`; o de caneca tinha `.cn-guia` no fim do
    `caneca.css` — mesmos cartões, mesma numeração, mesma promessa no pé, com
    tamanhos de fonte e de ícone que já divergiam em quatro pontos. Cada peça
    nova acrescentaria uma terceira cópia, e a página nova nasceria parecida
    com uma das duas e diferente da outra.

    Aqui é UMA escrita só. Quem monta uma peça nova carrega este arquivo e
    escreve `.s3-*` no HTML: o texto embaixo da janela já sai igual ao das
    outras, sem copiar CSS de lugar nenhum.

    ─── O QUE NÃO ENTRA AQUI ───

    A JANELA. O palco, o painel de controles e a chapa são de cada peça: a
    camisa tem cinco partes, alças e lupa; a caneca tem uma área e três
    controles deslizantes. Eles moram no `mockup.css` e no `caneca.css`, e é
    certo que morem — o que se parece de verdade fica junto, o que só se
    pareceria por força fica separado.

    ─── AS CORES ───

    As da casa (`--cor-marca` e as suas), do `assets/css/base.css`, com valor
    de reserva escrito ao lado caso a folha mude de nome. Este arquivo vive na
    página, e não dentro do `#app` reescopado do sublimarker — aqui as
    variáveis do site chegam.
    ══════════════════════════════════════════════════════════════════════════ */

:root {
    /*  A LARGURA DA CASA, num lugar só.
        O `<main>` do site é `.cw-container`: 1280px com 16px de folga de cada
        lado, o que dá 1248px de miolo. As páginas de simulador ocupam esse
        miolo inteiro e não põem folga própria — folga em cima de folga é o que
        fazia o palco da caneca nascer 32px mais estreito que o da camisa, com
        as duas telas lado a lado numa aba cada.                             */
    --s3-larg: 1248px;
}

/* ══════════════════════════════════════════════════════════════════════════
   O TEXTO ABAIXO DA JANELA

   Alinhado com a beira esquerda do palco, e não numa coluna estreita centrada:
   o título tem de nascer no prumo da peça que está logo acima dele. Os
   parágrafos soltos é que são limitados — linha de 1240px de texto corrido
   ninguém lê.
   ══════════════════════════════════════════════════════════════════════════ */
.s3-texto {
    max-width: var(--s3-larg);
    margin: 26px auto 40px;
    color: var(--cor-texto, #0f172a);
}
.s3-texto h1 {
    font-size: 2rem;
    line-height: 1.2;
    letter-spacing: -.01em;
    margin: 10px 0 10px;
}
.s3-texto p {
    color: var(--cor-texto-suave, #475569);
    line-height: 1.65;
    margin: 0 0 10px;
}
.s3-texto__lead { max-width: 900px; font-size: 1.05rem; }
/*  ─── ELE PERDIA NA CASCATA, E POR ISSO ENCOSTAVA ─── (10/09/2026)
    `.s3-texto p` acima diz `margin: 0 0 10px` — e vale mais que `.s3-texto__pe`
    sozinho: uma classe DENTRO de outra (0,1,1) ganha de uma classe só (0,1,0).
    O `margin-top: 22px` escrito aqui nunca chegou a valer, e o computado saía
    zero: medido na tela, o vão até a caixa verde de cima era de 10 px — os
    10 px de baixo do parágrafo anterior, e nada de cima.
    Com o `p` no seletor a conta empata em especificidade e a ordem decide, que
    é o que esta linha já queria dizer desde o começo.                       */
.s3-texto p.s3-texto__pe { max-width: 900px; margin-top: 20px; font-size: .9rem; }
/*  A CAIXA VERDE CAI NA MESMA ARMADILHA: escrita como `.s3-nota` (0,1,0) ela
    perdia para `.s3-texto p` (0,1,1), e o `margin-top` aparecia RISCADO no
    inspetor. Com o `p` no seletor a conta empata e a ordem decide.         */
.s3-texto p.s3-nota { margin-top: 20px; }

/*  A trilha vinha com um `style=` inline em cada página, e com um valor
    diferente em cada uma. Ela é parte da casca — mora aqui.                 */
.s3-texto .cw-breadcrumb { margin-top: 0; }

/* ══════════════════════════════════════════════════════════════════════════
   O GUIA — "como usar o simulador"

   DEPOIS da janela, e não antes: quem chega já vê a peça e quase sempre começa
   a mexer sozinho. Um manual antes dela seria um muro de texto entre o
   visitante e o que ele veio ver; aqui embaixo ele acha quando trava, que é
   quando ele procura.

   E é texto de verdade, indexável: estas páginas vivem de busca, e uma
   explicação escrita para gente vale mais que uma lista de palavras.
   ══════════════════════════════════════════════════════════════════════════ */
.s3-guia { margin-top: 30px; }

.s3-guia__cab { max-width: 760px; margin: 0 0 20px; }
.s3-guia__cab h2 {
    font-size: 1.4rem;
    font-weight: 700;
    letter-spacing: -.01em;
    margin: 0 0 7px;
    color: var(--cor-texto, #0f172a);
}
.s3-guia__cab p {
    margin: 0;
    font-size: 1rem;
    line-height: 1.65;
    color: var(--cor-texto-suave, #475569);
}

/*  Três colunas que viram duas e depois uma, por `auto-fit`: a quebra acontece
    quando o cartão fica estreito demais para o texto, e não numa largura de
    tela escolhida a dedo — que envelheceria no primeiro aparelho novo.      */
.s3-cards {
    display: grid;
    gap: 14px;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}

.s3-card {
    display: flex;
    align-items: flex-start;
    gap: 13px;
    padding: 16px 17px;
    border-radius: 14px;
    background: var(--cor-fundo-suave, #f8fafc);
    border: 1px solid var(--cor-borda, #e2e8f0);
    transition: border-color .18s, box-shadow .18s, transform .18s;
}
.s3-card:hover {
    border-color: var(--cor-marca, #e2507d);
    box-shadow: 0 8px 26px #0f172a14;
    transform: translateY(-2px);
}

/*  A caixa do desenho não encolhe: é ela que mantém os seis ícones alinhados
    de cima a baixo, por mais que os textos tenham alturas diferentes.

    E ela aceita OS DOIS DESENHOS que a casa usa: o `<svg>` do sprite, na
    camisa, e o emoji, na caneca. Não é indecisão — o sprite da camisa é
    animado e responde ao `:hover` do cartão, e trocá-lo por emoji para
    "uniformizar" seria jogar fora trabalho feito. O que uniformiza é a CAIXA,
    que é o que se vê de longe.                                             */
.s3-card__ic {
    flex: 0 0 auto;
    width: 48px;
    height: 48px;
    border-radius: 13px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #fff;
    border: 1px solid var(--cor-borda, #e2e8f0);
    font-size: 1.35rem;   /* vale para o emoji; o `<svg>` traz o tamanho dele */
    line-height: 1;
}
/*  ── AS ANIMAÇÕES DOS ÍCONES ACENDEM AQUI ──
    Elas ficam definidas dentro do sprite (`icones.php`), porque folha de fora
    não alcança o miolo de um `<use>`. O que atravessa é a herança, então basta
    acender a variável neste ponto. Nos botões da tela ela continua apagada, e
    nada se mexe lá.                                                         */
.s3-card .ic, .s3-nota .ic { --ic-anim: running; }
.s3-card:hover .ic { animation-duration: 1.1s; }
.s3-guia .ic { width: 28px; height: 28px; display: block; flex: 0 0 auto; }

/*  O NÚMERO NO CANTO, e não antes do título: assim ele numera o cartão sem
    entrar na leitura da frase. É o desenho do simulador de caneca, que virou
    o padrão da casa.                                                        */
.s3-card__txt { position: relative; min-width: 0; padding-right: 26px; }
.s3-card__n {
    position: absolute;
    top: 1px;
    right: 0;
    width: 21px;
    height: 21px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--cor-marca, #e2507d);
    color: #fff;
    font-size: 11.5px;
    font-weight: 700;
    line-height: 1;
}
.s3-card__txt h3 {
    margin: 0 0 4px;
    font-size: 1rem;
    font-weight: 650;
    color: var(--cor-texto, #0f172a);
}
.s3-card__txt p {
    margin: 0;
    font-size: .89rem;
    line-height: 1.6;
    color: var(--cor-texto-suave, #475569);
}
.s3-card__txt b { color: var(--cor-texto, #0f172a); font-weight: 650; }

/*  ═══ O CARTÃO ABRE A AJUDA (fase 5, 15/09/2026) ═══

    O guia nasce agora do `ajuda/conteudo/artigos.json` (ver o
    `ajuda/ajuda_guia.php`), e o título de cada cartão é um botão que abre a
    Central naquele artigo. Aqui ele se veste de título — sem a cara de botão
    do navegador —, e o que o faz parecer clicável só aparece depois que o
    `ajuda.js` está no ar e marcou o `<html>` com `aj-pronto`. Antes disso,
    ou sem ele, o cartão é o texto de sempre, e nada promete um clique que
    não faria nada.

    O clique vale na coluna de texto inteira: o `::after` do botão a cobre,
    e a coluna já é `position: relative` por causa do número no canto.     */
.s3-card__abre {
    appearance: none;
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    color: inherit;
    text-align: left;
    cursor: default;
}
.s3-card__sr {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}
.s3-card__mais { display: none; }
.aj-pronto .s3-card__abre { cursor: pointer; }
.aj-pronto .s3-card__abre::after { content: ""; position: absolute; inset: -4px; border-radius: 10px; }
.aj-pronto .s3-card__abre:focus-visible { outline: none; }
.aj-pronto .s3-card__abre:focus-visible::after { outline: 3px solid #f0759b; outline-offset: 2px; }
.aj-pronto .s3-card__mais {
    display: inline-block;
    margin-top: 7px;
    font-size: .8rem;
    font-weight: 650;
    color: var(--cor-marca, #e2507d);
}
.aj-pronto .s3-card:hover .s3-card__mais { text-decoration: underline; text-underline-offset: 2px; }

/*  A PROMESSA, repetida no pé do guia. Ela já está dentro da janela, ao lado
    do botão de carregar — mas quem lê o "como usar" ainda não mandou arquivo
    nenhum, e é exatamente nessa hora que a pergunta aparece.                */
.s3-nota {
    display: flex;
    align-items: flex-start;
    gap: 11px;
    margin: 16px 0 0;
    padding: 14px 16px;
    border-radius: 12px;
    background: #fdf4f7;
    border: 1px solid #f3d3dd;
    font-size: .89rem;
    line-height: 1.62;
    color: var(--cor-texto-suave, #475569);
}
.s3-nota b { color: var(--cor-marca, #e2507d); }

/* ══════════════════════════════════════════════════════════════════════════
   OS BOTÕES DE "MINHAS PREFERÊNCIAS"

   Montados pelo `preferencias.js`, e iguais nas duas telas — por isso moram
   aqui, e não no `mockup.css` nem no `caneca.css`. Nenhuma classe da casa é
   reaproveitada de propósito: `.bt` só existe dentro do `#app` da camisa, e
   `.cn-bt` só dentro da caneca; um botão que precisa ser o mesmo nas duas não
   pode herdar de nenhum dos dois.

   Pesos diferentes pelo mesmo motivo dos botões do molde: guardar é a decisão,
   apagar é a saída. Dois botões cheios não diriam qual é qual.
   ══════════════════════════════════════════════════════════════════════════ */
.sim-pref-bts {
    display: flex;
    flex-wrap: wrap;
    gap: 7px;
    margin: 11px 0 3px;
}
.sim-pref-bt {
    flex: 1 1 100%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 10px 13px;
    border-radius: 10px;
    border: 1.5px solid transparent;
    font-family: inherit;
    font-size: 13px;
    font-weight: 700;
    line-height: 1.15;
    cursor: pointer;
    transition: background-color .14s, box-shadow .14s, transform .12s;
}
.sim-pref-bt:hover { transform: translateY(-1px); }
.sim-pref-bt--salva {
    background: var(--cor-marca, #e2507d);
    color: #fff;
    box-shadow: 0 3px 12px #e2507d33;
}
.sim-pref-bt--salva:hover { background: var(--cor-marca-escura, #be2d59); }
.sim-pref-bt--limpa {
    background: #fff;
    color: var(--cor-texto-suave, #475569);
    border-color: var(--cor-borda, #e2e8f0);
}
.sim-pref-bt--limpa:hover { background: var(--cor-fundo-suave, #f8fafc); }

#prefEstado { margin-top: 8px; }
#prefEstado.ruim { color: #c0392b; }

/* ══════════════════════════════════════════════════════════════════════════
   O BOTÃO "TODAS AS VISTAS"

   Ele entra na barra de cada tela e VESTE O QUE A BARRA VESTE: na camisa é
   filho de `.sim-salvar` e herda dela a pílula de vidro; na caneca leva a
   classe `.cn-bt-palco`. Nada de forma é escrito aqui — um botão com desenho
   próprio no meio de cinco iguais leria como coisa de fora.

   O que fica é só o que as duas folhas não têm como saber: o tamanho do
   desenho na caneca (onde `.ic` não existe) e a cara do botão enquanto a
   cascata corre.
   ══════════════════════════════════════════════════════════════════════════ */
#btCascata svg { width: 17px; height: 17px; flex: 0 0 auto; }
/*  Trabalhando: sem clique e com o cursor dizendo por quê. Ele continua
    legível — é ele que mostra "3/6" enquanto os arquivos saem.              */
#btCascata[disabled] { opacity: .85; cursor: progress; }

/* ══════════════════════════════════════════════════════════════════════════
   O OLHO — ver a peça sem nada em volta

   Montado pelo `olho_palco.js`, e igual nas duas telas.

   Ele fica no canto de baixo à direita, que é o único canto do palco livre nas
   duas: em cima à esquerda está o mostrador, em cima à direita o botão do
   painel, embaixo ao centro as pílulas de vista e à esquerda a barra de
   ferramentas.

   `z-index: 30` o põe acima de tudo o que flutua — inclusive da alça da
   largura, que corre a beira direita inteira. Ele precisa continuar clicável
   justamente quando todo o resto está apagado.
   ══════════════════════════════════════════════════════════════════════════ */
.s3-olho {
    position: absolute;
    right: 10px;
    bottom: 10px;
    z-index: 30;
    width: 34px;
    height: 34px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 9px;
    cursor: pointer;
    border: 1px solid #e2e8f0;
    background: #ffffffdc;
    color: var(--cor-texto-suave, #475569);
    backdrop-filter: blur(8px);
    box-shadow: 0 2px 10px #0f172a1f;
    transition: background-color .14s, color .14s, transform .12s;
}
.s3-olho:hover {
    background: var(--cor-marca, #e2507d);
    border-color: var(--cor-marca, #e2507d);
    color: #fff;
    transform: translateY(-1px);
}
.s3-olho svg { width: 19px; height: 19px; }
/*  UM DESENHO DE CADA VEZ: olho aberto quando há o que esconder, olho cortado
    quando já está escondido.

    Os quatro seletores levam `.s3-olho` na frente por CONTA. `.s3-olho svg` é
    classe mais tipo, e ganha de uma classe sozinha: escrito `.s3-olho__ocultar
    { display:none }`, o `display:block` da regra de cima passava por cima e os
    dois desenhos apareciam lado a lado dentro do botão. Aqui todos disputam com
    o mesmo peso, e quem decide é a ordem — como tem de ser.                 */
.s3-olho .s3-olho__ver     { display: block; }
.s3-olho .s3-olho__ocultar { display: none; }
.s3-limpo .s3-olho .s3-olho__ver     { display: none; }
.s3-limpo .s3-olho .s3-olho__ocultar { display: block; }

/*  ── O PALCO LIMPO ──
    Some TODO filho do palco que não seja o canvas nem o próprio botão — e não
    uma lista de nomes, que envelheceria na próxima ferramenta flutuante.
    Por opacidade, e não por `display`: o palco não muda de tamanho, então o 3D
    não é redesenhado e a alça da altura não perde a beira que ela mede.     */
/*  ─── E O `!important` NÃO É PREGUIÇA ─── (16/09/2026)

    Sem ele o olho DEIXOU DE ESCONDER A BARRA DE VISTAS, e o CW viu no celular.

    A conta: este seletor pesa `0,0,2,1` — uma classe (`.s3-limpo`), mais
    `:not(canvas)` (um tipo) e `:not(.s3-olho)` (uma classe), porque o `:not`
    vale o peso do que está dentro dele. A transparência da barra de vistas,
    escrita hoje de manhã, é `#app .mk-vistas` — `0,1,1,0`. **Um id ganha de
    qualquer número de classes**, então a opacidade dela passava por cima desta,
    e a barra continuava à vista com o palco "limpo". No telefone era pior
    ainda: lá a regra `@media (hover: none)` a prende em 1.

    Daria para subir o peso daqui com um `#app` na frente, mas seriam quatro
    seletores por família e a mesma armadilha esperando a próxima ferramenta
    flutuante. O palco limpo NÃO É um estilo entre outros — é um MODO, e um
    modo tem de ganhar de todo mundo, inclusive do `:hover` que traz a barra de
    volta (com o palco limpo, passar o dedo não pode acender nada).        */
.s3-limpo > *:not(canvas):not(.s3-olho) {
    opacity: 0 !important;
    pointer-events: none;
    transition: opacity .18s;
}
/*  E a alça da altura, que é a única ferramenta que mora fora do palco.     */
body.s3-palco-limpo .s3-alca-alt {
    opacity: 0 !important;
    pointer-events: none;
}
/*  Escondido, o próprio olho fica discreto — ele é o caminho de volta, e não
    tem por que continuar chamando atenção sobre uma peça que se quis ver
    limpa. No `:hover` ele reaparece inteiro.                                */
.s3-limpo .s3-olho { background: #ffffff8f; box-shadow: none; }
.s3-limpo .s3-olho:hover { background: var(--cor-marca, #e2507d); }

@media (prefers-reduced-motion: reduce) {
    .s3-limpo > *:not(canvas):not(.s3-olho) { transition: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   A ALÇA DA ALTURA DO PALCO

   Montada pelo `alca_palco.js`, e igual nas duas telas — por isso mora aqui, e
   não no `mockup.css` nem no `caneca.css`.

   Uma faixa no pé do palco, da largura toda, com o punho no meio. A faixa é
   invisível e generosa (é ela que pega o ponteiro); o punho é o que se vê, e
   ele fica À VISTA SEMPRE. Já foi só no `:hover`, na alça da largura, e a
   lição está escrita lá: alça que só aparece quando o mouse chega perto é alça
   que ninguém descobre — a pessoa precisaria passar o dedo por cima dela sem
   ter motivo para isso.

   `z-index: 1` a põe ABAIXO das pílulas de vista, que são o que se aperta o
   tempo todo. Um alvo de arrasto por cima delas roubaria o clique.
   ══════════════════════════════════════════════════════════════════════════ */
/*  O DESENHO É O DA ALÇA DA LARGURA, deitado — mesmo traço fino na beira,
    mesmo punho de pastilha branca com dois risquinhos, mesma engordada no
    `:hover`. São a mesma ferramenta em dois sentidos, e duas ferramentas
    parecidas com desenhos diferentes fazem a pessoa achar que fazem coisas
    diferentes.

    A ÁREA DE PEGAR É MAIOR QUE O TRAÇO que se vê: acertar três pixels com o
    mouse é o tipo de exigência que faz achar que a alça não funciona. O
    `::before` invisível estende o alvo para cima e para baixo.

    Os 3px de recuo da beira são para o traço não ser cortado pelo canto
    arredondado do palco — o mesmo motivo, e o mesmo número, da outra.       */
.s3-alca-alt {
    position: absolute;
    /*  `left`, `top` e `width` VÊM DO JS, e não daqui: a alça não mora mais
        dentro do palco — ela é irmã dele, no primeiro ancestral que não corta
        o que passa da beira —, e por isso precisa que alguém diga onde essa
        beira está. Ver `poeAlca` no `alca_palco.js`.

        Foi o que a tirou de dentro: o palco tem `overflow:hidden` (é ele que
        arredonda os cantos do canvas), e o punho, que fica SOBRE a linha,
        aparecia cortado ao meio.                                            */
    height: 18px;
    z-index: 6;
    cursor: ns-resize;
    /*  Sem isto o navegador do celular entende o arrasto como rolagem da
        página e a alça não se mexe.                                         */
    touch-action: none;
    /*  SEM O TRAÇO ATRAVESSADO.
        A alça da largura tem um, e ali ele funciona: é vertical, tem a altura
        da moldura e cai sobre a beira do cenário, onde já há uma divisa. Este
        seria HORIZONTAL e da largura toda — uma linha branca cortando o pé da
        peça, no lugar onde ninguém pediu divisa nenhuma.
        Fica só o punho, que é o que se pega e o que anuncia a alça.         */
    background: transparent;
}
.s3-alca-alt::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: -6px;
    bottom: -6px;
}
/*  O PUNHO FICA À VISTA, SEMPRE. Ele já dependeu do `:hover` na alça irmã, e a
    lição está escrita lá: alça que só aparece quando o mouse chega perto é
    alça que ninguém descobre. Parado ele é discreto; no `:hover` ganha corpo. */
/*  CENTRADO NA FAIXA, que por sua vez é centrada na linha de baixo do palco:
    o punho fica metade para dentro e metade para fora, sobre a divisa — que é
    onde a alça da largura fica em relação à beira dela.                     */
.s3-alca-alt i {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 34px;
    height: 12px;
    border-radius: 4px;
    background: #ffffffee;
    box-shadow: 0 2px 10px #0000002e;
    transition: transform .15s, box-shadow .15s;
}
.s3-alca-alt:hover i,
.s3-alca-alt.puxando i {
    transform: translate(-50%, -50%) scale(1.12);
    box-shadow: 0 3px 14px #00000040;
}
/*  os dois risquinhos do meio, que dizem "isto se arrasta".

    A COR É CRAVADA, e é o mesmo `#4c3fd6` da alça da largura (`.sim-alca i`
    no `mockup.css`). Ela chegou a sair de `--cor-marca` — e aí as duas alças
    da mesma janela ficaram com risquinhos de cores diferentes, uma verde e a
    outra azul. São a mesma ferramenta em dois sentidos; o que as diferencia
    tem de ser só a direção.                                                 */
.s3-alca-alt i::before,
.s3-alca-alt i::after {
    content: "";
    position: absolute;
    left: 9px;
    right: 9px;
    height: 2px;
    border-radius: 1px;
    background: #4c3fd6;
}
.s3-alca-alt i::before { top: 3px; }
.s3-alca-alt i::after  { bottom: 3px; }

/*  Enquanto se puxa, a página inteira para de selecionar texto e o cursor de
    redimensionar acompanha o ponteiro mesmo fora da faixa.                  */
body.s3-puxando-alt { user-select: none; cursor: ns-resize; }

/* ══════════════════════════════════════════════════════════════════════════
   O HUB — a lista de simuladores em `/simulador-3d/`

   Cartões grandes, um por peça, e é a página inteira: não há janela 3D aqui.
   Cada cartão é UM LINK — o `<a>` é o cartão, e não um botão dentro dele: em
   tela de toque a área que responde tem de ser a que se vê.
   ══════════════════════════════════════════════════════════════════════════ */
.s3-hub {
    max-width: var(--s3-larg);
    margin: 26px auto 44px;
    color: var(--cor-texto, #0f172a);
}
.s3-hub__tit {
    font-size: 2rem;
    line-height: 1.2;
    letter-spacing: -.01em;
    margin: 10px 0 10px;
}
/*  A cor e o entrelinhamento dos parágrafos soltos do hub. Eles não estão
    dentro do `.s3-texto` — o hub não tem janela acima de si, e o wrapper de lá
    existe para o que vem DEPOIS da peça.                                     */
.s3-hub > p {
    color: var(--cor-texto-suave, #475569);
    line-height: 1.65;
    margin: 0 0 10px;
}

.s3-hub__lista {
    display: grid;
    gap: 18px;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    margin-top: 24px;
}

.s3-peca {
    display: flex;
    flex-direction: column;
    /*  Âncora do feixe que dá a volta na moldura (`::after`, logo abaixo).  */
    position: relative;
    border: 1px solid var(--cor-borda, #e2e8f0);
    border-radius: 16px;
    background: #fff;
    overflow: hidden;
    text-decoration: none;
    color: inherit;
    transition: border-color .18s, box-shadow .18s, transform .18s;
}
.s3-peca:hover {
    border-color: var(--cor-marca, #e2507d);
    box-shadow: 0 12px 32px #0f172a1a;
    transform: translateY(-3px);
    text-decoration: none;
}

/* ── O FEIXE QUE DÁ A VOLTA NA MOLDURA ─────────────────────────────────────
   Uma luz grossa passando pela borda, em laço. Ela diz que o cartão é um
   caminho, e não uma ficha: a lista inteira fica parada e a moldura anda.

   ─── COMO ELA É FEITA, E POR QUE ASSIM ───

   O caminho óbvio seria um elemento por trás do cartão, maior que ele, girando
   — e ele morre no `overflow:hidden` que a tampa precisa ter para arredondar.
   Então a luz é desenhada DENTRO: um `conic-gradient` que ocupa o cartão todo
   e uma MÁSCARA que apaga o miolo, deixando ver só a faixa de 3px da beira.
   Duas máscaras, uma na caixa de conteúdo e outra na caixa inteira, subtraídas
   uma da outra — o que sobra é exatamente a moldura.

   ─── O ÂNGULO É UMA PROPRIEDADE REGISTRADA ───

   `@property` com `syntax: "<angle>"` é o que faz o navegador saber INTERPOLAR
   o giro. Uma variável comum é texto para ele: a animação pularia de 0 a 360
   sem nada no meio, e o feixe ficaria parado.

   ─── E É UM ARCO, NÃO UM ANEL ───

   Só uns 90° acendem; o resto do círculo é transparente. Um anel inteiro aceso
   seria uma borda de neon em três cartões ao mesmo tempo, e a página passaria
   a ser sobre a borda. Assim é uma luz que PASSA.
   ────────────────────────────────────────────────────────────────────────── */
@property --s3-luz {
    syntax: "<angle>";
    initial-value: 0deg;
    inherits: false;
}
@keyframes s3-luz-gira { to { --s3-luz: 360deg; } }

.s3-peca::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 16px;
    /*  A ESPESSURA DA LUZ. É o `padding` que a máscara vai poupar.          */
    padding: 3px;
    background: conic-gradient(from var(--s3-luz),
        transparent 0deg 262deg,
        #f0759b26  278deg,
        #ff9dbb    312deg,
        #ffe0ea    338deg,
        var(--cor-marca, #e2507d) 350deg,
        transparent 360deg);
    -webkit-mask:
        linear-gradient(#000 0 0) content-box,
        linear-gradient(#000 0 0);
            mask:
        linear-gradient(#000 0 0) content-box,
        linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    pointer-events: none;
    animation: s3-luz-gira 5s linear infinite;
}
/*  No ponteiro ela acelera. O cartão já responde ao `:hover` subindo e
    ganhando sombra; a luz acompanhar é o que faz as três coisas parecerem uma
    reação só, e não três enfeites empilhados.                               */
.s3-peca:hover::after { animation-duration: 2.6s; }

/*  O cartão do que ainda não existe NÃO ACENDE. Ele não é um caminho, é um
    aviso — e uma luz correndo em volta prometeria um clique que não há.     */
.s3-peca--breve::after { content: none; }

/*  A TAMPA DO CARTÃO é o desenho da peça sobre o verde da marca — o mesmo
    verde que é o cenário padrão dentro do 3D das duas telas. Quem chega aqui
    e clica encontra do outro lado a cor que já viu na lista.

    Ela é `aspect-ratio`, e não altura em pixel: os cartões ficam lado a lado e
    as tampas têm de bater no prumo em qualquer largura de tela.             */
.s3-peca__capa {
    aspect-ratio: 16 / 9;
    display: flex;
    align-items: center;
    justify-content: center;
    /*  A ÂNCORA DA FOTO. Ela é `position:absolute` (ver `.s3-peca__foto`), e
        sem esta linha o bloco que a mede seria o CARTÃO — que é quem está
        posicionado, por causa do `::after` da moldura. Medido assim: a camisa
        saía com 405 px de altura numa tampa de 226, cobrindo o título e metade
        do texto.                                                             */
    position: relative;
    /*  E o que passar da tampa fica escondido. Isto é o cinto de segurança: a
        foto já cabe pelos dois tetos, e se um dia uma entrar fora de medida o
        cartão continua um cartão.                                            */
    overflow: hidden;
    background:
        radial-gradient(120% 120% at 50% 0%, #ffc4d6 0%, #ff9dbb 55%, #f483a8 100%);
    border-bottom: 1px solid var(--cor-borda, #e2e8f0);
}
.s3-peca__capa svg {
    width: 44%;
    max-width: 190px;
    height: auto;
    /*  O desenho ganha uma sombra própria: sobre o verde chapado, um contorno
        branco sem profundidade lia como adesivo colado.                     */
    filter: drop-shadow(0 6px 14px #00000038);
    transition: transform .25s;
}
.s3-peca:hover .s3-peca__capa svg { transform: scale(1.045); }

/*  ── A FOTO DA PEÇA (08/09/2026) ──
 *
 *  Desde esta data quase todas as tampas são FOTO, e não desenho: a peça
 *  tirada do próprio simulador, com as partes pintadas de cores diferentes.
 *  Ver o cabeçalho do `$PECAS`, em `index.php`, e o do
 *  `trabalho/scripts/cartoes_captura.mjs`, que as gera.
 *
 *  ELA É LIMITADA PELOS DOIS LADOS, e não por um. As fotos não têm formato
 *  comum: a camisa sai em pé (320 x 520), o boné sai deitado (520 x 310).
 *  Limitando só a altura, o boné vazaria a tampa na largura; limitando só a
 *  largura, a camisa estouraria na altura. Com os dois tetos, cada peça para
 *  no que a apertar primeiro e todas ficam do mesmo tamanho aparente.
 *
 *  A SOMBRA É MAIS FUNDA que a do desenho. Um traço branco chapado sobre o
 *  verde já se destaca sozinho; uma foto com volume precisa de chão, ou fica
 *  parecendo colada.                                                        */
.s3-peca__foto {
    /*  ── E ELA É ABSOLUTA, o que não é capricho ──
     *
     *  Em fluxo normal, dentro do `flex` da tampa, o `max-width` em
     *  porcentagem resolvia e o `max-height` NÃO — medido: a camisa saía com
     *  209 x 340 px numa tampa de 209 px de altura, vazando 131 px por baixo
     *  do cartão. Altura em porcentagem só resolve com certeza contra um bloco
     *  de altura definida, e a tampa tem a dela por `aspect-ratio`.
     *
     *  Absoluta, com `inset: 0` e `margin: auto`, ela é medida contra a tampa,
     *  os dois tetos valem e a centragem sai de graça nos dois eixos.        */
    position: absolute;
    inset: 0;
    margin: auto;
    max-height: 84%;
    max-width: 62%;
    width: auto;
    height: auto;
    object-fit: contain;
    filter: drop-shadow(0 10px 18px #00000045);
    transition: transform .25s;
}
.s3-peca:hover .s3-peca__foto { transform: scale(1.05); }

/*  ── E ELA NÃO BOIA ──
 *  O desenho flutuava quatro pixels para a lista não parecer uma captura de
 *  tela. As fotos SÃO capturas de tela, e essa é a graça delas — fazê-las
 *  balançar seria maquiar o que o cartão passou a dizer. Vinte peças subindo
 *  e descendo ao mesmo tempo também seriam vinte coisas pedindo atenção numa
 *  página cujo trabalho é deixar escolher uma.                              */

/* ── AS ANIMAÇÕES DO DESENHO ────────────────────────────────────────────────
   Sobrou UM desenho na lista — o cubo do "em breve", que não tem simulador de
   onde tirar foto. Estas regras são as dele, e o que segue é o que restou de
   um conjunto que servia a vinte e um (ver o cabeçalho de `.s3-peca__foto`).

   Duas camadas:

   1. O TRAÇO SE DESENHA, uma vez, ao abrir a página. Os traços entram em
      cascata, com um sexto de segundo entre eles — juntos seriam um pisca só.
   2. A PEÇA BOIA, sempre e muito pouco: quatro pixels em cinco segundos. Não é
      para ser notado; é para o cartão não parecer um selo apagado.

   A flutuação mora num `<g>`, e o `scale` do `:hover` no `<svg>` de fora: as
   duas mexem em `transform`, e no mesmo elemento a última calaria a primeira.

   O QUE SAIU DAQUI EM 08/09/2026: a camisa balançando pendurada pelos ombros
   e o vapor da caneca. As duas eram animações de ponteiro escritas para
   desenhos que deixaram de existir — e uma regra que não casa com nada é pior
   que uma regra a menos: ela faz procurar o elemento que a explicaria.
   ────────────────────────────────────────────────────────────────────────── */

/*  O traço é escondido por um tracejado do tamanho do desenho inteiro e
    "puxado" para dentro do quadro. 520 é maior que o mais comprido deles —
    medir cada um daria quatro números para manter, e o que a mais não faz
    diferença: o que passa do comprimento do path não é desenhado.           */
@keyframes s3-risca { from { stroke-dashoffset: 520; } to { stroke-dashoffset: 0; } }
/*  E o preenchimento chega DEPOIS do contorno, como quem pinta dentro da
    linha. Ao mesmo tempo, a forma apareceria pronta e o traço não teria o que
    revelar.                                                                 */
@keyframes s3-enche { from { fill-opacity: 0; } to { fill-opacity: 1; } }

.s3-svg .s3-tr {
    stroke-dasharray: 520;
    animation: s3-risca 1.5s cubic-bezier(.62, 0, .3, 1) both,
               s3-enche .7s ease .95s backwards;
}
/*  `nth-child`, e NÃO `nth-of-type`: a caneca tem um `<ellipse>` no meio dos
    `<path>` — a boca —, e `of-type` conta cada tipo por si. A boca seria a
    primeira elipse, entraria sem atraso nenhum e a cascata quebraria bem no
    meio do desenho.                                                         */
.s3-svg .s3-tr:nth-child(2) { animation-delay: .16s, 1.05s; }
.s3-svg .s3-tr:nth-child(3) { animation-delay: .32s, 1.15s; }
.s3-svg .s3-tr:nth-child(4) { animation-delay: .46s, 1.25s; }

@keyframes s3-boia {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-4px); }
}
.s3-svg__g {
    /*  `fill-box` para a origem em porcentagem valer sobre o desenho, e não
        sobre o sistema de coordenadas do SVG inteiro.                       */
    transform-box: fill-box;
    transform-origin: 50% 50%;
    /*  Começa depois que o traço terminou de se desenhar.                   */
    animation: s3-boia 5s ease-in-out 1.7s infinite;
}
/*  O cubo do "em breve" boia mais devagar: ele não é um convite, é um aviso. */
.s3-svg--breve .s3-svg__g { animation-duration: 7.5s; }

.s3-peca__txt { padding: 16px 18px 18px; }
.s3-peca__txt h2 {
    margin: 0 0 6px;
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--cor-texto, #0f172a);
}
.s3-peca__txt p {
    margin: 0;
    font-size: .9rem;
    line-height: 1.6;
    color: var(--cor-texto-suave, #475569);
}

/*  A LISTA DO QUE A PEÇA FAZ, três itens curtos. Ela responde à pergunta que
    a pessoa faz olhando a lista — "esta é a que eu preciso?" — sem obrigar a
    abrir as duas para descobrir.                                            */
.s3-peca__itens {
    list-style: none;
    margin: 11px 0 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.s3-peca__itens li {
    font-size: .78rem;
    line-height: 1;
    padding: 6px 9px;
    border-radius: 20px;
    background: var(--cor-fundo-suave, #f8fafc);
    border: 1px solid var(--cor-borda, #e2e8f0);
    color: var(--cor-texto-suave, #475569);
}

.s3-peca__ir {
    margin-top: 14px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: .9rem;
    font-weight: 650;
    color: var(--cor-marca, #e2507d);
}
.s3-peca:hover .s3-peca__ir { text-decoration: underline; }

/*  ── O CARTÃO DO QUE AINDA NÃO EXISTE ──
    Ele não é link, e não finge ser: sem `href` não há clique, e a tampa é
    cinza em vez de verde. Está aqui porque a pergunta "vocês têm de caneca?"
    é feita antes de a caneca existir — e uma lista que responde "ainda não,
    mas vem" vale mais do que uma que se cala.                              */
.s3-peca--breve { cursor: default; }
.s3-peca--breve:hover {
    border-color: var(--cor-borda, #e2e8f0);
    box-shadow: none;
    transform: none;
}
.s3-peca--breve .s3-peca__capa {
    background: linear-gradient(160deg, #eef2f7 0%, #dfe5ee 100%);
}
.s3-peca--breve .s3-peca__capa svg { opacity: .55; filter: none; }
.s3-peca--breve .s3-peca__txt h2 { color: var(--cor-texto-suave, #475569); }
.s3-peca__breve {
    display: inline-block;
    margin-top: 12px;
    padding: 5px 10px;
    border-radius: 20px;
    background: var(--cor-fundo-suave, #f8fafc);
    border: 1px dashed var(--cor-borda-forte, #cbd5e1);
    font-size: .78rem;
    font-weight: 650;
    color: var(--cor-texto-fraco, #94a3b8);
}

/* ══════════════════════════════════════════════════════════════════════════
   TELEFONE — e é a última coisa do arquivo, de propósito.

   Com a especificidade toda igual, quem decide é a ordem: uma regra de
   computador escrita abaixo deste bloco passaria a valer no telefone também.
   É a mesma armadilha descrita no `_fonte/LEIA.md`.
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 700px) {
    .s3-texto h1, .s3-hub__tit { font-size: 1.6rem; }
    .s3-guia__cab h2 { font-size: 1.25rem; }
    .s3-card { padding: 14px; }
    .s3-card__ic { width: 42px; height: 42px; border-radius: 11px; }
}

@media (prefers-reduced-motion: reduce) {
    .s3-card, .s3-peca, .s3-peca__capa svg, .s3-peca__foto { transition: none; }
    .s3-card:hover, .s3-peca:hover { transform: none; }
    .s3-peca:hover .s3-peca__capa svg,
    .s3-peca:hover .s3-peca__foto { transform: none; }
    /*  Os desenhos ficam PRONTOS, e não escondidos: sem a animação, um traço
        com `stroke-dashoffset` de 520 seria um cartão vazio.                */
    .s3-svg .s3-tr {
        animation: none;
        stroke-dasharray: none;
        fill-opacity: 1;
    }
    .s3-svg__g { animation: none; }
    /*  E o feixe da moldura sai de cena: parado ele seria um arco verde num
        canto do cartão, que não é desenho nenhum.                           */
    .s3-peca::after { content: none; }
}


/*  ↓ ↓ ↓  TRAZIDO DA PRODUÇÃO EM 08/09/2026  ↓ ↓ ↓
    `www.docesdesenhos.com/simulador-3d/sim3d.css`, verbatim.

    A bancada estava atrás: o aviso flutuante já existia no ar e nunca tinha
    descido para cá — o `preferencias.js` daqui ainda escrevia o resultado como
    texto embaixo do botão, e o CW reparou ("os botões de ações não têm um
    alerta na tela; o do site online já tinha").

    Copiado sem retoque, de propósito: mexer nele aqui criaria uma segunda
    verdade sobre um componente que está publicado.                          */
/* ══════════════════════════════════════════════════════════════════════════
   O AVISO FLUTUANTE DAS PREFERÊNCIAS

   Aqui, e não no `mockup.css` nem no `caneca.css`, pelo mesmo motivo dos
   botões logo acima: ele é o MESMO nas quatro telas, e as outras duas folhas
   são cada uma de uma peça.  O `mockup.css` ainda por cima é GERADO
   (`_fonte/LEIA.md`) — o que se escrevesse lá morreria na próxima montagem.

   ─── ONDE ELE FICA NA PILHA ───

   9990.  Acima da janela cheia do simulador (1200, ver a nota no fim deste
   arquivo) e das duas camadas nomeadas da casa (`--z-modal` 1000, `--z-toast`
   1100), porque um aviso coberto não avisa.  E abaixo do carrinho (9998), que
   continua sendo o único que cobre tudo.

   No pé em telas estreitas e no canto inferior direito nas largas: no celular
   o polegar mora embaixo, e num monitor o canto não passa por cima do painel
   de controles, que é justamente o que a pessoa acabou de mexer.
   ══════════════════════════════════════════════════════════════════════════ */
.s3-toast {
    position: fixed;
    z-index: 9990;
    left: 12px;
    right: 12px;
    bottom: 12px;
    display: flex;
    align-items: flex-start;
    gap: 11px;
    padding: 13px 14px;
    border-radius: 14px;
    border: 1px solid var(--cor-borda, #e2e8f0);
    border-left: 5px solid var(--s3-toast-cor, #e2507d);
    background: #fff;
    box-shadow: 0 14px 38px #0f172a2e, 0 3px 10px #0f172a1a;
    font-family: var(--fonte-principal, system-ui, sans-serif);
    /*  Escondido de verdade: sem `visibility` ele continuaria clicável por
        cima do palco 3D depois de sumir, e um botão invisível engolindo o
        arrasto da câmera é o tipo de defeito que ninguém liga ao aviso.     */
    opacity: 0;
    visibility: hidden;
    transform: translateY(14px);
    transition: opacity .22s ease, transform .22s ease, visibility .22s;
}
.s3-toast.is-vendo {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}
.s3-toast[data-tipo="aviso"] { --s3-toast-cor: #b7791f; }
.s3-toast[data-tipo="ruim"]  { --s3-toast-cor: #c0392b; }

.s3-toast__ic {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    color: #fff;
    background: var(--s3-toast-cor, #e2507d);
}
.s3-toast__ic svg { width: 15px; height: 15px; }

.s3-toast__txt { flex: 1 1 auto; min-width: 0; }
.s3-toast__tit {
    display: block;
    font-size: 14px;
    font-weight: 800;
    line-height: 1.25;
    color: var(--cor-texto, #0f172a);
}
.s3-toast__det {
    display: block;
    margin-top: 3px;
    font-size: 12.5px;
    line-height: 1.45;
    color: var(--cor-texto-suave, #475569);
}
.s3-toast__acao:empty { display: none; }
.s3-toast__bt {
    margin-top: 9px;
    padding: 7px 13px;
    border: 0;
    border-radius: 9px;
    background: var(--s3-toast-cor, #e2507d);
    color: #fff;
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 700;
    cursor: pointer;
}
.s3-toast__bt:hover { filter: brightness(.92); }

.s3-toast__x {
    flex: 0 0 auto;
    width: 24px;
    height: 24px;
    margin: -3px -3px 0 0;
    border: 0;
    border-radius: 7px;
    background: none;
    color: var(--cor-texto-suave, #475569);
    font-size: 19px;
    line-height: 1;
    cursor: pointer;
}
.s3-toast__x:hover { background: var(--cor-fundo-suave, #f1f5f9); }

/*  O foco do teclado tem de aparecer SOBRE o branco do aviso — os dois botões
    são a única forma de fechá-lo e de recarregar sem o mouse.               */
.s3-toast__bt:focus-visible,
.s3-toast__x:focus-visible {
    outline: 2px solid var(--cor-marca, #e2507d);
    outline-offset: 2px;
}

@media (min-width: 700px) {
    .s3-toast {
        left: auto;
        right: 18px;
        bottom: 18px;
        max-width: 380px;
    }
}

/*  Quem pediu menos movimento ganha o aparecer sem o deslize.               */
@media (prefers-reduced-motion: reduce) {
    .s3-toast { transition: opacity .01s, visibility .01s; transform: none; }
    .s3-toast.is-vendo { transform: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   A PELE COMUM DOS SIMULADORES (08/09/2026)

   O CW abriu o boné militar depois de a camiseta de pesca ter ganho a pele
   nova e disse: "a aparência que aplicamos no painel de pesca aqui nesses
   está diferente — pegue como base o simulador de pesca e passe para todos os
   outros". Este bloco é isso.

   ─── O QUE ESTAVA DIFERENTE, MEDIDO E NÃO OLHADO ───

       camiseta-pesca   sombra do card  3 camadas       fundo da página  #eef3fa
       boné             sombra do card  NENHUMA         fundo da página  #ffffff
       garrafa          idem
       caneca           idem

   Só isso, e é muito: um card branco sobre fundo branco não se separa. A pele
   da malha resolve com DUAS coisas ao mesmo tempo — o gelo atrás e a sombra
   de três camadas —, e as outras três não tinham nenhuma das duas.

   ─── POR QUE ELA MORA AQUI, E NÃO EM CADA FOLHA ───

   Porque `bone.css`, `garrafa.css` e `caneca/caneca.css` são o MESMO ARQUIVO
   com o prefixo trocado. Conferido byte a byte:

       sed 's/gf-/XX-/' garrafa.css   ==   sed 's/bn-/XX-/' bone.css       ==
       sed 's/cn-/XX-/' caneca.css                                (0 diferenças)

   Escrever a pele nas três seria escrevê-la três vezes, e a terceira ficaria
   para trás no dia em que alguém mexesse na primeira. Aqui é uma vez só, num
   arquivo que as VINTE páginas já carregam — inclusive as de malha, que assim
   passam a beber os tokens da mesma fonte que as outras.

   ─── E POR QUE AS TRÊS FOLHAS NÃO FORAM TOCADAS ───

   Elas continuam sendo o desenho da peça. Isto aqui é a camada de cima, e
   tirar este bloco devolve as três ao que eram — o mesmo contrato dos módulos
   que trabalham por cima do `mockup.js`.
   ────────────────────────────────────────────────────────────────────────── */

/*  ── OS TOKENS, PARA AS QUATRO FAMÍLIAS ──
 *
 *  Eles NASCIAM no `_fonte/rodape.css`, dentro do `mockup.css` — que só a
 *  família de malha carrega. Mudaram de casa para cá em 08/09/2026, e a
 *  explicação longa de cada um (as três camadas da sombra, e por que a cor é
 *  o azul-tinta e não preto) continua lá, junto de quem os usa.
 *
 *  SÃO TRÊS CAMADAS de sombra, e cada uma faz uma coisa: 1 px quase opaca
 *  desenha a quina; 5 px é o contato, que diz que a superfície está pousada;
 *  16 px bem aberta é o levantamento. Uma sombra só, forte o bastante para
 *  separar, sairia dura e sujaria o branco.                                 */
#app, .bn-app, .gf-app, .cn-app {
    --sim-elevacao: 0 1px 2px #0f172a24, 0 5px 12px #0f172a26, 0 16px 32px #0f172a1c;
    --sim-hover: var(--cw-verde-esc, #be2d59);
}

/*  ── O FUNDO GELO ──
 *
 *  `#eef3fa`. O tom foi escolhido pelo CW contra o `#f8fafc` da casa, que ele
 *  achou pouco azulado: entre um e outro a distância de luminância até o card
 *  branco sobe de 7 para 17 pontos, e é essa distância que faz o card subir.
 *
 *  O ESCOPO É `:has()` de propósito, e não um `body{}` solto: esta folha vem
 *  depois do `base.css`, mas depender da ORDEM para ganhar de uma regra de
 *  mesmo peso é o empate que o `cascata.py` existe para pegar. Com o `:has()`
 *  a regra ganha por especificidade. E o escopo protege o resto do site: o
 *  `--cor-fundo` da casa continua branco na loja e no carrinho.             */
body:has(#app),
body:has(.bn-app),
body:has(.gf-app),
body:has(.cn-app) { background: #eef3fa; }

/*  Em tela cheia a raiz vira a página inteira, e é ela que pinta o vão ao
    lado do palco. Mesmo gelo, pelo mesmo motivo.                            */
#app, .bn-app, .gf-app, .cn-app { --fundo: #eef3fa; }

/*  ── OS CARDS E A BARRA DE ABAS SOBEM ──
 *
 *  São a MESMA superfície — fundo branco, borda de 1 px, raio 12 —, então têm
 *  de flutuar à mesma altura. Dois brancos a alturas diferentes sobre o gelo
 *  leem-se como desalinho sem que se saiba por quê.                         */
.bn-bloco, .gf-bloco, .cn-bloco,
.bn-abas,  .gf-abas,  .cn-abas { box-shadow: var(--sim-elevacao); }

/*  ── QUATRO ABAS NUMA LINHA (12/09/2026) ──
 *
 *  Arte · Cor da arte · Peça · Estúdio. Com o respiro de 10 px de cada lado,
 *  que servia para duas abas, "Cor da arte" em negrito passava da largura do
 *  botão e saía cortada (a folha da família proíbe a quebra de linha, e com
 *  razão: um nome em duas linhas desalinha a barra inteira). O respiro lateral
 *  encolhe e a letra desce um tiquinho; a altura do botão fica a mesma.     */
.bn-app .bn-abas button, .gf-app .gf-abas button, .cn-app .cn-abas button {
    padding: 9px 4px;
    font-size: .8rem;
}

/*  ── E COM DESENHO EM CIMA DO NOME, como na camisa (12/09/2026) ──
 *  Ao lado do nome o desenho não cabe em quatro botões de 80 px — "Cor da
 *  arte" sairia cortado. Em cima, o botão cresce para baixo e não para o
 *  lado. As cores do desenho são FIXAS (ver o cabeçalho do `icones.php`): o
 *  contorno azul-tinta segura a leitura também no verde da aba aberta.      */
.bn-app .bn-abas button, .gf-app .gf-abas button, .cn-app .cn-abas button {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    padding: 7px 4px;
    line-height: 1.15;
}
.bn-abas .ic, .gf-abas .ic, .cn-abas .ic { width: 17px; height: 17px; display: block; flex: none; }

/*  ── UMA COR DE HOVER SÓ, E ELA ESCURECE ──
 *
 *  Nas três famílias o hover era `#f1f5f9` (um cinza quase invisível) nos
 *  botões claros e `--cor-marca-escura` no botão principal — dois gestos
 *  diferentes na mesma tela. A malha já tinha resolvido isso: passar o mouse
 *  ESCURECE, venha o botão de onde vier. Um que clareia e outro que escurece
 *  fazem duvidar se os dois são clicáveis do mesmo jeito.
 *
 *  A pílula ACESA entra junto. Ela respondia clareando, com o argumento de
 *  que "um botão aceso clareia" — bom sozinho, ruim no conjunto.            */
/*  ── E CADA SELETOR COMEÇA NA RAIZ, QUE NÃO É CAPRICHO ──
 *
 *  Custou um defeito na tela do CW: "o texto do botão ativo está branco, e a
 *  mesma coisa quando o mouse passa pelos outros". Medido: texto #fff sobre
 *  #fff, contraste 1,0 — o botão sumia.
 *
 *  A causa é ORDEM DE CARGA. As páginas pedem `sim3d.css` ANTES da folha da
 *  família (`$pageCss = ['simulador-3d/sim3d.css', 'simulador-3d/bone.css']`),
 *  e `.bn-bt-palco:hover` tem exatamente o mesmo peso aqui e lá. No empate
 *  ganha a de baixo — a `bone.css`. O `background` dela vencia, o `color:#fff`
 *  daqui não tinha concorrente e passava, e sobrava branco sobre branco.
 *
 *  Com `.bn-app` na frente esta regra ganha por ESPECIFICIDADE, e não por
 *  sorte de ordem — que é a mesma lição do `cascata.py`.                    */
.bn-app .bn-bt:hover, .gf-app .gf-bt:hover, .cn-app .cn-bt:hover,
.bn-app .bn-bt--fantasma:hover, .gf-app .gf-bt--fantasma:hover, .cn-app .cn-bt--fantasma:hover,
.bn-app .bn-bt--principal:hover, .gf-app .gf-bt--principal:hover, .cn-app .cn-bt--principal:hover,
.bn-app .bn-bt-palco:hover, .gf-app .gf-bt-palco:hover, .cn-app .cn-bt-palco:hover,
.bn-app .bn-abas button:hover, .gf-app .gf-abas button:hover, .cn-app .cn-abas button:hover,
.bn-app .bn-abas button.on:hover, .gf-app .gf-abas button.on:hover, .cn-app .cn-abas button.on:hover,
.bn-app .bn-vistas button:hover, .gf-app .gf-vistas button:hover, .cn-app .cn-vistas button:hover,
.bn-app .bn-vistas button.on:hover, .gf-app .gf-vistas button.on:hover, .cn-app .cn-vistas button.on:hover {
    background: var(--sim-hover);
    border-color: var(--sim-hover);
    color: #fff;
}

/*  ── E A MÃOZINHA EM TUDO O QUE RESPONDE ──
 *
 *  A folha das três já põe `cursor:pointer` na maioria; o que faltava era o
 *  `<label>` que embrulha um `<input type=file>` e os seletores de cor. No
 *  Chrome, o que fica sob o ponteiro num campo de arquivo é o conteúdo do
 *  shadow DOM dele — que traz a setinha de volta. `pointer-events:none` no
 *  input devolve o ponteiro ao rótulo, e o seletor continua abrindo: quem
 *  abre é o clique no `<label>`, e não o campo.                             */
.bn-app button, .gf-app button, .cn-app button,
.bn-app label,  .gf-app label,  .cn-app label,
.bn-app summary, .gf-app summary, .cn-app summary,
.bn-app input[type=color], .gf-app input[type=color], .cn-app input[type=color],
.bn-app input[type=checkbox], .gf-app input[type=checkbox], .cn-app input[type=checkbox],
.bn-app select, .gf-app select, .cn-app select { cursor: pointer; }
.bn-app button:disabled, .gf-app button:disabled, .cn-app button:disabled { cursor: default; }
.bn-zona input[type=file], .gf-zona input[type=file], .cn-zona input[type=file] {
    pointer-events: none;
}


/*  ══════════════════════════════════════════════════════════════════════════
    O BALÃO DE DICA (08/09/2026) — no lugar do `title` do navegador.

    O comportamento (posição, virar para baixo, seguir a tela cheia) mora no
    `balao_dica.js`. Aqui fica só o desenho.

    ─── BRANCO, COM UMA MOLDURA DE DEGRADÊ ───

    Nasceu escuro, que é o que todo tooltip faz. O CW pediu branco com texto
    preto e uma moldura em degradê.

    ELA CHEGOU A SER A LUZ QUE GIRA — a mesma `.s3-peca::after` dos cartões do
    hub — e o CW pediu para parar: "em vez da borda animada deixa ela fixa, só
    o degradê mesmo".

    **E parar não é só tirar a animação.** Aquele anel é um `conic-gradient` em
    que só uns 90 graus acendem; congelado, ele vira um arco verde num canto e
    nada no resto da volta — que não é moldura nenhuma. Então o degradê aqui é
    LINEAR e dá a volta inteira: verde claro numa ponta, verde da casa na
    outra, contorno fechado.

    Por dar a volta inteira, ele DISPENSA a borda de 1 px que existia embaixo
    do anel para tapar o trecho apagado. Duas linhas de contorno seriam uma a
    mais.

    ─── O TAMANHO DO TEXTO ACHOU O PONTO EM 13 px ───

    Nasceu em 11,5. O CW pediu 50% maior (17,25), achou grande demais, pediu
    metade (8,63) — e aí ficou menor que o texto do painel. Parou em **13 px**,
    um passo acima dos 11,5 do painel: a dica é uma frase que se lê de relance
    sobre a peça, e ler de relance pede um corpo um pouco maior que o do
    controle que ela explica.

    A LARGURA ACOMPANHA O TEXTO, sempre. Foi 240 px em 11,5, 360 em 17,25, 180
    em 8,63 e agora 270 em 13. Ela não é gosto — é o que mantém a dica mais
    longa das telas (101 caracteres) dentro das três linhas. Mexer no tamanho
    sem mexer na largura faz o `line-clamp` deixar de ser teto e passar a
    cortar texto todo dia.

    ─── A PONTA É UM QUADRADO GIRADO ───

    E não um `border` triangular: girado, ele herda o MESMO fundo do balão, e
    duas bordas dele viram as duas beiras da ponta. Com triângulo de borda
    seriam duas cores para manter iguais a cada mudança.

    Quem a move é o JS — ela aponta para o BOTÃO, e os dois deixam de estar
    alinhados assim que o balão é empurrado para dentro da janela.
    ══════════════════════════════════════════════════════════════════════════ */
.mk-dica{
  position:absolute;
  /*  ─── A DICA FICA ACIMA DE TUDO ─── (16/09/2026)

      Eram 9985, e o balão de configuração do player (`.pl-balao`) abre em
      2.147.482.000 — a dica do X saía POR TRÁS dele, que é o mesmo que não
      sair. Uma dica descreve o que está por baixo dela; ficar atrás de alguma
      coisa é o único lugar onde ela não serve.

      O número passa do balão e do menu dos `<select>` (2.147.483.000). Ela é
      `pointer-events:none` e some sozinha, então estar no topo não atrapalha
      nada.                                                                  */
  z-index:2147483600;
  max-width:270px; padding:9px 12px;
  border-radius:12px;
  background:var(--cartao, #fff); color:var(--texto, #1c2030);
  font-size:13px; line-height:1.42; letter-spacing:.1px;
  box-shadow:var(--sim-elevacao, 0 1px 2px #0f172a24, 0 5px 12px #0f172a26, 0 16px 32px #0f172a1c);
  pointer-events:none;               /* ela nunca rouba o ponteiro do botão */
  opacity:0; transform:translateY(3px);
  transition:opacity .12s ease, transform .12s ease;
}
.mk-dica.is-vendo{ opacity:1; transform:none }
.mk-dica[hidden]{ display:none !important }

/*  A MOLDURA DE DEGRADÊ. `::before` e não `::after`, porque a ponta é um filho
    de verdade e o `::after` fica livre para quem vier depois.

    A MÁSCARA É O TRUQUE: duas camadas iguais, uma presa ao `content-box` e
    outra à caixa inteira, subtraídas — sobra só a moldura de 2 px. É o que
    permite um contorno em DEGRADÊ, coisa que `border` não faz.              */
.mk-dica::before{
  content:""; position:absolute; inset:0; z-index:1;
  border-radius:12px; padding:2px;
  background:linear-gradient(135deg,
      #ffc4d6 0%,
      #ff9dbb 32%,
      var(--cw-verde, #e2507d) 68%,
      #f0759b 100%);
  -webkit-mask:
      linear-gradient(#000 0 0) content-box,
      linear-gradient(#000 0 0);
          mask:
      linear-gradient(#000 0 0) content-box,
      linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
          mask-composite:exclude;
  pointer-events:none;
}
/*  O TEXTO POR CIMA DO ANEL. Ele é `position:absolute` sobre o balão, e sem
    isto a última linha passaria por baixo da luz na beira de baixo.        */
.mk-dica__txt{
  position:relative; z-index:2;
  display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:3;
  overflow:hidden;
}

.mk-dica__ponta{
  position:absolute; width:11px; height:11px; z-index:0;
  margin-left:-5.5px;
  background:inherit; border-radius:2px;
  transform:rotate(45deg);
}
/*  Em cima do botão, a ponta sai por BAIXO do balão; virado, por cima. As duas
    bordas que ficam para fora são as que se veem.                          */
/*  As duas beiras da ponta acompanham o VERDE do degradê, e não o cinza de
    antes: com a moldura verde em volta, um cinza ali seria a única parte do
    contorno de outra cor.                                                   */
.mk-dica__ponta{
  bottom:-6px;
  border-right:2px solid var(--cw-verde, #e2507d);
  border-bottom:2px solid var(--cw-verde, #e2507d);
}
.mk-dica.abaixo .mk-dica__ponta{
  bottom:auto; top:-6px;
  border-right:0; border-bottom:0;
  border-left:2px solid #ff9dbb; border-top:2px solid #ff9dbb;
}

/*  Quem pediu menos movimento ganha o balão sem o deslize. A moldura FICA:
    ela não se move mais, então não há o que reduzir.                        */
@media (prefers-reduced-motion: reduce){
  .mk-dica{ transition:opacity .01s; transform:none }
  .mk-dica.is-vendo{ transform:none }
}


/* ══════════════════════════════════════════════════════════════════════════
   AS SETINHAS DE SUBIR E DESCER O CARD (08/09/2026)

   O comportamento mora em `mover_cards.js`; aqui fica só o desenho. Elas
   nascem ao lado dos pontinhos do arrasto, e as duas coisas juntas dizem o
   mesmo: este cabeçalho move o card.

   ─── ELAS SÓ APARECEM DE VERDADE NO PONTEIRO ───

   Em repouso ficam apagadas a 45%. São duas por card, e um painel com oito
   cards teria dezesseis setinhas competindo com os controles — que é o que a
   pessoa veio usar. Passando o mouse no cabeçalho, elas acendem.

   E ACENDEM TAMBÉM NO FOCO DO TECLADO, sempre: quem navega por Tab não tem
   ponteiro para revelar nada, e uma setinha invisível com foco é um botão que
   não existe.

   ─── DESLIGADA, E NÃO ESCONDIDA, NAS PONTAS ───

   O primeiro card não sobe e o último não desce. Sumir com o botão faria o
   vizinho pular de lugar, e o segundo clique cairia onde estava o primeiro.
   ────────────────────────────────────────────────────────────────────────── */
.mk-mover-cx {
    display: inline-flex;
    gap: 2px;
    margin: 0 6px 0 -2px;
    vertical-align: middle;
}
.mk-mover {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /*  ── O TAMANHO, pedido pelo CW em 08/09/2026 ──
        Nasceram com 17 px e o desenho com 10. Ficaram discretas demais para
        serem achadas: a alça de arrastar ao lado tem a mesma altura do texto
        do título, e uma setinha menor que ela lê-se como enfeite.

        24 px é também o alvo de toque mínimo confortável numa barra lateral —
        abaixo disso, num telefone, erra-se o botão e recolhe-se o card.    */
    width: 24px;
    height: 24px;
    padding: 0;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--cor-texto-suave, #64748b);
    cursor: pointer;
    opacity: .45;
    transition: opacity .13s, background-color .13s, color .13s;
}
.mk-mover svg { width: 14px; height: 14px; fill: currentColor; }

/*  O cabeçalho inteiro acende as duas.                                      */
h3:hover > .mk-mover-cx .mk-mover,
.bn-bloco__tit:hover .mk-mover,
.gf-bloco__tit:hover .mk-mover,
.cn-bloco__tit:hover .mk-mover { opacity: .9; }

.mk-mover:hover:not(:disabled) {
    opacity: 1;
    background: var(--sim-hover, #be2d59);
    color: #fff;
}
/*  O foco do teclado acende sozinho, sem depender do ponteiro.              */
.mk-mover:focus-visible {
    opacity: 1;
    outline: 2px solid var(--cor-marca, #e2507d);
    outline-offset: 1px;
}
.mk-mover:disabled { opacity: .16; cursor: default; }

@media (prefers-reduced-motion: reduce) {
    .mk-mover { transition: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   TRAZIDO DO PROJETO DE ORIGEM EM 10/09/2026 — o filtro do hub e a janela do
   lote. Copiado sem alteracao: os dois arquivos de JavaScript que usam
   estas regras (`hub_filtro.js` e `lote_montagem.js`) vieram de la inteiros,
   e uma regra mexida aqui seria a primeira coisa a desencontrar na proxima
   vez que um deles voltar de la.
   ══════════════════════════════════════════════════════════════════════════ */
/* ══════════════════════════════════════════════════════════════════════════
   O FILTRO DA LISTA — 03/09/2026, quando as peças passaram de sete a dezenove

   Os botões ficam ACIMA da lista e não numa coluna ao lado: numa coluna eles
   roubariam largura dos cartões, que já quebram de três para duas em tela de
   1000px. Em cima eles custam 44px de altura uma vez.
   ══════════════════════════════════════════════════════════════════════════ */
.s3-filtro {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    max-width: var(--s3-larg);
    margin: 0 auto 16px;
}
.s3-filtro__bt {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 9px 14px;
    border-radius: 999px;
    border: 1px solid var(--cor-borda, #e2e8f0);
    background: #fff;
    color: var(--cor-texto, #0f172a);
    font: inherit;
    font-size: .92rem;
    font-weight: 600;
    cursor: pointer;
    transition: border-color .15s, background .15s, color .15s;
}
.s3-filtro__bt:hover { border-color: var(--cor-marca, #e2507d); }
/*  A MARCA DE ESCOLHIDO SAI DO `aria-pressed`, e não de uma classe: é o mesmo
    atributo que o leitor de tela anuncia, então não há como a pintura e o
    anúncio discordarem. Ver `hub_filtro.js`.                                */
.s3-filtro__bt[aria-pressed="true"] {
    background: var(--cor-marca, #e2507d);
    border-color: var(--cor-marca, #e2507d);
    color: #fff;
}
/*  O NÚMERO é texto de verdade dentro do `<span>`, escrito pelo PHP. A pastilha
    atrás dele é um fundo translúcido — `currentColor` com pouca opacidade —,
    e é isso que a faz acompanhar o botão nos dois estados sem uma segunda
    regra: cinza-escuro sobre branco, branco sobre o verde.                  */
.s3-filtro__n {
    padding: 1px 7px;
    border-radius: 999px;
    background: color-mix(in srgb, currentColor 14%, transparent);
    font-size: .8rem;
    font-weight: 700;
}
/*  Reserva para quem não tem `color-mix` (Safari < 16.4): uma pastilha cinza
    fixa, que continua legível nos dois estados por ser translúcida.         */
@supports not (background: color-mix(in srgb, red 10%, transparent)) {
    .s3-filtro__n { background: #7f7f7f38; }
}
/*  Sem JavaScript a barra nem aparece — o `hidden` sai no `hub_filtro.js`.
    Esta regra é o cinto: `[hidden]` perde para `display:flex` na cascata, e
    sem ela a barra apareceria mesmo escondida.                              */
.s3-filtro[hidden] { display: none; }

/*  ── E O MESMO CINTO NOS CARTÕES, que é onde ele fazia falta ──
    O `.s3-peca` é `display:flex`, e `display` de autor ganha do `display:none`
    que o navegador dá ao `[hidden]`. Sem esta linha o filtro marcava o botão,
    escondia no papel — `c.hidden = true` — e a lista não mexia um cartão: o
    defeito só apareceu na foto da tela, porque no console o atributo estava lá
    certinho. É a mesma pedra do `[hidden]` das abas, no `mockup.css`.       */
.s3-peca[hidden] { display: none !important; }

/*  O aviso é só para o leitor de tela: quem enxerga já viu a lista mudar.   */
.s3-filtro__aviso {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0; border: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* ══════════════════════════════════════════════════════════════════════════
   A JANELA DO LOTE — montar várias artes de uma vez

   Montada pelo `lote_montagem.js`, e igual nas quatro telas: por isso mora
   aqui, e não no `mockup.css` nem no `caneca.css`.

   NÃO É `<dialog>`: o `showModal()` nativo põe o elemento na camada de topo do
   navegador, ACIMA de tudo, e o palco da camisa tem controles em `position:
   fixed` que precisam continuar clicáveis quando a janela está fechada. Um
   `div` com `position: fixed` e um `z-index` alto resolve o mesmo com regras
   que já se entendem com o resto da página.
   ══════════════════════════════════════════════════════════════════════════ */
.s3-lote {
    position: fixed;
    inset: 0;
    /*  ACIMA DO CABEÇALHO VERDE DO SITE, que é `position: fixed` com
        `z-index: 999` (`.cw-header__topo`, no `assets/css/layout.css`).
        A janela nasceu em 90 — o bastante para os controles do palco, que vão
        até 80, e não para o cabeçalho: ele passava por cima e comia o título e
        o botão de fechar.

        1200 fica acima dele e das duas camadas nomeadas da casa (`--z-modal`
        1000, `--z-toast` 1100), e abaixo do carrinho (9998), que é o único que
        deve cobrir qualquer coisa.                                          */
    z-index: 1200;
    background: #0f172a66;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    /*  A cortina rola junto quando a janela não cabe na tela do celular: sem
        isto o pé com o botão Montar ficaria fora do alcance.                */
    overflow: auto;
}
.s3-lote__cx {
    /*  LARGA (900 px).  Eram 560, e a lista é o que sofria: com cartões de
        96 px, cabiam CINCO por fileira — sessenta e três artes viravam treze
        fileiras de rolagem, e conferir a escolha era rolar a janela inteira.
        A 900 cabem nove, e a mesma lista ocupa sete fileiras.

        O `min()` continua mandando: em telas estreitas ela vira 100% e nada
        estoura.  Os campos de baixo, que são de duas colunas, só ficam mais
        folgados.                                                            */
    width: min(900px, 100%);
    max-height: 92vh;
    display: flex;
    flex-direction: column;
    background: #fff;
    color: #1c2030;
    border-radius: 14px;
    box-shadow: 0 24px 60px #0f172a4d;
    font: 13.5px/1.45 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    overflow: hidden;
}
.s3-lote__topo {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 13px 15px;
    border-bottom: 1px solid #e2e8f0;
}
.s3-lote__topo b { font-size: 15px; }
.s3-lote__x {
    margin-left: auto;
    border: 0;
    background: transparent;
    font-size: 17px;
    line-height: 1;
    padding: 4px 6px;
    border-radius: 7px;
    cursor: pointer;
    color: #697084;
}
.s3-lote__x:hover { background: #eef2f7; color: #1c2030; }

.s3-lote__corpo {
    padding: 15px;
    display: flex;
    flex-direction: column;
    gap: 13px;
    overflow: auto;
}
/*  Enquanto o lote corre, os campos param de aceitar mão: trocar as vistas no
    meio do trabalho mudaria o que já foi contado na barrinha.               */
.s3-lote__corpo--travado { pointer-events: none; opacity: .55; }

.s3-lote__zona {
    display: block;
    text-align: center;
    padding: 18px 14px;
    border: 2px dashed #cbd5e1;
    border-radius: 11px;
    cursor: pointer;
    background: #f8fafc;
    transition: border-color .15s, background .15s;
}
.s3-lote__zona:hover { border-color: var(--cor-marca, #e2507d); background: #f1f5f9; }
.s3-lote__zona b { display: block; margin-bottom: 3px; }
.s3-lote__zona span { color: #697084; font-size: 12px; }

/*  ══════════════════════════════════════════════════════════════════════
    O CABEÇALHO DA LISTA — a conta e o botão de limpar.

    Discreto de propósito.  Ele divide a janela com o "Montar", que é a ação
    que a pessoa veio fazer; um segundo botão cheio ao lado disputaria o olho
    com ele, e o que apaga trabalho não pode ser o mais fácil de acertar sem
    querer.  Fica com cara de link, e só o vermelho ao passar o ponteiro diz
    do que se trata.
    ══════════════════════════════════════════════════════════════════════ */
.s3-lote__cab {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    /*  Cola no que vem depois: o cabeçalho é da lista, não um bloco solto no
        meio da coluna — e o `gap: 13px` do corpo o afastaria dela tanto
        quanto do campo de cima.                                            */
    margin-bottom: -6px;
}
.s3-lote__cab[hidden] { display: none; }

.s3-lote__conta { font-size: 12.5px; color: #697084; }

/*  VERMELHO DE VERDADE, E DO TAMANHO DE UM BOTÃO.

    Ele nasceu discreto — cinza, com cara de link, só ficando vermelho ao
    passar o ponteiro.  Na tela ficou tímido demais para o que faz: some com
    uma lista de sessenta e três artes.  Vermelho desde o primeiro olhar diz o
    que ele é ANTES do clique, que é quando a informação serve.

    O preenchimento fica CLARO e o traço forte: um bloco vermelho sólido do
    tamanho do "Montar" disputaria o olho com ele, e o que apaga trabalho não
    pode parecer a ação principal da janela.  O sólido fica para o `:hover`,
    quando o ponteiro já está em cima e a intenção já é outra.

    E o desfazer é a mesma peça em verde — nenhum tamanho muda entre os dois,
    para o botão não pular de lugar no instante em que troca de papel.       */
.s3-lote__limpa {
    padding: 9px 16px;
    border: 1.5px solid #fecaca;
    border-radius: 9px;
    background: #fef2f2;
    font: inherit;
    font-size: 14px;
    font-weight: 700;
    line-height: 1.15;
    color: #b91c1c;
    cursor: pointer;
    transition: color .14s, background .14s, border-color .14s;
}
.s3-lote__limpa:hover {
    color: #fff;
    background: #b91c1c;
    border-color: #b91c1c;
}
.s3-lote__limpa:focus-visible {
    outline: 2px solid #b91c1c;
    outline-offset: 2px;
}
/*  Desfazer não é destruir: sai do vermelho e ganha a cor da casa, que é a
    mesma diferença que o "Montar" faz do "Parar" no pé da janela.          */
.s3-lote__limpa--desfaz {
    color: var(--cor-marca, #e2507d);
    background: #fff0f4;
    border-color: #f6cbd8;
}
.s3-lote__limpa--desfaz:hover {
    color: #fff;
    background: var(--cor-marca, #e2507d);
    border-color: var(--cor-marca, #e2507d);
}
.s3-lote__limpa--desfaz:focus-visible { outline-color: var(--cor-marca, #e2507d); }

.s3-lote__lista { display: flex; flex-wrap: wrap; gap: 8px; }
.s3-lote__lista:empty { display: none; }
/*  Um cartãozinho por arte: a imagem em cima, o nome embaixo e o ✕ no canto.

    LARGURA FIXA, e não conteúdo: os nomes de um pacote têm comprimentos
    diferentes, e cartões de larguras diferentes fazem a fileira parecer uma
    lista quebrada em vez de uma grade.                                      */
.s3-lote__arq {
    position: relative;
    width: 96px;
    border: 1px solid #e2e8f0;
    border-radius: 9px;
    overflow: hidden;
    background: #fff;
}
.s3-lote__arq img {
    display: block;
    width: 100%;
    height: 64px;
    /*  `contain` e não `cover`: a arte de uma camisa é alta, a de uma caneca é
        larga, e cortar para preencher esconderia justamente a parte pela qual
        se reconhece a estampa. O xadrez por baixo mostra onde ela é
        transparente.                                                        */
    object-fit: contain;
    background: #f8fafc;
}
.s3-lote__arq span {
    display: block;
    padding: 4px 6px;
    font-size: 10.5px;
    line-height: 1.25;
    color: #46506a;
    /*  Duas linhas no máximo, e o resto some com reticências: um nome de
        quarenta letras esticaria o cartão e desmancharia a grade.           */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    word-break: break-word;
}
.s3-lote__arqx {
    position: absolute;
    top: 3px;
    right: 3px;
    width: 19px;
    height: 19px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: #0f172abf;
    color: #fff;
    font-size: 11px;
    line-height: 19px;
    cursor: pointer;
}
.s3-lote__arqx:hover { background: #b91c1c; }

.s3-lote__grade { display: flex; flex-wrap: wrap; gap: 13px; }
.s3-lote__campo { display: flex; flex-direction: column; gap: 5px; flex: 1 1 180px; }
.s3-lote__campo > label { font-size: 12px; font-weight: 600; color: #46506a; }
/*  ─── A CAIXA VALE PARA OS DOIS: O `<select>` E O BOTÃO QUE O SUBSTITUI ───
    (20/09/2026)

    O `seletor_bonito.js` troca cada `<select>` por um `<button class="cw-sel">`
    e esconde o nativo. Ele COPIA as classes do `<select>` para o botão — e
    estes dois não têm nenhuma: são pintados por TAG (`.s3-lote__campo select`),
    e um `<button>` não casa com isso.

    O resultado era o da tela do CW: "Com cenário" e "2400 px" soltos no branco
    da janela, sem borda nem fundo, sem parecer que se podia clicar. É a mesma
    pedra das dezoito listas do painel, resolvida lá dentro do próprio
    `seletor_bonito.js`; aqui a casa é esta, porque a caixa é desta janela.

    `box-sizing` explícito porque o botão não é filho do `#app` em todas as
    telas — na caneca a janela nasce no `<body>`, e o `border-box` que o mockup
    dá de presente lá dentro não chega até ela.                              */
.s3-lote__campo select,
.s3-lote__campo .cw-sel {
    width: 100%;
    box-sizing: border-box;
    padding: 7px 9px;
    border: 1px solid #cbd5e1;
    border-radius: 8px;
    background: #fff;
    font: inherit;
    color: inherit;
}
.s3-lote__campo .cw-sel:hover,
.s3-lote__campo .cw-sel[aria-expanded="true"] { border-color: var(--cor-marca, #e2507d); }

.s3-lote__vistas { display: flex; flex-wrap: wrap; gap: 6px; }
/*  Cada vista é uma pastilha que se aperta, e não uma caixinha com rótulo ao
    lado: são quatro a seis delas numa janela estreita, e a fileira de pastilhas
    é a mesma linguagem das pílulas de vista no palco.                       */
.s3-lote__vista {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 10px;
    border: 1px solid #cbd5e1;
    border-radius: 999px;
    cursor: pointer;
    font-size: 12.5px;
    user-select: none;
}
.s3-lote__vista:hover { border-color: var(--cor-marca, #e2507d); }
.s3-lote__vista:has(input:checked) {
    border-color: var(--cor-marca, #e2507d);
    background: #fff0f4;
    color: #932546;
}
.s3-lote__vista input { margin: 0; accent-color: var(--cor-marca, #e2507d); }

.s3-lote__nota { margin: 0; font-size: 12px; color: #697084; }

/*  ══════════════════════════════════════════════════════════════════════
    "ONDE SALVAR" — o botão, o nome da pasta e o ✕ de voltar atrás.

    Uma linha só, com o nome no meio encolhendo: nome de pasta pode ser um
    caminho inteiro, e sem o `min-width: 0` o flex se recusa a encolher um
    filho abaixo do conteúdo dele — a linha estouraria a largura da janela.
    ══════════════════════════════════════════════════════════════════════ */
.s3-lote__pasta { display: flex; align-items: center; gap: 9px; }
.s3-lote__pastanome {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 12.5px;
    color: #697084;
}
/*  Escolhida, ela deixa de ser um aviso e passa a ser um dado: ganha o peso e
    a cor de quem responde "onde", em vez do cinza de quem explica.          */
.s3-lote__pastanome--tem { color: #0f172a; font-weight: 600; }

.s3-lote__pastax {
    flex: 0 0 auto;
    width: 26px;
    height: 26px;
    border: 0;
    border-radius: 7px;
    background: none;
    color: #697084;
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
}
.s3-lote__pastax:hover { background: #fef2f2; color: #b91c1c; }
.s3-lote__pastax[hidden] { display: none; }

.s3-lote__pe {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 12px 15px;
    border-top: 1px solid #e2e8f0;
    background: #f8fafc;
}
/*  A BARRINHA OCUPA A LINHA INTEIRA, acima dos botões: no meio deles ela teria
    uns cem pixels e não daria para ver o andamento de oitenta arquivos.     */
.s3-lote__barra {
    flex: 0 0 100%;
    height: 6px;
    border-radius: 999px;
    background: #e2e8f0;
    overflow: hidden;
}
.s3-lote__barra i {
    display: block;
    height: 100%;
    width: 0;
    background: var(--cor-marca, #e2507d);
    transition: width .2s;
}
.s3-lote__msg { flex: 1 1 auto; font-size: 12px; color: #46506a; min-width: 0; }
.s3-lote__bt {
    padding: 8px 14px;
    border: 1px solid #cbd5e1;
    border-radius: 9px;
    background: #fff;
    font: inherit;
    cursor: pointer;
}
.s3-lote__bt:hover { border-color: #94a3b8; }
.s3-lote__bt--acao {
    background: var(--cor-marca, #e2507d);
    border-color: var(--cor-marca, #e2507d);
    color: #fff;
    font-weight: 600;
}
.s3-lote__bt--acao:hover { filter: brightness(1.08); }
.s3-lote__bt[disabled] { opacity: .5; cursor: default; }

@media (prefers-reduced-motion: reduce) {
    .s3-lote__barra i { transition: none; }
}
/*  Retocado em 02/09/2026 só para o SFTP reenviar — a fila tinha travado.  */

/* ══════════════════════════════════════════════════════════════════════════
   A ALÇA DA LARGURA DO PALCO — a mesma de cima, em pé.

   Ela só é montada onde não existe a `#alcaLarg` do `mockup.js`: hoje, a
   caneca. Ver o porquê no `alca_palco.js` — lá a alça da largura move a
   MOLDURA do arquivo dentro do palco, aqui não há moldura e o que se move é o
   palco.

   O DESENHO É O MESMO, virado: mesmo punho de pastilha branca, mesmos dois
   risquinhos roxos, mesma engordada no `:hover`, mesma área de pegar maior que
   o traço. São a mesma ferramenta em dois sentidos, e o que as diferencia tem
   de ser só a direção — duas ferramentas parecidas com desenhos diferentes
   fazem a pessoa achar que fazem coisas diferentes.
   ══════════════════════════════════════════════════════════════════════════ */
.s3-alca-larg {
    position: absolute;
    /*  `left`, `top` e `height` VÊM DO JS: a alça é irmã do palco, não filha —
        o palco tem `overflow:hidden` e cortaria o punho ao meio —, então
        alguém precisa dizer onde a beira dele está. Ver `poeAlcaL`.         */
    width: 18px;
    z-index: 6;
    cursor: ew-resize;
    /*  Sem isto o navegador do celular entende o arrasto como rolagem da
        página e a alça não se mexe.                                         */
    touch-action: none;
    background: transparent;
}
/*  A ÁREA DE PEGAR É MAIOR QUE O TRAÇO que se vê: acertar três pixels com o
    mouse é o tipo de exigência que faz achar que a alça não funciona.       */
.s3-alca-larg::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: -6px;
    right: -6px;
}
/*  O PUNHO FICA À VISTA, SEMPRE — a lição está escrita na alça irmã: alça que
    só aparece no `:hover` é alça que ninguém descobre.

    CENTRADO NA FAIXA, que por sua vez é centrada na beira direita do palco: ele
    fica metade para dentro e metade para fora, sobre a divisa.              */
.s3-alca-larg i {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 12px;
    height: 34px;
    border-radius: 4px;
    background: #ffffffee;
    box-shadow: 0 2px 10px #0000002e;
    transition: transform .15s, box-shadow .15s;
}
.s3-alca-larg:hover i,
.s3-alca-larg.puxando i {
    transform: translate(-50%, -50%) scale(1.12);
    box-shadow: 0 3px 14px #00000040;
}
/*  Os dois risquinhos, agora em pé. A cor é cravada, e é o mesmo `#4c3fd6` das
    outras duas alças da casa — ver a nota na `.s3-alca-alt i::before`.      */
.s3-alca-larg i::before,
.s3-alca-larg i::after {
    content: "";
    position: absolute;
    top: 9px;
    bottom: 9px;
    width: 2px;
    border-radius: 1px;
    background: #4c3fd6;
}
.s3-alca-larg i::before { left: 3px; }
.s3-alca-larg i::after  { right: 3px; }

body.s3-puxando-larg { user-select: none; cursor: ew-resize; }

/* ══════════════════════════════════════════════════════════════════════════
   A POSIÇÃO DAS PEÇAS DENTRO DO CARD — 10/09/2026.

   O `<details>` da posição saiu da barra do palco e virou card na lateral
   (ver o porquê no HTML de cada tela). O desenho dele foi feito para FLUTUAR
   sobre a cena — caixa branca de 216 px, com borda e sombra, para se destacar
   do verde por trás. Dentro de um card branco isso vira uma caixa dentro de
   outra, com duas bordas e uma sombra que não separa nada.

   Então aqui ela larga o disfarce: toma a largura do card e fica sem moldura.
   O que continua é o `<details>` — o resumo é a chave que abre, e as quatro
   barrinhas não ficam abertas ocupando meio painel.

   AS TRÊS FAMÍLIAS NUMA REGRA SÓ, e não uma cópia em cada folha: são a mesma
   ferramenta com três prefixos, e três cópias desencontrariam na primeira vez
   que alguém ajustasse uma delas.
   ══════════════════════════════════════════════════════════════════════════ */
.cn-bloco .cn-pos__cx,
.gf-bloco .gf-pos__cx,
.bn-bloco .bn-pos__cx {
    width: auto;
    padding: 0;
    border: 0;
    box-shadow: none;
    background: transparent;
}
/*  E A GAVETA SAIU JUNTO. Ela era um `<details>` com um resumo escrito
    "Posição das canecas" — dentro de um card que JÁ SE CHAMA "Posição das
    canecas", isso é o mesmo rótulo duas vezes, uma em cima da outra. Os
    outros cards do painel não têm gaveta nenhuma: a lateral rola, e quem não
    quer ver o card passa por ele. Este passou a ser como os outros.        */

/*  ── E O BOTÃO DO LOTE TOMA A LINHA INTEIRA ──
    Ele nasce encostado no próprio texto — é um `<button>`, e botão encolhe
    até o conteúdo. Ao lado do "Ver artes de caneca prontas", que é largura
    cheia, um botão estreito no card de cima lê como um detalhe do texto e não
    como a ação do card. Nas camisas ele já é assim: no card do molde, os três
    tomam a linha toda.                                                     */
#cnLoteCasa > button,
#gfLoteCasa > button,
#bnLoteCasa > button {
    width: 100%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    /*  A BORDA É A MESMA DA CAMISA (ver `.sim-molde-bt--lote` no `mockup.css`),
        e pelo mesmo motivo: com o cinza claro do card ele sumia entre o branco
        do card e o branco da página, e lia como texto e não como botão. É o
        mesmo botão nas duas telas — não podia ter duas aparências.         */
    border-color: #94a3b8;
}
/*  ── E O MOUSE EM CIMA É O DA CASA: VERDE, LETRA BRANCA ── (12/09/2026)
    Aqui estava `background:#f1f5f9`, o cinza quase branco. Com o peso de um id,
    ele ganhava do hover da casa (`.cn-app .cn-bt:hover`, lá em cima) só no
    FUNDO — o `color:#fff` de lá continuava valendo, porque esta regra não falava
    de texto. Resultado, medido no Chrome: letra branca sobre #f1f5f9, contraste
    1,1:1 — o "Montar em lote" sumia debaixo do mouse (o CW viu na caneca).
    Agora as duas dizem a mesma coisa, com reserva no `var()` para o dia em que
    a variável faltar.                                                        */
#cnLoteCasa > button:hover,
#gfLoteCasa > button:hover,
#bnLoteCasa > button:hover {
    border-color: var(--sim-hover, #be2d59);
    background: var(--sim-hover, #be2d59);
    color: #fff;
}

/* ══════════════════════════════════════════════════════════════════════════
   A BORDA DOS BOTÕES CLAROS — UMA SÓ, EM TODOS OS SIMULADORES (10/09/2026)

   MEDIDO, botão a botão, nas telas de camisa e de caneca: a distância de
   luminância entre a borda e o fundo do botão era de 12 a 45 na maioria deles
   — `#dbe3ec` e `var(--linha)` sobre branco. Nessa faixa a borda existe no
   código e não existe no olho: a fileira lia como palavras soltas.

   O alvo é o mesmo do `.mk-parte` e do "Montar em lote", que já tinham sido
   escurecidos a pedido: `#94a3b8`, que dá ~90 de distância sobre branco. Uma
   borda só para "isto é apertável" em toda a casa.

   ─── A ESPECIFICIDADE MUDA DE FAMÍLIA PARA FAMÍLIA, E NÃO POR CAPRICHO ───

   Nas telas de MALHA o `mockup.css` escreve com `#app#app`, e esta folha
   precisa alcançar isso. Nas de COPO a ordem é o contrário — o `sim3d.css`
   carrega ANTES do `caneca.css`/`garrafa.css`/`bone.css` —, então uma classe
   solta perderia para a de lá mesmo escrita depois; por isso o `.cn-app` na
   frente. Conferido nas duas telas antes de escrever.

   O QUE FICA DE FORA: o botão escolhido (`.on`, `.ativo`), o cheio de cor
   (`--principal`) e o sem moldura (`--fantasma`). A borda deles é a cor deles,
   e é assim que se sabe qual está apertado.
   ══════════════════════════════════════════════════════════════════════════ */
/*  A SEGUNDA VARREDURA. A primeira pegou o painel e deixou de fora três
    grupos, que a medição mostrou um a um: os botões flutuantes da barra do
    palco ("Imagem sem fundo", "Vídeo", "Todas as vistas"), as ferramentas de
    `.bt.fino` que ficam FORA do `.mk-corpo` (a fileira de espelhar e alinhar),
    as amostras de tecido, e os números das peças na posição do copo.      */
#app#app .sim-girar > button:not(.on),
#app#app .sim-salvar > button:not(.on),
#app#app .mk-tec button:not(.on),
#app#app .bt.fino:not(.on),
.cn-app .cn-pos__pecas button:not(.ativo),
.gf-app .gf-pos__pecas button:not(.ativo),
.bn-app .bn-pos__pecas button:not(.ativo),
#app#app .mk-corpo .bt.fino:not(.on),
#app#app .sim-amostra,
#app#app .sim-vazio,
#app#app .mk-fundo,
.cn-app .mk-fundo, .gf-app .mk-fundo, .bn-app .mk-fundo,
.s3-olho.s3-olho,
.sim-pref-bt--limpa.sim-pref-bt--limpa,
.cn-app .cn-bt-palco, .gf-app .gf-bt-palco, .bn-app .bn-bt-palco,
.cn-app .cn-sel-palco, .gf-app .gf-sel-palco, .bn-app .bn-sel-palco,
.cn-app .cn-bt:not(.ativo):not(.cn-bt--principal):not(.cn-bt--fantasma),
.gf-app .gf-bt:not(.ativo):not(.gf-bt--principal):not(.gf-bt--fantasma),
.bn-app .bn-bt:not(.ativo):not(.bn-bt--principal):not(.bn-bt--fantasma) {
    border-color: #94a3b8;
}

/* ══════════════════════════════════════════════════════════════════════════
   AMBIENTE DO ESTÚDIO NA CANECA, NA GARRAFA E NO BONÉ (12/09/2026).

   O card da camisa, levado para as três famílias de peça única. Os campos
   usam o `.xx-campo` de cada uma; aqui fica só o que é novo: a linha com
   dois controles lado a lado (cor + tipo, caixa + cor), o seletor, a fileira
   de botões da imagem e as bolinhas do `fundo_rapido.js` — que na camisa
   moram no `mockup.css`, atrás do `#app#app`, e aqui não chegariam.

   O `[hidden]` da linha da segunda cor precisa de `!important`: o
   `.xx-campo--cor` é `display:flex`, e o atributo age pela folha do
   navegador, a mais fraca de todas.
   ══════════════════════════════════════════════════════════════════════════ */
/*  RÓTULO À ESQUERDA, CONTROLES AO LADO — como a `.lin` da camisa. O
    `.xx-campo` das famílias é `display:block` e vem depois do `--cor` na
    folha delas, então sozinho ele empilharia o rótulo em cima do controle;
    o `.xx-app` na frente é o que vence (ver a regra no topo deste bloco). */
.cn-app .s3-amb-lin, .gf-app .s3-amb-lin, .bn-app .s3-amb-lin {
    display: flex;
    align-items: center;
    gap: 10px;
}
.s3-amb-lin > span:first-child { flex: 0 0 88px; margin: 0; }
.s3-amb-lin[hidden] { display: none !important; }
.s3-amb-lin > .s3-amb-par {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 8px;
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
}
.s3-amb-sel {
    flex: 1 1 auto;
    min-width: 0;
    max-width: 100%;
    font: inherit;
    font-size: .82rem;
    color: #1f2937;
    padding: 5px 8px;
    border: 1px solid #94a3b8;
    border-radius: 8px;
    background: #fff;
    cursor: pointer;
}
.s3-amb-lin > .s3-amb-sel { flex: 1 1 auto; }
.s3-amb-lin input[type="checkbox"] {
    flex: 0 0 auto;
    width: 16px; height: 16px; margin: 0;
    accent-color: var(--cor-marca, #e2507d);
    cursor: pointer;
}
.s3-amb-lin label { cursor: pointer; }
.s3-amb-bts {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0 0 12px;
}
/*  21 px e 4 de vão: as doze cabem numa fileira só na coluna de 340 px, como
    na camisa. Com os 24 + 6 de lá elas quebravam em duas linhas.            */
.cn-app .mk-fundos, .gf-app .mk-fundos, .bn-app .mk-fundos {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin: 0 0 14px;
}
.cn-app .mk-fundo, .gf-app .mk-fundo, .bn-app .mk-fundo {
    width: 21px; height: 21px; padding: 0;
    border-radius: 50%;
    border: 1px solid #94a3b8;
    cursor: pointer;
    transition: transform .12s, outline-color .12s;
    outline: 2px solid transparent;
    outline-offset: 2px;
}
.cn-app .mk-fundo:hover, .gf-app .mk-fundo:hover, .bn-app .mk-fundo:hover { transform: scale(1.15); }
.cn-app .mk-fundo.on, .gf-app .mk-fundo.on, .bn-app .mk-fundo.on,
.cn-app .mk-fundo:focus-visible, .gf-app .mk-fundo:focus-visible, .bn-app .mk-fundo:focus-visible {
    outline-color: var(--cor-marca, #e2507d);
}

/* ══════════════════════════════════════════════════════════════════════════
   A BOTOEIRA DA ARTE NA CANECA, NA GARRAFA E NO BONÉ (12/09/2026).

   A mesma da camisa — dez ícones em duas linhas de cinco e, embaixo, os seis
   de "Alinhar a arte na peça" em duas de três —, montada pelo
   `ferra_copos.js`. As medidas são as do `mockup.css` (`.mk-ferra` e
   `.mk-alinha`), que lá moram atrás do `#app#app` e aqui não chegariam. A
   pele do botão é a de cada família (`.xx-bt`); o `.s3-ferra` na frente é o
   que vence o `padding` do `.xx-bt--pequeno`, que vem numa folha posterior.
   ══════════════════════════════════════════════════════════════════════════ */
.s3-ferra {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 5px;
    margin: 10px 0 0;
}
.s3-ferra .s3-ferra__bt,
.s3-alinha .s3-ferra__bt {
    width: 100%;
    padding: 6px 0;
    justify-content: center;
    line-height: 1;
}
.s3-ferra .s3-ferra__bt svg { width: 18px; height: 18px; display: block; }
.s3-ferra .s3-ferra__bt--perigo:hover { border-color: #e03e3e; background: #fef2f2; }
.s3-alinha { margin: 9px 0 2px; }
.s3-alinha__rot {
    display: block;
    margin: 0 0 6px;
    font-size: .78rem;
    color: #64748b;
    line-height: 1.25;
}
.s3-alinha__grade {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 5px;
}
.s3-alinha .s3-ferra__bt svg { width: 21px; height: 21px; display: block; }
/*  O primeiro bloco mais forte, o segundo mais claro — como na camisa.     */
.s3-alinha .s3-ferra__bt svg rect { fill: #6c5ce7; }
.s3-alinha .s3-ferra__bt svg rect + rect { fill: #8b7bf0; }
.s3-alinha .s3-ferra__bt svg .ln {
    stroke: var(--cor-marca, #e2507d);
    stroke-width: 2;
    stroke-linecap: round;
    fill: none;
}

/*  O "REFLEXO" DA CANECA E DA GARRAFA (12/09/2026) — dois botões colados, um
    clique troca de um para o outro. Mesmo desenho do "1x 2x 3x" do palco.  */
.s3-reflexo {
    display: inline-flex;
    flex: 1 1 auto;
    gap: 2px;
    padding: 2px;
    border-radius: 8px;
    background: rgba(15, 23, 42, .07);
}
.s3-reflexo button {
    flex: 1 1 0;
    border: 0;
    background: transparent;
    padding: 5px 8px;
    border-radius: 6px;
    font: inherit;
    font-size: 12.5px;
    color: inherit;
    white-space: nowrap;
    cursor: pointer;
}
.s3-reflexo button.on { background: var(--cor-marca, #e2507d); color: #fff; }

/* ══════════════════════════════════════════════════════════════════════════
   AJUSTES DA ESTAMPA — o card do `ajuste_arte.js` (11/09/2026).

   Os controles usam as classes de cada família (`.lin`/`.chk`/`.bt` na malha,
   `.xx-campo`/`.xx-bt` nos copos), então aqui fica só o que é deste card: a
   fileira de atalhos, as duas chaves nos copos e o aviso de "arte ajustada".

   A especificidade segue a regra do bloco acima: `#app#app` na malha, o
   `.xx-app` na frente nos copos.
   ══════════════════════════════════════════════════════════════════════════ */
.aj-arte__predef {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0 0 14px;
}
#app#app .aj-arte .aj-arte__predef .bt,
.cn-app .aj-arte__predef .cn-bt,
.gf-app .aj-arte__predef .gf-bt,
.bn-app .aj-arte__predef .bn-bt {
    flex: 1 1 auto;
    justify-content: center;
    padding: 5px 9px;
    font-size: 11.5px;
    line-height: 1.2;
}
.aj-arte__chaves { margin: 2px 0 10px; }
/*  Nos copos não há chave de liga-desliga pronta: uma caixinha com a cor da
    marca, do tamanho da letra do `.xx-campo` ao lado.                        */
.aj-arte__chk {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 8px;
    font-size: .82rem;
    color: #374151;
    cursor: pointer;
    user-select: none;
}
.aj-arte__chk input {
    width: 16px;
    height: 16px;
    margin: 0;
    accent-color: var(--cor-marca, #e2507d);
}
.aj-arte__bts {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.aj-arte__bts > button { flex: 1 1 0; }
#app#app .aj-arte .aj-arte__bts .bt {
    justify-content: center;
    padding: 6px 8px;
    font-size: 11.5px;
}
/*  Segurar é o gesto: sem isto, no toque, o dedo parado selecionaria o texto
    do botão ou rolaria a barra em vez de mostrar a original.                 */
.aj-arte__compara {
    user-select: none;
    -webkit-user-select: none;
    touch-action: none;
}
/*  ARTE AJUSTADA: um contorno verde no card inteiro. Continua à vista com o
    card recolhido, que é quando mais se esquece que há um ajuste ligado. É
    contorno, e não borda, para não mudar a medida de nada; e não é texto no
    título porque a ordem dos cards é guardada PELO TÍTULO.                   */
.aj-arte-card.aj-arte--ligado {
    outline: 2px solid rgba(226, 80, 125, .6);
    outline-offset: -2px;
}

/*  ══════════════════════════════════════════════════════════════════════════
    O OLHO DA ESTAMPA — esconder a arte NA PEÇA, sem tirá-la. (11/09/2026)

    Ele nasceu no uniforme e passou a ser de todos os simuladores. O pedido foi
    literal: "aqui nesse projeto colocamos um olinho pra ocultar a arte, coloca
    esse mesmo olho em todos os simuladores".

    ─── ESCONDER NÃO É TIRAR ───

    A lixeira da botoeira apaga a arte da parte e some com ela do servidor;
    este olho só deixa de desenhá-la na PEÇA, para se ver o tecido cru embaixo
    — o corte, a costura, a cor da malha — e volta no mesmo botão. A imagem
    continua carregada e a chapa ao lado continua mostrando a arte, para se
    poder mexer nela enquanto se olha.

    ─── POR QUE A PELE É A DO OLHO DO PALCO ───

    Porque é o mesmo gesto, e os dois moram no canto de baixo à direita da
    caixa em que vivem — um no palco, outro na chapa. Duas peles diferentes
    para a mesma ideia fariam a pessoa aprender duas vezes. Este é menor, que é
    a diferença que há: a chapa é menor que o palco.

    Apagado enquanto ninguém o procura, aceso quando o dedo chega perto — como
    a lupa que divide a caixa com ele. E aceso de vez quando está escondendo,
    porque aí a peça fica igual a uma peça sem arte nenhuma: sem sinal, ninguém
    lembra por quê.

    ─── A CAIXA PRECISA SER O REFERENCIAL ───

    `position:relative` na caixa está aqui e não em cada folha de peça porque
    só a `.mk-chapa-cx` tinha (as de caneca, garrafa e boné são `div` sem
    estilo próprio). Sem isso o botão iria para o canto da PÁGINA.
    ══════════════════════════════════════════════════════════════════════════ */
.mk-chapa-cx, .cn-chapa-cx, .gf-chapa-cx, .bn-chapa-cx { position: relative; }

.s3-olho-arte {
    position: absolute;
    right: 6px;
    bottom: 6px;
    z-index: 3;
    width: 30px;
    height: 28px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 7px;
    cursor: pointer;
    border: 1px solid #00000022;
    background: #ffffffdd;
    color: #2a2f3a;
    box-shadow: 0 1px 4px #00000022;
    opacity: .5;
    transition: opacity .15s, background-color .14s, color .14s;
}
.mk-chapa-cx:hover .s3-olho-arte,
.cn-chapa-cx:hover .s3-olho-arte,
.gf-chapa-cx:hover .s3-olho-arte,
.bn-chapa-cx:hover .s3-olho-arte,
.s3-olho-arte:hover,
.s3-olho-arte:focus-visible { opacity: 1; }
.s3-olho-arte:hover:not(:disabled) { background: #0000000f; }
/*  ESCONDENDO: fica aceso sozinho, e não só no hover — ver o cabeçalho.     */
.s3-olho-arte[aria-pressed="true"] {
    opacity: 1;
    background: var(--cor-marca, #e2507d);
    border-color: var(--cor-marca, #e2507d);
    color: #fff;
}
.s3-olho-arte:disabled { opacity: .28; cursor: default; }
.s3-olho-arte svg { width: 15px; height: 15px; display: block; }
/*  Um desenho de cada vez. Os seletores levam `.s3-olho-arte` na frente pela
    mesma conta de peso explicada no olho do palco, logo acima.             */
.s3-olho-arte .s3-olho__ver     { display: block; }
.s3-olho-arte .s3-olho__ocultar { display: none; }
.s3-olho-arte[aria-pressed="true"] .s3-olho__ver     { display: none; }
.s3-olho-arte[aria-pressed="true"] .s3-olho__ocultar { display: block; }

/*  ══════════════════════════════════════════════════════════════════════════
    O CARD DE FERRAMENTAS NO TELEFONE — as quatro famílias.  (12/09/2026)

    No telefone as ferramentas do palco saem de cima da peça e vêm para um card
    logo embaixo dela: quem as move é o `salvar_celular.js`, no corte de cada
    família, e ele marca a barra com `s3-fer-card`. Esta regra é o card.

    ─── POR QUE AQUI, E NÃO NA FOLHA DE CADA PEÇA ───

    Porque é o mesmo card nas oito telas, e o pedido foi esse: "a opção mobile
    tem que funcionar padrão em todos os simuladores, camisa, caneca, garrafa,
    boné". Esta folha é a única que as oito carregam. Uma pele por família
    seriam quatro cópias para desencontrar.

    Ela não tem `@media`: a classe só existe quando o módulo a põe, e ele só a
    põe no corte de telefone. O corte fica escrito num lugar só — o módulo, que
    o copia da folha de cada família.

    ─── A CONTA DO PESO ───

    Cada família escreve a barra com o próprio peso, e este card tem de ganhar
    de todos: na camisa a barra é `#app .sim-salvar` e `#app#app .sim-salvar`
    (dois ids), por isso o `#app#app` aqui; nas outras é `.cn-fer-palco` e
    irmãs (uma classe), e `.cn-app .cn-fer-palco.s3-fer-card` passa com folga.
    ══════════════════════════════════════════════════════════════════════════ */
#app#app .sim-salvar.s3-fer-card,
.cn-app .cn-fer-palco.s3-fer-card,
.gf-app .gf-fer-palco.s3-fer-card,
.bn-app .bn-fer-palco.s3-fer-card {
    position: static;
    top: auto; right: auto; bottom: auto; left: auto;
    z-index: auto;
    width: auto; max-width: none; height: auto;
    margin: 0;
    transform: none;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 6px;
    /*  A barra das outras famílias é `pointer-events:none` no palco, para o
        dedo passar para a peça pelos vãos entre os botões. No card não há peça
        embaixo.                                                            */
    pointer-events: auto;
    /*  A pele é a dos cards da coluna — fundo, linha, raio de 12 e a elevação
        da casa —, para ele ler como mais um deles, e não como uma barra solta
        entre a peça e a coluna.                                           */
    background: var(--cartao, #fff);
    border: 1px solid var(--linha, #e2e8f0);
    border-radius: 12px;
    padding: 12px 13px;
    box-shadow: var(--sim-elevacao, 0 1px 2px #0f172a24, 0 5px 12px #0f172a26, 0 16px 32px #0f172a1c);
}
/*  O título, no corpo dos títulos dos outros cards. Pseudo-elemento, e não um
    `<h3>` no HTML das oito telas: ele só existe quando a barra é card, e a
    barra só é card no telefone. `flex-basis:100%` o põe numa linha só dele.
    O MESMO TEXTO nas quatro famílias — é o mesmo card.                     */
#app#app .sim-salvar.s3-fer-card::before,
.cn-app .cn-fer-palco.s3-fer-card::before,
.gf-app .gf-fer-palco.s3-fer-card::before,
.bn-app .bn-fer-palco.s3-fer-card::before {
    content: 'Girar, imagem e vídeo';
    flex-basis: 100%;
    margin: 0 0 4px;
    font-size: 12.5px;
    font-weight: 700;
    color: var(--texto, #1c2030);
}
/*  Os botões perdem o vidro: dentro de um card branco, a sombra de flutuar
    sobre a peça vira sujeira.                                             */
#app#app .s3-fer-card button,
#app#app .s3-fer-card select,
#app#app .s3-fer-card .sim-vel,
.cn-app .s3-fer-card button, .cn-app .s3-fer-card select, .cn-app .s3-fer-card .cn-vel,
.gf-app .s3-fer-card button, .gf-app .s3-fer-card select, .gf-app .s3-fer-card .gf-vel,
.bn-app .s3-fer-card button, .bn-app .s3-fer-card select, .bn-app .s3-fer-card .bn-vel {
    box-shadow: none;
}

/*  ══════════════════════════════════════════════════════════════════════════
    O QUADRO DE NOVIDADES DO HUB — o `<dialog>` do `index.php`, aberto pelo
    `hub_novidades.js`.  (14/09/2026)

    ─── TRÊS ANDARES, E SÓ O DO MEIO ROLA ───

    O topo verde (o que mudou, e que é de graça) e o pé (fechar e ir escolher
    a peça) ficam sempre à vista; a lista rola entre os dois. Num telefone de
    844 px a lista inteira não cabe, e um quadro que rolasse inteiro levaria
    embora o botão de sair — que é o que mais irrita num modal.

    ─── O VERDE DO TOPO É MAIS ESCURO QUE A MARCA ───

    Texto branco sobre o `#e2507d` da marca dá 4,5:1, no limite; o degradê vai
    de `#932546` a `#be2d59`, e o ponto mais claro dele ainda dá 5,5:1 com o
    branco. Um degradê que clareasse até um verde vivo, como o primeiro
    rascunho, deixava o parágrafo com 2,7:1.

    ─── `min(…, 100%)` NAS GRADES ───

    Os 300 px da coluna viram 100% da caixa quando ela é menor que isso: num
    telefone de 320 px o quadro tem 296 e o miolo 264 — um `minmax(300px, …)`
    seco vazaria para o lado.
    ══════════════════════════════════════════════════════════════════════════ */
.s3-novo-bt {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    /*  14 px embaixo: com 2 px ele encostava na barra do filtro (medido na
        foto, 3 px de vão) e os dois liam como uma fileira só de botões.     */
    margin: 4px 0 14px;
    padding: 8px 16px;
    border-radius: 999px;
    border: 1px solid #f3d3dd;
    background: #fdf4f7;
    color: var(--cor-marca, #e2507d);
    font: inherit;
    font-size: .92rem;
    font-weight: 650;
    cursor: pointer;
    transition: background-color .15s, color .15s, border-color .15s;
}
.s3-novo-bt:hover {
    background: var(--cor-marca, #e2507d);
    border-color: var(--cor-marca, #e2507d);
    color: #fff;
}
.s3-novo-bt[hidden] { display: none; }

/*  A página de trás não rola enquanto o quadro está aberto: o dedo que rola a
    lista, ao chegar no fim, passaria a rolar os cartões por baixo do véu.   */
html:has(.s3-novo[open]) { overflow: hidden; }

.s3-novo {
    padding: 0;
    border: 0;
    border-radius: 20px;
    width: min(820px, calc(100vw - 24px));
    max-width: none;
    max-height: min(90vh, 920px);
    max-height: min(90dvh, 920px);
    background: #fff;
    color: var(--cor-texto, #0f172a);
    box-shadow: 0 30px 80px #0f172a59;
    overflow: hidden;
}
.s3-novo[open] {
    display: flex;
    animation: s3NovoEntra .28s cubic-bezier(.2, .8, .2, 1);
}
.s3-novo::backdrop {
    background: #0f172a99;
    backdrop-filter: blur(3px);
}
@keyframes s3NovoEntra {
    from { opacity: 0; transform: translateY(14px) scale(.98); }
    to   { opacity: 1; transform: none; }
}

.s3-novo__caixa {
    display: flex;
    flex-direction: column;
    width: 100%;
    min-height: 0;
}

.s3-novo__topo {
    position: relative;
    flex: 0 0 auto;
    padding: 26px 28px 22px;
    background: linear-gradient(135deg, #932546, #be2d59);
    color: #fff;
}
.s3-novo__selo {
    display: inline-block;
    padding: 4px 11px;
    border-radius: 999px;
    background: #ffffff24;
    border: 1px solid #ffffff4d;
    font-size: .74rem;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
}
/*  O TÍTULO É O RECADO: grande, pesado e com a promessa em amarelo-claro numa
    linha só dela. O amarelo `#fef08a` dá 4,8:1 contra o ponto mais claro do
    degradê — passa até na régua de texto pequeno, e o título é texto grande
    (a régua dele é 3:1).                                                    */
.s3-novo__topo h2 {
    margin: 14px 44px 10px 0;
    font-size: clamp(1.6rem, 1.1rem + 2.2vw, 2.35rem);
    font-weight: 800;
    line-height: 1.12;
    letter-spacing: -.02em;
    color: #fff;
    text-wrap: balance;
}
.s3-novo__topo h2 em {
    display: block;
    font-style: normal;
    color: #fef08a;
}
.s3-novo__topo p {
    margin: 0;
    max-width: 660px;
    font-size: .98rem;
    line-height: 1.6;
    color: #fff0f4;
}
.s3-novo__x {
    position: absolute;
    top: 14px;
    right: 14px;
    width: 38px;
    height: 38px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: #ffffff24;
    color: #fff;
    font: inherit;
    font-size: 1.55rem;
    line-height: 1;
    cursor: pointer;
}
.s3-novo__x:hover { background: #ffffff45; }

.s3-novo__corpo {
    flex: 1 1 auto;
    min-height: 0;
    overflow: auto;
    overscroll-behavior: contain;
    padding: 20px 28px 16px;
}

.s3-novo__num {
    list-style: none;
    margin: 0 0 16px;
    padding: 0;
    display: grid;
    gap: 10px;
    grid-template-columns: repeat(auto-fit, minmax(min(170px, 100%), 1fr));
}
.s3-novo__num li {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 12px 14px;
    border-radius: 14px;
    background: #fdf4f7;
    border: 1px solid #f3d3dd;
}
.s3-novo__num b {
    font-size: 1.7rem;
    line-height: 1;
    font-weight: 800;
    letter-spacing: -.02em;
    color: var(--cor-marca, #e2507d);
    white-space: nowrap;
}
.s3-novo__num span {
    display: flex;
    flex-direction: column;
    font-size: .86rem;
    line-height: 1.3;
    font-weight: 650;
}
.s3-novo__num small {
    font-size: .78rem;
    font-weight: 500;
    color: var(--cor-texto-suave, #475569);
}

.s3-novo__lista {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 10px;
    grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
}
.s3-novo__lista li {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 13px 14px;
    border-radius: 14px;
    border: 1px solid var(--cor-borda, #e2e8f0);
    background: var(--cor-fundo-suave, #f8fafc);
}
.s3-novo__ic {
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 11px;
    background: #fff;
    border: 1px solid var(--cor-borda, #e2e8f0);
    font-size: 1.2rem;
    font-style: normal;
    line-height: 1;
}
.s3-novo__lista h3 {
    margin: 1px 0 3px;
    font-size: .96rem;
    font-weight: 700;
    color: var(--cor-texto, #0f172a);
}
.s3-novo__lista p {
    margin: 0;
    font-size: .86rem;
    line-height: 1.55;
    color: var(--cor-texto-suave, #475569);
}

.s3-novo__pe {
    flex: 0 0 auto;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px 16px;
    padding: 14px 28px 18px;
    border-top: 1px solid var(--cor-borda, #e2e8f0);
    background: #fff;
}
.s3-novo__nao {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: .88rem;
    color: var(--cor-texto-suave, #475569);
    cursor: pointer;
    user-select: none;
}
.s3-novo__nao input {
    width: 17px;
    height: 17px;
    margin: 0;
    accent-color: var(--cor-marca, #e2507d);
}
.s3-novo__ir {
    padding: 12px 22px;
    border: 0;
    border-radius: 12px;
    background: var(--cor-marca, #e2507d);
    color: #fff;
    font: inherit;
    font-size: 1rem;
    font-weight: 700;
    cursor: pointer;
    box-shadow: 0 6px 16px #e2507d40;
    transition: background-color .15s;
}
.s3-novo__ir:hover { background: var(--cw-verde-esc, #be2d59); }
.s3-novo__ir:focus-visible,
.s3-novo__x:focus-visible,
.s3-novo-bt:focus-visible {
    outline: 3px solid #f59e0b;
    outline-offset: 2px;
}

/*  ══════════════════════════════════════════════════════════════════════════
    A BARRA DE VISTAS FICA DISCRETA ATÉ A MÃO CHEGAR (16/09/2026)

    Pedido do CW: 80% de opacidade, e 100% no hover.

    Ela flutua SOBRE a peça, no pé do cenário — e é o único pedaço de interface
    que fica por cima do produto. Numa foto de camisa escura ou numa caneca
    clara, aquela pílula branca opaca é a primeira coisa que o olho encontra, e
    não deveria ser: quem abriu a página veio ver a peça.

    A 80% ela continua legível (é texto escuro sobre branco, não some), mas
    para de disputar. E volta inteira no instante em que a mão vai usá-la.

    ─── AS DUAS FAMÍLIAS, E O `:focus-within` ───

    `#app .mk-vistas` é a da malha; `.cn-vistas` e as irmãs são as de peça
    única. A regra é uma só, com os quatro seletores, no mesmo formato que este
    arquivo já usa para os botões.

    O `:focus-within` está aí porque hover não é o único jeito de chegar num
    botão: quem anda de Tab precisa ver onde está, e uma barra a 80% com o foco
    dentro dela seria um foco desenhado no escuro.

    ─── NO TOQUE ELA FICA INTEIRA ───

    `hover: none` — no telefone não existe "passar o mouse", e a barra ficaria
    a 80% para sempre sem nunca ter o momento de acender. Ali ela volta a ser
    o que era.                                                                */
#app .mk-vistas,
.bn-app .bn-vistas, .gf-app .gf-vistas, .cn-app .cn-vistas {
    /*  ─── ELA SAI DO CAMINHO, MAS NAO SOME ───

        O numero levou tres voltas, e vale registrar as tres para ninguem
        refazer o caminho:

          .80  primeiro palpite — "ainda esta muito fraco", disse o CW;
          .95  eu li "fraco" como "pouco visivel" e SUBI. Errado: o pedido
               sempre foi 95% de TRANSPARENCIA, que e' 5% de opacidade;
          .05  o literal. No ar ficou fantasma de verdade — "esta muito";
          .30  o meio-termo, e o que ficou.

        A 30% ela sai da frente da peca (que e' o ponto: e' a unica interface
        por cima do produto) e ainda se enxerga onde esta — o olho acha a barra
        sem precisar procurar com o mouse.

        Regra para a proxima vez: transparencia X% = opacity (100 - X)%.

        Quem precisa dela leva o mouse ali e ela acende inteira; no toque
        (`hover: none`) ela nunca apaga.                                    */
    opacity: .30;
    transition: opacity .15s ease;
}
#app .mk-vistas:hover,        #app .mk-vistas:focus-within,
.bn-app .bn-vistas:hover,     .bn-app .bn-vistas:focus-within,
.gf-app .gf-vistas:hover,     .gf-app .gf-vistas:focus-within,
.cn-app .cn-vistas:hover,     .cn-app .cn-vistas:focus-within {
    opacity: 1;
}
@media (hover: none) {
    #app .mk-vistas,
    .bn-app .bn-vistas, .gf-app .gf-vistas, .cn-app .cn-vistas { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
    #app .mk-vistas,
    .bn-app .bn-vistas, .gf-app .gf-vistas, .cn-app .cn-vistas { transition: none; }
}

@media (max-width: 560px) {
    .s3-novo__topo  { padding: 22px 18px 18px; }
    .s3-novo__topo h2 { font-size: 1.3rem; }
    .s3-novo__topo p  { font-size: .92rem; }
    .s3-novo__corpo { padding: 16px 16px 12px; }
    .s3-novo__pe    { padding: 12px 16px 14px; }
    .s3-novo__ir    { width: 100%; }
}
@media (prefers-reduced-motion: reduce) {
    .s3-novo[open] { animation: none; }
}


/*  ═══════════════════════════════════════════════════════════════════════
    O VISOR — a peça de alguém, para quem vai comprar.   (16/09/2026)

    Liga em `/simulador-3d/ver/<id>`: o `includes/layout.php` põe `s3-visor` no
    `<body>` e não imprime o cabeçalho nem o rodapé do site. O que sobra de
    página é escondido aqui.

    ─── POR EXCLUSÃO, E NÃO POR LISTA ───

    `#app > *:not(.pl-col)` esconde TODO filho do simulador que não seja a
    coluna do palco — o painel, a lateral de ajustes, a alça. Uma lista de
    nomes envelheceria no dia em que entrasse um cartão novo, e o defeito seria
    o pior possível: um controle nosso aparecendo na tela do cliente do
    revendedor.

    A estrutura é a mesma nas duas famílias (medido): o app tem a `.pl-col` e
    mais os painéis, e a `<main>` tem o app e o texto da página.
    ═══════════════════════════════════════════════════════════════════════ */
body.s3-visor #app > *:not(.pl-col),
body.s3-visor .cn-app > *:not(.pl-col),
body.s3-visor .gf-app > *:not(.pl-col),
body.s3-visor .bn-app > *:not(.pl-col) {
    display: none !important;
}
/*  E o que mora fora do simulador: o texto da página, o botão de ajuda, a
    alça da altura (que é irmã do app) e o próprio botão de compartilhar —
    quem está vendo não compartilha de novo.                                 */
body.s3-visor .s3-texto,
body.s3-visor .aj-botao,
body.s3-visor .s3-alca-alt,
body.s3-visor .s3-share,
body.s3-visor .s3-share-balao {
    display: none !important;
}

/*  ─── O PALCO É A TELA INTEIRA ─── (16/09/2026)

    O CW: *"quero que o simulador fique do tamanho da tela do celular, sem as
    vistas e sem o controle de rotação, só pro cliente usar com os dedos,
    rodar e dar zoom"*.

    Um dedo gira, dois dão zoom — é o que os controles de órbita de todo motor
    já faziam no canvas, e o canvas já é `touch-action: none`, então o
    navegador não rouba o gesto para rolar ou ampliar a página.

    `100dvh` e não só `100vh`: no celular a barra de endereço entra e sai, e
    `vh` é a altura SEM ela — a peça ficaria com o pé escondido atrás da barra.
    A linha de `vh` antes é para o navegador que não conhece `dvh`.

    Tudo com `!important` porque o palco carrega três limites de altura
    (`aspect-ratio`, `max-height`, `min-height`), a coluna um `sticky` escrito
    em linha, e o app uma grade de duas colunas — e todos têm de perder.   */
body.s3-visor {
    margin: 0;
    overflow: hidden;
}
body.s3-visor .s3-visor-main {
    max-width: none !important;
    width: 100%;
    margin: 0 !important;
    padding: 0 !important;
}
body.s3-visor #app,
body.s3-visor .cn-app,
body.s3-visor .gf-app,
body.s3-visor .bn-app {
    display: block !important;
    max-width: none !important;
    height: auto !important;
    margin: 0 !important;
    padding: 0 !important;
    gap: 0 !important;
}
body.s3-visor .pl-col {
    position: static !important;
    top: auto !important;
    margin: 0 !important;
}
body.s3-visor .cn-palco-caixa,
body.s3-visor .gf-palco-caixa,
body.s3-visor .bn-palco-caixa {
    position: static !important;
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
}
body.s3-visor #palco,
body.s3-visor #cnPalco,
body.s3-visor #gfPalco,
body.s3-visor #bnPalco {
    width: 100% !important;
    height: 100vh !important;
    height: 100dvh !important;
    aspect-ratio: auto !important;
    max-height: none !important;
    min-height: 0 !important;
    border: 0 !important;
    border-radius: 0 !important;
}

/*  ─── NADA POR CIMA DA PEÇA ─── (16/09/2026)

    A barra do player inteira, as pílulas de vista, o olho e as alças de
    largura do cenário (a `.sim-alca` da malha e o `#cnAlcaLarg` e irmãos da
    peça única — aquele "||" na beira direita). O CW pediu o simulador só
    para os dedos, e cada um destes era um botão nosso na tela do cliente do
    revendedor.

    Na primeira versão a barra ficava só com o botão redondo de girar; na tela
    do celular ela sobrava sozinha embaixo da peça, um pedaço de interface que
    não dizia nada. Girar com o dedo já faz o mesmo, e melhor.              */
body.s3-visor .pl-barra,
body.s3-visor #vistas,
body.s3-visor #cnVistas,
body.s3-visor #gfVistas,
body.s3-visor #bnVistas,
body.s3-visor .s3-olho,
body.s3-visor .sim-alca,
body.s3-visor #cnAlcaLarg,
body.s3-visor #gfAlcaLarg,
body.s3-visor #bnAlcaLarg {
    display: none !important;
}

/*  ─── A PEÇA SÓ APARECE PRONTA ───

    Entre o primeiro quadro e a arte vestida a peça está BRANCA, e quem abriu o
    link veio ver a estampa. O `visor.js` tira esta classe quando termina — ou
    depois de oito segundos, aconteça o que acontecer.                       */
body.s3-visor .pl-col {
    transition: opacity .3s ease;
}
body.s3-visor-carregando .pl-col {
    opacity: 0;
}
@media (prefers-reduced-motion: reduce) {
    body.s3-visor .pl-col { transition: none; }
}
