/* @slice 8/9 · lab-campaign.css · linhas 1014–1334 do antigo lab.css
   @slice
   @slice 🛑 A ORDEM DOS NOVE É OBRIGATÓRIA, e o index.html a define.
   @slice    tokens · stage · hud · nav · panel · versions · layers · campaign · overrides
   @slice
   @slice Duas regras deste conjunto vencem por ORDEM e não carregam `!important`
   @slice para avisar: `.desktop-overlay{top}` contra o `inset:0` do desktop.css da
   @slice 2026.5, e `.sc-wx-trip` contra o `.sc-wx` do site-chrome.css. As duas moram
   @slice em lab-overrides.css, que por isso é sempre o ÚLTIMO.
   @slice
   @slice O corte é reversível: `./scripts/split-lab-css.sh --verify` remonta os nove
   @slice e compara com o lab.css de origem, ignorando estas linhas. */

/* E o banner desce a altura do notch quando há música tocando, senão os dois
   ocupariam a mesma faixa. 40px = altura do notch (26px) mais o respiro. O
   `:has` é o que torna isto automático: sem música o dock fica `hidden` e o
   banner volta para cima sozinho. */
:root { --np-stack: 0px; }
body:has(.np-dock:not([hidden])) { --np-stack: 40px; }

.banner-dock {
  position: fixed;
  right: 20px;
  /* Abaixo do chrome, medido — a altura dele muda entre desktop e telefone.
     `trip.js` escreve a variável; o 88px é o valor de desktop, como reserva. */
  top: calc(var(--lab-chrome-bottom, 88px) + 16px + var(--np-stack, 0px));
  transform: translateY(-10px);
  z-index: 38;
  display: flex;
  align-items: center;
  gap: 14px;
  width: min(420px, calc(100vw - 32px));
  padding: 12px 14px;
  border-radius: 16px;
  border: 1px solid rgba(100, 240, 208, .22);
  background: rgba(11, 16, 32, .94);
  backdrop-filter: blur(16px);
  box-shadow: 0 18px 44px rgba(0, 0, 0, .5);
  opacity: 0;
  pointer-events: none;
  transition: opacity .24s ease-out, transform .3s cubic-bezier(.2, .9, .3, 1);
  overflow: hidden;
}

.banner-dock.open { opacity: 1; transform: translateY(0); pointer-events: auto; }
.banner-dock[hidden] { display: none; }

/* Barra de tempo restante, colada no topo do cartão. `scaleX` a partir da
   esquerda: animar `width` num elemento de 2 px borra a borda. */
.bn-bar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: rgba(100, 240, 208, .12);
}

.bn-bar b {
  display: block;
  height: 100%;
  transform-origin: left center;
  transform: scaleX(0);
  background: linear-gradient(90deg, #64f0d0, #2a5cff);
}

.bn-art {
  width: 54px;
  height: 54px;
  flex: none;
  border-radius: 10px;
  object-fit: cover;
  /* A arte é escura nas duas campanhas; a moldura evita que ela se dissolva no
     fundo do cartão. */
  border: 1px solid rgba(150, 170, 220, .16);
}

.bn-text { flex: 1; min-width: 0; }

.bn-tag {
  display: block;
  font-size: 9.5px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: #64f0d0;
  opacity: .85;
}

.bn-title {
  margin: 3px 0 0;
  font-size: 14px;
  line-height: 1.35;
  color: #e6ecfb;
  /* Duas linhas no máximo: o título é a isca, não o texto. O resto está no
     painel que a baliza abre. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.bn-title b { color: #8ff2dd; font-weight: 600; }

.bn-actions { display: flex; align-items: center; gap: 6px; flex: none; }

.bn-go {
  min-height: 34px;
  padding: 0 14px;
  border-radius: 999px;
  border: 1px solid rgba(100, 240, 208, .4);
  background: rgba(100, 240, 208, .14);
  color: #8ff2dd;
  font: inherit;
  font-size: 12.5px;
  letter-spacing: .04em;
  cursor: pointer;
  white-space: nowrap;
  transition: background .15s;
}

.bn-go:hover { background: rgba(100, 240, 208, .26); }

.bn-close {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  border: 1px solid transparent;
  background: transparent;
  color: #8e9ab8;
  font-size: 13px;
  cursor: pointer;
}

.bn-close:hover { color: #e6ecfb; border-color: rgba(150, 170, 220, .22); }

.bn-dots {
  position: absolute;
  left: 50%;
  bottom: 4px;
  transform: translateX(-50%);
  display: flex;
  gap: 5px;
}

.bn-dots[hidden] { display: none; }

/* A bolinha DESENHADA tem 5 px; a clicável tem 22×18. O `padding` com
   `background-clip: content-box` separa as duas: a área de acerto cresce sem
   engordar o ponto. Com 5 px de alvo o clique erra mais do que acerta — e a
   bolinha é justamente como se pula para a outra campanha. */
.bn-dot {
  width: 5px;
  height: 5px;
  padding: 7px 8px;
  border: none;
  border-radius: 999px;
  background: rgba(150, 170, 220, .3);
  background-clip: content-box;
  cursor: pointer;
  transition: width .2s, background .2s;
}

.bn-dot:hover { background: rgba(150, 170, 220, .6); background-clip: content-box; }
.bn-dot.is-on { width: 14px; background: #64f0d0; background-clip: content-box; }

/* O `.bn-dots` fica sobre o cartão; sem `pointer-events` explícito ele herdaria
   o `none` do dock fechado e a bolinha só responderia depois do primeiro hover. */
.bn-dots { pointer-events: auto; }

@media (max-width: 560px) {
  /* No telefone a arte sai: 54 px dela custam metade do espaço do título, e o
     título é o que decide se a pessoa toca. */
  .bn-art { display: none; }
  /* No telefone não há canto sobrando: a planta ocupa quase tudo. O cartão vira
     uma faixa da largura da tela, ainda no alto — embaixo ele brigaria com o HUD
     e com a barra de gestos do aparelho. */
  .banner-dock {
    gap: 10px;
    padding: 11px 12px;
    right: 12px;
    left: 12px;
    width: auto;
  }
  .bn-go { padding: 0 12px; font-size: 12px; }
}

@media (pointer: coarse) {
  .bn-go { min-height: 44px; }
  .bn-close { width: 44px; height: 44px; }
  /* No dedo o alvo cresce mais ainda: 44 px de altura total. */
  .bn-dot { padding: 19px 8px; }
  .bn-dots { bottom: -8px; }
}

@media (prefers-reduced-motion: reduce) {
  .banner-dock { transition: opacity .14s linear; transform: none; }
  .banner-dock.open { transform: none; }
  .bn-dot { transition: none; }
}

/* ── painel de campanha ────────────────────────────────────────────────────
   Mesmo painel dos cômodos, com o conteúdo do anúncio. O `is-campaign` só muda
   o corpo: posição, animação e fecho são os mesmos, e é isso que faz os dois
   lerem como a mesma coisa. */

.room-panel.is-campaign .rp-order {
  color: #64f0d0;
  font-size: 10px;
  letter-spacing: .18em;
  text-transform: uppercase;
}

/* A arte da campanha, INTEIRA.
   `cover` decepava o robô — a arte é um render com o corpo todo, e recortá-la
   pela altura deixava tronco e braços, sem cabeça nem pés. `contain` mostra o
   que o designer desenhou; o halo atrás preenche o que sobra, em vez de deixar
   uma faixa vazia.

   Altura fluida em `vh`: fixa em 190 px ela ocupava metade de um painel curto e
   um quinto de um alto. */
.cp-art-wrap {
  position: relative;
  display: grid;
  place-items: center;
  /* Mais alto do que parecia necessário, e por medida: a arte é QUADRADA
     (520×520). Numa caixa larga e baixa, `contain` a encolhe até a altura — o
     robô virava uma miniatura no meio de dois vazios laterais. Dando altura, ele
     cresce até preencher, que é o que faz a peça parecer produto em exibição. */
  height: clamp(220px, 34vh, 380px);
  margin-bottom: 18px;
  border-radius: 14px;
  border: 1px solid rgba(150, 170, 220, .14);
  overflow: hidden;
  /* Halo radial atrás do produto, como na faixa da 2026.5 — dá profundidade e
     ancora a figura no centro. */
  background:
    radial-gradient(120% 90% at 50% 42%, rgba(100, 240, 208, .1), transparent 62%),
    radial-gradient(90% 70% at 50% 100%, rgba(42, 92, 255, .16), transparent 70%),
    rgba(7, 11, 24, .6);
}

/* Anéis concêntricos, discretos, girando devagar. É o que separa "imagem numa
   caixa" de "produto em exibição" — e é barato: um pseudo-elemento, sem asset. */
.cp-art-wrap::before {
  content: '';
  position: absolute;
  width: 78%;
  aspect-ratio: 1;
  border-radius: 50%;
  border: 1px solid rgba(100, 240, 208, .12);
  box-shadow: 0 0 0 22px rgba(100, 240, 208, .04);
  animation: cp-spin 22s linear infinite;
}

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

.cp-art {
  /* ⚠️ `position: absolute` com `inset`, e NÃO altura percentual.
     Medido duas vezes na tela: `max-height: 88%` deixou a imagem com 458 px num
     contêiner de 185, e `height: 100%` a deixou com 635 px. Porcentagem de
     altura não resolve num item de grid centrado por `place-items` — o navegador
     cai para `auto` e a imagem estoura, sendo recortada pelo `overflow`.
     `inset` define os quatro lados e não depende dessa resolução. */
  position: absolute;
  top: 3%;
  left: 12%;
  /* Largura e altura EXPLÍCITAS, não `auto`. Imagem é elemento substituído: com
     `width/height: auto` ela usa o tamanho intrínseco e ignora o `inset`, que
     foi o que sobrou da tentativa anterior — 520 px dentro de um contêiner de
     216. Fixadas em porcentagem sobre um pai absolutamente posicionado, elas
     resolvem, e o `object-fit` cuida da proporção. */
  width: 76%;
  height: 92%;
  object-fit: contain;
  /* Enquadramento ACIMA do centro: a arte tem o robô cercado de espaço vazio, e
     centrado ele afunda no cartão. Puxar para 28% o traz para a altura em que o
     olho o encontra primeiro, e deixa a sobra embaixo, onde o halo já preenche. */
  object-position: 50% 28%;
  /* Flutuação lenta: o robô da campanha aparece no ar, e parado ele lê como
     recorte colado. */
  animation: cp-float 5.5s ease-in-out infinite;
  filter: drop-shadow(0 18px 26px rgba(0, 0, 0, .45));
}

@keyframes cp-float {
  0%, 100% { transform: translateY(-4px); }
  50%      { transform: translateY(6px); }
}

@media (prefers-reduced-motion: reduce) {
  .cp-art, .cp-art-wrap::before { animation: none; }
}

.cp-sub {
  margin: 0 0 16px;
  font-size: 14px;
  line-height: 1.6;
  color: #b9c6e4;
}

.cp-chips { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 20px; }

.cp-chip {
  padding: 5px 11px;
  border-radius: 999px;
  border: 1px solid rgba(150, 170, 220, .2);
  background: rgba(150, 170, 220, .06);
  color: #9fb0d4;
  font-family: var(--font-mono);
  font-size: 11px;
}

.cp-go {
  display: inline-flex;
  align-items: center;
  min-height: 42px;
  padding: 0 20px;
  border-radius: 999px;
  border: 1px solid rgba(100, 240, 208, .4);
  background: rgba(100, 240, 208, .14);
  color: #8ff2dd;
  font-size: 13px;
  letter-spacing: .04em;
  text-decoration: none;
  transition: background .15s;
}

.cp-go:hover { background: rgba(100, 240, 208, .26); }

@media (pointer: coarse) { .cp-go { min-height: 48px; } }

