/* ═══════════════════════════════════════════════════════════════════════════
   BoomPass — sistema visual
   Grafite #0F1115 · carta #1B1D22 · verde #36f29d · Inter

   Duas superfícies com regras diferentes:
     · Painel  — segue a escolha do usuário (claro/escuro).
     · Público — SEMPRE escuro. É a vitrine da marca, e a consistência
       importa mais do que a preferência do sistema de quem visita.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Escuro é o padrão e a identidade. */
  --bg:            hsl(222 17% 8%);
  --bg-fundo:      hsl(222 18% 6%);    /* atrás dos cartões */
  --fg:            hsl(0 0% 96%);
  --fg-forte:      hsl(0 0% 100%);
  --card:          hsl(222 11% 12%);
  --card-alto:     hsl(222 11% 15%);   /* card sobre card */
  --border:        hsl(222 10% 18%);
  --border-forte:  hsl(222 10% 26%);

  /* UM verde só — decisão do dono, 30/09/2026: "o verde do texto sem
     complicação tem que ser o padrão para todos os verdes". #36f29d é o da
     capa da home, e é ele que pinta todo botão, selo e destaque.
     `--primary-texto` é o mesmo verde quando ele é LETRA: no escuro é igual;
     no claro ele escurece (ver o bloco claro abaixo), porque #36f29d sobre
     branco dá 1,46:1 e preço e total viram ilegíveis. */
  --primary:       #36f29d;
  --primary-suave: rgb(54 242 157 / .14);
  --primary-fg:    #06130d;
  --primary-texto: #36f29d;
  --secondary:     hsl(222 10% 17%);
  --muted:         hsl(222 10% 17%);
  --muted-fg:      hsl(222 7% 58%);
  --destructive:   hsl(0 75% 58%);
  --warning:       hsl(43 96% 56%);
  --info:          hsl(210 90% 62%);
  --ring:          #36f29d;

  /* Fundo de botão verde sob o mouse: o mesmo verde, um pouco mais fundo.
     Escurecer com filter: brightness() quase não muda um verde tão claro. */
  --primary-hover: color-mix(in srgb, var(--primary) 88%, #000);

  /* Elevação em camadas: sombra difusa + contato curto. Uma sombra só,
     chapada, é o que faz interface parecer amadora. */
  --sombra-1: 0 1px 2px hsl(0 0% 0% / .28);
  --sombra-2: 0 2px 4px hsl(0 0% 0% / .22), 0 8px 20px hsl(0 0% 0% / .28);
  --sombra-3: 0 4px 8px hsl(0 0% 0% / .24), 0 18px 44px hsl(0 0% 0% / .40);
  --brilho:   0 0 0 1px rgb(54 242 157 / .35), 0 8px 28px rgb(54 242 157 / .18);

  --radius:    .5rem;
  --radius-lg: .75rem;
  --radius-xl: 1.125rem;

  --sidebar-w: 15rem;
  --header-h:  4rem;

  --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --mono: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;

  color-scheme: dark;
}

/* Claro é o padrão da plataforma — por isso o :not. Ele vale no instante em
   que o <html> ainda não tem data-tema, antes de iniciarTema() rodar: sem ele
   o painel pintava um quadro escuro e só então clareava. A CSP proíbe script
   inline, então decidir o tema antes da primeira pintura só dá por CSS.
   As páginas públicas e o login declaram data-tema no próprio HTML, então esta
   regra não as alcança — o escuro do login continua escuro. */
:root[data-tema="claro"], :root:not([data-tema]) {
  --bg:            hsl(0 0% 100%);
  --bg-fundo:      hsl(220 20% 97%);
  --fg:            hsl(222 22% 11%);
  --fg-forte:      hsl(222 30% 6%);
  --card:          hsl(0 0% 100%);
  --card-alto:     hsl(220 20% 98%);
  --border:        hsl(220 14% 90%);
  --border-forte:  hsl(220 13% 80%);

  /* O mesmo #36f29d do escuro em toda superfície — botão Comprar incluído —,
     com texto quase preto por cima (12,96:1). E também como LETRA: até
     30/09/2026 o texto verde era escurecido (#087d48) para passar dos 4,5:1
     sobre branco, e o dono pediu duas vezes o verde do projeto em tudo — "o
     preço está em um verde diferente do verde padrão". A troca é consciente:
     #36f29d sobre branco dá 1,46:1, então verde como letra fica para número
     grande e negrito (preço, total), nunca para texto corrido. */
  --primary:       #36f29d;
  --primary-suave: rgb(54 242 157 / .18);
  --primary-fg:    #06130d;
  --primary-texto: #36f29d;
  --secondary:     hsl(220 16% 95%);
  --muted:         hsl(220 16% 95%);
  --muted-fg:      hsl(220 9% 44%);
  --destructive:   hsl(0 72% 47%);
  --warning:       hsl(38 92% 42%);
  --info:          hsl(214 84% 46%);
  --ring:          #36f29d;

  --sombra-1: 0 1px 2px hsl(220 20% 20% / .07);
  --sombra-2: 0 1px 3px hsl(220 20% 20% / .08), 0 6px 16px hsl(220 20% 20% / .07);
  --sombra-3: 0 2px 6px hsl(220 20% 20% / .09), 0 16px 40px hsl(220 20% 20% / .12);
  --brilho:   0 0 0 1px rgb(54 242 157 / .45), 0 8px 24px rgb(54 242 157 / .22);

  color-scheme: light;
}

*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0;
  background: var(--bg-fundo);
  color: var(--fg);
  font-family: var(--font);
  font-size: 18px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: inherit; text-decoration: none; }
img { max-width: 100%; }

h1, h2, h3 { margin: 0; color: var(--fg-forte); }
h1 { font-size: 1.75rem; font-weight: 700; letter-spacing: -.025em; line-height: 1.2; }
h2 { font-size: 1.1875rem; font-weight: 650; letter-spacing: -.015em; }
h3 { font-size: 1rem; font-weight: 650; }

::selection { background: var(--primary); color: var(--primary-fg); }

:where(a, button, input, select, textarea):focus-visible {
  outline: 2px solid var(--ring); outline-offset: 2px; border-radius: var(--radius);
}

/* O "R$" de todo valor — o <span> é posto por /assets/moeda.js. Metade do
   tamanho do número e com o topo na altura do topo dele: o número é o que se
   lê, o símbolo só diz a moeda (pedido do dono, 30/09/2026). `vertical-align`
   em em é medido na fonte do PRÓPRIO span (a metade): .7em dele sobem o
   símbolo até a altura das maiúsculas do número. `line-height: 0` impede que
   o símbolo erguido estique a linha.
   O seletor é forte de propósito (`html body span`): regras de tela como
   `.total span` foram escritas para o rótulo ao lado e pegariam o símbolo
   também — foi assim que o "R$" do total saiu cinza. Cor e peso são sempre
   os do número. */
/* TESTE de 01/10/2026 (pedido do dono): invertido — o "R$" no tamanho do
   número e os CENTAVOS (",00", <span class="centavos">) com a metade do
   tamanho, no alto. Para voltar ao desenho de 30/09: `.moeda` com
   `font-size: .5em; vertical-align: .7em; line-height: 0` e `.centavos`
   sem regra nenhuma. */
html body span.moeda {
  display: inline; margin: 0; padding: 0;
  font-size: 1em; vertical-align: baseline; letter-spacing: 0;
  color: inherit; font-weight: inherit; text-transform: none;
}
/* O espaço entre "R$" e o número fica no texto, mas não aparece (moeda.js). */
html body span.moeda__espaco { display: none; }
html body span.centavos {
  display: inline; margin: 0; padding: 0;
  font-size: .5em; vertical-align: .7em; line-height: 0; letter-spacing: 0;
  color: inherit; font-weight: inherit; text-transform: none;
}

/* ── Botões ──────────────────────────────────────────────────────────────── */

.bp-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  height: 2.375rem; padding: 0 1rem;
  border: 1px solid transparent; border-radius: var(--radius);
  font: inherit; font-weight: 600; font-size: .8125rem; letter-spacing: -.005em;
  cursor: pointer; white-space: nowrap; user-select: none;
  transition: background .15s, border-color .15s, box-shadow .15s, transform .08s, opacity .15s;
}
.bp-btn:active:not(:disabled) { transform: translateY(1px); }
.bp-btn:disabled { opacity: .45; cursor: not-allowed; }
.bp-btn svg { flex-shrink: 0; }

.bp-btn--primary {
  background: var(--primary); color: var(--primary-fg);
  box-shadow: var(--sombra-1);
}
.bp-btn--primary:hover:not(:disabled) { background: var(--primary-hover); box-shadow: var(--brilho); }

.bp-btn--outline { background: var(--card); color: var(--fg); border-color: var(--border-forte); }
.bp-btn--outline:hover:not(:disabled) { background: var(--card-alto); border-color: var(--muted-fg); }

.bp-btn--ghost { background: transparent; color: var(--muted-fg); }
.bp-btn--ghost:hover:not(:disabled) { background: var(--secondary); color: var(--fg); }

.bp-btn--danger { background: var(--destructive); color: #fff; }
.bp-btn--danger:hover:not(:disabled) { filter: brightness(1.08); }

.bp-btn--icone { width: 2.375rem; padding: 0; }
.bp-btn--bloco { width: 100%; }
.bp-btn--grande { height: 2.875rem; font-size: .9375rem; padding: 0 1.5rem; }

/* ── Campos ──────────────────────────────────────────────────────────────── */

.bp-campo { display: flex; flex-direction: column; gap: .375rem; min-width: 0; }
.bp-campo > label { font-size: .8125rem; font-weight: 550; color: var(--fg); }

.bp-input, .bp-select {
  height: 2.375rem; width: 100%; padding: 0 .75rem;
  background: var(--bg); color: var(--fg);
  border: 1px solid var(--border-forte); border-radius: var(--radius);
  font: inherit; font-size: .875rem;
  transition: border-color .15s, box-shadow .15s;
}
.bp-select {
  appearance: none; padding-right: 2rem; cursor: pointer;
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right .55rem center; background-size: 1rem;
}
.bp-input:hover, .bp-select:hover { border-color: var(--muted-fg); }
.bp-input:focus, .bp-select:focus {
  outline: none; border-color: var(--ring);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 22%, transparent);
}
.bp-input::placeholder { color: var(--muted-fg); }
.bp-input[aria-invalid="true"] { border-color: var(--destructive); }

textarea.bp-input { height: auto; min-height: 7rem; padding: .625rem .75rem; resize: vertical; line-height: 1.6; }

.bp-senha { position: relative; }
.bp-senha > .bp-input { padding-right: 48px; }
.bp-senha__olho {
  position: absolute; right: 1px; top: 1px; bottom: 1px; width: 44px;
  display: grid; place-items: center; padding: 0; border: 0;
  border-radius: var(--radius); background: transparent; color: var(--muted-fg); cursor: pointer;
}
.bp-senha__olho:hover { color: var(--fg); }
.bp-senha__olho svg { width: 20px; height: 20px; }
.bp-senha__risco { display: none; }
.bp-senha__olho[aria-pressed="true"] .bp-senha__risco { display: block; }
.bp-senha > .bp-input::-ms-reveal { display: none; }

/* Lista de sugestões sob um campo (busca de local, em assets/busca-local.js).
   Flutua por cima do formulário em vez de empurrá-lo: a lista abre e fecha a
   cada pausa de digitação, e o formulário pulando junto seria enjoativo. */
.bp-busca { position: relative; }
.bp-sugestoes {
  position: absolute; z-index: 30; top: 100%; left: 0; right: 0; margin: .25rem 0 0;
  list-style: none; padding: .25rem; max-height: 18rem; overflow-y: auto;
  background: var(--card); border: 1px solid var(--border-forte);
  border-radius: var(--radius); box-shadow: var(--sombra-3);
}
.bp-sugestoes [role="option"] {
  display: flex; flex-direction: column; gap: .125rem; padding: .5rem .625rem;
  border-radius: calc(var(--radius) - .125rem); cursor: pointer;
}
.bp-sugestoes [role="option"] strong { font-size: .875rem; font-weight: 600; color: var(--fg); }
.bp-sugestoes [role="option"] span { font-size: .75rem; color: var(--muted-fg); }
.bp-sugestoes [role="option"]:hover,
.bp-sugestoes [role="option"][aria-selected="true"] { background: var(--primary-suave); }
.bp-sugestoes__fonte { padding: .375rem .625rem .25rem; font-size: .6875rem; color: var(--muted-fg); text-align: right; }

.bp-erro { font-size: .75rem; color: var(--destructive); min-height: 1rem; margin: 0; }
/* Sem `min-height`, ao contrário do erro: o erro reserva a linha para o
   formulário não pular quando aparece, e o aviso de sucesso só existe depois
   de uma ação da pessoa — reservar espaço para ele deixaria um vão permanente
   no meio da tela de login. */
.bp-ok   { font-size: .75rem; color: var(--primary-texto); margin: 0; }
.bp-ok:empty { display: none; }
.bp-dica { font-size: .75rem; color: var(--muted-fg); margin: .25rem 0 0; line-height: 1.55; }

/* Botão que se parece com link. É <button> e não <a> porque executa uma ação
   na própria página — um <a href="#"> aqui mentiria para o leitor de tela. */
.bp-link {
  display: block; margin: .75rem auto 0; padding: .25rem;
  background: none; border: 0; font: inherit; font-size: .8125rem;
  color: var(--muted-fg); text-decoration: underline; cursor: pointer;
}
.bp-link:hover { color: var(--fg); }

/* ── Superfícies ─────────────────────────────────────────────────────────── */

.bp-card {
  background: var(--card); color: var(--fg);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--sombra-1);
}

.bp-selo {
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .1875rem .5rem; border-radius: 9999px;
  font-size: .625rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em;
  white-space: nowrap;
}
.bp-selo--publicado { background: var(--primary); color: var(--primary-fg); }
.bp-selo--rascunho  { background: var(--secondary); color: var(--muted-fg); box-shadow: inset 0 0 0 1px var(--border-forte); }
.bp-selo--encerrado { background: color-mix(in srgb, var(--destructive) 18%, transparent); color: var(--destructive); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--destructive) 40%, transparent); }
.bp-selo--aviso     { background: color-mix(in srgb, var(--warning) 18%, transparent); color: var(--warning); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warning) 40%, transparent); }

/* ── Imagem de evento e seu substituto ───────────────────────────────────── */
/* Sem banner, o espaço não pode virar um buraco preto. Vira uma marca:
   gradiente da identidade + a inicial do evento em marca-d'água. */

.bp-img {
  position: relative; aspect-ratio: 16/9; overflow: hidden;
  background: var(--card-alto);
}
.bp-img > img { width: 100%; height: 100%; object-fit: cover; display: block; }

.bp-img__falta {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  background:
    radial-gradient(120% 120% at 15% 0%, color-mix(in srgb, var(--primary) 26%, transparent) 0%, transparent 55%),
    linear-gradient(135deg, hsl(222 22% 16%) 0%, hsl(222 24% 11%) 100%);
}
:root[data-tema="claro"] .bp-img__falta, :root:not([data-tema]) .bp-img__falta {
  background:
    radial-gradient(120% 120% at 15% 0%, color-mix(in srgb, var(--primary) 20%, transparent) 0%, transparent 55%),
    linear-gradient(135deg, hsl(220 18% 94%) 0%, hsl(220 16% 88%) 100%);
}
.bp-img__inicial {
  font-size: clamp(2rem, 14cqw, 3.5rem); font-weight: 800; letter-spacing: -.04em;
  color: color-mix(in srgb, var(--fg) 26%, transparent);
  user-select: none; line-height: 1;
}

/* ── Layout do painel ────────────────────────────────────────────────────── */

.bp-shell { display: flex; min-height: 100dvh; background: var(--bg-fundo); }

.bp-sidebar {
  width: var(--sidebar-w); flex-shrink: 0;
  background: var(--card); border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100dvh;
}

.bp-sidebar__marca {
  height: var(--header-h); display: flex; align-items: center; gap: .5rem;
  padding: 0 1.25rem; border-bottom: 1px solid var(--border);
}
/* A marca é o próprio desenho, não mais um quadrado verde com as letras "BP"
   dentro. O B é vazado no SVG, então ele mostra o fundo da barra — é por isso
   que o mesmo arquivo serve no tema claro e no escuro sem uma segunda versão. */
.bp-sidebar__logo {
  width: 1.875rem; height: 1.875rem;
  color: var(--primary-texto);
  filter: drop-shadow(0 2px 10px color-mix(in srgb, var(--primary) 35%, transparent));
}
.bp-sidebar__nome { font-weight: 700; font-size: 1.0625rem; letter-spacing: -.02em; color: var(--fg-forte); }

.bp-nav { flex: 1; overflow-y: auto; padding: 1rem .75rem; display: flex; flex-direction: column; gap: .1875rem; }
.bp-nav__item {
  display: flex; align-items: center; gap: .6875rem;
  padding: .625rem .75rem; border-radius: var(--radius);
  font-size: .875rem; font-weight: 550; color: var(--muted-fg);
  transition: background .12s, color .12s;
  position: relative;
}
.bp-nav__item:hover { background: var(--secondary); color: var(--fg); }
.bp-nav__item[aria-current="page"] { background: var(--primary-suave); color: var(--primary-texto); font-weight: 650; }
.bp-nav__item[aria-current="page"]::before {
  content: ""; position: absolute; left: -.75rem; top: 50%; transform: translateY(-50%);
  width: 3px; height: 1.125rem; border-radius: 0 2px 2px 0; background: var(--primary);
}
.bp-nav__item svg { width: 1.125rem; height: 1.125rem; flex-shrink: 0; }

/* Rodapé em duas linhas: quem está conectado (e em qual organização) em
   cima, ferramentas embaixo. Numa linha só os quatro ícones espremiam o nome
   até "Administra…", justamente a informação que diz em que conta se está. */
.bp-sidebar__rodape { padding: .75rem; border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: .375rem; }
.bp-sidebar__usuario {
  display: flex; align-items: center; gap: .625rem; min-width: 0;
  padding: .5rem; border-radius: var(--radius); transition: background .12s;
}
.bp-sidebar__usuario:hover { background: var(--secondary); }
.bp-avatar {
  display: grid; place-items: center; flex-shrink: 0;
  width: 2.125rem; height: 2.125rem; border-radius: 50%;
  background: var(--primary-suave); color: var(--primary-texto);
  font-weight: 700; font-size: .875rem;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 30%, transparent);
}
.bp-sidebar__quem { display: flex; flex-direction: column; min-width: 0; line-height: 1.3; }
.bp-sidebar__quem b { font-size: .8125rem; font-weight: 650; color: var(--fg-forte); }
.bp-sidebar__quem small { font-size: .6875rem; color: var(--muted-fg); }
.bp-sidebar__quem b, .bp-sidebar__quem small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bp-sidebar__ferramentas { display: flex; justify-content: space-between; gap: .25rem; }

/* O alternador mostra para onde leva: lua no claro, sol no escuro. */
.bp-tema > span { display: inline-flex; }
:root:not([data-tema="escuro"]) .bp-tema__sol,
:root[data-tema="escuro"] .bp-tema__lua { display: none; }

/* A casca recebe foco por código quando a gaveta abre no celular (ver
   painel.js). Anel aqui não diz nada: o que apareceu foi um painel inteiro, não
   um controle — e no toque ele lê como item selecionado. Os itens de dentro
   continuam com o anel deles. */
.bp-sidebar:focus { outline: none; }

.bp-main { flex: 1; min-width: 0; }
.bp-pagina { padding: 2rem 2.25rem 4rem; max-width: 82rem; margin: 0 auto; display: flex; flex-direction: column; gap: 1.75rem; }

/* ── Barra superior e gaveta do celular ──────────────────────────────────── */
/* No desktop a barra lateral está sempre à vista e esta barra não existe. No
   celular ela é a única navegação: a lateral sai da tela e volta como gaveta.

   Antes a lateral virava um bloco empilhado no topo de toda página — marca,
   fileira de ícones rolando na horizontal e o rodapé com nome, tema e sair.
   Comia um terço da tela em toda página, a fileira escondia metade dos itens sem
   dar pista de que rolava, e o rodapé encostava no conteúdo. Mesmo desenho que
   o intranet-lojas usa: botão de menu, marca e título; a gaveta entra
   deslizando e fecha no véu, no Esc, no botão ou ao navegar.

   `visibility` entra na transição de propósito: sem ela a gaveta fechada
   continua no caminho do Tab e do leitor de tela, que anuncia um menu que
   ninguém vê. Ao ABRIR o valor troca na hora; ao FECHAR ele espera o fim do
   deslize — é o que deixa a saída visível. */

.bp-topbar { display: none; }
.bp-veu { display: none; }

@media (max-width: 860px) {
  /* A altura real da barra: o recorte do aparelho (a "orelha" do iPhone) entra
     como padding, então some do espaço útil e não corta o botão de menu. */
  :root { --topbar-h: calc(var(--header-h) + env(safe-area-inset-top, 0px)); }

  .bp-shell { flex-direction: column; }

  .bp-topbar {
    display: flex; align-items: center; gap: .5rem;
    position: fixed; top: 0; left: 0; right: 0; z-index: 90;
    height: var(--topbar-h); padding: 0 .75rem;
    padding-top: env(safe-area-inset-top, 0px);
    background: var(--card); border-bottom: 1px solid var(--border);
  }
  .bp-topbar__marca { display: flex; align-items: center; gap: .5rem; min-width: 0; }
  .bp-topbar__logo { width: 1.625rem; height: 1.625rem; flex-shrink: 0; color: var(--primary-texto); }
  /* Uma linha só, cortada com reticências: título de evento é longo e não pode
     empurrar o botão de menu para fora da tela. */
  .bp-topbar__titulo {
    font-size: .9375rem; font-weight: 650; letter-spacing: -.015em; color: var(--fg-forte);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 1;
  }
  /* A ação da tela (ver acaoNoTopo em painel.js). Não encolhe: é o título
     que corta com reticências, nunca o botão. */
  .bp-topbar__acao { flex-shrink: 0; }
  .bp-topbar__acao:empty { display: none; }
  .bp-topbar__acao .bp-btn { padding: 0 .875rem; gap: .375rem; }

  .bp-sidebar {
    position: fixed; top: 0; left: 0; bottom: 0; height: 100dvh;
    /* Gaveta que cobre a tela inteira não parece gaveta: parece que a página
       trocou, e a pessoa procura um "voltar" em vez de tocar fora. A faixa
       de página que sobra à direita é o que diz "isto está por cima, e o que
       estava continua ali" — quanto mais faixa, mais claro. 84vw não deixava
       faixa nenhuma; 76vw deixava pouca. Em 13rem (234px, porque a raiz do
       tema é 18px) sobram 126px num aparelho de 360. */
    width: min(13rem, 66vw); z-index: 101;
    transform: translateX(-100%); visibility: hidden;
    transition: transform .26s ease, visibility .26s;
    box-shadow: var(--sombra-3);
    /* Entrega o arrasto horizontal ao arrastar-gaveta.js e deixa o vertical
       com o navegador, que continua rolando a lista. Sem isto o JS teria de
       adivinhar a direção e disputar o gesto com a rolagem nativa. */
    touch-action: pan-y;
  }
  .bp-sidebar--aberta { transform: translateX(0); visibility: visible; }

  /* Gaveta mais estreita pede tipografia menor, senão nome de item quebra em
     duas linhas — e uma lista de nove itens em duas linhas cada volta a
     ocupar a tela inteira, que é o que se queria evitar.

     O QUE NÃO ENCOLHE É O ALVO DE TOQUE. O `min-height: 44px` é o mesmo
     número de plataforma explicado mais abaixo: o que sai daqui é espaço em
     branco e corpo de letra, nunca a área que a mão precisa acertar. Antes
     a altura vinha do padding (.9375rem dos dois lados dava os 44px); agora
     vem declarada, e o padding fica livre para diminuir. */
  .bp-nav__item {
    min-height: 44px; padding: .4375rem .625rem;
    font-size: .8125rem; gap: .5625rem;
  }
  .bp-nav__item svg { width: 1rem; height: 1rem; }
  /* O traço da página atual mora na sangria da lista; se ela encolhe, ele
     acompanha, senão fica solto no meio do nada. */
  .bp-nav__item[aria-current="page"]::before { left: -.5rem; }
  .bp-nav { padding: .625rem .5rem; }

  .bp-sidebar__marca { padding: 0 .875rem; gap: .4375rem; }
  .bp-sidebar__logo { width: 1.625rem; height: 1.625rem; }
  .bp-sidebar__nome { font-size: .9375rem; }
  .bp-sidebar__usuario { padding: .375rem; gap: .5rem; }
  .bp-avatar { width: 1.75rem; height: 1.75rem; font-size: .75rem; }
  .bp-sidebar__quem b { font-size: .75rem; }
  .bp-sidebar__quem small { font-size: .625rem; }
  /* A gaveta vai de ponta a ponta da tela: sem isto o rodapé fica embaixo da
     barra de gestos do iPhone e o botão de sair não aceita toque. */
  .bp-sidebar__rodape { padding-bottom: calc(.875rem + env(safe-area-inset-bottom, 0px)); }

  .bp-veu {
    display: block; position: fixed; inset: 0; z-index: 100;
    background: hsl(0 0% 0% / .55);
    opacity: 0; visibility: hidden; pointer-events: none;
    transition: opacity .26s ease, visibility .26s;
  }
  .bp-veu--visivel { opacity: 1; visibility: visible; pointer-events: auto; }
  /* `none` e não `pan-y`: atrás do véu não há nada para rolar (o body está
     travado), então todo gesto que nasce nele é para arrastar a gaveta. */
  .bp-veu { touch-action: none; }

  /* A gaveta cobre a tela inteira; deixar o fundo rolar atrás dela move o
     conteúdo sob o dedo de quem só queria escolher um item do menu. */
  body.bp-travado { overflow: hidden; }

  .bp-main { padding-top: var(--topbar-h); }
  .bp-pagina { padding: 1.25rem 1rem 3rem; gap: 1.25rem; }

  /* ── Dedo, não ponteiro ───────────────────────────────────────────────────
     Dois números de PLATAFORMA, não de desenho, e por isso escritos em px:

     44px é o alvo mínimo que a mão acerta sem olhar. Medido antes desta regra:
     o check-in tinha 31 alvos menores que isso — entre eles o botão da câmera
     (362×33) e os dois campos (287×33) —, comissários tinha 39 e o WhatsApp 39.

     16px é o limiar abaixo do qual o Safari e o Chrome do iPhone DÃO ZOOM na
     página ao focar um campo. `.bp-input` usa .875rem e a raiz do projeto era
     14px, então o campo ficava com 12,25px e disparava esse zoom em toda tela
     com formulário. No check-in é pior: portaria.js chama `.focus()` no campo
     de código ao terminar de carregar, então a tela abre e MUDA DE ESCALA
     SOZINHA, sem ninguém tocar em nada — é o "diminui todo tamanho da tela"
     que o dono descreveu.

     Em rem os dois números mudariam junto com a raiz e as duas defesas cairiam
     sem ninguém mexer nelas. Por isso px, e só aqui. */
  .bp-btn { min-height: 44px; }
  .bp-btn--icone { min-width: 44px; }
  .bp-input, .bp-select { min-height: 44px; font-size: 16px; }
  textarea.bp-input { font-size: 16px; }
  /* A aba e o item de menu são links: o que lhes dá altura é o padding. */
  .bp-aba { padding: .9375rem .875rem; }
  /* A seta de voltar era o menor alvo de todas as telas: 57×17. */
  .bp-voltar { min-height: 44px; align-items: center; }
}

@media (prefers-reduced-motion: reduce) {
  .bp-sidebar, .bp-veu { transition: none; }
}

/* ── Cabeçalho de página ─────────────────────────────────────────────────── */

.bp-topo { display: flex; align-items: flex-end; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.bp-topo p { color: var(--muted-fg); font-size: .8125rem; margin: .25rem 0 0; }
/* O voltar do alto das telas é um BOTÃO, não um link solto — pedido do dono,
   01/10/2026 ("precisa ter o botão de voltar para voltar para o evento"). */
.bp-voltar {
  display: inline-flex; align-items: center; gap: .3rem; align-self: flex-start;
  height: 2.125rem; padding: 0 .875rem; border-radius: 999px;
  border: 1px solid var(--border-forte); background: var(--card);
  color: var(--fg); font-size: .8125rem; font-weight: 600; text-decoration: none;
  transition: background .12s, border-color .12s;
}
.bp-voltar:hover { background: var(--card-alto); border-color: var(--muted-fg); }

/* ── Números ─────────────────────────────────────────────────────────────── */

.bp-numeros { display: grid; grid-template-columns: repeat(auto-fill, minmax(10.5rem, 1fr)); gap: .875rem; }
.bp-numero { padding: 1rem 1.125rem; }
.bp-numero b {
  display: block; font-size: 1.5rem; font-weight: 700; line-height: 1.1;
  font-variant-numeric: tabular-nums; letter-spacing: -.025em; color: var(--fg-forte);
}
.bp-numero span {
  display: block; font-size: .625rem; color: var(--muted-fg);
  text-transform: uppercase; letter-spacing: .07em; font-weight: 650; margin-top: .4375rem;
}
.bp-numero small { display: block; font-size: .6875rem; color: var(--muted-fg); margin-top: .25rem; }
.bp-numero--verde b { color: var(--primary-texto); }

/* Ícone do cartão: fica ACIMA do número, não sobreposto no canto — o valor
   pode ser "R$ 14.240,00" e num cartão estreito passaria por baixo dele.
   O ícone é decorativo (leva aria-hidden): quem lê por leitor de tela já tem
   o rótulo em <span> e a explicação em <small>. O realce no hover é a única
   "interação": acende o ícone do cartão sob o cursor, sem mover nada. */
.bp-numero__icone {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.75rem; height: 1.75rem; border-radius: 8px; margin-bottom: .625rem;
  background: var(--secondary); color: var(--muted-fg);
  transition: background .15s, color .15s;
}
@media (hover: hover) and (pointer: fine) { .bp-numero:hover .bp-numero__icone { background: color-mix(in srgb, var(--primary) 15%, transparent); color: var(--fg-forte); } }
/* Ícone preto sobre o fundo verde claro: verde sobre verde não se lia. */
.bp-numero--verde .bp-numero__icone { background: color-mix(in srgb, var(--primary) 15%, transparent); color: var(--fg-forte); }

/* ── Nota presa na tela ──────────────────────────────────────────────────── */
/* Não confundir com .bp-aviso, que é o balão que some sozinho no canto. Esta
   fica onde a pessoa vai agir e continua lá enquanto o problema existir — foi
   feita para o "ainda não dá para publicar", que antes morava no estado vazio
   da tabela de lotes e sumiria junto com ela. */
.bp-nota {
  display: flex; gap: .75rem; align-items: flex-start;
  padding: .9375rem 1.125rem; font-size: .8125rem; color: var(--muted-fg); line-height: 1.6;
}
.bp-nota b { display: block; color: var(--fg-forte); margin-bottom: .125rem; }
.bp-nota > svg { flex-shrink: 0; margin-top: .125rem; }
.bp-nota a, .bp-nota .bp-btn { margin-top: .625rem; }
.bp-nota--atencao { border-left: 3px solid var(--warning); }
.bp-nota--atencao > svg { color: var(--warning); }

/* ── Botão de acesso a uma tela de dentro ────────────────────────────────── */
/* Cartão inteiro clicável: ícone, o que é, o resumo de uma linha e a seta.
   Nasceu quando os ingressos saíram da visão geral do evento — tirar a tabela
   sem deixar um caminho visível seria esconder a tela, não organizá-la. */
.bp-acesso {
  display: flex; align-items: center; gap: .875rem; padding: 1rem 1.125rem;
  color: var(--fg); transition: border-color .18s, box-shadow .18s, transform .18s;
}
/* Hover de cartão só onde há MOUSE. No toque o navegador simula o :hover e o
   deixa preso depois do toque: o cartão ficava levantado e com borda verde
   até a pessoa tocar em outro lugar. Pedido do dono, 30/09/2026 — a mesma
   regra vale para todos os cartões do site. */
@media (hover: hover) and (pointer: fine) {
  .bp-acesso:hover {
    border-color: color-mix(in srgb, var(--primary) 45%, var(--border));
    box-shadow: var(--sombra-2); transform: translateY(-1px);
  }
}
.bp-acesso__icone {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 2.5rem; height: 2.5rem; border-radius: 10px;
  background: color-mix(in srgb, var(--primary) 15%, transparent); color: var(--fg-forte);
}
.bp-acesso__texto { flex: 1; min-width: 0; }
.bp-acesso__texto b { display: block; font-size: .9375rem; color: var(--fg-forte); }
.bp-acesso__texto small { display: block; font-size: .75rem; color: var(--muted-fg); margin-top: .125rem; }
.bp-acesso__seta { color: var(--muted-fg); flex-shrink: 0; transition: color .15s, transform .15s; }
@media (hover: hover) and (pointer: fine) {
  .bp-acesso:hover .bp-acesso__seta { color: var(--fg-forte); transform: translateX(3px); }
}

/* ── Grade de eventos ────────────────────────────────────────────────────── */

.bp-grade { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(17.5rem, 100%), 1fr)); gap: 1.125rem; }

/* A grade da LISTA DO PAINEL. Não é a .bp-grade, que a vitrine do comprador
   também usa: mudar aquela mexeria numa tela que não é do produtor.
   Mínimo de 15rem dá quatro colunas num notebook comum, como na referência
   do escopo, e cai para duas num tablet sem precisar de media query. */
.bp-grade-eventos { display: grid; grid-template-columns: repeat(auto-fill, minmax(15.5rem, 1fr)); gap: 1rem; }

/* O cartão inteiro é clicável sem ser um <a> gigante: o link é o NOME, e um
   ::after dele cobre o cartão. Assim o atalho de check-in pode ficar dentro
   do cartão como um segundo link de verdade — link dentro de link não existe
   em HTML, e o leitor de tela anunciaria o cartão inteiro como um rótulo só. */
.bp-evento {
  position: relative; display: flex; flex-direction: column; overflow: hidden;
  /* Sem efeito de mouse nem de toque — nada de borda verde, sombra, subir ou
     zoom na foto (pedido do dono, 30/09/2026, para todo cartão de evento).
     O realce do toque do navegador também sai: era a "borda" que aparecia ao
     tocar no celular. */
  -webkit-tap-highlight-color: transparent;
}
.bp-evento:has(.bp-evento__link:focus-visible) { outline: 2px solid var(--ring); outline-offset: 2px; }
.bp-evento__link:focus-visible { outline: none; }
.bp-evento__link::after { content: ""; position: absolute; inset: 0; z-index: 1; }

.bp-evento__capa { position: relative; container-type: inline-size; }

/* Status no canto direito do banner, como na referência. O segundo selo
   (--linha) é o mesmo status para o cartão compacto do celular, onde a
   miniatura é pequena demais para carregar texto. */
.bp-evento__selo { position: absolute; top: .625rem; right: .625rem; z-index: 1; box-shadow: var(--sombra-1); }
.bp-evento__selo-linha { display: none; align-self: flex-start; margin-bottom: .375rem; }

.bp-evento__corpo { padding: .9375rem 1rem .25rem; display: flex; flex-direction: column; min-width: 0; }
.bp-evento__nome {
  font-size: 1rem; font-weight: 650; line-height: 1.35; margin: 0 0 .5rem;
  color: var(--fg-forte); letter-spacing: -.012em;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.bp-evento__meta { display: flex; align-items: center; gap: .4375rem; font-size: .75rem; color: var(--muted-fg); margin-bottom: .25rem; min-width: 0; }
.bp-evento__meta svg { width: .8125rem; height: .8125rem; flex-shrink: 0; opacity: .8; }
.bp-evento__meta span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.bp-evento__numeros {
  margin: .75rem 1rem 0; padding: .8125rem 0 .875rem; border-top: 1px solid var(--border);
  /* Flex que quebra, e não grade de colunas iguais: "R$ 14.300,00" é três
     vezes mais largo que "12", e em terços iguais os dois se sobrepunham. */
  display: flex; flex-wrap: wrap; column-gap: 1.5rem; row-gap: .5rem;
}
.bp-evento__numeros b { display: block; font-size: 1.125rem; font-weight: 700; color: var(--primary-texto); font-variant-numeric: tabular-nums; line-height: 1.1; letter-spacing: -.02em; white-space: nowrap; }
.bp-evento__numeros span { display: block; font-size: .6875rem; color: var(--muted-fg); margin-top: .25rem; font-weight: 550; }

/* Rodapé do cartão: o atalho para a portaria. Fica ACIMA do ::after do nome
   (z-index 2), senão o toque nele abriria a visão geral. */
.bp-evento__acoes {
  margin-top: auto; display: flex; align-items: center; justify-content: space-between; gap: .5rem;
  padding: .625rem 1rem; border-top: 1px solid var(--border); background: var(--card-alto);
}
.bp-evento__abrir { display: inline-flex; align-items: center; gap: .25rem; font-size: .75rem; font-weight: 600; color: var(--muted-fg); }
.bp-evento__atalho { position: relative; z-index: 2; height: 2rem; padding: 0 .75rem; font-size: .75rem; }

/* ── Primeiro passo (lista vazia do painel) ──────────────────────────────── */
/* Quem acabou de contratar abre o painel e encontra uma tela vazia. Em vez de
   "nenhum evento encontrado", ela mostra o caminho inteiro em três passos —
   é o treinamento que a pessoa não teve. */
.bp-guia { padding: 2rem 1.5rem; display: flex; flex-direction: column; align-items: center; text-align: center; gap: .375rem; }
.bp-guia__icone {
  display: grid; place-items: center; width: 3.25rem; height: 3.25rem; border-radius: 14px; margin-bottom: .5rem;
  background: var(--primary-suave); color: var(--primary-texto);
}
.bp-guia h2 { font-size: 1.3125rem; }
.bp-guia > p { color: var(--muted-fg); margin: 0 0 .75rem; max-width: 30rem; }
.bp-guia__passos {
  list-style: none; margin: .5rem 0 1.5rem; padding: 0; width: 100%; max-width: 44rem;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); gap: .75rem; counter-reset: passo;
  text-align: left;
}
.bp-guia__passos li {
  counter-increment: passo; position: relative;
  padding: 1rem 1rem 1rem 3.25rem; border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--card-alto);
}
.bp-guia__passos li::before {
  content: counter(passo); position: absolute; left: 1rem; top: 1rem;
  display: grid; place-items: center; width: 1.625rem; height: 1.625rem; border-radius: 50%;
  background: var(--primary); color: var(--primary-fg); font-weight: 700; font-size: .75rem;
}
.bp-guia__passos b { display: block; color: var(--fg-forte); font-size: .875rem; }
.bp-guia__passos span { display: block; color: var(--muted-fg); font-size: .75rem; margin-top: .125rem; line-height: 1.5; }

/* ── Menu "Mais ações" ───────────────────────────────────────────────────── */
/* <details> nativo: abre e fecha sem JavaScript, funciona no teclado e o
   leitor de tela anuncia "recolhido/expandido" sozinho. Guarda as ações raras
   (duplicar, arquivar) para que a linha de botões mostre só as frequentes. */
.bp-menu { position: relative; }
.bp-menu > summary { list-style: none; }
.bp-menu > summary::-webkit-details-marker { display: none; }
.bp-menu__lista {
  position: absolute; right: 0; top: calc(100% + .375rem); z-index: 40; min-width: 13rem;
  display: flex; flex-direction: column; padding: .3125rem;
  background: var(--card); border: 1px solid var(--border-forte); border-radius: var(--radius-lg);
  box-shadow: var(--sombra-3); animation: bp-entrar .14s ease-out;
}
.bp-menu__lista .bp-btn { justify-content: flex-start; width: 100%; font-weight: 550; color: var(--fg); flex-shrink: 0; }
/* O "⋯" do evento com as seções: SEIS itens à vista e rolagem dali em diante
   (pedido do dono, 01/10/2026). A altura sai da do próprio botão (2.375rem). */
.bp-menu--secoes .bp-menu__lista {
  max-height: calc(6 * 2.375rem + .625rem); overflow-y: auto; overscroll-behavior: contain;
  min-width: 15rem;
}
.bp-menu__divisa { flex-shrink: 0; height: 1px; margin: .25rem .375rem; background: var(--border); }

/* ── Tabelas ─────────────────────────────────────────────────────────────── */

.bp-tabela { overflow-x: auto; }
.bp-tabela table { width: 100%; border-collapse: collapse; font-size: .8125rem; }
.bp-tabela th {
  text-align: left; padding: .6875rem .875rem; white-space: nowrap;
  font-size: .625rem; font-weight: 700; text-transform: uppercase; letter-spacing: .07em;
  color: var(--muted-fg); border-bottom: 1px solid var(--border);
  background: var(--card-alto); position: sticky; top: 0;
}
.bp-tabela td { padding: .75rem .875rem; border-bottom: 1px solid var(--border); }
.bp-tabela tbody tr:last-child td { border-bottom: 0; }
.bp-tabela tbody tr { transition: background .12s; }
.bp-tabela tbody tr:hover { background: var(--card-alto); }
.bp-tabela .num { text-align: right; font-variant-numeric: tabular-nums; }
.bp-tabela code, code.bp-cod {
  font-family: var(--mono); font-size: .75rem; letter-spacing: .02em;
  background: var(--secondary); padding: .1875rem .375rem; border-radius: 4px;
  border: 1px solid var(--border);
}

/* ── Estados ─────────────────────────────────────────────────────────────── */

.bp-vazio {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 4.5rem 1.5rem; text-align: center; gap: .25rem;
  border: 1px dashed var(--border-forte); border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--card) 45%, transparent);
}
.bp-vazio h3 { color: var(--fg-forte); }
.bp-vazio p { color: var(--muted-fg); max-width: 26rem; line-height: 1.65; margin: .5rem 0 1.25rem; font-size: .875rem; }
/* Linha de saídas do estado vazio. Quebra em coluna no celular porque três
   botões lado a lado ficariam com o rótulo cortado em tela estreita. */
.bp-vazio .bp-acoes { display: flex; flex-wrap: wrap; gap: .5rem; justify-content: center; }

.bp-esqueleto {
  background: linear-gradient(90deg, var(--secondary) 25%, var(--card-alto) 50%, var(--secondary) 75%);
  background-size: 200% 100%; animation: bp-brilho 1.4s infinite linear; border-radius: var(--radius);
}
@keyframes bp-brilho { to { background-position: -200% 0; } }

.bp-girando {
  width: 1.75rem; height: 1.75rem; border: 2.5px solid var(--primary);
  border-top-color: transparent; border-radius: 50%;
  animation: bp-girar .65s linear infinite;
}
@keyframes bp-girar { to { transform: rotate(360deg); } }

.bp-carregando { display: grid; place-items: center; padding: 5rem 1rem; }

/* ── Avisos ──────────────────────────────────────────────────────────────── */

.bp-avisos { position: fixed; bottom: 1.25rem; right: 1.25rem; display: flex; flex-direction: column; gap: .5rem; z-index: 130; }
/* No celular o aviso vai para o CENTRO da tela — pedido do dono, 01/10/2026,
   com print: no canto de baixo ele nascia atrás do menu inferior (z-index
   95) e da faixa de compra, e a pessoa via só a ponta. z-index 130 o põe
   acima de abas, faixa e gaveta. */
@media (max-width: 640px) {
  .bp-avisos { top: 50%; bottom: auto; left: 1rem; right: 1rem; translate: 0 -50%; align-items: center; }
  .bp-avisos .bp-aviso { min-width: 0; width: 100%; }
}
.bp-aviso {
  background: var(--card); border: 1px solid var(--border); border-left: 3px solid var(--primary);
  border-radius: var(--radius); padding: .75rem 1rem; min-width: 17rem; max-width: 23rem;
  box-shadow: var(--sombra-3); animation: bp-entrar .18s ease-out;
}
.bp-aviso--erro { border-left-color: var(--destructive); }
.bp-aviso b { display: block; font-size: .8125rem; margin-bottom: .125rem; color: var(--fg-forte); }
.bp-aviso span { font-size: .75rem; color: var(--muted-fg); line-height: 1.5; }
@keyframes bp-entrar { from { opacity: 0; transform: translateY(.5rem) scale(.98); } }

/* ── Diálogos ────────────────────────────────────────────────────────────── */

dialog.bp-dialogo {
  border: 1px solid var(--border); border-radius: var(--radius-xl);
  background: var(--card); color: var(--fg); padding: 0;
  max-width: 32rem; width: calc(100% - 2rem);
  box-shadow: var(--sombra-3);
}
dialog.bp-dialogo::backdrop { background: hsl(222 25% 4% / .72); backdrop-filter: blur(3px); }
dialog.bp-dialogo form, dialog.bp-dialogo .corpo { padding: 1.5rem; display: flex; flex-direction: column; gap: 1rem; }
dialog.bp-dialogo h2 { margin-bottom: .25rem; }

/* ── Abas ────────────────────────────────────────────────────────────────── */

.bp-abas {
  display: flex; gap: .25rem; border-bottom: 1px solid var(--border);
  overflow-x: auto;
  /* A rolagem existe só para caber no celular. No desktop a barra aparecia
     como duas setinhas soltas ao lado das abas. */
  scrollbar-width: none;
}
.bp-abas::-webkit-scrollbar { display: none; }
.bp-aba {
  padding: .625rem .875rem; font-size: .8125rem; font-weight: 600; color: var(--muted-fg);
  border-bottom: 2px solid transparent; margin-bottom: -1px; white-space: nowrap;
  transition: color .12s, border-color .12s;
}
.bp-aba:hover { color: var(--fg); }
.bp-aba[aria-current="page"] { color: var(--primary-texto); border-bottom-color: var(--primary); }

/* ── Campo de banner ─────────────────────────────────────────────────────── */

.bnr { display: flex; flex-direction: column; gap: .75rem; }
.bnr__previa {
  aspect-ratio: 16/9; max-width: 26rem; border-radius: var(--radius-lg);
  overflow: hidden; border: 1px solid var(--border); container-type: inline-size;
  position: relative;
}
.bnr__previa img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bnr__acoes { display: flex; gap: .5rem; align-items: center; }
.bnr__barra { height: 4px; max-width: 26rem; background: var(--secondary); border-radius: 2px; overflow: hidden; }
.bnr__barra > div { height: 100%; width: 0; background: var(--primary); transition: width .2s; }
.bnr__dica { font-size: .75rem; color: var(--muted-fg); margin: 0; line-height: 1.55; }

/* ── Público: sempre escuro, sem exceção ─────────────────────────────────── */

.bp-publico { background: var(--bg-fundo); min-height: 100dvh; display: flex; flex-direction: column; }

.bp-pub-topo {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between;
  padding: .875rem 1.5rem; border-bottom: 1px solid var(--border);
  background: color-mix(in srgb, var(--bg-fundo) 88%, transparent);
  backdrop-filter: blur(14px) saturate(140%);
}
.bp-marca { display: flex; align-items: center; gap: .5625rem; }
/* Com textos maiores, o cabeçalho precisa de menos margem nos celulares
   estreitos para manter a marca e o acesso aos ingressos lado a lado. */
@media (max-width: 360px) {
  .bp-pub-topo { padding-inline: .75rem; }
}
.bp-marca__bloco {
  width: 1.875rem; height: 1.875rem; border-radius: .5rem;
  background: var(--primary); color: var(--primary-fg);
  display: grid; place-items: center; font-weight: 800; font-size: .75rem;
  box-shadow: 0 2px 12px color-mix(in srgb, var(--primary) 45%, transparent);
}
.bp-marca__logo { width: 1.875rem; height: 1.875rem; flex-shrink: 0; color: var(--primary-texto); }
.bp-marca__nome { font-weight: 700; font-size: 1.0625rem; letter-spacing: -.02em; color: var(--fg-forte); }


/* ── Utilidades ──────────────────────────────────────────────────────────── */

.secao { margin-bottom: .875rem; }
section > h2.secao { margin-bottom: .75rem; }
.num { text-align: right; font-variant-numeric: tabular-nums; }

.bp-oculto { display: none !important; }

/* ── Gráficos ────────────────────────────────────────────────────────────── */
/* Paleta VALIDADA contra as superfícies do BoomPass (seis checks, dois modos).
   Não trocar hex sem rodar o validador: a ordem dos tons é o mecanismo de
   segurança para daltonismo, não escolha estética.
   O verde #36f29d da marca fica nos botões e números — como marca de gráfico
   ele sai da banda de luminosidade do modo escuro (L 0.81). */

:root {
  --gr-1: #0aa858;   /* verde da marca, passo do modo escuro */
  --gr-2: #3987e5;
  --gr-3: #d95926;
  --gr-4: #9085e9;
  --gr-trilha: hsl(222 10% 22%);
  --gr-grade:  hsl(222 10% 18%);
  --gr-base:   hsl(222 10% 26%);
}
:root[data-tema="claro"] {
  --gr-1: #0f9958;
  --gr-2: #2a78d6;
  --gr-3: #eb6834;
  --gr-4: #4a3aa7;
  --gr-trilha: hsl(220 16% 91%);
  --gr-grade:  hsl(220 14% 92%);
  --gr-base:   hsl(220 13% 82%);
}

.gr { margin: 0; display: flex; flex-direction: column; gap: .625rem; }
.gr__titulo { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; font-size: .875rem; font-weight: 650; color: var(--fg-forte); }
.gr__titulo span { font-size: .75rem; font-weight: 400; color: var(--muted-fg); }
.gr__area { width: 100%; }
.gr__area svg { display: block; overflow: visible; }

.gr__legenda { display: flex; gap: .875rem; flex-wrap: wrap; }
.gr__chave { display: inline-flex; align-items: center; gap: .375rem; font-size: .75rem; color: var(--muted-fg); }
.gr__chave i { width: .625rem; height: .625rem; border-radius: 3px; flex-shrink: 0; }

/* Texto de eixo usa cor de texto, nunca a cor da série. */
.gr-eixo { font-size: 10px; fill: var(--muted-fg); font-variant-numeric: tabular-nums; }
.gr-grade { stroke: var(--gr-grade); stroke-width: 1; }
.gr-base  { stroke: var(--gr-base);  stroke-width: 1; }
.gr-meta  { stroke: var(--muted-fg); stroke-width: 1; stroke-dasharray: 3 3; opacity: .7; }
/* Anel da superfície: o ponto continua legível onde cruza a linha. */
.gr-ponto { stroke: var(--card); stroke-width: 2; }

.gr-dica {
  position: fixed; z-index: 80; display: none; pointer-events: none;
  background: var(--card); border: 1px solid var(--border-forte);
  border-radius: var(--radius); padding: .5rem .625rem;
  box-shadow: var(--sombra-3); max-width: 15rem;
}
.gr-dica b { display: block; font-size: .75rem; color: var(--fg-forte); margin-bottom: .125rem; }
.gr-dica span { display: block; font-size: .6875rem; color: var(--muted-fg); font-variant-numeric: tabular-nums; }

.gr__tabela { font-size: .75rem; }
.gr__tabela summary { cursor: pointer; color: var(--muted-fg); font-weight: 550; padding: .25rem 0; }
.gr__tabela summary:hover { color: var(--fg); }
.gr__tabela table { width: 100%; border-collapse: collapse; margin-top: .5rem; }
.gr__tabela th { text-align: left; font-size: .625rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted-fg); padding: .25rem .5rem; border-bottom: 1px solid var(--border); }
.gr__tabela td { padding: .25rem .5rem; border-bottom: 1px solid var(--border); font-variant-numeric: tabular-nums; }

/* Lotes */
.gr-lotes { display: flex; flex-direction: column; gap: .875rem; }
.gr-lote__topo { display: flex; justify-content: space-between; align-items: baseline; gap: .5rem; margin-bottom: .3125rem; }
.gr-lote__nome { font-size: .8125rem; font-weight: 600; color: var(--fg); }
.gr-lote__num { font-size: .75rem; color: var(--muted-fg); font-variant-numeric: tabular-nums; }
.gr-lote__trilha { display: flex; height: .625rem; border-radius: 9999px; overflow: hidden; background: var(--gr-trilha); gap: 2px; }
.gr-lote__parte { min-width: 0; }
.gr-lote__pe { font-size: .6875rem; color: var(--muted-fg); margin-top: .25rem; font-variant-numeric: tabular-nums; }

/* Barra empilhada: 2px da superfície separando os segmentos. */
.gr-empilhada { display: flex; height: 1.5rem; border-radius: var(--radius); overflow: hidden; gap: 2px; background: var(--card); }
.gr-empilhada > div { min-width: 2px; transition: opacity .12s; }
.gr-empilhada > div:hover { opacity: .85; }

.gr-painel { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(19rem, 100%), 1fr)); gap: 1.125rem; }
.gr-painel > .bp-card { padding: 1.125rem; }


/* ── Ingressos do comprador (/pedido/<numero>) ───────────────────────────── */
/* Cartão de ingresso: uma peça por vez, no formato de um bilhete recortado.
   O prefixo .bpi- isola este bloco do resto do sistema visual. */

/* Carrossel: rolagem horizontal com encaixe. No celular o polegar já sabe
   o que fazer; as setas existem para o desktop e para quem usa teclado. */
.bpi-carrossel {
  display: flex; gap: 1rem;
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; scroll-behavior: smooth;
  /* O encaixe respeita o respiro lateral. Sem isto o ingresso encaixava na
     borda da faixa — que tem margem negativa para a rolagem ir de ponta a
     ponta — e o primeiro ficava colado na borda do cartão de fora. */
  scroll-padding-inline: 1.25rem;
  scrollbar-width: none; margin: 0 -1.25rem; padding: .25rem 1.25rem .5rem;
}
.bpi-carrossel::-webkit-scrollbar { display: none; }
.bpi-slide { flex: 0 0 100%; min-width: 0; scroll-snap-align: start; display: flex; flex-direction: column; gap: .875rem; }

/* O RECORTE É DE VERDADE desde 01/10/2026 — pedido do dono, com print: os
   meios círculos eram discos pintados da cor do fundo POR CIMA do cartão, e
   a sombra do cartão passava reta por trás deles; o recorte parecia uma
   folha encostada no fundo, não um corte.

   Agora o cartão não tem fundo nem borda: quem pinta são as peças de dentro
   (faixa, seções, ações), e as peças vizinhas de um picote têm as quinas
   CORTADAS por máscara (ver `.bpi-serrilha` abaixo). A sombra e o contorno
   saem de `drop-shadow`, que segue a silhueta — com o corte, o meio círculo
   ganha sombra por dentro da curva, como um furo. `box-shadow` não serve:
   ele desenha o retângulo inteiro, com ou sem corte.

   `--bpi-sombra` é a sombra de cartão solto; quem mostra o ingresso dentro
   de outro cartão (página do pedido, diálogos do painel) a desliga, e o
   contorno fica. */
.bpi-cartao {
  --bpi-contorno: drop-shadow(0 0 .6px hsl(220 20% 20% / .55));
  --bpi-sombra: drop-shadow(0 2px 3px hsl(220 20% 20% / .1));
  position: relative; border-radius: var(--radius-lg);
  filter: var(--bpi-contorno) var(--bpi-sombra);
}
.bpi-cartao > * { background: var(--card); }
.bpi-cartao > :last-child { border-radius: 0 0 var(--radius-lg) var(--radius-lg); }
.bpi-cartao--inativo { opacity: .5; filter: saturate(.35) var(--bpi-contorno); }

.bpi-cartao > .bpi-faixa,
.bpi-faixa {
  display: flex; align-items: center; justify-content: space-between; gap: .75rem;
  padding: .75rem 1.25rem;
  background: var(--primary); color: var(--primary-fg);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  font-weight: 700; font-size: .9375rem; letter-spacing: -.01em;
}
.bpi-faixa__conta { font-variant-numeric: tabular-nums; font-size: .8125rem; opacity: .85; }

.bpi-secao { padding: 1.125rem 1.25rem; display: flex; flex-direction: column; gap: .5rem; }
.bpi-rotulo {
  font-size: .625rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .12em; color: var(--muted-fg);
}
.bpi-titulo { font-size: 1.0625rem; font-weight: 650; color: var(--fg-forte); line-height: 1.3; }

.bpi-linha { display: flex; align-items: flex-start; gap: .5rem; font-size: .875rem; color: var(--fg); }
.bpi-linha svg { width: 1rem; height: 1rem; flex-shrink: 0; margin-top: .125rem; color: var(--muted-fg); }

/* Serrilha: o corte que faz a peça parecer um ingresso de verdade.
   Ela mesma não ocupa altura: é a fronteira entre duas peças. A linha
   tracejada é desenhada por cima dessa fronteira (::before), e os dois meios
   círculos são as quinas das peças vizinhas, cortadas por máscara — a de
   cima perde as quinas de baixo, a de baixo as de cima. Raio de 10px, o
   tamanho do recorte de antes. */
.bpi-serrilha { position: relative; height: 0; background: none !important; }
.bpi-serrilha::before {
  content: ""; position: absolute; z-index: 1; left: 1.25rem; right: 1.25rem; top: -1px;
  border-top: 2px dashed var(--border-forte);
}
.bpi-cartao > :has(+ .bpi-serrilha) { --bpi-corte-baixo: 10px; }
.bpi-serrilha + * { --bpi-corte-cima: 10px; margin-top: -1px; }
/* O -1px fecha a emenda: altura fracionária (rem) deixava um fio de 1px
   transparente entre as duas peças, e o contorno o desenhava como linha. */
.bpi-cartao > :has(+ .bpi-serrilha),
.bpi-serrilha + * {
  --c: var(--bpi-corte-cima, 0px);
  --b: var(--bpi-corte-baixo, 0px);
  -webkit-mask:
    radial-gradient(circle at 0 0, #0000 var(--c), #000 calc(var(--c) + .5px)) top left / 51% 51% no-repeat,
    radial-gradient(circle at 100% 0, #0000 var(--c), #000 calc(var(--c) + .5px)) top right / 51% 51% no-repeat,
    radial-gradient(circle at 0 100%, #0000 var(--b), #000 calc(var(--b) + .5px)) bottom left / 51% 51% no-repeat,
    radial-gradient(circle at 100% 100%, #0000 var(--b), #000 calc(var(--b) + .5px)) bottom right / 51% 51% no-repeat;
  mask:
    radial-gradient(circle at 0 0, #0000 var(--c), #000 calc(var(--c) + .5px)) top left / 51% 51% no-repeat,
    radial-gradient(circle at 100% 0, #0000 var(--c), #000 calc(var(--c) + .5px)) top right / 51% 51% no-repeat,
    radial-gradient(circle at 0 100%, #0000 var(--b), #000 calc(var(--b) + .5px)) bottom left / 51% 51% no-repeat,
    radial-gradient(circle at 100% 100%, #0000 var(--b), #000 calc(var(--b) + .5px)) bottom right / 51% 51% no-repeat;
}

.bpi-qr { display: flex; flex-direction: column; align-items: center; gap: .75rem; }
.bpi-qr canvas {
  width: 13rem; height: 13rem; max-width: 100%;
  image-rendering: pixelated; background: #fff;
  padding: .75rem; border-radius: var(--radius); box-shadow: var(--sombra-1);
}
.bpi-codigo {
  font-family: var(--mono); font-size: .75rem; letter-spacing: .08em;
  color: var(--muted-fg); text-align: center; word-break: break-all;
}

.bpi-tipo { display: flex; align-items: center; justify-content: space-between; gap: .75rem; flex-wrap: wrap; }

/* Ações DENTRO do cartão, depois do último picote: ícones de traço,
   monocromáticos como os das linhas do cartão, com o nome embaixo. Lado a
   lado em qualquer largura — são quatro alvos de 44px+ e cabem em 320px. */
.bpi-acoes { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: .25rem; padding: .625rem .75rem .75rem; }
.bpi-acao {
  display: flex; flex-direction: column; align-items: center; gap: .3125rem;
  min-height: 3.5rem; padding: .5rem .25rem; border: 0; border-radius: var(--radius);
  background: none; color: var(--fg); font: inherit; font-size: .6875rem; font-weight: 600;
  cursor: pointer; transition: background .15s;
}
.bpi-acao svg { width: 1.375rem; height: 1.375rem; color: var(--fg); }
.bpi-acao span { white-space: nowrap; }
.bpi-acao:active { background: var(--muted); }
.bpi-acao:disabled { opacity: .5; cursor: progress; }
@media (hover: hover) and (pointer: fine) { .bpi-acao:hover { background: var(--muted); } }
/* Cinco ações (Meus ingressos soma o Transferir às quatro da compra): em
   320–390px o rótulo de 11px não cabe em um quinto da largura, e "Transferir"
   saía cortado na borda. Com cinco, a letra desce um ponto e "Como chegar"
   pode quebrar em duas linhas — o alvo de toque continua do mesmo tamanho. */
.bpi-acoes:has(> .bpi-acao:nth-child(5)) { gap: 0; padding-inline: .375rem; }
.bpi-acoes:has(> .bpi-acao:nth-child(5)) .bpi-acao { font-size: .625rem; padding-inline: 0; }
.bpi-acoes:has(> .bpi-acao:nth-child(5)) .bpi-acao span { white-space: normal; text-align: center; line-height: 1.15; }

/* Guias com o primeiro nome de cada titular, em cima dos ingressos. Com dois,
   dividem a largura; com três ou mais, cada uma tem 40% da faixa — a terceira
   aparece cortada e diz que a faixa rola. Quem posiciona a selecionada é o
   JS (`pilulas` em pedido-ingressos.js), sempre no mesmo lugar. */
.bpi-pilulas {
  display: flex; gap: .5rem; overflow-x: auto; scrollbar-width: none;
  overscroll-behavior-x: contain; padding: .125rem 0 .25rem;
}
.bpi-pilulas::-webkit-scrollbar { display: none; }
.bpi-pilula {
  flex: 1 1 0; min-width: 0; height: 2.375rem; padding: 0 1rem;
  /* O mesmo raio dos cantos do ingresso, e não pílula redonda — pedido do
     dono, 30/09/2026: as guias são do ingresso e têm de ter a cara dele. */
  border: 1px solid var(--border-forte); border-radius: var(--radius-lg);
  background: var(--card); color: var(--fg); font: inherit; font-size: .8125rem; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer;
  transition: background .1s, border-color .1s, color .1s;
}
.bpi-pilulas[data-rola] .bpi-pilula { flex: 0 0 40%; }
/* Folga no fim da faixa, para a ÚLTIMA pílula também chegar ao lugar da
   selecionada (a 10% da borda). Sem ela a faixa acabava antes, e as duas
   últimas paravam mais à direita que as outras. */
.bpi-pilulas[data-rola]::after { content: ""; flex: 0 0 calc(50% - .5rem); }
.bpi-pilula[aria-selected="true"] { background: var(--primary); border-color: var(--primary); color: var(--primary-fg); }

.bpi-nav { display: flex; align-items: center; justify-content: center; gap: .75rem; }
.bpi-pontos { display: flex; gap: .375rem; }
/* Acima de seis ingressos a fileira de bolinhas vira uma régua que ninguém
   lê, e em 320px ela chega a empurrar as setas para fora. Aí só a contagem
   fica — ela diz a mesma coisa em qualquer quantidade. */
.bpi-pontos[data-demais] { display: none; }
.bpi-conta { font-size: .75rem; font-weight: 600; color: var(--muted-fg); font-variant-numeric: tabular-nums; }
.bpi-ponto {
  width: .5rem; height: .5rem; padding: 0; border: 0; border-radius: 50%;
  background: var(--border-forte); cursor: pointer; transition: background .15s, transform .15s;
}
.bpi-ponto[aria-current="true"] { background: var(--primary); transform: scale(1.25); }

/* Régua vertical do gráfico combinado. */
.gr-regua { stroke: var(--muted-fg); stroke-width: 1; opacity: .5; }


/* ═══════════════════════════════════════════════════════════════════════════
   Painel no celular — POR ÚLTIMO de propósito
   As regras base de .bp-numeros, .bp-aba e .bp-evento estão acima deste ponto
   e têm a mesma especificidade: escritas dentro do bloco de 860px lá no alto,
   elas perdiam para a regra base que vem depois. Foi assim que o padding de
   dedo da aba nunca chegou a valer.
   ═══════════════════════════════════════════════════════════════════════════ */

@media (max-width: 860px) {
  .bp-shell h1 { font-size: 1.4375rem; }

  /* Números em duas colunas e mais baixos: um cartão por linha transformava
     sete números em sete telas de rolagem, e o dono queria ver "quanto
     vendeu" de relance. O ícone sai — no celular o rótulo já basta. */
  .bp-numeros { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .625rem; }
  .bp-numero { padding: .8125rem .875rem; }
  /* 1.0625rem com a base de 18px do celular: "R$ 13.980,00" cabe em meia
     tela de 360px sem cortar. */
  .bp-numero b { font-size: 1.0625rem; }
  .bp-numero span { font-size: .5625rem; margin-top: .3125rem; }
  .bp-numero small { font-size: .625rem; }
  /* Duas classes: o ícone também é um <span>, e `.bp-numero span` lá em
     cima (display: block) ganharia de uma classe só. */
  .bp-numero .bp-numero__icone { display: none; }

  .bp-aba { padding: .9375rem .875rem; }
}

/* Cartão de evento compacto: miniatura à esquerda, nome e data ao lado, os
   números e o atalho de check-in embaixo. O banner de 16:9 a toda largura
   fazia cada evento ocupar uma tela inteira — quatro eventos eram quatro
   rolagens, com um retângulo quase vazio no meio de cada uma. */
@media (max-width: 34rem) {
  .bp-grade-eventos { grid-template-columns: 1fr; gap: .75rem; }

  /* Números e check-in dividem a última linha: numa linha para cada, o
     cartão passava de 290px e voltava a ser uma tela por evento. */
  .bp-evento {
    display: grid; grid-template-columns: 4.5rem minmax(0, 1fr) auto;
    grid-template-areas: "capa corpo corpo" "num num acoes";
    column-gap: .875rem; padding: .875rem;
  }
  .bp-evento__capa { grid-area: capa; align-self: start; border-radius: var(--radius); overflow: hidden; border: 1px solid var(--border); }
  .bp-evento__capa .bp-img { aspect-ratio: 1; }
  .bp-evento__capa .bp-evento__selo { display: none; }
  .bp-evento__selo-linha { display: inline-flex; }
  .bp-evento__corpo { grid-area: corpo; padding: 0; }
  .bp-evento__nome { font-size: .9375rem; margin-bottom: .3125rem; }
  /* `start`, e NÃO `center`. As duas células da última linha — números e
     ações — têm cada uma o seu `border-top`, e juntas formam o que parece
     uma linha só (o `margin-left` negativo de `acoes` cobre o vão da
     grade). Com os números centrados, a borda DELES descia quando o bloco
     era mais curto que o botão, e a "linha única" aparecia partida em dois
     degraus — era o defeito que o dono viu no cartão de rascunho, onde há
     dois números em vez de três.

     Alinhados no topo, as duas bordas nascem no mesmo y e a linha fecha. */
  .bp-evento__numeros {
    grid-area: num; margin: .75rem 0 0; padding: .75rem 0 0; align-self: start;
    display: flex; flex-wrap: wrap; column-gap: 1.125rem; row-gap: .375rem;
  }
  .bp-evento__numeros b { font-size: .9375rem; }
  .bp-evento__numeros span { font-size: .625rem; margin-top: .125rem; }
  /* A linha divisória atravessa as duas colunas da última linha. */
  .bp-evento__acoes {
    grid-area: acoes; margin: .75rem 0 0 -.875rem; padding: .75rem 0 0 .875rem; align-self: stretch;
    border-top: 1px solid var(--border); background: none; align-items: center;
  }
  .bp-evento__abrir { display: none; }
  .bp-evento__atalho { height: 2.75rem; padding: 0 .875rem; }
}

@media (prefers-reduced-motion: reduce) {
  /* Os cartões continuam reagindo ao ponteiro pela cor da borda; só não se
     movem. */
  .bp-acesso, .bp-acesso__seta { transition: none; }
  .bp-acesso:hover { transform: none; }
  .bp-acesso:hover .bp-acesso__seta { transform: none; }
  .bp-shell .bp-esqueleto { animation: none; }
  .bp-menu__lista { animation: none; }
}

/* ── Etiquetas do evento (migration 018) ───────────────────────────────────
   Caixas de seleção desenhadas como chips, agrupadas por gênero e por
   característica. São <label> com <input> escondido, e não <button>: assim
   o teclado e o leitor de tela recebem um grupo de caixas de verdade, com
   estado marcado/desmarcado, em vez de botões que só parecem alternar. */
.bp-etiquetas { display: flex; flex-direction: column; gap: 14px; }
.bp-etiquetas__grupo { display: flex; flex-direction: column; gap: 8px; }
.bp-etiquetas__titulo {
  font-size: .75rem; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--muted-fg);
}
.bp-etiquetas__lista { display: flex; flex-wrap: wrap; gap: 8px; }
.bp-etiquetas__conta { font-size: .75rem; color: var(--muted-fg); }

.bp-etiqueta-op { display: inline-flex; cursor: pointer; }
/* O input some da tela mas continua no fluxo do foco — `display: none` o
   tiraria do Tab e o chip viraria decoração inalcançável pelo teclado. */
.bp-etiqueta-op input {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
.bp-etiqueta-op span {
  display: inline-flex; align-items: center; height: 34px; padding: 0 14px;
  border: 1px solid var(--border-forte); border-radius: 9999px;
  background: var(--card); color: var(--fg);
  font-size: .8125rem; font-weight: 550; white-space: nowrap;
  transition: background .15s, border-color .15s, color .15s;
}
.bp-etiqueta-op:hover span { border-color: var(--muted-fg); }
.bp-etiqueta-op input:checked + span {
  background: var(--primary); border-color: var(--primary); color: var(--primary-fg); font-weight: 650;
}
.bp-etiqueta-op input:focus-visible + span {
  outline: 2px solid var(--primary); outline-offset: 2px;
}
.bp-etiqueta-op--fora { cursor: not-allowed; }
.bp-etiqueta-op--fora span { opacity: .45; }

/* O selo de versão no pé da lateral do painel, abaixo das ferramentas. */
.bp-sidebar__rodape [data-versao] { display: block; padding: 6px 2px 0; text-align: center; }

/* ── A árvore do evento na lateral ─────────────────────────────────────────
   Substitui a barra horizontal de abas, que chegou a nove itens e, em 390px,
   virava uma faixa rolável onde a última seção nunca aparecia sem arrastar.
   Aqui as nove cabem, com o nome inteiro e agrupadas por assunto. */
/* `flex-shrink: 0` em tudo que entra na lateral. `.bp-nav` é uma coluna flex
   com `overflow-y: auto`, e item de flex encolhe por padrão: com a árvore do
   evento aberta a lista passa da altura da tela, e sem isto as linhas eram
   espremidas umas por cima das outras — o nome do evento aparecia cortado ao
   meio, com "Visão geral" escrito por cima. Elas não devem encolher; a
   lateral é que rola. */
.bp-nav__voltar, .bp-nav__evento, .bp-nav__item, .bp-nav__filhos { flex-shrink: 0; }

.bp-nav__voltar {
  display: flex; align-items: center; gap: .5rem;
  padding: .5rem .75rem; margin-bottom: .25rem; border-radius: .5rem;
  font-size: .8125rem; font-weight: 600; color: var(--muted-fg);
}
.bp-nav__voltar svg { width: 1rem; height: 1rem; flex-shrink: 0; }
.bp-nav__voltar:hover { background: var(--muted); color: var(--fg); }
.bp-nav__evento {
  padding: .125rem .75rem .5rem; line-height: 1.3; font-size: .6875rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em; color: var(--muted-fg);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.bp-nav__grupo { display: contents; }
.bp-nav__cabeca { width: 100%; border: 0; background: none; font: inherit; cursor: pointer; text-align: left; }
.bp-nav__cabeca span { flex: 1; min-width: 0; }
.bp-nav__chevron { width: 1rem; height: 1rem; flex-shrink: 0; transition: transform .18s; }
.bp-nav__grupo[data-aberto="true"] .bp-nav__chevron { transform: rotate(180deg); }
/* Fechado some do fluxo E do Tab: `display: none`, e não `height: 0`. Um link
   invisível que o teclado ainda alcança é uma armadilha para quem navega
   sem ver a tela. */
.bp-nav__filhos { display: none; flex-direction: column; }
.bp-nav__grupo[data-aberto="true"] .bp-nav__filhos { display: flex; }
/* O recuo é o que diz "isto pertence ao grupo acima" — por isso os filhos
   não levam ícone: o alinhamento já conta a hierarquia. */
.bp-nav__filho {
  padding-left: 2.625rem; font-size: .8125rem;
}
@media (prefers-reduced-motion: reduce) { .bp-nav__chevron { transition: none; } }

/* O resto do encolhimento da gaveta no celular mora AQUI, e não lá em cima
   junto com as outras regras de `max-width: 860px`.
   O MOTIVO: media query não soma especificidade. Estas três classes são
   definidas logo acima, no fim do arquivo; escrita lá em cima, a versão do
   celular perdia para a definição de baixo e não valia nada — o recuo do
   filho continuava 2.625rem e a fonte .8125rem, como se nada tivesse sido
   escrito. Regra do celular para seletor definido no fim vai no fim. */
@media (max-width: 860px) {
  .bp-nav__voltar { padding: .375rem .625rem; font-size: .75rem; }
  .bp-nav__evento { padding: .125rem .625rem .375rem; font-size: .625rem; }
  /* O recuo tem de bater com ícone + espaço + padding do pai, que no celular
     somam 1 + .5625 + .625 = 2.1875rem. Fora disso o alinhamento deixa de
     contar a hierarquia e o filho fica solto. */
  .bp-nav__filho { padding-left: 2.1875rem; font-size: .75rem; }
}

/* ── Administração da BoomPass (/plataforma/*) ───────────────────────────────
   Peças de public/assets/plataforma-comum.js. O selo de área restrita fica
   SEMPRE no alto das três telas — pedido do dono: "precisa ser claro que essas
   páginas somente administrador pode ter acesso". */
.bp-plat-restrito {
  display: flex; align-items: flex-start; gap: .625rem;
  background: color-mix(in srgb, var(--destructive) 9%, transparent);
  border: 1px solid color-mix(in srgb, var(--destructive) 32%, transparent);
  border-radius: var(--radius); padding: .625rem .875rem; margin: 0 0 1rem;
  font-size: .8125rem; line-height: 1.5; color: var(--fg-forte);
}
.bp-plat-restrito svg { color: var(--destructive); flex: none; margin-top: .0625rem; }
.bp-plat-sobretitulo {
  display: block; font-size: .6875rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--muted-fg); margin-bottom: .25rem;
}
.bp-plat-topo p { max-width: 68ch; }
.bp-plat-secoes { margin: 1rem 0 .75rem; }
/* A gaveta: título da seção da plataforma em vermelho com o escudo, para não
   ser confundida com os itens da organização logo acima. */
.bp-gaveta__secao--plataforma { display: flex; align-items: center; gap: .375rem; color: var(--destructive); }
/* No celular as duas barras QUEBRAM linha em vez de rolar de lado: rolando, a
   última aba (Permissões, Histórico) ficava cortada pela borda e ninguém
   descobre que dá para arrastar uma faixa de navegação. */
@media (max-width: 40rem) {
  .bp-plat-secoes, .bp-plat-abas { flex-wrap: wrap; overflow-x: visible; border-bottom: 0; gap: .25rem .5rem; }
  .bp-plat-secoes .bp-aba, .bp-plat-abas .bp-aba { border: 1px solid var(--border); border-radius: 999px; margin: 0; padding: .4375rem .75rem; }
  .bp-plat-secoes .bp-aba[aria-current="page"], .bp-plat-abas .bp-aba[aria-current="page"] { border-color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, transparent); }
}
.bp-plat-secoes .bp-aba,
.bp-plat-abas .bp-aba { display: inline-flex; align-items: center; gap: .4375rem; }
button.bp-aba { background: none; border: 0; border-bottom: 2px solid transparent; font: inherit; font-size: .8125rem; font-weight: 600; cursor: pointer; }
.bp-plat-abas { margin: 0 0 1.25rem; }
.bp-plat-contador {
  display: inline-block; min-width: 1.25rem; padding: 0 .375rem; border-radius: 999px;
  background: color-mix(in srgb, var(--warning) 22%, transparent); color: var(--fg-forte);
  font-size: .6875rem; line-height: 1.25rem; text-align: center;
}
.bp-plat-contador[hidden] { display: none; }

.bp-paginacao {
  display: flex; align-items: center; justify-content: space-between; gap: .75rem;
  flex-wrap: wrap; margin-top: .75rem; font-size: .8125rem;
}
.bp-paginacao__conta { color: var(--muted-fg); font-variant-numeric: tabular-nums; }
.bp-paginacao__botoes { display: flex; gap: .25rem; flex-wrap: wrap; align-items: center; }
.bp-paginacao__botoes .bp-btn { min-width: 2.25rem; padding-inline: .5rem; justify-content: center; }
.bp-paginacao__lacuna { padding: 0 .25rem; color: var(--muted-fg); }

/* Barra de ferramentas de lista: busca à esquerda, filtros à direita. */
.bp-plat-ferramentas { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; margin-bottom: .75rem; }
.bp-plat-ferramentas .bp-input { flex: 1 1 14rem; min-width: 0; }
.bp-plat-ferramentas .bp-select { flex: 0 1 13rem; }
