/* ============================================================
   visual-2026-w2 — Segunda camada de aprimoramento (Waves 6-10)
   Curso 'Frontends com Vibecoding' · dinheirodaminhaempresa.com
   Bundle gerado por scripts/build_waves2_bundle.py — NAO editar a mao.
   ============================================================ */


/* ---- Wave 6 (css) ---- */
/* Wave 6 — Formulários acessíveis + máscaras financeiras (curso Módulo 4). dinheirodaminhaempresa.com */

/* ==========================================================================
   Wave 6 — Estilos de formulário acessível.
   - Reusa os tokens canônicos do site (--ink, --ink-2, --ink-3, --muted, --bg,
     --card, --green, --green-dark, --green-text, --green-soft, --v26-yes,
     --v26-no, --focus-ring). NUNCA redefine esses tokens; só define tokens
     internos com prefixo --ddf-* (sempre com fallback embutido).
   - Estados de erro e sucesso NUNCA dependem só de cor: vêm acompanhados de
     ícone (check / x) e de texto. Contraste mira WCAG 2.2 AA (>= 4,5:1).
   - Todo movimento respeita prefers-reduced-motion.
   - Escopo restrito a elementos com prefixo de classe .ddf- para não vazar
     estilo sobre o restante do site nem sobre as calculadoras (calc.js).
   ========================================================================== */

:root {
  /* Vermelho de erro com contraste AA sobre fundo claro (mesmo valor do --v26-no light). */
  --ddf-erro: var(--v26-no, #DC2626);
  /* Verde de sucesso com contraste AA sobre fundo claro. */
  --ddf-ok: var(--v26-yes, #047857);
  /* Cor de texto de apoio (dicas, contador). */
  --ddf-apoio: var(--ink-3, #374151);
  /* Borda neutra padrão dos campos. */
  --ddf-borda: var(--line, #D1D5DB);
  /* Anel de foco (reusa o token global que já adapta ao tema). */
  --ddf-foco: var(--focus-ring, #005C32);
  /* Halos translúcidos dos estados (derivados, não dependem de cor sólida). */
  --ddf-halo-erro: rgba(220, 38, 38, .16);
  --ddf-halo-ok: rgba(4, 120, 87, .16);
}

/* No modo escuro, ergue os tons para manter contraste e usa os valores dark
   já presentes no site para sim/não. */
[data-theme="dark"] {
  --ddf-erro: var(--v26-no, #F87171);
  --ddf-ok: var(--v26-yes, #34D399);
  --ddf-apoio: var(--ink-3, #CBD5E1);
  --ddf-borda: var(--line, #374151);
  --ddf-halo-erro: rgba(248, 113, 113, .22);
  --ddf-halo-ok: rgba(52, 211, 153, .22);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ddf-erro: var(--v26-no, #F87171);
    --ddf-ok: var(--v26-yes, #34D399);
    --ddf-apoio: var(--ink-3, #CBD5E1);
    --ddf-borda: var(--line, #374151);
    --ddf-halo-erro: rgba(248, 113, 113, .22);
    --ddf-halo-ok: rgba(52, 211, 153, .22);
  }
}

/* --------------------------------------------------------------------------
   Mensagem de erro inline (abaixo do campo).
   Renderizada pelo JS com role="alert" + aria-live. Fica oculta até existir
   conteúdo (atributo data-ddf-empty) para não criar espaço vazio anunciável.
   -------------------------------------------------------------------------- */
.ddf-erro {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  margin: 6px 0 0;
  font-size: 13.5px;
  line-height: 1.4;
  color: var(--ddf-erro);
  font-weight: 600;
}
.ddf-erro[hidden] { display: none; }
.ddf-erro .ddf-ico {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  margin-top: 1px;
  color: currentColor;
}

/* Dica de ajuda (descrição opcional do campo, ligada via aria-describedby). */
.ddf-dica {
  margin: 5px 0 0;
  font-size: 13px;
  line-height: 1.4;
  color: var(--ddf-apoio);
}

/* --------------------------------------------------------------------------
   Estados visuais do campo. Aplicados via atributo aria-invalid (erro) e via
   classe .ddf-ok (sucesso). Sempre acompanhados de ícone/texto pelo JS.
   -------------------------------------------------------------------------- */
.ddf-field[aria-invalid="true"],
.ddf-field.ddf-invalid {
  border-color: var(--ddf-erro) !important;
}
.ddf-field[aria-invalid="true"]:focus-visible,
.ddf-field.ddf-invalid:focus-visible {
  outline: 2px solid var(--ddf-erro);
  outline-offset: 1px;
  box-shadow: 0 0 0 4px var(--ddf-halo-erro);
}
.ddf-field.ddf-ok {
  border-color: var(--ddf-ok) !important;
}
.ddf-field.ddf-ok:focus-visible {
  outline: 2px solid var(--ddf-ok);
  outline-offset: 1px;
  box-shadow: 0 0 0 4px var(--ddf-halo-ok);
}

/* Foco genérico dos campos aprimorados (caso o site não dê um já).
   Apenas :focus-visible para não poluir clique de mouse. */
.ddf-field:focus-visible {
  outline: 2px solid var(--ddf-foco);
  outline-offset: 1px;
}

/* --------------------------------------------------------------------------
   Ícone de status dentro do campo (sufixo). O JS embrulha o campo numa
   .ddf-wrap relativa e posiciona um ícone à direita. Reserva de espaço evita
   que o texto digitado fique sob o ícone.
   -------------------------------------------------------------------------- */
.ddf-wrap {
  position: relative;
  display: block;
}
.ddf-wrap > .ddf-field { width: 100%; }
.ddf-status {
  position: absolute;
  top: 50%;
  right: 10px;
  transform: translateY(-50%);
  width: 18px;
  height: 18px;
  pointer-events: none;
  opacity: 0;
}
/* Quando há ícone de status, reserva o espaço à direita do campo. */
.ddf-wrap.ddf-has-status > .ddf-field { padding-right: 38px; }
.ddf-wrap.ddf-state-ok > .ddf-status { opacity: 1; color: var(--ddf-ok); }
.ddf-wrap.ddf-state-erro > .ddf-status { opacity: 1; color: var(--ddf-erro); }
.ddf-status .ddf-ico { width: 18px; height: 18px; color: currentColor; }

@media (prefers-reduced-motion: no-preference) {
  .ddf-status { transition: opacity .15s ease; }
  .ddf-field { transition: border-color .15s ease, box-shadow .15s ease; }
}

/* --------------------------------------------------------------------------
   Contador de caracteres (textarea / input com maxlength).
   Alinhado à direita, ligado ao campo via aria-describedby. Vira "alerta"
   visual ao se aproximar do limite — sempre com número, nunca só cor.
   -------------------------------------------------------------------------- */
.ddf-contador {
  display: block;
  margin: 5px 0 0;
  font-size: 12.5px;
  line-height: 1.3;
  text-align: right;
  color: var(--ddf-apoio);
  font-variant-numeric: tabular-nums;
}
.ddf-contador.ddf-perto { color: var(--ddf-erro); font-weight: 600; }

/* --------------------------------------------------------------------------
   Auto-resize de textarea. CSS nativo (field-sizing) quando suportado; o JS
   faz fallback em navegadores sem suporte. min/max em linhas evitam saltos.
   -------------------------------------------------------------------------- */
.ddf-autosize {
  field-sizing: content;
  min-height: 3lh;
  max-height: 18lh;
  overflow-y: auto;
  resize: vertical;
}

/* --------------------------------------------------------------------------
   Botão de submit em estado "enviando" (aria-busy="true").
   Spinner em CSS; respeita reduced-motion (vira pulso de opacidade).
   -------------------------------------------------------------------------- */
.ddf-btn[aria-busy="true"],
[data-ddf-enhance] button[type="submit"][aria-busy="true"],
[data-ddf-enhance] [type="submit"][aria-busy="true"] {
  position: relative;
  cursor: progress;
  opacity: .85;
}
.ddf-spinner {
  display: inline-block;
  width: 1em;
  height: 1em;
  margin-right: .5em;
  vertical-align: -0.15em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: ddf-spin .7s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .ddf-spinner {
    animation: ddf-pulse 1s ease-in-out infinite;
    border-right-color: currentColor;
  }
}
@keyframes ddf-spin { to { transform: rotate(360deg); } }
@keyframes ddf-pulse { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }

/* --------------------------------------------------------------------------
   Banner de resultado do formulário (sucesso / erro de envio).
   Renderizado pelo JS com role="status" (sucesso) ou role="alert" (erro).
   Sempre ícone + texto.
   -------------------------------------------------------------------------- */
.ddf-resultado {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 14px 0 0;
  padding: 12px 14px;
  border-radius: 10px;
  font-size: 14.5px;
  line-height: 1.45;
  border: 1px solid transparent;
}
.ddf-resultado .ddf-ico {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin-top: 1px;
}
.ddf-resultado.ddf-res-ok {
  color: var(--ddf-ok);
  background: var(--green-soft, #E6F5EE);
  border-color: var(--ddf-ok);
}
.ddf-resultado.ddf-res-erro {
  color: var(--ddf-erro);
  background: var(--ddf-halo-erro);
  border-color: var(--ddf-erro);
}
/* O texto do resultado herda a cor (já AA); negrito leve para hierarquia. */
.ddf-resultado strong { font-weight: 700; }

/* Classe utilitária para conteúdo só de leitor de tela (caso o site não tenha). */
.ddf-sr {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}


/* ---- Wave 7 (css) ---- */
/* Wave 7 — Copiar para a area de transferencia + impressao/PDF limpa (curso Modulos 5/10). dinheirodaminhaempresa.com */

/*
 * Camada puramente progressiva. NAO redefine tokens de tema (--ink, --bg,
 * --card, --green*, --pill, --focus-ring etc.) — apenas os consome. Define
 * somente tokens proprios com prefixo --ddu-*. Todo o CSS visivel usa o
 * prefixo de classe ddu-. Zero impacto se o JS da Wave 7 nao rodar.
 *
 * Estrutura:
 *   1) Tokens proprios (--ddu-*)
 *   2) Botao "Copiar" generico (codigo / prompt / tabela)
 *   3) Posicionamento por contexto (bloco de codigo, prompt, tabela)
 *   4) Botao "Imprimir / salvar em PDF" ao final de artigos
 *   5) Cabecalho de marca para impressao (.ddu-print-brand)
 *   6) Folha de impressao / PDF limpa (@media print) — site-wide
 *   7) Respeito a prefers-reduced-motion
 */

/* ============================================================
   1) Tokens proprios da Wave 7
   ============================================================ */
:root{
  --ddu-btn-bg: var(--card,#fff);
  --ddu-btn-ink: var(--ink-2,#1F2937);
  --ddu-btn-line: var(--line-2,#CBD5E1);
  --ddu-btn-bg-hover: var(--pill,#F1F5F1);
  --ddu-ok-ink: var(--green-text,#005C32);
  --ddu-ok-line: var(--green,#00A868);
  --ddu-radius: var(--r-sm,8px);
}

/* No escuro, derivamos uma superficie levemente elevada para o botao. */
[data-theme="dark"]{
  --ddu-btn-bg: rgba(255,255,255,.06);
  --ddu-btn-ink: var(--ink-2,#E5E7EB);
  --ddu-btn-line: var(--line-2,#3A4658);
  --ddu-btn-bg-hover: rgba(255,255,255,.12);
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --ddu-btn-bg: rgba(255,255,255,.06);
    --ddu-btn-ink: var(--ink-2,#E5E7EB);
    --ddu-btn-line: var(--line-2,#3A4658);
    --ddu-btn-bg-hover: rgba(255,255,255,.12);
  }
}

/* ============================================================
   2) Botao "Copiar" generico
   ============================================================
   Usado para "Copiar codigo", "Copiar prompt" e "Copiar tabela".
   Alvo de toque >= 28px (acima do minimo 24px da WCAG 2.2 AA).
   Contraste AA garantido pelos tokens de texto/superficie. */
.ddu-copy{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:6px;
  min-height:28px;
  padding:5px 10px;
  font-family:inherit;
  font-size:12.5px;
  font-weight:700;
  line-height:1.2;
  color:var(--ddu-btn-ink);
  background:var(--ddu-btn-bg);
  border:1px solid var(--ddu-btn-line);
  border-radius:var(--ddu-radius);
  cursor:pointer;
  white-space:nowrap;
  -webkit-user-select:none;
  user-select:none;
  transition:background-color .15s ease,color .15s ease,border-color .15s ease;
}
.ddu-copy:hover{
  background:var(--ddu-btn-bg-hover);
  color:var(--ink,#0F172A);
}
[data-theme="dark"] .ddu-copy:hover{ color:var(--ink,#F8FAFC); }
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .ddu-copy:hover{ color:var(--ink,#F8FAFC); }
}

/* Foco visivel AA — nao dependemos do reset global. */
.ddu-copy:focus-visible{
  outline:2px solid var(--focus-ring,#005C32);
  outline-offset:2px;
}

/* Icone do botao: tamanho consistente, herda a cor do texto (currentColor). */
.ddu-copy svg{
  width:15px;
  height:15px;
  flex:0 0 auto;
  display:block;
  fill:none;
  stroke:currentColor;
  stroke-width:2;
  stroke-linecap:round;
  stroke-linejoin:round;
}

/* Estado "Copiado!": feedback NUNCA so por cor — ha tambem o icone de check
   e a troca de texto. A cor verde reforca, mas nao e o unico sinal. */
.ddu-copy.ddu-done{
  color:var(--ddu-ok-ink);
  border-color:var(--ddu-ok-line);
}
[data-theme="dark"] .ddu-copy.ddu-done{
  color:var(--green,#3DDC97);
  border-color:var(--green,#00A868);
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .ddu-copy.ddu-done{
    color:var(--green,#3DDC97);
    border-color:var(--green,#00A868);
  }
}

/* Estado de falha: borda/texto neutros + texto "Falha ao copiar" (no JS). */
.ddu-copy.ddu-fail{
  color:var(--ink,#0F172A);
  border-color:var(--ddu-btn-line);
}
[data-theme="dark"] .ddu-copy.ddu-fail{ color:var(--ink,#F8FAFC); }
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .ddu-copy.ddu-fail{ color:var(--ink,#F8FAFC); }
}

/* ============================================================
   3) Posicionamento por contexto
   ============================================================ */

/* (a) Bloco de codigo — wrapper relativo criado pelo JS ao redor do <pre>.
   O botao flutua no canto superior direito sem cobrir o conteudo. */
.ddu-pre-wrap{
  position:relative;
}
.ddu-pre-wrap > .ddu-copy{
  position:absolute;
  top:8px;
  right:8px;
  z-index:2;
  /* Levemente translucido para nao competir com o codigo; opaco no hover/foco. */
  opacity:.85;
}
.ddu-pre-wrap > .ddu-copy:hover,
.ddu-pre-wrap > .ddu-copy:focus-visible,
.ddu-pre-wrap > .ddu-copy.ddu-done,
.ddu-pre-wrap > .ddu-copy.ddu-fail{
  opacity:1;
}
/* Garante espaco no topo do <pre> para o botao nao colar no texto. */
.ddu-pre-wrap > pre{
  padding-top:max(2.6em, 1em);
}

/* (b) Prompt — botao alinhado a direita, logo acima do bloco de prompt. */
.ddu-prompt-bar{
  display:flex;
  justify-content:flex-end;
  margin:0 0 6px;
}

/* (c) Tabela — barra discreta acima da tabela, alinhada a direita. */
.ddu-table-bar{
  display:flex;
  justify-content:flex-end;
  align-items:center;
  margin:0 0 8px;
}

/* ============================================================
   4) Botao "Imprimir / salvar em PDF" ao final de artigos
   ============================================================ */
.ddu-print{
  display:inline-flex;
  align-items:center;
  gap:8px;
  min-height:40px;
  margin:28px 0 4px;
  padding:9px 16px;
  font-family:inherit;
  font-size:14px;
  font-weight:700;
  line-height:1.2;
  color:var(--ddu-btn-ink);
  background:var(--ddu-btn-bg);
  border:1px solid var(--ddu-btn-line);
  border-radius:var(--ddu-radius);
  cursor:pointer;
  transition:background-color .15s ease,color .15s ease;
}
.ddu-print:hover{
  background:var(--ddu-btn-bg-hover);
  color:var(--ink,#0F172A);
}
[data-theme="dark"] .ddu-print:hover{ color:var(--ink,#F8FAFC); }
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .ddu-print:hover{ color:var(--ink,#F8FAFC); }
}
.ddu-print:focus-visible{
  outline:2px solid var(--focus-ring,#005C32);
  outline-offset:2px;
}
.ddu-print svg{
  width:17px;
  height:17px;
  flex:0 0 auto;
  fill:none;
  stroke:currentColor;
  stroke-width:2;
  stroke-linecap:round;
  stroke-linejoin:round;
}

/* ============================================================
   5) Cabecalho de marca para impressao
   ============================================================
   Inserido pelo JS no inicio do artigo. Fica OCULTO na tela e so
   aparece em @media print (regra na secao 6). */
.ddu-print-brand{
  display:none;
}

/* ============================================================
   6) Folha de impressao / PDF limpa — site-wide
   ============================================================ */
@media print{

  /* --- 6.1 Ocultar tudo que e "interface" e nao conteudo --- */
  header, .hdr, nav, .nav, .botnav,
  .drawer, .mega, .mega-panel, .v26-grp-panel,
  .reading-progress, .btt-fab, .v26-fab,
  .share-bar, .calc-share, .toc, .paginator,
  .ddu-copy, .ddu-print, .ddu-prompt-bar, .ddu-table-bar,
  #drawer, #v26-sprite,
  .cookie, .cookie-banner, .consent, [data-consent],
  .ddp-banner, .ddp-install, .ddp-update,
  .no-print, [data-no-print],
  [role="dialog"], [aria-modal="true"]{
    display:none !important;
  }

  /* --- 6.2 Tipografia para papel: tinta escura sobre branco --- */
  html, body{
    background:#fff !important;
    color:#111 !important;
    font-size:12pt;
    line-height:1.5;
  }
  body *{
    color:#111 !important;
    background:transparent !important;
    box-shadow:none !important;
    text-shadow:none !important;
  }

  /* --- 6.3 Conteudo principal ocupa 100% da largura (sem grids/sidebars) --- */
  main, #main, .article-wrap, .article-body, .container,
  article, .content, .prose{
    display:block !important;
    width:100% !important;
    max-width:100% !important;
    margin:0 !important;
    padding:0 !important;
    float:none !important;
    grid-template-columns:1fr !important;
  }
  aside, .sidebar, .toc, .related, .article-aside{
    display:none !important;
  }

  /* --- 6.4 Links de conteudo mostram a URL entre parenteses --- */
  /* Apenas para links de conteudo com http(s); ancoras internas (#) e
     itens de navegacao ja foram ocultados em 6.1. */
  .article-body a[href^="http"]::after,
  article a[href^="http"]::after,
  .prose a[href^="http"]::after,
  .content a[href^="http"]::after{
    content:" (" attr(href) ")";
    font-size:9pt;
    color:#555 !important;
    word-break:break-all;
  }
  /* Nunca anexar URL a ancoras internas nem a links ja sem http. */
  a[href^="#"]::after,
  a[href^="/"]::after,
  a[href^="mailto:"]::after,
  a[href^="tel:"]::after{
    content:"" !important;
  }
  a{ text-decoration:underline; }

  /* --- 6.5 Quebra de pagina inteligente --- */
  figure, table, pre, blockquote,
  .callout, .ddu-pre-wrap, .card, img{
    break-inside:avoid;
    page-break-inside:avoid;
  }
  h1, h2, h3, h4{
    break-after:avoid;
    page-break-after:avoid;
  }
  p, li{
    orphans:3;
    widows:3;
  }

  /* --- 6.6 Cabecalho de marca discreto no topo do conteudo impresso --- */
  .ddu-print-brand{
    display:block !important;
    margin:0 0 16px;
    padding:0 0 8px;
    border-bottom:1px solid #ccc;
  }
  .ddu-print-brand .ddu-pb-title{
    display:block;
    font-size:14pt;
    font-weight:700;
    color:#111 !important;
    margin:0 0 2px;
  }
  .ddu-print-brand .ddu-pb-site{
    display:block;
    font-size:9.5pt;
    color:#555 !important;
  }

  /* --- 6.7 Imagens nao estouram a pagina --- */
  img{ max-width:100% !important; height:auto !important; }

  /* --- 6.8 Limpeza de posicionamento fixo/sticky (nao "viaja" no papel) --- */
  *{
    position:static !important;
  }
}

/* ============================================================
   7) Respeito a prefers-reduced-motion
   ============================================================ */
@media (prefers-reduced-motion:reduce){
  .ddu-copy,
  .ddu-print{
    transition:none;
  }
}


/* ---- Wave 8 (css) ---- */
/* Wave 8 — Leitura longa: progresso + índice (TOC) + scroll-spy (curso Módulos 6/8). dinheirodaminhaempresa.com */

/* ==========================================================================
   Wave 8 — Experiência de leitura longa.
   - Barra de progresso de leitura (decorativa, aria-hidden) fixa no topo.
   - Índice (TOC) automático a partir dos H2/H3 do artigo: coluna sticky no
     desktop largo, <details> recolhível no mobile/estreito.
   - Scroll-spy via IntersectionObserver marca a seção atual (aria-current).
   - Selo discreto de tempo estimado de leitura quando ainda não houver um.

   Reusa SOMENTE os tokens canônicos do site (--ink, --ink-2, --ink-3, --muted,
   --bg, --card, --green, --green-dark, --green-text, --green-soft, --stone-green,
   --stone-green-deep, --stone-lime, --line, --line-2, --pill, --focus-ring).
   NUNCA redefine esses tokens; tokens internos usam o prefixo --ddr-* com
   fallback embutido para nunca depender da ordem de carregamento.

   Escopo isolado pelo prefixo de classe/ID .ddr- / #ddr- para não colidir com
   nada existente (inclusive com a camada legada .reading-progress/.toc-sticky).
   Todo movimento respeita prefers-reduced-motion. Contraste mira WCAG 2.2 AA.
   ========================================================================== */

:root {
  /* Altura visual da barra de progresso. */
  --ddr-bar-h: 3px;
  /* Distância do topo para o cabeçalho-alvo não ficar sob o header fixo (.hdr). */
  --ddr-offset: 88px;
  /* Cor de texto de apoio do índice (links inativos). */
  --ddr-link: var(--ink-4, #475569);
  /* Cor do link/seção ativa — token que já adapta ao tema. */
  --ddr-ativo: var(--green-text, #005C32);
  /* Trilho/borda do índice. */
  --ddr-trilho: var(--line, #E2E8F0);
  /* Anel de foco (reusa o token global que adapta ao tema). */
  --ddr-foco: var(--focus-ring, #005C32);
}

/* No modo escuro, eleva o contraste dos links inativos do índice. */
[data-theme="dark"] {
  --ddr-link: var(--ink-3, #CBD5E1);
  --ddr-trilho: var(--line, #334155);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ddr-link: var(--ink-3, #CBD5E1);
    --ddr-trilho: var(--line, #334155);
  }
}

/* --------------------------------------------------------------------------
   Cabeçalhos do artigo: respiro sob o header fixo ao navegar por âncora.
   O JS só adiciona a classe .ddr-on no <html> quando a Wave 8 entra em ação,
   evitando aplicar scroll-margin em páginas onde o índice não foi montado.
   -------------------------------------------------------------------------- */
.ddr-on :where(.article-body, article, main .prose, #main) :where(h2, h3)[id] {
  scroll-margin-top: calc(var(--ddr-offset) + 12px);
}

/* --------------------------------------------------------------------------
   1) Barra de progresso de leitura.
   Puramente decorativa (o JS marca aria-hidden="true"). Fixa no topo, acima
   do header. A largura do preenchimento é definida pelo JS via --ddr-pct.
   -------------------------------------------------------------------------- */
#ddr-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: var(--ddr-bar-h);
  z-index: 110; /* acima do header sticky .hdr (z-index:50) */
  background: transparent;
  pointer-events: none;
  opacity: 0;
}
#ddr-progress.ddr-visivel { opacity: 1; }
#ddr-progress > .ddr-progress-fill {
  display: block;
  height: 100%;
  width: var(--ddr-pct, 0%);
  background: linear-gradient(
    90deg,
    var(--stone-green-deep, #00461E) 0%,
    var(--stone-green, #00D700) 60%,
    var(--stone-lime, #A5FA00) 100%
  );
  will-change: width;
}
/* Transições só quando o usuário não pediu menos movimento. */
@media (prefers-reduced-motion: no-preference) {
  #ddr-progress { transition: opacity .25s ease; }
  #ddr-progress > .ddr-progress-fill { transition: width .12s linear; }
}

/* --------------------------------------------------------------------------
   Base comum dos links do índice (desktop e mobile).
   -------------------------------------------------------------------------- */
.ddr-toc a {
  display: block;
  color: var(--ddr-link);
  line-height: 1.4;
  text-decoration: none;
  border-radius: 6px;
}
.ddr-toc a:hover { color: var(--ddr-ativo); }
.ddr-toc a:focus-visible {
  outline: 2px solid var(--ddr-foco);
  outline-offset: 2px;
}
/* Seção atual: realce por cor + peso + barra lateral (nunca só cor). */
.ddr-toc a[aria-current="true"] {
  color: var(--ddr-ativo);
  font-weight: 700;
}

/* --------------------------------------------------------------------------
   2a) Índice sticky lateral (desktop largo, >=1200px).
   Posicionado pelo JS como elemento fixo à direita, ocupando a calha livre.
   -------------------------------------------------------------------------- */
#ddr-toc-side {
  position: fixed;
  top: calc(var(--ddr-offset) + 16px);
  right: max(16px, calc((100vw - var(--ddr-conteudo, 760px)) / 2 - 232px));
  width: 216px;
  max-height: calc(100vh - var(--ddr-offset) - 48px);
  overflow-y: auto;
  z-index: 30;
  padding: 4px 2px 4px 0;
  font-size: 13.5px;
  /* Esconde até o JS confirmar que cabe na tela; vira visível com .ddr-pronto. */
  display: none;
}
#ddr-toc-side.ddr-pronto { display: block; }
#ddr-toc-side .ddr-toc-titulo {
  margin: 0 0 10px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--muted, #64748B);
}
#ddr-toc-side ul {
  list-style: none;
  margin: 0;
  padding: 0;
  border-left: 2px solid var(--ddr-trilho);
}
#ddr-toc-side li { margin: 0; }
#ddr-toc-side li.ddr-l3 a { padding-left: 24px; }
#ddr-toc-side a {
  padding: 6px 12px;
  border-left: 2px solid transparent;
  margin-left: -2px;
  font-size: 13.5px;
}
#ddr-toc-side a[aria-current="true"] {
  border-left-color: var(--stone-green, #00D700);
}
@media (prefers-reduced-motion: no-preference) {
  #ddr-toc-side a { transition: color .15s ease, border-color .15s ease; }
}

/* --------------------------------------------------------------------------
   2b) Índice recolhível inline (mobile/estreito, ou fallback do desktop quando
   a calha lateral não couber). Renderizado como <details class="ddr-toc-inline">.
   -------------------------------------------------------------------------- */
.ddr-toc-inline {
  margin: 18px 0 26px;
  background: var(--card, #fff);
  border: 1px solid var(--line, #E2E8F0);
  border-radius: 10px;
  padding: 0;
}
.ddr-toc-inline > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 12px 16px;
  font-weight: 700;
  font-size: 14px;
  color: var(--ink, #0F172A);
}
.ddr-toc-inline > summary::-webkit-details-marker { display: none; }
.ddr-toc-inline > summary::marker { content: ""; }
.ddr-toc-inline > summary .ddr-cont {
  color: var(--muted, #64748B);
  font-weight: 500;
  font-size: 12px;
  letter-spacing: .02em;
}
/* Indicador de aberto/fechado (sinal +/−), além do estado nativo do <details>. */
.ddr-toc-inline > summary .ddr-sinal {
  flex: 0 0 auto;
  width: 20px;
  text-align: center;
  font-size: 18px;
  font-weight: 300;
  color: var(--muted, #64748B);
}
.ddr-toc-inline > summary .ddr-sinal::before { content: "+"; }
.ddr-toc-inline[open] > summary .ddr-sinal::before { content: "\2212"; }
.ddr-toc-inline ul {
  list-style: none;
  margin: 0;
  padding: 6px 16px 14px;
  border-top: 1px solid var(--line, #E2E8F0);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.ddr-toc-inline li { margin: 0; }
.ddr-toc-inline li.ddr-l3 a { padding-left: 18px; }
.ddr-toc-inline a {
  padding: 7px 6px;
  font-size: 13.5px;
}
.ddr-toc-inline a:hover { background: var(--green-soft, #E6F5EE); }
.ddr-toc-inline a[aria-current="true"] { background: var(--green-soft, #E6F5EE); }

/* --------------------------------------------------------------------------
   3) Selo discreto de tempo estimado de leitura, inserido perto do título
   apenas quando a página ainda não exibe essa informação.
   -------------------------------------------------------------------------- */
.ddr-tempo {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 8px 0 4px;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--pill, #F1F5F1);
  color: var(--ink-3, #374151);
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: .01em;
}
.ddr-tempo svg {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  color: var(--green-text, #005C32);
}

/* Conteúdo só para leitor de tela (caso o site não exponha um utilitário). */
.ddr-sr {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* A calha lateral só existe em telas largas; abaixo disso usamos o inline. */
@media (max-width: 1199.98px) {
  #ddr-toc-side { display: none !important; }
}


/* ---- Wave 9 (css) ---- */
/* Wave 9 — Descoberta: "Leia também" + JSON-LD condicional (curso Módulo 9). dinheirodaminhaempresa.com */

/*
 * Esta folha NÃO redefine tokens de tema. Ela apenas CONSOME as variáveis
 * canônicas já declaradas em styles.css / visual-2026.css:
 *   --ink, --ink-2, --ink-3, --muted, --bg, --card, --line, --line-2,
 *   --green, --green-dark, --green-text, --green-soft, --pill, --focus-ring,
 *   --stone-green, --stone-lime.
 * O dark mode é herdado automaticamente porque os tokens acima já adaptam
 * via [data-theme="dark"] E @media (prefers-color-scheme: dark)
 * com :root:not([data-theme="light"]). Nada a fazer aqui além de usar
 * as variáveis — assim claro e escuro ficam corretos sem código duplicado.
 *
 * Acessibilidade (WCAG 2.2 AA):
 *   - texto sobre superfície usa --ink / --ink-2 (contraste folgado);
 *   - metadados usam --muted (já calibrado para AA nos dois temas);
 *   - foco visível com anel de 2px usando --focus-ring;
 *   - cada card é um <a> com rótulo descritivo (sem "clique aqui");
 *   - alvos de toque com altura confortável.
 */

/* ----------------------------------------------------------------------------
 * Bloco "Leia também" — contêiner
 * -------------------------------------------------------------------------- */
.ddl-related{
  margin:48px 0 8px;
  padding:24px;
  border:1px solid var(--line, #E2E8F0);
  border-radius:16px;
  background:var(--card, #FFFFFF);
}

/* Cabeçalho do bloco */
.ddl-related__head{
  display:flex;
  align-items:center;
  gap:10px;
  margin:0 0 4px;
}
.ddl-related__title{
  margin:0;
  font-size:clamp(18px,2vw,22px);
  line-height:1.2;
  font-weight:800;
  letter-spacing:-.01em;
  color:var(--ink, #0F172A);
}
/* Ícone do título (sprite #v26-compass) */
.ddl-related__head-ico{
  width:22px;
  height:22px;
  flex:0 0 auto;
  color:var(--green-text, #005C32);
}
.ddl-related__sub{
  margin:0 0 16px;
  font-size:14px;
  line-height:1.5;
  color:var(--muted, #64748B);
}

/* Grade de cards — responsiva, sem overflow horizontal */
.ddl-related__grid{
  display:grid;
  gap:12px;
  grid-template-columns:1fr;
}
@media(min-width:640px){
  .ddl-related__grid{ grid-template-columns:repeat(2,minmax(0,1fr)); }
}
@media(min-width:1024px){
  .ddl-related__grid{ grid-template-columns:repeat(3,minmax(0,1fr)); }
}

/* Card-link: o <a> inteiro é clicável e focável */
.ddl-related__card{
  display:flex;
  align-items:flex-start;
  gap:12px;
  min-width:0;                 /* evita estouro do texto dentro do grid */
  padding:14px 16px;
  border:1px solid var(--line, #E2E8F0);
  border-radius:12px;
  background:var(--bg, #FAFAF7);
  text-decoration:none;
  color:var(--ink, #0F172A);
  transition:border-color .15s ease, background-color .15s ease, transform .15s ease;
}
.ddl-related__card:hover{
  border-color:var(--green, #00A868);
  background:var(--green-soft, #E6F5EE);
}
.ddl-related__card:focus-visible{
  outline:2px solid var(--focus-ring, #005C32);
  outline-offset:2px;
}

/* Ícone do card (sprite #v26-arrow-right / #v26-book) */
.ddl-related__card-ico{
  width:18px;
  height:18px;
  flex:0 0 auto;
  margin-top:2px;
  color:var(--green-text, #005C32);
}
.ddl-related__card-body{ min-width:0; }   /* permite o title quebrar/elipsar */
.ddl-related__card-title{
  display:block;
  font-size:15px;
  line-height:1.35;
  font-weight:600;
  color:var(--ink, #0F172A);
}
/* Migalha de contexto (hub) — discreta */
.ddl-related__card-hub{
  display:block;
  margin-top:3px;
  font-size:12.5px;
  line-height:1.4;
  color:var(--muted, #64748B);
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}

/* ----------------------------------------------------------------------------
 * Selo de frescor — "Última atualização"
 * -------------------------------------------------------------------------- */
.ddl-freshness{
  display:inline-flex;
  align-items:center;
  gap:7px;
  margin:12px 0 0;
  padding:5px 12px;
  border:1px solid var(--line, #E2E8F0);
  border-radius:999px;
  background:var(--pill, #F1F5F1);
  font-size:13px;
  line-height:1.2;
  color:var(--ink-3, #374151);
  white-space:nowrap;
}
.ddl-freshness__ico{
  width:15px;
  height:15px;
  flex:0 0 auto;
  color:var(--green-text, #005C32);
}
.ddl-freshness time{ font-weight:600; color:var(--ink-2, #1F2937); }

/* ----------------------------------------------------------------------------
 * Movimento — respeita prefers-reduced-motion
 * -------------------------------------------------------------------------- */
@media(prefers-reduced-motion:no-preference){
  .ddl-related__card:hover{ transform:translateY(-1px); }
}
@media(prefers-reduced-motion:reduce){
  .ddl-related__card{ transition:none; }
  .ddl-related__card:hover{ transform:none; }
}


/* ---- Wave 10 (css) ---- */
/* Wave 10 — Performance e PWA: lazy-load + skeletons + service worker offline (curso Módulos 8/10). dinheirodaminhaempresa.com */

/*
 * Camada puramente progressiva. NÃO redefine tokens de tema (--ink, --bg,
 * --card, --green*, --pill etc.) — apenas os consome. Tudo aqui é aditivo,
 * com prefixo ddp- para isolamento. Zero impacto se o JS da Wave 10 não rodar.
 */

/* ============================================================
   1) Fade-in de imagens / iframes ao terminar o carregamento
   ============================================================
   A classe .ddp-fade é aplicada pelo w10.js a <img>/<iframe> com
   loading="lazy". Enquanto não carregam ficam levemente transparentes;
   ao disparar o evento load (classe .ddp-loaded), surgem suavemente.
   Importante: o estado padrão (sem .ddp-fade) é opacidade total, de modo
   que se o JS falhar nada some — a imagem aparece normalmente. */
.ddp-fade{
  opacity:0;
  transition:opacity .45s ease;
  will-change:opacity;
}
.ddp-fade.ddp-loaded{
  opacity:1;
}

/* ============================================================
   2) Skeleton / shimmer utilitário (.ddp-skeleton)
   ============================================================
   Placeholder de carregamento com gradiente animado. Usa cores de
   superfície derivadas dos tokens de tema, então adapta a dark/light
   automaticamente. Contraste não é requisito (é decorativo, sem texto),
   mas mantemos tons sóbrios e aria-hidden via marcação. */
.ddp-skeleton{
  position:relative;
  overflow:hidden;
  background:var(--pill,#F1F5F1);
  border-radius:var(--r-sm,8px);
  /* Evita que conteúdo real fique visível por baixo durante o shimmer */
  color:transparent;
}
.ddp-skeleton::after{
  content:"";
  position:absolute;
  inset:0;
  transform:translateX(-100%);
  background-image:linear-gradient(
    90deg,
    rgba(255,255,255,0) 0%,
    rgba(255,255,255,.55) 50%,
    rgba(255,255,255,0) 100%
  );
  animation:ddp-shimmer 1.35s ease-in-out infinite;
}

/* No escuro o brilho branco fica forte demais — suaviza a faixa. */
[data-theme="dark"] .ddp-skeleton::after{
  background-image:linear-gradient(
    90deg,
    rgba(255,255,255,0) 0%,
    rgba(255,255,255,.10) 50%,
    rgba(255,255,255,0) 100%
  );
}
@media(prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .ddp-skeleton::after{
    background-image:linear-gradient(
      90deg,
      rgba(255,255,255,0) 0%,
      rgba(255,255,255,.10) 50%,
      rgba(255,255,255,0) 100%
    );
  }
}

@keyframes ddp-shimmer{
  100%{transform:translateX(100%);}
}

/* Placeholder de imagem: shimmer leve enquanto a imagem lazy carrega.
   Aplicado pelo JS APENAS quando a imagem tem dimensão/aspect-ratio
   conhecida, para nunca causar layout shift (CLS). */
.ddp-img-skeleton{
  background:var(--pill,#F1F5F1);
  position:relative;
  overflow:hidden;
}
.ddp-img-skeleton::after{
  content:"";
  position:absolute;
  inset:0;
  transform:translateX(-100%);
  background-image:linear-gradient(
    90deg,
    rgba(255,255,255,0) 0%,
    rgba(255,255,255,.45) 50%,
    rgba(255,255,255,0) 100%
  );
  animation:ddp-shimmer 1.35s ease-in-out infinite;
  pointer-events:none;
}
[data-theme="dark"] .ddp-img-skeleton::after{
  background-image:linear-gradient(90deg,rgba(255,255,255,0) 0%,rgba(255,255,255,.10) 50%,rgba(255,255,255,0) 100%);
}
@media(prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .ddp-img-skeleton::after{
    background-image:linear-gradient(90deg,rgba(255,255,255,0) 0%,rgba(255,255,255,.10) 50%,rgba(255,255,255,0) 100%);
  }
}

/* ============================================================
   3) content-visibility para seções longas abaixo da dobra
   ============================================================
   Classe OPCIONAL aplicada com critério pelo w10.js a candidatos seguros
   (seções longas no fim da página). contain-intrinsic-size reserva altura
   estimada para evitar saltos de barra de rolagem. */
.ddp-cv{
  content-visibility:auto;
  contain-intrinsic-size:auto 600px;
}

/* ============================================================
   4) Banner de atualização do Service Worker (#ddp-update)
   ============================================================
   Aviso discreto, acessível, dispensável. Contraste AA garantido
   reutilizando tokens de texto/superfície. */
.ddp-banner{
  position:fixed;
  left:50%;
  bottom:18px;
  transform:translateX(-50%) translateY(8px);
  z-index:9000;
  max-width:min(560px,calc(100vw - 32px));
  display:flex;
  align-items:center;
  gap:12px;
  padding:12px 14px;
  background:var(--card,#fff);
  color:var(--ink,#0F172A);
  border:1px solid var(--line-2,#CBD5E1);
  border-left:4px solid var(--green,#00A868);
  border-radius:var(--r-md,12px);
  box-shadow:var(--shadow-lg,0 12px 32px rgba(15,23,42,.18));
  opacity:0;
  visibility:hidden;
  transition:opacity .25s ease,transform .25s ease,visibility .25s;
  font-size:14px;
  line-height:1.45;
}
.ddp-banner.ddp-show{
  opacity:1;
  visibility:visible;
  transform:translateX(-50%) translateY(0);
}
.ddp-banner__text{
  flex:1 1 auto;
  min-width:0;
  color:var(--ink-2,#1F2937);
}
.ddp-banner__actions{
  flex:0 0 auto;
  display:flex;
  align-items:center;
  gap:6px;
}
.ddp-banner__btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  min-height:38px;
  padding:8px 14px;
  border-radius:var(--r-sm,8px);
  font-weight:700;
  font-size:13.5px;
  background:var(--green,#00A868);
  color:#fff;
  border:1px solid transparent;
  white-space:nowrap;
  cursor:pointer;
}
.ddp-banner__btn:hover{
  background:var(--green-dark,#008550);
  text-decoration:none;
}
.ddp-banner__dismiss{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:38px;
  height:38px;
  border-radius:var(--r-sm,8px);
  color:var(--ink-3,#374151);
  background:transparent;
  border:1px solid var(--line,#E2E8F0);
  font-size:18px;
  line-height:1;
  cursor:pointer;
}
.ddp-banner__dismiss:hover{
  background:var(--pill,#F1F5F1);
  color:var(--ink,#0F172A);
}

/* Foco visível AA nos controles dos banners (não dependemos do reset global). */
.ddp-banner__btn:focus-visible,
.ddp-banner__dismiss:focus-visible{
  outline:2px solid var(--focus-ring,#005C32);
  outline-offset:2px;
}

/* ============================================================
   5) Botão discreto de instalação A2HS (#ddp-install)
   ============================================================
   Reutiliza o visual do banner, ancorado à esquerda para não competir
   com o aviso de atualização. */
.ddp-install{
  position:fixed;
  left:18px;
  bottom:18px;
  z-index:8990;
  max-width:min(380px,calc(100vw - 36px));
}
@media(max-width:560px){
  /* Em telas pequenas, empilha: instalação acima do rodapé, largura cheia. */
  .ddp-install{left:16px;right:16px;max-width:none;}
}

/* ============================================================
   6) Respeito a prefers-reduced-motion
   ============================================================
   Sem shimmer animado nem fade: placeholders viram estáticos e as
   imagens aparecem sem transição. Os banners surgem sem deslocamento. */
@media(prefers-reduced-motion:reduce){
  .ddp-skeleton::after,
  .ddp-img-skeleton::after{
    animation:none;
    /* placeholder estático: faixa sutil fixa, sem movimento */
    transform:none;
    background-image:none;
  }
  .ddp-fade{
    opacity:1;
    transition:none;
  }
  .ddp-banner{
    transition:opacity .01s linear;
    transform:translateX(-50%);
  }
  .ddp-banner.ddp-show{
    transform:translateX(-50%);
  }
}
