
  :root{
    --ink:#3B2A1A;
    --paper:#FFF4E2;
    --laranja:#F97316;  --laranja-soft:#FFE3C7;
    --azul:#2F7DE1;     --azul-soft:#D9E9FF;
    --verde:#1F9D55;    --verde-soft:#D8F3E1;
    --vermelho:#E5484D; --vermelho-soft:#FFDFDF;
    --roxo:#8B5CF6;     --roxo-soft:#EBE1FF;
    --teal:#0FA3A3;     --teal-soft:#D3F4F1;
    --rosa:#D946EF;     --rosa-soft:#FBE2FF;
  }
  /* MOVIMENTO: por que cada bloco "sem animacao" aparece DUAS vezes.
     O padrao e obedecer ao sistema, e a media query sozinha ja faz isso. Mas
     a ajuda do mapa tem um botao "Movimento" que precisa VENCER o sistema nos
     dois sentidos (ver setMotionPref/prefersReducedMotion no map-engine.js), e
     `@media (prefers-reduced-motion)` nao enxerga localStorage. Entao o JS
     publica a escolha explicita em <html data-motion="full|reduced"> e cada
     regra de reducao vira um par:
       @media (prefers-reduced-motion:reduce){ :root:not([data-motion=full]) X }
       :root[data-motion=reduced] X
     Sem o par, quem tem "efeitos de animacao" desligados no Windows ficava sem
     o giro dos flashcards mesmo depois de ligar o Movimento na ajuda - o
     ajuste do app so alcancava as animacoes feitas em JS (ago/2026).
     Ao criar uma animacao nova, escreva as DUAS linhas. */
  *{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
  html,body{height:100%}
  body{
    font-family:'Nunito',sans-serif;color:var(--ink);
    background:var(--paper);
    display:flex;flex-direction:column;overflow:hidden;
  }
  /* No celular, `height:100%` mede o viewport GRANDE (o de barra de endereco
     recolhida), e como a barra costuma estar visivel o rodape do app fica
     cortado: no painel lateral era justamente o fim da lei seca que sumia.
     `dvh` mede o que esta de fato na tela. Declaracao separada de proposito:
     navegador sem suporte a dvh descarta esta linha e fica com o 100% acima.
     Nao ha risco de oscilar junto com a barra de endereco (o que dispararia
     `resize` e um reenquadramento do mapa a cada quadro): o documento tem
     `overflow:hidden` e o canvas usa `touch-action:none`, entao nao existe
     rolagem de pagina para recolher barra nenhuma. */
  body{height:100dvh}
  /* quanto do fundo da janela o teclado virtual esta cobrindo. Fica em zero no
     desktop e enquanto o teclado nao sobe; quem mede e publica e o modulo do
     teclado virtual em map-engine.js */
  :root{--kb-inset:0px}

  /* Barra de rolagem fina e discreta nas areas que rolam (canvas do mapa,
     estudo rapido, painel lateral de lei seca/anotacoes) - mesmo padrao do
     /admin (ver admin.css): some quando o mouse nao esta em cima, e mesmo
     visivel e so um traco, nao a barra grossa e opaca do SO.
     POR QUE: sem isto a barra saia grossa e SEMPRE visivel em algumas
     maquinas e em outras nao, porque no Windows a barra sobreposta (fina, que
     some sozinha) so vale com "Ocultar automaticamente as barras de rolagem"
     ligado - opcao cujo padrao varia por maquina. Fixando o estilo aqui, todo
     mundo ve a mesma coisa. Esconder por completo foi tentado e revertido:
     sem nenhum traco o aluno perde a nocao de onde esta no texto. */
  #viewport,#study,.sp-body{scrollbar-width:thin;scrollbar-color:transparent transparent}
  #viewport:hover,#study:hover,.sp-body:hover{scrollbar-color:rgba(59,42,26,.28) transparent}
  #viewport::-webkit-scrollbar,#study::-webkit-scrollbar,.sp-body::-webkit-scrollbar{width:7px;height:7px}
  #viewport::-webkit-scrollbar-track,#study::-webkit-scrollbar-track,.sp-body::-webkit-scrollbar-track{background:transparent}
  #viewport::-webkit-scrollbar-thumb,#study::-webkit-scrollbar-thumb,.sp-body::-webkit-scrollbar-thumb{
    background:transparent;border-radius:999px}
  #viewport:hover::-webkit-scrollbar-thumb,#study:hover::-webkit-scrollbar-thumb,.sp-body:hover::-webkit-scrollbar-thumb{
    background:rgba(59,42,26,.28)}
  #viewport::-webkit-scrollbar-thumb:hover,#study::-webkit-scrollbar-thumb:hover,.sp-body::-webkit-scrollbar-thumb:hover{
    background:rgba(59,42,26,.5)}

  /* ------------ barra superior ------------ */
  .topbar{
    position:relative;z-index:30;display:flex;flex-wrap:wrap;gap:8px 14px;align-items:center;
    padding:10px 14px;
    background:linear-gradient(90deg,#FF9A3D,#F97316 55%,#EA5D04);
    box-shadow:0 4px 0 #C7510A, 0 8px 18px rgba(170,75,0,.28);
  }
  /* marca "Ativa Maps": volta para o catalogo (Mapas Prontos/index.html) */
  .homelink{
    flex:0 0 auto;width:40px;height:40px;border-radius:13px;
    background:#FFF4E2;border:2.5px solid #7A3400;box-shadow:0 3px 0 #7A3400;
    display:flex;align-items:center;justify-content:center;
    text-decoration:none;
  }
  /* o cerebro do Otto tem viewBox 28x18, mais largo que alto: height:auto
     para o desenho nao ficar boiando no meio de um quadrado */
  .homelink svg{width:26px;height:auto;display:block}
  .homelink:hover{background:#FFE3C7}
  .homelink:active{transform:translateY(2px);box-shadow:0 1px 0 #7A3400}
  .homelink:focus-visible{outline:3px solid #FFF4E2;outline-offset:2px}
  .subjectlink{
    position:absolute;top:calc(100% + 7px);left:17px;z-index:32;
    width:34px;height:26px;border-radius:9px;background:#FFF4E2;border:2px solid #7A3400;
    color:#7A3400;display:flex;align-items:center;justify-content:center;text-decoration:none;
    box-shadow:0 2px 0 #7A3400
  }
  .subjectlink svg{width:16px;height:16px;display:block}
  .subjectlink:hover{background:#FFE3C7}
  .subjectlink:active{transform:translateY(1px);box-shadow:0 1px 0 #7A3400}
  .subjectlink:focus-visible{outline:3px solid #FFF4E2;outline-offset:2px}

  .topbar h1{
    font-family:'Fredoka',sans-serif;font-weight:700;color:#fff;
    font-size:clamp(15px,2.4vw,22px);line-height:1.05;
    text-shadow:0 2px 0 rgba(140,50,0,.4);
  }
  .topbar small{display:block;font-weight:900;font-size:11px;color:#FFE3C7;letter-spacing:.4px}
  .controls{margin-left:auto;display:flex;gap:6px;flex-wrap:wrap;align-items:center}

  .modeswitch{display:flex;gap:4px;background:#FFF4E2;border:2.5px solid #7A3400;border-radius:14px;padding:3px;box-shadow:0 3px 0 #7A3400}
  .modeswitch button{
    font-family:'Fredoka',sans-serif;font-weight:600;font-size:13.5px;
    border:none;border-radius:10px;padding:6px 12px;cursor:pointer;
    background:transparent;color:#9A4200;
  }
  .modeswitch button.active{background:linear-gradient(180deg,#FFB25E,#FF8A2A);color:#fff;text-shadow:0 1px 0 #B14700}

  .zoomctl{display:flex;gap:6px}
  .zoomctl button{
    font-family:'Fredoka',sans-serif;font-weight:600;font-size:15px;
    border:2.5px solid #7A3400;border-radius:12px;padding:4px 11px;cursor:pointer;
    background:#FFF4E2;color:#9A4200;box-shadow:0 3px 0 #7A3400;min-width:38px;
  }
  .zoomctl button:active{transform:translateY(2px);box-shadow:0 1px 0 #7A3400}
  .zoomctl.hidden{display:none}

  /* ------------ palco ------------ */
  .workspace{flex:1;display:flex;min-height:0;overflow:hidden}
  .stage{flex:1 1 auto;min-width:0;position:relative;overflow:hidden}
  #overview,#study{position:absolute;inset:0}
  .hidden{display:none !important}

  /* ------------ painel lateral (lei seca / anotações) ------------ */
  #sidePanel{
    flex:0 0 0px;width:0;overflow:hidden;min-height:0;
    background:#FFFDF8;border-left:0 solid var(--ink);
    display:flex;flex-direction:column;
    transition:flex-basis .22s ease, width .22s ease, border-left-width .22s ease;
  }
  #sidePanel.open{flex:0 0 min(420px,42vw);width:min(420px,42vw);border-left-width:5px}
  .sp-head{display:flex;align-items:center;gap:10px;padding:12px 14px;border-bottom:3px solid var(--ink);
    background:linear-gradient(180deg,#FFF4E2,#FFE9CC)}
  .sp-head .sp-icon{flex:0 0 30px;width:30px;height:30px;display:flex;align-items:center;justify-content:center;
    border-radius:50%;background:linear-gradient(180deg,#FFE08A,#F5B93A);border:2.5px solid var(--ink)}
  .sp-head .sp-icon svg{width:17px;height:17px}
  .sp-head .sp-titles{flex:1;min-width:0}
  .sp-head h3{font-family:'Fredoka',sans-serif;font-weight:700;font-size:16px;line-height:1.1;color:var(--ink)}
  .sp-head small{font-weight:900;font-size:10.5px;color:#8A6A3A;letter-spacing:.3px}
  .sp-close{flex:0 0 auto;border:2.5px solid var(--ink);border-radius:10px;background:var(--paper);
    color:var(--ink);font-weight:700;cursor:pointer;padding:5px 10px;box-shadow:0 2px 0 var(--ink)}
  .sp-close:active{transform:translateY(2px);box-shadow:0 0 0 var(--ink)}
  .sp-body{flex:1;overflow:auto;padding:14px 16px 24px}

  /* lei seca */
  .law-art{margin-bottom:18px;padding-bottom:14px;border-bottom:2px dashed #E7D3B0}
  .law-art:last-child{border-bottom:none}
  .law-art h4{font-family:'Fredoka',sans-serif;font-weight:700;font-size:15.5px;color:var(--laranja);margin-bottom:6px}
  .law-line{font-size:13.5px;line-height:1.55;margin:0 0 6px;color:#3B2A1A}
  .law-line.indent{padding-left:14px;color:#5A3A22}
  .law-inc-line{display:block;padding-left:22px}
  .law-inc-line.law-inc-l2{padding-left:44px}
  /* NUNCA `white-space:nowrap` aqui nem no selo abaixo. O texto do link de lei
     seca as vezes e uma citacao inteira entre aspas ("unidade de atuacao dotada
     de personalidade juridica", Lei 9.784/99, em da-organizacao-administrativa-1):
     com nowrap ela fica mais larga que o card e VAZA para fora dele, por cima da
     borda. Achado pelo usuario em set/2026, num print do mapa publicado.
     Como o botao e inline-block, ele encolhe para caber: referencia curta
     ("Art. 37, XI") continua numa linha so, porque cabe, e so a citacao longa
     quebra em duas. `max-width:100%` e o teto que garante isso mesmo quando o
     card e estreito, e `overflow-wrap:break-word` cobre a palavra unica maior
     que a linha. */
  .lawlink{color:#B14700;font-weight:800;cursor:pointer;border-bottom:1.5px dotted #B14700;max-width:100%;overflow-wrap:break-word}
  .lawlink:hover{color:#F97316}
  /* A barra fixa de cores (.highlight-toolbar e companhia) e o botao × de
     excluir sairam em ago/2026. A barra ficava grudada no topo da lei seca e
     exigia ESCOLHER A COR ANTES de selecionar, o inverso do que Kindle e Apple
     Books fazem; o × so aparecia no hover, que nao existe no dedo, e quando
     passou a ficar sempre visivel no celular punha um circulo vermelho sobre
     cada grifo. As duas coisas viraram a barra que aparece junto da selecao
     (ver "MARCA-TEXTO" no fim deste arquivo). */
  .law-highlight{border-radius:3px;padding:1px 0;box-decoration-break:clone;-webkit-box-decoration-break:clone;cursor:pointer}
  .law-highlight-wrap{position:relative;display:inline}
  /* marcacao que o aluno acabou de tocar: recebe contorno enquanto a barra
     estiver aberta em cima dela */
  .law-highlight-wrap.mt-ativa .law-highlight{box-shadow:0 0 0 2px var(--ink)}
  /* menção a artigo DENTRO de um card, ou no texto do hub central: mesmo selo
     branco arredondado dos tópicos. O hub (.central) não tem classe .t-*, então
     --c não existe ali dentro — por isso o selo do centro fixa a borda em
     --laranja em vez de var(--c) (ago/2026: sem isso o link caía no estilo
     genérico de texto, sem selo nenhum). */
  .sub .lawlink,.subnode .lawlink,.central .lawlink{
    display:inline-block;font-family:'Nunito',sans-serif;font-weight:900;font-size:11.5px;
    background:rgba(255,255,255,.94);color:var(--ink);border:2px solid var(--c);border-radius:999px;
    padding:1px 10px;margin:0 1px;line-height:1.35;white-space:normal;max-width:100%;
    overflow-wrap:break-word;cursor:pointer;vertical-align:baseline;
    box-shadow:0 1px 0 rgba(59,42,26,.28);-webkit-appearance:none;appearance:none;
  }
  .central .lawlink{border-color:var(--laranja)}
  .sub .lawlink:hover,.subnode .lawlink:hover,.central .lawlink:hover{background:#fff;color:var(--ink)}
  .sub .lawlink:active,.subnode .lawlink:active,.central .lawlink:active{transform:translateY(1px);box-shadow:0 0 0 rgba(59,42,26,.28)}

  /* anotações */
  .pencil-btn{
    flex:0 0 auto;width:26px;height:26px;border-radius:50%;cursor:pointer;
    display:flex;align-items:center;justify-content:center;
    background:#FFFDF8;color:#8A6A3A;border:2.5px solid var(--ink);box-shadow:0 2px 0 rgba(59,42,26,.55);
  }
  .pencil-btn svg{width:13px;height:13px}
  .pencil-btn:active{transform:translateY(2px);box-shadow:0 0 0 rgba(59,42,26,.55)}
  .pencil-btn.has-note{background:linear-gradient(180deg,#FFE08A,#F5B93A);color:#5A3A00}
  .branch .pencil-btn{position:absolute;top:8px;right:8px;background:rgba(255,255,255,.92)}
  .sub header .pencil-btn{margin-left:2px}
  .study-branchhead .pencil-btn{margin-left:auto}

  .note-toolbar{display:flex;gap:6px;align-items:center;padding:0 0 10px;flex-wrap:wrap}
  .note-toolbar button{
    font-family:'Fredoka',sans-serif;font-weight:700;font-size:13px;cursor:pointer;
    border:2.5px solid var(--ink);border-radius:9px;padding:4px 9px;background:var(--paper);color:var(--ink);
    box-shadow:0 2px 0 var(--ink);
  }
  .note-toolbar button:active{transform:translateY(1px);box-shadow:0 0 0 var(--ink)}
  .note-toolbar button.b{font-weight:900}
  .note-toolbar button.i{font-style:italic}
  .note-toolbar button.u{text-decoration:underline}
  /* as pastilhas de cor (.nc-sw) sao estilizadas junto da paleta, mais
     abaixo - o seletor <input type=color> saiu em ago/2026 */
  /* botao de salvar (piloto, meta.manualNoteSave): so o icone (disquete),
     mesma cor/fundo dos demais botoes da barra - nao precisa se destacar por
     cor, o rotulo "Alterações não salvas" ja avisa que ha algo pendente */
  .note-save-btn svg{width:15px;height:15px;stroke:var(--ink)}
  .note-editor{
    min-height:220px;border:3px solid var(--ink);border-radius:14px;background:#fff;
    padding:12px;font-size:14px;line-height:1.5;color:var(--ink);outline:none;
  }
  .note-editor:empty:before{content:attr(data-placeholder);color:#B7A488}
  .note-editor ul,.note-editor ol{padding-left:1.4em;margin:.3em 0}
  .note-editor li{margin:.15em 0}
  .note-editor img{display:block;max-width:100%;height:auto;border:2px solid var(--ink);border-radius:10px;margin:8px 0;cursor:zoom-in}
  /* imagem da anotacao ampliada (ver abrirImagemNota no map-engine.js) */
  .nota-zoom{position:fixed;inset:0;z-index:900;display:flex;align-items:center;justify-content:center;
    padding:16px;background:rgba(10,10,12,.85);cursor:zoom-out}
  .nota-zoom.hidden{display:none}
  .nota-zoom img{max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain;
    border-radius:8px;background:#fff;box-shadow:0 10px 40px rgba(0,0,0,.5);cursor:default}
  .nota-zoom-x{position:absolute;top:12px;right:12px;width:40px;height:40px;border:0;border-radius:50%;
    background:rgba(255,255,255,.92);color:#1c1917;font-size:26px;line-height:40px;padding:0;cursor:pointer}
  .note-saved{margin-top:8px;font-size:11px;font-weight:800;color:#1F9D55;min-height:14px}
  .note-saved.dirty{color:#D6483A}

  /* ---- barra da anotação: dois botões-menu de cor ----
     Dois botões com menu no lugar da fileira de pastilhas: "A" com barra
     colorida embaixo (cor do texto) e a caneta (marca-texto). O disquete vem
     ANTES do "Limpar": salvar é o gesto comum, apagar tudo é o raro. */
  .note-toolbar .nt-sep{width:1px;height:20px;background:rgba(59,42,26,.22);margin:0 1px}
  .note-toolbar .nt-menu{position:relative;display:inline-flex}
  .note-toolbar .nt-btn{display:inline-flex;align-items:center;justify-content:center}
  .note-toolbar .tx-btn{flex-direction:column;gap:2px;padding:3px 7px;line-height:1}
  .note-toolbar .tx-btn .tx-a{font-family:'Fredoka',sans-serif;font-weight:900;font-size:13px}
  .note-toolbar .tx-btn .tx-bar{width:15px;height:3px;border-radius:2px;background:var(--tx-cor,#8A7A66)}
  .note-toolbar .mk-btn svg{width:15px;height:15px}
  .note-toolbar .nt-pop{
    position:absolute;top:calc(100% + 8px);left:0;z-index:30;
    display:flex;align-items:center;gap:6px;padding:7px;
    background:#fff;border:2.5px solid var(--ink);border-radius:12px;box-shadow:0 4px 0 rgba(59,42,26,.35);
  }
  .note-toolbar .nt-pop[hidden]{display:none}
  .note-toolbar .nt-sep-pop{width:1px;height:20px;background:rgba(59,42,26,.22);margin:0 1px}
  /* duas classes de propósito: ".note-toolbar button" (classe + tipo) pesa mais
     que uma classe sozinha e apagaria o fundo colorido da pastilha */
  .note-toolbar .nh-sw{
    width:24px;height:22px;padding:0;border-radius:6px 6px 3px 3px;cursor:pointer;
    border:2px solid var(--ink);background:var(--nh);box-shadow:0 2px 0 rgba(59,42,26,.4);
  }
  .note-toolbar .nh-sw:hover{transform:translateY(-1px)}
  .note-toolbar .nh-limpa{
    width:24px;height:22px;padding:0;border-radius:6px 6px 3px 3px;cursor:pointer;
    border:2px solid var(--ink);
    background:
      linear-gradient(to bottom right,
        transparent calc(50% - 1.5px), rgba(59,42,26,.6) calc(50% - 1.5px),
        rgba(59,42,26,.6) calc(50% + 1.5px), transparent calc(50% + 1.5px)),
      repeating-linear-gradient(45deg, #EFE6D6, #EFE6D6 3px, #fff 3px, #fff 6px);
  }

  /* marca-texto DENTRO da anotação: mesma ideia do .law-highlight da lei seca.
     Padding só na vertical - com padding lateral, dois trechos marcados
     vizinhos abrem um vão visível entre as letras. */
  .nh{
    background:var(--nh);border-radius:3px;padding:1px 0;
    box-decoration-break:clone;-webkit-box-decoration-break:clone;
  }
  .nh-amarelo{--nh:#FDE68A} .nh-verde{--nh:#BBF7D0} .nh-azul{--nh:#BFDBFE}

  /* ---- balão de anotação preso ao card (piloto) ----
     Tamanho FIXO, sempre (set/2026): uma anotação longa nao pode fazer o
     balao crescer sem limite - `.stage`, onde ele mora, tem overflow:hidden,
     entao a parte que passasse da borda ficava fisicamente cortada, sem
     clique nem scroll possiveis (nem pra fechar). A correcao e o balao virar
     uma coluna flex com altura MAXIMA: cabecalho e status ficam de tamanho
     fixo (flex:0 0 auto), e so o campo de texto cresce e rola por dentro
     (flex:1 1 auto + overflow-y:auto). `min(520px, calc(100% - 24px))` cobre
     os dois casos - tela normal usa o teto de 520px, tela baixa (janela
     redimensionada, notebook pequeno) usa a % antes de estourar o palco. */
  .nota-balao{
    position:absolute;z-index:40;width:340px;
    max-height:min(520px, calc(100% - 24px));
    display:flex;flex-direction:column;
    background:#fff;border:3px solid var(--ink);border-radius:16px;
    box-shadow:0 6px 0 rgba(59,42,26,.35), 0 14px 34px rgba(59,42,26,.22);
  }
  .nota-balao[hidden]{display:none}
  .nota-balao .nb-bico{
    position:absolute;top:24px;width:12px;height:12px;background:#fff;
    border-left:3px solid var(--ink);border-bottom:3px solid var(--ink);
    transform:rotate(45deg);
  }
  .nota-balao.a-direita .nb-bico{left:-8px}
  .nota-balao.a-esquerda .nb-bico{right:-8px;transform:rotate(225deg)}
  .nota-balao.sem-bico .nb-bico{display:none}
  .nota-balao .nb-cab{
    flex:0 0 auto;
    display:flex;align-items:center;gap:8px;padding:9px 10px 8px 12px;
    border-bottom:2.5px solid var(--ink);
  }
  .nota-balao .nb-ico{
    width:24px;height:24px;flex:none;border-radius:8px;background:var(--laranja-soft);color:#8A4B10;
    display:flex;align-items:center;justify-content:center;
  }
  .nota-balao .nb-ico svg{width:13px;height:13px}
  .nota-balao .nb-titulo{
    flex:1 1 auto;min-width:0;font-family:'Fredoka',sans-serif;font-weight:700;font-size:13px;
    color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  }
  .nota-balao .nb-btn{
    width:26px;height:26px;flex:none;border-radius:8px;cursor:pointer;
    border:2.5px solid var(--ink);background:var(--paper);color:var(--ink);
    display:inline-flex;align-items:center;justify-content:center;box-shadow:0 2px 0 var(--ink);
  }
  .nota-balao .nb-btn svg{width:13px;height:13px}
  .nota-balao .nb-btn:active{transform:translateY(1px);box-shadow:0 0 0 var(--ink)}
  /* corpo tambem em coluna, e com min-height:0 - sem isto um flex item nao
     encolhe abaixo do proprio conteudo, e o campo de texto nunca chegaria a
     rolar, so empurraria o balao pra fora do teto de novo */
  .nota-balao .nb-corpo{
    flex:1 1 auto;min-height:0;padding:10px 12px 12px;
    display:flex;flex-direction:column;
  }
  /* dentro do balão o editor é menor: ele divide a tela com o card, não é uma
     coluna inteira como no painel. So ELE cresce e rola; cabecalho, barra e
     status ficam sempre visiveis e clicaveis, nunca empurrados pra fora */
  .nota-balao .note-editor{
    flex:1 1 auto;min-height:70px;font-size:13.5px;
    overflow-y:auto;overscroll-behavior:contain;
  }
  .nota-balao .note-toolbar{flex:0 0 auto;padding-bottom:8px;gap:5px}
  .nota-balao .note-saved{flex:0 0 auto}


  /* ------------ overview / canvas ------------ */
  #viewport{position:absolute;inset:0;overflow:auto;cursor:grab;touch-action:none;
    background:
      radial-gradient(circle at 1px 1px, rgba(210,140,60,.22) 1.7px, transparent 0) 0 0/26px 26px,
      var(--paper);
  }
  #viewport.dragging{cursor:grabbing}
  #scaler{position:relative}
  /* NAO acrescente `will-change:transform` aqui. Foi tentado (ago/2026) para
     resolver um relato de camera "nao fluida" e REVERTIDO: nao era esse o
     problema (era `prefers-reduced-motion` ligado no Windows de quem relatou,
     ver prefersReducedMotion() no map-engine.js), e promover um elemento de
     7000x7000 a camada de composicao propria custa memoria de video a toa -
     justamente nas GPUs fracas que a mudanca pretendia ajudar. */
  #canvas{position:relative;width:7000px;height:7000px;transform-origin:0 0}
  #ovwires{position:absolute;inset:0;pointer-events:none}
  #ovwires path{fill:none;stroke-linecap:round}

  .ov-node{position:absolute;transform:translate(-50%,-50%)}
  /* movimento de cards/tópicos/linhas é animado em JS (tween único p/ tudo) */

  /* nó central */
  .central{
    width:346px;text-align:center;padding:16px 20px 20px;border-radius:22px;background:#fff;
    border:5px solid var(--ink);
    background:linear-gradient(180deg,#FFB25E,#FF8A2A);
    box-shadow:0 10px 0 rgba(59,42,26,.9), 0 18px 30px rgba(150,70,0,.3);
  }
  /* quando algum tópico está aberto, o hub central ganha o mesmo halo de foco,
     dois pontos de foco principal do mapa, reforçados com um halo branco,
     pra guiar o olho antes dos cards ao redor */
  .central.hub-focus{
    box-shadow:0 10px 0 rgba(59,42,26,.9), 0 0 0 7px rgba(255,255,255,.85), 0 0 34px rgba(255,178,60,.55), 0 18px 30px rgba(150,70,0,.3);
  }
  .central h2{
    font-family:'Fredoka',sans-serif;font-weight:700;font-size:34px;line-height:.98;
    color:var(--ink);text-shadow:0 2px 0 rgba(255,255,255,.20);letter-spacing:.5px;margin-top:4px;
  }
  .central .base{
    display:inline-block;margin-top:9px;font-weight:900;font-size:13px;
    background:#3B2A1A;color:#FFD9A6;border-radius:999px;padding:4px 14px;
  }
  .central p{margin-top:10px;font-weight:800;font-size:14px;color:#5A2E00;
    background:#FFF4E2;border:3px solid var(--ink);border-radius:14px;padding:8px 10px;line-height:1.35}
  .central .illus{margin:-64px auto 0;width:140px;height:140px;
    filter:drop-shadow(0 6px 0 rgba(59,42,26,.35));animation:float 4s ease-in-out infinite}
  @keyframes float{0%,100%{transform:translateY(0)}50%{transform:translateY(-7px)}}
  @media (prefers-reduced-motion: reduce){:root:not([data-motion="full"]) .central .illus{animation:none}}
  :root[data-motion="reduced"] .central .illus{animation:none}

  /* ramos (chips) */
  .branch{
    width:214px;padding:12px 14px 14px;text-align:center;border-radius:22px;
    border:4px solid var(--ink);cursor:pointer;user-select:none;
    box-shadow:0 7px 0 rgba(59,42,26,.85);transition:transform .12s, box-shadow .12s;
  }
  .branch:active{transform:translateY(3px);box-shadow:0 4px 0 rgba(59,42,26,.85)}
  .branch .illus{width:96px;height:96px;margin:-56px auto 2px;
    filter:drop-shadow(0 4px 0 rgba(59,42,26,.3))}
  /* titulo em TINTA, nao branco: branco sobre o gradiente claro do topico dava
     2,0-2,9:1 (minimo 3:1 para texto grande) e reprovava em laranja, verde, teal
     e rosa. Em tinta o pior caso vira 3,8:1 e as cores da marca ficam intactas.
     Bonus: casa com o traco #3B2A1A das ilustracoes. */
  .branch h3{font-family:'Fredoka',sans-serif;font-weight:700;font-size:20px;line-height:1.05;color:var(--ink);
    text-shadow:0 1px 0 rgba(255,255,255,.22)}
  /* plaquinha de artigos = o gatilho da lei seca dentro do mapa (ago/2026).
     O livro vem ANTES do rótulo, no mesmo alvo: o rótulo "arts. 1º a 3º" ja
     e a melhor etiqueta possivel (diz exatamente o que abre), entao gastar um
     segundo botao so pro icone seria dois alvos pra uma acao so num no ja
     apertado. min-height:24px atende o alvo de toque do WCAG 2.2 (2.5.8) - a
     plaquinha tinha ~20px de altura.
     A COR DO LIVRO e o laranja escuro #C2410C, fixo, e nao var(--ink) nem
     var(--ui-accent):
     - em tinta ele viraria mais um glifo no meio do texto, e o problema que
       estamos consertando e justamente a plaquinha parecer texto/metadado;
     - #C2410C e exatamente a cor do livro no cabecalho do painel em modo
       claro, entao gatilho e destino combinam (a promessa do link);
     - fixo, e nao o token --ui-accent, porque no modo noturno o token vira
       #FB923C claro e esta plaquinha NAO escurece junto (nao ha regra noturna
       pra .branch .art - o topico segue colorido de proposito), o que daria
       laranja claro sobre branco, ~2:1, reprovando no WCAG 1.4.11.
       Fixo em #C2410C da 5,2:1 no claro e ~4,8:1 no noturno (o brightness(.88)
       do --map-dim atenua fundo e icone juntos). */
  .branch .art{display:inline-flex;align-items:center;gap:5px;min-height:24px;
    margin-top:6px;font-size:11.5px;font-weight:900;
    background:rgba(255,255,255,.94);border-radius:999px;padding:4px 11px;color:var(--ink)}
  .branch .art svg{width:13px;height:13px;flex:0 0 auto;stroke:#C2410C}
  button.art{border:none;font:inherit;font-family:'Nunito',sans-serif;cursor:pointer;appearance:none;-webkit-appearance:none}
  button.art:active{transform:translateY(1px)}
  .branch .toggle{display:inline-flex;align-items:center;gap:5px;margin-top:8px;
    font-size:11.5px;font-weight:900;color:#fff;background:rgba(0,0,0,.16);
    border-radius:999px;padding:3px 10px}
  .branch.open .toggle .plus{transform:rotate(45deg)}
  .toggle .plus{display:inline-block;transition:transform .15s;font-size:14px;line-height:1}

  /* cards (subramos) */
  .sub{
    width:322px;padding:11px 14px 13px;border-radius:20px;border:3.5px solid var(--ink);
    border-top:9px solid var(--c);
    box-shadow:0 5px 0 rgba(59,42,26,.75);background:#FFFDF8;
    cursor:auto;user-select:text;
  }
  .ov-node .sub{animation:pop .18s ease-out}
  @keyframes pop{from{opacity:0;transform:scale(.9)}to{opacity:1;transform:scale(1)}}
  /* fechar os detalhes: mesmo efeito do pop de abrir, só que ao contrário e na mesma duração */
  @keyframes popOut{from{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.9)}}
  .ov-node.closing .sub, .ov-node.closing .subnode{animation:popOut .18s ease-in forwards;pointer-events:none}
  .sub header{display:flex;align-items:center;gap:9px;margin-bottom:5px}
  .sub .mini{flex:0 0 46px;width:46px;height:46px}
  .sub .mini svg{width:46px;height:46px}
  .sub h4{font-family:'Fredoka',sans-serif;font-weight:600;font-size:17.5px;line-height:1.05;color:var(--ink);flex:1}
  .sub ul{list-style:none}
  /* overflow-wrap (ago/2026): o card tem largura fixa (322px), e a lei seca vive
     produzindo cadeias com barra que o navegador trata como UMA palavra so —
     "dispensa/exoneracao/destituicao/demissao/aposentadoria" da 55 caracteres e
     nao cabe na coluna de texto. Sem isto a palavra final vaza para fora da
     borda do card e some da tela (bug real: "aposentadoria" sumiu do card
     "Conflito de interesses apos o exercicio", em rt-comite-gestor-1). O
     break-word so age quando a palavra sozinha nao cabe; texto normal continua
     quebrando nos espacos como antes. */
  .sub li{position:relative;padding:3px 0 3px 16px;font-size:13.5px;font-weight:700;line-height:1.3;
    overflow-wrap:break-word}
  .sub li::before{content:"";position:absolute;left:2px;top:9px;width:7px;height:7px;border-radius:50%;
    background:var(--c);border:1.5px solid var(--ink)}
  .sub b{background:var(--soft);border-radius:5px;padding:0 4px;border-bottom:2px solid var(--c)}
  /* trecho de código ou comando (set/2026, mapas de TI): fonte monoespaçada e
     fundo leve na cor do tópico; quebra em qualquer ponto para um comando longo
     não vazar da largura fixa do card */
  .sub code,.subnode code{font-family:ui-monospace,'Cascadia Mono',Consolas,'SF Mono',Menlo,'Courier New',monospace;
    font-size:.9em;font-weight:600;background:color-mix(in srgb, var(--c) 9%, #FFFFFF);
    border:1px solid color-mix(in srgb, var(--c) 35%, transparent);border-radius:5px;padding:0 4px;
    overflow-wrap:anywhere}
  .sub b code,.subnode b code{background:transparent;border:0;padding:0}
  .sub .tip{margin-top:7px;font-size:12px;font-weight:900;border-radius:10px;padding:5px 9px;
    background:var(--soft);border:2px dashed var(--c);line-height:1.3}

  /* "escada visual" (ago/2026): faixas de valor com a aliquota em destaque e
     uma barra de largura proporcional. A largura vem do dado, nao e calculada
     aqui - ver ladderHTML() em map-engine.js. */
  .sub .ladder{margin:6px 0 2px;display:grid;gap:5px}
  .sub .ladder-group{font-family:'Fredoka',sans-serif;font-size:13px;font-weight:600;
    display:flex;align-items:center;gap:7px;margin-top:2px}
  .sub .ladder-group::after{content:"";flex:1;height:2.5px;background:var(--c);border-radius:2px;opacity:.5}
  .sub .ladder-row{display:grid;grid-template-columns:46px 1fr;align-items:center;gap:8px}
  .sub .ladder-pct{font-weight:900;font-size:13px;text-align:center;font-variant-numeric:tabular-nums;
    background:var(--soft);border:2px solid var(--ink);border-radius:8px;padding:1px 0}
  .sub .ladder-bar{position:relative;height:21px;border:2px solid var(--ink);border-radius:7px;
    overflow:hidden;display:flex;align-items:center}
  .sub .ladder-fill{position:absolute;left:0;top:0;bottom:0;background:var(--c);opacity:.24}
  .sub .ladder-lbl{position:relative;font-size:11px;font-weight:800;padding-left:6px}

  /* notas extras do card (jul/2026): formula, artigo, mnemonico, outro. O
     admin adiciona quantas quiser, de qualquer tipo, pelo /admin. Mesmo
     estilo visual da dica (.tip) de proposito: e o mesmo "cartao de destaque
     na cor do topico" que a dica ja usa, so que repetivel e com uma etiqueta
     dizendo que tipo de nota e. */
  .sub .note{margin-top:7px;font-size:12px;font-weight:700;border-radius:10px;padding:5px 9px;
    background:var(--soft);border:2px dashed var(--c);line-height:1.3}
  .sub .note-label{display:block;font-weight:900;font-size:10px;letter-spacing:.04em;
    text-transform:uppercase;color:var(--c);margin-bottom:1px}

  /* gráfico didático do card (set/2026): campo opcional "chart" {svg, caption,
     legend}. O SVG vem só com classes (ax, cv, cv-c, cv-ghost, dash, pt, pt-c,
     ar-*, bar*, arr*, text.c/.mut/.bad/.ok/.ttl): a cor é a do tópico (--c) e
     a tinta é local (--ck-ink), trocada no modo noturno lá embaixo. Montado com
     workflow/tools/chartkit.js; ver WORKFLOW.md, seção "chart". */
  .ov-node .sub[data-has-chart="1"]{width:400px}
  .ov-node .subnode[data-has-chart="1"]{width:380px}
  .sub .chart,.subnode .chart{--ck-ink:#3B2A1A;--ck-mut:#7A6450;--ck-bg:#FFFFFF;--ck-pt:#FFFDF8;
    --ck-txt-c:color-mix(in srgb, var(--c) 72%, #1A1109);
    margin:8px 0 2px;border:2px solid var(--ck-ink);border-radius:12px;background:var(--ck-bg);padding:6px 6px 6px}
  .chart svg{display:block;width:100%;height:auto}
  .chart .ax{stroke:var(--ck-ink);stroke-width:1.8;fill:none;stroke-linecap:round}
  .chart .cv{stroke:var(--ck-ink);stroke-width:2.6;fill:none;stroke-linecap:round;stroke-linejoin:round}
  .chart .cv-c{stroke:var(--c);stroke-width:3;fill:none;stroke-linecap:round;stroke-linejoin:round}
  .chart .cv-dash{stroke-dasharray:6 4}
  .chart .cv-ghost{stroke:var(--ck-mut);stroke-width:2.3;fill:none;stroke-dasharray:5 4;stroke-linecap:round;stroke-linejoin:round}
  .chart .cv-bad{stroke:#D6483A;stroke-width:2.6;fill:none;stroke-linecap:round}
  .chart .cv-ok{stroke:#1F9D55;stroke-width:2.6;fill:none;stroke-linecap:round}
  .chart .dash{stroke:var(--ck-mut);stroke-width:1.3;stroke-dasharray:3 3;fill:none}
  .chart .arr{stroke:var(--c);stroke-width:2.2;fill:none;stroke-linecap:round}
  .chart .arr-h{fill:var(--c);stroke:none}
  .chart .arr.arr-ink{stroke:var(--ck-ink)} .chart .arr-h.arr-ink{fill:var(--ck-ink)}
  .chart .pt{fill:var(--ck-pt);stroke:var(--ck-ink);stroke-width:2}
  .chart .pt-c{fill:var(--c);stroke:var(--ck-ink);stroke-width:2}
  .chart .ar-c{fill:var(--c);fill-opacity:.2;stroke:none}
  .chart .ar-bad{fill:#E5484D;fill-opacity:.24;stroke:none}
  .chart .ar-ok{fill:#1F9D55;fill-opacity:.2;stroke:none}
  .chart .ar-ink{fill:var(--ck-ink);fill-opacity:.1;stroke:none}
  .chart .ar-warn{fill:#F7C948;fill-opacity:.35;stroke:none}
  .chart .bar{fill:var(--ck-pt);stroke:var(--ck-ink);stroke-width:1.6}
  .chart .bar-c{fill:var(--c);fill-opacity:.45;stroke:var(--ck-ink);stroke-width:1.6}
  .chart .bar-bad{fill:#E5484D;fill-opacity:.5;stroke:var(--ck-ink);stroke-width:1.6}
  .chart .bar-ok{fill:#1F9D55;fill-opacity:.45;stroke:var(--ck-ink);stroke-width:1.6}
  .chart .bar-warn{fill:#F7C948;fill-opacity:.7;stroke:var(--ck-ink);stroke-width:1.6}
  .chart text{fill:var(--ck-ink);font-family:'Nunito',sans-serif;font-weight:800;font-size:11px}
  .chart text.c{fill:var(--ck-txt-c)}
  .chart text.mut{fill:var(--ck-mut);font-weight:700}
  .chart text.bad{fill:#C0392B} .chart text.ok{fill:#16803F}
  .chart text.ttl{font-family:'Fredoka',sans-serif;font-weight:600;font-size:12px}
  .chart figcaption{font-size:12px;font-weight:800;line-height:1.3;padding:5px 3px 0;color:var(--ck-ink)}
  .chart .chart-legend{margin:6px 0 0;padding:6px 3px 0;border-top:1.5px dashed color-mix(in srgb, var(--ck-ink) 30%, transparent);
    display:grid;grid-template-columns:auto 1fr;gap:2px 8px;font-size:11.5px;line-height:1.3;color:var(--ck-ink)}
  .chart .chart-legend-label{grid-column:1/-1;font-weight:900;font-size:10px;letter-spacing:.04em;text-transform:uppercase;color:var(--ck-txt-c);margin-bottom:1px}
  .chart .chart-legend dt{font-weight:900;white-space:nowrap}
  .chart .chart-legend dd{margin:0;font-weight:700}


  /* ícones por item de lista (facilitam memorização): ficam antes do texto,
     como um "emoji líder" (inline, sem flutuar nem quebrar a frase). Ficam
     parados; só animam de leve no hover. Quando/como usar: ver
     workflow/svg-library.md, seção "Ícones por item (li-ico)". */
  .li-ico{display:inline-block;vertical-align:-7px;width:26px;height:26px;margin-right:6px}
  .subnode .li-ico{vertical-align:-6px;width:22px;height:22px;margin-right:5px}
  .li-ico svg{display:block;width:100%;height:100%}
  /* entidade/empresa real: recorte do símbolo oficial (PNG em data URI), com
     filtro de sombra pra combinar com o resto do traço do mapa: ver
     svg-library.md, seção "Entidades/empresas reais" */
  .li-ico img{display:block;width:100%;height:100%;object-fit:contain;filter:drop-shadow(0 1.5px 0 #3B2A1A)}
  .li-ico:hover svg,.li-ico:hover img{animation:li-ico-bob 1.3s ease-in-out infinite}
  @keyframes li-ico-bob{0%,100%{transform:translateY(0) rotate(0deg)}50%{transform:translateY(-3px) rotate(-4deg)}}
  @media(prefers-reduced-motion:reduce){
    :root:not([data-motion="full"]) .li-ico:hover svg,
    :root:not([data-motion="full"]) .li-ico:hover img{animation:none}}
  :root[data-motion="reduced"] .li-ico:hover svg,
  :root[data-motion="reduced"] .li-ico:hover img{animation:none}
  /* largura extra automática: cardHTML/subHTML marcam data-has-ico="1" quando
     algum item tem .li-ico, então nenhum mapa novo precisa de CSS por card só
     para isso: funciona sozinho ao adotar o padrão nos dados. */
  .ov-node .sub[data-has-ico="1"]{width:400px}
  .ov-node .subnode[data-has-ico="1"]{width:340px}

  /* botão de jurisprudência */
  .juris-btn{
    flex:0 0 auto;width:30px;height:30px;border-radius:50%;cursor:pointer;
    display:flex;align-items:center;justify-content:center;
    background:linear-gradient(180deg,#FFE08A,#F5B93A);color:#5A3A00;
    border:2.5px solid var(--ink);box-shadow:0 2px 0 rgba(59,42,26,.6);
  }
  .juris-btn:active{transform:translateY(2px);box-shadow:0 0 0 rgba(59,42,26,.6)}
  .juris-btn svg{width:16px;height:16px}

  /* ------------ olho de "visualizar" (cena mnemonica) ------------
     Mesma silhueta do selo de jurisprudencia (mesmo tamanho, mesma borda,
     mesma sombrinha que afunda no clique), com UMA diferenca deliberada: o
     dourado continua sendo so da balanca. O olho veste a cor do proprio
     topico (var(--c) sobre var(--soft)), entao dois selos no mesmo cabecalho
     nunca se confundem, e a cor ja diz de que ramo do mapa aquele card e. */
  .scene-btn{
    flex:0 0 auto;width:30px;height:30px;border-radius:50%;cursor:pointer;
    display:flex;align-items:center;justify-content:center;
    background:var(--soft);color:var(--c);
    border:2.5px solid var(--ink);box-shadow:0 2px 0 rgba(59,42,26,.6);
  }
  .scene-btn:active{transform:translateY(2px);box-shadow:0 0 0 rgba(59,42,26,.6)}
  .scene-btn svg{width:17px;height:17px}
  .subnode .scene-btn{width:24px;height:24px}
  .subnode .scene-btn svg{width:14px;height:14px}

  .t-laranja {--c:var(--laranja); --soft:var(--laranja-soft)}
  .t-azul    {--c:var(--azul);    --soft:var(--azul-soft)}
  .t-verde   {--c:var(--verde);   --soft:var(--verde-soft)}
  .t-vermelho{--c:var(--vermelho);--soft:var(--vermelho-soft)}
  .t-roxo    {--c:var(--roxo);    --soft:var(--roxo-soft)}
  .t-teal    {--c:var(--teal);    --soft:var(--teal-soft)}
  .t-rosa    {--c:var(--rosa);    --soft:var(--rosa-soft)}
  .branch.t-laranja {background:linear-gradient(180deg,#FFA24A,var(--laranja))}
  .branch.t-azul    {background:linear-gradient(180deg,#5D9BEC,var(--azul))}
  .branch.t-verde   {background:linear-gradient(180deg,#43B879,var(--verde))}
  .branch.t-vermelho{background:linear-gradient(180deg,#F0716F,var(--vermelho))}
  .branch.t-roxo    {background:linear-gradient(180deg,#A683F8,var(--roxo))}
  .branch.t-teal    {background:linear-gradient(180deg,#3CBFBB,var(--teal))}
  .branch.t-rosa    {background:linear-gradient(180deg,#E879F9,var(--rosa))}

  /* ------------ subtópicos (4º/5º nível) ------------ */
  .subnode{
    width:260px;padding:9px 12px 11px;border-radius:16px;
    border:2.5px dashed var(--c);background:#FFFEFB;
    box-shadow:0 3px 0 rgba(59,42,26,.35);
    cursor:auto;user-select:text;
  }
  .ov-node .subnode{animation:pop .18s ease-out}
  .subnode header{display:flex;align-items:flex-start;gap:7px;margin-bottom:4px}
  .subnode h5{font-family:'Fredoka',sans-serif;font-weight:600;font-size:14.5px;line-height:1.1;color:var(--ink);flex:1;padding-top:2px}
  .subnode ul{list-style:none}
  /* mesmo motivo do .sub li acima: card estreito, palavra longa sem espaco. */
  .subnode li{position:relative;padding:2px 0 2px 13px;font-size:12px;font-weight:700;line-height:1.3;
    overflow-wrap:break-word}
  .subnode li::before{content:"";position:absolute;left:1px;top:8px;width:5px;height:5px;border-radius:50%;
    background:var(--c);border:1px solid var(--ink)}
  .subnode b{background:var(--soft);border-radius:4px;padding:0 3px;border-bottom:1.5px solid var(--c)}
  .subnode .tip{margin-top:5px;font-size:11px;font-weight:900;border-radius:8px;padding:4px 8px;
    background:var(--soft);border:2px dashed var(--c);line-height:1.3}
  .subnode .note{margin-top:5px;font-size:11px;font-weight:700;border-radius:8px;padding:4px 8px;
    background:var(--soft);border:2px dashed var(--c);line-height:1.3}
  .subnode .note-label{display:block;font-weight:900;font-size:9px;letter-spacing:.04em;
    text-transform:uppercase;color:var(--c);margin-bottom:1px}
  .subnode .pencil-btn{width:22px;height:22px}
  .subnode .pencil-btn svg{width:11px;height:11px}
  .subnode .juris-btn{width:24px;height:24px}
  .subnode .juris-btn svg{width:13px;height:13px}

  /* botão "+ detalhes" (abre os subtópicos de um card) */
  .subtoggle{
    display:inline-flex;align-items:center;gap:5px;margin-top:8px;cursor:pointer;
    font-family:'Fredoka',sans-serif;font-weight:600;font-size:12px;color:var(--ink);
    background:var(--soft);border:2px solid var(--c);border-radius:999px;padding:3px 11px;
    box-shadow:0 2px 0 rgba(59,42,26,.5);
  }
  .subtoggle:active{transform:translateY(1px);box-shadow:0 0 0 rgba(59,42,26,.5)}
  .subtoggle .plus{display:inline-block;transition:transform .15s;font-size:13px;line-height:1}
  .subtoggle.open .plus{transform:rotate(45deg)}

  /* subtópicos aninhados no modo estudo */
  .study-subs{margin-top:9px;padding-left:12px;border-left:3px dashed var(--c);
    display:flex;flex-direction:column;gap:9px}
  .study-subs .subnode{width:auto}

  /* ------------ estudo rápido ------------ */
  /* overflow-anchor:none evita o loop do cabecalho retratil: sem isso, o
     scroll-anchoring nativo do navegador compensa sozinho o scrollTop quando
     .study-center encolhe/expande dentro deste mesmo container rolavel, o
     que reexecuta o listener de scroll e faz .collapsed alternar sem parar
     perto de certas posicoes (ver workflow/verifica_estudo_navegador.js). */
  #study{overflow:auto;overflow-anchor:none;background:
      radial-gradient(circle at 1px 1px, rgba(210,140,60,.16) 1.6px, transparent 0) 0 0/26px 26px,
      var(--paper);}
  .study-top{position:sticky;top:0;z-index:12;background:linear-gradient(180deg,var(--paper),var(--paper) 78%,rgba(255,244,226,0));
    padding:12px 12px 6px;}
  .study-center{max-width:760px;margin:0 auto;display:flex;align-items:center;gap:12px;
    background:linear-gradient(180deg,#FFB25E,#FF8A2A);border:4px solid var(--ink);border-radius:18px;
    padding:9px 16px;box-shadow:0 6px 0 rgba(59,42,26,.85)}
  .study-center .ic{flex:0 0 44px;width:44px;height:44px}
  .study-center .ic svg{width:44px;height:44px}
  .study-center h2{font-family:'Fredoka',sans-serif;font-weight:700;font-size:20px;color:#fff;line-height:1;text-shadow:0 2px 0 #B14700}
  .study-center small{display:block;font-weight:900;font-size:11px;color:#FFE9CF;margin-top:3px;letter-spacing:.3px}

  .chiprail{max-width:1050px;margin:10px auto 0;display:flex;flex-wrap:wrap;gap:7px;justify-content:center}
  .chip{
    display:inline-flex;align-items:center;gap:7px;cursor:pointer;user-select:none;
    font-family:'Fredoka',sans-serif;font-weight:600;font-size:13.5px;color:var(--ink);
    border:3px solid var(--ink);border-radius:999px;padding:5px 13px 5px 8px;
    box-shadow:0 3px 0 rgba(59,42,26,.8);opacity:.62;transition:opacity .12s, transform .12s}
  .chip .dot{width:22px;height:22px;flex:0 0 22px}
  .chip .dot svg{width:22px;height:22px}
  .chip:hover{opacity:.85}
  .chip.active{opacity:1;transform:translateY(-1px)}
  .chip.active::after{content:"";width:9px;height:9px;border-radius:50%;background:#fff;box-shadow:0 0 0 2px var(--ink)}
  .chip.t-laranja {background:linear-gradient(180deg,#FFA24A,var(--laranja))}
  .chip.t-azul    {background:linear-gradient(180deg,#5D9BEC,var(--azul))}
  .chip.t-verde   {background:linear-gradient(180deg,#43B879,var(--verde))}
  .chip.t-vermelho{background:linear-gradient(180deg,#F0716F,var(--vermelho))}
  .chip.t-roxo    {background:linear-gradient(180deg,#A683F8,var(--roxo))}
  .chip.t-teal    {background:linear-gradient(180deg,#3CBFBB,var(--teal))}
  .chip.t-rosa    {background:linear-gradient(180deg,#E879F9,var(--rosa))}

  .study-body{max-width:820px;margin:8px auto 60px;padding:6px 14px 0}
  .study-branchhead{display:flex;align-items:center;gap:14px;margin:14px 4px 4px}
  .study-branchhead .big{flex:0 0 88px;width:88px;height:88px;filter:drop-shadow(0 4px 0 rgba(59,42,26,.28))}
  .study-branchhead .big svg{width:88px;height:88px}
  .study-branchhead h3{font-family:'Fredoka',sans-serif;font-weight:700;font-size:27px;line-height:1;color:var(--c)}
  /* mesma plaquinha do mapa, mas aqui ela e COLORIDA com texto branco, entao o
     livro herda o branco (currentColor) em vez do #C2410C - laranja sobre um
     topico verde ou teal seria ruido, e o contraste ja vem do fundo cheio */
  .study-branchhead .art{display:inline-flex;align-items:center;gap:5px;min-height:24px;
    margin-top:6px;font-size:12px;font-weight:900;
    background:var(--c);color:#fff;border-radius:999px;padding:4px 12px}
  .study-branchhead .art svg{width:13px;height:13px;flex:0 0 auto;stroke:currentColor}
  .study-cards{display:grid;grid-template-columns:1fr;gap:16px;margin-top:14px}
  .study-cards .sub{width:auto}
  /* Duas colunas encaixadas (set/2026): encaixarColunas() em map-engine.js põe cada
     card na coluna mais baixa, na ordem. Sem JS (ou caixa estreita) vale a grade
     de uma coluna acima. */
  .study-cards.is-encaixe{display:block;position:relative}
  .study-cards.is-encaixe > *{position:absolute;margin:0;box-sizing:border-box}

  /* ==========================================================================
     ESTUDO RAPIDO EM TELA ESTREITA (jul/2026): abaixo de 720px o chiprail
     (texto cheio de cada topico, sem quebra) nao cabe lado a lado e QUEBRA em
     ate 3 linhas; como .study-top e sticky, essas 3 linhas ficam grudadas no
     topo o tempo todo e comem boa parte da tela, atrapalhando a leitura dos
     cards. So entra em vigor aqui dentro do media query: em telas normais o
     chiprail continua quebrando linha exatamente como antes, sem rolagem e
     sem cabecalho retratil: nada disso e necessario quando ja cabe tudo.
     ========================================================================== */
  @media (max-width:720px){
    .chiprail{
      flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;justify-content:flex-start;
      -webkit-overflow-scrolling:touch;padding:2px 2px 8px;margin:10px -12px 0;padding-left:12px;padding-right:12px;
      /* barra de rolagem oculta (ago/2026): no toque ela ja e sobreposta e
         some sozinha; quem a mostrava permanente era so a janela estreita de
         desktop, roubando os 8px do padding. O convite a rolar e o chip
         cortado na borda, como nos trilhos de chips do mercado - e a rolagem
         continua por arrasto, trackpad e Shift+roda. */
      scrollbar-width:none;
    }
    .chiprail::-webkit-scrollbar{display:none}
    .chip{flex:0 0 auto;white-space:nowrap;padding:4px 10px 4px 6px;font-size:11.5px;gap:5px;border-width:2.5px}
    .chip .dot{width:17px;height:17px;flex:0 0 17px}
    .chip .dot svg{width:17px;height:17px}
    /* cabecalho (icone+titulo) recolhe ao rolar os cards, deixando so a
       fileira fina de chips fixa no topo; a classe .collapsed e alternada em
       JS (ver map-engine.js) e so tem efeito aqui dentro do media query */
    .study-center{
      max-height:90px;opacity:1;overflow:hidden;
      transition:max-height .2s ease, opacity .2s ease, padding .2s ease, margin .2s ease, border-width .2s ease;
    }
    .study-top.collapsed{padding-bottom:2px}
    .study-top.collapsed .study-center{
      max-height:0;opacity:0;padding-top:0;padding-bottom:0;margin-top:0;margin-bottom:0;border-width:0;
    }
  }

  /* ------------ modal jurisprudência ------------ */
  .modal-bg{position:fixed;inset:0;z-index:60;background:rgba(40,24,8,.55);
    display:flex;align-items:center;justify-content:center;padding:18px;backdrop-filter:blur(2px)}
  .modal-bg.hidden{display:none}
  .modal{max-width:520px;width:100%;background:#FFFDF8;border:4px solid var(--ink);border-radius:20px;
    border-top:11px solid var(--c);box-shadow:0 14px 34px rgba(0,0,0,.35);padding:18px 20px 20px;
    max-height:min(600px,90vh);max-height:min(600px,90dvh);overflow:auto;
    animation:pop .18s ease-out}
  .modal .mhead{display:flex;align-items:center;gap:10px;margin-bottom:4px}
  .modal .mscale{flex:0 0 40px;width:40px;height:40px;border-radius:50%;background:linear-gradient(180deg,#FFE08A,#F5B93A);
    border:2.5px solid var(--ink);display:flex;align-items:center;justify-content:center;color:#5A3A00}
  .modal .mscale svg{width:22px;height:22px}
  .modal .mtag{font-weight:900;font-size:11px;letter-spacing:.6px;color:var(--c);text-transform:uppercase}
  .modal h4{font-family:'Fredoka',sans-serif;font-weight:700;font-size:19px;color:var(--ink);line-height:1.05}
  .modal .mref{margin-top:12px;font-weight:900;font-size:14.5px;color:#fff;background:var(--c);
    border-radius:12px;padding:8px 12px;line-height:1.25}
  .modal .mtese{margin-top:10px;font-weight:700;font-size:14.5px;line-height:1.42;color:var(--ink)}
  .modal .mtese b{background:var(--soft);border-radius:5px;padding:0 4px}
  .modal .mfoot{margin-top:14px;display:flex;justify-content:space-between;align-items:center;gap:10px}
  .modal .mnote{font-size:11px;font-weight:800;color:#8A6A3A}
  .modal .mclose{font-family:'Fredoka',sans-serif;font-weight:600;font-size:14px;cursor:pointer;
    border:2.5px solid var(--ink);border-radius:12px;padding:7px 16px;background:var(--paper);color:var(--ink);
    box-shadow:0 3px 0 var(--ink)}
  .modal .mclose:active{transform:translateY(2px);box-shadow:0 1px 0 var(--ink)}

  /* ------------ modal da cena (botao do olho) ------------
     Mais largo que o da jurisprudencia (820 x 520 e o formato em que as cenas
     sao desenhadas) e com o teto de altura em dvh, para o celular deitado nao
     esconder o Fechar. A imagem entra com aspect-ratio fixo: sem isso, a
     caixa "pula" de altura quando o arquivo termina de baixar, e o dedo que
     ja estava indo no Fechar acerta outra coisa. */
  /* a altura tem DOIS limites, e os dois sao necessarios: o do modal (para o
     rodape com a referencia e o Fechar caberem na tela sem rolagem) e o da
     caixa da imagem (que senao empurra o rodape para fora numa janela baixa,
     que foi o que aconteceu no primeiro teste: a cena abria bonita e o botao
     Fechar ficava abaixo da dobra). */
  .modal-scene{max-width:860px;max-height:min(94vh,94dvh)}
  /* foto real: a cena desenhada usa 860px porque a arte nasce grande (1400x1050)
     para caber detalhe/rotulo pequeno; uma foto documental nao precisa da
     mesma bitola - caixa mais proxima do modal comum (520px) fica menos
     dominante na tela sem cortar a legenda. */
  .modal-scene.is-foto{max-width:620px}
  .modal-scene .mscale-scene{background:var(--soft);color:var(--c)}
  .scene-wrap{
    margin-top:12px;border:3px solid var(--ink);border-radius:16px;overflow:hidden;
    background:var(--soft);aspect-ratio:4/3;max-height:calc(94vh - 200px);
    display:flex;align-items:center;justify-content:center;
  }
  /* contain, nao cover: a frase-gancho e o selo estao DESENHADOS na imagem,
     entao cortar a borda para preencher a caixa cortaria texto. Quando a
     janela e baixa demais para o 4:3, sobra a cor do topico nas laterais. */
  .scene-wrap img{max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain;display:block}
  /* foto real (scene.tipo="foto"): a caixa 4:3 e o teto de altura existem so
     por causa do canvas fixo da cena desenhada (ver comentario em map-engine.js,
     openScene()). Uma foto tem proporcao propria - travar em 4:3 encolhe a
     LARGURA da caixa inteira quando a janela e baixa (aspect-ratio deriva a
     largura da altura ja espremida pelo max-height), sobrando vao vazio do
     lado. Sem aspect-ratio nem teto de altura, a caixa so limita a largura
     (100% do modal, igual as outras) e a foto preenche por completo. */
  .scene-wrap.is-foto{aspect-ratio:auto;max-height:none}
  .scene-wrap.is-foto img{width:100%;height:auto}
  .modal-scene .mfoot{margin-top:12px}
  .modal-scene .mnote{font-size:12px;font-weight:900;color:var(--c)}
  /* legenda visivel da foto real (variante "foto" da cena, ver map-engine.js) -
     a cena desenhada nunca usa isto, porque a frase-gancho ja esta no desenho */
  .scene-caption{margin-top:10px;font-weight:600;font-size:13.5px;line-height:1.42;color:var(--ink)}

  .branch{position:relative}

  /* ------------ navegação por teclado (setas + enter) ------------ */
  .branch:focus-visible,.sub:focus-visible,.subnode:focus-visible{
    outline:3.5px solid #3B2A1A;outline-offset:3px;
    box-shadow:0 0 0 6px rgba(59,42,26,.28);
  }
  .branch:focus,.sub:focus,.subnode:focus{outline:3.5px solid #3B2A1A;outline-offset:3px}

  /* cor extra da paleta (8º tema) */
  :root{ --indigo:#6366F1; --indigo-soft:#E4E4FF; }
  .t-indigo    {--c:var(--indigo);  --soft:var(--indigo-soft)}
  .branch.t-indigo  {background:linear-gradient(180deg,#8A8BF7,var(--indigo))}
  .chip.t-indigo    {background:linear-gradient(180deg,#8A8BF7,var(--indigo))}

  /* ==========================================================================
     CAMADA DE TEMA (ago/2026): moldura profissional + modo escuro.
     Regra de ouro: SÓ mexe na MOLDURA (barra, painéis, modal, botões, canvas).
     NUNCA toca em .branch/.sub/.subnode/.central (largura, padding, borda,
     fonte): a altura desses cards é medida do DOM e alimenta a física de
     colisão, então mudá-los reembaralha o layout de todos os mapas.
     No escuro os CARDS CONTINUAM CLAROS de propósito: as ilustrações têm
     traço #3B2A1A gravado nos JSONs e sumiriam sobre fundo escuro.
     ========================================================================== */
  :root{
    --ui-canvas:#FFF4E2;
    --ui-dot:rgba(210,140,60,.22);
    --ui-surface:#FFFFFF;
    --ui-surface-2:#F1F0ED;
    --ui-border:#E4E2DE;
    --ui-border-strong:#D6D3CD;
    --ui-text:#1B1917;
    --ui-muted:#6E6862;
    --ui-faint:#9A938B;
    --ui-accent:#C2410C;
    --ui-accent-soft:#FDF0E7;
    --ui-ring:rgba(194,65,12,.20);
    /* o amarelo da estrela e o MESMO do catalogo (--star em catalog.css): o
       favorito precisa ser reconhecido como a mesma coisa nas duas telas */
    --ui-star:#D97706;
    --ui-star-soft:#FEF3C7;
    --ui-sh-sm:0 1px 2px rgba(28,25,23,.05), 0 1px 3px rgba(28,25,23,.04);
    --ui-sh-md:0 2px 4px rgba(28,25,23,.04), 0 8px 20px rgba(28,25,23,.07);
    --ui-sh-lg:0 4px 8px rgba(28,25,23,.05), 0 16px 36px rgba(28,25,23,.11);
  }
  @media (prefers-color-scheme: dark){
    :root:not([data-theme="light"]){
      --ui-canvas:#181411;
      --ui-dot:rgba(255,216,168,.075);
      --ui-surface:#221D19;
      --ui-surface-2:#2B2520;
      --ui-border:#38312A;
      --ui-border-strong:#4A4137;
      --ui-text:#EFE9E1;
      --ui-muted:#A79E94;
      --ui-faint:#7C736A;
      --ui-accent:#FB923C;
      --ui-accent-soft:rgba(251,146,60,.13);
      --ui-ring:rgba(251,146,60,.30);
      --ui-star:#FBBF24;
      --ui-star-soft:rgba(251,191,36,.16);
      --ui-sh-sm:0 1px 2px rgba(0,0,0,.35);
      --ui-sh-md:0 2px 6px rgba(0,0,0,.40), 0 10px 24px rgba(0,0,0,.32);
      --ui-sh-lg:0 6px 14px rgba(0,0,0,.45), 0 20px 44px rgba(0,0,0,.42);
    }
  }
  :root[data-theme="dark"]{
    --ui-canvas:#181411;
    --ui-dot:rgba(255,216,168,.075);
    --ui-surface:#221D19;
    --ui-surface-2:#2B2520;
    --ui-border:#38312A;
    --ui-border-strong:#4A4137;
    --ui-text:#EFE9E1;
    --ui-muted:#A79E94;
    --ui-faint:#7C736A;
    --ui-accent:#FB923C;
    --ui-accent-soft:rgba(251,146,60,.13);
    --ui-ring:rgba(251,146,60,.30);
    --ui-star:#FBBF24;
    --ui-star-soft:rgba(251,191,36,.16);
    --ui-sh-sm:0 1px 2px rgba(0,0,0,.35);
    --ui-sh-md:0 2px 6px rgba(0,0,0,.40), 0 10px 24px rgba(0,0,0,.32);
    --ui-sh-lg:0 6px 14px rgba(0,0,0,.45), 0 20px 44px rgba(0,0,0,.42);
  }

  body{background:var(--ui-canvas)}

  /* ==========================================================================
     MODO NOTURNO DA CAMADA DO MAPA ("papel noturno", fixado jul/2026).
     No escuro o card deixa de ser papel branco e vira papel noturno com texto
     claro. O que impedia isso era a ilustracao: o traco #3B2A1A esta gravado
     nos JSONs e sumiria no card escuro. A saida e a mesma ja usada no
     catalogo: PLAQUINHA PASTEL atras do desenho (ver mais abaixo).
     Numeros: o card sai de 18,97:1 contra o fundo (ofuscante) para 1,19:1, e o
     texto fica em 12,2:1 dentro do card.
     Topicos e hub CONTINUAM COLORIDOS de proposito: a cor identifica o assunto
     e o titulo neles e tinta escura, que exige fundo claro. Eles recebem so a
     atenuacao geral --map-dim, aplicada ao #canvas (conteudo). O fundo mora no
     #viewport, que e o PAI, entao o fundo nao e atenuado junto.
     REGRA DE OURO: nada aqui muda largura, altura, margem ou fonte de card. Os
     unicos padding novos estao em caixas de tamanho fixo com box-sizing:
     border-box, logo a caixa nao cresce e a fisica de colisao segue intacta.
     ========================================================================== */
  :root{ --map-dim:1 }
  :root[data-theme="dark"]{
  --np-card:#2A241D;     /* papel noturno   (1,19:1 de separacao do fundo)     */
  --np-card2:#262019;    /* papel do 4o nivel, um degrau abaixo               */
  --np-txt:#ECE4D8;      /* texto principal (12,2:1 sobre o card)             */
  --np-txt2:#C9BFB0;     /* texto secundario (8,5:1)                          */
  --np-line:#4A4036;     /* contorno: a tinta #3B2A1A sumiria no card escuro  */
  --map-dim:.88;         /* atenuacao geral menor: o card ja nasce escuro     */
}

/* ---------- o card vira papel noturno ---------- */
  :root[data-theme="dark"] .sub{
  background:var(--np-card); color:var(--np-txt);
  border-color:var(--np-line); border-top-color:var(--c);
}
  :root[data-theme="dark"] .subnode{ background:var(--np-card2); color:var(--np-txt) }
  :root[data-theme="dark"] .sub h4,   :root[data-theme="dark"] .subnode h5{ color:var(--np-txt) }

/* ---------- destaques e dicas ----------
   o pastel original (--soft) viraria mancha luminosa no card escuro; usamos a
   propria cor do topico diluida no papel, que mantem o codigo de cor sem brilhar */
  :root[data-theme="dark"] .sub b,   :root[data-theme="dark"] .subnode b{
  background:color-mix(in srgb, var(--c) 22%, var(--np-card));
  color:var(--np-txt); border-bottom-color:var(--c);
}
  :root[data-theme="dark"] .sub code,   :root[data-theme="dark"] .subnode code{
  background:color-mix(in srgb, var(--c) 14%, var(--np-card));
  color:var(--np-txt); border-color:color-mix(in srgb, var(--c) 40%, var(--np-card));
}
  :root[data-theme="dark"] .sub .tip,   :root[data-theme="dark"] .subnode .tip,
  :root[data-theme="dark"] .sub .note,  :root[data-theme="dark"] .subnode .note{
  background:color-mix(in srgb, var(--c) 15%, var(--np-card));
  color:var(--np-txt);
}
/* marcador da lista: o contorno de tinta sumiria, entao ele se funde ao papel */
  :root[data-theme="dark"] .sub li::before,   :root[data-theme="dark"] .subnode li::before{ border-color:var(--np-card) }
  :root[data-theme="dark"] .sub .ladder-pct{
  background:color-mix(in srgb, var(--c) 22%, var(--np-card));
  color:var(--np-txt); border-color:var(--np-card);
}
  /* a barra e um recipiente: fundir a borda ao papel (como no marcador da
     lista) apagaria a caixa das faixas de 100%, que ficariam sem contorno.
     Entao ela usa a cor do topico diluida, visivel sem brilhar. */
  :root[data-theme="dark"] .sub .ladder-bar{
  border-color:color-mix(in srgb, var(--c) 45%, var(--np-card));
}

/* ---------- gráfico do card: só troca as variáveis locais do bloco ---------- */
  :root[data-theme="dark"] .sub .chart,   :root[data-theme="dark"] .subnode .chart{
  --ck-ink:var(--np-txt); --ck-mut:#A8998A; --ck-bg:var(--np-card2); --ck-pt:var(--np-card);
  --ck-txt-c:color-mix(in srgb, var(--c) 70%, #FFFFFF); border-color:var(--np-line);
}

/* ---------- controles dentro do card ---------- */
  :root[data-theme="dark"] .sub .lawlink,   :root[data-theme="dark"] .subnode .lawlink{
  background:color-mix(in srgb, var(--c) 24%, var(--np-card));
  color:var(--np-txt); box-shadow:none;
}
  :root[data-theme="dark"] .sub .lawlink:hover,   :root[data-theme="dark"] .subnode .lawlink:hover{
  background:color-mix(in srgb, var(--c) 40%, var(--np-card)); color:#FFFFFF;
}
  :root[data-theme="dark"] .sub .pencil-btn,   :root[data-theme="dark"] .subnode .pencil-btn{
  background:var(--np-card2); color:var(--np-txt2);
  border-color:var(--np-line); box-shadow:0 2px 0 rgba(0,0,0,.45);
}
  :root[data-theme="dark"] .sub .juris-btn,   :root[data-theme="dark"] .subnode .juris-btn,
  :root[data-theme="dark"] .sub .scene-btn,   :root[data-theme="dark"] .subnode .scene-btn{ border-color:var(--np-line) }

/* ---------- ILUSTRACOES: o ponto critico ----------
   O traco #3B2A1A esta gravado nos JSONs e desapareceria sobre o card
   escuro. Solucao ja validada no catalogo: plaquinha pastel atras do desenho.
   O padding cabe dentro da caixa (box-sizing:border-box), entao nada muda de
   tamanho e o layout dos mapas nao se altera. */
  :root[data-theme="dark"] .sub .mini{ background:var(--soft); border-radius:12px; padding:3px }
  :root[data-theme="dark"] .sub .mini svg{ width:100%; height:100% }
  :root[data-theme="dark"] .li-ico{ background:var(--soft); border-radius:7px; padding:2px }
/* no Estudo rapido a ilustracao do topico fica solta sobre o fundo escuro */
  :root[data-theme="dark"] .study-branchhead .big{
  background:var(--soft); border-radius:16px; padding:5px;
}
  :root[data-theme="dark"] .study-branchhead .big svg{ width:100%; height:100% }

/* Topicos e hub continuam COLORIDOS de proposito: a cor identifica o assunto
   e o titulo neles ja e tinta escura, que exige fundo claro. Eles so recebem a
   atenuacao geral (--map-dim), como na opcao A+B. */


  @media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
  --np-card:#2A241D;     /* papel noturno   (1,19:1 de separacao do fundo)     */
  --np-card2:#262019;    /* papel do 4o nivel, um degrau abaixo               */
  --np-txt:#ECE4D8;      /* texto principal (12,2:1 sobre o card)             */
  --np-txt2:#C9BFB0;     /* texto secundario (8,5:1)                          */
  --np-line:#4A4036;     /* contorno: a tinta #3B2A1A sumiria no card escuro  */
  --map-dim:.88;         /* atenuacao geral menor: o card ja nasce escuro     */
}

/* ---------- o card vira papel noturno ---------- */
  :root:not([data-theme="light"]) .sub{
  background:var(--np-card); color:var(--np-txt);
  border-color:var(--np-line); border-top-color:var(--c);
}
  :root:not([data-theme="light"]) .subnode{ background:var(--np-card2); color:var(--np-txt) }
  :root:not([data-theme="light"]) .sub h4,   :root:not([data-theme="light"]) .subnode h5{ color:var(--np-txt) }

/* ---------- destaques e dicas ----------
   o pastel original (--soft) viraria mancha luminosa no card escuro; usamos a
   propria cor do topico diluida no papel, que mantem o codigo de cor sem brilhar */
  :root:not([data-theme="light"]) .sub b,   :root:not([data-theme="light"]) .subnode b{
  background:color-mix(in srgb, var(--c) 22%, var(--np-card));
  color:var(--np-txt); border-bottom-color:var(--c);
}
  :root:not([data-theme="light"]) .sub code,   :root:not([data-theme="light"]) .subnode code{
  background:color-mix(in srgb, var(--c) 14%, var(--np-card));
  color:var(--np-txt); border-color:color-mix(in srgb, var(--c) 40%, var(--np-card));
}
  :root:not([data-theme="light"]) .sub .tip,   :root:not([data-theme="light"]) .subnode .tip,
  :root:not([data-theme="light"]) .sub .note,  :root:not([data-theme="light"]) .subnode .note{
  background:color-mix(in srgb, var(--c) 15%, var(--np-card));
  color:var(--np-txt);
}
/* marcador da lista: o contorno de tinta sumiria, entao ele se funde ao papel */
  :root:not([data-theme="light"]) .sub li::before,   :root:not([data-theme="light"]) .subnode li::before{ border-color:var(--np-card) }
  :root:not([data-theme="light"]) .sub .ladder-pct{
  background:color-mix(in srgb, var(--c) 22%, var(--np-card));
  color:var(--np-txt); border-color:var(--np-card);
}
  :root:not([data-theme="light"]) .sub .ladder-bar{
  border-color:color-mix(in srgb, var(--c) 45%, var(--np-card));
}

/* ---------- gráfico do card: só troca as variáveis locais do bloco ---------- */
  :root:not([data-theme="light"]) .sub .chart,   :root:not([data-theme="light"]) .subnode .chart{
  --ck-ink:var(--np-txt); --ck-mut:#A8998A; --ck-bg:var(--np-card2); --ck-pt:var(--np-card);
  --ck-txt-c:color-mix(in srgb, var(--c) 70%, #FFFFFF); border-color:var(--np-line);
}

/* ---------- controles dentro do card ---------- */
  :root:not([data-theme="light"]) .sub .lawlink,   :root:not([data-theme="light"]) .subnode .lawlink{
  background:color-mix(in srgb, var(--c) 24%, var(--np-card));
  color:var(--np-txt); box-shadow:none;
}
  :root:not([data-theme="light"]) .sub .lawlink:hover,   :root:not([data-theme="light"]) .subnode .lawlink:hover{
  background:color-mix(in srgb, var(--c) 40%, var(--np-card)); color:#FFFFFF;
}
  :root:not([data-theme="light"]) .sub .pencil-btn,   :root:not([data-theme="light"]) .subnode .pencil-btn{
  background:var(--np-card2); color:var(--np-txt2);
  border-color:var(--np-line); box-shadow:0 2px 0 rgba(0,0,0,.45);
}
  :root:not([data-theme="light"]) .sub .juris-btn,   :root:not([data-theme="light"]) .subnode .juris-btn,
  :root:not([data-theme="light"]) .sub .scene-btn,   :root:not([data-theme="light"]) .subnode .scene-btn{ border-color:var(--np-line) }

/* ---------- ILUSTRACOES: o ponto critico ----------
   O traco #3B2A1A esta gravado nos JSONs e desapareceria sobre o card
   escuro. Solucao ja validada no catalogo: plaquinha pastel atras do desenho.
   O padding cabe dentro da caixa (box-sizing:border-box), entao nada muda de
   tamanho e o layout dos mapas nao se altera. */
  :root:not([data-theme="light"]) .sub .mini{ background:var(--soft); border-radius:12px; padding:3px }
  :root:not([data-theme="light"]) .sub .mini svg{ width:100%; height:100% }
  :root:not([data-theme="light"]) .li-ico{ background:var(--soft); border-radius:7px; padding:2px }
/* no Estudo rapido a ilustracao do topico fica solta sobre o fundo escuro */
  :root:not([data-theme="light"]) .study-branchhead .big{
  background:var(--soft); border-radius:16px; padding:5px;
}
  :root:not([data-theme="light"]) .study-branchhead .big svg{ width:100%; height:100% }

/* Topicos e hub continuam COLORIDOS de proposito: a cor identifica o assunto
   e o titulo neles ja e tinta escura, que exige fundo claro. Eles so recebem a
   atenuacao geral (--map-dim), como na opcao A+B. */

  }

  #canvas,.study-body,.chiprail{ filter:brightness(var(--map-dim)) }

  /* ---------- barra superior ---------- */
  .topbar{
    padding:0 16px;height:56px;gap:12px;flex-wrap:nowrap;
    background:color-mix(in srgb, var(--ui-surface) 85%, transparent);
    backdrop-filter:saturate(180%) blur(14px);
    -webkit-backdrop-filter:saturate(180%) blur(14px);
    border-bottom:1px solid var(--ui-border);
    box-shadow:none;
  }
  .topbar > div:first-of-type{min-width:0}
  /* O bloco de IDENTIDADE do mapa: [titulo + subtitulo] [estrela]. A estrela
     mora aqui, e nao em .controls, por tres motivos: ela age sobre O MAPA (o
     mesmo objeto que o titulo nomeia) e nao sobre a visualizacao, como zoom,
     modo e tema; abaixo de 720px .controls nasce RECOLHIDO atras do chevron, e
     favoritar e justamente o que mais se quer fazer no celular; e .controls ja
     tem oito controles, onde um nono nao seria notado.
     O texto usa flex:0 1 auto para a estrela encostar no titulo quando ele e
     curto, em vez de flutuar sozinha no meio da barra. */
  .tbident{display:flex;align-items:center;gap:4px}
  .tbident-texts{flex:0 1 auto;min-width:0}
  .topbar h1{
    font-family:'Inter',system-ui,sans-serif;font-weight:600;letter-spacing:-.015em;
    font-size:clamp(13.5px,1.9vw,16px);color:var(--ui-text);text-shadow:none;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  }
  .topbar small{
    font-family:'Inter',system-ui,sans-serif;font-weight:500;font-size:10px;
    letter-spacing:.04em;color:var(--ui-faint);
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;
  }
  .homelink{
    width:32px;height:32px;border-radius:9px;
    background:var(--ui-accent-soft);border:none;box-shadow:none;
  }
  .homelink svg{width:21px;height:auto}
  .homelink:hover{background:var(--ui-surface-2)}
  .homelink:active{transform:none;box-shadow:none}
  .homelink:focus-visible{outline:2px solid var(--ui-accent);outline-offset:2px}
  .subjectlink{
    background:var(--ui-surface);border:1px solid var(--ui-border);color:var(--ui-accent);
    box-shadow:var(--ui-sh-sm)
  }
  .subjectlink:hover{background:var(--ui-surface-2)}
  .subjectlink:active{transform:none;box-shadow:var(--ui-sh-sm)}
  .subjectlink:focus-visible{outline:2px solid var(--ui-accent);outline-offset:2px}

  /* ---------- botões da barra ---------- */
  .modeswitch{
    background:var(--ui-surface-2);border:1px solid var(--ui-border);
    border-radius:10px;padding:2px;box-shadow:none;gap:2px;
  }
  .modeswitch button{
    font-family:'Inter',system-ui,sans-serif;font-weight:500;font-size:12.5px;
    border-radius:8px;padding:5px 11px;color:var(--ui-muted);background:transparent;
  }
  .modeswitch button:hover{color:var(--ui-text)}
  .modeswitch button.active{
    background:var(--ui-surface);color:var(--ui-text);text-shadow:none;
    box-shadow:var(--ui-sh-sm);font-weight:600;
  }
  .zoomctl button{
    font-family:'Inter',system-ui,sans-serif;font-weight:500;font-size:12.5px;
    border:1px solid var(--ui-border);border-radius:10px;
    background:var(--ui-surface);color:var(--ui-muted);box-shadow:var(--ui-sh-sm);
    padding:5px 10px;
  }
  .zoomctl button{min-width:34px;padding:5px 9px}
  .zoomctl button:hover{
    background:var(--ui-surface-2);color:var(--ui-text);border-color:var(--ui-border-strong);
  }
  .zoomctl button:active{transform:none;box-shadow:var(--ui-sh-sm)}
  .zoomctl button:focus-visible,
  .modeswitch button:focus-visible{outline:2px solid var(--ui-accent);outline-offset:1px}

  /* estrela de favorito (fica ao lado do titulo, ver .tbident) */
  .favbtn{
    flex:0 0 auto;width:32px;height:32px;border-radius:10px;cursor:pointer;padding:0;
    display:flex;align-items:center;justify-content:center;
    background:transparent;border:1px solid transparent;color:var(--ui-muted);
    transition:background-color .15s ease,border-color .15s ease,color .15s ease;
  }
  .favbtn svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.9}
  .favbtn:hover{background:var(--ui-surface-2);color:var(--ui-text);border-color:var(--ui-border)}
  .favbtn:focus-visible{outline:2px solid var(--ui-accent);outline-offset:1px}
  .favbtn[aria-pressed="true"]{background:var(--ui-star-soft);border-color:transparent;color:var(--ui-star)}
  .favbtn[aria-pressed="true"] svg{fill:var(--ui-star);stroke:var(--ui-star)}
  /* a estrela estala ao ser ligada: e o unico retorno imediato que existe antes
     de o aviso subir no rodape */
  @keyframes favPop{0%{transform:scale(1)}45%{transform:scale(1.3)}100%{transform:scale(1)}}
  .favbtn.fav-pop svg{animation:favPop .34s ease}
  @media (prefers-reduced-motion:reduce){
    :root:not([data-motion="full"]) .favbtn{transition:none}
    :root:not([data-motion="full"]) .favbtn.fav-pop svg{animation:none}
  }
  :root[data-motion="reduced"] .favbtn{transition:none}
  :root[data-motion="reduced"] .favbtn.fav-pop svg{animation:none}

  /* alternador de tema (claro/escuro) */
  .themebtn{
    flex:0 0 auto;width:32px;height:32px;border-radius:10px;cursor:pointer;padding:0;
    display:flex;align-items:center;justify-content:center;
    background:transparent;border:1px solid transparent;color:var(--ui-muted);
  }
  .themebtn svg{width:16px;height:16px}
  .themebtn:hover{background:var(--ui-surface-2);color:var(--ui-text);border-color:var(--ui-border)}
  .themebtn:focus-visible{outline:2px solid var(--ui-accent);outline-offset:1px}
  .themebtn .i-sun{display:none}
  .themebtn .i-moon{display:block}
  @media (prefers-color-scheme: dark){
    :root:not([data-theme="light"]) .themebtn .i-sun{display:block}
    :root:not([data-theme="light"]) .themebtn .i-moon{display:none}
  }
  :root[data-theme="dark"] .themebtn .i-sun{display:block}
  :root[data-theme="dark"] .themebtn .i-moon{display:none}
  :root[data-theme="light"] .themebtn .i-sun{display:none}
  :root[data-theme="light"] .themebtn .i-moon{display:block}

  /* ---------- canvas ---------- */
  #viewport{
    background:
      radial-gradient(circle at 1px 1px, var(--ui-dot) 1.7px, transparent 0) 0 0/26px 26px,
      var(--ui-canvas);
  }
  /* as linhas usam a cor do tópico: no escuro ganham um empurrão de brilho */
  :root[data-theme="dark"] #ovwires{filter:saturate(1.1) brightness(1.25)}
  @media (prefers-color-scheme: dark){
    :root:not([data-theme="light"]) #ovwires{filter:saturate(1.1) brightness(1.25)}
  }

  /* ---------- painel lateral ---------- */
  #sidePanel{background:var(--ui-surface);border-left-color:var(--ui-border)}
  #sidePanel.open{border-left-width:1px}
  .sp-head{
    background:var(--ui-surface);border-bottom:1px solid var(--ui-border);
    padding:13px 16px;
  }
  .sp-head .sp-icon{
    background:var(--ui-accent-soft);border:none;color:var(--ui-accent);border-radius:9px;
  }
  .sp-head .sp-icon svg{stroke:var(--ui-accent)}
  .sp-head h3{
    font-family:'Inter',system-ui,sans-serif;font-weight:600;font-size:14.5px;
    letter-spacing:-.01em;color:var(--ui-text);
  }
  .sp-head small{
    font-family:'Inter',system-ui,sans-serif;font-weight:450;font-size:11.5px;
    letter-spacing:0;color:var(--ui-muted);
  }
  .sp-close{
    font-family:'Inter',system-ui,sans-serif;font-weight:500;font-size:12.5px;
    border:1px solid var(--ui-border);border-radius:9px;
    background:var(--ui-surface);color:var(--ui-muted);box-shadow:var(--ui-sh-sm);
  }
  .sp-close:hover{background:var(--ui-surface-2);color:var(--ui-text)}
  .sp-close:active{transform:none;box-shadow:var(--ui-sh-sm)}
  .sp-body{padding:16px 18px 28px}

  /* lei seca */
  .law-art{border-bottom:1px solid var(--ui-border);padding-bottom:16px;margin-bottom:18px}
  .law-art h4{
    font-family:'Inter',system-ui,sans-serif;font-weight:600;font-size:13px;
    letter-spacing:.02em;text-transform:uppercase;color:var(--ui-accent);margin-bottom:8px;
  }
  .law-line{font-size:13.5px;line-height:1.6;color:var(--ui-text);font-weight:450}
  .law-line.indent{color:var(--ui-muted);padding-left:16px}
  .law-inc-line{display:block;padding-left:22px}
  .law-inc-line.law-inc-l2{padding-left:44px}
  /* tabela da norma (set/2026): rola na horizontal dentro do proprio
     involucro, nunca a pagina. As duas sombras nas bordas so aparecem quando
     ha coluna escondida daquele lado (as capas "local" cobrem a sombra quando
     a rolagem chega ao fim): sem elas, a coluna cortada parecia nao existir. */
  .law-table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;margin:10px 0 12px;
    border:1px solid var(--ui-border);border-radius:8px;
    background:
      linear-gradient(to right, var(--ui-surface) 30%, transparent) left center / 28px 100% no-repeat local,
      linear-gradient(to left, var(--ui-surface) 30%, transparent) right center / 28px 100% no-repeat local,
      radial-gradient(farthest-side at 0 50%, color-mix(in srgb, var(--ui-text) 22%, transparent), transparent) left center / 10px 100% no-repeat scroll,
      radial-gradient(farthest-side at 100% 50%, color-mix(in srgb, var(--ui-text) 22%, transparent), transparent) right center / 10px 100% no-repeat scroll;
    background-color:var(--ui-surface)}
  .law-table{border-collapse:collapse;width:100%;font-size:12px;
    line-height:1.45;color:var(--ui-text)}
  .law-table caption{caption-side:top;text-align:left;font-weight:600;font-size:12.5px;
    padding:8px 10px 6px;color:var(--ui-text)}
  .law-table th,.law-table td{border:1px solid var(--ui-border);padding:5px 6px;
    text-align:left;vertical-align:top}
  .law-table tr > :first-child{border-left:0}
  .law-table tr > :last-child{border-right:0}
  .law-table thead tr:first-child > *{border-top:0}
  .law-table tbody tr:last-child > *{border-bottom:0}
  .law-table th{background:var(--ui-surface-2);font-weight:600;hyphens:auto;-webkit-hyphens:auto}
  .law-table td{font-weight:450;min-width:6.5em;hyphens:auto;-webkit-hyphens:auto;overflow-wrap:break-word}
  .law-table .law-cel-curta{white-space:nowrap;min-width:0}
  /* o selo de artigo DENTRO do card não muda (é conteúdo); aqui é só o link do painel */
  .sp-body .lawlink{color:var(--ui-accent);border-bottom-color:var(--ui-accent);font-weight:600}
  .sp-body .lawlink:hover{color:var(--ui-text)}
  .law-highlight-wrap.mt-ativa .law-highlight{box-shadow:0 0 0 2px var(--ui-text)}

  /* "ler a lei completa": mora no CABECALHO do painel, ao lado do "Fechar" -
     e uma acao do painel inteiro, nao um item de conteudo, entao fica discreta
     (pilula pequena, rotulo curto, no mesmo porte do "Fechar" ao lado).
     SEM ICONE de proposito (ago/2026): a folha que morava aqui era o segundo
     desenho competindo com o livro da lei seca. O botao ja tem rotulo em
     texto, que e mais claro que qualquer icone - ver "LEI SECA: UM SIMBOLO
     SO" no topo de map-engine.js. */
  .law-full-btn{
    flex:0 0 auto;display:flex;align-items:center;height:28px;padding:0 10px;
    border-radius:999px;cursor:pointer;white-space:nowrap;
    font-family:'Inter',system-ui,sans-serif;font-weight:600;font-size:11.5px;
    border:1px solid var(--ui-border);background:var(--ui-accent-soft);
    color:var(--ui-accent);box-shadow:var(--ui-sh-sm);
  }
  .law-full-btn:hover{background:var(--ui-surface-2)}
  .law-full-btn:active{transform:none;box-shadow:var(--ui-sh-sm)}
  .law-full-btn[hidden]{display:none}

  /* anotações */
  .note-toolbar button{
    font-family:'Inter',system-ui,sans-serif;font-weight:500;font-size:12.5px;
    border:1px solid var(--ui-border);border-radius:8px;
    background:var(--ui-surface);color:var(--ui-text);box-shadow:var(--ui-sh-sm);
  }
  .note-toolbar button:hover{background:var(--ui-surface-2)}
  .note-toolbar button:active{transform:none;box-shadow:var(--ui-sh-sm)}
  /* PALETA DAS ANOTACOES (5 pastilhas fixas, no lugar do seletor de cores do
     sistema - aquele quadro de infinitas cores deixava escolher preto no modo
     escuro e amarelo claro no modo claro, ambos ilegiveis).
     Sao os mesmos cinco tons do marca-texto (HIGHLIGHT_COLORS), mas aqui a cor
     e do TEXTO, nao do fundo: no claro tem de escurecer para ler sobre branco,
     no escuro tem de clarear para ler sobre #221D19. Por isso a nota guarda
     so a CLASSE (.nc-amarelo...), nunca o hex - assim o mesmo texto acerta a
     cor nos dois modos, inclusive quando o aluno troca de tema depois de ter
     escrito. Notas antigas, gravadas com hex embutido pelo seletor antigo,
     continuam valendo como estao (o style inline vence estas regras).
     Desde set/2026 as pastilhas nao ficam mais em linha na barra: moram no
     menu do botao "A" (ver a barra da anotacao mais abaixo), e o preto entrou
     como sexta cor, para voltar ao normal. */
  .note-toolbar .nc-sw{
    width:22px;height:22px;padding:0;border-radius:50%;cursor:pointer;
    border:2px solid var(--ui-border);background:var(--nc);box-shadow:var(--ui-sh-sm);
  }
  .note-toolbar .nc-sw:hover{transform:scale(1.08)}
  .note-toolbar .nc-sw[aria-pressed="true"]{border-color:var(--ui-text);box-shadow:0 0 0 2px var(--ui-ring)}
  .nc{color:var(--nc)}
  .nc-amarelo{--nc:#B45309}
  .nc-verde  {--nc:#15803D}
  .nc-azul   {--nc:#1D4ED8}
  .nc-rosa   {--nc:#BE185D}
  .nc-roxo   {--nc:#6D28D9}
  /* "Preto" é a tinta NORMAL da anotação, e é assim que ele
     serve de "voltar ao normal". Por isso aponta para --ui-text em vez de um
     hex: no tema claro dá quase preto, no escuro dá o creme claro do texto.
     Um "#000" fixo sumiria no papel noturno - exatamente o oposto do que o
     botão promete. Não precisa de par claro/escuro: o token já vira sozinho. */
  .nc-preto  {--nc:var(--ui-text)}
  @media (prefers-color-scheme: dark){
    :root:not([data-theme="light"]) .nc-amarelo{--nc:#FBBF24}
    :root:not([data-theme="light"]) .nc-verde  {--nc:#4ADE80}
    :root:not([data-theme="light"]) .nc-azul   {--nc:#93C5FD}
    :root:not([data-theme="light"]) .nc-rosa   {--nc:#F9A8D4}
    :root:not([data-theme="light"]) .nc-roxo   {--nc:#C4B5FD}
  }
  :root[data-theme="dark"] .nc-amarelo{--nc:#FBBF24}
  :root[data-theme="dark"] .nc-verde  {--nc:#4ADE80}
  :root[data-theme="dark"] .nc-azul   {--nc:#93C5FD}
  :root[data-theme="dark"] .nc-rosa   {--nc:#F9A8D4}
  :root[data-theme="dark"] .nc-roxo   {--nc:#C4B5FD}
  /* botao de salvar (piloto, meta.manualNoteSave): so o icone (disquete),
     mesma cor/fundo dos demais botoes da barra */
  .note-save-btn svg{width:15px;height:15px;stroke:var(--ui-text)}
  .note-editor{
    border:1px solid var(--ui-border);border-radius:10px;
    background:var(--ui-surface);color:var(--ui-text);font-size:13.5px;
  }
  .note-editor:focus{border-color:var(--ui-accent);box-shadow:0 0 0 3px var(--ui-ring)}
  .note-editor:empty:before{color:var(--ui-faint)}
  .note-editor ul,.note-editor ol{padding-left:1.4em;margin:.3em 0}
  .note-editor li{margin:.15em 0}
  .note-editor img{border-color:var(--ui-border)}
  .note-saved{color:#1F9D55;font-weight:600;font-size:11.5px}
  .note-saved.dirty{color:#E5534B}

  /* ---------- barra + balão da anotação ----------
     A regra de ouro aqui é a mesma da paleta de texto acima: a cor viaja em
     CLASSE, nunca em hex gravado na nota, porque a nota tem de continuar
     legível se o aluno trocar de tema depois de escrever. */
  .note-toolbar .nt-sep,.note-toolbar .nt-sep-pop{background:var(--ui-border)}
  .note-toolbar .tx-btn .tx-a{font-family:'Inter',system-ui,sans-serif;font-weight:800;font-size:12.5px}
  .note-toolbar .tx-btn .tx-bar{background:var(--tx-cor, var(--ui-muted))}
  .note-toolbar .mk-btn svg{stroke:var(--ui-text)}
  .note-toolbar .nt-pop{
    background:var(--ui-surface);border:1px solid var(--ui-border);border-radius:10px;
    box-shadow:var(--ui-sh-lg);padding:7px;
  }
  .note-toolbar .nh-sw{
    border:1px solid color-mix(in srgb, var(--nh) 55%, var(--ui-text) 20%);
    box-shadow:var(--ui-sh-sm);
  }
  .note-toolbar .nh-limpa{
    border:1px solid var(--ui-border);
    background:
      linear-gradient(to bottom right,
        transparent calc(50% - 1.5px), var(--ui-faint) calc(50% - 1.5px),
        var(--ui-faint) calc(50% + 1.5px), transparent calc(50% + 1.5px)),
      repeating-linear-gradient(45deg, var(--ui-surface-2), var(--ui-surface-2) 3px,
        var(--ui-surface) 3px, var(--ui-surface) 6px);
  }
  /* MARCA-TEXTO NO ESCURO: o pastel claro por baixo de texto claro apaga a
     palavra. Mesma saída do destaque das teses de jurisprudência - tinge o
     fundo ESCURO com a cor, em vez de aplicar o pastel puro. */
  @media (prefers-color-scheme: dark){
    :root:not([data-theme="light"]) .nh-amarelo{--nh:color-mix(in srgb, #FDE68A 32%, var(--ui-surface))}
    :root:not([data-theme="light"]) .nh-verde  {--nh:color-mix(in srgb, #BBF7D0 32%, var(--ui-surface))}
    :root:not([data-theme="light"]) .nh-azul   {--nh:color-mix(in srgb, #BFDBFE 32%, var(--ui-surface))}
  }
  :root[data-theme="dark"] .nh-amarelo{--nh:color-mix(in srgb, #FDE68A 32%, var(--ui-surface))}
  :root[data-theme="dark"] .nh-verde  {--nh:color-mix(in srgb, #BBF7D0 32%, var(--ui-surface))}
  :root[data-theme="dark"] .nh-azul   {--nh:color-mix(in srgb, #BFDBFE 32%, var(--ui-surface))}

  .nota-balao{
    border:1px solid var(--ui-border);border-radius:14px;background:var(--ui-surface);
    box-shadow:var(--ui-sh-lg);
  }
  .nota-balao .nb-bico{
    background:var(--ui-surface);border-left:1px solid var(--ui-border);border-bottom:1px solid var(--ui-border);
    width:10px;height:10px;
  }
  .nota-balao.a-direita .nb-bico{left:-6px}
  .nota-balao.a-esquerda .nb-bico{right:-6px}
  .nota-balao .nb-cab{border-bottom:1px solid var(--ui-border)}
  .nota-balao .nb-ico{background:var(--ui-accent-soft);color:var(--ui-accent)}
  .nota-balao .nb-titulo{
    font-family:'Inter',system-ui,sans-serif;font-weight:700;font-size:12.5px;color:var(--ui-text);
  }
  .nota-balao .nb-btn{
    border:1px solid var(--ui-border);border-radius:8px;background:var(--ui-surface);
    color:var(--ui-muted);box-shadow:var(--ui-sh-sm);width:25px;height:25px;
  }
  .nota-balao .nb-btn:hover{background:var(--ui-surface-2);color:var(--ui-text)}
  .nota-balao .nb-btn:active{transform:none;box-shadow:var(--ui-sh-sm)}

  /* ---------- estudo rápido ---------- */
  #study{
    background:
      radial-gradient(circle at 1px 1px, var(--ui-dot) 1.6px, transparent 0) 0 0/26px 26px,
      var(--ui-canvas);
  }
  .study-top{
    background:linear-gradient(180deg, var(--ui-canvas), var(--ui-canvas) 78%, transparent);
  }
  .study-center{
    background:var(--ui-surface);border:1px solid var(--ui-border);border-radius:14px;
    box-shadow:var(--ui-sh-sm);padding:11px 18px;
  }
  .study-center h2{
    font-family:'Inter',system-ui,sans-serif;font-weight:600;font-size:17px;
    letter-spacing:-.015em;color:var(--ui-text);text-shadow:none;
  }
  .study-center small{
    font-family:'Inter',system-ui,sans-serif;font-weight:450;font-size:11.5px;
    letter-spacing:0;color:var(--ui-muted);
  }
  /* os chips continuam coloridos: a cor é funcional (identifica o tópico) */
  .chip{
    font-family:'Inter',system-ui,sans-serif;font-weight:500;font-size:12.5px;
    border:none;box-shadow:var(--ui-sh-sm);padding:5px 13px 5px 7px;
  }
  .chip.active::after{box-shadow:0 0 0 2px rgba(0,0,0,.25)}
  .study-branchhead h3{
    font-family:'Inter',system-ui,sans-serif;font-weight:650;letter-spacing:-.02em;font-size:24px;
  }

  /* ---------- modal de jurisprudência ---------- */
  .modal-bg{background:rgba(10,10,12,.55);backdrop-filter:blur(4px)}
  .modal{
    background:var(--ui-surface);border:1px solid var(--ui-border);
    border-top:4px solid var(--c);border-radius:16px;
    box-shadow:var(--ui-sh-lg);padding:20px 22px 22px;
  }
  .modal .mscale{background:var(--ui-accent-soft);border:none;color:var(--ui-accent);border-radius:10px}
  .modal .mtag{
    font-family:'Inter',system-ui,sans-serif;font-weight:600;font-size:10.5px;letter-spacing:.05em;
  }
  .modal h4{
    font-family:'Inter',system-ui,sans-serif;font-weight:600;font-size:17px;
    letter-spacing:-.015em;color:var(--ui-text);line-height:1.25;
  }
  .modal .mref{font-family:'Inter',system-ui,sans-serif;font-weight:600;font-size:13.5px;border-radius:9px}
  .modal .mtese{font-weight:450;font-size:14px;line-height:1.55;color:var(--ui-text)}
  /* destaque (marca-texto) do texto da jurisprudencia: no escuro o --soft pastel
     fica claro igual ao texto claro (--ui-text) e a palavra some. Solucao igual
     a dos cards (.sub b): tinta o fundo escuro com a cor do topico em vez de
     usar o pastel claro, mantendo o texto claro legivel por cima. */
  :root[data-theme="dark"] .modal .mtese b{
    background:color-mix(in srgb, var(--c) 30%, var(--ui-surface));color:var(--ui-text);
  }
  @media (prefers-color-scheme: dark){
    :root:not([data-theme="light"]) .modal .mtese b{
      background:color-mix(in srgb, var(--c) 30%, var(--ui-surface));color:var(--ui-text);
    }
  }
  .modal .mnote{font-family:'Inter',system-ui,sans-serif;font-weight:450;font-size:11.5px;color:var(--ui-faint)}
  .scene-caption{font-family:'Inter',system-ui,sans-serif;font-weight:500;font-size:13.5px;line-height:1.5;color:var(--ui-text)}
  .modal .mclose{
    font-family:'Inter',system-ui,sans-serif;font-weight:500;font-size:13px;
    border:1px solid var(--ui-border);border-radius:9px;
    background:var(--ui-surface);color:var(--ui-text);box-shadow:var(--ui-sh-sm);padding:7px 15px;
  }
  .modal .mclose:hover{background:var(--ui-surface-2)}
  .modal .mclose:active{transform:none;box-shadow:var(--ui-sh-sm)}

  /* foco visível legível nos dois temas */
  .branch:focus-visible,.sub:focus-visible,.subnode:focus-visible,
  .branch:focus,.sub:focus,.subnode:focus{
    outline:3px solid var(--ui-accent);outline-offset:3px;box-shadow:0 0 0 6px var(--ui-ring);
  }

  /* ==========================================================================
     ONDA 1 (ago/2026): profundidade dos cards e tópicos.
     Troca as sombras duras deslocadas ("adesivo") por sombras difusas em
     camadas e suaviza os realces de texto.
     Segurança: box-shadow, text-shadow e filter NÃO participam do layout, então
     nenhuma altura de card muda e a física de colisão fica intacta. Largura,
     padding, borda, fonte e cores dos tópicos seguem exatamente como estavam.
     ========================================================================== */
  :root{
    /* cards flutuando sobre o canvas: precisam de um pouco mais de presença
       que as superfícies da moldura */
    --card-sh:0 1px 2px rgba(28,25,23,.07), 0 4px 10px rgba(28,25,23,.10), 0 12px 24px rgba(28,25,23,.07);
    --card-sh-press:0 1px 2px rgba(28,25,23,.09), 0 2px 5px rgba(28,25,23,.11);
    --card-sh-soft:0 1px 2px rgba(28,25,23,.06), 0 3px 8px rgba(28,25,23,.08);
    --hub-sh:0 2px 4px rgba(28,25,23,.10), 0 10px 24px rgba(28,25,23,.16), 0 24px 48px rgba(28,25,23,.12);
    --illus-sh:drop-shadow(0 3px 6px rgba(28,25,23,.22));
    --illus-sh-lg:drop-shadow(0 5px 12px rgba(28,25,23,.26));
  }
  @media (prefers-color-scheme: dark){
    :root:not([data-theme="light"]){
      --card-sh:0 1px 2px rgba(0,0,0,.45), 0 6px 16px rgba(0,0,0,.42), 0 16px 32px rgba(0,0,0,.34);
      --card-sh-press:0 1px 3px rgba(0,0,0,.5), 0 3px 8px rgba(0,0,0,.45);
      --card-sh-soft:0 1px 3px rgba(0,0,0,.45), 0 4px 10px rgba(0,0,0,.38);
      --hub-sh:0 3px 8px rgba(0,0,0,.5), 0 14px 32px rgba(0,0,0,.5), 0 30px 60px rgba(0,0,0,.42);
      --illus-sh:drop-shadow(0 3px 7px rgba(0,0,0,.5));
      --illus-sh-lg:drop-shadow(0 6px 14px rgba(0,0,0,.55));
    }
  }
  :root[data-theme="dark"]{
    --card-sh:0 1px 2px rgba(0,0,0,.45), 0 6px 16px rgba(0,0,0,.42), 0 16px 32px rgba(0,0,0,.34);
    --card-sh-press:0 1px 3px rgba(0,0,0,.5), 0 3px 8px rgba(0,0,0,.45);
    --card-sh-soft:0 1px 3px rgba(0,0,0,.45), 0 4px 10px rgba(0,0,0,.38);
    --hub-sh:0 3px 8px rgba(0,0,0,.5), 0 14px 32px rgba(0,0,0,.5), 0 30px 60px rgba(0,0,0,.42);
    --illus-sh:drop-shadow(0 3px 7px rgba(0,0,0,.5));
    --illus-sh-lg:drop-shadow(0 6px 14px rgba(0,0,0,.55));
  }

  /* ---------- nó central (hub) ---------- */
  .central{box-shadow:var(--hub-sh)}
  .central.hub-focus{
    box-shadow:0 0 0 5px var(--ui-ring), 0 0 30px rgba(255,178,60,.35), var(--hub-sh);
  }
  /* realce sutil no lugar do relevo tipo carimbo: mantém legibilidade do texto
     branco sobre o gradiente sem o aspecto de desenho animado */
  .central h2{text-shadow:0 1px 0 rgba(255,255,255,.20)}
  .central .illus{filter:var(--illus-sh-lg)}

  /* ---------- tópicos ---------- */
  .branch{box-shadow:var(--card-sh)}
  .branch:active{transform:translateY(1px);box-shadow:var(--card-sh-press)}
  .branch .illus{filter:var(--illus-sh)}
  .branch h3{text-shadow:0 1px 0 rgba(255,255,255,.20)}

  /* ---------- cards e subtópicos ---------- */
  .sub{box-shadow:var(--card-sh)}
  .subnode{box-shadow:var(--card-sh-soft)}

  /* ---------- controles dentro dos cards ---------- */
  .sub .lawlink,.subnode .lawlink{box-shadow:0 1px 2px rgba(28,25,23,.16)}
  .sub .lawlink:active,.subnode .lawlink:active{transform:translateY(1px);box-shadow:none}
  .subtoggle{box-shadow:var(--card-sh-soft)}
  .subtoggle:active{transform:translateY(1px);box-shadow:none}
  .pencil-btn{box-shadow:0 1px 3px rgba(28,25,23,.20)}
  .pencil-btn:active{transform:translateY(1px);box-shadow:none}
  .juris-btn,.scene-btn{box-shadow:0 1px 3px rgba(28,25,23,.20)}
  .juris-btn:active,.scene-btn:active{transform:translateY(1px);box-shadow:none}

  /* ---------- estudo rápido ---------- */
  .study-branchhead .big{filter:var(--illus-sh)}
  .study-cards .sub{box-shadow:var(--card-sh)}

  /* ==========================================================================
     ONDA 2 (ago/2026): tipografia e traço dentro dos cards.
     Objetivo: acabar com o "tudo em negrito", que achatava a hierarquia e
     roubava força do <b> (o termo-chave). O corpo fica em 500 e o
     destaque passa a ser carregado pelo <b>, que já tem fundo e sublinhado.
     Bordas afinam para tirar o aspecto de adesivo.

     ATENÇÃO: diferente da Onda 1, isto MEXE na altura medida dos cards
     (peso de fonte e espessura de borda mudam a quebra de linha), portanto
     exige rebuild + reteste dos 43 mapas. Ambas as mudanças tendem a ENCURTAR
     os cards (texto mais estreito, borda menor), o que alivia a colisão.
     Largura dos cards, cores por tópico e ilustrações continuam intocadas.
     ========================================================================== */

  /* ---------- corpo de texto: deixa o <b> ser o destaque ---------- */
  .sub li{font-weight:500}
  .subnode li{font-weight:500}
  .sub b,.subnode b{font-weight:700}

  /* tips: continuam evidentes, sem gritar */
  .sub .tip{font-weight:600}
  .subnode .tip{font-weight:600}

  /* NÍVEIS 1 e 2 (tema e tópico) SEGUEM EM NEGRITO, de propósito (pedido do
     usuário, ago/2026): o texto explicativo do nó central e os selos de
     referência legislativa são âncoras de leitura, poucas e curtas, e ficam
     melhor com peso alto. O aligeiramento da Onda 2 vale só do 3º nível para
     baixo (itens dos cards e subtópicos), onde o excesso de negrito de fato
     achatava a hierarquia.
     Ou seja: .central p, .central .base, .branch .art e .study-branchhead .art
     mantêm os pesos originais (800/900) e NÃO devem ser sobrescritos aqui. */

  /* ---------- traço mais fino ---------- */
  .central{border-width:2px}
  .branch{border-width:2px}
  .sub{border-width:2px;border-top-width:5px}
  .subnode{border-width:1.5px}
  .sub .tip,.subnode .tip{border-width:1.5px}
  .sub .note,.subnode .note{border-width:1.5px}
  .subtoggle{border-width:1.5px}

  /* ---------- busca nos cards ---------- */
  .map-search{position:relative;flex:0 1 230px;min-width:170px}
  .map-search-field{
    width:100%;height:34px;border:1px solid var(--ui-border);border-radius:9px;
    background:var(--ui-surface);color:var(--ui-text);padding:6px 30px 6px 31px;
    font:500 12.5px 'Inter',system-ui,sans-serif;outline:none;box-shadow:var(--ui-sh-sm)
  }
  .map-search-field::placeholder{color:var(--ui-muted)}
  .map-search-field:focus{border-color:var(--ui-accent);box-shadow:0 0 0 3px var(--ui-ring)}
  .map-search-field::-webkit-search-cancel-button,.map-search-field::-webkit-search-decoration{-webkit-appearance:none;appearance:none}
  .map-search-field::-ms-clear{display:none;width:0;height:0}
  .map-search-icon{position:absolute;left:9px;top:8px;width:17px;height:17px;color:var(--ui-muted);pointer-events:none}
  .map-search-clear{
    display:none;position:absolute;right:6px;top:5px;width:24px;height:24px;border:0;
    border-radius:6px;background:transparent;color:var(--ui-muted);font:700 16px/1 Arial;cursor:pointer
  }
  .map-search.has-value .map-search-clear{display:block}
  .map-search-clear:hover{background:var(--ui-surface-2);color:var(--ui-text)}
  /* position:fixed, nao absolute: `.map-search` muda demais de largura e
     posicao entre desktop largo, janela de desktop estreita e celular para
     servir de ancora sozinho via CSS (right:0 relativo a ele cortava o
     dropdown toda vez que o campo ficava estreito e perto da borda - visto
     em duas larguras diferentes, celular e desktop redimensionado, mesma
     causa). top/left/width REAIS vem sempre de JS a cada abertura
     (posicionarResultados, no modulo de busca) - os valores aqui sao so o
     estado inicial/fallback antes do primeiro calculo. */
  .map-search-results{
    display:none;position:fixed;top:40px;left:0;z-index:80;width:min(360px,82vw);
    max-height:min(330px,55vh);overflow:auto;padding:6px;background:var(--ui-surface);
    border:1px solid var(--ui-border);border-radius:11px;box-shadow:var(--ui-sh-lg)
  }
  .map-search-results.open{display:block}
  .map-search-result{
    display:block;width:100%;border:0;border-radius:8px;background:transparent;color:var(--ui-text);
    padding:9px 10px;text-align:left;font:500 12.5px/1.25 'Inter',system-ui,sans-serif;cursor:pointer
  }
  .map-search-result:hover,.map-search-result:focus{background:var(--ui-surface-2);outline:none}
  .map-search-result strong{display:block;font-weight:650}
  .map-search-result small{display:block;margin-top:3px;color:var(--ui-muted);font-size:10.5px}
  .map-search-empty{padding:12px;color:var(--ui-muted);font:500 12px 'Inter',system-ui,sans-serif;text-align:center}
  .search-hit{animation:searchHit 1s ease-in-out 3;outline:4px solid #F7C948 !important;outline-offset:5px}
  @keyframes searchHit{50%{outline-color:#F97316;filter:brightness(1.05)}}
  .helpbtn{
    flex:0 0 34px;width:34px;height:34px;border:1px solid var(--ui-border);border-radius:9px;
    background:var(--ui-surface);color:var(--ui-text);font:700 16px/1 'Inter',system-ui,sans-serif;
    cursor:pointer;box-shadow:var(--ui-sh-sm)
  }
  .helpbtn:hover{background:var(--ui-surface-2);color:var(--ui-accent)}
  .helpbtn:focus-visible{outline:2px solid var(--ui-accent);outline-offset:1px}
  .allbtn{
    flex:0 0 34px;width:34px;height:28px;border-radius:10px;cursor:pointer;padding:0;
    display:flex;align-items:center;justify-content:center;position:relative;
    background:var(--ui-surface);color:var(--ui-muted);border:1px solid var(--ui-border);box-shadow:var(--ui-sh-sm);
  }
  .allbtn svg{width:15px;height:15px;position:absolute}
  .allbtn .i-collapse{display:none}
  .allbtn[aria-pressed="true"] .i-expand{display:none}
  .allbtn[aria-pressed="true"] .i-collapse{display:block}
  .allbtn:hover{background:var(--ui-surface-2);color:var(--ui-accent);border-color:var(--ui-border-strong)}
  .allbtn:focus-visible{outline:2px solid var(--ui-accent);outline-offset:1px}
  .help-bg{position:fixed;inset:0;z-index:90;display:flex;align-items:center;justify-content:center;padding:18px;background:rgba(15,15,18,.55);backdrop-filter:blur(3px)}
  .help-bg.hidden{display:none}
  .help-card{width:min(620px,96vw);max-height:min(720px,90vh);overflow:auto;border:1px solid var(--ui-border);border-radius:16px;background:var(--ui-surface);color:var(--ui-text);box-shadow:0 24px 70px rgba(0,0,0,.35)}
  .help-head{position:sticky;top:0;z-index:2;display:flex;align-items:center;gap:12px;padding:15px 18px;border-bottom:1px solid var(--ui-border);background:var(--ui-surface)}
  .help-head-icon{flex:0 0 34px;width:34px;height:34px;border-radius:50%;display:flex;align-items:center;justify-content:center;background:var(--ui-accent-soft);color:var(--ui-accent);font:700 17px 'Inter'}
  .help-head h3{flex:1;font:650 17px 'Inter',system-ui,sans-serif}
  .help-close{width:30px;height:30px;border:1px solid var(--ui-border);border-radius:8px;background:var(--ui-surface);color:var(--ui-muted);font:700 17px Arial;cursor:pointer}
  .help-close:hover{background:var(--ui-surface-2);color:var(--ui-text)}
  .help-body{display:grid;grid-template-columns:1fr 1fr;gap:12px;padding:16px}
  .help-section{padding:14px;border:1px solid var(--ui-border);border-radius:12px;background:var(--ui-surface-2)}
  .help-section:last-child{grid-column:1/-1}
  .help-section h4{margin-bottom:9px;color:var(--ui-accent);font:650 12px 'Inter';text-transform:uppercase;letter-spacing:.05em}
  .help-list{list-style:none;display:grid;gap:8px}
  .help-list li{font:450 12.5px/1.4 'Inter',system-ui,sans-serif;color:var(--ui-text)}
  .help-list strong{font-weight:650}
  .help-list kbd,.help-v2 kbd{display:inline-block;min-width:25px;margin-right:4px;padding:2px 6px;border:1px solid var(--ui-border);border-bottom-width:2px;border-radius:5px;background:var(--ui-surface);color:var(--ui-text);font:600 11px 'Inter',system-ui,sans-serif;text-align:center}
  @media(max-width:600px){.help-body{grid-template-columns:1fr}.help-section:last-child{grid-column:auto}}
  /* rodapé da ajuda: "não mostrar automaticamente" + "Entendi". Criado por JS
     (ver o módulo da ajuda em map-engine.js) para não obrigar a remontar todos os
     mapas por causa de uma linha de interface. Fica grudado no fim do cartão,
     que rola: numa tela baixa o aluno precisa alcançar a caixa sem caçar. */
  .help-foot{
    position:sticky;bottom:0;z-index:2;
    display:flex;align-items:center;gap:14px;flex-wrap:wrap;
    padding:13px 18px;border-top:1px solid var(--ui-border);background:var(--ui-surface);
  }
  .help-never{
    display:flex;align-items:center;gap:9px;cursor:pointer;
    font:450 12.5px/1.4 'Inter',system-ui,sans-serif;color:var(--ui-muted);
  }
  .help-never input{
    flex:0 0 auto;width:17px;height:17px;cursor:pointer;accent-color:var(--ui-accent);margin:0;
  }
  .help-never:hover{color:var(--ui-text)}
  .help-never input:focus-visible{outline:2px solid var(--ui-accent);outline-offset:2px}
  .help-got{
    margin-left:auto;flex:0 0 auto;cursor:pointer;
    font:600 13px 'Inter',system-ui,sans-serif;
    padding:8px 18px;border-radius:9px;border:1px solid transparent;
    background:var(--ui-accent);color:#fff;
  }
  .help-got:hover{filter:brightness(1.06)}
  .help-got:focus-visible{outline:2px solid var(--ui-accent);outline-offset:2px}
  @media (pointer:coarse){
    /* a caixinha de 17px é alvo de dedo aqui: quem cresce é o rótulo inteiro,
       que já é clicável por ser <label> */
    .help-never{min-height:44px}
    .help-got{min-height:44px;padding:8px 22px}
  }

  /* ==========================================================================
     AJUDA v2 (ago/2026): "início rápido + referência recolhida".

     O corpo da ajuda era um grid de DUAS colunas, e grid estica as duas
     células de uma linha pela altura da mais alta. Quando a seção "Teclado"
     passou de 4 para 8 itens (os atalhos do foco ampliado, acrescentados por
     JS), a célula vizinha "Navegação" - cinco linhas curtas - passou a
     mostrar metade do bloco vazio. Nenhuma dose de reordenação conserta isso
     em definitivo: basta uma seção crescer de novo e o buraco volta.

     Uma COLUNA só resolve por construção, com qualquer número de seções. E,
     já que o painel se abre sozinho na primeira visita, a primeira tela passa
     a ser curta (três passos numerados + a regra do sentido horário, que é a
     única pedagógica) e o resto vira referência recolhida em <details>: quem
     só quer começar fecha em segundos, quem veio buscar uma tecla abre
     "Atalhos de teclado" e lê uma TABELA (ação à esquerda, tecla ancorada à
     direita), em vez de garimpar teclas dentro de frases.

     O conteúdo é montado por JS (módulo da ajuda em map-engine.js) e não pelo
     template: interface que não muda a estrutura do mapa entra por ali e vale
     para todos os mapas sem rebuild (LEI Nº 10).
     ========================================================================== */
  .help-card.help-compacta{width:min(560px,96vw)}
  .help-head h3 .help-sub{display:block;margin-top:1px;font:450 12.5px 'Inter',system-ui,sans-serif;color:var(--ui-muted)}
  .help-body.help-v2{display:block;padding:0}

  .help-quick{padding:16px 18px 4px}
  .help-passos{list-style:none;display:grid;gap:11px}
  .help-passos li{display:flex;gap:11px;align-items:flex-start;font:450 13px/1.5 'Inter',system-ui,sans-serif;color:var(--ui-text)}
  .help-passos b{font-weight:650}
  .help-passo-n{
    flex:0 0 24px;width:24px;height:24px;border-radius:50%;
    display:flex;align-items:center;justify-content:center;
    background:var(--ui-accent);color:#fff;font:700 12px 'Inter',system-ui,sans-serif
  }
  /* o item do "voltar ao menu" não é passo do fluxo: mesmo lugar na lista,
     peso menor, para os três primeiros seguirem lidos como sequência */
  .help-passos li.secundario .help-passo-n{background:var(--ui-surface-2);color:var(--ui-muted)}

  /* "estude no sentido horário" não é instrução de interface, é a única regra
     de ESTUDO da ajuda - dentro de uma lista de cliques ela desaparecia */
  .help-destaque{
    display:flex;gap:11px;align-items:flex-start;margin-top:13px;
    padding:12px 13px;border-radius:12px;
    border:1px solid var(--ui-accent);background:var(--ui-accent-soft)
  }
  .help-destaque svg{flex:0 0 18px;width:18px;height:18px;color:var(--ui-accent);margin-top:1px}
  .help-destaque p{font:450 12.5px/1.5 'Inter',system-ui,sans-serif;color:var(--ui-text)}
  .help-destaque b{font-weight:650}

  .help-acc{padding:14px 18px 18px;display:grid;gap:8px}
  .help-acc details{border:1px solid var(--ui-border);border-radius:12px;background:var(--ui-surface-2);overflow:hidden}
  .help-acc summary{
    display:flex;align-items:center;gap:10px;cursor:pointer;list-style:none;
    padding:12px 13px;font:600 13px 'Inter',system-ui,sans-serif;color:var(--ui-text)
  }
  .help-acc summary::-webkit-details-marker{display:none}
  .help-acc summary:hover{background:var(--ui-surface)}
  .help-acc summary:focus-visible{outline:2px solid var(--ui-accent);outline-offset:-2px}
  .help-acc summary small{display:block;margin-top:1px;font:450 11.5px 'Inter',system-ui,sans-serif;color:var(--ui-muted)}
  .help-sum-ico{
    flex:0 0 26px;width:26px;height:26px;border-radius:8px;
    display:flex;align-items:center;justify-content:center;
    background:var(--ui-accent-soft);color:var(--ui-accent)
  }
  .help-sum-ico svg{width:15px;height:15px}
  .help-chev{margin-left:auto;color:var(--ui-faint);transition:transform .18s ease}
  .help-acc details[open] > summary .help-chev{transform:rotate(180deg)}
  @media (prefers-reduced-motion:reduce){:root:not([data-motion="full"]) .help-chev{transition:none}}
  :root[data-motion="reduced"] .help-chev{transition:none}
  .help-det-body{padding:2px 13px 14px}

  .help-atalhos{list-style:none;display:grid;gap:2px}
  .help-atalhos li{
    display:flex;align-items:baseline;gap:10px;padding:6px 0;
    border-bottom:1px dashed var(--ui-border);
    font:450 12.5px/1.45 'Inter',system-ui,sans-serif;color:var(--ui-text)
  }
  .help-atalhos li:last-child{border-bottom:0}
  .help-atalhos .acao{flex:1;min-width:0}
  .help-atalhos .teclas{flex:0 0 auto;display:flex;gap:3px;white-space:nowrap}
  .help-atalhos .teclas kbd{margin-right:0}
  .help-atalhos em{font-style:normal;color:var(--ui-faint)}
  .help-nota{
    margin-top:10px;padding:9px 11px;border-radius:9px;background:var(--ui-accent-soft);
    font:450 12px/1.5 'Inter',system-ui,sans-serif;color:var(--ui-text)
  }
  .help-nota b{font-weight:650}

  /* ==========================================================================
     RELATAR UM PROBLEMA (ago/2026)

     A bandeira herda .helpbtn (mesmo porte do "?" ao lado, e já entra de graça
     na regra de alvo de 44px do bloco `(pointer:coarse)` no fim deste arquivo).
     Só precisa do tamanho do SVG, que o "?" não tem por ser texto.

     A cor é var(--ui-accent), e não a tinta dos outros ícones da barra: o
     botão precisa ser achável sem competir com os controles de uso frequente
     (busca, zoom, lápis). Ele forma um par de "suporte" com o "?" no fim da
     barra - a taxa de clique esperada num botão desses é baixa (0,3-1,2% em
     produtos de painel), então o lugar dele é o canto, não o centro.
     ========================================================================== */
  .bugbtn{display:flex;align-items:center;justify-content:center;color:var(--ui-accent)}
  .bugbtn svg{width:15px;height:15px}
  .bugbtn:hover{background:var(--ui-surface-2);color:var(--ui-accent)}

  .bug-card{width:min(430px,96vw)}
  .bug-head-icon{color:var(--ui-accent);background:var(--ui-accent-soft)}
  .bug-head-icon svg{width:16px;height:16px}
  .bug-body{padding:14px 16px 16px}
  /* diz o que o relato leva junto. É o MAPA, não o card: o botão vive na barra,
     que é geral - ver o comentário longo em map-engine.js */
  .bug-ctx{
    font:600 12px/1.45 'Inter',system-ui,sans-serif;color:var(--ui-accent);
    background:var(--ui-accent-soft);border-radius:9px;padding:8px 11px;
  }
  .bug-label{display:block;font:650 12px 'Inter',system-ui,sans-serif;color:var(--ui-muted);margin:13px 0 7px}
  .bug-chips{display:flex;flex-wrap:wrap;gap:6px}
  .bug-chip{
    font:600 11.5px 'Inter',system-ui,sans-serif;padding:6px 11px;border-radius:999px;cursor:pointer;
    border:1.5px solid var(--ui-border);background:var(--ui-surface);color:var(--ui-text);
  }
  .bug-chip:hover{border-color:var(--ui-border-strong)}
  .bug-chip.on{border-color:var(--ui-accent);background:var(--ui-accent-soft);color:var(--ui-accent)}
  .bug-chip:focus-visible{outline:2px solid var(--ui-accent);outline-offset:1px}
  .bug-ta{
    width:100%;border:1px solid var(--ui-border);border-radius:9px;resize:vertical;
    background:var(--ui-surface-2);color:var(--ui-text);
    font:450 13px/1.5 'Inter',system-ui,sans-serif;padding:9px 11px;
  }
  .bug-ta:focus{outline:2px solid var(--ui-accent);outline-offset:1px}
  .bug-erro{
    margin-top:9px;font:600 12px/1.45 'Inter',system-ui,sans-serif;
    color:#B42318;background:#FEF3F2;border:1px solid #FDA29B;border-radius:8px;padding:7px 10px;
  }
  .bug-erro[hidden]{display:none}
  .bug-actions{display:flex;justify-content:flex-end;gap:9px;margin-top:14px}
  .bug-btn2{
    height:33px;padding:0 13px;border-radius:9px;cursor:pointer;
    border:1px solid var(--ui-border);background:var(--ui-surface);color:var(--ui-text);
    font:650 12.5px 'Inter',system-ui,sans-serif;
  }
  .bug-btn2:hover{background:var(--ui-surface-2)}
  .bug-btn1{
    height:33px;padding:0 15px;border-radius:9px;border:none;cursor:pointer;
    background:var(--laranja);color:#fff;font:700 12.5px 'Inter',system-ui,sans-serif;
    box-shadow:0 2px 0 rgba(59,42,26,.28);
  }
  .bug-btn1:hover{filter:brightness(1.05)}
  .bug-btn1:disabled{opacity:.6;cursor:default;box-shadow:none}
  .bug-btn1:focus-visible,.bug-btn2:focus-visible{outline:2px solid var(--ui-accent);outline-offset:2px}
  .bug-form[hidden],.bug-ok[hidden]{display:none}
  .bug-ok{text-align:center;padding:16px 6px 8px}
  .bug-tick{
    width:44px;height:44px;border-radius:50%;margin:0 auto 11px;
    display:flex;align-items:center;justify-content:center;
    background:var(--ui-accent-soft);color:var(--ui-accent);
  }
  .bug-tick svg{width:22px;height:22px}
  .bug-ok p{font:700 14px 'Inter',system-ui,sans-serif;color:var(--ui-text);margin:0 0 5px}
  .bug-ok small{font:450 12.5px/1.5 'Inter',system-ui,sans-serif;color:var(--ui-muted)}

  .help-recursos{list-style:none;display:grid;gap:10px}
  .help-recursos li{display:flex;gap:10px;align-items:flex-start;font:450 12.5px/1.45 'Inter',system-ui,sans-serif}
  .help-rec-ico{
    flex:0 0 26px;width:26px;height:26px;border-radius:8px;
    display:flex;align-items:center;justify-content:center;
    background:var(--ui-accent-soft);color:var(--ui-accent)
  }
  .help-rec-ico svg{width:15px;height:15px}
  .help-recursos b{display:block;font-weight:650;color:var(--ui-text)}
  .help-recursos .desc{color:var(--ui-muted)}
  @media (pointer:coarse){
    /* a barra do <summary> é o alvo de dedo que abre cada seção */
    .help-acc summary{min-height:52px}
  }
  .sub .lawlink,.subnode .lawlink,.central .lawlink{border-width:1.5px}
  .sub b,.subnode b{border-bottom-width:1.5px}

  /* marcador dos itens: bolinha limpa, sem o contorno escuro grosso */
  .sub li::before,.subnode li::before{border:none}

  /* ==========================================================================
     REVISÕES ESPAÇADAS (botão do topbar + painel): segue a MOLDURA (--ui-*).
     Estados do botão: .set (agendado, em dia) · .due (pendente hoje) ·
     .late (atrasada). O ponto (.rev-dot) só aparece quando há pendência.
     ========================================================================== */
  :root{
    --rev-danger:#DC2626;
    --rev-danger-soft:rgba(220,38,38,.10);
    --rev-ok:#15803D;
    --rev-ok-soft:rgba(21,128,61,.10);
  }
  @media (prefers-color-scheme: dark){
    :root:not([data-theme="light"]){
      --rev-danger:#F87171;
      --rev-danger-soft:rgba(248,113,113,.14);
      --rev-ok:#4ADE80;
      --rev-ok-soft:rgba(74,222,128,.14);
    }
  }
  :root[data-theme="dark"]{
    --rev-danger:#F87171;
    --rev-danger-soft:rgba(248,113,113,.14);
    --rev-ok:#4ADE80;
    --rev-ok-soft:rgba(74,222,128,.14);
  }

  .revwrap{position:relative;flex:0 0 auto}
  .revbtn{
    position:relative;width:32px;height:32px;border-radius:10px;cursor:pointer;padding:0;
    display:flex;align-items:center;justify-content:center;
    background:transparent;border:1px solid transparent;color:var(--ui-muted);
  }
  .revbtn svg{width:16px;height:16px}
  .revbtn:hover{background:var(--ui-surface-2);color:var(--ui-text);border-color:var(--ui-border)}
  .revbtn:focus-visible{outline:2px solid var(--ui-accent);outline-offset:1px}
  .revbtn.set{color:var(--ui-accent)}
  .revbtn.due{color:var(--ui-accent);background:var(--ui-accent-soft);border-color:transparent}
  .revbtn.late{color:var(--rev-danger);background:var(--rev-danger-soft)}
  .rev-dot{
    position:absolute;top:4px;right:4px;width:8px;height:8px;border-radius:50%;
    background:var(--ui-accent);box-shadow:0 0 0 2px var(--ui-surface);
    animation:revpulse 2s ease-in-out infinite;
  }
  .revbtn.late .rev-dot{background:var(--rev-danger)}
  @keyframes revpulse{
    0%,100%{transform:scale(1);opacity:1}
    50%{transform:scale(1.35);opacity:.65}
  }
  @media (prefers-reduced-motion: reduce){ :root:not([data-motion="full"]) .rev-dot{animation:none} }
  :root[data-motion="reduced"] .rev-dot{animation:none}

  .rev-panel{
    position:absolute;top:calc(100% + 8px);right:0;z-index:60;
    width:min(320px, calc(100vw - 24px));
    background:var(--ui-surface);border:1px solid var(--ui-border);border-radius:14px;
    box-shadow:var(--ui-sh-lg);padding:14px;
    font-family:'Inter',system-ui,sans-serif;color:var(--ui-text);
    text-align:left;
  }
  .rev-panel.hidden{display:none}
  .rev-head{display:flex;align-items:center;gap:10px;margin-bottom:10px}
  .rev-head .rev-ic{
    width:30px;height:30px;flex:0 0 30px;border-radius:9px;
    background:var(--ui-accent-soft);color:var(--ui-accent);
    display:flex;align-items:center;justify-content:center;
  }
  .rev-head .rev-ic svg{width:16px;height:16px}
  .rev-head.late .rev-ic{background:var(--rev-danger-soft);color:var(--rev-danger)}
  .rev-head.ok .rev-ic{background:var(--rev-ok-soft);color:var(--rev-ok)}
  .rev-head h4{font-size:13.5px;font-weight:600;letter-spacing:-.01em;margin:0}
  .rev-head small{display:block;font-size:11px;color:var(--ui-muted);margin-top:1px}
  .rev-text{font-size:12px;color:var(--ui-muted);line-height:1.55;margin:0 0 10px}
  .rev-text b{color:var(--ui-text);font-weight:600}
  .rev-late-badge{
    display:inline-block;font-size:10.5px;font-weight:600;letter-spacing:.02em;
    color:var(--rev-danger);background:var(--rev-danger-soft);
    border-radius:6px;padding:2px 7px;margin-left:6px;vertical-align:1px;
  }
  .rev-meta{
    display:flex;gap:5px;flex-wrap:wrap;margin:0 0 10px;
  }
  .rev-meta span{
    font-size:10.5px;font-weight:500;color:var(--ui-muted);
    background:var(--ui-surface-2);border-radius:6px;padding:3px 8px;
  }
  .rev-opt{
    display:block;width:100%;text-align:left;cursor:pointer;
    font-family:inherit;background:var(--ui-surface);color:var(--ui-text);
    border:1px solid var(--ui-border);border-radius:10px;
    padding:9px 11px;margin-top:6px;box-shadow:var(--ui-sh-sm);
    transition:border-color .15s ease, background-color .15s ease;
  }
  .rev-opt:hover{background:var(--ui-surface-2);border-color:var(--ui-border-strong)}
  .rev-opt:focus-visible{outline:2px solid var(--ui-accent);outline-offset:1px}
  .rev-opt b{display:block;font-size:12.5px;font-weight:600}
  .rev-opt span{display:block;font-size:11px;color:var(--ui-muted);margin-top:2px;line-height:1.45}
  .rev-rate{display:flex;gap:6px;margin-top:4px}
  .rev-rate button{
    flex:1;cursor:pointer;font-family:inherit;text-align:center;
    border:1px solid var(--ui-border);border-radius:10px;padding:8px 4px;
    background:var(--ui-surface);color:var(--ui-text);box-shadow:var(--ui-sh-sm);
    transition:border-color .15s ease, background-color .15s ease;
  }
  .rev-rate button:hover{background:var(--ui-surface-2);border-color:var(--ui-border-strong)}
  .rev-rate button:focus-visible{outline:2px solid var(--ui-accent);outline-offset:1px}
  .rev-rate b{display:block;font-size:12px;font-weight:600;color:var(--ui-text)}
  .rev-rate small{display:block;font-size:10.5px;color:var(--ui-muted);margin-top:2px}
  .rev-rate .r-dif b{color:var(--rev-danger)}
  .rev-rate .r-fac b{color:var(--rev-ok)}
  .rev-done-btn{
    display:block;width:100%;cursor:pointer;font-family:inherit;text-align:center;
    font-size:12.5px;font-weight:600;color:#fff;
    background:var(--ui-accent);border:none;border-radius:10px;padding:10px 12px;
    margin-top:4px;box-shadow:var(--ui-sh-sm);
  }
  .rev-done-btn:hover{filter:brightness(1.08)}
  .rev-done-btn:focus-visible{outline:2px solid var(--ui-accent);outline-offset:2px}
  .rev-foot{
    display:flex;align-items:center;justify-content:flex-end;gap:8px;
    margin-top:12px;padding-top:10px;border-top:1px solid var(--ui-border);
  }
  .rev-del{
    cursor:pointer;font-family:inherit;font-size:11.5px;font-weight:500;
    color:var(--ui-muted);background:none;border:none;padding:4px 6px;border-radius:8px;
  }
  .rev-del:hover{color:var(--rev-danger);background:var(--rev-danger-soft)}
  .rev-del.armed{color:#fff;background:var(--rev-danger);font-weight:600}
  .rev-del:focus-visible{outline:2px solid var(--rev-danger);outline-offset:1px}
  .rev-success{
    display:flex;align-items:center;gap:8px;
    font-size:12px;font-weight:500;color:var(--rev-ok);
    background:var(--rev-ok-soft);border-radius:10px;padding:8px 10px;margin-bottom:10px;
  }
  .rev-success svg{width:14px;height:14px;flex:0 0 14px}

  @media (max-width:720px){
    .rev-panel{position:fixed;top:64px;right:12px;left:12px;width:auto}
  }

  /* ==========================================================================
     COTA DIÁRIA ESGOTADA (freemium, ago/2026): overlay mostrado dentro da
     própria página do mapa quando a conta gratuita já abriu os 2 mapas
     distintos do dia e tenta um 3º. Reaproveita .modal-bg (mesma casca de
     fundo escurecido do modal de jurisprudência), mas com sua PRÓPRIA classe
     de card em vez de .modal: aquele modal é temático por matéria (--c/--soft
     variam por cor da disciplina) e tem estrutura própria (mtag/mref/mtese);
     este é neutro e sempre igual, então usa os tokens --ui-* (o mesmo sistema
     do .rev-panel acima) em vez de --c/--soft.
     ========================================================================== */
  .cota-esgotada-modal{
    width:100%;max-width:420px;
    background:var(--ui-surface);
    border-radius:24px;
    box-shadow:var(--ui-sh-lg);
    padding:44px 34px 34px;
    text-align:center;
    animation:pop .22s cubic-bezier(.2,.9,.3,1.2);
  }
  @media (prefers-reduced-motion:reduce){ :root:not([data-motion="full"]) .cota-esgotada-modal{animation:none} }
  :root[data-motion="reduced"] .cota-esgotada-modal{animation:none}
  .cota-esgotada-otto{
    width:116px;height:116px;margin:0 auto 22px;
    filter:drop-shadow(0 6px 10px rgba(59,42,26,.22));
  }
  .cota-esgotada-otto img{width:100%;height:100%;display:block}
  .cota-esgotada-modal h2{
    font-family:'Fredoka',sans-serif;font-weight:700;font-size:22px;
    line-height:1.3;color:var(--ui-text);
  }
  .cota-esgotada-modal p{
    margin-top:14px;font-size:14.5px;line-height:1.6;color:var(--ui-muted);
  }
  .cota-esgotada-modal p b{color:var(--ui-text);font-weight:700}
  .cota-esgotada-count{
    display:inline-flex;align-items:center;gap:6px;
    margin:20px auto 0;padding:6px 14px;border-radius:999px;
    background:var(--ui-accent-soft);color:var(--ui-accent);
    font-weight:800;font-size:13px;letter-spacing:.02em;text-align:left;
  }
  .cota-esgotada-count svg{width:15px;height:15px;flex:0 0 auto}
  .cota-esgotada-actions{display:flex;flex-direction:column;gap:10px;margin-top:28px}
  .cota-esgotada-actions .btn-primary{
    font-family:'Fredoka',sans-serif;font-weight:600;font-size:15px;
    color:#fff;background:var(--ui-accent);text-decoration:none;
    border:none;border-radius:14px;padding:13px 18px;cursor:pointer;
    box-shadow:0 3px 0 rgba(0,0,0,.15);
    transition:filter .12s ease, transform .12s ease, box-shadow .12s ease;
  }
  .cota-esgotada-actions .btn-primary:hover{filter:brightness(1.05)}
  .cota-esgotada-actions .btn-primary:active{transform:translateY(2px);box-shadow:0 1px 0 rgba(0,0,0,.15)}
  .cota-esgotada-actions .btn-secondary{
    font-family:'Nunito',sans-serif;font-weight:700;font-size:13.5px;
    color:var(--ui-muted);background:transparent;border:none;text-decoration:none;
    padding:6px;cursor:pointer;
  }
  .cota-esgotada-actions .btn-secondary:hover{color:var(--ui-text)}

  /* ==========================================================================
     SINO DE NOTIFICAÇÕES no topbar do mapa (mesmo símbolo/uso do catálogo).
     ========================================================================== */
  .bellwrap{position:relative;flex:0 0 auto}
  .bellbtn{
    position:relative;width:32px;height:32px;border-radius:10px;cursor:pointer;padding:0;
    display:flex;align-items:center;justify-content:center;
    background:transparent;border:1px solid transparent;color:var(--ui-muted);
  }
  .bellbtn svg{width:16px;height:16px}
  .bellbtn:hover{background:var(--ui-surface-2);color:var(--ui-text);border-color:var(--ui-border)}
  .bellbtn:focus-visible{outline:2px solid var(--ui-accent);outline-offset:1px}
  .bellbadge{
    position:absolute;top:-3px;right:-4px;
    min-width:16px;height:16px;border-radius:8px;padding:0 4px;
    background:var(--rev-danger);color:#fff;
    font-family:'Inter',system-ui,sans-serif;
    font-size:10px;font-weight:700;line-height:16px;text-align:center;
    box-shadow:0 0 0 2px var(--ui-surface);
  }
  .bellbadge.today-only{background:var(--ui-accent)}
  .bellpanel{
    position:absolute;top:calc(100% + 8px);right:0;z-index:60;
    width:min(330px, calc(100vw - 24px));
    background:var(--ui-surface);border:1px solid var(--ui-border);border-radius:14px;
    box-shadow:var(--ui-sh-lg);padding:8px;
    font-family:'Inter',system-ui,sans-serif;color:var(--ui-text);text-align:left;
  }
  .bellpanel.hidden{display:none}
  .bellpanel .bp-head{
    font-size:12px;font-weight:600;color:var(--ui-muted);
    padding:8px 10px 6px;letter-spacing:.02em;
  }
  .bellpanel .bp-empty{
    padding:16px 12px 18px;text-align:center;font-size:12.5px;color:var(--ui-muted);line-height:1.55;
  }
  .bellpanel .bp-empty svg{width:20px;height:20px;color:var(--ui-accent)}
  .bellpanel .bp-item{
    display:flex;align-items:center;gap:10px;width:100%;text-align:left;
    background:none;border:none;cursor:pointer;font:inherit;color:var(--ui-text);
    padding:8px 10px;border-radius:10px;text-decoration:none;
  }
  .bellpanel .bp-item:hover{background:var(--ui-surface-2)}
  .bellpanel .bp-item .bp-dot{width:8px;height:8px;flex:0 0 8px;border-radius:50%;background:var(--ui-accent)}
  .bellpanel .bp-item.late .bp-dot{background:var(--rev-danger)}
  .bellpanel .bp-item .bp-tit{display:block;font-size:12.5px;font-weight:550;line-height:1.3;
    background:none;border:none;box-shadow:none;padding:0;margin:0}
  .bellpanel .bp-item .bp-sub{display:block;font-size:11px;color:var(--ui-muted);margin-top:1px;
    background:none;border:none;box-shadow:none;border-radius:0;padding:0;width:auto;animation:none}
  .bellpanel .bp-item .bp-when{margin-left:auto;font-size:11px;font-weight:600;color:var(--ui-accent);white-space:nowrap}
  .bellpanel .bp-item.late .bp-when{color:var(--rev-danger)}
  .bellpanel .bp-item.here{opacity:.75}
  .bellpanel .bp-foot{
    display:block;width:100%;text-align:center;cursor:pointer;
    font:inherit;font-size:12.5px;font-weight:600;color:var(--ui-accent);
    background:none;border:none;border-top:1px solid var(--ui-border);
    padding:10px;margin-top:4px;text-decoration:none;
  }
  .bellpanel .bp-foot:hover{background:var(--ui-surface-2)}
  @media (max-width:720px){
    .bellpanel{position:fixed;top:64px;right:12px;left:12px;width:auto}
  }

  /* ==========================================================================
     POMODORO (ago/2026)
     Mesmo padrao wrap->botao->painel do sino/revisoes acima: popover ancorado
     por position:relative no wrap, mesma casca (var(--ui-surface), borda,
     raio 14-16px, var(--ui-sh-lg)), mesma conversao pra folha fixa abaixo de
     720px. Cores vermelho/verde reaproveitam --rev-danger/--rev-ok (ja
     existem para o sino de revisoes) em vez de inventar tokens novos - e
     coincide com o par de cores que a industria usa pra foco/descanso.
     ========================================================================== */
  .pomowrap{position:relative}
  .pomobtn{
    position:relative;width:32px;height:32px;border-radius:10px;cursor:pointer;padding:0;
    display:flex;align-items:center;justify-content:center;gap:0;
    background:transparent;border:1px solid transparent;color:var(--ui-muted);
    font-family:'Inter',system-ui,sans-serif;font-weight:700;font-size:12.5px;
    font-variant-numeric:tabular-nums;
    transition:width .18s ease,padding .18s ease,background-color .15s ease,border-color .15s ease,color .15s ease;
  }
  .pomobtn.running{gap:6px}
  .pomobtn:hover{background:var(--ui-surface-2);color:var(--ui-text);border-color:var(--ui-border)}
  .pomobtn:focus-visible{outline:2px solid var(--ui-accent);outline-offset:1px}
  .pomobtn #pomoIcon{width:16px;height:16px;flex:0 0 16px;display:block}
  .pomobtn .pomo-dot{
    width:7px;height:7px;border-radius:50%;background:var(--ui-accent);flex:0 0 7px;
    display:none;
  }
  .pomobtn.running{
    width:auto;min-width:32px;padding:0 10px;
    background:var(--ui-accent-soft);color:var(--ui-accent);border-color:transparent;
  }
  .pomobtn.running #pomoIcon{display:none}
  .pomobtn.running .pomo-dot{display:block;animation:pomoPulse 1.6s ease-in-out infinite}
  .pomobtn.running.resting{background:var(--rev-ok-soft);color:var(--rev-ok)}
  .pomobtn.running.resting .pomo-dot{background:var(--rev-ok)}
  @keyframes pomoPulse{
    0%,100%{transform:scale(1);opacity:.95}
    50%{transform:scale(1.35);opacity:.55}
  }
  @media (prefers-reduced-motion:reduce){
    .pomobtn.running .pomo-dot{animation:none}
  }
  :root[data-motion="reduced"] .pomobtn.running .pomo-dot{animation:none}

  .pomopanel{
    position:absolute;top:calc(100% + 8px);right:0;z-index:60;
    width:min(320px, calc(100vw - 24px));
    background:var(--ui-surface);border:1px solid var(--ui-border);border-radius:16px;
    box-shadow:var(--ui-sh-lg);
    font-family:'Inter',system-ui,sans-serif;color:var(--ui-text);text-align:left;
  }
  .pomopanel.hidden{display:none}

  .pomo-modes{
    display:flex;gap:3px;margin:12px 12px 0;padding:3px;
    background:var(--ui-surface-2);border-radius:11px;
  }
  .pomo-modes button{
    flex:1 1 0;font-family:'Fredoka',sans-serif;font-weight:600;font-size:12.5px;
    border:none;border-radius:8px;padding:7px 4px;cursor:pointer;
    background:transparent;color:var(--ui-muted);
    transition:background-color .15s ease,color .15s ease;
  }
  .pomo-modes button:disabled{cursor:not-allowed;opacity:.6}
  .pomo-modes button.active{background:var(--ui-accent);color:#fff}
  .pomo-modes button.active.rest-active{background:var(--rev-ok)}

  .pomo-face{display:flex;flex-direction:column;align-items:center;padding:22px 20px 6px}
  .pomo-ring{position:relative;width:150px;height:150px;display:flex;align-items:center;justify-content:center}
  .pomo-ring svg{position:absolute;inset:0;width:100%;height:100%;transform:rotate(-90deg)}
  .pomo-ring circle{fill:none;stroke-width:8}
  .pomo-ring .track{stroke:var(--ui-surface-2)}
  .pomo-ring .fill{
    stroke:var(--ui-accent);stroke-linecap:round;
    transition:stroke-dashoffset .3s linear,stroke .3s ease;
  }
  .pomo-ring.resting .fill{stroke:var(--rev-ok)}
  .pomo-time{
    font-family:'Fredoka',sans-serif;font-weight:700;font-size:34px;
    font-variant-numeric:tabular-nums;letter-spacing:-.01em;color:var(--ui-text);line-height:1;
  }
  .pomo-label{
    margin-top:5px;font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
    color:var(--ui-accent);
  }
  .pomo-label.resting{color:var(--rev-ok)}

  .pomo-steppers{display:flex;flex-direction:column;align-items:center;gap:5px;margin:14px 0 4px}
  .pomo-steppers .step-row{display:flex;align-items:center;gap:9px}
  .stepbtn{
    width:26px;height:26px;border-radius:8px;cursor:pointer;
    border:1px solid var(--ui-border);background:var(--ui-surface);color:var(--ui-text);
    font-size:15px;font-weight:700;line-height:1;
    display:flex;align-items:center;justify-content:center;
    transition:background-color .12s ease,border-color .12s ease;
  }
  .stepbtn:hover{background:var(--ui-surface-2);border-color:var(--ui-border-strong)}
  .stepbtn:disabled{opacity:.35;cursor:not-allowed}
  .stepbtn:focus-visible{outline:2px solid var(--ui-accent);outline-offset:1px}
  .step-val{
    min-width:30px;text-align:center;font-family:'Fredoka',sans-serif;font-weight:600;
    font-size:14px;font-variant-numeric:tabular-nums;
  }
  .step-cap{font-size:10px;color:var(--ui-muted);letter-spacing:.03em;text-transform:uppercase}

  .pomo-auto{
    display:flex;align-items:center;gap:8px;margin:14px 16px 0;padding:9px 10px;
    border-radius:10px;background:var(--ui-surface-2);cursor:pointer;
    font-size:12.5px;color:var(--ui-text);user-select:none;
  }
  .pomo-auto input{width:15px;height:15px;accent-color:var(--ui-accent);cursor:pointer;flex:0 0 auto}

  .pomo-actions{display:flex;gap:8px;padding:14px 16px 16px}
  .pomo-actions button{
    flex:1 1 0;font-family:'Fredoka',sans-serif;font-weight:600;font-size:13.5px;
    border-radius:11px;padding:10px 8px;cursor:pointer;border:1px solid transparent;
    display:flex;align-items:center;justify-content:center;gap:6px;
    transition:background-color .12s ease,transform .06s ease;
  }
  .pomo-actions button:active{transform:translateY(1px)}
  .pomo-primary{background:var(--ui-accent);color:#fff}
  .pomo-primary.resting{background:var(--rev-ok)}
  .pomo-primary:hover{filter:brightness(1.06)}
  .pomo-secondary{background:var(--ui-surface-2);color:var(--ui-text);border-color:var(--ui-border)}
  .pomo-secondary:hover{background:var(--ui-border)}
  .pomo-actions svg{width:14px;height:14px}

  .pomo-cycles{display:flex;align-items:center;justify-content:center;gap:6px;padding:0 16px 14px}
  .pomo-cycles .dot{width:6px;height:6px;border-radius:50%;background:var(--ui-border-strong)}
  .pomo-cycles .dot.done{background:var(--ui-accent)}

  /* Aviso de fim de sessao: cartao com a mesma cara do .pomopanel (fundo,
     borda, raio, sombra), mas `position:fixed` num canto da TELA (nao
     `absolute` dentro de #pomoWrap) e z-index alto o bastante para ficar por
     cima de QUALQUER coisa - inclusive o overlay de flashcards
     (.fc-overlay, z-index:200) ou qualquer outro painel aberto no momento em
     que a sessao termina. Ancorar no botao (versao anterior) escondia o
     aviso atras dessas camadas: o aluno estudando flashcards nunca via que o
     foco/descanso tinha acabado (visto em ago/2026). Sem essa garantia de
     primeiro plano o som e a mensagem de nada adiantam se ninguem enxerga. */
  .pomo-toast{
    position:fixed;top:64px;right:16px;z-index:1000;
    width:min(320px, calc(100vw - 24px));
    background:var(--ui-surface);border:1px solid var(--ui-border);border-radius:14px;
    box-shadow:var(--ui-sh-lg);padding:14px 16px;
    font-family:'Inter',system-ui,sans-serif;
    opacity:0;transform:translateY(-6px);pointer-events:none;
    transition:opacity .18s ease,transform .18s ease;
  }
  .pomo-toast.on{opacity:1;transform:none;pointer-events:auto}
  .pomo-toast .txt{margin:0;font-size:13px;line-height:1.5;color:var(--ui-text)}
  .pomo-toast .acts{display:flex;justify-content:flex-end;margin-top:10px}
  .pomo-toast button{
    font-family:'Fredoka',sans-serif;font-weight:600;font-size:12.5px;
    background:var(--ui-accent);color:#fff;border:none;border-radius:9px;
    padding:7px 12px;cursor:pointer;transition:filter .12s ease;
  }
  .pomo-toast button:hover{filter:brightness(1.06)}
  @media (prefers-reduced-motion:reduce){
    :root:not([data-motion="full"]) .pomo-toast{transition:none}
  }
  :root[data-motion="reduced"] .pomo-toast{transition:none}

  @media (max-width:720px){
    .pomopanel{position:fixed;top:64px;right:12px;left:12px;width:auto}
    .pomo-toast{top:58px;right:12px;left:12px;width:auto}
  }

  /* ==========================================================================
     BARRA SUPERIOR RESPONSIVA (jul/2026)
     Antes a barra tinha altura FIXA (56px) enquanto .controls usava
     flex-wrap:wrap: ao estreitar a janela os icones quebravam para uma 2a
     linha e VAZAVAM para fora da barra. Agora a altura e automatica (a barra
     nunca transborda) e os controles encolhem por ordem de prioridade antes de
     chegar a esse ponto: busca -> subtitulo -> rotulos -> zoom.
     ========================================================================== */
  .topbar{
    height:auto;min-height:56px;padding:7px 16px;
    flex-wrap:wrap;row-gap:7px;align-content:center;
  }
  .topbar > div:first-of-type{flex:1 1 130px;min-width:0}
  .controls{flex-wrap:wrap;justify-content:flex-end;row-gap:7px;min-width:0}
  .map-search{flex:1 1 170px;max-width:230px}

  @media (max-width:1180px){ .map-search{min-width:140px} }
  @media (max-width:1040px){
    /* so o subtitulo do titulo do mapa - NAO "small" generico: essa forma
       ampla tambem batia no numero de dias dos botoes Dificil/Bom/Facil (e em
       qualquer outro <small> dentro de painel/popover), porque eles moram no
       DOM dentro de .topbar mesmo abrindo como position:fixed (ago/2026,
       bug relatado no celular - a régua de dias sumia so no mobile). */
    #tbSubtitle{display:none}
    .modeswitch button{padding:5px 9px;font-size:12px}
  }
  @media (max-width:900px){
    .map-search{min-width:118px}
    .zoomctl button{min-width:30px;padding:5px 7px}
  }
  /* o zoom continua disponivel por ctrl+roda, pinca e teclado */
  @media (max-width:780px){ .zoomctl{display:none} }

  /* --------------------------------------------------------------------------
     BUSCA COMPACTA ate 618px (jul/2026)
     Ate aqui a busca era o ultimo item a ceder largura, e ela nunca descia de
     ~118px: somada ao alternador de modo (~215px) e aos cinco icones (~162px),
     a linha de controles pedia ~530px e o botao "?" -- o ultimo da fila --
     caia SOZINHO numa 2a linha por volta de 556px. Um "?" orfao no meio da
     barra e o tipo de detalhe que faz o mapa parecer quebrado no celular.
     Agora, abaixo de 618px, a busca fica so com a lupa (34px): a linha volta a
     caber inteira, com folga para o titulo. Nao ha botao novo -- o proprio
     <input> e o alvo do toque, e :focus-within faz o resto, sem JS.
     Os 618px sao folga deliberada sobre os ~556px onde a quebra comecava: entre
     618 e 556 a busca ja aparecia mutilada ("Buscar no ma..."), e nao ha por
     que esperar a barra quebrar para trocar por um alvo que se entende sozinho.
     -------------------------------------------------------------------------- */
  @media (max-width:618px){
    .map-search{
      flex:0 0 34px;min-width:34px;max-width:34px;
      transition:max-width .22s ease, flex-basis .22s ease;
    }
    .map-search-field{padding:6px 4px 6px 30px;cursor:pointer}
    /* o placeholder nao cabe nos 34px, e um pedaco de "Buscar..." aparando na
       borda e pior que lupa nenhuma. O aria-label do <input> continua la, entao
       o leitor de tela nao perde nada. */
    .map-search-field::placeholder{opacity:0}

    /* Aberta: foco dentro, OU ja tem texto digitado (.has-value e a classe que
       o motor mesmo poe -- ver o modulo de busca em map-engine.js). O texto
       digitado precisa manter a busca aberta porque o resultado clicado leva o
       foco para o card no mapa: sem .has-value a caixa se recolheria com o
       termo dentro dela, invisivel, e o aluno nao acharia como limpar. */
    .map-search:focus-within,
    .map-search.has-value{flex:1 1 120px;max-width:none}
    .map-search:focus-within .map-search-field,
    .map-search.has-value .map-search-field{padding:6px 30px 6px 31px;cursor:text}
    .map-search:focus-within .map-search-field::placeholder,
    .map-search.has-value .map-search-field::placeholder{opacity:1}

    /* Quem esta buscando nao esta trocando de modo: o alternador cede o espaco
       e a barra NUNCA ganha uma linha durante a busca. Volta sozinho quando a
       busca esvazia e perde o foco. */
    .map-search:focus-within ~ .modeswitch,
    .map-search.has-value ~ .modeswitch{display:none}
  }
  @media (max-width:618px) and (prefers-reduced-motion:reduce){
    :root:not([data-motion="full"]) .map-search{transition:none}
  }
  @media (max-width:618px){
    :root[data-motion="reduced"] .map-search{transition:none}
  }

  /* ==========================================================================
     ANOTACOES: um unico botao de lapis com menu (ver todas / exportar /
     importar). Substitui os dois botoes largos "Exportar notas" e
     "Importar notas", que ocupavam ~230px da barra.
     ========================================================================== */
  .noteswrap{position:relative;flex:0 0 auto}
  .notesbtn{
    position:relative;width:32px;height:32px;border-radius:10px;cursor:pointer;padding:0;
    display:flex;align-items:center;justify-content:center;
    background:transparent;border:1px solid transparent;color:var(--ui-muted);
  }
  .notesbtn svg{width:16px;height:16px}
  .notesbtn:hover{background:var(--ui-surface-2);color:var(--ui-text);border-color:var(--ui-border)}
  .notesbtn:focus-visible{outline:2px solid var(--ui-accent);outline-offset:1px}
  .notesbtn.has-notes{color:var(--ui-accent)}
  .notesbadge{
    position:absolute;top:-3px;right:-4px;min-width:15px;height:15px;border-radius:8px;padding:0 4px;
    background:var(--ui-accent);color:#fff;
    font-family:'Inter',system-ui,sans-serif;font-size:9.5px;font-weight:700;line-height:15px;
    text-align:center;box-shadow:0 0 0 2px var(--ui-surface);
  }
  .notesmenu{
    position:absolute;top:calc(100% + 8px);right:0;z-index:60;
    width:min(268px, calc(100vw - 24px));
    background:var(--ui-surface);border:1px solid var(--ui-border);border-radius:14px;
    box-shadow:var(--ui-sh-lg);padding:6px;
    font-family:'Inter',system-ui,sans-serif;text-align:left;
  }
  .notesmenu.hidden{display:none}
  .notesmenu button{
    display:flex;align-items:center;gap:10px;width:100%;text-align:left;cursor:pointer;
    background:none;border:none;font:inherit;color:var(--ui-text);
    padding:8px 10px;border-radius:10px;
  }
  .notesmenu button:hover{background:var(--ui-surface-2)}
  .notesmenu button:focus-visible{outline:2px solid var(--ui-accent);outline-offset:-2px}
  .notesmenu button svg{width:16px;height:16px;flex:0 0 16px;color:var(--ui-muted)}
  .notesmenu button b{display:block;font-size:12.5px;font-weight:600;line-height:1.25}
  .notesmenu button small{display:block;font-size:11px;color:var(--ui-muted);margin-top:1px}
  @media (max-width:720px){
    .notesmenu{position:fixed;top:64px;right:12px;left:12px;width:auto}
  }

  /* ---------- painel "todas as anotacoes" (dentro do #sidePanel) ---------- */
  .notes-all{display:flex;flex-direction:column;gap:11px}
  .na-empty{
    border:1px dashed var(--ui-border-strong);border-radius:12px;
    padding:26px 18px;text-align:center;color:var(--ui-muted);
    font-family:'Inter',system-ui,sans-serif;font-size:12.5px;line-height:1.6;
  }
  .na-empty b{display:block;color:var(--ui-text);font-size:13.5px;margin-bottom:5px}
  .na-item{
    border:1px solid var(--ui-border);border-radius:12px;overflow:hidden;
    background:var(--ui-surface);box-shadow:var(--ui-sh-sm);
  }
  .na-item.na-active{border-color:var(--ui-accent);box-shadow:0 0 0 2px var(--ui-ring)}
  /* a referencia: diz de qual card veio a anotacao e leva ate ele */
  .na-ref{
    display:flex;align-items:center;gap:9px;width:100%;text-align:left;cursor:pointer;
    font:inherit;color:var(--ui-text);background:var(--ui-surface-2);
    border:none;border-bottom:1px solid var(--ui-border);padding:8px 11px;
  }
  .na-ref:hover{background:var(--ui-accent-soft)}
  .na-ref:focus-visible{outline:2px solid var(--ui-accent);outline-offset:-2px}
  .na-ref > span{min-width:0}
  .na-top{
    display:block;font-family:'Inter',system-ui,sans-serif;
    font-size:9.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
    color:var(--ui-accent);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  }
  .na-card{
    display:block;font-family:'Inter',system-ui,sans-serif;
    font-size:12.5px;font-weight:600;line-height:1.3;color:var(--ui-text);margin-top:1px;
  }
  .na-go{
    margin-left:auto;flex:0 0 auto;display:flex;align-items:center;gap:4px;
    font-family:'Inter',system-ui,sans-serif;font-size:10.5px;font-weight:600;
    color:var(--ui-accent);white-space:nowrap;
  }
  .na-go svg{width:12px;height:12px}
  .na-body{
    padding:9px 11px;font-family:'Inter',system-ui,sans-serif;
    font-size:12.5px;line-height:1.55;color:var(--ui-text);
    word-break:break-word;
  }
  .na-body *{max-width:100%}
  .na-foot{display:flex;gap:6px;padding:0 11px 9px}
  .na-edit{
    font-family:'Inter',system-ui,sans-serif;font-size:11.5px;font-weight:550;cursor:pointer;
    background:var(--ui-surface);color:var(--ui-muted);
    border:1px solid var(--ui-border);border-radius:8px;padding:4px 9px;
  }
  .na-edit:hover{background:var(--ui-surface-2);color:var(--ui-text)}
  .na-edit:focus-visible{outline:2px solid var(--ui-accent);outline-offset:1px}

  /* ==========================================================================
     LAPIS ANOTADO: o preenchimento dourado tem que vencer os fundos especificos.
     `.pencil-btn.has-note` e `.branch .pencil-btn` tem a MESMA especificidade
     (0,2,0), entao o que vinha depois no arquivo ganhava: anotacao feita em
     nivel de topico nunca aparecia como preenchida. O papel noturno criou o
     mesmo conflito nos cards. Esta regra fecha os dois casos.
     ========================================================================== */
  .branch .pencil-btn.has-note,
  .sub .pencil-btn.has-note,
  .subnode .pencil-btn.has-note,
  .study-branchhead .pencil-btn.has-note,
  :root[data-theme="dark"] .sub .pencil-btn.has-note,
  :root[data-theme="dark"] .subnode .pencil-btn.has-note{
    background:linear-gradient(180deg,#FFE08A,#F5B93A);color:#5A3A00;
  }
  @media (prefers-color-scheme: dark){
    :root:not([data-theme="light"]) .sub .pencil-btn.has-note,
    :root:not([data-theme="light"]) .subnode .pencil-btn.has-note{
      background:linear-gradient(180deg,#FFE08A,#F5B93A);color:#5A3A00;
    }
  }

  /* anotacao orfa (sem card de origem): nao da para "abrir", entao ela nao
     finge ser clicavel e ganha um caminho de limpeza */
  .na-item.na-orphan .na-ref{cursor:default;background:var(--ui-surface-2)}
  .na-item.na-orphan .na-ref:hover{background:var(--ui-surface-2)}
  .na-item.na-orphan .na-top{color:var(--ui-muted)}
  .na-drop{
    font-family:'Inter',system-ui,sans-serif;font-size:11.5px;font-weight:550;cursor:pointer;
    background:var(--ui-surface);color:var(--ui-muted);
    border:1px solid var(--ui-border);border-radius:8px;padding:4px 9px;
  }
  .na-drop:hover{color:#fff;background:var(--rev-danger);border-color:var(--rev-danger)}
  .na-drop.armed{color:#fff;background:var(--rev-danger);border-color:var(--rev-danger);font-weight:600}

  /* ==========================================================================
     CABECALHO DO ESTUDO RAPIDO (ago/2026): o cabecalho fixo comia 226px, ~29%
     da area de leitura, porque os 7 chips traziam o nome inteiro de cada
     topico e quebravam em 2-3 linhas. Pior: o fundo terminava em transparente,
     entao o texto do card passava POR TRAS dos chips ao rolar.

     Tres mudancas, nesta ordem de importancia:
     (0) fundo opaco: o texto do card nunca mais atravessa o cabecalho;
     (1) o nome sai do chip e fica so no topico SELECIONADO (o nome completo ja
         estava repetido no titulo de 24px logo abaixo, entao nada se perde);
     (2) o bloco de titulo do mapa recolhe ao rolar em QUALQUER largura -- antes
         isso so acontecia abaixo de 720px.

     Resultado medido: 129px parado no topo (18%) e 51px rolando (7%), dentro da
     faixa que a NN/g considera aceitavel para uma barra fixa. Esta camada vem
     depois de TEMA/ONDA 1/ONDA 2 de proposito: e ela que tem de vencer.
     ========================================================================== */

  .study-top{
    background:var(--ui-canvas);
    border-bottom:1px solid var(--ui-border);
    box-shadow:0 8px 12px -10px rgba(0,0,0,.45);
  }

  /* (1) o nome do topico: fechado nos demais, aberto no selecionado. A abertura
     e animada por max-width, e --w e a largura real do nome, medida em JS (ver
     medirNomesDeTopico em map-engine.js) -- um teto fixo cortaria os titulos
     longos (o maior do acervo tem 73 caracteres). O 60ch e so rede de
     seguranca: se a medida falhar, o nome aparece inteiro em vez de sumir. */
  .chip{gap:0}
  .chip:not(.active){padding-left:7px;padding-right:7px}
  .chip .chip-label{
    display:inline-block;max-width:0;margin-left:0;opacity:0;
    overflow:hidden;white-space:nowrap;vertical-align:middle;
    transition:max-width .26s ease, margin-left .26s ease, opacity .18s ease;
  }
  .chip.active .chip-label{max-width:var(--w, 60ch);margin-left:7px;opacity:1}
  .chip.active::after{margin-left:7px}

  /* (2) o bloco de titulo do mapa recolhe ao rolar (a classe .collapsed e
     alternada em map-engine.js, com histerese) */
  .study-center{
    overflow:hidden;max-height:110px;
    transition:max-height .3s ease, opacity .3s ease, padding .3s ease,
               margin .3s ease, border-width .3s ease;
  }
  .study-top.collapsed .study-center{
    max-height:0;opacity:0;padding-top:0;padding-bottom:0;
    margin-top:0;margin-bottom:0;border-width:0;
  }
  .study-top.collapsed{padding-bottom:6px}
  .study-top.collapsed .chiprail{margin-top:0}

  /* usada por um instante pelo JS para MEDIR quanto o cabecalho encolhe ao
     recolher (ver o bloco do cabecalho retratil em map-engine.js): sem desligar
     a transicao, a medida pegaria uma altura no meio da animacao */
  .study-top.medindo,.study-top.medindo *{transition:none!important}

  @media (prefers-reduced-motion:reduce){
    :root:not([data-motion="full"]) .chip .chip-label,
    :root:not([data-motion="full"]) .study-center{transition:none}
  }
  :root[data-motion="reduced"] .chip .chip-label,
  :root[data-motion="reduced"] .study-center{transition:none}

  /* ==========================================================================
     BARRA SUPERIOR RETRATIL NO CELULAR (ago/2026): abaixo de 720px a barra
     nasce recolhida, com as duas SAIDAS, o titulo do mapa e uma seta a direita
     que abre a barra inteira (busca, alternador de modo, lapis, sino, revisoes,
     tema, ajuda). Recolhida ela mede 52px contra 127px aberta. Acima de 720px
     a seta nao existe e a barra e exatamente a de sempre.

     CORRIGIDO ago/2026: a versao original recolhia TAMBEM o .homelink e o
     .subjectlink, e com isso o aluno de celular ficava dentro do mapa sem
     nenhuma saida visivel -- as duas so reapareciam depois de descobrir o
     chevron. Junto com o gesto de voltar do Android (que sai do site inteiro,
     nao sobe um nivel), isso era um beco. O que recolhe agora sao so os
     CONTROLES DE ESTUDO; sair do mapa nunca depende de abrir nada.
     ========================================================================== */

  .tbtoggle{display:none}
  @media (max-width:720px){
    .tbtoggle{
      display:flex;align-items:center;justify-content:center;
      flex:0 0 auto;margin-left:auto;
      width:40px;height:40px;padding:0;border-radius:10px;cursor:pointer;
      background:transparent;border:1px solid var(--ui-border);color:var(--ui-muted);
    }
    .tbtoggle:hover{background:var(--ui-surface-2);color:var(--ui-text)}
    .tbtoggle:focus-visible{outline:2px solid var(--ui-accent);outline-offset:1px}
    .tbtoggle svg{width:16px;height:16px;transition:transform .22s ease}
    .topbar.tb-open .tbtoggle svg{transform:rotate(180deg)}

    /* recolhida: as duas saidas + o titulo do mapa + a seta */
    .topbar:not(.tb-open) .controls{display:none}
    .topbar{min-height:52px;padding:6px 12px;gap:8px}

    /* A seta da disciplina flutua ABAIXO da barra (position:absolute) para nao
       roubar largura quando a barra e larga. Na barra recolhida do celular ela
       nao pode flutuar: ali embaixo comeca o canvas do mapa, e ela ficaria
       pairando sobre o conteudo. Entra na fila, ao lado do logo.
       Com a barra aberta volta a flutuar, como sempre.

       CORRIGIDO ago/2026 - ela entra na fila com `position:relative` e
       top/left zerados, e nao com `static`: ocupa o mesmo lugar, mas continua
       sendo um elemento POSICIONADO. Isso nao e detalhe de estilo, e o que
       impede um bug feio: a area de toque ampliada e um `::after` absoluto de
       width/height:100%, e porcentagem de absoluto se mede pelo ancestral
       POSICIONADO mais proximo. Com a seta `static` esse ancestral virava a
       propria `.topbar`, e o "anel de toque" da seta cobria A BARRA INTEIRA:
       no celular, tocar em qualquer ponto do topo (estrela, chevron, titulo)
       caia neste link e voltava para o catalogo. Ver ALVOS DE TOQUE.

       `z-index:auto` junto: o valor 32 existe para a seta FLUTUANTE ficar
       acima do canvas, e voltaria a valer agora que ela e posicionada. Na
       fila ele so faria a seta ganhar de quem estiver ao lado - e num titulo
       longo a estrela chega perto. Empate ali tem de ser resolvido pela ordem
       do documento (a estrela vence), nao por uma camada herdada de outro
       contexto: voltar ao catalogo e a acao mais cara das duas. */
    .topbar:not(.tb-open) .subjectlink{
      position:relative;top:auto;left:auto;z-index:auto;
      flex:0 0 auto;width:40px;height:40px;border-radius:10px;
    }
    /* 40px reais (e nao 32 + area ampliada por pseudo-elemento) porque aqui os
       tres alvos sao vizinhos: areas de toque ampliadas se sobreporiam, e um
       toque na fronteira abriria o botao errado */
    /* a estrela nao recolhe junto com os controles: favoritar tem de custar um
       toque tambem no celular, que e onde "marco para voltar depois" mais
       acontece. Ela encolhe um pouco para o titulo nao perder espaco - o alvo
       de toque continua em 44px pelo pseudo-elemento (ver ALVOS DE TOQUE) */
    .topbar:not(.tb-open) .favbtn{width:30px;height:30px}
    .topbar:not(.tb-open) .favbtn svg{width:16px;height:16px}
    .topbar:not(.tb-open) .homelink{width:40px;height:40px;border-radius:10px}
    .topbar:not(.tb-open) .homelink svg{width:24px}
    .topbar:not(.tb-open) .subjectlink svg{width:18px;height:18px}

    /* aberta: os controles descem para uma faixa inteira abaixo do titulo, e a
       seta continua na 1a linha (order a manda antes de .controls, que quebra a
       linha por causa do width:100%) */
    .topbar.tb-open .tbtoggle{order:0}
    .topbar.tb-open .controls{order:1;width:100%;justify-content:flex-start;margin-left:0}
  }
  @media (max-width:720px) and (prefers-reduced-motion:reduce){
    :root:not([data-motion="full"]) .tbtoggle svg{transition:none}
  }
  @media (max-width:720px){
    :root[data-motion="reduced"] .tbtoggle svg{transition:none}
  }

  /* ==========================================================================
     ESQUELETO DE CARREGAMENTO (ago/2026)

     Só existe no site AO VIVO. A ESPERA em si agora é a tela cheia de
     AtivaCarregando.mostrarMapa() (assets/carregando.js) - a mesma que o
     catalogo acende ao clicar em "Abrir mapa" - carregada e acesa por
     engine/map-boot.js antes de buscar o conteudo do mapa. O que resta aqui
     é só o estado de FALHA (.map-boot.failed): se o motor nao conseguir
     carregar, map-boot.js apaga aquela tela e injeta esta caixa dentro de
     .stage. O mapa offline abre de arquivo local, em que a espera e
     imperceptivel, e por isso nunca chega a montar nenhum dos dois. */
  .map-boot{
    position:absolute;inset:0;z-index:5;
    display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;
    padding:40px 24px;text-align:center;
    font:500 14px/1.6 'Inter',system-ui,sans-serif;color:var(--ui-text);
  }
  .map-boot a{color:var(--ui-accent)}

  /* ==========================================================================
     ALVOS DE TOQUE (ago/2026)

     Os controles do mapa foram desenhados na medida do mouse: 20 a 34px, que
     no ponteiro e um alvo confortavel e mantem a moldura leve. No dedo, todos
     estao abaixo do minimo de 44x44 -- e aqui errar custa mais caro do que o
     normal, porque esses botoes vivem DENTRO de uma tela que faz pan ao
     arrastar. Um toque que erra por 6px nao e um clique perdido: e um arrasto
     acidental que move o mapa inteiro e desorienta quem estava lendo.

     A area cresce por pseudo-elemento, nao por width/height: o desenho fica
     idêntico (mesmo circulo, mesma sombra, mesmo alinhamento) e so a regiao
     sensivel ao toque aumenta, centrada no mesmo ponto. Isso importa em
     especial no lapis e no selo de jurisprudencia, que ficam DENTRO do card e
     cujo tamanho real entra na medida de altura que alimenta a fisica de
     colisao (ver WORKFLOW.md, "o risco real e a ALTURA dos cards"): mexer em
     width/height ali obrigaria a remontar e reenquadrar todos os mapas.
     Pseudo-elemento nao entra no layout, entao a colisao nao percebe nada.

     `(pointer:coarse)`, e nao uma largura de tela: quem decide e o aparelho de
     entrada. Notebook com janela estreita continua compacto; tablet grande, no
     dedo, ganha os alvos maiores.

     CUIDADO AO INCLUIR UM BOTAO NOVO NA LISTA ABAIXO: `position:relative` so
     pode ser aplicado a quem ja era `static`. Quem ja nasce `absolute` (o lapis
     dentro do chip, o "x" da busca, a seta da disciplina) NAO entra aqui - ja e
     posicionado, e trocar para `relative` faz duas coisas ruins de uma vez:
     devolve o elemento ao fluxo e passa a ler `top`/`left` como DESLOCAMENTO,
     jogando o desenho para fora do lugar. E, se por outro lado o elemento
     acabar `static`, o `::after` de width/height:100% mede o ancestral
     posicionado mais proximo e a area de toque cresce ate o tamanho DELE - foi
     assim que a seta da disciplina cobriu a barra superior inteira no celular.
     ========================================================================== */
  @media (pointer:coarse){
    .pencil-btn,.juris-btn,.scene-btn,.themebtn,.helpbtn,.notesbtn,.bellbtn,.revbtn,.favbtn,
    .help-close,.zoomctl button,.modeswitch button,.sp-close,
    .note-toolbar button,.homelink{
      position:relative;
    }
    .pencil-btn::after,.juris-btn::after,.scene-btn::after,.themebtn::after,.helpbtn::after,
    .notesbtn::after,.bellbtn::after,.revbtn::after,.favbtn::after,
    .map-search-clear::after,
    .help-close::after,.zoomctl button::after,.modeswitch button::after,
    .sp-close::after,.note-toolbar button::after,
    .homelink::after,.subjectlink::after{
      content:"";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
      width:100%;height:100%;min-width:44px;min-height:44px;
    }
    /* o lapis e o selo de juris ficam por cima do card, que e clicavel (abre e
       fecha o proprio card): sem subir a camada, a area ampliada seria
       capturada pelo card em vez do botao */
    .pencil-btn,.juris-btn,.scene-btn{z-index:4}
    /* as cores da barra de marca-texto tem area de 44px por pseudo-elemento e
       so 30px de desenho: sem abrir o intervalo entre elas, as areas se
       sobreporiam e o dedo pegaria a cor vizinha */
    .mt-bar{gap:12px}

    /* ----------------------------------------------------------------------
       EXCECAO: o lapis do chip de topico FECHADO volta ao tamanho do desenho.

       A area ampliada existe para o dedo nao ERRAR o botao. Mas dentro de um
       chip FECHADO ela so tira: o anel invisivel de 44px em volta de um
       desenho de 26px rouba toques destinados ao proprio chip - cuja acao
       primaria, fechado, e ABRIR O TOPICO - e nao devolve nada visivel em
       troca. Fora daqui (chip aberto, cards, subtopicos, barra) os 44px
       continuam valendo integralmente.

       26px continua acima do minimo de 24x24 do WCAG 2.5.8 (AA), entao isto
       nao e regressao de acessibilidade: o alvo deixa de ser AAA (2.5.5) so
       neste contexto, e passa a valer a regra de "o alvo e o que se ve".

       Contraparte em JS: o supressor de toque de map-engine.js ja trata o
       caso do SELO DE LEI SECA no chip fechado (que fica no meio do chip e
       nao tem area ampliada nenhuma). Este bloco fecha o outro lado do mesmo
       problema, o do canto superior direito. Ver WORKFLOW.md, secao "Lapis,
       juris e lei seca no dedo".

       min-width/min-height:0 devolve o ::after para width/height:100%, isto
       e, exatamente o circulo desenhado. Segue sem tocar em width/height do
       BOTAO (LEI 15): o pseudo-elemento nao entra no layout, entao a fisica
       de colisao nao percebe nada e nenhum mapa precisa ser remontado.
       ---------------------------------------------------------------------- */
    .branch:not(.open) .pencil-btn::after{min-width:0;min-height:0}
  }

  /* ==========================================================================
     MARCA-TEXTO: BARRA QUE APARECE JUNTO DA SELECAO (ago/2026)

     Substitui a barra fixa de cores, que ficava grudada no topo da lei seca e
     exigia armar a cor ANTES de selecionar. O comportamento e a razao de cada
     decisao estao no bloco "MARCA-TEXTO" de map-engine.js; aqui fica so a
     aparencia.

     A barra nasce ABAIXO da selecao porque no iOS o balao nativo (Copiar /
     Consultar) sai ACIMA, e ele nao pode ser desligado nem substituido para
     texto. Se nao couber embaixo, o JS a sobe.
     ========================================================================== */
  .mt-bar{
    position:fixed; z-index:80;
    display:flex; align-items:center; gap:8px;
    padding:8px 10px;
    /* `manipulation` tira o atraso de toque e o duplo-toque-para-zoom em cima
       da barra; `user-select:none` impede que encostar nela comece uma selecao
       nova por cima da que acabou de ser feita */
    touch-action:manipulation;
    -webkit-user-select:none; user-select:none;
    background:var(--ui-surface, #FFFDF8);
    border:1px solid var(--ui-border, #C9B99F);
    border-radius:14px;
    box-shadow:0 8px 26px rgba(0,0,0,.28);
    font-family:'Inter',system-ui,sans-serif;
    opacity:0; transform:translateY(6px) scale(.97);
    transition:opacity .14s ease, transform .14s ease;
    pointer-events:none;
  }
  .mt-bar.on{opacity:1; transform:none; pointer-events:auto}
  .mt-bar button{
    flex:0 0 auto; cursor:pointer; padding:0; border:none; background:none;
    display:flex; align-items:center; justify-content:center;
  }
  /* area de 44px por pseudo-elemento, do mesmo jeito que o resto do motor: o
     desenho continua 30px e so a regiao sensivel cresce */
  .mt-cor{
    position:relative; width:30px; height:30px; border-radius:50%;
    box-shadow:0 0 0 1px rgba(59,42,26,.3);
  }
  .mt-cor::after{
    content:""; position:absolute; left:50%; top:50%;
    transform:translate(-50%,-50%);
    width:100%; height:100%; min-width:44px; min-height:44px;
  }
  .mt-cor.sel{box-shadow:0 0 0 2px var(--ui-surface,#fff), 0 0 0 4px var(--ui-text,#3B2A1A)}
  .mt-sep{flex:0 0 1px; width:1px; height:26px; background:var(--ui-border,#C9B99F)}
  .mt-acao{
    position:relative;
    font:600 12.5px 'Inter',system-ui,sans-serif;
    color:var(--ui-text,#3B2A1A);
    padding:7px 10px; border-radius:9px;
    background:var(--ui-surface-2, #F3ECE1);
  }
  .mt-acao::after{
    content:""; position:absolute; left:50%; top:50%;
    transform:translate(-50%,-50%); width:100%; height:100%; min-height:44px;
  }
  .mt-acao.perigo{color:#B91C1C}

  /* Aviso curto, com dois papeis: confirmar oferecendo "Desfazer", e explicar
     quando uma selecao nao pode virar marcacao. Fica no rodape e POR CIMA da
     folha do celular (z-index maior), porque a folha ocupa justamente o
     rodape. */
  .mt-toast{
    /* 1000: acima de QUALQUER camada do motor, inclusive o overlay de
       flashcards (.fc-overlay, z-index:200) - antes disso o toast do
       Pomodoro ficava escondido atras do fundo desfocado dos flashcards
       quando a sessao terminava durante um estudo de cartoes (ago/2026) */
    position:fixed; left:12px; right:12px; z-index:1000;
    bottom:calc(12px + env(safe-area-inset-bottom, 0px));
    display:flex; align-items:center; gap:12px;
    padding:12px 14px;
    background:#1E1B16; color:#F5EFE6;
    border-radius:12px; box-shadow:0 10px 30px rgba(0,0,0,.35);
    font:500 13px/1.35 'Inter',system-ui,sans-serif;
    opacity:0; transform:translateY(10px);
    transition:opacity .18s ease, transform .18s ease;
    pointer-events:none;
    touch-action:manipulation;
    -webkit-user-select:none; user-select:none;
  }
  .mt-toast.on{opacity:1; transform:none; pointer-events:auto}
  .mt-toast .txt{flex:1 1 auto; min-width:0}
  .mt-toast button{
    flex:0 0 auto; position:relative; cursor:pointer;
    background:none; border:none; padding:8px 4px;
    font:700 13px 'Inter',system-ui,sans-serif; color:#FDBA74;
  }
  .mt-toast button::after{
    content:""; position:absolute; left:50%; top:50%;
    transform:translate(-50%,-50%); width:100%; height:100%;
    min-width:44px; min-height:44px;
  }
  @media (prefers-reduced-motion:reduce){
    :root:not([data-motion="full"]) .mt-bar,
    :root:not([data-motion="full"]) .mt-toast{transition:none}
  }
  :root[data-motion="reduced"] .mt-bar,
  :root[data-motion="reduced"] .mt-toast{transition:none}

  /* O fim do painel precisa alcancar o topo do teclado virtual. Sem esta folga
     o `.sp-body` acha que ja mostrou todo o conteudo e nao rola mais, deixando
     o fim do editor e o aviso "Salvo automaticamente" atras das teclas.
     Depois das duas declaracoes de padding do `.sp-body` (a clara e a da
     moldura --ui-*) para vencer as duas por ordem, ja que tem a mesma
     especificidade. */
  .sp-body{padding-bottom:calc(28px + var(--kb-inset))}

  /* ==========================================================================
     PAINEL LATERAL VIRA BOTTOM SHEET NO CELULAR (ago/2026)

     A coluna de `min(420px,42vw)` foi desenhada para desktop. Num telefone de
     390px ela vira 164px, algo como 18 caracteres por linha (a faixa
     confortavel de leitura vai de 45 a 75), e como o painel vivia dentro do
     flex do `.workspace` ele ROUBAVA largura do mapa em vez de sobrepor:
     sobravam 225px, menos que a largura de um unico card (`.branch` tem 214px
     fixos). O aluno perdia as duas coisas ao mesmo tempo.

     O requisito esta escrito no proprio motor, no comentario de
     `setSidePanelOpen`: "ler a lei enquanto se mexe no mapa e justamente o
     uso". Numa tela alta e estreita, a divisao que preserva esse uso e
     horizontal (mapa em cima, lei embaixo), nao vertical. Dai a folha ancorada
     no rodape, com tres alturas, como em mapas de rua:

       PEEK   so o cabecalho, servindo de aba: da para saber qual artigo esta
              aberto sem perder o mapa de vista.
       MEIO   le a lei E ve o card que a originou.
       CHEIO  leitura corrida de artigo longo.

     Qual delas abre e decidido MEDINDO o conteudo, nao chutando: ver
     `sheetAlturaPorConteudo` em map-engine.js.

     Sem escurecimento de fundo, de proposito: o mapa continua arrastavel e com
     zoom o tempo todo, que e o comportamento nao modal correto para conteudo
     consultado em paralelo com o fundo. Por isso tambem o painel continua
     sendo um `<aside>` e nao virou `role="dialog"`.
     ========================================================================== */
  @media (max-width:720px){
    #sidePanel{
      /* fora do flex do .workspace: sobrepoe o palco em vez de encolhe-lo */
      position:fixed;
      left:0; right:0; top:auto;
      /* acompanha o teclado virtual (ver o modulo do teclado em
         map-engine.js). Sem isto a folha ficaria ancorada no fundo do viewport
         de LAYOUT, ou seja, atras das teclas. */
      bottom:var(--kb-inset, 0px);
      z-index:45;

      flex:0 0 auto;
      width:auto;
      height:var(--sheet-h, 55dvh);
      max-height:calc(96dvh - var(--kb-inset, 0px));

      border-left:none;
      border-top:1px solid var(--ui-border, #E7D3B0);
      border-radius:20px 20px 0 0;
      box-shadow:0 -10px 34px rgba(0,0,0,.22);
      overflow:hidden;

      transform:translateY(100%);
      transition:transform .26s cubic-bezier(.32,.72,0,1),
                 height    .26s cubic-bezier(.32,.72,0,1);
    }
    /* repetir flex/width e obrigatorio: a regra `.open` la de cima devolveria
       a folha ao formato de coluna */
    #sidePanel.open{
      flex:0 0 auto;
      width:auto;
      border-left-width:0;
      transform:translateY(0);
    }
    /* enquanto o dedo arrasta, a altura tem de seguir o dedo: qualquer tween
       aqui vira borracha e a folha parece presa */
    #sidePanel.sheet-dragging{transition:none}

    /* Alcinha de arrastar, criada por JS no mesmo espirito do rodape da ajuda:
       uma linha de interface nao justifica remontar todos os mapas. E um
       <button> de verdade porque a alcinha sozinha nao e acessivel: no teclado
       e no leitor de tela ela precisa responder e anunciar o estado. O botao
       Fechar continua ao lado, que e a saida obvia para quem ignora a alca. */
    .sheet-grip{
      flex:0 0 auto;
      display:flex; align-items:center; justify-content:center;
      width:100%; height:26px; padding:0;
      border:none; background:transparent; cursor:grab;
      touch-action:none;   /* o gesto e nosso, nao a rolagem do navegador */
    }
    .sheet-grip:active{cursor:grabbing}
    .sheet-grip::before{
      content:"";
      width:40px; height:5px; border-radius:999px;
      background:var(--ui-border-strong, #C9B99F);
    }
    .sheet-grip:focus-visible{outline:2px solid var(--ui-accent, #B14700); outline-offset:-3px}

    /* o cabecalho tambem arrasta: e o alvo grande, e o dedo costuma cair nele
       antes de acertar a alcinha */
    .sp-head{cursor:grab; touch-action:none; padding-top:6px}
    .sp-head:active{cursor:grabbing}

    /* a rolagem da lei seca nao pode vazar e arrastar a folha ou a pagina */
    .sp-body{overscroll-behavior:contain; -webkit-overflow-scrolling:touch}

    /* Respiro do iPhone (barra de gestos) no CORPO, nunca no painel: com
       `box-sizing:border-box` valendo para tudo, um padding no painel sairia
       da altura util e, no PEEK, os 84px virariam 50px de cabecalho num
       aparelho com 34px de area segura. */
    .sp-body{
      padding-bottom:calc(28px + var(--kb-inset, 0px) + env(safe-area-inset-bottom, 0px));
    }

    /* no PEEK so o cabecalho aparece. `visibility` e nao `display` para o
       texto da lei nao ficar alcancavel por teclado dentro de uma area
       invisivel, mantendo a altura do corpo estavel para a medicao. */
    #sidePanel.sheet-peek .sp-body{visibility:hidden}
    /* no PEEK a folha ja e so um cabecalho e o gesto de descartar e arrastar
       para baixo; o Fechar volta assim que ela cresce */
    #sidePanel.sheet-peek .sp-close{display:none}
  }

  @media (max-width:720px) and (prefers-reduced-motion:reduce){
    :root:not([data-motion="full"]) #sidePanel{transition:none}
  }
  @media (max-width:720px){
    :root[data-motion="reduced"] #sidePanel{transition:none}
  }

/* ==========================================================================
   FLASHCARDS (ago/2026) - estudo por cartoes dentro do mapa
   O botao (.flashbtn) e o baralho inteiro sao criados por map-engine.js
   (LEI 16: interface nova sem mudanca de estrutura vai no JS do motor), e SO
   aparecem quando MAP_DATA.flashcards existe e nao esta vazio - hoje, so nos
   mapas cujo JSON ja recebeu o bloco "flashcards".
   Visual validado em piloto com o usuario (01/08/2026):
   - claro: cartao de papel com moldura marrom, Fredoka na pergunta (o baralho
     e CONTEUDO, como os cards do mapa; a moldura sobria fica de fora daqui);
   - escuro: "papel noturno" (mesma filosofia do bloco MODO NOTURNO acima -
     cartao creme no escuro e um farol), dica em plaquinha pastel com tinta
     escura, como as ilustracoes;
   - celular: chips de topico em UMA linha com rolagem horizontal (mesma
     solucao do .chiprail do Estudo rapido) e cartao mais baixo (48dvh) para
     setas e autoavaliacao nunca sairem da tela.
   ========================================================================== */
  .flashbtn{
    position:relative;flex:0 0 auto;width:32px;height:32px;border-radius:10px;
    cursor:pointer;padding:0;display:flex;align-items:center;justify-content:center;
    background:transparent;border:1px solid transparent;color:var(--ui-muted);
  }
  .flashbtn svg{width:17px;height:17px}
  .flashbtn:hover{background:var(--ui-surface-2);color:var(--ui-text);border-color:var(--ui-border)}
  .flashbtn:focus-visible{outline:2px solid var(--ui-accent);outline-offset:1px}

  .fc-overlay{position:fixed;inset:0;z-index:200;display:none;overflow-y:auto;
    background:rgba(46,28,12,.55);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px)}
  body.fc-open .fc-overlay{display:flex;flex-direction:column;align-items:center}
  .fc-deck{width:min(680px,94vw);margin:auto;display:flex;flex-direction:column;gap:12px;padding:16px 0}
  .fc-head{display:flex;align-items:center;gap:12px;color:#FFF4E2}
  .fc-head .fc-t{margin-right:auto;min-width:0}
  .fc-head h2{font-family:'Fredoka',sans-serif;font-weight:600;font-size:19px;white-space:nowrap}
  .fc-head small{display:block;font-family:'Inter',sans-serif;font-size:11.5px;font-weight:550;
    color:#FFD9AE;letter-spacing:.03em}
  .fc-ib{width:44px;height:44px;border-radius:12px;border:2px solid rgba(255,244,226,.45);
    background:rgba(255,244,226,.12);color:#FFF4E2;cursor:pointer;
    display:flex;align-items:center;justify-content:center;flex:0 0 auto}
  .fc-ib:hover{background:rgba(255,244,226,.22)}
  .fc-ib:focus-visible{outline:3px solid #FFF4E2;outline-offset:2px}
  .fc-ib svg{width:20px;height:20px}
  .fc-chips{display:flex;gap:7px;flex-wrap:wrap}
  .fc-chip{font-family:'Inter',sans-serif;font-size:12px;font-weight:600;color:#FFF4E2;
    background:rgba(255,244,226,.13);border:1.5px solid rgba(255,244,226,.4);
    border-radius:999px;padding:7px 13px;cursor:pointer;min-height:32px}
  .fc-chip:hover{background:rgba(255,244,226,.24)}
  .fc-chip[aria-pressed="true"]{background:#FFF4E2;color:#7A3400;border-color:#FFF4E2}
  .fc-chip .fc-dot{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:6px}
  .fc-card{perspective:1400px;height:min(400px,56dvh);position:relative;cursor:pointer;outline:none}
  .fc-card:focus{outline:none}
  .fc-card:focus-visible{outline:none}
  .fc-card:focus-visible .fc-face{box-shadow:0 6px 0 #7A3400, 0 18px 40px rgba(46,28,12,.35), 0 0 0 3px var(--fc-c,var(--laranja))}
  .fc-card .fc-in{position:absolute;inset:0;transform-style:preserve-3d;
    transition:transform .45s cubic-bezier(.2,.7,.3,1)}
  .fc-card.fc-flip .fc-in{transform:rotateY(180deg)}
  .fc-face{position:absolute;inset:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;
    background:#FFF9EF;border:3px solid #7A3400;border-radius:22px;
    box-shadow:0 6px 0 #7A3400, 0 18px 40px rgba(46,28,12,.35);
    display:flex;flex-direction:column;padding:22px 26px;overflow:hidden;color:#3B2A1A;
    font-family:'Nunito',sans-serif}
  .fc-face.fc-back{transform:rotateY(180deg)}
  .fc-face::before{content:"";position:absolute;left:0;top:0;bottom:0;width:9px;background:var(--fc-c,var(--laranja))}
  .fc-top{display:flex;align-items:center;gap:10px;margin-bottom:14px}
  .fc-tag{font-family:'Inter',sans-serif;font-size:11px;font-weight:650;letter-spacing:.05em;
    text-transform:uppercase;color:var(--fc-c,var(--laranja));background:var(--fc-cs,var(--laranja-soft));
    border-radius:999px;padding:4px 11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:60%}
  .fc-side{margin-left:auto;font-family:'Inter',sans-serif;font-size:10.5px;font-weight:650;
    letter-spacing:.06em;text-transform:uppercase;color:rgba(59,42,26,.45)}
  .fc-star{width:44px;height:44px;border:none;background:none;cursor:pointer;
    display:flex;align-items:center;justify-content:center;border-radius:12px;
    color:rgba(59,42,26,.38);flex:0 0 auto}
  .fc-star:hover{background:rgba(122,52,0,.08)}
  .fc-star:focus-visible{outline:2px solid var(--laranja);outline-offset:1px}
  .fc-star svg{width:23px;height:23px;fill:none;stroke:currentColor;stroke-width:2}
  .fc-star.fc-on{color:#E8A200}
  .fc-star.fc-on svg{fill:#F7C948;stroke:#B87F00}
  .fc-qa{flex:1;display:flex;flex-direction:column;justify-content:center;min-height:0;overflow:auto}
  .fc-q{font-family:'Fredoka',sans-serif;font-weight:600;font-size:clamp(19px,2.6vw,25px);line-height:1.3;text-wrap:balance}
  .fc-a{font-size:clamp(15px,1.9vw,17.5px);line-height:1.55;font-weight:600}
  .fc-a b{color:var(--fc-c,var(--laranja))}
  .fc-a ul{margin:6px 0 0 20px;display:flex;flex-direction:column;gap:6px}
  .fc-tip{margin-top:14px;font-size:13px;font-weight:650;line-height:1.45;color:#3B2A1A;
    background:var(--fc-cs,var(--laranja-soft));border-left:4px solid var(--fc-c,var(--laranja));
    border-radius:10px;padding:9px 12px}
  .fc-hint{text-align:center;font-family:'Inter',sans-serif;font-size:12px;font-weight:550;
    color:rgba(59,42,26,.5);margin-top:12px}
  .fc-prog{display:flex;align-items:center;gap:12px;color:#FFF4E2;
    font-family:'Inter',sans-serif;font-size:12.5px;font-weight:600}
  .fc-bar{flex:1;height:8px;border-radius:999px;background:rgba(255,244,226,.25);overflow:hidden}
  .fc-bar i{display:block;height:100%;width:0;background:#FFD34D;border-radius:999px;transition:width .25s ease}
  .fc-nav{display:flex;align-items:center;justify-content:center;gap:12px}
  .fc-arrow{width:52px;height:52px;border-radius:16px;background:#FFF4E2;color:#7A3400;
    border:2.5px solid #7A3400;box-shadow:0 3px 0 #7A3400;cursor:pointer;
    display:flex;align-items:center;justify-content:center}
  .fc-arrow:hover{background:#FFE3C7}
  .fc-arrow:active{transform:translateY(2px);box-shadow:0 1px 0 #7A3400}
  .fc-arrow:disabled{opacity:.35;cursor:default;transform:none}
  .fc-arrow:focus-visible{outline:3px solid #FFF4E2;outline-offset:2px}
  .fc-arrow svg{width:22px;height:22px}
  .fc-grade{display:flex;gap:10px;min-height:52px;align-items:center}
  .fc-gb{font-family:'Fredoka',sans-serif;font-weight:600;font-size:15px;
    border-radius:16px;border:2.5px solid #7A3400;box-shadow:0 3px 0 #7A3400;
    padding:11px 20px;min-height:48px;cursor:pointer;display:inline-flex;align-items:center;gap:8px}
  .fc-gb:active{transform:translateY(2px);box-shadow:0 1px 0 #7A3400}
  .fc-gb:focus-visible{outline:3px solid #FFF4E2;outline-offset:2px}
  .fc-gb.fc-hit{background:#D8F3E1;color:#14532D}
  .fc-gb.fc-hit:hover{background:#B7E8C9}
  .fc-gb.fc-miss{background:#FFDFDF;color:#7F1D1D}
  .fc-gb.fc-miss:hover{background:#FFC9C9}
  .fc-gb svg{width:18px;height:18px}
  .fc-grade .fc-call{font-family:'Inter',sans-serif;font-size:13px;font-weight:600;color:#FFD9AE}
  .fc-done{display:none;text-align:center;color:#FFF4E2;padding:20px 0}
  .fc-done h3{font-family:'Fredoka',sans-serif;font-weight:600;font-size:24px;margin-bottom:6px}
  .fc-done p{font-family:'Inter',sans-serif;font-size:14px;font-weight:550;color:#FFD9AE;margin-bottom:18px}
  .fc-nums{display:flex;justify-content:center;gap:14px;margin-bottom:22px;flex-wrap:wrap}
  .fc-num{background:rgba(255,244,226,.12);border:2px solid rgba(255,244,226,.4);
    border-radius:16px;padding:12px 22px;min-width:110px}
  .fc-num b{display:block;font-family:'Fredoka',sans-serif;font-size:26px}
  .fc-num span{font-family:'Inter',sans-serif;font-size:11.5px;font-weight:600;letter-spacing:.04em}
  .fc-acts{display:flex;justify-content:center;gap:10px;flex-wrap:wrap}
  .fc-deck.fc-fim .fc-card,.fc-deck.fc-fim .fc-nav,.fc-deck.fc-fim .fc-prog{display:none}
  .fc-deck.fc-fim .fc-done{display:block}

  /* papel noturno do baralho: escolha manual vence, sistema decide no resto
     (mesmo escopo duplo dos --ui-* la em cima) */
  :root[data-theme="dark"] .fc-face{
    background:var(--np-card,#2A241D);border-color:#4A4137;color:#EFE9E1;
    box-shadow:0 6px 0 #14100C, 0 18px 40px rgba(0,0,0,.5);
  }
  :root[data-theme="dark"] .fc-side{color:rgba(239,233,225,.5)}
  :root[data-theme="dark"] .fc-hint{color:rgba(239,233,225,.55)}
  :root[data-theme="dark"] .fc-star{color:rgba(239,233,225,.4)}
  :root[data-theme="dark"] .fc-star:hover{background:rgba(239,233,225,.08)}
  :root[data-theme="dark"] .fc-arrow{background:#2B2520;color:#EFE9E1;border-color:#4A4137;box-shadow:0 3px 0 #14100C}
  :root[data-theme="dark"] .fc-arrow:hover{background:#38312A}
  :root[data-theme="dark"] .fc-arrow:active{box-shadow:0 1px 0 #14100C}
  :root[data-theme="dark"] .fc-gb{border-color:#4A4137;box-shadow:0 3px 0 #14100C}
  :root[data-theme="dark"] .fc-gb:active{box-shadow:0 1px 0 #14100C}
  :root[data-theme="dark"] .fc-gb.fc-hit{background:rgba(74,222,128,.16);color:#4ADE80}
  :root[data-theme="dark"] .fc-gb.fc-hit:hover{background:rgba(74,222,128,.26)}
  :root[data-theme="dark"] .fc-gb.fc-miss{background:rgba(248,113,113,.16);color:#F87171}
  :root[data-theme="dark"] .fc-gb.fc-miss:hover{background:rgba(248,113,113,.26)}
  @media (prefers-color-scheme: dark){
    :root:not([data-theme="light"]) .fc-face{
      background:var(--np-card,#2A241D);border-color:#4A4137;color:#EFE9E1;
      box-shadow:0 6px 0 #14100C, 0 18px 40px rgba(0,0,0,.5);
    }
    :root:not([data-theme="light"]) .fc-side{color:rgba(239,233,225,.5)}
    :root:not([data-theme="light"]) .fc-hint{color:rgba(239,233,225,.55)}
    :root:not([data-theme="light"]) .fc-star{color:rgba(239,233,225,.4)}
    :root:not([data-theme="light"]) .fc-star:hover{background:rgba(239,233,225,.08)}
    :root:not([data-theme="light"]) .fc-arrow{background:#2B2520;color:#EFE9E1;border-color:#4A4137;box-shadow:0 3px 0 #14100C}
    :root:not([data-theme="light"]) .fc-arrow:hover{background:#38312A}
    :root:not([data-theme="light"]) .fc-arrow:active{box-shadow:0 1px 0 #14100C}
    :root:not([data-theme="light"]) .fc-gb{border-color:#4A4137;box-shadow:0 3px 0 #14100C}
    :root:not([data-theme="light"]) .fc-gb:active{box-shadow:0 1px 0 #14100C}
    :root:not([data-theme="light"]) .fc-gb.fc-hit{background:rgba(74,222,128,.16);color:#4ADE80}
    :root:not([data-theme="light"]) .fc-gb.fc-hit:hover{background:rgba(74,222,128,.26)}
    :root:not([data-theme="light"]) .fc-gb.fc-miss{background:rgba(248,113,113,.16);color:#F87171}
    :root:not([data-theme="light"]) .fc-gb.fc-miss:hover{background:rgba(248,113,113,.26)}
  }

  /* topicos em tela estreita: trilho de UMA linha, como o .chiprail */
  @media (max-width:720px){
    .fc-chips{
      flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;justify-content:flex-start;
      -webkit-overflow-scrolling:touch;scrollbar-width:none;
      margin:0 -12px;padding:2px 12px 6px;
    }
    .fc-chips::-webkit-scrollbar{display:none}
    .fc-chip{flex:0 0 auto;white-space:nowrap;font-size:11.5px;padding:6px 11px;min-height:30px}
  }
  @media (max-width:560px){
    .fc-face{padding:16px 16px 16px 22px}
    .fc-head h2{font-size:16px}
    .fc-card{height:min(380px,48dvh)}
    .fc-deck{gap:10px;padding:12px 0}
  }
  @media (pointer:coarse){
    .flashbtn::after{
      content:"";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
      width:100%;height:100%;min-width:44px;min-height:44px;
    }
  }
  @media (prefers-reduced-motion: reduce){
    :root:not([data-motion="full"]) .fc-card .fc-in{transition:none}
    :root:not([data-motion="full"]) .fc-bar i{transition:none}
  }
  :root[data-motion="reduced"] .fc-card .fc-in{transition:none}
  :root[data-motion="reduced"] .fc-bar i{transition:none}

  /* ---------- exemplos de Lingua Portuguesa: negrito sem etiqueta ----------
     (set/2026, pedido do usuario) Nos blocos "Exemplo", o pedaco de palavra
     (tún<u>el</u>, órg<u>ão</u>) e marcado com <u>, o sublinhado padrao. O <b>
     ali e so negrito: sem fundo, padding e borda, que abriam um vao dentro da
     palavra. Ate 26/09/2026 este bloco desenhava o <b> COMO sublinhado, e
     negrito e sublinhado ficavam iguais (o botao S do admin acendia sozinho
     no negrito); os 702 <b> desses itens viraram <u> no conteudo. Fica no
     fim do arquivo de proposito: precisa vencer as regras de .sub b e
     .subnode b do tema escuro, que tem a mesma especificidade. */
  :root[data-subject="lingua-portuguesa"] .is-exemplo > ul b{
    background:transparent;border:0;border-radius:0;padding:0;
  }

  /* ---------- sublinhado padrao dos cards ----------
     (set/2026, pedido do usuario) O <u> que o admin grava saia com o
     sublinhado fino do navegador, na cor do texto. Agora e o mesmo traco dos
     exemplos acima: 2px, na cor do topico. So dentro dos cards (.sub/.subnode):
     a anotacao do aluno tem o sublinhado dela. */
  .sub u,.subnode u{
    text-decoration:underline 2px var(--c);text-underline-offset:3px;
    text-decoration-skip-ink:none;
  }

  /* ---------- busca nos outros mapas da disciplina (set/2026) ----------
     Um icone DENTRO do campo de busca, no canto direito: a barra nao ganha
     botao nem largura (o "?" orfao da BUSCA COMPACTA, mais acima, nao volta).
     O × de limpar anda para a esquerda dele. */
  .map-search-field{padding-right:56px}
  .map-search-clear{right:31px}
  .map-search-cross{
    position:absolute;right:5px;top:5px;width:24px;height:24px;border:0;padding:0;
    border-radius:6px;background:transparent;color:var(--ui-muted);cursor:pointer;
    display:grid;place-items:center
  }
  .map-search-cross svg{width:16px;height:16px}
  .map-search-cross:hover{background:var(--ui-surface-2);color:var(--ui-text)}
  /* ligado: so o icone na cor de destaque, fundo transparente (pedido do usuario) */
  .map-search.is-cross .map-search-cross{background:transparent;color:var(--ui-accent)}
  .map-search.is-cross .map-search-cross:hover{background:var(--ui-surface-2)}
  .map-search.is-cross .map-search-field{border-color:var(--ui-accent)}
  @media (max-width:618px){
    /* lupa compacta: o icone so aparece com a busca aberta */
    .map-search:not(:focus-within):not(.has-value):not(.is-cross) .map-search-cross{display:none}
    .map-search:not(:focus-within):not(.has-value):not(.is-cross) .map-search-field{padding:6px 4px 6px 30px}
    .map-search:focus-within .map-search-field,
    .map-search.has-value .map-search-field,
    .map-search.is-cross .map-search-field{padding:6px 56px 6px 31px;cursor:text}
    .map-search.is-cross{flex:1 1 120px;max-width:none}
    .map-search.is-cross .map-search-field::placeholder{opacity:1}
    .map-search.is-cross ~ .modeswitch{display:none}
  }

  /* barra aberta do celular em duas linhas (pedido do usuario, set/2026):
     em cima a busca e o alternador Mapa interativo / Estudo rapido; embaixo
     todos os icones. O ::before e uma quebra de linha: ocupa a largura toda
     (flex-basis 100%) e, pela ordem, fica entre as duas turmas. A margem
     negativa desconta o row-gap que a linha vazia dele somaria. */
  @media (max-width:720px){
    .topbar.tb-open .controls::before{content:"";order:-1;flex:0 0 100%;height:0;margin-top:-7px}
    .topbar.tb-open .controls .map-search,
    .topbar.tb-open .controls .modeswitch{order:-2}
  }

  .map-search-results.msx{max-height:min(460px,65vh)}
  /* texto escuro fixo: no tema escuro o texto claro sobre o amarelo sumia */
  .map-search-results mark,mark.cmp-marca{background:#FFE58A;color:#3B2A1A;border-radius:3px;padding:0 1px}
  .msx-sum{padding:6px 10px 8px;color:var(--ui-muted);font:500 11.5px 'Inter',system-ui,sans-serif}
  /* MAPA: faixa propria, grudada no topo da lista enquanto os cards dele
     rolam, para nunca se confundir com o topico (que vai dentro do card) */
  .msx-mapa{margin-top:6px}
  .msx-grp{
    position:sticky;top:-6px;z-index:1;display:flex;align-items:center;gap:9px;
    padding:8px 10px;border-radius:9px;background:var(--ui-surface-2);color:var(--ui-text);
    font:650 13px/1.2 'Inter',system-ui,sans-serif
  }
  .msx-grp svg{flex:0 0 22px;width:22px;height:14px}
  .msx-grp span{flex:1;min-width:0}
  .msx-grp span small{display:block;font-size:9.5px;font-weight:650;letter-spacing:.07em;text-transform:uppercase;color:var(--ui-muted);margin-bottom:1px}
  .msx-grp em{font-style:normal;font-weight:600;font-size:11px;color:var(--ui-muted);white-space:nowrap}
  .msx-itens{margin:4px 0 2px 18px;padding-left:8px;border-left:2px solid var(--ui-border)}
  .msx-hit{padding:8px 10px}
  .msx-hit .msx-onde{display:flex;gap:6px;align-items:baseline}
  .msx-hit .msx-onde b{flex:0 0 auto;font-size:9.5px;font-weight:650;letter-spacing:.06em;text-transform:uppercase;
    border:1px solid var(--ui-border);border-radius:5px;padding:0 4px;line-height:1.5}
  .msx-hit span{display:block;margin-top:4px;color:var(--ui-muted);font-size:11.5px;line-height:1.35}
  .msx-mais{display:block;border:0;background:transparent;color:var(--ui-accent);font:600 11.5px 'Inter',system-ui,sans-serif;padding:3px 10px 8px;cursor:pointer}
  .msx-choice{padding:6px 6px 8px;font-family:'Inter',system-ui,sans-serif;color:var(--ui-text)}
  .msx-choice > strong{display:block;font-weight:650;font-size:13.5px;padding:6px 4px 0}
  .msx-choice > small{display:block;color:var(--ui-muted);font-size:11.5px;padding:2px 4px 10px}
  .msx-voltar{border:0;background:transparent;color:var(--ui-muted);font:600 11.5px 'Inter',system-ui,sans-serif;padding:2px 4px;cursor:pointer}
  .msx-voltar:hover{color:var(--ui-text)}
  .msx-acao{
    display:flex;align-items:center;gap:10px;width:100%;text-align:left;margin-top:6px;
    border:1px solid var(--ui-border);border-radius:9px;background:var(--ui-surface);color:var(--ui-text);
    padding:9px 10px;cursor:pointer;font:500 12.5px/1.25 'Inter',system-ui,sans-serif
  }
  .msx-acao:hover,.msx-acao:focus-visible{background:var(--ui-surface-2);outline:none}
  .msx-acao:disabled{opacity:.6;cursor:wait}
  .msx-acao svg{flex:0 0 18px;width:18px;height:18px;color:var(--ui-accent)}
  .msx-acao b{display:block;font-weight:650}
  .msx-acao small{display:block;color:var(--ui-muted);font-size:11px;margin-top:2px}
  .msx-aviso{margin-top:8px;padding:8px 10px;border-radius:8px;background:var(--ui-surface-2);color:var(--ui-text);font-size:12px;line-height:1.4}

  /* ---------- comparar no Estudo rapido: duas colunas ---------- */
  /* fundo um tom diferente do mapa de origem (pedido do usuario): o canvas
     misturado com o cinza de apoio. No claro fica um pouco mais escuro, no
     escuro um pouco mais claro, sem trocar de cor */
  #studyCmp{
    --cmp-bg:color-mix(in srgb, var(--ui-canvas) 91%, var(--ui-muted));
    position:absolute;top:0;bottom:0;left:50%;right:0;overflow:auto;overflow-anchor:none;
    border-left:1px solid var(--ui-border);
    background:
      radial-gradient(circle at 1px 1px, var(--ui-dot) 1.6px, transparent 0) 0 0/26px 26px,
      var(--cmp-bg);
  }
  #studyCmp .study-top{background:linear-gradient(180deg, var(--cmp-bg), var(--cmp-bg) 78%, transparent)}
  #studyCmp .cmp-conta{box-shadow:0 0 0 2px var(--cmp-bg)}
  #studyCmp.hidden{display:none}
  .estudo-comparando #study{right:50%}
  .estudo-comparando .study-cards{grid-template-columns:1fr}
  #studyCmp .study-center{position:relative;padding-right:48px}
  .cmp-fechar{
    position:absolute;right:10px;top:50%;margin-top:-16px;width:32px;height:32px;border:0;border-radius:8px;
    background:transparent;color:var(--ui-muted);cursor:pointer;display:grid;place-items:center
  }
  .cmp-fechar svg{width:18px;height:18px}
  .cmp-fechar:hover{background:var(--ui-surface-2);color:var(--ui-text)}
  .cmp-troca{display:none}
  /* botoes da coluna secundaria: visiveis, mas apagados (so funcionam no
     mapa de origem); o clique mostra a .cmp-dica */
  #studyCmp .cmp-off{opacity:.3;filter:grayscale(1);cursor:help}
  #studyCmp .cmp-off:hover{opacity:.45}
  .cmp-dica{
    position:fixed;z-index:95;padding:9px 11px;border-radius:9px;background:var(--ui-text);color:var(--ui-surface);
    font:500 12px/1.4 'Inter',system-ui,sans-serif;box-shadow:var(--ui-sh-lg);
    opacity:0;pointer-events:none;transition:opacity .15s
  }
  .cmp-dica.on{opacity:1}
  /* contagem de cards com o termo em cada topico do mapa comparado */
  #studyCmp .chip,.estudo-comparando #study .chip{position:relative}
  .cmp-conta{
    position:absolute;top:-6px;right:-5px;min-width:17px;height:17px;padding:0 4px;border-radius:9px;
    background:#FFE58A;color:#3B2A1A;box-shadow:0 0 0 2px var(--ui-canvas);
    font:700 10px/17px 'Inter',system-ui,sans-serif;font-style:normal;text-align:center
  }
  /* barra do termo: "crase em 5 cards de 3 topicos  ‹ 2/5 ›  ×" */
  .cmp-busca{
    max-width:760px;margin:8px auto 0;display:flex;align-items:center;gap:4px;
    padding:4px 4px 4px 12px;border-radius:10px;background:var(--ui-surface);border:1px solid var(--ui-border);
    box-shadow:var(--ui-sh-sm);font:500 12px 'Inter',system-ui,sans-serif;color:var(--ui-muted)
  }
  .cmp-busca[hidden]{display:none}
  .cmp-busca-txt{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .cmp-busca-txt b{color:var(--ui-text);font-weight:650}
  .cmp-busca-pos{min-width:34px;text-align:center;font-variant-numeric:tabular-nums;color:var(--ui-text);font-weight:600}
  .cmp-busca button{
    width:28px;height:28px;border:0;border-radius:7px;background:transparent;color:var(--ui-text);
    font:600 17px/1 'Inter',system-ui,sans-serif;cursor:pointer
  }
  .cmp-busca button:hover{background:var(--ui-surface-2)}
  .cmp-busca [data-cmp-limpar]{color:var(--ui-muted);font-size:15px}
  .study-top.collapsed .cmp-busca{margin-top:0}
  @media (max-width:720px){
    /* celular: nao cabem duas colunas; um mapa por vez, com a troca embaixo */
    .estudo-comparando #study{right:0}
    /* acima do cabecalho grudado do #study (.study-top, z-index 12), que
       nao cria camada propria e disputaria com esta coluna */
    #studyCmp{left:0;border-left:0;z-index:20}
    .cmp-lado-a #studyCmp{display:none}
    .estudo-comparando .cmp-troca{
      display:flex;position:fixed;left:50%;bottom:14px;transform:translateX(-50%);z-index:90;
      gap:4px;padding:4px;border-radius:12px;background:var(--ui-surface);border:1px solid var(--ui-border);
      box-shadow:var(--ui-sh-lg);max-width:calc(100vw - 32px)
    }
    .cmp-troca button{
      border:0;border-radius:9px;background:transparent;color:var(--ui-muted);cursor:pointer;
      font:600 12px 'Inter',system-ui,sans-serif;padding:8px 12px;max-width:44vw;
      white-space:nowrap;overflow:hidden;text-overflow:ellipsis
    }
    .cmp-troca button.on{background:var(--ui-accent);color:#fff}
    .estudo-comparando .study-body{margin-bottom:90px}
  }

/* Caixa "Fórmula" (set/2026, pedido do dono): a fórmula aparece grande e
   centralizada, e o <b> dentro dela destaca o sinal de que o card trata na cor
   do tópico, sem o fundo de marca-texto do <b> comum. Fica no fim do arquivo
   para vencer .sub b / .subnode b do tema escuro, que têm a mesma especificidade. */
.sub .note.note-formula{text-align:center;font-size:17px;font-weight:800;line-height:1.35;padding:7px 10px 9px}
.subnode .note.note-formula{text-align:center;font-size:14px;font-weight:800;line-height:1.35;padding:5px 8px 7px}
.sub .note.note-formula .note-label,.subnode .note.note-formula .note-label{text-align:left}
.sub .note.note-formula b,.subnode .note.note-formula b{background:none;border:0;padding:0 1px;color:var(--c);font-weight:900;font-size:1.2em}
/* Índice e expoente legíveis em fórmula (set/2026): os caracteres Unicode ₙ, ₁, ⁿ⁻¹
   saem minúsculos na Nunito. <span class="ix">n</span> é subscrito e
   <span class="ex">n−1</span> é expoente, com letra normal um pouco menor. */
.ix,.ex{font-size:.72em;line-height:0;position:relative;font-weight:inherit}
.ix{vertical-align:-.3em}
.ex{vertical-align:.55em}
