/* Estilos base do portal — usam apenas tokens (nada de cor fixa solta). */
* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: var(--font);
    font-size: var(--fs-body);
    background: var(--color-bg);
    color: var(--color-text);
    line-height: var(--lh-base);
    -webkit-font-smoothing: antialiased;
}

/* Tipografia de títulos (Onda 1) */
h1, h2, h3 { font-family: var(--font-display); line-height: var(--lh-snug); }

/* Foco de teclado visível — vale p/ link, botão, input, [tabindex] (Onda 1) */
:focus-visible {
    outline: none;
    box-shadow: var(--ring);
    border-radius: var(--radius-sm);
}
:focus:not(:focus-visible) { outline: none; } /* sem anel ao clicar com o mouse */

/* Skeleton de carregamento (Onda 1) */
@keyframes gu-shimmer {
    0%   { background-position: -200% 0; }
    100% { background-position:  200% 0; }
}
.skel {
    background: linear-gradient(90deg,
        var(--color-surface-2) 25%, var(--color-border) 37%, var(--color-surface-2) 63%);
    background-size: 200% 100%;
    animation: gu-shimmer 1.4s ease-in-out infinite;
    border-radius: var(--radius-sm);
}
@media (prefers-reduced-motion: reduce) {
    .skel { animation: none; }
}

.site-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-2) var(--space-3);
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
}
.site-header .brand { display: flex; flex-direction: column; line-height: 1.1; }
.site-header .brand-name { font-weight: 700; font-size: 1.05rem; }
.site-header .brand-tagline { font-size: .72rem; color: var(--color-text-muted); }
.site-header .nav a { color: var(--color-brand); text-decoration: none; font-weight: 600; }

.container {
    max-width: 760px;
    margin: var(--space-3) auto;
    padding: 0 var(--space-2);
    display: grid;
    gap: var(--space-3);
}

.card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: var(--space-3);
}
.card h1 { margin: var(--space-1) 0; font-size: 1.6rem; }
.card h2 { margin-top: 0; font-size: 1.2rem; }

.badge {
    display: inline-block;
    background: var(--color-brand);
    color: var(--color-on-brand);
    border-radius: var(--radius-pill);
    padding: 4px 12px;
    font-size: .8rem;
    font-weight: 600;
}

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 44px;
    background: var(--color-brand);
    color: var(--color-on-brand);
    border: none;
    border-radius: var(--radius-pill);
    padding: 12px 22px;
    font-size: .95rem;
    font-weight: var(--fw-bold);
    cursor: pointer;
    transition: background var(--dur-1), box-shadow var(--dur-1), transform var(--dur-1);
}
.btn:hover { background: var(--color-brand-strong); }
.btn:active { transform: translateY(1px); }

.ping { margin-top: var(--space-1); }
.muted { color: var(--color-text-muted); }

.steps { padding-left: 1.2rem; }
.steps li { margin-bottom: var(--space-1); }

code {
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: 4px;
    padding: 1px 6px;
    font-size: .9em;
}

.site-footer {
    text-align: center;
    padding: var(--space-3);
    font-size: .85rem;
}
.footer-about {
    max-width: 580px;
    margin: 0 auto var(--space-1);
    color: var(--color-text-muted);
}
.footer-about strong { color: var(--color-text); }

/* ---- Navegacao (estado de login) ---- */
.site-header .brand { text-decoration: none; color: inherit; }
.nav { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.nav-group { display: inline-flex; align-items: center; gap: var(--space-2); }
.nav-cta { background: var(--color-brand); color: var(--color-on-brand) !important; padding: 6px 12px; border-radius: var(--radius-sm); }
.nav-cta:hover { background: var(--color-brand-strong); }
.nav-logout { display: inline; margin: 0; }
.linklike {
    background: none; border: none; padding: 0;
    color: var(--color-brand); font-weight: 600; font-size: 1rem;
    font-family: inherit; cursor: pointer;
}
.linklike:hover { text-decoration: underline; }

/* ---- Formularios ---- */
.container-narrow { max-width: 520px; }
.form-field { display: flex; flex-direction: column; gap: 4px; margin-bottom: var(--space-2); }
.form-field label { font-weight: 600; font-size: .9rem; }
.form-field input,
.form-field select,
.form-field textarea {
    padding: 10px 12px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font-size: .95rem;
    font-family: inherit;
    background: var(--color-surface);
}
.form-field textarea { resize: vertical; }
.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus {
    outline: 2px solid var(--color-brand);
    outline-offset: 1px;
    border-color: var(--color-brand);
}
.form-check { flex-direction: row; align-items: center; gap: 8px; }
.form-check input { width: auto; }
.form-check label { font-weight: 400; }
.field-error { color: var(--color-danger-text); font-size: .82rem; }
.field-hint { color: var(--color-text-muted); font-size: .8rem; }
.req { color: var(--color-danger-text); font-weight: 700; }
.required-legend { font-size: .8rem; color: var(--color-text-muted); margin: 0 0 var(--space-2); }
input[aria-invalid='true'] { border-color: var(--color-danger); }
.minor-notice {
    background: var(--color-warning-bg);
    border: 1px solid var(--color-warning-border);
    color: var(--color-warning-text);
    padding: 8px 12px;
    border-radius: var(--radius-sm);
    font-size: .85rem;
    margin-bottom: var(--space-1);
}
.guardian-box {
    border: 1px solid var(--color-brand);
    border-radius: var(--radius-sm);
    padding: var(--space-2);
    margin-bottom: var(--space-2);
}
.guardian-box[hidden] { display: none; }
.guardian-box legend { font-weight: 600; font-size: .85rem; padding: 0 6px; }
.auth-links { margin-top: var(--space-2); font-size: .9rem; }

/* ---- Alerts ---- */
.alert { display: flex; gap: 10px; align-items: flex-start; padding: 12px 14px; border-radius: var(--radius-sm); font-size: var(--fs-sm); line-height: 1.5; margin-bottom: var(--space-2); }
.alert svg { flex-shrink: 0; }
.alert-error { background: var(--color-danger-bg); color: var(--color-danger-text); border: 1px solid var(--color-danger-border); }
.alert-ok, .alert-success { background: var(--color-success-bg); color: var(--color-success-text); border: 1px solid var(--color-success-border); }
.alert-warning { background: var(--color-warning-bg); color: var(--color-warning-text); border: 1px solid var(--color-warning-border); }
.alert-info { background: var(--color-info-bg); color: var(--color-info-text); border: 1px solid var(--color-info-border); }

/* ---- Botao secundario ---- */
.btn-secondary { background: var(--color-surface); color: var(--color-text); border: 1px solid var(--color-border); }
.btn-secondary:hover { background: var(--color-bg); }
.btn-danger { background: var(--color-surface); color: var(--color-danger-text); border: 1px solid var(--color-danger); }
.btn-danger:hover { background: var(--color-danger-bg); }
.btn-ghost { background: transparent; color: var(--color-text); border: 1.5px solid var(--color-border-strong); }
.btn-ghost:hover { border-color: var(--color-brand); color: var(--color-brand-ink); }
.btn-sm { min-height: 36px; padding: 9px 16px; font-size: var(--fs-sm); }
.theme-toggle { margin-left: var(--space-1); }

/* Conteudo so para leitor de tela (acessibilidade). */
.sr-only, .gu-visually-hidden {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ---- Lista de dados (painel) ---- */
.data-list { display: grid; grid-template-columns: auto 1fr; gap: 6px 16px; margin: var(--space-2) 0; }
.data-list dt { font-weight: 600; color: var(--color-text-muted); }
.data-list dd { margin: 0; }

/* ---- Catalogo ---- */
.catalog-toolbar {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-2);
    flex-wrap: wrap;
    margin-bottom: var(--space-2);
}
.search-box { position: relative; min-width: 240px; flex: 1; max-width: 320px; margin: 0; }
.search-box input {
    width: 100%;
    padding: 11px 14px;
    border: 1.5px solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    color: var(--color-text);
    font-family: inherit;
    font-size: .95rem;
}
.search-box input:focus { outline: 2px solid var(--color-brand); outline-offset: 1px; border-color: var(--color-brand); }

.chips { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: var(--space-3); }
.chip {
    padding: 5px 12px;
    border-radius: 999px;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    color: var(--color-text-muted);
    text-decoration: none;
    font-size: .85rem;
}
.chip:hover { border-color: var(--color-brand); color: var(--color-text); }
.chip-active { border-color: var(--color-brand); background: var(--color-brand); color: var(--color-on-brand); }

.course-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: var(--space-2);
}
.course-card {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    text-decoration: none;
    color: inherit;
    transition: transform var(--dur-1), box-shadow var(--dur-1), border-color var(--dur-1);
}
.course-card:hover { transform: translateY(-2px); border-color: var(--color-border-strong); box-shadow: var(--shadow); }
.course-card-media {
    display: flex; align-items: flex-start; justify-content: flex-end;
    min-height: 76px; padding: var(--space-2);
    background: var(--color-surface-2); border-bottom: 1px solid var(--color-border);
}
.course-card-body { display: flex; flex-direction: column; gap: 6px; padding: var(--space-2); flex: 1; }
.course-card-cat { font-size: var(--fs-caption); font-weight: var(--fw-bold); letter-spacing: .04em; text-transform: uppercase; color: var(--color-brand-ink); }
.course-card-title { font-family: var(--font-display); font-size: var(--fs-h3); font-weight: var(--fw-bold); line-height: 1.25; margin: 0; color: var(--color-text); }
.course-card-summary { font-size: var(--fs-sm); color: var(--color-text-muted); margin: 0; }
.course-card-meta { margin-top: auto; padding-top: var(--space-1); font-size: var(--fs-caption); color: var(--color-text-soft); }
/* detalhe ainda usa .course-card-top + .cat */
.course-card-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.card .cat { font-size: var(--fs-caption); color: var(--color-text-muted); }
.course-description { margin: var(--space-2) 0; line-height: 1.6; }
.catalog-empty { text-align: center; padding: var(--space-3); color: var(--color-text-muted); }

/* ---- Estados (componentes reutilizaveis: vazio/carregando) ---- */
.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--space-2); }
.estado { text-align: center; padding: 56px 24px; background: var(--color-surface); border: 1px dashed var(--color-border-strong); border-radius: var(--radius-lg); }
.estado-icon { width: 60px; height: 60px; border-radius: 18px; background: var(--color-surface-2); color: var(--color-text-soft); display: inline-flex; align-items: center; justify-content: center; margin-bottom: 16px; }
.estado h3 { font-family: var(--font-display); font-size: var(--fs-h3); margin: 0 0 8px; color: var(--color-text); }
.estado p { font-size: var(--fs-body); color: var(--color-text-muted); max-width: 34em; margin: 0 auto 20px; }

.course-badge {
    font-size: .72rem;
    font-weight: 600;
    padding: 3px 10px;
    border-radius: 999px;
    white-space: nowrap;
}
.badge-free { background: var(--color-free-bg); color: var(--color-free-text); }
.badge-paid { background: var(--color-paid-bg); color: var(--color-paid-text); }
.badge-directed { background: var(--color-directed-bg); color: var(--color-directed-text); border: 1px solid var(--color-directed-border); }
.badge-directed::before { content: "\2605 "; } /* estrela: ícone + cor (não só cor) */

.btn:disabled { opacity: .55; cursor: not-allowed; }

/* ---- Player de curso ---- */
.progress-row { display: flex; align-items: center; gap: 12px; margin: var(--space-1) 0 var(--space-3); }
.progress-track { flex: 1; height: 8px; background: var(--color-bg); border: 1px solid var(--color-border); border-radius: 999px; overflow: hidden; }
.progress-fill { height: 100%; background: var(--color-progress); border-radius: var(--radius-pill); transition: width var(--dur-2) var(--ease-out); }
.progress-label { font-size: .85rem; color: var(--color-text-muted); white-space: nowrap; }

.player-grid { display: grid; grid-template-columns: minmax(0, 220px) minmax(0, 1fr); gap: var(--space-3); align-items: start; }
.lesson-list { display: flex; flex-direction: column; gap: 2px; }
.lesson {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 12px; border-radius: var(--radius-sm);
    text-decoration: none; color: var(--color-text); font-size: .9rem;
}
.lesson:hover { background: var(--color-surface-2); }
.lesson[aria-current='true'] { background: var(--color-brand-soft); color: var(--color-brand-ink); font-weight: 600; }
.lesson.done { color: var(--color-text-muted); }
.lesson-ico { width: 16px; height: 16px; border-radius: 50%; border: 2px solid var(--color-border); flex: none; }
.lesson.done .lesson-ico { background: var(--color-success); border-color: var(--color-success); }

.player-main { min-width: 0; }
.player-box {
    aspect-ratio: 16 / 9;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
    display: flex; align-items: center; justify-content: center;
}
.player-video { width: 100%; height: 100%; border: 0; }

@media (max-width: 640px) {
    .player-grid { grid-template-columns: 1fr; }
}

/* ---- Admin/empresa/auditoria: listas de linhas ----
   As telas migraram para .gu-table (tabela alinhada no desktop, vira card no
   estreito). O padrao antigo .approw (display:flex) foi REMOVIDO: quando ficou
   numa <tr class="approw"> dentro de .gu-table, o flex vencia o table-row SEM
   media query e quebrava a tabela no desktop (cabecalho orfao, linha espremida).
   Se precisar de uma lista em cartoes-grade, use .gu-approw (grid). */

/* ---- Prova: alternativas ---- */
.alt-box { border: 1px solid var(--color-border); border-radius: var(--radius-sm); padding: var(--space-2); margin-bottom: var(--space-2); }
.alt-box legend { font-weight: 600; font-size: .85rem; padding: 0 6px; }
.alt-row { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.alt-row input[type="text"] {
    flex: 1; padding: 10px 12px;
    border: 1px solid var(--color-border); border-radius: var(--radius-sm);
    font-family: inherit; font-size: .95rem;
}
.alt-row input[type="text"]:focus { outline: 2px solid var(--color-brand); outline-offset: 1px; border-color: var(--color-brand); }
.alt-row input[type="radio"] { width: auto; flex: none; }
.alt-letter {
    width: 24px; height: 24px; border-radius: 50%;
    background: var(--color-bg);
    display: inline-flex; align-items: center; justify-content: center;
    font-size: .8rem; font-weight: 600; flex: none;
}

/* ---- Prova do aluno ---- */
.q {
    border: 1px solid var(--color-border); border-radius: var(--radius);
    background: var(--color-surface); padding: var(--space-2); margin-bottom: var(--space-2);
}
.q-statement { font-weight: 600; margin: 0 0 10px; }
.opt { display: flex; align-items: center; gap: 10px; padding: 7px 0; cursor: pointer; }
.opt input[type="radio"] { flex: none; }
.opt .lt {
    width: 22px; height: 22px; border-radius: 50%;
    background: var(--color-bg);
    display: inline-flex; align-items: center; justify-content: center;
    font-size: .75rem; font-weight: 600; flex: none;
}

/* ---- Certificado ---- */
.result-score { font-family: var(--font-display); font-size: var(--fs-display); font-weight: var(--fw-x); line-height: 1; margin: var(--space-1) 0; color: var(--color-brand-ink); }

.cert-actions { display: flex; gap: 10px; justify-content: flex-end; flex-wrap: wrap; margin-bottom: var(--space-2); }
.cert {
    max-width: 640px; margin: 0 auto;
    border: 2px solid var(--color-border); border-top: 5px solid var(--color-brand); border-radius: var(--radius);
    padding: 40px 32px; text-align: center;
    background: var(--color-surface); box-shadow: var(--shadow);
}
.cert-eyebrow { letter-spacing: .16em; text-transform: uppercase; font-size: .72rem; color: var(--color-text-muted); margin: 0 0 18px; }
.cert-intro { font-size: .95rem; color: var(--color-text-muted); margin: 10px 0 2px; }
.cert-name { font-family: var(--font-display); font-size: 1.9rem; font-weight: var(--fw-x); margin: 4px 0; color: var(--color-brand-ink); }
.cert-course { font-size: 1.2rem; font-weight: 600; margin: 4px 0; color: var(--color-text); }
.cert-rule { height: 1px; background: var(--color-border); width: 70%; margin: 24px auto; }
.cert-meta { font-size: .8rem; color: var(--color-text-muted); margin: 3px 0; word-break: break-word; }
.cert code { background: var(--color-bg); padding: 2px 8px; border-radius: 6px; font-size: .8rem; }
@media print {
    header, footer, .cert-actions { display: none !important; }
    .cert { border-color: var(--color-text-muted); box-shadow: none; }
}

/* ---- Admin: subnav + liberação de acesso ---- */
.admin-subnav { display: flex; gap: 18px; font-size: .9rem; margin-bottom: var(--space-3); border-bottom: 1px solid var(--color-border); padding-bottom: 10px; }
.admin-subnav a { color: var(--color-text-muted); text-decoration: none; padding-bottom: 10px; margin-bottom: -11px; }
.admin-subnav a.on { color: var(--color-brand); font-weight: 600; border-bottom: 2px solid var(--color-brand); }
.grant-form { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.grant-field { flex: 1; min-width: 240px; }
.grant-field label { display: block; font-size: .8rem; color: var(--color-text-muted); margin-bottom: 5px; }
.grant-field input { width: 100%; box-sizing: border-box; }
.pill { display: inline-block; font-size: .65rem; text-transform: uppercase; letter-spacing: .04em; padding: 1px 7px; border-radius: 20px; background: var(--color-bg); color: var(--color-text-muted); border: 1px solid var(--color-border); vertical-align: middle; }

/* ---- Gerar questões com IA ---- */
.ai-card { border: 1px solid var(--color-border); border-radius: var(--radius); background: var(--color-bg); padding: 16px 18px; margin-bottom: var(--space-3); }
.ai-head { display: flex; align-items: center; gap: 8px; font-weight: 600; margin-bottom: 4px; }
.ai-badge { font-size: .62rem; text-transform: uppercase; letter-spacing: .06em; background: var(--color-surface); color: var(--color-brand-ink); border: 1px solid var(--color-border); border-radius: 20px; padding: 2px 8px; }
.ai-sub { font-size: .8rem; color: var(--color-text-muted); margin: 0 0 12px; }
.ai-form { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.ai-tema { flex: 1; min-width: 220px; }
.ai-tema label, .ai-qtd label { display: block; font-size: .8rem; color: var(--color-text-muted); margin-bottom: 4px; }
.ai-tema input { width: 100%; box-sizing: border-box; }
.ai-qtd input { width: 72px; }

/* ---- Configurações (admin) ---- */
.cfg-field { margin-bottom: var(--space-2); max-width: 480px; }
.cfg-field label { display: block; font-size: .85rem; color: var(--color-text-muted); margin-bottom: 5px; }
.cfg-field input, .cfg-field select { width: 100%; box-sizing: border-box; }

/* =============================================================================
   Sistema gu-* — componentes do protótipo (Direção B). As telas migram p/ estes.
   Base scoped em .gu-app: ao reconstruir cada tela, por class="gu-app" no <body>.
   ============================================================================= */
.gu-app { font-family: var(--font-sans); color: var(--color-text); background: var(--color-bg); -webkit-font-smoothing: antialiased; }
.gu-app *::selection { background: var(--color-brand-soft-2); }
.gu-app :focus-visible { outline: none; box-shadow: var(--ring); border-radius: 8px; }
.gu-app a { color: inherit; text-decoration: none; }
.gu-link { color: var(--color-brand-ink); font-weight: var(--fw-semi); cursor: pointer; }
.gu-link:hover { text-decoration: underline; }

.gu-btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; font-family: var(--font-sans); font-weight: var(--fw-bold); font-size: var(--fs-body); line-height: 1; cursor: pointer; border: none; border-radius: var(--radius-pill); padding: 14px 24px; transition: transform .12s, background .15s, box-shadow .15s; }
/* Pressão tátil no clique: o botão encolhe de leve (scale .97), ~120ms (transition do próprio
   .gu-btn). Só transform; :not(:disabled) preserva o botão inativo sem reação ao toque. */
.gu-btn:not(:disabled):active { transform: scale(.97); }
.gu-btn-primary { background: var(--color-brand); color: var(--color-on-brand); box-shadow: 0 8px 18px -8px rgba(15,138,126,.55); }
.gu-btn-primary:hover { background: var(--color-brand-strong); }
.gu-btn-ghost { background: transparent; color: var(--color-text); border: 1.5px solid var(--color-border-strong); }
.gu-btn-ghost:hover { border-color: var(--color-brand); color: var(--color-brand-ink); }
.gu-btn-sm { padding: 9px 16px; font-size: var(--fs-sm); }
.gu-btn-block { width: 100%; }
.gu-btn:disabled { opacity: .5; cursor: not-allowed; box-shadow: none; }

.gu-chip { display: inline-flex; align-items: center; gap: 6px; font-weight: var(--fw-bold); font-size: var(--fs-caption); padding: 5px 12px; border-radius: var(--radius-pill); }
.gu-dot { width: 7px; height: 7px; border-radius: 50%; }
.gu-card { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius); }

.gu-input { width: 100%; font-family: var(--font-sans); font-size: var(--fs-body); color: var(--color-text); background: var(--color-surface); border: 1.5px solid var(--color-border-strong); border-radius: var(--radius-sm); padding: 12px 14px; transition: border .15s, box-shadow .15s; }
.gu-input::placeholder { color: var(--color-text-soft); }
.gu-input:focus { outline: none; border-color: var(--color-brand); box-shadow: var(--ring); }
.gu-label { display: block; font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--color-text); margin-bottom: 6px; }
.gu-hint { font-size: var(--fs-caption); color: var(--color-text-soft); margin-top: 6px; }

.gu-track { height: 8px; border-radius: var(--radius-pill); background: var(--color-track); overflow: hidden; }
.gu-fill { height: 100%; border-radius: var(--radius-pill); background: var(--color-progress); }

@keyframes gu-shimmer { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } }
.gu-skel { background: linear-gradient(90deg, var(--color-surface-2) 25%, var(--color-border) 37%, var(--color-surface-2) 63%); background-size: 200% 100%; animation: gu-shimmer 1.4s ease-in-out infinite; border-radius: 8px; }
@keyframes gu-spin { to { transform: rotate(360deg); } }
.gu-spin { animation: gu-spin .8s linear infinite; }
@keyframes gu-rise { from { transform: translateY(10px); } to { transform: none; } }
.gu-screen { animation: gu-rise .34s cubic-bezier(.2,.7,.2,1) both; }
/* Abertura da home em cascata: cada seção principal sobe (reusa o keyframe gu-rise, só
   transform) com um atraso incremental, criando a leitura de cima para baixo. gu-rise não tem
   opacity nem display, então nada fica escondido: quem chega por âncora vê o conteúdo e não há
   salto de layout (transform não muda a caixa). Usado apenas na home (index.html).
   gu-cascade (opt-out): a home marca o wrapper .gu-screen com esta classe para desligar o rise
   do wrapper. Sem isso, wrapper e seções animavam JUNTOS (dupla coreografia: ~20px compostos no
   hero e movimento dobrado); com a cascata por seção, o rise do wrapper vira ruído. As demais
   telas seguem com o .gu-screen intacto.
   A faixa "Continue de onde parou" (1º bloco da home logada) fica DE PROPÓSITO fora da cascata:
   é o CTA de retomada do aluno e deve estar pronto e estável no instante zero, sem esperar
   coreografia; a leitura em cascata começa no hero, logo abaixo. */
.gu-screen.gu-cascade { animation: none; }
.gu-rise-1, .gu-rise-2, .gu-rise-3, .gu-rise-4, .gu-rise-5, .gu-rise-6 {
    animation: gu-rise .45s var(--ease-out) both;
}
.gu-rise-1 { animation-delay: 60ms; }
.gu-rise-2 { animation-delay: 150ms; }
.gu-rise-3 { animation-delay: 240ms; }
.gu-rise-4 { animation-delay: 330ms; }
.gu-rise-5 { animation-delay: 420ms; }
.gu-rise-6 { animation-delay: 510ms; }
@media (prefers-reduced-motion: reduce) {
    .gu-screen, .gu-skel, .gu-spin,
    .gu-rise-1, .gu-rise-2, .gu-rise-3, .gu-rise-4, .gu-rise-5, .gu-rise-6,
    .gu-bar-fill, .gu-notif-badge { animation: none !important; }
    /* Check da aprovação: sem desenho progressivo, aparece pronto (traço completo).
       O !important no stroke-dashoffset é obrigatório: a regra base .gu-check-draw (mais abaixo
       no arquivo, junto do keyframe) declara stroke-dashoffset:1 com a MESMA especificidade e,
       vindo depois, venceria a cascata; sem animação preenchendo o valor, o traço ficaria
       invisível para quem pede movimento reduzido. */
    .gu-check-draw { animation: none !important; stroke-dashoffset: 0 !important; }
    .gu-btn { transition: none; }
    /* Logo do header: aparece estático (sem crescer), nada de animação (F5). */
    .gu-logo-pillar-1, .gu-logo-pillar-2, .gu-logo-pillar-3, .gu-logo-arrow { animation: none !important; }
}

/* ---- Dashboards de analytics (instrutor/admin): gráfico de barras, sparkline, barra que "cresce" ---- */
.gu-num { font-variant-numeric: tabular-nums; }
.gu-bar-chart { display: flex; align-items: flex-end; gap: 4px; height: 130px; overflow-x: auto; padding-bottom: 2px; }
.gu-bar-col { flex: 1 1 32px; min-width: 32px; display: flex; flex-direction: column; align-items: center; gap: 6px; height: 100%; justify-content: flex-end; }
.gu-bar-fill { width: 100%; border-radius: 5px 5px 0 0; background: var(--color-brand); min-height: 2px; transition: filter var(--dur-1) var(--ease-out); }
@media (hover: hover) and (pointer: fine) { .gu-bar-fill:hover { filter: brightness(1.18); } }
/* Barras verticais das analytics sobem escalonadas: cada coluna cresce da base (scaleY, só
   transform — a altura real segue no estilo inline), com atraso por posição, dando a leitura da
   esquerda para a direita. transform-origin:bottom cresce de baixo para cima. Cap no atraso a
   partir da 11ª coluna para séries longas (12 meses) não arrastarem demais. Passo de 32ms
   (antes 50ms, cap 520ms): comprime a escada para a última barra assentar em ~360ms sem quebrar
   a ordem esquerda-direita (o cap continua maior que o atraso da 10ª coluna). */
@keyframes gu-bar-rise { from { transform: scaleY(0); } to { transform: scaleY(1); } }
.gu-bar-fill { transform-origin: bottom; animation: gu-bar-rise var(--dur-3) var(--ease-out) both; }
.gu-bar-col:nth-child(1) .gu-bar-fill { animation-delay: 40ms; }
.gu-bar-col:nth-child(2) .gu-bar-fill { animation-delay: 72ms; }
.gu-bar-col:nth-child(3) .gu-bar-fill { animation-delay: 104ms; }
.gu-bar-col:nth-child(4) .gu-bar-fill { animation-delay: 136ms; }
.gu-bar-col:nth-child(5) .gu-bar-fill { animation-delay: 168ms; }
.gu-bar-col:nth-child(6) .gu-bar-fill { animation-delay: 200ms; }
.gu-bar-col:nth-child(7) .gu-bar-fill { animation-delay: 232ms; }
.gu-bar-col:nth-child(8) .gu-bar-fill { animation-delay: 264ms; }
.gu-bar-col:nth-child(9) .gu-bar-fill { animation-delay: 296ms; }
.gu-bar-col:nth-child(10) .gu-bar-fill { animation-delay: 328ms; }
.gu-bar-col:nth-child(n+11) .gu-bar-fill { animation-delay: 360ms; }

.gu-spark { display: flex; align-items: flex-end; gap: 2px; height: 26px; }
.gu-spark-bar { flex: 1; min-width: 3px; border-radius: 2px 2px 0 0; background: var(--color-brand-soft-2); min-height: 2px; }

@keyframes gu-grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }
.gu-fill-grow { transform-origin: left; animation: gu-grow var(--dur-3) var(--ease-out) both; }
@media (prefers-reduced-motion: reduce) { .gu-fill-grow { animation: none; } }

/* Check da aprovação se desenhando: na tela de resultado APROVADO o traço do "certo" é
   desenhado da ponta ao fim (stroke-dashoffset), ~600ms. O atributo pathLength=1 no path
   normaliza o comprimento, então dasharray/dashoffset trabalham na faixa 0..1 sem depender da
   medida real do traço. Só no aprovado; o reprovado não anima (momento errado para floreio).
   O reset para movimento reduzido mora no bloco prefers-reduced-motion acima. */
@keyframes gu-check-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
.gu-check-draw { stroke-dasharray: 1; stroke-dashoffset: 1; animation: gu-check-draw .6s var(--ease-out) .12s both; }

.gu-wrap { width: 100%; max-width: 1080px; margin: 0 auto; padding-left: var(--sp-7); padding-right: var(--sp-7); }
.gu-wrap-narrow { width: 100%; max-width: 560px; margin: 0 auto; padding-left: var(--sp-5); padding-right: var(--sp-5); }
.gu-grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-5); }
.gu-grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--sp-5); }
/* Atalhos do painel: grade que respira no container estreito (2 col no painel, 1 no celular) em
   vez de 3 cards espremidos num flex, onde o texto quebrava palavra a palavra (fix 07/07). */
.gu-quicklinks { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: var(--sp-4); }
.gu-grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-4); }
.gu-hero-grid { display: grid; grid-template-columns: 1.05fr .95fr; gap: var(--sp-7); align-items: center; }
.gu-split { display: grid; grid-template-columns: 1fr 320px; gap: var(--sp-6); align-items: start; }
.gu-row { display: flex; align-items: center; gap: var(--sp-4); }

/* ---- Subcabeçalho do portal da empresa (dono logado): um portal dentro do portal ----
   Correção 06/07 (rodada 2, achado 1): este bloco vive dentro do MESMO <header> sticky da barra
   principal (fragments/header.html ~121), então precisa ser a MESMA peça navy, não uma faixa
   creme colada embaixo. Fundo e bordas migraram para os tokens de header (a família
   --color-header-* mais --color-header-border, iguais aos da barra principal); textos soltos
   (marca da empresa, links do menu, "Ver
   o Gradup") migraram de --color-text/-muted/-soft para --color-header-text/-muted (não existe
   um 3º tom "soft" dedicado ao header, então o link de saída perde um pouco da discrição extra
   que tinha antes, mas ganha AA garantido — a borda + a seta "→" já bastam p/ diferenciá-lo).
   O par --color-brand-soft/--color-brand-ink do hover/aria-current NÃO mudou: ele desenha o
   próprio fundo (pill), então o contraste do texto é contra esse fundo claro, não contra o novo
   navy — continua ~5,6:1 nos 2 temas (já era usado assim em outros pontos do app) e a troca
   aqui alteraria a aparência no ESCURO, que deve ficar intocada. JÁ o hover/foco do link de
   saída (sem pill, cor direta sobre o fundo do header) usava --color-brand-ink puro: sobre o
   novo navy do claro isso caía p/ ~2:1 (reprovado). Trocado por --color-header-accent, igual ao
   hover do nav principal — no escuro os 2 tokens já valiam exatamente o mesmo tom (ver
   tokens.css), então nenhuma mudança visual lá. */
/* Centralização REAL do menu na barra, sem espremer a marca (corrigido 08/07): grade de 3 trilhas
   [ marca | menu | espelho vazio ]. A trilha da marca é minmax(max-content, 1fr) e a espelho é
   minmax(0, 1fr). Com folga, as duas viram 1fr iguais e o menu (trilha do meio) fica no centro
   ÓTICO da barra INTEIRA. Apertado (notebooks de 1366/1440px), a esquerda respeita o max-content
   da marca (piso inquebrável) em vez de encolher: assim "Aurora Tech Treinamentos" e o chip
   "Portal da empresa" NUNCA quebram em 2 linhas. A folga que sobra fica só do lado espelho, então
   o menu desliza suavemente para a direita em vez de espremer a marca. Detalhe que fecha o buraco
   antigo (menu transbordando a PÁGINA na faixa 900-1080): a trilha do meio é minmax(0, auto) e o
   próprio menu é justify-self:stretch com min-width:0 e overflow-x:auto. Quando o menu cabe, o auto
   mede o conteúdo e o menu ocupa exatamente essa largura, centrado; quando NÃO cabe, o menu é
   encolhido à largura da trilha (não ao conteúdo) e rola POR DENTRO (overflow-x + máscara mais
   abaixo), sem estourar a barra, sem sobrepor a marca e sem rolagem horizontal da página.
   Antes disso o menu era justify-self:center: com a trilha apertada ele mantinha a largura do
   conteúdo e transbordava centrado para os dois lados, empurrando a página (WCAG 1.4.10).
   A marca leva white-space:nowrap só aqui no desktop; abaixo de 768px ela volta a normal (empilhado).
   Obs. importante: até 07/07 este bloco inteiro NÃO valia porque havia, no comentário logo acima
   (na família de tokens do header), uma sequência de fecha-comentário (asterisco seguido de barra)
   solta dentro do texto, que fechava o comentário cedo; a regra .gu-subheader era então engolida
   por um seletor inválido e descartada, o div caía em display:block e a marca e o menu empilhavam
   encostados à esquerda. Nunca cite a sequência de fecha-comentário literal no texto de um
   comentário: escreva sempre por extenso (asterisco seguido de barra), como aqui. O comentário
   foi reescrito junto com esta correção. */
.gu-subheader {
  display: grid;
  grid-template-columns: minmax(max-content, 1fr) minmax(0, auto) minmax(0, 1fr);
  align-items: center; gap: var(--sp-5);
  padding: 9px 48px; background: var(--color-header-bg); border-top: 1px solid var(--color-header-border);
}
.gu-subheader-brand { grid-column: 1; justify-self: start; min-width: 0; display: flex; align-items: center; gap: 9px; font-weight: 700; font-size: var(--fs-sm); color: var(--color-header-text); white-space: nowrap; }
.gu-subheader-links {
  grid-column: 2; justify-self: stretch; min-width: 0;
  display: flex; align-items: center; gap: var(--sp-5);
  font-size: var(--fs-sm); font-weight: var(--fw-med); color: var(--color-header-text-muted);
  overflow-x: auto;
  /* Esconde a barra de rolagem nativa mantendo o scroll funcional: a máscara de gradiente nas
     bordas (abaixo) já sinaliza que há mais itens fora da vista, então a barra crua só sujaria a
     faixa. scrollbar-width:none cobre Firefox; a regra ::-webkit-scrollbar logo abaixo cobre
     Chrome/Edge/Safari. O conteúdo continua rolável por toque, roda do mouse e teclado. */
  scrollbar-width: none;
  /* Indicador de que há mais itens fora da vista quando o menu não cabe na largura (empresa com o
     menu completo em tela estreita). Máscara de gradiente nas duas bordas; sem cor real sendo
     exibida (é opacidade, não precisa de token de cor). */
  -webkit-mask-image: linear-gradient(to right, transparent, black 16px, black calc(100% - 16px), transparent);
  mask-image: linear-gradient(to right, transparent, black 16px, black calc(100% - 16px), transparent);
}
.gu-subheader-links::-webkit-scrollbar { display: none; }
.gu-subheader-links a {
  display: inline-flex; align-items: center;
  color: inherit; text-decoration: none; white-space: nowrap;
  padding: 6px 4px; border-radius: var(--radius-sm);
  transition: color .15s, background .15s;
}
.gu-subheader-links a:hover,
.gu-subheader-links a:focus-visible { color: var(--color-brand-ink); background: var(--color-brand-soft); }
/* aria-current="page" (g2): mesmo par cor/fundo do hover, já validado AA nos 2 temas. */
.gu-subheader-links a[aria-current="page"] { color: var(--color-brand-ink); background: var(--color-brand-soft); }
/* "Ver o Gradup": sai do grupo de gestao da empresa; diferenciado por separador + seta "→" no
   texto (não por um tom mais discreto: não existe um --color-header-text-soft, então a cor de
   repouso é a mesma dos outros links do menu, ver correção 06/07 acima). */
.gu-subheader-links a.gu-subheader-exit {
  margin-left: var(--sp-2);
  padding-left: var(--sp-4);
  border-left: 1px solid var(--color-header-border);
  color: var(--color-header-text-muted);
}
.gu-subheader-links a.gu-subheader-exit:hover,
.gu-subheader-links a.gu-subheader-exit:focus-visible { color: var(--color-header-accent); }
@media (max-width: 768px) {
  /* No estreito não cabe menu centralizado ao lado da marca: empilha (marca em cima, menu embaixo
     ocupando a linha toda e rolando na horizontal), que é a leitura natural no celular. */
  .gu-subheader { grid-template-columns: 1fr; padding: 9px var(--sp-5); }
  /* A marca segue encostada à esquerda (justify-self:start). O menu, porém, precisa OCUPAR a
     trilha inteira (stretch) e não encolher ao tamanho do conteúdo: com justify-self:start numa
     faixa 1fr a fileira de links (~934px com o menu completo da empresa) transbordava a coluna e
     a PÁGINA inteira rolava na horizontal (WCAG 1.4.10). Com stretch o item cabe na trilha e o
     overflow-x:auto do próprio menu engata, rolando só a faixa de links, não a página. */
  /* No estreito a marca volta a poder quebrar (white-space:normal): o comportamento empilhado
     ja aprovado nao muda, e uma marca muito longa nao força rolagem horizontal da PÁGINA. */
  .gu-subheader-brand { grid-column: 1; justify-self: start; white-space: normal; }
  .gu-subheader-links { grid-column: 1; justify-self: stretch; }
}
/* Densidade em notebook (1366/1440, os mais comuns): os 10 links do portal da empresa cabem sem
   rolagem interna reduzindo o gap entre eles (var(--sp-5) -> var(--sp-3)) e o respiro lateral da
   barra (48px -> var(--sp-6) 32px), SEM encurtar rotulos (copy e decisao de produto). Limitado a
   min-width:769px para nao pisar no layout empilhado do mobile (bloco 768px acima), onde a barra
   ja empilha e o menu rola por dentro, comportamento aprovado. Se ainda faltar espaco numa fonte
   larga, o overflow-x:auto + mascara seguram: rola por dentro, nunca estoura a pagina. */
@media (min-width: 769px) and (max-width: 1500px) {
  .gu-subheader { padding-left: var(--sp-6); padding-right: var(--sp-6); }
  .gu-subheader-links { gap: var(--sp-3); }
}

/* Menu mobile: painel que devolve a navegacao escondida no estreito (abre pelo hamburguer). */
.gu-mobile-menu {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 40;
  display: none; flex-direction: column;
  background: var(--color-surface); border-bottom: 1px solid var(--color-border);
  box-shadow: var(--shadow);
}
.gu-mobile-menu a {
  padding: 15px 24px; text-decoration: none; color: var(--color-text);
  font-size: var(--fs-body); font-weight: var(--fw-med);
  border-top: 1px solid var(--color-border);
  transition: color .15s, background .15s;
}
.gu-mobile-menu a:active { background: var(--color-surface-2); }
/* Hover/foco (não existia): mesmo par já validado AA do .gu-subheader-links (o painel mobile
   usa --color-surface normal, não o fundo escuro do header, então este par funciona direto). */
.gu-mobile-menu a:hover,
.gu-mobile-menu a:focus-visible { color: var(--color-brand-ink); background: var(--color-brand-soft); }
/* "Sair" no menu mobile: um form POST (logout com CSRF) que precisa parecer e responder igual aos
   links <a> do painel. O botão herda a mesma altura, tipografia, borda e estados de hover/foco. */
.gu-mobile-menu form { margin: 0; }
.gu-mobile-menu form button {
  display: block; width: 100%; text-align: left;
  padding: 15px 24px; background: none; border: none; border-top: 1px solid var(--color-border);
  color: var(--color-text); font-family: inherit; font-size: var(--fs-body); font-weight: var(--fw-med);
  cursor: pointer; transition: color .15s, background .15s;
}
.gu-mobile-menu form button:hover,
.gu-mobile-menu form button:focus-visible { color: var(--color-brand-ink); background: var(--color-brand-soft); }

@media (max-width: 768px) {
  .gu-mobile-menu:not([hidden]) { display: flex; }
  .gu-grid-3, .gu-grid-2, .gu-hero-grid, .gu-split { grid-template-columns: 1fr !important; }
  .gu-grid-4 { grid-template-columns: repeat(2, 1fr) !important; }
  .gu-wrap, .gu-wrap-narrow { padding-left: var(--sp-5); padding-right: var(--sp-5); }
  .gu-hide-mobile { display: none !important; }
  .gu-stack-mobile { flex-direction: column !important; align-items: stretch !important; }
  .gu-nav-links { display: none !important; }
  .gu-mobile-only { display: flex !important; }
}
.gu-mobile-only { display: none; }

/* ---- Cabeçalho: fixo no topo da janela, fundo destacado do fundo da página via token proprio
   (--color-header-bg; desde 06/07 é um azul-grafite escuro no tema claro, e o mesmo verde-grafite
   de sempre no escuro — ver a conta de contraste em tokens.css) + borda/sombra para dar
   profundidade. Fica acima do conteúdo comum, mas abaixo dos painéis/folhas (sininho 40, prévia
   mobile 50). Como o fundo é escuro nos 2 temas agora, todo texto/ícone que fica direto em cima
   dele (fora de um "cartão" próprio, tipo o chip do usuário ou o input de busca) usa os tokens
   --color-header-text/-muted/-accent em vez de --color-text/-muted. */
.gu-header {
  position: sticky; top: 0; z-index: 30;
  background: var(--color-header-bg);
  border-bottom: 1px solid var(--color-border-strong);
  box-shadow: var(--shadow-sm);
}
/* Com o ticker acima (faixa fina fixa no topo), o header sticky desce a altura da faixa: as duas
   barras empilham sem sobrepor. A classe .gu-com-ticker so entra quando o ticker renderiza
   (tickerCursos nao-vazio); sem ela o header segue colado no topo (top:0), sem vao. */
.gu-header.gu-com-ticker { top: var(--gu-ticker-h); }
/* Recomendado (a): celular deitado (altura curta) não perde ~25% da tela pro header fixo;
   volta a rolar junto com a página só nesse caso extremo (o ticker acompanha). */
@media (max-height: 480px) {
  .gu-header { position: static; }
  .gu-ticker { position: static; }
}

/* Compensa o header fixo: o pulo do skip-link para #conteudo não fica coberto pelo header (só
   afeta a rolagem por âncora; não adiciona espaço em branco visível na página).
   --gu-header-h começa em 72px (altura real da barra principal, com folga de ~3px) e sobe para
   112px quando o dono de empresa está logado: o .gu-subheader (filho do MESMO header sticky)
   soma ~39-40px reais de altura (padding 9px+9px + linha de texto ~20px + borda 1px) ->
   72 + 40 = 112. CSS não sobe a árvore do DOM (a variável declarada no header não alcança um
   irmão), então a detecção usa a classe .gu-header-com-sub — ligada no <header> via
   th:classappend em fragments/header.html quando minhaEmpresa != null — num seletor de irmão
   que mira o próprio #conteudo. #conteudo é sempre o <main> logo após o <header> no body em
   todos os templates (conferido); por isso o combinador adjacente (+) já basta, mas o geral (~)
   fica como rede de segurança caso algum template futuro insira algo entre os dois. */
:root { --gu-header-h: 72px; --gu-ticker-h: 34px; }
/* O recuo da ancora (skip-link) soma o header + (quando presente) a faixa fina do ticker acima dele.
   --gu-ticker-offset e 0 por padrao e vira a altura da faixa via a classe .gu-com-ticker do header
   irmao (regra abaixo), mesmo esquema de irmao adjacente/geral usado pelo subcabecalho. */
#conteudo { scroll-margin-top: calc(var(--gu-header-h) + var(--gu-ticker-offset, 0px)); }
.gu-header-com-sub + main#conteudo,
.gu-header-com-sub ~ main#conteudo { --gu-header-h: 112px; }
.gu-com-ticker + main#conteudo,
.gu-com-ticker ~ main#conteudo { --gu-ticker-offset: var(--gu-ticker-h); }

/* ---- Logo "crescendo" no carregamento (F5): os 3 pilares sobem de baixo p/ cima, escalonados,
   e a seta/chapéu aparece por último — reforça o conceito Gradup (gradual + up). Só transform/
   opacity (nunca width/height) e roda 1x (sem loop). transform-box:fill-box faz o "bottom" do
   transform-origin valer para a caixa do próprio rect/path (senão o SVG usa o viewport todo). */
@keyframes gu-logo-grow { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@keyframes gu-logo-arrow-in { from { opacity: 0; transform: translateY(-3px); } to { opacity: 1; transform: translateY(0); } }
.gu-logo-pillar-1, .gu-logo-pillar-2, .gu-logo-pillar-3 {
    transform-box: fill-box; transform-origin: bottom;
    animation: gu-logo-grow .34s var(--ease-out) both;
}
.gu-logo-pillar-1 { animation-delay: 0ms; }
.gu-logo-pillar-2 { animation-delay: 80ms; }
.gu-logo-pillar-3 { animation-delay: 160ms; }
.gu-logo-arrow { animation: gu-logo-arrow-in .28s var(--ease-out) both; animation-delay: 320ms; }

/* ---- Cabeçalho: barra principal (logo + nav + ações), sem estilo inline ---- */
.gu-header-pad { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); padding: 18px 48px; }
/* Menu principal centralizado no VÃO entre a marca e as ações (07/07), via auto-margin nos 2 lados:
   a marca (.gu-header-brand) fica fixa à esquerda e busca+ações fixas à direita, sem margin próprio,
   então nunca são empurradas; o nav só ganha a folga que sobra, dividida igual dos 2 lados, sem
   risco de sobreposição em nenhuma largura. No estreito a nav some (regra @media abaixo já existente),
   então o margin:auto não tem efeito nenhum ali.
   Nota (08/07): aqui NÃO se aplica a grade de 3 colunas simétricas usada no .gu-subheader (menu do
   portal da empresa). Lá o centro é ótico-perfeito porque há só 2 grupos (marca + menu) e o menu ROLA
   quando aperta; aqui há 3 grupos e o da direita (busca + ações) é bem mais largo que a marca, então
   uma grade simétrica centraria de fato mas, como este nav não rola nem quebra em linha própria, ele
   passaria por cima da marca/busca/ações nas larguras intermediárias (~900-1366px, perfil com muitos
   itens do instrutor/admin). O auto-margin abre mão do centro exato justamente para nunca sobrepor:
   é o comportamento robusto possível sem redesenhar o nav (torná-lo rolável ou reduzir itens). */
.gu-nav-links { display: flex; align-items: center; gap: 26px; margin: 0 auto; font-size: var(--fs-sm); font-weight: var(--fw-med); color: var(--color-header-text-muted); }
.gu-nav-links a { color: inherit; text-decoration: none; transition: color .15s; }
/* Hover/foco do menu principal (antes não existia nenhum estado): cor de destaque + sublinhado
   leve; no foco por teclado soma o anel do header (visível sobre o fundo escuro do header). */
.gu-nav-links a:hover { color: var(--color-header-accent); text-decoration: underline; text-underline-offset: 3px; }
.gu-nav-links a:focus-visible {
  color: var(--color-header-accent); text-decoration: underline; text-underline-offset: 3px;
  box-shadow: 0 0 0 3px var(--color-header-accent);
}
.gu-header-search { flex: 0 1 200px; margin: 0; }
.gu-header-search .gu-input { padding: 8px 14px; font-size: var(--fs-sm); }
.gu-header-brand { display: flex; align-items: center; gap: 11px; text-decoration: none; }
/* Anel de foco proprio (o global usa --ring, translucido demais sobre o header escuro). */
.gu-header-brand:focus-visible { box-shadow: 0 0 0 3px var(--color-header-accent); }
.gu-header-logo-mark { display: inline-flex; }
.gu-header-logo-img { height: 32px; width: auto; max-width: 190px; object-fit: contain; }
.gu-header-brand-name { font-family: var(--font-display); font-weight: 800; font-size: 21px; letter-spacing: -.02em; color: var(--color-header-text); }
.gu-header-actions { display: flex; align-items: center; gap: 12px; }
.gu-header-anon { display: flex; align-items: center; gap: 12px; }
.gu-header-user { display: flex; align-items: center; gap: 10px; }
/* Chip do usuário: tem fundo/borda proprios (não é o fundo do header direto), então continua
   com --color-surface-2/--color-text normais — já é AA nos 2 temas, sem depender da cor do header. */
.gu-header-user-link { display: flex; align-items: center; gap: 9px; background: var(--color-surface-2); border: 1px solid var(--color-border); border-radius: var(--radius-pill); padding: 5px 14px 5px 6px; text-decoration: none; }
.gu-header-user-label { font-size: var(--fs-sm); font-weight: 600; color: var(--color-text); }
/* Botões "fantasma" do header (tema, sininho, hamburguer, Entrar): ficam direto sobre o fundo
   escuro do header, por isso usam os tokens de texto do header (não --color-text, que é escuro
   demais em cima do header escuro). O anel de foco tambem é o proprio (o global --ring é
   translucido demais sobre o fundo escuro). Sair (logout) é a exceção: fica mais discreto (muted)
   em repouso, mas realça igual aos outros no hover/foco. */
/* Correção 06/07 (rodada 2, achado 3): a borda de repouso vinha da regra base .gu-btn-ghost
   (--color-border-strong, bege quente pensado p/ --color-surface) e destoava sobre o navy do
   header. --color-header-border é um cinza-azulado da mesma família do header (>=3:1 contra
   --color-header-bg, WCAG 1.4.11) e no escuro vale o mesmo hex que --color-border-strong já
   tinha lá, então nenhuma mudança visual no escuro. */
.gu-header-actions .gu-btn-ghost { color: var(--color-header-text); border-color: var(--color-header-border); }
.gu-header-actions .gu-btn-ghost:hover { color: var(--color-header-accent); border-color: var(--color-header-accent); }
.gu-header-actions .gu-btn-ghost:focus-visible {
  color: var(--color-header-accent); border-color: var(--color-header-accent);
  box-shadow: 0 0 0 3px var(--color-header-accent);
}
.gu-header-actions .gu-header-logout { color: var(--color-header-text-muted); }
.gu-avatar { width: 30px; height: 30px; border-radius: 50%; background: var(--color-brand); color: var(--color-on-brand); display: inline-flex; align-items: center; justify-content: center; font-weight: 700; font-size: 13px; }
@media (max-width: 768px) {
  .gu-header-pad { padding: 14px var(--sp-5); }
  /* Mesma conta do desktop, com a altura móvel: 64px base -> 104px (64 + ~40 do subheader). */
  :root { --gu-header-h: 64px; }
  .gu-header-com-sub + main#conteudo,
  .gu-header-com-sub ~ main#conteudo { --gu-header-h: 104px; }
}
/* Telefone (<=480px): o cluster de ações do cabeçalho autenticado (tema + sino + hamburguer +
   pill do painel + Sair) somava ~310px de largura e, junto com a marca (~111px), estourava os
   ~272px úteis de um aparelho de 390px, forçando rolagem horizontal da PÁGINA inteira (WCAG
   1.4.10; docScrollWidth ficava cravado em 461 de 320 a 460). Aqui o cluster é adensado, sem
   perder acesso a nada: menos respiro lateral na barra, gaps menores entre os botões, botões de
   ícone mais justos e o pill do painel enxuto. O "Sair" sai da barra por ser redundante com o
   menu do hamburguer, que agora traz "Sair" no rodapé (ver fragments/header.html) — no estreito
   a nav principal já vive lá; o pill do painel continua visível (identidade + atalho de 1 toque
   ao painel, também presente no hamburguer). Tudo segue alcançável pelo hamburguer. */
@media (max-width: 480px) {
  .gu-header-pad { padding: 14px var(--sp-3); gap: var(--sp-2); }
  .gu-header-actions { gap: var(--sp-2); }
  .gu-header-actions .gu-btn-sm { padding-left: var(--sp-2); padding-right: var(--sp-2); }
  .gu-header-user-link { padding: 4px 6px; }
  /* Sair vira item do hamburguer no estreito; o form some inteiro (não deixa gap órfão). */
  .gu-header-user form { display: none; }
}

/* ---- Sininho de notificações: badge + painel (abre pelo botão, sem AJAX) ---- */
.gu-notif-wrap { position: relative; display: flex; align-items: center; }
.gu-notif-btn { position: relative; }
.gu-notif-badge { position: absolute; top: -3px; right: -3px; min-width: 16px; height: 16px; padding: 0 3px; line-height: 1; border-radius: var(--radius-pill); background: var(--color-danger); color: var(--color-on-danger); font-size: 10px; font-weight: var(--fw-bold); display: flex; align-items: center; justify-content: center; border: 2px solid var(--color-surface); }
/* Pop de entrada do contador do sininho: quando há não lidas, o badge surge com um leve estouro
   (scale 0 -> 1.15 -> 1), ~250ms, chamando o olho sem distrair. Só transform. O reset para
   movimento reduzido mora no bloco prefers-reduced-motion mais acima.
   Débito consciente 1 (re-pop): server-rendered sem estado no cliente, o badge re-anima a CADA
   navegação enquanto houver não lidas; inevitável sem JS/armazenamento local, e aceito porque o
   pop é curto e o lembrete recorrente da pendência é até desejável.
   Débito consciente 2 (overshoot): o scale(1.15) é a ÚNICA exceção de "bounce" do sistema de
   animação (todo o resto assenta direto no destino). Não é precedente: vale só para este badge
   de 16px; componente novo não deve copiar o overshoot. */
@keyframes gu-badge-pop { 0% { transform: scale(0); } 60% { transform: scale(1.15); } 100% { transform: scale(1); } }
.gu-notif-badge { animation: gu-badge-pop .25s var(--ease-out) both; }
.gu-notif-panel { position: absolute; top: calc(100% + 10px); right: 0; width: 360px; max-width: 90vw; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden; z-index: 40; }
.gu-notif-panel[hidden] { display: none; }
.gu-notif-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 14px 16px; border-bottom: 1px solid var(--color-border); }
.gu-notif-head strong { font-size: var(--fs-sm); color: var(--color-text); }
.gu-notif-head form, .gu-notif-list form { margin: 0; }
.gu-notif-mark-all { background: none; border: none; color: var(--color-brand-ink); font-size: var(--fs-caption); font-weight: var(--fw-semi); cursor: pointer; padding: 4px; }
.gu-notif-list { max-height: 360px; overflow-y: auto; }
.gu-notif-item { display: flex; align-items: flex-start; gap: 12px; width: 100%; padding: 13px 16px; border: none; border-bottom: 1px solid var(--color-border); background: none; text-align: left; font: inherit; color: inherit; cursor: pointer; }
.gu-notif-item:last-child { border-bottom: none; }
.gu-notif-item:hover, .gu-notif-item:focus-visible { background: var(--color-surface-2); }
.gu-notif-item.unread { background: var(--color-brand-soft); }
.gu-notif-item.unread:hover { background: var(--color-brand-soft-2); }
.gu-notif-icon { width: 34px; height: 34px; flex: 0 0 auto; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: var(--color-brand-ink); background: var(--color-brand-soft); }
.gu-notif-body { flex: 1; min-width: 0; }
.gu-notif-title { display: block; font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--color-text); margin: 0 0 2px; }
.gu-notif-msg { display: block; font-size: var(--fs-caption); color: var(--color-text-muted); margin: 0; line-height: 1.4; overflow-wrap: break-word; }
.gu-notif-time { display: block; font-size: 11px; color: var(--color-text-soft); margin-top: 4px; }
.gu-notif-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--color-brand); flex: 0 0 auto; margin-top: 6px; }
.gu-notif-foot { padding: 11px 16px; text-align: center; border-top: 1px solid var(--color-border); }
.gu-notif-foot a { color: var(--color-brand-ink); font-size: var(--fs-sm); font-weight: var(--fw-semi); text-decoration: none; }
.gu-notif-empty { padding: 40px 20px; text-align: center; color: var(--color-text-muted); font-size: var(--fs-sm); }
@media (max-width: 768px) {
  .gu-notif-panel { position: fixed; top: auto; left: 0; right: 0; bottom: 0; width: 100%; max-width: none; border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
}

.gu-tablehead { display: grid; gap: var(--sp-4); align-items: center; padding: 11px 18px; font-size: var(--fs-caption); font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--color-text-soft); }
.gu-approw { display: grid; gap: var(--sp-4); align-items: center; padding: 15px 18px; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-sm); transition: border .15s, box-shadow .15s; }
.gu-approw:hover { border-color: var(--color-border-strong); box-shadow: var(--shadow-sm); }

/* ---- Tabela de dados (.gu-table): colunas alinhadas no desktop; vira card no estreito ---- */
.gu-table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.gu-table thead th {
  text-align: left; padding: 12px 18px; white-space: nowrap;
  font-size: var(--fs-caption); font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--color-text-soft); background: var(--color-surface-2);
  border-bottom: 1px solid var(--color-border);
}
.gu-table tbody td { padding: 14px 18px; vertical-align: middle; color: var(--color-text-muted); border-bottom: 1px solid var(--color-border); }
.gu-table tbody tr:last-child td { border-bottom: 0; }
.gu-table tbody tr:hover td { background: var(--color-surface-2); }
@media (max-width: 768px) {
  /* Vira card: cada linha e um bloco; o rotulo da coluna vem do data-label. */
  .gu-table thead { display: none; }
  .gu-table, .gu-table tbody, .gu-table tbody tr, .gu-table tbody td { display: block; width: 100%; }
  .gu-table tbody tr { border-bottom: 1px solid var(--color-border); padding: 8px 0; }
  .gu-table tbody tr:last-child { border-bottom: 0; }
  .gu-table tbody td { border-bottom: 0; padding: 6px 18px; }
  .gu-table tbody tr:hover td { background: transparent; }
  .gu-table tbody td[data-label]::before {
    content: attr(data-label);
    display: block; margin-bottom: 2px;
    font-size: var(--fs-caption); font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
    color: var(--color-text-soft);
  }
}
.gu-meta { font-family: var(--font-mono); font-size: var(--fs-caption); color: var(--color-text-soft); }

.gu-alert { display: flex; gap: 12px; align-items: flex-start; padding: 14px 16px; border-radius: var(--radius-sm); font-size: var(--fs-sm); line-height: 1.5; }
.gu-alert-success { background: var(--color-success-bg); color: var(--color-success-text); border: 1px solid var(--color-success-border); }
.gu-alert-error { background: var(--color-danger-bg); color: var(--color-danger-text); border: 1px solid var(--color-danger-border); }
.gu-alert-info { background: var(--color-info-bg); color: var(--color-info-text); border: 1px solid var(--color-info-border); }
.gu-alert-warning { background: var(--color-warning-bg); color: var(--color-warning-text); border: 1px solid var(--color-warning-border); }

/* ---- Catálogo: capa do card + chip por modo de acesso + chips de filtro ---- */
.course-cover { background: linear-gradient(135deg, var(--color-brand-soft), var(--color-brand-soft-2)); }
.course-cover.badge-paid { background: linear-gradient(135deg, var(--color-paid-bg), var(--color-paid-bg-2)); }
.course-cover.badge-directed { background: linear-gradient(135deg, var(--color-directed-bg), var(--color-directed-bg-2)); }
.course-cover-chip { background: var(--color-free-bg); color: var(--color-free-text); }
.course-cover-chip.badge-paid { background: var(--color-paid-bg); color: var(--color-paid-text); }
.course-cover-chip.badge-directed { background: var(--color-surface); color: var(--color-directed-text); border: 1px solid var(--color-warning-border); }
.course-cover-chip .gu-dot { background: currentColor; }
.chip-filter { background: var(--color-surface-2); color: var(--color-text-muted); border: 1px solid var(--color-border); text-decoration: none; cursor: pointer; }
.chip-filter:hover { border-color: var(--color-brand); color: var(--color-text); }
.chip-filter.is-active { background: var(--color-brand); color: var(--color-on-brand); border-color: var(--color-brand); }
/* Fundo trocado de --color-accent-soft para --color-accent (base): o soft escurece demais no
   tema escuro e --color-on-accent também é tinta escura nos 2 temas, dando texto escuro sobre
   fundo escuro (contraste ~1:1, reprova AA). --color-accent usa o MESMO valor nos 2 temas
   (ver tokens.css), então o par fica estável nos dois: claro 5,35:1, escuro 7,17:1 (conta no PR). */
.gu-chip-bestseller { background: var(--color-accent); color: var(--color-on-accent); }

/* ---- Catálogo: preview do curso ao passar o mouse/focar ----
   Balão de conversa AO LADO do card (não em cima): abre para o lado com MAIS espaço livre na
   grade de 3 colunas (.gu-grid-3) — à ESQUERDA por padrão, com rabinho do lado direito do
   balão; só a 1ª coluna abre à DIREITA, porque à esquerda ela vazaria da viewport.
   Correção 06/07 (rodada 2, achado 2): o comentário antigo dizia que abrir à esquerda "evita
   cobrir o curso do meio" — falso, a geometria não sustenta isso. Uma coluna de ~312px
   (.gu-grid-3 dentro de .gu-wrap, 1080px) e um balão de ~1 coluna de largura SEMPRE cobre o
   card vizinho mais próximo, não importa o lado: é intrínseco a um popover deste tamanho numa
   grade de 3. A largura caiu de 380 para 340px só para não invadir também o vizinho-do-vizinho
   (o balão passava ~34-58px além do card ao lado do imediato); o conteúdo continua rolando por
   dentro (.gu-card-popover-scroll), então 340px ainda cabe tudo.
   O mouse pode entrar no balão e clicar (ponte invisível cobre o vão entre card e balão). */
.gu-course-card { position: relative; }
.gu-card-popover {
    display: none;
    position: absolute;
    top: 0;
    width: 340px;
    max-width: min(340px, 42vw);
    z-index: 20;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: 20px;
    text-align: left;
}
/* conteudo rola por dentro; o botao Ver curso fica sempre visivel no pe do balão */
.gu-card-popover-scroll { max-height: min(62vh, 480px); overflow-y: auto; }
/* rabinho (quadrado girado 45°: mostra 2 bordas p/ formar a seta) e ponte invisível (o mouse
   atravessa do card ao balão sem fechar). Posição e bordas são definidas por coluna abaixo. */
.gu-card-popover::before {
    content: ""; position: absolute; width: 16px; height: 16px;
    background: var(--color-surface); transform: rotate(45deg);
}
.gu-card-popover::after { content: ""; position: absolute; }
/* ---------------------------------------------------------------------------
   Direção do balão por coluna na grade de 3 (pedido do Jeremias, 07/07): abre para onde NÃO há
   card vizinho, então nunca cobre outro curso. SAFE base (vale em qualquer largura, nada vaza
   da viewport): esquerda (3n+1) abre à DIREITA, direita (3n) abre à ESQUERDA, centro (3n+2) abre
   PARA CIMA. Em telas largas (mais abaixo) as colunas de FORA passam a abrir PARA FORA. */
.gu-course-card:nth-child(3n+1) .gu-card-popover { left: calc(100% + 14px); right: auto; top: 0; bottom: auto; transform: none; }
.gu-course-card:nth-child(3n+1) .gu-card-popover::before { top: 26px; bottom: auto; left: -8.5px; right: auto; border: 0; border-left: 1px solid var(--color-border); border-bottom: 1px solid var(--color-border); }
.gu-course-card:nth-child(3n+1) .gu-card-popover::after { top: 0; bottom: 0; left: -18px; right: auto; width: 18px; height: auto; }
.gu-course-card:nth-child(3n) .gu-card-popover { right: calc(100% + 14px); left: auto; top: 0; bottom: auto; transform: none; }
.gu-course-card:nth-child(3n) .gu-card-popover::before { top: 26px; bottom: auto; right: -8.5px; left: auto; border: 0; border-right: 1px solid var(--color-border); border-top: 1px solid var(--color-border); }
.gu-course-card:nth-child(3n) .gu-card-popover::after { top: 0; bottom: 0; right: -18px; left: auto; width: 18px; height: auto; }
.gu-course-card:nth-child(3n+2) .gu-card-popover { bottom: calc(100% + 14px); top: auto; left: 50%; right: auto; transform: translateX(-50%); }
.gu-course-card:nth-child(3n+2) .gu-card-popover::before { top: auto; bottom: -8.5px; left: 50%; right: auto; margin-left: -8px; border: 0; border-right: 1px solid var(--color-border); border-bottom: 1px solid var(--color-border); }
.gu-course-card:nth-child(3n+2) .gu-card-popover::after { top: auto; bottom: -18px; left: 0; right: 0; height: 18px; width: auto; }
/* Telas largas (há margem sobrando na viewport, ~1720px+): as colunas de FORA abrem PARA FORA,
   como pedido, aí nenhum balão cobre card vizinho. Abaixo dessa largura fica o SAFE acima (abre
   pra dentro), pra não vazar da tela / criar rolagem horizontal — proteção que já existia p/ a 1ª col. */
@media (min-width: 1720px) {
    .gu-course-card:nth-child(3n+1) .gu-card-popover { left: auto; right: calc(100% + 14px); }
    .gu-course-card:nth-child(3n+1) .gu-card-popover::before { left: auto; right: -8.5px; border: 0; border-right: 1px solid var(--color-border); border-top: 1px solid var(--color-border); }
    .gu-course-card:nth-child(3n+1) .gu-card-popover::after { left: auto; right: -18px; }
    .gu-course-card:nth-child(3n) .gu-card-popover { right: auto; left: calc(100% + 14px); }
    .gu-course-card:nth-child(3n) .gu-card-popover::before { right: auto; left: -8.5px; border: 0; border-left: 1px solid var(--color-border); border-bottom: 1px solid var(--color-border); }
    .gu-course-card:nth-child(3n) .gu-card-popover::after { right: auto; left: -18px; }
}
.gu-card-popover-objectives { display: flex; flex-direction: column; gap: 8px; margin: 10px 0 0; padding: 0; list-style: none; }
.gu-card-popover-objectives li { display: flex; gap: 8px; align-items: flex-start; font-size: var(--fs-sm); color: var(--color-text-muted); line-height: 1.4; }
@media (hover: hover) and (pointer: fine) {
    .gu-course-card:hover, .gu-course-card:focus-within { z-index: 5; }
    .gu-course-card:hover .gu-card-popover,
    .gu-course-card:focus-within .gu-card-popover {
        display: block;
    }
}

/* Skip-link: invisivel ate receber foco de teclado; primeiro item focavel da pagina. */
.gu-skip {
    position: absolute; left: -9999px; top: 0; z-index: 100;
    background: var(--color-brand); color: var(--color-on-brand);
    padding: 10px 18px; border-radius: 0 0 var(--radius-sm) 0;
    font-weight: 700; text-decoration: none;
}
.gu-skip:focus { left: 0; }

/* Previa do card no TOQUE: hover nao existe em touch; no estreito um botao abre o balao
   como folha inferior fixa (uma por vez; fecha no proprio botao ou no Fechar). */
.gu-card-preview-btn { display: none; }
@media (max-width: 720px) {
    .gu-card-preview-btn {
        display: inline-flex; position: absolute; top: 8px; right: 8px; z-index: 3;
        background: var(--color-surface); border: 1px solid var(--color-border-strong);
        border-radius: var(--radius-pill); padding: 4px 12px;
        font-size: 12px; font-weight: 700; color: var(--color-text); cursor: pointer;
    }
    .gu-course-card .gu-card-popover { display: none; }
    .gu-course-card .gu-card-popover.aberta {
        display: block; position: fixed; left: 12px; right: 12px; bottom: 12px; top: auto;
        width: auto; max-width: none; z-index: 50; transform: none;
    }
    .gu-course-card .gu-card-popover.aberta::before,
    .gu-course-card .gu-card-popover.aberta::after { display: none; }
}

/* =============================================================================
   Utilitárias (P3-20) — extraídas de style="" inline repetido nos templates.
   Valores copiados literalmente do inline original (nenhuma mudança visual).

   Grupos A e B: utilitárias atômicas (uma propriedade+valor por classe), com
   !important só para reproduzir a especificidade que o style inline tinha.
   NÃO usar esse padrão (atômico + !important) para estilo novo: é resíduo
   da extração, não um modelo a seguir.
   Grupo C: blocos semânticos compostos (mini-componentes com várias
   declarações relacionadas). É o alvo preferencial para os próximos padrões.
   Critério de corte para novas rodadas do P3-20: só extrair conjuntos de
   declarações EXATAMENTE repetidos em 3+ ocorrências entre templates;
   estilo genuinamente único continua inline.

   Grupo A: overrides atômicos de espaçamento/layout (equivalem ao que o
   style inline garantia por especificidade máxima -> !important preserva).
   ============================================================================= */
.gu-mb-4 { margin-bottom: var(--sp-4) !important; }
.gu-mb-5 { margin-bottom: var(--sp-5) !important; }
.gu-mb-16 { margin-bottom: 16px !important; }
.gu-mb-16-reset { margin: 0 0 16px !important; }
.gu-mt-8 { margin-top: 8px !important; }
.gu-m-0 { margin: 0 !important; }
.gu-gap-6 { gap: 6px !important; }
.gu-gap-8 { gap: 8px !important; }
.gu-gap-10 { gap: 10px !important; }
.gu-gap-8-wrap { gap: 8px !important; flex-wrap: wrap !important; }
.gu-gap-8-center { gap: 8px !important; align-items: center !important; }
.gu-shrink-0 { flex-shrink: 0 !important; }
.gu-opacity-50 { opacity: .5 !important; }
.gu-min-w-0 { min-width: 0 !important; }
.gu-w-100 { width: 100% !important; }
.gu-text-right { text-align: right !important; }
.gu-bg-current { background: currentColor !important; }
.gu-fs-sm { font-size: var(--fs-sm) !important; }
.gu-inline-normal { display: inline !important; font-weight: 400 !important; }
.gu-flex-1-min0 { flex: 1 !important; min-width: 0 !important; }

/* Grupo B: cor/texto pontuais (mesma lógica de override do inline). */
.gu-text-danger { color: var(--color-danger) !important; }
.gu-text-default { color: var(--color-text) !important; }
.gu-text-strong { font-weight: 700 !important; color: var(--color-text) !important; }
.gu-text-semi { font-weight: 600 !important; color: var(--color-text) !important; }
.gu-text-strong-mb2 { font-weight: 700 !important; color: var(--color-text) !important; margin-bottom: 2px !important; }
.gu-link-muted { color: var(--color-text-muted) !important; text-decoration: none !important; }
.gu-tone-success { background: var(--color-success-bg) !important; color: var(--color-success-text) !important; }

/* Grupo C: blocos compostos recorrentes (título, legenda, estado vazio, pilhas
   flex, cartões com padding+sombra) — equivalem a mini-componentes do protótipo. */
.gu-subtitle { margin: 0; font-size: var(--fs-body); color: var(--color-text-muted); }
.gu-subtitle-sm { margin: 0; font-size: var(--fs-sm); color: var(--color-text-muted); }
.gu-lede-center { margin: 0 auto 22px; font-size: var(--fs-body); color: var(--color-text-muted); max-width: 34em; }
.gu-lede-center-auto { margin: 0 auto; font-size: var(--fs-body); color: var(--color-text-muted); max-width: 34em; }
.gu-fs-sm-soft { font-size: var(--fs-sm); color: var(--color-text-soft); }
.gu-fs-body-text { font-size: var(--fs-body); color: var(--color-text); }
.gu-meta-row { gap: 8px; font-size: var(--fs-sm); color: var(--color-text-muted); margin-bottom: 14px; }
.gu-kicker { font-size: var(--fs-caption); color: var(--color-text-soft); text-transform: uppercase; letter-spacing: .05em; font-weight: 700; margin-bottom: 3px; }
.gu-heading-h3 { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-h3); margin: 0 0 8px; color: var(--color-text); }
.gu-heading-hero-sm { font-family: var(--font-display); font-weight: 800; font-size: var(--fs-h1); line-height: 1.1; margin: 0 0 6px; color: var(--color-text); }
.gu-heading-hero-xs { font-family: var(--font-display); font-weight: 800; font-size: var(--fs-h1); line-height: 1.1; margin: 0 0 4px; color: var(--color-text); }
.gu-heading-hero { font-family: var(--font-display); font-weight: 800; font-size: var(--fs-h1); line-height: 1.1; margin: 0 0 8px; color: var(--color-text); }
.gu-stat-value { font-size: var(--fs-h1); font-weight: 800; color: var(--color-text); }
/* Titulo do card de plano (pagina de planos): reune o bloco repetido nos 4 estados (CLAUDE.md: componentes em app.css). Margem fica por utilitario/estado. */
.gu-plan-title { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-h3); color: var(--color-text); margin: 0; }
.gu-section-pad { padding-top: var(--sp-6); padding-bottom: var(--sp-8); }
.gu-section-pad-alt { padding-top: var(--sp-7); padding-bottom: var(--sp-8); }
.gu-section-pad-narrow { padding-top: var(--sp-6); padding-bottom: var(--sp-8); max-width: 820px; }
.gu-section-head { justify-content: space-between; align-items: flex-end; flex-wrap: wrap; gap: 12px; margin-bottom: var(--sp-5); }
.gu-empty-state { text-align: center; padding: 64px 24px; background: var(--color-surface); border: 1px dashed var(--color-border-strong); border-radius: var(--radius-lg); }
.gu-empty-state-sm { text-align: center; padding: 56px 24px; background: var(--color-surface); border: 1px dashed var(--color-border-strong); border-radius: var(--radius-lg); }
.gu-stack-10 { display: flex; flex-direction: column; gap: 10px; }
.gu-stack-12 { display: flex; flex-direction: column; gap: 12px; }
.gu-stack-14 { display: flex; flex-direction: column; gap: 14px; }
.gu-stack-16 { display: flex; flex-direction: column; gap: 16px; }
.gu-stack-18 { display: flex; flex-direction: column; gap: 18px; }
.gu-tab-link { font-size: var(--fs-sm); font-weight: 600; color: var(--color-text-muted); padding: 13px 14px; border-bottom: 2.5px solid transparent; text-decoration: none; }
.gu-icon-tile-lg { width: 64px; height: 64px; border-radius: 20px; background: var(--color-surface-2); display: flex; align-items: center; justify-content: center; margin: 0 auto 18px; color: var(--color-text-soft); }
.gu-card-pad-md { padding: 18px 20px; box-shadow: var(--shadow-sm); }
.gu-card-pad-sm { padding: 20px; box-shadow: var(--shadow-sm); }
.gu-card-pad-lg { padding: 28px; box-shadow: var(--shadow); }
.gu-card-pad-lg-soft { padding: 28px; box-shadow: var(--shadow-sm); }
.gu-card-flush { padding: 0; box-shadow: var(--shadow-sm); overflow: hidden; }
.gu-actions-end { justify-content: flex-end; gap: 12px; margin-top: var(--sp-5); }
.gu-center-mb-6 { text-align: center; margin-bottom: var(--sp-6); }

/* Componentes reutilizados na home (index) e na landing de provedores, extraídos do inline para
   cumprir o contrato do CLAUDE.md ("Componentes ficam em app.css"). Só var(--token). Variantes
   -accent/-lg cobrem os usos de fundo/tamanho sem duplicar o bloco base.
   .gu-icon-tile: quadro do ícone dos cards. .gu-step-badge: círculo numerado dos passos.
   .gu-flow-row: linha do mini-fluxo "do treino à comprovação". .gu-proof-step: passo dentro da
   faixa escura de comprovação. .gu-anchor-offset: recuo de âncora sob o header fixo (mesmo cálculo
   do #conteudo, para o H3 do passo não ficar escondido ao clicar num chip). */
.gu-icon-tile { width: 46px; height: 46px; border-radius: 13px; background: var(--color-brand-soft); color: var(--color-brand-ink); display: flex; align-items: center; justify-content: center; margin-bottom: 14px; }
.gu-icon-tile-accent { background: var(--color-accent); color: var(--color-on-accent); }
.gu-step-badge { width: 38px; height: 38px; border-radius: 13px; background: var(--color-brand-soft-2); color: var(--color-brand-ink); display: flex; align-items: center; justify-content: center; font-weight: 800; flex-shrink: 0; }
.gu-step-badge-accent { background: var(--color-accent); color: var(--color-on-accent); }
.gu-step-badge-lg { width: 40px; height: 40px; }
.gu-flow-row { display: flex; align-items: center; gap: 14px; background: var(--color-surface-2); border-radius: var(--radius); padding: 13px 15px; }
.gu-proof-step { background: var(--color-band-overlay); border-radius: var(--radius); padding: 22px 24px; display: flex; gap: 16px; align-items: flex-start; }
.gu-anchor-offset { scroll-margin-top: calc(var(--gu-header-h) + var(--gu-ticker-offset, 0px)); }

/* Ticker de cursos ("faixa de cotações"): barra fina FIXA no topo, ACIMA do header, que rola
   NOME + PREÇO dos cursos públicos publicados continuamente (da direita para a esquerda). Vem do
   TickerAdvice (tickerCursos); aparece em toda tela com header + no topo da vitrine da empresa.
   Marquee sem emenda: o track tem DUAS cópias idênticas da lista lado a lado (as .gu-ticker-group) e
   a animação desliza translateX de 0 a -50% (a largura de uma cópia); ao chegar em -50% a 2ª cópia
   está exatamente onde a 1ª começou, então o loop é invisível. Cores: reusa os tokens do header
   (fundo/texto/borda) + --color-header-accent no preço, todos AA nos 2 temas (conta em tokens.css).
   Pausa no hover/foco (bônus, não é o controle principal) E no botão .gu-ticker-toggle sempre
   visível (WCAG 2.2.2 Pause/Stop/Hide — ver fragments/ticker.html); respeita prefers-reduced-motion
   (vira rolagem manual). Markup completo (botão + faixa) vem do fragmento único fragments/ticker.html,
   incluído em fragments/header.html e company/vitrine.html. */
.gu-ticker {
    position: sticky; top: 0; z-index: 31;
    height: var(--gu-ticker-h);
    background: var(--color-header-bg);
    border-bottom: 1px solid var(--color-header-border);
    display: flex; align-items: stretch;
}
/* Botão de pausa/retomada: fica FORA do viewport que rola, então nunca sai de vista (o pedido do
   bloqueador 1 é justamente um controle SEMPRE disponível, não só em hover/foco). Reusa as cores
   dos botões "fantasma" do header (mesma lógica de .gu-header-actions .gu-btn-ghost acima: o
   .gu-btn-ghost padrão usa tokens pensados p/ --color-surface, que não têm contraste aqui em cima
   do fundo escuro do header). */
.gu-ticker-toggle { flex: 0 0 auto; align-self: center; margin: 0 6px 0 10px; }
.gu-ticker .gu-btn-ghost { color: var(--color-header-text); border-color: var(--color-header-border); }
.gu-ticker .gu-btn-ghost:hover { color: var(--color-header-accent); border-color: var(--color-header-accent); }
.gu-ticker .gu-btn-ghost:focus-visible {
    color: var(--color-header-accent); border-color: var(--color-header-accent);
    box-shadow: 0 0 0 3px var(--color-header-accent);
}
/* Ícone mostra a AÇÃO que o clique vai fazer: pausa (2 barras) enquanto roda, play (triângulo)
   enquanto pausado. Troca por CSS a partir da classe .is-paused (o JS só alterna a classe + os
   atributos aria-pressed/aria-label; ver gradupToggleTicker no fragmento do ticker). */
.gu-ticker-icon-play { display: none; }
.gu-ticker.is-paused .gu-ticker-icon-pause { display: none; }
.gu-ticker.is-paused .gu-ticker-icon-play { display: inline-flex; }
.gu-ticker.is-paused .gu-ticker-track { animation-play-state: paused; }
.gu-ticker-viewport { flex: 1 1 auto; min-width: 0; height: 100%; overflow: hidden; }
.gu-ticker-track {
    display: flex; width: max-content; height: 100%; align-items: center;
    animation: gu-ticker-scroll 45s linear infinite; will-change: transform;
}
@keyframes gu-ticker-scroll {
    from { transform: translateX(0); }
    to { transform: translateX(-50%); }
}
/* Pausa quando o mouse passa por cima OU quando um item recebe foco por teclado (dá tempo de ler/
   clicar); bônus sobre o botão de pausa acima, que é o controle que funciona em qualquer entrada. */
.gu-ticker:hover .gu-ticker-track,
.gu-ticker:focus-within .gu-ticker-track { animation-play-state: paused; }
.gu-ticker-group { display: flex; align-items: center; flex: 0 0 auto; }
.gu-ticker-item {
    position: relative; display: inline-flex; align-items: center; gap: 7px;
    padding: 0 18px; height: 100%; white-space: nowrap; text-decoration: none; font-size: var(--fs-sm);
}
/* Separador: um ponto discreto centrado no vão entre um item e o próximo (decorativo). */
.gu-ticker-item::after {
    content: ""; position: absolute; right: 0; top: 50%; transform: translate(50%, -50%);
    width: 3px; height: 3px; border-radius: 50%; background: var(--color-header-text-muted);
}
.gu-ticker-name { color: var(--color-header-text); font-weight: var(--fw-semi); }
.gu-ticker-price { color: var(--color-header-accent); font-weight: var(--fw-bold); font-variant-numeric: tabular-nums; }
.gu-ticker-item:hover .gu-ticker-name { text-decoration: underline; text-underline-offset: 3px; }
.gu-ticker-item:focus-visible {
    outline: none; border-radius: var(--radius-sm);
    box-shadow: inset 0 0 0 2px var(--color-header-accent);
}
/* Movimento reduzido: sem animação; a faixa vira rolável na mão (arrastar) e a 2ª cópia some
   (não repete a lista quando está parada). */
@media (prefers-reduced-motion: reduce) {
    .gu-ticker-track { animation: none; }
    .gu-ticker-viewport { overflow-x: auto; }
    .gu-ticker-group[aria-hidden="true"] { display: none; }
    /* Sem animação não há o que pausar; some o botão em vez de deixar um controle morto na tela. */
    .gu-ticker-toggle { display: none; }
}

/* =============================================================================
   Convite rico (ADR-0011): a página que o convidado vê ao abrir o QR/link do
   convite vira um mini cartão de venda. Identidade da empresa no cabeçalho
   próprio da tela, treinamento em destaque (carga horária, aulas, instrutor),
   lista das aulas e o QR do próprio convite para reencaminhar. Só tokens
   (funciona no claro e no escuro). A estrutura já prevê um banner opcional
   futuro da empresa (imagem via URL) no topo do cartão, sem foto nesta versão.
   ============================================================================= */
.gu-convite-curso { padding: 20px 22px; margin-bottom: var(--sp-4); box-shadow: var(--shadow-sm); text-align: left; }
.gu-convite-curso-titulo { font-family: var(--font-display); font-weight: 800; font-size: var(--fs-h2); line-height: 1.2; margin: 2px 0 6px; color: var(--color-text); }
.gu-convite-meta { display: flex; flex-wrap: wrap; gap: 6px 16px; list-style: none; margin: 12px 0 0; padding: 0; }
.gu-convite-meta li { display: inline-flex; align-items: center; gap: 7px; font-size: var(--fs-sm); font-weight: 600; color: var(--color-text-muted); }
.gu-convite-meta .gu-dot { background: var(--color-accent); flex-shrink: 0; }
.gu-convite-aulas-head { font-size: var(--fs-caption); font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--color-text-soft); margin: 16px 0 6px; }
.gu-convite-aulas { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; counter-reset: gu-aula; }
.gu-convite-aulas li { counter-increment: gu-aula; display: flex; gap: 10px; align-items: center; padding: 7px 0; border-top: 1px solid var(--color-border); font-size: var(--fs-sm); color: var(--color-text); }
.gu-convite-aulas li::before {
    content: counter(gu-aula);
    flex-shrink: 0; min-width: 22px; height: 22px; border-radius: 50%;
    background: var(--color-brand-soft); color: var(--color-brand-ink);
    font-size: var(--fs-caption); font-weight: 700;
    display: inline-flex; align-items: center; justify-content: center;
}
.gu-convite-aulas-vazio { margin: 14px 0 0; padding: 14px; border: 1px dashed var(--color-border-strong); border-radius: var(--radius); font-size: var(--fs-sm); color: var(--color-text-muted); text-align: center; }
.gu-convite-reenviar { padding: 20px 22px; margin-top: var(--sp-4); box-shadow: var(--shadow-sm); text-align: center; }
.gu-convite-qr { display: block; margin: 14px auto 12px; border: 1px solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); max-width: 100%; height: auto; }
.gu-convite-link { padding: 10px 14px; background: var(--color-surface-2); border-radius: var(--radius); font-size: var(--fs-caption); word-break: break-all; color: var(--color-text); text-align: left; }
.gu-convite-aulas-mais { margin: 8px 0 0; font-size: var(--fs-sm); font-weight: 600; color: var(--color-text-muted); }

.gu-cols-2 { columns: 2; column-gap: 32px; }

/* =============================================================================
   Checklist "Primeiros passos" (onboarding do provedor, company/gerenciar.html):
   card com os passos derivados dos dados reais da empresa (marca, curso, prova,
   alunos, certificado). Passo feito = ícone de check (mesmo par bg/cor tinta de
   .gu-success já usado em cadastro-aluno-feito.html) + rótulo "Feito"; pendente =
   círculo vazio (mesmo desenho do .lesson-ico do player) + botão que leva direto
   a resolver. Com todos os passos feitos, o card cede lugar a uma linha única e
   discreta (.gu-onboarding-complete): o onboarding não some da tela, só para de
   pedir atenção.
   ============================================================================= */
.gu-onboarding-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.gu-onboarding-count { font-size: var(--fs-sm); font-weight: 700; color: var(--color-text-muted); white-space: nowrap; }
.gu-onboarding-list { list-style: none; margin: 16px 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.gu-onboarding-item {
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
    padding: 12px 14px; border-radius: var(--radius); background: var(--color-surface-2);
}
.gu-onboarding-icon {
    flex-shrink: 0; width: 30px; height: 30px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    border: 2px solid var(--color-border-strong);
}
.gu-onboarding-item.is-done .gu-onboarding-icon {
    border-color: transparent; background: var(--color-success-bg); color: var(--color-success);
}
.gu-onboarding-text { flex: 1 1 auto; min-width: 0; }
.gu-onboarding-text strong { display: block; font-size: var(--fs-sm); color: var(--color-text); }
.gu-onboarding-item.is-done .gu-onboarding-text strong { color: var(--color-text-muted); }
.gu-onboarding-text .gu-meta { margin-top: 2px; }
.gu-onboarding-done-label { flex-shrink: 0; font-size: var(--fs-sm); font-weight: 700; color: var(--color-success-text); }
.gu-onboarding-complete {
    display: flex; align-items: center; gap: 10px;
    padding: 14px 18px; border-radius: var(--radius); background: var(--color-success-bg);
    color: var(--color-success-text); font-size: var(--fs-sm); font-weight: 600;
}
.gu-onboarding-complete svg { flex-shrink: 0; }
@media (max-width: 480px) {
    .gu-onboarding-item .gu-btn { margin-left: 44px; }
}

/* =============================================================================
   Termos de Uso (/termos): prose de documento juridico longo, legibilidade
   de leitura. Componente unico servido de app.css (contrato de tokens do
   CLAUDE.md): so var(--token), zero cor fixa, funciona no claro e no escuro.
   O container fica dentro do gu-wrap-narrow da tela (padding lateral em todo
   viewport); o sumario tem duas colunas que viram uma no estreito.
   ============================================================================= */
.gu-terms { max-width: 760px; margin: 0 auto; }
.gu-terms h2 {
    font-family: var(--font-display); font-weight: 800; font-size: var(--fs-h2);
    color: var(--color-text); margin: 40px 0 12px; line-height: 1.25; scroll-margin-top: 90px;
}
.gu-terms h2:first-of-type { margin-top: 8px; }
.gu-terms p, .gu-terms li { color: var(--color-text-soft); line-height: 1.7; font-size: var(--fs-md); }
.gu-terms p { margin: 0 0 12px; }
.gu-terms ul { margin: 0 0 14px; padding-left: 22px; }
.gu-terms li { margin: 0 0 7px; }
.gu-terms strong { color: var(--color-text); font-weight: 700; }
.gu-terms-num { color: var(--color-text-muted); font-weight: 700; }
.gu-terms-pend {
    color: var(--color-text-muted); font-style: italic;
    border-bottom: 1px dashed var(--color-border-strong); padding-bottom: 1px;
}
.gu-terms-toc {
    background: var(--color-surface-2); border: 1px solid var(--color-border);
    border-radius: 14px; padding: 20px 24px; margin: 0 0 36px;
}
.gu-terms-toc h2 { font-size: var(--fs-md); margin: 0 0 12px; }
.gu-terms-toc ol { margin: 0; padding-left: 20px; columns: 2; column-gap: 28px; }
.gu-terms-toc li { margin: 0 0 6px; font-size: var(--fs-sm); break-inside: avoid; }
@media (max-width: 560px) { .gu-terms-toc ol { columns: 1; } }
@media (max-width: 480px) { .gu-cols-2 { columns: 1; } }
