/* ======================================================================
   visual-2026.css — Sistema de iconografia e elementos visuais 2026
   Dinheiro da Minha Empresa (Brasil GEO)

   Princípios (curso Frontends com Vibecoding):
   - Cor de ícone via TOKEN; adapta em dark/light (nunca hex fixo sumindo).
   - Traço coerente (currentColor herdado do contexto, 1 conjunto só).
   - Estado nunca só por cor: ícone + cor + rótulo acessível.
   - Alvo de toque >= 44px e foco visível nos interativos novos.
   - Respeita prefers-reduced-motion.
   ====================================================================== */

:root {
  --v26-ico: var(--ink-3, #374151);     /* cor padrão de ícone (light) */
  --v26-ico-soft: var(--muted, #64748B);
  --v26-accent: var(--green-dark, #008550);
  --v26-yes: #047857;                    /* verde com contraste AA sobre branco */
  --v26-no: #DC2626;                     /* vermelho AA */
  --v26-na: var(--muted, #64748B);
  --v26-warn: #B45309;
  --v26-warn-bg: #FFF7ED;
  --v26-warn-line: #FDBA74;
  --v26-tip: #0E7490;
  --v26-tip-bg: #ECFEFF;
  --v26-tip-line: #67E8F9;
  --v26-info: var(--green-dark, #008550);
  --v26-chip-bg: var(--green-soft, #E6F5EE);
}

/* Tokens dark. Espelham o padrão canônico do site (styles.css):
   ativam por atributo explícito E por preferência do SO (sem data-theme="light"),
   para que os ícones adaptem já no flash inicial, antes de nav.js rodar. */
[data-theme="dark"],
:root[data-theme="dark"] {
  --v26-ico: #CBD5E1;
  --v26-ico-soft: #94A3B8;
  --v26-accent: #34D399;
  --v26-yes: #34D399;
  --v26-no: #F87171;
  --v26-na: #94A3B8;
  --v26-warn: #FCD34D;
  --v26-warn-bg: rgba(251, 191, 36, .10);
  --v26-warn-line: rgba(251, 191, 36, .45);
  --v26-tip: #67E8F9;
  --v26-tip-bg: rgba(34, 211, 238, .10);
  --v26-tip-line: rgba(34, 211, 238, .40);
  --v26-info: #34D399;
  --v26-chip-bg: rgba(52, 211, 153, .14);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --v26-ico: #CBD5E1;
    --v26-ico-soft: #94A3B8;
    --v26-accent: #34D399;
    --v26-yes: #34D399;
    --v26-no: #F87171;
    --v26-na: #94A3B8;
    --v26-warn: #FCD34D;
    --v26-warn-bg: rgba(251, 191, 36, .10);
    --v26-warn-line: rgba(251, 191, 36, .45);
    --v26-tip: #67E8F9;
    --v26-tip-bg: rgba(34, 211, 238, .10);
    --v26-tip-line: rgba(34, 211, 238, .40);
    --v26-info: #34D399;
    --v26-chip-bg: rgba(52, 211, 153, .14);
  }
}

/* ---- base do ícone: herda cor do contexto via token ------------------- */
.v26-ico {
  color: var(--v26-ico);
  flex: 0 0 auto;
  vertical-align: -0.18em;
  display: inline-block;
  width: 20px;
  height: 20px;
}
.v26-ico use { color: inherit; }

@media (prefers-reduced-motion: no-preference) {
  .v26-ico { transition: transform .18s cubic-bezier(.2,.7,.3,1), color .18s ease; }
}

/* ---- (1) navegação principal ------------------------------------------ */
/* A navbar precisa de mais largura que o conteúdo para os 9 itens + ícones
   caberem sem vazar. Damos ao header um container um pouco maior (a barra
   pode ser mais larga que o corpo) e comprimimos a nav em telas médias. */
@media (min-width: 1280px) {
  .hdr .hdr-row, .hdr .mega > .container { max-width: 1336px; }
}
.nav button[data-mega], .nav button.v26-grp { gap: 6px; }
.v26-nav-ico { width: 17px; height: 17px; color: var(--v26-ico-soft); }
@media (min-width: 1280px) {
  .nav button[data-mega], .nav button.v26-grp { padding: 6px 7px; gap: 4px; font-size: 12.5px; }
  .v26-nav-ico { width: 15px; height: 15px; }
}
.nav button:hover .v26-nav-ico,
.nav button[aria-expanded="true"] .v26-nav-ico { color: var(--v26-accent); }

/* ---- (1b) aglutinação: guarda-chuvas "Soluções Stone" e "Aprender" ----- */
.nav li.v26-nav-hidden { display: none !important; } /* esconde os agrupados */
.nav button.v26-grp {
  padding: 7px 8px; border-radius: 8px; font-weight: 500;
  color: var(--ink-3, #374151); font-size: 13px;
  display: inline-flex; align-items: center; white-space: nowrap;
}
.nav button.v26-grp:hover,
.nav button.v26-grp[aria-expanded="true"] {
  background: var(--green-soft, #E6F5EE); color: var(--green-dark, #008550);
}
[data-theme="dark"] .nav button.v26-grp { color: var(--ink-3, #CBD5E1); }
.v26-grp-chev { width: 10px; height: 10px; color: var(--v26-ico-soft); }
.nav button.v26-grp[aria-expanded="true"] .v26-grp-chev { transform: rotate(180deg); }
/* painel combinado: reusa a base .mega; layout em colunas por sub-menu */
.v26-grp-panel .v26-grp-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 8px 28px;
}
.v26-grp-col { min-width: 0; }
.v26-grp-col-h {
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 8px; padding: 0 0 8px; font-weight: 800; font-size: 12px;
  letter-spacing: .04em; text-transform: uppercase;
  color: var(--green-dark, #008550); border-bottom: 1px solid var(--line, #E2E8F0);
}
[data-theme="dark"] .v26-grp-col-h { color: var(--v26-accent); border-color: var(--line, #334155); }
.v26-grp-col-ico { width: 16px; height: 16px; color: inherit; }
.v26-grp-col > a { display: block; }
@media (min-width: 1280px) and (max-width: 1439px) {
  .nav button.v26-grp { padding: 6px 7px; font-size: 12.5px; }
}

/* ---- (1c) drawer mobile: ícones nas categorias + toque confortável ----- */
.drawer-panel details > summary.v26-dw {
  gap: 10px; padding: 11px 2px; min-height: 44px; /* alvo de toque >= 44px */
}
.v26-dw-l { display: flex; align-items: center; gap: 12px; flex: 1 1 auto; min-width: 0; }
.v26-dw-ico {
  width: 21px; height: 21px; flex: 0 0 auto;
  color: var(--v26-accent);
}
.drawer-panel details[open] > summary.v26-dw .v26-dw-ico { color: var(--green-dark, #008550); }
[data-theme="dark"] .drawer-panel details[open] > summary.v26-dw .v26-dw-ico { color: var(--v26-accent); }
/* badge dentro do rótulo não empurra o ícone */
.v26-dw-l .nav-badge { margin-left: 4px; }
/* links internos: marcador de seta sutil, recuo alinhado ao ícone da categoria */
.drawer-panel ul.v26-dw-list { padding-left: 33px; }
.drawer-panel ul.v26-dw-list > li > a {
  position: relative; display: block; padding: 7px 0; min-height: 36px;
}
.drawer-panel ul.v26-dw-list > li > a::before {
  content: ""; position: absolute; left: -18px; top: 50%; width: 14px; height: 14px;
  transform: translateY(-50%); opacity: .55;
  background: center/contain no-repeat
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23008550' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E");
}
[data-theme="dark"] .drawer-panel ul.v26-dw-list > li > a::before {
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2334D399' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E");
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .drawer-panel ul.v26-dw-list > li > a::before {
    background-image:
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2334D399' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E");
  }
}

/* ---- (2) links dos mega-menus ----------------------------------------- */
.mega-grid a { position: relative; }
.mega-grid a .v26-mega-ico {
  width: 20px; height: 20px;
  color: var(--v26-accent);
  margin-right: 11px;
  float: left;
  margin-top: 1px;
}
.mega-grid a:hover .v26-mega-ico { transform: translateX(1px); }

/* ---- (3) marca / logo ------------------------------------------------- */
.brand-mark .v26-ico,
.brand-mark svg { color: #fff; width: 20px; height: 20px; }

/* ---- (4) FAQ ---------------------------------------------------------- */
.faq summary.v26-has-ico { gap: 10px; }
.v26-faq-ico {
  width: 19px; height: 19px;
  color: var(--v26-accent);
  margin-right: 2px;
}

/* ---- (5) glossário ---------------------------------------------------- */
.term dt { gap: 8px; }
.v26-term-ico {
  width: 16px; height: 16px;
  color: var(--v26-accent);
}

/* ---- (6) células de tabela (Sim / Não / parcial) ---------------------- */
td.v26-cell { text-align: center; vertical-align: middle; }
.v26-yes { color: var(--v26-yes); width: 21px; height: 21px; }
.v26-no  { color: var(--v26-no);  width: 21px; height: 21px; }
.v26-na  { color: var(--v26-na);  width: 21px; height: 21px; opacity: .85; }

/* ---- (7) links externos ----------------------------------------------- */
.v26-ext-ico {
  width: 14px; height: 14px;
  color: var(--v26-ico-soft);
  margin-left: 4px;
  vertical-align: -0.10em;
}
a:hover .v26-ext-ico { color: var(--green-dark, #008550); }

/* ---- (8) footer ------------------------------------------------------- */
footer h4.v26-foot-h { display: flex; align-items: center; gap: 9px; }
.v26-foot-ico {
  width: 18px; height: 18px;
  color: var(--stone-lime, #A5FA00);
}

/* ---- (9) newsletter --------------------------------------------------- */
.v26-field { position: relative; display: flex; flex: 1; align-items: center; }
.v26-field-ico {
  position: absolute; left: 14px; top: 50%; transform: translateY(-50%);
  width: 18px; height: 18px; color: var(--v26-ico-soft); pointer-events: none;
}
.v26-field input { padding-left: 42px !important; width: 100%; }
.v26-btn-ico { width: 18px; height: 18px; color: currentColor; margin-right: 6px; }

/* ---- (10) cards ------------------------------------------------------- */
.card .ico .v26-card-ico,
.hub-card .ico .v26-card-ico,
.tool-card .ico .v26-card-ico,
.persona-card .ico .v26-card-ico {
  width: 24px; height: 24px; color: inherit;
}
.card:hover .ico .v26-card-ico { transform: scale(1.06); }

/* ---- (11) breadcrumb -------------------------------------------------- */
.breadcrumb.v26-bc { display: flex; align-items: center; flex-wrap: wrap; gap: 4px; }
.v26-bc-ico {
  width: 15px; height: 15px; color: var(--v26-ico-soft); margin-right: 5px;
  vertical-align: -0.12em;
}

/* ---- (12) CTAs -------------------------------------------------------- */
.v26-cta-ico { width: 18px; height: 18px; color: currentColor; margin-left: 2px; }
a.btn-primary:hover .v26-cta-ico { transform: translateX(3px); }

/* ---- (13) meta / tempo de leitura ------------------------------------- */
.v26-meta { display: inline-flex; align-items: center; gap: 6px; }
.v26-meta-ico { width: 15px; height: 15px; color: var(--v26-ico-soft); }

/* ---- (14) stat-strip / dh-stat ---------------------------------------- */
.v26-stat-ico {
  width: 22px; height: 22px; display: block; margin: 0 0 8px;
  color: var(--stone-lime, #A5FA00);
}

/* ---- (15) callouts tipados -------------------------------------------- */
.v26-callout { position: relative; }
.v26-callout-ico {
  position: absolute; left: 16px; top: 16px;
  width: 22px; height: 22px;
}
.callout.v26-callout::before,
.stone-callout.v26-callout::before { display: none !important; }
.v26-callout { padding-left: 50px; }
.v26-callout--info .v26-callout-ico { color: var(--v26-info); }
.v26-callout--tip { background: linear-gradient(180deg, var(--v26-tip-bg), transparent); border-color: var(--v26-tip-line); border-left-color: var(--v26-tip); }
.v26-callout--tip .v26-callout-ico { color: var(--v26-tip); }
.v26-callout--warn { background: var(--v26-warn-bg); border-color: var(--v26-warn-line); border-left: 4px solid var(--v26-warn); }
.v26-callout--warn .v26-callout-ico { color: var(--v26-warn); }
.v26-callout--warn strong, .v26-callout--warn h4 { color: var(--v26-warn); }

/* ---- (16) botão flutuante "voltar ao topo" ---------------------------- */
.v26-fab {
  position: fixed; right: 18px; bottom: 18px; z-index: 60;
  width: 48px; height: 48px; border-radius: 14px;
  display: grid; place-items: center;
  background: var(--green, #00A868); color: #fff;
  box-shadow: var(--shadow-lg, 0 12px 32px rgba(15,23,42,.18));
  border: 1px solid rgba(255,255,255,.18);
  opacity: 0; visibility: hidden; transform: translateY(12px);
  cursor: pointer;
}
.v26-fab .v26-fab-ico { width: 22px; height: 22px; color: #fff; }
.v26-fab.is-on { opacity: 1; visibility: visible; transform: translateY(0); }
.v26-fab:hover { background: var(--green-dark, #008550); }
.v26-fab:focus-visible { outline: 2px solid var(--green, #00A868); outline-offset: 3px; }
[data-theme="dark"] .v26-fab { background: var(--v26-accent); color: #06251A; }
[data-theme="dark"] .v26-fab .v26-fab-ico { color: #06251A; }
@media (prefers-reduced-motion: no-preference) {
  .v26-fab { transition: opacity .22s ease, transform .22s cubic-bezier(.2,.7,.3,1), background .15s ease; }
}
@media (max-width: 760px) { .v26-fab { right: 14px; bottom: 14px; width: 46px; height: 46px; } }

/* ---- (19) cabeçalhos de seção ----------------------------------------- */
h2.v26-h2 { display: flex; align-items: center; gap: 11px; }
.v26-h2-ico {
  width: 26px; height: 26px; flex: 0 0 auto;
  color: var(--v26-accent);
}

/* ---- (17) tags -------------------------------------------------------- */
.tag.v26-tag { display: inline-flex; align-items: center; gap: 5px; }
.v26-tag-ico { width: 13px; height: 13px; color: currentColor; }

/* ---- (19) listas do corpo do artigo: marcador em ícone de check ------- */
.article-body ul:not([class]) {
  list-style: none; padding-left: 4px;
}
.article-body ul:not([class]) > li {
  position: relative; padding-left: 30px; margin: 8px 0;
}
.article-body ul:not([class]) > li::before {
  content: ""; position: absolute; left: 0; top: 4px;
  width: 18px; height: 18px;
  background: center/contain no-repeat
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23047857' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
}
[data-theme="dark"] .article-body ul:not([class]) > li::before {
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2334D399' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .article-body ul:not([class]) > li::before {
    background-image:
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2334D399' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
  }
}

/* ---- foco visível universal nos ícones interativos -------------------- */
.v26-search:focus-visible { outline: 2px solid var(--green, #00A868); outline-offset: 2px; }

/* =======================================================================
 * P0 acessibilidade 2026 — contraste e foco (escopo .v26-*)
 * Aditivo e conservador: não muda iconografia nem identidade. Reaproveita
 * os tokens --green-text/--focus-ring definidos em styles.css (com fallback
 * inline para o caso de a ordem de carga falhar). O mecanismo [data-theme]
 * não é tocado: os tokens já adaptam ao tema.
 * ===================================================================== */

/* (1) Realce de TEXTO verde dos componentes v26 que reprovavam AA no claro:
   summary do flowchart e o rótulo da seta do drawer herdavam --green-dark
   (~4.0:1). Passam ao verde acessível (--green-text ~5.4:1 no claro;
   #34D399 no escuro). Ícones (limite 3:1) já passam, então não mexemos. */
.article-body.justify .dh-flowchart summary{ color: var(--green-text, #005C32); }

/* (2) Foco visível padronizado nos interativos próprios do v26 (FAB topo,
   busca, e qualquer link/botão dentro de blocos v26). Só :focus-visible. */
.v26-fab:focus-visible,
.v26-search:focus-visible,
.v26-grp-col > a:focus-visible,
.mega-grid a:focus-visible{
  outline: 2px solid var(--focus-ring, #005C32);
  outline-offset: 3px;
  border-radius: 8px;
}
[data-theme="dark"] .v26-fab:focus-visible{ outline-color: var(--focus-ring, #34D399); }

/* ---- reduced motion: zera transições dos ícones ----------------------- */
@media (prefers-reduced-motion: reduce) {
  .v26-ico, .v26-fab { transition: none !important; }
}

/* =======================================================================
 * P1 micro-interacoes e transicoes 2026
 * Aditivo e idempotente. Anima SOMENTE propriedades baratas (transform,
 * opacity) — nunca left/width/top. Reaproveita as variaveis de sombra do
 * styles.css (--shadow-md/--shadow-lg). Toda animacao fica sob guarda de
 * `prefers-reduced-motion: no-preference`; o bloco reduce zera tudo. Nao
 * altera os estilos de foco do P0 (so usamos :active e :hover aqui).
 * ===================================================================== */

/* (P1-A) View Transitions API — progressive enhancement cross-document.
   Onde suportado, a navegacao entre paginas ganha um cross-fade nativo;
   onde nao, o navegador simplesmente ignora a regra (degradacao segura). */
@view-transition { navigation: auto; }
/* O header e persistente entre paginas: dar-lhe um nome evita que ele
   "pisque" durante a transicao (nome unico, nao duplicado). */
.hdr { view-transition-name: hdr; }

/* (P1-B) Micro-interacoes de press/hover (apenas com movimento permitido) */
@media (prefers-reduced-motion: no-preference) {

  /* Press ("afundar") nos interativos: transicao curta so de transform,
     para nao competir com as transicoes de cor/sombra ja definidas. */
  .btn, .btn-primary, .btn-ghost, .icon-btn, .menu-toggle, .cta,
  .card, .hub-card, .tool-card, .persona-card, .pager-card {
    transition: transform .12s ease;
  }
  .btn:active, .btn-primary:active, .btn-ghost:active, .icon-btn:active,
  .menu-toggle:active, .cta:active,
  .card:active, .hub-card:active, .tool-card:active,
  .persona-card:active, .pager-card:active {
    transform: translateY(1px) scale(.985);
  }

  /* Hover dos cards clicaveis: leve elevacao + sombra suave existente.
     (.card e .pager-card ja sobem -2px no styles.css; aqui reforcamos os
     demais cards de forma idempotente, reusando --shadow-md.) */
  .hub-card:hover, .tool-card:hover, .persona-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-md, 0 4px 12px rgba(15,23,42,.06));
  }
}

/* (P1-C) Contrato de reveal por scroll (classes aplicadas pelo JS).
   So escondemos conteudo quando o JS confirmou que pode animar, marcando
   <html> com .v26-anim. Sem isso (JS desligado ou reduced-motion), o
   elemento permanece totalmente visivel — nada some sem garantia de in. */
html.v26-anim .v26-reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity .5s ease, transform .5s ease;
  will-change: opacity, transform;
}
html.v26-anim .v26-reveal.v26-in {
  opacity: 1;
  transform: none;
}

/* (P1-D) Reduced motion: neutraliza press, reveal e view transitions. */
@media (prefers-reduced-motion: reduce) {
  .btn, .btn-primary, .btn-ghost, .icon-btn, .menu-toggle, .cta,
  .card, .hub-card, .tool-card, .persona-card, .pager-card {
    transition: none;
  }
  .btn:active, .btn-primary:active, .btn-ghost:active, .icon-btn:active,
  .menu-toggle:active, .cta:active,
  .card:active, .hub-card:active, .tool-card:active,
  .persona-card:active, .pager-card:active {
    transform: none;
  }
  html.v26-anim .v26-reveal,
  .v26-reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation: none;
  }
}

/* =======================================================================
 * P2 hero fluxograma 2026
 * Componente-assinatura "Fluxo do dinheiro" inserido como seção logo abaixo
 * do hero da home (injetado por enhFluxoHero() em visual-enhance.js). Aditivo
 * e idempotente: todo o escopo tem prefixo .fluxo- para não colidir com o
 * resto. Tokens reusam as variáveis canônicas do site (--bg, --card, --ink,
 * --muted, --line, --green-dark, --green-text, --focus-ring) com fallback
 * inline para o flash inicial. Anima SOMENTE transform/opacity/
 * stroke-dashoffset; o bloco reduced-motion zera o movimento e mantém o
 * estado final legível. Reempilha em <=720px sem overflow-x.
 * ===================================================================== */

/* Tokens locais do componente, mapeados aos tokens reais do site.
   Light: lado direito dos fallbacks aterrado nos tokens existentes. */
:root {
  --fluxo-bg:        var(--bg, #FAFAF7);
  --fluxo-bg-2:      var(--card, #FFFFFF);     /* superfície clara intermediária */
  --fluxo-card:      var(--card, #FFFFFF);
  --fluxo-ink:       var(--ink, #0F172A);
  --fluxo-ink-soft:  var(--muted, #64748B);
  --fluxo-line:      var(--line, #E2E8F0);
  /* Paleta verde Stone / Brasil GEO (realces, não dependem de token de texto) */
  --fluxo-lime:      #A5FA00;   /* realce / token em movimento */
  --fluxo-green:     #00D700;   /* verde vivo */
  --fluxo-dark:      #00461E;   /* verde escuro (superfície de nó aceso) */
  --fluxo-text-green:var(--green-text, #005C32); /* verde de texto AA no claro */
  --fluxo-accent:    var(--green-dark, #008550);
  --fluxo-track:     #C9E8D6;   /* trilho apagado do caminho */
  --fluxo-shadow:    0 1px 2px rgba(11,31,20,.06), 0 8px 24px rgba(11,31,20,.08);
  --fluxo-focus:     var(--focus-ring, #005C32); /* anel de foco com contraste */
}

/* Dark: ativa por atributo explícito E por preferência do SO (sem
   data-theme="light"), espelhando o padrão canônico do site para que o
   componente adapte já no flash inicial, antes de o nav.js rodar. */
[data-theme="dark"] {
  --fluxo-bg:        #0B1410;
  --fluxo-bg-2:      #0F1B15;
  --fluxo-card:      #14241C;
  --fluxo-ink:       #E8F3EC;
  --fluxo-ink-soft:  #9FB3A8;
  --fluxo-line:      rgba(165,250,0,.18);
  --fluxo-lime:      #B6FF2E;
  --fluxo-green:     #34D399;
  --fluxo-dark:      #062E14;
  --fluxo-text-green:#7BE0A6;   /* claro sobre superfície escura (AA) */
  --fluxo-accent:    #34D399;
  --fluxo-track:     rgba(126,224,166,.22);
  --fluxo-shadow:    0 1px 2px rgba(0,0,0,.4), 0 10px 30px rgba(0,0,0,.45);
  --fluxo-focus:     #67E8F9;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --fluxo-bg:        #0B1410;
    --fluxo-bg-2:      #0F1B15;
    --fluxo-card:      #14241C;
    --fluxo-ink:       #E8F3EC;
    --fluxo-ink-soft:  #9FB3A8;
    --fluxo-line:      rgba(165,250,0,.18);
    --fluxo-lime:      #B6FF2E;
    --fluxo-green:     #34D399;
    --fluxo-dark:      #062E14;
    --fluxo-text-green:#7BE0A6;
    --fluxo-accent:    #34D399;
    --fluxo-track:     rgba(126,224,166,.22);
    --fluxo-shadow:    0 1px 2px rgba(0,0,0,.4), 0 10px 30px rgba(0,0,0,.45);
    --fluxo-focus:     #67E8F9;
  }
}

/* ====================== COMPONENTE ==================================== */
.fluxo{
  background:linear-gradient(180deg,var(--fluxo-bg-2),var(--fluxo-bg));
  color:var(--fluxo-ink);
  padding:clamp(20px,4vw,40px) 0;
}
.fluxo .fluxo-wrap{max-width:1100px; margin:0 auto; padding:0 clamp(16px,4vw,40px)}

.fluxo-head{
  display:flex; gap:16px; align-items:flex-end; justify-content:space-between;
  flex-wrap:wrap; margin-bottom:18px;
}
.fluxo-title{margin:0; font-size:clamp(1.3rem,3.2vw,2rem); letter-spacing:-.01em}
.fluxo-title b{color:var(--fluxo-text-green)}
.fluxo-sub{margin:.35rem 0 0; color:var(--fluxo-ink-soft); max-width:52ch}

/* Controles: seletor de negócio + botão rodar simulação */
.fluxo-controls{display:flex; gap:10px; align-items:center; flex-wrap:wrap}
.fluxo-seg{
  display:inline-flex; background:var(--fluxo-card);
  border:1px solid var(--fluxo-line); border-radius:12px; padding:4px;
  box-shadow:var(--fluxo-shadow);
}
.fluxo-seg button{
  font:inherit; font-weight:600; cursor:pointer; border:0; background:transparent;
  color:var(--fluxo-ink-soft); border-radius:9px; padding:8px 12px; min-height:44px;
}
.fluxo-seg button[aria-pressed="true"]{
  background:var(--fluxo-text-green); color:#fff;
}
[data-theme="dark"] .fluxo-seg button[aria-pressed="true"]{
  background:var(--fluxo-green); color:#062E14;
}
.fluxo-seg button:focus-visible{outline:3px solid var(--fluxo-focus); outline-offset:2px}

.fluxo-run{
  font:inherit; font-weight:700; cursor:pointer; min-height:48px;
  display:inline-flex; align-items:center; gap:9px;
  border:0; border-radius:12px; padding:0 18px;
  color:#062E14; background:linear-gradient(180deg,var(--fluxo-lime),var(--fluxo-green));
  box-shadow:0 6px 18px rgba(0,215,0,.28);
}
.fluxo-run:hover{filter:brightness(1.03)}
.fluxo-run:active{transform:translateY(1px)}
.fluxo-run:focus-visible{outline:3px solid var(--fluxo-focus); outline-offset:3px}
.fluxo-run[disabled]{opacity:.6; cursor:progress}
.fluxo-run .ic{width:18px; height:18px; display:block}

/* --------------------------- O PALCO SVG ------------------------------ */
.fluxo-stage{
  position:relative; margin-top:18px;
  background:var(--fluxo-card); border:1px solid var(--fluxo-line);
  border-radius:20px; box-shadow:var(--fluxo-shadow);
  padding:clamp(14px,3vw,26px);
  /* Reserva de altura mínima do palco: evita salto (CLS) ao montar o SVG.
     O viewBox é 1000x300 (proporção 10:3); abaixo segue a versão empilhada. */
  min-height:clamp(280px,34vw,360px);
}
.fluxo-svg{display:block; width:100%; height:auto}

/* Trilho e caminho percorrido pelo token */
.fluxo-track{ fill:none; stroke:var(--fluxo-track); stroke-width:5; stroke-linecap:round }
.fluxo-flow{
  fill:none; stroke:url(#fluxoGrad); stroke-width:5; stroke-linecap:round;
  /* Estado FINAL (degradação graciosa / reduced-motion): caminho cheio.
     O JS sobrescreve dashoffset para animar o preenchimento. */
  stroke-dasharray:1 0;
}
.fluxo-endpoint{ fill:var(--fluxo-bg-2); stroke:var(--fluxo-text-green); stroke-width:2 }
[data-theme="dark"] .fluxo-endpoint{ stroke:var(--fluxo-green) }
.fluxo-endpoint-label{ fill:var(--fluxo-ink); font-weight:700; font-size:13px }
.fluxo-endpoint-sub{ fill:var(--fluxo-ink-soft); font-size:11px }

/* O token (moeda em movimento). Animado só via transform/opacity. */
.fluxo-token{ opacity:0 }
.fluxo-token circle{ fill:var(--fluxo-lime); stroke:var(--fluxo-dark); stroke-width:1.5 }
.fluxo-token text{ fill:var(--fluxo-dark); font-weight:800; font-size:11px; text-anchor:middle }
.fluxo.is-playing .fluxo-token{ opacity:1 }

/* Os 4 nós de estágio (cartões dentro do SVG via foreignObject) */
.fluxo-node{
  height:100%;
  display:flex; flex-direction:column; gap:6px; justify-content:center;
  border-radius:16px; padding:12px 14px;
  background:var(--fluxo-bg-2); border:1.5px solid var(--fluxo-line);
  color:var(--fluxo-ink);
  transition:transform .35s cubic-bezier(.2,.7,.3,1),
             box-shadow .35s ease, background .35s ease, border-color .35s ease;
}
.fluxo-node .n-top{display:flex; align-items:center; gap:8px}
.fluxo-node .n-ic{
  width:34px; height:34px; flex:0 0 auto; border-radius:10px;
  display:grid; place-items:center; background:var(--fluxo-card);
  border:1px solid var(--fluxo-line); color:var(--fluxo-text-green);
}
.fluxo-node .n-ic svg{width:20px; height:20px}
.fluxo-node .n-step{
  font-size:11px; font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  color:var(--fluxo-ink-soft);
}
.fluxo-node .n-title{font-size:1rem; font-weight:800; margin:0}
.fluxo-node .n-desc{font-size:.8rem; color:var(--fluxo-ink-soft); margin:0}

/* Estado ACESO de um estágio (sequência da simulação OU estado final estático) */
.fluxo-node.is-lit{
  background:var(--fluxo-dark); border-color:var(--fluxo-green);
  box-shadow:0 0 0 3px rgba(0,215,0,.22), 0 14px 30px rgba(0,70,30,.35);
  transform:translateY(-3px);
}
.fluxo-node.is-lit .n-step{color:var(--fluxo-lime)}
.fluxo-node.is-lit .n-title,
.fluxo-node.is-lit .n-desc{color:#EAFFEF}
.fluxo-node.is-lit .n-ic{
  background:var(--fluxo-lime); color:var(--fluxo-dark); border-color:var(--fluxo-lime);
}

/* ----------------------------- MEDIDORES ------------------------------ */
.fluxo-meters{
  list-style:none; padding:0; margin:18px 0 0;
  display:grid; gap:12px;
  grid-template-columns:repeat(4,1fr);
}
.fluxo-meter{
  background:var(--fluxo-card); border:1px solid var(--fluxo-line);
  border-radius:14px; padding:12px 14px; box-shadow:var(--fluxo-shadow);
}
.fluxo-meter .m-label{
  display:flex; align-items:center; gap:7px;
  font-size:.78rem; font-weight:600; color:var(--fluxo-ink-soft);
}
.fluxo-meter .m-label svg{width:16px; height:16px; color:var(--fluxo-text-green)}
[data-theme="dark"] .fluxo-meter .m-label svg{color:var(--fluxo-green)}
.fluxo-meter .m-value{
  font-size:clamp(1.25rem,2.6vw,1.6rem); font-weight:800; letter-spacing:-.01em;
  color:var(--fluxo-text-green);
}
[data-theme="dark"] .fluxo-meter .m-value{color:var(--fluxo-green)}
.fluxo-meter .m-bar{
  height:6px; border-radius:99px; margin-top:8px; overflow:hidden;
  background:var(--fluxo-track);
}
.fluxo-meter .m-bar span{
  display:block; height:100%; width:var(--fill,0%);
  background:linear-gradient(90deg,var(--fluxo-green),var(--fluxo-lime));
  transform-origin:left; transition:width .5s cubic-bezier(.2,.7,.3,1);
}

.fluxo-foot{
  margin-top:14px; display:flex; gap:8px; align-items:center;
  font-size:.78rem; color:var(--fluxo-ink-soft);
}
.fluxo-foot svg{width:15px; height:15px; flex:0 0 auto}

/* Acessibilidade: rótulo só para leitor de tela */
.fluxo-sr{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

/* ----------------------- KEYFRAMES (só transform/opacity) ------------- */
@keyframes fluxoPulse{
  0%{transform:translateY(-3px) scale(1)}
  50%{transform:translateY(-3px) scale(1.015)}
  100%{transform:translateY(-3px) scale(1)}
}
.fluxo.is-playing .fluxo-node.is-lit{animation:fluxoPulse .9s ease}

/* ---------------------------- MOBILE (<=720px) ------------------------- */
/* Reempilha os medidores em coluna e ajusta o cabeçalho. O palco SVG escala
   pelo width:100% (viewBox preserva a proporção), sem overflow-x. */
@media (max-width:720px){
  .fluxo-meters{grid-template-columns:repeat(2,1fr)}
  .fluxo-head{align-items:flex-start}
  .fluxo-stage{min-height:0}
}
@media (max-width:520px){
  .fluxo-meters{grid-template-columns:1fr}
}

/* --------------------- PREFERS-REDUCED-MOTION -------------------------- */
/* Sem movimento: sem pulso, sem transição de nó, token escondido. O estado
   final aceso já está aplicado (o JS adiciona is-lit em todos os nós), então
   o usuário vê o diagrama completo, e o botão recalcula números na hora. */
@media (prefers-reduced-motion:reduce){
  .fluxo *,
  .fluxo *::before,
  .fluxo *::after{animation:none !important; transition:none !important}
  .fluxo .fluxo-token{opacity:0 !important}
}

/* =======================================================================
 * WAVE 1 - TIPOGRAFIA, LEGIBILIDADE E JUSTIFICACAO
 * (curso Frontends com Vibecoding, modulos 4 e 9)
 *
 * Objetivo do cliente: "todos os parágrafos devem ter alinhamento
 * justificado". Tornamos a justificação UNIVERSAL na prosa editorial.
 *
 * Escopo. O único container de prosa do site é o `.article-body` (728
 * páginas de conteúdo + 215 páginas /datahub/, estas com o modificador
 * `.justify`). A regra opt-in antiga vive em styles.css:
 *   `.article-body.justify p,.article-body.justify li{text-align:justify}`
 * e cobria só cerca de 306 páginas. Aqui estendemos o mesmo tratamento a
 * TODO `.article-body`, com ou sem `.justify`, sem reescrever nenhum HTML.
 *
 * Anti-regressão. Tudo é ancorado em `.article-body` (prosa), nunca em
 * `p`/`li` crus. Navbar, mega-menu, breadcrumbs, drawer, rótulos, KPIs,
 * código, tabelas e os menus (`nav li`, `.menu li`) ficam fora do escopo
 * por construção: não são descendentes de `.article-body`. Itens de
 * componente que já eram alinhados à esquerda (callout, blockquote,
 * legendas, passos dh-*, células) são reafirmados à esquerda para não
 * herdarem o justify. Sem `@layer` (o arquivo não usa). `!important`
 * usado só onde imprescindível, sempre comentado.
 * ===================================================================== */

/* (W1-1) JUSTIFICACAO UNIVERSAL DA PROSA -------------------------------
   Parágrafos e itens de lista de QUALQUER `.article-body` passam a ser
   justificados, com hifenização (lang="pt-BR" no <html> habilita o
   dicionário português). text-justify:inter-word e hyphenate-limit-chars
   reduzem os "buracos" e evitam hifenizar palavras curtas. text-wrap:
   pretty (onde suportado; ignorado nos demais) ataca órfãs/viúvas/rios.
   A regra opt-in de styles.css já cobre `.article-body.justify`; esta
   amplia para `.article-body` cru sem conflitar (mesma declaração). */
.article-body p,
.article-body li{
  text-align: justify;
  text-justify: inter-word;
  -webkit-hyphens: auto;
  hyphens: auto;
  hyphenate-limit-chars: 6 3 2;   /* mínimo 6 letras; 3 antes e 2 depois do hífen */
  text-wrap: pretty;              /* progressive enhancement; evita viúvas e rios */
}

/* (W1-1b) Reafirma o alinhamento à ESQUERDA onde a prosa não deve ser
   justificada: caixas de destaque, citações, legendas, passos e células.
   styles.css já zera `.article-body.justify .callout p` e os blocos dh-*;
   replicamos para o `.article-body` cru (sem `.justify`) manter o mesmo
   comportamento. São seletores mais específicos, então vencem (W1-1) sem
   precisar de `!important`. */
.article-body .callout p,
.article-body .callout li,
.article-body blockquote p,
.article-body blockquote li,
.article-body figcaption,
.article-body .dh-step p,
.article-body .dh-timeline li,
.article-body td,
.article-body th{
  text-align: left;
}

/* (W1-2) MEDIDA OTIMA DE LEITURA ---------------------------------------
   styles.css NÃO define measure para `.article-body`: a coluna herda a
   largura do `.article-wrap` (cerca de 868px em telas >=1080px, perto de
   85ch a 17px), larga demais para leitura confortável de texto justificado.
   Limitamos a 70ch SOMENTE nas páginas editoriais (`.article-body` sem
   `.justify`). As páginas /datahub/ (`.justify`) já têm largura e medida
   próprias via `body[data-portal="datahub"] .article-body.justify` e seus
   cartões, por isso NÃO são tocadas aqui (evita duplicar ou reduzir o que
   já existe). `.article-body` é célula de grid em `.article-wrap`, então
   max-width só encolhe a coluna de texto; não quebra o grid de 2 colunas. */
.article-body:not(.justify){
  max-width: 70ch;
}
/* Blocos largos da prosa editorial podem extravasar a medida (bleed),
   recuperando a largura total da coluna. Aplica-se só onde a medida foi
   imposta (páginas sem `.justify`). */
.article-body:not(.justify) .table-wrap,
.article-body:not(.justify) table,
.article-body:not(.justify) figure,
.article-body:not(.justify) hr{
  max-width: none;
}

/* (W1-3) TITULOS: equilibrio de quebras -------------------------------
   text-wrap:balance distribui as palavras entre as linhas de títulos
   curtos (h1-h4) da prosa, evitando uma última linha com uma palavra
   solta. Restrito a títulos dentro de `.article-body`, nunca a títulos de
   componentes interativos (fluxo, mega-menu, cards), que ficam fora do
   escopo por não serem descendentes de `.article-body`. */
.article-body h1,
.article-body h2,
.article-body h3,
.article-body h4{
  text-wrap: balance;
}

/* (W1-4) RITMO VERTICAL -------------------------------------------------
   O line-height da prosa já é confortável (1.72 no HTML inline; 1.65 no
   mobile), então NÃO redefinimos line-height global. Apenas garantimos um
   piso de 1.65 caso algum parágrafo de prosa herde um valor mais apertado
   de um componente ancestral. Aplica-se só a parágrafos diretos do corpo,
   fora de cartões e passos que têm ritmo próprio. */
.article-body > p,
.article-body > ul > li,
.article-body > ol > li{
  line-height: 1.65;
}

/* =======================================================================
 * WAVE 2 - ACESSIBILIDADE WCAG 2.2 (curso Frontends com Vibecoding, modulo 9)
 *
 * Objetivo. Levar a interface global ao nível AA do WCAG 2.2, completando o
 * que as ondas anteriores já iniciaram, SEM duplicar regras existentes e SEM
 * mexer nas cores de marca (verdes). O que já existia e foi PRESERVADO:
 *   - Foco visível parcial nos interativos próprios do v26 (FAB, busca, mega
 *     e cards do v26) no bloco P0 mais acima; aqui estendemos a TODOS os
 *     interativos (a, button, input, select, textarea, summary, [tabindex]).
 *   - prefers-reduced-motion já cobre .fluxo, .v26-ico/.v26-fab e o bloco P1;
 *     aqui adicionamos só o fallback GLOBAL seguro que faltava.
 *   - Tokens de cor --muted/--ink-3/--focus-ring (definidos em styles.css):
 *     reaproveitados; só o que reprova AA é corrigido abaixo.
 *
 * Anti-regressão. Seletores específicos, sem vazamento. `!important` apenas
 * onde imprescindível (foco e reduced-motion globais), sempre comentado. As
 * cores de marca (--green, --stone-*) NÃO são tocadas: corrigimos apenas
 * tons de cinza de texto secundário que reprovavam o contraste mínimo.
 * ===================================================================== */

/* (W2-1) FOCO VISÍVEL UNIVERSAL - WCAG 2.4.7 ----------------------------
   O bloco P0 (mais acima) só cobre os interativos próprios do v26. Aqui
   garantimos um anel de foco de 2px de alto contraste em TODOS os elementos
   interativos do site, usando o token --focus-ring (que já adapta ao tema:
   #005C32 no claro ~6.3:1, #34D399 no escuro ~9:1) com fallback literal.
   Usamos :focus-visible para não poluir o clique de mouse, e mantemos um
   :focus simples como rede de segurança em navegadores sem :focus-visible.
   Nunca removemos o outline sem oferecer substituto. */
a:focus-visible,
button:focus-visible,
[role="button"]:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible{
  outline: 2px solid var(--focus-ring, #005C32);
  outline-offset: 2px;
  /* Halo extra para superfícies onde o offset sozinho some sobre cor próxima.
     Não altera layout (box-shadow não ocupa fluxo). */
  box-shadow: 0 0 0 4px var(--focus-ring-halo, rgba(0, 92, 50, .18));
}
/* Rede de segurança para navegadores antigos sem suporte a :focus-visible:
   só aplica quando o seletor :focus-visible NÃO é entendido (a regra acima
   é ignorada nesses navegadores; esta garante um anel mesmo assim). */
a:focus:not(:focus-visible),
button:focus:not(:focus-visible){
  outline: 2px solid var(--focus-ring, #005C32);
  outline-offset: 2px;
}
[data-theme="dark"] a:focus-visible,
[data-theme="dark"] button:focus-visible,
[data-theme="dark"] [role="button"]:focus-visible,
[data-theme="dark"] input:focus-visible,
[data-theme="dark"] select:focus-visible,
[data-theme="dark"] textarea:focus-visible,
[data-theme="dark"] summary:focus-visible,
[data-theme="dark"] [tabindex]:focus-visible{
  outline-color: var(--focus-ring, #34D399);
  box-shadow: 0 0 0 4px var(--focus-ring-halo-dark, rgba(52, 211, 153, .26));
}

/* (W2-2) SKIP-LINK "Pular para o conteúdo" - WCAG 2.4.1 -----------------
   O HTML gerado NÃO trazia skip-link (auditado: nenhum "skip"/"pular" no
   CSS nem nos HTMLs). O link é injetado por visual-enhance.js (enhSkipLink)
   no início do <body>, apontando para #main. Aqui está só o estilo: fora da
   tela por padrão (sem display:none, para permanecer no fluxo de Tab) e,
   ao receber foco, salta para o canto superior esquerdo, bem destacado. */
.v26-skip{
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 10000;
  /* Escondido sem sair da árvore de foco: deslocado para fora da viewport. */
  transform: translateY(-200%);
  background: var(--green-text, #005C32);
  color: #FFFFFF;
  padding: 12px 18px;
  border-radius: 8px;
  font-weight: 700;
  font-size: 15px;
  line-height: 1.2;
  text-decoration: none;
  box-shadow: 0 6px 20px rgba(15, 23, 42, .25);
  transition: transform .15s ease;
}
.v26-skip:focus,
.v26-skip:focus-visible{
  transform: translateY(0);
  outline: 3px solid #FFFFFF;
  outline-offset: 2px;
}
/* No escuro, o verde de texto clareado (#34D399) precisa de tinta escura. */
[data-theme="dark"] .v26-skip{
  background: var(--green-text, #34D399);
  color: #0F172A;
}
[data-theme="dark"] .v26-skip:focus,
[data-theme="dark"] .v26-skip:focus-visible{
  outline-color: #0F172A;
}
/* O destino do salto recebe tabindex=-1 (via JS); ao focá-lo por âncora não
   queremos um anel desnecessário ao redor do bloco inteiro de conteúdo. */
#main:focus,
main:focus,
.article-wrap:focus{
  outline: none;
}

/* (W2-3) ALVO DE TOQUE - WCAG 2.5.8 (mínimo 24x24 CSS px) ---------------
   Garante área mínima de 24px nos controles globais pequenos (ícones de
   nav, alternador de tema, fechar drawer, paginação, chips/tags, links da
   busca). Onde o controle é menor, usamos min-height/min-width e centramos
   o conteúdo; isso aumenta a ÁREA clicável sem mexer no tamanho visual do
   ícone. Restrito aos controles de interface (nunca a links de prosa, que
   o critério 2.5.8 isenta quando inline em texto). */
.icon-btn,
.menu-toggle,
.theme-toggle,
button.v26-grp,
.v26-fab,
.drawer-close,
.drawer .close,
[data-drawer-close],
.pager a,
.pager-card,
.tag,
.chip,
.v26-search{
  min-height: 24px;
  min-width: 24px;
}
/* Botões de ícone puramente quadrados ganham centralização do glifo para
   que o alvo de 24px fique simétrico (não desloca o ícone). */
.icon-btn,
.menu-toggle,
.theme-toggle,
.drawer-close,
.drawer .close,
[data-drawer-close]{
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* (W2-4) CONTRASTE DE TEXTO SECUNDÁRIO - WCAG 1.4.3 ---------------------
   Auditoria dos tokens de cinza (medições com a fórmula WCAG):
     CLARO  (sobre --bg #FAFAF7 / --card #FFFFFF):
       --muted  #64748B -> 4.55:1 / 4.76:1  (passa AA por margem mínima)
       --ink-3  #374151 -> 9.86:1 / 10.31:1 (folgado; NÃO mexer)
     ESCURO (sobre --bg #0F172A / --card #1E293B):
       --muted  #64748B -> 3.75:1 / 3.07:1  (REPROVA AA para texto normal)
       --ink-3  #CBD5E1 -> 12.02:1          (folgado; NÃO mexer)
   Correções (só o cinza de texto secundário; verdes intactos):
     - CLARO: escurece --muted para #5A6573 -> 5.67:1 (bg) / 5.93:1 (card),
       dando folga acima do piso de 4.5:1 sem virar quase-preto.
     - ESCURO: clareia --muted para #94A3B8 -> 6.96:1 (bg) / 5.71:1 (card),
       cruzando o piso de 4.5:1 com folga.
   Override por token, escopado aos containers de tema, para herdar em todo
   uso de --muted (legendas, metadados, rótulos secundários). */
:root:not([data-theme="dark"]){
  --muted: #5A6573;
}
[data-theme="dark"]{
  --muted: #94A3B8;
}
/* Espelha a correção do escuro no fallback por preferência do SO (quando o
   atributo data-theme não está presente), igual ao padrão de styles.css. */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --muted: #94A3B8;
  }
}

/* (W2-5) prefers-reduced-motion: FALLBACK GLOBAL SEGURO -----------------
   Os blocos anteriores cobrem .fluxo, ícones v26 e o P1. Falta uma rede
   global para quem pede menos movimento. Padrão recomendado (a11y-project):
   não REMOVER animações (pode quebrar estados que dependem do fim da
   transição), e sim reduzi-las a uma duração desprezível e desligar o
   scroll suave. Mantém a funcionalidade; só remove o movimento percebido.
   `!important` é imprescindível aqui para vencer durações declaradas em
   qualquer componente; é o uso canônico deste critério. */
@media (prefers-reduced-motion: reduce){
  *,
  *::before,
  *::after{
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  html{
    scroll-behavior: auto !important;
  }
}

/* (W2-6) prefers-contrast: high e forced-colors -------------------------
   Em modo de alto contraste, reforçamos contornos para que botões, cards,
   campos e o foco não dependam apenas de sombra ou cor sutil. */
@media (prefers-contrast: more){
  a:focus-visible,
  button:focus-visible,
  [role="button"]:focus-visible,
  input:focus-visible,
  select:focus-visible,
  textarea:focus-visible,
  summary:focus-visible,
  [tabindex]:focus-visible{
    outline-width: 3px;
    outline-offset: 3px;
  }
  .icon-btn,
  .menu-toggle,
  .theme-toggle,
  .btn,
  .btn-ghost,
  .card,
  .hub-card,
  .tool-card,
  input,
  select,
  textarea{
    border: 1px solid currentColor;
  }
}
/* Windows High Contrast / forced-colors: o SO substitui as cores por uma
   paleta própria; cabe a nós garantir que o foco e os contornos continuem
   visíveis usando as cores de sistema (CanvasText, Highlight). */
@media (forced-colors: active){
  a:focus-visible,
  button:focus-visible,
  [role="button"]:focus-visible,
  input:focus-visible,
  select:focus-visible,
  textarea:focus-visible,
  summary:focus-visible,
  [tabindex]:focus-visible{
    /* Highlight é a cor de seleção do sistema; garante anel sempre visível. */
    outline: 3px solid Highlight;
    outline-offset: 2px;
  }
  .v26-skip{
    border: 2px solid ButtonText;
  }
  .icon-btn,
  .menu-toggle,
  .theme-toggle,
  .card,
  .hub-card,
  .tool-card{
    border: 1px solid ButtonText;
  }
}

/* =======================================================================
 * WAVE 3 - MICROINTERACOES, ANIMACAO E ICONES
 * (curso Frontends com Vibecoding, modulo 8: "Animacao, microinteracoes,
 * icones")
 *
 * Bloco aditivo e idempotente. Complementa as Waves 1 e 2 e os blocos P0/P1
 * sem redefinir nada existente. Principios inegociaveis respeitados:
 *   - Anima SOMENTE transform/opacity (composicao barata), nunca propriedades
 *     que disparam layout/reflow.
 *   - TODA animacao respeita prefers-reduced-motion (o fallback global W2-5 ja
 *     reduz a duracao; aqui ainda neutralizamos os transforms para nao deixar
 *     "salto" residual).
 *   - Progressive enhancement: o que depende de JS (reveal de prosa) so esconde
 *     conteudo sob html.v26-anim, garantido pelo mesmo contrato do P1-C.
 * ===================================================================== */

/* (W3-A) Fisica de press estendida: cobertura coerente do "afundar e pulsar".
   O P1-B ja trata a familia .btn e os cards. Aqui ESTENDEMOS para os demais
   alvos de acao que ficavam de fora (chips, tags, botoes guarda-chuva da nav,
   segmentos do fluxograma e CTAs de prosa marcados), usando uma curva de mola
   (cubic-bezier com leve overshoot) para o retorno dar a sensacao de pulso.
   So transform; a transicao de cor/sombra de cada componente continua intacta.
   Restrito a no-preference; o bloco reduce abaixo zera. */
@media (prefers-reduced-motion: no-preference) {
  .chip, .tag, button.v26-grp, .fluxo-seg button, a.v26-press {
    transition: transform .16s cubic-bezier(.34, 1.56, .64, 1);
  }
  .chip:active, .tag:active, button.v26-grp:active,
  .fluxo-seg button:active, a.v26-press:active {
    transform: translateY(1px) scale(.97);
  }
}

/* (W3-B) Affordance moderna de link de prosa: sublinhado animado.
   Links dentro do corpo do artigo ganham um sublinhado que "cresce" no hover
   via background-size (composicao barata; nao anima text-decoration nem causa
   reflow). Mantem legibilidade e contraste: a cor herda o verde de texto ja
   usado no tema e o foco continua sendo o anel da Wave 2 (nao tocamos foco).
   Excluimos botoes/CTAs disfarcados de link, ancoras de cabecalho e qualquer
   link que ja contenha midia/icone proprio. */
.article-body a:not(.btn):not(.btn-primary):not(.btn-ghost):not(.cta):not(.headerlink):not([class*="card"]) {
  text-decoration: none;
  text-underline-offset: .18em;
  background-image: linear-gradient(currentColor, currentColor);
  background-position: 0 100%;
  background-repeat: no-repeat;
  background-size: 0% 1.5px;
}
@media (prefers-reduced-motion: no-preference) {
  .article-body a:not(.btn):not(.btn-primary):not(.btn-ghost):not(.cta):not(.headerlink):not([class*="card"]) {
    transition: background-size .25s cubic-bezier(.2, .7, .3, 1), color .18s ease;
  }
}
.article-body a:not(.btn):not(.btn-primary):not(.btn-ghost):not(.cta):not(.headerlink):not([class*="card"]):hover {
  background-size: 100% 1.5px;
}
/* Garante o sublinhado tambem em foco por teclado, sem mexer no anel da W2:
   o foco-visivel revela o sublinhado completo como reforco da affordance. */
.article-body a:not(.btn):not(.btn-primary):not(.btn-ghost):not(.cta):not(.headerlink):not([class*="card"]):focus-visible {
  background-size: 100% 1.5px;
}

/* (W3-C) Reveal escalonado para blocos de prosa (aplicado pelo passo JS
   enhRevealProse). Mesmo contrato do P1-C: so esconde sob html.v26-anim, logo
   sem JS ou com reduced-motion o conteudo permanece sempre visivel. O atraso
   por indice e definido inline pelo JS na variavel --v26-d (escalonamento
   suave, limitado para nunca prender conteudo por muito tempo). */
html.v26-anim .v26-reveal-prose {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .55s ease, transform .55s ease;
  transition-delay: var(--v26-d, 0ms);
  will-change: opacity, transform;
}
html.v26-anim .v26-reveal-prose.v26-in {
  opacity: 1;
  transform: none;
}

/* (W3-D) Reduced motion: neutraliza press estendido, sublinhado animado e
   reveal de prosa. O conteudo de prosa nunca fica preso invisivel. */
@media (prefers-reduced-motion: reduce) {
  .chip, .tag, button.v26-grp, .fluxo-seg button, a.v26-press {
    transition: none;
  }
  .chip:active, .tag:active, button.v26-grp:active,
  .fluxo-seg button:active, a.v26-press:active {
    transform: none;
  }
  .article-body a:not(.btn):not(.btn-primary):not(.btn-ghost):not(.cta):not(.headerlink):not([class*="card"]) {
    transition: none;
    /* Sem movimento: sublinhado estatico sempre presente para manter a
       affordance (o link permanece claramente clicavel). */
    background-size: 100% 1.5px;
  }
  html.v26-anim .v26-reveal-prose,
  .v26-reveal-prose {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ======================================================================
 * WAVE 4 - LAYOUT, NAVEGACAO E DASHBOARDS
 * Dinheiro da Minha Empresa (Brasil GEO) - curso Frontends com Vibecoding,
 * modulo 7 (navegacao) e dashboards/KPIs.
 *
 * Escopo desta wave (injetada site-wide pelo worker via visual-2026.css):
 *   1. Robustez do drawer no breakpoint (suporte ao passo enhDrawerResizeFix).
 *   2. Conter o overflow-x horizontal site-wide nas tres fontes confirmadas
 *      (tabelas largas, popover .dh-term__pop, animacao .dh-grid-scan) sem
 *      cegar com overflow-x:hidden no html/body.
 *   3. Polish de navegacao: estados coerentes, mega/dropdown sem vazar,
 *      bottom-nav com alvo de toque e safe-area, abas (.dh-abas) preservadas.
 *   4. Padronizacao dos cartoes de KPI/estatistica (stat-strip).
 *
 * Anima so transform/opacity; respeita prefers-reduced-motion e o foco-visivel
 * da Wave 2. Mobile-first. !important so onde imprescindivel (comentado).
 * ====================================================================== */

/* ----------------------------------------------------------------------
 * (W4-A) OVERFLOW-X: conter vazamento horizontal nas fontes confirmadas
 * ----------------------------------------------------------------------
 * Estes assets de pagina (styles.css, datahub.css, dh-experience-2.css) sao
 * linkados por-pagina, NAO site-wide; so visual-2026.css roda em todo HTML.
 * Logo as defesas abaixo precisam viver aqui para valerem em qualquer pagina.
 */

/* (a) Tabelas largas na prosa. O passo enhTableWrap (JS) envolve cada
   <table> "nua" do corpo do artigo num .v26-table-wrap rolavel; aqui damos o
   scroll horizontal contido, sem cortar dados. Tambem reforcamos o
   .table-wrap canonico do projeto (que so tinha overflow sob .justify). */
.v26-table-wrap,
.article-body .table-wrap {
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch; /* rolagem por inercia no iOS */
}
.v26-table-wrap > table {
  margin: 0;             /* a margem vai para o wrapper, evitando salto */
  min-width: max-content; /* a tabela mantem seu layout; o wrapper e que rola */
}

/* (b) Popover de termo do glossario inline (.dh-term__pop). Era
   position:absolute; left:0; max-width:280px -> num termo proximo da borda
   direita ele estoura o viewport e cria scroll horizontal. Clampamos a
   largura ao viewport (deixando uma folga de 16px de cada lado) sem mudar o
   ancoramento, e prendemos o conteudo para nunca empurrar a pagina. */
body[data-portal="datahub"] .dh-term__pop {
  max-width: min(280px, calc(100vw - 32px));
  overflow-wrap: anywhere; /* quebra termos longos em vez de alargar a caixa */
}

/* (c) Animacao do hero do hub /datahub/ (.dh-grid-scan). Ela e
   position:absolute; transform:translateX() varrendo de -100% a +100%; o
   palco (.dh-graph) ja tem overflow:hidden, mas reforcamos a contencao caso a
   marcacao mude, sem afetar o movimento (so transform anima). */
body[data-portal="datahub"] .dh-hero-lab,
body[data-portal="datahub"] .dh-graph {
  overflow: hidden; /* contem a faixa de varredura dentro do palco */
}
body[data-portal="datahub"] .dh-grid-scan {
  max-width: 100%;
  pointer-events: none;
}

/* (d) Rede de seguranca discreta: midia e SVG DECORATIVOS nunca excedem a
   largura disponivel (causa comum de overflow-x). Nao usamos overflow-x:hidden
   no html/body (quebraria position:sticky e o scroll-to-anchor); corrigimos na
   fonte. Restringimos a imagens/iframes/video e a SVGs sem viewBox proprio de
   layout, preservando os SVGs de dataviz que controlam a propria largura. */
img, iframe, video, embed, object {
  max-width: 100%;
}
svg.v26-ico { max-width: 100%; }

/* ----------------------------------------------------------------------
 * (W4-B) DRAWER: estado consistente no breakpoint desktop (>=1280px)
 * ----------------------------------------------------------------------
 * Defesa em CSS, complementar ao passo JS enhDrawerResizeFix. O .drawer e
 * fixed inset:0 e vira overlay quando [data-open]; styles.css nao tem media
 * query escondendo-o no desktop. Aqui garantimos que, a partir de 1280px (o
 * mesmo ponto em que o .menu-toggle some), o overlay do drawer jamais fique
 * preso visivel/clicavel mesmo que algum estado [data-open] sobreviva. */
@media (min-width: 1280px) {
  .drawer[data-open] {
    /* neutraliza o overlay presso no desktop: invisivel e nao-clicavel.
       !important imprescindivel: vence a regra .drawer[data-open] de styles.css
       (mesma especificidade, mas styles.css carrega depois em algumas paginas). */
    opacity: 0 !important;
    pointer-events: none !important;
  }
  .drawer[data-open] .drawer-panel {
    transform: translateX(-100%); /* recolhe o painel */
  }
}

/* ----------------------------------------------------------------------
 * (W4-C) POLISH DA NAVEGACAO (modulo 7)
 * ---------------------------------------------------------------------- */

/* (a) Item de navegacao atual: realce coerente por aria-current, sem depender
   so de cor (adiciona peso e uma barra-guia). Cobre nav desktop, drawer e
   footer. Transicao suave que respeita reduced-motion (regra global ja existe).*/
.nav a[aria-current="page"],
.nav button[aria-current="page"],
.drawer-panel a[aria-current="page"],
footer a[aria-current="page"] {
  font-weight: 700;
  color: var(--v26-accent);
}

/* (b) Mega-menu e dropdown: nunca vazar da viewport em telas medias. O painel
   .mega e full-bleed (container interno), mas os paineis de grupo (.v26-grp-panel)
   e qualquer dropdown ancorado ganham um teto de largura e rolagem vertical
   defensiva para nao ultrapassar a altura util. Elevacao coerente. */
.mega.v26-grp-panel {
  max-width: 100vw;
}
.mega.v26-grp-panel .v26-grp-grid {
  max-height: min(72vh, 560px);
  overflow-y: auto;
}

/* (c) Bottom-nav (.botnav): alvo de toque >= 44px de area e safe-area do notch.
   styles.css ja aplica padding com env(safe-area-inset-bottom); aqui garantimos
   a altura minima de toque por item e um realce de item ativo que nao dependa
   so de cor (adiciona um indicador acima). */
.botnav a {
  min-height: 44px;          /* alvo de toque confortavel (WCAG 2.5.5) */
  justify-content: center;
  position: relative;
}
.botnav a.active::before {
  content: "";
  position: absolute;
  top: 2px;
  left: 50%;
  transform: translateX(-50%);
  width: 18px;
  height: 3px;
  border-radius: 3px;
  background: var(--green-dark, #008550);
}
[data-theme="dark"] .botnav a.active::before { background: var(--v26-accent); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .botnav a.active::before { background: var(--v26-accent); }
}
/* reforco do safe-area-inset-bottom (idempotente com styles.css; protege
   paginas cujo styles.css esteja em cache antigo sem o env()). */
.botnav {
  padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 8px);
}

/* (d) Abas (.dh-abas): a aba ativa ja tem realce coerente (borda inferior lime
   + peso). NAO regredimos esse comportamento; apenas garantimos que a lista de
   abas role na horizontal sem vazar a pagina (a fonte do CSS das abas e por-
   pagina; aqui e rede de seguranca site-wide). */
.dh-abas__lista {
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.dh-abas__tab { min-height: 44px; } /* alvo de toque, idempotente */

/* ----------------------------------------------------------------------
 * (W4-D) DASHBOARDS / CARTOES KPI (stat-strip)
 * ----------------------------------------------------------------------
 * Padroniza a APRESENTACAO dos cartoes existentes (nao inventa dados):
 * alinhamento de numero e rotulo, espacamento, raio coerente e tendencia
 * (seta) com cor + icone + rotulo (nunca so cor). */
.stat-strip > div,
.stat-strip > .stat {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;                  /* espacamento consistente numero/rotulo */
}
.stat-strip .num {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  line-height: 1;
}
.stat-strip .lbl {
  line-height: 1.3;
}
/* o marcador decorativo do enhStats (trending-up) acima do numero fica
   alinhado e com tamanho coerente com o sistema. */
.stat-strip .v26-stat-ico {
  width: 20px;
  height: 20px;
  margin-bottom: 2px;
  color: var(--stone-lime, #A5FA00); /* sobre o gradiente escuro do strip */
}
/* (W4-E) Tendencia explicita em KPI: chip com seta + rotulo textual, cor
   reforcada por ICONE e por TEXTO (acessivel sem depender de cor). O passo
   enhKpiTrend (JS) injeta .v26-trend em cartoes que ja declaram a direcao via
   data-trend="up|down" no HTML; aqui so o estilo. */
.v26-trend {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: 4px;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  line-height: 1.4;
}
.v26-trend .v26-ico { width: 14px; height: 14px; }
.v26-trend--up   { color: var(--v26-yes); background: rgba(4, 120, 87, .12); }
.v26-trend--down { color: var(--v26-no);  background: rgba(220, 38, 38, .12); }
[data-theme="dark"] .v26-trend--up   { background: rgba(52, 211, 153, .16); }
[data-theme="dark"] .v26-trend--down { background: rgba(248, 113, 113, .16); }

/* ======================================================================
 * WAVE 5 - PERFORMANCE, SEO/GEO E PWA
 * ======================================================================
 * Ancorada nos modulos 9, 10 e 11 do curso (Core Web Vitals, render
 * performance e GEO). Foco: nao regredir Waves 1-4, progressive
 * enhancement, custo de render menor e zero CLS. Comentarios ASCII por
 * coerencia com os blocos anteriores.
 * ====================================================================== */

/* (W5-A) PREVENCAO DE CLS (Cumulative Layout Shift)
 * --------------------------------------------------------------------
 * Rede de seguranca para midia sem dimensoes. O reflow tardio de uma
 * imagem/iframe que carrega depois empurra o layout e gera CLS (modulo 9).
 *
 * Estrategia conservadora e nao destrutiva:
 *  - img { height:auto } SO quando o autor declarou width via atributo
 *    HTML (seletor img[width]): mantem a proporcao intrinseca e nunca
 *    distorce. NAO mexemos em img sem width (poderiam ter altura fixa
 *    proposital via CSS do projeto).
 *  - max-width:100% universal evita estouro horizontal (defensivo).
 *  - iframe/video sem dimensoes conhecidas: reservamos espaco com
 *    aspect-ratio 16/9 APENAS quando nenhuma dimensao foi declarada
 *    (sem atributo width e height), para nao sobrescrever embeds que ja
 *    trazem seu proprio tamanho. */
img {
  max-width: 100%;
}
img[width] {
  height: auto;            /* preserva proporcao quando width foi declarado */
}
iframe:not([width]):not([height]),
video:not([width]):not([height]) {
  max-width: 100%;
  aspect-ratio: 16 / 9;    /* reserva espaco e evita o salto ao carregar */
}

/* Componentes injetados pelas Waves anteriores nao podem causar shift.
 * - O skip-link (.v26-skip) e position:fixed fora da tela ate o foco, logo
 *   nao ocupa fluxo (sem CLS). Reforcamos que nunca participe do layout.
 * - O hero do fluxograma (.fluxo-svg) ja tem width:100%/height:auto e o
 *   .fluxo-stage reserva area; garantimos um piso de altura para a area do
 *   diagrama, de modo que quando o JS injeta a secao ela ja "ocupa" o espaco
 *   esperado sem reflow perceptivel (o conteudo nasce no estado final). */
.v26-skip {
  position: fixed;         /* idempotente com o bloco da Wave 2 */
}
.fluxo-stage {
  min-height: 1px;         /* ancora de containing block; nao impoe altura fixa */
}
/* O FAB "voltar ao topo" e fixed (fora do fluxo) - nunca empurra layout. */
.v26-fab { position: fixed; }

/* (W5-B) RENDER PERFORMANCE com content-visibility
 * --------------------------------------------------------------------
 * content-visibility:auto pula o render/layout de subarvores fora da tela,
 * reduzindo o custo do primeiro paint (modulo 9). PORE'M tem dois efeitos
 * colaterais conhecidos:
 *   1) quebra rolagem para ancora (#id) dentro do container pulado;
 *   2) atrapalha a busca nativa na pagina (Ctrl+F) ate o bloco entrar.
 * Por isso aplicamos de forma CONSERVADORA, so onde o risco e baixo:
 *
 *   - <footer> do site (rodape): esta sempre abaixo da dobra, nao contem
 *     ancoras de TOC e nao e alvo de Ctrl+F critico. Ganho real, risco
 *     minimo. contain-intrinsic-size generoso o suficiente para o rodape
 *     tipico, evitando CLS ao revelar (a altura reservada ~ a real).
 *
 * NAO aplicamos em .article-body, .toc, .container de conteudo nem no
 * primeiro bloco visivel: essas areas tem ancoras de sumario (#secao) e
 * sao alvo de busca; content-visibility ali quebraria navegacao por
 * ancora. Mantemos o escopo restrito ao rodape por seguranca. */
footer {
  content-visibility: auto;
  /* altura estimada do rodape para reservar espaco e nao gerar salto ao
     entrar no viewport. Valor folgado; o conteudo real fica proximo disso. */
  contain-intrinsic-size: auto 520px;
}
/* Em telas estreitas o rodape empilha e fica mais alto: reserva mais area
   para o intrinsic-size acompanhar e nao causar CLS na revelacao. */
@media (max-width: 720px) {
  footer { contain-intrinsic-size: auto 900px; }
}

/* (W5-C) Sem @font-face no projeto (fontes do sistema): nada a ajustar de
 * font-display aqui. Caso uma @font-face seja adicionada futuramente neste
 * arquivo, ela deve trazer font-display:swap para evitar FOIT. Documentado
 * no relatorio da Wave 5. */
