/* ═══════════════════════════════════════════════════════════════════════════
   or-a11y.css — Módulo de ACESSIBILIDADE do site público (MÓDULO PORTÁVEL OneRank).
   Emitido INCONDICIONALMENTE (skip-link e foco visível são estruturais, não recurso
   opcional) — carregado DEPOIS do custom.css e do or-dark.css (a ordem é load-bearing:
   ver header.php). Aplicável a qualquer site de qualquer cliente, nos 4 modos de chrome.

   Seções deste arquivo (crescem por fase — ver docs/acessibilidade.md):
     F0 — Skip-link + foco visível global (SEMPRE ativos, sem gate de atributo)
     F1 — Camada de pilha de FABs (layout mora inline em fab-stack.php; aqui só o skin)
     F2 — Widget: FAB + painel + os 9 controles (data-or-fs/ts/hc/lk/rm/cu)
     F3 — Erro inline persistente de formulário (or-form.js)
     F5/F6 — Carrossel + prefers-reduced-motion
   ═══════════════════════════════════════════════════════════════════════════ */

/* ═══════════════ F3 — Erro inline de formulário (or-form.js) ═══════════════
   Inserido pelo or-form.js junto de aria-invalid/aria-describedby — sobrevive ao Swal
   fechar (o Swal é transiente; sem isto o campo ficava visualmente idêntico ao válido). */
.or-form-erro-inline {
    color: #dc3545;
    font-size: .82rem;
    margin-top: 4px;
}

/* ═══════════════ F0 — Skip-link ═══════════════
   Primeiro nó focável do documento (header.php, logo após <body>). position:fixed
   (não absolute) para o -9999px não abrir scroll horizontal — o validar-responsivo.php
   mediria isso como overflow. */
.or-skip {
    position: fixed;
    left: -9999px;
    top: 0;
    z-index: 100000;
    padding: .7rem 1.1rem;
    background: #000;
    color: #fff;
    border-radius: 0 0 6px 0;
    font: 600 .95rem/1 system-ui, -apple-system, "Segoe UI", sans-serif;
    text-decoration: none;
}
.or-skip:focus {
    left: 8px;
    top: 8px;
    outline: 3px solid #fff;
    outline-offset: -6px;
}

/* ═══════════════ F0 — Foco visível global ═══════════════
   O maior ganho de conformidade por byte do módulo (WCAG 2.4.7 AA). O style.css do
   Canvas 7 (gitignored, por-fork) tem outline:none!important em vários pontos — por
   isso a lista é EXPLÍCITA de elementos interativos (nunca `*`) e usa !important.
   Anel duplo (outline escuro + halo claro) garante 3:1 contra fundo claro E escuro
   sem conhecer a paleta do fork (WCAG 1.4.11). */
html body :is(
    a[href], area[href], button, input, select, textarea, summary,
    [tabindex]:not([tabindex="-1"]), [contenteditable="true"]
):focus-visible {
    outline: 3px solid var(--marca-primaria, #0B3D91) !important;
    outline-offset: 2px !important;
    box-shadow: 0 0 0 5px rgba(255, 255, 255, .85) !important;
    border-radius: 3px;
}
html[data-bs-theme="dark"] body :is(
    a[href], area[href], button, input, select, textarea, summary,
    [tabindex]:not([tabindex="-1"]), [contenteditable="true"]
):focus-visible {
    box-shadow: 0 0 0 5px rgba(0, 0, 0, .85) !important;
}

/* ═══════════════ F2 — Widget: tokens locais ═══════════════
   NÃO usa os tokens --or-* de or-dark.css — este arquivo carrega INCONDICIONALMENTE (mesmo com
   o dark desligado), então precisa ser autossuficiente. Escuro é ortogonal ao widget em si:
   [data-bs-theme="dark"] só existe quando Theme::darkAtivo() (que também gateia or-dark.css). */
:root {
    --a11y-surface:      #ffffff;
    --a11y-surface-2:    #f2f4f7;  /* trilho do switch OFF, hover sutil de linha */
    --a11y-text:         #1a2332;
    --a11y-text-muted:   #667085;
    --a11y-border:       rgba(0, 0, 0, .14);
    --a11y-accent:       var(--marca-primaria, #0B3D91);
    --a11y-accent-soft:  color-mix(in srgb, var(--a11y-accent), transparent 88%);
    --a11y-elev:         0 14px 38px rgba(20, 24, 33, .16);
}
[data-bs-theme="dark"] {
    --a11y-surface:      #1c1f26;
    --a11y-surface-2:    #262b34;
    --a11y-text:         #e6e8ec;
    --a11y-text-muted:   #9aa3af;
    --a11y-border:       rgba(255, 255, 255, .16);
    --a11y-accent:       color-mix(in srgb, var(--marca-primaria, #0B3D91), white 35%);
    --a11y-accent-soft:  color-mix(in srgb, var(--a11y-accent), transparent 82%);
    --a11y-elev:         0 14px 38px rgba(0, 0, 0, .55);
}

/* ═══════════════ F2 — FAB (neutro por padrão — mesma filosofia do FAB de tema, irmão na
   pilha) ═══════════════
   A cor de marca do cliente NUNCA vira fundo sólido do botão fechado: uma marca clara/pastel
   deixaria o ícone ilegível, e um disco saturado "briga" visualmente com o FAB de tema (que já é
   neutro) na mesma pilha. A marca entra só como REALCE — no hover e quando o painel está aberto —
   então continua presente na identidade sem depender dela para contraste/legibilidade. */
.or-a11y-fab {
    width: var(--or-fab-size, 48px);
    height: var(--or-fab-size, 48px);
    padding: 0;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--a11y-border);
    background: var(--a11y-surface);
    color: var(--a11y-text);
    box-shadow: 0 4px 14px rgba(0, 0, 0, .18);
    cursor: pointer;
    transition: background .2s ease, color .2s ease, border-color .2s ease, transform .15s ease, box-shadow .2s ease;
}
.or-a11y-fab:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(0, 0, 0, .25);
    color: var(--a11y-accent);
    border-color: var(--a11y-accent);
}
.or-a11y-fab[aria-expanded="true"] {
    background: var(--a11y-accent);
    border-color: var(--a11y-accent);
    color: #fff;
}
/* O ícone vem envolto num <span> (a11y-fab.php) — sem isto ele herda `display:inline-block` +
   `vertical-align:-0.125em` do `.or-icon` genérico (custom.css), e o span (linha de texto) fica
   mais alto que o SVG de 24px, descentralizando o ícone dentro do círculo. `display:flex` no
   próprio span neutraliza baseline/line-height — centralização robusta, não depende do texto ao
   redor. */
.or-a11y-fab > span {
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: 0;
}
.or-a11y-fab .or-icon { width: 24px; height: 24px; display: block; }

/* ═══════════════ F2 — Painel (Disclosure — NÃO é dialog/modal) ═══════════════
   Irmão da pilha, não filho: se fosse filho de .or-fab-stack, a largura do painel viraria a
   largura do container e o column-reverse empurraria os outros FABs. Ancorado nos MESMOS
   tokens (--or-fab-gap/size/lift) para acompanhar a pilha quando o banner LGPD empurra tudo. */
.or-a11y-panel {
    position: fixed;
    z-index: 9990; /* abaixo do banner LGPD (9999); acima do conteúdo */
    left: var(--or-fab-gap, 20px);
    bottom: calc(var(--or-fab-gap, 20px) * 2 + var(--or-fab-size, 48px) + var(--or-fab-lift, 0px));
    width: min(340px, calc(100vw - var(--or-fab-gap, 20px) * 2));
    /* Acompanha o lado ATUAL do FAB (\OneRank\Acessibilidade::posicao(), configurável desde a
       padronização dos FABs) — sem isto, mover o botão pra direita deixava o painel "flutuando"
       ainda ancorado à esquerda, longe do gatilho que o abriu.
       max-height também NUNCA pode exceder o espaço acima do próprio FAB (o terceiro termo do
       min()) — sem isso, com --or-fab-lift alto (banner LGPD grande em mobile) o painel estourava
       o topo da viewport e o cabeçalho/botão fechar ficavam inalcançáveis. Achado real, 22/08/2026,
       em fork com tema bespoke (custom.css sem a Camada 3 do adapter escondendo overflow).
       !important: este componente é documentado como portável para QUALQUER template Envato —
       não dá pra confiar em especificidade contra um reset arbitrário de terceiro. As propriedades
       ESTRUTURAIS da pilha de FABs (posição/tamanho/z-index/overflow) sempre vencem; cor/sombra/
       borda (abaixo) continuam sem !important — o template pode restilizar a aparência à vontade. */
    max-height: min(70vh, 620px, calc(100vh - (var(--or-fab-gap, 20px) * 2 + var(--or-fab-size, 48px) + var(--or-fab-lift, 0px)) - 16px)) !important;
    overflow-y: auto;
    overscroll-behavior: contain;
    background: var(--a11y-surface);
    color: var(--a11y-text);
    border: 1px solid var(--a11y-border);
    border-radius: 14px;
    box-shadow: var(--a11y-elev);
    padding: 18px;
    font-size: .95rem;
    /* Rolagem SEMPRE visível quando o conteúdo excede max-height — templates que zeram
       ::-webkit-scrollbar globalmente (ex.: Envato "Azurio", `::-webkit-scrollbar{display:none
       !important}`) escondiam a barra aqui também, deixando o painel roláve mas sem affordance
       nenhuma. Escopado ao painel — não é uma opinião de scrollbar pro site inteiro. Achado
       real, 22/08/2026 — o reset do template usava `width:0 !important`, então width AQUI
       também precisa de !important (display/appearance vencem por especificidade sozinhos,
       mas width perderia pro !important do template sem reforço). */
    scrollbar-width: thin !important;
}
.or-a11y-panel::-webkit-scrollbar { display: block; width: 6px !important; -webkit-appearance: none !important; }
.or-a11y-panel::-webkit-scrollbar-thumb { background: var(--a11y-border); border-radius: 999px; }
.or-a11y-panel[hidden] { display: none; }
.or-a11y-panel[data-or-lado="direita"] { left: auto; right: var(--or-fab-gap, 20px); }
@media (max-width: 575.98px) {
    /* Cobre a tela (bottom-sheet) — o foco fica preso via `inert` no #wrapper (or-a11y.js), não CSS. */
    .or-a11y-panel {
        left: 0;
        right: 0;
        width: auto;
        bottom: var(--or-fab-lift, 0px);
        border-radius: 16px 16px 0 0;
        max-height: min(80vh, calc(100vh - var(--or-fab-lift, 0px) - 16px)) !important;
    }
}

.or-a11y-panel-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 16px; }
.or-a11y-panel-title { display: flex; align-items: center; gap: 10px; min-width: 0; }
.or-a11y-badge {
    display: flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 30px; height: 30px; border-radius: 50%;
    background: var(--a11y-accent-soft); color: var(--a11y-accent);
}
.or-a11y-badge .or-icon { width: 17px; height: 17px; display: block; }
.or-a11y-panel-head h2 { font-size: 1.05rem; font-weight: 700; margin: 0; outline: none; }
.or-a11y-close {
    width: 30px; height: 30px; flex-shrink: 0; border: 0; border-radius: 8px;
    background: transparent; color: var(--a11y-text-muted); cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    transition: background .15s ease, color .15s ease;
}
.or-a11y-close:hover { background: var(--a11y-surface-2); color: var(--a11y-text); }

.or-a11y-field { border: 0; padding: 0; margin: 0 0 16px; }
.or-a11y-field legend {
    font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
    color: var(--a11y-text-muted); padding: 0; margin-bottom: 9px;
}

.or-a11y-scale { display: flex; gap: 6px; }
.or-a11y-scale input {
    position: absolute; opacity: 0; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0, 0, 0, 0); white-space: nowrap;
}
.or-a11y-scale label {
    flex: 1; text-align: center; padding: 9px 4px; border: 1px solid var(--a11y-border);
    background: var(--a11y-surface); border-radius: 9px; cursor: pointer; font-weight: 700; font-size: .84rem;
    transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.or-a11y-scale label:hover { border-color: var(--a11y-accent); }
.or-a11y-scale input:checked + label { background: var(--a11y-accent); color: #fff; border-color: var(--a11y-accent); }
.or-a11y-scale input:focus-visible + label { outline: 3px solid var(--a11y-accent); outline-offset: 2px; }

/* Toggles (checkbox) — switch moderno, CSS puro sobre o <input> real (nunca div decorativa: o
   input continua focável/operável por teclado e leitor de tela, só a pele muda). O trilho é
   desenhado pelo próprio input via `appearance:none` + `::after` (a bolinha); nenhum JS a mais —
   or-a11y.js já lê estes mesmos IDs via `.checked`/evento `change`, inalterado. */
.or-a11y-toggle {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 9px 2px; margin: 0 -2px; border-radius: 8px; cursor: pointer; font-size: .92rem;
    transition: background .15s ease;
}
.or-a11y-toggle:hover { background: var(--a11y-surface-2); }
.or-a11y-toggle input[type="checkbox"] {
    appearance: none; -webkit-appearance: none; flex-shrink: 0;
    width: 38px; height: 22px; border-radius: 999px;
    background: var(--a11y-surface-2); border: 1px solid var(--a11y-border);
    position: relative; cursor: pointer; margin: 0;
    transition: background .18s ease, border-color .18s ease;
}
.or-a11y-toggle input[type="checkbox"]::after {
    content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px;
    border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, .35);
    transition: transform .18s ease;
}
.or-a11y-toggle input[type="checkbox"]:checked {
    background: var(--a11y-accent); border-color: var(--a11y-accent);
}
.or-a11y-toggle input[type="checkbox"]:checked::after { transform: translateX(16px); }
.or-a11y-toggle input[type="checkbox"]:focus-visible { outline: 3px solid var(--a11y-accent); outline-offset: 2px; }

/* Botão "Tema escuro" — MESMA pele de switch dos checkboxes acima (era um bloco retangular
   destoante; um `<button aria-pressed>` não tem `:checked`, então o estado espelha via atributo). */
.or-a11y-toggle-btn {
    width: 100%; border: 0; background: transparent; color: var(--a11y-text);
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    text-align: left; padding: 9px 2px; margin: 0 -2px; border-radius: 8px;
    font-weight: 500; font-size: .92rem; cursor: pointer; transition: background .15s ease;
}
.or-a11y-toggle-btn:hover { background: var(--a11y-surface-2); }
.or-a11y-toggle-btn::after {
    content: ""; flex-shrink: 0; width: 38px; height: 22px; border-radius: 999px;
    background: var(--a11y-surface-2); border: 1px solid var(--a11y-border); position: relative;
    transition: background .18s ease, border-color .18s ease;
}
.or-a11y-toggle-btn::before {
    content: ""; position: absolute; top: 0; right: 18px; width: 16px; height: 16px;
    margin-top: 3px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, .35);
    transition: transform .18s ease; pointer-events: none;
}
.or-a11y-toggle-btn[aria-pressed="true"]::after { background: var(--a11y-accent); border-color: var(--a11y-accent); }
.or-a11y-toggle-btn[aria-pressed="true"]::before { transform: translateX(16px); }

/* Radios (Animações) — dot customizado, mesma lógica do switch: input real, pele por cima. */
.or-a11y-radio {
    display: flex; align-items: center; gap: 10px; padding: 7px 2px; margin: 0 -2px;
    border-radius: 8px; font-size: .9rem; cursor: pointer; transition: background .15s ease;
}
.or-a11y-radio:hover { background: var(--a11y-surface-2); }
.or-a11y-radio input {
    appearance: none; -webkit-appearance: none; flex-shrink: 0; margin: 0;
    width: 18px; height: 18px; border-radius: 50%; border: 2px solid var(--a11y-border);
    background: var(--a11y-surface); position: relative; cursor: pointer;
    transition: border-color .15s ease;
}
.or-a11y-radio input::after {
    content: ""; position: absolute; inset: 3px; border-radius: 50%;
    background: var(--a11y-accent); transform: scale(0); transition: transform .15s ease;
}
.or-a11y-radio input:checked { border-color: var(--a11y-accent); }
.or-a11y-radio input:checked::after { transform: scale(1); }
.or-a11y-radio input:focus-visible { outline: 3px solid var(--a11y-accent); outline-offset: 2px; }

.or-a11y-panel-foot {
    margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--a11y-border);
    display: flex; flex-direction: column; gap: 10px;
}
.or-a11y-reset {
    border: 1px solid var(--a11y-border); background: var(--a11y-surface); color: var(--a11y-text);
    border-radius: 9px; padding: 9px 10px; cursor: pointer; font-weight: 700; font-size: .88rem;
    transition: background .15s ease, border-color .15s ease;
}
.or-a11y-reset:hover { background: var(--a11y-surface-2); border-color: var(--a11y-accent); }
.or-a11y-link {
    display: inline-flex; align-items: center; justify-content: center; gap: 5px;
    color: var(--a11y-accent); font-size: .86rem; font-weight: 600; text-decoration: none;
}
.or-a11y-link:hover { text-decoration: underline; }
/* width/height explícitos (não só flex-shrink) — sem isso, um template com reset global de
   `svg { width:100% }` (comum em bundles de ícone/Swiper) estica esta seta pro tamanho do
   painel inteiro. O HTML já declara width="13" height="13", mas atributo HTML perde de
   qualquer regra CSS que mire o elemento — precisa da regra explícita pra vencer. Achado
   real, 22/08/2026 (renderizava 389×389px em fork com tema bespoke). */
.or-a11y-link svg { width: 13px !important; height: 13px !important; flex-shrink: 0 !important; }

/* Live region + descrições sr-only (padrão .visually-hidden do Bootstrap, mas SEM depender dele —
   Autoridade/Tema podem não carregar o bundle Bootstrap). */
.or-a11y-sr {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; padding: 0; margin: -1px;
}

/* ═══════════════ F2 — Tamanho do texto (html[data-or-fs]) ═══════════════
   `html { font-size }` por atributo discreto, NÃO zoom/calc(em): zoom cria novo sistema de
   coordenadas para descendentes position:fixed (o header sticky, os FABs, o banner LGPD sairiam
   do lugar); calc(1em*var(--k)) multiplica em cascata em elementos aninhados. Bootstrap/Canvas
   usam rem para tipografia E espaçamento — a página cresce na VERTICAL, não na horizontal.
   Nível 0 = SEM atributo ⇒ zero CSS ativo (mesma garantia de não-regressão do dark mode). */
html[data-or-fs="1"] { font-size: 112.5%; }
html[data-or-fs="2"] { font-size: 125%; }
html[data-or-fs="3"] { font-size: 137.5%; } /* teto prático; 200% (WCAG 1.4.4) via zoom do navegador, que isto não atrapalha */

/* CAMADA 2 — portável (qualquer template Bootstrap 5): reset de altura fixa em componentes que
   truncariam o texto maior por dentro de uma caixa que não cresce junto. */
html[data-or-fs] :where(.btn, .button, .badge, .nav-link, .form-control, .form-select) {
    height: auto !important;
    min-height: 0 !important;
    line-height: 1.4 !important;
}

/* CAMADA 3 — ADAPTER do template atual (Canvas 7). Deixado deliberadamente vazio: o header sticky
   usa --cnvs-header-height para a altura da LOGO (não um contêiner com overflow:hidden óbvio) —
   afinar isso sem medição é adivinhação. Preencher com base no detector de clipping do
   bin/validar-responsivo.php --a11y (fase de auditoria automatizada), NUNCA por estimativa. */

/* ═══════════════ F2 — Espaçamento do texto (html[data-or-ts], WCAG 1.4.12) ═══════════════
   Valores exatos do critério de sucesso. Escopo só a elementos de TEXTO DE CONTEÚDO — nunca
   .btn/.badge/ícone: letter-spacing nesses infla largura e é a causa nº1 de overflow horizontal. */
html[data-or-ts="1"] :where(p, li, dd, dt, blockquote, figcaption, td, th, .lead, .entry-content *) {
    line-height: 1.5 !important;
    letter-spacing: .12em !important;
    word-spacing: .16em !important;
}
html[data-or-ts="1"] :where(p, blockquote, ul, ol, dl) {
    margin-bottom: 2em !important;
}

/* ═══════════════ F2 — Alto contraste (html[data-or-hc]) ═══════════════
   Override de TOKENS (os mesmos que Colors::toCssVars() já emite em :root, inline no <head>),
   não filtro CSS: filter() cria bloco de contenção para descendentes position:fixed (mesmo
   problema do zoom) e não alcança background-image/SVG. Ortogonal ao claro/escuro — por isso a
   variante [data-bs-theme="dark"] (especificidade 0,2,1) vence o :root inline (0,1,0) sozinha. */
html[data-or-hc="1"] {
    --texto-principal: #101010;
    --texto-secundario: #101010;
    --texto-link: #0b3ea8;
    --fundo-site: #ffffff;
    --fundo-card: #ffffff;
    --fundo-secao-alt: #f2f2f2;
    --or-surface: #ffffff;
    --or-text: #101010;
    --or-text-muted: #101010;
    --or-border: #101010;
}
html[data-or-hc="1"][data-bs-theme="dark"] {
    --texto-principal: #f5f5f5;
    --texto-secundario: #f5f5f5;
    --texto-link: #8ab4ff;
    --fundo-site: #000000;
    --fundo-card: #000000;
    --fundo-secao-alt: #0d0d0d;
    --or-surface: #000000;
    --or-text: #f5f5f5;
    --or-text-muted: #f5f5f5;
    --or-border: #f5f5f5;
}
/* Reforço cirúrgico — NUNCA background global (o rodapé é bg-dark fixo, a legenda do hero é
   branca sobre foto; um color:#000 cego produziria preto sobre preto). */
html[data-or-hc="1"] :where(.text-muted, .text-white-50, [class*="opacity-"], small) {
    opacity: 1 !important;
    color: inherit !important;
}
html[data-or-hc="1"] * { text-shadow: none !important; }
html[data-or-hc="1"] :where(.card, .form-control, .form-select, .btn, .or-service-card, .or-blog-card) {
    border: 1px solid currentColor !important;
}

/* ═══════════════ F2 — Realçar links (html[data-or-lk]) ═══════════════
   `:is()`, não `:where()`: o Canvas 7 (gitignored, por-fork) tem `a:not(.btn-link):not(...):not(...)
   { text-decoration:none !important }` — 3 `:not()` somam especificidade (0,3,1), que VENCIA a regra
   antiga com `:where()` (especificidade zero por definição). `:is()` herda a especificidade do
   argumento mais específico — some com o `[data-or-lk="1"]` repetido (hack de especificidade
   deliberado, sem efeito semântico) para vencer o tema com folga em qualquer template razoável, não
   só o Canvas atual. Achado real via QA de navegador (18/08/2026, PR #201): a regra original nunca
   vencia contra qualquer tema que "limpa" `<a>` — corrigido nesse PR.

   ESCOPO — só texto de CONTEÚDO, nunca `<nav>` (achado #2, mesma rodada de QA — regressão do
   próprio fix acima): a 1ª correção incluía `li` solto na lista, o que também sublinhava os itens do
   MENU PRINCIPAL (`<li class="menu-item">`) — o `<li>` é usado tanto por listas de conteúdo quanto
   por menus. Em vez de caçar a classe de "isto é menu" por template (o Canvas usa `.menu-item`, o
   Autoridade usa `<li>` cru — cada tema teria uma exclusão diferente), a exclusão é por CONTEXTO
   ESTRUTURAL: `:not(nav li)` — qualquer `<li>` fora de um `<nav>`, cobrindo os 4 modos de chrome de
   uma vez (todo `<nav>` do site tem `aria-label`, F4). Isso também tira o RODAPÉ do escopo (ele virou
   `<nav aria-label="Rodapé">` na F4) — decisão deliberada: navegação (mesmo no rodapé) já comunica
   "isto é clicável" pelo contexto de lista/menu, sem depender só da cor (WCAG 1.4.1); o realce é para
   links dentro de PROSA, onde só a cor diferencia.

   `.form-check-label` entrou na 3ª rodada de QA (19/08/2026): o link da Política de Privacidade no
   texto de consentimento LGPD (contato, newsletter, candidatura) é prosa dentro de um `<label>`, não
   de `<p>`/`.entry-content` — mesmo caso de "só a cor diferencia" que o resto da regra já cobre. */
html[data-or-lk="1"][data-or-lk="1"] :is(.entry-content, .lead, p, .form-check-label) a[href],
html[data-or-lk="1"][data-or-lk="1"] li:not(nav li) a[href] {
    text-decoration: underline !important;
    text-decoration-thickness: 2px !important;
    text-underline-offset: 3px !important;
    font-weight: 700 !important;
}

/* ── BASE (sem toggle): link em prosa do CORE nunca se distingue só pela cor ──────────────────
   WCAG 1.4.1 não é uma preferência do visitante — é o piso. A regra ACIMA depende de
   `data-or-lk="1"`, que só existe depois de alguém ligar "Realçar links" no painel de
   acessibilidade; numa visita limpa (o estado de 100% dos visitantes, e o estado em que o axe
   roda) ela nunca casa, e o que sobra é `a { color: … }` do tema — só cor.

   Medido em 10/09/2026 no axe-core: 5 violações de `link-in-text-block`, de apenas DUAS fontes de
   markup do core — o partial de consentimento LGPD (4 rotas) e o parágrafo de contato da página de
   acessibilidade. A contraprova estava no próprio repositório: a home Autoridade NÃO era acusada,
   porque `or-autoridade.css` sublinha `.or-aut-consent a` incondicionalmente. O mesmo partial
   passava ali e falhava no /contato — a diferença era só o wrapper que o chamador passava.

   ESCOPO DELIBERADO: a classe é aplicada nos pontos do CORE que falharam, não numa regra `p a`
   sitewide. Um seletor amplo mudaria a aparência de todo fork da frota para corrigir um defeito
   que está em dois lugares identificados — e cada tema Envato tem sua própria linguagem de link.

   ⚠️ A CLASSE REPETIDA NÃO É ENGANO — é o mesmo truque do `[data-or-lk="1"][data-or-lk="1"]` da
   regra acima, e pela mesma razão, agora medida no navegador (10/09/2026). O template Envato traz:

       a:not(.btn-link):not(.text-decoration-underline):not(.more-link) { text-decoration: none !important; }

   Especificidade (0,3,1) com `!important`. A 1ª versão desta regra era `.or-link-prosa[href]`
   (0,2,0), também com `!important` — os dois `!important` se anulam e a ESPECIFICIDADE decide, então
   o tema vencia e o computado seguia `text-decoration-line: none`. O axe continuou acusando as 5
   violações e o defeito parecia corrigido no código-fonte. Repetir a classe leva a (0,4,1), que
   ganha pela contagem de classes, independente da ordem de carga das folhas.

   Sem `font-weight`, que é do realce opcional: aqui o objetivo é só existir uma distinção
   não-cromática, não parecer que o toggle de acessibilidade está ligado. */
a.or-link-prosa.or-link-prosa.or-link-prosa[href] {
    text-decoration: underline !important;
    text-underline-offset: 2px;
}

/* ═══════════════ F2 — Reduzir animações (html[data-or-rm], base — carrossel na F6) ═══════════════
   Tri-estado: ausente = respeita o sistema (@media abaixo) · "reduce" = força mesmo com o SO em
   no-preference · "no-preference" = desliga mesmo com o SO pedindo redução (evita prender o
   usuário sem carrossel por config de SO/perfil corporativo que ele não controla). */
@media (prefers-reduced-motion: reduce) {
    html:not([data-or-rm="no-preference"]) *,
    html:not([data-or-rm="no-preference"]) *::before,
    html:not([data-or-rm="no-preference"]) *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
}
html[data-or-rm="reduce"] *,
html[data-or-rm="reduce"] *::before,
html[data-or-rm="reduce"] *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
}

/* F5/F6 — Elementos `[data-animate]` (Canvas 7 — hero.php e outras seções) nascem `opacity:0`
   (regra do próprio template) até o bundle gitignored adicionar a classe `.animated`, ~750ms+
   depois via setTimeout — o `animation-duration` reduzido acima NÃO alcança essa janela, porque
   ainda não existe `.animated` para ter duração nenhuma. Resolvido por CSS, não JS: o bundle lê o
   atributo `data-animate` no load, antes do nosso script rodar — JS teria corrida. */
@media (prefers-reduced-motion: reduce) {
    html:not([data-or-rm="no-preference"]) [data-animate] {
        opacity: 1 !important;
        transform: none !important;
        animation: none !important;
    }
}
html[data-or-rm="reduce"] [data-animate] {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
}

/* ═══════════════ F2 — Cursor ampliado (html[data-or-cu]) ═══════════════
   SVG 48px (acima disso alguns browsers ignoram o cursor custom); `, auto`/`, pointer` finais
   são obrigatórios — sem eles um data-URI malformado deixaria o usuário SEM cursor nenhum. */
html[data-or-cu="1"],
html[data-or-cu="1"] * {
    cursor: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewBox='0 0 24 24'><path d='M4 2l14 8-6 2 4 6-3 2-4-6-4 4z' fill='%23111' stroke='%23fff' stroke-width='1.2'/></svg>") 4 4, auto !important;
}
html[data-or-cu="1"] :where(a, button, [role="button"], label, summary) {
    cursor: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewBox='0 0 24 24'><circle cx='12' cy='12' r='9' fill='%23111' stroke='%23fff' stroke-width='1.5'/></svg>") 12 12, pointer !important;
}

/* Scroll-lock do fundo quando o painel cobre a tela no mobile (or-a11y.js liga/desliga a classe). */
body.or-a11y-open { overflow: hidden; }

/* ═══════════════ F5/F6 — Botão de pausa do carrossel (WCAG 2.2.2) ═══════════════
   Nasce `hidden` no markup (hero.php) — or-a11y.js só o revela se achar a instância Swiper.
   Nunca oferecer um controle que não funciona. */
.or-carousel-toggle {
    position: absolute;
    z-index: 10;
    right: 16px;
    bottom: 16px;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba(0, 0, 0, .45);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}
.or-carousel-toggle:hover { background: rgba(0, 0, 0, .65); }
.or-carousel-toggle .or-ct-icon { width: 14px; height: 14px; position: relative; }
/* Ícone puro CSS (sem depender de fonte de ícone do template) — duas barras = pausa. */
.or-carousel-toggle .or-ct-icon::before,
.or-carousel-toggle .or-ct-icon::after {
    content: ""; position: absolute; top: 0; width: 4px; height: 14px; background: currentColor;
}
.or-carousel-toggle .or-ct-icon::before { left: 2px; }
.or-carousel-toggle .or-ct-icon::after { right: 2px; }
/* Pressionado (pausado) → ícone vira "play" (triângulo). */
.or-carousel-toggle[aria-pressed="true"] .or-ct-icon::before,
.or-carousel-toggle[aria-pressed="true"] .or-ct-icon::after {
    content: ""; top: 0; width: 0; height: 0; background: transparent;
    border-style: solid; border-width: 7px 0 7px 12px; border-color: transparent transparent transparent currentColor;
}
.or-carousel-toggle[aria-pressed="true"] .or-ct-icon::after { display: none; }
.or-carousel-toggle[aria-pressed="true"] .or-ct-icon::before { left: 1px; }
