/* =====================================================================
   RÁDIO DRAGOON — aparência
   =====================================================================
   Toda a geometria e os ajustes visuais moram no bloco :root logo
   abaixo. Nenhum número de posição aparece fora dele.

   TROCOU UMA IMAGEM? Abra o verificador.html: a aba de geometria mede
   os arquivos e aponta quais variáveis daqui saíram do lugar.

   Ordem das seções:
     :root          geometria e ajustes
     #fundo         a imagem desfocada atrás do aparelho
     .conjunto      corpo, gaveta e a sombra entre os dois
     .visor         a tela grande, atrás do recorte do corpo
     .comando       as tampas dos botões, sobre os furos
     #gaveta        a peça que desliza
     modo app       o que muda no programa de desktop
   ===================================================================== */
:root{
    /* =================== GEOMETRIA ===================
       Todo número de posição do aparelho mora aqui, e em lugar nenhum
       mais. São frações da imagem a que pertencem, medidas com o
       verificador.html — se você trocar um PNG, rode ele: a aba de
       geometria diz exatamente quais destes valores mudaram.

       ---- corpo.png · 1536x1030 ---- */
    --visor-x:11.59%;  --visor-y:22.04%;  --visor-w:77.02%;  --visor-h:40.78%;
    --nome-x:10.48%;   --nome-y:10.00%;   --nome-w:38.48%;   --nome-h:9.22%;
    --liga-x:9.70%;    --liga-y:66.99%;   --liga-w:11.07%;   --liga-h:15.44%;
    --vol-x:23.63%;    --vol-y:69.81%;    --vol-w:45.96%;    --vol-h:10.39%;
    --yt-x:71.68%;     --yt-y:69.22%;     --yt-w:7.81%;      --yt-h:11.46%;
    --abrir-x:81.64%;  --abrir-y:69.32%;  --abrir-w:7.88%;   --abrir-h:11.55%;

    /* ---- gaveta.png · 1614x1089 ---- */
    --tela-x:8.24%;    --tela-y:13.68%;   --tela-w:83.58%;   --tela-h:70.16%;
    --modo-x:47.46%;   --modo-y:90.08%;  --modo-w:4.89%;   --modo-h:6.89%;
    --gaveta-lado:6.3%;                 /* recuo lateral, para caber atrás do corpo */
    --gaveta-base:2%;

    /* ---- visor-nome.png · 1164x184 · janela em fração da própria peça ---- */
    --nome-jx:0.0344;  --nome-jy:0.1793; --nome-jw:0.9304;  --nome-jh:0.6522;

    /* =================== AJUSTES A OLHO ===================
       Estes não vieram de medição: são calibragem visual. Mexer neles é
       seguro e não quebra encaixe nenhum. */
    --tampa-grande:106%;                /* tampa transbordando o furo */
    --tampa-pequena:108%;
    --icone-grande:42%;                 /* glifo dentro da tampa */
    --icone-pequeno:46%;
    --tampa-modo:112%;                  /* a tampa da gaveta sobre o furo */
    --app-largura:460px;                /* o mesmo do site: sem isto o aparelho
                                           encolhia para caber na janela, a janela
                                           media o encolhido, e ele nunca crescia */
    --app-folga:52px;                   /* espaço para a sombra não ser cortada */
    --app-folga-topo:14px;
    /* Ao recortar o magenta das peças eu dilatei a máscara em 5px, para
       não sobrar franja colorida. Com isso o buraco no PNG ficou um
       pouco maior que a caixa que o CSS pinta atrás dele, e por essas
       frestas aparece o que estiver por trás — invisível no site, que
       tem fundo, e evidente no programa, onde é a área de trabalho.
       A tela é esticada além da caixa; o excesso fica sob a moldura. */
    --sangria:6px;

    --video-altura:300%;                /* altura do iframe: joga a interface do
                                           YouTube para fora do recorte */
    --botoes-desce:2px;                 /* desce as três tampas, no olho */
    --app-sobe-pequenos:1px;            /* só no programa: as duas tampas
                                           pequenas sobem um pixel */
    --vidro-brilho:.17;                 /* pico do reflexo no vidro */
    --sombra-forca:.42;                 /* preto no encosto da sombra */
    --sombra-altura:10.2cqw;
    --sombra-sobe:-1.2cqw;              /* enfia a sombra atrás do corpo */
    --sombra-lado:7.4%;                 /* recuo, para não vazar da gaveta */

    /* visor de cristal líquido retroiluminado */
    --visor-a:#0a2c39;
    --visor-b:#05191f;
    --tinta:#7ce6f4;
    --tinta-fraca:rgba(124,230,244,.42);
    --led:#ff3b30;

    --corredica-cheia:#c9d4d8;
    --corredica-trilho:rgba(0,0,0,.45);

    /* ---- rebaixo do nome, medido no corpo.png ----
       Se o corpo mudar, só estes quatro números mudam: a moldura, o LCD
       e o vidro são todos posicionados a partir daqui. */
    --nome-x:10.48%;
    --nome-y:10.00%;
    --nome-w:38.48%;
    --nome-h:9.22%;
    /* janela recortada dentro da moldura, em fração dela mesma */
    --nome-jx:0.0344;
    --nome-jy:0.1793;
    --nome-jw:0.9304;
    --nome-jh:0.6522;

    --mono:ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;
    --sans:"Helvetica Neue", Helvetica, Arial, sans-serif;

    /* ---- medidas lidas dos PNGs, em fração da imagem ----
       corpo.png  1536x1024   ·   gaveta.png  1614x975          */
    --corpo-prop:1536 / 1024;
    --gaveta-prop:1614 / 975;
  }

  *{ box-sizing:border-box; }
  html, body{ height:100%; }

  body{
    margin:0;
    font-family:var(--sans);
    background:#1b2026;
    display:flex;
    align-items:center;
    justify-content:center;
    padding:28px 16px;
    min-height:100%;
  }

  /* ---------- fundo desfocado ---------- */

  /* Até as peças chegarem, o aparelho não aparece: sem isso o usuário vê
     ele sendo montado, e a gaveta pulando de altura quando a imagem dela
     carrega. O fundo tem vida própria — entra antes, assim que carregar,
     e forma o ambiente enquanto o resto vem. */
  #fundo, #radio{
    opacity:0;
    transition:opacity .45s ease;
  }
  body.com-fundo #fundo{ opacity:1; }
  body.montado #radio{ opacity:1; }

  /* O anel não existe até o fundo estar posto. A ordem é essa: primeiro o
     ambiente se forma, e só então aparece o sinal de que algo está sendo
     carregado dentro dele. */
  #carregando{
    position:fixed;
    inset:0;
    z-index:5;
    display:flex;
    align-items:center;
    justify-content:center;
    pointer-events:none;
    opacity:0;
    transition:opacity .3s ease;
  }
  body.esperando #carregando{ opacity:1; }
  body.montado #carregando{ opacity:0; visibility:hidden; }

  /* Um anel de cristal líquido, não um spinner genérico: mesma tinta do
     visor, e a lacuna gira em vez de a peça inteira piscar. */
  #carregando .anel{
    width:34px; height:34px;
    border-radius:50%;
    border:2px solid rgba(124,230,244,.16);
    border-top-color:var(--tinta);
    box-shadow:0 0 10px rgba(124,230,244,.22);
    animation:girando .9s linear infinite;
  }
  @keyframes girando{ to{ transform:rotate(360deg); } }

  #fundo{
    position:fixed;
    inset:-4%;                       /* sobra além da tela para o desfoque não deixar borda mole */
    background:#1b2026 center/cover no-repeat;
    filter:blur(6px) saturate(1.06) brightness(.78);
    z-index:-2;
  }
  #fundo::after{
    content:"";
    position:absolute;
    inset:0;
    background:radial-gradient(ellipse at 50% 38%, rgba(0,0,0,0) 34%, rgba(0,0,0,.5) 100%);
  }

  /* ---------- o conjunto ---------- */

  #radio{ width:100%; max-width:460px; }
  .conjunto{ position:relative; container-type:inline-size; }

  /* A sombra que o corpo joga sobre a gaveta. Fica ancorada na base do
     corpo (top:100%), e não na gaveta: se descesse junto com a peça,
     viraria um contorno colado nela em vez de sombra de algo à frente.
     Uma linha de contato forte no encosto e uma queda longa depois, que
     é como uma sombra se comporta quando a fonte de luz é ampla. */
  .sombra-corpo{
    position:absolute;
    left:var(--sombra-lado); right:var(--sombra-lado);
    top:100%;
    /* O corpo acaba em y=1024 de uma imagem de 1030: sobram 6 linhas
       vazias na base. Como top:100% se refere à caixa e não à silhueta,
       a sombra nascia 6px abaixo do fim real da peça, e aquela tira sem
       sombra aparecia clara. Sobe 1,2cqw: a parte de cima fica enfiada
       atrás do corpo, que é onde ela some. */
    margin-top:var(--sombra-sobe);
    height:var(--sombra-altura);
    z-index:0;
    pointer-events:none;
    opacity:0;
    transition:opacity .38s ease;
    background:linear-gradient(180deg,
      rgba(0,0,0,var(--sombra-forca)) 0,
      rgba(0,0,0,calc(var(--sombra-forca) * .71)) 14%,
      rgba(0,0,0,calc(var(--sombra-forca) * .38)) 38%,
      rgba(0,0,0,calc(var(--sombra-forca) * .14)) 68%,
      rgba(0,0,0,0) 100%);
  }
  #radio.aberto .sombra-corpo{ opacity:1; }

  /* O aparelho é a fotografia. Tudo que vive por cima é posicionado em
     porcentagem dela, então o conjunto inteiro escala junto com a largura.
     A unidade cqw vale 1% da largura do aparelho: é ela que faz o texto
     do visor acompanhar o tamanho da foto em vez de ficar fixo em px. */
  /* A sombra fica na fotografia, não no conjunto. Um filter no pai joga
     ele e todos os filhos numa camada rasterizada só, e aí qualquer
     mudança na barra de progresso obrigava a redesenhar o aparelho
     inteiro cinco vezes por segundo — era isso que piscava. */
  .aparelho{
    position:relative;
    z-index:1;
    container-type:inline-size;
  }
  .chassi{
    position:relative;
    z-index:1;                       /* a foto cobre o visor: é ela que faz a moldura */
    display:block;
    width:100%;
    height:auto;
    filter:drop-shadow(0 18px 30px rgba(0,0,0,.5));
    pointer-events:none;
    user-select:none;
    -webkit-user-drag:none;
  }

  /* o corpo recua quando a tela é empurrada para fora ou volta à trava */
  @keyframes empurra{
    0%   { transform:translateY(0) rotate(0deg); }
    16%  { transform:translateY(-.6cqw) rotate(-.55deg); }
    40%  { transform:translateY(.3cqw) rotate(.34deg); }
    68%  { transform:translateY(-.12cqw) rotate(-.14deg); }
    100% { transform:translateY(0) rotate(0deg); }
  }
  @keyframes recolhe{
    0%   { transform:translateY(0) rotate(0deg); }
    22%  { transform:translateY(.5cqw) rotate(.42deg); }
    52%  { transform:translateY(-.2cqw) rotate(-.22deg); }
    100% { transform:translateY(0) rotate(0deg); }
  }
  .aparelho.empurra{ animation:empurra .44s cubic-bezier(.3,.8,.3,1); }
  .aparelho.recolhe{ animation:recolhe .38s cubic-bezier(.3,.8,.3,1); }

  /* ---------- o visor, atrás do recorte da foto ---------- */

  .visor{
    position:absolute;
    left:calc(var(--visor-x) - var(--sangria));
    top:calc(var(--visor-y) - var(--sangria));
    width:calc(var(--visor-w) + var(--sangria) * 2);
    height:calc(var(--visor-h) + var(--sangria) * 2);
    z-index:0;                       /* por baixo do chassi: a moldura da foto o encobre */
    /* A sangria estica a caixa para fora, e o afastamento do texto é
       medido da borda dela — sem somar a sangria aqui, o conteúdo sairia
       junto e ficaria colado na moldura. */
    padding:calc(2.1cqw + var(--sangria)) calc(2.4cqw + var(--sangria));
    background:linear-gradient(180deg, var(--visor-a), var(--visor-b));
    overflow:hidden;
  }
  .visor::after{                     /* linhas de varredura */
    content:"";
    position:absolute; inset:0;
    background:repeating-linear-gradient(180deg,
      rgba(255,255,255,.05) 0 1px, transparent 1px 3px);
    pointer-events:none;
  }

  .visor-topo{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:2cqw;
    font-family:var(--mono);
    font-size:2.05cqw;
    letter-spacing:.08em;
    color:var(--tinta-fraca);
    text-transform:uppercase;
  }
  #estado{ display:flex; align-items:center; gap:1.1cqw; }
  #led{
    width:1.3cqw; height:1.3cqw;
    border-radius:50%;
    background:rgba(255,255,255,.18);
    flex-shrink:0;
  }
  #radio.no-ar #led{
    background:var(--led);
    box-shadow:0 0 1.2cqw var(--led);
    animation:pisca 2.4s infinite;
  }
  @keyframes pisca{ 0%,100%{opacity:1} 50%{opacity:.3} }
  #tempo{ font-variant-numeric:tabular-nums; }

  .rolagem{ overflow:hidden; margin-top:1.7cqw; }
  #tocando{
    font-family:var(--mono);
    font-size:3.25cqw;
    line-height:1.3;
    color:var(--tinta);
    text-shadow:0 0 1.8cqw rgba(124,230,244,.45);
    white-space:nowrap;
  }
  .rolagem.rolando #tocando{
    display:inline-block;
    padding-right:10cqw;
    animation:desliza var(--giro, 14s) linear infinite;
  }
  @keyframes desliza{
    0%, 8%   { transform:translateX(0); }
    92%, 100%{ transform:translateX(var(--desloca, 0)); }
  }

  #canal{
    font-family:var(--mono);
    font-size:2.15cqw;
    color:var(--tinta-fraca);
    margin-top:.5cqw;
    min-height:2.9cqw;
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  }

  /* barra em blocos, do jeito que um cristal líquido de verdade desenha */
  #barra{
    margin-top:2cqw;
    height:1.5cqw;
    border-radius:.3cqw;
    background:rgba(124,230,244,.10);
    box-shadow:inset 0 0 0 1px rgba(124,230,244,.16);
    overflow:hidden;
  }
  /* O bloco e o vão vêm do JS em pixels inteiros. Em cqw eles caíam em
     frações de pixel, e o arredondador do navegador comia meio pixel de
     um bloco sim, outro não — daí umas poucas barrinhas mais finas. */
  #progresso{
    height:100%;
    width:0;
    background-image:repeating-linear-gradient(90deg,
      var(--tinta) 0 var(--aceso, 4px),
      transparent  var(--aceso, 4px) var(--bloco, 6px));
    box-shadow:0 0 1.6cqw rgba(124,230,244,.5);
  }

  #aseguir{
    font-family:var(--mono);
    font-size:1.95cqw;
    color:var(--tinta-fraca);
    margin-top:1.4cqw;
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  }

  #aviso{
    display:none;
    font-family:var(--mono);
    font-size:1.95cqw;
    color:#ff8f88;
    margin-top:1.2cqw;
  }
  #aviso.visivel{ display:block; }
  /* o visor tem altura fixa: o aviso ocupa a linha do "a seguir" */
  .visor:has(#aviso.visivel) #aseguir{ display:none; }

  /* ---------- o que fica por cima da foto ---------- */

  /* A moldura é a peça fotografada; o texto vive atrás dela, dentro da
     janela recortada, e por isso vira um segundo visor em vez de uma
     etiqueta impressa. */
  /* O LCD ocupa exatamente a janela recortada da moldura, e não o rebaixo
     inteiro. Preenchendo o rebaixo, o escuro vazava por fora dos cantos
     arredondados da peça e virava um contorno preto em volta dela. */
  .placa-nome{
    position:absolute;
    left:var(--nome-x); top:var(--nome-y);
    width:var(--nome-w); height:var(--nome-h);
    z-index:3;                       /* a moldura vem por cima do texto */
    pointer-events:none;
  }
  .placa-nome img{ width:100%; height:100%; display:block; }

  /* O LCD ocupa a janela recortada da moldura, e não o rebaixo inteiro:
     preenchendo o rebaixo, o escuro vazava por fora dos cantos
     arredondados da peça e virava um contorno preto em volta dela. */
  #emissora{
    position:absolute;
    left:calc(var(--nome-x) + var(--nome-w) * var(--nome-jx));
    top:calc(var(--nome-y) + var(--nome-h) * var(--nome-jy));
    width:calc(var(--nome-w) * var(--nome-jw));
    height:calc(var(--nome-h) * var(--nome-jh));
    z-index:2;
    display:flex; align-items:center; justify-content:center;
    background:linear-gradient(180deg, var(--visor-a), var(--visor-b));
    font-family:var(--mono);
    font-size:1.95cqw;
    font-weight:bold;
    letter-spacing:.14em;
    text-transform:uppercase;
    color:var(--tinta);
    text-shadow:0 0 1.4cqw rgba(124,230,244,.5);
    white-space:nowrap; overflow:hidden;
  }

  .comando{
    position:absolute;
    z-index:2;
    border:none;
    background:none;
    padding:0;
    cursor:pointer;
    display:flex;
    align-items:center;
    justify-content:center;
    color:#2e343a;
  }
  /* A classe acompanha o :active. No programa, quem recebe o mouse é
     uma camada por cima, e a página só vê eventos fabricados — com eles
     o :active nunca acontece, e o botão não afundaria ao ser apertado. */
  .comando:active,
  .comando.apertado{ transform:translateY(.15cqw) scale(.97); }

  /* encaixes medidos na foto */
  /* Cada tampa é um pouco menor que o furo: a folga deixa a borda do
     rebaixo aparecer em volta, e é ela que faz a peça parecer encaixada
     em vez de colada por cima. */
  /* A tampa transborda o furo de propósito: ela precisa cobrir o anel de
     sombra que representa a profundidade, senão o botão parece afundado
     e pequeno dentro do próprio encaixe. */
  #liga{
    left:var(--liga-x);  top:calc(var(--liga-y) + var(--botoes-desce));
    width:var(--liga-w); height:var(--liga-h);
    border-radius:50%;
    background-repeat:no-repeat;
    background-position:center;
    background-size:var(--tampa-grande) auto;
  }
  #youtube{
    left:var(--yt-x);  top:calc(var(--yt-y) + var(--botoes-desce));
    width:var(--yt-w); height:var(--yt-h);
    border-radius:50%;
    text-decoration:none;
    background-repeat:no-repeat;
    background-position:center;
    background-size:var(--tampa-pequena) auto;
  }
  #abrir{
    left:var(--abrir-x);  top:calc(var(--abrir-y) + var(--botoes-desce));
    width:var(--abrir-w); height:var(--abrir-h);
    border-radius:50%;
    background-repeat:no-repeat;
    background-position:center;
    background-size:var(--tampa-pequena) auto;
  }
  /* tampa analógica: nada de mudar de tamanho ao clicar */
  .comando:active,
  .comando.apertado{ transform:none; }

  /* O símbolo era um caractere de texto: fino, e com a métrica da fonte
     empurrando o triângulo para fora do centro. Em SVG ele é uma forma
     cheia, centrada pela caixa de desenho e não pela linha de base. */
  #liga .glifo{
    width:var(--icone-grande); height:var(--icone-grande);
    display:block;
    fill:currentColor;
    stroke:none;
    filter:drop-shadow(0 1px 0 rgba(255,255,255,.4));
  }
  #liga .pausa{ display:none; }
  #radio.no-ar #liga .triangulo{ display:none; }
  #radio.no-ar #liga .pausa{ display:block; }

  /* As tampas são analógicas: não mudam de tamanho quando pressionadas.
     O que acende é uma lâmpada atrás do símbolo. Três camadas de difusão
     sobrepostas, fechada, média e larga, porque é a queda gradual que
     lê como filamento; um halo de raio único lê como brilho de CSS.
     A oscilação é assimétrica pelo mesmo motivo. */
  @keyframes brasa{
    0%, 100%{ opacity:.86; }
    37%     { opacity:1; }
    61%     { opacity:.92; }
  }

  .acesa{ animation:brasa 4.2s ease-in-out infinite; }

  #radio.no-ar #liga .glifo{
    fill:#ff6a4d;
    filter:
      drop-shadow(0 0 .5cqw rgba(255,120,80,.95))
      drop-shadow(0 0 1.5cqw rgba(255,80,40,.6))
      drop-shadow(0 0 3.2cqw rgba(255,60,20,.28));
    animation:brasa 4.2s ease-in-out infinite;
  }

  /* O botão da gaveta tem estado, então acende enquanto ela está fora. */
  #radio.aberto #abrir svg{
    stroke:#7ce6f4;
    filter:
      drop-shadow(0 0 .4cqw rgba(124,230,244,.95))
      drop-shadow(0 0 1.2cqw rgba(124,230,244,.55))
      drop-shadow(0 0 2.6cqw rgba(80,200,230,.25));
    animation:brasa 5.1s ease-in-out infinite;
  }

  /* O do YouTube é momentâneo: pisca no toque e apaga. */
  #youtube:active svg,
  #youtube.apertado svg{
    stroke:#8ef0a8;
    filter:
      drop-shadow(0 0 .4cqw rgba(140,240,170,.95))
      drop-shadow(0 0 1.4cqw rgba(120,230,150,.5));
  }

  #youtube svg, #abrir svg{
    width:var(--icone-pequeno); height:var(--icone-pequeno);
    fill:none; stroke:currentColor;
    stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round;
  }
  #abrir svg{ transition:transform .28s; }
  #radio.aberto #abrir svg{ transform:rotate(180deg); }

  /* a corrediça do volume, assentada dentro da ranhura da foto */
  .corredica{
    position:absolute;
    left:var(--vol-x);  top:var(--vol-y);
    width:var(--vol-w); height:var(--vol-h);
    z-index:2;
    display:flex;
    align-items:center;
    padding:0 2.2cqw;
    background-repeat:no-repeat;
    background-position:center;
    background-size:100% 100%;
  }
  /* O trilho já vem desenhado na peça, então o input não pinta nada: nem
     fundo, nem trilha, nem preenchimento. Um cursor analógico mostra o
     volume pela posição, e não por uma barra que muda de cor. */
  #volume{
    flex:1;
    min-width:0;
    -webkit-appearance:none; appearance:none;
    height:9.4cqw;
    outline:none;
    background:transparent;
    border:none;
    margin:0;
  }
  #volume::-webkit-slider-thumb{
    -webkit-appearance:none; appearance:none;
    width:3.8cqw; height:9.4cqw;
    background-repeat:no-repeat;
    background-position:center;
    background-size:contain;
    border:none;
    cursor:grab;
  }
  #volume:active::-webkit-slider-thumb{ cursor:grabbing; }
  #volume::-moz-range-thumb{
    width:3.8cqw; height:9.4cqw;
    background-repeat:no-repeat;
    background-position:center;
    background-size:contain;
    border:none;
    cursor:grab;
  }
  #volume::-webkit-slider-runnable-track{ background:none; border:none; height:9.4cqw; }
  #volume::-moz-range-track{ background:none; border:none; height:9.4cqw; }
  #volume::-moz-range-progress{ background:none; }

  /* ---------- a gaveta ---------- */

  /* Guardada atrás do corpo, enfiada sob ele. Descer a gaveta é a única
     coisa que muda o tamanho do conjunto, e o corpo em si nunca se mexe. */
  #gaveta{
    position:absolute;
    left:var(--gaveta-lado); right:var(--gaveta-lado);
    bottom:var(--gaveta-base);
    z-index:0;
    container-type:inline-size;
    transform:translateY(0);
    transition:transform .5s cubic-bezier(.2,1.12,.3,1);
  }
  /* Recolhida, a gaveta está escondida atrás do corpo — mas a sombra dela
     não estava: deslocada 10px e desfocada em 18px, ela vazava uns 22px
     abaixo da base do corpo, e a parte densa dessa sombra aparecia como
     uma linha escura. Peça escondida não projeta sombra. */
  #gaveta .chassi{ filter:none; }
  #radio.aberto #gaveta .chassi{ filter:drop-shadow(0 10px 18px rgba(0,0,0,.45)); }
  #radio.aberto #gaveta{ transform:translateY(var(--saida, 0px)); }

  .tela{
    position:absolute;
    left:calc(var(--tela-x) - var(--sangria));
    top:calc(var(--tela-y) - var(--sangria));
    width:calc(var(--tela-w) + var(--sangria) * 2);
    height:calc(var(--tela-h) + var(--sangria) * 2);
    z-index:0;                       /* atrás do recorte da foto da gaveta */
    overflow:hidden;
    background:#0c1013;
  }
  .tela > *{
    position:absolute; inset:0;
    width:100%; height:100%;
    opacity:0;
    transition:opacity .3s;
    pointer-events:none;
  }
  .tela > .ativa{ opacity:1; }
  #capa{ object-fit:cover; }

  /* A espera pelo fim do vídeo. Em vez da miniatura, que ali não explica
     nada, a imagem da estação com a contagem do que falta — assim a troca
     tem um motivo visível em vez de parecer defeito. */
  #espera{
    background:center/cover no-repeat;
    display:flex;
    align-items:center;
    justify-content:center;
  }
  #espera::before{
    content:"";
    position:absolute;
    inset:0;
    background:radial-gradient(ellipse at center,
      rgba(4,16,20,.72) 0%, rgba(4,16,20,.86) 70%, rgba(4,16,20,.94) 100%);
  }
  /* A legenda é mais larga que o número e, sendo bloco, é ela que define a
     largura do conjunto — sem isto o número encostava à esquerda dela. */
  /* No primeiro segundo a imagem entra sozinha: a contagem só acende
     quando o número dela é redondo. */
  #conta{
    position:relative;
    opacity:0;
    transition:opacity .22s ease;
    text-align:center;
    font-family:var(--mono);
    font-size:11cqw;
    line-height:1;
    color:var(--tinta);
    text-shadow:0 0 2.4cqw rgba(124,230,244,.5);
    font-variant-numeric:tabular-nums;
  }
  #conta.visivel{ opacity:1; }
  #conta small{
    display:block;
    font-size:.22em;
    letter-spacing:.22em;
    /* o espaçamento sobra depois da última letra e não antes da primeira:
       sem compensar, a legenda fica meio caractere à esquerda do centro */
    text-indent:.22em;
    text-transform:uppercase;
    color:var(--tinta-fraca);
    margin-top:.5em;
    text-shadow:none;
  }
  /* O YouTube ancora título, compartilhar e logo nas bordas do iframe. Em
     vez de mascarar, o iframe é feito três vezes mais alto que a janela:
     o vídeo, sendo 16:9, se ajusta pela largura e fica centrado, ocupando
     exatamente o terço do meio. Os enfeites caem nos terços de cima e de
     baixo, fora do recorte da gaveta. O vídeo aparece inteiro, sem corte. */
  #video{ overflow:hidden; }
  #video iframe{
    position:absolute;
    left:0;
    top:calc((100% - var(--video-altura)) / 2);
    width:100%;
    height:var(--video-altura);
    border:0;
  }

  /* O espaço extra fica no #radio, não no .conjunto: a gaveta é ancorada
     pela base do .conjunto, e se ele crescesse ela desceria duas vezes. */
  #radio{
    padding-bottom:0;
    transition:padding-bottom .5s cubic-bezier(.2,1.12,.3,1), opacity .45s ease;
  }
  #radio.aberto{ padding-bottom:var(--saida, 0px); }

  /* O vidro na frente dos visores. Fica acima da foto, então o reflexo
     passa por cima do texto, que é o que vende a lâmina de vidro. Duas
     camadas só: um brilho diagonal fraco e um escurecimento nas bordas,
     que sugere a espessura. Passar disso vira plástico brilhante. */
  .vidro{
    position:absolute;
    z-index:4;
    pointer-events:none;
    background:
      /* a faixa de reflexo, com aresta definida: é a borda dura que
         convence, não a quantidade de branco. Degradê sozinho o olho lê
         como iluminação, não como uma lâmina refletindo alguma coisa. */
      linear-gradient(104deg,
        rgba(255,255,255,var(--vidro-brilho)) 0%,
        rgba(255,255,255,calc(var(--vidro-brilho) * .88)) 15%,
        rgba(255,255,255,calc(var(--vidro-brilho) * .32)) 15.6%,
        rgba(255,255,255,calc(var(--vidro-brilho) * .21)) 31%,
        rgba(255,255,255,0)  31.5%,
        rgba(255,255,255,0)  88%,
        rgba(255,255,255,calc(var(--vidro-brilho) * .26)) 100%),
      /* o brilho da própria aresta superior do vidro */
      linear-gradient(180deg,
        rgba(255,255,255,.14) 0,
        rgba(255,255,255,.02) 3.5%,
        rgba(255,255,255,0)   9%);
    box-shadow:
      inset 0 0 2.2cqw rgba(0,0,0,.42),
      inset 0 .3cqw .35cqw rgba(0,0,0,.5),
      inset 0 -.15cqw .2cqw rgba(255,255,255,.06);
  }
  .vidro.no-visor{
    left:var(--visor-x);  top:var(--visor-y);
    width:var(--visor-w); height:var(--visor-h);
  }
  .vidro.no-nome{
    left:calc(var(--nome-x) + var(--nome-w) * var(--nome-jx));
    top:calc(var(--nome-y) + var(--nome-h) * var(--nome-jy));
    width:calc(var(--nome-w) * var(--nome-jw));
    height:calc(var(--nome-h) * var(--nome-jh));
  }
  .vidro.na-gaveta{
    left:var(--tela-x);  top:var(--tela-y);
    width:var(--tela-w); height:var(--tela-h);
  }

  /* As peças que entram por background só ganham endereço quando a classe
     chega. Sem isto o navegador as buscava ao renderizar o elemento —
     opacity:0 não impede download — e elas disputavam banda com o fundo
     desde o primeiro instante, muito antes do JS pedir. */
  body.com-pecas #liga{ background-image:url("imagens/botao-grande.png"); }
  body.com-pecas #youtube,
  body.com-pecas #abrir{ background-image:url("imagens/botao-pequeno.png"); }
  body.com-pecas .corredica{ background-image:url("imagens/trilho.png"); }
  body.com-pecas #volume::-webkit-slider-thumb{ background-image:url("imagens/cursor.png"); }
  body.com-pecas #volume::-moz-range-thumb{ background-image:url("imagens/cursor.png"); }

  /* O botão de modo, na aba da gaveta. Ele cicla entre capa e vídeo, e o
     estado é dito por um ponto aceso no meio da tampa: forte para vídeo,
     fraco para capa. Mesma tinta do visor nos dois, porque uma terceira
     cor no aparelho começaria a virar árvore de Natal. */
  #modo{
    position:absolute;
    left:var(--modo-x);  top:var(--modo-y);
    width:var(--modo-w); height:var(--modo-h);
    z-index:2;
    border:none;
    padding:0;
    border-radius:50%;
    cursor:pointer;
    background:center/var(--tampa-modo) auto no-repeat;
    display:flex;
    align-items:center;
    justify-content:center;
  }
  body.com-pecas #modo{ background-image:url("imagens/botao-gaveta.png"); }

  #modo .ponto{
    width:34%; height:34%;
    border-radius:50%;
    background:var(--tinta);
    opacity:.34;
    box-shadow:0 0 .5cqw rgba(124,230,244,.45);
    transition:opacity .25s, box-shadow .25s;
  }
  #radio.no-video #modo .ponto{
    opacity:1;
    box-shadow:
      0 0 .5cqw rgba(124,230,244,.95),
      0 0 1.4cqw rgba(124,230,244,.55),
      0 0 3cqw rgba(80,200,230,.25);
    animation:brasa 5.1s ease-in-out infinite;
  }

  /* ===== modo aplicativo (?app=1) =====
     Sem fundo, sem vinheta, sem centralização vertical: a janela é do
     tamanho do aparelho, e tudo o que não é aparelho é área de trabalho. */
  /* A sombra do aparelho se espalha uns 48px; com folga menor que isso a
     borda da janela a corta em linha reta e o efeito denuncia o truque. */
  /* Sem isto aparece barra de rolagem, e ela rouba uns 15px da largura
     útil. Como o aparelho é centralizado, ele desliza para a esquerda —
     e aí as coordenadas que o programa repassa deixam de bater com o que
     está na tela, fazendo os alvos pequenos errarem. */
  html.app, body.app{ height:auto; min-height:0; overflow:hidden; }
  body.app{
    background:transparent;
    padding:var(--app-folga-topo) var(--app-folga) var(--app-folga);
    align-items:flex-start;
  }
  body.app #fundo{ display:none; }
  body.app #radio{ width:var(--app-largura); max-width:none; flex:0 0 auto; }

  /* As duas tampas pequenas sobem um pixel no programa. O ajuste vive
     aqui, e não nas variáveis de geometria, porque aquelas vêm da
     medição das peças e valem para os dois — este é correção no olho,
     e só do lado do programa. */
  body.app #youtube{
    top:calc(var(--yt-y) + var(--botoes-desce) - var(--app-sobe-pequenos));
  }
  body.app #abrir{
    top:calc(var(--abrir-y) + var(--botoes-desce) - var(--app-sobe-pequenos));
  }

  /* Sombra mais curta no programa: a do site se espalha quase 50px e era
     cortada pela borda da janela. Aumentar a folga resolveria, mas o anel
     transparente em volta rouba cliques da área de trabalho — encurtar a
     sombra custa menos, e sobre papel de parede ela pesa menos mesmo. */
  /* Sombra sutil, só para dar profundidade. A anterior desfocava o dobro
     do que descia, e sombra que se espalha mais do que desce lê como
     sujeira em volta da peça, não como altura. Aqui o desfoque é menor
     que o deslocamento, e a opacidade caiu quase à metade. */
  body.app .aparelho .chassi{ filter:drop-shadow(0 7px 6px rgba(0,0,0,.32)); }
  body.app #gaveta .chassi{ filter:none; }
  body.app #radio.aberto #gaveta .chassi{
    filter:drop-shadow(0 5px 5px rgba(0,0,0,.28));
  }

  /* O cursor diz onde dá para agarrar: mão aberta sobre a borracha e o
     metal, seta sobre as telas, dedo sobre os comandos. Sem isso a área
     de arrasto é invisível e a pessoa fica tentando. */
  body.app .conjunto{ cursor:grab; }
  body.app .conjunto:active{ cursor:grabbing; }
  body.app .visor,
  body.app .tela,
  body.app #espera,
  body.app #video,
  body.app #capa{ cursor:default; }
  body.app .comando,
  body.app #modo,
  body.app #janela button{ cursor:pointer; }
  body.app #volume{ cursor:grab; }
  body.app #volume:active{ cursor:grabbing; }

  #janela{ display:none; }
  body.app #janela{
    display:flex;
    justify-content:flex-end;
    gap:7px;
    margin:0 0 7px;
  }
  #janela button{
    width:20px; height:20px;
    padding:0;
    border:none;
    border-radius:50%;
    cursor:pointer;
    font:bold 12px/1 var(--sans);
    color:#cdd6dd;
    background:rgba(28,34,40,.78);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.14), 0 1px 3px rgba(0,0,0,.5);
    transition:background .18s, color .18s;
  }
  #janela button:hover{ background:rgba(52,62,70,.95); color:#fff; }
  #fechar:hover{ background:#c0392b; }

  /* a barra é o que se agarra para arrastar; o aparelho não se move ao
     ser clicado, senão apertar um botão viraria arrastar sem querer */
  body.app #janela{ -webkit-user-select:none; user-select:none; }

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

  @media (prefers-reduced-motion: reduce){
    #radio.no-ar #led{ animation:none; }
    #radio.no-ar #liga .glifo{ animation:none; }
    .rolagem.rolando #tocando{ animation:none; }
    #conta{ transition:none; }
    .aparelho.empurra, .aparelho.recolhe{ animation:none; }
    #radio.no-video #modo .ponto{ animation:none; }
    #gaveta, .conjunto, .tela > *, #abrir svg, .comando{ transition:none; }
    .sombra-corpo{ transition:none; }
    #fundo, #radio, #carregando{ transition:none; }
    #carregando .anel{ animation:none; border-top-color:rgba(124,230,244,.5); }
  }
