/* ============================================================
   vbmendes.dev — moldura das páginas de palestra
   Arquivo gerado: sai junto com os slides, do mesmo lugar que os
   produz. Editar aqui não adianta — a próxima publicação de uma
   palestra sobrescreve.

   O deck em si é HTML vivo: cor, tipografia e layout do slide vêm
   do tokens.css, o mesmo arquivo que o rasterizador usa. Aqui só
   existe o que fica em volta — letterbox, índice, o link de volta e
   os controles do reveal repintados em petróleo.

   Não damos <link> em /styles.css de propósito: as regras de body e
   .pagina de lá disputariam o layout com o reveal.
   ============================================================ */

@font-face {
  font-family: "Poppins"; src: url("/fonts/Poppins-Regular.ttf") format("truetype");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Poppins"; src: url("/fonts/Poppins-Medium.ttf") format("truetype");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono"; src: url("/fonts/JetBrainsMono-Regular.ttf") format("truetype");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono"; src: url("/fonts/JetBrainsMono-Medium.ttf") format("truetype");
  font-weight: 500; font-style: normal; font-display: swap;
}

:root {
  --ink:    #101418;
  --paper:  #FAF9F7;

  --bg:     var(--paper);
  --fg:     var(--ink);
  --dim:    #5F676E;
  --hair:   #E2DED8;
  --card:   #FFFFFF;
  --accent: #00636B;   /* petróleo, degrau de fundo claro */

  --display: "Poppins", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --raio: 14px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg:     var(--ink);
    --fg:     var(--paper);
    --dim:    #8A9198;
    --hair:   #242A31;
    --card:   #171C22;
    --accent: #3BBFB2; /* petróleo, degrau de fundo escuro */
  }
}

/* O reveal mede esta caixa para decidir a escala do slide, então ela precisa
   ser a área realmente visível. No celular `100%` resolve contra o viewport
   grande, o que conta a altura da barra do navegador mesmo enquanto ela está
   na frente: o slide nascia alto demais e a última faixa ficava atrás da
   barra. `dvh` acompanha a barra recolhendo. A página não rola, então o valor
   é estável na prática e não fica remedindo a cada gesto. */
html, body { height: 100%; }
@supports (height: 100dvh) {
  html, body { height: 100dvh; }
}

/* A moldura preta em volta do slide.

   O slide é 16:9 e a tela quase nunca é. O reveal escala o slide para caber
   inteiro e centraliza; o que sobra é esta cor. Num celular em pé sobra
   muito, e é aí que ela vira de fato uma tarja em cima e outra embaixo.

   É tinta em qualquer esquema, e não `var(--bg)`: a faixa é moldura de
   projeção, como a de um vídeo, e trocar de cor com o tema do sistema faria
   o slide claro nadar num campo claro, sem borda nenhuma para o olho achar.
   Os chips continuam legíveis porque são pílulas sólidas, não texto solto. */
body {
  margin: 0;
  background: var(--ink);
  color: var(--fg);
  font-family: var(--display);
  -webkit-font-smoothing: antialiased;
}

/* Só imagem: o conteúdo do slide é o <h2> para leitor de tela e busca. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --- velocidade da troca de slide ----------------------------------------
   0.2s. O reveal só tem três velocidades — 0.8s, `fast` 0.4s e `slow` 1.2s —
   e a mais rápida delas ainda deixa um tempo morto entre o clique e o slide.
   Num deck de composições que sangram, o fade não precisa ser percebido: ele
   existe só para a troca não piscar.

   A regra mora aqui, fora de camada, e por isso vence o `reveal` sem disputa
   de especificidade — o mesmo motivo pelo qual toda a moldura mora neste
   arquivo. Ver o camadas.css. */
.reveal .slides section { transition-duration: .05s; }

/* --- controles do reveal ------------------------------------------------- */
.reveal .controls { color: var(--accent); }
.reveal .progress { color: var(--accent); height: 3px; }
/* Vai para a esquerda: no canto direito ele fica embaixo das setas do reveal,
   e o `51` some atrás do chevron. */
.reveal .slide-number {
  right: auto;
  left: 12px;
  bottom: 12px;
  font-family: var(--mono);
  font-size: .68rem;
  letter-spacing: .1em;
  background: color-mix(in srgb, var(--ink) 62%, transparent);
  color: var(--paper);
  border-radius: 6px;
  padding: .25em .55em;
}

.reveal .slide-number a { text-decoration: none; color: inherit; }

/* --- sumir com a moldura -------------------------------------------------
   Três segundos de mouse parado e tudo que não é slide sai de cena; o
   primeiro movimento traz de volta. Quem liga é o deck.js, e só onde existe
   ponteiro — no toque não há mousemove para desfazer.

   `visibility` junto com `opacity` para o que sumiu não continuar clicável:
   um botão invisível ainda intercepta o clique que ia para o slide. */
.sem-moldura .chip,
.sem-moldura .reveal .controls,
.sem-moldura .reveal .progress,
.sem-moldura .reveal .slide-number {
  opacity: 0;
  visibility: hidden;
  transition: opacity .45s ease, visibility 0s linear .45s;
}

/* --- link de volta e botões ----------------------------------------------
   Os da direita vão num flex, para que entrar ou sair um botão não obrigue a
   recalcular o `right` de todos os outros na mão. */
/* Os `env()` são para quando não há barra de navegador para empurrar a página
   para baixo: instalado na tela de início, o deck começa colado no topo, e sem
   isso os chips ficariam embaixo do notch e da barra de status. Numa aba
   comum os valores são zero e nada muda. */
.voltar {
  position: fixed;
  top: calc(1rem + env(safe-area-inset-top));
  left: calc(1rem + env(safe-area-inset-left));
  z-index: 40;
}

.cromo-dir {
  position: fixed;
  top: calc(1rem + env(safe-area-inset-top));
  right: calc(1rem + env(safe-area-inset-right));
  z-index: 40;
  display: flex;
  align-items: center;
  gap: .5rem;
}

.chip {
  font-family: var(--mono);
  font-size: .68rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--fg);
  background: var(--card);
  border: 1px solid var(--hair);
  border-radius: 999px;
  padding: .5rem .9rem;
  text-decoration: none;
  box-shadow: 0 1px 2px rgba(16, 20, 24, .06);
  /* Some por baixo do slide até o ponteiro chegar perto: em cima do fundo
     de um slide claro, um botão claro some; em cima de um escuro, grita. */
  opacity: .32;
  transition: opacity .18s ease;
}

.indice > summary { cursor: pointer; list-style: none; }
.indice > summary::-webkit-details-marker { display: none; }

.chip:hover, .chip:focus-visible,
.indice[open] > summary { opacity: 1; color: var(--accent); }

/* --- link do PDF ---------------------------------------------------------
   O peso vai no rótulo: 17 MB começando a baixar sem aviso, numa rede de
   evento, é uma surpresa ruim. */
.pdf { display: flex; align-items: baseline; gap: .45rem; }
.pdf .peso { opacity: .6; letter-spacing: .08em; }

/* --- botão de tela cheia -------------------------------------------------
   O reveal já tem o atalho F, mas nada visível. Quem chega pelo link não
   adivinha um atalho. */
.tela-cheia {
  display: grid;
  place-items: center;
  width: 2.35rem;
  height: 2.35rem;
  padding: 0;
  cursor: pointer;
  font: inherit;
}

.tela-cheia svg { width: 1rem; height: 1rem; display: block; }
.tela-cheia .sair,
.em-tela-cheia .tela-cheia .entrar { display: none; }
.em-tela-cheia .tela-cheia .sair { display: block; }

/* --- modo imersivo: onde não há Fullscreen API ----------------------------
   Chrome no iPhone roda em WKWebView, e ali a API só existe se o app
   hospedeiro ligar `isElementFullscreenEnabled`, o que o Chrome não faz.

   Mas a barra do navegador não é intocável: Chrome e Safari recolhem a
   própria barra quando a página rola. Todo site comum ganha isso de graça — e
   o deck não ganhava porque o reveal declara `touch-action: pinch-zoom` no
   `.reveal` e `overflow: hidden` no `html.reveal-full-page`. Sem pan e sem
   rolagem, o navegador nunca recebe o gesto que recolheria a barra. O modo
   imersivo desfaz as duas coisas, e só enquanto está ligado.

   Some a nossa moldura e recolhe a do navegador. O que sobra é o botão,
   esmaecido: no toque não há `mousemove` para trazer a moldura de volta, e
   sem ele o modo não teria saída. */
.imersivo .chip:not(.tela-cheia),
.imersivo .indice,
.imersivo .reveal .controls,
.imersivo .reveal .progress,
.imersivo .reveal .slide-number {
  opacity: 0;
  visibility: hidden;
  transition: opacity .45s ease, visibility 0s linear .45s;
}
.imersivo .tela-cheia { opacity: .28; }

/* Devolve o arrasto vertical ao navegador — é ele que recolhe a barra. O
   swipe horizontal continua chegando ao reveal, porque `pan-y` não permite
   pan horizontal: o navegador não tem o que fazer com aquele gesto e deixa
   passar. O que se perde é o swipe vertical de navegação, e este deck não tem
   pilha vertical: as seções são todas irmãs. */
html.imersivo .reveal { touch-action: pan-y pinch-zoom; }

/* Destrava a rolagem que o reveal prendeu. `html.reveal-full-page` é dele e
   traz `height: 100dvh; overflow: hidden`; o `.reveal-viewport` (que fora do
   modo `embedded` é o próprio body) traz outro `overflow: hidden`. */
html.imersivo.reveal-full-page {
  height: auto;
  overflow: visible;
}

.imersivo body,
.imersivo .reveal-viewport {
  height: auto;
  overflow: visible;
  /* O arrasto é para recolher a barra, não para dar bounce nem para recarregar
     a página no meio de uma apresentação. */
  overscroll-behavior: none;
}

/* O slide fica preso: quem rola é a página em volta dele, e o único efeito
   visível da rolagem é a barra do navegador saindo.

   `dvh`, e não `lvh`. Já foi `lvh` — o viewport com a barra recolhida, que é o
   estado final — para poupar o reveal de reescalar durante o recolhimento. Era
   errado: enquanto a barra está lá, `lvh` é maior que o visível e o slide nasce
   com o pé cortado. Em paisagem, onde a barra come mais altura, o corte comia a
   linha de créditos. `dvh` acompanha, o slide sempre cabe inteiro, e reescalar
   é o preço certo a pagar por isso. */
html.imersivo .reveal {
  position: fixed;
  inset: 0;
  height: 100dvh;
}

/* O curso de rolagem. O iOS não recolhe a barra por um pixel de sobra: precisa
   de um arrasto com distância. Este espaçador é criado pelo deck.js ao entrar
   no modo e removido ao sair — conteúdo nenhum, só curso. */
.respiro {
  height: 120px;
  margin-top: 100dvh;
  pointer-events: none;
}

/* --- a dica do iPhone -----------------------------------------------------
   Nenhum navegador do iPhone faz fullscreen de elemento. O que existe é
   arrastar (o navegador recolhe a própria barra) e instalar na tela de início
   (onde não há barra). Nenhum dos dois é descobrível, e por isso a dica.

   Aparece só depois que a pessoa toca no botão — responde a um pedido, não
   interrompe a leitura. Fica embaixo e no centro, longe do número do slide
   (que é embaixo à esquerda) e do polegar que tocou no botão lá em cima. */
.dica {
  position: fixed;
  left: 50%;
  bottom: calc(1.15rem + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 50;
  max-width: calc(100vw - 2rem);
  font-family: var(--mono);
  font-size: .66rem;
  letter-spacing: .06em;
  display: flex;
  flex-direction: column;
  gap: .3rem;
  text-align: center;
  color: var(--paper);
  background: color-mix(in srgb, var(--ink) 88%, transparent);
  border: 1px solid color-mix(in srgb, var(--paper) 22%, transparent);
  border-radius: 999px;
  padding: .6rem 1rem;
  box-shadow: 0 6px 18px rgba(16, 20, 24, .35);
  animation: dica-entra .25s ease both;
}

/* A segunda linha é a rota definitiva, e por isso não é o destaque: quem está
   no meio de uma apresentação quer o gesto, não uma instalação. */
.dica-instalar {
  color: var(--accent);
  text-decoration: none;
  opacity: .85;
  font-size: .62rem;
}

@keyframes dica-entra {
  from { opacity: 0; transform: translate(-50%, .5rem); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .dica { animation: none; }
}

/* Os controles do reveal entram no mesmo desvanecer da moldura. */
.reveal .controls,
.reveal .progress,
.reveal .slide-number { transition: opacity .3s ease; }

/* --- índice das seções --------------------------------------------------- */
.indice { position: relative; z-index: 40; }

.indice nav {
  position: fixed;
  top: 3.6rem;
  right: 1rem;
  z-index: 40;
  width: min(23rem, calc(100vw - 2rem));
  max-height: min(70vh, 34rem);
  overflow-y: auto;
  background: var(--card);
  border: 1px solid var(--hair);
  border-radius: var(--raio);
  box-shadow: 0 10px 30px rgba(16, 20, 24, .18);
  padding: .5rem;
}

.indice ol { list-style: none; margin: 0; padding: 0; counter-reset: secao; }

.indice a {
  display: block;
  padding: .6rem .75rem;
  border-radius: 9px;
  text-decoration: none;
  color: var(--fg);
}

.indice a:hover, .indice a:focus-visible {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  color: var(--accent);
  outline: none;
}

.indice .kicker {
  display: block;
  font-family: var(--mono);
  font-size: .6rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: .2rem;
}

.indice .salto-titulo {
  display: block;
  font-size: .95rem;
  font-weight: 500;
  line-height: 1.3;
}

/* Sem ponteiro não há hover para acender o chip, nem `mousemove` para desfazer
   o sumiço por ociosidade: a moldura fica, e fica legível.

   A condição é `hover: none` e não largura. Largura errava o caso mais comum:
   um celular deitado tem 844px, passava longe de qualquer limiar de "telefone"
   e os botões ficavam nos 32% de opacidade para sempre, sem hover que os
   trouxesse de volta. */
@media (hover: none) {
  .chip { opacity: 1; }
}

/* Espaço curto: fica o rótulo, sai o peso do arquivo. */
@media (max-width: 34rem) {
  .pdf .peso { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .chip, .indice a,
  .reveal .controls, .reveal .progress, .reveal .slide-number { transition: none; }
  /* O sumiço continua — quem pediu menos movimento não pediu mais interface. */
}

@media print {
  .voltar, .cromo-dir { display: none; }
}
