/* Blog IAJUS: folha unica gerada (P1, 2026-07-20). Cada pagina linka /blog/blog.css
   em vez de embutir ~8k de CSS inline. Tokens base = mesmos VALORES do design system
   da landing (saas/landing/styles.css, :root + [data-theme=light]); exclusivos do blog:
   --stf/--stj/--tst/--guia/--produto (tribunal/categoria) e --measure (medida editorial).
   Ouro de superficie (--btn-gold-hi/lo) e tema-invariante: sem override no bloco light.

   --header-veil e COPIA DELIBERADA de saas/landing/styles.css, e a razao e estrutural,
   nao descuido: as 16 paginas do blog linkam SO /blog/blog.css (medido 2026-08-31 nas
   130 paginas HTML da landing — nenhuma delas carrega styles.css E blog.css ao mesmo
   tempo, e este ficheiro nao tem @import nenhum). Uma ilha de tokens disjunta nao
   alcanca declaracao nenhuma da outra: sem esta linha, var(--header-veil) aqui seria
   custom property indefinida sem fallback e a barra fixa do blog ficaria SEM fundo.
   Mesma razao pela qual nao aponta ao --scrim da app, que a landing tambem nao alcanca. */
@font-face{font-family:Lora;src:url('/assets/fonts/lora-latin.woff2') format('woff2');font-display:swap}
@font-face{font-family:'Public Sans';src:url('/assets/fonts/public-sans-latin.woff2') format('woff2');font-display:swap}
@font-face{font-family:'Fira Code';src:url('/assets/fonts/fira-code-latin.woff2') format('woff2');font-display:swap}
@font-face{font-family:Inter;src:url('/assets/fonts/inter-latin.woff2') format('woff2');font-display:swap}
/* #108 T2: fallbacks metricos IDENTICOS aos de saas/landing/styles.css (autoridade; o spec
   primeira-pintura-sem-deslocamento prende os dois). Sem eles o swap da webfont refluia o
   indice do blog: CLS 0,30 a 768 (auditoria 23/09). */
@font-face{font-family:'Lora Fallback';src:local('Georgia');size-adjust:104.06%;ascent-override:96.68%;descent-override:26.33%;line-gap-override:0%}
@font-face{font-family:'Lora Fallback';font-style:italic;src:local('Georgia Italic');size-adjust:99.54%;ascent-override:101.07%;descent-override:27.53%;line-gap-override:0%}
@font-face{font-family:'Public Sans Fallback';src:local('Arial');size-adjust:101.56%;ascent-override:93.54%;descent-override:22.15%;line-gap-override:0%}
@font-face{font-family:'Public Sans Fallback';font-style:italic;src:local('Arial Italic');size-adjust:98.31%;ascent-override:96.63%;descent-override:22.89%;line-gap-override:0%}
@font-face{font-family:'Inter Fallback';src:local('Arial');size-adjust:105.48%;ascent-override:91.84%;descent-override:22.87%;line-gap-override:0%}
:root{color-scheme:dark;--font-nav:'Inter','Inter Fallback','Public Sans','Public Sans Fallback',system-ui,-apple-system,sans-serif;--font-display:Lora,'Lora Fallback',Georgia,serif;--font-mono:'Fira Code',ui-monospace,monospace;--bg:#161b28;--bg-2:#1a1f2e;--bg-3:#202637;--ink:#f8f9fa;--ink-soft:#e7e8ea;--text:#e9e7dd;--muted:#b4b1a5;--tertiary:#9c9a8e;--gold:#b89244;--gold2:#d8b86a;--gold-soft:#a37f37;--btn-gold-hi:#d8b86a;--btn-gold-lo:#a37f37;--field-border:color-mix(in srgb, var(--ink) 50%, transparent);--hair:rgba(255,255,255,.09);--header-veil:rgba(8,11,20,.72);--rule:color-mix(in srgb,var(--gold) 28%,transparent);--card:rgba(255,255,255,.03);--stf:#d97706;--stj:#57a8e0;--tst:#4fbf96;--guia:#8d89f5;--produto:#d98ad9;--autoral:#e0806e;--gutter:clamp(20px,5vw,56px);--measure:68ch;--radius:14px;--maxw:1200px}
*{box-sizing:border-box}
html{scroll-behavior:smooth;scroll-padding-top:88px}
body{margin:0;background:var(--bg);color:var(--text);font:400 clamp(1.02rem,1vw,1.15rem)/1.7 'Public Sans','Public Sans Fallback',system-ui,-apple-system,sans-serif}
a{color:var(--gold2);text-underline-offset:.18em}
button,input{font:inherit}
button,a{touch-action:manipulation}
a:focus-visible,button:focus-visible,input:focus-visible{outline:2px solid var(--gold2);outline-offset:3px;border-radius:6px;box-shadow:0 0 0 4px color-mix(in srgb,var(--gold) 18%,transparent)}
h1,h2,h3{color:var(--ink);font-family:var(--font-display);line-height:1.15;margin-top:0}
h1{font-size:clamp(2.2rem,6vw,4.5rem);max-width:18ch}
h2{font-size:clamp(1.45rem,3vw,2rem)}
h3{font-size:1.28rem}
.skip-link{position:absolute;z-index:100;left:16px;top:-64px;padding:11px 18px;background:var(--btn-gold-hi);color:#1c1917;font:600 .85rem var(--font-mono);border-radius:10px;text-decoration:none;transition:top .2s ease}
.skip-link:focus{top:16px}
.site-header{position:sticky;top:0;z-index:30;background:var(--header-veil);border-bottom:1px solid var(--hair);backdrop-filter:saturate(140%) blur(14px);-webkit-backdrop-filter:saturate(140%) blur(14px)}
.header-inner,.page,.site-footer{width:min(var(--maxw),100%);margin:auto;padding-inline:var(--gutter)}
/* Teto PRÓPRIO do header (1360px), espelho do `.topbar .wrap{max-width:1360px}` da
   landing (styles.css). Herdar --maxw 1200 aqui fazia a barra NUNCA caber: medido
   2026-08-07 no header servido, o conteúdo do nav pedia 895px numa caixa de 820px e
   transbordava 75px em QUALQUER viewport >=1081px — idêntico em 1440 e em 1920,
   porque `width:min(1200,100%)` trava a caixa e alargar a tela não dava um pixel.
   O corpo editorial (.page/.site-footer) segue em --maxw 1200, como na landing. */
.header-inner{position:relative;width:min(1360px,100%);min-height:80px;display:flex;align-items:center;justify-content:space-between;gap:16px}
.brand{display:inline-flex;align-items:center;gap:13px;min-height:44px;color:var(--ink);text-decoration:none}
.brand svg{width:38px;height:38px;flex:none}
.brand b{font:700 1.34rem/1 'Public Sans','Public Sans Fallback',system-ui,sans-serif;letter-spacing:.01em}
.brand b span{color:var(--gold);font-family:var(--font-display);font-style:italic;font-weight:600}
.brand small{display:block;margin-top:3px;font-size:.55rem;font-family:var(--font-mono);letter-spacing:.12em;text-transform:uppercase;color:var(--tertiary);white-space:nowrap}
/* GARANTIA ESTRUTURAL do não-overlap com o toggle de tema, espelho do `.nav-right`
   da landing. `flex:1` + `min-width:0` já cedem a largura do toggle (`flex:none`);
   o que sobrepunha era o CONTEÚDO: os itens são `white-space:nowrap`, logo não
   encolhem abaixo do min-content, transbordam a caixa e PINTAM por cima do irmão
   seguinte — e o toggle, por vir depois no DOM, recebia a pílula "Cadastre-se" por
   cima. `clip` corta o excedente na borda da caixa; precisa ser `clip` e não
   `hidden` porque `hidden` num eixo força o outro a `auto`. Isto é o cinto: o teto
   de 1360px acima é quem dá a largura, mas rótulo mais longo (i18n) volta a
   transbordar e aqui degrada para CORTE, nunca para sobreposição. */
.header-nav{display:flex;flex:1;align-items:center;gap:clamp(6px,.65vw,8px);min-width:0;overflow-x:clip;overflow-y:visible}
.header-nav a{display:inline-flex;align-items:center;min-height:40px;padding-block:8px;font-family:var(--font-nav);font-weight:500;font-size:.95rem;letter-spacing:.005em;color:var(--muted);text-decoration:none;white-space:nowrap;transition:color .2s ease}
.header-nav a:hover,.header-nav a[aria-current]{color:var(--gold)}
/* BOARD-01: par da landing master — Entrar = outline (nav-cta); Cadastre-se = dourado (nav-entrar). */
.header-nav .nav-cta{margin-left:auto;min-height:44px;padding:8px 16px;color:var(--ink);background:transparent;font-weight:600;border:1px solid var(--hair);border-radius:999px}
.header-nav .nav-cta:hover{color:var(--gold);border-color:var(--gold)}
.header-nav .nav-entrar{min-height:44px;padding:8px 16px;color:#1c1917;background:linear-gradient(180deg,var(--btn-gold-hi),var(--btn-gold-lo));font-weight:600;border:1px solid color-mix(in srgb,var(--btn-gold-lo) 62%,#1c1917);border-radius:999px;box-shadow:inset 0 1px 0 rgba(255,255,255,.3),0 1px 2px rgba(0,0,0,.28);text-decoration:none}
.header-nav .nav-entrar:hover{color:#1c1917;background:linear-gradient(180deg,color-mix(in srgb,var(--btn-gold-hi) 88%,white),var(--btn-gold-hi))}
.theme-toggle{display:inline-flex;align-items:center;justify-content:center;flex:none;width:38px;height:38px;margin-left:14px;background:var(--card);border:1px solid var(--hair);border-radius:999px;color:var(--ink);cursor:pointer;transition:color .15s ease,background .15s ease,border-color .15s ease}
.theme-toggle:hover{color:var(--gold);border-color:var(--gold)}
.theme-toggle svg{width:18px;height:18px;display:block}
.nav-toggle{display:none;width:44px;height:44px;padding:10px 11px;border:1px solid var(--hair);border-radius:10px;background:transparent;color:var(--ink);cursor:pointer;flex-direction:column;justify-content:center;align-items:center;gap:5px}
.nav-toggle-bar{display:block;width:20px;height:2px;background:var(--ink-soft);border-radius:2px;transition:transform .25s ease,opacity .2s ease}
.nav-toggle[aria-expanded=true] .nav-toggle-bar:nth-child(1){transform:translateY(7px) rotate(45deg)}
.nav-toggle[aria-expanded=true] .nav-toggle-bar:nth-child(2){opacity:0}
.nav-toggle[aria-expanded=true] .nav-toggle-bar:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
.nav-close{display:none}
.nav-scrim{position:fixed;inset:0;z-index:25;background:rgba(0,0,0,.55);opacity:0;visibility:hidden;pointer-events:none;transition:opacity .25s ease,visibility .25s ease}
.nav-scrim.open{opacity:1;visibility:visible;pointer-events:auto}
html.nav-open,html.nav-open body{overflow:hidden}
html.nav-open .site-header{position:fixed;top:0;left:0;right:0}
/* Par OBRIGATÓRIO do `max-width:1080px` do drawer, espelho do mesmo bloco no
   `styles.css`: acima do ponto a barra é horizontal e o scrim nunca tem de aparecer.
   Sem esta linha ele fica no DOM à espera de `.open` — e `.open` sobrevive a um resize
   com a gaveta aberta, que foi como se mediu (2026-09-01, /blog/ aberto a 1024 e
   alargado para 1280: véu preto por cima da página inteira, com `pointer-events:auto`,
   e a barra horizontal servida por baixo).
   ⚠️ O que esta linha NÃO desfaz, e o `styles.css` também não (medido no mesmo dia,
   mesma sequência, na landing: scrim `display:none`, mas `navOpen:true`,
   `bodyOverflow:hidden`, `topbar position:fixed`): a classe `nav-open` continua a
   travar a rolagem e a fixar o header. Isso é buraco de JS — nem o `app.js` nem o
   script inline do blog ouvem `resize` — e não se fecha a partir desta folha. */
@media(min-width:1081px){.nav-scrim{display:none}}
.page{padding-block:clamp(54px,8vw,96px)}
.kicker,.meta,.card-kicker,.nav-direction,.category-count{font:600 .76rem/1.4 var(--font-mono);letter-spacing:.12em;text-transform:uppercase;color:var(--tertiary)}
.lede{max-width:64ch;color:var(--muted);font-size:clamp(1.08rem,2vw,1.28rem)}
.search{margin-block:36px 18px;position:relative;max-width:760px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.search-row{display:flex;gap:10px}
.search input{width:100%;min-height:52px;padding:12px 16px;background:var(--bg-2);color:var(--ink);border:1px solid var(--field-border);border-radius:var(--radius)}
.search input:focus{border-color:var(--gold)}
.clear-search{min-width:88px;min-height:52px;background:var(--bg-3);color:var(--ink);border:1px solid var(--hair);border-radius:var(--radius);cursor:pointer}
.search-status{min-height:28px;margin:.45rem 0 0;color:var(--muted);font-size:.9rem}
.chips{display:flex;gap:8px;overflow-x:auto;padding:6px 2px 18px;scrollbar-width:none}.chips::-webkit-scrollbar{display:none}
.chip{flex:0 0 auto;min-height:44px;padding:8px 14px;border:1px solid var(--hair);border-radius:999px;background:transparent;color:var(--muted);cursor:pointer}
.chip[aria-pressed=true]{color:var(--ink);border-color:var(--gold);background:color-mix(in srgb,var(--gold) 14%,transparent)}
.featured,.post-card,.juris-cite,.cta,.post-nav a{background:var(--bg-2);border:1px solid var(--hair);border-radius:var(--radius)}
.featured{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(220px,.75fr);gap:32px;padding:clamp(24px,4vw,44px);margin:20px 0 58px}
/* Faixa de destaque DECLARADA VAZIA (nenhum autoral publicado). A coluna da capa nao existe
   aqui, entao mante-la reservada abriria um vao de ~30% da faixa que parece defeito de
   layout em vez de estado honesto. Dupla classe de proposito: `.featured` e' redeclarado
   mais abaixo dentro de media queries, e com especificidade igual venceria pela ordem. */
.featured.featured-vazio{grid-template-columns:minmax(0,1fr)}
.featured.featured-vazio h2+p{max-width:var(--measure)}
.featured>picture,.post-card>picture{display:block}
.featured>picture{align-self:center}
.featured img,.post-card img{display:block;width:100%;height:auto;aspect-ratio:1200/630;object-fit:cover;border-radius:10px;background:var(--bg-3)}
.category{margin-top:52px}
.category-head{display:flex;align-items:end;justify-content:space-between;gap:20px;border-bottom:1px solid var(--hair);margin-bottom:20px}
.category-head h2{margin-bottom:12px}
.post-grid,.results-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,300px),1fr));gap:18px}
.post-card{position:relative;display:flex;flex-direction:column;min-height:250px;padding:22px;transition:transform .18s,border-color .18s}
.post-card:hover,.post-card:focus-within{transform:translateY(-2px);border-color:var(--gold)}
.post-card h3{margin:.65rem 0}
.post-card h3 a:after{content:'';position:absolute;inset:0}
.post-card p{color:var(--muted);margin:.4rem 0}
.post-card .meta{margin-top:auto;padding-top:18px}
.dot{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:7px;background:var(--gold)}
[data-tribunal=STF] .dot{background:var(--stf)}
[data-tribunal=STJ] .dot{background:var(--stj)}
[data-tribunal=TST] .dot{background:var(--tst)}
/* `~=` casa UM TOKEN da lista: com multiplas categorias no atributo (cat-teses cat-autoral
   org-stf), o `=` de igualdade deixaria de casar e a cor do ponto sumia sem ninguem notar. */
[data-category~=cat-guias] .dot{background:var(--guia)}
[data-category~=cat-novidades] .dot{background:var(--produto)}
[data-category~=cat-autoral] .dot{background:var(--autoral)}
.empty{padding:56px 24px;text-align:center;border:1px dashed var(--rule);border-radius:var(--radius)}
[hidden]{display:none!important}
.article-page{width:min(880px,100%)}
.breadcrumb{font-size:.88rem;color:var(--muted);margin-bottom:18px}
.breadcrumb a{display:inline-block;min-height:24px;padding-block:4px}
.back{display:inline-flex;align-items:center;min-height:44px;margin-block:8px 24px}
.article-head{border-bottom:1px solid var(--hair);padding-bottom:28px}
.article-head h1{max-width:20ch}
/* BLOG-REVIEWER-TRUST-01: only present when BLOG_HUMAN_REVIEWER.name is set. */
.article-head .reviewer{margin:10px 0 0;font:500 .92rem/1.45 var(--font-display);color:var(--muted);letter-spacing:0;text-transform:none}
.body{max-width:var(--measure);margin:48px auto}
.body p,.body li{color:var(--text)}
.body h2,.body h3{margin-top:2.4em}
.body pre{overflow:auto;padding:18px;background:var(--bg-2);border-radius:10px}
.body img{max-width:100%;height:auto}
.juris-cite,.cta{max-width:var(--measure);margin:40px auto;padding:clamp(22px,4vw,34px)}
.juris-cite strong{display:block;font:600 clamp(1.5rem,4vw,2.4rem)/1.2 var(--font-display);margin:.75rem 0}
.cta{display:flex;align-items:center;justify-content:space-between;gap:24px}
.cta a{display:inline-flex;align-items:center;justify-content:center;min-height:48px;padding:10px 18px;border-radius:10px;background:linear-gradient(180deg,var(--btn-gold-hi),var(--btn-gold-lo));color:#1c1917;font-weight:700;text-decoration:none}
.post-nav{max-width:var(--measure);margin:34px auto;display:grid;grid-template-columns:1fr 1fr;gap:14px}
.post-nav a{display:flex;flex-direction:column;justify-content:center;min-height:110px;padding:18px;text-decoration:none}
.post-nav a:last-child{text-align:right}
.site-footer{padding-block:32px 48px;border-top:1px solid var(--hair);color:var(--muted)}
.site-footer nav{display:flex;flex-wrap:wrap;gap:6px 18px;margin-top:10px}
.site-footer a{display:inline-flex;align-items:center;min-height:44px}
.results{margin-top:34px}
/* Drawer do HEADER do blog em <=1080px — o MESMO ponto do styles.css desde 2026-09-01,
   e agora AFERIDO, não prometido. Este comentário dizia "o MESMO ponto da landing
   (styles.css @media 1329)" e deixou de ser verdade no dia em que a landing desceu para
   1080: o blog ficou sozinho a servir o HAMBÚRGUER a um desktop de 1280 CSS px (1920
   físicos a 150% de escala), que é exatamente o defeito reportado com print pelo
   operador. Medido a 2026-09-01 no header servido, antes de mexer: hambúrguer em
   1081/1100/1180/1280/1329, nas 3 rotas do blog.
   ⛔ Mover o número SOZINHO não chegava, e isso também se mediu antes: com o par
   reescrito por CSSOM para 1080/1081 e mais nada, o `.header-nav` pede 887,2px numa
   caixa de 705px a 1081 (folga −182,2), −166,3 a 1100 e −93,0 a 1180 — e como a caixa
   traz `overflow-x: clip`, o excedente é DECAPITADO em silêncio: o "Cadastre-se" pinta
   "Cadastr…", que é pior que o hambúrguer porque o hambúrguer pelo menos se vê. Quem
   paga a descida é a banda compacta declarada logo abaixo do bloco.
   ⚠️ O `@media(max-width:1080px)` EDITORIAL (destaque, post-nav, busca) passou a
   partilhar o número e a coincidência é ACIDENTAL: um é onde a barra vira drawer, o
   outro é onde o corpo vira uma coluna única. Quem mexer num não arrasta o outro.
   Juiz: saas/landing/spec/o-header-do-blog-fecha-no-mesmo-ponto-da-landing.test.js */
@media(max-width:1080px){.nav-toggle{display:inline-flex}
.header-nav{position:absolute;top:100%;left:0;right:0;z-index:35;display:none;flex:none;flex-direction:column;align-items:stretch;gap:0;margin:0;padding:8px var(--gutter) 22px;background:#0a0d16;border-bottom:1px solid var(--rule);box-shadow:0 28px 60px -30px rgba(0,0,0,.95);max-height:calc(100vh - 100%);max-height:calc(100dvh - 100%);overflow-y:auto;overflow-x:hidden}
.header-nav.is-open{display:flex}
.nav-close{display:inline-flex;align-items:center;justify-content:center;align-self:flex-end;flex:none;margin:4px 0 10px;width:40px;height:40px;border-radius:9px;border:1px solid var(--hair);background:var(--bg-3);color:var(--muted);font-size:1.05rem;line-height:1;cursor:pointer}
.nav-close:hover{color:var(--gold2);border-color:var(--rule)}
.nav-close:focus-visible{outline:2px solid var(--gold2);outline-offset:2px}
.header-nav a{min-height:44px;padding-block:14px;border-bottom:1px solid var(--hair)}
.header-nav .nav-cta,.header-nav .nav-entrar{margin:12px 0 0;padding:11px 18px;justify-content:center;border-bottom:0;border-radius:12px}
[data-theme=light] .header-nav{background:#f6f3ea;box-shadow:0 28px 60px -30px rgba(26,31,46,.25)}
}
/* BANDA COMPACTA do header, 1081-1329px: é ela que PAGA a descida do drawer acima, com
   os mesmos cinco movimentos, os mesmos tokens e a mesma derivação da banda irmã do
   `styles.css` (@media 1081-1329). Medido a 1081px, o ponto mais apertado (Playwright
   1.61.1 Chromium, deviceScaleFactor 1, /blog/ com as fontes servidas):
     - legenda da marca fora ........... marca 184,1 → 112,2px   (+71,9 de caixa)
     - gutter do header 54,05 → 20px ... (+68,1 de caixa)
     - gap do .header-inner 16 → 12px .. (+8,0 de caixa)
     - corpo do nav 15,2 → 13,6px ...... (−79,6 de conteúdo)
     - pills com padding-inline 12px ... (−16,0 de conteúdo)
   Resultado: o nav pedia 887,2px numa caixa de 705 (−182,2) e passa a pedir 791,6 numa
   de 853 — folga +61,4px, e +100,0px no primeiro frame sem os woff2. NENHUM dos cinco é
   enfeite, e isso foi falsificado um a um: tirando só as pills a folga cai para +45,4;
   tirando só o corpo do nav volta a −18,2, ou seja ainda cortava 18,1px.
   ⭐ Apertar o gutter do HEADER não é invenção: o `.header-inner` já tem teto próprio de
   1360px contra os 1200px de `.page`/`.site-footer` (comentado acima), logo a barra já
   não alinha com a coluna de texto por decisão anterior. E é FLUIDO de propósito — 20px
   a 1081 → 56,0px a 1329 — para encontrar a regra base exatamente no limite: a base é
   `--gutter: clamp(20px,5vw,56px)`, que a 1330 dá 56px. Mesma razão para o corpo do nav
   ser fluido com teto em .95rem, que é o valor da regra base: atravessar 1329→1330 não
   salta tipografia nem gutter, só devolve a legenda da marca.
   ⛔ O que NÃO cedeu, e não é esquecimento: o `margin-left:14px` do `.theme-toggle` é
   ruling do operador (2026-07-05, overlap toggle × CTA) e valia ~10px; comprar largura
   aí reabre o defeito visual que o ruling fechou.
   ⭐ A legenda é `aria-hidden` e o nome acessível da marca é o `aria-label="IAJUS
   Inteligência Jurídica, página inicial"`, que CONTÉM o rótulo visível que sobra
   ("IAJUS") — WCAG 2.5.3 continua satisfeito. O precedente é o `@media(max-width:420px)`
   desta mesma folha, que já cede a mesma legenda pelo mesmo motivo. */
@media(min-width:1081px) and (max-width:1329px){.site-header .brand small{display:none}
.site-header .header-inner{padding-inline:clamp(20px,14.516vw - 136.92px,56px);gap:12px}
.site-header .header-nav a{font-size:clamp(.85rem,.414rem + .645vw,.95rem)}
.site-header .header-nav .nav-cta,.site-header .header-nav .nav-entrar{padding-inline:12px}
}
@media(max-width:1080px){.featured{grid-template-columns:1fr}
.featured img{max-height:220px}
.cta{align-items:flex-start;flex-direction:column}
.post-nav{grid-template-columns:1fr}
.post-nav a:last-child{text-align:left}
.search-row{flex-direction:column}
.clear-search{width:100%}
}
@media(max-width:420px){.brand small{display:none}}
@media(pointer:coarse){.theme-toggle{width:44px;height:44px}}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}
.post-card,.theme-toggle,.nav-toggle-bar,.nav-scrim,.skip-link{transition:none}
.post-card:hover{transform:none}
}
/* ==========================================================================
   BLOG-EDITORIAL-01 (2026-08-08) — camada editorial do blog.
   Entra no FIM da constante STYLE de saas/landing/tools/build_blog_snapshots.py,
   IMEDIATAMENTE ANTES do bloco [data-theme=light] (que precisa continuar por
   ultimo para os tokens de tema claro vencerem).

   Nao substitui nenhuma regra anterior: as que precisam mudar de valor estao
   como EDICAO CIRURGICA no relatorio, com old -> new. Este bloco so ACRESCENTA
   o que nao existia (deck, citacao, nota legal, listas, ritmo) e reancora os
   eixos. Os comentarios longos do STYLE atual documentam medicoes reais de
   2026-08-07 (overflow do header) e ficam INTOCADOS.

   Cada numero abaixo saiu de medicao no DOM servido em 2026-08-08, nao de
   estimativa. O que foi medido esta nomeado em cada bloco.
   ========================================================================== */

/* --- 1. ESCALA MODULAR + MEDIDA DE LINHA CORRIGIDA -----------------------
   MEDIDO: a escala atual salta 2.25x (h1 72px -> h2 32px), 1.96x (h2 -> corpo
   16.32px) e 1.34x (corpo -> meta 12.16px). Nao e escala: sao tres razoes
   diferentes. Aqui a razao e CONSTANTE em 1.25 (terca maior) ancorada em 17px.

   MEDIDO: --measure:68ch entrega 81 CARACTERES por linha, nao 68. A unidade
   `ch` e a largura do glifo "0", que em Public Sans e mais largo que a media
   das minusculas (8.4px medidos vs 10px do "0"). 57ch e o valor que entrega
   ~68 caracteres reais -- o teto de legibilidade para texto longo.

   ⭐ CONFIRMADO em 2026-08-09, na pagina servida, contra a medicao acima: 21
   paragrafos do post "quem-limpa-a-escola" numa coluna de 592px entregam
   media de 68,1 caracteres por linha (min 44, max 76). A conta de 2026-08-08
   estava CERTA -- o alvo editorial se sustenta.

   ⛔ MAS a unidade estava declarada no lugar errado, e isso nunca apareceu.
   MEDIDO no mesmo dia: uma caixa de `57ch` mede 456px quando resolvida em
   `:root` (que herda Times New Roman 16px, porque `html` nao declara fonte) e
   593px quando resolvida dentro de `.body` (Public Sans 17px). Sao 137px de
   diferenca, 30%. `ch` depende da fonte do elemento ONDE E USADO, e o token
   vive num elemento cuja fonte nao e a do texto. Os 592px que o bloco 2 abaixo
   deriva batem com a resolucao em `.body`, nao com a de `:root`.
   ⭐ Por que ninguem viu: o token estava MORTO. Medido, `max-width` computa
   `none` em `.body` E em `.cta` -- as linhas 212-213 sobrescrevem TODOS os
   consumidores de --measure. Um token errado que nao e lido por ninguem nao
   produz sintoma; ele espera o proximo consumidor. Passa a px, que nao tem
   essa ambiguidade, e volta a ser LIDO (o `.article-page` deriva dele agora).

   O valor deixa de ser fixo e passa a crescer com a tela, que e a ordem do
   operador em 2026-08-09 ("ta muito estreito... temos que ser responsivo").

   ⛔ ATE 2026-08-09 este paragrafo DERIVAVA o teto de um coeficiente: "a
   0,11503 caracteres por pixel (68,1/592), 640px entrega 73,6 caracteres e
   652px entrega 75". Esse numero era CALCULADO e estava impresso ao lado de
   numeros MEDIDOS, indistinguivel deles. RE-MEDIDO no browser em 2026-08-09,
   sobre a pagina servida: 635,2px entrega media de 75,7 caracteres por linha
   (n=16 paragrafos, min 58, max 82), e o ponto dos 75 caracteres fica em
   ~628px -- nao em 652px.
   ⭐ A razao de a derivacao falhar sobrevive ao numero: quebra de linha e
   DISCRETA e depende do texto da amostra, entao caracteres por pixel nao sao
   constantes -- 0,11503 aos 592px contra 0,11917 aos 635,2px, 3,6% de
   diferenca. Extrapolar de uma largura para outra nao e medir, e MODELAR; e um
   modelo impresso como medicao e a familia de erro mais cara aqui, porque o
   proximo a mexer confia no comentario em vez de voltar ao browser.

   O TETO de 640px FICA, e por decisao e nao por descuido: o operador pediu
   coluna mais larga, e raspar 12px para bater na regra dos 75 trocaria um ganho
   que ele ve por um arredondamento. E ele so entra em tela de 2000px ou mais
   (520 + 6vw = 640 => vw = 2000px); a 1920px, o desktop comum, a clamp entrega
   exatamente os 635,2px medidos acima -- ou seja, a largura que a maioria ve
   ja esta abaixo do teto. Piso 592px: nada abaixo do que ja estava servido.  */
:root{
  --measure:clamp(592px,520px + 6vw,640px);
  --fs-corpo:1.0625rem;                              /* 17px */
  --fs-meta:.8125rem;                                /* 13px, era 12.16px */
  --fs-h3:1.3125rem;                                 /* 21px  = 17 x 1.25   */
  --fs-h2:clamp(1.375rem,1.15rem + .75vw,1.6875rem); /* 22 -> 27px          */
  --fs-h1:clamp(1.625rem,1.1rem + 2.1vw,2.625rem);   /* 26 -> 42px, era 72  */
  --leading-corpo:1.65;
  --vao-paragrafo:1.8em;                             /* > 1 altura de linha */
  --eixo-editorial:clamp(14px,3vw,20px);             /* recuo interno unico */
}

/* --- 2. EIXO UNICO --------------------------------------------------------
   MEDIDO em 1280px: h1 comeca em x=256, .body em x=300.4 (o `margin:auto`
   centra a coluna de 679px dentro dos 768 disponiveis) e blockquote em
   x=340.4 (mais 40px do default do navegador). Sao TRES eixos verticais na
   mesma pagina, nenhum deles intencional -- o olho nao acha onde ancorar.

   A coluna do ARTIGO passa a ter a largura da medida de leitura, e tudo
   dentro dela alinha pelo mesmo eixo: titulo, corpo, citacao, CTA e a
   navegacao entre posts.

   ⛔ ATE 2026-08-09 esta linha dizia `width:min(704px,100%)` e o comentario
   derivava "704px de caixa - 112px de gutter = 592px de texto". A CONTA
   estava certa e o NUMERO estava solto: 704 era o resultado de somar a medida
   ao gutter UMA VEZ, a mao, e ficou constante enquanto os dois lados da soma
   continuaram a poder mudar. Mexer em --measure OU em --gutter passava a nao
   ter efeito nenhum na coluna, em silencio -- e foi exatamente isso que
   aconteceu: --measure ficou morto (ver bloco 1) e ninguem notou, porque quem
   mandava na largura era o 704 e nao o token.
   ⭐ A regra sobrevive ao numero: a caixa continua a ser "medida + 2 gutters".
   So que agora ela CALCULA isso em vez de lembrar do resultado, entao o
   raciocinio editorial volta a ser executavel e nao decorativo.

   PORQUE NAO SO `margin-inline:0` NO CORPO: alinhar tudo a esquerda dentro
   de uma caixa de 880px resolvia os tres eixos mas deixava ~290px de vazio
   so do lado direito -- pagina desequilibrada. Estreitar a COLUNA resolve as
   duas coisas de uma vez: eixo unico e vazio simetrico. Continua valido -- o
   que o bloco BLOG-LARGURA-01 acrescenta nao e alargar o TEXTO ate encher a
   tela (isso reabriria o problema de legibilidade), e dar aos blocos de DADOS
   um trilho proprio, mais largo, centrado no MESMO eixo.                     */
.article-page{width:min(calc(var(--measure) + 2 * var(--gutter)),100%)}
.body{max-width:none;margin-inline:0}
.juris-cite,.cta,.post-nav{max-width:none;margin-inline:0}

/* --- 3. RITMO VERTICAL ----------------------------------------------------
   MEDIDO: vao entre paragrafos 16.32px < altura de linha 27.74px. O espaco
   que separa dois PARAGRAFOS e menor que o que separa duas LINHAS do mesmo
   paragrafo, logo o bloco nao se le como bloco -- o texto vira uma mancha
   continua. Aqui o vao passa a ~29px, acima da altura de linha.             */
.body{font-size:var(--fs-corpo);line-height:var(--leading-corpo)}
.body p{margin-block:0 var(--vao-paragrafo)}
.body>*:last-child{margin-bottom:0}

/* --- 4. TITULOS -----------------------------------------------------------
   MEDIDO: h1 a 72px ocupa 5 linhas em 1280px e 7 linhas / 283px (35% da tela)
   em 360px. 72px e tamanho de landing page, nao de artigo. `text-wrap:balance`
   equilibra as linhas em vez de deixar a ultima orfa -- e degrada em silencio
   onde nao houver suporte.                                                  */
.article-head h1{font-size:var(--fs-h1);line-height:1.12;max-width:26ch;text-wrap:balance;letter-spacing:-.015em}
.body h2{font-size:var(--fs-h2);line-height:1.25;margin-block:2.2em .55em;text-wrap:balance;letter-spacing:-.01em}
.body h3{font-size:var(--fs-h3);line-height:1.3;margin-block:1.9em .4em;text-wrap:balance}
/* Fio dourado curto sob o h2: sinaliza secao sem pesar como borda cheia. */
.body h2::after{content:'';display:block;width:2.25rem;height:2px;margin-top:.5rem;background:var(--gold);opacity:.62;border-radius:2px}

/* --- 5. DECK (resumo de abertura) -----------------------------------------
   MEDIDO: 10 dos 14 posts abrem com <p><em>...</em></p> -- e o resumo do
   artigo, escrito em markdown como *texto*, sem classe nenhuma. Hoje ele sai
   do mesmo tamanho e cor do corpo: a entrada do leitor nao se distingue do
   texto corrido. `:has(> em:only-child)` so pega o paragrafo que e SO o
   italico; os 4 posts que abrem diferente caem no estilo de paragrafo normal,
   que e a degradacao correta -- nada quebra.                                */
.body>p:first-child:has(>em:only-child){
  font-family:var(--font-display);font-size:clamp(1.15rem,1.05rem + .4vw,1.35rem);
  line-height:1.5;color:var(--ink-soft);margin-block:0 2em;
  padding-left:var(--eixo-editorial);border-left:3px solid var(--gold);
}
.body>p:first-child:has(>em:only-child)>em{font-style:normal}

/* --- 6. NOTA LEGAL (blockquote) -------------------------------------------
   MEDIDO: 13 dos 14 posts tem exatamente UM <blockquote>, e nos 13 o conteudo
   e o MESMO aviso ("Este conteudo e informativo e nao constitui consulta ou
   aconselhamento juridico individual"). Nenhum e citacao de acordao.
   Por isso o tratamento e DISCRETO, nao pull-quote: transformar o disclaimer
   legal num destaque dramatico seria o erro oposto ao atual.
   MEDIDO: hoje o unico estilo que ele tem e o recuo de 40px do NAVEGADOR --
   sem borda, sem fundo, mesma fonte e mesmo tamanho do corpo. Em 360px esses
   80px laterais consomem 22% da tela e a citacao cai para ~26 caracteres.   */
.body blockquote{
  margin:2.4em 0 0;padding:.05px 0 .05px var(--eixo-editorial);
  border-left:2px solid var(--hair);
  color:var(--muted);font-size:.94em;line-height:1.55;
}
.body blockquote p{margin-block:0}

/* --- 7. LISTAS ------------------------------------------------------------
   MEDIDO: `li{margin:0}` -- itens colados. O post com checklist tem 14 <li>
   seguidos, o que vira um paredao. E `ul{padding-left:40px}` e o default do
   navegador em px fixos, que nao acompanha a fonte.                         */
.body ul,.body ol{margin-block:0 var(--vao-paragrafo);padding-left:1.4em}
.body li{margin-block:0 .55em}
.body li::marker{color:var(--gold);font-weight:600}
.body li>ul,.body li>ol{margin-block:.5em 0}

/* --- 8. METADADOS ---------------------------------------------------------
   MEDIDO em 360px: a linha de meta do artigo quebra em 3 linhas / 51px de
   altura, porque soma mono + uppercase + letter-spacing 1.46px. O mono com
   tracking e o que faz a string inchar. Aqui a meta do ARTIGO passa a nav
   font com tracking curto (o kicker de card mantem o mono, que ali funciona
   como etiqueta curta e e identidade da marca).                             */
.article-head .meta{
  font-family:var(--font-nav);font-size:var(--fs-meta);font-weight:500;
  letter-spacing:.02em;text-transform:none;line-height:1.5;
  display:flex;flex-wrap:wrap;gap:.35em .75em;margin-top:1.15rem;
}
.article-head .meta>*{white-space:nowrap}

/* --- 9. CITACAO DE ACORDAO (.juris-cite) ----------------------------------
   Ja existia e continua sendo o pull-quote -- este e o lugar da voz do
   tribunal, agora que o blockquote foi para nota legal. Aspa tipografica
   como marca d'agua, sem depender de imagem.                                */
.juris-cite{position:relative;overflow:hidden;border-left:3px solid var(--gold)}
.juris-cite::before{
  content:'C';position:absolute;top:-.15em;right:.12em;
  font:700 7rem/1 var(--font-display);color:var(--gold);opacity:.11;pointer-events:none;
}
.juris-cite strong{line-height:1.25;letter-spacing:-.01em}

/* --- 10. LISTAGEM: cartao -------------------------------------------------
   MEDIDO: o titulo do cartao herda o sublinhado do navegador -- os 14 cartoes
   da listagem saem com titulo sublinhado em dourado, que e a assinatura
   visual de lista de links, nao de vitrine editorial. O sublinhado volta no
   hover/foco, onde ele significa alguma coisa.
   MEDIDO: `min-height:250px` deixa cartao de texto curto com ar sobrando; o
   conteudo passa a mandar na altura e o grid iguala as fileiras.            */
.post-card h3 a,.featured h3 a,.featured h2 a{text-decoration:none;color:var(--ink)}
.post-card h3 a:hover,.post-card h3 a:focus-visible,
.featured h3 a:hover,.featured h2 a:hover{text-decoration:underline;text-decoration-color:var(--gold);text-decoration-thickness:2px}
.post-card{min-height:0;padding:20px}
.post-card h3{font-size:var(--fs-h3);line-height:1.3;margin:.55rem 0 .1rem;text-wrap:balance}
.post-card p{font-size:.95rem;line-height:1.55;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
/* BLOG-LEVA3-01. A meta do cartao adota a forma que a meta do ARTIGO ja usa
   (seccao 8 acima): nav font, caixa normal, tracking curto. A justificacao e a
   MESMA que ja esta escrita la -- mono + maiusculas + tracking incha a string --
   e ela valia para os dois sitios desde sempre; so um foi corrigido.
   ⭐ O ponto nao e o tamanho, e a SEPARACAO DE PAPEIS: o kicker identifica
   (tribunal, tema, especie) e decide o clique; a meta so situa (data, tempo de
   leitura) e nunca decide nada. Renderizados quase iguais, competiam entre si e
   com o titulo. Fica UM tratamento mono/maiusculas por cartao. */
.post-card .meta{
  padding-top:14px;font-family:var(--font-nav);font-size:var(--fs-meta);
  font-weight:500;letter-spacing:.02em;text-transform:none;
  color:var(--tertiary);line-height:1.5;
}
.post-grid,.results-grid{gap:20px}

/* Destaque: hoje usa o MESMO fundo e a MESMA borda do cartao comum, so que
   maior -- nada nele diz "leia este primeiro". Um fio dourado no topo e uma
   borda de acento resolvem sem introduzir cor nova.                         */
.featured{border-color:color-mix(in srgb,var(--gold) 34%,transparent);position:relative;overflow:hidden}
.featured::before{content:'';position:absolute;inset:0 0 auto;height:3px;background:linear-gradient(90deg,var(--gold),transparent 72%)}

/* --- 11. ESTADO VAZIO -----------------------------------------------------
   Existe (.empty) mas e so uma caixa tracejada com texto centrado. Ganha
   hierarquia interna para que "nada encontrado" nao pareca "quebrou".       */
.empty{padding:clamp(40px,7vw,64px) 24px;background:var(--card)}
.empty strong{display:block;font:600 1.15rem/1.35 var(--font-display);color:var(--ink);margin-bottom:.5rem}
.empty p{max-width:46ch;margin:0 auto;color:var(--muted)}

/* --- 11b. CTA E NAVEGACAO ENTRE POSTS -------------------------------------
   MEDIDO apos estreitar a coluna: o botao do CTA quebrou em duas linhas
   ("Pesquisar no / IAJUS"). O `.cta` e flex com space-between e o link nao
   declarava `flex`, entao encolheu junto com a caixa. `flex:none` +
   `white-space:nowrap` prendem o rotulo numa linha -- o texto a esquerda e
   que cede, que e a ordem certa de prioridade.                              */
.cta a{flex:none;white-space:nowrap}
.cta strong{display:block;font:600 1.05rem/1.4 var(--font-display);color:var(--ink)}
/* A navegacao anterior/proximo com titulos longos numa coluna estreita: o
   alinhamento a direita do segundo cartao deixava linhas raggeadas dos dois
   lados. Rotulo mantem a direcao, o titulo alinha sempre a esquerda.        */
.post-nav a:last-child{text-align:left}
.post-nav a:last-child .nav-direction{text-align:right}
.post-nav a{gap:.4rem;min-height:0;padding:16px 18px}
.post-nav a strong,.post-nav a span:not(.nav-direction){font:600 .95rem/1.35 var(--font-display);color:var(--ink)}

/* --- 12. RESPONSIVO -------------------------------------------------------
   O breakpoint editorial de 1080px ja existe e NAO se toca (o comentario do
   STYLE explica por que ele e deliberadamente separado do de 1329px do
   header). Aqui so o que e proprio da camada editorial.                     */
@media(max-width:640px){
  .body blockquote,.body>p:first-child:has(>em:only-child){padding-left:14px}
  .article-head .meta{gap:.3em .6em}
  .post-card{padding:18px}
  .juris-cite::before{font-size:5rem;opacity:.09}
}

/* --- 13. IMAGEM DE CORPO: reserva de espaco ------------------------------
   O corpo do post nao tem imagem hoje (MEDIDO: 0 de 14 posts assados tem
   <img> dentro de .body -- controle positivo: o mesmo regex casa 14 vezes na
   LISTAGEM, onde as capas existem). Mas markdown.js:107 JA emite <img> e o
   suporte a ![alt](url) entrou hoje, logo a primeira imagem de corpo chega
   sem `width`/`height` e desloca o texto ao carregar.
   `aspect-ratio` com `height:auto` reserva a caixa ANTES do byte chegar, o
   que remove o deslocamento sem exigir que o autor saiba a dimensao.
   LIMITE HONESTO: 16/9 e um palpite de enquadramento, nao a proporcao real
   do arquivo. Fica correto para o caso comum e recorta o resto por
   `object-fit`; a solucao completa e o gerador estampar width/height reais
   no HTML -- proposta como funcionalidade F3 no relatorio.                  */
.body img{aspect-ratio:16/9;object-fit:cover;width:100%;border-radius:10px;background:var(--bg-3);margin-block:.6em}
.body img[width]{aspect-ratio:auto}   /* se o gerador estampar, a real vence */
/* ===================== BLOG-LEVA2-01 ===================================
   O blog continuava a parecer amador por tres razoes que a leva anterior nao
   tocou, porque ela era de TIPOGRAFIA e estas sao de IMAGEM e de GRELHA.

   1. O titulo aparecia DUAS vezes em cada cartao: queimado no bitmap da capa,
      em baixa resolucao e cortado a meio, e outra vez em texto logo abaixo.
      Medido nas 14 capas: o texto queimado comeca sempre em y=396 de 630.
      ⛔ A garantia e uma RAZAO, nunca uma altura. Com `object-fit:cover`, uma
      caixa mais alta que 396/1200 = 0,330 passa a limitar pela ALTURA e mostra
      a imagem inteira -- titulo incluido. Qualquer caixa de capa nova confere
      contra 0,330. No primeiro prototipo desta leva eu proprio quebrei isto: um
      cartao horizontal a 1200/744 (razao 0,62) trouxe o texto todo de volta.

   2. A pagina do ARTIGO nao tinha imagem nenhuma. Medido: 0 de 15 posts com
      capa no topo, 14 de 15 sem qualquer imagem no corpo. A capa existia, era
      servida na listagem, e o destino era uma parede de texto.

   3. Duas das tres secoes mostravam um cartao solitario numa linha de 1088px --
      698px de vazio -- porque a grelha e de 3 colunas fixas e as secoes tem 10,
      2 e 1 artigo. Vazio de molde le-se como pagina por acabar. */
/* BLOG-LEVA2-FIX1: `object-fit:cover` VIVE AQUI, junto da razao e da ancora.
   Ele existe numa regra ~285 linhas acima, mas aquela so alcanca `.featured img` e
   `.post-card img`; `.capa-artigo img` e seletor novo e ficou com o default `fill`,
   que ESTICA em vez de cortar -- a capa do artigo mostrou os 1200x630 inteiros
   achatados, com o titulo queimado de volta e a ilustracao distorcida, em 13 posts
   e em todos os viewports. ⛔ Nao separar estes tres: a razao 1200/372 so descreve
   o que aparece SE o ajuste for `cover`. Separados, a regra do corte parece completa
   e nao e, e a proxima caixa de capa herda o mesmo buraco em silencio. */
.featured img,.post-card img,.capa-artigo img{aspect-ratio:1200/372;object-fit:cover;object-position:top}
/* Destaque: faixa no topo. Cortada, a capa lateral virava uma tira de 112px numa
   coluna de 190px, com vazio por baixo -- o corte resolvia a duplicacao e criava
   um buraco. Largura inteira devolve ao destaque a escala que o nome promete. */
.featured{grid-template-columns:minmax(0,1fr);gap:24px}
.featured>picture{align-self:stretch;order:-1}
/* Secao que nao enche a linha de 3 colunas ajusta as colunas em vez de deixar vao.
   `sizes` acompanha no gerador; sem isso o cartao de 1047px amplia a variante de
   370w em 2,83x, que troca um vao visivel por uma imagem borrada. */
.post-grid[data-cards="1"]{grid-template-columns:minmax(0,1fr)}
.post-grid[data-cards="2"]{grid-template-columns:repeat(2,minmax(0,1fr))}
/* Capa do artigo: abre a peca logo abaixo do cabecalho, antes do indice. Fica
   DEPOIS do <h1> de proposito -- a capa repete o titulo em imagem, entao poe-la
   antes empurraria o titulo real para baixo da dobra no telemovel sem acrescentar
   informacao. */
.capa-artigo{margin:26px 0 32px;padding:0}
.capa-artigo img{display:block;width:100%;height:auto;border-radius:12px;background:var(--bg-3)}
/* Figura de dados: ate aqui era `<p><img></p>` com a legenda num paragrafo em
   italico ao lado, ligada por proximidade -- ligacao nenhuma para um leitor de
   ecra. E o respiro era 10,2px contra os 30,6px entre paragrafos: a figura ficava
   mais colada aos vizinhos do que dois paragrafos entre si, o mesmo defeito de
   ritmo que a leva anterior corrigiu no texto corrido. */
.body figure{margin:32px 0;padding:18px;background:var(--bg-2);border:1px solid var(--hair);border-radius:12px}
.body figure img{display:block;width:100%;height:auto;margin:0;border-radius:8px;aspect-ratio:auto}
.body figcaption{margin-top:14px;font-size:.86rem;line-height:1.5;color:var(--muted)}
@media(max-width:760px){.capa-artigo{margin:20px 0 24px}
.body figure{padding:12px;margin:26px 0}}

/* ===================== BLOG-FUNCIONALIDADES-01 =========================
   Indice do artigo + relacionados. Reusa os tokens da camada editorial
   (--fs-meta, --eixo-editorial, --gold, --hair) -- zero token novo. */

/* O cabecalho e' `position:sticky;top:0` (linha .site-header), entao um <h2>
   alvo de ancora encostaria POR BAIXO dele. `scroll-margin` e a unica forma que
   nao exige medir a altura em JS; o valor cobre a barra medida (~64px) mais uma
   folga de respiro. Sem isto o indice leva o leitor a um titulo invisivel, que
   e pior do que nao ter indice. */
.body h2{scroll-margin-block-start:5.5rem}

.sumario{
  margin:0 0 2.2em;padding:1rem 1.15rem 1.1rem;
  border:1px solid var(--hair);border-left:3px solid var(--gold);border-radius:8px;
  background:color-mix(in srgb,var(--card) 70%,transparent);
}
.sumario-titulo{
  margin:0 0 .55rem;font-family:var(--font-nav);font-size:var(--fs-meta);
  font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);
}
.sumario ol{margin:0;padding:0;list-style:none;counter-reset:sumario}
.sumario li{counter-increment:sumario;margin:0;line-height:1.45}
.sumario li+li{margin-top:.4rem}
.sumario a{
  display:flex;gap:.55rem;align-items:baseline;
  color:var(--ink-soft);text-decoration:none;font-size:.95rem;
  padding-block:.15rem;
}
/* Alvo de toque. DECISAO DECLARADA, nao descuido: fica no piso AA (WCAG 2.2
   SC 2.5.8, 24px) e NAO no piso AAA (SC 2.5.5, 44px) que o `.back-link` da SPA
   usa. Motivo medido: sao ate 7 itens, e 7x44px + titulo + folgas dariam ~386px
   de indice num viewport de 780px -- metade da primeira tela so para o sumario,
   empurrando o artigo para fora dela. 34px passa o AA com folga e cabe. Se o
   dono preferir AAA, o valor a mexer e este e o custo e a altura acima. */
/* As DUAS condicoes, de proposito. `pointer:coarse` e a pergunta certa (dedo, nao
   largura), mas nao e verificavel no arnes headless -- este Chromium reporta
   ponteiro FINO mesmo a 360px, entao um teste que dependesse so dela seria um
   verde incapaz de ficar vermelho. `max-width` e provavel aqui e cobre o caso
   real de telefone; a de ponteiro cobre o notebook com toque, que a largura
   nao alcanca. Erram para o lado seguro: alvo maior do que o preciso. */
@media(max-width:640px),(pointer:coarse){.sumario a{padding-block:.42rem}}
.sumario a::before{
  content:counter(sumario);flex:none;min-width:1.35em;
  font-family:var(--font-nav);font-size:.8em;font-weight:600;color:var(--gold);
}
.sumario a:hover,.sumario a:focus-visible{color:var(--ink);text-decoration:underline;
  text-decoration-color:var(--gold);text-underline-offset:3px}

.relacionados{margin:2.6em 0 0;padding-top:1.4rem;border-top:1px solid var(--hair)}
.relacionados ul{margin:.9rem 0 0;padding:0;list-style:none;display:grid;gap:.65rem}
.relacionados a{
  display:block;padding:.75rem .9rem;border:1px solid var(--hair);border-radius:8px;
  background:var(--card);text-decoration:none;
  transition:border-color .15s ease,transform .15s ease;
}
.relacionados a:hover,.relacionados a:focus-visible{
  border-color:color-mix(in srgb,var(--gold) 45%,transparent);
}
/* BLOG-LEVA3-01. ⛔ Defeito meu da leva 1: esta etiqueta nasceu com uma
   TERCEIRA forma -- Inter maiusculas com tracking curto -- ao lado do mono do
   kicker e da sentenca da meta. Tres formas para "etiqueta pequena", nenhuma
   errada sozinha. Passa a herdar o tratamento do kicker, que e o sistema de
   etiqueta desta folha; a unica coisa que continua propria e o espacamento. */
.rel-contexto{
  display:block;font:600 .76rem/1.4 var(--font-mono);letter-spacing:.12em;
  text-transform:uppercase;color:var(--tertiary);margin-bottom:.2rem;
}
.relacionados strong{
  display:block;font:600 .98rem/1.35 var(--font-display);color:var(--ink);text-wrap:balance;
}
@media(prefers-reduced-motion:reduce){.relacionados a{transition:none}}
@media(max-width:640px){
  .sumario{padding:.9rem 1rem}
  .relacionados a{padding:.7rem .8rem}
}

/* ===================== BLOG-LARGURA-01 (2026-08-09) ====================
   Ordem do operador, verbatim: «ta muito estreito, podendo ser mais largo,
   cara, pq isso aqui e no computador, pow, temos que ser responsivo».

   MEDIDO na pagina servida (blog/quem-limpa-a-escola..., 2026-08-09), ANTES:
   em 1920px de viewport a coluna do artigo ocupa 704px e sobram 1201px de
   vazio -- 63% da tela. Em 1440: 704 contra 721 de vazio. Em 1280: 704 contra
   561. A coluna e a MESMA em qualquer tela grande, porque `min(704px,100%)`
   trava a caixa e alargar o monitor nao dava um pixel. E o mesmo modo de
   falha que o comentario do header ja documentava em 2026-08-07, uma linha
   acima nesta folha, agora do lado do corpo editorial.

   ⛔ O CONSERTO NAO E ALARGAR O TEXTO ATE ENCHER A TELA. Medido hoje, 592px
   ja entregam 68,1 caracteres por linha (bloco 1); 1200px entregariam ~138,
   que e ilegivel para texto corrido. Quem "conserta" o estreito esticando o
   paragrafo troca uma queixa por outra pior, e a segunda ninguem sabe nomear.
   O texto cresce POUCO e com teto medido (592 -> 640px, ate 73,6 caracteres).

   ⭐ Quem ganha a largura sao os DADOS. Medido: o grafico deste post tem
   1388px de largura natural e era servido a 555px -- 40%. Os rotulos de eixo
   e os numeros eram reduzidos a 40% num monitor onde sobravam 1201px vazios.
   Este post e "em numeros" e o numero era a coisa menos legivel da pagina.

   COMO, sem tocar no HTML (o gerador e de outro dono): sangria simetrica por
   margem negativa. A margem se calcula sozinha e vale ZERO quando nao ha o
   que ganhar -- nao precisa de media query e nao tem salto:

     sangria = max(0px, (trilho - medida) / 2)
     trilho  = min(--dados-max, 100vw - 2 gutters)

   Quando a tela e estreita, `100vw - 2 gutters` fica MENOR que --measure, a
   subtracao da negativo, o `max(0px,...)` zera e o bloco volta a coincidir
   com a coluna. O eixo unico do bloco 2 fica intacto no telemovel, que era a
   condicao para poder mexer nisto.

   ⛔ POR QUE ISTO NAO PODE GERAR ROLAGEM HORIZONTAL, e nao e torcida: o
   trilho e limitado a `100vw - 2 * --gutter`, e o util e `100vw - barra de
   rolagem`. Medido neste arnes: 1920 de viewport contra 1905 de util, logo a
   barra pesa 15px. O gutter minimo e 20px (clamp), entao 2 gutters >= 40px >
   15px em QUALQUER largura -- a folga que reservamos e sempre maior que a
   barra que o `100vw` ignora. A prova esta na aritmetica, mas o controle
   negativo a 390px foi medido na mesma.

   ⛔ O QUE FICA DE FORA DO TRILHO, de proposito: `.juris-cite` (a voz do
   tribunal e editorial, nao dado -- e o bloco 9 desta folha ja a define como
   o pull-quote da coluna de texto), `.cta`, `.post-nav` e `.sumario`. Se
   tudo alarga, "largo" deixa de significar "isto aqui e dado" e vira ruido.  */
:root{
  /* Teto do trilho de dados. Nao e o --maxw 1200 da casca: 1040 deixa o
     grafico a 1004px dentro do padding de 18px da figura, 72% da largura
     natural de 1388 (contra 40% antes), e ainda guarda respiro lateral numa
     tela de 1280. Acima de 1040 uma figura comeca a ler-se como banner. */
  --dados-max:1040px;
  /* ⛔ TERCEIRO TERMO, `--maxw`, e ele e para a DEC-079 (unificacao no apex):
     hoje `.article-page` e filha direta do <body> e nada acima dela limita
     largura — o trilho so responde ao viewport. Quando a fatia 1 vestir o post
     com a casca da aplicacao, ele passa a viver dentro de `.wrap`
     (`saas/app/src/app.css:205`), que e `max-width:var(--maxw)` com o MESMO
     `--gutter` daqui (`saas/app/src/lib/styles/brand-tokens.css:112-113`) —
     1200 - 112 = 1088px de conteudo. O trilho de 1040 cabe nos 1088 com 48px
     de folga, mas cabia por ACIDENTE: quem subisse `--dados-max` para 1100
     furaria a casca sem nada ficar vermelho. Com o termo, a casca passa a ser
     um limite DECLARADO e o teto degrada sozinho.
     ⭐ Medido: hoje isto e no-op exato (1040 < 1088 em toda largura), logo
     entra sem mudar um pixel — guarda que so age quando a casca chegar. */
  --sangria-dados:max(0px,(min(var(--dados-max),100vw - 2 * var(--gutter),var(--maxw) - 2 * var(--gutter)) - var(--measure)) / 2);
}
/* `.capa-artigo` entra NOMEADA: ela e um <figure> filho de <article>, nao de
   `.body`, entao `.body figure` nunca a alcanca (medido). O corte que esconde
   o titulo queimado na capa e uma RAZAO (`aspect-ratio:1200/372` = 0,310,
   abaixo do limite 0,330 do bloco BLOG-LEVA2), e razao nao depende da
   largura -- alargar a capa NAO reabre aquele defeito. */
/* Imagem solta de markdown (`![alt](url)`) chega como `<p><img></p>`. Quem
   recebe o trilho e o PARAGRAFO, nao a imagem: margem negativa num elemento
   inline replaced depende de como a linha e construida, e o paragrafo e um
   bloco -- comportamento previsivel. `:only-child` garante que so pega o
   paragrafo que E a imagem; paragrafo com texto e imagem junto continua na
   coluna, que e a degradacao certa. */
.body figure,
.body>pre,
.body>table,
.body>p:has(>img:only-child),
.capa-artigo{margin-inline:calc(-1 * var(--sangria-dados))}
/* Tabela: hoje NAO existe nenhuma no blog (medido 2026-08-09: zero `<table>`
   nos 14 posts assados), entao esta regra e defensiva e foi validada com uma
   tabela SINTETICA injectada no DOM, nunca com conteudo real -- quem trouxer
   a primeira tabela confere de novo. Larga demais para o trilho, ela rola
   DENTRO de si em vez de empurrar a pagina.
   ⚠️ LIMITE HONESTO, e ele e de acessibilidade: uma regiao que rola so e
   alcancavel pelo teclado se for focavel, e `tabindex` e atributo de HTML --
   CSS nao o cria. Enquanto o gerador nao envolver a tabela em
   `<div class="tabela-rolavel" tabindex="0" role="region" aria-label="...">`,
   quem navega so por teclado NAO alcanca a parte escondida. Esta na secao de
   achados do relatorio, com o diff proposto para o dono do gerador.
   ⛔ DEFEITO MEU, apanhado na medicao de 2026-08-09 e registrado porque a
   forma errada e mais plausivel que a certa: a primeira versao desta linha
   era `width:max-content;max-width:100%`. Medido, ela punha a tabela em
   x=432 (a borda esquerda do trilho, porque a margem negativa ja tinha
   aplicado) com apenas 635px de largura -- deslocada para o trilho e presa a
   coluna ao mesmo tempo. `100%` num bloco com margem negativa continua a
   resolver contra o BLOCO CONTENDOR, nunca contra a caixa alargada; e
   `max-content` desliga o preenchimento do trilho. `width:auto` num bloco
   toma a largura do contendor MAIS as margens negativas, que e o que se quer. */
.body table{display:block;width:auto;overflow-x:auto;border-collapse:collapse}
/* A figura ja tem fundo e borda proprios; no trilho largo o respiro interno
   cresce junto, senao a imagem encosta na moldura numa caixa de 1040px. */
@media(min-width:1080px){.body figure{padding:22px}}

[data-theme=light]{color-scheme:light;--bg:#faf8f2;--bg-2:#f3f0e7;--bg-3:#ebe7da;--ink:#1a1f2e;--ink-soft:#2c3242;--text:#2c3242;--muted:#555b6b;--tertiary:#5f6573;--gold:#765d16;--gold2:#6f570f;--gold-soft:#a07f1c;--hair:rgba(26,31,46,.12);--rule:rgba(138,109,26,.35);--card:rgba(26,31,46,.035);--stf:#92580a;--stj:#4a90c0;--tst:#3f9a79;--guia:#837fe3;--produto:#b673b6;--autoral:#a34a38}
[data-theme=light] .site-header{background:rgba(250,248,242,.78)}
[data-theme=light] .search input{background:#fff;color-scheme:light}
