/**
 * ═══════════════════════════════════════════════════════
 * Calculoteca — Custom CSS
 * ═══════════════════════════════════════════════════════
 */

/* ─── Fonte Inter (self-hosted, subset latin — cobre acentos PT-BR; pesos 400/500/600/700/800 usados no CSS) ─── */
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 400; font-display: swap; src: url('../fonts/inter-400.woff2') format('woff2'); }
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 500; font-display: swap; src: url('../fonts/inter-500.woff2') format('woff2'); }
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 600; font-display: swap; src: url('../fonts/inter-600.woff2') format('woff2'); }
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 700; font-display: swap; src: url('../fonts/inter-700.woff2') format('woff2'); }
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 800; font-display: swap; src: url('../fonts/inter-800.woff2') format('woff2'); }

/* ─── Reset / Base ──────────────────────────────────── */

*, *::before, *::after {
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
    -webkit-text-size-adjust: 100%;
}

body {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* ─── Scrollbar Customizada ─────────────────────────── */
/* Mudou de casa: agora é o bloco "Barras de rolagem" do src/input.css (app.css),
   que o site E o painel carregam. Aqui a regra valia só para o site público — e,
   por vir DEPOIS do app.css no <head>, sobrepunha a versão com dark mode. */

/* ─── Hide Scrollbar (nav horizontal) ───────────────── */

.scrollbar-hide {
    -ms-overflow-style: none;
    scrollbar-width: none;
}

.scrollbar-hide::-webkit-scrollbar {
    display: none;
}

/* ─── Menus do cabeçalho: teto de altura ────────────── */
/* O <header> é `sticky top-0`: o que passa da borda de baixo da tela NÃO é
   alcançável rolando a página — o cabeçalho fica parado onde está. Em celular
   deitado (altura útil de 360 a 430px) o painel de Categorias pede 423px e o
   menu do hambúrguer, 538px: "Educação" e "Veículos" ficavam fora do quadro,
   sem gesto nenhum que chegasse até eles.

   Teto na altura da tela + rolagem DENTRO do painel resolve os dois de uma vez,
   e sem trocar o menu por outro em telas baixas — o hambúrguer estourava ainda
   mais que o dropdown. `dvh` desconta a barra do navegador do celular; o `vh`
   logo acima é a reserva para quem não entende `dvh`. Em tela alta o conteúdo
   não alcança o teto: o menu fica exatamente como sempre foi.

   Estes 5rem são o PISO (valem sem JS): supõem o cabeçalho encostado no topo.
   O app.js afina o teto com a medida real do espaço livre — o que importa quando
   a barra de avisos empurra o cabeçalho para baixo ou o aviso de cookies cobre a
   parte de baixo da tela. Ver "Menus do cabeçalho" em app.js. */

.menu-scroll {
    max-height: calc(100vh - 5rem);
    max-height: calc(100dvh - 5rem);
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* ─── Menu superior: Categorias marcado ─────────────── */
/* Com o painel de Categorias aberto, a evidência é DELE. O item da página atual
   (Início, Glossário, Sobre ou Contato) volta ao neutro enquanto isso — senão dois
   itens ficam marcados ao mesmo tempo e o realce deixa de responder "onde estou".
   Fechou o painel, o realce volta para a página atual, sem estado nenhum guardado.

   Só o CLIQUE troca o realce: quem manda aqui é a classe `.menu-marcado`, que o
   componente põe no botão quando o visitante escolhe o menu (clique/Enter) — e não o
   `aria-expanded`, que segue o painel e também sobe no mouse over. Passar o ponteiro
   por cima não é escolha, e realce piscando a cada passada do mouse é ruído.
   Navegador sem `:has()` (anterior a 2023) ignora a segunda regra e fica com dois
   itens marcados — nada quebra, só perde o requinte.

   As cores são as MESMAS das utilitárias que o PHP aplica (primary-700/primary-50 e
   gray-600), repetidas aqui em hex porque classe própria não entra no auto-dark do
   app.css — por isso cada regra tem seu par em .dark, com os valores que o remapeamento
   daria (#60a5fa, rgba(37,99,235,.16), #b6c2d4). */

header nav[aria-label="Menu principal"] button.menu-marcado {
    font-weight: 600;
    color: #1d4ed8;
    background-color: #eff6ff;
}

.dark header nav[aria-label="Menu principal"] button.menu-marcado {
    color: #60a5fa;
    background-color: rgba(37, 99, 235, .16);
}

header nav[aria-label="Menu principal"]:has(> div > button.menu-marcado) > a[aria-current="page"] {
    font-weight: 500;
    color: #4b5563;
    background-color: transparent;
}

.dark header nav[aria-label="Menu principal"]:has(> div > button.menu-marcado) > a[aria-current="page"] {
    color: #b6c2d4;
}

/* ─── Line Clamp ────────────────────────────────────── */

.line-clamp-2 {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.line-clamp-3 {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* ─── Prose (conteúdo editorial) ────────────────────── */

.prose {
    line-height: 1.75;
    color: #374151;
}

.prose h2 {
    font-size: 1.5rem;
    font-weight: 700;
    color: #111827;
    margin-top: 2rem;
    margin-bottom: 0.75rem;
    line-height: 1.3;
}

.prose h3 {
    font-size: 1.25rem;
    font-weight: 600;
    color: #1f2937;
    margin-top: 1.5rem;
    margin-bottom: 0.5rem;
    line-height: 1.4;
}

.prose p {
    margin-bottom: 1rem;
}

.prose ul, .prose ol {
    margin-bottom: 1rem;
    padding-left: 1.5rem;
}

.prose ul {
    list-style-type: disc;
}

.prose ol {
    list-style-type: decimal;
}

.prose li {
    margin-bottom: 0.375rem;
}

.prose strong {
    font-weight: 600;
    color: #111827;
}

.prose a {
    color: #2563eb;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.prose a:hover {
    color: #1d4ed8;
}

.prose blockquote {
    border-left: 4px solid #2563eb;
    padding-left: 1rem;
    margin: 1.5rem 0;
    font-style: italic;
    color: #6b7280;
}

.prose code {
    background: #f1f5f9;
    padding: 0.125rem 0.375rem;
    border-radius: 0.25rem;
    font-size: 0.875rem;
    font-family: 'Fira Code', 'Cascadia Code', monospace;
}

.prose table {
    width: 100%;
    border-collapse: collapse;
    margin: 1.5rem 0;
}

.prose th, .prose td {
    border: 1px solid #e5e7eb;
    padding: 0.625rem 0.75rem;
    text-align: left;
    font-size: 0.875rem;
}

.prose th {
    background: #f9fafb;
    font-weight: 600;
}

.prose tr:hover {
    background: #f9fafb;
}

/* ─── Animações ─────────────────────────────────────── */

@keyframes fadeIn {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}

.animate-fade-in {
    animation: fadeIn 0.3s ease-out forwards;
}

@keyframes slideUp {
    from { opacity: 0; transform: translateY(16px); }
    to   { opacity: 1; transform: translateY(0); }
}

.animate-slide-up {
    animation: slideUp 0.4s ease-out forwards;
}

@keyframes pulse-soft {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.7; }
}

.animate-pulse-soft {
    animation: pulse-soft 2s ease-in-out infinite;
}

/* ─── Focus Visible ─────────────────────────────────── */

/* Foco visível — cor ÚNICA do site (primary-600). O mesmo azul aparece como borda nos
   campos (focus:border-primary-600 nas views) e como anel aqui, em botão e link.

   SEM border-radius: focar um elemento não pode mudar a GEOMETRIA dele. A regra antiga
   forçava 4px e, num campo rounded-xl (12px), o canto quadrava no clique — lido como um
   "pisca" do destaque. Também era desnecessário: navegador atual já desenha o outline
   acompanhando o border-radius do próprio elemento. */
/* Cor do foco por tema. Variável, e NÃO um seletor `.dark *:focus-visible` — esse
   pesaria (0,2,0), empataria com o focus:outline-none do Tailwind e, como este arquivo
   carrega depois do app.css, venceria: o anel externo voltava a aparecer nos campos que
   o desligaram de propósito, e o campo ficava com contorno DUPLO (borda + anel). Com a
   variável, `*:focus-visible` continua valendo (0,1,0) e perde para o outline-none, que
   é o comportamento desejado: campo mostra só a borda. */
:root { --foco-cor: #2563eb; }
.dark { --foco-cor: #60a5fa; }   /* mesmo tom da borda no escuro (contraste 5,75:1) */

/* Anel de foco para quem NÃO tem borda própria de foco: botão, link, resumo. Quem tem
   (os campos, via focus:border-*) desliga este anel com focus:outline-none e fica só
   com o contorno interno — um indicador por elemento, nunca dois. */
*:focus-visible {
    outline: 2px solid var(--foco-cor);
    outline-offset: 2px;
}

/* ─── Inputs ────────────────────────────────────────── */

input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

input[type="number"] {
    -moz-appearance: textfield;
}

input::placeholder {
    color: #9ca3af;
}

/* ─── Print ─────────────────────────────────────────── */

@media print {
    header, footer, nav,
    .no-print,
    .adsbygoogle,
    [x-data*="cookie"] {
        display: none !important;
    }

    body {
        background: white;
        color: black;
        font-size: 12pt;
    }

    a {
        color: black;
        text-decoration: none;
    }

    a[href]::after {
        content: " (" attr(href) ")";
        font-size: 0.8em;
        color: #666;
    }
}

/* ─── Dark Mode (base — Tailwind cuida do resto) ───── */

.dark body {
    background-color: #0f172a;
    color: #e2e8f0;
}

.dark .prose {
    color: #cbd5e1;
}

.dark .prose h2,
.dark .prose h3 {
    color: #f1f5f9;
}

.dark .prose strong {
    color: #f1f5f9;
}

.dark .prose code {
    background: #1e293b;
    color: #e2e8f0;
}

.dark .prose th {
    background: #1e293b;
}

.dark .prose th,
.dark .prose td {
    border-color: #334155;
}

.dark .prose tr:hover {
    background: #243349;
}

/* ─── Utilidades ────────────────────────────────────── */

.text-balance {
    text-wrap: balance;
}

.gradient-text {
    background: linear-gradient(135deg, #2563eb, #7c3aed);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

/* ─── AdSense placeholder fix ───────────────────────── */

.adsbygoogle {
    display: block;
    min-height: 50px;
}

ins.adsbygoogle[data-ad-status="unfilled"] {
    display: none !important;
}

/* ═══════════════════════════════════════════════════════════════
   PDF Preview Modal
   ═══════════════════════════════════════════════════════════════ */
.pdf-modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.6);
    -webkit-backdrop-filter: blur(4px);   /* Safari só entende a versão prefixada até a 18 */
    backdrop-filter: blur(4px);
    z-index: 99999;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    opacity: 0;
    transition: opacity 0.2s ease;
}
.pdf-modal-overlay.is-visible { opacity: 1; }

.pdf-modal {
    background: #fff;
    border-radius: 1rem;
    box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);
    width: 100%;
    max-width: 56rem;
    max-height: 92vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    transform: scale(0.95);
    transition: transform 0.2s ease;
}
.pdf-modal-overlay.is-visible .pdf-modal { transform: scale(1); }

.pdf-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1rem 1.25rem;
    border-bottom: 1px solid #e2e8f0;
    gap: 0.75rem;
}
.pdf-modal-header h3 {
    font-size: 1rem;
    font-weight: 700;
    color: #1e293b;
    margin: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.pdf-modal-actions {
    display: flex;
    gap: 0.5rem;
    flex-shrink: 0;
}
.pdf-modal-actions button {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.5rem 1rem;
    border-radius: 0.5rem;
    font-size: 0.8125rem;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.15s ease;
    border: none;
}
.btn-pdf-download {
    background-color: #2563eb;
    color: #fff;
}
.btn-pdf-download:hover { background-color: #1d4ed8; }
.btn-pdf-close {
    background-color: #f1f5f9;
    color: #475569;
}
.btn-pdf-close:hover { background-color: #e2e8f0; }

.pdf-modal-body { flex: 1; overflow: auto; min-height: 0; }
.pdf-modal-body iframe {
    width: 100%;
    height: 70vh;
    border: none;
    display: block;
}
.pdf-fallback {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 3rem 1.5rem;
    text-align: center;
    gap: 1rem;
    min-height: 300px;
}
.pdf-fallback-icon { width: 4rem; height: 4rem; color: #2563eb; }
.pdf-fallback p { color: #64748b; font-size: 0.9375rem; margin: 0; }

/* Dark mode (classe .dark no <html>) — espelha o auto-dark dos utilitários.
   O botão "Baixar" (azul primário) e o iframe (PDF sempre branco) ficam como estão. */
.dark .pdf-modal { background: #1e293b; }
.dark .pdf-modal-header { border-bottom-color: #334155; }
.dark .pdf-modal-header h3 { color: #f1f5f9; }
.dark .btn-pdf-close { background-color: #334155; color: #cbd5e1; }
.dark .btn-pdf-close:hover { background-color: #475569; }
.dark .pdf-fallback p { color: #b6c2d4; }

@media (max-width: 640px) {
    .pdf-modal-overlay { padding: 0; align-items: flex-end; }
    .pdf-modal {
        max-height: 95vh;
        border-radius: 1rem 1rem 0 0;
        max-width: 100%;
    }
    .pdf-modal-header { flex-wrap: wrap; padding: 0.875rem 1rem; }
    .pdf-modal-header h3 { width: 100%; font-size: 0.9375rem; }
    .pdf-modal-actions { width: 100%; }
    .pdf-modal-actions button { flex: 1; justify-content: center; padding: 0.625rem 0.75rem; }
    .pdf-modal-body iframe { height: 60vh; }
}

/* ─── Not-Prose (reset prose dentro de blocos específicos) ── */

.prose .not-prose {
    line-height: normal;
}

.prose .not-prose p {
    margin-bottom: 0;
    line-height: inherit;
    color: inherit;
}

/* ─── Utilitário py-1.5 ── */
.py-1\.5 {
    padding-top: 0.375rem;
    padding-bottom: 0.375rem;
}

/* ─── Aviso na caixa amarela: alinhado à ESQUERDA ──────────────────────────
   Havia aqui uma regra `.bg-yellow-50 .text-yellow-800 { text-align: center }`.
   Ela centralizava o texto de TODOS os avisos do site — e aviso costuma ter duas
   ou três linhas, que centralizadas ficam com as bordas irregulares e mais lentas
   de ler; o padrão dos demais balões (resultado das calculadoras) sempre foi
   ícone à esquerda e texto alinhado à esquerda.

   A regra foi REMOVIDA em vez de trocada para `left`: sem ela o texto herda o
   alinhamento normal da página, e quem quiser centralizar um aviso específico
   ainda pode — basta a classe `text-center` no próprio bloco, como faz a caixa
   de destaque da calculadora de férias. Regra global sobrescrevendo utilitário
   é exatamente o que impede esse tipo de exceção. */

/* ─── Fallback justify-center ── */
.justify-center {
    justify-content: center;
}

/* ═══════════════════════════════════════════════════════
   SPRINT 1 — Horas Trabalhadas: Correções Visuais
   Data: 2025-04-10
   ═══════════════════════════════════════════════════════ */

/* ─── 1.1 Campo Data: garantir que ano não fique cortado ── */
.day-row input[type="date"] {
    min-width: 0;
    width: 100%;
    /* 1rem = 16px: o limiar exato do WebKit. Era 0.8125rem (13px), herança do layout de
       5 colunas de 2025 — e abaixo de 16px o Safari do iPhone amplia a página a cada
       campo focado, o que nesta calculadora significa a cada linha de jornada. Mais
       compacto que os 18px do .calc-field, sem cair na faixa que dispara o zoom. */
    font-size: 1rem;
    letter-spacing: -0.01em;
    padding-left: 0.5rem;
    padding-right: 0.25rem;
}

/* Webkit (Chrome/Edge/Samsung): reduzir ícone calendário */
.day-row input[type="date"]::-webkit-calendar-picker-indicator {
    width: 16px;
    height: 16px;
    margin-left: 0;
    padding: 0;
    opacity: 0.6;
}

/* Firefox: ajustar padding interno */
.day-row input[type="date"]::-moz-datetime-edit {
    padding: 0;
}
.day-row input[type="date"]::-moz-datetime-edit-fields-wrapper {
    padding: 0;
}

/* ─── 1.2 Campos Entrada/Saída: compactar no mobile ────── */
.day-row input[type="time"] {
    min-width: 0;
    width: 100%;
    font-size: 1rem;   /* mesmo motivo do campo de data acima (era 14px) */
    padding-left: 0.5rem;
    padding-right: 0.25rem;
}

.day-row input[type="time"]::-webkit-calendar-picker-indicator {
    width: 16px;
    height: 16px;
    margin-left: 0;
    padding: 0;
    opacity: 0.6;
}

/* ─── Mobile: grid 2 colunas para campos do dia ───────── */
@media (max-width: 639px) {
    .day-row .grid {
        grid-template-columns: 1fr 1fr;
        gap: 0.5rem;
    }

    /* Data ocupa linha inteira no mobile */
    .day-row .grid > div:first-child {
        grid-column: 1 / -1;
    }

    /* Tipo dia ocupa linha inteira no mobile */
    .day-row .grid > div:last-child {
        grid-column: 1 / -1;
    }

    /* Inputs menores no mobile */
    .day-row input[type="date"],
    .day-row input[type="time"],
    .day-row input[type="number"],
    .day-row select {
        padding-top: 0.625rem;
        padding-bottom: 0.625rem;
        font-size: 1rem;   /* piso do WebKit; era 13px e ampliava a página no iPhone */
    }
}

/* ─── 1.3 Balão de Alerta CLT — Estilo "Padrão Ouro" ──── */

/* Container principal dos alertas */
.clt-alerts-container {
    margin-bottom: 1.5rem;
}

.clt-alerts-container .clt-alert-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}

.clt-alerts-container .clt-alert-header h3 {
    font-size: 0.875rem;
    font-weight: 700;
    color: #92400e;
    margin: 0;
}

.clt-alerts-container .clt-alert-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.25rem;
    height: 1.25rem;
    padding: 0 0.375rem;
    background: #f59e0b;
    color: #fff;
    font-size: 0.6875rem;
    font-weight: 700;
    border-radius: 9999px;
}

/* Card individual de alerta */
.clt-alert-card {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.875rem 1rem;
    background: #fffbeb;
    border: 1px solid #fde68a;
    border-left: 4px solid #f59e0b;
    border-radius: 0.75rem;
    margin-bottom: 0.5rem;
    transition: background 0.15s ease;
}

.clt-alert-card:hover {
    background: #fef3c7;
}

.clt-alert-card:last-child {
    margin-bottom: 0;
}

/* Ícone do alerta */
.clt-alert-icon {
    flex-shrink: 0;
    width: 1.5rem;
    height: 1.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #fef3c7;
    border-radius: 50%;
    margin-top: 0.0625rem;
}

.clt-alert-icon svg,
.clt-alert-icon i {
    width: 0.875rem;
    height: 0.875rem;
    color: #d97706;
}

/* Conteúdo do alerta */
.clt-alert-body {
    flex: 1;
    min-width: 0;
}

.clt-alert-body .clt-alert-title {
    font-size: 0.8125rem;
    font-weight: 600;
    color: #92400e;
    margin: 0 0 0.125rem 0;
    line-height: 1.4;
}

.clt-alert-body .clt-alert-detail {
    font-size: 0.75rem;
    color: #a16207;
    margin: 0;
    line-height: 1.5;
}

.clt-alert-body .clt-alert-legal {
    display: inline-block;
    font-size: 0.6875rem;
    color: #b45309;
    background: #fef3c7;
    padding: 0.125rem 0.5rem;
    border-radius: 9999px;
    margin-top: 0.375rem;
    font-weight: 500;
}

/* ─── 1.4 Tabela detalhada: hover + zebra melhorados ───── */
.day-detail-table tbody tr {
    transition: background 0.1s ease;
}

.day-detail-table tbody tr:hover {
    background: #f0fdfa !important;
}

/* ─── N1: Asteriscos vermelhos garantidos ──────────────── */
.day-row .text-red-500 {
    color: #ef4444;
    font-weight: 700;
}

/* ═══════════════════════════════════════════════════════════════
   Zoom da imagem das Indicações de afiliado
   hover (mouse) → preview flutuante · toque → lightbox centralizado
   ═══════════════════════════════════════════════════════════════ */
.aff-zoom-img { cursor: zoom-in; }

/* Overlay único (criado 1x via JS). O position:fixed é também forçado inline no
   JS, à prova de qualquer conflito de containing-block/cascata. */
.aff-zoom-overlay { position: fixed; z-index: 9998; display: none; }
.aff-zoom-overlay.is-open { display: block; }

/* Caixa no MESMO estilo dos cards das calculadoras (howto): fundo branco,
   borda gray-200, cantos rounded-2xl — claro/escuro. Sombra p/ o efeito flutuante. */
.aff-zoom-box {
    position: relative;
    margin: 0;                       /* zera a margem default do <figure> */
    background: #fff;
    border: 1px solid #e5e7eb;       /* gray-200 (igual ao card) */
    border-radius: 1rem;             /* rounded-2xl (igual ao card) */
    padding: .625rem;
    box-shadow: 0 14px 40px rgba(0, 0, 0, .18);
}
/* Imagem SEMPRE em proporção natural, escalada para caber (sem cortar, sem esticar,
   sem ampliar além do tamanho original). Responsivo por limites em px/vh/vw. */
.aff-zoom-full {
    display: block;
    width: auto;
    height: auto;
    margin: 0 auto;          /* sempre centralizada no balão (mesmo se a legenda for mais larga) */
    border-radius: .625rem;
    background: #f8fafc;
}
.aff-zoom-cap {
    margin: .5rem .25rem 0;
    font-size: .8125rem;
    line-height: 1.3;
    color: #475569;                  /* gray-600, como o texto dos cards */
    text-align: center;
    overflow-wrap: anywhere;
}
.aff-zoom-plat {                     /* plataforma: mesmo tom discreto do texto no card */
    display: block;
    margin: .125rem .25rem 0;
    font-size: .75rem;
    line-height: 1.3;
    color: #9ca3af;                  /* gray-400, como a plataforma no card */
    text-align: center;
    overflow-wrap: anywhere;
}

/* PREVIEW (hover, desktop/laptop): balão que SEGUE o cursor; não bloqueia o mouse.
   width:max-content encolhe o overlay ao conteúdo (sem faixa full-width). */
.aff-zoom-overlay.is-preview {
    width: max-content;
    pointer-events: none;
    background: transparent;
}
.aff-zoom-overlay.is-preview .aff-zoom-box { min-width: 120px; }
.aff-zoom-overlay.is-preview .aff-zoom-full { max-width: 260px; max-height: 240px; }

/* MODAL (toque, mobile/tablet): backdrop + centralizado. Fecha tocando em qualquer
   lugar (ou Esc) — sem botão X. A imagem escala p/ caber em qualquer tela. */
.aff-zoom-overlay.is-modal {
    inset: 0;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    background: rgba(0, 0, 0, .72);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
}
.aff-zoom-overlay.is-modal.is-open { display: flex; }
.aff-zoom-overlay.is-modal .aff-zoom-box { max-width: min(94vw, 620px); }
.aff-zoom-overlay.is-modal .aff-zoom-full { max-width: 100%; max-height: 76vh; }

/* Dark mode — mesmo tom dos cards (slate-800 / slate-700 / slate-300) */
.dark .aff-zoom-box { background: #1e293b; border-color: #334155; }
.dark .aff-zoom-full { background: #0f172a; }
.dark .aff-zoom-cap { color: #cbd5e1; }
.dark .aff-zoom-plat { color: #94a3b8; }

/* ─── Botão "Copiar" nos cards (howto + tabelas fiscais INSS/IRRF/etc) ─── */
.copy-card { position: relative; }
.copy-card > h2:first-child,
.copy-card > h3:first-child { padding-right: 2.75rem; }  /* reserva o canto p/ o botão */
.copy-card-btn {
    position: absolute;
    top: 1rem;
    right: 1rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border-radius: 0.5rem;
    border: 1px solid #e5e7eb;
    background: #fff;
    color: #6b7280;
    cursor: pointer;
    transition: color .15s, background .15s, border-color .15s;
    z-index: 5;
}
.copy-card-btn:hover { color: #2563eb; background: #eff6ff; border-color: #bfdbfe; }
.copy-card-btn:focus-visible { outline: 2px solid #2563eb; outline-offset: 2px; }
.copy-card-btn.is-copied { color: #16a34a; background: #f0fdf4; border-color: #bbf7d0; }
.copy-card-btn svg { width: 16px; height: 16px; pointer-events: none; }

/* Dark mode (classe .dark no <html>) */
.dark .copy-card-btn { background: #1e293b; border-color: #334155; color: #94a3b8; }
.dark .copy-card-btn:hover { color: #93c5fd; background: #0f172a; border-color: #3b82f6; }
.dark .copy-card-btn.is-copied { color: #4ade80; background: #0f172a; border-color: #16a34a; }

/* ─── Cards de calculadora: ALTURA MÍNIMA p/ consistência visual (home + categorias) ──
   Fonte única do tamanho. A descrição segue cortada em 2 linhas (line-clamp) — ali o corte
   é o desenho, é um resumo. O NOME não é mais cortado: ele identifica o card, e cortá-lo
   deixa a pessoa sem saber que calculadora é aquela.

   Era `height` fixa. Virou `min-height` porque, com a fonte do navegador aumentada, o nome
   passava a ocupar 3 linhas e o line-clamp comia o final: a 125% já eram 52 dos 106 textos
   truncados (a 100% eram 18, e só descrições). Isso é perda de conteúdo por redimensionar,
   que a WCAG 1.4.4 não admite.

   A grade continua regular: os três contêineres de card são `grid`, e no grid os itens de
   uma mesma linha esticam para a altura da linha (align-items: stretch é o padrão). Ou seja,
   os cards só crescem JUNTOS, quando algum precisa — não viram uma serra. No tamanho de
   fonte padrão nada muda: medido, nenhum nome ultrapassa 2 linhas a 16px. */
.calc-card      { display: flex; flex-direction: column; min-height: 13.5rem; }   /* grade principal: ícone + nome + descrição(2) + CTA */
.calc-card-mini { display: flex; flex-direction: column; justify-content: center; min-height: 8rem; } /* "Mais Populares": ícone + nome, centralizado */

/* Solta o clamp SÓ do nome (o cabeçalho do card). Trocar para display:block tira o elemento
   do contexto -webkit-box, e sem ele o -webkit-line-clamp simplesmente não se aplica — mais
   robusto que tentar zerar a propriedade. A descrição é um <p> irmão e segue clampada.

   h2 E h3 porque o nível varia com a página, e com razão: na home o card é h3 (o h1 é o nome
   do site), na categoria é h2 (o h1 é o nome da categoria). Listado à mão em vez de :is()
   para não depender de suporte a seletor novo em navegador antigo. */
.calc-card > h2.line-clamp-2,
.calc-card > h3.line-clamp-2,
.calc-card-mini > h2.line-clamp-2,
.calc-card-mini > h3.line-clamp-2 { display: block; overflow: visible; }

/* Gap superior do card de apoio na página "Sobre" (dentro do container de conteúdo,
   cuja pb-8/sm:pb-12 já dá o inferior) — casa o ritmo da página (2rem / 3rem no sm). */
.donation-top-gap { margin-top: 2rem; }
@media (min-width: 640px) { .donation-top-gap { margin-top: 3rem; } }

/* ─── Bloco de apoio/doação ─────────────────────────────────────────
   Botão: cores vêm por style inline (escolha do admin); o hover é só esmaecimento,
   reaproveitando o fundo escolhido (sem cor de hover separada). */
.donation-btn { border-style: solid; border-width: 2px; transition: opacity .15s ease; cursor: pointer; }
.donation-btn:hover { opacity: .85; }
/* Modal do QR Code (público) — único, aberto por qualquer [data-qr-zoom] (app.js). */
.donation-qr-overlay { position: fixed; inset: 0; z-index: 9999; display: none; align-items: center; justify-content: center; padding: 1rem; background: rgba(0,0,0,.6); }
.donation-qr-overlay.is-open { display: flex; }
.donation-qr-box { position: relative; background: #fff; border-radius: 1rem; padding: 1.25rem; box-shadow: 0 25px 50px -12px rgba(0,0,0,.35); max-width: 92vw; }
.donation-qr-title { font-size: .875rem; font-weight: 600; color: #374151; text-align: center; margin-bottom: .75rem; }
.donation-qr-img { display: block; width: min(80vmin, 340px); height: min(80vmin, 340px); object-fit: contain; background: #fff; border: 1px solid #e5e7eb; border-radius: .75rem; }
.donation-qr-close { position: absolute; top: .5rem; right: .5rem; width: 2rem; height: 2rem; border: none; background: transparent; color: #9ca3af; font-size: 1.5rem; line-height: 1; cursor: pointer; border-radius: .5rem; }
.donation-qr-close:hover { background: #f3f4f6; color: #374151; }
.donation-qr-recipient { margin-top: .75rem; text-align: center; font-size: .8125rem; color: #4b5563; }

/* Acessibilidade (WCAG 2.3.3) — respeita "reduzir movimento" do sistema operacional.
   Neutraliza animações/transições para quem pede menos movimento; sem efeito nos demais. */
@media (prefers-reduced-motion: reduce) {
    *, ::before, ::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}
