/* ===== BEATRIZ — HUD (redesign v1.2) sobre a base ATHENA =====
   REMAPEAMENTO DE PALETA (design system, seção 2.2 — ver tokens.css): as variáveis
   LEGADAS abaixo viraram ALIASES dos tokens novos. É isto que troca a paleta do app
   inteiro sem reescrever as ~2.500 linhas deste arquivo. REGRA: não reintroduzir hex
   nas legadas — cor muda SÓ no tokens.css. (--ok saiu daqui de propósito: o token de
   mesmo nome em tokens.css é a definição única — redefinir aqui seria colisão.) */
:root{
  --bg:var(--bg-0); --bg2:var(--bg-1); --panel:var(--bg-2); --panel2:var(--bg-3);
  --line:var(--stroke-1); --line2:var(--stroke-2);
  --ink:var(--text-1); --ink-dim:var(--text-2); --muted:var(--text-3);
  --blue:var(--ciano); --violet:var(--proc); --teal:var(--ok); --gold:var(--warn);
  --danger:var(--crit);
  --tier-core:var(--serie-2); --tier-breadth:var(--serie-3); --tier-depth:var(--serie-4);
  --glow:0 0 24px var(--ciano-halo);
  --rail-w:88px; --dock-w:380px;
  /* Default de --rail-user, espelhando o --dock-user logo abaixo. NÃO é decorativo: se a classe
     .rail-manual existisse sem a variável, `body{--rail-w:var(--rail-user)}` viraria guaranteed-invalid
     — e --rail-w no body NÃO herdaria os 88px do :root, então .rail{width} e .stage{left} cairiam para
     `auto` e o layout inteiro sairia do lugar. Hoje é inalcançável (os dois escritores setam a variável
     ANTES da classe: index.html anti-flash e app.js applyRailWidth; o reset remove a classe antes da
     variável), mas o dock tem essa rede e o rail não tinha. */
  --rail-user:88px;
  /* Largura MANUAL do dock (alca de arrasto). O JS escreve SO esta variavel (no <html>) — nunca --dock-w
     direto, senao o inline venceria o @media mobile que zera --dock-w e a .stage reservaria margem para um
     dock invisivel. Quem aplica e a regra html.dock-manual body la embaixo. Ver public/dockkit.js. */
  --dock-user:380px;
  /* Largura do dock ENQUANTO A AULA TOCA (fDW). MEDIDA na tela do Richard (1536px de janela), nao cravada de
     cabeca: e a largura ate onde ele estreitou o dock na mao para assistir. Quem aplica e a regra
     body.lesson-live la embaixo; aqui so o numero, para ficar ao lado das outras larguras do dock. */
  --dock-lesson:330px;
  /* TAMANHO do retrato da Athena (alca de arrasto do avatar). 176px == o valor que estava CRAVADO em
     `.avatar-stage{height:176px}` antes desta rodada: quem nunca arrastar ve exatamente o de sempre.
     Governa a ALTURA do palco; a LARGURA da figura acompanha sozinha, na proporcao, porque a .avatar-img e
     object-fit:contain limitada por max-height. Ver public/avatarkit.js (a autoridade da faixa).
     Mesma REGRA DE OURO do dock/rail: o JS escreve SO --avatar-user (no <html>) + a classe .avatar-manual;
     quem aplica e a regra html.avatar-manual la embaixo. O default de --avatar-user e a mesma rede do
     --rail-user: sem ele, a classe sem a variavel viraria guaranteed-invalid e o palco perderia a altura. */
  --avatar-h:176px; --avatar-user:176px;
  --h-sans:'Space Grotesk',system-ui,sans-serif; --h-disp:'Orbitron',sans-serif;
  --b-sans:'Inter',system-ui,sans-serif; --mono:'JetBrains Mono',monospace;
}
*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{
  background:var(--bg); color:var(--ink); font-family:var(--b-sans);
  font-size:14.5px; overflow:hidden; -webkit-font-smoothing:antialiased;
}
.bg-grid{position:fixed;inset:0;z-index:0;pointer-events:none;
  background-image:linear-gradient(rgba(120,160,255,.05) 1px,transparent 1px),linear-gradient(90deg,rgba(120,160,255,.05) 1px,transparent 1px);
  background-size:46px 46px;mask-image:radial-gradient(ellipse 80% 70% at 50% 30%,#000 30%,transparent 100%);}
.bg-glow{position:fixed;inset:0;z-index:0;pointer-events:none;
  background:radial-gradient(700px 460px at 22% 0%,rgba(77,163,255,.12),transparent 60%),radial-gradient(700px 520px at 95% 20%,rgba(139,123,255,.10),transparent 60%);}

/* ---- Topbar ---- */
.topbar{position:fixed;top:0;left:0;right:0;height:60px;z-index:5;
  display:flex;align-items:center;justify-content:space-between;padding:0 22px;
  background:linear-gradient(180deg,rgba(8,12,22,.92),rgba(8,12,22,.55));
  border-bottom:1px solid var(--line);backdrop-filter:blur(10px);}
.brand{display:flex;align-items:center;gap:12px}
.brand-mark{width:34px;height:34px;border-radius:50%;position:relative;
  background:radial-gradient(circle at 50% 40%,#bfe0ff,#4da3ff 45%,#1b3a78 75%);
  box-shadow:var(--glow);animation:pulse 3.4s ease-in-out infinite}
.brand-mark::after{content:"";position:absolute;inset:-5px;border-radius:50%;border:1px solid rgba(77,163,255,.45)}
.brand-name{font-family:var(--h-disp);font-weight:800;letter-spacing:5px;font-size:18px}
.brand-sub{font-size:10.5px;color:var(--muted);letter-spacing:2px;text-transform:uppercase}
.top-status{display:flex;align-items:center;gap:10px}
.chip[hidden]{display:none !important}   /* o atributo hidden tem que valer mesmo (o display:inline-flex abaixo o sobreporia) */
.chip{display:inline-flex;align-items:center;gap:7px;font-size:12px;color:var(--ink-dim);
  padding:6px 12px;border:1px solid var(--line);border-radius:999px;background:var(--panel)}
.chip .dot{width:8px;height:8px;border-radius:50%;background:var(--muted);box-shadow:0 0 8px var(--muted)}
.chip.on .dot{background:var(--ok);box-shadow:0 0 10px var(--ok)}
.chip.warn .dot{background:var(--warn,#ffb454);box-shadow:0 0 10px var(--warn,#ffb454)}   /* voz indisponível (âmbar) — mesmo tom do erro visível da lousa */
.chip.clock{font-family:var(--mono);color:var(--ink);letter-spacing:1px}
/* fWHO: e-mail da conta logada no topbar (desambigua admin × aluno do mesmo humano) */
.chip .who-email{font-family:var(--mono);color:var(--ink);letter-spacing:.3px;font-size:11.5px}

/* ---- Rail ---- */
.rail{position:fixed;top:60px;bottom:0;left:0;width:var(--rail-w);z-index:4;
  display:flex;flex-direction:column;gap:4px;padding:14px 8px;
  border-right:1px solid var(--line);background:rgba(8,12,22,.5);backdrop-filter:blur(8px)}
.rail-spacer{flex:1}
.rail-btn[hidden]{display:none !important}   /* o atributo hidden tem que valer mesmo (o display:flex abaixo o sobreporia) */
.rail-btn{display:flex;flex-direction:column;align-items:center;gap:6px;cursor:pointer;
  background:transparent;border:1px solid transparent;border-radius:14px;padding:11px 4px;color:var(--muted);
  font-family:var(--b-sans);font-size:10px;letter-spacing:.3px;transition:.18s}
.rail-btn svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.rail-btn:hover{color:var(--ink-dim);background:var(--panel);border-color:var(--line)}
.rail-btn.active{color:#fff;background:linear-gradient(180deg,rgba(77,163,255,.22),rgba(77,163,255,.05));border-color:var(--line2);box-shadow:inset 0 0 18px rgba(77,163,255,.12)}
.rail-btn.active svg{stroke:var(--blue);filter:drop-shadow(0 0 6px rgba(77,163,255,.6))}

/* ---- Stage ---- */
.stage{position:fixed;top:60px;left:var(--rail-w);right:var(--dock-w);bottom:0;z-index:2;overflow-y:auto;padding:24px 26px 60px}
.view{display:none;animation:fade .25s ease}
.view.active{display:block}
.view-head{margin-bottom:18px}
.view-head h1{font-family:var(--h-sans);font-weight:600;font-size:23px;margin:0 0 4px}
.muted{color:var(--muted)}
.view-head .muted{font-size:13px;max-width:760px;line-height:1.5}

/* ---- Panels ---- */
.panel{background:var(--panel);border:1px solid var(--line);border-radius:18px;padding:18px 18px 20px;margin-bottom:18px;
  backdrop-filter:blur(6px);box-shadow:0 8px 30px rgba(0,0,0,.25)}
.panel-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px}
.panel-head h2{font-family:var(--h-sans);font-weight:600;font-size:15px;margin:0;letter-spacing:.3px}
.panel-head .muted{font-size:12px}
.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:18px}
.grid-aula{display:grid;grid-template-columns:1fr;gap:18px;align-items:start}
@media(max-width:1180px){.grid-2,.grid-aula{grid-template-columns:1fr}}
/* Tempo com a ATHENA (lançado no 70/20/10) */
.time-athena{background:var(--panel,#0e1626);border:1px solid var(--line,#1d2940);border-radius:14px;padding:12px 16px;margin-bottom:18px}
.time-athena[hidden]{display:none}
.ta-head{font-size:13px;font-weight:600;margin-bottom:8px}
.ta-head .muted{font-weight:400;font-size:11.5px}
.ta-bands{display:flex;gap:22px;flex-wrap:wrap}
.ta-band{display:flex;align-items:center;gap:7px;font-size:12.5px}
.ta-dot{width:9px;height:9px;border-radius:50%;display:inline-block}
.ta-band b{font-family:var(--mono);font-size:12px}
.ta-val{font-weight:700;margin-left:2px}
.ta-wk{color:var(--muted);font-size:11px;font-family:var(--mono)}
.ta-pending{margin-top:7px;font-size:11.5px}

/* ---- Radar ---- */
.radar-wrap{display:flex;justify-content:center}
#radar{width:100%;max-width:420px;height:auto}
.legend{display:flex;gap:18px;justify-content:center;margin-top:6px;font-size:12px;color:var(--ink-dim)}
.legend .sw{display:inline-block;width:12px;height:12px;border-radius:3px;margin-right:6px;vertical-align:-1px}
.sw.cur{background:var(--blue)} .sw.tgt{background:transparent;border:1.5px dashed var(--violet)}

/* ---- Dimension bars ---- */
.dim-tier{margin-bottom:14px}
.dim-tier-h{font-size:11px;letter-spacing:1.5px;text-transform:uppercase;color:var(--muted);margin:0 0 8px}
.dim-row{display:grid;grid-template-columns:1fr auto;gap:6px;margin-bottom:9px}
.dim-name{font-size:12.5px;color:var(--ink-dim)}
.dim-val{font-family:var(--mono);font-size:12px;color:var(--ink)}
.dim-track{grid-column:1/3;height:7px;border-radius:6px;background:rgba(255,255,255,.06);overflow:hidden;position:relative}
.dim-fill{height:100%;border-radius:6px;transition:width .6s cubic-bezier(.3,1,.4,1)}
.dim-tgt{position:absolute;top:-2px;height:11px;width:2px;background:var(--violet);opacity:.8}

/* ---- PDI Gantt ---- */
.pdi-panel .panel-head{align-items:flex-start}
.pdi-scroll{overflow-x:auto;padding-bottom:4px}
.pdi{min-width:780px;position:relative}
/* faixa brilhante animada passando pelas semanas (estado vazio/preview do Gantt) */
.pdi-sweep{position:absolute;top:0;bottom:0;left:194px;width:84px;pointer-events:none;z-index:3;mix-blend-mode:screen;
  background:linear-gradient(90deg,transparent,rgba(77,163,255,.18) 35%,rgba(180,220,255,.5) 50%,rgba(77,163,255,.18) 65%,transparent);
  filter:blur(1px);animation:pdi-sweep 5.2s cubic-bezier(.45,0,.55,1) infinite}
.pdi-sweep::after{content:"";position:absolute;top:0;bottom:0;left:50%;width:2px;transform:translateX(-50%);background:linear-gradient(180deg,transparent,rgba(200,230,255,.95),transparent);box-shadow:0 0 14px 3px rgba(120,200,255,.7)}
@keyframes pdi-sweep{0%{left:194px;opacity:0}8%{opacity:1}92%{opacity:1}100%{left:calc(100% - 84px);opacity:0}}
@media(prefers-reduced-motion:reduce){.pdi-sweep{animation:none;opacity:0}}
.pdi.is-empty .blk{opacity:.5}   /* blocos do preview: presentes, mas sem conteúdo definido */
/* CTA grande: iniciar avaliação inicial */
.assess-cta{display:flex;align-items:center;justify-content:space-between;gap:18px;flex-wrap:wrap;
  background:linear-gradient(180deg,rgba(77,163,255,.16),rgba(77,163,255,.04));border:1px solid var(--line2);box-shadow:inset 0 0 26px rgba(77,163,255,.1)}
.assess-cta[hidden]{display:none}
.assess-btn{font-family:var(--h-sans);font-weight:600;font-size:15px;padding:13px 22px;border-radius:12px;cursor:pointer;
  background:linear-gradient(180deg,#4da3ff,#2f6fd0);color:#fff;border:none;box-shadow:var(--glow);white-space:nowrap}
.assess-btn:hover{filter:brightness(1.08)}
/* Banner de ATIVIDADE DIRIGIDA (só aluno de teste) — espelha o .assess-cta, em violeta p/ não competir
   com o CTA azul da Avaliação Inicial (que é o gate obrigatório e continua sendo a prioridade visual). */
.act-cta{display:flex;align-items:center;justify-content:space-between;gap:18px;flex-wrap:wrap;
  background:linear-gradient(180deg,rgba(167,124,255,.16),rgba(167,124,255,.04));border:1px solid var(--line2);box-shadow:inset 0 0 26px rgba(167,124,255,.1)}
.act-cta[hidden]{display:none}
.act-btn{font-family:var(--h-sans);font-weight:600;font-size:15px;padding:13px 22px;border-radius:12px;cursor:pointer;
  background:linear-gradient(180deg,#a77cff,#7a4fd0);color:#fff;border:none;white-space:nowrap}
.act-btn:hover{filter:brightness(1.08)}
/* Painel do Master: lista de atividades dirigidas */
#actText{width:100%;box-sizing:border-box;background:var(--panel2,rgba(255,255,255,.03));border:1px solid var(--line2);border-radius:10px;
  color:var(--fg);font-family:inherit;font-size:13px;padding:10px;resize:vertical}
.act-row{border:1px solid var(--line2);border-radius:10px;padding:10px 12px;margin-bottom:10px}
.act-row-top{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:6px}
.act-badge{font-family:var(--mono);font-size:9.5px;letter-spacing:1px;padding:2px 7px;border-radius:999px;border:1px solid var(--line2)}
.act-badge.on{color:#a77cff;border-color:rgba(167,124,255,.5);background:rgba(167,124,255,.12)}
.act-badge.off{color:var(--muted)}
.act-text{font-size:13px;white-space:pre-wrap;margin:4px 0 8px}
.act-students{display:flex;flex-wrap:wrap;gap:10px}
.act-stu{display:flex;align-items:center;gap:6px;font-size:12px;border:1px solid var(--line2);border-radius:8px;padding:4px 8px;cursor:pointer}
/* ===== CÔMODO DE TESTES (cômodo 5) — backlog + registro + relatório =====
   Reusa a linguagem visual do painel de atividades logo acima (mesma borda, mesmo raio, mesmos chips),
   para o cômodo parecer um cômodo só. Nada de identidade nova. */
.tr-actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
/* `[hidden]` é regra do user-agent e PERDE para `.btn{display:inline-flex}` (classe, 0-1-0) — sem esta
   linha os botões de escrita continuariam VISÍVEIS para a sócia. Mesma armadilha já paga no bloco de
   avatares; escopo restrito aqui para não mexer em telas não auditadas. */
.tr-actions .btn[hidden],.tr-item-acts[hidden],.tr-item-acts .btn[hidden]{display:none!important}
.tr-form{border-top:1px solid var(--line2);margin-top:12px;padding-top:12px}
.tr-lbl{display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:1px;color:var(--muted);text-transform:uppercase;margin:10px 0 4px}
.tr-hint{font-size:11.5px;margin-bottom:6px}
.tr-form textarea,.tr-form input[type=text],.tr-form input:not([type]),.tr-form input[type=date],.tr-form select{width:100%;box-sizing:border-box;
  background:var(--panel2,rgba(255,255,255,.03));border:1px solid var(--line2);border-radius:10px;color:var(--fg);
  font-family:inherit;font-size:13px;padding:10px;resize:vertical}
.tr-row{display:flex;align-items:center;gap:10px;margin-top:10px;flex-wrap:wrap}
.tr-row .muted{font-size:12px}
.tr-imp-out{margin-top:10px;font-size:12px;border:1px solid var(--line2);border-radius:10px;padding:10px;max-height:280px;overflow:auto}
.tr-imp-out ul{margin:6px 0 0;padding-left:18px}
.tr-imp-out li{margin-bottom:3px}
.tr-item{border:1px solid var(--line2);border-radius:10px;padding:10px 12px;margin-bottom:10px}
.tr-item-top{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:6px}
.tr-badge{font-family:var(--mono);font-size:9.5px;letter-spacing:1px;padding:2px 7px;border-radius:999px;border:1px solid var(--line2);color:var(--muted)}
.tr-badge.s-pendente{color:#ffb454;border-color:rgba(255,180,84,.5);background:rgba(255,180,84,.12)}
.tr-badge.s-em_andamento{color:#7da0ff;border-color:rgba(125,160,255,.5);background:rgba(125,160,255,.12)}
.tr-badge.s-feito{color:#4ade80;border-color:rgba(74,222,128,.45);background:rgba(74,222,128,.12)}
.tr-dest{font-size:11.5px;color:var(--fg);opacity:.85}
.tr-chip{font-family:var(--mono);font-size:9.5px;letter-spacing:1px;padding:2px 7px;border-radius:999px;
  color:#a77cff;border:1px solid rgba(167,124,255,.5);background:rgba(167,124,255,.12)}
.tr-desc{font-size:13px;white-space:pre-wrap;margin-bottom:4px}
.tr-por,.tr-ori{font-size:12px;color:var(--muted);white-space:pre-wrap;margin-bottom:3px}
.tr-item-acts{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:8px}
.tr-item-acts select{background:var(--panel2,rgba(255,255,255,.03));border:1px solid var(--line2);border-radius:8px;color:var(--fg);font-size:12px;padding:4px 8px}
.tr-rec{border:1px solid var(--line2);border-radius:10px;padding:10px 12px;margin-bottom:10px}
.tr-rec-top{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:6px}
.tr-when{font-family:var(--mono);font-size:11.5px;color:var(--muted)}
.tr-who{font-size:12.5px;font-weight:600}
.tr-orig{font-family:var(--mono);font-size:9.5px;letter-spacing:1px;padding:2px 7px;border-radius:999px;border:1px solid var(--line2);color:var(--muted)}
.tr-orig.o-coleta_automatica{color:#4ade80;border-color:rgba(74,222,128,.45);background:rgba(74,222,128,.12)}
.tr-orig.o-arquivo{color:#7da0ff;border-color:rgba(125,160,255,.5);background:rgba(125,160,255,.12)}
.tr-rec-body{font-size:12.5px;display:flex;flex-direction:column;gap:2px}
.pdi-head{display:flex;border-bottom:1px solid var(--line2)}
.pdi-corner{width:194px;flex-shrink:0;font-family:var(--mono);font-size:9.5px;letter-spacing:1px;color:var(--muted);text-transform:uppercase;display:flex;align-items:center;padding-left:6px}
.pdi-weeks{flex:1;display:grid}
.pdi-weeks .wk{font-family:var(--mono);font-size:9px;color:var(--muted);text-align:center;padding:5px 0;border-left:1px solid rgba(125,160,255,.06)}
.pdi-weeks .wk.now{color:var(--gold);background:rgba(255,194,77,.12);font-weight:600}
.pdi-dim{display:flex;border-bottom:1px solid var(--line)}
.pdi-dimlabel{width:168px;flex-shrink:0;display:flex;align-items:center;gap:7px;padding:0 8px;font-size:11px;color:var(--ink-dim);border-right:1px solid var(--line2);border-left:3px solid var(--tc,transparent);line-height:1.15}
.pdi-dimlabel .cn{font-family:var(--h-disp);font-weight:700;color:var(--tc);font-size:11px;flex-shrink:0}
.pdi-lanes{flex:1;display:flex;flex-direction:column}
/* --lane-h: a ALTURA DA RAIA, desacoplada do --rh. POR QUE existe: o JS crava `--rh` INLINE no #pdi
   (app.js renderPDI: host.style.setProperty('--rh', rowH+'px')), e estilo inline vence QUALQUER regra desta
   folha — entao uma media-query nunca conseguiria alargar a raia no toque. --lane-h nao e escrito pelo JS,
   logo o CSS pode defini-la. Default = o --rh de hoje: sem a classe de toque, NADA muda (byte-a-byte). */
.pdi-lane{display:flex;height:var(--lane-h,var(--rh,20px))}
.pdi-faixa{width:26px;flex-shrink:0;font-family:var(--mono);font-size:9px;display:flex;align-items:center;justify-content:center;border-right:1px solid var(--line)}
.pdi-faixa.f70{color:var(--blue)} .pdi-faixa.f20{color:var(--violet)} .pdi-faixa.f10{color:var(--teal)}
.pdi-track{flex:1;display:grid;align-items:center}
.pdi-cell{height:var(--lane-h,var(--rh,20px));border-left:1px solid rgba(125,160,255,.05);grid-row:1}
.pdi-cell.now{background:rgba(255,194,77,.07)}
/* O bloco segue derivado de --rh (NAO de --lane-h): numa tela de toque a raia cresce e o bloco NAO —
   e exatamente o requisito "hitbox generoso, DESACOPLADO do tamanho visual, sem aumentar o bloco". */
.blk{height:calc(var(--rh,20px) - 8px);border-radius:4px;margin:0 2px;cursor:pointer;position:relative;z-index:2;transition:.14s;background:#46506a;border:1px solid rgba(255,255,255,.08)}
.blk:hover{transform:scaleY(1.3);filter:brightness(1.35);box-shadow:0 0 8px rgba(77,163,255,.4)}

/* ---- GANTT EM TELA DE TOQUE (tablet E celular — o requisito diz "tela de toque", nao "tablet") ----
   O PROBLEMA (medido): o bloco tem 12px de altura (`calc(var(--rh,20px) - 8px)`) e ~26px de largura, e o
   clique CHAMA togglePdi -> marca a tarefa como CONCLUIDA. 12px sob o dedo, num alvo que MUDA DADO, e furo.
   A SOLUCAO: a RAIA vai a 44px (minimo de toque iOS/Material) e o BLOCO fica nos 12px. O .pdi-track ja tem
   `align-items:center`, entao o bloco se centraliza sozinho na raia — sem uma linha de JS.
   O ALVO em si e um ::after invisivel: pseudo-elemento ENCAMINHA o evento ao .blk, entao o handler existente
   (delegado no renderPDI) nao muda nada. */
html.is-tablet .pdi,html.is-mobile .pdi{--lane-h:44px}
html.is-tablet .blk::after,html.is-mobile .blk::after{
  content:'';position:absolute;top:50%;transform:translateY(-50%);height:44px;
  /* -2px de cada lado = reclama exatamente a `margin:0 2px` do bloco -> o alvo cobre a COLUNA DA SEMANA
     INTEIRA (30px) e para ali. LIMITE CONSCIENTE: nao vou aos 44px de LARGURA porque a coluna mede 30px —
     transbordar invadiria o bloco da semana vizinha e um toque ambiguo marcaria a TAREFA ERRADA. 30x44
     (3,4x a area de hoje) sem ambiguidade e melhor que 44x44 que as vezes erra o alvo. */
  left:-2px;right:-2px;
}
/* HOVER GRUDADO: `.blk:hover{transform:scaleY(1.3)}` fica preso apos o toque ate o proximo toque (o mesmo
   furo que o bloco @media(hover:none) ja trata para .rail-btn/.drawer-btn). */
@media (hover:none){
  html.is-tablet .blk:hover,html.is-mobile .blk:hover{transform:none;filter:none;box-shadow:none}
}
.blk.done{background:linear-gradient(180deg,#3be0a0,#1d9e6e);border-color:#5dffc0}
.blk.now{background:linear-gradient(180deg,#ffc24d,#d99a1f);border-color:#ffe0a0;box-shadow:0 0 8px rgba(255,194,77,.5)}
.blk.late{background:linear-gradient(180deg,#ff6b85,#c33b54);border-color:#ff9aac}
.blk.plan{background:#46506a}
/* ===== AULA NO GANTT (decisão 2026-07-26, complemento): a distinção por COR/BRILHO foi CANCELADA — o
   bloco de aula usa as MESMAS 4 cores de estado da tarefa comum; quem diz "isto é aula" é SÓ o TRIÂNGULO ▶
   abaixo. ROXO (aguarda) é EXCLUSIVO de aula — pedido de conclusão aguardando confirmação; sem gêmeo comum. ===== */
.blk.aguarda{background:linear-gradient(180deg,#b18cff,#7a4fd6);border-color:#d4bcff;box-shadow:0 0 8px rgba(157,110,255,.55)}
/* MARCADOR DE AULA: triângulo de play PRETO dentro do bloco — CSS puro (clip-path), sem imagem/SVG.
   Preto sólido nos 4 estados temporais (no cinza da "prevista" fica menos evidente — aceito de propósito).
   Altura quase total com respiro: os insets contam do PADDING-box (dentro da borda de 1px do .blk), então
   inset 1px = 2px de folga VISUAL por lado (borda+inset) — nunca encosta, e escala com o zoom via a altura
   do bloco; largura deriva da altura (aspect-ratio). Centralizado.
   O ROXO (aguarda) fica como está hoje — sem triângulo nesta rodada (:not(.aguarda)). pointer-events:none
   preserva o clique no bloco (o handler mora no .blk). */
.blk.lesson:not(.aguarda)::before{
  content:'';position:absolute;top:1px;bottom:1px;left:50%;transform:translateX(-50%);
  width:auto;aspect-ratio:.9;background:#000;
  clip-path:polygon(0 0,100% 50%,0 100%);pointer-events:none;
}
.app-flash{animation:app-flash 1.9s ease;border-radius:14px;position:relative;z-index:3}
@keyframes app-flash{0%,100%{box-shadow:0 0 0 0 rgba(77,163,255,0)}25%{box-shadow:0 0 0 3px rgba(77,163,255,.95),0 0 26px rgba(77,163,255,.55)}65%{box-shadow:0 0 0 2px rgba(77,163,255,.5),0 0 14px rgba(77,163,255,.3)}}
.blk.flash{z-index:6;animation:blk-flash 1.5s ease}
@keyframes blk-flash{0%,100%{box-shadow:0 0 0 0 rgba(255,194,77,0);outline:0 solid transparent}35%{box-shadow:0 0 16px 5px rgba(255,194,77,.95);outline:2px solid #ffe08a;outline-offset:1px}70%{box-shadow:0 0 10px 2px rgba(255,194,77,.6);outline:2px solid rgba(255,224,138,.5)}}
.pdi-legend{display:flex;flex-wrap:wrap;align-items:center;gap:8px 18px;margin-top:12px;font-size:11.5px;color:var(--ink-dim)}
/* armadilha conhecida [hidden]×display (fechada ESCOPADA, como nos precedentes .av-btns/.master-only):
   garante que o item condicional da legenda (#lgAguarda) some de verdade quando hidden */
.pdi-legend [hidden]{display:none!important}
.pdi-legend .lg{display:inline-block;width:14px;height:9px;border-radius:3px;margin-right:6px}
/* grupo ESTADO: swatches nas cores MAIS BRILHANTES, casando com o TOPO do gradiente do bloco (os tons
   antigos #2bbe84/#e0556e eram mais apagados que a tela) + o roxo CONDICIONAL (só com claim pendente) */
.lg.done{background:#3be0a0} .lg.now{background:#ffc24d} .lg.late{background:#ff6b85} .lg.plan{background:#46506a}
.lg.aguarda{background:#b18cff}
/* grupo TIPO: o glifo ▶ SOLTO, na COR DO TEXTO da legenda (herda currentColor do .pdi-legend) — SEM
   moldura/fundo imitando bloco (o chip-retângulo confundia: o triângulo preto sumia no cinza do fundo).
   Só o símbolo + o texto, como os demais itens. O triângulo DENTRO dos blocos (.blk.lesson::before,
   preto) NÃO é afetado por isto — segue como está. */
.pdi-legend .lg-play{font-style:normal;font-size:1.15em;line-height:1;margin-right:6px}
.pdi-legend .lgrp{opacity:.6;font-size:10.5px;text-transform:uppercase;letter-spacing:.4px}
/* AULA NO GANTT: menu do bloco de aula (assistir / pedir confirmação) */
.pdi-lmenu{position:fixed;z-index:300;background:#151b2e;border:1px solid var(--line);border-radius:10px;padding:10px;display:flex;flex-direction:column;gap:8px;box-shadow:0 10px 30px rgba(0,0,0,.5);max-width:320px}
.pdi-lmenu .lm-title{font-size:12px;font-weight:600}
.pdi-lmenu .lm-note{font-size:11.5px;color:var(--ink-dim)}
/* fila do master: pedidos de confirmação de aula (roxo) + o registro do que o juiz buscou/achou (fP) */
.lc-item{border:1px solid var(--line);border-radius:10px;padding:10px;margin:8px 0;font-size:12.5px}
.lc-head{margin-bottom:6px}
.lc-busca{margin:4px 0}
.lc-ev{font-family:var(--mono);font-size:11px;background:rgba(125,160,255,.08);border-radius:6px;padding:4px 6px;margin-top:2px;word-break:break-word}
.lc-note{margin-top:6px;font-size:11.5px}
.lc-actions{display:flex;gap:8px;margin-top:8px}
.lc-hist{margin-top:10px}
.pdi-controls{display:flex;align-items:center;gap:6px;flex-shrink:0}
.pctl{cursor:pointer;background:var(--panel);border:1px solid var(--line);color:var(--ink-dim);border-radius:8px;width:26px;height:26px;font-size:14px;line-height:1;display:grid;place-items:center}
.pctl:hover{color:#fff;border-color:var(--line2)}
.pctl-week{font-family:var(--mono);font-size:11px;color:var(--gold);min-width:30px;text-align:center}
.pctl-sep{width:1px;height:18px;background:var(--line)}
.pctl-toggle{display:flex;align-items:center;gap:5px;font-size:11.5px;color:var(--ink-dim);cursor:pointer;user-select:none}
.pctl-toggle input{accent-color:var(--blue)}

/* ---- Timeline ---- */
.timeline{display:flex;flex-direction:column;gap:0}
.tl-row{display:grid;grid-template-columns:96px 1fr;gap:12px;padding:10px 0;border-bottom:1px solid var(--line)}
.tl-row:last-child{border-bottom:none}
.tl-date{font-family:var(--mono);font-size:11px;color:var(--muted)}
.tl-act b{color:var(--ink)} .tl-act .tl-dim{font-size:11px;color:var(--blue)}
.empty{color:var(--muted);font-size:13px;padding:8px 0;font-style:italic}

/* ---- Browser viewer ---- */
.browser-panel .panel-head .muted{font-family:var(--mono);font-size:11px;max-width:60%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.browser-view{aspect-ratio:16/10;border-radius:12px;border:1px solid var(--line2);overflow:hidden;position:relative;
  background:#05080f url() center/cover no-repeat;display:flex;align-items:center;justify-content:center}
.browser-view img{width:100%;height:100%;object-fit:cover;object-position:top}
.browser-empty{color:var(--muted);text-align:center;font-size:13px;line-height:1.7;padding:20px}
/* Zoom da Aula ao vivo: controles no cabeçalho + visor rolável quando ampliado */
.aula-zoom{margin-left:auto;display:flex;align-items:center;gap:6px}
.browser-view.zoomed{overflow:auto}
.browser-view.zoomed img{object-fit:contain;display:block}

/* ===== LOUSA da Aula ao vivo (premium) ===== */
.aula-tabbar{display:flex;align-items:center;gap:12px;margin-bottom:12px;flex-wrap:wrap}
.aula-tabs{display:inline-flex;background:rgba(0,0,0,.25);border:1px solid var(--line);border-radius:999px;padding:3px}
.aula-tab{cursor:pointer;border:0;background:transparent;color:var(--ink-dim);font-family:var(--h-sans);font-size:13px;padding:7px 16px;border-radius:999px;letter-spacing:.3px}
.aula-tab.active{background:linear-gradient(180deg,rgba(77,163,255,.28),rgba(77,163,255,.08));color:#fff;box-shadow:var(--glow)}
.board-controls{display:inline-flex;align-items:center;gap:8px;margin-left:auto}
/* O atributo `hidden` do HTML só vale via folha do NAVEGADOR ([hidden]{display:none}), e qualquer `display`
   de AUTOR o vence — então a linha acima anulava o hidden e o grupo continuava na tela (medido: #mapControls
   com hidden=true e display:flex, os botões do mapa aparecendo na aba Lousa). Isto restaura o contrato do
   atributo, que o JS usa em setAulaTab. Vale também para o #boardControls (o furo era pré-existente ali). */
.board-controls[hidden]{display:none}
/* REGIÃO ÚNICA de ações da Aula ao vivo (PDF da aula / gravar aula / PDF do mapa / zerar / arquivo).
   O margin-left:auto vive AQUI, no wrapper — não em cada grupo. Com ele em cada .board-controls, o 1º grupo
   absorvia todo o espaço livre e empurrava os demais para uma 2ª linha, separados por um vão (medido em
   1440px: 3 grupos, 2 linhas). Um wrapper só = tudo junto, à direita, na mesma linha das abas. */
.aula-actions{display:inline-flex;align-items:center;gap:8px;margin-left:auto;flex-wrap:wrap}
.aula-actions .board-controls{margin-left:0}
/* ===== LOUSA cinematográfica (HUD/Jarvis) ===== */
.board-panel{padding:0;overflow:hidden;position:relative;isolation:isolate;border-color:var(--line2);
  background:radial-gradient(130% 90% at 0% 0%,rgba(77,163,255,.12),transparent 55%),radial-gradient(130% 90% at 100% 100%,rgba(139,123,255,.12),transparent 55%),linear-gradient(180deg,#070b16,#090e1d)}
.board-panel::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;opacity:.5;
  background-image:linear-gradient(rgba(120,160,255,.06) 1px,transparent 1px),linear-gradient(90deg,rgba(120,160,255,.06) 1px,transparent 1px);
  background-size:40px 40px;mask-image:radial-gradient(ellipse 90% 80% at 50% 30%,#000 35%,transparent 100%)}
.board-panel::after{content:"";position:absolute;left:-30%;top:0;width:55%;height:100%;z-index:0;pointer-events:none;will-change:transform;
  background:linear-gradient(90deg,transparent,rgba(77,163,255,.06),transparent);filter:blur(7px);animation:bdSweep 11s ease-in-out infinite}
@keyframes bdSweep{0%{transform:translateX(-40%)}50%{transform:translateX(200%)}100%{transform:translateX(-40%)}}
@media (prefers-reduced-motion:reduce){.board-panel::after{animation:none;opacity:0}}
.board-stage{position:relative;z-index:1;min-height:64vh;max-height:78vh;overflow:auto;padding:40px 44px 56px;scroll-behavior:smooth}
.board-empty{color:var(--ink-dim);text-align:center;font-size:17px;line-height:1.9;padding:70px 20px}
.board-empty.board-err{color:var(--warn,#ffb454)}   /* fC: erro de render é VISÍVEL na lousa, nunca silencioso */
.bd-slide{max-width:960px;margin:0 auto;position:relative}
/* moldura HUD nos 4 cantos */
.bd-frame{position:absolute;inset:-8px -6px;pointer-events:none;z-index:0}
.bd-frame i{position:absolute;width:26px;height:26px;border:2px solid rgba(77,163,255,.5);filter:drop-shadow(0 0 6px rgba(77,163,255,.4))}
.bd-frame i:nth-child(1){left:0;top:0;border-right:0;border-bottom:0}
.bd-frame i:nth-child(2){right:0;top:0;border-left:0;border-bottom:0}
.bd-frame i:nth-child(3){left:0;bottom:0;border-right:0;border-top:0}
.bd-frame i:nth-child(4){right:0;bottom:0;border-left:0;border-top:0}
.bd-head{margin-bottom:26px;padding-bottom:18px;border-bottom:1px solid var(--line2);position:relative}
.bd-head:after{content:"";position:absolute;left:0;bottom:-1px;width:120px;height:3px;border-radius:3px;background:linear-gradient(90deg,var(--blue),var(--violet));box-shadow:0 0 14px rgba(77,163,255,.6);animation:bdLine 2.4s ease-in-out infinite}
@keyframes bdLine{0%,100%{width:120px;opacity:.85}50%{width:180px;opacity:1}}
.bd-lesson{font-family:var(--mono);font-size:12px;letter-spacing:3px;text-transform:uppercase;color:var(--gold);margin-bottom:8px;opacity:.9}
.bd-title{font-family:var(--h-sans);font-size:38px;font-weight:700;line-height:1.1;letter-spacing:-.3px;min-height:1.1em;
  background:linear-gradient(92deg,#fff 10%,#bcd6ff 60%,#a99bff);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;
  filter:drop-shadow(0 2px 18px rgba(77,163,255,.25))}
.bd-title.typing::after{content:"";display:inline-block;width:3px;height:.92em;margin-left:4px;vertical-align:-2px;background:var(--blue);box-shadow:0 0 10px var(--blue);animation:bdCaret .7s steps(1) infinite}
@keyframes bdCaret{50%{opacity:0}}
.bd-sub{color:var(--ink-dim);font-size:17px;margin-top:8px;line-height:1.5}
.bd-body{display:flex;flex-direction:column;gap:18px;position:relative}
/* revelação dos blocos */
.bd-block{opacity:0;transform:translateY(20px) scale(.985);filter:blur(7px)}
.bd-block.show{animation:bdReveal .6s cubic-bezier(.2,.75,.2,1) forwards}
@keyframes bdReveal{to{opacity:1;transform:none;filter:blur(0)}}
@media (prefers-reduced-motion:reduce){.bd-block{opacity:1!important;transform:none!important;filter:none!important;animation:none!important}}
/* palavra que "se digita" */
.tw-w{display:inline-block;opacity:0;animation:twWord .42s cubic-bezier(.2,.7,.2,1) forwards;will-change:opacity,transform}
@keyframes twWord{from{opacity:0;transform:translateY(.3em)}to{opacity:1;transform:none}}
/* destaque de palavra-chave (neon chip) */
.bd-key{background:linear-gradient(180deg,rgba(77,163,255,.26),rgba(139,123,255,.18));color:#eaf2ff;padding:.04em .34em;border-radius:6px;font-weight:600;
  box-shadow:inset 0 0 0 1px rgba(125,160,255,.35),0 0 14px rgba(77,163,255,.25);-webkit-text-fill-color:#eaf2ff}
/* HERO cinematográfico */
.bd-hero{padding:18px 6px 8px;text-align:center}
.bd-hero-kicker{font-family:var(--mono);font-size:12px;letter-spacing:4px;text-transform:uppercase;color:var(--teal);margin-bottom:14px}
.bd-hero-words{display:flex;flex-wrap:wrap;gap:.32em;justify-content:center;align-items:baseline;font-family:var(--h-disp);font-weight:800;font-size:clamp(30px,5.4vw,58px);line-height:1.06}
.bd-hw{opacity:0;color:#eaf1ff;animation:hwIn .6s cubic-bezier(.2,.8,.2,1) forwards;animation-delay:calc(var(--i) * .16s + .1s);text-shadow:0 0 26px rgba(77,163,255,.25)}
.bd-hw.focus{background:linear-gradient(90deg,var(--blue),var(--violet),var(--teal));-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;filter:drop-shadow(0 0 18px rgba(139,123,255,.5))}
@keyframes hwIn{from{opacity:0;transform:translateY(26px) rotateX(40deg);filter:blur(6px)}to{opacity:1;transform:none;filter:blur(0)}}
.bd-hero-line{font-family:var(--h-disp);font-weight:800;font-size:clamp(26px,4.4vw,46px);color:#eaf1ff;letter-spacing:.5px;min-height:1.1em}
.bd-hero-line .bd-caret{display:inline-block;width:3px;height:.9em;margin-left:5px;vertical-align:-2px;background:var(--teal);box-shadow:0 0 12px var(--teal);animation:bdCaret .7s steps(1) infinite}
.bd-hero-line.done .bd-caret{animation:none;opacity:0}
/* MORPH: palavra que cruza a tela e vira outra */
/* "from" e "to" lado a lado (flex), que se SEPARAM na animação (from desliza p/ a esquerda e encolhe;
   to entra da direita e assenta). Lado a lado eles nunca se sobrepõem; overflow VISÍVEL p/ não cortar. */
.bd-morph{position:relative;min-height:140px;display:flex;align-items:center;justify-content:center;gap:.45em;flex-wrap:nowrap;font-family:var(--h-disp);font-weight:800;font-size:clamp(28px,4.6vw,54px);overflow:visible}
.bd-morph-from{white-space:nowrap;color:#cfe0ff;animation:morphFrom 3s cubic-bezier(.7,0,.3,1) forwards}
.bd-morph-to{position:relative;white-space:nowrap;opacity:0;background:linear-gradient(90deg,var(--blue),var(--violet),var(--teal));-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;filter:drop-shadow(0 0 20px rgba(139,123,255,.5));animation:morphTo 3s cubic-bezier(.7,0,.3,1) forwards}
.bd-morph-trail{position:absolute;left:0;top:50%;height:2px;width:0;background:linear-gradient(90deg,transparent,var(--blue),var(--teal),transparent);box-shadow:0 0 14px var(--blue);transform:translateY(-50%);opacity:0;animation:morphTrail 3s ease forwards}
@keyframes morphFrom{0%{opacity:0;transform:translateX(0) scale(1)}18%{opacity:1;transform:translateX(0) scale(1.04)}55%{opacity:1;transform:translateX(-120px) scale(.62);filter:blur(0)}72%,100%{opacity:.4;transform:translateX(-150px) scale(.52);filter:blur(.3px)}}
@keyframes morphTo{0%,40%{opacity:0;transform:translateX(170px) scale(.6);filter:blur(8px)}70%{opacity:1;transform:translateX(8px) scale(1.06);filter:blur(0)}100%{opacity:1;transform:translateX(-30px) scale(1)}}
@keyframes morphTrail{0%,38%{width:0;left:30%;opacity:0}55%{opacity:1}70%{width:62%;left:18%;opacity:.8}100%{width:0;left:80%;opacity:0}}

/* ============ ABERTURA CINEMATOGRÁFICA (Jarvis/Star Wars) — antes do tour ============ */
.cine-intro{position:fixed;inset:0;z-index:9999;display:flex;align-items:center;justify-content:center;
  background:radial-gradient(circle at 50% 42%,#0c1430 0%,#070b1c 55%,#04060f 100%);
  opacity:0;transition:opacity .5s ease;overflow:hidden;cursor:pointer}
.cine-intro.on{opacity:1}
.cine-intro.out{opacity:0;transition:opacity .5s ease}
.cine-intro.out .cine-core{transform:scale(1.16);opacity:0;transition:transform .55s cubic-bezier(.5,0,.5,1),opacity .55s ease}
/* grade HUD de fundo, respirando */
.cine-grid{position:absolute;inset:-20%;background-image:linear-gradient(rgba(77,163,255,.10) 1px,transparent 1px),linear-gradient(90deg,rgba(77,163,255,.10) 1px,transparent 1px);background-size:46px 46px;
  mask:radial-gradient(circle at 50% 45%,#000 0%,transparent 70%);-webkit-mask:radial-gradient(circle at 50% 45%,#000 0%,transparent 70%);opacity:0;animation:cineGrid 2.6s ease forwards}
@keyframes cineGrid{0%{opacity:0;transform:scale(1.15)}30%{opacity:.7}100%{opacity:.35;transform:scale(1)}}
/* varredura de luz cobrindo a TELA INTEIRA (maior e mais cinematográfica que a do Gantt) */
.cine-sweep{position:absolute;top:0;bottom:0;left:-30%;width:30%;pointer-events:none;mix-blend-mode:screen;
  background:linear-gradient(90deg,transparent,rgba(120,200,255,.10),rgba(180,225,255,.55),rgba(120,200,255,.10),transparent);
  filter:blur(2px);animation:cineSweep 1.7s cubic-bezier(.5,0,.4,1) .55s forwards;opacity:0}
.cine-sweep::after{content:"";position:absolute;top:0;bottom:0;left:50%;width:2px;transform:translateX(-50%);background:linear-gradient(180deg,transparent,rgba(220,240,255,.95),transparent);box-shadow:0 0 26px 6px rgba(120,200,255,.7)}
@keyframes cineSweep{0%{left:-30%;opacity:0}12%{opacity:1}88%{opacity:1}100%{left:115%;opacity:0}}
.cine-core{position:relative;display:flex;flex-direction:column;align-items:center;gap:16px;text-align:center;will-change:transform,opacity}
/* orbe central com anéis */
.cine-orb{position:relative;width:128px;height:128px;display:flex;align-items:center;justify-content:center;animation:cineOrbIn 1s cubic-bezier(.2,.8,.2,1) forwards;opacity:0}
.cine-orb span{position:absolute;inset:30%;border-radius:50%;background:radial-gradient(circle at 40% 35%,#bcd6ff,#4da3ff 55%,#6a4bff);box-shadow:0 0 40px rgba(77,163,255,.8),0 0 90px rgba(106,75,255,.5)}
.cine-orb i{position:absolute;border-radius:50%;border:2px solid rgba(120,180,255,.5)}
.cine-orb i:nth-child(1){inset:0;border-top-color:#bcd6ff;animation:cineSpin 2.6s linear infinite}
.cine-orb i:nth-child(2){inset:14%;border-right-color:#8b7bff;animation:cineSpin 3.4s linear infinite reverse}
.cine-orb i:nth-child(3){inset:26%;border-bottom-color:#34e0c8;animation:cineSpin 4.6s linear infinite}
@keyframes cineSpin{to{transform:rotate(360deg)}}
@keyframes cineOrbIn{0%{opacity:0;transform:scale(.2);filter:blur(8px)}60%{opacity:1;transform:scale(1.12)}100%{opacity:1;transform:scale(1);filter:blur(0)}}
/* imagem da Athena grande, surgindo do centro */
.cine-ava{width:188px;height:188px;border-radius:50%;overflow:hidden;border:2px solid rgba(125,170,255,.55);
  box-shadow:0 0 50px rgba(77,163,255,.55),inset 0 0 30px rgba(10,20,50,.6);opacity:0;animation:cineAvaIn 1.2s cubic-bezier(.2,.8,.2,1) .15s forwards;margin-top:6px}
.cine-ava img{width:100%;height:100%;object-fit:cover;object-position:center top}
@keyframes cineAvaIn{0%{opacity:0;transform:scale(1.5);filter:blur(14px)}55%{opacity:1}100%{opacity:1;transform:scale(1);filter:blur(0)}}
.cine-title{font-family:var(--h-disp,'Orbitron',sans-serif);font-weight:900;letter-spacing:.42em;font-size:clamp(36px,7vw,82px);
  background:linear-gradient(92deg,#fff,#bcd6ff 55%,#a99bff);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;
  filter:drop-shadow(0 0 28px rgba(77,163,255,.45));padding-left:.42em;opacity:0;animation:cineTitleIn 1s cubic-bezier(.2,.8,.2,1) .45s forwards}
@keyframes cineTitleIn{0%{opacity:0;transform:translateY(16px) scale(.94);letter-spacing:.9em}100%{opacity:1;transform:none;letter-spacing:.42em}}
.cine-tag{font-family:var(--mono,monospace);font-size:clamp(11px,1.4vw,15px);letter-spacing:.55em;color:var(--teal,#34e0c8);text-transform:uppercase;padding-left:.55em;opacity:0;animation:cineTagIn .8s ease .95s forwards}
@keyframes cineTagIn{from{opacity:0}to{opacity:.92}}
@media (prefers-reduced-motion:reduce){.cine-intro *{animation-duration:.01s!important}}
/* títulos / texto — GRANDES e legíveis */
.bd-h{font-family:var(--h-sans);font-weight:700;color:#fff;margin:2px 0;line-height:1.2}
.bd-h1{font-size:30px}.bd-h2{font-size:24px}.bd-h3{font-size:19px;color:#cdd9f2}
.bd-text{font-size:19px;line-height:1.66;color:var(--ink)}
.bd-list{margin:0 0 0 8px;padding:0;list-style:none;font-size:18px;line-height:1.55;color:var(--ink);display:flex;flex-direction:column;gap:10px}
.bd-list li{position:relative;padding-left:30px}
.bd-list li::before{content:"";position:absolute;left:4px;top:.62em;width:9px;height:9px;border-radius:50%;background:radial-gradient(circle,#bfe0ff,var(--blue));box-shadow:0 0 10px var(--blue)}
ol.bd-list{counter-reset:bdli}
ol.bd-list li{counter-increment:bdli}
ol.bd-list li::before{content:counter(bdli);width:auto;height:auto;left:0;top:0;background:none;box-shadow:none;color:var(--blue);font-family:var(--h-disp);font-weight:700;font-size:15px}
/* STAT — números de impacto */
.bd-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:14px}
.bd-stat{background:linear-gradient(180deg,rgba(77,163,255,.08),rgba(0,0,0,.25));border:1px solid var(--line2);border-radius:16px;padding:20px 16px;text-align:center;position:relative;overflow:hidden}
.bd-stat::after{content:"";position:absolute;inset:0;border-radius:16px;box-shadow:inset 0 0 28px rgba(77,163,255,.1)}
.bd-stat-v{font-family:var(--h-disp);font-weight:800;font-size:clamp(30px,4vw,46px);line-height:1;background:linear-gradient(180deg,#fff,var(--blue));-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;filter:drop-shadow(0 0 16px rgba(77,163,255,.35))}
.bd-stat-l{margin-top:8px;font-size:14px;color:var(--ink-dim);font-family:var(--h-sans);letter-spacing:.3px}
.bd-stat-h{margin-top:4px;font-size:12px;color:var(--muted)}
/* STEPS — fluxo numerado */
.bd-steps{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:0}
.bd-step{position:relative;display:flex;gap:16px;padding:0 0 18px 0}
.bd-step:not(:last-child)::before{content:"";position:absolute;left:18px;top:38px;bottom:0;width:2px;background:linear-gradient(180deg,var(--blue),transparent)}
.bd-step-n{flex:none;width:38px;height:38px;border-radius:50%;display:grid;place-items:center;font-family:var(--h-disp);font-weight:700;font-size:16px;color:#fff;
  background:radial-gradient(circle at 50% 35%,rgba(77,163,255,.5),rgba(77,163,255,.12));border:1px solid var(--line2);box-shadow:0 0 16px rgba(77,163,255,.3)}
.bd-step-t{font-family:var(--h-sans);font-weight:700;color:#fff;font-size:18px}
.bd-step-d{color:var(--ink-dim);font-size:15.5px;line-height:1.5;margin-top:3px}
/* BRAND — logos de empresas de IA */
.bd-brands{display:flex;flex-wrap:wrap;gap:14px;justify-content:center}
.bd-brand-card{position:relative;min-width:128px;flex:0 1 150px;border:1px solid var(--line2);border-radius:16px;padding:18px 14px 12px;text-align:center;overflow:hidden;
  background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(0,0,0,.28));transition:transform .25s,box-shadow .25s,border-color .25s}
.bd-brand-card:hover{transform:translateY(-3px);border-color:var(--bc);box-shadow:0 10px 30px rgba(0,0,0,.35),0 0 22px color-mix(in srgb,var(--bc) 45%,transparent)}
.bd-brand-build{position:absolute;inset:0;background-size:cover;background-position:center;opacity:.16;filter:saturate(.7)}
.bd-brand-logo{position:relative;height:52px;display:flex;align-items:center;justify-content:center}
.bd-brand-img{max-height:46px;max-width:88%;object-fit:contain;filter:drop-shadow(0 2px 10px rgba(0,0,0,.4))}
/* WORDMARK: nome da marca na cor dela (fallback premium quando não há logo nítido) */
.bd-brand-mark{display:none;font-family:var(--h-sans);font-weight:700;font-size:19px;letter-spacing:.2px;line-height:1.1;
  color:color-mix(in srgb,var(--bc) 78%,#fff);text-shadow:0 0 18px color-mix(in srgb,var(--bc) 50%,transparent)}
.bd-brand-card.wordmark .bd-brand-logo{height:auto;min-height:46px;padding:4px 2px}
.bd-brand-card.wordmark .bd-brand-mark{display:block}
.bd-brand-card.wordmark .bd-brand-name{display:none}
.bd-brand-card.wordmark{border-color:color-mix(in srgb,var(--bc) 40%,var(--line2))}
.bd-brand-name{position:relative;margin-top:12px;font-family:var(--h-sans);font-weight:600;font-size:14px;color:#eaf1ff}
.bd-brands-cap{text-align:center;color:var(--muted);font-size:13px;margin-top:10px}
/* tabela */
.bd-tablewrap{overflow:auto;border:1px solid var(--line2);border-radius:14px;background:rgba(0,0,0,.18)}
.bd-table{border-collapse:collapse;width:100%;font-size:16px}
.bd-table th,.bd-table td{padding:13px 16px;text-align:left;vertical-align:top;border-bottom:1px solid var(--line)}
.bd-table th{background:rgba(77,163,255,.14);color:#fff;font-weight:600;font-family:var(--h-sans);letter-spacing:.2px}
.bd-table tr:last-child td{border-bottom:0}
.bd-table tbody tr:hover{background:rgba(125,160,255,.06)}
/* comparativo */
.bd-compare{display:flex;gap:16px}
.bd-compare.cols-3{flex-wrap:wrap}
.bd-col{flex:1;min-width:210px;background:linear-gradient(180deg,rgba(255,255,255,.04),rgba(0,0,0,.24));border:1px solid var(--line2);border-radius:16px;padding:18px 18px;border-top:3px solid var(--blue);box-shadow:0 6px 22px rgba(0,0,0,.22)}
.bd-col.green{border-top-color:var(--teal)}.bd-col.amber{border-top-color:var(--gold)}.bd-col.violet{border-top-color:var(--violet)}
.bd-col-h{font-family:var(--h-sans);font-weight:700;color:#fff;margin-bottom:12px;font-size:18px}
.bd-col ul{margin:0;padding:0;list-style:none;line-height:1.5;font-size:16px;color:var(--ink);display:flex;flex-direction:column;gap:8px}
.bd-col ul li{position:relative;padding-left:20px}
.bd-col ul li::before{content:"›";position:absolute;left:2px;top:-1px;color:var(--blue);font-weight:700}
/* callout */
.bd-callout{border-left:4px solid var(--blue);background:linear-gradient(90deg,rgba(77,163,255,.12),transparent);padding:16px 20px;border-radius:12px;font-size:17px;line-height:1.55}
.bd-callout.key{border-left-color:var(--violet);background:linear-gradient(90deg,rgba(179,136,255,.14),transparent)}
.bd-callout.warn{border-left-color:var(--gold);background:linear-gradient(90deg,rgba(255,209,102,.14),transparent)}
.bd-callout.quote{border-left-color:var(--teal);font-style:italic;color:var(--ink-dim)}
.bd-callout-t{font-family:var(--h-sans);font-weight:700;color:#fff;margin-bottom:4px;font-size:16px}
/* código — janela de terminal */
.bd-code{border:1px solid var(--line2);border-radius:14px;overflow:hidden;box-shadow:0 8px 26px rgba(0,0,0,.32)}
.bd-code-bar{display:flex;align-items:center;gap:7px;background:rgba(0,0,0,.5);padding:9px 14px;border-bottom:1px solid var(--line)}
.bd-dot{width:11px;height:11px;border-radius:50%;display:inline-block}
.bd-dot.r{background:#ff5f57}.bd-dot.y{background:#febc2e}.bd-dot.g{background:#28c840}
.bd-code-lang{margin-left:8px;color:var(--ink-dim);font-family:var(--mono);font-size:11px;letter-spacing:1.5px;text-transform:uppercase}
.bd-code pre{margin:0;padding:18px;background:rgba(2,6,14,.65);overflow:auto}
.bd-code code{font-family:var(--mono);font-size:15px;line-height:1.6;color:#e6edf6;white-space:pre-wrap}
/* imagem — moldura premium + Ken Burns */
.bd-figure{margin:0;text-align:center}
.bd-figure-frame{position:relative;display:inline-block;max-width:100%;border-radius:16px;overflow:hidden;border:1px solid var(--line2);box-shadow:0 12px 34px rgba(0,0,0,.4),0 0 0 1px rgba(125,160,255,.1)}
.bd-figure-frame::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,transparent 60%,rgba(7,11,22,.55));pointer-events:none}
.bd-figure img{display:block;max-width:100%;max-height:420px;object-fit:cover;transform:scale(1.02)}
.bd-block.show .bd-figure img{animation:bdKen 9s ease-out forwards}   /* zoom suave UMA vez ao revelar (não infinito = mais leve) */
@keyframes bdKen{from{transform:scale(1.02)}to{transform:scale(1.07)}}
.bd-figure figcaption{color:var(--ink-dim);font-size:14px;margin-top:10px}
/* gráfico */
.bd-chart{background:rgba(0,0,0,.2);border:1px solid var(--line2);border-radius:16px;padding:16px 18px}
.bd-chart-t{font-family:var(--h-sans);font-weight:700;color:#fff;margin-bottom:10px;font-size:18px}
.bd-svg{width:100%;height:auto;display:block}
.bd-grid{stroke:var(--line)}
.bd-axis{fill:var(--muted);font-size:11px;font-family:var(--mono)}
.bd-legend{display:flex;gap:16px;flex-wrap:wrap;margin-top:10px;font-size:13.5px;color:var(--ink-dim)}
.bd-leg{display:inline-flex;align-items:center;gap:6px}.bd-leg i{width:12px;height:12px;border-radius:3px;display:inline-block}
/* pergunta de fixação */
.bd-question{border:1.5px dashed var(--blue);background:radial-gradient(120% 120% at 0% 0%,rgba(77,163,255,.12),transparent 60%),rgba(77,163,255,.05);border-radius:18px;padding:22px 24px;box-shadow:0 0 30px rgba(77,163,255,.12)}
.bd-q-tag{font-family:var(--mono);font-size:12px;letter-spacing:2px;text-transform:uppercase;color:var(--blue)}
.bd-q-prompt{font-size:21px;font-weight:700;color:#fff;margin:8px 0;line-height:1.35}
.bd-q-opts{margin:10px 0 0;padding:0;list-style:none;line-height:1.7;color:var(--ink);font-size:17px;display:flex;flex-direction:column;gap:8px}
/* TABLET 1 — a opcao virou um <button> de verdade (ver boardkit.js). O antigo `li::before{content:"○"}` saiu:
   a bolinha decorativa foi substituida pela LETRA (A/B/C), que e o que o texto da resposta cita ("C. ...").
   ALVO DE TOQUE: min-height 44px (WCAG 2.5.5 / HIG). Aqui e min-height no PROPRIO botao, e nao o truque do
   ::after usado no .stop-btn/.blk, porque a opcao e um bloco de texto que ja ocupa a linha inteira — crescer
   a caixa nao desalinha nada (no .stop-btn crescia a faixa e descentralizava o icone do avatar; aqui nao ha
   vizinho ancorado a mao). touch-action:manipulation mata o atraso de ~300ms do duplo-toque-zoom no iOS. */
.bd-q-opt{display:flex;align-items:center;gap:12px;width:100%;min-height:44px;text-align:left;
  padding:9px 14px 9px 10px;border:1px solid var(--line2);border-radius:12px;background:rgba(255,255,255,.03);
  color:var(--ink);font-family:inherit;font-size:inherit;line-height:1.5;cursor:pointer;
  touch-action:manipulation;-webkit-tap-highlight-color:transparent;transition:border-color .15s ease,background .15s ease}
.bd-q-opt:hover{border-color:var(--blue);background:rgba(77,163,255,.08)}
.bd-q-opt:focus-visible{outline:none;border-color:var(--blue);box-shadow:var(--glow)}
.bd-q-letter{flex:none;width:26px;height:26px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  border:1px solid var(--line2);color:var(--blue);font-family:var(--mono);font-size:12.5px}
.bd-q-otext{flex:1}
/* Estados APOS responder. .sel = a que o aluno tocou; .ok/.no = o veredito, que so aparece quando o
   correctOptionIndex resolveu (27 dos 31 blocos reais). Sem veredito, so a selecao e marcada. */
.bd-q-opt.sel{border-color:var(--blue);background:rgba(77,163,255,.14)}
.bd-q-opt.ok{border-color:var(--ok);background:rgba(56,224,160,.14)}
.bd-q-opt.ok .bd-q-letter{border-color:var(--ok);color:var(--ok)}
.bd-q-opt.no{border-color:var(--danger);background:rgba(255,92,122,.12)}
.bd-q-opt.no .bd-q-letter{border-color:var(--danger);color:var(--danger)}
/* Respondida: as demais esmaecem, mas continuam LEGIVEIS (o aluno relê as alternativas junto da explicação). */
.bd-q-opts.answered .bd-q-opt:not(.sel):not(.ok){opacity:.62}
@media (hover:none){ .bd-q-opt:hover{border-color:var(--line2);background:rgba(255,255,255,.03)} }
.bd-q-btn{margin-top:14px;cursor:pointer;background:linear-gradient(180deg,rgba(77,163,255,.28),rgba(77,163,255,.06));border:1px solid var(--line2);color:#fff;border-radius:999px;padding:9px 18px;font-family:var(--h-sans);font-size:14px;transition:.18s}
.bd-q-btn:hover{box-shadow:var(--glow);border-color:var(--blue)}
.bd-q-ans{margin-top:12px;color:var(--ok);font-weight:600;font-size:17px}
/* Q3 — convite da pergunta ABERTA (a de aplicação, o formato das aulas novas). Não é botão: a resposta vai
   para o chat, onde a Beatriz avalia contra o gabarito de referência e registra a evidência de retenção. */
.bd-q-open{margin-top:14px;color:var(--blue);font-size:15px;font-weight:600}
/* Q4 — RODAPÉ DE FONTE DO SLIDE. Discreto por desenho: é procedência, não conteúdo — não pode competir com
   o que está sendo ensinado, mas tem de estar legível ao lado do dado que sustenta. */
.bd-fontes{margin-top:22px;padding-top:10px;border-top:1px solid var(--line);display:flex;gap:10px;align-items:baseline;flex-wrap:wrap}
.bd-fontes-t{font-family:var(--h-sans);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);flex:0 0 auto}
.bd-fontes ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px}
.bd-fontes li{color:var(--muted);font-size:13px;line-height:1.45}
.bd-fontes a{color:var(--muted);text-decoration:underline;text-underline-offset:2px}
.bd-fontes a:hover{color:var(--blue)}
.bd-muted{color:var(--muted);font-size:14px}
/* ===== LOTE A — acabamento HUD portado do mockup rag-hud (2026-07-06) =====
   Escopo TRAVADO em #boardPanel/#boardStage/.bd-* -> NAO afeta o mapa vivo (#mapPanel, mesma classe
   .board-panel) nem o PDF (pp-slide nao fica sob #boardStage). NAO toca schema de blocos nem reveal por voz. */
#boardStage{
  --bd-cyan:#35e6ff;--bd-cyan2:#8af4ff;--bd-cyan-line:rgba(53,230,255,.22);--bd-cyan-soft:rgba(53,230,255,.09);--bd-cyan-glow:rgba(53,230,255,.42);
  --bd-amber:#ffb454;--bd-amber-line:rgba(255,180,84,.32);--bd-amber-soft:rgba(255,180,84,.07);
  --bd-emerald:#4de3a0;--bd-emerald-line:rgba(77,227,160,.32);--bd-emerald-soft:rgba(77,227,160,.07);
  --bd-ink-faint:#46575f;--bd-disp:'Space Grotesk',system-ui,sans-serif;
  display:flex;flex-direction:column;   /* fI: habilita centralização V+H do slide via margin:auto (escopado no #boardStage; NÃO toca #mapStage) */
  /* ticks de aresta (4 slivers ciano no meio das bordas) — no fundo do stage, fixos ao box */
  background:
    linear-gradient(var(--bd-cyan-line) 0 0) top center/1px 12px no-repeat,
    linear-gradient(var(--bd-cyan-line) 0 0) bottom center/1px 12px no-repeat,
    linear-gradient(var(--bd-cyan-line) 0 0) left center/12px 1px no-repeat,
    linear-gradient(var(--bd-cyan-line) 0 0) right center/12px 1px no-repeat;
}
/* fI: CENTRALIZA a lousa no palco (flex-column). width:100% é ESSENCIAL — sem ele, margin:auto no eixo cruzado
   sobrepõe o align-items:stretch e o slide encolhe para a largura do CONTEÚDO (fica estreito); com width:100% ele
   preenche até o max-width:960px e aí as margens auto centram. margin:auto (não 0 auto) centra V+H; quando o slide
   passa da altura do stage as margens auto viram 0 → topo alinhado e overflow:auto rola SEM cortar o topo (o
   justify-content:center é que cortaria). Especificidade (#boardStage .bd-slide) vence o .bd-slide{margin:0 auto}.
   O mapa vivo (#mapStage .bd-slide) NÃO é atingido → mantém só o horizontal. */
#boardStage .bd-slide{width:100%;margin:auto}
/* BLOCO 3: chip de ORIGEM de um slide CITADO (show_slide) — marca "veio de outra aula", distinto de aula ativa. */
#boardStage .bd-cite,.bd-cite{display:inline-flex;align-items:center;gap:6px;align-self:flex-start;margin:0 0 12px;padding:4px 12px;border:1px solid var(--bd-amber-line,rgba(255,180,84,.32));border-radius:999px;background:var(--bd-amber-soft,rgba(255,180,84,.09));color:var(--bd-amber,#ffb454);font-family:var(--mono,monospace);font-size:11.5px;letter-spacing:.06em;text-transform:uppercase}
/* tela: gradiente + brilho interno + borda ciano (board only) */
#boardPanel{border-color:var(--bd-cyan-line);
  background:radial-gradient(140% 120% at 50% -20%,rgba(53,230,255,.06) 0%,transparent 42%),linear-gradient(180deg,#0a141d 0%,#060d14 40%,#04090e 100%);
  box-shadow:0 40px 120px -30px rgba(0,0,0,.7),inset 0 0 140px rgba(53,230,255,.035),inset 0 1px 0 rgba(255,255,255,.04)}
/* grid interior ciano (override do grid azul do .board-panel) */
#boardPanel::before{background-image:linear-gradient(rgba(53,230,255,.045) 1px,transparent 1px),linear-gradient(90deg,rgba(53,230,255,.045) 1px,transparent 1px);background-size:52px 52px;opacity:.55;
  -webkit-mask-image:radial-gradient(ellipse at 50% 45%,#000 30%,transparent 88%);mask-image:radial-gradient(ellipse at 50% 45%,#000 30%,transparent 88%)}
/* scan vertical passando ATRAS (override do sweep horizontal do .board-panel) */
#boardPanel::after{left:0;top:-64px;width:100%;height:64px;filter:none;mix-blend-mode:screen;opacity:.7;
  background:linear-gradient(180deg,transparent,rgba(53,230,255,.10),transparent);animation:bdScanV 8.5s linear infinite}
@keyframes bdScanV{0%{top:-64px}100%{top:100%}}
@media (prefers-reduced-motion:reduce){#boardPanel::after{animation:none;opacity:0}}
/* cantos + underline do titulo em ciano */
#boardStage .bd-frame i{border-color:var(--bd-cyan);filter:drop-shadow(0 0 6px var(--bd-cyan-soft));opacity:.6}
#boardStage .bd-head::after{background:linear-gradient(90deg,var(--bd-cyan),transparent);box-shadow:0 0 14px var(--bd-cyan-glow)}
/* eyebrow — linha ciano antes do rotulo */
#boardStage .bd-lesson{color:var(--bd-cyan);letter-spacing:.22em;display:flex;align-items:center;gap:10px;text-shadow:0 0 14px var(--bd-cyan-soft)}
#boardStage .bd-lesson::before{content:"";flex:none;width:26px;height:1px;background:var(--bd-cyan);box-shadow:0 0 8px var(--bd-cyan)}
/* chip neon (==destaque==) */
#boardStage .bd-key{background:var(--bd-cyan-soft);border:1px solid var(--bd-cyan-line);color:var(--bd-cyan);-webkit-text-fill-color:var(--bd-cyan);box-shadow:0 0 18px var(--bd-cyan-soft) inset;border-radius:6px;padding:.06em .42em;font-weight:500}
/* fonte de display ESCOPADA no board (Space Grotesk; NAO mexe em --h-disp global) */
#boardStage .bd-hero-words,#boardStage .bd-hero-line,#boardStage .bd-morph,#boardStage .bd-stat-v,#boardStage .bd-step-n,#boardStage ol.bd-list li::before{font-family:var(--bd-disp)}
/* stat — HUD do mockup: borda esquerda + numero ciano tabular + glow */
#boardStage .bd-stat{background:none;border:0;border-left:1px solid var(--bd-cyan-line);border-radius:0;padding:2px 0 2px 16px;text-align:left;overflow:visible}
#boardStage .bd-stat::after{display:none}
#boardStage .bd-stat-v{background:none;-webkit-background-clip:border-box;background-clip:border-box;-webkit-text-fill-color:var(--bd-cyan);color:var(--bd-cyan);font-variant-numeric:tabular-nums;text-shadow:0 0 28px var(--bd-cyan-glow)}
#boardStage .bd-stat-l{color:var(--ink);text-align:left}
#boardStage .bd-stat-h{color:var(--bd-ink-faint);font-family:var(--mono);text-align:left}
/* compare — barra inset lateral + glow + bullets glow (a marca ✕/✓ segue vindo no texto do rotulo) */
#boardStage .bd-col{background:rgba(255,255,255,.015);border:1px solid var(--bd-cyan-line);border-top:1px solid var(--bd-cyan-line);box-shadow:inset 3px 0 0 var(--bd-cyan),0 0 40px var(--bd-cyan-soft)}
#boardStage .bd-col.amber{border-color:var(--bd-amber-line);box-shadow:inset 3px 0 0 var(--bd-amber),0 0 40px var(--bd-amber-soft)}
#boardStage .bd-col.green{border-color:var(--bd-emerald-line);box-shadow:inset 3px 0 0 var(--bd-emerald),0 0 40px var(--bd-emerald-soft)}
#boardStage .bd-col.violet{border-color:rgba(185,162,255,.32);box-shadow:inset 3px 0 0 var(--violet),0 0 40px rgba(185,162,255,.07)}
#boardStage .bd-col-h{color:#fff}
#boardStage .bd-col.amber .bd-col-h{color:var(--bd-amber)}
#boardStage .bd-col.green .bd-col-h{color:var(--bd-emerald)}
#boardStage .bd-col ul li{padding-left:16px}
#boardStage .bd-col ul li::before{content:"";left:0;top:.6em;width:5px;height:5px;border-radius:50%;background:var(--bd-cyan);opacity:.8;font-weight:400}
#boardStage .bd-col.amber ul li::before{background:var(--bd-amber);opacity:.7}
#boardStage .bd-col.green ul li::before{background:var(--bd-emerald);opacity:.85;box-shadow:0 0 6px var(--bd-emerald)}
/* table — HUD mono do mockup */
#boardStage .bd-tablewrap{background:none;border:0;border-radius:0}
#boardStage .bd-table{font-family:var(--mono)}
#boardStage .bd-table th{background:none;color:var(--bd-cyan);text-transform:uppercase;letter-spacing:.14em;font-weight:500;font-size:12px;font-family:var(--mono);border-bottom:1px solid var(--bd-cyan-line)}
#boardStage .bd-table td{color:var(--ink-dim);border-bottom:1px solid rgba(53,230,255,.07)}
#boardStage .bd-table td:first-child{color:var(--bd-cyan2);font-weight:500}
#boardStage .bd-table tbody tr:hover{background:rgba(53,230,255,.05)}
/* morph — risco ambar na palavra velha + clip-reveal ciano na nova (caráter do mockup) */
#boardStage .bd-morph{flex-wrap:wrap}
#boardStage .bd-morph-from{position:relative;color:var(--bd-amber);animation:bdMorphFrom2 7s ease-in-out infinite}
#boardStage .bd-morph-from::after{content:"";position:absolute;left:-2%;right:-2%;top:52%;height:3px;background:var(--bd-amber);opacity:.7;transform:scaleX(0);transform-origin:left;box-shadow:0 0 10px var(--bd-amber);animation:bdStrike 7s ease-in-out infinite}
#boardStage .bd-morph-to{background:none;-webkit-background-clip:border-box;background-clip:border-box;-webkit-text-fill-color:var(--bd-cyan);color:var(--bd-cyan);filter:none;text-shadow:0 0 30px var(--bd-cyan-glow);animation:bdMorphTo2 7s ease-in-out infinite}
#boardStage .bd-morph-trail{display:none}
@keyframes bdMorphFrom2{0%{opacity:.85}8%{opacity:.4}10%{opacity:.75}13%{opacity:.35}44%{opacity:.5}100%{opacity:.5}}
@keyframes bdMorphTo2{0%{clip-path:inset(0 100% 0 0);opacity:0}14%{clip-path:inset(0 0 0 0);opacity:1}82%{opacity:1}100%{opacity:1}}
@keyframes bdStrike{0%,26%{transform:scaleX(0)}44%{transform:scaleX(1)}100%{transform:scaleX(1)}}
@media (prefers-reduced-motion:reduce){#boardStage .bd-morph-from,#boardStage .bd-morph-from::after,#boardStage .bd-morph-to{animation:none}#boardStage .bd-morph-to{clip-path:none;opacity:1}#boardStage .bd-morph-from{opacity:.5}#boardStage .bd-morph-from::after{transform:scaleX(1)}}
/* ===== Currículo vivo (Master Admin) ===== */
.cur-row{display:flex;gap:12px;align-items:flex-start;padding:11px 0;border-bottom:1px solid var(--line)}
.cur-main{flex:1;min-width:0}
.cur-topic{font-weight:600;color:var(--ink)}
.cur-why{font-size:12px;color:var(--ink-dim);margin-top:2px;line-height:1.5}
.cur-dim{display:inline-block;margin-top:5px;font-size:10.5px;font-family:var(--mono);color:var(--gold);border:1px solid var(--line2);border-radius:999px;padding:1px 9px}
.cur-acts{display:flex;gap:6px;flex-shrink:0}
.cur-drow{font-size:12.5px;padding:3px 0;color:var(--ink-dim)}
.reassess-panel{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}
.browser-cap{position:absolute;left:0;right:0;bottom:0;padding:8px 12px;font-size:11px;color:var(--ink-dim);
  background:linear-gradient(0deg,rgba(0,0,0,.78),transparent);font-family:var(--mono)}

/* ---- Orb panel ---- */
.orb-panel{display:flex;flex-direction:column;align-items:center;gap:12px;padding-top:26px}
.orb{position:relative;width:180px;height:180px;border-radius:50%;display:grid;place-items:center}
.orb-core{width:118px;height:118px;border-radius:50%;
  background:radial-gradient(circle at 50% 38%,#cfe6ff,#4da3ff 50%,#16356e 80%);
  box-shadow:0 0 40px rgba(77,163,255,.5),inset 0 0 30px rgba(255,255,255,.25);transition:.3s}
.orb-ring{position:absolute;inset:0;border-radius:50%;border:1.5px solid rgba(77,163,255,.4);
  border-top-color:var(--blue);animation:spin 6s linear infinite;opacity:.55}
.orb.listening .orb-core{background:radial-gradient(circle at 50% 38%,#d7fff2,#34e0c8 50%,#0c5a4d 80%);box-shadow:0 0 48px rgba(52,224,200,.6)}
.orb.listening{animation:breathe 1.6s ease-in-out infinite}
.orb.thinking .orb-core{background:radial-gradient(circle at 50% 38%,#fff0cf,#ffc24d 50%,#7a5413 80%);box-shadow:0 0 44px rgba(255,194,77,.55)}
.orb.thinking .orb-ring{animation:spin 1.1s linear infinite}
.orb.speaking .orb-core{background:radial-gradient(circle at 50% 38%,#e6dcff,#8b7bff 50%,#34216e 80%);box-shadow:0 0 48px rgba(139,123,255,.6)}
.orb-state{font-family:var(--mono);font-size:12px;color:var(--ink-dim);letter-spacing:1px;text-transform:uppercase}
.mic-btn{display:flex;align-items:center;gap:9px;cursor:pointer;border:1px solid var(--line2);border-radius:999px;
  padding:11px 20px;color:var(--ink);background:linear-gradient(180deg,rgba(77,163,255,.16),rgba(77,163,255,.04));
  font-family:var(--h-sans);font-size:13px;letter-spacing:.5px;transition:.18s}
.mic-btn:hover{box-shadow:var(--glow)}
.mic-btn.on{background:linear-gradient(180deg,rgba(52,224,200,.2),rgba(52,224,200,.05));border-color:rgba(52,224,200,.5)}
.mic-ico{width:11px;height:11px;border-radius:50%;background:var(--danger);box-shadow:0 0 10px var(--danger)}
.mic-btn.on .mic-ico{background:var(--ok);box-shadow:0 0 10px var(--ok)}
.hint{font-size:11px}

/* ---- Buttons / inputs ---- */
.btn{display:inline-flex;align-items:center;gap:8px;cursor:pointer;text-decoration:none;
  background:linear-gradient(180deg,rgba(77,163,255,.22),rgba(77,163,255,.06));color:#fff;
  border:1px solid var(--line2);border-radius:10px;padding:10px 16px;font-family:var(--h-sans);font-size:13px;transition:.18s}
.btn:hover{box-shadow:var(--glow)}
.btn.small{padding:6px 12px;font-size:12px}
.greet-cta{align-self:flex-start;display:flex;flex-wrap:wrap;gap:8px;margin:2px 0 4px}
.greet-cta .btn{padding:8px 14px;font-size:12.5px}
.ghost{cursor:pointer;background:transparent;border:1px solid var(--line);color:var(--muted);border-radius:8px;padding:5px 11px;font-size:12px;font-family:var(--b-sans)}
.ghost:hover{color:var(--ink);border-color:var(--line2)}
.row{display:flex;align-items:center;gap:10px;margin:10px 0;color:var(--ink-dim);font-size:13px}
.row input[type=range]{flex:1;accent-color:var(--blue)}
.proto{width:100%;min-height:240px;background:rgba(0,0,0,.3);border:1px solid var(--line);border-radius:12px;
  color:var(--ink-dim);font-family:var(--mono);font-size:12.5px;line-height:1.6;padding:14px;resize:vertical}
code{font-family:var(--mono);background:rgba(255,255,255,.07);padding:1px 6px;border-radius:5px;font-size:12px;color:var(--teal)}

/* ---- Diagnostico ---- */
.diag-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px}
@media(max-width:1180px){.diag-grid{grid-template-columns:1fr}}
.sg-list{list-style:none;margin:0;padding:0}
.sg-list li{padding:7px 0 7px 22px;position:relative;font-size:13px;color:var(--ink-dim);border-bottom:1px solid var(--line)}
.sg-list.str li::before{content:"▲";position:absolute;left:0;color:var(--ok);font-size:10px;top:9px}
.sg-list.gap li::before{content:"▼";position:absolute;left:0;color:var(--gold);font-size:10px;top:9px}
.summary-box{font-size:13.5px;line-height:1.65;color:var(--ink-dim)}

/* ---- Plano ---- */
.phase{border:1px solid var(--line);border-radius:16px;padding:16px;margin-bottom:14px;background:var(--panel)}
.phase.cur{border-color:var(--line2);box-shadow:inset 0 0 26px rgba(77,163,255,.1)}
.phase-h{display:flex;align-items:center;gap:12px;margin-bottom:6px}
.phase-n{width:30px;height:30px;border-radius:9px;display:grid;place-items:center;font-family:var(--h-disp);font-weight:700;
  background:rgba(77,163,255,.16);border:1px solid var(--line2);color:var(--blue);font-size:14px}
.phase-h h3{margin:0;font-family:var(--h-sans);font-size:16px;font-weight:600}
.phase-wk{font-family:var(--mono);font-size:11px;color:var(--muted);margin-left:auto}
.phase-focus{display:flex;flex-wrap:wrap;gap:6px;margin:6px 0 12px}
.tag{font-size:11px;padding:3px 9px;border-radius:999px;border:1px solid var(--line);color:var(--ink-dim);background:rgba(255,255,255,.03)}
.three{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
@media(max-width:900px){.three{grid-template-columns:1fr}}
.col70,.col20,.col10{border-radius:12px;padding:12px;background:rgba(0,0,0,.18);border:1px solid var(--line)}
.col-h{font-size:11px;letter-spacing:1px;text-transform:uppercase;margin:0 0 8px;font-weight:600}
.col70 .col-h{color:var(--blue)} .col20 .col-h{color:var(--violet)} .col10 .col-h{color:var(--teal)}
.col-list{list-style:none;margin:0;padding:0}
.col-list li{font-size:12.5px;color:var(--ink-dim);padding:5px 0 5px 16px;position:relative;line-height:1.4}
.col-list li::before{content:"";position:absolute;left:2px;top:10px;width:5px;height:5px;border-radius:50%;background:var(--muted)}

/* ---- Biblioteca ---- */
.lib-filters{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:16px}
.fchip{cursor:pointer;font-size:12px;padding:6px 13px;border-radius:999px;border:1px solid var(--line);color:var(--muted);background:var(--panel)}
.fchip.on{color:#fff;border-color:var(--line2);background:linear-gradient(180deg,rgba(77,163,255,.2),rgba(77,163,255,.05))}
.lib-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:14px}
.src{border:1px solid var(--line);border-radius:14px;padding:14px;background:var(--panel);transition:.18s;display:flex;flex-direction:column;gap:7px}
.src:hover{border-color:var(--line2);transform:translateY(-2px);box-shadow:0 10px 30px rgba(0,0,0,.3)}
.src-top{display:flex;align-items:center;gap:8px;justify-content:space-between}
.src-type{font-size:10px;text-transform:uppercase;letter-spacing:1px;color:var(--teal);font-family:var(--mono)}
.src-p{font-size:10px;font-family:var(--mono);padding:2px 7px;border-radius:6px;background:rgba(255,194,77,.14);color:var(--gold)}
.src-name{font-family:var(--h-sans);font-weight:600;font-size:14px;line-height:1.3}
.src-name a{color:var(--ink);text-decoration:none}
.src-name a:hover{color:var(--blue)}
.src-prov{font-size:11.5px;color:var(--muted)}
.src-desc{font-size:12px;color:var(--ink-dim);line-height:1.45}
.src-meta{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:2px;font-size:10.5px;color:var(--muted);font-family:var(--mono)}
/* Selo de custo — enquadra o pago como APROFUNDAMENTO opcional (aluno já paga a assinatura), não cobrança.
   Escopado à Biblioteca (#libBody) p/ não vazar. Hierarquia: free destacado > freemium neutro > paid o mais discreto. */
#libBody .cost-badge{display:inline-flex;align-items:center;font-size:10px;line-height:1;padding:3px 8px;border-radius:999px;border:1px solid var(--line);font-family:var(--mono);letter-spacing:.2px;white-space:nowrap}
#libBody .cost-free{color:var(--teal);border-color:rgba(52,224,200,.35);background:rgba(52,224,200,.08)}
#libBody .cost-freemium{color:var(--ink-dim);border-color:var(--line);background:var(--panel)}
#libBody .cost-opt{color:var(--muted);border-color:var(--line);background:var(--panel2);cursor:default}
#libBody .cost-other{color:var(--muted);border-color:var(--line);background:var(--panel)}

/* ---- Avatar animado ---- */
/* A altura vem da variavel (era 176px cravado). MOBILE/TABLET NAO SAO AFETADOS por construcao: as regras
   `html.is-mobile .avatar-stage{height:30px}` (0,2,1) e `html.is-tablet.chat-full .avatar-stage{height:96px}`
   (0,3,1) setam a PROPRIEDADE direto, com especificidade maior que este `.avatar-stage` (0,1,0) — entao o
   icone de 30px do celular continua imune ao que o aluno arrastar no desktop, sem nenhum `if` no JS. */
.avatar-stage{position:relative;height:var(--avatar-h);flex-shrink:0;display:flex;align-items:flex-end;justify-content:center;border-bottom:1px solid var(--line);overflow:hidden}
/* A escolha do aluno (ver public/avatarkit.js). Fica DEPOIS do :root e e mais especifica (0,1,1 > 0,1,0). */
html.avatar-manual{--avatar-h:var(--avatar-user)}
.avatar-aura{position:absolute;top:16px;left:50%;width:124px;height:124px;border-radius:50%;transform:translateX(-50%);background:radial-gradient(circle,rgba(139,123,255,.32),transparent 65%);filter:blur(8px);opacity:.6;transition:transform .16s ease,opacity .28s ease,background .4s ease}
/* max-height acompanha o palco (era 174px cravado = 176 - 2, a folga da border-bottom). E ESTE max-height
   que governa o tamanho VISIVEL do retrato: com object-fit:contain, mexer nele muda altura E largura JUNTAS,
   na proporcao original da imagem — por isso a alca move um numero so e a figura escala inteira.
   SEM transition de tamanho de proposito: durante o arrasto ela faria a figura "perseguir" o ponteiro com
   atraso. A transition de `transform` (a respiracao/apontar) segue intacta — sao propriedades diferentes. */
.avatar-img{position:relative;z-index:2;max-height:calc(var(--avatar-h) - 2px);max-width:96%;object-fit:contain;transform-origin:50% 100%;will-change:transform;filter:drop-shadow(0 6px 14px rgba(0,0,0,.5));transition:transform .5s cubic-bezier(.25,.8,.3,1)}
.avatar-placeholder{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);z-index:3;cursor:pointer;background:var(--panel);border:1px dashed var(--line2);color:var(--ink-dim);border-radius:12px;padding:16px 18px;font-size:18px;display:flex;flex-direction:column;align-items:center;gap:6px;font-family:var(--b-sans)}
.avatar-placeholder span{font-size:11px}
.avatar-placeholder:hover{color:#fff;border-color:var(--blue)}
/* Painel "Imagem da Athena" em Configurações (preview + trocar + restaurar) */
.avatar-cfg{display:flex;gap:16px;align-items:flex-start;margin-top:8px;flex-wrap:wrap}
.avatar-cfg-img{width:112px;height:112px;flex:none;border-radius:14px;object-fit:cover;border:1px solid var(--line);background:rgba(255,255,255,.03)}
.avatar-cfg-actions{display:flex;flex-direction:column;gap:8px;align-items:flex-start}
/* Bloco AVATARES do Master (#asec-avatares): as 3 linhas empilhadas, separadas por um filete.
   Reusa .avatar-cfg/.avatar-cfg-img/.avatar-cfg-actions (mesma cara dos painéis antigos de Config). */
.av-row{padding:16px 0;border-bottom:1px solid var(--line)}
.av-row:first-child{padding-top:4px}
.av-row:last-child{border-bottom:0;padding-bottom:4px}
.av-row .avatar-cfg-actions{flex:1;min-width:240px}
.av-btns{display:flex;gap:8px;flex-wrap:wrap;margin-top:2px}
/* O atributo `hidden` NÃO funciona sozinho em .btn: `.btn{display:inline-flex}` é seletor de CLASSE
   (0-1-0) e vence o `[hidden]{display:none}` do user-agent. Sem esta regra, o "Restaurar padrão"
   aparece mesmo quando não há nada a restaurar (pego na verificação: hidden=true e width=124px).
   Escopado ao bloco de avatares de propósito — a mesma armadilha existe em outros .btn[hidden] do app,
   mas um `[hidden]{display:none!important}` global mexeria em telas que não auditei. */
.av-btns .btn[hidden]{display:none}
.point-hand{position:absolute;z-index:4;left:50%;bottom:46px;width:46px;height:46px;opacity:0;transform-origin:50% 50%;transition:opacity .2s;pointer-events:none}
.point-hand svg{width:100%;height:100%;fill:none;stroke:var(--gold);stroke-width:3.4;stroke-linecap:round;stroke-linejoin:round;filter:drop-shadow(0 0 8px rgba(255,194,77,.9))}
.point-text{position:absolute;z-index:4;bottom:7px;left:6px;right:6px;text-align:center;font-size:11px;color:var(--gold);font-family:var(--mono);opacity:0;transition:.2s;text-shadow:0 1px 6px rgba(0,0,0,.9)}
/* Animação calma: respiração lenta (sem rotação) + aura que pulsa por palavra ao falar */
.avatar-stage.idle .avatar-img,
.avatar-stage.thinking .avatar-img,
.avatar-stage.speaking .avatar-img{animation:av-breathe 4.6s ease-in-out infinite}
.avatar-stage.thinking .avatar-aura{background:radial-gradient(circle,rgba(255,194,77,.4),transparent 65%);animation:av-glow 2.8s ease-in-out infinite}
.avatar-stage.speaking .avatar-aura{background:radial-gradient(circle,rgba(77,163,255,.5),transparent 65%);animation:av-glow 2.4s ease-in-out infinite}
.avatar-stage.pulse .avatar-aura{animation:none;opacity:1;transform:translateX(-50%) scale(1.16)}
.avatar-stage.pointing .point-hand{opacity:1;animation:av-hand .7s ease-in-out infinite}
.avatar-stage.pointing .point-text{opacity:1}
.avatar-stage.pointing .avatar-img{animation:none}
.avatar-stage.dir-up-left .avatar-img{transform:rotate(-4deg) translateX(-6px) translateY(-2px)}
.avatar-stage.dir-up-left .point-hand{transform:rotate(-135deg);bottom:104px;left:16%}
.avatar-stage.dir-left .avatar-img{transform:rotate(-2.5deg) translateX(-5px)}
.avatar-stage.dir-left .point-hand{transform:rotate(180deg);bottom:84px;left:8%}
.avatar-stage.dir-down-left .avatar-img{transform:rotate(2.5deg) translateX(-5px)}
.avatar-stage.dir-down-left .point-hand{transform:rotate(135deg);bottom:24px;left:12%}
.avatar-stage.dir-center .avatar-img{transform:scale(1.015)}
.avatar-stage.dir-center .point-hand{transform:rotate(90deg);bottom:8px;left:calc(50% - 23px)}
@keyframes av-breathe{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-5px) scale(1.012)}}
@keyframes av-glow{0%,100%{opacity:.6}50%{opacity:.95}}
@keyframes av-hand{0%,100%{filter:drop-shadow(0 0 6px rgba(255,194,77,.6))}50%{filter:drop-shadow(0 0 16px rgba(255,194,77,1))}}

/* ---- Chat dock ---- */
.chatdock{position:fixed;top:60px;right:0;bottom:0;width:var(--dock-w);z-index:4;display:flex;flex-direction:column;
  border-left:1px solid var(--line);background:rgba(7,11,20,.72);backdrop-filter:blur(12px)}
.chat-head{display:flex;align-items:center;gap:8px;padding:11px 14px;border-bottom:1px solid var(--line);
  font-family:var(--h-sans);font-size:13px;letter-spacing:.5px}
.voice-toggle{display:inline-flex;align-items:center;gap:7px;cursor:pointer;border:1px solid var(--line2);border-radius:999px;
  padding:6px 13px;background:linear-gradient(180deg,rgba(77,163,255,.16),rgba(77,163,255,.04));color:var(--ink);
  font-family:var(--h-sans);font-size:12px;letter-spacing:.4px}
.voice-toggle:hover{box-shadow:var(--glow)}
.voice-toggle .mic-dot{width:9px;height:9px;border-radius:50%;background:var(--danger);box-shadow:0 0 8px var(--danger)}
.voice-toggle.on{background:linear-gradient(180deg,rgba(52,224,200,.2),rgba(52,224,200,.05));border-color:rgba(52,224,200,.5)}
.voice-toggle.on .mic-dot{background:var(--ok);box-shadow:0 0 10px var(--ok);animation:pulse 1.2s infinite}
/* Botão FALAR (TTS): "on" = teal (de .voice-toggle.on); "off" = apagado (só texto) */
.speak-toggle:not(.on){background:linear-gradient(180deg,rgba(255,255,255,.06),rgba(255,255,255,.02));border-color:var(--line);color:var(--muted)}
.stop-btn{display:inline-flex;align-items:center;gap:5px;cursor:pointer;border:1px solid var(--danger);border-radius:999px;
  padding:6px 12px;background:rgba(255,92,122,.16);color:#ffd2dc;font-family:var(--h-sans);font-size:12px;letter-spacing:.4px}
.stop-btn:hover{background:rgba(255,92,122,.28);box-shadow:0 0 14px rgba(255,92,122,.4)}
.stop-btn[hidden]{display:none}
.voice-status{font-family:var(--mono);font-size:10px;color:var(--gold);letter-spacing:1px;text-transform:uppercase;margin-right:auto}
.vsel{background:rgba(0,0,0,.3);border:1px solid var(--line);color:var(--ink);border-radius:8px;padding:6px 8px;font-size:12.5px;max-width:230px}
.vval{font-family:var(--mono);font-size:11px;color:var(--ink-dim);min-width:34px}
.clear-spacer{margin-left:auto}

/* =========================================================================================================
   f31 — O PARAR E O FREIO: nunca espremido, cortado nem fora de alcance
   =========================================================================================================
   POR QUE (medido ANTES, no navegador real, janela 1536, com o #stopBtn visivel):
     dock 320 (= DOCK_MIN do dockkit, alcancavel pelo arrasto) -> o PARAR era CORTADO em 10px (borda direita
       1546 contra a borda do dock em 1536) e o "limpar" sumia inteiro (85px fora, alem da propria janela);
     dock 330 (a largura da AULA) -> o PARAR terminava EXATAMENTE em 1536, a borda do dock: ZERO px de folga.
       Cabia por sorte, nao por regra — 1px a mais no rotulo do Mic e ele saia da tela;
     dock 380 (padrao de fabrica) -> "limpar" ja saia cortado em 25px;
     e em TODAS as larguras o alvo tinha 29.6px de altura (< 44).
   A causa: .chat-head e flex nowrap sem NENHUMA regra de quem cede espaco. Itens flex tem min-width:auto,
   entao nao encolhem abaixo do conteudo — em vez de encolher, a faixa TRANSBORDA para fora do dock (que esta
   em right:0), ou seja, para FORA DA JANELA. Quem transborda e quem esta por ultimo no DOM; o PARAR so
   sobrevivia por ser o 3o. Isso e sorte de ordem, e o freio nao pode depender disso.

   O GATILHO E A LARGURA DO DOCK, NAO DA JANELA -> @container, nao @media. O dock muda de largura sem a
   janela mudar (o arrasto da alca e a largura de aula do fDW), entao media-query e cega para o unico numero
   que importa aqui. Por isso .chatdock vira um container de consulta.
   contain: e SEGURO aqui — .chatdock ja e position:fixed (= ja era o bloco de contencao dos seus absolutos:
   .dock-gutter e, no mobile, .avatar-stage); .stop-float/.chat-fab sao fixed mas vivem FORA do dock.

   ESCADA DE QUEM CEDE (o PARAR manda; os outros colapsam primeiro). A ordem e DECORACAO ANTES DE FUNCAO, e
   os numeros sao MEDIDOS, nao chutados:
     1o a faixa de status -> colapsa com reticencias (min-width:0). Vem DEPOIS do PARAR no DOM, entao nunca o
        empurra, mas com texto ("OUVINDO"...) empurrava o "limpar" para fora.
     2o a dica "Esc para parar" DENTRO do botao -> some. E TEXTO AUXILIAR, nao o freio (o atalho Esc continua
        funcionando; so a legenda sai). E ela que infla o pill de 71.7px para 156px, entao derruba-la sozinha
        devolve 84px — mais do que qualquer outro degrau.
     3o "limpar" -> some (controle menos essencial; a conversa se limpa em Config). Mesma escolha que o bloco
        mobile (html.is-mobile #clearChat) ja tinha feito, agora valendo em qualquer largura de dock.
   POR QUE a dica cede ANTES do "limpar" (invertido depois de MEDIR): a faixa inteira precisa de 418px, mas
   SEM a dica precisa de so 334px — ou seja, derrubar a decoracao ja faz o "limpar" caber inteiro ate no
   padrao de fabrica (380px), onde hoje ele sai cortado em 25px. Sacrificar um CONTROLE para preservar uma
   LEGENDA seria a troca errada.
   O PARAR nunca entra na escada: flex-shrink:0 + nowrap = nao encolhe nem quebra em duas linhas. */
.chatdock{container-type:inline-size}

/* O freio, blindado. O flex-shrink/nowrap tambem estao inline no app.js (WIP) — aqui eles viram regra
   DURAVEL, no CSS, junto das outras larguras do dock: se o inline sair, a blindagem fica. */
.stop-btn{flex-shrink:0;white-space:nowrap;position:relative}
/* ALVO DE TOQUE 44x44 sem mexer no visual nem na altura da faixa. O ::after e um alvo TRANSPARENTE que
   estica a area clicavel para 44px de altura (o pill desenhado tem 29.6px) invadindo so o padding da faixa,
   que e vazio. Hit-test em pseudo-elemento acerta o ELEMENTO HOSPEDEIRO -> o clique chega ao botao sem
   nenhum handler novo. Mesma tecnica ja usada na raia do Gantt no toque (bloco do TABLET).
   POR QUE nao min-height:44px no botao: no mobile a faixa e ancorada em min-height:44px e o icone do avatar
   e absolute top:7px/30px, centrado A MAO contra essa altura (furo ja medido e corrigido em rodada anterior:
   centro do avatar 514 x centro do botao 526). Um botao de 44px empurraria a faixa para ~58px e
   descentralizaria o icone de novo. O ::after da o alvo sem tocar no layout. left/right:0 = mesma largura do
   pill (que nunca e menor que 44), entao nao invade o vizinho. */
.stop-btn::after{content:'';position:absolute;top:50%;left:0;right:0;transform:translateY(-50%);height:44px}
/* Mic/Som nao podem empurrar o PARAR para fora: eles vem ANTES dele no DOM. */
.chat-head .voice-toggle{flex-shrink:0}
/* A faixa de status vem DEPOIS do PARAR (nunca o empurra), mas com texto ("OUVINDO"...) empurrava o limpar.
   Colapsa com reticencias em vez de transbordar. */
.voice-status{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* Degrau 2 — a DICA cede (a decoracao antes da funcao). MEDIDO: com a dica a faixa precisa de 418px; sem ela,
   334px. O corte em 420 e o ponto onde ela deixaria de caber; a partir dai o pill volta a 71.7px e todo o
   resto (inclusive o "limpar") passa a caber. A dica reaparece sozinha acima de 420px — que inclui a
   preferencia real do Richard (697) e qualquer dock medio/largo. */
@container (max-width:420px){ .chat-head .stop-hint{display:none} }
/* Degrau 3 — "limpar" cede. MEDIDO: sem a dica, a faixa precisa de 334px; abaixo disso o "limpar" seria o
   proximo a ser empurrado para fora. 345 da folga para metricas de fonte. Depois deste degrau sobram Mic +
   Som + PARAR = 267px: no piso de 320 (DOCK_MIN) isso deixa 52px de FOLGA REAL, e em 330 (largura de AULA)
   62px — o freio para de depender de sorte de metrica. Por isso Mic/Som nao precisam encolher. */
@container (max-width:345px){ .chat-head #clearChat{display:none} }
/* Histórico: entra na MESMA escada de cedência da faixa (ela é flex nowrap — item novo sem regra de quem
   cede é o que já empurrou controle para fora daqui). Cede o RÓTULO e fica só o 🕘 — o alvo continua
   clicável. NÃO tem degrau que o remova: MEDIDO na tela, o dock em uso normal fica em 330px (a largura de
   AULA), e um degrau em 345 — copiado do "limpar" — apagava o botão justamente ali. Depois que o "limpar"
   cede sobram Mic+Som+PARAR=267px, e o 🕘 sozinho ocupa ~36: cabe com folga até no piso de 320 (DOCK_MIN).
   `.ghost` não define display, então o [hidden] do UA continua valendo para o gate de papel (admin). */
@container (max-width:430px){ .chat-head #historyBtn .hb-txt{display:none} }
.msg.interim{opacity:.65;font-style:italic;border-style:dashed}
.chat-log{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:12px}
.msg{max-width:90%;padding:10px 13px;border-radius:14px;font-size:13.5px;line-height:1.5;white-space:pre-wrap;word-wrap:break-word}
.msg.user{align-self:flex-end;background:linear-gradient(180deg,rgba(77,163,255,.2),rgba(77,163,255,.08));border:1px solid var(--line2);border-bottom-right-radius:4px}
.msg.ai{align-self:flex-start;background:var(--panel2);border:1px solid var(--line);border-bottom-left-radius:4px}
.msg.ai b{color:#fff}
.msg img{max-width:100%;border-radius:8px;margin-top:6px}
.pill{align-self:flex-start;font-size:11px;font-family:var(--mono);color:var(--blue);background:rgba(77,163,255,.1);
  border:1px solid var(--line);border-radius:999px;padding:4px 11px;display:inline-flex;gap:6px;align-items:center}
.pill.status{color:var(--gold);background:rgba(255,194,77,.08)}
/* PÍLULA DE DOIS ESTADOS (ferramenta): .run = em andamento (neutro, o azul de sempre) -> .ok (sucesso) ou
   .err (recusa/falha). Os três são visualmente distintos entre si; a mudança é IN-PLACE, na mesma pílula. */
.pill.run{opacity:.85}
.pill.ok{color:var(--ok);background:rgba(56,224,160,.1);border-color:rgba(56,224,160,.35)}
.pill.err{color:var(--danger);background:rgba(255,92,122,.1);border-color:rgba(255,92,122,.45)}
.chat-attach{display:flex;flex-wrap:wrap;gap:7px;padding:0 16px}
.chat-attach:not(:empty){padding:8px 16px}
.att{position:relative;width:52px;height:52px;border-radius:8px;border:1px solid var(--line2);overflow:hidden;background:#000}
.att img{width:100%;height:100%;object-fit:cover}
.att .x{position:absolute;top:1px;right:1px;width:16px;height:16px;border-radius:50%;background:rgba(0,0,0,.7);color:#fff;font-size:11px;display:grid;place-items:center;cursor:pointer}
.att .doc{font-size:9px;color:var(--ink-dim);padding:4px;word-break:break-all}
.chat-input{display:flex;align-items:flex-end;gap:8px;padding:12px 14px;border-top:1px solid var(--line)}
.chat-input textarea{flex:1;resize:none;max-height:130px;background:rgba(0,0,0,.3);border:1px solid var(--line);border-radius:12px;
  color:var(--ink);font-family:var(--b-sans);font-size:13.5px;padding:11px 12px;line-height:1.4}
.chat-input textarea:focus{outline:none;border-color:var(--line2)}
.icon-btn{flex-shrink:0;width:40px;height:40px;border-radius:11px;display:grid;place-items:center;cursor:pointer;
  background:var(--panel);border:1px solid var(--line);color:var(--ink-dim)}
.icon-btn svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.icon-btn:hover{color:var(--ink);border-color:var(--line2)}
.icon-btn.send{background:linear-gradient(180deg,rgba(77,163,255,.3),rgba(77,163,255,.1));color:#fff}
.icon-btn.send svg{fill:currentColor;stroke:none}

/* ---- Image overlay ---- */
.img-overlay{position:fixed;inset:0;z-index:30;display:none;align-items:center;justify-content:center;background:rgba(3,6,12,.85);backdrop-filter:blur(6px)}
.img-overlay.on{display:flex}
.img-overlay img{max-width:78vw;max-height:78vh;border-radius:14px;border:1px solid var(--line2);box-shadow:0 0 60px rgba(77,163,255,.4)}
.img-cap{position:absolute;bottom:6vh;font-size:13px;color:var(--ink-dim);font-family:var(--mono)}
.img-x{position:absolute;top:24px;right:28px;width:44px;height:44px;border-radius:50%;border:1px solid rgba(255,255,255,.25);background:rgba(20,26,38,.8);color:#fff;font-size:26px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;z-index:1;transition:background .15s,border-color .15s}
.img-x:hover{background:rgba(40,50,70,.95);border-color:rgba(255,255,255,.5)}

/* ---- Transcrição de chat do aluno (Master Admin) ---- */
.tx-overlay{position:fixed;inset:0;z-index:40;display:flex;align-items:center;justify-content:center;background:rgba(3,6,12,.85);backdrop-filter:blur(6px);padding:3vh 2vw}
.tx-overlay[hidden]{display:none}
.tx-modal{width:min(880px,96vw);max-height:94vh;display:flex;flex-direction:column;background:var(--panel,#0d1320);border:1px solid var(--line2);border-radius:14px;box-shadow:0 24px 80px rgba(0,0,0,.55);overflow:hidden}
.tx-head{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;padding:14px 16px;border-bottom:1px solid var(--line2);flex-wrap:wrap}
.tx-head h3{margin:0;font-size:16px;color:var(--ink)}
.tx-sub{font-size:12px;color:var(--muted);margin-top:3px}
.tx-tools{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.tx-tools input[type=search]{background:rgba(110,168,254,.08);border:1px solid var(--line);border-radius:8px;padding:6px 10px;color:var(--ink);font-size:13px;min-width:180px}
.tx-badge{font-size:12px;font-family:var(--mono);padding:3px 8px;border-radius:999px;border:1px solid var(--line);color:var(--muted)}
.tx-badge.ok{color:var(--ok);border-color:rgba(80,220,150,.4)}
.tx-badge.bad{color:#ff6b6b;border-color:rgba(255,107,107,.4)}
.tx-body{overflow-y:auto;padding:14px 16px;display:flex;flex-direction:column;gap:12px}
.tx-msg{border:1px solid var(--line);border-radius:10px;padding:10px 12px;max-width:88%}
.tx-msg.u{align-self:flex-end;background:rgba(110,168,254,.10);border-color:rgba(110,168,254,.25)}
.tx-msg.a{align-self:flex-start;background:rgba(255,255,255,.03)}
.tx-meta{display:flex;align-items:center;gap:8px;font-size:11px;color:var(--muted);margin-bottom:5px}
.tx-meta b{color:var(--ink-dim);font-size:12px}
.tx-seq{font-family:var(--mono);opacity:.7}
.tx-when{margin-left:auto;font-family:var(--mono)}
.tx-bf{font-size:10px;text-transform:uppercase;letter-spacing:.5px;padding:1px 6px;border:1px solid var(--line);border-radius:999px;color:var(--muted)}
.tx-text{font-size:13.5px;line-height:1.55;color:var(--ink);white-space:normal;word-break:break-word}
.tx-tools-used{margin-top:8px;display:flex;flex-wrap:wrap;gap:6px}
.tx-tchip{font-size:11px;font-family:var(--mono);background:rgba(110,168,254,.12);border:1px solid var(--line);border-radius:6px;padding:2px 7px;color:var(--ink-dim);cursor:help}
.tx-err{margin-top:6px;font-size:12px;color:#ff8c8c}
/* HISTÓRICO DO ALUNO (pop-up do chat): reusa .tx-msg/.tx-meta/.tx-text; só o que é próprio dele mora aqui. */
.hist-mark{background:rgba(255,196,84,.28);color:var(--ink);border-radius:3px;padding:0 1px}
.hist-more{align-self:center;font-size:12px;color:var(--muted);padding:8px 0}
.hist-note{align-self:center;font-size:12px;color:var(--muted);text-align:center;max-width:60ch;line-height:1.5}

/* ---- Fiscalização (Juiz de Qualidade) ---- */
.incident-banner{border:1px solid rgba(255,77,79,.45);background:rgba(255,77,79,.08);border-radius:12px;padding:14px 16px;margin-bottom:16px}
.incident-banner .ib-head{display:flex;align-items:center;gap:8px;font-size:14px;color:#ff8c8c}
.incident-banner .ib-head b{color:#ff6b6b}
.ib-dot{width:10px;height:10px;border-radius:50%;background:#ff4d4f;box-shadow:0 0 0 4px rgba(255,77,79,.2);flex:none}
.ib-list{margin-top:10px;display:flex;flex-direction:column;gap:6px}
.ib-row{font-size:13px;color:var(--ink-dim);padding:6px 8px;border-radius:8px;cursor:pointer;border:1px solid transparent}
.ib-row:hover{background:rgba(255,77,79,.07);border-color:rgba(255,77,79,.3)}
.ib-row b{color:var(--ink)}
.ib-when{font-family:var(--mono);font-size:11px;color:var(--muted);margin-right:8px}
.judge-modes{display:flex;align-items:center;gap:14px;flex-wrap:wrap;padding:10px 12px;border:1px solid var(--line);border-radius:10px;margin-bottom:14px}
.jm-label{font-size:12px;color:var(--muted);text-transform:uppercase;letter-spacing:1px}
.jm-opt{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--ink-dim);cursor:pointer}
.jm-opt input{accent-color:var(--blue,#4da3ff)}
.judge-kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));gap:10px}
.kpi{border:1px solid var(--line);border-radius:10px;padding:12px 14px;background:rgba(255,255,255,.02)}
.kpi-v{font-size:24px;font-weight:600;color:var(--ink)}
.kpi-l{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.5px;margin-top:2px}
.kpi-bad{border-color:rgba(255,77,79,.5);background:rgba(255,77,79,.08)} .kpi-bad .kpi-v{color:#ff6b6b}
.kpi-warn{border-color:rgba(240,160,32,.5);background:rgba(240,160,32,.08)} .kpi-warn .kpi-v{color:#f0a020}
.jcol{min-width:0}
.vrow{border:1px solid var(--line);border-left-width:3px;border-radius:8px;padding:8px 10px;margin-bottom:7px;cursor:pointer}
.vrow:hover{border-color:var(--line2)}
.vrow-top{display:flex;align-items:center;gap:8px;font-size:13px}
.vrow-top b{color:var(--ink)}
.vlayer{font-size:10px;text-transform:uppercase;letter-spacing:.5px;color:var(--muted);border:1px solid var(--line);border-radius:4px;padding:0 5px}
.vwhen{margin-left:auto;font-family:var(--mono);font-size:11px;color:var(--muted)}
.vsum{font-size:12px;color:var(--ink-dim);margin-top:4px;line-height:1.5;word-break:break-word}
.vbadge{font-size:10px;text-transform:uppercase;letter-spacing:.5px;border-radius:4px;padding:1px 6px;font-weight:500}
.rflag{display:inline-block;font-size:11px;background:rgba(240,160,32,.12);border:1px solid rgba(240,160,32,.35);color:#f0a020;border-radius:5px;padding:1px 7px;margin:2px 2px 0 0}
.sev-critical{border-left-color:#ff4d4f} .vbadge.sev-critical{background:rgba(255,77,79,.16);color:#ff6b6b}
.sev-warn{border-left-color:#f0a020} .vbadge.sev-warn{background:rgba(240,160,32,.16);color:#f0a020}
.sev-info{border-left-color:var(--blue,#4da3ff)} .vbadge.sev-info{background:rgba(77,163,255,.14);color:var(--blue,#4da3ff)}
.sev-ok{border-left-color:var(--ok,#4ade80)} .vbadge.sev-ok{background:rgba(74,222,128,.12);color:var(--ok,#4ade80)}

/* ---- Auth ---- */
.auth-overlay{position:fixed;inset:0;z-index:60;display:none;align-items:center;justify-content:center;background:radial-gradient(800px 600px at 50% 0%,rgba(77,163,255,.1),transparent),var(--bg);
  overflow-y:auto;padding:24px 0}   /* tela pequena: o overlay ROLA em vez de cortar o card */
.auth-overlay.on{display:flex}
.auth-card{width:360px;max-width:92vw;background:var(--panel);border:1px solid var(--line2);border-radius:20px;padding:26px;backdrop-filter:blur(10px);box-shadow:0 20px 60px rgba(0,0,0,.5);
  margin:auto}   /* com overflow no overlay, o margin:auto mantém o card centrado E rolável */
/* o atributo hidden TEM que valer: o display:flex de .auth-form/#rsStep2 o sobreporia
   (mesmo bug já corrigido em .rail-btn) — sem isto, os 3 formulários aparecem empilhados */
.auth-form[hidden],#rsStep2[hidden],.auth-msg[hidden]{display:none !important}
.auth-brand{display:flex;align-items:center;gap:12px;margin-bottom:20px}
.auth-tabs{display:flex;gap:6px;margin-bottom:16px}
.auth-tab{flex:1;cursor:pointer;background:transparent;border:1px solid var(--line);color:var(--muted);border-radius:10px;padding:9px;font-family:var(--h-sans);font-size:13px}
.auth-tab.active{color:#fff;border-color:var(--line2);background:linear-gradient(180deg,rgba(77,163,255,.2),rgba(77,163,255,.05))}
.auth-form{display:flex;flex-direction:column;gap:11px}
.auth-form input,.auth-plan select{background:rgba(0,0,0,.3);border:1px solid var(--line);color:var(--ink);border-radius:10px;padding:11px 12px;font-size:14px;font-family:var(--b-sans)}
.auth-form input:focus,.auth-plan select:focus{outline:none;border-color:var(--line2)}
.auth-form .btn{justify-content:center;margin-top:4px}
.auth-plan{display:flex;flex-direction:column;gap:5px;font-size:12px;color:var(--ink-dim)}
.auth-err{color:var(--danger);font-size:12.5px;min-height:16px}
.auth-hint{font-size:11.5px}
.auth-link{color:var(--accent,#6ea8fe);text-decoration:none;cursor:pointer}
.auth-link:hover{text-decoration:underline}
.auth-msg{font-size:12px;color:var(--ink-dim);background:rgba(110,168,254,.08);border:1px solid var(--line);border-radius:8px;padding:8px 10px;margin:2px 0}
#rsStep2{display:flex;flex-direction:column;gap:10px;margin-top:8px}
.codebox{font-family:var(--b-mono,ui-monospace,monospace);background:rgba(110,168,254,.12);border:1px solid var(--line);border-radius:6px;padding:2px 8px;letter-spacing:1px;font-size:13px;color:var(--ink)}

/* ---- Onboarding ---- */
.onb-overlay{position:fixed;inset:0;z-index:55;display:none;align-items:center;justify-content:center;padding:20px;background:radial-gradient(900px 700px at 50% 0%,rgba(139,123,255,.12),transparent),var(--bg)}
.onb-overlay.on{display:flex}
.onb-card{width:680px;max-width:96vw;max-height:92vh;display:flex;flex-direction:column;background:var(--panel);border:1px solid var(--line2);border-radius:20px;backdrop-filter:blur(10px);box-shadow:0 24px 70px rgba(0,0,0,.5)}
.onb-head{display:flex;align-items:center;gap:12px;padding:20px 24px;border-bottom:1px solid var(--line)}
.onb-body{flex:1;overflow-y:auto;padding:22px 24px}
.onb-body h3{font-family:var(--h-sans);font-size:17px;margin:0 0 4px}
.onb-body .sub{color:var(--muted);font-size:13px;margin-bottom:16px}
.onb-foot{display:flex;align-items:center;gap:12px;padding:16px 24px;border-top:1px solid var(--line)}
.onb-dots{flex:1;display:flex;gap:6px;justify-content:center}
.onb-dot{width:8px;height:8px;border-radius:50%;background:rgba(255,255,255,.15)}
.onb-dot.on{background:var(--blue);box-shadow:0 0 8px var(--blue)}
.onb-field{margin-bottom:16px}
.onb-field label{display:block;font-size:13px;color:var(--ink-dim);margin-bottom:6px}
.onb-field input[type=text],.onb-field input[type=number],.onb-field textarea,.onb-field select{width:100%;background:rgba(0,0,0,.3);border:1px solid var(--line);color:var(--ink);border-radius:10px;padding:10px 12px;font-size:13.5px;font-family:var(--b-sans)}
.onb-field textarea{min-height:64px;resize:vertical}
.onb-time{display:flex;align-items:center;gap:12px}
.onb-time input[type=range]{flex:1;accent-color:var(--blue)}
.onb-time .val{font-family:var(--mono);color:var(--gold);min-width:60px}
.onb-slider{display:grid;grid-template-columns:1fr auto;gap:6px;align-items:center;margin-bottom:9px}
.onb-slider .nm{font-size:12.5px;color:var(--ink-dim)}
.onb-slider input[type=range]{grid-column:1/3;accent-color:var(--blue)}
.onb-slider .sv{font-family:var(--mono);font-size:11px;color:var(--ink)}
/* Autoavaliação com critérios (rubrica) */
.onb-dim{padding:12px 0;border-bottom:1px solid var(--line)}
.onb-dim-top{display:flex;align-items:center;justify-content:space-between;gap:8px}
.onb-dim-top .nm{font-size:13.5px;font-weight:600;color:var(--ink)}
.onb-dim-top .sv{font-family:var(--mono);font-size:22px;color:var(--blue);font-weight:700;min-width:34px;text-align:right;line-height:1}
.onb-dim-top .sv small{font-size:11px;color:var(--muted);font-weight:400}
/* régua numerada 0–10: marcações clicáveis, com explicação no hover (title) */
.onb-ticks{display:flex;justify-content:space-between;gap:2px;margin-top:6px}
.onb-ticks .tick{flex:1;cursor:pointer;background:transparent;border:0;color:var(--muted);font-family:var(--mono);font-size:12px;padding:5px 0;border-radius:7px;transition:background .15s,color .15s,transform .1s}
.onb-ticks .tick:hover{color:#fff;background:rgba(77,163,255,.14)}
.onb-ticks .tick.sel{color:#fff;background:linear-gradient(180deg,rgba(77,163,255,.4),rgba(77,163,255,.12));font-weight:700;box-shadow:0 0 9px rgba(77,163,255,.45);transform:translateY(-1px)}
.onb-theme{font-size:12px;color:var(--ink-dim);line-height:1.5;margin:4px 0 8px}
.onb-dim input[type=range]{width:100%;accent-color:var(--blue)}
.onb-rubric{margin-top:7px}
.onb-rubric summary{cursor:pointer;font-size:11.5px;color:var(--blue);list-style:none}
.onb-rubric summary::-webkit-details-marker{display:none}
.onb-rubric summary::before{content:"▸ ";font-size:10px}
.onb-rubric[open] summary::before{content:"▾ "}
.onb-anchors{margin-top:6px;background:rgba(0,0,0,.18);border:1px solid var(--line2);border-radius:10px;padding:10px 12px;display:flex;flex-direction:column;gap:5px}
.onb-anchors>div{font-size:11.5px;color:var(--ink-dim);line-height:1.5}
.onb-anchors>div b{display:inline-block;min-width:20px;color:var(--blue);font-family:var(--mono)}
.onb-ex{margin-top:4px;border-top:1px dashed var(--line);padding-top:6px;color:var(--muted)!important;font-size:11px!important}
.onb-up{border:1px dashed var(--line2);border-radius:12px;padding:12px;margin-bottom:12px}
.onb-up h4{margin:0 0 8px;font-size:13px;color:var(--ink-dim);font-weight:500}
.onb-thumbs{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.onb-thumbs img{width:46px;height:46px;object-fit:cover;border-radius:6px;border:1px solid var(--line2)}
.onb-course{display:grid;grid-template-columns:1fr 1fr auto;gap:6px;margin-bottom:6px}
.onb-loading{text-align:center;padding:30px 10px}
.onb-loading .orb{margin:0 auto 16px}
.onb-grade{font-family:var(--h-disp);font-weight:700;font-size:48px;color:#fff;text-align:center}
.onb-grade-l{text-align:center;color:var(--muted);font-size:12px;text-transform:uppercase;letter-spacing:1px;margin-bottom:14px}
/* ===== Avaliação inicial — UX cinematográfica (Jarvis-HUD, sutil) ===== */
.onb-overlay::before{content:"";position:absolute;inset:0;pointer-events:none;background:repeating-linear-gradient(to bottom,rgba(77,163,255,.045) 0,rgba(77,163,255,.045) 1px,transparent 1px,transparent 3px);opacity:.6;animation:onbScan 8s linear infinite}
@keyframes onbScan{to{background-position:0 120px}}
.onb-overlay.on .onb-card{animation:onbCardIn .5s cubic-bezier(.2,.8,.2,1) both;position:relative;overflow:hidden}
@keyframes onbCardIn{from{opacity:0;transform:translateY(16px) scale(.985)}to{opacity:1;transform:none}}
.onb-card>.onb-head::after{content:"";position:absolute;left:0;top:0;width:28%;height:2px;background:linear-gradient(90deg,transparent,var(--blue),transparent);animation:onbSweep 3.4s ease-in-out infinite}
.onb-head{position:relative}
@keyframes onbSweep{0%{left:-28%}60%,100%{left:128%}}
.onb-body.reveal>*{animation:onbUp .42s ease both}
.onb-body.reveal>*:nth-child(2){animation-delay:.04s}.onb-body.reveal>*:nth-child(3){animation-delay:.08s}.onb-body.reveal>*:nth-child(n+4){animation-delay:.12s}
@keyframes onbUp{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.onb-dots{align-items:center}
.onb-dot{width:26px;height:4px;border-radius:3px;background:rgba(255,255,255,.13);transition:all .3s}
.onb-dot.on{background:linear-gradient(90deg,var(--blue),var(--violet));box-shadow:0 0 10px rgba(77,163,255,.6);width:36px}
.onb-dot.done{background:var(--blue);opacity:.55}
.onb-dim input[type=range],.onb-time input[type=range]{-webkit-appearance:none;appearance:none;height:6px;border-radius:6px;background:rgba(255,255,255,.1);outline:none}
.onb-dim input[type=range]::-webkit-slider-thumb,.onb-time input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:18px;height:18px;border-radius:50%;background:radial-gradient(circle at 35% 30%,#cfe6ff,var(--blue));box-shadow:0 0 10px rgba(77,163,255,.85);cursor:pointer;border:0}
.onb-scan{text-align:center;padding:30px 10px 22px}
.scan-orb{position:relative;width:120px;height:120px;margin:0 auto 20px}
.scan-orb i{position:absolute;inset:0;border-radius:50%;border:1px solid rgba(77,163,255,.5);animation:scanPulse 2.4s ease-out infinite}
.scan-orb i:nth-child(2){animation-delay:.8s}.scan-orb i:nth-child(3){animation-delay:1.6s}
@keyframes scanPulse{0%{transform:scale(.45);opacity:.9}100%{transform:scale(1.15);opacity:0}}
.scan-sweep{position:absolute;inset:0;border-radius:50%;background:conic-gradient(from 0deg,rgba(77,163,255,0) 0deg,rgba(77,163,255,.38) 45deg,transparent 90deg);animation:spin 1.8s linear infinite}
.scan-core{position:absolute;inset:36px;border-radius:50%;background:radial-gradient(circle at 40% 35%,#cfe6ff,var(--blue) 58%,#163255);box-shadow:0 0 28px rgba(77,163,255,.75);animation:breathe 2.2s ease-in-out infinite}
.scan-title{font-family:var(--h-disp,var(--h-sans));font-size:20px;letter-spacing:2px;color:#fff;margin-bottom:8px}
.scan-status{font-family:var(--mono);font-size:13px;color:var(--blue);min-height:18px;transition:opacity .25s}
.scan-bars{display:flex;gap:4px;justify-content:center;margin-top:16px}
.scan-bars span{width:3px;height:14px;background:var(--blue);border-radius:2px;animation:scanEq 1s ease-in-out infinite}
.scan-bars span:nth-child(2){animation-delay:.1s}.scan-bars span:nth-child(3){animation-delay:.2s}.scan-bars span:nth-child(4){animation-delay:.3s}.scan-bars span:nth-child(5){animation-delay:.4s}
@keyframes scanEq{0%,100%{transform:scaleY(.4)}50%{transform:scaleY(1.4)}}
.onb-card .dim-fill{transition:width 1s cubic-bezier(.2,.7,.2,1)}

/* ---- Admin ---- */
.admin-cards{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-bottom:18px}
@media(max-width:760px){.admin-cards{grid-template-columns:repeat(2,1fr)}}
.acard{background:var(--panel);border:1px solid var(--line);border-radius:16px;padding:18px}
.acard-v{font-family:var(--h-disp);font-weight:700;font-size:26px;color:#fff}
.acard-l{font-size:12px;color:var(--muted);margin-top:4px;text-transform:uppercase;letter-spacing:1px}
.acard-s{font-size:11px;color:var(--muted);margin-top:6px;opacity:.8}

/* ---- CÔMODO 1 — DASHBOARD: o RADAR (2026-07-20) ----
   5 números críticos, cada um clicável para o cômodo DONO. O estilo tem uma responsabilidade além do
   visual: fazer "sem dado ainda" LER como ausência, não como número. Por isso o .rc-nd é apagado,
   menor e sem a fonte de display — o olho não pode confundir com um valor real. */
.radar-cards{display:grid;grid-template-columns:repeat(6,1fr);gap:12px;margin-bottom:14px}
@media(max-width:1200px){.radar-cards{grid-template-columns:repeat(3,1fr)}}
@media(max-width:760px){.radar-cards{grid-template-columns:repeat(2,1fr)}}
.radar-card{position:relative;text-align:left;background:var(--panel);border:1px solid var(--line);border-radius:16px;padding:16px;cursor:pointer;transition:border-color .15s,transform .15s;font:inherit;color:inherit}
.radar-card:hover{border-color:var(--accent);transform:translateY(-1px)}
/* SEM CONVITE: número restrito, ou cômodo que este papel nem enxerga. O card continua mostrando o
   que sabe (a ausência é declarada), mas não finge ser porta — nem cursor, nem hover, nem <button>.
   Precisa vencer as duas regras acima (mesma especificidade, então vem depois E é mais específica). */
.radar-card.noNav{cursor:default}
.radar-card.noNav:hover{border-color:var(--line);transform:none}
.radar-card.nodata{opacity:.72}
.radar-card.alert-alto{border-color:#ff6b6b}
.radar-card.alert-medio{border-color:#ffb454}
.radar-card .rc-tr{display:flex;flex-direction:column;gap:2px;margin-bottom:2px}
.radar-card .rc-tr-l{display:flex;align-items:baseline;gap:8px}
.radar-card .rc-tr-v{font-family:var(--font-mono,inherit);font-variant-numeric:tabular-nums;font-size:20px;font-weight:700;min-width:2ch}
.radar-card .rc-tr-t{font-size:12px;color:var(--muted)}
.rc-flag{position:absolute;top:12px;right:12px;font-size:11px;line-height:1}
.radar-card.alert-alto .rc-flag{color:#ff6b6b}
.radar-card.alert-medio .rc-flag{color:#ffb454}
.rc-v{font-family:var(--h-disp);font-weight:700;font-size:26px;color:#fff;line-height:1.1}
/* Ausência NUNCA se parece com número: sem display font, menor, apagado. */
.rc-nd{font-family:inherit;font-weight:600;font-size:13px;color:var(--muted);font-style:italic}
.rc-t{font-size:12px;color:var(--muted);margin-top:6px;text-transform:uppercase;letter-spacing:.6px}
.rc-s{font-size:11px;color:var(--muted);margin-top:5px;opacity:.85}
.rc-m{font-size:11px;color:var(--muted);margin-top:6px;line-height:1.35;opacity:.9}
.rc-n{font-size:10.5px;color:var(--muted);margin-top:6px;line-height:1.35;opacity:.7}
.rc-src{font-size:10px;color:var(--muted);margin-top:8px;opacity:.55;letter-spacing:.3px}

/* Cômodos pedindo atenção — deep-link para o DONO do alerta. Some inteiro quando não há alerta:
   uma faixa vazia permanente ensina o olho a ignorar a região. */
.dash-atencao{background:var(--panel);border:1px solid var(--line);border-radius:16px;padding:14px 16px;margin-bottom:18px}
.da-head{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:1px;margin-bottom:10px}
.da-item{display:flex;align-items:center;gap:10px;width:100%;text-align:left;background:transparent;border:0;border-radius:10px;padding:8px 10px;cursor:pointer;font:inherit;color:inherit}
.da-item:hover{background:rgba(255,255,255,.05)}
/* Alerta sem destino alcançável p/ este papel: continua avisando, mas não finge ser porta. */
.da-item.noNav{cursor:default}
.da-item.noNav:hover{background:transparent}
.da-dot{width:8px;height:8px;border-radius:50%;flex:0 0 8px}
.da-item.alto .da-dot{background:#ff6b6b}
.da-item.medio .da-dot{background:#ffb454}
.da-txt{flex:1;font-size:13px}
.da-go{font-size:11px;color:var(--muted);opacity:.8}

/* CHECKPOINT DO DUELO V1×V2 — o alarme que conta a base e o relógio de maturação (só master).
   Faixa discreta enquanto MATURA; vira alarme só quando fica DEVIDO — um card que grita desde o
   primeiro dia ensina o olho a ignorá-lo, e aí o dia em que ele importa passa batido. */
.duel-card{background:var(--panel);border:1px solid var(--line);border-radius:16px;padding:14px 16px;margin-bottom:18px}
.duel-card.alarme{border-color:#ffb454;background:rgba(255,180,84,.07)}
.duel-head{display:flex;align-items:center;gap:8px;font-size:12px;text-transform:uppercase;letter-spacing:.8px;color:var(--muted)}
.duel-card.alarme .duel-head{color:#ffb454}
.duel-msg{font-size:14px;margin-top:8px;line-height:1.4}
.duel-card.alarme .duel-msg{font-weight:600}
/* Barra de progresso da fase 1 — só existe enquanto a base não foi atingida. */
.duel-bar{height:6px;border-radius:3px;background:rgba(255,255,255,.08);margin-top:10px;overflow:hidden}
.duel-bar > i{display:block;height:100%;background:var(--accent);border-radius:3px}
.duel-note{font-size:10.5px;color:var(--muted);margin-top:8px;line-height:1.35;opacity:.75}
/* [hidden] é regra do user-agent e perde para qualquer classe que defina display — o mesmo furo já
   medido em .btn e .row. Escopado, para não mexer em telas não auditadas. */
#asec-dashboard .duel-card[hidden]{display:none !important}

/* Badge de alerta no trilho (cômodo 1). O modelo puro já produzia `badge`; o cliente não pintava.
   O .rail-btn precisa de contexto de posicionamento, senão o badge absoluto escapa para o ancestral
   posicionado mais próximo e aparece no canto errado da tela. `position:relative` num flex-item não
   altera layout nenhum — só cria o contexto. */
.rail-btn{position:relative}
.rail-badge{position:absolute;top:6px;right:10px;min-width:16px;height:16px;padding:0 4px;border-radius:8px;background:#ff6b6b;color:#fff;font-size:10px;font-weight:700;line-height:16px;text-align:center}

/* ---- Master Admin: seções do painel ----
   O menu horizontal antigo (.admin-menu / .am-btn / .am-ic) foi APAGADO: a navegação do Master é
   UMA só — o trilho global (nav.rail). Não há barra no meio da tela em estado nenhum. */
.admin-sec{display:none}
.admin-sec.active{display:block;animation:fade .2s ease}
.dash-lead{font-size:12.5px;margin:2px 0 14px}
.dash-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(212px,1fr));gap:14px}
.dash-card{position:relative;text-align:left;background:var(--panel);border:1px solid var(--line);border-radius:16px;
  padding:16px 16px 15px;cursor:pointer;transition:transform .16s,box-shadow .16s,border-color .16s,background .16s;
  backdrop-filter:blur(6px);color:var(--ink);font-family:var(--b-sans)}
.dash-card:hover{border-color:var(--line2);background:var(--panel2);transform:translateY(-2px);box-shadow:0 10px 26px rgba(0,0,0,.32)}
.dash-card::after{content:"→";position:absolute;top:15px;right:15px;color:var(--muted);font-size:15px;transition:.16s}
.dash-card:hover::after{color:var(--blue);transform:translateX(3px)}
.dc-ic{font-size:20px;display:block;margin-bottom:9px}
.dc-v{font-family:var(--h-disp);font-weight:700;font-size:23px;color:#fff;line-height:1}
.dc-v.dc-go{font-family:var(--h-sans);font-size:15px;color:var(--blue);font-weight:600}
/* Atalho em estado de AUSÊNCIA ("restrito" / "sem dado ainda" / "fonte indisponível"). Mesma regra
   visual do radar (.rc-nd): ausência não pode LER como número. A classe dupla (0-2-0) é obrigatória
   — `.rc-nd` sozinha (0-1-0) perde para `.dc-v`, que vem depois no arquivo e pintaria de branco 23px.
   É a mesma armadilha de cascata já registrada aqui com `.btn` × `[hidden]`. */
.dc-v.rc-nd{font-family:inherit;font-weight:600;font-size:13px;color:var(--muted);font-style:italic;line-height:1.35}
.dc-t{font-size:12.5px;color:var(--ink-dim);margin-top:7px;font-weight:600}
.dc-h{font-size:11px;color:var(--muted);margin-top:2px}
.demo-tag{display:inline-block;font-size:11px;padding:2px 8px;border-radius:999px;border:1px solid rgba(255,194,77,.4);color:var(--gold);background:rgba(255,194,77,.08)}
/* ALUNO DE TESTE (conta interna): etiqueta de bater o olho. Mesma pílula do .demo-tag, cor distinta
   de propósito — isDemo (selo comercial) e isTest (conta interna) são eixos DIFERENTES e podem
   coexistir na mesma linha; se usassem a mesma cor, o master leria um pelo outro. */
.test-tag{display:inline-block;font-size:11px;font-weight:700;letter-spacing:.4px;padding:2px 8px;border-radius:999px;border:1px solid rgba(77,163,255,.45);color:var(--blue);background:rgba(77,163,255,.10)}
/* "convertido": era teste, virou pagante. O histórico conta inteiro (retroativo); a fronteira só localiza. */
.conv-tag{display:inline-block;font-size:11px;padding:2px 8px;border-radius:999px;border:1px solid rgba(52,224,200,.4);color:var(--teal);background:rgba(52,224,200,.08)}
/* "pagante": plano pago atribuído de propósito -> a trava recusa marcá-lo como teste (409). */
.pay-tag{display:inline-block;font-size:10px;padding:1px 6px;border-radius:999px;border:1px solid rgba(255,194,77,.4);color:var(--gold);background:rgba(255,194,77,.08)}
.dash-card.warn{border-color:rgba(255,92,122,.45)}
.dash-card.warn .dc-v{color:var(--danger)}
.dash-card.warn::after{color:var(--danger)}
@media(max-width:760px){.dash-grid{grid-template-columns:repeat(2,1fr)}}

/* ---- Placeholder do comodo "em construcao" ----
   Casca sem dado. Reaproveitada pelos 10 comodos do painel Master, cujos itens de navegacao
   viraram parte do TRILHO GLOBAL (rail) — nao ha barra interna dentro do painel. */
.msb-placeholder { padding: 18px 22px; }
.msb-placeholder h2 { font-family: var(--h-disp); font-size: 20px; color:#fff; margin:0 0 4px; }
.msb-crumb { font-size: 11.5px; color: var(--muted); letter-spacing:.4px; margin-bottom: 8px; text-transform: uppercase; }
.msb-empty { border: 1px dashed var(--line2); border-radius: 12px; padding: 24px; color: var(--muted); font-size: 13px;
  background: var(--panel); display:flex; align-items:center; gap:12px; }
.msb-empty::before { content:"🚧"; font-size: 22px; }
.msb-note { font-size:10px; color: var(--muted); background: var(--panel2); border:1px solid var(--line);
  padding: 1px 6px; border-radius: 999px; font-weight: 400; margin-left:6px; }

/* ---- CABEÇALHO DO CÔMODO — o TRILHO manda no nome ----
   Cada cômodo abre com o SEU nome canônico (o mesmo rótulo do trilho) + a trilha de onde ele fica.
   É isto que faz "rótulo do trilho == cabeçalho do cômodo" ser verdade na TELA, não só no código.
   Os painéis internos mantêm títulos DESCRITIVOS (ex.: "Receita mensal (12 meses)") — o nome de
   navegação é do cômodo; o do painel descreve o conteúdo. */
.room-head { margin: 0 0 18px; padding-bottom: 12px; border-bottom: 1px solid var(--line); }
.room-crumb { font-size: 11px; color: var(--muted); letter-spacing: 1.1px; text-transform: uppercase; margin-bottom: 5px; }
.room-title { font-family: var(--h-disp); font-weight: 700; font-size: 21px; color: #fff; margin: 0; letter-spacing: .2px; }

/* ---- ABAS INTERNAS de um cômodo (hoje só "Configurações do sistema") ----
   Decisão de arquitetura travada: profundidade máxima 2 — seção interna de cômodo é ABA dentro da
   página, NUNCA submenu no trilho. */
.cfg-tabs { display:flex; gap:6px; flex-wrap:wrap; margin:0 0 16px; border-bottom:1px solid var(--line); padding-bottom:10px; }
.cfg-tab { background:var(--panel); border:1px solid var(--line); border-radius:999px; padding:7px 14px;
  color:var(--ink-dim); cursor:pointer; font-family:var(--h-sans); font-weight:500; font-size:12.5px;
  letter-spacing:.3px; display:inline-flex; align-items:center; gap:7px; transition:all .15s; }
.cfg-tab:hover { color:#fff; border-color:var(--line2); background:var(--panel2); }
.cfg-tab.active { color:#fff; border-color:var(--blue); background:rgba(77,163,255,.16); box-shadow:inset 0 0 14px rgba(77,163,255,.12); }
.cfg-pane { display:none; }
.cfg-pane.active { display:block; animation:fade .2s ease; }

/* ---- TRILHO do painel MASTER (10 cômodos) — largura ARRASTÁVEL + os 10 SEMPRE visíveis ----
   Escopado em html.rail-many, que SÓ o admin recebe (initApp) => o rail do ALUNO fica byte-a-byte.

   A REGRA DE OURO do dockkit vale aqui: o JS escreve `--rail-user` + a classe .rail-manual no <html>,
   NUNCA `--rail-w` inline (o inline venceria os @media que escondem o rail no mobile/tablet).

   ALTURA — o requisito duro, resolvido por FLEXBOX em vez de cálculo em JS:
     `flex:1 1 0` faz os 10 dividirem a altura => cabem por CONSTRUÇÃO, sem scroll.
     `min-height` é o PISO: quando a tela é baixa demais, os itens PARAM de encolher, o container
     transborda e o `overflow-y:auto` entra — que é exatamente a ordem de prioridade pedida:
     (a) 10 sem scroll; (b) ícone legível, com piso; (c) o texto é o elástico; scroll só no fim. */
html.rail-many .rail {
  overflow-y: auto; overflow-x: hidden;
  gap: 2px; padding: 8px 6px;
  container-type: size;            /* habilita as unidades cqh/cqw nos filhos e as @container abaixo */
  container-name: railnav;
}
html.rail-many .rail-btn {
  flex: 1 1 0;                     /* os 10 dividem a altura disponível — nunca estouram por si */
  min-height: 42px;                /* PISO (== SLOT_MIN no railkit.js): abaixo disto, prefere-se scroll */
  max-height: 76px;                /* tela muito alta não vira 10 botões gigantes */
  overflow: hidden;
  justify-content: center;
  padding: 4px; gap: 3px;
  font-size: clamp(9px, 1.15cqh, 11px);
  letter-spacing: .2px;
}
/* ÍCONE = ÂNCORA: piso de 18px (== ICON_FLOOR no railkit.js). NUNCA encolhe abaixo disso. */
html.rail-many .rail-btn svg {
  width: clamp(18px, 3.4cqh, 24px);
  height: clamp(18px, 3.4cqh, 24px);
  flex: none;
}
html.rail-many .rail-btn .rail-num { font-family: var(--mono); color: var(--muted); font-size: 8.5px; letter-spacing:.3px; flex:none; }
html.rail-many .rail-btn > span:last-child {
  /* O TEXTO é o elástico: corta com reticências conforme o trilho estreita. */
  max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; line-height: 1.15;
}
html.rail-many .rail-btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
html.rail-many .rail-btn[aria-disabled="true"]:hover { color: var(--muted); background: transparent; border-color: transparent; }

/* TRUNCAGEM PROGRESSIVA por LARGURA (espelha labelTier() do railkit.js — a fonte da regra).
   Container query: reage à largura REAL do trilho, sem listener de resize no JS. */
@container railnav (width < 96px) {
  /* estreito demais para texto: sobra o ícone (o nome segue no title=""/tooltip) */
  html.rail-many .rail-btn > span:last-child { display: none; }
  html.rail-many .rail-btn .rail-num { display: none; }
}
/* O LAYOUT EM LINHA (ícone à esquerda do nome, como uma lista de verdade) só entra quando há largura
   para ele mostrar os nomes INTEIROS.
   POR QUE 237 e não 148: com o limiar em 148 (=161px de trilho) o botão virava linha E subia a fonte
   para 12px, e aí ícone(24) + gap(9) + padding(20) comiam a largura. Resultado MEDIDO: em 160px de
   trilho havia 0 nomes cortados e em 161px passavam a 3 — ou seja, ALARGAR o trilho fazia o usuário
   PERDER nome. O requisito manda o contrário: degradar ao ESTREITAR. Com 237 a progressão fica
   monotônica em toda a faixa de arrasto (MEDIDO: 3,3,2,1,0,0,0,0,0,0,0,0,0 de 109px a 280px). */
@container railnav (width >= 237px) {
  html.rail-many .rail-btn { flex-direction: row; justify-content: flex-start; gap: 9px; padding: 4px 10px; text-align: left; }
  html.rail-many .rail-btn > span:last-child { font-size: 12px; }
}

/* ALÇA de arrasto do trilho — irmã da .dock-gutter, mesma disciplina.
   POSITION:FIXED e IRMÃ do <nav.rail>, não filha: o rail tem `overflow-y:auto` (o último recurso
   do requisito de altura) e um filho absolute em `right:-3px` seria RECORTADO pelo scroll —
   a alça sumiria justamente na tela baixa, que é quando ela mais importa.
   Ancorada em `left:var(--rail-w)`, ela SEGUE a largura do trilho de graça. */
html.rail-many .rail-gutter {
  position: fixed; top: 60px; bottom: 0; left: var(--rail-w);
  width: 6px; margin-left: -3px; cursor: col-resize;
  z-index: 6; background: transparent; border: 0; padding: 0;
}
html:not(.rail-many) .rail-gutter { display: none; }   /* aluno: a alça nem existe */
html.rail-many .rail-gutter:hover, html.rail-many .rail-gutter:focus-visible { background: rgba(77,163,255,.35); outline: none; }
body.rail-dragging { cursor: col-resize; user-select: none; }
/* As TRÊS guardas, espelhando a .dock-gutter (style.css:1175/1486/1554). A media query sozinha NÃO
   basta: um tablet DEITADO tem is-tablet E largura > 1024 (iPad Pro 11 = 1194), então a alça sobrevivia
   ali — MEDIDO: faixa invisível de 6x774px em x=85, hit-testável (elementFromPoint devolvia #railGutter),
   roubando toque da coluna esquerda inteira, justo onde o rail nem existe. */
@media (max-width: 1024px) { html.rail-many .rail-gutter { display: none; } }
html.is-tablet .rail-gutter { display: none; }
html.is-mobile .rail-gutter { display: none; }

/* A LARGURA MANUAL só vale no desktop e só no master — espelha exatamente o padrão do dock
   (html.dock-manual:not(.is-tablet) body{--dock-w:var(--dock-user)}), inclusive o alvo BODY. */
@media (min-width: 1025px) {
  html.rail-manual.rail-many:not(.is-tablet):not(.is-mobile) body { --rail-w: var(--rail-user); }
}
html.rail-many .rail-btn.active .rail-num { color: var(--blue); }

.achart{display:flex;align-items:flex-end;gap:6px;height:150px;padding-top:8px}
.abar{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;height:100%;gap:5px}
.abar-fill{width:70%;min-height:2px;border-radius:4px 4px 0 0;background:linear-gradient(180deg,var(--blue),rgba(77,163,255,.3))}
.abar-lbl{font-family:var(--mono);font-size:8.5px;color:var(--muted)}
.utab{width:100%;border-collapse:collapse;font-size:13px}
.utab th{text-align:left;color:var(--muted);font-weight:500;font-size:11px;text-transform:uppercase;letter-spacing:1px;padding:8px 10px;border-bottom:1px solid var(--line2)}
.utab td{padding:9px 10px;border-bottom:1px solid var(--line);color:var(--ink-dim)}
.utab .ok{color:var(--ok)} .utab .off{color:var(--muted)}
/* Todas as Athenas — seletores de CATEGORIA (col 2) e MODELO (col 4) + botão EXCLUIR (col 3) */
.utab .cat-sel,.utab .mdl-sel{background:rgba(0,0,0,.3);border:1px solid var(--line);color:var(--ink);border-radius:8px;padding:4px 6px;font-size:12px;font-family:var(--b-sans);max-width:190px}
.utab .cat-sel:disabled,.utab .mdl-sel:disabled{opacity:.5}
.utab .cat-sel.saved,.utab .mdl-sel.saved{border-color:var(--ok);box-shadow:0 0 0 1px var(--ok)}
.utab .mdl-sel optgroup{color:var(--muted);font-style:normal}
.utab .mdl-sel option{color:var(--ink);background:#14151b}
.btn.danger{border-color:rgba(255,92,122,.5);color:var(--danger)}
.btn.danger:hover{background:rgba(255,92,122,.12);border-color:var(--danger)}
/* Card de custo de IA por aluno (só Master Admin) */
.cost-cell{font-size:12px;line-height:1.35;white-space:nowrap}
.cost-cell .cc-month b{font-family:var(--mono);color:var(--ink)}
.cost-cell .cc-life{font-family:var(--mono);font-size:11px}
.cost-cell .cc-brk{font-size:10px;letter-spacing:.2px}

/* ---- Cofre de credenciais ---- */
.cred-list{display:flex;flex-direction:column;gap:8px;margin-bottom:12px}
.cred-row{display:flex;align-items:center;gap:10px;padding:9px 12px;border:1px solid var(--line);border-radius:10px;background:var(--panel);font-size:13px}
.cred-row .cs{font-weight:600;color:#fff;min-width:120px}
.cred-row .cu{color:var(--ink-dim);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cred-row .ok{color:var(--ok);font-size:11px;font-family:var(--mono)}
.cred-form{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.cred-form input{background:rgba(0,0,0,.3);border:1px solid var(--line);color:var(--ink);border-radius:9px;padding:9px 11px;font-size:13px;font-family:var(--b-sans)}
.cred-form .btn{grid-column:1/3;justify-content:center}
.cred-form .auth-err{grid-column:1/3}

/* MOBILE: sem dock -> sem alca. O .chatdock{display:none} ja esconderia a alca (ela e filha dele), mas a
   regra explicita e a trava do requisito "so no desktop" no CSS (nao so no JS): se um dia o dock virar
   drawer no mobile, a alca continua fora. O --dock-w:0px aqui SO sobrevive porque o JS nunca escreve
   --dock-w inline (escreve --dock-user) e html.dock-manual body esta preso ao @media(min-width:1025px). */
@media(max-width:1024px){:root{--dock-w:0px}.chatdock{display:none}.dock-gutter{display:none}.avatar-gutter{display:none}}
@keyframes pulse{0%,100%{box-shadow:0 0 18px rgba(77,163,255,.4)}50%{box-shadow:0 0 30px rgba(77,163,255,.7)}}
@keyframes spin{to{transform:rotate(360deg)}}
@keyframes breathe{0%,100%{transform:scale(1)}50%{transform:scale(1.05)}}
@keyframes fade{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.chat-log::-webkit-scrollbar,.stage::-webkit-scrollbar{width:8px}
.chat-log::-webkit-scrollbar-thumb,.stage::-webkit-scrollbar-thumb{background:rgba(125,160,255,.18);border-radius:8px}
#calList,#mailList{display:flex;flex-direction:column;gap:8px}
.evt{border:1px solid var(--line);border-left:3px solid var(--teal);border-radius:10px;padding:9px 12px;background:var(--panel);display:flex;flex-direction:column;gap:3px}
.evt-when{font-size:11px;font-family:var(--mono);color:var(--teal);text-transform:capitalize}
.evt-sum{font-family:var(--h-sans);font-weight:600;font-size:13.5px;line-height:1.3;color:var(--ink)}
.evt-loc{font-size:11.5px;color:var(--muted)}
.guide{margin:6px 0 12px;border:1px solid var(--line);border-radius:10px;background:rgba(0,0,0,.18);padding:2px 12px}
.guide summary{cursor:pointer;font-size:12.5px;color:var(--blue);font-family:var(--b-sans);padding:8px 0;user-select:none}
.guide-steps{margin:4px 0 6px;padding-left:20px;font-size:12.5px;line-height:1.65;color:var(--ink-dim)}
.guide-steps li{margin-bottom:8px}
.guide-steps code{background:rgba(0,0,0,.4);padding:2px 6px;border-radius:5px;font-family:var(--mono);font-size:11px;color:var(--teal);word-break:break-all}
.guide-steps a{color:var(--blue)}

/* ===== Inteligência coletiva (painel do Master Admin) ===== */
.ci-link{color:var(--blue);cursor:pointer;text-decoration:underline;font-size:12px}
.ci-proto{border:1px solid var(--line);border-radius:10px;background:rgba(0,0,0,.25);padding:10px 12px;margin-bottom:12px;max-height:340px;overflow:auto}
.ci-prototext{white-space:pre-wrap;font-size:12px;line-height:1.6;color:var(--ink-dim);font-family:var(--b-sans);margin:0}
.ci-ind{display:flex;align-items:center;justify-content:space-between;gap:10px;font-size:13px;color:var(--ink-dim);padding:6px 2px;border-bottom:1px solid var(--line)}
.ci-ind b{color:var(--ink);font-weight:600}
.ci-ind.warn b{color:#f0a020}
.ci-ind .ok{color:var(--ok)} .ci-ind .off{color:var(--muted)}
.ci-sub{font-size:11px;text-transform:uppercase;letter-spacing:.5px;color:var(--muted);margin:12px 0 4px}
.ci-bar{height:6px;border-radius:4px;background:rgba(255,255,255,.05);overflow:hidden;margin:0 0 6px}
.ci-bar-fill{height:100%;border-radius:4px;background:var(--blue)}
.ci-bar-fill.good{background:var(--ok,#4ade80)} .ci-bar-fill.mid{background:#8a93a3} .ci-bar-fill.bad{background:#ff6b6b}
.ci-prow{display:flex;gap:12px;align-items:flex-start;padding:10px 0;border-bottom:1px solid var(--line)}
.ci-pmain{flex:1;min-width:0}
.ci-ptitle{font-weight:600;color:var(--ink);font-size:13.5px;line-height:1.4}
.ci-pdetail{font-size:12.5px;color:var(--ink-dim);margin-top:3px;line-height:1.5}
.ci-pev{font-size:11.5px;color:var(--muted);margin-top:3px;font-style:italic;line-height:1.5}
.ci-pmeta{margin-top:5px;font-size:11px}
.ci-conf{display:inline-block;font-size:10px;text-transform:uppercase;letter-spacing:.5px;border-radius:4px;padding:1px 7px;font-weight:600}
.ci-conf-hi{background:rgba(74,222,128,.16);color:var(--ok,#4ade80)}
.ci-conf-mid{background:rgba(77,163,255,.14);color:var(--blue,#4da3ff)}
.ci-conf-lo{background:rgba(240,160,32,.14);color:#f0a020}
.ci-add{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-top:8px}
.ci-add input{flex:1;min-width:160px;background:rgba(0,0,0,.25);border:1px solid var(--line);border-radius:8px;padding:7px 10px;color:var(--ink);font-size:12.5px}
.ci-add select{background:rgba(0,0,0,.25);border:1px solid var(--line);border-radius:8px;padding:7px 10px;color:var(--ink);font-size:12.5px}

/* ===================== Perfis de aluno + LUMEN + desmame + satisfação (2026-07-01) ===================== */
/* Seletor de perfil no onboarding */
.prof-cards{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin:14px 0}
@media(max-width:640px){.prof-cards{grid-template-columns:1fr}}
.prof-card{text-align:left;background:var(--panel);border:1px solid var(--line);border-radius:16px;padding:16px;cursor:pointer;transition:.18s;color:var(--ink)}
.prof-card:hover{border-color:var(--line2);background:var(--panel2)}
.prof-card.sel{border-color:var(--blue);background:linear-gradient(180deg,rgba(77,163,255,.14),rgba(77,163,255,.03));box-shadow:inset 0 0 24px rgba(77,163,255,.1)}
.prof-t{font-size:15px;font-weight:600;margin-bottom:2px}
.prof-sub{font-size:12px;color:var(--blue);margin-bottom:8px}
.prof-blurb{font-size:12px;color:var(--ink-dim);line-height:1.5}
.prof-ex{margin:10px 0 0;padding:0;list-style:none;display:flex;flex-direction:column;gap:4px}
.prof-ex li{font-size:11.5px;color:var(--muted);padding-left:16px;position:relative}
.prof-ex li:before{content:"›";position:absolute;left:4px;color:var(--blue)}
.prof-corp{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:6px}
@media(max-width:640px){.prof-corp{grid-template-columns:1fr}}
.prof-opts{display:flex;gap:8px;flex-wrap:wrap}
.popt{background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:8px 12px;color:var(--ink-dim);cursor:pointer;font-size:12.5px}
.popt.sel{border-color:var(--blue);color:#fff;background:rgba(77,163,255,.15)}
/* Notas A/B + risco no relatório do perfil funcionário */
.ab-grades{display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px;margin:8px 0 16px}
@media(max-width:640px){.ab-grades{grid-template-columns:1fr}}
.ab-card{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:12px 14px;text-align:center}
.ab-card .ab-l{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.5px;margin-bottom:4px}
.ab-card .ab-v{font-family:var(--mono);font-size:26px;color:var(--ink)}
.ab-card .ab-v small{font-size:12px;color:var(--muted)}
.ab-card.risk.amber{border-color:rgba(255,194,77,.5);background:rgba(255,194,77,.08)}
.ab-card.risk.violet{border-color:var(--line2)}
.ab-card.risk.green{border-color:rgba(52,224,200,.4);background:rgba(52,224,200,.06)}
.ab-card .ab-note{font-size:10.5px;color:var(--ink-dim);margin-top:4px;line-height:1.4}
/* Painel LUMEN do aluno */
.lumen-panel{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:14px 16px;margin-bottom:18px}
.lm-head{font-size:13px;font-weight:600;margin-bottom:10px}
.lm-wean{font-size:12px;color:var(--ink-dim);background:rgba(139,123,255,.08);border:1px solid var(--line);border-radius:10px;padding:9px 12px;margin-bottom:10px}
.lm-wean.on{color:var(--ink);background:linear-gradient(180deg,rgba(139,123,255,.16),rgba(139,123,255,.04));border-color:var(--line2)}
.lm-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
@media(max-width:640px){.lm-grid{grid-template-columns:1fr 1fr}}
.lm-card{background:rgba(0,0,0,.2);border:1px solid var(--line);border-radius:12px;padding:10px 12px}
.lm-l{font-size:11px;color:var(--muted);margin-bottom:4px}
.lm-v{font-family:var(--mono);font-size:20px;color:var(--ink);display:block}
.lm-v.good{color:var(--teal)} .lm-v.bad{color:var(--gold)}
.lm-n{font-size:10px;color:var(--muted)}
/* Pulso / NPS */
/* mkt3: o pulso saiu de DENTRO do painel LUMEN (que se esconde de quem não tem métrica de
   aprendizado) e virou painel PRÓPRIO, visível a todo aluno. Ganha a mesma casca do .lumen-panel;
   o .pulse por dentro perde o border-top, que só fazia sentido como separador do painel anterior. */
.pulse-panel{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:14px 16px;margin-bottom:18px}
.pulse-panel .pulse{margin-top:0;border-top:0;padding-top:0}
.pulse{margin-top:12px;border-top:1px solid var(--line);padding-top:12px}
.pulse.done{opacity:.55}
.pulse-q{font-size:12.5px;color:var(--ink-dim);margin-bottom:6px}
.pulse-stars{display:flex;gap:4px;margin-bottom:8px}
.pstar{font-size:22px;line-height:1;color:var(--muted);background:none;border:none;cursor:pointer;transition:.12s}
.pstar:hover,.pstar.on{color:var(--gold)}
.pulse-nps{display:flex;align-items:center;gap:10px;flex-wrap:wrap;font-size:11.5px;color:var(--muted)}
.pulse-scale{display:flex;gap:3px}
.pnps{width:24px;height:24px;border-radius:6px;border:1px solid var(--line);background:var(--panel);color:var(--ink-dim);cursor:pointer;font-size:11px}
.pnps.on{border-color:var(--blue);color:#fff;background:rgba(77,163,255,.2)}
.pulse-msg{font-size:11.5px;color:var(--teal);margin-top:6px;min-height:14px}
/* Filtro de perfil nos painéis do admin */
.prof-filter{display:flex;align-items:center;gap:6px;margin-bottom:10px;flex-wrap:wrap}
.prof-filter .pf-l{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.5px}
.pf-btn{background:var(--panel);border:1px solid var(--line);border-radius:999px;padding:5px 12px;color:var(--ink-dim);cursor:pointer;font-size:12px}
.pf-btn.on{border-color:var(--blue);color:#fff;background:rgba(77,163,255,.16)}
/* Badge de perfil (lista de alunos, biblioteca) */
.pf-badge,.src-pf{font-size:10px;padding:2px 7px;border-radius:999px;border:1px solid var(--line);text-transform:uppercase;letter-spacing:.3px}
.pf-badge.funcionario,.src-pf.funcionario{color:var(--teal);border-color:rgba(52,224,200,.4);background:rgba(52,224,200,.08)}
.pf-badge.executivo,.src-pf.executivo{color:var(--blue);border-color:rgba(77,163,255,.4);background:rgba(77,163,255,.08)}
.src-pf.ambos{color:var(--violet);border-color:var(--line2)}
.src.guide{border-color:var(--line2);box-shadow:inset 0 0 20px rgba(77,163,255,.06)}
/* Tabela aprendizado+satisfação por perfil (admin) */
.ci-learn{margin-top:14px}
.ci-sub{font-size:12px;font-weight:600;color:var(--ink-dim);margin-bottom:6px}
.ls-wrap{overflow-x:auto}
.ls-table{width:100%;border-collapse:collapse;font-size:11.5px}
.ls-table th{color:var(--muted);font-weight:500;text-align:center;padding:5px 6px;border-bottom:1px solid var(--line);white-space:nowrap}
.ls-table td{text-align:center;padding:6px;border-bottom:1px solid var(--line);font-family:var(--mono);color:var(--ink)}
.ls-table td.ls-pf{text-align:left;font-family:var(--b-sans);color:var(--ink-dim)}

/* ===================== Tour: destaque de navegação + termo de aceite (2026-07-01) ===================== */
/* Botão real do app aceso GRANDE e BRILHANTE quando o tour o menciona */
.nav-spotlight{position:relative;z-index:60;border-color:var(--blue)!important;
  background:linear-gradient(180deg,rgba(77,163,255,.34),rgba(77,163,255,.12))!important;
  animation:navpulse 1.15s ease-in-out infinite}
.nav-spotlight svg{stroke:#fff!important;filter:drop-shadow(0 0 8px rgba(77,163,255,.95))}
@keyframes navpulse{
  0%,100%{transform:scale(1.14);box-shadow:0 0 0 3px rgba(77,163,255,.85),0 0 20px 6px rgba(77,163,255,.6)}
  50%{transform:scale(1.26);box-shadow:0 0 0 4px rgba(77,163,255,1),0 0 36px 13px rgba(77,163,255,.9)}}
/* Card do termo no chat */
.terms-card{background:linear-gradient(180deg,rgba(77,163,255,.1),rgba(77,163,255,.03));border:1px solid var(--line2);border-radius:14px;padding:14px 16px;margin:10px 0}
.tc-head{font-weight:600;font-size:13.5px;margin-bottom:6px}
.tc-body{font-size:12.5px;color:var(--ink-dim);line-height:1.5;margin-bottom:10px}
.tc-acts{display:flex;gap:10px;flex-wrap:wrap;align-items:center}
.tc-acts a.btn{text-decoration:none}
.tc-msg{font-size:11.5px;color:var(--teal);margin-top:6px;min-height:14px}

/* ===================== Gate obrigatório do termo (LGPD) — trava chat/voz até o aceite ===================== */
.terms-gate-ov{position:fixed;inset:0;z-index:9000;display:flex;align-items:center;justify-content:center;background:rgba(6,9,18,.86);backdrop-filter:blur(8px);animation:tgIn .3s ease}
.terms-gate-ov.out{opacity:0;transition:opacity .3s}
.tg-card{width:min(560px,92vw);background:linear-gradient(180deg,#0d1526,#0a0f1c);border:1px solid var(--line2);border-radius:20px;padding:28px 28px 24px;box-shadow:0 20px 80px rgba(0,0,0,.6)}
.tg-brand{font-weight:800;letter-spacing:4px;color:var(--blue);font-size:15px;text-align:center;margin-bottom:10px}
.tg-card h2{margin:0 0 8px;font-size:22px;text-align:center}
.tg-sub{font-size:13.5px;color:var(--ink-dim);line-height:1.6;margin:0 0 18px}
.tg-acts{display:flex;flex-direction:column;gap:12px;align-items:stretch}
.tg-chk{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--ink-dim);cursor:pointer}
.tg-chk input{width:16px;height:16px;flex:0 0 auto}
.tg-acts a.btn{text-decoration:none;text-align:center}
.tg-acts .btn:disabled{opacity:.45;cursor:not-allowed}
.tg-msg{font-size:12px;color:var(--gold);margin-top:8px;min-height:14px;text-align:center}
.locked-terms{opacity:.5;cursor:not-allowed!important}
@keyframes tgIn{from{opacity:0}to{opacity:1}}

/* ===== MAPA VIVO da sessão (lousa em modo placar de construção) ===== */
.map-badge{display:inline-block;margin-left:5px;color:var(--gold);font-size:9px;vertical-align:middle;animation:lmPulse 1.6s ease infinite}
.map-badge[hidden]{display:none}
@keyframes lmPulse{0%,100%{opacity:.45}50%{opacity:1}}
.lm-map{max-width:960px;margin:0 auto;position:relative;padding:6px 2px}
.lm-head{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;margin-bottom:14px;flex-wrap:wrap}
.lm-kicker{font-family:var(--mono);font-size:11px;letter-spacing:2.5px;text-transform:uppercase;color:var(--teal)}
.lm-title{font-family:var(--h-sans);font-weight:700;font-size:24px;margin-top:4px;line-height:1.2}
.lm-mode{display:flex;gap:6px;flex-wrap:wrap}
.lm-mbtn{cursor:pointer;font-size:12px;padding:7px 13px;border-radius:999px;border:1px solid var(--line);color:var(--muted);background:var(--panel);transition:.15s}
.lm-mbtn:hover{color:var(--ink-dim);border-color:var(--line2)}
.lm-mbtn.on{color:#fff;border-color:var(--line2);background:linear-gradient(180deg,rgba(77,163,255,.22),rgba(77,163,255,.05));box-shadow:inset 0 0 14px rgba(77,163,255,.12)}
.lm-principle{border:1px solid rgba(255,194,77,.35);background:rgba(255,194,77,.07);color:var(--ink);border-radius:12px;padding:12px 16px;font-size:15.5px;line-height:1.5;margin-bottom:16px;box-shadow:inset 0 0 22px rgba(255,194,77,.05)}
.lm-cards{display:flex;flex-direction:column;gap:10px}
.lm-card{display:flex;gap:12px;align-items:flex-start;border:1px solid var(--line);border-radius:12px;padding:12px 14px;background:var(--panel);position:relative}
.lm-card.proximo{border-color:rgba(255,194,77,.45);background:rgba(255,194,77,.06)}
.lm-card.proximo.aberto{order:-1;box-shadow:0 0 18px rgba(255,194,77,.12)}   /* próximo passo aberto fica PINADO no topo */
.lm-card.furo{border-color:rgba(255,92,122,.4);background:rgba(255,92,122,.05)}
.lm-card.feito{opacity:.62}
.lm-card.feito .lm-t{text-decoration:line-through;text-decoration-color:rgba(56,224,160,.7);text-decoration-thickness:2px}
.lm-card.descartado{opacity:.38}.lm-card.descartado .lm-t{text-decoration:line-through}
.lm-ico{font-size:17px;line-height:1.3;flex:none}
.lm-body{flex:1;min-width:0}
.lm-t{font-family:var(--h-sans);font-weight:600;font-size:15.5px;line-height:1.35}
.lm-why{color:var(--ink-dim);font-size:13px;line-height:1.55;margin-top:5px;border-left:2px solid var(--line2);padding-left:10px}
.lm-map.diario .lm-why{display:none}   /* modo A (diário de bordo): placar seco; modo B (didático) mostra os porquês */
.lm-st{flex:none;color:var(--ok);font-size:15px;font-weight:700}
.lm-count{margin-top:14px;font-family:var(--mono);font-size:11px;color:var(--muted);text-align:right}
.lm-in{animation:lmIn .45s cubic-bezier(.2,.9,.3,1.2)}
@keyframes lmIn{from{opacity:0;transform:translateY(14px) scale(.97)}to{opacity:1;transform:none}}
.lm-flash{animation:lmFlash 1.1s ease}
@keyframes lmFlash{0%{box-shadow:0 0 0 rgba(77,163,255,0)}25%{box-shadow:0 0 22px rgba(77,163,255,.45);border-color:var(--blue)}100%{box-shadow:0 0 0 rgba(77,163,255,0)}}

/* ---- Bloco copiável (prompt/código) na saída da Athena ---- */
.cb{margin:8px 0;border:1px solid var(--line2);border-radius:10px;overflow:hidden;background:rgba(8,14,28,.7)}
.cb-bar{display:flex;align-items:center;justify-content:space-between;padding:5px 10px;
  background:rgba(125,160,255,.10);border-bottom:1px solid var(--line);font-family:var(--mono);font-size:11px}
.cb-lang{color:var(--muted);text-transform:lowercase;letter-spacing:.04em}
.cb-copy{cursor:pointer;border:1px solid var(--line2);background:var(--panel2);color:var(--ink-dim);
  font-family:var(--mono);font-size:11px;padding:3px 10px;border-radius:7px;transition:all .15s ease}
.cb-copy:hover{color:var(--ink);border-color:var(--blue);background:rgba(77,163,255,.14)}
.cb-copy.done{color:var(--ok);border-color:var(--ok);background:rgba(56,224,160,.14)}
.cb-pre{margin:0;padding:11px 12px;overflow-x:auto;font-family:var(--mono);font-size:12.5px;line-height:1.5;
  color:var(--ink);white-space:pre;tab-size:2}
.cb-pre code{font-family:inherit;color:inherit;background:none;padding:0}

/* Sessão de construção (conversa É o trabalho): mais espaço ao chat. Só desktop (mobile esconde o dock).
   ESPECIFICIDADE (0,3,2) — DELIBERADA, e é a correção do furo "passou na preview, falhou ao vivo":
   a regra da alça `html.dock-manual:not(.is-tablet) body` é (0,1,2) e vem DEPOIS no arquivo, então ANTES ela
   vencia e o dock NÃO alargava para quem já tinha arrastado uma vez (largura no localStorage). Medido na
   tela: sem arrasto salvo -> 452px; com arrasto salvo -> 380px, com .building ligada nos dois casos. Como a
   preview nunca tem arrasto salvo e o navegador do dono tem, o bug só aparecia ao vivo.
   `:not(.dock-user-wins)` é a válvula de escape combinada: se o aluno arrastar DURANTE a sessão de
   construção, o app liga essa classe, esta regra deixa de casar e o gesto dele reassume até a sessão acabar.
   vs .lesson-live (0,3,2, mais abaixo): especificidade IGUAL e ela vem depois -> a aula tocando continua
   vencendo e estreitando o dock. Ordem preservada de propósito. */
@media(min-width:1025px){ html:not(.is-tablet):not(.dock-user-wins) body.building{--dock-w:452px} }

/* ---- Alça de redimensionar o dock (controle MANUAL) ----
   PRECEDENCIA sobre o fB: `html.dock-manual body` tem especificidade (0,1,2) — MAIOR que `body.building`
   (0,1,1) — e ainda vem DEPOIS no arquivo. Dupla garantia: o que o usuario escolheu na mao manda sobre o
   alargamento automatico (452px), como pedido. Nao ha JS nessa disputa: syncBuildingClass segue intocado e
   continua livre para ligar/desligar .building a vontade.
   POR QUE a classe mora no <html> e nao no <body>: o anti-flash roda no <head> (script sincrono, antes de
   qualquer paint), quando o <body> ainda NAO EXISTE — so o documentElement esta disponivel tao cedo.
   MOBILE: mora dentro do mesmo @media(min-width:1025px) do fB, entao abaixo disso nem existe -> --dock-w
   volta a valer o 0px do @media(max-width:1024px) e a .stage ocupa a tela inteira. Ver public/dockkit.js.

   TABLET (`:not(.is-tablet)`) — ARMADILHA DE CASCATA, a mesma familia que o dockkit.js documenta:
   esta regra escreve --dock-w no BODY, e o body e ancestral mais PROXIMO da .stage/.chatdock que o <html>
   onde o bloco do tablet define `html.is-tablet{--dock-w:380px}`. Em variavel CSS quem ganha e o ancestral
   mais proximo, NAO a especificidade -> sem o :not(), um iPad Air em PAISAGEM (1180px de largura, portanto
   DENTRO deste @media) com uma largura manual antiga no localStorage teria o dock do desktop sobrepondo o
   tablet. E preciso cortar AQUI, na propria regra: uma regra IRMA `html.dock-manual:not(.is-tablet) body`
   adicionada em outro ponto NAO resolveria — ela simplesmente nao casaria no tablet, e esta continuaria
   valendo. A alca nem existe no tablet (o bloco do tablet a esconde), entao aqui nao se perde nada. */
@media(min-width:1025px){ html.dock-manual:not(.is-tablet) body{--dock-w:var(--dock-user)} }

/* ---- fDW: largura do dock ENQUANTO A AULA TOCA (desktop) ----
   REGRA: aula em REPRODUCAO -> dock na largura medida (--dock-lesson); aula parada/fim/saiu -> o dock volta
   sozinho para a PREFERENCIA DO ALUNO (o --dock-user da alca, se ele ja arrastou) ou para o padrao de
   fabrica (380px do :root). Nada aqui persiste nem apaga a escolha do aluno: esta regra so DEIXA DE CASAR
   quando .lesson-live sai do body, e a cascata reassume o valor que ja estava la embaixo.

   PRECEDENCIA (o ponto load-bearing — medido na tela real): tem que vencer o html.dock-manual acima, senao a
   largura salva do aluno (ex.: 697px no localStorage) pinta por cima e a aula NUNCA estreita. Ambas escrevem
   --dock-w no BODY (mesmo ancestral), entao quem decide e a especificidade: esta e (0,3,2) contra (0,2,2) da
   manual -> ganha por especificidade, NAO por ordem no arquivo. Isso e deliberado: um dia alguem reordena o
   CSS e um desempate por ordem quebraria calado.
   POR QUE o :not(.is-mobile) alem do @media: e a trava "so desktop" no CSS (por CLASSE de aparelho, nao so
   por largura), na mesma disciplina do .dock-gutter{display:none} do mobile. O :not(.is-tablet) NAO e
   cosmetico: um iPad em PAISAGEM tem 1180px e cai DENTRO deste @media — sem ele, o tablet (que tem layout
   proprio e nem tem alca) herdaria a largura de aula do desktop. O efeito colateral de ambos e subir a
   especificidade para (0,3,2), que e justamente o que ganha da manual.
   CONSEQUENCIA DECLARADA: enquanto a aula toca, arrastar a alca nao muda a largura (esta regra vence o
   --dock-user). O gesto NAO se perde — ele persiste no localStorage e reaparece assim que a aula para. */
@media(min-width:1025px){ html:not(.is-tablet):not(.is-mobile) body.lesson-live{--dock-w:var(--dock-lesson)} }

/* A alca em si: faixa fina na borda ESQUERDA do dock, por cima da border-left ja existente.
   z-index 5 = acima do .chatdock (4), abaixo do topbar (5, mas nao se cruzam) e dos overlays (30..60).
   left:0 (e NAO um valor negativo) e load-bearing: a .stage termina exatamente onde o dock comeca, e a
   barra de rolagem dela ocupa os ultimos 8px. Com left:-3px a alca cobria os 3px direitos DESSA barra
   (o dock esta acima no z-order) e roubava o clique: pegar o thumb ali nao rolava a pagina. Ancorada em 0,
   a alca vive inteira dentro do dock e nao disputa nada com a .stage. */
.dock-gutter{position:absolute;top:0;left:0;bottom:0;width:6px;z-index:5;cursor:col-resize;
  background:transparent;transition:background .15s ease;touch-action:none;-webkit-tap-highlight-color:transparent}
/* Trilho visivel so no hover/arrasto: em repouso a borda do dock ja e a dica visual, sem poluir a UI. */
.dock-gutter::after{content:'';position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:3px;height:34px;border-radius:3px;background:var(--line2);opacity:0;transition:opacity .15s ease}
.dock-gutter:hover{background:rgba(77,163,255,.10)}
.dock-gutter:hover::after{opacity:.9}
.dock-gutter:focus-visible{outline:none;background:rgba(77,163,255,.14)}
.dock-gutter:focus-visible::after{opacity:1;background:var(--blue)}
/* Estado ARRASTANDO: a classe vive no <body> (nao na alca) porque o setPointerCapture deixa o ponteiro sair
   da alca — o realce tem que sobreviver ao mouse correndo longe. Tambem mata a selecao de texto do app todo. */
body.dock-dragging{user-select:none;cursor:col-resize}
body.dock-dragging .dock-gutter{background:rgba(77,163,255,.18)}
body.dock-dragging .dock-gutter::after{opacity:1;background:var(--blue);box-shadow:0 0 10px rgba(77,163,255,.8)}

/* ---- ALCA do AVATAR — irma da .dock-gutter, mesma disciplina (ver public/avatarkit.js) ----
   POSICAO: canto INFERIOR-ESQUERDO do palco, deslocado 14px. Os dois numeros sao MEDIDOS na tela (1440x900),
   nao escolhidos de cabeca:
   · POR QUE na borda de BAIXO: a borda de CIMA e o topo do dock e a DIREITA e a borda da janela — nenhuma
     das duas tem folga. A de baixo ja e um filete visivel (border-bottom) separando o retrato dos controles.
   · POR QUE 14px da esquerda e nao left:0: a .dock-gutter (o redimensionador do DOCK) e absolute;left:0;
     top:0;bottom:0 — ela cobre a altura INTEIRA do dock, inclusive a faixa do avatar. MEDIDO: ela ocupa
     x=1061..1067. Uma alca em left:0 disputaria o mesmo pixel com ela: dois gestos diferentes no mesmo
     lugar, e o de cima ganharia calado. Com 14px a alca vive em x=1075..1129 — 8px de folga real.
   · POR QUE NAO no canto DIREITO (era o desenho inicial, DERRUBADO PELA MEDICAO): la a alca caia em
     x=1386..1440, ou seja, colada na borda da janela — sobravam 27px de curso para a DIREITA, e a faixa
     inteira (72..340) precisa de 268px. Crescer o avatar seria praticamente impossivel com o mouse.
     Daqui, o curso util e ~365px ate a borda direita: a faixa inteira cabe, com folga.
   z-index 6 > .point-hand/.point-text (4) e > .avatar-img (2): o gesto nunca fica sob a figura (MEDIDO por
   hit-test: elementFromPoint no centro da alca devolve a propria alca).
   O palco tem overflow:hidden — a alca esta INTEIRA dentro dele (bottom:0), entao nao e recortada. */
.avatar-gutter{position:absolute;left:14px;bottom:0;width:54px;height:16px;z-index:6;cursor:ew-resize;
  background:transparent;transition:background .15s ease;touch-action:none;-webkit-tap-highlight-color:transparent}
/* Trilho visivel so no hover/arrasto/foco: em repouso o filete da borda ja e a dica visual, sem poluir a UI
   (mesma decisao da .dock-gutter). Deitado (28x3) porque o gesto e HORIZONTAL — a forma anuncia o eixo. */
.avatar-gutter::after{content:'';position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:28px;height:3px;border-radius:3px;background:var(--line2);opacity:0;transition:opacity .15s ease}
.avatar-gutter:hover{background:rgba(77,163,255,.10)}
.avatar-gutter:hover::after{opacity:.9}
.avatar-gutter:focus-visible{outline:none;background:rgba(77,163,255,.14)}
.avatar-gutter:focus-visible::after{opacity:1;background:var(--blue)}
/* Estado ARRASTANDO no <body> (nao na alca) pelo MESMO motivo da .dock-gutter: o setPointerCapture deixa o
   ponteiro sair da alca, e o realce tem que sobreviver ao mouse correndo longe. Tambem mata a selecao de
   texto do app todo durante o gesto. */
body.avatar-dragging{user-select:none;cursor:ew-resize}
body.avatar-dragging .avatar-gutter{background:rgba(77,163,255,.18)}
body.avatar-dragging .avatar-gutter::after{opacity:1;background:var(--blue);box-shadow:0 0 10px rgba(77,163,255,.8)}

/* Picker "por onde começar" (urgência + quick win) na Avaliação Inicial */
.onb-start{margin-top:10px;padding-top:14px;border-top:1px dashed var(--line2)}
.pick-chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
.pick-chip{cursor:pointer;border:1px solid var(--line2);background:var(--panel);color:var(--ink-dim);
  font-size:12.5px;padding:6px 12px;border-radius:20px;transition:all .14s ease}
.pick-chip:hover{color:var(--ink);border-color:var(--blue)}
.pick-chip.sel{color:var(--bg);background:var(--blue);border-color:var(--blue);font-weight:600;box-shadow:var(--glow)}

/* =========================================================================================================
   TABLET — O DESKTOP COM O MENU DOBRADO PRA CIMA
   =========================================================================================================
   PRINCIPIO (regra do Richard, literal): "TABLET = O DESKTOP COM O MENU DOBRADO PRA CIMA. NAO invente layout
   novo de tablet." A area principal e o chat se comportam como no desktop; a UNICA mudanca ESTRUTURAL e a
   navegacao (o rail vira a gaveta que o mobile ja tem). Por isso este bloco NAO cria layout: ele so
   (a) dobra o menu, (b) RESSUSCITA o chat que o `@media(max-width:1024px)` mata, e (c) reancora 2 insets.

   POR QUE O TABLET PRECISOU DE CLASSE PROPRIA (o furo que esta rodada fechou):
     Ate aqui classifyDevice devolvia 'mobile' para TODO iPad (minSide <= 1024) — CONFIRMADO em iPad emulado
     com toque real (iPad mini 768, gen 7 810, Pro 11 834 => todos 'mobile'). Efeito: em RETRATO o chat cobria
     a tela inteira (o palco sumia atras) e em PAISAGEM o chat MORRIA (`.chatdock{display:none}`). Os dois
     violam "o chat fica SEMPRE visivel ao lado da area principal". O proprio surfacekit ja registrava isso
     como preco consciente ("tablet como classe propria = melhoria futura"). Esta e a melhoria.

   O QUE O TABLET **NAO** HERDA DO MOBILE: o bloco `html.is-mobile` de escrita/consumo. Nao ha "uma superficie
   so" aqui — o tablet tem palco E chat ao mesmo tempo, como o desktop. Todas as regras daquele bloco sao
   prefixadas `html.is-mobile`, entao o tablet fica de fora POR CONSTRUCAO (nao por um `:not()` fragil).
   E o MOTOR de roteamento de superficie tambem nao o rege: applySurfaceRoute() so aplica foco em
   `isMobile() && !isPortrait()`, e isMobile() significa CELULAR. Logo o tablet herda o focusTargetForEvent
   por evento — o mesmo do desktop, que custou ~10 rodadas (fC/fJ/fO/f11/fW/fS/fU) e nao vamos reabrir.
   ========================================================================================================= */

/* ---- Chassi comum as duas orientacoes: so a navegacao dobra ---- */
/* O rail lateral vira a BARRA SUPERIOR (.topnav, definida no bloco do celular abaixo) — decisao fechada do
   mockup: os destinos ficam VISIVEIS no topo, nao atras de um hamburguer. A gaveta foi removida do produto;
   por isso aqui nao ha mais nenhuma regra de .nav-toggle/.nav-drawer. */
html.is-tablet .rail{display:none}
/* TABLET: o botao "sair" TEM que continuar no canto superior direito, igual ao desktop (regra do Richard).
   Antes, o `.top-status{display:none}` escondia o bloco INTEIRO — e levava o "sair" junto. Agora o bloco
   FICA; so os elementos SECUNDARIOS cedem espaco para o "sair" caber no MESMO canto, sem empurrar nada para
   fora: a pilula "Interface de voz" e o relogio saem; o NOME (redundante — igual nas duas contas) sai; a
   identidade encolhe com reticencias. O e-mail (fWHO — o que desambigua admin x aluno) fica em PRIMEIRO e
   sempre visivel. (Chips de bastidor Google/Navegador ja nascem `hidden` p/ aluno; so aparecem p/ Master.) */
html.is-tablet #chipVoice{display:none}                /* "Interface de voz": pilula secundaria, cede a largura */
html.is-tablet #clock{display:none}                    /* relogio: secundario (o mobile tambem nao o mostra)   */
html.is-tablet #userChip{max-width:44vw;min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
html.is-tablet #userChip b{display:none}               /* o NOME e igual nas duas contas; o e-mail distingue e vem primeiro */
/* O "sair": MESMO canto, MESMO estilo (ghost). So ganha alvo de toque >= 44px (dedo no iPad, nao mouse) e
   NUNCA encolhe (flex-shrink:0 => a identidade cede espaco primeiro; o botao jamais e empurrado para fora). */
html.is-tablet #logoutBtn:not([hidden]){flex-shrink:0;min-height:44px;padding:8px 16px;display:inline-flex;align-items:center}
/* A .stage e o .chatdock precisam descer abaixo da barra (topbar 60 + topnav ~46 no tablet). */
html.is-tablet .stage{top:calc(60px + var(--nav-h))}
/* A alca de arrastar o dock nao sobrevive ao dedo: 6px de largura nao e alvo de toque. O tablet usa as
   proporcoes fixas abaixo. (No celular ela ja morre com o proprio .chatdock no @media(max-width:1024px).) */
html.is-tablet .dock-gutter{display:none}
/* Mesma razao para a alca do AVATAR: 16px de altura nao e alvo de toque, e no tablet o retrato ja tem o seu
   proprio tamanho por regra (176px no split, 96px no chat cheio). O tamanho arrastado no desktop CONTINUA
   guardado — so o gesto e que nao existe aqui. */
html.is-tablet .avatar-gutter{display:none}
/* ...E O TAMANHO ESCOLHIDO NO DESKTOP NAO PODE ESTOURAR O SPLIT DO TABLET (medido: sem esta regra, uma
   escolha de 320px vinha inteira para ca). No tablet em retrato o chat e METADE da tela (--split-h ~510px);
   com avatar 320 + faixa de controles + input sobrariam ~66px de conversa, e aqui NAO HA alca para desfazer.
   min() e o teto, nao um valor fixo: quem escolheu MENOR que 176 continua vendo a escolha dele (encolher
   nunca espreme a conversa); quem escolheu MAIOR e limitado ao tamanho que o tablet sempre teve. Estritamente
   mais seguro que o comportamento anterior (176 cravado), nunca pior. O chat cheio (0,3,1) segue vencendo. */
html.is-tablet .avatar-stage{height:min(var(--avatar-h), 176px)}

/* ---- PAISAGEM = o desktop, literalmente: palco protagonista + chat na coluna lateral ---- */
@media (orientation:landscape){
  /* --dock-w e a UNICA alavanca: a .stage le `right:var(--dock-w)` e o .chatdock le `width:var(--dock-w)`
     (uma variavel dirige os dois). Reancorar aqui e o que faz "o desktop" aparecer sem nenhum layout novo.
     `html.is-tablet` (0,1,1) vence o `:root{--dock-w:0px}` (0,1,0) do @media(max-width:1024px) por
     ESPECIFICIDADE — nao depende da ordem no arquivo. */
  /* TABLET 3 — a MESMA alavanca (--dock-w), com PROPORCAO em vez de um numero fixo.
     O PROBLEMA (medido): 380px sao 26% de um desktop de 1440, mas 37% de um iPad mini DEITADO (1024) — o
     mesmo numero absoluto come uma fatia MUITO maior da tela pequena. O chat virava o protagonista num
     aparelho onde o palco (lousa, Gantt) e quem precisa do espaco.
     Os TRES numeros do clamp sao reusados, nao inventados:
       · piso 320px  = DOCK_MIN do dockkit.js — o proprio app ja declara que abaixo disso "o chat fica
                       inutilizavel". Protege o iPad mini, onde 28vw dariam so 287px.
       · meio 28vw   = a proporcao do DESKTOP (380/1440 = 26,4%), arredondada para cima. E o unico numero
                       novo, e ele e DERIVADO da referencia que ja existia.
       · teto 380px  = exatamente a largura de hoje. Garante ZERO regressao no tablet grande: iPad Pro 12.9
                       (1366) segue em 380px, identico ao que ja era.
     Efeito: so os tablets APERTADOS ganham palco; os largos ficam byte-a-byte como estavam. */
  html.is-tablet{--dock-w:clamp(320px, 28vw, 380px)}
  html.is-tablet .stage{left:0}          /* sem rail a esquerda; o `right` segue a variavel acima */
  /* Ressuscita o chat. !important espelha a regra irma do modo escrita (a especificidade ja bastaria; o
     marcador deixa a intencao "isto reverte o display:none de cima" impossivel de ler errado). */
  html.is-tablet .chatdock{display:flex !important}
}

/* ---- RETRATO = empilhado: palco em cima, chat embaixo, metades EXATAS ---- */
/* DECISAO DO RICHARD (perguntada, nao presumida): em retrato o par NAO divide a largura em duas colunas —
   empilha. Motivo dele: coluna estreita numa tela de 744-768px sofre (seriam ~372px para o palco, e a lousa
   e o Gantt, que ja pede min-width:780px, ficariam ilegiveis). Empilhado cada um fica com a largura INTEIRA.
   Isto vale para TODO tablet por ORIENTACAO — o iPad mini herda de graca, sem regra especial por tamanho. */
@media (orientation:portrait){
  /* Metades iguais do espaco ABAIXO do topbar. Um `50%` cru daria 452px de palco contra 512px de chat num
     iPad de 1024 de altura, porque os 60px do topbar sairiam so do palco. dvh (nao vh) acompanha a barra de
     URL que recolhe — mesmo motivo do .board-stage do modo consumo. */
  html.is-tablet{--split-h:calc((100dvh - 60px) / 2)}
  html.is-tablet .stage{left:0;right:0;bottom:var(--split-h)}
  /* O dock deixa de ter "largura" e passa a ter ALTURA: top:auto + bottom:0 + height. Nenhum --dock-w
     envolvido (a regra de ouro do dockkit segue: esta folha nunca escreve --dock-w inline nem toca --dock-user). */
  html.is-tablet .chatdock{display:flex !important;
    top:auto;left:0;right:0;bottom:0;width:auto;height:var(--split-h);
    border-left:0;border-top:1px solid var(--line2);
    padding-bottom:env(safe-area-inset-bottom);   /* barra de gestos nao come o input */
  }
  html.is-tablet .chat-input{padding-bottom:calc(12px + env(safe-area-inset-bottom))}
  /* A LOUSA TEM QUE CABER NO SLOT DO SPLIT (furo PRE-EXISTENTE, achado medindo o TABLET 1 em iPad emulado).
     `.board-stage{min-height:64vh}` da 655px num iPad de 1024 de altura — mas em RETRATO o split deixa para
     o palco so ~436px (1024 - 60 topbar - 46 nav - 482 do --split-h). O bloco nascia 219px MAIOR que o slot,
     e o terco de baixo — justamente onde a PERGUNTA DE FIXACAO fica, por ser o ultimo bloco do slide — caia
     ATRAS do painel do chat. MEDIDO: opcao em y=666 com o chatdock comecando em y=542; elementFromPoint no
     centro dela devolvia `avatar-img` (o chat por cima). Dava para alcancar rolando, mas o aluno nao ve o
     que nao aparece: e exatamente o "a aula termina sem pergunta".
     min-height:0 devolve a altura ao CONTEUDO. max-height:none de proposito: com ele o `.board-stage` teria
     rolagem PROPRIA dentro da `.stage`, que ja rola — dois scrollers aninhados no toque prendem o gesto
     (o dedo rola o de dentro e a pagina nao anda). Com um scroller so, a `.stage` rola e o slide inteiro
     fica alcancavel. Escopado a html.is-tablet + retrato: desktop, paisagem e celular intactos. */
  html.is-tablet .board-stage{min-height:0;max-height:none}
}

/* NOTA: o corte do tablet contra a alca manual do dock NAO mora aqui — mora na PROPRIA regra
   `html.dock-manual:not(.is-tablet) body` la em cima (secao da alca). Uma regra irma aqui embaixo nao
   funcionaria: ela nao casaria no tablet e a original seguiria valendo. Ver o comentario de la. */

/* =========================================================================================================
   MOBILE (CELULAR) — BARRA SUPERIOR + SPLIT + AULA EM PAISAGEM
   =========================================================================================================
   ESCOPO: celular (minSide <= 743, html.is-mobile). O TABLET tem bloco proprio acima e nao entra aqui.

   LAYOUT (decisao fechada, mockup aprovado):
     - NAVEGACAO: barra SUPERIOR com os destinos VISIVEIS (o rail "dobrado para cima"). Sem gaveta, sem
       hamburguer — a navegacao nao fica atras de um gesto.
     - RETRATO = SPLIT (o padrao): painel de cima = conteudo/lousa; painel de baixo = chat. O aluno le e
       escreve na mesma tela; nao ha "modo" a aprender.
     - PAISAGEM = AULA EM TELA CHEIA: a lousa toma tudo e o chat COLAPSA num FAB. O chat nao fica plantado
       comendo espaco — e um toque.
     - AVISO "vire o celular": so ao DISPARAR a aula em retrato (a aula pre-gravada exige paisagem).

   POR QUE `html.is-mobile` (classe) e nao so @media de largura: a regra de aparelho e
   `(pointer:coarse) && (hover:none) && minSide<=743` — MEDIDO: um desktop com janela de 390px reporta
   pointer:fine/hover:hover; so a largura o classificaria como celular e QUEBRARIA o desktop. A classe vem de
   public/surfacekit.js classifyDevice (node-testavel) + anti-flash no <head>. A ORIENTACAO fica em
   @media(orientation:...) puro — instantanea, sem depender de JS.

   O QUE NAO E TOCADO: nada aqui existe fora de html.is-mobile/.is-tablet. O desktop (inclusive o dock
   arrastavel) segue byte-a-byte. Esta folha NUNCA escreve --dock-w inline nem mexe em --dock-user: a regra de
   ouro do dockkit continua valendo.
   ========================================================================================================= */

/* ---- Chassi ---- */
html.is-mobile .rail{display:none}                     /* 88px = 23% de um celular de 390px (MEDIDO) */
html.is-mobile .top-status{display:none}               /* chips = ruido na faixa nobre; o e-mail volta abaixo */
html.is-mobile .dock-gutter{display:none}              /* a alca do dock nao existe no celular */
html.is-mobile .avatar-gutter{display:none}            /* nem a do avatar: aqui o retrato e um icone de 30px */
/* Topbar compacto: logo + identidade. Menor que o desktop (60px) porque agora ha a barra de navegacao logo
   abaixo — as duas juntas nao podem comer a leitura. */
html.is-mobile .topbar{height:48px;padding-left:max(12px,env(safe-area-inset-left));padding-right:max(12px,env(safe-area-inset-right))}
html.is-mobile .brand-mark{width:26px;height:26px}
html.is-mobile .brand-name{font-size:14px;letter-spacing:3px}
html.is-mobile .brand-sub{display:none}
/* fWHO: o e-mail da conta NAO pode sumir (o mesmo humano tem conta admin e conta aluno com o mesmo nome; so o
   e-mail desambigua). Os outros chips saem; este fica, compacto. */
html.is-mobile #userChip{display:inline-flex;padding:4px 9px;font-size:11px;max-width:56vw;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
html.is-mobile #userChip b{display:none}               /* o NOME e igual nas duas contas — o e-mail e que distingue */
html.is-mobile #userPlan{display:none}
html.is-mobile #logoutBtn{display:none}                /* sair vive em Configuracoes; nao gasta a faixa nobre */

/* HOVER GRUDADO (furo real de touch): :hover fica preso apos o toque ate o proximo toque. Guardar atras de
   @media(hover:none) e a correcao padrao. So neutraliza os alvos do mobile; o desktop segue intacto. */
@media (hover:none){
  html.is-mobile .rail-btn:hover{color:var(--muted);background:transparent;border-color:transparent}
  html.is-mobile .topnav-btn:hover{background:transparent}
}

/* ---- BARRA SUPERIOR de navegacao (o rail dobrado para cima) ---- */
/* --nav-h e a FONTE UNICA da altura da barra: a propria .topnav a usa como height, e a .stage a desconta do
   topo. Um numero so — nunca mais barra de 63px contra palco ancorado em 46px. */
html.is-mobile,html.is-tablet{--nav-h:60px}
/* Some por padrao: so existe em mobile/tablet (no desktop quem navega e o rail lateral). */
.topnav{display:none}
html.is-mobile .topnav,html.is-tablet .topnav{
  /* altura FIXA e a MESMA que a .stage desconta (--nav-h). Sem isto a barra cresce com o conteudo e passa a
     cobrir o topo do palco — bug MEDIDO: barra 63px x --nav-h 46px = 17px de sobreposicao. */
  display:flex;position:fixed;left:0;right:0;top:48px;z-index:5;height:var(--nav-h);align-items:center;
  gap:6px;padding:6px max(8px,env(safe-area-inset-left)) 6px max(8px,env(safe-area-inset-right));
  overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;scrollbar-width:none;
  background:linear-gradient(180deg,rgba(8,12,22,.96),rgba(8,12,22,.72));
  border-bottom:1px solid var(--line);backdrop-filter:blur(10px)}
html.is-tablet .topnav{top:60px}                        /* o tablet mantem o topbar de 60px */
html.is-mobile .topnav::-webkit-scrollbar,html.is-tablet .topnav::-webkit-scrollbar{display:none}
/* DICA DE ROLAGEM: os 6 rotulos completos somam 472px (MEDIDO) e a tela tem 390 — a barra ROLA (provado: apos
   rolar, o ultimo item entra e e alcancavel por hit-test). Sem uma borda que desvanece, o aluno nao descobre
   que ha mais itens e "Configuracoes" some do mundo. O fade e puramente visual: pointer-events:none garante
   que ele nunca roube um toque do item por baixo. */
html.is-mobile .topnav::after,html.is-tablet .topnav::after{
  content:'';position:fixed;pointer-events:none;z-index:6;
  right:0;height:var(--nav-h);width:26px;
  background:linear-gradient(90deg,transparent,rgba(8,12,22,.92))}
html.is-mobile .topnav::after{top:48px}
html.is-tablet .topnav::after{top:60px}
.topnav-btn{flex:0 0 auto;display:flex;flex-direction:column;align-items:center;gap:3px;cursor:pointer;
  background:transparent;border:1px solid transparent;border-radius:12px;padding:7px 11px;color:var(--muted);
  font-family:var(--b-sans);font-size:10px;letter-spacing:.2px;white-space:nowrap;
  -webkit-tap-highlight-color:transparent}
.topnav-btn[hidden]{display:none !important}
.topnav-btn svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.topnav-btn.active{color:#fff;background:linear-gradient(180deg,rgba(77,163,255,.22),rgba(77,163,255,.05));
  border-color:var(--line2);box-shadow:inset 0 0 14px rgba(77,163,255,.12)}
.topnav-btn.active svg{stroke:var(--blue);filter:drop-shadow(0 0 5px rgba(77,163,255,.6))}

/* ---- FAB do chat (paisagem/aula) ---- */
.chat-fab{display:none}
.chat-fab[hidden]{display:none !important}
.chat-fab svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}

/* =========================== RETRATO = SPLIT (o padrao) =========================== */
@media (orientation:portrait){
  /* --split-h = a metade de BAIXO (chat). Desconta o cromo (topbar 48 + topnav ~46) de UMA vez, senao a
     divisao sairia torta: um 50% cru daria mais palco que chat. dvh (nao vh) acompanha a barra de URL que
     recolhe — o mesmo motivo do .board-stage. 0.48 (nao 0.5): o chat precisa de um pouco menos que o palco,
     porque o input + o chat-head ja sao cromo dentro dele. */
  html.is-mobile{--split-h:calc((100dvh - 48px - var(--nav-h)) * 0.48)}
  /* O palco ocupa de baixo do topnav ate onde o chat comeca. */
  html.is-mobile .stage{top:calc(48px + var(--nav-h));left:0;right:0;bottom:var(--split-h);padding:10px 12px 14px;z-index:2}
  /* O CHAT volta a existir (o @media(max-width:1024px) o mata com display:none) e vira a metade DE BAIXO:
     top:auto + bottom:0 + height. Nenhum --dock-w envolvido (a regra de ouro do dockkit segue).
     !important: o `.chatdock{display:none}` do @media(max-width:1024px) tem a mesma especificidade e vem
     ANTES; sem ele a cascata o manteria escondido. */
  html.is-mobile .chatdock{
    display:flex !important;top:auto;left:0;right:0;bottom:0;width:auto;height:var(--split-h);z-index:4;
    border-left:0;border-top:1px solid var(--line2);
    padding-bottom:env(safe-area-inset-bottom);
  }
  html.is-mobile .chat-input{padding-bottom:calc(10px + env(safe-area-inset-bottom))}
  /* A lousa dentro do split: sem os tetos de vh do desktop (64/78vh), que num celular estouram a metade. */
  html.is-mobile .board-stage{min-height:0;max-height:none;height:100%;padding:12px 12px 16px}
  html.is-mobile .board-panel{border-radius:12px}
  html.is-mobile .view-head{margin-bottom:10px}
  html.is-mobile .view-head h1{font-size:18px}
  html.is-mobile .view-head .muted{font-size:12px}
  /* Em retrato o #stopBtn real esta visivel no chat-head -> o flutuante seria redundante. */
  html.is-mobile .stop-float{display:none !important}
  html.is-mobile .chat-fab{display:none !important}    /* o chat ja esta na tela: FAB nao faz sentido */
}

/* =========================== PAISAGEM = AULA EM TELA CHEIA =========================== */
/* A CONTA (MEDIDA num viewport 844x390): topbar 60 + tabbar 83 + padding 84 = 227px de cromo -> sobravam
   163px para a superficie, e o .board-stage{min-height:64vh} sozinho ja pedia 249.6px. Por isso o modo
   paisagem NAO e "esconder o chat": e recuperar a tela inteira para a aula. */
@media (orientation:landscape){
  html.is-mobile .topbar{display:none}                 /* 48px de 390 = 12% da tela para um logo */
  html.is-mobile .topnav{display:none}                 /* navegacao volta ao girar; aqui a aula manda */
  html.is-mobile .stage{top:0;bottom:0;left:env(safe-area-inset-left);right:env(safe-area-inset-right);padding:0}
  html.is-mobile .view-head{display:none}
  html.is-mobile .panel{margin-bottom:0;border-radius:0;border-left:0;border-right:0}
  html.is-mobile .aula-tabbar{display:none}            /* quem escolhe a aba e o MOTOR de roteamento */
  html.is-mobile .board-stage{min-height:0;max-height:none;height:100dvh;padding:10px 12px}
  html.is-mobile .board-panel{border:0;border-radius:0;background:transparent}
  /* O chat COLAPSA: fora da tela por padrao. Nao e display:none — o dock continua montado (o chat-head tem os
     controles de voz reais e o #stopBtn; o chat-log preserva o historico e o scroll). */
  html.is-mobile .chatdock{
    display:flex !important;top:auto;left:auto;bottom:0;
    right:max(8px,env(safe-area-inset-right));width:min(400px,86vw);height:min(78dvh,420px);
    z-index:9;border:1px solid var(--line2);border-radius:16px 16px 0 0;
    transform:translateY(102%);transition:transform .22s ease;   /* 102% = some com a sombra junto */
    box-shadow:0 -8px 40px rgba(0,0,0,.6);pointer-events:none;
  }
  /* ...e SOBE quando o aluno toca o FAB. A classe mora no <html> (o app.js so alterna). */
  html.is-mobile.chat-open .chatdock{transform:translateY(0);pointer-events:auto}
  html.is-mobile .chat-fab{display:grid;position:fixed;z-index:10;place-items:center;
    right:max(10px,env(safe-area-inset-right));bottom:max(10px,env(safe-area-inset-bottom));
    width:48px;height:48px;border-radius:50%;cursor:pointer;
    background:linear-gradient(180deg,rgba(77,163,255,.95),rgba(40,110,200,.95));color:#fff;
    border:1px solid var(--line2);box-shadow:0 4px 20px rgba(0,0,0,.5);-webkit-tap-highlight-color:transparent}
  html.is-mobile.chat-open .chat-fab{background:rgba(8,12,22,.9);color:var(--ink-dim)}
  /* PARAR flutuante: sem o dock plantado, e o UNICO jeito de cortar a fala (no celular nao ha Esc). */
  html.is-mobile .stop-float{display:inline-flex}
}

/* ---- AVATAR no celular: ICONE na barra de controles (nao um bloco vertical) ---- */
/* ANTES: `.avatar-stage` era um bloco de 176px FIXOS com flex-shrink:0 (nao encolhia) entre o conteudo e o
   chat — 22% de um chatdock de 784px, e o `.chat-log` (flex:1) era quem pagava a conta. Reduzir a altura
   (84px) ajudou, mas o bloco continuava COMENDO uma faixa vertical inteira so para decoracao.
   AGORA: no celular o avatar SAI DO FLUXO (position:absolute) e vira um ICONE de 30px ancorado na MESMA linha
   do "Mic"/"Som". O `.chat-log` recupera os 176px INTEIROS.

   POR QUE absolute e NAO mover no DOM: o `#avatarStage` e irmao do `.chat-head` (nao filho), entao CSS puro
   nao o poe "dentro" da linha. Move-lo por JS funcionaria, mas o app.js referencia #avatarStage/#avatarImg/
   .point-hand em varios pontos (setAvatar/avatarPoint/upload) e mover no DOM so no mobile viraria estado a
   sincronizar no giro e na reclassificacao. Com absolute o DOM NAO muda: zero risco para o desktop e para as
   referencias, e a volta e automatica (a regra so existe em html.is-mobile).
   O `.chatdock` e position:fixed = ja e o containing block; o `.chat-head` ganha padding-left para o icone
   nao cobrir o "Mic".

   AS ANIMACOES CONTINUAM: `.avatar-stage.speaking .avatar-aura{animation:av-glow}` e
   `.avatar-stage.{idle,thinking,speaking} .avatar-img{animation:av-breathe}` sao disparadas pela CLASSE que o
   setAvatar() poe no #avatarStage — que segue existindo e recebendo as classes. O icone pequeno pisca/pulsa ao
   falar exatamente como o grande, sem uma linha de JS nova. (A aura foi reescalada p/ caber nos 30px.) */
html.is-mobile .avatar-stage{
  position:absolute;top:7px;left:10px;z-index:5;
  width:30px;height:30px;flex-shrink:0;
  border-bottom:0;border-radius:50%;overflow:hidden;
  align-items:center;                     /* o grande alinha flex-end (figura "em pe"); no icone, centrado */
  background:rgba(255,255,255,.05);border:1px solid var(--line2);
}
/* A vaga do icone + os controles CABENDO numa linha so. Sem o nowrap/encolher, o padding-left espremia a
   faixa e o botao do mic (entao "Ativar voz", hoje "Mic") QUEBRAVA EM DUAS LINHAS assim que o #stopBtn aparecia
   (aula tocando): o botao ia de
   30px para 46px e o icone saia do alinhamento — MEDIDO (centro do avatar 514 x centro do botao 526).
   min-height fixa a faixa: com ela o icone (top:7px, 30px) fica centrado independente do que entre na linha. */
html.is-mobile .chat-head{padding:7px 10px 7px 46px;gap:6px;min-height:44px;flex-wrap:nowrap}
html.is-mobile .chat-head .voice-toggle{padding:5px 9px;font-size:11px;white-space:nowrap;flex-shrink:0}
html.is-mobile .chat-head .stop-btn{padding:5px 9px;font-size:11px;white-space:nowrap;flex-shrink:0}
html.is-mobile .voice-status{font-size:9px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* "limpar" e o controle menos essencial da faixa: no celular ele e o primeiro a ceder o espaco (a conversa
   se limpa pelo desktop/Config). Sem isto os 4 controles + o icone nao cabem em 390px sem quebrar. */
html.is-mobile #clearChat{display:none}
html.is-mobile .avatar-img{max-height:100%;max-width:100%;height:100%;width:100%;object-fit:cover;
  filter:none;transform-origin:50% 50%}             /* o drop-shadow do grande vira sujeira em 30px */
html.is-mobile .avatar-aura{top:-4px;left:50%;width:38px;height:38px;filter:blur(5px)}
/* O placeholder "carregar avatar" (aluno sem foto) nao cabe em 30px: vira so o simbolo. */
html.is-mobile .avatar-placeholder{padding:0;font-size:12px;border:0;background:transparent;inset:0;transform:none;
  width:100%;height:100%;align-items:center;justify-content:center;border-radius:50%}
html.is-mobile .avatar-placeholder span{display:none}
/* A mao que aponta e o texto do "olhe a lousa" nao fazem sentido num icone de 30px (e cobririam os botoes). */
html.is-mobile .point-hand,html.is-mobile .point-text{display:none}
/* PAISAGEM: o chat e um painel flutuante e curto — o icone continua util (indica fala), so nao ha o que cobrir.
   Mantido. Com o TECLADO aberto tambem fica: agora ele nao rouba altura de leitura (esta fora do fluxo). */

/* ---- f18: TECLADO VIRTUAL ---- */
/* O interactive-widget=resizes-content (meta viewport) cobre o Android; no iOS Safari ele e IGNORADO — o
   teclado NAO encolhe o layout viewport, so o visual viewport, e um `position:fixed;bottom:0` fica ATRAS do
   teclado. Por isso o app.js mede o visualViewport e publica --kb-h; aqui so consumimos.
   --kb-h = 0 quando nao ha teclado, entao estas regras sao no-op no estado normal. */
html.is-mobile{--kb-h:0px}
@media (orientation:portrait){
  /* O chat sobe junto do teclado (o dock inteiro, nao so o input) e CRESCE: com o teclado aberto o aluno esta
     lendo a resposta e escrevendo — o palco pode ceder.
     ANCORADO POR INSETS (top+bottom), NAO por height calculada: um `height:calc(--split-h + 22dvh)` fixo dava
     539px num espaco livre de 508 (844 - 336 do teclado) e o chat ESTOURAVA o topo -> y=-31 (MEDIDO). Com
     top/bottom o flex resolve a altura sozinho e o dock nunca passa da barra nem do teclado, em NENHUMA
     combinacao de teclado x aparelho. */
  /* :not(.chat-full) — MUTUAMENTE EXCLUSIVAS de proposito (achado da auditoria). Esta regra e a do chat cheio
     (`html.is-mobile.chat-full .chatdock`) tem a MESMA especificidade (0,3,1); sem o :not, quem vence e a ORDEM
     NO ARQUIVO, e mover um bloco reverteria o `top:0` do chat cheio para `top:108px` EM SILENCIO. Com o :not
     nao ha competicao: o chat cheio tem a sua propria regra (que ja trata o teclado pelo bottom:var(--kb-h)). */
  html.is-mobile.kb-open:not(.chat-full) .chatdock{top:calc(48px + var(--nav-h));bottom:var(--kb-h);height:auto}
  /* O palco cede o que sobra (pode zerar: com o teclado aberto quem manda e a leitura+escrita). */
  html.is-mobile.kb-open .stage{bottom:calc(100dvh - 48px - var(--nav-h))}
}
@media (orientation:landscape){
  html.is-mobile.kb-open .chatdock{bottom:var(--kb-h)}
  html.is-mobile.kb-open .chat-fab{bottom:calc(max(10px,env(safe-area-inset-bottom)) + var(--kb-h))}
}

/* =========================================================================================================
   CHAT CHEIO (toggle pelo AVATAR) — SO EM RETRATO, mobile E tablet
   =========================================================================================================
   O PROBLEMA: em retrato o chat e a metade de baixo do split (--split-h). Cabe pouca conversa: no celular
   sobram ~240px de .chat-log, e com o teclado aberto menos ainda. Ler uma resposta longa vira rolagem infinita
   num tubo.
   A SOLUCAO: tocar no AVATAR da Athena expande o chat para o viewport INTEIRO; tocar de novo volta ao split.
   Liga-desliga no mesmo icone (o avatar fica visivel no topo do chat cheio = o alvo de fechar).

   POR QUE TUDO AQUI VIVE DENTRO DE @media(orientation:portrait):
   e a exigencia "em paisagem NAO ativar o toggle" resolvida por CONSTRUCAO, nao por JS. Mesmo que a classe
   .chat-full fique ligada (ex.: o aluno gira o aparelho com o chat cheio aberto), em paisagem ela NAO casa
   nenhuma regra -> o layout deitado (chat lado a lado no tablet / FAB no celular) reaparece sozinho, sem
   flicker e sem corrida entre o giro e um handler. O JS ainda limpa a classe no giro (aria-pressed correto),
   mas o CSS ja garantiria a saida graciosa se o JS falhasse.

   DESKTOP: intocado — toda regra e prefixada html.is-mobile / html.is-tablet.
   ========================================================================================================= */
@media (orientation:portrait){
  /* O dock cobre a tela inteira. z-index 20 > topbar/topnav (5) e > o proprio dock no split (4); e MENOR que
     os overlays de sistema (auth 60, termos 9000) — o chat cheio nunca cobre um login ou um gate legal.
     padding-top com safe-area: sem isto o avatar (o botao de fechar) fica sob o notch num iPhone. */
  html.is-mobile.chat-full .chatdock,
  html.is-tablet.chat-full .chatdock{
    display:flex !important;
    top:0;left:0;right:0;bottom:var(--kb-h,0px);      /* bottom segue o TECLADO: o input nunca fica atras dele */
    width:auto;height:auto;z-index:20;
    border-left:0;border-top:0;
    padding-top:env(safe-area-inset-top);
    padding-bottom:env(safe-area-inset-bottom);
    background:var(--bg);                              /* opaco: o split por baixo nao pode vazar */
  }
  /* Com o dock cobrindo tudo, a barra de navegacao por baixo so atrapalharia o toque. */
  html.is-mobile.chat-full .topnav,html.is-tablet.chat-full .topnav{pointer-events:none}
  /* MOBILE: o avatar e um icone absoluto no canto do .chat-head — desce junto da safe-area para nao ficar sob
     o notch, e ganha um anel indicando que ESTA ativo (e o botao de voltar). */
  html.is-mobile.chat-full .avatar-stage{
    top:calc(7px + env(safe-area-inset-top));
    border-color:var(--blue);box-shadow:0 0 0 2px rgba(77,163,255,.35)}
  /* TABLET: o avatar e o bloco de 176px (regra do desktop, preservada). Em chat cheio ele encolhe — a tela e
     do texto, nao do retrato — mas continua sendo o alvo de fechar. */
  html.is-tablet.chat-full .avatar-stage{height:96px;cursor:pointer}
  html.is-tablet.chat-full .avatar-img{max-height:94px}
  /* O input encosta no fim do dock; o padding-bottom da safe-area ja esta no container. */
  html.is-mobile.chat-full .chat-input,html.is-tablet.chat-full .chat-input{padding-bottom:10px}
  /* O TECLADO no TABLET: o --kb-h so era publicado/consumido no celular (syncKeyboardInset saia cedo em
     tablet). O app.js agora publica nos dois; aqui o consumo fica ESCOPADO ao chat cheio, entao o split
     normal do tablet segue exatamente como estava — nenhuma mudanca fora desta feature. */
  html.is-tablet{--kb-h:0px}
}
/* Afordancia de toque: o avatar vira botao (o alvo do toggle) no mobile/tablet — no desktop ele segue levando
   ao painel de trocar imagem, e por isso o cursor/aria nao mudam la. */
html.is-mobile .avatar-stage,html.is-tablet .avatar-stage{cursor:pointer;-webkit-tap-highlight-color:transparent}
/* ALVO DE TOQUE de 44px no CELULAR (achado da auditoria). O icone tem 30x30 e passou a ser o gesto PRIMARIO da
   feature — e, no chat cheio, o UNICO jeito de voltar. 30px fica abaixo do minimo de HIG/WCAG 2.5.5.
   Tem de ser ::after e NAO width/height: crescer a caixa desalinha o icone da linha do "Mic"/"Som" (a faixa tem
   min-height:44px e padding-left:46px; a rodada passada MEDIU o desalinho ao mexer no tamanho). O pseudo-elemento
   amplia so a AREA CLICAVEL — o clique nele borbulha para o #avatarStage, que e onde a captura escuta.
   44 centrado no icone ocupa x=3..47; o "Mic" comeca em 48 -> nao rouba o toque do vizinho. */
html.is-mobile .avatar-stage::after{content:'';position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:44px;height:44px;border-radius:50%}
/* O .avatar-stage do celular tem overflow:hidden (recorta a foto no circulo), o que CORTARIA o ::after de 44px.
   Solucao: quem recorta passa a ser a propria imagem (border-radius no img), liberando o overflow do container. */
html.is-mobile .avatar-stage{overflow:visible}
html.is-mobile .avatar-img{border-radius:50%}

/* ---- PARAR flutuante ---- */
.stop-float{position:fixed;z-index:11;display:none;align-items:center;gap:6px;
  top:max(8px,env(safe-area-inset-top));right:max(8px,env(safe-area-inset-right));
  cursor:pointer;border:1px solid var(--danger);border-radius:999px;padding:9px 15px;
  background:rgba(255,92,122,.9);color:#fff;font-family:var(--h-sans);font-size:12.5px;letter-spacing:.4px;
  backdrop-filter:blur(8px);box-shadow:0 4px 18px rgba(0,0,0,.4);-webkit-tap-highlight-color:transparent}
.stop-float[hidden]{display:none !important}

/* ===================== MENU ALUNOS — tabela operacional + ficha individual =====================
   Reusa a base já existente (.utab, .tx-overlay/.tx-modal, .btn, .test-tag) — nada de um segundo
   design system para a mesma tela. O que entra aqui é só o que não existia: a barra de filtros, os
   indicadores de linha (churn/atividade/modelo) e o layout do prontuário. */

/* --- barra de busca + filtros da tabela --- */
.stab-bar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin:0 0 12px}
.stab-search{flex:1 1 220px;min-width:180px;background:rgba(0,0,0,.3);border:1px solid var(--line);color:var(--ink);
  border-radius:9px;padding:7px 11px;font-size:13px;font-family:var(--b-sans)}
.stab-search:focus{outline:none;border-color:var(--blue)}
.stab-bar .vsel{background:rgba(0,0,0,.3);border:1px solid var(--line);color:var(--ink);border-radius:9px;
  padding:6px 8px;font-size:12px;font-family:var(--b-sans)}

/* --- cabeçalho ordenável: a coluna inteira é o alvo do clique --- */
.utab .st-th{cursor:pointer;user-select:none;white-space:nowrap}
.utab .st-th:hover{color:var(--ink)}
.utab .st-th.sorted{color:var(--blue)}

/* --- nome do aluno = link para a ficha (botão, não <a>: não navega) --- */
.st-name{background:none;border:none;padding:0;font:inherit;color:var(--blue);cursor:pointer;text-align:left;
  font-weight:600;border-bottom:1px dotted rgba(77,163,255,.5)}
.st-name:hover{color:var(--ink);border-bottom-color:var(--ink)}

/* --- indicadores de linha --- */
.churn{display:inline-block;font-size:11px;font-weight:700;padding:2px 8px;border-radius:999px;white-space:nowrap}
.churn.ok{color:var(--ok);background:rgba(60,220,150,.10);border:1px solid rgba(60,220,150,.35)}
.churn.medio{color:#ffb454;background:rgba(255,180,84,.10);border:1px solid rgba(255,180,84,.40)}
.churn.alto{color:var(--danger);background:rgba(255,92,122,.12);border:1px solid rgba(255,92,122,.45)}
.churn.sem_dado{color:var(--muted);background:rgba(255,255,255,.05);border:1px solid var(--line2)}
.act-lvl{display:inline-block;min-width:26px;text-align:center;font-weight:700;font-size:12px;padding:2px 7px;border-radius:7px}
.act-lvl.zero{color:var(--muted);background:rgba(255,255,255,.04)}
.act-lvl.baixo{color:#ffb454;background:rgba(255,180,84,.10)}
.act-lvl.medio{color:var(--blue);background:rgba(77,163,255,.10)}
.act-lvl.alto{color:var(--ok);background:rgba(60,220,150,.12)}
.mdl-use{font-size:12px}
.mdl-use.pin{color:var(--ink)}
.mdl-use.padrao{color:var(--muted)}

/* --- FICHA (prontuário) --- */
.st-modal{width:min(1180px,97vw)}
.st-tabs{display:flex;flex-wrap:wrap;gap:4px;padding:0 16px 10px;border-bottom:1px solid var(--line2)}
.st-tab{background:none;border:1px solid transparent;color:var(--muted);cursor:pointer;font-family:var(--b-sans);
  font-size:12.5px;padding:6px 12px;border-radius:8px}
.st-tab:hover{color:var(--ink);background:rgba(255,255,255,.04)}
.st-tab.active{color:var(--ink);background:rgba(77,163,255,.12);border-color:rgba(77,163,255,.35)}
.st-body{gap:14px}
.sf-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:12px}
.sf-card{background:rgba(255,255,255,.02);border:1px solid var(--line2);border-radius:12px;padding:14px 16px}
.sf-card + .sf-card{margin-top:12px}
.sf-card h4{margin:0 0 10px;font-size:12px;text-transform:uppercase;letter-spacing:1px;color:var(--muted);font-weight:600}
.sf-kv{display:flex;justify-content:space-between;align-items:baseline;gap:12px;padding:5px 0;border-bottom:1px solid var(--line);font-size:13px}
.sf-kv:last-child{border-bottom:none}
.sf-kv span{color:var(--muted)}
.sf-kv b{color:var(--ink);font-weight:600;text-align:right}
.sf-note{font-size:12px;line-height:1.55;color:var(--muted);margin-top:8px}
.sf-actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}
.sf-list{margin:8px 0 0;padding-left:20px;font-size:13px;color:var(--ink-dim)}
.sf-list li{margin-bottom:6px}
.sf-arq{margin-top:12px;padding-top:12px;border-top:1px solid var(--line2)}
.sf-arq h5{margin:0 0 6px;font-size:14px;color:var(--ink)}
/* evolução: entrada -> atual */
.sf-evo{display:flex;align-items:center;gap:18px;flex-wrap:wrap;margin-bottom:12px}
.sf-evo > div{text-align:center}
.sf-big{display:block;font-size:30px;font-weight:700;color:var(--ink);font-family:var(--h-sans)}
.sf-evo small{color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:1px}
.sf-arrow{font-size:22px;color:var(--muted)}
.sf-delta{font-size:18px;font-weight:700;padding:4px 12px;border-radius:999px}
.sf-delta.ok{color:var(--ok);background:rgba(60,220,150,.12)}
.sf-delta.off{color:var(--danger);background:rgba(255,92,122,.12)}
.sf-chart{display:flex;align-items:flex-end;gap:10px;height:120px;padding-top:8px}
.sf-bar{flex:1;max-width:70px;height:100%;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;gap:4px}
.sf-bar-fill{width:100%;background:linear-gradient(180deg,var(--blue),rgba(77,163,255,.25));border-radius:5px 5px 0 0;min-height:2px}
.sf-bar span{font-size:9.5px;color:var(--muted);white-space:nowrap}
/* visualizador de imagem dentro da ficha */
.sf-imgbox{margin-top:12px;padding-top:12px;border-top:1px solid var(--line2)}
.sf-imgcap{font-size:12px;color:var(--muted);margin-bottom:6px}
.sf-imgbox img{max-width:100%;border-radius:10px;border:1px solid var(--line2)}

/* GATE DE PAPEL — o `hidden` do applyRoleUI() tem que VALER, sempre.
   Armadilha real (pega na verificação ao vivo, e já registrada como pendência geral no CLAUDE.md):
   `[hidden]{display:none}` vem do user-agent e perde para QUALQUER seletor de classe que defina
   display — `.row{display:flex}` e `.btn{display:inline-flex}` são exatamente isso. Os primeiros
   `.master-only` do projeto eram `.panel`/`div` (que não definem display) e funcionaram por sorte;
   ao marcar `label.row` e `button.btn` na Config, o atributo passou a ser ignorado e o aluno seguia
   vendo TODOS os controles de voz.
   Escopado ao mecanismo do gate (não um `[hidden]` global, que mexeria em telas não auditadas):
   qualquer elemento marcado como exclusivo do master some de verdade quando o papel não bate. */
.master-only[hidden] { display: none !important; }

/* ===== CÔMODO MARKETING (crescimento e retenção — #asec-marketing) ===== */
/* Mesma armadilha do [hidden] do Financeiro: .admin-cards/.grid-2/.btn definem display e VENCEM o
   [hidden] do user-agent. Escopado ao cômodo (nunca um [hidden] global — telas não auditadas). */
#asec-marketing [hidden] { display: none !important; }
.mk-cards { grid-template-columns: repeat(5, 1fr); }
@media (max-width: 1280px) { .mk-cards { grid-template-columns: repeat(2, 1fr); } }
.mk-acard .acard-v { font-size: 20px; }
.mk-na { font-size: 12.5px; line-height: 1.4; display: inline-block; }
.mk-head { flex-wrap: wrap; gap: 8px; }
.mk-tabs { display: flex; gap: 6px; flex-wrap: wrap; }
.mk-tab.active { border-color: var(--acc, #5aa0ff); color: var(--fg, #dfe7f3); }
.mk-pane { display: none; }
.mk-pane.active { display: block; }
.mk-sub { font-size: 12px; margin-bottom: 14px; line-height: 1.6; }
.mk-h3 { font-family: var(--h-sans); font-size: 13px; font-weight: 600; margin: 22px 0 10px; letter-spacing: .3px; }
.mk-foot { font-size: 11.5px; line-height: 1.6; margin-top: 8px; }
.mk-tab-wrap { overflow-x: auto; }
.mk-tab { margin-top: 10px; }
#asec-marketing .bd-svg { width: 100%; height: auto; }
/* Funil: barra proporcional + a PERDA entre etapas (é a perda que ensina, não o total). */
.mk-funil { display: flex; flex-direction: column; gap: 10px; }
.mk-fun-row { display: grid; grid-template-columns: 260px 1fr 150px 120px; gap: 12px; align-items: center; }
@media (max-width: 1100px) { .mk-fun-row { grid-template-columns: 1fr; gap: 4px; } }
.mk-fun-l { font-size: 12.5px; }
.mk-fun-f { font-size: 10.5px; }
.mk-fun-bar { background: var(--panel2, #121a28); border: 1px solid var(--line, #22304a); border-radius: 8px; height: 18px; overflow: hidden; }
.mk-fun-bar span { display: block; height: 100%; background: linear-gradient(90deg, #4da3ff, #34e0c8); }
.mk-fun-n { font-size: 12.5px; }
.mk-fun-d { font-size: 11.5px; }
.mk-fun-d .bad { color: #ffb454; }
/* Eixo transversal (recência): visualmente SEPARADO do encaixe, para ninguém ler como degrau. */
.mk-fun-sep { font-size: 10.5px; color: var(--muted, #8a93a6); text-transform: uppercase; letter-spacing: 1px;
  margin-top: 14px; padding-top: 10px; border-top: 1px dashed var(--line2, #2b3a55); }
/* AMOSTRA INSUFICIENTE: o valor real fica visível, o badge diz que ele não é régua. Âmbar (o mesmo
   tom de alerta do .fin-delta.bad), nunca vermelho — não é erro, é limite de amostra. */
.mk-badge-amostra { display: inline-block; vertical-align: middle; margin-left: 8px; font-family: var(--b-sans);
  font-size: 10px; font-weight: 400; letter-spacing: .2px; text-transform: none; color: #ffb454;
  background: rgba(255, 180, 84, .10); border: 1px solid rgba(255, 180, 84, .35);
  border-radius: 999px; padding: 2px 8px; white-space: nowrap; }
.mk-fun-row.transversal .mk-fun-bar span { background: linear-gradient(90deg, #b388ff, #7CFFB2); opacity: .85; }

/* ===== CÔMODO FINANCEIRO (ERP da empresa — #asec-mrr) ===== */
/* A armadilha conhecida do [hidden]: .grid-2/.admin-cards definem display (grid) e VENCEM o
   [hidden] do user-agent. Escopado ao cômodo (não um [hidden] global — telas não auditadas). */
#asec-mrr [hidden] { display: none !important; }
.fin-cards { grid-template-columns: repeat(5, 1fr); }
@media (max-width: 1280px) { .fin-cards { grid-template-columns: repeat(2, 1fr); } }
.fin-acard .acard-v { font-size: 20px; }
.fin-delta { font-size: 11.5px; margin-top: 4px; }
.fin-delta.good { color: var(--ok, #39d98a); }
.fin-delta.bad { color: #ffb454; }
.fin-delta.flat { color: var(--muted, #8a93a6); }
.fin-sub { font-size: 11.5px; line-height: 1.5; margin-top: 6px; }
.fin-form { display: flex; flex-direction: column; gap: 8px; }
.fin-form input, .fin-form select, .fin-prop input, .fin-prop select {
  background: var(--bg2, #0e1420); color: var(--fg, #dfe7f3); border: 1px solid var(--line, #22304a);
  border-radius: 10px; padding: 8px 10px; font: inherit; font-size: 13px;
}
.fin-row-master { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.fin-scan-row { display: flex; gap: 8px; align-items: center; margin: 8px 0; flex-wrap: wrap; }
.fin-prop { display: grid; grid-template-columns: 110px 140px 1fr 200px auto; gap: 6px; margin: 8px 0; align-items: center; }
@media (max-width: 1100px) { .fin-prop { grid-template-columns: 1fr 1fr; } }
.fin-reemb-total { margin-bottom: 10px; }
.fin-reemb-socia { margin: 12px 0; }
.fin-reemb-head { margin-bottom: 6px; }
#finChartA .bd-svg, #finChartB svg, #finChartC .bd-svg { width: 100%; height: auto; }

/* ===== CÔMODO DE AUDITORIA (2026-07-19) ===== */
/* Armadilha .btn×[hidden] (classe define display e vence o user-agent) — fix ESCOPADO ao cômodo,
   mesmo precedente do .av-btns e do .master-only[hidden]. */
#asec-auditoria .btn[hidden] { display: none !important; }
.aud-head { flex-wrap: wrap; gap: 8px; }
.aud-tabs { display: flex; gap: 6px; flex-wrap: wrap; }
.aud-tab.active { border-color: var(--acc, #5aa0ff); color: var(--fg, #dfe7f3); }
.aud-pane { display: none; }
.aud-pane.active { display: block; }
.aud-sub { font-size: 12px; margin: 6px 0 10px; line-height: 1.5; }
.aud-filtros { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 8px; }
.aud-green { color: var(--ok, #39d98a); }
.aud-red, .aud-red-t { color: #ff6b6b; }
.aud-uncal { opacity: .8; }
.aud-badge { display: inline-block; margin-left: 8px; padding: 2px 8px; border-radius: 999px; background: rgba(255, 180, 84, .15); color: #ffb454; font-size: 11px; font-weight: 600; vertical-align: middle; cursor: help; }
.aud-uncal-note { border: 1px solid rgba(255, 180, 84, .4); background: rgba(255, 180, 84, .08); color: #ffb454; border-radius: 10px; padding: 8px 10px; font-size: 12px; margin-bottom: 10px; line-height: 1.5; }
.aud-run-row { display: flex; gap: 10px; align-items: center; margin-bottom: 10px; flex-wrap: wrap; }
.aud-verify { font-weight: 700; margin: 6px 0 10px; }
.aud-verify.ok { color: var(--ok, #39d98a); }
.aud-verify.bad { color: #ff6b6b; }
.aud-broken { font-size: 12px; color: #ff6b6b; margin-top: 8px; line-height: 1.6; }
.aud-h3 { font-size: 13px; margin: 14px 0 8px; }
.aud-kv { display: flex; flex-direction: column; gap: 6px; font-size: 12.5px; line-height: 1.5; }
.aud-sev { display: inline-block; padding: 1px 8px; border-radius: 999px; font-size: 11px; font-weight: 600; }
.aud-sev-critical { background: rgba(255, 107, 107, .16); color: #ff6b6b; }
.aud-sev-warn { background: rgba(255, 180, 84, .16); color: #ffb454; }
.aud-sev-info { background: rgba(138, 147, 166, .16); color: var(--muted, #8a93a6); }
.aud-sev-ok { background: rgba(57, 217, 138, .14); color: var(--ok, #39d98a); }

/* ===== CÔMODO GESTÃO DA IA (2026-07-19) — prateleiras A/B/C + HANDOFF do dock ===== */
/* Barra de persona do dock: diz QUAL criatura está ativa (copiloto de operação × Athena Master).
   ARMADILHA CONHECIDA do repo: classe que define display VENCE o [hidden] do user-agent — por isso
   os dois fixes escopados abaixo (mesmo precedente do #asec-mrr e do .av-btns). */
.persona-bar { display: flex; align-items: center; gap: 8px; padding: 6px 10px; border-bottom: 1px solid rgba(255, 255, 255, .06); background: rgba(84, 110, 255, .07); }
.persona-bar[hidden] { display: none !important; }
.persona-bar .btn[hidden] { display: none !important; }
.persona-label { font-size: 11.5px; font-weight: 700; letter-spacing: .4px; color: var(--acc, #7c9aff); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.persona-label.is-master-persona { color: #ffb454; }
#asec-gestao-ia .btn[hidden] { display: none !important; }
/* Listas de regra (protocolo global/pessoal, tools da Master, tarefas de modelo) */
.su-rules { display: flex; flex-direction: column; gap: 6px; margin-bottom: 8px; }
.su-rule { display: flex; align-items: baseline; gap: 8px; padding: 6px 10px; border: 1px solid rgba(255, 255, 255, .07); border-radius: 8px; font-size: 12.5px; line-height: 1.5; }
.su-rule .su-text { flex: 1; min-width: 0; }
.su-rule .su-meta { font-size: 11px; white-space: nowrap; }
.su-rule .su-del { flex: none; }
.ai-add-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 6px; }
.ai-add-row input, .ai-add-row select { flex: 1; min-width: 220px; background: rgba(255, 255, 255, .04); border: 1px solid rgba(255, 255, 255, .1); border-radius: 8px; color: inherit; padding: 7px 10px; font-size: 12.5px; }
.ai-master-grid { display: flex; gap: 18px; flex-wrap: wrap; font-size: 12.5px; }

/* ===== CÔMODO METODOLOGIA (cômodo 8, 2026-07-19) ===== */
.met-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.met-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin: 10px 0 12px; }
/* armadilha .btn×[hidden]: classe com display vence o [hidden] do user-agent — fix ESCOPADO (precedente avatares/financeiro) */
#asec-metodologia .btn[hidden] { display: none !important; }
#asec-metodologia .master-only[hidden] { display: none !important; }
.met-sec { margin: 14px 0; padding: 12px 14px; border: 1px solid rgba(255, 255, 255, .07); border-radius: 12px; background: rgba(255, 255, 255, .015); }
.met-sec h3 { font-size: 13px; margin: 0 0 8px; }
.met-sub { margin-top: 10px; padding-top: 8px; border-top: 1px dashed rgba(255, 255, 255, .08); font-size: 13px; }
.met-lock { font-size: 10.5px; color: var(--muted); border: 1px solid rgba(255, 255, 255, .14); border-radius: 999px; padding: 1px 8px; white-space: nowrap; }
.met-hot { font-size: 10.5px; color: var(--ok); border: 1px solid rgba(60, 220, 150, .35); border-radius: 999px; padding: 1px 8px; white-space: nowrap; }
.met-grp { font-size: 10px; color: var(--gold); border: 1px solid var(--line2); border-radius: 999px; padding: 0 6px; }
.met-draft { color: var(--gold); }
.met-dims td code, .met-sec code { font-family: var(--mono); font-size: 11.5px; }
.met-rub-dim { padding: 6px 0; border-bottom: 1px solid var(--line); font-size: 12.5px; }
.met-proto { white-space: pre-wrap; font-size: 12px; line-height: 1.55; font-family: var(--mono); background: rgba(0, 0, 0, .25); border: 1px solid var(--line2); border-radius: 8px; padding: 10px 12px; margin-top: 6px; max-height: 340px; overflow: auto; }
.met-json { width: 100%; min-height: 220px; max-height: 420px; background: rgba(0, 0, 0, .3); border: 1px solid var(--line2); border-radius: 8px; color: var(--ink); font-family: var(--mono); font-size: 11.5px; line-height: 1.5; padding: 8px 10px; margin-top: 6px; }
.met-bench-txt { min-height: 320px; }
/* editor de aula (overlay reusa .tx-overlay/.tx-modal) */
.met-ed-modal { width: min(1020px, 96vw); }
.met-ed-scroll { overflow: auto; max-height: calc(92vh - 90px); padding: 0 16px 16px; }
.met-ed-meta { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 8px 12px; margin-bottom: 10px; }
.met-ed-meta label { display: flex; flex-direction: column; gap: 3px; font-size: 11.5px; color: var(--muted); }
.met-ed-meta input { background: rgba(255, 255, 255, .04); border: 1px solid rgba(255, 255, 255, .1); border-radius: 8px; color: var(--ink); padding: 7px 10px; font-size: 12.5px; }
.met-ed-slide { border: 1px solid rgba(255, 255, 255, .09); border-radius: 10px; margin: 10px 0; padding: 10px 12px; background: rgba(255, 255, 255, .015); }
.met-ed-block { border-left: 2px solid rgba(255, 255, 255, .14); margin: 8px 0; padding: 6px 10px; }
.met-ed-block .med-bl-say { width: 100%; min-height: 56px; background: rgba(0, 0, 0, .25); border: 1px solid var(--line2); border-radius: 8px; color: var(--ink); font-size: 12.5px; line-height: 1.5; padding: 6px 9px; }
.met-ed-block .med-bl-json { min-height: 120px; }

/* ===== CÔMODO USUÁRIOS ADMINISTRATIVOS (2026-07-20) — visão do ADMIN DE TENANT (papel B) =====
   Gente de FORA: sem rail (não há navegação — o cômodo é único), sem chat/Athena (o backend nega o
   /api/chat de qualquer forma; aqui é só o espelho visual). O palco ocupa a tela toda.
   Regra por VARIÁVEL (não display) nas larguras: .stage lê --rail-w/--dock-w — zerar as duas
   reancora o palco sem tocar no layout base (mesma técnica do modo tablet). */
html.is-tenant-admin body { --rail-w: 0px; --dock-w: 0px; }
html.is-tenant-admin .rail { display: none; }
html.is-tenant-admin .chatdock { display: none; }
html.is-tenant-admin .topnav { display: none; }

/* Barra de cota do tenant (usada também com .warn >= 90%) */
.tn-quota-bar { height: 10px; border-radius: 6px; background: rgba(255, 255, 255, .07); overflow: hidden; border: 1px solid var(--line2); }
.tn-quota-fill { height: 100%; width: 0; border-radius: 6px; background: var(--ok, #35c48d); transition: width .3s ease; }
.tn-quota-fill.warn { background: #ffb454; }

/* Transcrição (painel simples do tenant; cada acesso é auditado no backend) */
.tn-tx { max-height: 46vh; overflow-y: auto; }
.tn-msg { border-left: 2px solid rgba(255, 255, 255, .14); margin: 8px 0; padding: 6px 10px; font-size: 12.5px; line-height: 1.5; white-space: pre-wrap; }
.tn-msg.tn-user { border-left-color: #5aa7ff; }
.tn-msg.tn-ai { border-left-color: rgba(255, 255, 255, .25); }

/* A armadilha conhecida `.btn` × [hidden] (display de classe vence o user-agent): fix escopado ao
   cômodo, como nos precedentes (#asec-mrr, .av-btns, #asec-auditoria). */
#asec-usuarios-admin .btn[hidden], #view-tenant .btn[hidden] { display: none !important; }
#tenPanel[hidden] { display: none !important; }

/* ===== ARQUIVINHO DE INFORMAÇÕES E DECISÕES (4ª aba da Aula ao vivo — só leitura + correção) ===== */
.dec-list { max-width: 860px; margin: 0 auto; display: flex; flex-direction: column; gap: 10px; }
.dec-head { color: var(--muted); font-size: 13px; padding: 2px 2px 6px; border-bottom: 1px solid var(--line); }
.dec-frio-head { margin-top: 18px; }
.dec-item { display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel); }
.dec-main { flex: 1; min-width: 0; }
.dec-text { font-size: 14px; }
.dec-meta { color: var(--muted); font-size: 12px; margin-top: 4px; }
.dec-chip { display: inline-block; font-size: 10px; font-weight: 700; letter-spacing: .4px; padding: 2px 7px; border-radius: 999px; margin-right: 6px; vertical-align: middle; }
.dec-chip.dec-dec { background: rgba(122, 92, 255, .18); color: #b39dff; border: 1px solid rgba(122, 92, 255, .4); }
.dec-chip.dec-info { background: rgba(64, 160, 255, .14); color: #7fbcff; border: 1px solid rgba(64, 160, 255, .35); }
.dec-item.dec-frio { opacity: .55; }
.dec-rm { flex-shrink: 0; }

/* ===== PREMISSAS DE PREÇO (cômodo Financeiro) — a premissa sempre ao lado do custo ===== */
#finPrecosPanel .pb-h3 { font-size: 13px; margin: 16px 0 8px; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
#finPrecosPanel .pb-selo { font-size: 10px; padding: 1px 6px; border-radius: 999px; white-space: nowrap; }
#finPrecosPanel .pb-selo.def  { background: rgba(155,176,214,.14); color: var(--muted); }
#finPrecosPanel .pb-selo.edit { background: rgba(59,224,160,.15); color: #3be0a0; }
#finPrecosPanel .pb-selo.pend { background: rgba(255,180,84,.18); color: #ffb454; }
#finPrecosPanel .pb-val { white-space: nowrap; }
#finPrecosPanel .pb-premissa { font-size: 12px; color: var(--muted); }
#finPrecosPanel .pb-row-pend td { background: rgba(255,180,84,.06); }
#finPrecosPanel .pb-alert { border: 1px solid #ffb454; background: rgba(255,180,84,.08); border-radius: 8px; padding: 10px 14px; margin-bottom: 12px; font-size: 13px; }
#finPrecosPanel .pb-alert ul, #finPrecosPanel .pb-divida ul { margin: 6px 0 0; padding-left: 18px; }
#finPrecosPanel .pb-divida { border: 1px dashed rgba(155,176,214,.35); border-radius: 8px; padding: 10px 14px; margin-bottom: 12px; font-size: 12px; }
#finPrecosPanel .pb-nm { color: #ffb454; font-weight: 600; }
.pb-chain { font-size: 12px; }
.pb-chain.ok { color: #3be0a0; }
.pb-chain.bad { color: #ff6b85; font-weight: 700; }
/* armadilha conhecida: .btn tem display:inline-flex (classe) e vence o [hidden] do user-agent */
#finPrecosPanel .btn[hidden] { display: none !important; }

/* ===== CONSUMO BT/BVT: pills do cabeçalho + seção Consumo + painel do tenant ===== */
.chip.cn-pill { cursor: pointer; }
.chip.cn-pill.laranja .dot { background: #ffb454; }
.chip.cn-pill.laranja { border-color: rgba(255,180,84,.5); color: #ffb454; }
.chip.cn-pill.vermelho .dot { background: #ff6b85; }
.chip.cn-pill.vermelho { border-color: rgba(255,107,133,.6); color: #ff6b85; font-weight: 600; }
.cn-grupo { margin-bottom: 14px; }
.cn-grupo h4 { font-size: 13px; margin: 0 0 6px; }
.cn-linha { display: grid; grid-template-columns: 130px 1fr 64px; align-items: center; gap: 10px; margin: 4px 0; font-size: 12px; }
.cn-bar { height: 8px; border-radius: 999px; background: rgba(155,176,214,.16); overflow: hidden; }
.cn-fill { height: 100%; background: var(--ok, #3be0a0); }
.cn-fill.laranja { background: #ffb454; }
.cn-fill.vermelho { background: #ff6b85; }
.cn-num { text-align: right; font-variant-numeric: tabular-nums; }
.cn-num.laranja, td.laranja { color: #ffb454; }
.cn-num.vermelho, td.vermelho { color: #ff6b85; font-weight: 600; }
.cn-drill { margin: 8px 0; font-size: 12px; }
.cn-hist { margin: 6px 0 0; padding-left: 18px; }
.cn-continuar { margin-top: 12px; padding-top: 10px; border-top: 1px solid rgba(155,176,214,.18); }
.cn-agregado { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.cn-card { border: 1px solid rgba(155,176,214,.22); border-radius: 10px; padding: 10px 14px; min-width: 150px; }
.cn-card-t { font-size: 12px; color: var(--muted); }
.cn-card-v { font-size: 22px; font-weight: 700; }
.cn-setup { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; margin: 10px 0; font-size: 12px; }
.cn-setup label { display: flex; flex-direction: column; gap: 4px; }
.cn-fila { border: 1px solid rgba(255,180,84,.4); background: rgba(255,180,84,.06); border-radius: 8px; padding: 10px 14px; margin: 10px 0; font-size: 13px; }
.cn-pedido { display: flex; gap: 8px; align-items: center; margin-top: 6px; }
#tnConsumoPanel .btn[hidden], #consumoPanel .btn[hidden] { display: none !important; }

/* ===== PACOTES DE EXCEDENTE (2026-08-06) — a unidade de venda, nunca token solto =====
   Dois botões (~1h e ~5h). O preço só aparece para B2C: o aluno de licença SOLICITA, não compra. */
.cn-pacotes { display: flex; gap: 10px; flex-wrap: wrap; }
.cn-pacote-btn { display: inline-flex; flex-direction: column; align-items: flex-start; gap: 2px;
  text-align: left; padding: 8px 14px; line-height: 1.3; }
.cn-pacote-btn b { font-weight: 700; }
/* Banco vazio NÃO desabilita o botão — o aluno nunca é bloqueado. O aviso só antecipa o que vai
   acontecer (o pedido fica aguardando), para a tela não prometer crédito que não vem. */
.cn-aguarda { font-size: 11px; color: var(--muted); font-weight: 400; }
/* Saldo do banco por TIPO, na tela do gestor (só leitura — o cadastro é master-only). */
.cn-banco { margin: 10px 0; }
.cn-pk-grid { display: flex; gap: 12px; flex-wrap: wrap; }
.cn-pk { border: 1px solid rgba(155,176,214,.22); border-radius: 10px; padding: 10px 14px; min-width: 160px; }
.cn-pk.vazio { border-color: rgba(255,180,84,.45); background: rgba(255,180,84,.06); }
.cn-pk-t { font-size: 12px; color: var(--muted); }
.cn-pk-v { font-size: 22px; font-weight: 700; }
/* Solicitação que o gestor não consegue aprovar por falta de saldo daquele tipo. */
.cn-pedido.sem-saldo { opacity: .85; }
.cn-pedido button[disabled] { opacity: .45; cursor: not-allowed; }


/* ===== ANÉIS DE CONSUMO (painel do aluno) =====
   CORES: puxadas dos MESMOS tokens do Gantt do Dashboard, para as duas telas lerem como um sistema só.
     --cn-ok    = .blk.done  (#3be0a0)  -> normal/calmo
     --cn-warn  = .blk.now   (#ffc24d)  -> alerta 75–99%
     --cn-out   = .blk.late  (#ff6b85)  -> esgotado 100%
     --cn-track = .blk.plan  (#46506a)  -> trilho do anel (o "previsto" do Gantt)
   Nenhum hexadecimal novo: os quatro valores são os que style.css já usa nos blocos (linhas .blk.*). */
#consumoPanel {
  --cn-ok: #3be0a0; --cn-warn: #ffc24d; --cn-out: #ff6b85; --cn-track: #46506a;
}
#consumoPanel .cn-pill-cal { font-size: 11px; color: var(--cn-warn); border: 1px solid rgba(255,194,77,.35);
  background: rgba(255,194,77,.10); border-radius: 999px; padding: 2px 10px; white-space: nowrap; }
#consumoPanel .cn-pill-cal:empty { display: none; }

.cn-cards { display: flex; gap: 16px; flex-wrap: wrap; margin: 6px 0 4px; }
.cn-card { flex: 1 1 200px; min-width: 190px; border: 1px solid rgba(155,176,214,.18); border-radius: 14px;
  padding: 14px 12px 12px; background: rgba(155,176,214,.04); }
.cn-card h4 { margin: 0 0 10px; font-size: 12px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); text-align: center; font-weight: 600; }
.cn-card-rings { display: flex; gap: 14px; justify-content: center; }

.cn-ring { position: relative; width: 92px; text-align: center; }
.cn-ring svg { width: 92px; height: 92px; transform: rotate(-90deg); display: block; }
.cn-ring-track { fill: none; stroke: var(--cn-track); stroke-width: 7; opacity: .55; }
.cn-ring-arc { fill: none; stroke-width: 7; stroke-linecap: round; stroke: var(--cn-ok);
  transition: stroke-dasharray .6s cubic-bezier(.22,.9,.3,1), stroke .3s ease; }
.cn-ring.warn .cn-ring-arc { stroke: var(--cn-warn); }
.cn-ring.out  .cn-ring-arc { stroke: var(--cn-out); }
.cn-ring.out svg { filter: drop-shadow(0 0 6px rgba(255,107,133,.45)); }

/* percentual GRANDE no centro do arco */
.cn-ring-txt { position: absolute; top: 46px; left: 0; right: 0; transform: translateY(-50%);
  font-size: 21px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--text, #e8eefc);
  pointer-events: none; letter-spacing: -.02em; }
.cn-ring-txt.out { font-size: 13px; color: var(--cn-out); letter-spacing: 0; }
.cn-ring.warn .cn-ring-txt { color: var(--cn-warn); }
/* rótulo do ANEL = só o TIPO (Texto/Voz). A janela é o título do CARTÃO — nunca se repete aqui. */
.cn-ring-lbl { margin-top: 2px; font-size: 12px; color: var(--muted); }

.cn-legenda { font-size: 11px; color: var(--muted); margin: 10px 0 2px; opacity: .85; }

@media (max-width: 720px) {
  .cn-cards { gap: 12px; }
  .cn-card { flex: 1 1 100%; }
  .cn-ring, .cn-ring svg { width: 84px; }
  .cn-ring svg { height: 84px; }
  .cn-ring-txt { top: 42px; font-size: 19px; }
}

/* ===== NOME DE TRATAMENTO — padrão "editável × travado" (design system §2.6 + adendo DELTA 1, 2026-07-31).
   Campo EDITÁVEL = hairline + ícone de lápis (o aluno vê que é dele para mexer); valor TRAVADO = fundo
   liso que NÃO parece input + cadeado + legenda de apoio dizendo DE ONDE deriva ("chave de acesso —
   definida no cadastro/contrato da empresa", preenchida por setupNamePanel conforme ME.access).
   ESCOPADO ao #namePanel de propósito — não é um passe global de tokens (a adoção da régua completa do
   design system é projeto próprio; aqui entra só o par lápis/cadeado que o adendo manda). */
#namePanel .fld-edit{position:relative;flex:1;display:flex;align-items:center;max-width:420px}
#namePanel .fld-edit input{flex:1;min-width:0;background:rgba(0,0,0,.3);border:1px solid var(--line);border-radius:10px;padding:9px 34px 9px 12px;color:var(--ink);font-size:13.5px;font-family:var(--b-sans)}
#namePanel .fld-edit input:focus{outline:none;border-color:var(--line2)}
#namePanel .fld-pencil{position:absolute;right:11px;color:var(--ink-dim);font-size:13px;pointer-events:none}
#namePanel .fld-locked{display:inline-flex;align-items:baseline;gap:7px;color:var(--ink);font-size:13px;background:none;border:none;flex-wrap:wrap}
#namePanel .fld-lock{font-size:12px;opacity:.75}
#namePanel .fld-key{color:var(--muted);font-size:11.5px}

/* ===== Checkpoint: estado de PROCESSAMENTO visível (fase enfileirado/processando) =====
   Três pontinhos mudos leem como travado. O indicador de movimento é o que diz "está trabalhando":
   spinner ao lado do texto + barra indeterminada no rodapé do card. */
.ckp-spinner{width:22px;height:22px;flex:0 0 auto;border-radius:50%;
  border:2.5px solid var(--line2,#2a3550);border-top-color:var(--blue,#7cc4ff);
  animation:ckpSpin .9s linear infinite}
@keyframes ckpSpin{to{transform:rotate(360deg)}}
.ckp-barra{height:3px;margin-top:12px;border-radius:3px;overflow:hidden;background:var(--line2,#2a3550)}
.ckp-barra > i{display:block;height:100%;width:38%;border-radius:3px;background:var(--blue,#7cc4ff);
  animation:ckpBarra 1.5s ease-in-out infinite}
@keyframes ckpBarra{0%{margin-left:-40%}100%{margin-left:100%}}
.ckp-panel.ckp-trabalhando .ckp-titulo{color:var(--blue,#7cc4ff)}
.ckp-panel.ckp-erro{border-color:var(--danger,#ff6b85)}
.ckp-panel.ckp-erro .ckp-titulo{color:var(--danger,#ff6b85)}
/* Respeita quem pediu menos movimento: o estado continua legível pelo texto e pela cor. */
@media (prefers-reduced-motion: reduce){
  .ckp-spinner,.ckp-barra > i{animation:none}
  .ckp-barra > i{width:100%;opacity:.5}
}

/* Barra DETERMINADA do checkpoint: largura = páginas mineradas / total (fato consumado).
   A transição suaviza o salto entre batidas do polling; ela NUNCA anima sozinha para a frente —
   uma barra que anda sem página nova seria previsão de tempo disfarçada. */
.ckp-barra.ckp-barra-det > i{width:0;animation:none;margin-left:0;transition:width .4s ease}
.ckp-pct{margin-top:5px;font-size:11.5px;color:var(--muted);font-variant-numeric:tabular-nums;text-align:right}

/* ===== Pílula de STATUS do checkpoint (chat) =====
   NÃO é chip: sem borda, sem fundo, sem raio de botão. É uma LINHA DE TEXTO neutra com uma barra fina.
   `pointer-events:none` é a garantia dura de que nenhum clique encontra alvo aqui — o furo era a pílula
   de ferramenta parecer um botão clicável com o NOME de uma ação de bastidor dentro. */
.ckps{align-self:flex-start;max-width:92%;margin:2px 0 6px;padding:0 2px;
  font-size:12px;color:var(--muted);background:none;border:none;border-radius:0;
  pointer-events:none;user-select:text;cursor:default}
.ckps.ok{color:var(--ok)}
.ckps-barra{height:3px;margin-top:6px;border-radius:3px;overflow:hidden;background:var(--line2,#2a3550);width:230px}
.ckps-barra > i{display:block;height:100%;border-radius:3px;background:var(--blue,#7cc4ff);
  width:0;transition:width .4s ease}

/* ===== Ingestão de artefato (topo da Metodologia) ===== */
.mi-form{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-top:8px}
.mi-form input[type=text],.mi-form select{background:var(--bg-3,#0d1526);border:1px solid var(--line-1,#233048);color:var(--text-1,#eaf2ff);border-radius:8px;padding:7px 10px;font-size:13px}
.mi-err{border:1px solid var(--crit,#f26d6d);border-radius:8px;padding:8px 10px;margin-top:10px;font-size:13px}
.mi-err ul{margin:6px 0 0 18px}
.mi-pend{margin-top:8px;font-size:13px;display:flex;gap:6px;flex-wrap:wrap;align-items:center}
.mi-plan{border:1px solid var(--line-1,#233048);border-radius:10px;padding:10px 12px;margin-top:10px}
.mi-plan-sum{font-size:12.5px;color:var(--text-3,#9bb0d6);margin-top:4px}
.mi-apos{margin-top:10px}
.mi-apos-item{border-top:1px dashed var(--line-1,#233048);padding:8px 0}
.mi-apos-item.rev{opacity:.85}
.mi-rev-badge{color:var(--warn,#ffb454);font-weight:600}
.mi-ok{color:var(--ok,#59e0a0);margin-top:10px;font-weight:600}
.mi-efeitos{margin-top:8px;font-size:13px}
.mi-efeitos ul{margin:6px 0 0 18px}
#metIngestPanel[hidden]{display:none!important} /* armadilha .panel×[hidden] já conhecida — fix escopado */

/* ===== Versões da régua no store (topo da constituição) ===== */
.met-store{border:1px solid var(--line-1,#233048);border-radius:10px;padding:10px 12px;margin-bottom:14px}
.met-store>h3{margin:0 0 4px;font-size:14px}
.met-lin{margin-top:10px}
.met-lin-head{font-size:12.5px;padding-bottom:4px;border-bottom:1px solid var(--line-1,#233048)}
.met-ver{border-left:3px solid var(--line-1,#233048);padding:8px 0 8px 10px;margin-top:8px}
.met-ver.vigente{border-left-color:var(--ok,#59e0a0)}
.met-ver.congelada-de-coorte{border-left-color:var(--warn,#ffb454)}
.met-ver-top{display:flex;gap:8px;align-items:center;flex-wrap:wrap;font-size:13px}
.met-ver-ref{font-weight:600}
.met-ver-badge{font-size:10.5px;font-weight:700;letter-spacing:.04em;padding:2px 7px;border-radius:999px;border:1px solid currentColor}
.met-ver-badge.ok{color:var(--ok,#59e0a0)}
.met-ver-badge.warn{color:var(--warn,#ffb454)}
.met-ver-badge.off{color:var(--text-3,#9bb0d6)}
.met-ver-datas{font-size:12.5px;color:var(--text-2,#c3d3ee);margin-top:2px}
.met-ver-anula{font-size:12px;color:var(--warn,#ffb454);margin-top:2px}
.met-ver-anexo{margin-top:6px;font-size:12.5px;border-top:1px dashed var(--line-1,#233048);padding-top:6px}
.met-ver-link{font-size:12px;margin-bottom:8px}

/* ===== CÔMODO METODOLOGIA — navegação interna (2026-08-08) =====================================
   ⚠️ TUDO AQUI É ESCOPADO A `#asec-metodologia`. Não existe uma linha que alcance o trilho de cômodos
   (`nav.rail`, o menu EXTERNO do Master) nem o dock da direita (`.chatdock`) — são superfícies de
   outra frente e ficam intocadas.
   A coluna da esquerda é obtida por GRID no próprio cômodo: nenhum painel foi reparentado (o requisito
   "não mover DOM"). Cabeçalho e cartões atravessam as duas colunas; a nav ocupa a coluna 1 e todo o
   resto cai na coluna 2 — como só um bloco fica visível por vez (hidden alternado), o painel aberto
   assenta ao lado da nav. */
#asec-metodologia.active{display:grid;grid-template-columns:216px minmax(0,1fr);gap:0 18px;align-items:start;animation:fade .2s ease}
#asec-metodologia > .room-head,
#asec-metodologia > .admin-cards{grid-column:1 / -1}
#asec-metodologia > .met-nav{grid-column:1;position:sticky;top:12px}
/* Todo painel/overlay do cômodo vive na coluna do conteúdo. O overlay é position:fixed — não ocupa
   célula de grid, então a regra é inofensiva para ele. */
#asec-metodologia > .panel,
#asec-metodologia > .tx-overlay{grid-column:2}
@media(max-width:900px){
  #asec-metodologia.active{grid-template-columns:1fr}
  #asec-metodologia > .met-nav{grid-column:1;position:static}
  #asec-metodologia > .panel,#asec-metodologia > .tx-overlay{grid-column:1}
}
/* A barra de ABAS some: quem navega agora é a coluna. A fiação continua viva (setMetPane/deep-links) —
   é só a superfície que muda; por isso `#metTabs` é escondido em vez de removido. */
#asec-metodologia #metTabs{display:none}
/* Botões da navegação interna (padrão do trilho: ícone + rótulo, ativo com barra ciano à esquerda). */
#asec-metodologia .bzn-cab{font-size:10px;letter-spacing:.12em;color:var(--text-3,#5f7396);text-transform:uppercase;margin:12px 8px 6px;font-weight:700}
#asec-metodologia .bzn-cab:first-child{margin-top:0}
#asec-metodologia .bzn-b{display:flex;align-items:center;gap:10px;width:100%;padding:10px 12px;margin:3px 0;border:1px solid transparent;border-radius:10px;background:none;color:var(--text-2,#9bb0d6);font:600 13px var(--font-ui,Inter),system-ui,sans-serif;cursor:pointer;text-align:left}
#asec-metodologia .bzn-b:hover{background:var(--bg-2,#101a2e)}
#asec-metodologia .bzn-b.on{background:var(--bg-3,#16233c);border-color:var(--line-1,#233048);color:var(--text-1,#eaf2ff);box-shadow:inset 3px 0 0 var(--ciano,#39d5ff)}
#asec-metodologia .bzn-ico{width:20px;text-align:center;font-size:15px;flex:none}
#asec-metodologia .bzn-l{flex:1;min-width:0}
#asec-metodologia .bzn-badge{font:700 10px var(--font-ui,Inter),system-ui,sans-serif;background:var(--warn,#ffb454);color:#1a1205;border-radius:8px;padding:1px 7px;flex:none}
/* FAIXA DE AÇÕES: escrita nunca se mistura com leitura — âmbar tracejado, no topo do bloco.
   `:empty` some para um bloco de leitura pura não exibir uma faixa vazia. */
#asec-metodologia .met-actions{display:flex;flex-wrap:wrap;gap:8px;align-items:center;padding:10px 12px;margin-bottom:14px;background:var(--bg-2,#101a2e);border:1px dashed var(--line-1,#233048);border-radius:10px}
#asec-metodologia .met-actions:empty{display:none}
#asec-metodologia .met-actions::before{content:'AÇÕES';font:700 10px var(--font-ui,Inter),system-ui,sans-serif;letter-spacing:.1em;color:var(--warn,#ffb454)}
/* Estado do currículo: um cartão por TRILHA; a vigente em destaque e os legados numa LISTA QUE ROLA
   dentro do cartão — 10 versões numa trilha não podem empilhar 10 cartões e enterrar a tela. */
#asec-metodologia .met-trilhas{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:14px}
#asec-metodologia .met-tcard{background:var(--bg-2,#101a2e);border:1px solid var(--line-1,#233048);border-radius:12px;padding:14px 16px}
#asec-metodologia .met-tcard h4{margin:0 0 8px;font-size:13.5px;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
#asec-metodologia .met-vig{border-left:3px solid var(--ok,#3ddc97);padding-left:10px;margin-bottom:8px}
#asec-metodologia .met-legados{max-height:214px;overflow:auto;display:flex;flex-direction:column;gap:6px;padding-right:4px}
#asec-metodologia .met-legb{display:flex;align-items:center;gap:8px;width:100%;text-align:left;padding:8px 10px;border:1px solid var(--line-1,#233048);border-left:3px solid var(--warn,#ffb454);border-radius:8px;background:var(--bg-3,#16233c);color:var(--text-1,#eaf2ff);font:500 12.5px var(--font-ui,Inter),system-ui,sans-serif;cursor:pointer}
#asec-metodologia .met-legb:hover{border-color:var(--ciano,#39d5ff)}
#asec-metodologia .met-legb .ref{font-family:var(--font-mono,'JetBrains Mono'),monospace;font-size:11.5px;color:var(--ciano,#39d5ff);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#asec-metodologia .met-legb .qtd{font:700 12px var(--font-mono,'JetBrains Mono'),monospace;flex:none}
#asec-metodologia .met-legb .qtd.zero{color:var(--text-3,#5f7396);font-weight:500}
#asec-metodologia .met-cnt{font-size:11.5px;color:var(--text-3,#5f7396)}
/* Coortes: tabela enxuta; a lista NOMINAL é consulta e abre em pop-up. */
#asec-metodologia .met-coo{width:100%;border-collapse:collapse;font-size:12.5px}
#asec-metodologia .met-coo th{text-align:left;font-size:10px;letter-spacing:.1em;color:var(--text-3,#5f7396);text-transform:uppercase;padding:6px 8px;border-bottom:1px solid var(--line-1,#233048)}
#asec-metodologia .met-coo td{padding:7px 8px;border-bottom:1px solid var(--line-1,#233048)}

/* ===== FASE 4 — PAINEL DE PROGRESSO DA GERAÇÃO DE AULAS (#lessonGenPanel) =====
   Mesma linguagem visual do card de checkpoint do aluno (spinner + barra determinada + % tabular),
   com classes PRÓPRIAS: as `.ckp-*` vivem no painel do ALUNO, e acoplar duas superfícies sem relação
   faria uma mudança de lá quebrar aqui em silêncio.
   A barra NUNCA anima sozinha para a frente — só a `transition` suaviza o salto entre batidas do
   polling. Uma barra que anda sem aula nova seria previsão de tempo disfarçada (é a mesma regra dura
   que o checkpoint já carrega). */
#asec-metodologia .lg-corrida{border:1px solid var(--line-1,#233048);border-radius:10px;padding:12px 14px;margin-top:8px;background:var(--bg-2,#101A2E)}
#asec-metodologia .lg-corrida.lg-trabalhando{border-color:var(--blue,#7cc4ff)}
#asec-metodologia .lg-corrida.lg-erro{border-color:var(--danger,#ff6b85)}
#asec-metodologia .lg-head{display:flex;align-items:center;gap:10px}
#asec-metodologia .lg-titulo{font-weight:600}
#asec-metodologia .lg-corrida.lg-trabalhando .lg-titulo{color:var(--blue,#7cc4ff)}
#asec-metodologia .lg-corrida.lg-erro .lg-titulo{color:var(--danger,#ff6b85)}
#asec-metodologia .lg-ajuda{font-size:12px;color:var(--muted);margin-top:2px}
#asec-metodologia .lg-spinner{width:18px;height:18px;flex:0 0 auto;border-radius:50%;
  border:2.5px solid var(--line2,#2a3550);border-top-color:var(--blue,#7cc4ff);animation:lgSpin .9s linear infinite}
@keyframes lgSpin{to{transform:rotate(360deg)}}
#asec-metodologia .lg-barra{height:6px;margin-top:12px;border-radius:3px;overflow:hidden;background:var(--line2,#2a3550)}
#asec-metodologia .lg-barra > i{display:block;height:100%;width:38%;border-radius:3px;background:var(--blue,#7cc4ff);
  animation:lgBarra 1.5s ease-in-out infinite}
@keyframes lgBarra{0%{margin-left:-40%}100%{margin-left:100%}}
#asec-metodologia .lg-barra.lg-det > i{width:0;animation:none;margin-left:0;transition:width .4s ease}
#asec-metodologia .lg-nums{display:flex;flex-wrap:wrap;gap:14px;margin-top:8px;font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}
#asec-metodologia .lg-nums b{color:var(--text-1,#EAF2FF);font-weight:600}
#asec-metodologia .lg-pct{font-variant-numeric:tabular-nums;font-weight:600;color:var(--text-1,#EAF2FF)}
#asec-metodologia .lg-acoes{display:flex;gap:8px;margin-top:12px;flex-wrap:wrap}
/* Ausência/estimativa: itálico apagado — NUNCA a fonte de display de um número medido. */
#asec-metodologia .lg-na{font-style:italic;color:var(--text-3,#5f7396)}
#asec-metodologia .lg-dims{margin-top:10px;max-height:210px;overflow:auto;border-top:1px solid var(--line-1,#233048)}
#asec-metodologia .lg-dim{display:flex;align-items:center;gap:8px;padding:5px 2px;font-size:12px;border-bottom:1px solid var(--line-1,#233048)}
#asec-metodologia .lg-dim .lg-dnome{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#asec-metodologia .lg-badge{font-size:10px;letter-spacing:.06em;text-transform:uppercase;padding:2px 6px;border-radius:4px;border:1px solid var(--line-1,#233048);color:var(--text-3,#5f7396)}
#asec-metodologia .lg-badge.ok{color:var(--ok,#3bd6a0);border-color:var(--ok,#3bd6a0)}
#asec-metodologia .lg-badge.run{color:var(--blue,#7cc4ff);border-color:var(--blue,#7cc4ff)}
#asec-metodologia .lg-badge.err{color:var(--danger,#ff6b85);border-color:var(--danger,#ff6b85)}
#asec-metodologia .lg-alvo{display:flex;align-items:center;gap:10px;padding:7px 2px;border-bottom:1px solid var(--line-1,#233048);font-size:12.5px}
#asec-metodologia .lg-alvo .lg-anome{flex:1;min-width:0}
#asec-metodologia .lg-alvo .lg-impedida{color:var(--danger,#ff6b85);font-size:11.5px}
/* PLACAR VIVO da geração — aula por aula, com os dois portões AUTOMÁTICOS (construída / validada).
   O cheque apagado (○) e o aceso (✓) têm de ser distinguíveis à distância: o apagado usa o texto de
   menor hierarquia, o aceso ganha cor semântica. Ausência nunca usa a mesma tinta do fato. */
#asec-metodologia .lg-aulas{margin-top:10px;max-height:340px;overflow:auto}
#asec-metodologia .lg-aula{display:flex;align-items:center;flex-wrap:wrap;gap:8px;padding:6px 2px;font-size:12px;border-bottom:1px solid var(--line-1,#233048)}
#asec-metodologia .lg-aula .lg-anome2{flex:1;min-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-3,#5f7396)}
#asec-metodologia .lg-aula.run .lg-anome2,#asec-metodologia .lg-aula.ok .lg-anome2{color:var(--text-1,#eaf2ff)}
#asec-metodologia .lg-aula.err .lg-anome2{color:var(--danger,#ff6b85)}
#asec-metodologia .lg-gate{font-size:10.5px;padding:1px 6px;border-radius:4px;border:1px dashed var(--line-1,#233048);color:var(--text-3,#5f7396)}
#asec-metodologia .lg-gate.on{border-style:solid;border-color:var(--ok,#3bd6a0);color:var(--ok,#3bd6a0)}
#asec-metodologia .lg-afalha{flex-basis:100%;font-size:11.5px;color:var(--danger,#ff6b85)}
#asec-metodologia .lg-alarme{margin:10px 0;padding:8px 10px;border-radius:6px;font-size:12px;
  border:1px solid var(--warn,#ffb454);color:var(--warn,#ffb454);background:rgba(255,180,84,.08)}
#asec-metodologia .lg-placar{margin:10px 0;padding:10px;border-radius:6px;border:1px solid var(--line-1,#233048)}
#asec-metodologia .lg-placar.atencao{border-color:var(--warn,#ffb454);background:rgba(255,180,84,.06)}
#asec-metodologia .lg-placar.atencao .lg-titulo{color:var(--warn,#ffb454)}
#asec-metodologia .lg-placar.completo{border-color:var(--ok,#3bd6a0)}
#asec-metodologia .lg-placar.completo .lg-titulo{color:var(--ok,#3bd6a0)}
#asec-metodologia .lg-falhas{margin-top:8px;font-size:11.5px}
/* A armadilha [hidden] × display: `.btn` é classe (0-1-0) e vence o [hidden] do user-agent. */
#asec-metodologia .lg-acoes .btn[hidden],#asec-metodologia .lg-alvo .btn[hidden]{display:none!important}
@media (prefers-reduced-motion: reduce){
  #asec-metodologia .lg-spinner,#asec-metodologia .lg-barra > i{animation:none}
  #asec-metodologia .lg-barra > i{width:100%;opacity:.5}
  #asec-metodologia .lg-barra.lg-det > i{width:0;opacity:1}
}
