/* V.I.V.I.A.N. Portal — CSS próprio simples (sem libs de UI externas pesadas). */
/* Redesign visual (spec 2026-09-06): paleta, tipografia e forma reorganizadas sobre design tokens
   `--v-*`. Os nomes antigos `--vivian-*` continuam existindo como aliases (ver bloco :root) porque
   regras deste próprio arquivo e eventual CSS isolado ainda os referenciam. */

@font-face {
    font-family: 'Fraunces';
    src: url('fonts/fraunces-400.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Fraunces';
    src: url('fonts/fraunces-600.woff2') format('woff2');
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Inter';
    src: url('fonts/inter-400.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Inter';
    src: url('fonts/inter-600.woff2') format('woff2');
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Inter';
    src: url('fonts/inter-700.woff2') format('woff2');
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

:root {
    /* Marca — evolução beauty-tech do roxo original #6b21ff */
    --v-purple: #5b1fd8;
    --v-purple-deep: #4a18b0;
    --v-ink: #241b3a;          /* violeta-berinjela: sidebar, títulos, snippet */
    --v-ink-soft: #3a2d5c;
    --v-bg: #faf8f5;           /* off-white quente */
    --v-surface: #ffffff;
    --v-border: #e7e1d8;
    --v-muted: #6d6478;        /* ≥4,5:1 sobre --v-bg e --v-surface */
    --v-gold: #b8860b;         /* acento dourado — parcimônia */
    --v-rose: #f6ece8;         /* superfície rosé suave */
    /* Semânticas — recalibradas, mesmos papéis de antes */
    --v-success: #1a7f37;  --v-success-bg: #e8f6ec;
    --v-warning: #7a5200;  --v-warning-bg: #fdf3d9;
    --v-danger:  #b3261e;  --v-danger-bg:  #fdeceb;
    --v-info:    #0b5fa5;  --v-info-bg:    #e9f3fb;
    /* Tipografia / forma */
    --v-font-serif: 'Fraunces', Georgia, 'Times New Roman', serif;
    --v-font-sans: 'Inter', 'Segoe UI', Helvetica, Arial, sans-serif;
    --v-radius: 10px;
    --v-radius-lg: 16px;
    --v-shadow-1: 0 1px 2px rgba(36, 27, 58, 0.06), 0 1px 6px rgba(36, 27, 58, 0.05);
    --v-shadow-2: 0 4px 12px rgba(36, 27, 58, 0.10), 0 2px 4px rgba(36, 27, 58, 0.06);
    --sidebar-width: 250px;
    /* Aliases legados — regras existentes e CSS isolado citam estes nomes */
    --vivian-purple: var(--v-purple);
    --vivian-purple-dark: var(--v-purple-deep);
    --vivian-ink: var(--v-ink);
    --vivian-bg: var(--v-bg);
    --vivian-border: var(--v-border);
    --vivian-muted: var(--v-muted);
    --vivian-success: var(--v-success);  --vivian-success-bg: var(--v-success-bg);
    --vivian-warning: var(--v-warning);  --vivian-warning-bg: var(--v-warning-bg);
    --vivian-danger: var(--v-danger);    --vivian-danger-bg: var(--v-danger-bg);
    --vivian-info: var(--v-info);        --vivian-info-bg: var(--v-info-bg);
}

* {
    box-sizing: border-box;
}

html, body {
    margin: 0;
    font-family: var(--v-font-sans);
    color: var(--v-ink);
    background: var(--v-bg);
}

a {
    color: var(--v-purple);
}

.text-danger {
    color: var(--v-danger);
}

h1, h2, h3 {
    line-height: 1.25;
    font-family: var(--v-font-serif);
    font-weight: 600;
    letter-spacing: -0.01em;
}

h1:focus {
    outline: none;
}

/* ---------- Layout ---------- */

.app-shell {
    display: flex;
    min-height: 100vh;
}

.sidebar {
    width: var(--sidebar-width);
    flex-shrink: 0;
    background: var(--v-ink);
    color: #fff;
    display: flex;
    flex-direction: column;
    padding: 1.25rem 0;
}

.app-main {
    flex: 1;
    min-width: 0;
}

.app-content {
    padding: 2rem;
    max-width: 960px;
}

@media (max-width: 640px) {
    .app-shell {
        flex-direction: column;
    }

    .sidebar {
        width: 100%;
    }
}

/* ---------- Sidebar / nav ---------- */

.brand {
    padding: 0 1.25rem 1.25rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.12);
    margin-bottom: 1rem;
}

.brand a {
    color: #fff;
    text-decoration: none;
    display: flex;
    flex-direction: column;
}

.brand-name {
    font-family: var(--v-font-serif);
    font-weight: 700;
    font-size: 1.15rem;
    letter-spacing: 0.03em;
}

.brand-sub {
    font-size: 0.75rem;
    color: rgba(255, 255, 255, 0.6);
}

.nav-links {
    list-style: none;
    margin: 0;
    padding: 0 0.75rem;
}

.nav-links li {
    margin-bottom: 0.15rem;
}

.nav-links :is(a, .nav-link) {
    display: block;
    padding: 0.55rem 0.75rem;
    border-radius: 6px;
    color: rgba(255, 255, 255, 0.85);
    text-decoration: none;
    font-size: 0.92rem;
}

.nav-links a:hover {
    background: rgba(255, 255, 255, 0.08);
}

.nav-links a.active {
    background: var(--v-purple);
    color: #fff;
}

.nav-section {
    margin-top: 1.25rem;
    padding-top: 0.75rem;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
}

.nav-section-title {
    display: block;
    padding: 0 1.25rem;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: rgba(255, 255, 255, 0.5);
    margin-bottom: 0.35rem;
}

.nav-footer {
    margin-top: auto;
    padding: 1rem 1.25rem 0;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.nav-user {
    font-size: 0.8rem;
    color: rgba(255, 255, 255, 0.7);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.nav-logout {
    font-size: 0.85rem;
    color: rgba(255, 255, 255, 0.85);
}

/* ---------- Unauthenticated fallback ---------- */

.unauthenticated-notice {
    max-width: 480px;
    margin: 4rem auto;
    text-align: center;
    padding: 2rem;
    background: var(--v-surface);
    border: 1px solid var(--v-border);
    border-radius: var(--v-radius-lg);
    box-shadow: var(--v-shadow-1);
}

/* ---------- Buttons ---------- */

.button, button, input[type="submit"] {
    font: inherit;
    cursor: pointer;
    border-radius: 8px;
    border: 1px solid var(--v-purple);
    padding: 0.55em 1.1em;
    background: var(--v-purple);
    color: #fff;
    display: inline-block;
    text-decoration: none;
    text-align: center;
    font-weight: 600;
    transition: background-color 150ms ease, border-color 150ms ease, box-shadow 150ms ease;
}

.button:hover, button:hover, input[type="submit"]:hover {
    background: var(--v-purple-deep);
    border-color: var(--v-purple-deep);
}

.button:focus-visible, button:focus-visible, input[type="submit"]:focus-visible {
    outline: 2px solid var(--v-purple);
    outline-offset: 2px;
}

/* Achado ALTO do ui-ux-reviewer (2026-09-08, entrega "auth real"): o outline --v-purple padrão mede só
   2,04:1 sobre o fundo --v-ink da faixa escura do CTA final da landing — abaixo do mínimo de 3:1 (WCAG
   2.4.11/1.4.11). #f5f0ff (já usado em .landing-cta-final h2, linha ~941) mede ~13:1 contra --v-ink,
   aprova com folga; largura/offset seguem herdados da regra genérica acima. */
.landing-cta-final .button:focus-visible, .landing-cta-final button:focus-visible {
    outline-color: #f5f0ff;
}

/* Achado do ui-ux-reviewer (ALTO, 2026-09-06, auditoria do redesign visual): contraste medido em
   ~2,68:1 com a antiga `opacity: 0.5` (fundo roxo + texto branco diluídos sobre --v-bg) — abaixo do
   mínimo AA de 4,5:1. Trocado por fundo sólido em --v-muted com opacity: 1: branco sobre #6D6478 mede
   5,61:1, aprova AA, e ainda fica visualmente distinto do roxo ativo (preserva o affordance de
   "desabilitado"). cursor: not-allowed mantido. */
.button:disabled, button:disabled {
    opacity: 1;
    background: var(--v-muted);
    border-color: var(--v-muted);
    color: #fff;
    cursor: not-allowed;
}

/* Auditoria do ui-ux-reviewer (WCAG 1.4.3): o rótulo "Selecionando..." em FrontalSelectionItemCard é o
   ÚNICO sinal de que a chamada ao modelo de visão está em andamento, e a 50% de opacidade padrão a
   contraste medido caía a ~2,5:1 — ilegível justamente no momento em que mais importa. Escopo estreito de
   propósito: só o botão em voo (classe .button-busy) opta por sair da opacidade compartilhada; os demais
   botões desabilitados do Portal continuam com o visual de sempre. Com --vivian-purple-dark sólido a razão
   sobe para 8,50:1 (branco #FFFFFF sobre --vivian-purple-dark #5417D6, luminância relativa 0,0735). */
.button-busy:disabled,
button.button-busy:disabled {
    opacity: 1;
    background: var(--v-purple-deep);
    color: #FFFFFF;
}

.button-secondary, button.button-secondary {
    background: var(--v-surface);
    color: var(--v-purple);
}

.button-secondary:hover, button.button-secondary:hover {
    background: #f1e9ff;
}

/* Achado do review final (2026-09-06): o secundário desabilitado vencia a regra genérica
   `.button:disabled` pela ordem do cascade — mesma especificidade, mas `.button-secondary` vem depois
   — e ficava com fundo branco, texto roxo e opacidade cheia, parecendo clicável. Visto ao vivo em
   AnchorReviewItemCard: "Aprovar sem alterar" desabilitado enquanto IsDirty continuava com a cara de
   botão ativo. --v-muted (#6D6478) sobre --v-bg (#FAF8F5) mede ≈5,3:1 — aprova AA para o rótulo — e a
   borda em --v-muted mantém ≥3:1 contra o fundo. */
.button-secondary:disabled, button.button-secondary:disabled {
    background: var(--v-bg);
    border-color: var(--v-muted);
    color: var(--v-muted);
}

.button-danger, button.button-danger {
    background: var(--v-danger);
    border-color: var(--v-danger);
}

/* Achado do ui-ux-reviewer (MÉDIO, 2026-08-18, item 1 — fila de revisão de âncora): ".actions" nunca teve
   regra própria — o espaçamento entre os botões era acidental (espaço em branco do markup), medido ao
   vivo em 4,4px. gap explícito substitui esse acidente por um valor deliberado; flex-wrap evita que dois
   botões de rótulo mais longo (ex. "Confirmar rejeição") estourem a largura do card em telas estreitas. */
.actions {
    display: flex;
    gap: 0.75rem;
    flex-wrap: wrap;
}

/* Achado do ui-ux-reviewer (BAIXO, 2026-08-18, item 4 — fila de revisão de âncora): sinal de estado leve
   ("há um ajuste local pendente"), nunca um toast — ver AnchorReviewItemCard.razor's IsDirty. Ponto sólido
   na cor da marca junto ao rótulo do indicador "(ajustado)", como o próprio relatório sugeriu. */
.anchor-dirty-dot {
    display: inline-block;
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background: var(--v-purple);
    margin-right: 0.4em;
    vertical-align: middle;
}

.link-button {
    background: none;
    border: none;
    color: var(--v-purple);
    padding: 0;
    text-decoration: underline;
}

/* ---------- Forms ---------- */

.form-field {
    margin-bottom: 1rem;
    max-width: 480px;
}

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

/* Achado do ui-ux-reviewer (BAIXO, 2026-08-18): esta regra só existia escopada a ".form-field .hint" — um
   ".hint" fora de um .form-field (ex.: "Você também pode arrastar a armação diretamente na prévia ao
   lado." em AnchorReviewItemCard.razor) renderizava com o texto do corpo (16px, cor de tinta cheia) em vez
   de atenuado. Generalizada para a classe sozinha: continua valendo para os .hint dentro de .form-field
   (nada muda ali), e passa a valer para qualquer outro também. */
.hint {
    font-size: 0.8rem;
    color: var(--v-muted);
    margin-top: 0.25rem;
}

/* Achado do ui-ux-reviewer (WCAG 1.4.11 — Non-text Contrast, task "Sliders com efeito imediato"):
   input[type="number"] (ex.: #glb-scale-hint) não estava nesta regra, então renderizava com a borda
   padrão do navegador (fonte 13,3px inclusive) em vez do estilo do Portal. Simplesmente incluí-lo
   herdaria --vivian-border, que mede 1,31:1 contra fundo branco — abaixo do mínimo 3:1 exigido para
   bordas de componente de UI. --vivian-muted mede 5,23:1 (mesmo método de luminância relativa), por
   isso a sobrescrita só nesse seletor, na época.
   Achado do ui-ux-reviewer (ALTO, 2026-09-06, auditoria do redesign visual): a mesma borda
   --v-border (1,30:1 medido) continuava reprovada em text/email/textarea/select — a correção acima
   nunca foi generalizada. --v-muted aplicado a todo o seletor compartilhado agora mede 5,61:1 em
   todos eles, e a sobrescrita duplicada de input[type="number"] foi removida por ficar redundante. */
input[type="text"], input[type="email"], input[type="number"], textarea, select {
    width: 100%;
    padding: 0.5em 0.65em;
    border: 1px solid var(--v-muted);
    border-radius: 6px;
    font: inherit;
    background: var(--v-surface);
    color: var(--v-ink);
}

input[type="text"]:focus, input[type="email"]:focus, input[type="number"]:focus,
textarea:focus, select:focus {
    border-color: var(--v-purple);
    box-shadow: 0 0 0 3px rgba(91, 31, 216, 0.12);
    outline: none;
}

textarea {
    min-height: 8rem;
    font-family: 'Cascadia Code', 'Consolas', monospace;
    font-size: 0.9rem;
}

.validation-message {
    color: var(--v-danger);
    font-size: 0.85rem;
    display: block;
    margin-top: 0.25rem;
}

/* ---------- Notices ---------- */

.notice {
    border-radius: 8px;
    padding: 0.85rem 1rem;
    margin-bottom: 1rem;
    font-size: 0.92rem;
}

.notice-info {
    background: var(--v-info-bg);
    color: var(--v-info);
}

.notice-success {
    background: var(--v-success-bg);
    color: var(--v-success);
}

.notice-warning {
    background: var(--v-warning-bg);
    color: var(--v-warning);
}

.notice-error {
    background: var(--v-danger-bg);
    color: var(--v-danger);
}

/* ---------- Cards / dashboard stats ---------- */

.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 1rem;
    margin: 1.5rem 0;
}

.stat-card {
    background: var(--v-surface);
    border: 1px solid var(--v-border);
    border-radius: var(--v-radius);
    padding: 1.1rem;
    box-shadow: var(--v-shadow-1);
    transition: box-shadow 150ms ease;
}

.stat-card:hover {
    box-shadow: var(--v-shadow-2);
}

.stat-value {
    font-size: 1.8rem;
    font-weight: 700;
}

.stat-label {
    font-size: 0.85rem;
    color: var(--v-muted);
}

.card {
    background: var(--v-surface);
    border: 1px solid var(--v-border);
    border-radius: var(--v-radius);
    padding: 1.25rem;
    margin-bottom: 1.25rem;
    box-shadow: var(--v-shadow-1);
    transition: box-shadow 150ms ease;
}

.card:hover {
    box-shadow: var(--v-shadow-2);
}

/* ---------- Tables ---------- */

table {
    width: 100%;
    border-collapse: collapse;
    background: var(--v-surface);
}

th, td {
    text-align: left;
    padding: 0.55rem 0.75rem;
    border-bottom: 1px solid var(--v-border);
    font-size: 0.9rem;
}

th {
    color: var(--v-muted);
    font-weight: 600;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

tbody tr:hover {
    background: #f6f2ec;
}

/* ---------- Classification badges (catálogo) ---------- */

.badge {
    display: inline-block;
    padding: 0.15em 0.6em;
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 600;
}

.badge-global-match {
    background: var(--v-success-bg);
    color: var(--v-success);
}

.badge-already-active {
    background: var(--v-info-bg);
    color: var(--v-info);
}

.badge-invalid {
    background: var(--v-danger-bg);
    color: var(--v-danger);
}

.badge-no-match {
    background: var(--v-warning-bg);
    color: var(--v-warning);
}

/* ---------- Analytics (/analytics) ---------- */

/* Visually hidden but still readable by screen readers — the accessible-fallback tables for the SVG
   charts on /analytics use this instead of `display: none` (which screen readers also skip). Standard
   "sr-only" recipe. */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.period-selector {
    display: flex;
    gap: 0.5rem;
    margin-bottom: 1.25rem;
}

.chart-wrap {
    width: 100%;
}

.sessions-chart {
    width: 100%;
    height: 140px;
    display: block;
}

.chart-bar {
    fill: var(--v-purple);
}

.chart-axis {
    position: relative;
    height: 1.1rem;
    margin-top: 0.15rem;
}

.chart-axis-label {
    position: absolute;
    transform: translateX(-50%);
    white-space: nowrap;
    font-size: 0.7rem;
    color: var(--v-muted);
}

.face-shape-bars {
    list-style: none;
    margin: 0;
    padding: 0;
}

.face-shape-bars li {
    margin-bottom: 0.75rem;
}

.face-shape-bar-label {
    display: flex;
    justify-content: space-between;
    font-size: 0.85rem;
    margin-bottom: 0.25rem;
}

.face-shape-bar-track {
    background: var(--v-bg);
    border: 1px solid var(--v-border);
    border-radius: 999px;
    height: 10px;
    overflow: hidden;
}

.face-shape-bar-fill {
    background: var(--v-purple);
    height: 100%;
    border-radius: 999px;
}

/* ---------- Code / snippet block ---------- */

pre.snippet {
    background: var(--v-ink);
    color: #d8f0ff;
    padding: 1rem;
    border-radius: 8px;
    overflow-x: auto;
    font-size: 0.85rem;
    white-space: pre;
}

code {
    font-family: 'Cascadia Code', 'Consolas', monospace;
    background: #f1f1f6;
    padding: 0.1em 0.3em;
    border-radius: 4px;
}

/* ---------- Blazor framework bits (kept from the template) ---------- */

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
    border-radius: 8px;
}

.blazor-error-boundary::after {
    content: "Ocorreu um erro.";
}

#blazor-error-ui {
    background: #b32121;
    color: #fff;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.8rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}

#blazor-error-ui a.reload {
    color: #fff;
    text-decoration: underline;
}

/* ---------- Revisão de âncora (task "Sliders com efeito imediato") ---------- */

/* Afford ância de arraste — sem isso nada no visual sugere que a imagem responde a pointerdown/pointermove
   (AnchorDrag.js — wwwroot/js/AnchorDrag.js). O grab/grabbing padrão do sistema operacional é o sinal
   universal de "isto se move"; :active cobre o intervalo entre pointerdown e o release, mesmo que o
   pointer capture já tenha sido tomado pelo próprio elemento. */
.anchor-preview [data-anchor-drag] {
    cursor: grab;
}

.anchor-preview [data-anchor-drag]:active {
    cursor: grabbing;
}

/* Achado do ui-ux-reviewer (MÉDIO, 2026-08-18): AnchorPreview.razor fixa width="360" height="360" em
   atributos HTML (sem regra responsiva alguma) — abaixo de 360px de viewport útil (ex.: o card inteiro em
   375px de tela, com padding/gap dos elementos ao redor) o SVG estourava a largura do card. O viewBox
   interno continua "0 0 400 400" — max-width/height:auto só reescala a CAIXA, sem tocar em nenhuma
   matemática de AnchorPreviewMath/AnchorDrag.js (ambos operam em coordenadas do viewBox, não em pixels de
   tela). */
.anchor-preview svg {
    max-width: 100%;
    height: auto;
}

.anchor-controls {
    min-width: 240px;
    flex: 1 1 240px;
}

/* Achado do ui-ux-reviewer (ALTO, 2026-08-18): input[type="range"] passou a existir no Portal só com esta
   task (os três sliders de ajuste de âncora), e a regra de "Forms" acima nunca incluiu esse seletor —
   nenhuma customização deste arquivo o alcançava. Duas consequências medidas ao vivo:
   1) WCAG 2.5.8 (Target Size Minimum) — os 24 sliders da fila de revisão de âncora mediam 129×16px
      (getBoundingClientRect() nos 8 itens reais da fila), abaixo do mínimo 24×24. min-height eleva só a
      CAIXA do elemento — todo navegador testado (Chromium/Firefox) centraliza a faixa fina dentro dela sem
      precisar customizar ::-webkit-slider-runnable-track/::-moz-range-track, então o clique-no-track que
      reposiciona o valor continua funcionando em qualquer ponto dos 24px de altura, não só na faixa fina
      visível.
   2) Contraste — appearance:auto (o padrão) pinta a faixa e o polegar com o tema do sistema operacional,
      fora do alcance do CSSOM: o contraste dos controles mais usados desta tela ficava delegado à máquina
      do curador. accent-color é suportado cross-browser (Chromium 93+, Firefox 113+, Safari 15.4+) sem
      exigir appearance:none, que reimplementaria thumb/track/foco do zero. */
input[type="range"] {
    min-height: 24px;
    accent-color: var(--v-purple);
}

/* ---------- Page header (shell interno) ---------- */
.page-header { margin-bottom: 1.75rem; }
.page-header h1 { margin: 0 0 0.25rem; font-size: 1.9rem; }
.page-header .page-subtitle { margin: 0; color: var(--v-muted); font-size: 0.95rem; }

.btn-lg { padding: 0.8em 1.6em; font-size: 1.05rem; border-radius: 10px; }

/* ---------- Public shell (redesign visual — visitante anônimo) ---------- */

.public-shell {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    background: var(--v-bg);
}

.public-header {
    position: sticky;
    top: 0;
    z-index: 10;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1rem 1.5rem;
    background: rgba(250, 248, 245, 0.9);
    backdrop-filter: blur(8px);
    border-bottom: 1px solid var(--v-border);
}

.public-brand {
    display: flex;
    flex-direction: column;
    text-decoration: none;
    line-height: 1.2;
}

.public-brand .brand-name {
    color: var(--v-ink);
}

.public-brand .brand-sub {
    color: var(--v-muted);
}

.public-header-actions {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.public-main {
    flex: 1;
}

.public-footer {
    color: var(--v-muted);
    border-top: 1px solid var(--v-border);
    padding: 2rem 1.5rem;
    font-size: 0.85rem;
    text-align: center;
}

/* ---------- Landing (redesign visual — página institucional pública) ---------- */

.landing-hero,
.landing-section {
    max-width: 1080px;
    margin-inline: auto;
    padding-inline: 1.5rem;
}

.landing-hero {
    display: grid;
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    align-items: center;
    gap: 3rem;
    padding-block: 5rem;
    background: linear-gradient(180deg, var(--v-rose), var(--v-bg));
}

.landing-hero h1 {
    font-size: clamp(2.2rem, 5vw, 3.4rem);
    margin: 0 0 1rem;
}

.landing-lead {
    font-size: 1.15rem;
    color: var(--v-muted);
    max-width: 34rem;
    margin: 0 0 1.5rem;
}

.landing-hero-art img {
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    display: block;
    border-radius: var(--v-radius-lg);
    box-shadow: var(--v-shadow-2);
}

@media (max-width: 860px) {
    .landing-hero {
        grid-template-columns: 1fr;
    }

    .landing-hero-art {
        order: 2;
    }
}

.landing-section {
    padding-block: 3.5rem;
}

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

.landing-steps {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 2rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

.landing-step img {
    width: 100%;
    aspect-ratio: 1;
    object-fit: cover;
    border-radius: var(--v-radius);
    margin-bottom: 1rem;
}

.landing-step h3 {
    margin: 0 0 0.4rem;
}

.landing-step p {
    color: var(--v-muted);
    margin: 0;
}

@media (max-width: 860px) {
    .landing-steps {
        grid-template-columns: 1fr;
    }
}

.landing-benefits {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1.5rem;
}

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

.landing-benefit h3 {
    margin: 0 0 0.5rem;
}

.landing-benefit p {
    color: var(--v-muted);
    margin: 0;
}

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

.landing-cta-final {
    background: var(--v-ink);
    padding: 4rem 1.5rem;
    text-align: center;
}

.landing-cta-final h2 {
    color: #f5f0ff;
    margin: 0 0 1.5rem;
}

.landing-cta-final .actions {
    justify-content: center;
}
