:root {
    --color-bg: #faf8f5;
    --color-surface: #ffffff;
    --color-text: #2b2b26;
    --color-text-muted: #6b6a63;
    --color-primary: #4d6b53;
    --color-primary-soft: #7fa88a;
    --color-primary-contrast: #ffffff;
    --color-border: #e4e0d8;
    --color-danger: #a33b34;
    --color-danger-border: #e2bfbc;
    --color-danger-surface: #fdf6f5;
    --color-danger-contrast: #ffffff;
    --oracle-glow: rgba(190, 148, 62, 0.48);
    --oracle-ring: rgba(190, 148, 62, 0.68);
    --oracle-sheen: rgba(255, 240, 200, 0.70);
    --oracle-veil: rgba(32, 26, 46, 0.78);
    --radius: 10px;
    --shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
    --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

/*
 * Tema dia/noite: [data-bs-theme] no <html> e o MESMO atributo que o
 * Bootstrap 5.3 usa para seus proprios componentes (bootstrap.min.css ja
 * tem variantes dark para card/table/alert/etc. reagindo a ele) — reusar
 * o atributo em vez de inventar um proprio faz nossas variaveis de cor e
 * as do Bootstrap mudarem juntas com uma unica escrita de atributo.
 *
 * O atributo e escrito ANTES do primeiro paint por um script inline
 * nonced no <head> de cada layout (ver layouts/app.php e admin.php),
 * lendo localStorage (escolha explicita do visitante, alternada pelo
 * botao .theme-toggle em app.js) ou, na primeira visita sem escolha
 * salva, prefers-color-scheme. A media query abaixo so importa quando
 * esse script nao rodou (JS desabilitado) — nesse caso o atributo nunca
 * e escrito e o navegador cai na preferencia do proprio SO.
 */
@media (prefers-color-scheme: dark) {
    :root:not([data-bs-theme="light"]) {
        --color-bg: #1d1e1a;
        --color-surface: #262722;
        --color-text: #f1efe9;
        --color-text-muted: #b7b5ac;
        --color-primary: #b39ddb;
        --color-primary-soft: #d9c8ef;
        --color-primary-contrast: #241a35;
        --color-border: #3a3b34;
        --color-danger: #e8908a;
        --color-danger-border: #5a302d;
        --color-danger-surface: #2a201f;
        --color-danger-contrast: #2a1412;
        --oracle-glow: rgba(179, 157, 219, 0.54);
        --oracle-ring: rgba(217, 200, 239, 0.62);
        --oracle-sheen: rgba(226, 214, 250, 0.32);
        --oracle-veil: rgba(9, 8, 14, 0.84);
        --shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
    }
}

:root[data-bs-theme="dark"] {
    --color-bg: #1d1e1a;
    --color-surface: #262722;
    --color-text: #f1efe9;
    --color-text-muted: #b7b5ac;
    --color-primary: #b39ddb;
    --color-primary-soft: #d9c8ef;
    --color-primary-contrast: #241a35;
    --color-border: #3a3b34;
    --color-danger: #e8908a;
    --color-danger-border: #5a302d;
    --color-danger-surface: #2a201f;
    --color-danger-contrast: #2a1412;
    --oracle-glow: rgba(179, 157, 219, 0.54);
    --oracle-ring: rgba(217, 200, 239, 0.62);
    --oracle-sheen: rgba(226, 214, 250, 0.32);
    --oracle-veil: rgba(9, 8, 14, 0.84);
    --shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}

:root[data-bs-theme="light"] {
    color-scheme: light;
}

:root[data-bs-theme="dark"] {
    color-scheme: dark;
}

* {
    box-sizing: border-box;
}

html {
    color-scheme: light dark;
}

body {
    margin: 0;
    font-family: var(--font-sans);
    background: var(--color-bg);
    color: var(--color-text);
    line-height: 1.5;
}

/*
 * Sem override de .container aqui de proposito: e a classe do Bootstrap
 * (bootstrap.min.css, carregado antes deste arquivo), com os breakpoints
 * responsivos que a fase de adequacao ao Bootstrap 5.3 pediu. Overrides
 * daqui pra baixo sao de cor/tipografia/decoracao, nao de estrutura.
 */

.theme-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    padding: 0;
    border-radius: 999px;
    border: 1px solid var(--color-border);
    background: transparent;
    color: var(--color-text);
    cursor: pointer;
}

.theme-toggle:hover,
.theme-toggle:focus-visible {
    border-color: var(--color-primary);
}

.theme-toggle__icon {
    width: 1.15rem;
    height: 1.15rem;
}

.theme-toggle__icon--moon {
    display: none;
}

:root[data-bs-theme="dark"] .theme-toggle__icon--sun {
    display: none;
}

:root[data-bs-theme="dark"] .theme-toggle__icon--moon {
    display: block;
}

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    background: var(--color-primary);
    color: var(--color-primary-contrast);
    padding: 0.75rem 1rem;
    z-index: 100;
}

.skip-link:focus {
    left: 1rem;
    top: 1rem;
}

.site-header {
    border-bottom: 1px solid var(--color-border);
    background: var(--color-surface);
    position: sticky;
    top: 0;
    z-index: 20;
}

.site-header__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-block: 1rem;
    gap: 1rem;
    flex-wrap: wrap;
}

.brand {
    font-weight: 700;
    font-size: 1.25rem;
    color: var(--color-text);
    text-decoration: none;
}

.main-nav {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    flex-wrap: wrap;
}

.main-nav a:not(.button) {
    color: var(--color-text-muted);
    text-decoration: none;
}

.main-nav a:not(.button):hover,
.main-nav a:not(.button):focus-visible {
    color: var(--color-text);
}

.button {
    display: inline-block;
    padding: 0.55rem 1.1rem;
    border-radius: var(--radius);
    text-decoration: none;
    font-weight: 600;
    border: 1px solid transparent;
}

.button--primary {
    background: var(--color-primary);
    color: var(--color-primary-contrast);
}

.button--ghost {
    border-color: var(--color-border);
    color: var(--color-text);
}

.button--outline-light {
    background: transparent;
    border: 2px solid #fff;
    color: #fff;
}

.button--outline-light:hover,
.button--outline-light:focus-visible {
    background: rgba(255, 255, 255, 0.18);
    border-color: #fff;
}

.button--lg {
    padding: 0.85rem 1.6rem;
    font-size: 1.05rem;
}

/*
 * Menu da conta no cabecalho (2026-09-21). E um <details>/<summary>
 * nativo: abrir e fechar nao custa uma linha de JS, e o marcador
 * triangular padrao do navegador e removido em favor do chevron em SVG.
 *
 * Nao e o dropdown do Bootstrap de proposito — ele posiciona via Popper
 * escrevendo `style` inline por JS, e style-src deste projeto nao tem
 * 'unsafe-inline' (ver CLAUDE.md). Aqui o posicionamento e estatico, no
 * proprio CSS, entao nao ha nada a calcular em runtime.
 */
.user-menu {
    position: relative;
}

.user-menu__trigger {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.7rem;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    color: var(--color-text);
    font-size: 0.95rem;
    cursor: pointer;
    list-style: none;
    user-select: none;
}

/* Remove o triangulo nativo do <summary> nos dois motores. */
.user-menu__trigger::-webkit-details-marker {
    display: none;
}


.user-menu__trigger:hover,
.user-menu__trigger:focus-visible {
    border-color: var(--color-primary);
}

.user-menu__name {
    max-width: 12rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.user-menu__chevron {
    flex-shrink: 0;
    transition: transform 0.15s ease;
}

.user-menu[open] .user-menu__chevron {
    transform: rotate(180deg);
}

.user-menu__panel {
    position: absolute;
    right: 0;
    top: calc(100% + 0.5rem);
    min-width: 15rem;
    padding: 0.4rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    box-shadow: var(--shadow);
    z-index: 30;
}

.user-menu__links {
    display: flex;
    flex-direction: column;
}

.user-menu__item {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
    padding: 0.55rem 0.7rem;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--color-text);
    font: inherit;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}

/*
 * .main-nav pinta todo link de --color-text-muted; dentro do painel o
 * item precisa do contraste normal de texto, entao a regra mais
 * especifica vence sem !important.
 */
.main-nav .user-menu__panel a.user-menu__item {
    color: var(--color-text);
}

.user-menu__item:hover,
.user-menu__item:focus-visible,
.main-nav .user-menu__panel a.user-menu__item:hover,
.main-nav .user-menu__panel a.user-menu__item:focus-visible {
    background: var(--color-bg);
    color: var(--color-text);
}

.user-menu__logout {
    margin: 0.4rem 0 0;
    padding-top: 0.4rem;
    border-top: 1px solid var(--color-border);
}

.user-menu__icon {
    flex-shrink: 0;
}

/*
 * Em tela estreita o cabecalho quebra em varias linhas (flex-wrap) e o
 * gatilho pode terminar perto da borda ESQUERDA — ai um painel absoluto
 * ancorado em `right: 0` com largura minima de 15rem sai da tela pela
 * esquerda. Abaixo de 640px (mesmo ponto de quebra que o resto do
 * arquivo ja usa) o painel passa a ocupar a largura do cabecalho.
 */
@media (max-width: 640px) {
    .user-menu {
        position: static;
    }

    .user-menu__panel {
        left: 0;
        right: 0;
        min-width: 0;
    }
}

/*
 * Efeito de rolagem da home (inspirado em corposelvagem.com): paralaxe
 * de verdade via background-attachment:fixed, sem JS, sem biblioteca de
 * scroll (gsap/locomotive etc. exigiriam CDN ou build, proibidos pela
 * hospedagem — ver "Restricoes de hospedagem"). Cada camada e um bloco
 * normal (nao sticky) com a IMAGEM como background fixo — enquanto o
 * bloco ocupa qualquer parte da tela, a imagem fica "ancorada" ao
 * viewport (nao se move com o scroll), dando a sensacao classica de
 * paralaxe: a rolagem revela progressivamente mais/menos da mesma
 * imagem parada, em vez de arrasta-la para cima como um bloco comum.
 * --intro (hero-2, menor, com o titulo+botao) e --reveal (hero-1, tela
 * cheia) sao dois blocos empilhados em fluxo normal — o limite entre
 * eles e so a fronteira entre as duas caixas, nao precisa de sticky
 * nenhum. Depois de --reveal vem #conteudo-principal (fluxo normal,
 * com min-height de uma tela cheia — ver regra abaixo — garantindo que
 * a imagem some por completo antes de qualquer outra coisa, e o
 * cabecalho do site, que e sticky, "gruda" no topo a partir dali).
 *
 * Nota de compatibilidade: background-attachment:fixed tem suporte
 * completo em todos os navegadores modernos (Chrome/Firefox/Edge) e em
 * iOS Safari 15.4+; versoes de iOS Safari mais antigas ignoram o fixed
 * silenciosamente (a imagem so rola normal, sem quebrar nada, so perde
 * o efeito) — degradacao graciosa, nao um erro visivel.
 *
 * background-image NAO fica aqui (2026-09-02): as duas imagens sao
 * gerenciaveis pelo admin (Domain\Site\SiteImageRepository), entao
 * home.php injeta um <style nonce="..."> por request com a url() de
 * cada slot — um <img> normal perderia o background-attachment:fixed
 * (nao existe em elemento <img>), e style="" inline e bloqueado pelo
 * CSP; nonce em style-src (so para esse bloco, ver SecurityHeaders) foi
 * a troca aceita para manter o efeito. Aqui fica so a parte estrutural.
 */
.scroll-hero {
    position: relative;
}

.scroll-hero__layer {
    background-size: cover;
    background-position: center;
    background-attachment: fixed;
}

.scroll-hero__layer--intro {
    position: relative;
    height: 70vh;
    height: 70dvh;
}

.scroll-hero__layer--reveal {
    height: 100vh;
    height: 100dvh;
}

.scroll-hero__overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.5));
    padding: 1.5rem;
}

.scroll-hero__title {
    color: #fff;
    font-size: clamp(2rem, 5vw, 3.5rem);
    font-weight: 700;
    letter-spacing: 0.02em;
    margin: 0 0 1.5rem;
    text-shadow: 0 2px 16px rgba(0, 0, 0, 0.5);
}

/*
 * Garante que a sequencia de imagens some por completo antes de
 * qualquer outra coisa aparecer, e que o cabecalho do site (sticky)
 * tenha uma tela cheia de conteudo real por baixo dele assim que gruda
 * no topo — sem isto, um #conteudo-principal mais curto que a tela
 * deixaria a ultima imagem "espiando" atras do cabecalho.
 */
#conteudo-principal {
    min-height: 100vh;
    min-height: 100dvh;
}

.hero {
    padding-block: 4.5rem;
    text-align: center;
    background: linear-gradient(180deg, var(--color-surface), var(--color-bg));
}

.hero h2 {
    font-size: clamp(2rem, 4vw, 3rem);
    margin-bottom: 1rem;
}

/*
 * Bloco de prosa longa de pagina institucional (home e /sobre desde
 * 2026-09-20, /oraculo desde 2026-09-21).
 * O numero de paragrafos nao e fixo — quem escreve e o admin, em
 * /admin/imagens-home, /admin/sobre e /admin/oraculo (tabela site_texts).
 * O titulo continua centralizado (.hero), mas a prosa fica alinhada a
 * esquerda e um pouco mais larga — paragrafo longo centralizado e dificil
 * de ler, a linha nao tem margem fixa para o olho voltar.
 */
.hero__prose {
    max-width: 62rem;
    margin-inline: auto;
    text-align: left;
}

.hero__lead {
    max-width: 640px;
    margin-inline: auto;
    color: var(--color-text-muted);
    font-size: 1.1rem;
}

.hero__prose .hero__lead {
    max-width: none;
}

.hero__prose .hero__lead + .hero__lead {
    margin-top: 1.1rem;
}

.hero__actions {
    margin-top: 2rem;
}

.section {
    padding-block: 3.5rem;
}

.section h2 {
    text-align: center;
    margin-bottom: 2rem;
}

.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 1.5rem;
}

.card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 1.5rem;
}

.card h3 {
    margin-top: 0;
}

.analytics-card__value {
    font-size: 1.75rem;
    font-weight: 700;
    margin: 0;
}

.analytics-range {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1.5rem;
}

.analytics-range a[aria-current="true"] {
    font-weight: 700;
    text-decoration: underline;
}

.site-footer {
    border-top: 1px solid var(--color-border);
    margin-top: 3rem;
}

.site-footer__row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding-block: 1.5rem;
    gap: 1rem;
    flex-wrap: wrap;
    color: var(--color-text-muted);
    font-size: 0.9rem;
}

.site-footer__row nav {
    display: flex;
    gap: 1rem;
}

.site-footer__row a {
    color: var(--color-text-muted);
}

/*
 * O icone fica no meio da linha do rodape: o <p> da esquerda e o <nav> da
 * direita crescem por igual (flex: 1) e empurram o icone para o centro
 * real, em vez de depender do space-between, que centraliza pelo espaco
 * sobrando e sai do lugar conforme o tamanho dos dois textos.
 */
.site-footer__row > p,
.site-footer__row > nav {
    flex: 1 1 0;
    margin: 0;
}

.site-footer__row > nav {
    justify-content: flex-end;
}

/* Em tela estreita as tres colunas nao cabem lado a lado — empilha tudo
   centralizado em vez de deixar "Termos de Uso" quebrar no meio. */
@media (max-width: 640px) {
    .site-footer__row {
        flex-direction: column;
        text-align: center;
    }

    .site-footer__row > p,
    .site-footer__row > nav {
        flex: 0 0 auto;
    }

    .site-footer__row > nav {
        justify-content: center;
    }
}

.site-footer__social {
    display: inline-flex;
    align-items: center;
}

.site-footer__social:hover,
.site-footer__social:focus-visible {
    color: var(--color-primary);
}

/*
 * Marca do rodape (2026-09-16). Duas imagens no HTML, uma por tema, com a
 * troca feita so por CSS — mesmo motivo do resto do projeto: o CSP nao
 * permite mutar estilo por JS. A altura e travada para o rodape nao virar
 * uma segunda tela; a largura acompanha a proporcao do desenho.
 */
.site-footer__mark {
    display: flex;
    justify-content: center;
    padding-bottom: 2rem;
}

.site-footer__mark-img {
    height: clamp(110px, 16vw, 170px);
    width: auto;
    max-width: 100%;
}

.site-footer__mark-img--dark {
    display: none;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-bs-theme="light"]) .site-footer__mark-img--light {
        display: none;
    }

    :root:not([data-bs-theme="light"]) .site-footer__mark-img--dark {
        display: block;
    }
}

:root[data-bs-theme="dark"] .site-footer__mark-img--light {
    display: none;
}

:root[data-bs-theme="dark"] .site-footer__mark-img--dark {
    display: block;
}

.error-page {
    padding-block: 5rem;
    text-align: center;
}

.error-page__correlation code {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    padding: 0.15rem 0.4rem;
    border-radius: 4px;
}

.auth-page {
    padding-block: 3.5rem;
    display: flex;
    justify-content: center;
}

.auth-card {
    width: 100%;
    max-width: 420px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 2rem;
}

.auth-card h1 {
    margin-top: 0;
    font-size: 1.5rem;
}

.auth-card__footer {
    text-align: center;
    color: var(--color-text-muted);
    font-size: 0.9rem;
    margin-top: 1rem;
}

.form-field {
    margin-bottom: 1.1rem;
}

.form-field label {
    display: block;
    font-weight: 600;
    font-size: 0.9rem;
    margin-bottom: 0.35rem;
}

.form-field input {
    width: 100%;
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background: var(--color-bg);
    color: var(--color-text);
    font-size: 1rem;
}

.form-field input:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 1px;
}

/*
 * Redimensionavel nos dois eixos (nao so vertical, que e o default do
 * navegador), mas sem estourar o pai: max-width:100% e respeitado pelo
 * proprio handle nativo de resize do navegador (nao e algo que nossa
 * pagina precise controlar via JS/CSP).
 */
.form-field textarea {
    width: 100%;
    max-width: 100%;
    min-height: 4.5rem;
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background: var(--color-bg);
    color: var(--color-text);
    font: inherit;
    resize: both;
    box-sizing: border-box;
}

.form-field textarea:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 1px;
}

.form-field__error {
    color: #b0413e;
    font-size: 0.85rem;
    margin: 0.35rem 0 0;
}

.button--block {
    display: block;
    width: 100%;
    text-align: center;
    border: none;
    cursor: pointer;
    font-size: 1rem;
}

.alert {
    padding: 0.75rem 1rem;
    border-radius: 8px;
    font-size: 0.9rem;
    margin-bottom: 1.25rem;
}

.alert--success {
    background: #e4efe6;
    color: #2f5233;
}

.alert--error {
    background: #f7e3e2;
    color: #8a2e29;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-bs-theme="light"]) .alert--success {
        background: #1e3324;
        color: #b7e0bf;
    }

    :root:not([data-bs-theme="light"]) .alert--error {
        background: #3a201f;
        color: #f0b3af;
    }
}

:root[data-bs-theme="dark"] .alert--success {
    background: #1e3324;
    color: #b7e0bf;
}

:root[data-bs-theme="dark"] .alert--error {
    background: #3a201f;
    color: #f0b3af;
}

.form-hint {
    color: var(--color-text-muted);
    font-size: 0.85rem;
    margin: 0.5rem 0;
}

.admin-lesson-stats {
    display: block;
    color: var(--color-text-muted);
    font-size: 0.8rem;
    margin-top: 0.25rem;
}

.recovery-codes {
    list-style: none;
    padding: 0;
    margin: 1.25rem 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 0.5rem;
}

.recovery-codes li {
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: 6px;
    padding: 0.5rem 0.75rem;
    text-align: center;
    font-family: monospace;
}

.stat-number {
    font-size: 2rem;
    font-weight: 700;
    margin: 0.25rem 0 0;
}

.admin-section-title {
    margin-top: 2.5rem;
}

.legal-page {
    max-width: 720px;
}

.legal-page h2 {
    margin-top: 2rem;
    font-size: 1.15rem;
}

/* Trilha de navegacao do painel (partials/admin_breadcrumb.php).
   Prefixo `admin-` de proposito: `.breadcrumb` cru e um componente do
   proprio Bootstrap 5.3 (que carrega ANTES de app.css), entao a classe
   sem prefixo herdaria display/padding/tokens --bs-breadcrumb-* dele.
   Separador desenhado com ::before no CSS, nunca um caractere no HTML —
   leitor de tela leria "barra" entre cada item. */
.admin-breadcrumb {
    margin-bottom: 1.25rem;
}

.admin-breadcrumb__list {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem 0.5rem;
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: 0.9rem;
}

.admin-breadcrumb__item {
    display: flex;
    align-items: center;
    gap: 0.35rem 0.5rem;
    color: var(--color-text-muted);
}

.admin-breadcrumb__item + .admin-breadcrumb__item::before {
    content: '/';
    color: var(--color-border);
}

.admin-breadcrumb__item a {
    color: var(--color-text-muted);
}

.admin-breadcrumb__item a:hover,
.admin-breadcrumb__item a:focus-visible {
    color: var(--color-primary);
}

.admin-breadcrumb__item [aria-current='page'] {
    color: var(--color-text);
    font-weight: 600;
}

/* Botao de voltar no topo das telas de criar/editar do painel. */
.back-link {
    margin-bottom: 1rem;
}

.back-link .button {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}

.data-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
}

.data-table th,
.data-table td {
    text-align: left;
    padding: 0.65rem 1rem;
    border-bottom: 1px solid var(--color-border);
}

.data-table th {
    background: var(--color-bg);
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--color-text-muted);
}

/* Modal de confirmacao de exclusao das listagens do painel
   (partials/delete_icon_button.php). <dialog> nativo: showModal() nao
   escreve estilo inline, que a CSP deste projeto bloqueia, e o
   ::backdrop da a camada escura sem JS de posicionamento. */
.confirm-dialog {
    width: min(92vw, 34rem);
    padding: 1.5rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    color: var(--color-text);
}

.confirm-dialog::backdrop {
    background: rgba(0, 0, 0, 0.55);
}

.confirm-dialog__title {
    margin: 0 0 0.5rem;
    font-size: 1.15rem;
}

.confirm-dialog__item {
    margin: 0 0 1rem;
    font-weight: 700;
}

.confirm-dialog__lead {
    margin: 0 0 0.5rem;
    color: var(--color-text-muted);
}

.confirm-dialog__relations {
    margin: 0 0 1rem;
    padding-left: 1.1rem;
}

.confirm-dialog__relations li {
    margin-bottom: 0.25rem;
}

.confirm-dialog__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    justify-content: flex-end;
    align-items: center;
}

/* Duas acoes lado a lado na mesma celula (editar + excluir). O seletor
   nomeia .icon-button e nao `> *`: o <dialog> de confirmacao tambem e
   filho direto dessa celula, e forcar display nele quebraria o modal
   (o navegador cuida do display do dialog sozinho, fechado ou aberto). */
.data-table__actions .icon-button {
    vertical-align: middle;
}

.data-table__actions {
    width: 6rem;
    text-align: right;
    white-space: nowrap;
}

/* Miniatura da imagem de capa nas listagens do painel (cursos, trilhas,
   aulas). Sem capa cadastrada, .admin-thumb--empty ocupa o mesmo espaco
   para a coluna nao "colapsar" e desalinhar a lista. */
.data-table__thumb-col {
    width: 88px;
}

.admin-thumb {
    display: block;
    width: 72px;
    height: 41px;
    object-fit: cover;
    border-radius: calc(var(--radius) / 2);
    border: 1px solid var(--color-border);
}

.admin-thumb--empty {
    background: var(--color-bg);
}

.two-factor-secret {
    word-break: break-all;
    font-size: 1.1rem;
}

.admin-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 1rem;
}

.admin-actions form {
    margin: 0;
}

.checkbox-option {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-weight: 400;
    margin-bottom: 0.35rem;
}

.checkbox-option input {
    width: auto;
}

.course-thumbnail-preview {
    max-width: 320px;
    border-radius: var(--radius);
    border: 1px solid var(--color-border);
    display: block;
    margin-bottom: 1rem;
}

/*
 * Um slot de imagem do site em /admin/conteudo. A previa tem um
 * tamanho base e um modificador POR SLOT, porque cada imagem aparece
 * de um jeito diferente na pagina publica: o fundo da tela inicial e
 * paisagem recortada, a ilustracao do Oraculo e um PNG transparente em
 * pe. Pagina nova com imagem de formato diferente ganha o seu
 * modificador aqui; sem ele, a previa so cai no tamanho base.
 */
.site-image-slot {
    margin-bottom: 2rem;
    padding-bottom: 2rem;
    border-bottom: 1px solid var(--color-border);
}

.site-image-slot:last-child {
    border-bottom: none;
    padding-bottom: 0;
    margin-bottom: 0;
}

/* Sem isto o nome do slot sai maior que o <h2> do cartao acima dele. */
.site-image-slot h3 {
    margin: 0 0 0.75rem;
    font-size: 1rem;
    font-weight: 600;
}

.site-image-slot__preview {
    display: block;
    width: 100%;
    max-width: 480px;
    height: auto;
    border-radius: var(--radius);
    border: 1px solid var(--color-border);
    margin-bottom: 1rem;
}

.site-image-slot__preview--intro,
.site-image-slot__preview--reveal {
    aspect-ratio: 16 / 9;
    object-fit: cover;
}

/*
 * Cor de fundo FIXA nas duas versoes da ilustracao do Oraculo, uma por
 * versao e independente do tema do painel: o traco branco sumiria no
 * painel claro e o preto no escuro, e o admin precisa ver cada arquivo
 * sobre o fundo em que ele vai aparecer de verdade.
 */
.site-image-slot__preview--oracle_light,
.site-image-slot__preview--oracle_dark {
    max-width: 220px;
    padding: 0.75rem;
}

.site-image-slot__preview--oracle_light {
    background-color: #ffffff;
}

.site-image-slot__preview--oracle_dark {
    background-color: #141414;
}

.admin-module-card {
    margin-bottom: 1.5rem;
}

.admin-inline-form {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
    margin-bottom: 0.75rem;
}

.admin-inline-form input[type="text"],
.admin-inline-form input[type="number"],
.admin-inline-form select {
    width: auto;
    flex: 1 1 160px;
    padding: 0.4rem 0.6rem;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    background: var(--color-bg);
    color: var(--color-text);
}

.admin-lesson-list {
    list-style: none;
    padding: 0;
    margin: 0 0 0.75rem;
}

.admin-lesson-list li {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
    padding: 0.5rem;
    border-top: 1px solid var(--color-border);
}

.admin-lesson-list li form {
    margin: 0;
}

/*
 * Criador rapido (curso/modulo/trilha) na tela de Aula (Etapa 2) —
 * <details>/<summary> nativo, mesmo principio zero-JS ja usado no
 * accordion publico de curso (nunca modal/JS de terceiro).
 */
.quick-create {
    margin: 0 0 1rem;
    padding: 0.5rem 0.75rem;
    border: 1px dashed var(--color-border);
    border-radius: 6px;
}

.quick-create summary {
    cursor: pointer;
    font-weight: 600;
}

.quick-create[open] summary {
    margin-bottom: 0.5rem;
}

.catalog-card {
    display: block;
    text-decoration: none;
    color: inherit;
}

.course-card-thumb {
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    border-radius: 6px;
    margin-bottom: 0.75rem;
}

.course-detail__thumb {
    max-width: 480px;
    width: 100%;
    border-radius: var(--radius);
    margin-bottom: 1.5rem;
}

.course-module {
    margin-bottom: 1.25rem;
    padding: 1rem 1.25rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
}

.course-module h3 {
    margin-top: 0;
}

.course-module ul {
    margin: 0;
    padding-left: 1.25rem;
}

.alert--info {
    background: #e3ecf3;
    color: #2c4a63;
}

.lesson-status {
    font-size: 0.8rem;
    margin-left: 0.4rem;
    color: var(--color-text-muted);
}

.lesson-status--completed {
    color: var(--color-primary);
    font-weight: 600;
}

.lesson-player {
    position: relative;
    max-width: 960px;
    margin-bottom: 1.5rem;
}

.lesson-player__facade,
.lesson-player__frame {
    position: relative;
    aspect-ratio: 16 / 9;
    background: #000;
    border-radius: var(--radius);
    overflow: hidden;
}

.lesson-player__facade img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    opacity: 0.75;
}

.lesson-player__facade[hidden],
.lesson-player__frame[hidden] {
    display: none;
}

.lesson-player__start {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.lesson-player__frame iframe {
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
}

.lesson-player__watermark {
    position: absolute;
    pointer-events: none;
    color: #fff;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
    font-size: 0.75rem;
    opacity: 0.35;
    white-space: nowrap;
}

/*
 * Posicoes fixas em vez de "top"/"left" via JS: o CSP deste projeto nao
 * tem 'unsafe-inline' em style-src, e isso bloqueia tambem mutacao de
 * estilo via JS (element.style.x), nao so o atributo style="" escrito
 * no HTML. O reposicionamento periodico da marca d'agua (ver player.js)
 * troca a CLASSE, nunca toca em .style diretamente.
 */
.lesson-player__watermark--pos-1 { top: 8%; left: 8%; }
.lesson-player__watermark--pos-2 { top: 8%; left: 70%; }
.lesson-player__watermark--pos-3 { top: 45%; left: 40%; }
.lesson-player__watermark--pos-4 { top: 80%; left: 8%; }
.lesson-player__watermark--pos-5 { top: 80%; left: 65%; }
.lesson-player__watermark--pos-6 { top: 45%; left: 8%; }

.lesson-player__error {
    margin-top: 0.75rem;
}

.lesson-player__actions {
    margin: 1rem 0;
}

.badge-completed {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 1.1rem;
    border-radius: 999px;
    background: var(--color-primary);
    color: var(--color-primary-contrast);
    font-weight: 600;
}

/*
 * Barra de progresso "desenhada": mais grossa que o default do
 * navegador, cantos arredondados, preenchimento em degrade
 * (--color-primary -> --color-primary-soft) em vez de cor solida. Ainda
 * o elemento <progress> nativo (acessivel, valor real via atributo
 * "value" — nunca CSS/JS) so com pseudo-elementos de aparencia.
 */
.progress-bar {
    width: 100%;
    height: 0.7rem;
    margin: 0.4rem 0;
    border: none;
    border-radius: 999px;
    overflow: hidden;
    background: var(--color-border);
}

.progress-bar::-webkit-progress-bar {
    background: var(--color-border);
    border-radius: 999px;
}

.progress-bar::-webkit-progress-value {
    background: linear-gradient(90deg, var(--color-primary), var(--color-primary-soft));
    border-radius: 999px;
    transition: width 0.3s ease;
}

.progress-bar::-moz-progress-bar {
    background: linear-gradient(90deg, var(--color-primary), var(--color-primary-soft));
    border-radius: 999px;
}

.learning-item {
    padding: 1rem 1.25rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    margin-bottom: 1rem;
}

.course-rating-summary {
    font-weight: 600;
    color: var(--color-primary);
}

.rating-form,
.comment-form {
    max-width: 480px;
    margin-bottom: 1.5rem;
}

.form-field__label-text {
    display: block;
    font-weight: 600;
    font-size: 0.9rem;
    margin-bottom: 0.35rem;
}

/*
 * Widget de estrelas: radios em ordem reversa (5..1) + row-reverse, ver
 * partials/star_rating_input.php para a explicacao completa do truque.
 * Radio visualmente oculto mas ainda focavel via teclado (nunca
 * display:none, que tira do foco/tab order) — padrao "sr-only".
 */
.star-rating {
    display: inline-flex;
    flex-direction: row-reverse;
    justify-content: flex-end;
    gap: 0.1rem;
}

.star-rating input {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.star-rating label {
    font-size: 1.9rem;
    line-height: 1;
    color: var(--color-border);
    cursor: pointer;
    transition: color 0.1s ease;
}

.star-rating label:hover,
.star-rating label:hover ~ label,
.star-rating input:checked ~ label {
    color: #f0b429;
}

.star-rating input:focus-visible + label {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
    border-radius: 4px;
}

.review-item,
.comment-item,
.note-item {
    padding: 0.85rem 1rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    margin-bottom: 0.75rem;
}

.comment-item--reply {
    margin-left: 2rem;
    background: var(--color-bg);
}

.review-item__meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin: 0 0 0.35rem;
}

.review-item__author,
.comment-item__author {
    font-weight: 600;
    font-size: 0.9rem;
}

.comment-item__author {
    margin: 0 0 0.35rem;
}

.review-item__rating {
    color: var(--color-primary);
    letter-spacing: 0.1em;
}

.comment-item__actions {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    margin-top: 0.5rem;
}

.comment-item__actions form {
    display: inline;
}

.comment-reply__form {
    margin-top: 0.75rem;
    max-width: 420px;
}

/*
 * Botao de icone com tooltip: sem Popper/data-bs-toggle (mesma restricao
 * de CSP ja documentada — Popper escreve estilo inline via JS). Tooltip
 * 100% CSS via atributo data-tooltip + ::after, nunca JS. aria-label
 * cobre leitor de tela (o texto do tooltip nao e lido por padrao, ja que
 * ::after com content:attr() e so visual).
 */
.icon-button {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border-radius: 999px;
    border: 1px solid var(--color-border);
    background: transparent;
    color: var(--color-text-muted);
    cursor: pointer;
}

a.icon-button {
    text-decoration: none;
}

.icon-button:hover,
.icon-button:focus-visible {
    color: var(--color-text);
    border-color: var(--color-primary);
}

.icon-button--danger:hover,
.icon-button--danger:focus-visible {
    color: #b0413e;
    border-color: #b0413e;
}

summary.icon-button {
    list-style: none;
}

summary.icon-button::-webkit-details-marker {
    display: none;
}

.icon-button[data-tooltip]::after {
    content: attr(data-tooltip);
    position: absolute;
    bottom: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%) translateY(4px);
    background: var(--color-text);
    color: var(--color-bg);
    padding: 0.3rem 0.55rem;
    border-radius: 6px;
    font-size: 0.72rem;
    font-weight: 600;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.1s ease, transform 0.1s ease;
    z-index: 5;
}

.icon-button[data-tooltip]:hover::after,
.icon-button[data-tooltip]:focus-visible::after {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}

.note-item {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 0.75rem;
}

/*
 * Cartoes de catalogo (listagem de cursos/trilhas/temas), inspirados na
 * referencia enviada pelo usuario (plataforma "AURA"): thumbnail com
 * cantos arredondados, leve elevacao no hover, selo de nivel sobreposto.
 * Trilhas/temas nao tem imagem propria no schema — usam gradiente
 * ciclico (--variant-0..3) em vez de <img> (ver partials/taxonomy_card.php).
 */
.catalog-card {
    display: block;
    text-decoration: none;
    color: inherit;
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    box-shadow: var(--shadow);
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.catalog-card:hover,
.catalog-card:focus-visible {
    transform: translateY(-3px);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.15);
}

.catalog-card__thumb {
    position: relative;
    aspect-ratio: 16 / 9;
    background: var(--color-bg);
    overflow: hidden;
}

.catalog-card__thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.catalog-card__thumb-placeholder {
    display: block;
    width: 100%;
    height: 100%;
    background: linear-gradient(135deg, var(--color-primary), var(--color-border));
}

.catalog-card__level {
    position: absolute;
    top: 0.6rem;
    right: 0.6rem;
}

.catalog-card__body {
    padding: 1rem 1.1rem;
}

.catalog-card__title {
    margin: 0 0 0.35rem;
    font-size: 1.05rem;
}

.catalog-card__rating {
    margin: 0;
    color: var(--color-text-muted);
    font-size: 0.85rem;
}

.catalog-card__rating-count {
    color: var(--color-text-muted);
}

.catalog-card--taxonomy {
    position: relative;
    aspect-ratio: 3 / 4;
    display: flex;
    align-items: flex-end;
    padding: 1rem;
    overflow: hidden;
}

.catalog-card--variant-0 { background: linear-gradient(160deg, #4d6b53, #23331f); }
.catalog-card--variant-1 { background: linear-gradient(160deg, #6b5b95, #2c2140); }
.catalog-card--variant-2 { background: linear-gradient(160deg, #4a7a8c, #1c2f38); }
.catalog-card--variant-3 { background: linear-gradient(160deg, #a56a4b, #3a2318); }

.catalog-card--taxonomy-photo {
    background: var(--color-bg);
}

/* Capa da trilha: <img> absoluta + veu escuro, nunca background-image
   inline (style-src nao tem 'unsafe-inline') — mesmo desenho de
   .course-hero__bg, que tem o mesmo problema por ser imagem por linha. */
.catalog-card__taxonomy-bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.catalog-card--taxonomy-photo::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(0deg, rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0.1) 70%);
}

.catalog-card__taxonomy-label {
    position: relative;
    color: #fff;
    font-weight: 700;
    font-size: 1.05rem;
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
}

.badge-level {
    display: inline-block;
    padding: 0.2rem 0.6rem;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
}

/*
 * Banner do topo da pagina de curso: a imagem de capa vira o fundo via
 * <img> absoluta + um gradiente por cima (NUNCA background-image inline,
 * que violaria style-src sem 'unsafe-inline' — mesmo motivo documentado
 * no scroll-hero da home, mas ali a imagem e fixa e pode ser uma classe
 * CSS; aqui e por curso, entao precisa ser um elemento real).
 */
/* .trilha-hero e o mesmo desenho do banner de curso: a imagem varia por
   linha, entao precisa ser <img> real e nao background-image inline, que
   a CSP bloqueia. So o min-height difere (override logo abaixo). */
.course-hero,
.trilha-hero {
    position: relative;
    min-height: 320px;
    display: flex;
    align-items: flex-end;
    border-radius: var(--radius);
    overflow: hidden;
    background: linear-gradient(160deg, var(--color-primary), var(--color-bg));
}

.trilha-hero {
    min-height: 260px;
}

.course-hero__bg,
.trilha-hero__bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.course-hero__overlay,
.trilha-hero__overlay {
    position: relative;
    width: 100%;
    background: linear-gradient(0deg, rgba(0, 0, 0, 0.78), rgba(0, 0, 0, 0.2) 70%);
    padding-block: 2rem;
}

.course-hero__content,
.trilha-hero__content {
    color: #fff;
}

.course-hero__content h1,
.trilha-hero__content h1 {
    margin: 0.5rem 0;
}

.course-hero__lead,
.trilha-hero__lead {
    max-width: 640px;
    opacity: 0.9;
}

.course-hero__rating {
    margin: 0.25rem 0;
}

.course-hero__taxonomy {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1rem;
    margin: 0.5rem 0 1rem;
}

.course-hero__taxonomy a {
    color: #fff;
    text-decoration: underline;
}

.course-hero__progress {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    max-width: 360px;
    margin-bottom: 1rem;
    color: #fff;
}

.course-hero__progress .progress-bar {
    flex: 1;
}

/*
 * O hero fica sobre uma foto com overlay escuro — as cores de tema
 * (--color-border/--color-primary) nao garantem contraste ali (podem
 * ficar quase invisiveis sobre a imagem, a depender do tema e da foto).
 * Override fixo em branco/verde-claro, independente do tema dia/noite.
 */
.course-hero__progress .progress-bar {
    background: rgba(255, 255, 255, 0.25);
}

.course-hero__progress .progress-bar::-webkit-progress-bar {
    background: rgba(255, 255, 255, 0.25);
}

.course-hero__progress .progress-bar::-webkit-progress-value {
    background: linear-gradient(90deg, #ffffff, #cfead4);
}

.course-hero__progress .progress-bar::-moz-progress-bar {
    background: linear-gradient(90deg, #ffffff, #cfead4);
}

/*
 * Accordion de modulos/aulas via <details>/<summary> nativo — sem
 * data-bs-toggle="collapse" do Bootstrap (que escreve estilo inline via
 * JS e esbarraria na mesma restricao de CSP ja documentada para
 * dropdown/tooltip/popover). Zero JS, zero mutacao de estilo.
 */
.course-accordion__module {
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    margin-bottom: 0.75rem;
    overflow: hidden;
}

.course-accordion__module summary {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.75rem;
    padding: 0.85rem 1.1rem;
    cursor: pointer;
    font-weight: 600;
    list-style: none;
}

.course-accordion__module summary::-webkit-details-marker {
    display: none;
}

.course-accordion__module summary::after {
    content: '⌄';
    margin-left: auto;
    transition: transform 0.15s ease;
}

.course-accordion__module[open] summary::after {
    transform: rotate(180deg);
}

.course-accordion__module-count {
    color: var(--color-text-muted);
    font-weight: 400;
    font-size: 0.85rem;
}

.course-accordion__lessons {
    list-style: none;
    margin: 0;
    padding: 0;
}

.course-accordion__lesson {
    border-top: 1px solid var(--color-border);
}

.course-accordion__lesson a,
.course-accordion__lesson-locked {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.6rem 1.1rem;
    text-decoration: none;
    color: var(--color-text);
}

.course-accordion__lesson-locked {
    color: var(--color-text-muted);
}

/*
 * Thumbnail da aula: nao existe imagem por AULA no schema (so por
 * curso), entao reusamos a capa do curso — "disponivel" e uma
 * propriedade do curso, nao da aula individual. Sem capa nenhuma, cai no
 * placeholder com icone de play.
 */
.course-accordion__lesson-thumb {
    position: relative;
    flex-shrink: 0;
    width: 76px;
    aspect-ratio: 16 / 9;
    border-radius: 6px;
    overflow: hidden;
    background: var(--color-bg);
}

.course-accordion__lesson-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.course-accordion__lesson-thumb-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    background: linear-gradient(135deg, var(--color-primary), var(--color-border));
    color: var(--color-primary-contrast);
}

.course-accordion__lesson-locked .course-accordion__lesson-thumb {
    opacity: 0.55;
}

.course-accordion__lesson-thumb-badge {
    position: absolute;
    bottom: 2px;
    right: 2px;
    width: 1.15rem;
    height: 1.15rem;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.65rem;
    font-weight: 700;
    line-height: 1;
}

.course-accordion__lesson-thumb-badge--done {
    background: var(--color-primary);
    color: var(--color-primary-contrast);
}

.course-accordion__lesson-thumb-badge--locked {
    background: rgba(0, 0, 0, 0.65);
    color: #fff;
}

.course-accordion__lesson-info {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}

.course-accordion__lesson-index {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--color-text-muted);
}

.course-accordion__lesson-title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.course-accordion__lesson-duration {
    color: var(--color-text-muted);
    font-size: 0.8rem;
    flex-shrink: 0;
}

/*
 * Layout de duas colunas do player (video + sidebar de conteudo do
 * curso), inspirado na referencia "AURA". Empilha em telas estreitas
 * (grid-template-columns de uma coluna abaixo do breakpoint lg).
 */
.player-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.25rem;
    flex-wrap: wrap;
}

.player-nav__adjacent {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.player-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 2rem;
    align-items: start;
}

@media (min-width: 992px) {
    .player-layout {
        grid-template-columns: minmax(0, 2fr) minmax(280px, 1fr);
    }
}

.player-sidebar {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 1.25rem;
}

.player-sidebar h2 {
    margin-top: 0;
    font-size: 1.05rem;
}

.playlist-search {
    width: 100%;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background: var(--color-bg);
    color: var(--color-text);
    margin-bottom: 1rem;
}

.playlist__module {
    margin-bottom: 1rem;
}

.playlist__module:last-child {
    margin-bottom: 0;
}

.playlist__module-title {
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--color-text-muted);
    margin: 0 0 0.4rem;
}

.playlist-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.6rem;
    border-radius: 8px;
    text-decoration: none;
    color: var(--color-text);
    font-size: 0.9rem;
}

.playlist-item:hover,
.playlist-item:focus-visible {
    background: var(--color-bg);
}

.playlist-item--active {
    background: var(--color-primary);
    color: var(--color-primary-contrast);
    font-weight: 600;
}

.playlist-item__status {
    width: 1.1rem;
    flex-shrink: 0;
    color: var(--color-primary);
    font-weight: 700;
}

.playlist-item--active .playlist-item__status {
    color: inherit;
}

.playlist-item__title {
    flex: 1;
}

.playlist-item__now {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    flex-shrink: 0;
}

/*
 * Oraculo do Corpo (2026-09-21). A ilustracao tem duas versoes (traco
 * preto para o tema claro, traco branco para o escuro) e a troca e so por
 * CSS, nos mesmos tres estados usados pela marca do rodape: sistema
 * claro (padrao), sistema escuro sem escolha salva, e escolha explicita
 * em [data-bs-theme].
 *
 * Desde 2026-09-21 os dois arquivos sao trocaveis pelo admin
 * (/admin/oraculo), entao o src e dinamico e precisa ser <img> de
 * verdade — nao da para fixar a URL numa classe do CSS. O CSS aqui so
 * decide qual dos dois aparece; trocar o src por JS nao e alternativa,
 * a CSP deste projeto bloqueia mutacao de estilo por script e a pagina
 * nao deve depender de JS para mostrar a arte.
 */
/*
 * Clima do Oraculo: misticismo leve em cima do yoga, so com CSS.
 *
 * Tudo aqui e animacao declarada em @keyframes e trocada por classe —
 * a CSP deste projeto nao tem 'unsafe-inline' em style-src e bloqueia
 * mutacao de `elemento.style` por JS, entao nao existe a opcao de
 * animar por script. Nenhuma biblioteca, nenhum build step.
 *
 * Os quatro pseudo-elementos (dois no .oracle__art-wrap, dois no
 * .oracle__aura) sao decoracao: halo que pulsa como respiracao, dois
 * aneis girando em sentidos opostos (mandala) e um feixe de luz
 * varrendo devagar. Ficam atras da arte com z-index negativo, presos
 * pelo `isolation: isolate` do involucro.
 *
 * O bloco @media (prefers-reduced-motion: reduce) no fim desta secao
 * desliga TODAS elas — quem pede menos movimento continua vendo a
 * pagina inteira, so parada.
 */
/*
 * O INVOLUCRO E O CIRCULO: quadrado (aspect-ratio 1), e a arte fica
 * dentro dele. Antes os aneis eram dimensionados pela LARGURA da arte
 * e, como a ilustracao e retrato (900x1181), a altura passava do
 * diametro e os cantos ficavam de fora.
 *
 * Dimensionar pela altura em vez da largura resolveria a arte de hoje,
 * mas o admin troca esse arquivo: os limites da arte abaixo cobrem
 * QUALQUER proporcao. 38rem mantem a arte do mesmo tamanho de antes num
 * desktop (76% de 608px = 462px de altura); em tela estreita o
 * `min(100%, ...)` segura tudo dentro da largura disponivel, sem
 * scroll horizontal.
 */
.oracle__art-wrap {
    position: relative;
    width: min(100%, 38rem);
    aspect-ratio: 1;
    display: grid;
    place-items: center;
    margin: 2.5rem auto;
    isolation: isolate;
}

.oracle__art-wrap::before,
.oracle__art-wrap::after,
.oracle__aura::before,
.oracle__aura::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    aspect-ratio: 1;
    border-radius: 50%;
    /* Centraliza de verdade. Fica na regra base (e nao so nos keyframes)
       porque com prefers-reduced-motion as animacoes somem e, sem isto,
       os circulos ficariam deslocados meio raio para baixo e direita. */
    transform: translate(-50%, -50%);
    z-index: -1;
}

/* Halo de incenso: respira no ritmo de uma inspiracao longa. */
.oracle__art-wrap::before {
    width: 100%;
    background: radial-gradient(circle, var(--oracle-glow) 0%, transparent 68%);
    animation: oracle-halo 7s ease-in-out infinite;
}

/* Anel externo tracejado: o circulo que contem a arte inteira. */
.oracle__art-wrap::after {
    width: 100%;
    border: 1px dashed var(--oracle-ring);
    transform: translate(-50%, -50%);
    animation: oracle-spin 54s linear infinite;
}

/* Anel interno pontilhado, girando ao contrario. */
.oracle__aura::before {
    width: 84%;
    border: 1px dotted var(--oracle-ring);
    opacity: 0.9;
    transform: translate(-50%, -50%);
    animation: oracle-spin-reverse 38s linear infinite;
}

/*
 * Dois feixes de luz atravessando o circulo, apontando para lados
 * opostos (180 graus um do outro). Sao duas cunhas do MESMO
 * conic-gradient, nao dois elementos: nao ha um quinto
 * pseudo-elemento disponivel aqui, e no mesmo gradiente os dois giram
 * sempre juntos — ficam opostos para sempre, sem risco de saírem de
 * sincronia.
 */
.oracle__aura::after {
    width: 100%;
    background: conic-gradient(
        from 0deg,
        transparent 0deg,
        var(--oracle-glow) 24deg,
        transparent 60deg,
        transparent 180deg,
        var(--oracle-glow) 204deg,
        transparent 240deg,
        transparent 360deg
    );
    opacity: 0.85;
    transform: translate(-50%, -50%);
    animation: oracle-spin 22s linear infinite;
}

/*
 * Limites escolhidos para a arte caber DENTRO do circulo qualquer que
 * seja a proporcao do arquivo enviado: a diagonal precisa ser menor que
 * o diametro, e 0.64^2 + 0.76^2 = 0.99 < 1. Com a ilustracao de hoje
 * (retrato) quem manda e a altura; a largura sai em ~58%.
 */
.oracle__art {
    display: block;
    position: relative;
    width: auto;
    max-width: 64%;
    max-height: 76%;
    animation: oracle-breathe 9s ease-in-out infinite;
}

@keyframes oracle-halo {
    0%, 100% { opacity: 0.8; transform: translate(-50%, -50%) scale(1); }
    50%      { opacity: 1;   transform: translate(-50%, -50%) scale(1.09); }
}

@keyframes oracle-spin {
    from { transform: translate(-50%, -50%) rotate(0deg); }
    to   { transform: translate(-50%, -50%) rotate(360deg); }
}

@keyframes oracle-spin-reverse {
    from { transform: translate(-50%, -50%) rotate(360deg); }
    to   { transform: translate(-50%, -50%) rotate(0deg); }
}

@keyframes oracle-breathe {
    0%, 100% { transform: translateY(0) scale(1); }
    50%      { transform: translateY(-10px) scale(1.015); }
}

.oracle__art--dark {
    display: none;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-bs-theme="light"]) .oracle__art--light {
        display: none;
    }

    :root:not([data-bs-theme="light"]) .oracle__art--dark {
        display: block;
    }
}

:root[data-bs-theme="dark"] .oracle__art--light {
    display: none;
}

:root[data-bs-theme="dark"] .oracle__art--dark {
    display: block;
}

.oracle {
    text-align: center;
}

/*
 * Botao de consulta: aura que pulsa como um convite. O anel cresce em
 * box-shadow (nao em tamanho real), entao nao empurra nada ao redor.
 */
.oracle__draw {
    position: relative;
    letter-spacing: 0.02em;
    animation: oracle-aura 3.4s ease-out infinite;
}

.oracle__draw:hover,
.oracle__draw:focus-visible {
    animation-play-state: paused;
}

@keyframes oracle-aura {
    0%   { box-shadow: 0 0 0 0 var(--oracle-glow); }
    70%  { box-shadow: 0 0 0 16px rgba(0, 0, 0, 0); }
    100% { box-shadow: 0 0 0 0 rgba(0, 0, 0, 0); }
}

/*
 * A carta do dia: sobe como quem vira uma carta de tara, e um brilho
 * atravessa a superficie uma unica vez logo depois (`both` + contagem 1,
 * nunca em laco — seria distracao numa pagina de pratica).
 */
.oracle__result {
    max-width: 40rem;
    margin-inline: auto;
    position: relative;
    overflow: hidden;
    animation: oracle-card-in 0.7s cubic-bezier(0.2, 0.8, 0.25, 1) both;
}

.oracle__result::after {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(105deg, transparent 38%, var(--oracle-sheen) 50%, transparent 62%);
    animation: oracle-sheen 2.2s ease-out 0.45s 1 both;
}

@keyframes oracle-card-in {
    from { opacity: 0; transform: perspective(900px) translateY(20px) scale(0.96) rotateX(9deg); }
    to   { opacity: 1; transform: perspective(900px) translateY(0) scale(1) rotateX(0deg); }
}

@keyframes oracle-sheen {
    from { opacity: 1; transform: translateX(-130%); }
    to   { opacity: 0; transform: translateX(130%); }
}

.oracle__lesson-title {
    font-size: 1.35rem;
    font-weight: 600;
}

.oracle__reset {
    color: var(--color-text-muted);
    font-size: 0.9rem;
    margin-bottom: 0;
}

/*
 * Modal da aula sorteada (<dialog> nativo). Visual proposital minimo:
 * cor, animacao e acabamento entram numa rodada futura, sem mexer na
 * mecanica de reproducao. Os tokens sao os mesmos do resto do site,
 * entao ele ja acompanha os tres estados de tema sem regra extra.
 *
 * <dialog> ja e display:none enquanto fechado — nao ha `hidden`/.style
 * envolvido aqui (a CSP bloquearia a segunda opcao de qualquer jeito).
 */
.oracle-modal {
    width: min(92vw, 860px);
    max-height: 92vh;
    padding: 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    color: var(--color-text);
    overflow: auto;
}

/*
 * Abertura: o veu escurece a pagina e a carta sobe girando de leve, como
 * uma carta sendo virada na mesa. So a ABERTURA e animada — fechar com
 * animacao exigiria `transition-behavior: allow-discrete`, que ainda nao
 * e confiavel em todo navegador; sem ele o dialog some antes da animacao
 * rodar, o que fica pior que fechar seco.
 *
 * O `perspective()` vai dentro do proprio transform: <dialog> vive na
 * top layer e nao tem pai util onde declarar a perspectiva.
 */
.oracle-modal[open] {
    animation: oracle-modal-in 0.5s cubic-bezier(0.2, 0.8, 0.25, 1) both;
}

.oracle-modal::backdrop {
    background:
        radial-gradient(circle at 50% 28%, var(--oracle-glow), transparent 55%),
        var(--oracle-veil);
    backdrop-filter: blur(3px);
}

.oracle-modal[open]::backdrop {
    animation: oracle-veil-in 0.4s ease both;
}

@keyframes oracle-modal-in {
    from { opacity: 0; transform: perspective(1000px) translateY(28px) scale(0.92) rotateX(11deg); }
    to   { opacity: 1; transform: perspective(1000px) translateY(0) scale(1) rotateX(0deg); }
}

@keyframes oracle-veil-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

.oracle-modal__box {
    padding: 1.5rem;
}

/* Fio de luz no topo da carta, no lugar de uma borda seca. */
.oracle-modal__box::before {
    content: '';
    display: block;
    height: 3px;
    margin: -1.5rem -1.5rem 1.25rem;
    background: linear-gradient(90deg, transparent, var(--oracle-ring) 20%, var(--color-primary) 50%, var(--oracle-ring) 80%, transparent);
}

/*
 * A aula do Oraculo quase nunca tem capa propria (ela nao precisa estar
 * em curso nenhum), e o preto liso do player fica duro dentro da carta.
 * Aqui a fachada vira uma penumbra com brilho — mesmo clima do halo da
 * ilustracao. Quando a aula TEM capa, a imagem entra por cima disto e o
 * degrade nem aparece.
 */
.oracle-modal .lesson-player__facade {
    background:
        radial-gradient(circle at 50% 38%, var(--oracle-glow), transparent 62%),
        #141019;
}

.oracle-modal .lesson-player {
    margin-bottom: 1rem;
}

.oracle-modal__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1rem;
}

.oracle-modal__head h2 {
    margin: 0;
    font-size: 1.25rem;
    text-align: left;
}

/*
 * Quem pede menos movimento no sistema continua vendo a pagina inteira
 * (halo, aneis, veu, fio de luz) — so parada. Nada some, nada muda de
 * lugar: o clima vem da cor e da forma, a animacao e o extra.
 */
@media (prefers-reduced-motion: reduce) {
    .oracle__art,
    .oracle__art-wrap::before,
    .oracle__art-wrap::after,
    .oracle__aura::before,
    .oracle__aura::after,
    .oracle__draw,
    .oracle__result,
    .oracle__result::after,
    .oracle-modal[open],
    .oracle-modal[open]::backdrop {
        animation: none;
    }

    .oracle__result::after {
        opacity: 0;
    }
}

/*
 * Retrato do usuario (2026-09-21). Sempre circulo, em tres tamanhos.
 *
 * A cor de fundo da marca padrao e uma CLASSE por slug da paleta
 * (Domain\Identity\Avatar::COLORS), nunca um hex vindo do banco num
 * `style=""` — style-src deste projeto nao tem 'unsafe-inline' e o
 * atributo nao pintaria. As cores sao FIXAS nos dois temas de
 * proposito: e uma escolha da pessoa, nao uma cor de marca, e nao
 * deveria mudar quando alguem troca dia/noite.
 */
.avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    border-radius: 50%;
    overflow: hidden;
    object-fit: cover;
    background-color: var(--color-border);
    vertical-align: middle;
}

.avatar--sm {
    width: 2rem;
    height: 2rem;
}

.avatar--md {
    width: 3rem;
    height: 3rem;
}

.avatar--lg {
    width: 7rem;
    height: 7rem;
}

.avatar__mark {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.avatar--cor-areia { background-color: #d9c9a8; }
.avatar--cor-argila { background-color: #d8a78b; }
.avatar--cor-rosa { background-color: #e0a9b4; }
.avatar--cor-lilas { background-color: #c3b0dd; }
.avatar--cor-salvia { background-color: #a9c4a4; }
.avatar--cor-ceu { background-color: #a5c3d9; }
.avatar--cor-ambar { background-color: #e5c07b; }
.avatar--cor-pedra { background-color: #c2bdb4; }

/* O retrato entra no gatilho do menu, antes do nome. */
.user-menu__trigger {
    padding-left: 0.35rem;
}

/* Autoria de comentario e avaliacao: retrato colado ao nome. */
.comment-item__author,
.moderation-item__author,
.review-item__meta {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

/* A linha de moderacao quebra em telas estreitas; o retrato nao encolhe. */
.moderation-item__author {
    flex-wrap: wrap;
}

/*
 * Editor de recorte. O <canvas> desenha a previa inteira (foto, mascara
 * circular e contorno) — arrastar/ampliar mexendo em `elemento.style`
 * seria o caminho comum, mas a CSP bloqueia isso; canvas nao encosta em
 * estilo. `touch-action: none` para o arraste de dedo mover o
 * enquadramento em vez de rolar a pagina.
 */
.avatar-editor__stage {
    margin: 1.5rem 0;
    max-width: 22rem;
}

.avatar-editor__title {
    font-weight: 600;
    margin-bottom: 0.5rem;
}

.avatar-editor__canvas {
    display: block;
    width: 100%;
    max-width: 20rem;
    height: auto;
    aspect-ratio: 1 / 1;
    border-radius: var(--radius);
    border: 1px solid var(--color-border);
    background-color: var(--color-bg);
    touch-action: none;
    cursor: grab;
}

.avatar-editor__canvas:active {
    cursor: grabbing;
}

.avatar-editor__hint {
    color: var(--color-text-muted);
    font-size: 0.9rem;
    margin-top: 0.5rem;
}

/* Seletor de cor: um radio por cor, o proprio circulo e o rotulo visual. */
.color-choice {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    margin-bottom: 1.5rem;
}

.color-choice__option {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.35rem;
    cursor: pointer;
    font-size: 0.85rem;
    color: var(--color-text-muted);
}

.color-choice__swatch {
    display: block;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: 50%;
    border: 2px solid transparent;
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08);
}

/*
 * O radio fica visualmente escondido mas continua no tab order (nunca
 * display:none, que o tiraria do teclado) — mesmo padrao das estrelas
 * de avaliacao.
 */
.color-choice__option input {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.color-choice__option input:checked + .color-choice__swatch {
    border-color: var(--color-text);
}

.color-choice__option input:focus-visible + .color-choice__swatch {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

.color-choice__option input:checked ~ .color-choice__label {
    color: var(--color-text);
    font-weight: 600;
}

/*
 * Area "Minha conta" (2026-09-21). Antes cada tela de conta era um <h1>
 * solto direto dentro de <main>: sem container, o texto encostava na
 * borda da janela e nao tinha respiro nenhum — o resto do site sempre
 * usou `.container .section`. Agora as cinco telas (perfil,
 * aprendizado, assinatura, seguranca e privacidade) compartilham o
 * mesmo cabecalho de identidade e um menu lateral, para deixarem de ser
 * becos sem saida alcancaveis so pelo menu do topo.
 */
.account__head {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding-bottom: 1.5rem;
    margin-bottom: 2rem;
    border-bottom: 1px solid var(--color-border);
}

.account__eyebrow {
    margin: 0;
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-text-muted);
}

.account__person {
    margin: 0.15rem 0 0;
    font-size: 1.25rem;
    font-weight: 600;
}

.side-layout {
    display: grid;
    grid-template-columns: 14rem 1fr;
    gap: 2.5rem;
    align-items: start;
}

.side-layout__nav {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    position: sticky;
    top: 6rem;
}

.side-layout__nav-item {
    display: block;
    padding: 0.6rem 0.85rem;
    border-radius: var(--radius);
    border-left: 3px solid transparent;
    color: var(--color-text-muted);
    text-decoration: none;
}

.side-layout__nav-item:hover,
.side-layout__nav-item:focus-visible {
    background: var(--color-surface);
    color: var(--color-text);
}

.side-layout__nav-item--current {
    border-left-color: var(--color-primary);
    background: var(--color-surface);
    color: var(--color-text);
    font-weight: 600;
}

.side-layout__content h1 {
    margin-top: 0;
}

.account__intro {
    color: var(--color-text-muted);
    max-width: 48rem;
}

.side-layout__content .card + .card {
    margin-top: 1.5rem;
}

/*
 * `.section h2` centraliza e da 2rem de respiro — faz sentido num
 * titulo de secao da home, nao no titulo de um cartao de formulario
 * alinhado a esquerda. A coluna de conteudo da o pontinho de
 * especificidade que reverte isso, na area da conta e no /admin/conteudo.
 */
.side-layout__content .card h2 {
    margin-top: 0;
    margin-bottom: 0.75rem;
    font-size: 1.15rem;
    text-align: left;
}


.account__empty {
    text-align: center;
}

.account__list {
    margin: 0;
    padding-left: 1.2rem;
}

/*
 * Cartao de acao irreversivel (excluir conta, desativar 2FA). Antes
 * essas acoes tinham exatamente o mesmo peso visual de "exportar meus
 * dados"; a borda e o titulo em vermelho existem para a pessoa parar
 * antes de clicar.
 */
.card--danger {
    border-color: var(--color-danger-border);
    background: var(--color-danger-surface);
}

.card--danger h2 {
    color: var(--color-danger);
}

.button--danger {
    background: var(--color-danger);
    border-color: var(--color-danger);
    /*
     * Nunca #fff fixo: no tema escuro --color-danger vira um salmao
     * claro e texto branco em cima da ~2.4:1, abaixo de qualquer piso
     * de contraste. Mesmo padrao de --color-primary-contrast.
     */
    color: var(--color-danger-contrast);
}

.button--danger:hover,
.button--danger:focus-visible {
    filter: brightness(0.92);
}

.button--sm {
    padding: 0.35rem 0.8rem;
    font-size: 0.85rem;
}

/* Tabela dentro de cartao nao pode empurrar a coluna em tela estreita. */
.table-scroll {
    overflow-x: auto;
}

/* Lista de rotulo/valor (assinatura, detalhes de admin). Nunca teve regra: a classe antiga era "admin-detail-list" e nao existia no CSS. */
.detail-list {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.5rem 1.5rem;
    margin: 0;
}

.detail-list dt {
    color: var(--color-text-muted);
    font-size: 0.9rem;
}

.detail-list dd {
    margin: 0;
    font-weight: 600;
}

/* Perfil: retrato atual ao lado do formulario de troca. */
.profile-photo {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 2rem;
    align-items: start;
}

.profile-photo__preview {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
}

.avatar-editor__controls {
    display: flex;
    align-items: flex-end;
    gap: 1rem;
    flex-wrap: wrap;
}

.avatar-editor__controls .form-field {
    flex: 1;
    min-width: 10rem;
    margin-bottom: 0;
}

@media (max-width: 991px) {
    .side-layout {
        grid-template-columns: 1fr;
        gap: 1.5rem;
    }

    /* Em coluna unica o menu vira uma fileira rolavel acima do conteudo. */
    .side-layout__nav {
        position: static;
        flex-direction: row;
        flex-wrap: nowrap;
        overflow-x: auto;
        gap: 0.5rem;
        padding-bottom: 0.5rem;
    }

    .side-layout__nav-item {
        border-left: 0;
        border-bottom: 3px solid transparent;
        white-space: nowrap;
    }

    .side-layout__nav-item--current {
        border-left-color: transparent;
        border-bottom-color: var(--color-primary);
    }

    .profile-photo {
        grid-template-columns: 1fr;
        gap: 1.5rem;
    }

    .profile-photo__preview {
        align-items: flex-start;
    }
}

/* Vitrine publica de planos (/planos). Cartao reusa .card; so o preco
   precisa de regra propria — numero grande com a periodicidade discreta
   ao lado, sem inventar um componente novo para isso. */
.plan-card__price {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    margin: 0 0 0.75rem;
}

.plan-card__price strong {
    font-size: 1.6rem;
    color: var(--color-primary);
}

.plan-card__price span {
    font-size: 0.9rem;
    color: var(--color-text-muted);
}
