/* ============================================================================
   CSS REAPROVEITADO DA SEPSE — Módulo 2 (S20–S25).
   Extraído em 14/11/2026 de H:/Aulas Fernando/04-deck/css/scenes.css e
   worlds.css, só o que as cenas reaproveitadas precisam. Ids renomeados:
     sepse S10 (linha do tempo)        → S20, S21, S22
     sepse S12 (IA generativa)         → S23
     sepse S13 (morph fórmula → rede)  → S24
     sepse S15 (hoje e o que erram)    → S25
   Os comentários internos são os da sepse e citam os ids ANTIGOS; ficaram
   porque explicam medidas que não são óbvias. Adaptar junto com as cenas.
   ========================================================================== */

/* --- scenes.css 14–23 · tamanhos de exceção ----------------------------- */
/* --- Os quatro tamanhos que o roteiro exige literalmente e que a escala
   tipográfica de §4.3 não tem. Ficam escopados no palco, e não em :root, para
   deixar explícito que são exceções de cena e não tokens do sistema. Se
   qualquer um deles for reutilizado numa terceira cena, promova a tokens.css. */
.stage {
  --fs-formula: 7rem;   /* 112px — fórmula do attention (S10, S13)           */
  --fs-timer:  5.5rem;  /* 88px  — cronômetro da demo e numerais da S26      */
  --fs-kpi:      4rem;  /* 64px  — os 4 indicadores da S18                   */
  --fs-72m:    4.5rem;  /* 72px  — blocos de dado em mono (S11, S14)         */
}

/* --- worlds.css 277–326 · o cartão flutuante (.float) e o drift ----------- */
.float {
  --z-blur: 0px; --z-op: 1; --z-scale: 1;
  --ax: .5rem; --ay: .875rem; --rot: 0deg; --del: 0s;
  /* --fw = largura do cartão. Vem das classes de tamanho abaixo; 0 aqui para
     que um .float sem classe de tamanho não invalide o min() do `left`. */
  --fw: 0px;
  /* --dur NÃO tem valor aqui de propósito: o padrão é de cada mundo (abaixo),
     e o drift.js sobrescreve por elemento, inline, dentro da faixa de §3.4. */
  position: absolute;
  /* A tabela canônica ancora o CANTO do cartão, não o centro, e não conhece a
     largura dele: um chip a --x:82% da faixa começa em 722px e termina em
     960px — 80px além do palco, e no telão "Gemini" vira "Gemin". O min()
     prende pela borda externa da faixa quem não caberia. Quem já cabia não
     sai do lugar, então a composição da tabela é preservada. --ax entra na
     conta porque o drift ainda vai empurrar o cartão até essa amplitude: sem
     reservá-la, quem fica rente à borda sai dela meio ciclo depois. */
  left: min(var(--x, 50%), calc(100% - var(--fw) - var(--ax))); top: var(--y, 50%);
  transform: translate3d(0, 0, 0) scale(var(--z-scale));
  filter: blur(var(--z-blur));
  opacity: var(--z-op);
  animation: drift var(--dur, 15s) var(--del) cubic-bezier(.37, 0, .63, 1) infinite alternate;
  will-change: transform;
}

/* Profundidade. O blur do fundo é o que faz a tela ter ar em vez de ter
   colagem — e é de graça, porque não anima. */
.float[data-z="1"] { --z-blur: 2.5px; --z-op: .42; --z-scale: .86 }
.float[data-z="2"] { --z-blur: 1px;   --z-op: .75; --z-scale: .94 }
.float[data-z="3"] { --z-blur: 0;     --z-op: 1;   --z-scale: 1   }

@keyframes drift {
  from { transform: translate3d(calc(var(--ax) * -1), calc(var(--ay) * -1), 0)
                    rotate(calc(var(--rot) * -1)) scale(var(--z-scale)) }
  to   { transform: translate3d(var(--ax), var(--ay), 0)
                    rotate(var(--rot)) scale(var(--z-scale)) }
}

/* Amplitude reduzida durante fala densa (S19, S23, S19B, S29, S25 — regra 11
   de §5.3). Desde 10/08 o gatilho existe: a cena declara data-amp="low" e o
   deck.js (syncChrome) copia para o palco a cada troca. Nota honesta: essas
   cenas não têm .float hoje (o tabuleiro só vive em S07–S09, S21–S22), então
   o efeito visível é nulo — o gancho fica real e reconciliado para o dia em
   que uma cena densa tiver elemento em drift. */
.stage[data-amp="low"] .float { animation-name: driftLow }
@keyframes driftLow {
  from { transform: translate3d(calc(var(--ax) * -.3), calc(var(--ay) * -.3), 0)
                    scale(var(--z-scale)) }
  to   { transform: translate3d(calc(var(--ax) * .3), calc(var(--ay) * .3), 0)
                    scale(var(--z-scale)) }
}

/* --- worlds.css 351–383 · tamanhos e chips minimizados -------------------- */
/* A largura passa por --fw porque o `left` do .float precisa dela para prender
   o cartão na borda da faixa. Declarar nos dois lugares abriria a porta para
   os dois valores divergirem. */
.float--xl { --fw: 46rem; width: var(--fw) }  /* 736px — a fórmula do attention */
.float--lg { --fw: 34rem; width: var(--fw) }  /* 544px — protocolo, prontuário  */
.float--md { --fw: 25rem; width: var(--fw) }  /* 400px — POP, formulário, DO    */
.float--sm { --fw: 17rem; width: var(--fw) }  /* 272px — SBAR, cálculo, chips   */

/* O chip de marca não tem largura de classe: a largura dele é o nome que
   carrega, de "Gemini · Google" a "Copilot · Microsoft". Não recebe `width` —
   continua intrínseco —, só o teto que o min() do `left` precisa conhecer.
   Literal local: 22rem = 352px, o mais largo medido (338px) arredondado para
   cima. Vem depois de .float--sm de propósito: os chips das S21/S22 herdam
   aquela classe, e 272px não bastariam para segurar o chip do Claude. */
.float.brand-chip { --fw: 22rem }

/* --- Chips minimizados (S13, fase 3: a fileira do rodapé) ---------------- */
/* `position: relative` e o par left/top em `auto` são o que faz a fileira
   existir. Sem eles o chip continua obedecendo ao posicionamento absoluto
   de .float — left do min(), top de --y — e os nove pousam empilhados no
   mesmo ponto, um por cima do outro e por cima da referência do rodapé. */
.float[data-min="1"] {
  position: relative; left: auto; top: auto;
  height: 4rem; width: auto; padding: 0 var(--sp-3);
  display: inline-flex; align-items: center; gap: var(--sp-2);
  opacity: .5; animation: none; filter: none;
  font: 600 var(--fs-label)/1 var(--font-body);
  letter-spacing: var(--tr-label); text-transform: uppercase;
  overflow: hidden; white-space: nowrap;
}
/* Minimizado, o chip carrega só o nome: a nota técnica do cartão de cálculo
   ("d_model · h · d_k") triplicaria a largura dele na fileira. */
.float[data-min="1"] .t-ref { display: none }

/* --- scenes.css 605–688 · fórmula, grade fluida, seta (sepse S12 → S23) --- */
/* ============================================================================
   ATO II — O MUNDO DA IA
   ========================================================================== */

/* --- S12 · A máquina toma a tela · 0:30 --------------------------------- */
/* Era a S10 até 12/08/2026: a reordenação do Ato II trocou esta cena com a da
   linha do tempo. Os seletores por classe (.formula-band, .rule-30,
   .grid-fluid, .split-arrow) não mudaram — só o id da cena que os hospeda. */
/* A faixa da fórmula ocupa os 30% superiores: top 96px, altura 324px. */
.formula-band {
  position: absolute; left: 0; right: 0; top: 6rem; height: 20.25rem;
  display: grid; place-items: center; z-index: 5;
}
.formula {
  font-size: var(--fs-formula); color: var(--ai-glow); line-height: 1;
  /* drop-shadow e não text-shadow: §5.3 proíbe sombra de texto para destacar
     sobre fundo, e o filtro é o que a lista de animáveis permite. */
  filter: drop-shadow(0 0 3.75rem rgba(125, 226, 230, .35));
}
/* .formula--small era o eco de 56px que abria a S11 enquanto ela vinha DEPOIS
   da fórmula. Com a reordenação de 12/08 a S11 passou a vir antes, e o eco
   viraria spoiler — a regra fica porque a classe é genérica e barata, mas
   hoje ela não tem nenhum uso no deck. */
.formula--small { font-size: var(--fs-h1); opacity: .35 }
/* A régua da linha dos 30% — 96 + 324 = 420px. */
.rule-30 {
  position: absolute; left: 0; right: 0; top: 26.25rem; height: 1px;
  background: rgba(125, 226, 230, .18); z-index: 5;
}
/* Grade fluida 3×3. O offset de ±16px por célula é deliberado: alinhada
   perfeitamente, a grade lê como planilha e mata o clima da cena. */
/* `bottom: --ref-band` e não --margin-v: desde 12/08 esta cena tem faixa de
   provas no pé, e a grade tem de parar acima dela. É a mesma reserva que a
   S26 faz para a citação. */
.grid-fluid {
  position: absolute; left: var(--margin-h); right: var(--margin-h);
  /* + --sp-2 de folga: o offset de +1rem da 8ª célula (Embeddings · RAG)
     encostava a borda dela no topo da faixa. */
  top: 29rem; bottom: calc(var(--provas-band) + var(--sp-2));
  display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr);
  gap: var(--sp-4); z-index: 4;
}
.grid-fluid > .float {
  position: relative; left: auto; top: auto; width: auto;
  transform: translate(var(--off-x, 0), var(--off-y, 0)) scale(.86);
  animation: none;
}
.grid-fluid > .float:nth-child(1) { --off-x:  1rem; --off-y: -1rem }
.grid-fluid > .float:nth-child(2) { --off-x: -1rem; --off-y:  1rem }
.grid-fluid > .float:nth-child(3) { --off-x:  1rem; --off-y:  1rem }
.grid-fluid > .float:nth-child(4) { --off-x: -1rem; --off-y: -1rem }
.grid-fluid > .float:nth-child(5) { --off-x:  1rem; --off-y:  1rem }
.grid-fluid > .float:nth-child(6) { --off-x: -1rem; --off-y:  1rem }
.grid-fluid > .float:nth-child(7) { --off-x:  1rem; --off-y: -1rem }
.grid-fluid > .float:nth-child(8) { --off-x:  1rem; --off-y:  1rem }
.grid-fluid > .float:nth-child(9) { --off-x: -1rem; --off-y: -1rem }

.split-arrow {
  display: flex; align-items: center; gap: var(--sp-4);
  opacity: 0; transition: opacity var(--dur-base);
}
.scene[data-beat="1"] .split-arrow { opacity: 1 }
.split-arrow__pred { color: var(--primary-soft) }
.split-arrow__gen  { color: var(--ai-core) }
/* A variante da S12 desde 12/08: três definições e um número, no lugar da
   seta preditiva⟶generativa. `space-evenly` e não `center` porque agora são
   quatro blocos de larguras muito diferentes, e centralizados eles encostam. */
.split-arrow--gen { justify-content: space-evenly; gap: var(--sp-3) }
.split-arrow--gen b { font-weight: 800 }
/* A régua tem 1px de altura e o conteúdo transborda para os dois lados a
   partir do centro. Com o stat em --fs-d3 (72px) ele descia até dentro da
   primeira fileira da grade — em --fs-h1 a linha inteira cabe entre a
   fórmula e o `top` da .grid-fluid, que também recuou. */
.gen-stat {
  display: flex; align-items: baseline; gap: var(--sp-2);
  font: 700 var(--fs-h1)/1 var(--font-mono); color: var(--ai-core);
  font-variant-numeric: tabular-nums;
}
#S23 .grid-fluid { top: 31rem }
.gen-stat i {
  font: 500 var(--fs-body)/1.2 var(--font-body); font-style: normal;
  color: var(--txt-low);
}


/* --- scenes.css 791–921 · linha do tempo (sepse S10 → S20–S22) e morph (S13 → S24) */
/* --- S12 · 1950 → 2017 · 0:30 · data-cut="1" ---------------------------- */
:is(#S20, #S21, #S22) .tl { position: absolute; left: 12rem; right: 12rem; top: 33.75rem; height: 0; z-index: 3 }
.tl::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 2px;
  background: rgba(255,255,255,.14);
}
.tl__mark {
  position: absolute; left: var(--x); top: 0; transform: translateX(-50%);
  transition: transform var(--dur-fast) var(--ease-in-out), opacity var(--dur-fast);
  transition-delay: calc(var(--i, 0) * 40ms);
}
.tl__node {
  width: 1.5rem; height: 1.5rem; border-radius: var(--r-full);
  background: var(--txt-low); transform: translateY(-50%);
}
.tl__label {
  position: absolute; left: 50%; transform: translateX(-50%); width: 15rem;
  text-align: center; font: 500 var(--fs-body)/1.2 var(--font-body); color: var(--txt-mid);
}
.tl__mark:nth-child(odd)  .tl__label { bottom: 2.5rem }
.tl__mark:nth-child(even) .tl__label { top: 2.5rem }
.tl__mark[data-key="1"] .tl__node {
  background: var(--accent); transform: translateY(-50%) scale(2);
}
.tl__mark[data-key="1"] .tl__label { color: var(--txt-high); font-weight: 700 }
.tl__curve { fill: none; stroke-width: 6; stroke-linecap: round }
/* Todos os marcos anteriores a 2017 colapsam para dentro do de 2017. */
:is(#S20, #S21, #S22)[data-beat="1"] .tl__mark:not([data-key="1"]) {
  transform: translateX(-50%) scale(0); opacity: 0;
}

/* --- S13 · O morph: fórmula → rede neural · 0:55 · assinatura ----------- */
#S24 .kqv { color: var(--accent) }
.callout {
  font: 500 var(--fs-body)/1.3 var(--font-body); color: var(--txt-mid);
  transition: opacity 200ms;
}
/* A régua dos 30% e os três callouts pertencem à fórmula, não à rede: depois
   do morph a régua vira um traço horizontal atravessando o meio do desenho.
   Some junto com os callouts, na mesma janela de 200 ms. */
#S24 .rule-30 { transition: opacity 200ms }
/* A faixa de provas entra na lista: nada divide a tela com o morfismo. Ela
   desce junto com a régua e os callouts, na mesma janela de 200 ms. */
#S24 .provas { transition: opacity 200ms }
#S24[data-beat="1"] .rule-30,
#S24[data-beat="1"] .provas,
#S24[data-beat="1"] .callout { opacity: 0 }
/* Canvas das ~3.400 partículas. Vive por cima da fórmula e some no handoff. */
/* width/height explícitos porque <canvas> é elemento SUBSTITUÍDO: inset:0
   sozinho não o estica — com width:auto ele fica no tamanho intrínseco de
   300×150 no canto, e o morph desenha em 0 pixels visíveis. Foi exatamente o
   que aconteceu até 11/08: morph:start nunca disparava e a cena de assinatura
   rodava sem a sua coreografia, mascarada em headless pelo caminho instantâneo
   do prefers-reduced-motion. */
.morph-canvas { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 6; pointer-events: none }

/* A rede neural viva (SVG, depois do handoff — §3.3, passo 4). */
.net { display: block; width: 68.75rem; margin: 0 auto }
.net-edge  { stroke: var(--primary-soft); stroke-width: 2; stroke-opacity: .35; fill: none }
.net-pulse {
  stroke: var(--ai-glow); stroke-width: 3; stroke-linecap: round; fill: none;
  stroke-dasharray: 26 900; stroke-dashoffset: 926;
  animation: netFlow 2.2s linear infinite calc(var(--i, 0) * -.11s);
}
@keyframes netFlow { to { stroke-dashoffset: 0 } }
/* O nó respira por transform, não por animação do atributo r: geometria de
   SVG não está na lista de propriedades animáveis do projeto. */
.net-node {
  fill: var(--bg-800); stroke: var(--ai-glow); stroke-width: 2.5;
  transform-box: fill-box; transform-origin: center;
  animation: netBreathe 3.4s ease-in-out infinite calc(var(--i, 0) * -.2s);
}
@keyframes netBreathe { 50% { transform: scale(1.16); stroke-opacity: 1 } }
.net--small { transform: scale(.4); transform-origin: right center }

/* O SÍMBOLO "O TRANSFORMADOR" (§3.6) — desenho ORIGINAL nosso.
   A marca da Hasbro nunca é desenhada: a piada é falada. Os três chevrons
   são Q, K e V — e a legenda de baixo é o easter egg da QKV Works, plantado
   na S02 ("vocês vão entender daqui a dez minutos") e colhido aqui. */
.tf-wrap { perspective: 56.25rem }
.tf-mark { display: block; width: 13.75rem; height: 13.75rem; margin: 0 auto }
.tf-shell {
  stroke-dasharray: 640; stroke-dashoffset: 640;
  animation: tfDraw .55s cubic-bezier(.65, 0, .35, 1) forwards;
}
.tf-half {
  transform-box: fill-box; transform-origin: center left; opacity: 0;
  animation: tfUnfold .5s .35s var(--ease-overshoot) forwards;
}
.tf-r { transform-origin: center right }
.tf-seam {
  stroke-dasharray: 190; stroke-dashoffset: 190;
  animation: tfDraw .4s .55s ease-out forwards;
}
/* Desenha e, em repouso, pulsa em cascata: parece um sinal descendo pelas
   camadas. Longhand porque são duas animações com atrasos diferentes. */
.tf-chev path {
  stroke-dasharray: 110; stroke-dashoffset: 110;
  animation-name: tfDraw, tfChev;
  animation-duration: .34s, 2.4s;
  animation-delay: calc(.72s + var(--i, 0) * .11s), calc(1.1s + var(--i, 0) * .2s);
  animation-timing-function: cubic-bezier(.65, 0, .35, 1), ease-in-out;
  animation-iteration-count: 1, infinite;
  animation-fill-mode: forwards, none;
}
@keyframes tfDraw   { to { stroke-dashoffset: 0 } }
@keyframes tfUnfold { from { transform: rotateY(78deg); opacity: 0 }
                      to   { transform: rotateY(0);     opacity: 1 } }
@keyframes tfChev   { 50% { opacity: .6 } }
.tf-legend {
  text-align: center; margin-top: var(--sp-2);
  font: 600 var(--fs-label)/1 var(--font-mono);
  letter-spacing: .28em; color: var(--txt-low);
}

/* A fileira dos nove chips minimizados não é rodapé nesta cena: é o terço
   inferior da composição — símbolo, rede, e embaixo os nove nomes que a
   plateia reconhece. Ancorada pelo topo (50rem = 800px) porque a altura dela
   depende de quantas fileiras o wrap produzir, e é o topo que precisa ficar
   à distância certa da rede. O teto de 80rem força a quebra em 5 + 4: em
   1728px de largura útil o wrap natural daria 7 + 2, que lê como sobra.
   A fileira é o desfecho da cena e não infraestrutura, então não herda o
   .35 de opacidade da S22. */
#S24 .infra-row {
  top: 50rem; bottom: auto;
  max-width: 80rem; margin-inline: auto;
  flex-wrap: wrap; row-gap: var(--sp-2);
  opacity: 1;
}
#S24 .infra-row .float[data-min="1"] { opacity: .8 }


/* --- scenes.css 1303–1306 · fileira de infraestrutura (destino do morph) -- */
.infra-row {
  position: absolute; left: var(--margin-h); right: var(--margin-h); bottom: var(--margin-v);
  display: flex; gap: var(--sp-3); justify-content: center; opacity: .35; z-index: 35;
}

/* --- scenes.css 1059–1075 · sepse S15 → S25 ------------------------------ */
/* --- S15 · O que eles são hoje (e o que eles erram) · 0:40 · cut 2 ------ */
#S25 .chips-row { display: flex; gap: var(--sp-3); justify-content: center; align-items: center }
#S25 .chips-row .brand-chip { height: 6rem; padding: 0 var(--sp-4); font-size: var(--fs-h2) }
/* ⚑ O balão de destaque do OpenEvidence tem espaço reservado, mas os números
   que o roteiro sugere (~45% dos médicos dos EUA, >20 mi de consultas/mês,
   +38% do "não sei" e o 43%→99% do RAG) estão em §4.3 da lista de números
   aprovados — SEM ENTRADA. Enquanto não migrarem para a lista branca, o
   balão só pode conter a ordem de grandeza dita em voz alta, sem dígito. */
.balloon-acc {
  border: 2px solid var(--accent); border-radius: var(--r-lg);
  background: rgba(230,57,70,.10); padding: var(--sp-2) var(--sp-3);
  font: 600 var(--fs-body)/1.2 var(--font-body); color: var(--accent-soft);
}
#S25 .defenses { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: var(--sp-4) }
#S25 .defenses > * { display: grid; grid-template-columns: 2rem 1fr; gap: var(--sp-2); align-items: start }
#S25 .defenses svg { width: 2rem; height: 2rem; color: var(--accent) }


/* --- worlds.css 586–593 · leitura no celular (sepse S12/S13 → S23/S24) --- */
@media (max-width: 900px) {
  #S23 .grid-fluid, #S24 .grid-fluid {
    display: flex; flex-wrap: wrap; gap: .625rem; margin: 1rem 0;
  }
  #S23 .grid-fluid .float, #S24 .grid-fluid .float {
    margin: 0; padding: .5rem .875rem; width: auto !important;
    min-height: 0; background-image: none;
  }
  #S23 .grid-fluid .float .t-ref, #S24 .grid-fluid .float .t-ref { display: none }
}

/* --- scenes.css 2181–2196 · degradações do morph (sepse) -----------------
   Movimento reduzido: o pulso e a respiração da rede param. Sem isto o
   verifica-ida-volta acusou 0,565% de pixels diferentes na S24 (14/11): o
   motor encurta toda animação para 200 ms no modo reduzido, e o pulso
   infinito da rede vira pisca-pisca, diferente a cada print. */
@media (prefers-reduced-motion: reduce) {
  .net-pulse, .net-node, .tf-chev path { animation: none !important }
}
:root[data-motion="reduced"] .net-pulse,
:root[data-motion="reduced"] .net-node { animation: none !important }

/* --- scenes.css 2371–2375 · S24 no modo de leitura: o morph nunca roda ---- */
@media (max-width: 900px) {
  .net { width: 100%; height: auto }
  #S24 .net { opacity: 1 !important }
  #S24 .tf-wrap, #S24 .morph-canvas { display: none }
}
