/* Gerado de /css/app-ajustes.css com a paleta do SeuCenoura (app/scripts/gerar-camada-sc.php). Nao editar: editar a original e gerar de novo. */
/* app-ajustes.css: 16/10/2026 (revisao 3 do app, F3, pergunta 2 do dono). FUSAO, na ordem exata da cascata
   de antes, de quatro folhas que o index carregava uma atras da outra: app-deferred.css, app-revisao.css,
   app-redesign.css e app-fixes.css (a camada final de correcoes). Mesma ordem e mesma pasta: nenhuma regra
   mudou de lugar na cascata (prova: diff de pixel no relato RODADA-2026-10-15-APP-PACIENTE.md). O link desta
   folha leva o id cssAncoraDeferred: o leitor de rotulos insere a folha dele ANTES dela, como antes.
   Correcao nova entra no FIM deste arquivo (o papel que era do app-fixes.css). */

/* ===== origem: css/app-deferred.css ===== */
/* app-deferred.css: bundle de features secundarias extraidas em 2026-05-10.
   Inclui: calc, chat, aval, onboarding, streak, agenda, plano, hidratacao.
   Total: 257 regras. Carregado async (media=print onload). */

/* calc.css: extraido de app.css em 2026-05-10 (sprint 7-6).
   40 regras. Carregado async (media=print onload). */


.calc-lista { display: flex; flex-direction: column; gap: 10px; margin-bottom: 14px; }.calc-card {
    background: var(--card); border: 1px solid var(--border); border-radius: 14px;
    overflow: hidden; transition: box-shadow .2s;
}.calc-card.open { box-shadow: 0 6px 20px rgba(61, 96, 65,0.16); border-color: #3d6041; }.calc-card.open .calc-card-arrow { transform: rotate(180deg); }.calc-card.open .calc-card-body { max-height: 900px; }.calc-form {
    padding: 8px 16px 16px;
    display: flex; flex-direction: column; gap: 10px;
    border-top: 1px solid var(--border);
}.calc-form label {
    display: flex; flex-direction: column; gap: 5px;
    font-size: 12.5px; font-weight: 600; color: var(--text-secondary);
}.calc-form input, .calc-form select {
    min-height: 44px; padding: 10px 12px;
    border: 2px solid var(--border); border-radius: 10px; background: var(--bg);
    font-size: 15px; font-family: inherit; color: var(--text); outline: none;
    transition: background .15s, color .15s, border-color .15s, box-shadow .15s, transform .15s, opacity .15s;
}.calc-form input:focus, .calc-form select:focus { border-color: #3d6041; background: var(--card); }.calc-result { margin-top: 8px; }.calc-destaque {
    padding: 16px; border-radius: 12px; border: 2px solid #e2e8f0;
    background: var(--bg); text-align: center;
}.calc-destaque-val { font-size: 32px; font-weight: 800; letter-spacing: -0.02em; }.calc-destaque-lbl { font-size: 13px; color: var(--text-secondary); margin-top: 4px; font-weight: 600; }.calc-extra {
    margin-top: 10px; padding: 10px 12px; background: var(--bg);
    border-radius: 10px; display: flex; flex-direction: column; gap: 6px;
}.calc-extra div { display: flex; justify-content: space-between; font-size: 13px; color: var(--text-secondary); }.calc-extra strong { color: var(--text); font-weight: 700; }.calc-hint {
    display: block; font-size: 12px; color: var(--text-muted);
    margin-top: 8px; font-style: italic; line-height: 1.4;
}.calc-aviso {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 12px 14px; background: rgba(90,120,145,0.08); border-radius: 12px;
    font-size: 12.5px; color: var(--text-secondary); line-height: 1.5;
}.calc-aviso i,.calc-aviso [data-lucide]{ color: #5a7891; margin-top: 2px; flex-shrink: 0; }.calc-card button,
.calc-card select,
.calc-card input { min-height: 44px; }.calc-card.open .calc-card-titulo { color: #3c493d; }.calc-card.open .calc-card-titulo { letter-spacing: -0.005em; }.calc-aviso {
    border-left: 3px solid #5a7891;
    background: rgba(90,120,145,0.06);
}.calc-section-title {
    font-size: 15px;
    font-weight: 700;
    margin: 0 0 10px 4px;
    color: var(--text, #0f172a);
    display: flex;
    align-items: center;
    gap: 8px;
    letter-spacing: -0.01em;
}.calc-section-title i,.calc-section-title [data-lucide]{ color: var(--accent); font-size: 14px; }
/* 2026-07-22: mesmo defeito das abas da Agenda (seletores nus dentro do media
   de tema do SO). Guard html:not(.theme-light) + par html.theme-dark. */
@media (prefers-color-scheme: dark) {
    html:not(.theme-light) .calc-card { background: var(--card); }
    html:not(.theme-light) .calc-form input, html:not(.theme-light) .calc-form select { background: var(--bg); color: var(--text); }
    html:not(.theme-light) .calc-destaque { background: var(--bg); border-color: var(--border); }
    html:not(.theme-light) .calc-extra { background: var(--bg); }
    html:not(.theme-light) .calc-aviso { background: rgba(90,120,145,0.14); }
}
html.theme-dark .calc-card { background: var(--card); }
html.theme-dark .calc-form input, html.theme-dark .calc-form select { background: var(--bg); color: var(--text); }
html.theme-dark .calc-destaque { background: var(--bg); border-color: var(--border); }
html.theme-dark .calc-extra { background: var(--bg); }
html.theme-dark .calc-aviso { background: rgba(90,120,145,0.14); }
/* chat.css: extraido de app.css em 2026-05-10 (sprint 7-6).
   27 regras. Carregado async (media=print onload). */


.chat-container {
    display: flex;
    flex-direction: column;
    /* Altura responsiva: max do viewport menos top/bottom nav reais.
       svh = small viewport height (estavel quando teclado abre/fecha em mobile).
       2026-05-09: usa --header-height (varia por breakpoint) em vez de 64px
       hardcoded. Antes, em mobile com header 60px, a chat-container ficava
       4px maior que o viewport e empurrava o composer ATRAS da bottom-nav. */
    height: calc(100svh - var(--header-height, 64px) - var(--nav-height, 65px) - var(--safe-top) - var(--safe-bottom) - 8px);
    min-height: clamp(280px, 55vh, 600px);
    max-height: calc(100dvh - var(--header-height, 64px) - var(--nav-height, 65px) - var(--safe-bottom));
    overflow: hidden;
}.chat-messages {
    flex: 1; overflow-y: auto; padding: 16px;
    display: flex; flex-direction: column; gap: 12px;
}.chat-msg {
    max-width: 85%; padding: 12px 14px; border-radius: 16px;
    font-size: 13px; line-height: 1.4; word-break: break-word;
}.chat-msg.enviada { align-self: flex-end; background: var(--primary); color: #fff; border-bottom-right-radius: 4px; }.chat-msg.recebida { align-self: flex-start; background: var(--bg); color: var(--text); border-bottom-left-radius: 4px; }/* 03/09/2026: a hora da mensagem recebida media 3,50:1 no tema claro. A cor
   ja vinha do token da bolha; a opacity .7 era um apagamento a mais em cima
   dela. Em .9 mede 5,62:1 e continua secundaria. */
.chat-msg .time { font-size: 10px; opacity: 0.9; margin-top: 4px; display: block; }.chat-input-area {
    /* 2026-05-14: aumenta padding lateral para dar respiro entre input/botao
       e margem direita. Antes 14px ficava muito apertado em desktop. */
    padding: 12px 18px calc(14px + var(--safe-bottom, 0px));
    padding-left: max(18px, env(safe-area-inset-left, 0px));
    padding-right: max(18px, env(safe-area-inset-right, 0px));
    border-top: 1px solid var(--border);
    background: var(--card);
    /* Mantém o composer ancorado na base do .chat-thread (que ja tem flex-column) */
    position: relative;
    z-index: 1;
}.chat-tipo-label {
    font-size: 11.5px;
    font-weight: 700;
    color: var(--text-secondary, #64748b);
    letter-spacing: .03em;
    text-transform: uppercase;
    margin: 0 2px 6px;
}.chat-tipo-select {
    display: flex;
    gap: 6px;
    margin-bottom: 10px;
    flex-wrap: nowrap;
}.chat-input-row { display: flex; gap: 10px; align-items: flex-end; min-width: 0; }.chat-input-row .chat-input {
    flex: 1; min-width: 0; padding: 10px 14px; border: 1px solid var(--border);
    border-radius: 24px; font-size: 16px; font-family: inherit; line-height: 1.4;
    resize: none; height: 44px; min-height: 44px; max-height: 120px; overflow-y: auto; background: var(--bg);
}.chat-input:focus { outline: none; border-color: var(--primary); background: var(--bg-white); }.chat-send {
    width: 44px; height: 44px; background: var(--primary); border: none;
    border-radius: 50%; color: #fff; font-size: 18px; cursor: pointer; flex-shrink: 0;
}.chat-msg.from-nutri {
    position: relative;
    padding-top: 12px;
    min-width: min(220px, 80vw);
}.chat-msg-author {
    position: static;
    display: flex; align-items: center; gap: 6px;
    font-size: 11px; font-weight: 700; color: #213423;
    margin-bottom: 6px; min-width: 0;
}.chat-msg-author-name {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    min-width: 0; flex: 1;
}.chat-msg-author img {
    width: 20px; height: 20px;
    border-radius: 50%;
    /* 2026-07-17 (auditoria contraste AA): ponta clara era #609165 = 3,66:1 com
       branco (reprova). Agora #2f4a32 (5,06:1) -> #3d6041 (7,12:1). */
    background: linear-gradient(135deg, #2f4a32, #213423);
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 9px;
    font-weight: 800;
    object-fit: cover;
}.chat-msg-badge.urgente { background: #fee2e2; color: #991b1b; }.chat-msg-badge.agendamento { background: #e8eef2; color: #1f3854; }.chat-sidebar { display: none; }.chat-thread { display: flex; flex-direction: column; flex: 1; min-height: 0; }
/* 2026-08-07 (relato do dono, iPhone): margin PROPRIA do separador de data
   somava com o gap:12px de .chat-messages (flex-column) em vez de substituir
   ele. Gap nao colapsa com margin em item de flex, entao o vao real era
   12+14=26px acima e 12+8=20px abaixo, mais que o dobro do espaco entre duas
   bolhas comuns (12px) e assimetrico entre os dois lados. Essa diferenca lia
   como espaco vazio e inconsistente no meio da conversa. Reduzido para uma
   folga simetrica e modesta por cima do gap ja existente (12+4=16px nos dois
   lados). */
.chat-date-sep {
    display: flex;
    align-items: center;
    text-align: center;
    margin: 4px;
    gap: 8px;
}.chat-date-sep::before,
.chat-date-sep::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--border-light, #e2e8f0);
}.chat-date-sep span {
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted, #94a3b8);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    background: var(--bg-alt, #f1f5f9);
    padding: 4px 10px;
    border-radius: 999px;
    white-space: nowrap;
}@media (min-width: 600px) {
    .chat-msg.from-nutri { min-width: 280px; }
}/* aval.css: extraido de app.css em 2026-05-10 (sprint 7-6).
   72 regras. Carregado async (media=print onload). */


.aval-full { font-size: 13px; line-height: 1.45; }.aval-hero {
    background: linear-gradient(135deg, #213423 0%, #49594b 100%);
    color: #fff;
    border-radius: 18px;
    padding: 18px 18px 16px;
    margin-bottom: 14px;
    box-shadow: 0 8px 24px rgba(33, 52, 35, 0.22);
    position: relative;
    overflow: hidden;
}.aval-hero::before {
    content: "";
    position: absolute;
    top: -40px; right: -40px;
    width: 160px; height: 160px;
    background: radial-gradient(circle, rgba(61, 96, 65, .4) 0%, transparent 70%);
    pointer-events: none;
}.aval-hero-top {
    display: flex; justify-content: space-between; align-items: center;
    margin-bottom: 14px;
}.aval-hero-label {
    font-size: 11px; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.08em;
    opacity: 0.82;
}.aval-hero-data {
    font-size: 12px; font-weight: 600;
    background: rgba(255, 255, 255, 0.14);
    padding: 5px 10px; border-radius: 99px;
    display: inline-flex; align-items: center; gap: 5px;
    backdrop-filter: blur(4px);
}.aval-hero-data i,.aval-hero-data [data-lucide]{ font-size: 10px; }.aval-kpis {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 10px;
}.aval-kpi {
    /* 2026-05-10: conteudo centralizado horizontal e vertical (era flex-start
       a esquerda, dados ficavam desorganizados). Agora ico em cima centro,
       valor abaixo centro, label abaixo centro. Visual mais limpo. */
    display: flex; flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    background: rgba(255, 255, 255, 0.1);
    border-radius: 12px;
    padding: 12px 8px;
    backdrop-filter: blur(4px);
    border: 1px solid rgba(255, 255, 255, 0.12);
    min-height: 96px;
}.aval-kpi-ico {
    width: 32px; height: 32px;
    border-radius: 9px;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 14px; color: #fff;
    margin: 0 auto 8px;
    flex-shrink: 0;
    background: rgba(255, 255, 255, 0.20);
    border: 1px solid rgba(255, 255, 255, 0.25);
    backdrop-filter: blur(2px);
}.aval-kpi-ico.peso, .aval-kpi-ico.imc, .aval-kpi-ico.gord, .aval-kpi-ico.magra { background: rgba(255, 255, 255, 0.20); }.aval-kpi-info {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    width: 100%;
}.aval-kpi-label {
    font-size: 10px; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.05em;
    opacity: 0.85;
    text-align: center;
    order: 2;
}.aval-kpi-valor {
    font-size: 19px; font-weight: 800;
    line-height: 1.05; letter-spacing: -0.02em;
    text-align: center;
    order: 1;
}.aval-kpi-valor small {
    font-size: 10px; font-weight: 600; opacity: 0.7; margin-left: 2px;
}.aval-compare-toggle-wrap { margin-bottom: 14px; }.aval-compare-toggle {
    width: 100%;
    display: flex; align-items: center; justify-content: space-between;
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 12px;
    padding: 12px 14px;
    color: #1e293b;
    font-size: 13.5px;
    font-weight: 700;
    cursor: pointer;
    transition: background .15s, border-color .15s;
    font-family: inherit;
}.aval-compare-toggle:hover, .aval-compare-toggle:focus-visible {
    background: #f1f5f9;
    border-color: #3d6041;
    outline: none;
}.aval-compare-toggle i.fa-exchange-alt,.aval-compare-toggle [data-lucide].fa-exchange-alt{ color: #3d6041; margin-right: 6px; }.aval-compare-chevron { transition: transform .2s ease; color: #64748b; font-size: 11px; }.aval-compare-toggle[aria-expanded="true"] .aval-compare-chevron { transform: rotate(180deg); color: #3d6041; }.aval-compare-collapsed { display: none; }.aval-compare-open { display: block; margin-top: 10px; animation: avalCompareIn .2s ease-out; }.aval-compare {
    background: #f8fafc;
    border: 1px solid #e2e8f0;
    border-radius: 14px;
    padding: 14px;
    margin-bottom: 14px;
}.aval-compare-head h4 {
    font-size: 12.5px; font-weight: 700; color: #0f172a;
    margin: 0 0 10px; display: flex; align-items: center; gap: 6px;
}.aval-compare-head h4 i,.aval-compare-head h4 [data-lucide]{ color: #213423; font-size: 12px; }.aval-compare-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
}.aval-compare-card {
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 10px;
    padding: 10px 8px;
    display: flex; flex-direction: column; gap: 5px;
    align-items: center; text-align: center;
}.aval-compare-lbl {
    font-size: 10.5px; font-weight: 600; color: #64748b;
    text-transform: uppercase; letter-spacing: 0.03em;
}.aval-delta {
    display: inline-flex; align-items: center; gap: 4px;
    font-size: 13px; font-weight: 800;
    padding: 4px 10px; border-radius: 99px;
}.aval-delta i,.aval-delta [data-lucide]{ font-size: 10px; }.aval-delta.good { background: #f1f5f9; color: #213423; }.aval-delta.bad { background: #fee2e2; color: #b91c1c; }.aval-delta.neutral { background: #f1f5f9; color: #64748b; }.aval-compare-group { margin-top: 10px; }.aval-compare-group-title {
    font-size: 11px; font-weight: 700; color: #213423;
    text-transform: uppercase; letter-spacing: 0.04em;
    margin-bottom: 6px; display: flex; align-items: center; gap: 5px;
}.aval-compare-group-title i,.aval-compare-group-title [data-lucide]{ font-size: 10px; }.aval-meta-head i,.aval-meta-head [data-lucide]{ font-size: 12px; opacity: 0.9; }.aval-compare-pdf-btn {
    display: flex; align-items: center; justify-content: center;
    gap: 8px; width: 100%;
    padding: 11px 16px;
    /* 2026-07-17 (auditoria contraste AA): ponta clara era #609165 = 3,66:1 com
       branco (reprova). Agora #2f4a32 (5,06:1) -> #3d6041 (7,12:1). */
    background: linear-gradient(135deg, #2f4a32, #213423);
    color: #fff; border: none; border-radius: 12px;
    font-size: 13.5px; font-weight: 700;
    cursor: pointer; margin-bottom: 16px;
    box-shadow: 0 4px 12px rgba(61, 96, 65, 0.28);
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}.aval-compare-pdf-btn:hover {
    transform: translateY(-1px);
    box-shadow: 0 6px 18px rgba(61, 96, 65, 0.38);
}.aval-compare-pdf-btn:active { transform: scale(0.98); }.aval-historico-titulo {
    font-size: 13px; font-weight: 700; color: #0f172a;
    display: flex; align-items: center; gap: 8px;
    margin: 0 0 14px;
}.aval-historico-titulo i,.aval-historico-titulo [data-lucide]{ color: #213423; font-size: 12px; }.aval-timeline {
    position: relative;
    padding-left: 20px;
}.aval-timeline::before {
    content: "";
    position: absolute;
    left: 7px; top: 12px; bottom: 12px;
    width: 2px;
    background: linear-gradient(180deg, #3d6041 0%, #cbd5e1 100%);
    border-radius: 1px;
}.aval-timeline-item {
    position: relative;
    margin-bottom: 12px;
}.aval-timeline-item:last-child { margin-bottom: 0; }.aval-timeline-dot {
    position: absolute;
    left: -18px; top: 12px;
    width: 12px; height: 12px;
    background: #fff;
    border: 3px solid #cbd5e1;
    border-radius: 50%;
    z-index: 1;
}.aval-timeline-item.latest .aval-timeline-dot {
    border-color: #3d6041;
    box-shadow: 0 0 0 4px rgba(61, 96, 65, 0.15);
}.aval-timeline-card {
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 12px;
    cursor: pointer;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}.aval-timeline-card:hover {
    border-color: #3d6041;
    box-shadow: 0 4px 12px rgba(15, 23, 42, 0.06);
}.aval-timeline-item.latest .aval-timeline-card {
    border-color: #3d6041;
    background: linear-gradient(135deg, #f1f5f9, #fff 40%);
}.aval-timeline-head {
    display: flex; justify-content: space-between; align-items: center;
    padding: 12px 14px;
}.aval-timeline-data {
    font-size: 13px; font-weight: 700; color: #0f172a;
    display: flex; align-items: center; gap: 8px;
    flex-wrap: wrap;
}.aval-badge-latest {
    /* 2026-07-17 (auditoria contraste AA): 9,5px nao e texto grande, entao exige
       4,5:1. Branco sobre #609165 dava 3,66:1; sobre #2f4a32 da 5,06:1. */
    font-size: 9.5px; font-weight: 700;
    background: #2f4a32; color: #fff;
    padding: 2px 7px; border-radius: 99px;
    text-transform: uppercase; letter-spacing: 0.04em;
}.aval-timeline-resumo {
    font-size: 11.5px; color: #64748b; margin-top: 3px;
    line-height: 1.35;
}.aval-chevron {
    /* 2026-05-09: AA Large — era #94a3b8 (2.85:1) — agora #64748b (4.6:1). */
    color: #64748b; font-size: 12px;
    transition: transform 0.2s ease;
    flex-shrink: 0;
}.aval-timeline-card.open .aval-chevron {
    transform: rotate(180deg);
}.aval-acoes {
    display: flex; gap: 6px; flex-wrap: wrap;
    margin-top: 12px;
}.aval-btn {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 8px 12px;
    background: #f1f5f9; color: #334155;
    border: none; border-radius: 8px;
    font-size: 11.5px; font-weight: 600;
    cursor: pointer;
    transition: background 0.15s ease;
}.aval-btn:hover { background: #e2e8f0; }/* 2026-07-17 (auditoria contraste AA): #609165 -> #2f4a32 (3,66:1 -> 5,06:1) e
   hover desce para #3d6041 (7,12:1) preservando o degrau de hover. */
.aval-btn.primary { background: #2f4a32; color: #fff; }.aval-btn.primary:hover { background: #213423; }@media (min-width: 1024px) {
    .aval-hero {
        max-width: 720px;
        margin-left: auto;
        margin-right: auto;
        padding: 28px 32px 24px;
        border-radius: 22px;
    }
    .aval-hero-top { margin-bottom: 22px; }
    .aval-hero-label { font-size: 13px; }
    .aval-kpis { gap: 14px; }
    .aval-kpi { padding: 14px 12px; }
    .aval-kpi-ico { width: 34px; height: 34px; font-size: 16px; }
}@media (max-width: 375px) {
    .aval-kpis { grid-template-columns: repeat(2, 1fr); gap: 6px; }
    .aval-kpi-valor { font-size: 16px; }
}/* onboarding.css: extraido de app.css em 2026-05-10 (sprint 7-6).
   14 regras. Carregado async (media=print onload). */


.onb-overlay {
    position: fixed; inset: 0; z-index: var(--z-tooltip, 1300);
    background: rgba(0,0,0,.75);
    display: none;
    align-items: center;
    justify-content: center;
    padding: 24px;
}.onb-overlay.active { display: flex; }.onb-card {
    /* 2026-05-10: tokens corretos (--card e --text) que existem nos :root.
       Antes usava --surface que nao existe -> fallback #ffffff sempre = branco
       no fundo branco em dark mode (texto invisivel reportado). */
    background: var(--card, #ffffff);
    color: var(--text, #0f172a);
    max-width: 360px;
    padding: 28px 24px;
    border-radius: 20px;
    text-align: center;
    box-shadow: 0 22px 64px rgba(0,0,0,.5);
    border: 1px solid var(--border, #e2e8f0);
    animation: errPop .35s cubic-bezier(.2,.9,.3,1);
}.onb-step-dots { display: flex; justify-content: center; gap: 6px; margin-bottom: 16px; }.onb-step-dot {
    width: 8px; height: 8px;
    border-radius: 50%;
    background: var(--border, #e2e8f0);
    transition: background .2s, color .2s, border-color .2s, box-shadow .2s, transform .2s, opacity .2s;
}.onb-step-dot.active { background: #3d6041; width: 24px; border-radius: 4px; }.onb-illust {
    font-size: 52px;
    margin-bottom: 12px;
    /* 2026-05-10: cor explicita para nao herdar branco/transparente em dark */
    color: #3d6041;
}.onb-title {
    font-size: 18px;
    font-weight: 800;
    margin: 0 0 8px;
    color: var(--text, #0f172a);
}.onb-desc {
    font-size: 14px;
    color: var(--text-secondary, #475569);
    line-height: 1.55;
    margin: 0 0 20px;
}.onb-actions { display: flex; gap: 10px; justify-content: space-between; align-items: center; }.onb-skip {
    background: transparent;
    border: none;
    color: var(--text-muted, #64748b);
    font-size: 13px;
    cursor: pointer;
    padding: 10px;
}.onb-skip:hover { color: var(--text, #334155); }.onb-next {
    padding: 11px 22px;
    /* 2026-07-17 (auditoria contraste AA): ponta clara era #609165 = 3,66:1 com
       branco (reprova). Agora #2f4a32 (5,06:1) -> #3d6041 (7,12:1). */
    background: linear-gradient(135deg, #2f4a32, #213423);
    color: #ffffff !important;
    /* -webkit-text-fill-color e propriedade herdavel; o pai .onb-card forca
       cor escura com !important que "vaza" para os descendentes via essa
       propriedade. Forcamos branco aqui para o texto do botao Proximo
       aparecer corretamente sobre o fundo verde brand em ambos os temas. */
    -webkit-text-fill-color: #ffffff !important;
    border: none;
    border-radius: 10px;
    font-weight: 700;
    cursor: pointer;
    min-height: 42px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}.onb-next * { -webkit-text-fill-color: #ffffff !important; color: #ffffff !important; }/* streak.css: extraido de app.css em 2026-05-10 (sprint 7-6).
   10 regras. Carregado async (media=print onload). */


.streak-celebration-overlay {
    position: fixed; inset: 0; z-index: var(--z-toast, 1100);
    background: rgba(15, 23, 42, .55);
    backdrop-filter: blur(6px);
    display: none;
    align-items: center;
    justify-content: center;
    animation: errFadeIn .3s;
    padding: 24px;
}.streak-celebration-overlay.active { display: flex; }.streak-celebration-card {
    background: #ffffff;
    color: #0f172a;
    max-width: 360px;
    width: 100%;
    padding: 28px 24px 22px;
    border-radius: 16px;
    text-align: center;
    box-shadow: 0 24px 60px rgba(15,23,42,.32), 0 0 0 1px rgba(15,23,42,.06);
    position: relative;
    animation: streakPop .35s cubic-bezier(.2,.9,.3,1);
    border-top: 3px solid #3d6041;
}.streak-fire-big {
    width: 56px; height: 56px;
    margin: 0 auto 10px;
    border-radius: 14px;
    background: #f1f5f9;
    color: #2f4a32;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 24px;
    line-height: 1;
}.streak-number {
    font-size: 42px;
    font-weight: 800;
    color: #2f4a32;
    letter-spacing: -.02em;
    line-height: 1;
    margin-bottom: 4px;
}.streak-label {
    font-size: 14.5px;
    font-weight: 700;
    color: #0f172a;
    margin: 4px 0 8px;
    letter-spacing: -.005em;
}.streak-msg {
    font-size: 13px;
    line-height: 1.55;
    color: #475569;
    margin-bottom: 18px;
}.streak-close {
    /* 2026-07-17 (auditoria contraste AA): ponta clara era #609165 = 3,66:1 com
       branco (reprova). Agora #2f4a32 (5,06:1) -> #3d6041 (7,12:1). */
    background: linear-gradient(135deg, #2f4a32, #213423);
    color: #fff;
    border: none;
    padding: 11px 26px;
    border-radius: 10px;
    font-weight: 700;
    font-size: 13px;
    cursor: pointer;
    min-height: 42px;
    transition: filter .15s, transform .15s;
    box-shadow: 0 4px 12px rgba(61, 96, 65,.28);
}.streak-close:hover { filter: brightness(0.95); transform: translateY(-1px); }.streak-close:active { transform: translateY(0); }/* agenda.css: extraido de app.css em 2026-05-10 (sprint 7-6).
   23 regras. Carregado async (media=print onload). */


.agenda-item { padding: 14px; background: var(--bg); border-radius: 12px; margin-bottom: 10px; }.agenda-item.passado { opacity: 0.5; }.agenda-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }.agenda-date { font-size: 15px; font-weight: 600; }.agenda-tipo { font-size: 12px; color: var(--text-muted); }.agenda-actions {
    display: flex; gap: 6px; margin-top: 10px; padding-top: 10px;
    border-top: 1px dashed var(--border); flex-wrap: wrap;
}.agenda-btn {
    flex: 1; min-width: 80px; padding: 10px; border-radius: 8px; border: none;
    font-size: 13px; font-weight: 700; cursor: pointer;
    letter-spacing: .01em;
    display: flex; align-items: center; justify-content: center; gap: 6px;
    text-decoration: none;
}.agenda-btn.confirm {
    background: linear-gradient(135deg, #2f4a32, #213423);
    color: #fff;
    box-shadow: 0 2px 6px rgba(107, 131, 110,0.35);
}.agenda-btn.confirm:hover { transform: translateY(-1px); box-shadow: 0 4px 10px rgba(61, 96, 65,0.4); }.agenda-btn.confirm:disabled { opacity: 0.6; cursor: default; transform: none; }.agenda-btn.cancel {
    background: linear-gradient(135deg, #ef4444, #dc2626);
    color: #fff;
    border: none;
    box-shadow: 0 2px 6px rgba(239,68,68,0.3);
}.agenda-btn.cancel:hover { transform: translateY(-1px); box-shadow: 0 4px 10px rgba(239,68,68,0.4); }.agenda-btn.video { background: var(--info); color: #fff; }.agenda-btn.whatsapp { background: #25D366; color: #fff; }/* 2026-07-22 (homologacao Dr. Jayme, defeito 2): as abas Proximas/Anteriores
   apareciam com as cores do modo escuro mesmo com o app em modo claro.
   Causa raiz: o bloco @media (prefers-color-scheme: dark) no fim desta secao
   usava seletores nus (.agenda-tabs / .agenda-tab-count), entao o tema do
   SISTEMA operacional vencia a escolha manual do usuario (html.theme-light).
   Correcao na origem: as regras abaixo passam a ler tokens de tema; os valores
   escuros sao declarados uma unica vez, no escopo correto (html.theme-dark e
   html:not(.theme-light) dentro do media). Sem !important. */
.agenda-tabs {
    display: flex;
    gap: 6px;
    padding: 6px;
    background: var(--agenda-tabs-bg, #f1f5f9);
    border-radius: 12px;
    margin-bottom: 16px;
}.agenda-tab {
    flex: 1;
    padding: 10px 12px;
    border: none;
    background: transparent;
    color: var(--agenda-tab-fg, #64748b);
    font-weight: 600;
    font-size: 13px;
    border-radius: 8px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    transition: background .2s, color .2s, box-shadow .2s;
    font-family: inherit;
}.agenda-tab:hover:not(.active) { background: var(--agenda-tab-hover-bg, rgba(255,255,255,.55)); color: var(--agenda-tab-hover-fg, #1e293b); }.agenda-tab.active {
    /* 2026-07-17 (auditoria contraste AA): ponta clara era #609165 = 3,66:1 com
       branco (reprova). Agora #2f4a32 (5,06:1) -> #3d6041 (7,12:1).
       2026-05-09: o mesmo gradient brand vale nos dois temas (antes o escuro
       usava #86C98C, emerald-300, fora da paleta SeuSaude). So a sombra muda. */
    background: linear-gradient(135deg, #2f4a32, #213423);
    color: #ffffff;
    box-shadow: var(--agenda-tab-active-shadow, 0 2px 6px rgba(61, 96, 65, .28));
}.agenda-tab.active i,.agenda-tab.active [data-lucide]{ color: #ffffff; }.agenda-tab-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 22px;
    height: 20px;
    padding: 0 6px;
    background: var(--agenda-count-bg, #e2e8f0);
    color: var(--agenda-count-fg, #475569);
    border-radius: 99px;
    font-size: 11px;
    font-weight: 700;
}.agenda-tab.active .agenda-tab-count {
    background: var(--agenda-count-active-bg, rgba(255, 255, 255, .22));
    color: #ffffff;
    border: 1px solid var(--agenda-count-active-border, rgba(255, 255, 255, .35));
}.agenda-sub-title {
    font-size: 12px;
    font-weight: 700;
    color: var(--agenda-sub-fg, #64748b);
    text-transform: uppercase;
    letter-spacing: .05em;
    margin: 4px 0 12px;
}
/* Tokens do tema escuro da Agenda: declarados uma unica vez e reaproveitados
   nos dois gatilhos de tema escuro do app.
   1) html.theme-dark: o usuario escolheu "escuro" no app (vale mesmo com o SO
      em claro, caso que o bloco antigo nao cobria);
   2) @media (prefers-color-scheme: dark) + html:not(.theme-light): o usuario
      esta em "automatico" e o SO esta escuro. O guard html:not(.theme-light) e
      o padrao da casa (ver leitor-rotulos.css, 2026-05-19) e e exatamente o que
      faltava aqui: sem ele, quem escolhia "claro" num aparelho com SO escuro
      continuava vendo a barra de abas azul-marinho. */
html.theme-dark {
    --agenda-tabs-bg: #1e293b;
    --agenda-tab-fg: #94a3b8;
    --agenda-tab-hover-bg: rgba(255,255,255,.08);
    --agenda-tab-hover-fg: #f1f5f9;
    --agenda-tab-active-shadow: 0 2px 6px rgba(0,0,0,.45);
    --agenda-count-bg: #334155;
    --agenda-count-fg: #cbd5e1;
    --agenda-count-active-bg: rgba(255,255,255,.18);
    --agenda-count-active-border: rgba(255,255,255,.30);
    --agenda-sub-fg: #94a3b8;
}
@media (prefers-color-scheme: dark) {
    html:not(.theme-light) {
        --agenda-tabs-bg: #1e293b;
        --agenda-tab-fg: #94a3b8;
        --agenda-tab-hover-bg: rgba(255,255,255,.08);
        --agenda-tab-hover-fg: #f1f5f9;
        --agenda-tab-active-shadow: 0 2px 6px rgba(0,0,0,.45);
        --agenda-count-bg: #334155;
        --agenda-count-fg: #cbd5e1;
        --agenda-count-active-bg: rgba(255,255,255,.18);
        --agenda-count-active-border: rgba(255,255,255,.30);
        --agenda-sub-fg: #94a3b8;
    }
}/* plano.css: extraido de app.css em 2026-05-10 (sprint 7-6).
   34 regras. Carregado async (media=print onload). */


.plano-header {
    display: flex; align-items: center; justify-content: space-between;
    padding: 14px 16px; background: var(--accent-light); color: #3c493d;
    gap: 10px;
    flex-wrap: wrap;
}.plano-info h4 { font-size: 14px; font-weight: 700; color: #3c493d; overflow: hidden; text-overflow: ellipsis; }.plano-info span { font-size: 11px; color: #213423; }.plano-calorias strong { font-weight: 800; }.plano-dia { display: none; }.plano-dia.active { display: block; }.plano-acoes {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px;
    margin: 12px 0 16px;
}.plano-acoes.plano-acoes-rodape {
    gap: 6px;
    margin: 0;
    padding: 10px 12px;
    border-top: 1px solid var(--border, #e2e8f0);
    background: var(--bg, #f8fafc);
    border-radius: 0 0 14px 14px;
}.plano-acoes.plano-acoes-rodape .plano-acao-btn {
    padding: 8px 6px;
    font-size: 12px;
    min-height: 38px;
    border-radius: 8px;
    gap: 5px;
}.plano-acoes.plano-acoes-rodape .plano-acao-btn i,.plano-acoes.plano-acoes-rodape .plano-acao-btn [data-lucide]{ font-size: 13px; }.plano-acao-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 10px 8px;
    background: var(--bg-alt, #f1f5f9);
    color: var(--text, #1e293b);
    border: 1px solid var(--border, #e2e8f0);
    border-radius: 10px;
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.2;
    cursor: pointer;
    transition: background .15s ease, border-color .15s ease, transform .1s ease;
    -webkit-tap-highlight-color: transparent;
    min-height: 44px; /* HIG iOS toque */
}.plano-acao-btn i,.plano-acao-btn [data-lucide]{ color: #3d6041; font-size: 14px; flex-shrink: 0; }.plano-acao-btn:hover { background: #f1f5f9; border-color: #b8e0bd; }.plano-acao-btn:active { transform: scale(0.97); }.plano-acao-btn:disabled { opacity: 0.55; cursor: wait; }.plano-acao-btn span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }.plano-meta-box {
    background: rgba(61, 96, 65, 0.08);
    border-left: 3px solid #3d6041;
    padding: 10px 14px;
    margin: 12px 0;
    border-radius: 0 8px 8px 0;
    font-size: 13.5px;
    color: var(--text-secondary);
}.plano-meta-box strong { color: var(--text); font-weight: 700; }.plano-orient-box {
    background: rgba(245,158,11,0.10);
    border-left: 3px solid #d8b774;
    padding: 10px 14px;
    margin: 12px 0;
    border-radius: 0 8px 8px 0;
    font-size: 13px;
    color: var(--text-secondary);
}.plano-orient-titulo {
    display: block;
    margin-bottom: 6px;
    color: var(--text);
    font-weight: 700;
}.plano-orient-titulo i,.plano-orient-titulo [data-lucide]{ color: #b45309; margin-right: 4px; }.plano-orient-lista { margin: 0; padding-left: 18px; }.plano-orient-lista li { margin-bottom: 4px; line-height: 1.5; }.plano-ver-todas {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: calc(100% - 28px);
    margin: 4px 14px 12px;
    padding: 12px 16px;
    background: rgba(61, 96, 65, 0.10);
    border: 1px dashed rgba(61, 96, 65, 0.45);
    border-radius: 12px;
    color: #2f4a32;
    font-family: inherit;
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
    transition: background .15s ease, border-color .15s ease, color .15s ease;
    -webkit-tap-highlight-color: transparent;
}.plano-ver-todas:hover,
.plano-ver-todas:focus-visible {
    background: rgba(61, 96, 65, 0.18);
    border-style: solid;
    border-color: #3d6041;
    color: #374438;
    outline: none;
}.plano-ver-todas .fa-arrow-right { font-size: 11px; }@media (max-width: 380px) {
    .plano-header { padding: 12px 14px; }
    .plano-info h4 { font-size: 13px; }
    .plano-calorias { font-size: 12px; padding: 5px 10px; }
}@media (min-width: 1024px) {
    .plano-header { padding: 18px 22px; }
    .plano-info h4 { font-size: 16px; }
    .plano-calorias { font-size: 14px; padding: 8px 16px; }
}@media (max-width: 380px) {
    .plano-acoes.plano-acoes-rodape .plano-acao-btn { padding: 7px 4px; font-size: 11.5px; }
    .plano-acoes.plano-acoes-rodape .plano-acao-btn i,
.plano-acoes.plano-acoes-rodape .plano-acao-btn [data-lucide]{ font-size: 12.5px; }
}@media (max-width: 380px) {
    .plano-acao-btn { font-size: 11.5px; padding: 9px 6px; gap: 4px; }
    .plano-acao-btn i,
.plano-acao-btn [data-lucide]{ font-size: 13px; }
}@media (min-width: 1024px) {
    .plano-acoes { gap: 12px; margin: 16px 0 20px; }
    .plano-acao-btn { padding: 12px 14px; font-size: 13.5px; }
}/* hidratacao.css: extraido de app.css em 2026-05-10 (sprint 7-6).
   37 regras. Carregado async (media=print onload). */


.water-card {
    background: linear-gradient(135deg, #e8eef2 0%, #f1f5f9 100%);
    border: 1px solid #cbd5e1;
    border-radius: 14px;
    padding: 16px;
    margin: 14px 0;
    box-shadow: 0 2px 8px rgba(44, 71, 98, 0.08);
}.water-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
}.water-title {
    font-size: 15px;
    font-weight: 700;
    color: #172a3f;
    display: flex;
    align-items: center;
    gap: 6px;
}.water-title i,.water-title [data-lucide]{ color: #3d5e7b; }.water-badge {
    font-size: 12px;
    font-weight: 600;
    color: #2c4762;
    background: rgba(255, 255, 255, 0.7);
    padding: 4px 10px;
    border-radius: 999px;
}.water-progress {
    height: 10px;
    background: rgba(255, 255, 255, 0.6);
    border-radius: 999px;
    overflow: hidden;
    margin-bottom: 10px;
}.water-progress-bar {
    height: 100%;
    background: linear-gradient(90deg, #5a7891, #2c4762);
    border-radius: 999px;
    transition: width 0.4s ease;
}.water-stats {
    display: flex;
    justify-content: space-between;
    gap: 6px;
    font-size: 12px;
    color: #334155;
    margin-bottom: 10px;
    flex-wrap: wrap;
}.water-actions { display: flex; gap: 8px; }.water-btn {
    flex: 1;
    padding: 10px 14px;
    background: #2c4762;
    color: #fff;
    border: none;
    border-radius: 10px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    transition: transform 0.1s, background 0.2s;
}.water-btn:active { transform: scale(0.97); background: #1f3854; }.water-note {
    margin-top: 8px;
    font-size: 11px;
    color: #475569;
    font-style: italic;
}
/* 2026-05-14: bloco "hidratacao-counter/dots/mini/splash/btn-mini" removido.
   Era da versao gamificada (renderHidratacaoGamificada), substituida pelo
   card unico #alertaHidratacao. Reducao: ~89 linhas, ~2.4KB. */
@media(pointer:coarse){.aval-btn{min-height:40px}}

/* ===== origem: css/app-revisao.css ===== */
/* =====================================================================
   app-revisao.css - Redesenho PROFUNDO do PWA do paciente (2026-05-28)
   ---------------------------------------------------------------------
   Camada ADITIVA, carregada por ultimo no <head>. Implementa o redesenho:
     1. Tipografia profissional + leve : Plus Jakarta Sans + Inter (fallback)
        + JetBrains Mono em numerais tabulares.
     2. Cards mais sutis (borda 1px + sombra leve, sem gradientes pesados).
     3. Bottom-nav refinado (altura 64-68px, alvos >=44px, item ativo em
        verde escuro com indicador 3px).
     4. Header compacto e fino.
     5. Botoes padronizados (>=44px em acoes importantes, raio 12px,
        estados default/hover/active/focus/disabled consistentes).
     6. Dark mode calibrado (#0a0e1b background, #1c2230 cards, bordas mais
        sutis). Mantem paridade clara/escura em todo texto.
     7. Estados de loading consistentes (skeleton/spinner) + estado vazio
        amigavel + toast central 3s.
     8. Micro-interacoes: scale .96 em :active, fade-in 180ms ao trocar
        de view (.app-section.active).
     9. Verde da marca consistente (usa tokens "--brand" prefixados; sem green ou emerald do Tailwind).
     10. Ritmo de cards compacto no mobile (menos rolagem).
   Reverter: comentar o <link> de app-revisao.css no index.html.
   ===================================================================== */

/* =====================================================================
   1. TIPOGRAFIA  : Plus Jakarta Sans + Inter (fallback) + JetBrains Mono
   Override dos tokens definidos em app.css (que tinha Inter + Fraunces).
   2026-05-28 (auditoria): comentario interno do :root parecia funcionar
   mas o parser ignorava a regra inteira (101 rules sem :root). Comentario
   foi movido para FORA do bloco — agora os tokens chegam ao runtime.
   ===================================================================== */
:root {
    --font-body: 'Plus Jakarta Sans', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --font-display: 'Plus Jakarta Sans', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    --font-numeric: 'Plus Jakarta Sans', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* Significado dos tokens:
   --font-body    : corpo, labels, paragrafos (Plus Jakarta 500/600)
   --font-display : titulos, KPIs hero (Plus Jakarta 700/800)
   --font-numeric : KPIs/IMC/peso (Inter tabular ou JetBrains Mono) */

/* Corpo da pagina: forca Plus Jakarta Sans em todo o ecossistema do app,
   inclusive em inputs/buttons/select (eles herdavam Inter via :root antigo). */
html, body,
input, button, select, textarea {
    font-family: var(--font-body);
}

/* Titulos: Plus Jakarta 700/800 com tracking levemente negativo.
   IMPORTANTE: sobrescreve --font-display antigo (Fraunces). */
h1, h2, h3, h4, h5, h6,
.dash-hero h1,
.historico-hero h2,
.calc-hero h2,
.avalcomp-hero h2,
.cog-hub-titulo,
.feedback-equipe-titulo,
.aval-timeline-data,
.card-header h3,
.home-hero-cta-title,
.next-appointment .date,
.app-header .header-brand {
    font-family: var(--font-display);
    font-feature-settings: "ss01" on, "cv11" on;
    letter-spacing: -0.012em;
}

/* Pesos dos titulos no PWA (sem serif/italic herdado): */
h1, h2 { font-weight: 800; }
h3, h4 { font-weight: 700; }
h5, h6 { font-weight: 600; }

/* Numeros : tabular + zero cortado em qualquer KPI. */
.stat-pro-value, .av-topo-imc-num, .av-topo-imc-val,
.kpi-value, .stat-card .value, .stat-card-pro .stat-value,
.stat-value, .progresso-streak strong {
    font-family: var(--font-numeric);
    font-variant-numeric: tabular-nums slashed-zero;
    letter-spacing: -0.008em;
    font-weight: 700;
}

/* =====================================================================
   2. CARDS MAIS SUTIS  (borda 1px + sombra leve, sem sombra pesada)
   ===================================================================== */
.main-content .card {
    border: 1px solid var(--border, #e5e7eb);
    border-radius: 14px;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
    transition: box-shadow .2s ease, border-color .2s ease;
}
.main-content .card:hover {
    box-shadow: 0 2px 6px rgba(15, 23, 42, 0.06);
}
.card-header {
    background: transparent;
    border-bottom: 1px solid var(--border-light, #f1f5f9);
    padding: 12px 16px;
}
.card-header h3 {
    font-size: 14.5px;
    font-weight: 700;
    color: var(--text);
}
.card-header h3 i,
.card-header h3 [data-lucide]{ color: var(--brand-primary, #3d6041); }

/* =====================================================================
   3. RITMO COMPACTO  (menos rolagem)
   No mobile, reduz espaco entre cards para 14px sem encostar.
   ===================================================================== */
@media (max-width: 599px) {
    .main-content .card { margin-bottom: 14px; }
    .main-content .card > .card-body { padding: 15px 16px; }
    .main-content .home-hero-cta { margin-bottom: 14px; }
    .main-content .next-appointment { margin-bottom: 14px; }
    .atalhos-grid { padding: 12px 0; }
}
@media (max-width: 480px) {
    .main-content .card { margin-bottom: 12px; }
    .stats-grid { gap: 8px; }
}

/* =====================================================================
   4. TITULOS E ROTULOS CENTRALIZADOS NAS CAIXAS
   Cabecalho de card sem acao a direita : centraliza o titulo.
   ===================================================================== */
.card-header > h3:only-child {
    justify-content: center;
    width: 100%;
    text-align: center;
}

/* =====================================================================
   5. ESTADOS VAZIOS  + CARREGANDO consistentes
   Padroniza estado vazio (icone em verde brand suave, max 28ch).
   Skeleton e spinner padronizados.
   ===================================================================== */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 8px;
    padding: 28px 18px;
}
.empty-state i,
.empty-state [data-lucide]{
    color: var(--brand-primary, #3d6041);
    opacity: 0.5;
    font-size: 32px;
    margin-bottom: 4px;
}
.empty-state p {
    margin: 0;
    max-width: 28ch;
    line-height: 1.45;
    color: var(--text-secondary, #475569);
    font-size: 14px;
}
.empty-state .btn,
.empty-state .btn-primary {
    margin-top: 10px;
}

/* Spinner padronizado (substitui fas fa-spinner espalhado). */
.app-spinner {
    width: 32px; height: 32px;
    border: 3px solid var(--border, #e2e8f0);
    border-top-color: var(--brand-primary, #3d6041);
    border-radius: 50%;
    animation: appSpin .8s linear infinite;
    display: inline-block;
}
@keyframes appSpin {
    to { transform: rotate(360deg); }
}

/* 2026-08-05 (limpeza de CSS morto): o skeleton .lr-skeleton (+ lr-skel-title,
   lr-skel-line, lr-skel-card e o keyframe lrSkelShine) foi removido. Nenhuma
   marcacao do app o usava: zero ocorrencia em index.html, pages/*.html e em
   todos os js/*.js, inclusive nos trechos que montam HTML por concatenacao.
   Quem desenha carregamento hoje e o .app-spinner (acima) e o texto
   "Carregando..." de cada secao. */

/* =====================================================================
   6. TOQUE / SAFE-AREA  : alvos >=44px (sem inflar)
   ===================================================================== */
.btn-icon,
button.icon-only,
.chip,
.pill,
.tab-pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* 2026-08-11 (auditoria desktop): alvo de 44px é regra de TOQUE. Sem o gate de
   ponteiro, chips e pílulas ficavam com 44px de altura no desktop com mouse,
   inflando cabeçalhos e filtros. Mesmo padrão já usado em app-fixes.css. */
@media (pointer: coarse) {
    .btn-icon,
    button.icon-only,
    .chip,
    .pill,
    .tab-pill { min-height: 44px; }
}
@media (pointer: fine) {
    .btn-icon,
    button.icon-only,
    .chip,
    .pill,
    .tab-pill { min-height: 34px; }
}

@media (max-width: 599px) {
    .main-content { padding-bottom: max(20px, var(--safe-bottom, 0px)); }
}

/* =====================================================================
   7. BOTOES PADRONIZADOS
   Primario   : verde brand, texto branco, raio 12, peso 700, >=44px
   Secundario : borda verde + texto verde, fundo transparente
   Destrutivo : vermelho semantico
   Estados    : :hover (eleva 1px), :active (scale .96), :focus-visible
                (outline 2 verde), :disabled (opacidade .6, sem sombra)
   ===================================================================== */
.btn-primary,
.btn-action,
.leitor-btn-primary,
.agenda-btn,
.btn-confirm,
.home-hero-cta-btn {
    font-family: var(--font-body);
    font-weight: 700;
    letter-spacing: 0.005em;
    border-radius: 12px;
    transition: transform .15s ease, box-shadow .18s ease,
                background .18s ease, opacity .15s ease, color .18s ease;
    -webkit-tap-highlight-color: transparent;
}

/* Garante altura minima 44px em CTAs principais (acoes do paciente).
   2026-08-11 (auditoria desktop): o 44px vale para TOQUE; com mouse o CTA
   fica em 38px. Padding e fonte continuam globais. */
.btn-primary,
.btn-action,
.agenda-btn,
.leitor-btn-primary {
    padding: 11px 18px;
    font-size: 14.5px;
}
@media (pointer: coarse) {
    .btn-primary,
    .btn-action,
    .agenda-btn,
    .leitor-btn-primary { min-height: 44px; }
}
@media (pointer: fine) {
    .btn-primary,
    .btn-action,
    .agenda-btn,
    .leitor-btn-primary { min-height: 38px; }
}

.btn-primary:hover:not(:disabled),
.btn-action:hover:not(:disabled),
.agenda-btn:hover:not(:disabled),
.leitor-btn-primary:hover:not(:disabled) {
    transform: translateY(-1px);
    box-shadow: 0 6px 16px rgba(61, 96, 65, 0.22);
}
.btn-primary:active:not(:disabled),
.btn-action:active:not(:disabled),
.agenda-btn:active:not(:disabled),
.leitor-btn-primary:active:not(:disabled),
.home-hero-cta-btn:active:not(:disabled) {
    transform: scale(.96);
}
.btn-primary:focus-visible,
.btn-action:focus-visible,
.agenda-btn:focus-visible,
.leitor-btn-primary:focus-visible {
    outline: 2px solid var(--brand-primary, #3d6041);
    outline-offset: 2px;
}
.btn-primary:disabled,
.btn-action:disabled,
.agenda-btn:disabled,
.leitor-btn-primary:disabled {
    opacity: .6;
    cursor: not-allowed;
    box-shadow: none;
    transform: none;
}

/* 2026-08-05 (limpeza de CSS morto): .btn-secondary e .btn-danger removidos.
   Nenhum elemento do app usa essas classes: a unica ocorrencia parecida no
   app.js e `cog-hub-btn-secondary`, outra classe, que so contem o nome como
   pedaco. Os botoes vivos do app sao .btn-action, .leitor-btn-primary,
   .cog-hub-btn-* e .tk-*. */

/* =====================================================================
   8. BOTTOM-NAV refinado (altura ~64-68px, item ativo verde escuro)
   ===================================================================== */
.bottom-nav {
    /* Sombra mais discreta + borda 1px sutil. */
    box-shadow: 0 -4px 14px rgba(15, 23, 42, 0.05);
    border-top: 1px solid rgba(226, 232, 240, 0.7);
    /* 2026-07-25 (Jayme): ainda sobrava faixa vazia embaixo do menu no
       celular. A almofada de 60% do safe-area (teto 18px) + padding do item
       deixava ~22px mortos abaixo dos rotulos no iPhone. Agora: almofada de
       35% do safe-area (piso 4px, teto 12px) e item mais compacto. O fundo
       da barra continua cobrindo a area do home indicator (bottom: 0) e o
       alvo de toque (pilula de 44px) fica acima da zona de gesto. */
    align-items: center;
    padding-top: 3px;
    /* 16/10/2026 (#703 h): no app Android o SystemBars do Capacitor 8 injeta --safe-area-inset-bottom e o menu
       pinta o proprio fundo atras da barra do sistema com os itens acima dela; fora do app vale a almofada. */
    padding-bottom: var(--safe-area-inset-bottom, clamp(4px, calc(env(safe-area-inset-bottom, 0px) * 0.35), 12px));
}
.nav-item {
    min-height: 52px;
    padding: 3px 4px 2px;
    color: #64748b;
}
.nav-item-icon {
    width: 52px;
    min-height: 44px;
    border-radius: 14px;
    transition: background .22s ease, transform .18s ease;
}
.nav-item-icon i,
.nav-item-icon [data-lucide]{
    font-size: 22px;
    line-height: 1;
    filter: none;
}
.nav-item-label {
    font-family: var(--font-body);
    font-size: 11px;
    font-weight: 600;
    line-height: 1.1;
    letter-spacing: 0.01em;
    margin-top: 1px;
}
.nav-item.active {
    color: var(--brand-primary-darker, #213423);
}
.nav-item.active .nav-item-icon {
    background: var(--brand-tint, #f1f5f9);
}
.nav-item.active .nav-item-icon i,
.nav-item.active .nav-item-icon [data-lucide]{
    color: var(--brand-primary-darker, #213423);
    transform: scale(1.04);
}
.nav-item.active .nav-item-label {
    font-weight: 800;
    color: var(--brand-primary-darker, #213423);
}
.nav-item::before {
    height: 3px;
    width: 28px;
    background: var(--brand-primary-dark, #2f4a32);
}
.nav-item-badge {
    background: #ef4444;
    color: #fff;
    font-family: var(--font-body);
    font-size: 10px;
    font-weight: 700;
    box-shadow: 0 1px 3px rgba(239, 68, 68, .35);
}

/* =====================================================================
   9. HEADER compacto e fino
   ===================================================================== */
.app-header {
    box-shadow: 0 1px 0 rgba(15, 23, 42, 0.05);
}
.app-header .header-brand img {
    height: 32px;
    width: auto;
    max-width: 180px;
}
.app-header .header-btn {
    min-width: 40px;
    min-height: 40px;
    border-radius: 10px;
    transition: background .15s ease, color .15s ease, transform .12s ease;
}
.app-header .header-btn:active { transform: scale(.94); }
.app-header .header-btn .badge {
    font-family: var(--font-body);
    font-weight: 700;
    font-size: 10px;
}

/* =====================================================================
   10. NEXT APPOINTMENT  : sombra mais sutil, mesma identidade
   ===================================================================== */
.next-appointment {
    box-shadow: 0 4px 12px rgba(61, 96, 65, 0.22);
    border-radius: 14px;
}
.next-appointment .date {
    font-family: var(--font-display);
    font-weight: 800;
    letter-spacing: -0.012em;
}
.next-appointment .btn-action {
    min-height: 40px;
    border-radius: 10px;
}

/* =====================================================================
   11. HOME HERO CTA  : tipografia atualizada (Plus Jakarta)
   ===================================================================== */
.home-hero-cta {
    box-shadow: 0 4px 14px rgba(107, 131, 110, 0.18);
}
.home-hero-cta-title {
    font-family: var(--font-display);
    font-weight: 800;
    letter-spacing: -0.012em;
}
.home-hero-cta-btn {
    min-height: 40px;
    padding: 10px 18px;
    border-radius: 10px;
}

/* =====================================================================
   12. STAT-CARDS  : tipografia + sombra coerente
   ===================================================================== */
.stat-card-pro,
.stat-card {
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}
.stat-card .value,
.stat-card-pro .stat-pro-value {
    font-family: var(--font-numeric);
    font-variant-numeric: tabular-nums slashed-zero;
    font-weight: 800;
}

/* =====================================================================
   13. CONSISTENCIA DE MARCA  (badges/labels verde residuais)
   ===================================================================== */
.badge.green,
.tag.green,
.label.green {
    background: var(--brand-tint, #f1f5f9);
    color: var(--brand-primary-darker, #213423);
}

/* =====================================================================
   14. FADE-IN entre views (180ms) + REDUCED MOTION
   ===================================================================== */
@keyframes appSectionFadeIn {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: translateY(0); }
}
.app-section.active {
    animation: appSectionFadeIn 0.18s ease-out;
}

@media (prefers-reduced-motion: reduce) {
    .app-section,
    .app-section.active,
    .btn-primary, .btn-secondary, .btn-danger,
    .nav-item, .nav-item.active,
    .home-hero-cta, .home-hero-cta-btn,
    .lr-skeleton, .app-spinner {
        animation: none !important;
        transition: none !important;
    }
}

/* =====================================================================
   15. DARK MODE  : paleta calibrada
   Antes : #0f172a (slate-900) / #1e293b (slate-800)
   Agora : #0a0e1b (mais profundo) / #1c2230 (cards) — visual mais premium
           e mais distinto entre superficie e card.
   ===================================================================== */
html.theme-dark {
    --bg: #0a0e1b;
    --bg-alt: #141824;
    --bg-white: #1c2230;
    --card: #1c2230;
    --card-hover: #242a3a;
    --text: #e2e8f0;
    --text-secondary: #cbd5e1;
    --text-muted: #94a3b8;
    --border: #2a3142;
    --border-light: #1e2433;
    color-scheme: dark;
}
html.theme-dark body {
    background: #0a0e1b;
    color: #e2e8f0;
}
html.theme-dark .main-content .card {
    background: #1c2230;
    border-color: #2a3142;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}
html.theme-dark .main-content .card:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
    border-color: #34405a;
}
html.theme-dark .card-header {
    border-bottom-color: #232a3a;
}
html.theme-dark .bottom-nav {
    background: #0f1422;
    border-top-color: #1f2535;
    box-shadow: 0 -4px 14px rgba(0, 0, 0, 0.4);
}
html.theme-dark .bottom-nav::after { background: #0f1422; }
html.theme-dark .nav-item { color: #94a3b8; }
html.theme-dark .nav-item.active {
    color: #86c98c;
}
html.theme-dark .nav-item.active .nav-item-icon {
    background: rgba(134, 201, 140, 0.14);
}
html.theme-dark .nav-item.active .nav-item-icon i,
html.theme-dark .nav-item.active .nav-item-label,
html.theme-dark .nav-item.active .nav-item-icon [data-lucide]{
    color: #86c98c;
}
html.theme-dark .nav-item::before { background: #86c98c; }

html.theme-dark .app-header {
    background: rgba(10, 14, 27, 0.92);
    border-bottom: 1px solid #1f2535;
    box-shadow: none;
}
html.theme-dark .app-header .header-btn {
    color: #cbd5e1;
}
html.theme-dark .app-header .header-btn:hover {
    background: rgba(134, 201, 140, 0.08);
    color: #86c98c;
}

html.theme-dark .empty-state i,
html.theme-dark .empty-state [data-lucide]{ color: #86c98c; opacity: .5; }
html.theme-dark .empty-state p { color: #94a3b8; }

/* 2026-05-28 (auditoria): titulos e texto dentro de cards estavam em
   verde escuro hardcoded (#3d6041 / #2f4a32) — invisivel sobre fundo
   #1c2230 do dark. Override para texto claro em todos os elementos
   de texto dentro de card no dark mode. Verde brand fica como cor
   semantica de icone/CTA, nunca como cor de texto sobre escuro. */
/* 2026-08-28 (revisao geral do texto secundario): a rede ganhou
   `:not([class*="muted"])` em div E em span. Antes, com especificidade (0,7,2),
   ela atropelava a propria saida que esta folha oferece
   (`.main-content .card .text-muted`, (0,4,1)) e qualquer regra de classe com
   `color: var(--text-muted)`: rotulo de KPI, contagem de categoria, data de
   live, separador de data do chat e estado vazio ficavam TODOS na mesma cor
   do titulo (#e2e8f0), sem hierarquia. Medido por Playwright em 16 telas no
   escuro em 27 e 28/08. O caminho canonico agora e marcar o texto secundario
   com a classe `text-muted` no template: a rede deixa passar e o tom #94a3b8
   (4,5:1 ou mais sobre o fundo de card #1e293b, medido 5,71:1) assume.
   A excecao pontual `:not(.produto-util-desc)` de 27/08 saiu: a descricao do
   produto agora carrega `text-muted` no proprio template.
   `small` dentro de card nunca precisou de excecao: a rede so casa div e span,
   e a regra `.card small` abaixo atinge o elemento direto, o que vence
   heranca. Medido: small na tela de Fotos ja rendia #94a3b8 antes da rede
   mudar. */
html.theme-dark .main-content .card,
html.theme-dark .main-content .card h1,
html.theme-dark .main-content .card h2,
html.theme-dark .main-content .card h3,
html.theme-dark .main-content .card h4,
html.theme-dark .main-content .card h5,
html.theme-dark .main-content .card h6,
html.theme-dark .main-content .card p,
html.theme-dark .main-content .card span:not([class*="badge"]):not([class*="chip"]):not([class*="muted"]),
html.theme-dark .main-content .card label,
html.theme-dark .main-content .card div:not([class*="badge"]):not([class*="chip"]):not([class*="time"]):not([class*="muted"]) {
    color: #e2e8f0;
}
html.theme-dark .main-content .card .text-muted,
html.theme-dark .main-content .card small {
    color: #94a3b8;
}
/* Verde brand SOMENTE em icones e acoes; titulo principal volta para claro. */
html.theme-dark .main-content .card .card-header h3,
html.theme-dark .main-content .card-header h3 {
    color: #e2e8f0;
}
html.theme-dark .main-content .card .card-header h3 i,
html.theme-dark .main-content .card .card-header h3 [data-lucide]{
    color: #86c98c;
}

html.theme-dark .lr-skeleton {
    background: linear-gradient(90deg, #1c2230 0%, #242a3a 50%, #1c2230 100%);
    background-size: 200% 100%;
}
html.theme-dark .app-spinner {
    border-color: #2a3142;
    border-top-color: #86c98c;
}

/* No dark, KPIs e numerais herdam um pouco mais de tracking pra leitura. */
html.theme-dark .stat-card-pro .stat-pro-value,
html.theme-dark .stat-card .value {
    color: #f1f5f9;
}

/* =====================================================================
   16. TOAST padronizado : canto inferior central no mobile, 3s
   (definido aqui pra qualquer view que chame showToast() ja herdar)
   ===================================================================== */
.app-toast,
#appToast,
.toast-container {
    position: fixed;
    left: 50%;
    bottom: calc(var(--nav-height, 65px) + var(--safe-bottom, 0px) + 16px);
    transform: translateX(-50%);
    z-index: 1100;
    pointer-events: none;
}
.app-toast .toast,
#appToast .toast,
.toast-container .toast {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 11px 16px;
    background: rgba(15, 23, 42, 0.94);
    color: #fff;
    border-radius: 12px;
    font-family: var(--font-body);
    font-size: 14px;
    font-weight: 600;
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.25);
    max-width: min(90vw, 360px);
    pointer-events: auto;
    animation: toastIn 0.2s ease-out, toastOut 0.25s ease-in 2.75s forwards;
}
.app-toast .toast.toast-success { background: var(--brand-primary-dark, #2f4a32); }
.app-toast .toast.toast-error,
.app-toast .toast.toast-danger { background: #dc2626; }
.app-toast .toast.toast-warn,
.app-toast .toast.toast-warning { background: #d97706; color: #fff; }
@keyframes toastIn {
    from { opacity: 0; transform: translate(-50%, 8px); }
    to   { opacity: 1; transform: translate(-50%, 0); }
}
@keyframes toastOut {
    to { opacity: 0; transform: translate(-50%, 8px); }
}

/* =====================================================================
   17. FOCUS VISIBLE GLOBAL  : padrao acessivel verde brand
   ===================================================================== */
:focus-visible {
    outline-color: var(--brand-primary, #3d6041);
}

/* =====================================================================
   18. PULL-TO-REFRESH preservado : nao mexer (ja existe no JS).
   Aqui apenas ajusta o indicador visual se houver classe .ptr-indicator.
   ===================================================================== */
.ptr-indicator i,
.ptr-indicator .fa-arrow-down,
.ptr-indicator .fa-sync,
/* =====================================================================
   18. PULL-TO-REFRESH preservado : nao mexer (ja existe no JS).
   Aqui apenas ajusta o indicador visual se houver classe .ptr-indicator.
   ===================================================================== */
.ptr-indicator [data-lucide]{
    color: var(--brand-primary, #3d6041);
}

/* =====================================================================
   19. REFEICAO: overflow / margem (2026-05-28)
   Caso reportado: paciente Carlos tinha uma refeicao chamada "ht" cujo
   conteudo ultrapassava a borda do card e ficava cortada. Causa: varios
   flex containers (.refeicao-header h5, .ref-alt, .alimento-item) sem
   min-width:0, entao os filhos texto nao shrinkavam abaixo do conteudo e
   overflowavam horizontalmente. Tambem havia chance de string longa sem
   espaco (ex.: link inteiro) escapar do flex.
   Fix: containment + min-width:0 + overflow-wrap:anywhere em texto.
   ===================================================================== */
.refeicao { box-sizing: border-box; overflow: hidden; }
.refeicao-header { box-sizing: border-box; gap: 8px; min-width: 0; }
.refeicao-header h5 { min-width: 0; flex: 1 1 auto; overflow-wrap: anywhere; word-break: break-word; line-height: 1.3; }
.refeicao-header .refeicao-horario { flex-shrink: 0; }
.refeicao-content { box-sizing: border-box; max-width: 100%; }
.ref-slot, .ref-slot * { box-sizing: border-box; max-width: 100%; }
.ref-alt { min-width: 0; max-width: 100%; }
.ref-alt-texto { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; word-break: break-word; }
.alimento-item { box-sizing: border-box; min-width: 0; }
.alimento-item > div:last-child { flex: 1 1 auto; min-width: 0; }
.alimento-nome, .alimento-quantidade { overflow-wrap: anywhere; word-break: break-word; }
.ref-obs { box-sizing: border-box; max-width: 100%; }
.ref-obs-texto, .ref-obs-lista { min-width: 0; overflow-wrap: anywhere; word-break: break-word; }

/* =====================================================================
   PWA: bloqueia pull-to-refresh NATIVO do browser (2026-05-28)
   Causa do "app sai e volta": o gesto de puxar a tela disparava o Chrome
   PTR (cria header com spinner verde e recarrega a URL inteira -> volta
   pra tela de carregando). overscroll-behavior-y:contain impede esse
   gesto subir pro browser, mantendo so o handler custom (iniciarPullToRefresh).
   ===================================================================== */
html, body { overscroll-behavior-y: contain; }
/* iOS Safari: overscroll-behavior nao funciona; usar -webkit-overflow-scrolling
   touch + bloqueio extra. */
#appWrapper { overscroll-behavior-y: contain; -webkit-overflow-scrolling: touch; }

/* =====================================================================
   AVALIACOES: refinamento editorial (2026-05-28)
   "use o front design": aproximar do padrao das paginas Resumo / Hoje
   ja redesenhadas. Mantem todos os IDs/ classes, so refina o visual.
   - Hero menos saturado, mais arejado, com numeros tabulares fortes
   - KPI cards mais espacados, ico em fundo translucido (vidro), label
     em maiusculo letterspaced
   - Timeline com card limpo, hover suave, badge "Recente" verde brand
   - Historico titulo refinado, sem icones agressivos
   ===================================================================== */
.aval-hero {
    border-radius: 18px !important;
    background: linear-gradient(135deg, #2f4a32 0%, #213423 100%) !important;
    box-shadow:
        0 1px 2px rgba(36, 49, 38, 0.18),
        0 18px 38px -18px rgba(47, 74, 50, 0.55) !important;
    border: 1px solid rgba(255, 255, 255, 0.06) !important;
    padding: 20px 22px !important;
    margin-bottom: 16px;
}
.aval-hero-top {
    margin-bottom: 16px !important;
}
.aval-hero-label {
    font-size: 10.5px !important;
    letter-spacing: 1.2px !important;
    text-transform: uppercase !important;
    font-weight: 800 !important;
    color: rgba(255, 255, 255, 0.78) !important;
}
.aval-hero-data {
    font-size: 12.5px !important;
    font-weight: 600 !important;
    color: rgba(255, 255, 255, 0.92) !important;
}
.aval-kpis {
    gap: 14px !important;
}
.aval-kpi {
    background: rgba(255, 255, 255, 0.06) !important;
    border: 1px solid rgba(255, 255, 255, 0.10) !important;
    border-radius: 12px !important;
    padding: 12px 14px !important;
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
}
.aval-kpi-ico {
    width: 36px !important; height: 36px !important;
    background: rgba(255, 255, 255, 0.12) !important;
    border-radius: 10px !important;
    display: flex; align-items: center; justify-content: center;
    font-size: 15px !important;
}
.aval-kpi-label {
    font-size: 10.5px !important;
    letter-spacing: 0.7px !important;
    text-transform: uppercase !important;
    font-weight: 700 !important;
    color: rgba(255, 255, 255, 0.72) !important;
}
.aval-kpi-valor {
    font-size: 22px !important;
    font-weight: 800 !important;
    letter-spacing: -0.6px !important;
    line-height: 1.05 !important;
    font-variant-numeric: tabular-nums;
    font-family: 'JetBrains Mono', 'SF Mono', Menlo, monospace !important;
    color: #ffffff !important;
}
.aval-kpi-valor small {
    font-size: 12px !important;
    font-weight: 600 !important;
    margin-left: 3px !important;
    color: rgba(255, 255, 255, 0.78) !important;
    font-family: inherit !important;
}

/* Historico timeline refinado */
.aval-historico-titulo {
    font-size: 13px !important;
    font-weight: 700 !important;
    letter-spacing: 0.5px !important;
    text-transform: uppercase !important;
    color: var(--brand-primary-darker, #2f4a32) !important;
    margin: 22px 0 12px !important;
    padding-left: 12px !important;
    border-left: 3px solid var(--brand-primary, #3d6041) !important;
}
.aval-timeline { padding-left: 14px !important; border-left: 2px dashed rgba(61, 96, 65,.22) !important; margin-left: 4px; }
.aval-timeline-item { position: relative; padding-bottom: 14px !important; }
.aval-timeline-dot {
    width: 12px !important; height: 12px !important;
    border-radius: 50% !important;
    background: #ffffff !important;
    border: 3px solid var(--brand-primary, #3d6041) !important;
    box-shadow: 0 0 0 3px rgba(61, 96, 65,.12) !important;
    position: absolute !important;
    left: -22px !important; top: 16px !important;
}
.aval-timeline-item.latest .aval-timeline-dot {
    background: var(--brand-primary, #3d6041) !important;
    border-color: #ffffff !important;
    box-shadow: 0 0 0 3px rgba(61, 96, 65,.32), 0 0 0 6px rgba(61, 96, 65,.10) !important;
}
.aval-timeline-card {
    border-radius: 14px !important;
    border: 1px solid rgba(61, 96, 65, 0.16) !important;
    box-shadow: 0 1px 2px rgba(36, 49, 38, 0.04), 0 6px 14px -8px rgba(47, 74, 50, 0.18) !important;
    background: #ffffff !important;
    transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease !important;
}
.aval-timeline-card:hover {
    transform: translateY(-1px);
    border-color: rgba(61, 96, 65, 0.32) !important;
    box-shadow: 0 1px 2px rgba(36, 49, 38, 0.05), 0 12px 22px -10px rgba(47, 74, 50, 0.28) !important;
}
.aval-timeline-head { padding: 14px 16px !important; }
.aval-timeline-data {
    font-size: 14px !important;
    font-weight: 700 !important;
    color: #1f2937 !important;
    display: flex !important; align-items: center; gap: 10px; flex-wrap: wrap;
}
.aval-timeline-resumo {
    font-size: 12.5px !important;
    color: #475569 !important;
    margin-top: 4px !important;
    font-variant-numeric: tabular-nums;
}
/* 2026-09-18: a linha de resumo do item ("68,5 kg . IMC 25,2") e a PREVIA do
   cartao fechado. Com o cartao aberto ela repetia, palavra por palavra, o que
   o detalhe logo abaixo ja mostrava: medido, o IMC aparecia QUATRO vezes na
   mesma tela e o peso em tres formatos. Some ao abrir e volta ao fechar.
   O gancho `aval-aberta` e posto pelo toggleAvaliacaoDetalhe. */
.aval-timeline-card.aval-aberta .aval-timeline-resumo { display: none; }

/* ===========================================================================
   2026-09-18: a calha do trilho no celular
   ---------------------------------------------------------------------------
   Medido em 390px: o texto da avaliacao so comecava em x=48, porque ate chegar
   nele havia CINCO recuos encaixados: .main-content 10px, borda do .card 1px,
   .card-body 16px, o trilho (margin 4 + borda 2 + padding 14 = 20px) e a borda
   do proprio cartao. Com os 24px do lado direito, 72px da tela (18,5%) eram
   moldura. Em 320px a conta piora para 20%.

   No celular o trilho sai e a marca passa para DENTRO do cartao: um filete
   verde no item mais recente diz a mesma coisa que o ponto na linha, sem
   gastar coluna. O trilho continua valendo do tablet para cima, onde sobra
   largura. As regras ficam AQUI, logo depois das globais que elas corrigem,
   para a historia nao se partir entre duas folhas.
   =========================================================================== */
@media (max-width: 560px) {
    .aval-timeline {
        padding-left: 0 !important;
        border-left: 0 !important;
        margin-left: 0 !important;
        width: 100% !important;
    }
    /* O ponto vivia em left:-22px, ou seja, dentro da calha que acabou de sair. */
    .aval-timeline-dot { display: none !important; }
    /* O filete da ultima avaliacao entra como sombra INTERNA, nao como borda:
       borda de 3px comeria 3px do texto de volta, e o ganho de largura era o
       motivo de tirar o trilho. A elevacao do cartao e repetida aqui porque
       box-shadow nao acumula entre regras. */
    .aval-timeline-item.latest > .aval-timeline-card {
        box-shadow:
            inset 3px 0 0 var(--brand-primary, #3d6041),
            0 1px 2px rgba(36, 49, 38, 0.04),
            0 6px 14px -8px rgba(47, 74, 50, 0.18) !important;
    }
    .aval-timeline-item { padding-bottom: 10px !important; }
    /* O historico e um cartao DENTRO de outro cartao: a moldura de fora nao
       carrega informacao nenhuma (o card so tem um card-body, sem cabecalho
       proprio) e no celular ela so consome largura. Vira espacamento, e cada
       avaliacao segue sendo o cartao que a pessoa toca. Escopo por :has para
       nao mexer em card nenhum fora do historico de avaliacoes. */
    .card:has(> .card-body > .aval-timeline) {
        border: 0 !important;
        background: transparent !important;
        box-shadow: none !important;
        border-radius: 0 !important;
    }
    .card-body:has(> .aval-timeline) {
        padding-left: 0 !important;
        padding-right: 0 !important;
    }
}
.aval-badge-latest {
    /* 2026-07-17 (auditoria contraste AA): esta regra carrega depois do
       app-deferred.css e tem !important, entao era ela quem valia de fato.
       Ponta clara #609165 = 3,66:1 com branco -> #2f4a32 (5,06:1) -> #3d6041. */
    background: linear-gradient(135deg, #2f4a32, #213423) !important;
    color: #ffffff !important;
    padding: 3px 9px !important;
    border-radius: 999px !important;
    font-size: 10px !important;
    font-weight: 800 !important;
    letter-spacing: 0.5px !important;
    text-transform: uppercase !important;
}
.aval-chevron {
    color: var(--brand-primary, #3d6041) !important;
    transition: transform 0.2s ease;
}

/* Botao comparativo PDF mais limpo */
.aval-compare-pdf-btn {
    width: 100%;
    background: rgba(61, 96, 65, 0.10) !important;
    /* 2026-08-11: --brand-text vira por tema. O verde escuro fixo dava 1,4:1
       no modo escuro e o override dark do app.css perdia para este important. */
    color: var(--brand-text, #2f4a32) !important;
    border: 1px dashed rgba(61, 96, 65, 0.40) !important;
    border-radius: 12px !important;
    padding: 12px 16px !important;
    font-weight: 700 !important;
    font-size: 13px !important;
    cursor: pointer;
    transition: background 0.18s ease;
}
.aval-compare-pdf-btn:hover {
    background: rgba(61, 96, 65, 0.18) !important;
}

/* Dark mode mantem hero verde escuro (ja esta em tom alvo); ajusta apenas
   timeline card pra nao misturar branco com fundo escuro. */
html.theme-dark .aval-timeline-card,
html:not(.theme-light) .aval-timeline-card {
    background: #1c2230 !important;
    border-color: rgba(134, 201, 140, 0.16) !important;
}
html.theme-dark .aval-timeline-data,
html:not(.theme-light) .aval-timeline-data { color: #e2e8f0 !important; }
html.theme-dark .aval-timeline-resumo,
html:not(.theme-light) .aval-timeline-resumo { color: #94a3b8 !important; }
html.theme-dark .aval-historico-titulo,
html:not(.theme-light) .aval-historico-titulo { color: #86c98c !important; }

/* =====================================================================
   20. PULL-TO-REFRESH suave (sem reload de browser) (2026-05-28)
   Suaviza a transicao do indicador ptr-indicator: antes o gesto disparava
   um window.location.reload() que sumia o app por 1-2s; agora o handler
   refaz so o estado e re-renderiza (ver mudanca em app.js).
   ===================================================================== */
.ptr-indicator {
    transition: transform 0.22s cubic-bezier(.2,.9,.3,1), opacity 0.18s ease;
}
.ptr-indicator.ptr-loading i,
.ptr-indicator.ptr-loading [data-lucide]{
    animation: ptrSpin 0.9s linear infinite;
}
@keyframes ptrSpin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

/* =====================================================================
   21. FIX DARK: modal de detalhe da avaliacao (Historico fisico)
   (2026-06-10)
   Causa raiz: app.css tem a regra global
     .modal-content [style*="color:#0f172a"], ... [style*="color:#475569"]
       { color:var(--text)!important }
   que, em html.theme-dark, forca o texto inline do modal para #f1f5f9
   (quase branco). Porem os FUNDOS inline do modal (#f8fafc nas linhas de
   medida e #e8f7ee nas observacoes) nao escureciam: o override antigo
     html.theme-dark .aval-detail-modal [style*="background:#f8fafc"]
       { background:#0f172a }
   nao tem !important e perde para o style inline. Resultado: letra
   branca sobre fundo claro, ilegivel. Bloco abaixo escurece os fundos
   (com !important pontual, mesma tecnica do nuclear fix) e clareia os
   acentos verdes/vermelhos para manter contraste AA (>=4.5:1) sobre
   #0f172a. Escopo estrito em html.theme-dark: modo claro intacto.
   ===================================================================== */
/* Linhas de medida (Peso, IMC, %Gordura, circunferencias, RCQ) */
html.theme-dark .aval-detail-modal [style*="background:#f8fafc"],
html.theme-dark .aval-detail-modal [style*="background: #f8fafc"] {
    background: #0f172a !important;
    border-left-color: var(--brand-pastel, #86c98c) !important;
}
/* Caixa de observacoes (tint verde claro no modo claro) */
html.theme-dark .aval-detail-modal [style*="background:#e8f7ee"],
html.theme-dark .aval-detail-modal [style*="background: #e8f7ee"] {
    background: rgba(61, 96, 65, 0.16) !important;
    border-left-color: var(--brand-pastel, #86c98c) !important;
}
/* Botao secundario "Enviar PDF para meu email" (fundo branco inline) */
html.theme-dark .aval-detail-modal button[style*="background:#fff"] {
    background: #0f172a !important;
    border-color: var(--brand-pastel, #86c98c) !important;
}
/* Titulos de secao e icones em verde escuro (#3d6041/#609165): ilegiveis
   sobre fundo escuro; viram verde pastel da marca. */
html.theme-dark .aval-detail-modal [style*="color:#213423"],
html.theme-dark .aval-detail-modal [style*="color: #213423"],
html.theme-dark .aval-detail-modal [style*="color:#3d6041"],
html.theme-dark .aval-detail-modal [style*="color: #3d6041"] {
    color: var(--brand-pastel, #86c98c) !important;
}
/* Status/deltas e classificacao IMC: tons mais claros para AA no escuro */
html.theme-dark .aval-detail-modal [style*="color:#dc2626"] { color: #f87171 !important; }
html.theme-dark .aval-detail-modal [style*="color:#ef4444"] { color: #f87171 !important; }
html.theme-dark .aval-detail-modal [style*="color:#991b1b"] { color: #fca5a5 !important; }
html.theme-dark .aval-detail-modal [style*="color:#b45309"] { color: #fbbf24 !important; }

/* =====================================================================
   22. FIX DARK: opcoes/alternativas do PLANO ALIMENTAR (2026-06-10)
   Causa raiz: as linhas de alternativa do plano (.ref-alt) tem em app.css
   fundo claro fixo (.alt-zebra = var(--brand-tint) = #f1f5f9 ; .alt-branco
   = #fff) e cor de texto #1e293b. Em html.theme-dark, --brand-tint NAO e
   sobrescrito (continua #f1f5f9) e uma regra global de modo escuro clareia
   o texto para #e2e8f0. Resultado provado no QA (paciente 2677, plano 156):
   texto cinza claro (#e2e8f0) sobre faixa clara (#f1f5f9 / #fff) => contraste
   ~1.1:1, alternativas praticamente ilegiveis no escuro.
   Fix: escurece as faixas (zebra = tint verde translucido ; branca = card
   escuro) e garante texto/numeracao/cabecalho legiveis (AA >=4.5:1) sobre
   #0f172a. Mantem a barra verde de acento. Mesma tecnica do bloco 21.
   Escopo estrito em html.theme-dark: modo claro 100% intacto.
   ===================================================================== */
html.theme-dark .ref-alt {
    color: var(--text-secondary, #cbd5e1) !important;
    border-left-color: var(--brand-pastel, #86c98c) !important;
}
html.theme-dark .ref-alt.alt-zebra {
    background: rgba(61, 96, 65, 0.14) !important;
}
html.theme-dark .ref-alt.alt-branco {
    background: var(--card, #1e293b) !important;
}
html.theme-dark .ref-alt-num {
    color: var(--brand-pastel, #86c98c) !important;
}
html.theme-dark .ref-alt-texto {
    color: var(--text, #f1f5f9) !important;
}
html.theme-dark .ref-slot-header {
    color: var(--brand-pastel, #86c98c) !important;
}
/* Caixa de observacoes da refeicao: creme claro -> amber translucido escuro */
html.theme-dark .ref-obs {
    background: rgba(202, 138, 4, 0.16) !important;
    color: #fcd9a3 !important;
}
html.theme-dark .ref-obs-label {
    color: #fbbf24 !important;
}
html.theme-dark .ref-obs-texto,
html.theme-dark .ref-obs-lista,
html.theme-dark .ref-obs-lista li {
    color: #fcd9a3 !important;
}
/* Estado vazio e itens estruturados (alimento-*) ja herdam --text no escuro,
   reforco defensivo para a quantidade que usa --text-muted. */
html.theme-dark .ref-vazia {
    color: var(--text-muted, #94a3b8) !important;
}

/* =====================================================================
   14. REVISAO 2026-07-25 (Jayme): Ultima avaliacao slim + cabecalhos de
       secao sem safe-area indevido + chip de formulario ja enviado
   ===================================================================== */

/* 14a. Cabecalhos de secao (forms/med/lives/leitor/historico/rec): a regra
   antiga aplicava padding-top:max(env(safe-area-inset-top),16px), pensada
   para headers colados no TOPO da viewport. Esses heroes ficam DENTRO do
   conteudo, abaixo do .app-header fixo; em celular com notch isso virava
   uma faixa vazia de ~50px dentro do card. Normaliza o padding. */
.forms-hero,
.historico-hero,
.leitor-hero,
.lives-hero,
.med-hero,
.rec-hero {
    padding-top: 18px !important;
    padding-bottom: 18px !important;
}

/* 14b. Ultima avaliacao: hero mais slim e profissional. Sem caixotes de
   icone (eram o maior gasto vertical), KPIs em faixa unica de 4 colunas,
   numeros menores e alinhados. O bloco cai de ~450px para ~150px. */
.aval-hero {
    padding: 14px 16px 13px !important;
    margin-bottom: 12px !important;
}
.aval-hero::before { display: none; }
.aval-hero-top {
    margin-bottom: 10px !important;
}
.aval-kpis {
    grid-template-columns: repeat(4, 1fr) !important;
    gap: 8px !important;
}
.aval-kpi {
    padding: 9px 4px 8px !important;
    border-radius: 10px !important;
    gap: 2px;
}
.aval-kpi-ico { display: none !important; }
.aval-kpi-valor {
    font-size: 16.5px !important;
    letter-spacing: -0.4px !important;
}
.aval-kpi-valor small { font-size: 10.5px !important; margin-left: 2px !important; }
.aval-kpi-label {
    font-size: 9.5px !important;
    letter-spacing: 0.5px !important;
    margin-top: 1px;
}
@media (min-width: 480px) {
    .aval-kpi-valor { font-size: 19px !important; }
    .aval-kpi-label { font-size: 10px !important; }
}
@media (min-width: 1024px) {
    .aval-hero { padding: 18px 22px 16px !important; }
    .aval-kpi { padding: 12px 8px 10px !important; }
}

/* 14c. Chip "Formulario desta semana ja enviado" na secao Meus Formularios. */
.forms-week-ok {
    display: flex;
    align-items: center;
    gap: 8px;
    background: #e8f7ee;
    color: #213423;
    border: 1px solid rgba(61, 96, 65, 0.35);
    border-radius: 10px;
    padding: 10px 14px;
    font-size: 13.5px;
    font-weight: 600;
    line-height: 1.35;
    margin-bottom: 8px;
}
.forms-week-ok i,
.forms-week-ok [data-lucide]{ font-size: 15px; flex-shrink: 0; }
html.theme-dark .forms-week-ok {
    background: rgba(61, 96, 65, 0.16);
    color: #a7d4ac;
    border-color: rgba(134, 201, 140, 0.35);
}

/* ====================================================================
 * Fotos de evolução (2026-07-30): a paciente fotografa e envia pelo app.
 * Alvos de toque de 44px+, pensados para uso com uma mão.
 * ==================================================================== */
/* 2026-08-11 (auditoria de tema): tokens no lugar de hex claro. A tela de
   fotos era a pior do modo escuro: cartao branco fixo com texto trocado para
   claro pela rede de resgate (contraste ~1,1:1). Com tokens, os dois temas
   ficam corretos na fonte, sem override dark. */
.foto-pose {
    display: flex; align-items: center; gap: 12px; width: 100%;
    min-height: 62px; padding: 12px 14px; margin-bottom: 8px;
    background: var(--card, #fff); border: 1px solid var(--border, #e2e8f0); border-radius: 12px;
    font: inherit; text-align: left; cursor: pointer;
}
.foto-pose:active { transform: translateY(1px); }
.foto-pose__ico {
    flex: 0 0 auto; width: 38px; height: 38px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--brand-tint, #e8f7ee); color: var(--brand-primary, #3d6041); font-size: 15px;
}
.foto-pose__txt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.foto-pose__txt strong { font-size: .95rem; color: var(--text, #0f172a); }
.foto-pose__txt small { font-size: .76rem; color: var(--text-muted, #64748b); line-height: 1.4; }
.foto-pose__seta { flex: 0 0 auto; color: var(--text-muted, #64748b); font-size: .8rem; }

.foto-consent {
    display: flex; align-items: flex-start; gap: 9px; margin-top: 12px;
    font-size: .8rem; color: var(--text-secondary, #475569); line-height: 1.45;
}
.foto-consent input { margin-top: 2px; width: 18px; height: 18px; flex: 0 0 auto; accent-color: var(--brand-primary, #3d6041); }

.foto-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 9px; }
.foto-item { margin: 0; }
.foto-item img {
    width: 100%; aspect-ratio: 3 / 4; object-fit: cover;
    border-radius: 10px; background: var(--bg-alt, #f1f5f9); display: block;
}
.foto-item figcaption { margin-top: 4px; font-size: .7rem; color: var(--text-muted, #64748b); text-align: center; }
.foto-vazio { margin: 0; font-size: .86rem; color: var(--text-muted, #64748b); line-height: 1.5; }

/* Botões de ação do próximo agendamento (2026-07-30): "Confirmar presença"
   quebrava em duas linhas ao lado de "Desmarcar" e desalinhava a fileira.
   O rótulo visível virou "Confirmar" e o nowrap impede recaída. */
.btn-action { white-space: nowrap; }

/* 2026-08-04 (a11y toque, WCAG 2.5.5): alvos de toque >= 44px em telas de toque.
   Expande a AREA de toque sem inchar o desktop (@media pointer:coarse). min-width/
   min-height vencem o width/height de 32-36px das media queries de tela pequena. */
@media (pointer: coarse) {
  .header-btn, .modal-close, .mais-close, .sc-close {
    min-width: 44px;
    min-height: 44px;
  }
}

/* 2026-08-10: KPI "Peso" truncava no tablet. Na faixa 768-1023px a grade ia a 4
   colunas dentro de um main de 720px, deixando cada card ~149px, e o valor
   "82,4kg" (nowrap + ellipsis) não cabia. 2x2 dá largura de sobra e a coluna do
   valor pode encolher sem cortar. */
@media (min-width: 640px) and (max-width: 1023px) {
  .stats-grid,
  .stats-grid-pro {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }
}
/* O valor do KPI não corta: se faltar espaço, diminui a fonte em vez de cortar. */
.stat-card-pro .stat-pro-value,
.stat-card .value {
  min-width: 0;
}


/* =====================================================================
   2026-10-08 (achados do dono no aparelho, prompt APPS-TESTE-NO-APARELHO)
   a) Cabecalho com UMA acao primaria (Hidratacao, 44 px) e o resto no menu
      "Mais acoes" (notificacoes, mensagens, suporte, tema, perfil).
   b) "Mais" (sec-mais): grade de 2 colunas de caixas deitadas, agrupadas.
   ===================================================================== */
.header-actions { position: relative; }
html body .header-btn--mais { position: relative; }
.header-btn--mais .header-mais-ponto { position: absolute; top: 5px; right: 5px; width: 9px; height: 9px; border-radius: 50%; background: #b91c1c; border: 2px solid var(--card, #fff); display: none; }
.header-btn--mais.tem-pendencia .header-mais-ponto { display: block; }
.header-mais-menu { position: absolute; top: calc(100% + 6px); right: 0; min-width: 236px; max-width: calc(100vw - 24px); background: var(--card, #fff); border: 1px solid var(--border, #e2e8f0); border-radius: 14px; box-shadow: 0 14px 40px rgba(15, 23, 42, .18); padding: 6px; z-index: 320; display: flex; flex-direction: column; gap: 2px; }
.header-mais-menu[hidden] { display: none; }
html body .header-mais-menu .header-btn,
html body.sn-mobile-shell .header-mais-menu .header-btn { display: flex !important; width: 100%; height: auto; min-height: 44px; justify-content: flex-start; gap: 10px; padding: 0 12px; background: transparent; border: 0; border-radius: 10px; color: var(--text, #0f172a); font-size: 14px; font-weight: 600; font-family: inherit; text-align: left; }
.header-mais-menu .header-btn:hover, .header-mais-menu .header-btn:focus-visible { background: var(--brand-tint, #f1f5f9); }
.header-mais-menu .header-btn > i:first-child { width: 22px; text-align: center; font-size: 16px; color: var(--brand-primary-darker, #213423); }
.header-mais-menu .header-mais-rotulo { flex: 1 1 auto; min-width: 0; }
html body .header-mais-menu .header-btn .badge { position: static; margin-left: auto; }
html body .header-mais-menu .header-btn .user-avatar { width: 28px; height: 28px; font-size: 12px; flex: 0 0 28px; }
html.theme-dark .header-mais-menu { background: #0f172a; border-color: #334155; }
html.theme-dark .header-mais-menu .header-btn { color: #e2e8f0; }
html.theme-dark .header-mais-menu .header-btn:hover, html.theme-dark .header-mais-menu .header-btn:focus-visible { background: #1e293b; }
html.theme-dark .header-mais-menu .header-btn > i:first-child { color: var(--brand-pastel, #86c98c); }
/* A folha de correcoes escondia o botao da agua no telefone (cabecalho lotado); com o menu ha lugar.
   O JS continua escondendo por style quando nao ha meta de agua. */
html body.sn-mobile-shell #btnHeaderAgua:not([style*="none"]) { display: flex !important; }
html body.sn-mobile-shell #btnHeaderMais { display: flex !important; }
.water-card--destaque { box-shadow: 0 0 0 3px var(--brand-pastel, #86c98c) !important; transition: box-shadow .3s ease; }

/* "Mais": caixas deitadas, 2 colunas, grupos com titulo (mais de 6 itens). */
html body .mais-secao-corpo { padding: 6px 12px 14px; display: flex; flex-direction: column; gap: 6px; }
.mais-grupo-titulo { margin: 10px 0 8px; font-size: 13px; font-weight: 600; color: var(--text-secondary, #475569); }
html body .mais-grid.mais-grid-secao { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
html body .mais-grid-secao .mais-item { flex-direction: row; align-items: center; justify-content: flex-start; gap: 10px; min-height: 56px; padding: 6px 10px; border: 1px solid var(--border, #e2e8f0); border-radius: 12px; background: var(--card, #fff); }
html body .mais-grid-secao .mais-item-icon { width: 40px; height: 40px; flex: 0 0 40px; border-radius: 10px; font-size: 17px; }
html body .mais-grid-secao .mais-item-label { text-align: left; font-size: 13px; line-height: 1.25; -webkit-line-clamp: 2; }
@media (min-width: 600px) { html body .mais-grid.mais-grid-secao { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 339px) { html body .mais-grid.mais-grid-secao { grid-template-columns: minmax(0, 1fr); } }
/* As regras antigas escondem esses botoes por ID no telefone (peso de ID); dentro do menu eles
   voltam com dois IDs no seletor, que e o unico jeito de vencer sem mexer na folha de correcoes. */
html body.sn-mobile-shell #headerMaisMenu #btnNotificacoes, html body.sn-mobile-shell #headerMaisMenu #btnChatHeader,
html body.sn-mobile-shell #headerMaisMenu #headerWhatsApp, html body.sn-mobile-shell #headerMaisMenu #headerThemeToggle,
html body.sn-mobile-shell #headerMaisMenu #headerAvatarBtn { display: flex !important; }
/* Sem depender da classe do body (o SeuCenoura nao a tem) e acima do :has() da folha de correcoes. */
html body .header-actions #btnHeaderAgua:not([style*="none"]) { display: flex !important; }
html body .header-actions #btnHeaderMais { display: flex !important; }
.app-header .header-content .header-actions .header-mais-menu#headerMaisMenu #btnNotificacoes,
.app-header .header-content .header-actions .header-mais-menu#headerMaisMenu #btnChatHeader,
.app-header .header-content .header-actions .header-mais-menu#headerMaisMenu #headerWhatsApp,
.app-header .header-content .header-actions .header-mais-menu#headerMaisMenu #headerThemeToggle,
.app-header .header-content .header-actions .header-mais-menu#headerMaisMenu #headerAvatarBtn { display: flex !important; }
/* A regra de tamanho dos filhos do .header-actions (40, 38 e 34 px por largura, com !important) nao vale
   para a caixa do menu, que e um filho mas nao e botao. */
html body .header-content .header-actions > .header-mais-menu { width: auto !important; height: auto !important; min-width: 236px !important; min-height: 0 !important; }

/* O tamanho por largura dos .header-btn (40, 38 e 34 px com !important) e o fundo de botao nao valem
   para as linhas do menu: cada linha e larga, de 44 px de altura, sem moldura. */
html body .header-mais-menu .header-btn { width: 100% !important; height: auto !important; min-width: 0 !important; min-height: 44px !important; font-size: 14px !important; background: transparent !important; border: 0 !important; justify-content: flex-start !important; padding: 0 12px !important; border-radius: 10px !important; box-shadow: none !important; transform: none !important; }
html body .header-mais-menu .header-btn:hover, html body .header-mais-menu .header-btn:focus-visible { background: var(--brand-tint, #f1f5f9) !important; }
html.theme-dark body .header-mais-menu .header-btn:hover, html.theme-dark body .header-mais-menu .header-btn:focus-visible { background: #1e293b !important; }
html body .header-mais-menu .header-btn .badge { position: static !important; margin-left: auto; min-width: 22px; height: 20px; }
html body .header-btn--mais .header-mais-svg { width: 20px; height: 20px; display: block; }

/* ===== origem: css/app-redesign.css ===== */
/*
 * app-redesign.css - App Paciente - Elevacao visual (2026-06-04)
 *
 * Camada de OVERRIDE final: carrega depois de app-revisao.css, entao vence a
 * cascata para selectores de igual especificidade. Objetivo: elevar a presenca
 * da marca, corrigir inputs <16px (zoom iOS), e refinar login/cards/nav/botoes.
 *
 * REGRAS:
 * - Tenant-aware: cores solidas SEMPRE via tokens --brand-*. Verde literal so em
 *   brilhos/aneis translucidos (mesmo padrao ja usado no app.css legado).
 * - color-mix mistura a partir de --brand-pastel para aquecer fundos sem perder
 *   o white-label (cada tenant aquece para a propria cor).
 * - Reversivel: remover o <link> deste arquivo restaura o visual anterior.
 * - Contraste: o botao primario fica no verde escuro (AA 4.56:1 com texto branco);
 *   nao clarear o fundo do botao.
 */

:root {
  --rd-brand-glow:    0 12px 30px -14px rgba(61, 96, 65, .48);
  --rd-card-shadow:   0 1px 2px rgba(15, 23, 42, .04), 0 10px 26px -18px rgba(15, 23, 42, .22);
  --rd-ring:          0 0 0 3px rgba(61, 96, 65, .18);
  --rd-radius-card:   18px;
}

/* ===== 1. Inputs: 16px no mobile (anti zoom iOS) + foco de marca ===== */
@media (max-width: 768px) {
  body .app-section input:not([type=checkbox]):not([type=radio]):not([type=range]),
  body .app-section select,
  body .app-section textarea,
  .compras-busca input,
  .rec-busca input,
  .chat-search-input,
  .cog-label input,
  .cog-label select,
  .sug-input,
  .sug-select,
  .sug-textarea,
  .registrar-foto-label textarea {
    font-size: 16px;
  }
}

body .app-section input:focus,
body .app-section select:focus,
body .app-section textarea:focus {
  border-color: var(--brand-primary);
  box-shadow: var(--rd-ring);
  outline: none;
}

/* ===== 2. Botao primario: verde escuro (AA) + brilho de marca + cantos suaves ===== */
.btn.btn-primary,
.btn-primary {
  background: linear-gradient(135deg, var(--brand-primary-dark), var(--brand-primary-darker));
  box-shadow: var(--rd-brand-glow);
  border-radius: 14px;
}

.btn.btn-primary:hover:not(:disabled):not(.btn-loading),
.btn-primary:hover:not(:disabled):not(.btn-loading) {
  box-shadow: 0 16px 36px -14px rgba(61, 96, 65, .58);
}

/* ===== 3. Bottom-nav: estado ativo com pill de marca mais presente ===== */
.nav-item.active .nav-item-icon {
  background: color-mix(in srgb, var(--brand-pastel) 22%, #fff);
  box-shadow: inset 0 0 0 1px rgba(61, 96, 65, .22);
}

/* ===== 4. Cards: elevacao (so raio+sombra; NAO mexer em border-color para nao
   clobberar bordas laterais de status em cards internos). body .card vence app.css. ===== */
body .card {
  border-radius: var(--rd-radius-card);
  box-shadow: var(--rd-card-shadow);
}

/* ===== 5. Header: assinatura sutil de marca na sombra inferior ===== */
body .app-header {
  box-shadow: 0 1px 0 rgba(15, 23, 42, .04), 0 10px 24px -20px rgba(61, 96, 65, .55);
}

/* ===== 6. Login: card mais marcante + porta de entrada coerente ===== */
body .login-box {
  border-radius: 24px;
  box-shadow: 0 26px 64px -26px rgba(33, 52, 35, .45), 0 2px 6px rgba(15, 23, 42, .06);
}

/* Desktop: deixar o card respirar sem ficar perdido no vazio (1440px) */
@media (min-width: 920px) {
  .login-container {
    width: 100%;
    max-width: 440px;
  }
  .login-box {
    padding: 38px 40px;
  }
}

/* ===== 7. Dark mode: manter coerencia da elevacao (theme-dark = mecanismo do app) ===== */
html.theme-dark body .card,
body.theme-dark .card {
  box-shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 10px 26px -18px rgba(0, 0, 0, .5);
}

/* ===== 8. 2026-06-12 (auditoria responsividade): anti zoom iOS - complemento =====
   Campos que escapavam do guard da secao 1 (fora de .app-section ou com
   classe propria de mesma especificidade declarada antes na cascata):
   .clube-busca input 14px, .sc-input-bar input 15px, .command-palette-input 15px
   (app.css) e .calc-form input/select 15px (app-deferred.css). Regra aditiva,
   vence por ordem de cascata (este arquivo e o ultimo <link>). */
@media (max-width: 768px) {
  .clube-busca input,
  .sc-input-bar input,
  .command-palette-input,
  .calc-form input,
  .calc-form select {
    font-size: 16px;
  }
}

/* ===== 9. 2026-06-12 (auditoria responsividade): touch targets >= 44px =====
   Botoes de fechar/acoes com caixa fixa 28-36px (.mais-close/.sc-close 36,
   .header-btn/.modal-close 32, .status-banner__close 28, .pdf-drawer-btn 36).
   Sem mexer no layout: pseudo-elemento transparente expande a area de toque
   apenas em ponteiro grosso (touch). Nenhum desses seletores usa ::after no
   bundle (verificado 2026-06-12) e nenhum define position, logo o relative
   nao desloca nada. */
@media (pointer: coarse) {
  .mais-close,
  .sc-close,
  .modal-close,
  .status-banner__close,
  .pdf-drawer-btn,
  .header-btn {
    position: relative;
  }
  .mais-close::after,
  .sc-close::after,
  .modal-close::after,
  .status-banner__close::after,
  .pdf-drawer-btn::after,
  .header-btn::after {
    content: "";
    position: absolute;
    top: -6px;
    right: -6px;
    bottom: -6px;
    left: -6px;
  }
  .status-banner__close::after {
    top: -8px;
    right: -8px;
    bottom: -8px;
    left: -8px;
  }
}

/* ===== 10. 2026-06-12 (auditoria responsividade): modal em viewport dinamico =====
   .modal-content usa max-height:90vh; no iOS o vh e o viewport GRANDE (com a
   barra de URL recolhida), entao em telas baixas o rodape do modal podia ficar
   atras da barra. dvh acompanha o viewport visivel. Mesmo valor no desktop. */
@supports (height: 1dvh) {
  .modal-overlay .modal-content {
    max-height: 90dvh;
  }
}

/* ===== 11. 2026-07-03 (mobile): avaliacao fisica — tabela vira CARD + resumo do topo =====
   No mobile a tabela .av-ptbl (Parametro | Atual | Recomendacao | Situacao) tinha 4
   colunas espremidas: os rotulos "Recomendacao"/"Situacao" e os textos quebravam letra
   a letra ("palavras montadas"). Aqui cada linha vira um card legivel: nome + valor no
   topo, badge de situacao e a recomendacao em linha propria (largura total). O cabecalho
   de colunas some (nao faz sentido em cards). */
@media (max-width: 520px) {
  .av-ptbl { overflow: visible !important; border-radius: 0 !important; }
  .av-ptbl-head { display: none !important; }

  /* 2026-09-18: a linha gastava TRES alturas de texto e media 145px em 390px.
     Duas causas somadas. Primeira: cada celula ainda carregava o
     `padding: 7px 10px` da tabela de desktop, que aqui vira padding dentro de
     padding e dobra a altura de cada uma. Segunda: situacao e recomendacao
     ocupavam uma linha cada, sendo que as duas juntas cabem numa. Agora sao
     duas alturas: rotulo com o valor em cima, situacao com a recomendacao
     embaixo. */
  .av-ptbl-row {
    display: grid !important;
    grid-template-columns: 1fr auto !important;
    grid-template-areas:
      "param val"
      "sit   rec" !important;
    column-gap: 10px;
    row-gap: 4px;
    align-items: baseline;
    padding: 11px 13px !important;
    margin-bottom: 8px;
    border: 1px solid var(--border, #e5e7eb);
    border-radius: 12px;
    background: var(--card, #fff);
    font-size: 13px !important;
  }
  /* A celula nao tem mais padding proprio: quem espaca e o cartao da linha. A
     borda esquerda transparente de 3px tambem e heranca da tabela e so comia
     largura. */
  .av-ptbl-row span { padding: 0 !important; border-left: 0 !important; }
  .av-ptbl-row .av-ptbl-col1 {
    grid-area: param !important;
    justify-self: start !important;
    text-align: left !important;
    font-weight: 700;
    font-size: 12.5px;
    line-height: 1.3;
    overflow-wrap: anywhere;
  }
  .av-ptbl-row .av-ptbl-val {
    grid-area: val !important;
    justify-self: end !important;
    text-align: right !important;
    font-size: 15px !important;
    font-weight: 800;
    white-space: nowrap;
  }
  .av-ptbl-row .av-ptbl-sit {
    grid-area: sit !important;
    justify-self: start !important;
    text-align: left !important;
    margin-top: 0;
  }
  .av-ptbl-row .av-ptbl-sit .av-badge { white-space: nowrap; }
  .av-ptbl-row .av-ptbl-rec {
    grid-area: rec !important;
    justify-self: end !important;
    text-align: right !important;
    white-space: normal !important;
    overflow-wrap: anywhere;
    font-size: 11.5px !important;
    line-height: 1.45;
    /* #475569 contra o branco do cartao da 7,5:1; o #64748b anterior dava
       4,4:1 e reprovava o AA por pouco, justo na linha que diz a faixa
       recomendada. */
    color: #475569;
    margin-top: 0;
  }

  .av-ptbl-row.av-z0, .av-ptbl-row.av-z1 { background: var(--card, #fff) !important; }

  /* Resumo do topo (.av-topo): IMC em destaque + colunas empilhadas com respiro. */
  .av-topo { gap: 10px !important; }
  .av-topo-col { flex: 1 1 100% !important; min-width: 0 !important; }
  .av-topo-imc {
    flex: 1 1 100% !important;
    padding: 14px 12px !important;
    border-radius: 14px !important;
  }
  .av-topo-imc-num { font-size: 30px !important; }
  .av-topo-linha { font-size: 13.5px !important; }
}

/* ===== 12. 2026-07-16 (auditoria contraste): status-banner no tema escuro =====
 *
 * O tema escuro tratou o TEXTO do banner (html.theme-dark .status-banner.is-warning
 * -> #fed7aa, .is-info -> #cdd9e3) mas esqueceu o ICONE e o botao FECHAR, que ficaram
 * com a cor do tema claro. E as regras do claro sao mais especificas que a correcao
 * do escuro, entao venciam mesmo no escuro:
 *    .status-banner.is-info .status-banner__icon  (0,3,0)  vencia
 *    html.theme-dark .status-banner__icon         (0,2,1)
 * Medido no navegador (theme-dark, fundo real do banner):
 *    is-info  icone  #2c4762 sobre #1c2535 = 1,60:1   fechar = 2,00:1
 *    is-warning icone #b45309 sobre #3e2e17 = 2,60:1  fechar = 3,83:1
 * Aqui a cor do icone/fechar passa a ser a MESMA ja usada no texto do banner no
 * escuro, o que da 9,65:1 (aviso) e 10,71:1 (informacao) e mantem a coerencia.
 * Especificidade (0,4,1) vence as regras do claro.
 */
html.theme-dark .status-banner.is-info .status-banner__icon,
html.theme-dark .status-banner.is-info .status-banner__close {
  color: #cdd9e3;
}

html.theme-dark .status-banner.is-warning .status-banner__icon,
html.theme-dark .status-banner.is-warning .status-banner__close {
  color: #fed7aa;
}

/* ===== 13. 2026-07-16 (auditoria contraste): hex escuro fixo sem variante escura =====
 *
 * O app tem uma rede de resgate em app-revisao.css:
 *    html.theme-dark .main-content .card div:not([class*=badge]):not(...)
 * que devolve #e2e8f0 a QUALQUER div dentro de um .card. Ela salva a maioria dos
 * hex escuros herdados do tw-app.css. Os itens abaixo escapam da rede por um destes
 * motivos e ficaram com letra escura sobre fundo escuro (medido no navegador):
 *   - nao sao div (h4, span, p, i) ou tem regra propria que vence a herança;
 *   - nao ficam dentro de .main-content .card (clube, prompt flutuante).
 */

/* 13a. Lives: ".lives-card-body h4,.med-card h4{color:#0f172a}" vem DEPOIS de
   ".lives-card-body h4{color:var(--text)}" e com a mesma especificidade (0,1,1),
   entao o hex vencia. Antes: 1,22:1. Com o token: 11,9:1. */
html.theme-dark .lives-card-body h4 {
  color: var(--text);
}

/* 13b. Legenda das lives e paragrafo da meditacao: #475569 sobre #1e293b = 1,93:1.
   --text-muted no escuro (#94a3b8) da 6,1:1. */
html.theme-dark .lives-card-body span,
html.theme-dark .med-card p {
  color: var(--text-muted);
}

/* 13c. Clube de vantagens: fica FORA de .main-content .card, entao a rede de
   resgate nao alcanca. Texto #475569 sobre #0f172a = 2,36:1; icone
   --brand-primary-darker (#3d6041) = 2,51:1. */
html.theme-dark .clube-info-item {
  color: var(--text-muted);
}
html.theme-dark .clube-info-item i,
html.theme-dark .clube-info-item [data-lucide] {
  color: var(--brand-pastel);
}
/* O icone do WhatsApp mantem o verde da marca dele (regra propria do app.css). */
html.theme-dark .clube-info-item .fa-whatsapp {
  color: #25d366;
}

/* 13c-2. Miniatura sem imagem (.med-card-noimg): o fundo e um gradiente CINZA CLARO
   (#cbd5e1 -> #94a3b8) nos dois temas, mas o icone era branco: 1,48:1 no claro e
   1,20:1 no escuro (onde vira #e2e8f0). Ou seja: o icone de "sem miniatura" estava
   invisivel sempre. #334155 da 6,97:1 na ponta clara e 4,04:1 na escura, acima dos
   3:1 exigidos para elemento grafico. Serve aos dois temas, entao sem escopo.
   O alvo e o <i>, nao o .med-card-noimg: a rede de resgate de app-revisao.css
   (especificidade 0,6,2) pinta QUALQUER div dentro de .main-content .card e
   venceria a regra no proprio contêiner. O seletor dela termina em `div`, entao
   o icone nao e alcancado e aqui so a heranca compete. */
.med-card-noimg > i,
.med-card-noimg > [data-lucide] {
  color: #334155;
}

/* 13d. Prompt "Ativar modo escuro?": o card e ESCURO nos DOIS temas
   (#0f172a no claro, #1e293b no escuro) mas o icone da lua e #b45309 (ambar
   escuro): 3,56:1 no claro e 2,91:1 no escuro. Ironia de o convite para o modo
   escuro ser o item menos legivel. #fbbf24 da 8,76:1 e serve aos dois temas,
   por isso a regra NAO e escopada por tema. */

/* ============================================================
   14. 2026-07-17 - Auditoria de contraste AA: verde de marca como
   FUNDO de texto branco.

   O padrao do sistema usava o verde medio #609165 (--accent / --brand-primary)
   como fundo de texto branco. Medido no navegador: 3,66:1, abaixo dos 4,5:1
   que a AA exige para texto normal. Reprovava nos DOIS temas, entao nao era
   regressao do modo escuro: era divida antiga.

   Correcao: o verde escuro que a marca JA tem (--brand-primary-dark #2f4a32,
   o "escurecido ~18%" da bbar do PDF e do cabecalho de email) da 5,06:1, e o
   --brand-primary-darker #3d6041 da 7,12:1. Nao e cor nova.

   Tenant-aware por token, como manda o cabecalho deste arquivo: quem tem
   white-label continua escurecendo para a PROPRIA cor.

   O #609165 segue valido como acento e como fundo SEM texto branco em cima:
   so muda onde o contraste reprovava. ============================================================ */

/* 14a. Card da proxima consulta: a ponta clara do gradiente era o #609165. */
.next-appointment {
  background: linear-gradient(135deg, var(--brand-primary-dark, #2f4a32) 0, var(--brand-primary-darker, #213423) 100%);
}

/* 14b. Botoes dentro do card, no tema escuro: mesma ponta clara #609165.
   O card em si NAO entra aqui: no escuro ele e um veu translucido
   (rgba(96,145,101,.18) sobre fundo escuro), entao o branco por cima ja passa
   folgado. So os dois botoes abaixo sao verde OPACO com texto branco. */
html.theme-dark .next-appointment .btn-confirm,
html.theme-dark .next-appointment .btn-confirmed-state {
  background: linear-gradient(135deg, var(--brand-primary-dark, #2f4a32) 0, var(--brand-primary-darker, #213423) 100%) !important;
}

/* 14c. Editar foto do perfil: 12px branco sobre verde solido. */
.profile-avatar-edit {
  background: var(--brand-primary-dark, #2f4a32);
}

/* 14d. Botao de agua do card compacto: 12,5px branco sobre verde solido. */
.water-card--compact .water-btn--inline {
  background: var(--brand-primary-dark, #2f4a32);
}

/* 14e. Hover do botao da gaveta de PDF: o hover levava o fundo de volta ao
   verde medio, entao o texto branco reprovava justamente ao passar o mouse. */
.pdf-drawer-btn:hover {
  background: var(--brand-primary-dark, #2f4a32);
}

/* ===== 15. SeuCenoura (FAB) x botao de enviar do Chat =====
   2026-07-22 (homologacao Dr. Jayme, defeito 1): na tela de Chat o botao
   flutuante do SeuCenoura colidia com o botao de enviar mensagem.

   Causa raiz: o FAB e position:fixed com bottom: 82px (valor cravado, pensado
   so para "logo acima da bottom-nav"), enquanto o composer do chat
   (.chat-input-area, ~180px medidos) ocupa exatamente essa faixa, com o
   .chat-send colado na direita. Medido antes da correcao em 360px de largura:
   FAB em 286-344 x 760-818 e botao de enviar em 289-333 x 757-801, ou seja
   sobreposicao quase total. Empurrar alguns pixels nao resolve porque a altura
   do composer muda com o tamanho da fonte, com a quebra dos chips de tipo e
   com env(safe-area-inset-bottom) das barras de gestos.

   Correcao: a posicao vertical do FAB passa a sair de --sc-fab-bottom, que o
   seu-cenoura.js calcula medindo o topo real do composer sempre que a secao de
   Chat entra em cena, quando a janela muda de tamanho e quando o teclado abre
   ou fecha. Os valores abaixo sao o fallback de CSS puro (JS indisponivel):
   fora do Chat reproduzem exatamente o comportamento anterior
   (65 + 0 + 17 = 82px) e, dentro do Chat, sobem o FAB acima do composer.
   Sem !important: esta camada carrega depois do app.css. */
.sc-fab {
  bottom: var(--sc-fab-bottom, calc(var(--nav-height, 65px) + env(safe-area-inset-bottom, 0px) + 17px));
}

/* Fallback do Chat: altura tipica do composer (rotulo + chips de tipo + linha
   do input + paddings) mais um respiro de 14px (medido: 179px em 360/390/414px). */
html.sc-chat-ativo .sc-fab {
  bottom: var(--sc-fab-bottom, calc(var(--nav-height, 65px) + env(safe-area-inset-bottom, 0px) + 196px));
}

/* Teclado virtual aberto dentro do Chat: o FAB sai de cena para nao disputar
   espaco com o composer ancorado no topo do teclado. */
.sc-fab.sc-fab-oculto {
  display: none;
}

@media (min-width: 1024px) {
  /* Desktop nao tem bottom-nav: base de 24px, mesma do layout original. */
  .sc-fab {
    bottom: var(--sc-fab-bottom, 24px);
  }
  html.sc-chat-ativo .sc-fab {
    bottom: var(--sc-fab-bottom, calc(var(--nav-height, 65px) + 196px));
  }
}

/* ===== origem: css/app-fixes.css ===== */
/* =====================================================================
   app-fixes.css : camada final de correcoes (2026-07-25)
   Carregada DEPOIS de app-redesign.css. Corrige, na ordem:

   1. Rolagem indevida da tela (trava global + trava de overlay)
   2. Card "Proxima consulta" da home (layout, contraste, 320px)
   3. Gaveta "Mais" (barra inferior sumindo + caixa dupla no modo escuro)
   4. Chat (espaco vazio acima do titulo, abaixo do campo de mensagem, lista
      de mensagens curta grudando no topo, e agrupamento do mesmo remetente)
   5. Responsividade transversal

   Sem !important salvo onde a regra anterior ja usava !important.
   Reverter: comentar o <link> de app-fixes.css no index.html.
   ===================================================================== */

/* =====================================================================
   1. ROLAGEM : a tela nao pode "correr" em nenhum eixo
   ---------------------------------------------------------------------
   Sintoma relatado: ao baixar um arquivo (PDF do plano, avaliacao,
   compartilhamento) a tela corria para cima, para baixo e para os lados.
   Causas: (a) nenhum eixo horizontal estava travado no documento;
   (b) os modais abriam sem travar o scroll do fundo, e no iOS
   "overflow:hidden" no body sozinho NAO trava (precisa position:fixed);
   (c) o <a download> temporario era anexado ao body sem sair do fluxo.
   ===================================================================== */

/* ATENCAO a arquitetura deste app: o app.css ja define
   `body,html{height:100%;overflow:hidden;overflow-x:hidden}` e quem realmente
   rola e o proprio <body> (overflow-y:auto, altura travada em 100%).
   Portanto NAO se pode usar aqui o padrao classico de trava
   (`body{position:fixed;top:-Ypx}`): isso quebraria o container de rolagem.
   Como o body E o container, `overflow:hidden` nele trava de verdade,
   inclusive no iOS, e o scrollTop e preservado. */
html {
    overscroll-behavior-x: none;
}

body {
    max-width: 100%;
    overscroll-behavior: contain;
}

/* Trava de rolagem enquanto um overlay esta aberto. */
body.scroll-locked {
    overflow: hidden;
    overscroll-behavior: none;
    touch-action: none;
}

/* O conteudo do overlay continua rolando normalmente.
   2026-08-11 (auditoria fluxos): SeuCenoura, command palette e uiConfirm/uiPrompt
   faltavam aqui; com a trava ativa, a rolagem por toque deles morria. */
body.scroll-locked .modal-content,
body.scroll-locked .modal-body,
body.scroll-locked .mais-content,
body.scroll-locked .err-modal,
body.scroll-locked .pdf-drawer,
body.scroll-locked .chat-messages,
body.scroll-locked .sc-modal-inner,
body.scroll-locked .command-palette-list,
body.scroll-locked .uim-box {
    touch-action: pan-y;
    overscroll-behavior: contain;
}

/* Ancora temporaria de download: fora do fluxo, sem gerar linha no body. */
a[download],
a[data-download-temp] {
    max-width: 100%;
}

/* Elementos injetados no fim do body para disparar download nunca podem
   empurrar o layout nem criar area rolavel. */
body > a[href^="blob:"],
body > a[data-download-temp] {
    position: fixed;
    top: 0;
    left: 0;
    width: 0;
    height: 0;
    opacity: 0;
    pointer-events: none;
}

/* =====================================================================
   2. CARD "PROXIMA CONSULTA"
   ---------------------------------------------------------------------
   Problemas corrigidos:
   - "Desmarcar" era branco a 20% sobre verde: praticamente ilegivel
   - selo de status cor de creme brigando com o verde da marca
   - linha do tipo de consulta e selo com alinhamento fora de base
   - local ("Online") estilizado por style inline no JS
   - a 320px os dois botoes quebravam com alturas diferentes
   ===================================================================== */

.next-appointment {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 13px 16px;
    overflow: hidden;
}

.next-appointment .label {
    font-size: 10.5px;
    font-weight: 800;
    letter-spacing: 0.08em;
    opacity: 0.82;
    margin-bottom: 2px;
}

/* Linha principal: data e hora a esquerda, tipo/status/local a direita.
   Antes eram tres linhas empilhadas e o card ficava alto demais. */
.na-slim .na-linha {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px 12px;
    flex-wrap: wrap;
}

.next-appointment .date {
    font-size: 19px;
    line-height: 1.25;
    margin: 0;
}

/* Sem margin-left:auto de proposito: quando a linha quebra no celular, a
   meta desce alinhada a esquerda, embaixo da data, em vez de ficar solta
   no canto direito. Em telas largas o space-between ja joga tudo a direita. */
.na-slim .na-meta {
    display: flex;
    align-items: center;
    gap: 7px;
    flex-wrap: wrap;
    min-width: 0;
}

/* Tipo de consulta */
.next-appointment .time {
    display: inline-flex;
    align-items: center;
    font-size: 12.5px;
    opacity: 0.92;
}

.next-appointment .time .status-badge {
    margin-left: 0;
}

/* Local (Online / presencial / domicilio) */
.next-appointment .local {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 12px;
    opacity: 0.88;
    margin-top: 0;
}

/* Separador discreto entre tipo e local, so quando os dois existem */
.na-slim .na-meta > .time + .status-badge::before {
    content: none;
}

/* Selo de status: pastilha de vidro, mesma familia visual do card.
   Substitui o creme #fdf6ec que destoava do verde. */
/* A regra antiga alcanca tambem os descendentes
   (.next-appointment .status-badge *) e fixa -webkit-text-fill-color:#92400e
   com !important, que vence o color na hora de pintar o texto. Por isso aqui
   o seletor precisa cobrir os mesmos descendentes e zerar as duas propriedades. */
.next-appointment .status-badge {
    background: rgba(255, 255, 255, 0.16) !important;
    border: 1px solid rgba(255, 255, 255, 0.42) !important;
    font-size: 9.5px;
    font-weight: 800;
    letter-spacing: 0.06em;
    padding: 3px 9px;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

.next-appointment .status-badge,
.next-appointment .status-badge * {
    color: #fff !important;
    -webkit-text-fill-color: #fff !important;
}

.next-appointment .status-badge.confirmado {
    background: rgba(255, 255, 255, 0.92) !important;
    border-color: rgba(255, 255, 255, 0.92) !important;
}

.next-appointment .status-badge.confirmado,
.next-appointment .status-badge.confirmado * {
    color: var(--brand-primary-darker, #213423) !important;
    -webkit-text-fill-color: var(--brand-primary-darker, #213423) !important;
}

.next-appointment .status-badge.cancelado {
    background: rgba(220, 38, 38, 0.9) !important;
    border-color: rgba(254, 202, 202, 0.6) !important;
}

.na-chip,
.na-chip * {
    color: #fff !important;
    -webkit-text-fill-color: #fff !important;
}

/* Selos de proximidade (Hoje / Amanha / Online) que antes vinham com
   style inline dentro do JS. */
.na-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 9px;
    border-radius: 999px;
    font-size: 9.5px;
    font-weight: 800;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    line-height: 1.4;
    white-space: nowrap;
}

.na-chip--hoje {
    background: #c2410c;
}

.na-chip--amanha {
    background: #b45309;
}

.na-chip--online {
    background: rgba(255, 255, 255, 0.2);
    border: 1px solid rgba(255, 255, 255, 0.45);
}

/* Acoes */
.next-appointment .actions {
    display: flex;
    gap: 8px;
    margin-top: 11px;
    flex-wrap: wrap;
}

.next-appointment .btn-action {
    flex: 1 1 132px;
    min-width: 132px;
    /* 44px e o minimo de alvo de toque das diretrizes de iOS e Android. */
    min-height: 44px;
    max-width: 320px;
    padding: 10px 10px;
    font-size: 12.5px;
    font-weight: 700;
    border-radius: 12px;
    line-height: 1.2;
    /* "Confirmar presenca" quebrava em duas linhas e engordava o card. */
    white-space: nowrap;
    gap: 5px;
}

/* Botao secundario legivel: borda solida + fundo mais denso.
   Antes: rgba(255,255,255,.2) sem borda = contraste ~1,5:1. */
.next-appointment .btn-cancel {
    background: rgba(255, 255, 255, 0.14);
    border: 1.5px solid rgba(255, 255, 255, 0.66);
    color: #fff;
}

.next-appointment .btn-cancel:hover,
.next-appointment .btn-cancel:focus-visible {
    background: rgba(255, 255, 255, 0.24);
    border-color: #fff;
}

.next-appointment .btn-confirm {
    background: #fff;
    border: 1.5px solid #fff;
    box-shadow: 0 2px 8px rgba(15, 23, 42, 0.16);
}

.next-appointment .btn-video {
    background: rgba(255, 255, 255, 0.14);
    border: 1.5px solid rgba(255, 255, 255, 0.66);
    color: #fff;
}

.next-appointment .btn-confirmed-state {
    flex: 1 1 100%;
    min-width: 100%;
    justify-content: center;
    background: rgba(255, 255, 255, 0.95);
    border: 1.5px solid rgba(255, 255, 255, 0.95);
    font-weight: 700;
    cursor: default;
    box-shadow: none;
}

/* Estado ja confirmado: card sem acao pendente, tom mais sereno */
.next-appointment.confirmed .actions {
    margin-top: 12px;
}

/* Telas estreitas: botoes empilhados de largura cheia (nunca meio-quebrados) */
@media (max-width: 379px) {
    .next-appointment {
        padding: 14px 15px;
    }

    .next-appointment .date {
        font-size: 17px;
    }

    .next-appointment .btn-action {
        flex: 1 1 100%;
        min-width: 100%;
    }
}

/* Modo escuro: o card e um veu translucido. O botao secundario precisa de
   borda ainda mais firme para nao sumir no fundo. */
/* A regra anterior de app.css usa !important nestes tres valores, entao aqui
   e obrigatorio acompanhar para conseguir subir o contraste da borda. */
html.theme-dark .next-appointment .btn-cancel,
html.theme-dark .next-appointment .btn-video {
    background: rgba(255, 255, 255, 0.12) !important;
    color: #fff !important;
    border: 1.5px solid rgba(255, 255, 255, 0.58) !important;
}

html.theme-dark .next-appointment .btn-cancel:hover,
html.theme-dark .next-appointment .btn-cancel:focus-visible,
html.theme-dark .next-appointment .btn-video:hover,
html.theme-dark .next-appointment .btn-video:focus-visible {
    background: rgba(255, 255, 255, 0.22) !important;
    border-color: rgba(255, 255, 255, 0.85) !important;
}

html.theme-dark .next-appointment .status-badge {
    background: rgba(255, 255, 255, 0.14) !important;
    border-color: rgba(255, 255, 255, 0.38) !important;
}

/* =====================================================================
   3. GAVETA "MAIS"
   ---------------------------------------------------------------------
   3a. 2026-08-30 (revisao dos tres dominios): a gaveta se declara
       role="dialog" aria-modal="true" e era a camada MAIS BAIXA da tela.
       .mais-drawer vinha com z-index 150 do app.css enquanto a barra
       inferior estava forcada aqui em 170, o cabecalho vale 200 e o balao
       do SeuCenoura (.sc-fab) vale 998. Medido em 320x568 com
       elementFromPoint e a gaveta ABERTA: os CINCO itens da barra inferior
       continuavam recebendo o clique por cima do dialogo e o mascote
       cobria o item "Mentorias". Dialogo modal que deixa a camada de tras
       receber o toque nao e modal.
       A compensacao antiga (recuar a folha a altura da barra) custava 82px
       de uma tela de 568px: 8 dos 18 itens ficavam sem nenhum ponto
       alcancavel antes de rolar, entre eles "Servicos" e "Clube".
       Agora a gaveta sobe para 999: acima da barra, do cabecalho e do
       mascote, e ainda abaixo dos modais (.modal-overlay, 1000). O recuo
       de 82px volta para a folha e o teto da folha passa a parar logo
       abaixo do cabecalho (medido: 61px de altura em 320x568).
       Medicao depois, mesmo metodo: 2 de 18 sem ponto alcancavel antes de
       rolar (Perfil e Sair, a 122px de rolagem numa folha que rola), zero
       item de barra e zero mascote recebendo clique.
       Preco assumido: com a gaveta aberta a barra inferior fica sob o veu,
       que e exatamente o que aria-modal promete. Manter a barra clicavel
       exigiria tirar o aria-modal do dialogo, ou seja, trocar um defeito
       que se ve por um defeito de leitor de tela.
   3b. Modo escuro: .mais-item e .mais-item-icon ficavam com o MESMO
       #1e293b, entao o quadrado do icone virava uma caixa fantasma com
       borda (lido pelo dono como "sombra"). Agora o item e transparente
       e so o icone tem superficie, com o verde pastel da marca.
   ===================================================================== */

/* 3a. a gaveta e um dialogo modal: fica acima da barra, do cabecalho e do
   mascote. A barra volta ao z-index 100 que o app.css ja declara: o 170
   daqui existia so para vencer a gaveta. */
.mais-drawer {
    z-index: 999;
}

.mais-drawer .mais-backdrop {
    z-index: 0;
}

.mais-sheet {
    /* A folha cobre a barra inferior, entao nao precisa mais recuar por ela. */
    padding-bottom: calc(var(--safe-bottom, 0px) + 10px);
    max-height: min(92svh, calc(100svh - 64px));
}

.mais-content {
    padding-bottom: 8px;
}

/* 3b. modo escuro sem caixa dupla */
html.theme-dark .mais-drawer .mais-item {
    background: transparent;
    border: 0;
    box-shadow: none;
}

html.theme-dark .mais-drawer .mais-item-icon {
    background: rgba(134, 201, 140, 0.14);
    color: var(--brand-pastel, #86c98c);
    border: 1px solid rgba(134, 201, 140, 0.3);
    box-shadow: none;
}

html.theme-dark .mais-drawer .mais-item:hover .mais-item-icon,
html.theme-dark .mais-drawer .mais-item:focus-visible .mais-item-icon {
    background: rgba(134, 201, 140, 0.26);
    border-color: rgba(134, 201, 140, 0.55);
    color: #fff;
}

html.theme-dark .mais-drawer .mais-item:hover,
html.theme-dark .mais-drawer .mais-item:focus-visible {
    background: rgba(148, 163, 184, 0.1);
}

/* Mesma limpeza na secao #sec-mais (lista compacta, atalho legado):
   o quadrado do icone ficava sem superficie propria e o icone saia cinza,
   perdendo a identidade da marca no modo escuro. */
html.theme-dark #sec-mais .mais-item .mais-item-icon {
    background: rgba(134, 201, 140, 0.14);
    color: var(--brand-pastel, #86c98c);
    border: 1px solid rgba(134, 201, 140, 0.3);
    box-shadow: none;
}

html.theme-dark #sec-mais .mais-item .mais-item-icon--logout {
    background: rgba(248, 113, 113, 0.14);
    color: #fca5a5;
    border-color: rgba(248, 113, 113, 0.32);
}

/* o botao de sair mantem o vermelho, sem virar caixa dupla */
html.theme-dark .mais-drawer .mais-item-icon--logout {
    background: rgba(248, 113, 113, 0.14);
    color: #fca5a5;
    border-color: rgba(248, 113, 113, 0.32);
}

/* mesma limpeza no tema claro: o item e transparente, o icone e a superficie */
.mais-drawer .mais-item {
    background: transparent;
    border: 0;
    box-shadow: none;
}

/* rotulos longos ("Avaliacao neurocognitiva", "Clube de descontos") nao
   podem deixar as celulas da grade com alturas diferentes */
.mais-grid {
    align-items: start;
}

.mais-drawer .mais-item {
    min-height: 86px;
    justify-content: flex-start;
}

.mais-item-label {
    -webkit-line-clamp: 2;
}

/* =====================================================================
   4. CHAT
   ---------------------------------------------------------------------
   4a. Espaco vazio ACIMA de "Fale Conosco": body.has-back-btn reserva
       50px fixos para o botao flutuante "Voltar". No chat, que e uma
       tela de altura travada, esses 50px viravam uma faixa morta. Agora
       o chat usa um botao de voltar DENTRO do cabecalho do card e o
       botao flutuante fica oculto.
   4b. Espaco vazio ABAIXO do campo de mensagem: .chat-input-area e
       sticky com bottom:var(--kb-h). Quando --kb-h ficava preso em um
       valor > 0 (barra do Safari confundida com teclado) o composer
       subia e abria um vao. O js/chat-keyboard.js foi corrigido; aqui
       fica a defesa em CSS.
   4c. Conversa curta grudava no TOPO da lista: .chat-messages e flex-column
       sem justify-content, entao o alinhamento padrao (flex-start) empurra
       as bolhas para cima e sobra uma faixa vazia inteira entre a ultima
       mensagem e o composer. Todo chat de referencia (WhatsApp, iMessage)
       cresce a partir do rodape.
   4d. Mensagens seguidas do MESMO remetente (nutricionista) repetiam o
       cabecalho com avatar e nome em toda bolha, plantando espaco extra que
       deveria estar junto em vez de separado.
   ===================================================================== */

/* 4a. no chat, sem faixa reservada para o botao flutuante */
body.has-back-btn:has(#sec-chat.active) .main-content {
    padding-top: calc(var(--header-height, 60px) + var(--safe-top, 0px) + var(--hero-top-gap, 8px));
}

body:has(#sec-chat.active) .page-back-btn {
    display: none;
}

body:has(#sec-chat.active) #sec-chat.app-section.active > .card {
    margin-top: 8px;
}

/* botao de voltar embutido no cabecalho do chat */
.chat-header-back {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-width: 44px;
    min-height: 40px;
    padding: 6px 12px 6px 9px;
    margin-right: 4px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg);
    color: var(--brand-primary-darker, #213423);
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    transition: background 0.15s ease, border-color 0.15s ease;
}

.chat-header-back:hover,
.chat-header-back:focus-visible {
    background: var(--brand-tint, #e8f7ee);
    border-color: var(--brand-primary-dark, #2f4a32);
}

html.theme-dark .chat-header-back {
    background: rgba(148, 163, 184, 0.1);
    border-color: rgba(134, 201, 140, 0.32);
    color: var(--brand-pastel, #86c98c);
}

#sec-chat .card-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding-top: 10px;
    padding-bottom: 10px;
}

#sec-chat .card-header h3 {
    flex: 1 1 auto;
    min-width: 0;
    justify-content: center;
}

/* compensa o botao a esquerda para o titulo continuar opticamente central */
#sec-chat .card-header:has(.chat-header-back) h3 {
    margin-right: 56px;
}

/* 4b. composer colado no rodape do thread */
body:has(#sec-chat.active) .chat-thread .chat-input-area {
    bottom: 0;
    padding-bottom: max(12px, var(--safe-bottom, 0px));
}

/* CAUSA RAIZ do "nao consigo ver a parte superior do chat e sobra um vao
   embaixo" (relato de 25/07):
   `body.logged-in` recebe `padding-bottom: calc(--nav-height + --safe-bottom
   + 8px)` para o conteudo nao terminar atras da barra inferior. Isso e certo
   nas telas que rolam. Mas o Chat trava a altura em 100svh e ja reserva a
   barra no proprio .main-content, entao esses ~73px viram FOLGA ROLAVEL: o
   body desliza e leva o cabecalho do chat para tras do header fixo, abrindo
   exatamente o mesmo tanto de vazio embaixo do campo de mensagem.
   Com o Chat ativo o body nao pode ter essa almofada. */
body.logged-in:has(#sec-chat.active) {
    padding-bottom: 0;
}

/* Reserva no proprio .main-content, medida pela altura real da barra.
   O !important acompanha a regra anterior do app.css, que tambem usa. */
body:has(#sec-chat.active) .main-content {
    padding-bottom: calc(var(--nav-height, 65px) + var(--safe-bottom, 0px) + 16px) !important;
}

/* area de mensagens sempre com altura util, mesmo em telas baixas */
body:has(#sec-chat.active) .chat-thread .chat-messages {
    min-height: 96px;
}

/* 4c. com poucas mensagens elas descem ate encostar no composer, igual a
   qualquer chat de referencia; com muitas, o overflow-y:auto de sempre
   continua rolando normalmente.

   E `margin-top:auto` no primeiro filho, e NAO `justify-content:flex-end` no
   container: num container rolavel, o flex-end empurra o inicio do conteudo
   para FORA da area de rolagem quando a conversa passa da altura da tela, e o
   trecho que vazou fica inalcancavel (a rolagem nao chega ate ele). E o modo de
   falhar mais grave possivel aqui, porque so aparece em conversa LONGA, que e
   justamente a de quem usa o app, e o Safari do iOS e onde mais morde.
   Com a margem automatica o efeito visual e o mesmo na conversa curta e o
   comportamento volta ao normal assim que o conteudo passa da altura. */
body:has(#sec-chat.active) .chat-thread .chat-messages > *:first-child {
    margin-top: auto;
}

/* excecao: tela SEM nenhuma mensagem ainda nao deve colar no composer, fica
   centralizada como qualquer estado vazio do app (empty-chat e o placeholder
   estatico do HTML antes do JS responder; empty-mascote e o que renderMensagens
   desenha quando a lista chega vazia). Margem automatica nos DOIS lados: o
   mesmo mecanismo do item acima, sem misturar com justify-content. */
body:has(#sec-chat.active) .chat-thread .chat-messages > .empty-chat:first-child,
body:has(#sec-chat.active) .chat-thread .chat-messages > .empty-mascote:first-child {
    margin-top: auto;
    margin-bottom: auto;
}

/* 4d. o separador de data ja quebra a sequencia no DOM (o seletor "+" so casa
   bolhas REALMENTE adjacentes), entao o cabecalho volta sozinho quando muda
   o dia ou quando o paciente responde no meio da conversa. */
.chat-msg.recebida.from-nutri + .chat-msg.recebida.from-nutri .chat-msg-author {
    display: none;
}

.chat-msg.recebida.from-nutri + .chat-msg.recebida.from-nutri {
    margin-top: -8px; /* gap:12px do container vira 4px so entre bolhas do mesmo grupo */
}

/* em paisagem o composer nao pode ocupar metade da tela */
@media (orientation: landscape) and (max-height: 500px) {
    .chat-tipo-label,
    .chat-tipo-select {
        display: none;
    }

    body:has(#sec-chat.active) .chat-thread .chat-input-area {
        padding-top: 8px;
    }
}

/* =====================================================================
   5. RESPONSIVIDADE TRANSVERSAL
   ===================================================================== */

/* Nenhum bloco pode furar a largura da tela. */
.main-content img,
.main-content video,
.main-content iframe,
.main-content canvas,
.main-content table,
.main-content pre {
    max-width: 100%;
}

/* Palavras longas (e-mails, URLs, nomes de arquivo) quebram em vez de
   alargar o card. */
.card-body,
.mais-item-label,
.next-appointment .date,
.doc-item,
.agenda-item,
.chat-msg {
    overflow-wrap: anywhere;
}

/* Faixas roláveis horizontais (abas de receitas, dias do plano) ficam
   contidas: rolam por dentro, sem arrastar a pagina. */
.rec-tabs,
.dias-tabs,
.chat-sidebar-filtros,
.orientacao-chips {
    overflow-x: auto;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}

.rec-tabs::-webkit-scrollbar,
.dias-tabs::-webkit-scrollbar,
.chat-sidebar-filtros::-webkit-scrollbar {
    display: none;
}

/* ---------------------------------------------------------------------
   5a. Alvos de toque
   Auditoria de 25/07 em 320/360/390/430px: varios controles abaixo do
   minimo de 44px das diretrizes de iOS e Android. Os piores eram links
   de 16px e 21px de altura, impossiveis de acertar com o polegar.
   --------------------------------------------------------------------- */
.refeicao-foto-btn,
.registrar-foto-btn,
.plano-acao-btn,
.water-btn,
.theme-pill,
.profile-btn,
.orientacao-chip,
.forms-cta-btn {
    min-height: 44px;
}

/* Alguns destes tinham `height` fixo (38px, 32px), que anula min-height.
   Sem `height:auto` o min-height acima nao teria efeito nenhum. */
.plano-acao-btn,
.water-btn,
.theme-pill,
.refeicao-foto-btn {
    height: auto;
}

/* Tres controles ficavam abaixo do minimo por regras mais especificas que a
   de cima (38px, 32px e 36px). O reforco vale so em ponteiro grosso (dedo):
   no mouse a densidade compacta original e mantida de proposito. */
@media (pointer: coarse) {
    .plano-acoes.plano-acoes-rodape .plano-acao-btn {
        min-height: 44px;
    }

    .water-card--compact .water-btn--inline {
        min-height: 44px;
        padding: 8px 14px;
    }

    .profile-btn.danger-link,
    .profile-btn.website-link {
        min-height: 44px;
    }
}

/* Links de texto que funcionam como botao ganham area de toque sem
   mudar o desenho: o padding entra por dentro da linha. */
.parceiro-insta,
.mentoria-link,
.servico-link {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding-top: 4px;
    padding-bottom: 4px;
}

/* ---------------------------------------------------------------------
   5b. Descricao do hero nao pode ser cortada
   ".home-hero-cta-desc" vinha com line-clamp e virava "Leva 2 minutos.
   Ajuda seu nutricioni..." ja em 390px.
   --------------------------------------------------------------------- */
.home-hero-cta-content {
    min-width: 0;
}

.home-hero-cta-title,
.home-hero-cta-desc {
    display: block;
    overflow: visible;
    text-overflow: clip;
    white-space: normal;
    -webkit-line-clamp: none;
}

/* Em celular o botao desce para a linha de baixo, em largura cheia. Enquanto
   ele disputava espaco na mesma linha, ou o titulo ou a descricao acabava
   cortado com reticencias. */
@media (max-width: 480px) {
    .home-hero-cta {
        flex-wrap: wrap;
        row-gap: 10px;
        align-items: center;
    }

    .home-hero-cta-icon {
        flex: 0 0 auto;
    }

    /* base 0 + min-width 0: o texto encolhe e continua ao lado do icone em
       vez de cair para a linha de baixo e deixar o icone orfao. */
    .home-hero-cta-content {
        flex: 1 1 0;
        min-width: 0;
    }

    .home-hero-cta-btn {
        flex: 1 1 100%;
        margin-top: 0;
    }
}

/* ---------------------------------------------------------------------
   5c. Cabecalho em telas estreitas
   A 320px os seis botoes do cabecalho estouravam o proprio container e
   o primeiro deles passava por cima da logomarca (o selo "97" cobria o
   texto). Agora a logomarca encolhe e as acoes nunca invadem a esquerda.
   --------------------------------------------------------------------- */
.app-header .header-content {
    gap: 8px;
}

.app-header .header-brand,
.app-header .header-user {
    min-width: 0;
    flex-shrink: 1;
    overflow: hidden;
}

.app-header .header-actions {
    flex-shrink: 0;
    flex-wrap: nowrap;
}

@media (max-width: 400px) {
    .app-header .header-actions {
        gap: 3px;
    }

    .app-header .header-brand img,
    .app-header .header-brand svg {
        max-width: 100%;
        height: auto;
    }
}

@media (max-width: 340px) {
    /* Ultimo recurso: a marca sai e as acoes ficam inteiras e tocaveis,
       distribuidas na largura toda em vez de amontoadas no centro. */
    .app-header .header-brand {
        display: none;
    }

    .app-header .header-actions {
        flex: 1 1 auto;
        justify-content: space-between;
    }
}

/* Telas muito estreitas (<=360px): respiro menor, alvos de toque mantidos */
@media (max-width: 360px) {
    .home-hero-cta {
        flex-wrap: wrap;
    }

    .home-hero-cta-btn {
        flex: 1 1 100%;
        margin-top: 8px;
    }

    .status-banner {
        align-items: flex-start;
    }
}

/* Paisagem em celular: cabecalho e barra encolhem para sobrar conteudo */
@media (orientation: landscape) and (max-height: 460px) {
    :root {
        --header-height: 52px;
        --nav-height: 56px;
    }

    .app-header {
        padding-top: calc(6px + var(--safe-top, 0px));
        padding-bottom: 6px;
    }

    .nav-item span {
        font-size: 9px;
    }
}

/* Tablets e telas grandes: o app centraliza, mas o card de consulta e a
   gaveta nao podem esticar demais. */
@media (min-width: 768px) {
    .mais-sheet {
        border-radius: 24px;
        margin-bottom: calc(var(--nav-height, 65px) + var(--safe-bottom, 0px) + 12px);
        max-height: min(80svh, calc(100svh - 140px));
    }

    .mais-sheet {
        padding-bottom: 12px;
    }
}

/* Preferencia de menos movimento: sem transform nas gavetas */
@media (prefers-reduced-motion: reduce) {
    .mais-sheet,
    .chat-input-area {
        transition: none;
    }
}

/* =====================================================================
   9. GAVETA "MAIS": TOM POR GRUPO  (2026-08-04)
   ---------------------------------------------------------------------
   A marcacao ja prometia isto nos comentarios ("tons emerald", "tons
   amber/sky", "violet/indigo"), mas nada disso existia no CSS: os 18
   icones saiam todos do mesmo cinza-esverdeado. Com quatro grupos
   identicos, o titulo do grupo era o UNICO sinal de separacao, e titulo
   de 9,5px em caixa alta nao segura divisao nenhuma num celular.

   Agora cada grupo tem superficie e tinta proprias, entao o olho acha o
   bloco antes de ler o rotulo. Fica no app-fixes.css porque este arquivo
   e o ultimo da cascata e ja e dono das outras regras .mais-* (as do
   app.css perderiam para as daqui).
   ===================================================================== */

.mais-group-title {
    display: flex;
    align-items: center;
    gap: 7px;
}

/* Marcador do tom antes do titulo: e o mesmo sinal do icone, em miniatura */
.mais-group-title::before {
    content: '';
    width: 14px;
    height: 3px;
    border-radius: 999px;
    background: currentColor;
    flex: none;
    opacity: .85;
}

/* --- verde da marca: o nucleo do acompanhamento --- */
.mais-group[data-tom="acompanhamento"] .mais-group-title { color: var(--brand-primary-darker, #213423); }
/* --tenant-cor-tint direto, e NAO --brand-tint: o fallback de --brand-tint e
   #f1f5f9, um cinza neutro (conferido no navegador). Usando aquele token o
   grupo do acompanhamento saia cinza, sem tom nenhum, enquanto ambar e indigo
   apareciam: o verde era o unico grupo sem identidade. Assim o tenant
   white-label continua mandando na cor e o padrao e o verde da marca. */
.mais-drawer .mais-group[data-tom="acompanhamento"] .mais-item-icon {
    background: var(--tenant-cor-tint, #e8f7ee);
    color: var(--brand-primary-darker, #213423);
    border-color: #cfe7d2;
}

/* --- ambar: o que se usa fora da consulta --- */
.mais-group[data-tom="diaadia"] .mais-group-title { color: #92400e; }
.mais-drawer .mais-group[data-tom="diaadia"] .mais-item-icon {
    background: #fef3c7;
    color: #92400e;
    border-color: #fde68a;
}

/* --- indigo: conteudo e oferta da clinica --- */
.mais-group[data-tom="clinica"] .mais-group-title { color: #3730a3; }
.mais-drawer .mais-group[data-tom="clinica"] .mais-item-icon {
    background: #e0e7ff;
    color: #3730a3;
    border-color: #c7d2fe;
}

/* --- neutro: conta --- */
.mais-group[data-tom="conta"] .mais-group-title { color: #475569; }
.mais-drawer .mais-group[data-tom="conta"] .mais-item-icon {
    background: #f1f5f9;
    color: #475569;
    border-color: #e2e8f0;
}

/* Modo escuro: pelicula translucida em vez do pastel, que sobre #0f172a
   viraria adesivo fluorescente. Precisa vencer a regra generica de
   html.theme-dark .mais-drawer .mais-item-icon do bloco 3b, logo acima. */
html.theme-dark .mais-group[data-tom="acompanhamento"] .mais-group-title { color: var(--brand-pastel, #86c98c); }
html.theme-dark .mais-drawer .mais-group[data-tom="acompanhamento"] .mais-item-icon {
    background: rgba(134, 201, 140, .14);
    color: var(--brand-pastel, #86c98c);
    border-color: rgba(134, 201, 140, .3);
}

html.theme-dark .mais-group[data-tom="diaadia"] .mais-group-title { color: #fcd34d; }
html.theme-dark .mais-drawer .mais-group[data-tom="diaadia"] .mais-item-icon {
    background: rgba(252, 211, 77, .13);
    color: #fcd34d;
    border-color: rgba(252, 211, 77, .28);
}

html.theme-dark .mais-group[data-tom="clinica"] .mais-group-title { color: #a5b4fc; }
html.theme-dark .mais-drawer .mais-group[data-tom="clinica"] .mais-item-icon {
    background: rgba(165, 180, 252, .13);
    color: #a5b4fc;
    border-color: rgba(165, 180, 252, .28);
}

html.theme-dark .mais-group[data-tom="conta"] .mais-group-title { color: #94a3b8; }
html.theme-dark .mais-drawer .mais-group[data-tom="conta"] .mais-item-icon {
    background: rgba(148, 163, 184, .13);
    color: #cbd5e1;
    border-color: rgba(148, 163, 184, .28);
}

/* O "Sair" mantem o vermelho mesmo dentro do grupo neutro: e a unica acao
   destrutiva da gaveta e nao pode se parecer com "Perfil", que fica ao lado. */
.mais-drawer .mais-group[data-tom="conta"] .mais-item-icon--logout {
    background: #fef2f2;
    color: #991b1b;
    border-color: #fecaca;
}
html.theme-dark .mais-drawer .mais-group[data-tom="conta"] .mais-item-icon--logout {
    background: rgba(248, 113, 113, .14);
    color: #fca5a5;
    border-color: rgba(248, 113, 113, .32);
}

/* Altura minima de 86px (bloco 3) foi calculada para rotulo de duas linhas.
   Nenhum rotulo passa de uma linha desde a reorganizacao, entao a celula
   sobrava ~18px de vazio em cada uma das seis linhas da grade. */
.mais-drawer .mais-item { min-height: 74px; }

@media (max-height: 720px) {
    .mais-drawer .mais-item { min-height: 66px; }
    /* 9,5px era pequeno demais para rotulo em tela pequena. O espaco veio da
       altura morta da celula, nao de espremer mais o texto. */
    .mais-item-label { font-size: 10px; }
}

/* A 5a coluna da gaveta estava declarada DUAS vezes: uma no trecho legivel do
   app.css (removida, com a medicao no comentario de la) e outra dentro do
   trecho minificado do mesmo arquivo, que sobreviveu. Como mexer no blob
   minificado a mao e pedir para quebrar outra coisa, a correcao fica aqui, no
   ultimo arquivo da cascata. Medido no iPhone SE (375x667): com os grupos de
   7, 4, 6 e 2 itens, 4 e 5 colunas dao as MESMAS 6 linhas e a MESMA altura de
   544px, entao a 5a coluna so encolhia icone e rotulo de graca. */
@media (max-height: 720px) {
    .mais-drawer .mais-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* ============================================================================
   CORREÇÃO 2026-08-04: `--border` ERA UM CICLO NO TEMA CLARO E APAGAVA
   TODA BORDA ESCRITA SEM FALLBACK.

   Defeito: no trecho minificado do app.css o bloco `html.theme-light` declara
   os tokens todos com valor literal, menos um:

       html.theme-light { ... --border: var(--border, #e2e8f0) !important; ... }

   Uma custom property que referencia a si mesma é um CICLO. A resolução do
   ciclo acontece DEPOIS da cascata, então o `!important` fazia essa declaração
   VENCER as outras três que davam `--border:#e2e8f0`, e aí o token virava
   guaranteed-invalid. Consequência: `var(--border, #e2e8f0)` seguia funcionando
   pelo fallback, mas `var(--border)` PURO, que aparece em 172 regras, ficava
   inválido em tempo de valor computado e a propriedade caía no valor inicial.
   Como o inicial de `border-style` é `none`, a borda inteira sumia.

   Medido no navegador, mesmo elemento nos dois temas (tema claro é o PADRÃO):
     .bottom-nav   escuro: border-top solid 1px rgb(51,65,85)  | claro: none 0px
     .chat-input   escuro: border    solid 1px rgb(71,85,105)  | claro: none 0px
     .app-header   escuro: border-bottom solid 1px             | claro: none 0px
     .modal-header escuro: border-bottom solid 1px rgb(51,65,85)| claro: none 0px
     .mais-item    escuro: none/none                            | claro: none 0px
   Ou seja: divisor do cabeçalho, do rodapé de navegação, do cabeçalho de todos
   os 9 modais e a moldura do campo do chat estavam invisíveis para quem usa o
   app no claro, que é o padrão de instalação.

   Correção: redeclarar o token com o literal. Mesma especificidade (0,1,1) do
   bloco quebrado, e este arquivo é o ÚLTIMO da cascata, então vence por ordem.
   O `!important` é obrigatório aqui, e só aqui: a declaração anterior é
   `!important` e sem ele a quebrada continuaria vencendo.
   ============================================================================ */
html.theme-light { --border: #e2e8f0 !important; }

/* ============================================================================
   CORREÇÃO 2026-08-04: CABEÇALHO DA GAVETA DE PDF NASCIA BRANCO NO ESCURO.

   Mesmo defeito de `--bg-card` que já foi corrigido em Treinos e Comunidade,
   ainda vivo no visualizador de documentos, dentro do trecho minificado:

       .pdf-drawer-head { background: var(--bg-card, #fff) }

   `--bg-card` NÃO existe (conferido com getComputedStyle: string vazia nos dois
   temas), então o fallback branco valia sempre, enquanto o título usa
   `color: var(--text)`, que no escuro é #f1f5f9.

   Medido no navegador, tema escuro: fundo do cabeçalho rgb(255,255,255) e
   título rgb(241,245,249), contraste 1,10:1. O nome do documento que a paciente
   abre para ler a prescrição ficava ilegível.

   O token de superfície deste app é `--card` (#ffffff no claro, #1e293b no
   escuro). Sem `!important`: a regra anterior não usa, e este arquivo vem
   depois na cascata.
   ============================================================================ */
.pdf-drawer-head { background: var(--card, #fff); }

/* ============================================================================
   CORREÇÃO 2026-08-04: TEXTO DE MARCA VERDE-ESCURO SOBRE CARTÃO ESCURO.

   `--brand-primary-dark` (#2f4a32) e `--brand-primary-darker` (#3d6041) são
   tons pensados para fundo claro. Usados como COR DE TEXTO sem par no escuro,
   caem sobre `--card` (#1e293b) e reprovam o AA com folga.

   Medido no navegador, tema escuro, larguras de 320 a 1440 (o valor não muda
   com a largura, é cor):
     .servico-preco       #3d6041 sobre #1e293b = 2,05:1 (mínimo 4,5)
     .forms-cta-btn.ghost #2f4a32 sobre #1e293b = 2,89:1 (mínimo 4,5)

   O par correto no escuro é o verde pastel da marca, que existe justamente
   para isto. Aferido depois da troca: #86C98C sobre #1e293b = 8,04:1.
   ============================================================================ */
html.theme-dark .servico-preco { color: var(--brand-pastel, #86c98c); }
html.theme-dark .forms-cta-btn.ghost {
    color: var(--brand-pastel, #86c98c);
    border-color: var(--brand-pastel, #86c98c);
}

/* ============================================================================
   CORREÇÃO 2026-08-04: BLOCO "ATENÇÃO ESPECIAL" DAS ORIENTAÇÕES NO ESCURO.

   O bloco JÁ tinha regra de tema escuro, mas ela repetia o âmbar escuro do
   tema claro (#b45309, que é o `--warning`, um tom para fundo branco):

       html.theme-dark .orientacao-alerta strong { color:#b45309 }
       html.theme-dark .orientacao-alerta p      { color:#b45309 }
       html.theme-dark .orientacao-alerta i      { color:#b45309 }

   Medido no navegador, tema escuro: #b45309 sobre a composição de
   rgba(217,119,6,.1) sobre #1e293b = 2,91:1, mínimo 4,5. É o aviso de
   interação medicamentosa, o texto que MENOS pode ficar apagado.

   Trocado pelo âmbar claro, que é o que o escuro pede. Aferido depois:
   #fcd34d sobre a mesma composição = 8,98:1. Sem `!important`: as regras
   anteriores não usam e este arquivo vem depois.
   ============================================================================ */
html.theme-dark .orientacao-alerta strong,
html.theme-dark .orientacao-alerta p,
html.theme-dark .orientacao-alerta i,
html.theme-dark .orientacao-alerta [data-lucide] { color: #fcd34d; }

/* ============================================================================
   CORREÇÃO 2026-08-04: RÓTULOS DA BARRA LATERAL (só aparece de 1024px acima).

   Dois textos de apoio da barra lateral ficaram com cinza de fundo errado:

   1) `.sidebar-group-title` tem `color:#64748b` LITERAL dentro do
      `@media (min-width:1024px)` do trecho minificado, sem par no escuro.
      Medido a 1440 no escuro: #64748b sobre #0f172a = 3,75:1, mínimo 4,5
      (fonte de 10px, então não entra na tolerância de texto grande).
      Com `--text-muted` (#94a3b8 no escuro) passa a 7,05:1, e no claro o
      token continua #64748b, que é o valor de hoje: nada muda no claro.

   2) `.sidebar-collapse-toggle` usa `var(--text-muted)` sobre `--bg-alt`.
      Medido a 1440 no CLARO: #64748b sobre #f1f5f9 = 4,34:1, mínimo 4,5.
      Reprova por pouco, mas reprova. `--text-secondary` (#475569) dá 6,88:1.

   O rótulo "Recolher menu" é um `<span>` sem cor própria: ele HERDA do botão.
   Por isso a correção é no botão. Atenção à especificidade: quem vencia era
   `html.theme-light .sidebar-collapse-toggle`, com (0,2,0). Um
   `.sidebar-collapse-toggle` solto, (0,1,0), perde e não muda nada, como foi
   medido na primeira tentativa. O seletor abaixo empata em (0,2,0) e vence
   por vir depois na cascata.
   ============================================================================ */
@media (min-width: 1024px) {
    .sidebar-group-title { color: var(--text-muted, #64748b); }
    html.theme-light .sidebar-collapse-toggle,
    .sidebar-collapse-toggle { color: var(--text-secondary, #475569); }
}

/* ============================================================================
   CORREÇÃO 2026-08-04: iPAD AINDA DAVA ZOOM AO FOCAR CAMPO.

   A trava que impede o auto-zoom do iOS existia, mas só até 768px:

       @media (max-width:768px){ input,select,textarea{font-size:16px!important} }

   Todo iPad acima disso ficava de fora. Medido no navegador a 820x1180
   (iPad Air em retrato), 9 campos abaixo de 16px, entre eles os do LOGIN:
     #loginIdentificador 15,5px | #loginSenha 15,5px | #chatInput 14,5px
     #chatSearch 14,5px | #leitorInput 14,5px | #recBusca 14,5px
     #tkTipo 14,5px | #tkDur 14,5px | #tkObs 14,5px
   O `<meta name="viewport">` não trava escala (não tem `maximum-scale` nem
   `user-scalable=no`), então o Safari amplia ao focar e desloca a tela.

   A largura não é o sinal certo: o sinal é o ponteiro. `pointer: coarse` pega
   qualquer aparelho de toque, de 320px ao iPad Pro, e não mexe no desktop.
   O `!important` acompanha a regra que já existia, senão ela venceria.
   ============================================================================ */
@media (pointer: coarse) {
    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]),
    select,
    textarea { font-size: 16px !important; }
}

/* ============================================================================
   CORREÇÃO 2026-08-04: ALVOS DE TOQUE ABAIXO DE 44px.

   Medido com getBoundingClientRect em 320, 360, 375, 390, 414, 768 e 1440,
   nos dois temas. Corrigido só onde há folga de layout comprovada:

     .mais-close        36x36 em TODAS as larguras. O cabeçalho da gaveta tem
                        320px de largura para um título curto: sobra espaço.
     .tipo-btn          altura 40 (os três do chat: dúvida, agendamento,
                        urgente). Estão numa linha; altura é espaço livre.
     .chat-header-back  altura 40. É o "voltar" da conversa, o controle mais
                        usado da tela e o mais fácil de errar com o polegar.
     .home-hero-cta-btn altura 40. É a chamada principal da Home.

   Só altura onde a largura é disputada: nada aqui muda a largura, então
   nenhuma linha passa a estourar.
   ============================================================================ */
.mais-close { min-width: 44px; min-height: 44px; }
.tipo-btn,
.chat-header-back,
.home-hero-cta-btn { min-height: 44px; }

/* ============================================================================
   CORREÇÃO 2026-08-04: `--primary` NÃO É A COR DA MARCA, E SUMIA NO ESCURO.

   O token está declarado com o MESMO valor nos dois temas, um azul-ardósia
   quase preto, o que só faz sentido no claro:

       :root, html.theme-light, html.theme-dark { --primary: #1e293b }

   Quem escreveu o app supôs que fosse o verde da marca, tanto que os usos
   trazem fallback verde (`var(--primary,#609165)`). Como o token EXISTE, o
   fallback nunca entra e o que vale é o #1e293b.

   Dois estragos medidos no navegador, tema escuro:

   1) Prescrições: os dois títulos ("Prescrições:" e "Solicitações de Exames:")
      saem do js/app.js com `style="color:var(--primary)"` e ficaram
      rgb(30,41,59) sobre rgb(28,34,48): contraste 1,09:1. Pior: `--card` no
      escuro é #1e293b, o MESMO valor, então o título é exatamente a cor do
      cartão. Corrigido no js/app.js trocando por `var(--text)`, que no claro
      vale #1e293b, idêntico ao de hoje, e no escuro vale #f1f5f9. O tema claro
      não muda em nada.

   2) Os três indicadores de carregamento traziam
      `style="color:var(--primary,#609165)"`, ou seja, #1e293b sobre o fundo
      #0f172a: 1,19:1. A paciente via uma área vazia enquanto a seção carregava,
      sem sinal nenhum de que algo estava acontecendo. Trocado por uma classe,
      abaixo, porque estilo em atributo não dá para tematizar.

   Aferido depois: #2f4a32 sobre #f8fafc = 4,82:1 no claro, e
   #86C98C sobre #0a0e1b = 9,85:1 no escuro. Um indicador de carregamento é
   elemento gráfico, então o piso é 3:1 (WCAG 1.4.11); os dois passam com
   folga. O token `--primary` foi deixado como está de propósito: ele também é
   usado como FUNDO em sete regras, e mexer no token trocaria a cor desses
   blocos.

   Os três indicadores vivem dentro de `.empty-state`, e o app já tem
   `body .empty-state i { color: var(--ds-brand-soft) }`, com especificidade
   (0,1,2). Um `.spinner-marca` solto, (0,1,0), PERDE dessa regra: medido, o
   claro saía #609165 em vez do #2f4a32 pretendido. Por isso o seletor do
   claro carrega o contexto `.empty-state i`, para empatar em (0,2,1) e vencer
   por ordem. Sem isto a cor do claro seria herdada por acidente, não por
   decisão.
   ============================================================================ */
.spinner-marca,
.empty-state i.spinner-marca,
.empty-state [data-lucide].spinner-marca { color: var(--brand-primary-dark, #2f4a32); }
html.theme-dark .spinner-marca,
html.theme-dark .empty-state i.spinner-marca,
html.theme-dark .empty-state [data-lucide].spinner-marca { color: var(--brand-pastel, #86c98c); }

/* =====================================================================
   10. DETALHE DA AVALIACAO FISICA  (2026-08-05)
   ---------------------------------------------------------------------
   Relato do dono: "abro uma avaliacao, e se eu descer ou subir a tela
   toda se move, o menu inferior some e o x de fechar fica quase
   invisivel".

   Tres causas distintas, e as tres estao em estilo INLINE gerado pelo
   app.js (arquivo minificado de 475 KB). Por isso a correcao vem daqui
   com !important: nao ha como vencer inline sem ele, e mexer no
   minificado para trocar tres valores e risco desproporcional.

   a) `max-height: 92vh`. No celular, `vh` e o viewport de LAYOUT, que
      nao encolhe quando a barra do navegador aparece. Entao a folha
      nasce mais alta do que a area visivel e, a cada rolagem que mostra
      ou esconde a barra, a altura util muda e tudo se desloca. `dvh` e
      a unidade que acompanha o viewport dinamico, que e exatamente o
      que falta aqui. O `vh` fica antes como reserva para navegador
      antigo, e o `dvh` sobrescreve onde existe.

   b) Rolagem encadeada. Ao chegar no fim do conteudo da folha, o gesto
      continua e passa a rolar a PAGINA atras dela, que e o "a tela toda
      se move". `overscroll-behavior: contain` para o encadeamento no
      proprio elemento.

   c) O botao de fechar era branco a 18% sobre um degrade verde claro:
      quase invisivel, como o dono disse, e com area de toque menor que
      o minimo. Vira superficie solida, com contraste real e 40px.
   ===================================================================== */

.aval-detail-overlay {
    align-items: flex-end !important;
    /* A folha nunca deve ficar sob a barra de gestos do sistema. */
    padding-bottom: env(safe-area-inset-bottom, 0px) !important;
}

.aval-detail-modal {
    max-height: 92vh !important;
    max-height: 92dvh !important;
    overscroll-behavior: contain !important;
    /* Rolagem por toque suave e previsivel dentro da folha. */
    -webkit-overflow-scrolling: touch;
}

/* O cabecalho da folha e sticky: o botao de fechar precisa continuar
   legivel enquanto o conteudo passa por tras dele. */
.aval-detail-modal [aria-label="Fechar"] {
    background: rgba(255, 255, 255, 0.95) !important;
    color: #213423 !important;
    border: 0 !important;
    width: 40px !important;
    height: 40px !important;
    min-width: 40px !important;
    border-radius: 12px !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    font-size: 16px !important;
    box-shadow: 0 1px 3px rgba(15, 23, 42, .18) !important;
}
.aval-detail-modal [aria-label="Fechar"]:hover,
.aval-detail-modal [aria-label="Fechar"]:focus-visible {
    background: #ffffff !important;
    color: #2d3a2e !important;
}
.aval-detail-modal [aria-label="Fechar"]:focus-visible {
    outline: 2px solid #ffffff !important;
    outline-offset: 2px !important;
}

html.theme-dark .aval-detail-modal [aria-label="Fechar"] {
    background: rgba(226, 232, 240, 0.92) !important;
    color: #2d3a2e !important;
}

/* =====================================================================
   Rodada do relatório do Marcos (06/08/2026): app.seucenoura.com
   ---------------------------------------------------------------------
   Correções puramente visuais, todas com causa raiz medida no navegador.
   Esta camada é a ÚLTIMA da cascata, por isso vence o design system.

   1. Ícones do menu inferior e check da cognitiva (ponte Font Awesome
      para Lucide): o icon-bridge.js troca o <i> por <svg>, e todo
      seletor `X i` que dimensionava o ícone parou de casar. O ícone
      passou a herdar o font-size do container. Medido no menu inferior:
      11x11 px dentro de uma caixa de 52x44, quando o CSS pedia 26px.
      O <svg> nasce com width/height de 1em (bridge) ou com os atributos
      width="24"/height="24" (render direto do Lucide), então as regras
      abaixo fixam os dois: font-size e o par largura/altura em 1em.
   2. Lupa sobreposta ao texto no Leitor de Rótulos: a regra do design
      system `body .app-section input[type=text]{padding:11px 13px}`
      (especificidade 0,2,2) atropelava `.leitor-input-wrap input`
      (0,1,1), que reservava 46px para o ícone.
   3. Tela de Perfil prensada no centro: `.profile-section-centered` é
      flex column com align-items center, então os filhos em bloco
      encolhem para o conteúdo em vez de ocupar a linha.
   4. Modal de vídeo (Meditação e Lives) colado no rodapé: o overlay
      global é bottom sheet (align-items flex-end), mas este modal tem
      canto arredondado nos quatro lados. Centraliza SÓ ele.
      Usa flex-start + margin auto de propósito: com align-items center
      o topo some quando o conteúdo é mais alto que a tela.
   5. Botão "Agendar primeira visita" ilegível: um !important forçava
      color var(--text) num botão de fundo branco. No tema escuro
      --text vale #f1f5f9, ou seja, branco sobre branco.
   ===================================================================== */

/* 1. Ícones convertidos para SVG voltam ao tamanho que o CSS pedia. */
.nav-item-icon i,
.nav-item-icon svg,
.nav-item-icon [data-lucide] {
    width: 1em;
    height: 1em;
    font-size: 32px;
}

@media (max-width: 480px) {
    .nav-item-icon i,
    .nav-item-icon svg,
    .nav-item-icon [data-lucide] {
        font-size: 26px;
    }
}

@media (max-width: 340px) {
    .nav-item-icon i,
    .nav-item-icon svg,
.nav-item-icon [data-lucide]{
        font-size: 22px;
    }
}

/* 1b. O rótulo do menu inferior "mais abaixo do ideal" (2026-08-06, medido no
      navegador depois da v3.68.3).

      Aumentar o ícone resolveu metade do relato. A outra metade sobreviveu: a
      pílula `.nav-item-icon` tem `min-height:44px` FIXO desde o app-revisao.css,
      medida para um ícone de 22px. Com o ícone certo de 26px continuavam
      sobrando 9px mortos abaixo do desenho, e o rótulo caía 14px do glifo.

      A pílula é o fundo do item ativo, então não pode sumir: o que ela deixa de
      ter é a altura fixa. Trocada por padding, ela passa a acompanhar o ícone
      (26+12=38px no celular, 32+12=44px no tablet, exatamente o que era antes
      nessa faixa) e o rótulo sobe. O alvo de toque não muda: quem recebe o
      toque é o `.nav-item` inteiro, de 72x65. */
.nav-item-icon {
    min-height: 0;
    height: auto;
    padding-top: 6px;
    padding-bottom: 6px;
    box-sizing: border-box;
}

/* Em telas de até 340px o app.css declara `min-height: 46px !important`, e o
   !important vence ordem de folha. Repare que o valor é MAIOR que os 40px da
   faixa de 480px: a tela mais estreita ficava com a pílula mais alta de todas,
   que é o oposto do que a faixa pede. Só aqui o !important é necessário. */
@media (max-width: 340px) {
    .nav-item-icon {
        min-height: 0 !important;
    }
}

.nav-item-label {
    margin-top: 0;
}

.bottom-nav .nav-item {
    gap: 2px;
}

/* Demais ícones que o CSS dimensionava pelo seletor `i`. */
.empty-state i,
.empty-state svg,
.empty-chat i,
.empty-chat svg,
.foto-preview i,
.foto-preview svg,
/* Demais ícones que o CSS dimensionava pelo seletor `i`. */
.empty-state [data-lucide],
.empty-chat [data-lucide],
.foto-preview [data-lucide]{
    width: 1em;
    height: 1em;
    font-size: 40px;
}

.empty-state-mini i,
.empty-state-mini svg,
.bottom-nav-item i,
.bottom-nav-item svg,
.empty-state-mini [data-lucide],
.bottom-nav-item [data-lucide]{
    width: 1em;
    height: 1em;
    font-size: 20px;
}

.forms-hero i,
.forms-hero svg,
.sug-stars i,
.sug-stars svg,
.forms-hero [data-lucide],
.sug-stars [data-lucide]{
    width: 1em;
    height: 1em;
    font-size: 22px;
}

/* Check de confirmação da avaliação cognitiva: virou contorno de 14px e
   sumia no fundo. Volta a ser grande, encorpado e escuro. */
.cog-opcao-check {
    width: 1em;
    height: 1em;
    font-size: 20px;
    color: var(--brand-primary-darker, #213423);
    /* !important porque o icon-bridge.js grava stroke-width 1.75 INLINE no
       elemento, e inline vence folha de estilo. Sem isto o traço continua
       fino e o check segue com cara de apagado, que foi o relato. */
    stroke-width: 2.75 !important;
}

html.theme-dark .cog-opcao-check {
    color: var(--brand-pastel, #86c98c);
}

/* 2. Campos com ícone embutido: o conserto do padding mudou de casa em
      27/08/2026 e agora vive no FIM do css/app.css. Motivo medido: esta folha é
      carregada de forma assíncrona (media="print" + onload), então no primeiro
      acesso, antes de o service worker ter cópia, a lupa ficava 14px POR CIMA da
      primeira letra até a folha chegar. O app.css é síncrono e já contém a regra
      do design system que precisa ser vencida: perto dela, sem janela aberta. */

/* 3. Perfil: grades e cards ocupam a largura da linha, o texto continua
      centralizado pelo próprio container. */
.profile-section-centered > .card,
.profile-section-centered > .profile-actions,
.profile-section-centered .profile-stats,
.profile-section-centered .theme-toggle-card {
    align-self: stretch;
    width: 100%;
}

/* O bloco de ações mantém o teto de 360px do desenho original; o que muda
   é parar de encolher para o conteúdo dentro do container centralizado. */
.profile-section-centered > .profile-actions {
    margin-left: auto;
    margin-right: auto;
}

/* 4. Modal de vídeo centralizado, sem cortar o topo em tela baixa. */
#modalVideo {
    align-items: flex-start;
    justify-content: center;
    overflow-y: auto;
    padding: 12px 10px;
}

#modalVideo .modal-content {
    margin: auto;
}

/* 5. Botão branco do bloco de mentoria: texto sempre escuro, inclusive
      no tema escuro, onde --text é quase branco. */
.mentoria-destaque .btn-mentoria-destaque,
.mentoria-destaque .btn-mentoria-destaque *,
html.theme-dark .mentoria-destaque .btn-mentoria-destaque,
html.theme-dark .mentoria-destaque .btn-mentoria-destaque * {
    color: var(--brand-primary-darker, #213423) !important;
    -webkit-text-fill-color: var(--brand-primary-darker, #213423) !important;
}

/* =====================================================================
   Aceite da Política de Privacidade no primeiro acesso (06/08/2026)
   ---------------------------------------------------------------------
   Camada bloqueante mostrada depois do login enquanto o paciente não
   registrou o consentimento da versão vigente do texto (LGPD).
   Usa flex-start com margin auto pelo mesmo motivo do modal de vídeo:
   com align-items center o topo do cartão some em tela baixa.
   ===================================================================== */
.lgpd-overlay {
    position: fixed;
    inset: 0;
    z-index: 1400;
    background: rgba(15, 23, 42, 0.62);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    overflow-y: auto;
    padding: 16px 12px;
}

.lgpd-card {
    background: var(--card, #ffffff);
    color: var(--text, #0f172a);
    border-radius: 16px;
    width: 100%;
    max-width: 440px;
    margin: auto;
    padding: 22px 20px;
    box-shadow: 0 22px 64px rgba(0, 0, 0, 0.35);
}

.lgpd-card h2 {
    font-size: 18px;
    line-height: 1.3;
    margin: 0 0 10px;
    color: var(--text, #0f172a);
}

.lgpd-card p {
    font-size: 14px;
    line-height: 1.55;
    margin: 0 0 10px;
    color: var(--text-secondary, #475569);
}

.lgpd-card .lgpd-link {
    color: var(--brand-primary-darker, #213423);
    font-weight: 700;
    text-decoration: underline;
}

html.theme-dark .lgpd-card .lgpd-link {
    color: var(--brand-pastel, #86c98c);
}

.lgpd-acoes {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 18px;
}

.lgpd-btn {
    min-height: 46px;
    border-radius: 10px;
    font-weight: 700;
    font-size: 15px;
    border: none;
    cursor: pointer;
    padding: 0 14px;
}

.lgpd-btn-aceitar {
    background: var(--brand-primary, #3d6041);
    color: #ffffff;
}

.lgpd-btn-aceitar:disabled {
    opacity: 0.65;
    cursor: default;
}

.lgpd-btn-recusar {
    background: transparent;
    color: var(--text-secondary, #475569);
    border: 1px solid var(--border, #e2e8f0);
}

.lgpd-erro {
    margin: 12px 0 0;
    font-size: 13px;
    color: #991b1b;
    background: #fee2e2;
    border: 1px solid #fecaca;
    border-radius: 8px;
    padding: 9px 11px;
}

/* ============================================================
   2026-08-08: quebra de linha da mensagem do chat.

   A mensagem chega do servidor com paragrafos separados por linha
   em branco (conferido no banco: a mensagem 230 tem dois "\n\n"),
   mas a bolha nao declarava white-space, entao o HTML colapsava
   tudo e a paciente lia um bloco unico grudado.

   `pre-line` e o valor certo para chat: preserva a quebra de linha
   e continua colapsando espaco repetido e indentacao do fonte. O
   cartao de documentos e uma excecao: ali o conteudo e markup
   montado por JS, e a quebra do proprio fonte viraria linha vazia.
   ============================================================ */
.chat-msg { white-space: pre-line; }
.chat-msg.chatdoc-msg,
.chat-msg .chatdoc-card,
.chat-msg .chat-msg-author,
.chat-msg .time,
.chat-msg .chat-msg-time { white-space: normal; }

/* ============================================================
   DESKTOP (2026-08-11, auditoria de responsividade):
   1) Medida de leitura ESTRUTURAL: antes o cap de 760px era uma
      lista de 17 IDs enumerada a mao (app.css) e home, agenda,
      historico, fotos, treino, comunidade e artigos ficavam de
      fora, com cards de ~1.144px de largura. A regra estrutural
      cobre toda secao; o chat (grid proprio) fica isento.
   2) CTA nao ocupa a largura inteira com mouse.
   3) Sparkline de peso sem distorcao; fotos com miniatura util;
      listas densas em 2 colunas; balao de chat com medida.
   4) Sidebar recolhida: o guard anti-FOUC do index.html marca
      html.sidebar-is-collapsed, mas nenhum CSS consumia a classe
      e o menu saltava de 264px para 64px a cada F5. O botao
      voltar tambem acompanha o recolhimento.
   ============================================================ */
@media (min-width: 1024px) {
    .main-content .app-section .card {
        max-width: 760px;
        margin-left: auto;
        margin-right: auto;
    }
    #sec-chat .card,
    .chat-container .card {
        max-width: none;
        margin-left: 0;
        margin-right: 0;
    }

    .agenda-btn,
    .profile-btn,
    .orientacao-btn,
    .btn-servico,
    .clube-btn {
        width: auto;
        min-width: 180px;
    }

    .peso-sparkline-svg {
        max-width: 520px;
        height: 120px;
        margin-left: auto;
        margin-right: auto;
    }

    .chat-msg { max-width: min(85%, 62ch); }

    .docs-lista {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 10px;
    }
    .historico-grid {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 12px;
    }

    .foto-grid {
        grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    }

    html.sidebar-is-collapsed .app-sidebar { width: 64px; }
    html.sidebar-is-collapsed .app-wrapper { padding-left: 64px; }
    html.sidebar-is-collapsed .app-header { left: 64px; width: calc(100% - 64px); }
    html.sidebar-is-collapsed .page-back-btn { left: calc(64px + 28px); }
}

/* ============================================================
   TEMA (2026-08-11, auditoria modo escuro + modo claro):
   1) --brand-text: cor de TEXTO da marca que vira por tema. No
      claro e o verde escuro; no escuro e o pastel. Antes,
      color:var(--brand-primary-dark|darker) sem par dark dava
      contraste 1,4:1 a 1,9:1 sobre os cards escuros.
   2) --brand-tint vira no escuro (veu verde translucido): mata
      as "ilhas claras" (badge.green, stat-pro-icon, selo do
      guia) sem tocar em cada seletor.
   3) --surface passa a existir nos dois temas: era lido em
      regras criticas do claro e nunca foi definido (funcionava
      so pelo fallback).
   ============================================================ */
:root {
    --brand-text: var(--brand-primary-darker, #213423);
    --surface: #ffffff;
}
html.theme-dark {
    --brand-text: var(--brand-pastel, #86c98c);
    --brand-tint: rgba(61, 96, 65, 0.14);
    --brand-tint-soft: rgba(148, 163, 184, 0.10);
    --surface: var(--card, #1c2230);
}

/* Numeracao do detalhe de documento: verde escuro era invisivel no dark. */
html.theme-dark .doc-detail-num { color: var(--brand-pastel, #86c98c); }

/* Estrelas vazias do modal de sugestoes: #334155 sumia no fundo escuro. */
html.theme-dark .sug-stars i,
/* Estrelas vazias do modal de sugestoes: #334155 sumia no fundo escuro. */
html.theme-dark .sug-stars [data-lucide]{ color: var(--text-muted, #94a3b8); }

/* Botao "Entrar no Google Meet": o blanket do hero pintava texto branco em
   botao de fundo branco (invisivel NOS DOIS temas) e a lista de excecao
   antiga usava a classe errada (.vc-btn) e nao tinha important. O botao e
   branco sempre, entao o texto fica no verde escuro fixo da marca. */
body .videochamada-card .videochamada-btn,
body .videochamada-card .videochamada-btn * {
    color: var(--brand-primary-darker, #213423) !important;
    -webkit-text-fill-color: var(--brand-primary-darker, #213423) !important;
}

/* Rede de resgate de inline style: a familia Tailwind gray (usada em modais
   e strings de JS) nao constava das listas do app.css; no escuro dava 1,3:1
   a 1,8:1. Fundos claros cravados tambem viram superficies do tema. */
html.theme-dark .card [style*="color:#374151"],
html.theme-dark .modal-content [style*="color:#374151"] { color: var(--text) !important; }
html.theme-dark .card [style*="color:#4b5563"],
html.theme-dark .modal-content [style*="color:#4b5563"] { color: var(--text-secondary) !important; }
html.theme-dark .card [style*="color:#6b7280"],
html.theme-dark .modal-content [style*="color:#6b7280"],
html.theme-dark .card [style*="color:#9ca3af"],
html.theme-dark .modal-content [style*="color:#9ca3af"] { color: var(--text-muted) !important; }
html.theme-dark .card [style*="background:#e8f7ee"],
html.theme-dark .modal-content [style*="background:#e8f7ee"] { background: rgba(61, 96, 65, 0.16) !important; }
html.theme-dark .card [style*="background:#f1f5f9"],
html.theme-dark .modal-content [style*="background:#f1f5f9"],
html.theme-dark .card [style*="background:#f3f4f6"],
html.theme-dark .modal-content [style*="background:#f3f4f6"] { background: var(--bg-alt, #141824) !important; }

/* Cabecalho de tag vindo parseado do servidor (blocos): subtitulo discreto. */
.ref-tag-sub { font-style: italic; font-weight: 400; color: var(--text-muted, #64748b); }

/* Grafico de evolucao (Avaliacoes): o SVG tinha height fixo 170 + "meet",
   entao o desenho ficava travado em 320px boiando num card de 760px no
   desktop. height:auto deixa a altura seguir o viewBox e o desenho escala. */
@media (min-width: 1024px) {
    .grafico-evolucao-svg {
        max-width: 560px;
        height: auto;
        margin-left: auto;
        margin-right: auto;
    }
}

/* ==========================================================================
   2026-08-29 - Revisao ponta a ponta do app do paciente.
   Esta folha carrega DEPOIS de app.css, app-revisao.css e app-redesign.css
   (ordem declarada no index.html), entao vence por ordem de cascata.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1) Cabecalho, area de toque dos seis botoes.

   O que ja existia: app-redesign.css (bloco 9, de 12/06/2026) expande a area
   de toque com `.header-btn::after{top:-6px;right:-6px;bottom:-6px;left:-6px}`
   em ponteiro grosso. O comentario diz "sem mexer no layout", e no vertical
   isso e verdade. No horizontal nao e: os botoes do cabecalho sao VIZINHOS,
   separados por 2px (320px), 3px (360px) ou 4px (390-430px). Duas zonas de
   -6px se sobrepoem em 12px menos o espaco, e na faixa sobreposta quem recebe
   o toque e o IRMAO SEGUINTE, que vem depois na ordem do documento.

   Medido em 29/08/2026 (Playwright, varredura de elementFromPoint pixel a
   pixel a partir do centro, em 390x844): o sino `#btnNotificacoes` e pintado
   de x=118 a x=158, mas so recebe o toque de 113 a 156. Os dois ultimos
   pixels da coluna VISIVEL do sino abrem Mensagens. O mesmo vale para os
   cinco botoes que tem vizinho a direita.

   Correcao: a folga lateral do pseudo passa a ser METADE do espaco entre os
   botoes, entao as zonas encostam sem invadir. A folga vertical fica em -6px
   porque ali nao ha vizinho.
   -------------------------------------------------------------------------- */
@media (pointer: coarse) {
    .app-header .header-btn::after { left: -2px; right: -2px; }
}
@media (pointer: coarse) and (max-width: 380px) {
    .app-header .header-btn::after { left: -1.5px; right: -1.5px; }
}
@media (pointer: coarse) and (max-width: 340px) {
    .app-header .header-btn::after { left: -1px; right: -1px; }
}

/* Ate 340px a caixa pintada caia para 34x34 por causa de tres blocos com
   !important em app.css (@media 414px, 380px e 340px), que atropelam a
   correcao sem !important de app-revisao.css (@media pointer:coarse).
   Medido: area de toque exclusiva de 36x44, contra o minimo de 44x44 que o
   proprio portao da casa exige (apps/app-seunutricionista.json, nivel falha).
   Nesta largura a logomarca ja esta recolhida (largura medida = 0), entao a
   caixa real de 44px CABE: 6x44 + 5x2 = 274px dentro dos 296px livres.
   De 341px a 429px nao cabe (em 390px sobram 245px para 284px de necessidade)
   e a area util fica no maximo geometrico: 41px em 360px, 44px em 390-414px.
   O que resolve os 360px nao e CSS, e tirar um botao do cabecalho. */
@media (pointer: coarse) and (max-width: 340px) {
    .app-header .header-btn {
        width: 44px !important;
        height: 44px !important;
        min-width: 44px !important;
        min-height: 44px !important;
        font-size: 15px !important;
    }
}

/* --------------------------------------------------------------------------
   2) Contraste. Razoes medidas em 29/08/2026 pelo algoritmo do WCAG 2.1
   (fundo efetivo resolvido subindo a arvore e compondo alfa), nos dois temas,
   nas 24 secoes do menu.
   -------------------------------------------------------------------------- */

/* Comunidade, "Denunciar": media 2,56:1 (#94a3b8 sobre #ffffff) com 10,5px,
   e a caixa inteira tinha 19,8px de altura, menos da metade do minimo.
   #64748b sobre #ffffff = 4,76:1. */
.cm-c-btn {
    color: #64748b;
    min-height: 44px;
    padding: 12px 8px;
    display: inline-flex;
    align-items: center;
}
html.theme-dark .cm-c-btn { color: #94a3b8; }

/* Comunidade, "Comentar": 40px de altura, 4px abaixo do minimo. */
.cm-abrir { min-height: 44px; }

/* Avaliacoes e Historico, etiqueta "Recente": #f7f5f0 sobre #609165 = 3,36:1
   com 10px. O creme vem de tw-app.css com !important e seletor mais especifico
   do que a correcao anterior de app-revisao.css, entao quem cede e o fundo. */
.aval-badge-latest,
.aval-timeline-data .aval-badge-latest,
.historico-badge-latest,
.historico-card-data .historico-badge-latest {
    background: #213423 !important;
}

/* Perfil, "Sair": 3,6:1 no tema claro e 3,89:1 no escuro (#ef4444). */
.profile-btn.logout { color: #b91c1c; }
html.theme-dark .profile-btn.logout { color: #f87171; }

/* Perfil, "Excluir minha conta": 3,29:1 no tema escuro (#dc2626 sobre #1c2230). */
html.theme-dark .profile-btn.danger-link {
    color: #f87171;
    border-color: rgba(248, 113, 113, .38);
}

/* Plano, "Orientacoes da nutri:": 2,27:1 no escuro (#b45309 sobre #433829). */
html.theme-dark .plano-orient-titulo,
html.theme-dark .plano-orient-titulo i,
html.theme-dark .plano-orient-titulo [data-lucide] {
    color: #fbbf24;
}

/* Inicio, "Ver todas as refeicoes do dia": 2,57:1 no escuro
   (#2f4a32 sobre #273339). */
html.theme-dark .plano-ver-todas { color: #86c98c; }

/* Agenda, aba inativa: 4,34:1 (#64748b sobre #f1f5f9). */
html:not(.theme-dark) .agenda-tab:not(.active) { color: #475569; }

/* --------------------------------------------------------------------------
   3) Aviso de instalacao do iPhone: o "x" de fechar media 32x32 e e o unico
   controle daquele aviso, que aparece para todo paciente de iPhone que abre
   pelo Safari sem ter instalado.
   -------------------------------------------------------------------------- */
.ios-install-hint-close {
    min-width: 44px;
    min-height: 44px;
}

/* --------------------------------------------------------------------------
   4) Tela de acesso e consentimento de fotos: alvos abaixo de 44px.
   Medido em 29/08/2026 em 320, 390 e 430px, nos dois temas:
     .login-keep (o rotulo inteiro de "Continuar conectado", nao so a caixa
                  de marcar): 226,4 x 19,5
     .login-forgot ("Esqueci a senha"):                        99,3 x 23,5
     .login-foot-help ("Falar com o suporte"):                145,2 x 19,5
     .foto-consent (autorizacao de uso das fotos):            328,0 x 37,1
   E a primeira tela que todo paciente ve, e os tres controles dela estavam
   abaixo do minimo. A caixa de marcar de 16px nao precisa crescer: quem
   recebe o toque e o <label> que a envolve.
   -------------------------------------------------------------------------- */
.login-options .login-keep,
.login-options .login-forgot,
.login-foot-help,
.foto-consent {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
}
.foto-consent { display: flex; }


/* ============================================================
   03/09/2026 (relato do teste): no MODO CLARO o (X) que fecha o modal
   "Sugestao" some. Medido no app.seunutricionista.com, tema claro:
     color            rgb(255,255,255)   branco
     background-color rgb(248,250,252)   quase branco
   ou seja, contraste de ~1,05:1.

   As duas metades vem de regras DIFERENTES do app.css, e cada uma esta
   certa sozinha:
     .sug-header .modal-close      { color: #fff !important }
        certo: o cabecalho da Sugestao e um gradiente verde escuro.
     html.theme-light .modal-close { background: var(--bg, #f8fafc) }
        certo para modal de cabecalho claro, e vence a regra acima porque
        tem um elemento a mais na conta de especificidade (0,2,1).
   Juntas produzem letra branca sobre fundo claro. O erro nao e a cor nem
   o fundo: e o fundo do TEMA alcancar um cabecalho que nao segue o tema.

   Aqui o cabecalho escuro passa a mandar nas duas propriedades, nos dois
   temas. Primeira tentativa foi `color: inherit`, que nao resolve: o
   .sug-header forca #fff, entao inherit devolvia branco de novo.
   ============================================================ */
html.theme-light .sug-header .modal-close,
html.theme-dark .sug-header .modal-close,
.sug-header .modal-close {
    color: #ffffff !important;
    background: rgba(255, 255, 255, 0.18) !important;
}
html.theme-light .sug-header .modal-close:hover,
html.theme-light .sug-header .modal-close:focus-visible,
html.theme-dark .sug-header .modal-close:hover,
html.theme-dark .sug-header .modal-close:focus-visible,
.sug-header .modal-close:hover,
.sug-header .modal-close:focus-visible {
    background: rgba(255, 255, 255, 0.32) !important;
}

/* ============================================================
   CABECALHO DE MODAL COM FAIXA COLORIDA: o titulo saia em ardosia
   Medido em 03/09/2026, modal "Fale conosco:" a 360x740, tema claro.

   O h3 do cabecalho tinha, ao mesmo tempo:
     color                    rgb(255,255,255)  branco
     -webkit-text-fill-color  rgb(30,41,59)     ardosia
   e o -webkit-text-fill-color e quem pinta: vence o color. Resultado
   medido sobre o gradiente da faixa: 2,1:1 com o verde antigo (#2f4a32)
   e 1,2:1 com o verde novo (#2f4a32), ou seja, o titulo desaparece.

   As duas metades vem de regras diferentes do app.css:
     .sug-header h3 { color: #fff !important }
        certo: a faixa e um gradiente verde escuro.
     html.theme-light body .modal-content .modal-header h3
        { -webkit-text-fill-color: var(--text, #0f172a) }
        guarda de legibilidade do tema claro, escrita para modal de fundo
        branco. Ela varre TODO h1..h5 de .modal-content, inclusive o que
        esta sobre faixa colorida.
   Ja existia guarda para esse caso, mas so para cabecalho com gradiente
   em atributo style INLINE (`.modal-header[style*=linear-gradient]`).
   O .sug-header e o .registrar-foto-header pintam a faixa por CLASSE, e
   por isso escapavam.

   Aqui as duas faixas de marca passam a mandar tambem no text-fill, nos
   dois temas. O !important e necessario: a regra concorrente tem
   especificidade (0,3,3) e ja vem de um arquivo anterior no bundle.
   O .glg-modal-header fica de fora de proposito: aquele cabecalho e
   claro, e o texto escuro dele esta certo.
   ============================================================ */
html body .modal-content .sug-header,
html body .modal-content .sug-header h3,
html body .modal-content .sug-header h3 i,
html body .modal-content .sug-header h3 [data-lucide],
html body .modal-content .registrar-foto-header,
html body .modal-content .registrar-foto-header h3,
html body .modal-content .registrar-foto-header h3 i,
html body .modal-content .registrar-foto-header h3 [data-lucide],
html body .sug-header,
html body .sug-header h3,
html body .registrar-foto-header,
html body .registrar-foto-header h3 {
    -webkit-text-fill-color: #ffffff !important;
    color: #ffffff !important;
}

/* ============================================================
   03/09/2026: bloco da META no cartao "Dados mais recentes".
   O calculo da meta existia no app desde sempre e NUNCA era exibido: a
   variavel com o texto ("3,2 kg acima") era montada e descartada, e o paciente
   nao via a meta em lugar nenhum daquele cartao. Agora ele ve a frase com a
   DIRECAO ("Faltam 3,2 kg para a meta de 65,0 kg"), que era a queixa do dono:
   numero solto nao diz se e para subir ou descer.
   ============================================================ */
.progresso-meta {
    margin-top: 12px;
    padding: 11px 13px;
    background: var(--surface, #ffffff);
    border: 1px solid var(--border, #e2e8f0);
    border-left: 3px solid #3d6041;
    border-radius: 10px;
}
.progresso-meta-txt {
    font-size: 13.5px;
    line-height: 1.45;
    color: var(--text, #334155);
}
.progresso-meta-txt i { color: #3d6041; margin-right: 6px; }
.progresso-meta-txt strong { color: #2f4a32; font-weight: 700; }
.progresso-meta-barra {
    margin-top: 8px;
    height: 6px;
    border-radius: 999px;
    background: #e2e8f0;
    overflow: hidden;
}
.progresso-meta-barra > span {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: linear-gradient(90deg, #3d6041, #86c98c);
}
.progresso-meta-pct {
    margin-top: 5px;
    font-size: 11.5px;
    color: var(--text-muted, #64748b);
}
/* Tema escuro: sem este par o cartao nasce branco dentro da tela escura, que e
   exatamente a classe de defeito relatada em "Ceia" e no numero do peso. */
html.theme-dark .progresso-meta { background: #1e293b; border-color: #334155; border-left-color: #86c98c; }
html.theme-dark .progresso-meta-txt { color: #e2e8f0; }
html.theme-dark .progresso-meta-txt i,
html.theme-dark .progresso-meta-txt strong { color: #86c98c; }
html.theme-dark .progresso-meta-barra { background: #334155; }
html.theme-dark .progresso-meta-pct { color: #94a3b8; }


/* ============================================================
   03/09/2026: contraste do TEMA ESCURO (relato do dono no celular).
   ------------------------------------------------------------
   Causa raiz medida, e nao a ocorrencia: o app tinha tokens de SUPERFÍCIE
   sendo usados como cor de TEXTO dentro de `html.theme-dark`.
     `--brand-tint` vale `#f1f5f9` no `:root` (claro), mas este arquivo o
     redefine no escuro para `rgba(61, 96, 65, .14)`, que é fundo, não letra.
     Quem escreveu `color: var(--brand-tint)` num bloco `html.theme-dark`
     ganhou letra quase transparente sobre fundo escuro. Foi assim que o nome
     da refeição ("Ceia", "Jantar") sumiu no cartão de próximas refeições da
     home: 1,08:1 medido, ou seja, invisível.
     `--brand-primary-dark` (#2f4a32) e `--brand-primary-darker` (#213423) são
     superfícies escuras da marca. Como letra sobre fundo escuro davam de
     1,48:1 ("Voltar") a 1,57:1 ("Ver todas").
   O par que faltava agora tem nome: no escuro a letra/realce da marca é o
   pastel `--brand-text`. Onde o pastel sozinho fica magro (número de 9,5px
   dentro de pílula translúcida), existe `--brand-text-strong`, um passo mais
   claro do MESMO matiz 163. Nenhum verde de matiz 95 a 148 entra aqui.
   As trocas de valor foram feitas na origem, em `css/app.css`. Aqui ficam só
   a definição dos tokens e as regras NOVAS que o app.css não tinha.
   ============================================================ */

/* Contrapartida clara de `--brand-text`: no tema claro a letra de realce da
   marca é a superfície escura, que é o inverso exato do tema escuro. Sem
   isto o token só existiria em metade do app e voltaria a nascer sem par. */
:root,
html.theme-light {
    --brand-text: var(--brand-primary-darker, #213423);
}
html.theme-dark {
    /* Um passo mais claro que o pastel, mesmo matiz 163: 6,8:1 sobre a pílula
       de `rgba(134, 201, 140, .22)`, contra 4,76:1 do pastel puro. Usado só
       onde a letra é pequena e o fundo já carrega o verde. */
    --brand-text-strong: #c3e7c7;
}

/* Cartão de hidratação: a linha de baixo ("/10 Copos", "Faltam 2400 mL") herda
   `--text-muted` do bloco `.water-row--bottom`. Sobre o véu azulado do cartão
   isso dava 3,75:1 no escuro e 4,20:1 no claro: reprova nos dois. O claro foi
   resolvido na origem (passou a `--text-secondary`); o escuro precisa de par
   próprio, porque `--text-secondary` do escuro ainda é o mesmo cinza. */
html.theme-dark .water-card--compact .water-row--bottom {
    color: #cbd5e1;
}
/* "Meta batida" usava `--brand-primary-dark`, que é superfície, não letra. */
html.theme-dark .water-card--compact .water-meta-ok {
    color: var(--brand-text, #86c98c);
}


/* ============================================================
   03/09/2026: grafico de evolucao do peso (cor cravada inline pelo JS).
   ------------------------------------------------------------
   É o MESMO "1,4" que o dono relatou, na outra tela onde ele aparece: em
   "Avaliações" a variação sai como `<span style="color:#3d6041">↓ 1,4 kg</span>`,
   escrita pelo `js/app.js`, e `#3d6041` é a superfície verde da marca. Sobre o
   cartão escuro (#1e293b) isso mede 1,86:1, ou seja, o número existe e não se lê.
   O estilo é inline e o JS não é meu nesta rodada, então o resgate segue a
   técnica que este arquivo já usa para a família cinza do Tailwind: seletor de
   atributo com `!important`, restrito às superfícies de tema (.card e
   .modal-content), para não alcançar bloco que de propósito é claro.
   Medido depois: 1,86 vira 7,71 (verde), 3,89 vira 5,29 (vermelho) e
   3,07 vira 5,71 (cinza neutro).
   ============================================================ */
html.theme-dark .card [style*="color:#3d6041"],
html.theme-dark .modal-content [style*="color:#3d6041"] {
    color: var(--brand-text, #86c98c) !important;
    -webkit-text-fill-color: var(--brand-text, #86c98c) !important;
}
html.theme-dark .card [style*="color:#ef4444"],
html.theme-dark .modal-content [style*="color:#ef4444"] {
    color: #f87171 !important;
    -webkit-text-fill-color: #f87171 !important;
}
html.theme-dark .card [style*="color:#64748b"],
html.theme-dark .modal-content [style*="color:#64748b"] {
    color: var(--text-muted, #94a3b8) !important;
    -webkit-text-fill-color: var(--text-muted, #94a3b8) !important;
}
/* O mesmo verde entra como atributo `fill` no texto do SVG do gráfico, e
   atributo de apresentação perde para CSS: aqui basta declarar `fill`. */
html.theme-dark .grafico-evolucao-svg text[fill="#3d6041"],
html.theme-dark .peso-sparkline-svg text[fill="#3d6041"] {
    fill: var(--brand-text, #86c98c);
}

/* ============================================================
   2026-09-07: alvos de toque, inputs de 16px, FAB e cabecalho (mobile)
   ------------------------------------------------------------
   Fica no FIM desta folha de proposito: css/app.css tem um bloco global com
   !important DEPOIS dos @media, que anula regra de mobile escrita antes dele.
   Esta folha carrega depois de app.css, entao o que esta aqui vence.
   Medido em 390x844 antes: 209 alvos abaixo de 44px em 24 secoes (cabecalho
   40x40, PDF/E-mail/Compartilhar 38px, "Ler artigo completo" 32px, link de
   mentorias 16px, "Excluir minha conta" 38px, "+250 mL" 32px) e o FAB do
   SeuCenoura (58px) por cima do botao E-mail na primeira dobra da home.
   ============================================================ */
/* Cabecalho: 44px de verdade (o ::after de -6px nao conta para leitor de tela
   nem para o portao, que mede o retangulo do proprio botao). */
.app-header .header-btn,
.top-header .header-btn { min-width: 44px !important; min-height: 44px !important; }
.app-header .header-brand { min-height: 44px; display: inline-flex; align-items: center; }
/* Acoes do plano, agenda e avaliacao: 40px viravam 38px com a borda. */
.agenda-btn, .aval-btn, .plano-acao-btn { min-height: 44px !important; }
/* Perfil: "Excluir minha conta" e o link do site. */
.profile-btn, .profile-btn.danger-link, .profile-btn.website-link { min-height: 44px; }
/* Mentorias: link em texto corrido de 16px de altura. */
#mentoriasContent .info-box a[href*="mentorias."], a.btn-mentoria { display: inline-flex; align-items: center; min-height: 44px; padding: 0 10px; margin: 2px 0; border: 1px solid rgba(61, 96, 65,.38); border-radius: 10px; font-weight: 600; text-decoration: none; }
/* Home: "Ver todas" das proximas refeicoes tinha 41px. */
.proximas-mini-link { min-height: 44px; }
/* Hidratacao compacta: "+ 250 mL" tinha 32px. */
.water-card--compact .water-btn--inline { min-height: 44px !important; padding-top: 8px; padding-bottom: 8px; }
/* Fotos de evolucao: a caixa de consentimento de 18px vira 24px dentro de um
   rotulo de 44px (o rotulo inteiro alterna a caixa). */
.foto-consent { min-height: 44px; align-items: center; gap: 12px; padding: 6px 0; cursor: pointer; }
.foto-consent input { width: 24px !important; height: 24px !important; margin-top: 0 !important; }
/* Barra lateral (desktop): "Recolher menu" 36px e o selo SeuSaude 28px. */
.sidebar-collapse-toggle { min-height: 44px; }
.sidebar-powered-link { min-height: 44px; padding: 8px 6px; }

/* Miniatura de video que caiu no placeholder da marca (404 no YouTube). */
.med-card-thumb img.med-card-thumb--placeholder { background: var(--brand-tint, #e8f7ee); }

@media (max-width: 1023px) {
    /* iOS da zoom automatico em campo com fonte menor que 16px. */
    .sc-input-bar input,
    .chat-search-input,
    .clube-busca input,
    .compras-busca input,
    .command-palette-input,
    .leitor-search input,
    .receitas-busca input,
    .app-section input[type="text"],
    .app-section input[type="search"],
    .app-section input[type="number"],
    .app-section input[type="email"],
    .app-section input[type="tel"],
    .app-section select,
    .app-section textarea { font-size: 16px !important; }

    /* FAB do SeuCenoura: 48px, colado ao canto e logo acima da barra inferior.
       Com 58px em right:16px ele cobria a ponta do botao E-mail da home. */
    .sc-fab {
        width: 48px !important;
        height: 48px !important;
        right: 10px !important;
        bottom: calc(var(--nav-height, 65px) + env(safe-area-inset-bottom, 0px) + 10px) !important;
    }
    .sc-fab-mascote { width: 36px !important; height: 36px !important; }
    /* 2026-09-18: a regra de respiro que vivia AQUI era INERTE e nunca valeu.
       Ela era `body.logged-in .main-content` (0,2,1) e disputava com
       `body:not(:has(#sec-chat.active)) .main-content { padding-bottom: 0 !important }`
       do app.css, que pesa (1,2,1): o `#sec-chat` dentro do `:has()` carrega
       peso de ID para fora do `:not()`. Com os dois `!important`, ganha a mais
       especifica, nao a ultima folha. Medido: padding-bottom computado = 0px,
       e o total da lista de compras (R$ 84,00) ficava 67px atras da barra em
       390px e 113px em 320px. O conserto foi feito na ORIGEM, no app.css, que
       agora usa `var(--respiro-fim)`. Nada entra aqui de novo: empilhar um
       terceiro `!important` esconderia a contradicao em vez de fecha-la. */

    /* Saudacao e data do cabecalho: ja escondidas para leitor de tela
       (aria-hidden) e sem uso visual no celular. */
    .header-greeting-hidden { display: none !important; }
}

/* ============================================================
   2026-09-07: conteudo nunca fica por baixo da barra lateral (desktop)
   ------------------------------------------------------------
   Na captura das 10:38 (1440x900, home) o heroi e o cartao de agua
   apareciam por baixo da aside de 280px: a geometria da captura bate com
   um padding-left do .app-wrapper em torno de 80px, que so existe no MEIO
   da transicao de .25s entre 280px e 64px (recolher/expandir o menu, ou o
   resize que a captura de pagina inteira dispara). Medido depois em 24
   secoes, com o menu aberto e recolhido: nenhum filho do main abaixo de
   280px/64px no estado final. A transicao do recuo do conteudo e do
   cabecalho sai (o recuo passa a ser imediato, sem estado intermediario);
   a barra lateral mantem a animacao de largura, por cima do conteudo
   (z-index 900), entao nao ha quadro em que o conteudo fique sob ela sem
   ela o cobrir por completo.
   ============================================================ */
@media (min-width: 1024px) {
    .app-wrapper { transition: none !important; }
    .app-header { transition: none !important; }
    .page-back-btn { transition: none !important; }
}

/* ============================================================
   2026-09-09: o botao "Voltar" flutuante nao tapa mais o texto ao rolar
   ------------------------------------------------------------
   O .page-back-btn e position:fixed no alto a esquerda. Ao ABRIR a tela ele
   nao atrapalha: body.has-back-btn ja reserva o espaco no .main-content. O
   problema aparece DEPOIS, quando a pessoa rola: o botao fica parado e o
   conteudo sobe por baixo dele.

   Medido em 09/09/2026 com a sessao de QA, nas 18 telas do menu Mais, em
   390x844: tapava texto em 5 delas. A pior era Meditacao, com 41% do titulo
   "Meditacao guiada para iniciantes" coberto; depois Treino (22% de "Treinos
   nos ultimos 7 dias"), Receitas (20%), Mentorias (20%) e Clube (14%).

   A correcao e a de aplicativo, nao a de esconder para sempre: o botao SAI ao
   rolar para baixo e VOLTA ao rolar para cima, que e quando a pessoa procura
   por ele. Perto do topo ele fica sempre visivel. A classe vem do
   js/back-btn-scroll (inline no index.html); se aquele script nao rodar, nada
   aqui se aplica e o botao continua exatamente como era.

   opacity + pointer-events, e nao display:none: display remove do fluxo de
   acessibilidade em cima de um foco que pode estar no botao, e o leitor de
   tela perde a referencia no meio do gesto.
   ============================================================ */
.page-back-btn {
    transition: opacity .18s ease, transform .18s ease;
}
body.back-btn-oculto .page-back-btn {
    opacity: 0;
    transform: translateY(-10px);
    pointer-events: none;
}
/* Quem pediu menos animacao nao ganha o deslize, so o sumico. */
@media (prefers-reduced-motion: reduce) {
    .page-back-btn { transition: opacity .01ms !important; }
    body.back-btn-oculto .page-back-btn { transform: none; }
}
/* No desktop a regra de 2026-09-07 zera a transicao do botao para evitar o
   quadro intermediario da barra lateral. Ela continua valendo, e por isso o
   sumico ali e seco: e o comportamento certo, porque no desktop a barra
   lateral ja da o caminho de volta. */

/* ============================================================
   2026-09-10: botoes "apagados" no celular (cartao 364) e contraste
   ------------------------------------------------------------
   A causa principal NAO estava no CSS: o enforceHeroTextColor (app.js)
   pintava inline, com !important, todo descendente de .app-header de
   branco, e o bloco que limpava a cor no tema claro so alcancava o filho
   direto do .header-btn. Os <path> dos icones Lucide (stroke=currentColor)
   ficavam brancos sobre o botao verde-claro: 1,17:1 medido nos quatro
   botoes do cabecalho (sino, chat, agua, WhatsApp), em todas as telas, no
   tema claro. Corrigido no app.js. O que fica aqui e o que era CSS mesmo,
   medido com Playwright em 390x844 e 360x800, nos dois temas.
   ============================================================ */

/* Cabecalho no tema escuro: o icone e o pastel da marca (era o que o JS
   fazia inline; agora e regra). O selo (.badge) tem cor propria. */
html.theme-dark .app-header .header-btn,
html.theme-dark .app-header .header-btn > i,
html.theme-dark .app-header .header-btn > [data-lucide],
html.theme-dark .app-header .header-btn > svg {
    color: var(--brand-pastel, #86c98c);
}

/* Estado vazio: a regra `.empty-state i { opacity:.55; color: brand }`
   e para o icone decorativo do vazio, mas alcancava o icone DENTRO do
   botao de acao ("Agendar horario no WhatsApp"): verde escuro a 55% sobre
   botao verde escuro, 1,27:1 no claro e 2,79:1 no escuro. */
.empty-state .empty-mascote-action i,
.empty-state .empty-mascote-action [data-lucide],
.empty-state .empty-mascote-action svg,
.empty-state a.btn i, .empty-state a.btn [data-lucide],
.empty-state button i, .empty-state button [data-lucide] {
    color: inherit !important;
    opacity: 1 !important;
}

/* Icones pintados com o verde da marca sobre cartao ESCURO (tema escuro):
   o token nao troca de tema, entao vira verde escuro sobre ardosia.
   Medido: "Mais opcoes" do perfil 1,19:1, voltar do chat 1,61:1, seta da
   linha do tempo das avaliacoes 2,02:1. --text-link e o token que ja
   troca (#2f4a32 claro / #86c98c escuro). */
html.theme-dark .profile-advanced > summary > i,
html.theme-dark .profile-advanced > summary > [data-lucide],
html.theme-dark .chat-header-back i,
html.theme-dark .chat-header-back [data-lucide],
html.theme-dark .aval-chevron,
html.theme-dark .aval-timeline-card .aval-chevron {
    color: var(--text-link, #86c98c) !important;
}

/* Ambar dos selos e do botao de indicacao: branco sobre o degrade
   #b45309 -> #d97706 media 3,98:1 (o lado claro, #d97706, da 3,2:1). O
   degrade desce um tom: o lado mais claro passa a ser #b45309 (5,02:1). */
.mentoria-badge,
.servico-badge,
.clube-promo-btn {
    background: linear-gradient(135deg, #92400e, #b45309) !important;
    color: #fff !important;
}

/* Texto ambar do convite do clube no tema escuro: #b45309 sobre o fundo
   marrom-escuro dava 3,22:1. */
html.theme-dark .clube-promo h3,
html.theme-dark .clube-promo p,
html:not(.theme-light) .clube-promo h3,
html:not(.theme-light) .clube-promo p {
    color: #fbbf24;
}
html.theme-light .clube-promo h3 { color: var(--text, #1e293b) !important; }
html.theme-light .clube-promo p { color: var(--text-secondary, #475569) !important; }

/* Botao "Avisar quando tiver live": branco sobre #25d366 -> #128c7e dava
   2,81:1. Verde WhatsApp escuro: o lado claro (#0f7c6e) mede 5,09:1. */
.lives-cta-btn {
    background: linear-gradient(135deg, #0f7c6e, #075e54) !important;
    color: #fff !important;
    box-shadow: 0 4px 14px rgba(7, 94, 84, .35) !important;
}

/* Data da proxima live: "SET" em 10px sobre vermelho #ef4444 dava 4,28:1
   (3,47:1 no escuro, onde a letra vem #e2e8f0). */
.lives-prox-data {
    background: linear-gradient(135deg, #dc2626, #b91c1c) !important;
    color: #fff !important;
}
.lives-prox-data .mes, .lives-prox-data .dia { color: #fff !important; }

/* Modal de notificacoes (medido em 10/09/2026 com o modal aberto):
   "Marcar todas como lidas" tinha 41px de altura e os dois filtros 36px
   (alvo minimo 44px, WCAG 2.5.5; os filtros ganharam min-height inline no
   notifications.js). O titulo de grupo (HOJE, ONTEM) em #64748b sobre
   #f1f5f9 media 4,34:1 no tema claro. */
#modalNotificacoes .modal-btn { min-height: 44px; }
html.theme-light .notif-group-title { color: #475569 !important; }

/* Modal "Registrar foto": o X do cabecalho media 40x40 (regra propria de
   .registrar-foto-header .modal-close); o minimo da casa e 44. O subtitulo
   "Jantar as 19:30" em #64748b sobre #f1f5f9 media 4,34:1 no tema claro. */
.registrar-foto-header .modal-close { width: 44px; height: 44px; min-width: 44px; min-height: 44px; }
html.theme-light .registrar-foto-sub { color: #475569; }
html.theme-light .notif-item .notif-meta { color: #475569 !important; }

/* ============================================================
   2026-09-10 (cartao 364, 2a rodada): a logomarca nao fica mais debaixo do
   primeiro botao do cabecalho no celular
   ------------------------------------------------------------
   Medido antes, com o botao de hidratacao visivel (6 acoes de 44px):
   sobreposicao de 77px em 320, 42px em 360, 35px em 390 e 13px em 412,
   nos dois temas. A conta nao fecha: 6 x 44px + 5 folgas = 279px, e em
   360px sobram 57px para uma marca de 2,96:1 de proporcao (ficaria com
   17px de altura). As regras antigas "resolviam" cortando a marca
   (overflow:hidden), e o corte e o que a paciente via ("seunutric").

   Saida sem encolher alvo: quando o botao de hidratacao esta visivel, a
   marca passa a ser o MONOGRAMA da propria logomarca (o tracado "Sn"),
   img/logo-marca-dark|white.{png,webp}, extraido do arquivo oficial por
   componente conexo (scripts na sessao de 10/09), sem avatar de inicial.
   A troca e por `content: url()` no <img>: o <picture> continua o mesmo e
   a marca inteira volta sozinha com 5 acoes, de 360 para cima.

   Em 320px nem a marca inteira com 5 acoes cabe (5 x 44 + 4 folgas =
   228px em 296px uteis deixam 62px, e a marca a 30px de altura pede
   89px): ali o monograma vale sempre, e o botao de tema sai do cabecalho
   quando a hidratacao esta visivel. Ele e um atalho puro: o tema tambem
   se troca em Perfil > Tema do app (Claro / Escuro / Auto). A hidratacao
   fica, porque carrega informacao (o percentual do dia).

   O botao de hidratacao nasce com display:none inline e o app.js limpa o
   inline (style.display = "") para mostrar: por isso a condicao e
   `:not([style*="none"])`. Navegador sem :has() (WebView < 105) cai no
   @supports not: monograma sempre em telas estreitas, que tambem nao
   sobrepoe nada.
   ============================================================ */
@media (max-width: 430px) {
    /* A marca e um link (site SeuNutricionista): com o monograma de 20px ela
       media 28x44. min-width de 44px mantem o alvo de toque; a conta continua
       fechando (em 360 com 6 acoes sobram 51px). */
    .app-header .header-brand {
        flex: 0 0 auto !important;
        overflow: visible !important;
        margin-left: 4px !important;
        min-width: 44px !important;
        justify-content: center;
    }
    body.sn-mobile-shell .app-header .header-content:has(#btnHeaderAgua:not([style*="none"])) .header-brand-light img {
        content: url("/img/logo-marca-dark.png");
    }
    body.sn-mobile-shell .app-header .header-content:has(#btnHeaderAgua:not([style*="none"])) .header-brand-dark img {
        content: url("/img/logo-marca-white.png");
    }
    body.sn-mobile-shell .app-header .header-content:has(#btnHeaderAgua:not([style*="none"])) .header-brand img {
        width: auto !important;
        height: 34px !important;
        max-width: 40px !important;
        max-height: 34px !important;
        object-fit: contain !important;
    }
    @supports not selector(:has(a)) {
        body.sn-mobile-shell .app-header .header-brand-light img { content: url("/img/logo-marca-dark.png"); }
        body.sn-mobile-shell .app-header .header-brand-dark img { content: url("/img/logo-marca-white.png"); }
        body.sn-mobile-shell .app-header .header-brand img { width: auto !important; height: 34px !important; max-width: 40px !important; max-height: 34px !important; object-fit: contain !important; }
    }
}
@media (max-width: 340px) {
    body.sn-mobile-shell .app-header .header-brand-light img { content: url("/img/logo-marca-dark.png"); }
    body.sn-mobile-shell .app-header .header-brand-dark img { content: url("/img/logo-marca-white.png"); }
    body.sn-mobile-shell .app-header .header-brand img { width: auto !important; height: 34px !important; max-width: 40px !important; max-height: 34px !important; object-fit: contain !important; }
    .app-header .header-content:has(#btnHeaderAgua:not([style*="none"])) #headerThemeToggle { display: none !important; }
    @supports not selector(:has(a)) {
        .app-header #headerThemeToggle { display: none !important; }
    }
}

/* Aviso "Ativar modo escuro?": os dois botoes tinham 36px de altura; alvo
   minimo da casa e 44px. */

/* 11/09/2026 (revisao, seunutri-css-02): o botao do hero AZUL ("Confirmar",
   "Abrir") era translucido (rgba(255,255,255,.2)) com texto branco sobre o
   degrade #0d6e8e -> #0a5670: 3,86:1 no claro e 3,53:1 no escuro (piso 4,5:1).
   A regra generica de app.css tem !important e vencia a da variante, que nao
   tinha. Botao branco solido com o azul escuro do proprio hero: 8,1:1 nos dois
   temas. O icone (SVG com stroke=currentColor) segue a mesma cor. */
body .home-hero-cta.variant-blue .home-hero-cta-btn {
    background: #ffffff !important;
    border-color: #ffffff !important;
}
/* 11/09/2026 (reverificacao seunutri-css-02): a regra de tw-app.css
   `.home-hero-cta-btn:not(.amber):not(.purple):not(.blue):not(.bg-white) *`
   tem especificidade (0,5,0) e vencia esta (0,3,1) no `color`: o texto ficava
   azul so pelo -webkit-text-fill-color, mas o SVG (stroke=currentColor) seguia
   branco sobre branco, 1,09:1. Seletor repetido para (0,6,1) e stroke/fill
   explicitos no SVG. Medido depois: texto 8,1:1 e icone 8,1:1 nos dois temas. */
body .home-hero-cta.variant-blue.variant-blue.variant-blue .home-hero-cta-btn.home-hero-cta-btn,
body .home-hero-cta.variant-blue.variant-blue.variant-blue .home-hero-cta-btn.home-hero-cta-btn * {
    color: #0a5670 !important;
    -webkit-text-fill-color: #0a5670 !important;
}
body .home-hero-cta.variant-blue .home-hero-cta-btn svg,
body .home-hero-cta.variant-blue .home-hero-cta-btn svg * {
    stroke: #0a5670 !important;
}
body .home-hero-cta.variant-blue .home-hero-cta-btn svg [fill]:not([fill="none"]) {
    fill: #0a5670 !important;
}

/* 11/09/2026 (revisao, seunutri-css-04): nota do Perfil quando a permissao de
   notificacao esta negada. Substitui um <button disabled> a 55% de opacidade
   (3,51:1): instrucao informativa nao e botao e nao pode nascer apagada. */
.profile-note {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 14px;
    border: 1px solid var(--border, #e2e8f0);
    border-radius: 12px;
    background: var(--card, #ffffff);
    color: var(--text, #1e293b);
    font-size: 13.5px;
    line-height: 1.5;
    opacity: 1;
}
.profile-note i,
.profile-note svg {
    flex: 0 0 auto;
    margin-top: 2px;
    color: var(--brand-primary-darker, #213423);
}
html.theme-dark .profile-note i,
html.theme-dark .profile-note svg {
    color: var(--text, #f1f5f9);
}

/* 11/09/2026: copia das regras do chat por classe (body.chat-ativo, marcada pelo js/chat-keyboard.js). Navegador sem :has() descarta a regra original inteira; sem esta copia o chat virava pagina comum e o teclado cobria o campo. */
body.chat-ativo .page-back-btn{
    display: none;
}
body.chat-ativo #sec-chat.app-section.active > .card{
    margin-top: 8px;
}
/* 4b. composer colado no rodape do thread */
body.chat-ativo .chat-thread .chat-input-area{
    bottom: 0;
    padding-bottom: max(12px, var(--safe-bottom, 0px));
}
/* Reserva no proprio .main-content, medida pela altura real da barra.
   O !important acompanha a regra anterior do app.css, que tambem usa. */
body.chat-ativo .main-content{
    padding-bottom: calc(var(--nav-height, 65px) + var(--safe-bottom, 0px) + 16px) !important;
}
/* area de mensagens sempre com altura util, mesmo em telas baixas */
body.chat-ativo .chat-thread .chat-messages{
    min-height: 96px;
}
/* 4c. com poucas mensagens elas descem ate encostar no composer, igual a
   qualquer chat de referencia; com muitas, o overflow-y:auto de sempre
   continua rolando normalmente.

   E `margin-top:auto` no primeiro filho, e NAO `justify-content:flex-end` no
   container: num container rolavel, o flex-end empurra o inicio do conteudo
   para FORA da area de rolagem quando a conversa passa da altura da tela, e o
   trecho que vazou fica inalcancavel (a rolagem nao chega ate ele). E o modo de
   falhar mais grave possivel aqui, porque so aparece em conversa LONGA, que e
   justamente a de quem usa o app, e o Safari do iOS e onde mais morde.
   Com a margem automatica o efeito visual e o mesmo na conversa curta e o
   comportamento volta ao normal assim que o conteudo passa da altura. */
body.chat-ativo .chat-thread .chat-messages > *:first-child{
    margin-top: auto;
}
/* excecao: tela SEM nenhuma mensagem ainda nao deve colar no composer, fica
   centralizada como qualquer estado vazio do app (empty-chat e o placeholder
   estatico do HTML antes do JS responder; empty-mascote e o que renderMensagens
   desenha quando a lista chega vazia). Margem automatica nos DOIS lados: o
   mesmo mecanismo do item acima, sem misturar com justify-content. */
body.chat-ativo .chat-thread .chat-messages > .empty-chat:first-child,
body.chat-ativo .chat-thread .chat-messages > .empty-mascote:first-child{
    margin-top: auto;
    margin-bottom: auto;
}
body.chat-ativo .chat-thread .chat-input-area{
        padding-top: 8px;
    }

/* ============================================================================
   2026-09-18 (pedido do dono): ULTIMA AVALIACAO no celular.
   "melhore a responsividade de layout de parametros, as caixas estao ocupando
    espaco excessivo; os botoes bioimpedancia, baixar pdf e enviar email devem
    ficar menores para ficar em uma linha so; anexos da avaliacao aparece os
    dados todos montados sem responsividade visual no mobile."
   Medido no Pixel 7 (390x844) com o Playwright do portao, antes e depois.
   ============================================================================ */

/* 1. Caixas de medida: grade que se ajusta. Quatro colunas fixas num telefone
      davam 66px por caixa, e o numero encostava no rotulo. Com minmax, duas
      medidas ficam numa linha confortavel e quatro viram 2x2 legivel. O JS ja
      nao desenha a caixa sem valor (ver _avalKpisHtml em js/app.js). */
/* !important porque app-revisao.css:1048 declara
   `.aval-kpis { grid-template-columns: repeat(4,1fr) !important }` FORA de
   @media, depois de app.css, que ja tentava 2 colunas dentro de
   `@media(max-width:560px)`. Entre dois !important de mesma especificidade
   vence o que vem por ultimo na ordem das folhas, entao a regra de celular do
   app.css estava morta e o telefone de 320px desenhava quatro colunas de
   62,5px. Medido com o Playwright do portao em 18/09/2026. */
.aval-hero .aval-kpis {
    display: grid !important;
    grid-template-columns: repeat(auto-fit, minmax(104px, 1fr)) !important;
    gap: 8px !important;
}
.aval-hero .aval-kpi { min-width: 0; }
.aval-hero .aval-kpi-valor { white-space: nowrap; }

/* 2. As tres acoes numa LINHA so, sempre. grid-auto-flow:column da uma coluna
      igual por botao, seja com dois botoes (sem bioimpedancia) ou tres, e
      nenhum deles quebra para a linha de baixo.
      A ALTURA continua em 44px de proposito: e o alvo de toque que o portao
      mede (WCAG 2.5.5) e que ja custou correcao aqui. "Menor" e na largura e no
      peso do texto, nao na area onde o dedo encosta. */
.aval-acoes {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 6px;
}
.aval-acoes .aval-btn {
    justify-content: center;
    min-width: 0;
    padding: 0 8px;
    font-size: 11px;
    gap: 5px;
}
.aval-acoes .aval-btn > span {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.aval-acoes .aval-btn i { flex: none; }

/* No CELULAR o icone sobe para cima do rotulo. Nao e enfeite: com icone e texto
   lado a lado, "Bioimpedância" precisa de 105px e a coluna tem 93px em 390px
   (72px em 320px), entao ou o texto era cortado no meio da palavra ou um dos
   botoes pulava para a linha de baixo. Empilhado, o rotulo usa a largura
   inteira da coluna: 66px de texto em 80px uteis, com folga ate em 320px.
   E o mesmo desenho da barra inferior do app, entao nao e um padrao novo.
   Medido em 320, 390 e 430px com o Playwright do portao. */
@media (max-width: 560px) {
    .aval-acoes .aval-btn {
        flex-direction: column;
        gap: 2px;
        padding: 4px 6px;
        font-size: 10.5px;
        line-height: 1.25;
    }
    .aval-acoes .aval-btn i { font-size: 13px; }
}

/* 3. Anexos: era uma fileira com estilo embutido, sem min-width:0 no nome do
      arquivo. Nome longo (o do exame costuma ser
      "bioimpedancia-2026-07-27-completa.pdf") empurrava os dois botoes para
      fora do cartao, e estilo embutido nao aceita @media: no celular nao havia
      como corrigir. Agora o nome trunca com reticencias e o titulo mostra o
      nome inteiro ao toque longo. */
.anx-bloco { margin-top: 10px; padding-top: 10px; border-top: 1px dashed #e2e8f0; }
.anx-titulo { font-size: 12px; font-weight: 600; color: #64748b; margin-bottom: 6px; }
/* 2026-09-18: a falha ao buscar os anexos era muda (o catch limpava o bloco).
   Agora ela aparece e pode ser repetida com um toque. 44px de altura porque
   a linha inteira e o alvo. */
.anx-falhou {
    display: flex;
    align-items: center;
    min-height: 44px;
    padding: 8px 10px;
    border: 1px dashed #b45309;
    border-radius: 10px;
    font-size: 12.5px;
    line-height: 1.4;
    color: #7c4708;          /* 6,4:1 sobre o branco do cartao */
    cursor: pointer;
}
html.theme-dark .anx-falhou { color: #fbbf24; border-color: #fbbf24; }
.anx-item {
    display: flex; align-items: center; gap: 8px;
    padding: 4px 0; font-size: 13px; min-width: 0;
}
.anx-item .anx-ico { flex: none; color: #3d6041; }
.anx-item .anx-nome {
    flex: 1 1 auto; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    color: #334155;
}
.anx-item .anx-acoes { flex: none; display: flex; gap: 6px; }
.anx-item .anx-btn {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 44px; min-height: 44px;
    background: #f1f5f9; color: #334155;
    border: none; border-radius: 8px;
    font-size: 13px; cursor: pointer; text-decoration: none;
    transition: background 0.15s ease;
}
.anx-item .anx-btn:hover { background: #e2e8f0; }
.anx-item .anx-btn:focus-visible { outline: 2px solid #3d6041; outline-offset: 2px; }

/* 4. "Parametros": o titulo da secao saia em rgb(247,245,240) sobre branco,
      1,04:1 medido no pixel renderizado (Pixel 7, 18/09/2026). Na pratica a
      palavra nao existia na tela: o paciente via a tabela comecar sozinha.
      A regra de origem e `.av-sec-titulo{color:var(--brand-text,#86c98c)}` em
      app.css: o token --brand-text vale um quase-branco (e cor de texto SOBRE
      fundo escuro), e aqui o fundo e branco. Verde escuro da casa: 12,2:1. */
.av-sec-titulo { color: #2f4a32 !important; }

/* ============================================================
   2026-09-18: exame de bioimpedancia que nao carrega
   ------------------------------------------------------------
   O modal tinha estado de erro, mas ele dizia so "Imagem
   indisponivel" em #94a3b8 sobre o branco do cartao: 2,6:1
   medido, reprovado no AA. Pior: nao dizia o que a pessoa faz
   depois, e o arquivo some por motivo do servidor, nunca por
   culpa de quem esta lendo. Agora a mensagem nomeia a causa e
   da a saida, com alvo de toque de 44px.
   ============================================================ */
.bio-erro {
    padding: 24px 20px;
    text-align: center;
    color: #2f4a32;
}
.bio-erro-ico {
    font-size: 26px;
    color: #b45309;          /* 4,6:1 sobre branco */
    margin-bottom: 10px;
    display: block;
}
/* O peso dos dois seletores abaixo nao e enfeite. Medido por CDP: dentro do
   modal quem pinta paragrafo e
   `html.theme-light body .modal-content p` (0,2,3), que traz --text-muted.
   `.bio-erro-tit` sozinho pesa (0,1,0) e perdia em silencio: a regra ficava
   escrita no arquivo e a cor na tela era outra. Estes nascem em (0,3,3), acima
   da concorrente, em vez de empatar e depender da ordem das folhas. */
html body .modal-content .bio-erro p.bio-erro-tit {
    margin: 0 0 6px;
    font-size: 15px;
    font-weight: 700;
    color: #2f4a32;          /* 12,2:1 sobre branco */
}
html body .modal-content .bio-erro p.bio-erro-txt {
    margin: 0 auto 16px;
    max-width: 34ch;
    font-size: 13.5px;
    line-height: 1.5;
    color: #475569;          /* 7,5:1 sobre branco */
}
.bio-erro-btn {
    min-height: 44px;        /* alvo de toque: o portao mede isto */
    padding: 0 20px;
    border: 0;
    border-radius: 10px;
    background: var(--brand-primary, #3d6041);
    color: #fff;
    font-family: inherit;
    font-size: 14px;
    font-weight: 700;
    cursor: pointer;
}
.bio-erro-btn:focus-visible,
.bio-erro-btn:hover { background: var(--brand-primary-dark, #2f4a32); }
html.theme-dark body .modal-content .bio-erro,
html.theme-dark body .modal-content .bio-erro p.bio-erro-tit { color: #e2e8f0; }
html.theme-dark body .modal-content .bio-erro p.bio-erro-txt { color: #cbd5e1; }
html.theme-dark .bio-erro-ico { color: #fbbf24; }

/* ============================================================
   2026-09-18: faixa que rola para o lado avisa que rola
   ------------------------------------------------------------
   Quem marca as classes e o script no fim do index.html. A
   mascara desbota so a borda em que ainda ha conteudo, entao
   ao chegar ao fim a ultima aba aparece inteira. Nada de
   sombra sobreposta: mascara nao precisa saber a cor do fundo
   e funciona igual no tema claro e no escuro.
   ============================================================ */
.js-rolador.rol-mais-dir {
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 34px), transparent 100%);
            mask-image: linear-gradient(to right, #000 calc(100% - 34px), transparent 100%);
}
.js-rolador.rol-mais-esq {
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 34px);
            mask-image: linear-gradient(to right, transparent 0, #000 34px);
}
.js-rolador.rol-mais-esq.rol-mais-dir {
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 34px, #000 calc(100% - 34px), transparent 100%);
            mask-image: linear-gradient(to right, transparent 0, #000 34px, #000 calc(100% - 34px), transparent 100%);
}

/* ============================================================
   2026-09-27: responsividade do app do paciente (pedido do dono:
   "revise a responsividade de layout no app para não bagunçar").
   Medição antes e depois, item por item, em
   erp/_audit/app-responsividade-2026-09-27 (RELATORIO.md, Top 15,
   e consertos-antes.txt x consertos-depois.txt).
   Só o SeuNutricionista lê este bloco: o SeuCenoura carrega a cópia
   gerada em css/sc/gerado e só o recebe quando alguém rodar
   scripts/gerar-camada-sc.php (e subir o sw-sc.js junto).
   ============================================================ */

/* Item 4: o respiro do conteúdo é calculado por --header-height, mas o
   cabeçalho real mede 73 px de 768 a 1023 e 81 px de 1024 em diante
   (padding de 14 e 18 px mais os botões de 44). Com os 60 px de antes o
   topo do Início nascia 1 px (768) e 9 px (1024 a 1920) embaixo do
   cabeçalho, e o cartão do chat 4 px. Celular deitado (altura até 460 px)
   fica de fora: lá o cabeçalho encolhe e a regra de paisagem acima manda.
   O Voltar flutuante passa a seguir a mesma medida, 8 px abaixo dela. */
@media (min-width: 768px) and (max-width: 1023px) and (min-height: 461px) {
    :root { --header-height: 73px; }
}
@media (min-width: 1024px) {
    :root { --header-height: 81px; }
}
@media (min-width: 768px) and (min-height: 461px) {
    .page-back-btn { top: calc(var(--header-height) + var(--safe-top, 0px) + 8px); }
}

/* Item 3: uma largura de conteúdo por tela no desktop. Antes os cartões e
   os heróis ficavam presos em 760 px (860 a partir de 1600) enquanto listas
   e grades iam até a largura inteira: 2 ou 3 larguras empilhadas na mesma
   tela em 9 telas (Receitas com os filtros num quadro de 760 px rolando de
   lado e a grade embaixo com 1368 px). Agora todo bloco ocupa a largura do
   .main-content (1054 px em 1366, 1368 px em 1920) e quem usa o espaço é a
   grade de cada tela. O Perfil mantém a coluna própria de 760 px (tela de
   formulário, uma largura só) e o chat o layout próprio. */
@media (min-width: 1024px) {
    .main-content .app-section .card,
    #alertasContent .card, #avaliacoesCompContent .card, #avaliacoesContent .card, #clubeContent .card,
    #cogContent .card, #comprasContent .card, #docsContent .card, #formulariosContent .card,
    #leitorContent .card, #livesContent .card, #meditacaoContent .card, #mentoriasContent .card,
    #orientacoesContent .card, #planosContent .card, #receitasContent .card, #servicosContent .card,
    .aval-hero, .avalcomp-hero, .calc-hero, .cog-hero, .compras-hero, .forms-hero,
    .historico-hero, .leitor-hero, .lives-hero, .med-hero, .rec-hero,
    #planosContent .dias-tabs {
        max-width: none;
    }
}

/* Item 5: menu lateral do desktop. Eram 24 links em linhas de 44 px e só 9
   apareciam em 1366x768 (Perfil e Sair só rolando). Agora: marca e rodapé
   mais baixos, linha de 36 px com mouse (com dedo continua 44), grupos que
   recolhem (js/app.js, _montarGruposMenuLateral: fecha de baixo para cima
   até caber, a menos que a pessoa já tenha escolhido) e o grupo de Perfil,
   Sugestão e Sair preso no pé do menu, visível mesmo quando o menu rola.
   O item da tela aberta aparece mesmo com o grupo dele fechado. No modo
   recolhido (só ícones) nada some. */
@media (min-width: 1024px) {
    .app-sidebar .sidebar-brand { padding: 12px 16px 10px; gap: 10px; }
    .app-sidebar .sidebar-mascote { width: 36px; }
    .app-sidebar .sidebar-nav { padding: 8px 10px; }
    .app-sidebar .sidebar-group { margin-bottom: 2px; }
    .app-sidebar .sidebar-group-title:has(.sidebar-group-toggle) { padding: 0; }
    .sidebar-group-toggle {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 8px;
        width: 100%;
        min-height: 44px;
        padding: 6px 12px;
        margin: 0;
        background: none;
        border: 0;
        border-radius: 8px;
        color: inherit;
        font: inherit;
        letter-spacing: inherit;
        text-transform: inherit;
        text-align: left;
        cursor: pointer;
    }
    .sidebar-group-toggle::after {
        content: "";
        flex: 0 0 auto;
        width: 6px;
        height: 6px;
        margin-right: 2px;
        border-right: 1.5px solid currentColor;
        border-bottom: 1.5px solid currentColor;
        transform: translateY(-2px) rotate(45deg);
        transition: transform .15s ease;
    }
    .sidebar-group.is-fechado .sidebar-group-toggle::after { transform: rotate(-45deg); }
    .sidebar-group-toggle:hover { background: var(--bg-alt, #f1f5f9); color: var(--text, #0f172a); }
    .sidebar-group-toggle:focus-visible { outline: 2px solid var(--brand-primary-dark, #2f4a32); outline-offset: -2px; }
    .app-sidebar:not(.collapsed) .sidebar-group.is-fechado > .sidebar-link:not(.active) { display: none; }
    .app-sidebar:not(.collapsed) .sidebar-group-bottom {
        position: sticky;
        bottom: -8px;
        z-index: 1;
        margin-bottom: -8px;
        padding-bottom: 8px;
        background: #0f172a;
    }
    html.theme-light .app-sidebar:not(.collapsed) .sidebar-group-bottom { background: var(--surface, #fff); }
    .app-sidebar .sidebar-collapse-toggle { margin: 6px 14px 0; }
    .app-sidebar .sidebar-footer { padding: 4px 20px; }
}
/* Com mouse a régua da casa para navegação densa é 36 a 40 px (css-pro, 0.2);
   com dedo (pointer: coarse, iPad deitado em 1024) tudo segue com 44. */
@media (min-width: 1024px) and (pointer: fine) {
    .app-sidebar .sidebar-link { min-height: 36px; padding-top: 7px; padding-bottom: 7px; margin-bottom: 0; }
    .sidebar-group-toggle { min-height: 36px; padding-top: 6px; padding-bottom: 6px; }
    .app-sidebar .sidebar-collapse-toggle { min-height: 36px; padding-top: 7px; padding-bottom: 7px; }
    .app-sidebar .sidebar-powered-link { min-height: 36px; padding-top: 2px; padding-bottom: 2px; }
}
@media (prefers-reduced-motion: reduce) {
    .sidebar-group-toggle::after { transition: none; }
}

/* Item 2: celular deitado e tela baixa (teclado aberto no Android encolhe a
   tela). Entre o cabeçalho e a barra inferior sobravam 234 px em 740x360;
   o cabeçalho do chat, a caixa de 80 px e a área de mensagens de no mínimo
   96 px não cabiam, a conversa virava uma faixa e em 320x300 o Enviar saía
   cortado pelo cartão. Na conversa com a tela baixa: a barra inferior sai
   (o chat tem o próprio Voltar, como já acontece com o teclado aberto), o
   campo começa com uma linha (44 px) e as folgas encolhem. */
/* Cada regra vem em par: a de :has(#sec-chat.active) pesa um id a mais que a
   da classe body.chat-ativo (cópia para navegador sem :has), e as originais
   acima existem nas duas formas. */
@media (max-height: 500px) and (max-width: 1023px) {
    html body.chat-ativo .bottom-nav,
    html body:has(#sec-chat.active) .bottom-nav { display: none; }
    html body.chat-ativo .main-content,
    html body:has(#sec-chat.active) .main-content { padding-bottom: calc(6px + var(--safe-bottom, 0px)) !important; }
    html body.chat-ativo #sec-chat.app-section.active > .card,
    html body:has(#sec-chat.active) #sec-chat.app-section.active > .card { margin-top: 4px; }
    html body #sec-chat > .card > .card-header { padding-top: 2px; padding-bottom: 2px; }
    html body #sec-chat > .card > .card-header h3 { font-size: 15px; }
    html body.chat-ativo .chat-thread .chat-messages,
    html body:has(#sec-chat.active) .chat-thread .chat-messages { min-height: 48px; }
    html body.chat-ativo .chat-thread .chat-input-area,
    html body:has(#sec-chat.active) .chat-thread .chat-input-area { padding-top: 6px; padding-bottom: max(6px, var(--safe-bottom, 0px)); }
    html body #sec-chat textarea.chat-input { min-height: 44px; max-height: 72px; padding-top: 10px; padding-bottom: 10px; }
}

/* Item 6: dias do plano em 320. A regra de celular zerava o mínimo de 44 px
   (7 botões de 39 px com letra de 9 a 10 px). Os sete cabem com 44 px sem
   rolar: até 360 px o trilho perde o vão entre os dias e ganha os 4 px de
   cada lado do respiro da página. */
@media (max-width: 480px) {
    .dia-tab { min-width: 44px; padding: 6px 4px; font-size: 12px; }
}
@media (max-width: 360px) {
    .dias-tabs { gap: 0; padding: 2px; margin-left: -4px; margin-right: -4px; }
    .dia-tab { flex: 1 0 44px; padding: 6px 2px; font-size: 11.5px; }
}

/* Item 8: botões de modal sem altura mínima mediam 40 a 42 px (Desmarcar,
   Voltar, Recusar e sair, Aceitar e continuar). */
.modal-btn { min-height: 44px; }

/* Item 9: títulos das lives cortados em duas linhas comiam justamente a parte
   que diferencia um vídeo do outro, e com três linhas ainda cortava um deles
   em 390, 412, 1024 e 1366. O título sai inteiro; o cartão cresce. */
.lives-card-body h4 { display: block; -webkit-line-clamp: unset; line-clamp: none; overflow: visible; }

/* Item 12: de 1024 em diante (iPad deitado tem toque) os campos caíam para
   14,5 px e o Safari dá zoom ao focar. Mesmo peso da regra que os encolhia. */
body .app-section input[type=date],
body .app-section input[type=email],
body .app-section input[type=number],
body .app-section input[type=password],
body .app-section input[type=search],
body .app-section input[type=tel],
body .app-section input[type=text],
body .app-section input[type=time],
body .app-section select,
body .app-section textarea { font-size: 16px; }

/* Item 13: a dica de primeiro uso "Deslize lateralmente..." aparecia no meio
   da gaveta Mais aberta (cobria o rótulo Clube) e por cima de modal. */
body:has(.mais-drawer.open) .swipe-hint,
body:has(.modal-overlay.active) .swipe-hint { display: none; }

/* 28/09/2026 (hidratação): o botão de somar um copo no cartão compacto herdava flex:1 da .water-btn
   (app-deferred.css) e esticava pela linha inteira no desktop (848 px em 1366, com a ponta sob o mascote
   flutuante). Fica com a largura do próprio texto, encostado à direita; no celular nada muda. */
.water-card--compact .water-btn--inline {
    flex: 0 0 auto;
    width: auto;
    margin-left: auto;
}

/* 29/09/2026 (quadro 8, revisão SEUNUTRI-L2): tablet em pé (601 a 1023 px), com a barra
   inferior ainda à vista. Medido em 768: o miolo do cabeçalho tinha 600 px (84 a 684) e o
   conteúdo 688 px (40 a 728), então logomarca e avatar não alinhavam com os cartões; e a
   barra inferior, com left 50% e right auto, encolhia ao próprio conteúdo (285 a 300 px,
   itens de 57 a 60 px, "Conversas" espremido). O miolo do cabeçalho passa a ter a largura
   útil do .main-content (max-width menos os 16 px de cada lado) e a barra ocupa a largura
   da tela menos 48 px, até 540, com os cinco itens de largura igual. Vale para os dois
   produtos (a camada do SeuCenoura é gerada desta folha). */
@media (min-width: 601px) and (max-width: 767px) {
    .app-header .header-content { max-width: 568px; }
}
@media (min-width: 768px) and (max-width: 899px) {
    .app-header .header-content { max-width: 688px; }
}
@media (min-width: 900px) and (max-width: 1023px) {
    .app-header .header-content { max-width: 828px; }
}
@media (min-width: 601px) and (max-width: 1023px) {
    .bottom-nav {
        left: 50% !important;
        right: auto !important;
        width: calc(100% - 48px);
        max-width: 540px;
        transform: translateX(-50%);
    }
    .bottom-nav .nav-item { flex: 1 1 0; min-width: 0; }
}

/* 29/09/2026: cabecalho mobile do paciente SN. O botao Voltar pertence ao
   cabecalho e nao cobre o conteudo; SC conserva sua interface dedicada. */
body.sn-mobile-shell .mobile-header-context{display:contents}
body.sn-mobile-shell .header-section-title{display:none}
@media(max-width:1023px){
  body.sn-mobile-shell.logged-in{padding-bottom:0}
  body.sn-mobile-shell .header-content{flex-wrap:nowrap;gap:8px}
  body.sn-mobile-shell .header-actions{flex:0 0 auto;gap:4px}
  body.sn-mobile-shell #btnChatHeader,body.sn-mobile-shell #btnHeaderAgua,body.sn-mobile-shell #headerWhatsApp,body.sn-mobile-shell #headerThemeToggle{display:none!important}
  body.sn-mobile-shell .mobile-header-context{display:none;align-items:center;gap:4px;flex:1;min-width:0}
  body.sn-mobile-shell.has-back-btn .mobile-header-context{display:flex}
  body.sn-mobile-shell.has-back-btn .header-brand{display:none}
  body.sn-mobile-shell .header-section-title{display:block;flex:1;min-width:0;margin:0;color:inherit;font-family:inherit;font-size:16px;font-weight:700;line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  body.sn-mobile-shell #pageBackBtn{position:static;display:inline-flex;flex:0 0 44px;align-items:center;justify-content:center;width:44px;height:44px;min-height:44px;margin:0;padding:0;z-index:auto;border:0;border-radius:12px;background:transparent;box-shadow:none;backdrop-filter:none;-webkit-backdrop-filter:none;color:inherit;opacity:1;transform:none;pointer-events:auto}
  body.sn-mobile-shell #pageBackBtn[hidden]{display:none}
  body.sn-mobile-shell #pageBackBtn span{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
  body.sn-mobile-shell.has-back-btn .main-content{padding-top:calc(var(--header-height) + var(--safe-top,0px) + var(--hero-top-gap,8px))}
  body.sn-mobile-shell .chat-header-back{display:none}
  body.sn-mobile-shell .sc-fab{display:none!important}
}

/* Mais dos aplicativos de paciente: paginas calculadas pelo tamanho real
   dos destinos, sem area rolavel nem truncamento de rotulos. */
body #maisDrawer.mais-paginado{padding:max(8px,env(safe-area-inset-top)) max(8px,env(safe-area-inset-right)) max(8px,env(safe-area-inset-bottom)) max(8px,env(safe-area-inset-left));box-sizing:border-box}
body #maisDrawer.mais-paginado[hidden]{display:none}
body #maisDrawer.mais-paginado .mais-sheet{display:flex;flex-direction:column;gap:8px;width:100%;max-width:680px;max-height:100%;margin:0;padding:12px;border-radius:20px;overflow:visible;box-sizing:border-box;transform:none;opacity:0;transition:opacity .15s ease}
body #maisDrawer.mais-paginado.open .mais-sheet{opacity:1}
body #maisDrawer.mais-paginado .mais-handle{display:none}
body #maisDrawer.mais-paginado .mais-header{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:44px;padding:0;border:0}
body #maisDrawer.mais-paginado .mais-header h3{display:block;margin:0;font-size:1rem;line-height:1.25;color:var(--text);overflow-wrap:break-word}
body #maisDrawer.mais-paginado .mais-close{flex:0 0 44px;width:44px;height:44px;min-width:44px;min-height:44px;margin:0}
body #maisDrawer.mais-paginado .mais-content{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;align-content:start;flex:none;min-height:0;margin:0;padding:0;overflow:visible;overscroll-behavior:contain}
body #maisDrawer.mais-paginado .mais-group,body #maisDrawer.mais-paginado .mais-grid{display:contents}
body #maisDrawer.mais-paginado .mais-group-title{display:none}
body #maisDrawer.mais-paginado .mais-item{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;min-width:44px;min-height:76px;margin:0;padding:6px 4px;border-radius:12px;box-sizing:border-box;overflow:visible}
body #maisDrawer.mais-paginado .mais-item[hidden],body #maisDrawer.mais-paginado .mais-item[data-mais-page-hidden]{display:none!important}
body #maisDrawer.mais-paginado .mais-item-icon{flex:0 0 28px;width:28px;height:28px;min-width:28px;border-radius:9px;font-size:16px}
body #maisDrawer.mais-paginado .mais-item-label{display:block;max-width:100%;font-size:.75rem;line-height:1.25;color:var(--text);overflow:visible;text-overflow:clip;white-space:normal;word-break:normal;overflow-wrap:break-word;hyphens:none;-webkit-line-clamp:unset;-webkit-box-orient:initial}
body #maisDrawer.mais-paginado .mais-pagination{display:flex;align-items:center;justify-content:space-between;gap:8px;flex:none;min-height:44px}
body #maisDrawer.mais-paginado .mais-pagination[hidden]{display:none}
body #maisDrawer.mais-paginado .mais-page-button{display:inline-flex;align-items:center;justify-content:center;flex:0 0 44px;min-width:44px;min-height:44px;width:44px;height:auto;line-height:1;padding:0;border:1px solid var(--border);border-radius:12px;background:var(--bg);color:var(--text);font:inherit;font-size:24px;cursor:pointer}
body #maisDrawer.mais-paginado .mais-page-button:disabled{opacity:.45;cursor:default}
body #maisDrawer.mais-paginado .mais-page-button:focus-visible,body #maisDrawer.mais-paginado .mais-item:focus-visible{outline:2px solid var(--brand-text,var(--brand-primary-dark));outline-offset:2px}
body #maisDrawer.mais-paginado #maisPageStatus{font-size:.8125rem;line-height:1.25;color:var(--text-secondary);text-align:center}
body #maisDrawer.mais-paginado.mais-compact .mais-item{flex-direction:row;min-height:44px;padding:4px;gap:4px}
body #maisDrawer.mais-paginado.mais-compact .mais-item-icon{display:none}
body #maisDrawer.mais-paginado.mais-short .mais-sheet{display:grid;grid-template-columns:44px minmax(0,1fr);gap:4px;padding:8px}
body #maisDrawer.mais-paginado.mais-short .mais-content{grid-column:1/-1;grid-row:1}
body #maisDrawer.mais-paginado.mais-short .mais-header{grid-column:1;grid-row:2}
body #maisDrawer.mais-paginado.mais-short .mais-header h3{display:none}
body #maisDrawer.mais-paginado.mais-short .mais-pagination{grid-column:2;grid-row:2}

/* =====================================================================
   12. Menu "Mais": a lista inteira volta a aparecer (01/10/2026)

   Na tarde de 30/09/2026 o painel ganhou faixa de categoria e paginacao:
   a pessoa escolhia 1 de 5 categorias e ainda paginava dentro dela, logo
   dos 23 destinos so 2 a 7 ficavam visiveis por vez. A faixa come 92px do
   painel (5 chips em 3 colunas) e o titulo do grupo outros 26px, que era
   justamente o espaco onde item aparecia. O PADROES.md (secao da dashboard)
   ja mandava o contrario: ate 1024px quem rola e a pagina, que e o gesto
   do aparelho; a regra de nao rolar e do desktop acima de 1024px.

   O conserto tira a classe mais-paginado do HTML. Com ela fora, toda a
   camada de paginacao (bloco 11 deste arquivo e mobile-review.css) fica
   inerte, atualizarPaginacaoMais() sai pelo early-return e o desenho base
   volta: painel de 92svh, os 5 grupos em sequencia, rolagem por toque
   (body.scroll-locked .mais-content ja garante touch-action: pan-y) e o
   tom de cor de cada grupo.

   O que fica MELHOR do que era antes de 30/09:
     a) o titulo do grupo aparece e e legivel (mais-paginado o escondia,
        e a base o deixava em 9,5px em caixa alta);
     b) o grupo Suporte ganha tom proprio (nasceu sem cor nenhuma);
     c) a rolagem do painel para no painel, sem empurrar a pagina atras.
   ===================================================================== */

/* a) Titulo do grupo legivel: 12px em caixa de frase. Em 9,5px com caixa
      alta e espacamento de 0,08em o rotulo competia com o proprio item. */
.mais-drawer .mais-group-title {
    margin: 0 0 8px;
    padding: 0 4px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0;
    line-height: 1.4;
    text-transform: none;
}

/* b) Tom do Suporte: o azul da familia semantica, no mesmo molde dos tres
      que ja existiam (ambar no dia a dia, indigo na clinica, neutro na
      conta). Sem isto o Suporte era o unico grupo sem identidade. */
.mais-group[data-tom="suporte"] .mais-group-title { color: #075985; }
.mais-drawer .mais-group[data-tom="suporte"] .mais-item-icon {
    background: #e0f2fe;
    color: #075985;
    border-color: #bae6fd;
}
html.theme-dark .mais-group[data-tom="suporte"] .mais-group-title { color: #7dd3fc; }
html.theme-dark .mais-drawer .mais-group[data-tom="suporte"] .mais-item-icon {
    background: rgba(125, 211, 252, .13);
    color: #7dd3fc;
    border-color: rgba(125, 211, 252, .28);
}

/* c) A rolagem do painel para no painel: sem isto, chegar ao fim da lista
      empurra a pagina que esta atras (scroll chaining). */
.mais-drawer .mais-content {
    overscroll-behavior: contain;
}

/* Respiro no fim da lista, para o ultimo grupo nao colar na borda. */
.mais-drawer .mais-group:last-child {
    margin-bottom: 4px;
}

/* 09/10/2026 (dono: "quando clica em Mais aparece uma linha na parte superior da lista de menu"):
   a alça cinza (.mais-handle) é desenho de folha que se arrasta, mas o menu Mais não tem arrastar em
   nenhum tamanho; no computador e no tablet ele abre como janela no centro e a alça ficava solta no
   topo. Fecha pelo X, pelo fundo e pelo Esc. */
#maisDrawer .mais-handle { display: none !important; }
/* Revisão de 09/10/2026: sem a alça, o X do cabeçalho encostava na borda de cima da folha (0 a 2 px, contra
   12 a 16 px à direita): o recuo de cima do cabeçalho contava com a alça acima dele. */
#maisDrawer:not(.mais-paginado) .mais-header { padding-top: 12px; }

/* ===== 16/10/2026 (revisao 3 do app, F4): correcoes novas entram aqui, no fim ===== */
/* F1-28 a F1-32: as estrelas da janela "Fale conosco" tinham 22 x 22 px de alvo. O icone continua com 22 px; a
   area de toque vai a 44 x 44 com o respiro em volta (o <i> vira <svg> pelo icon-bridge: o seletor pega os dois). */
#sugEstrelas > [data-v], #sugEstrelas > svg { box-sizing: content-box; width: 22px; height: 22px; padding: 11px; margin: 0; cursor: pointer; }
#sugEstrelas { gap: 0; }
/* F1-36: no chat, a marca no lugar do avatar de inicial (regra da casa: logomarca sempre). O fundo verde do
   circulo era para a letra; a marca vai sem fundo e inteira. */
.chat-msg-author img.chat-msg-marca, html.theme-dark .chat-msg-author img.chat-msg-marca { background: transparent; object-fit: contain; border-radius: 0; }

/* =====================================================================
   16/10/2026: tinta de icone no modo escuro (pedido do dono: icone escuro
   sobre fundo escuro). Causa medida por CDP: dezenas de regras pintam o
   icone com a tinta ESCURA da marca (--brand-primary-dark #2f4a32,
   --brand-primary-darker #213423, --accent, --brand-text), que e tinta
   para superficie clara; no escuro o par ficava por conta de override
   tela a tela, e quem nao tinha par sumia (h4 do card em Avaliacoes,
   1,86:1; selo de sequencia; chevron do comparativo, 3,75:1). Daqui em
   diante a tinta do icone no escuro e UM token: --icone-marca (tinta da
   marca sobre fundo escuro), --icone-neutro e --icone-forte. Regra nova
   de icone usa o token, nao a cor.
   ===================================================================== */
html.theme-dark {
  --icone-marca:  var(--brand-pastel, #86c98c);
  --icone-neutro: var(--text-muted, #94a3b8);
  --icone-forte:  var(--text, #f1f5f9);
  /* --brand-text e a tinta de titulo e icone de formularios: escura no claro, pastel no escuro. */
  --brand-text:   var(--brand-pastel, #86c98c);
}
html.theme-dark .card-header h3 i, html.theme-dark .card-header h3 [data-lucide],
html.theme-dark .card-body h4 i, html.theme-dark .card-body h4 [data-lucide],
html.theme-dark .card-body h3 i, html.theme-dark .card-body h3 [data-lucide],
html.theme-dark .progresso-streak i, html.theme-dark .progresso-streak [data-lucide],
html.theme-dark .refeicao-foto-btn.registrada i, html.theme-dark .refeicao-foto-btn.registrada [data-lucide],
html.theme-dark .av-legenda i, html.theme-dark .av-legenda [data-lucide],
html.theme-dark .profile-next-head i, html.theme-dark .profile-next-head [data-lucide],
html.theme-dark .profile-advanced > summary > i, html.theme-dark .profile-advanced > summary > [data-lucide],
html.theme-dark .orientacao-titulo i, html.theme-dark .orientacao-titulo [data-lucide],
html.theme-dark .orientacao-lista li i, html.theme-dark .orientacao-lista li [data-lucide],
html.theme-dark .orientacao-lista-bloco h4 i, html.theme-dark .orientacao-lista-bloco h4 [data-lucide],
html.theme-dark .mentoria-features li i, html.theme-dark .mentoria-features li [data-lucide],
html.theme-dark .servico-features li i, html.theme-dark .servico-features li [data-lucide],
html.theme-dark .clube-cat i, html.theme-dark .clube-cat [data-lucide],
html.theme-dark .clube-beneficios li i, html.theme-dark .clube-beneficios li [data-lucide],
html.theme-dark .clube-info-item i, html.theme-dark .clube-info-item [data-lucide],
html.theme-dark .clube-passo > i, html.theme-dark .clube-passo > [data-lucide],
html.theme-dark .forms-stat-icon,
html.theme-dark .forms-list-title i, html.theme-dark .forms-list-title [data-lucide],
html.theme-dark .rec-modal-meta i, html.theme-dark .rec-modal-meta [data-lucide],
html.theme-dark .rec-modal h4 i, html.theme-dark .rec-modal h4 [data-lucide],
html.theme-dark .lives-prox-info p i, html.theme-dark .lives-prox-info p [data-lucide],
html.theme-dark .sc-rodape i, html.theme-dark .sc-rodape [data-lucide],
html.theme-dark .calc-section-title i, html.theme-dark .calc-section-title [data-lucide],
html.theme-dark .aval-compare-head h4 i, html.theme-dark .aval-compare-head h4 [data-lucide],
html.theme-dark .aval-historico-titulo i, html.theme-dark .aval-historico-titulo [data-lucide],
html.theme-dark .header-mais-menu .header-btn > i:first-child,
html.theme-dark .header-mais-menu .header-btn > [data-lucide]:first-child,
html.theme-dark .spinner-marca, html.theme-dark .empty-state [data-lucide].spinner-marca,
html.theme-dark .command-palette-item-icon,
html.theme-dark .command-palette-item.is-active .command-palette-item-icon,
html.theme-dark .doc-icon,
html.theme-dark .historico-item-icon i, html.theme-dark .historico-item-icon [data-lucide],
html.theme-dark .tk-hist-ico {
  color: var(--icone-marca);
}
/* Icone que e so sinal (seta, chevron, lupa): neutro, nunca o cinza #64748b de 3,75:1. */
html.theme-dark .aval-compare-toggle i, html.theme-dark .aval-compare-toggle [data-lucide],
html.theme-dark .foto-preview i, html.theme-dark .foto-preview [data-lucide],
html.theme-dark .clube-busca i, html.theme-dark .clube-busca [data-lucide],
html.theme-dark .compras-busca i, html.theme-dark .compras-busca [data-lucide],
html.theme-dark .rec-busca i, html.theme-dark .rec-busca [data-lucide],
html.theme-dark .chat-sidebar-search i, html.theme-dark .chat-sidebar-search [data-lucide],
html.theme-dark .command-palette-search-icon,
html.theme-dark .gla-item-val i {
  color: var(--icone-neutro);
}
/* Chip de icone que no claro e tinta escura sobre tinta clara da marca (#e8f7ee): no escuro vira
   pastel sobre pastel translucido, o mesmo par do .tk-hist-dia. */
html.theme-dark .tk-hist-ico,
html.theme-dark .doc-icon,
html.theme-dark .historico-item-icon {
  background: rgba(134, 201, 140, .16);
}
/* Logomarca "Powered by" do rodape da barra lateral: a arte e tinta escura e sumia no escuro. */
html.theme-dark .sidebar-powered-logo {
  filter: brightness(0) invert(.82);
  opacity: .85;
}

/* =====================================================================
   26/10/2026: Av. Fisica Online no app (js/secoes/avfisica.js). Janela de tela cheia com 8 passos,
   cartao na Inicio (#atalhos, molde do cartao da glicose) e chamada no topo de Avaliacoes.
   Cor so por token: --brand-* da marca do inquilino e os tokens de superficie do app (--card, --bg,
   --text, --border), que ja viram no tema escuro. Os tokens --avf-* abaixo trocam nos dois gatilhos
   de tema escuro da casa (html.theme-dark e automatico sem .theme-light), declarados uma vez so.
   Campo com fonte de 16 px (sem zoom no iPhone), alvo de toque de 44 px, "?" de 16 px colado ao
   rotulo com area de toque de 44 px por ::before.
   ===================================================================== */
html {
    --avf-realce: var(--brand-primary, #3d6041);
    --avf-realce-escuro: var(--brand-primary-dark, #2f4a32);
    --avf-realce-mais-escuro: var(--brand-primary-darker, #213423);
    --avf-realce-fundo: var(--brand-tint, #f1f5f9);
    --avf-sobre-realce: #ffffff;
    --avf-ok-borda: var(--brand-pastel, #86c98c);
    --avf-erro: #b91c1c;
    --avf-erro-fundo: #fee2e2;
    --avf-erro-borda: #fca5a5;
    --avf-balao: var(--brand-primary-darker, #213423);
    --avf-veu: rgba(15, 23, 42, .55);
}
html.theme-dark {
    --avf-realce: var(--brand-pastel, #86c98c);
    --avf-realce-escuro: var(--brand-pastel, #86c98c);
    --avf-realce-mais-escuro: var(--brand-pastel, #86c98c);
    --avf-realce-fundo: rgba(134, 201, 140, .14);
    --avf-sobre-realce: #0f172a;
    --avf-ok-borda: var(--brand-pastel, #86c98c);
    --avf-erro: #fca5a5;
    --avf-erro-fundo: rgba(239, 68, 68, .16);
    --avf-erro-borda: #991b1b;
    --avf-balao: #334155;
    --avf-veu: rgba(0, 0, 0, .7);
}
@media (prefers-color-scheme: dark) {
    html:not(.theme-light) {
        --avf-realce: var(--brand-pastel, #86c98c);
        --avf-realce-escuro: var(--brand-pastel, #86c98c);
        --avf-realce-mais-escuro: var(--brand-pastel, #86c98c);
        --avf-realce-fundo: rgba(134, 201, 140, .14);
        --avf-sobre-realce: #0f172a;
        --avf-ok-borda: var(--brand-pastel, #86c98c);
        --avf-erro: #fca5a5;
        --avf-erro-fundo: rgba(239, 68, 68, .16);
        --avf-erro-borda: #991b1b;
        --avf-balao: #334155;
        --avf-veu: rgba(0, 0, 0, .7);
    }
}

/* Cartao da Inicio (#atalhos sai do hidden so para ele) */
#atalhos:not([hidden]) { display: block; }
.avf-home {
    display: flex; align-items: center; gap: 8px; margin: 14px 0 10px;
    padding: 6px 10px 6px 14px; border-radius: 14px;
    background: var(--card, #fff); border: 1px solid var(--border, #e2e8f0);
}
.avf-home-ico {
    flex: none; width: 44px; height: 44px; border-radius: 12px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--avf-realce-fundo); color: var(--avf-realce); font-size: 18px;
}
.avf-home-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.avf-home-txt strong { font-size: 14px; color: var(--text, #0f172a); }
.avf-home-txt span { font-size: 12.5px; color: var(--text-muted, #64748b); overflow-wrap: anywhere; }
.avf-home-btn {
    flex: none; min-height: 44px; padding: 0 14px; border-radius: 12px; cursor: pointer;
    border: 0; background: var(--avf-realce); color: var(--avf-sobre-realce);
    font-family: inherit; font-size: 13.5px; font-weight: 800;
}

/* Chamada no topo de Avaliacoes */
.avf-chamada {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 12px;
    padding: 12px 14px; border-radius: 14px;
    background: var(--card, #fff); border: 1px solid var(--border, #e2e8f0); border-left: 3px solid var(--avf-realce);
}
.avf-chamada-txt { flex: 1 1 200px; min-width: 0; font-size: 13px; line-height: 1.45; color: var(--text-secondary, #475569); }
.avf-chamada-txt strong { color: var(--text, #0f172a); }
.avf-chamada-btn {
    flex: 0 0 auto; min-height: 44px; padding: 0 16px; border-radius: 12px; border: 0;
    background: var(--avf-realce); color: var(--avf-sobre-realce);
    font-family: inherit; font-size: 13.5px; font-weight: 800; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
}
@media (max-width: 420px) { .avf-chamada-btn { width: 100%; } }

/* Janela */
.avf-janela {
    position: fixed; inset: 0; z-index: var(--z-modal, 900);
    display: flex; align-items: stretch; justify-content: center;
    background: var(--avf-veu);
}
.avf-janela[hidden] { display: none !important; }
.avf-painel {
    display: flex; flex-direction: column; width: 100%; max-width: 100%; height: 100%;
    background: var(--bg, #f8fafc); color: var(--text, #0f172a);
}
@media (min-width: 900px) {
    .avf-janela { padding: 24px; align-items: center; }
    .avf-painel { max-width: 760px; height: min(92vh, 980px); border-radius: 18px; overflow: hidden; box-shadow: 0 20px 60px rgba(0, 0, 0, .35); }
}
.avf-topo {
    display: flex; align-items: center; gap: 10px;
    padding: calc(10px + var(--safe-top, 0px)) 12px 10px;
    background: var(--card, #fff); border-bottom: 1px solid var(--border, #e2e8f0);
}
.avf-fechar {
    flex: none; width: 44px; height: 44px; border-radius: 12px; border: 0; background: transparent;
    color: var(--text-secondary, #475569); font-size: 18px; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
}
.avf-fechar:hover { background: var(--bg-alt, #f1f5f9); }
.avf-topo-txt { min-width: 0; flex: 1; }
.avf-titulo { margin: 0; font-size: 17px; font-weight: 800; line-height: 1.2; color: var(--text, #0f172a); }
.avf-sub { font-size: 12.5px; color: var(--text-muted, #64748b); margin-top: 2px; }
.avf-progresso { height: 4px; background: var(--border, #e2e8f0); }
.avf-progresso span { display: block; height: 100%; width: 0; background: var(--avf-realce); transition: width .25s ease; }
.avf-corpo {
    flex: 1 1 auto; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch;
    padding: 14px 16px 20px; overscroll-behavior: contain;
}
.avf-rodape {
    display: flex; gap: 10px; padding: 10px 16px calc(10px + var(--safe-bottom, 0px));
    background: var(--card, #fff); border-top: 1px solid var(--border, #e2e8f0);
}
.avf-rodape:empty { display: none; }
.avf-btn {
    flex: 1 1 0; min-height: 44px; padding: 0 16px; border-radius: 12px;
    font-family: inherit; font-size: 14px; font-weight: 800; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    border: 1px solid transparent;
}
.avf-btn--pri { background: var(--avf-realce); color: var(--avf-sobre-realce); }
.avf-btn--pri:disabled { opacity: .6; cursor: default; }
.avf-btn--sec { background: var(--card, #fff); color: var(--text, #0f172a); border-color: var(--border, #e2e8f0); }
.avf-bloco { max-width: 720px; margin: 0 auto; }
.avf-intro { margin: 0 0 14px; font-size: 13.5px; line-height: 1.5; color: var(--text-secondary, #475569); }
.avf-intro--fim { margin: 14px 0 0; }
.avf-nota {
    display: flex; gap: 10px; align-items: flex-start; margin: 0 0 14px; padding: 10px 12px; border-radius: 12px;
    background: var(--avf-realce-fundo); color: var(--text, #0f172a); font-size: 13px; line-height: 1.45;
}
.avf-nota i { margin-top: 2px; color: var(--avf-realce); }
.avf-aviso {
    display: flex; gap: 10px; align-items: flex-start; margin: 0 auto 14px; max-width: 720px;
    padding: 10px 12px; border-radius: 12px;
    background: var(--avf-erro-fundo); border: 1px solid var(--avf-erro-borda); color: var(--avf-erro);
    font-size: 13.5px; line-height: 1.45;
}
.avf-aviso i { margin-top: 2px; }

/* Campos */
.avf-grade { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px 12px; }
.avf-grade--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 359px) { .avf-grade, .avf-grade--2 { grid-template-columns: 1fr; } }
.avf-campo { min-width: 0; margin: 0 0 10px; }
.avf-grade .avf-campo { margin: 0; }
.avf-campo--largo { grid-column: 1 / -1; }
.avf-campo-rot { display: flex; align-items: center; gap: 6px; margin: 0 0 5px; flex-wrap: wrap; }
.avf-campo-rot label, .avf-rot-texto { font-size: 12.5px; font-weight: 700; color: var(--text-secondary, #475569); }
.avf-campo-rot b { color: var(--avf-erro); font-weight: 800; }
.avf-campo-ctl {
    display: flex; align-items: center; min-height: 44px; padding: 0 12px;
    border: 1px solid var(--border, #e2e8f0); border-radius: 12px; background: var(--card, #fff);
}
.avf-campo-ctl:focus-within { border-color: var(--avf-realce); box-shadow: 0 0 0 3px var(--avf-realce-fundo); }
.avf-campo-ctl input {
    flex: 1 1 auto; min-width: 0; width: 100%; min-height: 42px; border: 0; outline: 0; background: transparent;
    font-family: inherit; font-size: 16px; color: var(--text, #0f172a); font-variant-numeric: tabular-nums;
}
.avf-campo-ctl input[type="date"] { color-scheme: inherit; }
.avf-un { flex: none; font-size: 12.5px; font-weight: 700; color: var(--text-muted, #64748b); margin-left: 6px; }
.avf-textarea {
    width: 100%; min-height: 88px; padding: 10px 12px; resize: vertical;
    border: 1px solid var(--border, #e2e8f0); border-radius: 12px; background: var(--card, #fff);
    font-family: inherit; font-size: 16px; color: var(--text, #0f172a);
}
.avf-textarea:focus { outline: 0; border-color: var(--avf-realce); box-shadow: 0 0 0 3px var(--avf-realce-fundo); }
.avf-so-leitura {
    min-height: 44px; display: flex; align-items: center; padding: 0 12px; border-radius: 12px;
    background: var(--bg-alt, #f1f5f9); color: var(--text, #0f172a); font-size: 15px; overflow-wrap: anywhere;
}
.avf-campo-dica { margin-top: 5px; font-size: 12px; color: var(--text-muted, #64748b); line-height: 1.4; }
.avf-campo--erro .avf-campo-ctl { border-color: var(--avf-erro); }
.avf-campo-erro { margin-top: 5px; font-size: 12.5px; color: var(--avf-erro); line-height: 1.4; }
.avf-segmento { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.avf-seg {
    min-height: 44px; border-radius: 12px; border: 1px solid var(--border, #e2e8f0);
    background: var(--card, #fff); color: var(--text, #0f172a);
    font-family: inherit; font-size: 14px; font-weight: 700; cursor: pointer;
}
.avf-seg.is-ativo { background: var(--avf-realce); border-color: var(--avf-realce); color: var(--avf-sobre-realce); }

/* "?" de 16 px colado ao rotulo; a area de toque cresce por ::before sem inchar o visual */
.avf-ajuda {
    position: relative; flex: none; width: 16px; height: 16px; padding: 0; border-radius: 50%;
    border: 1.5px solid var(--avf-realce); background: transparent; color: var(--avf-realce);
    font-family: inherit; font-size: 10.5px; font-weight: 800; line-height: 1;
    display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
}
.avf-ajuda::before { content: ''; position: absolute; inset: -14px; }
.avf-ajuda[aria-expanded="true"] { background: var(--avf-realce); color: var(--avf-sobre-realce); }
.avf-ajuda-balao {
    flex: 1 0 100%; display: block; margin: 2px 0 4px; padding: 8px 10px; border-radius: 10px;
    background: var(--avf-balao); color: #ffffff; font-size: 12.5px; line-height: 1.45; font-weight: 500;
}
.avf-ajuda-balao[hidden] { display: none; }

/* IMC ao vivo */
.avf-imc {
    margin-top: 12px; padding: 12px 14px; border-radius: 12px;
    background: var(--card, #fff); border: 1px solid var(--border, #e2e8f0); border-left: 3px solid var(--avf-realce);
}
.avf-imc-vazio { font-size: 13px; color: var(--text-muted, #64748b); }
.avf-imc-topo { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.avf-imc-rot { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--avf-realce-mais-escuro); }
.avf-imc-val { font-size: 24px; font-weight: 800; color: var(--text, #0f172a); font-variant-numeric: tabular-nums; }
.avf-imc-cls { font-size: 13px; font-weight: 700; color: var(--avf-realce-escuro); }
.avf-imc-ref { margin-top: 4px; font-size: 12px; color: var(--text-muted, #64748b); line-height: 1.4; }

/* Grupos que recolhem (Mais medidas, Dobras, Composicao) */
.avf-grupo { margin-top: 12px; border: 1px solid var(--border, #e2e8f0); border-radius: 14px; background: var(--card, #fff); overflow: hidden; }
.avf-grupo-topo {
    display: flex; align-items: center; gap: 10px; width: 100%; min-height: 56px; padding: 10px 14px;
    border: 0; background: transparent; font-family: inherit; text-align: left; cursor: pointer; color: var(--text, #0f172a);
}
.avf-grupo-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.avf-grupo-txt strong { font-size: 14px; }
.avf-grupo-txt small { font-size: 12px; color: var(--text-muted, #64748b); line-height: 1.4; }
.avf-grupo-qtd {
    flex: none; min-width: 24px; height: 24px; padding: 0 8px; border-radius: 999px;
    background: var(--avf-realce-fundo); color: var(--avf-realce-escuro); font-size: 12px; font-weight: 800;
    display: inline-flex; align-items: center; justify-content: center;
}
.avf-grupo-seta { flex: none; color: var(--text-muted, #64748b); transition: transform .2s; }
.avf-grupo.is-aberto .avf-grupo-seta { transform: rotate(180deg); }
.avf-grupo-corpo { padding: 0 14px 14px; border-top: 1px solid var(--border, #e2e8f0); }
.avf-grupo-corpo[hidden] { display: none; }
.avf-grupo-ajuda { margin: 12px 0; font-size: 12.5px; color: var(--text-secondary, #475569); line-height: 1.45; }
.avf-grupo-corpo .avf-grade { margin-top: 12px; }

/* Fotos do corpo */
.avf-fotos { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.avf-foto {
    display: flex; flex-direction: column; gap: 8px; min-width: 0; padding: 10px; border-radius: 14px;
    background: var(--card, #fff); border: 1px solid var(--border, #e2e8f0);
}
.avf-foto.is-ok { border-color: var(--avf-ok-borda); }
.avf-foto-vazio {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
    width: 100%; aspect-ratio: 3 / 4; max-height: 260px; border-radius: 12px;
    border: 1.5px dashed var(--border, #e2e8f0); background: var(--bg-alt, #f1f5f9); color: var(--avf-realce);
    font-family: inherit; font-size: 12.5px; font-weight: 700; cursor: pointer;
}
.avf-foto-vazio i { font-size: 22px; }
.avf-foto-img { width: 100%; aspect-ratio: 3 / 4; max-height: 260px; object-fit: cover; border-radius: 12px; background: var(--bg-alt, #f1f5f9); display: block; }
.avf-foto-txt { display: flex; flex-direction: column; gap: 2px; }
.avf-foto-txt strong { font-size: 13.5px; color: var(--text, #0f172a); }
.avf-foto-txt small { font-size: 11.5px; color: var(--text-muted, #64748b); line-height: 1.4; }
.avf-foto-acoes { display: flex; gap: 8px; }
.avf-foto-acoes .avf-btn-mini { flex: 1; }
@media (max-width: 479px) {
    .avf-fotos { grid-template-columns: 1fr; }
    .avf-foto { flex-direction: row; flex-wrap: wrap; align-items: center; }
    .avf-foto-vazio, .avf-foto-img { width: 96px; flex: none; max-height: 128px; }
    .avf-foto-txt { flex: 1; min-width: 0; }
    .avf-foto-acoes { flex: 1 0 100%; }
}
.avf-btn-mini {
    min-height: 44px; padding: 0 14px; border-radius: 12px; white-space: nowrap;
    border: 1px solid var(--border, #e2e8f0); background: var(--card, #fff); color: var(--avf-realce-escuro);
    font-family: inherit; font-size: 13px; font-weight: 800; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
}
.avf-btn-mini--rm { color: var(--avf-erro); }
.avf-consent { margin-top: 14px; }

/* Anexos */
.avf-anexo { margin-top: 10px; padding: 12px 14px; border-radius: 14px; background: var(--card, #fff); border: 1px solid var(--border, #e2e8f0); }
.avf-anexo-topo { display: flex; align-items: center; gap: 10px; }
.avf-anexo-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.avf-anexo-txt strong { font-size: 14px; color: var(--text, #0f172a); }
.avf-anexo-txt small { font-size: 12px; color: var(--text-muted, #64748b); line-height: 1.4; }
.avf-anexo-lista { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.avf-anexo-lista li {
    display: flex; align-items: center; gap: 8px; min-height: 44px; padding: 4px 0 4px 10px; border-radius: 10px;
    background: var(--bg-alt, #f1f5f9); font-size: 13px; color: var(--text, #0f172a);
}
.avf-anexo-lista li > i { color: var(--avf-realce); flex: none; }
.avf-anexo-nome { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.avf-anexo-tam { flex: none; font-size: 12px; color: var(--text-muted, #64748b); }
.avf-anexo-rm { flex: none; width: 44px; height: 44px; border: 0; background: transparent; color: var(--text-muted, #64748b); font-size: 15px; cursor: pointer; border-radius: 10px; }
.avf-anexo-rm:hover { color: var(--avf-erro); }

/* Revisao */
.avf-rev { margin-top: 12px; padding: 12px 14px; border-radius: 14px; background: var(--card, #fff); border: 1px solid var(--border, #e2e8f0); }
.avf-rev-topo { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.avf-rev-topo h3 { margin: 0; font-size: 14px; font-weight: 800; color: var(--text, #0f172a); }
.avf-rev-lista { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 4px 16px; }
.avf-rev-lista li {
    display: flex; justify-content: space-between; gap: 10px; align-items: center; min-height: 28px;
    font-size: 13px; color: var(--text-secondary, #475569); border-bottom: 1px dashed var(--border, #e2e8f0);
}
.avf-rev-lista li b { color: var(--text, #0f172a); text-align: right; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.avf-rev-largo { grid-column: 1 / -1; }
.avf-rev-vazio { margin: 0; font-size: 13px; color: var(--text-muted, #64748b); }
.avf-falta { color: var(--avf-erro); font-style: normal; font-weight: 700; }
.avf-rev-fotos { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.avf-rev-fotos figure { margin: 0; }
.avf-rev-fotos img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; border-radius: 10px; display: block; background: var(--bg-alt, #f1f5f9); }
.avf-rev-fotos figcaption { margin-top: 4px; font-size: 11.5px; color: var(--text-muted, #64748b); text-align: center; }

/* Carregando, rascunho e sucesso */
.avf-carregando, .avf-sucesso, .avf-rascunho { text-align: center; padding: 28px 12px; }
.avf-carregando i { font-size: 28px; color: var(--avf-realce); }
.avf-carregando p { margin: 12px 0 0; color: var(--text-muted, #64748b); font-size: 14px; }
.avf-sucesso-ico, .avf-rascunho-ico {
    width: 64px; height: 64px; border-radius: 50%; margin-bottom: 12px;
    display: inline-flex; align-items: center; justify-content: center; font-size: 26px;
    background: var(--avf-realce-fundo); color: var(--avf-realce);
}
.avf-sucesso h3, .avf-rascunho h3 { margin: 0 0 8px; font-size: 20px; font-weight: 800; color: var(--text, #0f172a); }
.avf-sucesso p, .avf-rascunho p { margin: 0 auto; max-width: 460px; font-size: 14px; line-height: 1.5; color: var(--text-secondary, #475569); }
.avf-sucesso-lista { list-style: none; margin: 16px auto 0; padding: 0; max-width: 360px; text-align: left; display: flex; flex-direction: column; gap: 6px; }
.avf-sucesso-lista li { display: flex; align-items: center; gap: 10px; font-size: 13.5px; color: var(--text, #0f172a); }
.avf-sucesso-lista li i { color: var(--avf-realce); }
@media (prefers-reduced-motion: reduce) {
    .avf-progresso span, .avf-grupo-seta { transition: none; }
}

/* 26/10/2026: "Fotos do corpo" na lista de avaliacoes (anexos de pasta, categoria fotos_corpo, js/secoes/avaliacoes.js).
   Miniatura por fetch e objectURL (a entrega exige o Bearer). Botao inteiro e o alvo de toque. */
.anx-fotos { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; max-width: 420px; }
.anx-foto { display: flex; flex-direction: column; gap: 4px; min-width: 0; min-height: 44px; padding: 0; border: 0; background: transparent; font-family: inherit; cursor: pointer; text-align: center; }
.anx-foto img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; border-radius: 10px; background: var(--bg-alt, #f1f5f9); display: block; border: 1px solid var(--border, #e2e8f0); }
.anx-foto span { font-size: 11.5px; color: var(--text-muted, #64748b); }
.anx-foto.is-falhou img { opacity: .35; }
