/* Componentes reutilizáveis do Design System OdontoNet. Sem lógica clínica. */

/* ===================== Botões ===================== */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-4);
    font-family: inherit;
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-medium);
    line-height: 1;
    border-radius: var(--radius-md);
    border: 1px solid transparent;
    cursor: pointer;
    transition: background-color var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
    white-space: nowrap;
}

.btn-sm {
    padding: var(--space-1) var(--space-3);
    font-size: var(--font-size-sm);
}

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

    .btn-primary:hover:not(:disabled) {
        background: var(--color-primary-hover);
        border-color: var(--color-primary-hover);
    }

    .btn-primary:active:not(:disabled) {
        background: var(--color-primary-active);
        border-color: var(--color-primary-active);
    }

.btn-secondary {
    background: var(--color-surface);
    border-color: var(--color-border-strong);
    color: var(--color-text-primary);
}

    .btn-secondary:hover:not(:disabled) {
        background: var(--color-surface-alt);
    }

.btn-destructive {
    background: var(--color-error);
    border-color: var(--color-error);
    color: var(--color-text-inverse);
}

    .btn-destructive:hover:not(:disabled) {
        background: var(--color-error-hover);
        border-color: var(--color-error-hover);
    }

.btn-ghost {
    background: transparent;
    border-color: transparent;
    color: var(--color-primary);
}

    .btn-ghost:hover:not(:disabled) {
        background: var(--color-primary-soft);
    }

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

.btn-loading {
    color: transparent !important;
    pointer-events: none;
    position: relative;
}

    .btn-loading::after {
        content: "";
        position: absolute;
        width: 1rem;
        height: 1rem;
        border-radius: 50%;
        border: 2px solid rgba(255, 255, 255, 0.4);
        border-top-color: #fff;
        animation: ds-spin 0.6s linear infinite;
    }

.btn-secondary.btn-loading::after, .btn-ghost.btn-loading::after {
    border: 2px solid rgba(88, 75, 66, 0.25);
    border-top-color: var(--color-primary);
}

/* ===================== Spinner (uso avulso) ===================== */
.spinner {
    display: inline-block;
    width: 1.125rem;
    height: 1.125rem;
    border-radius: 50%;
    border: 2px solid var(--color-border-strong);
    border-top-color: var(--color-primary);
    animation: ds-spin 0.6s linear infinite;
}

@keyframes ds-spin {
    to {
        transform: rotate(360deg);
    }
}

/* ===================== Formulários ===================== */
.form-field {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    margin-bottom: var(--space-4);
}

.form-label {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--color-text-primary);
}

.form-label .required {
    color: var(--color-error);
    margin-left: 2px;
}

.form-control,
.form-select {
    width: 100%;
    padding: var(--space-2) var(--space-3);
    font-family: inherit;
    font-size: var(--font-size-base);
    color: var(--color-text-primary);
    background: var(--color-surface);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-md);
    transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

textarea.form-control {
    min-height: 6rem;
    resize: vertical;
}

.form-control:focus-visible,
.form-select:focus-visible {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-primary-soft);
}

.form-control::placeholder {
    color: var(--color-text-disabled);
}

.form-control:disabled,
.form-select:disabled {
    background: var(--color-surface-alt);
    color: var(--color-text-disabled);
    cursor: not-allowed;
}

.form-control[aria-invalid="true"],
.form-select[aria-invalid="true"] {
    border-color: var(--color-error);
}

    .form-control[aria-invalid="true"]:focus-visible {
        box-shadow: 0 0 0 3px var(--color-error-bg);
    }

.form-hint {
    font-size: var(--font-size-xs);
    color: var(--color-text-secondary);
}

.form-error {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    font-size: var(--font-size-xs);
    color: var(--color-error);
}

.form-check {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--font-size-base);
}

    .form-check input[type="checkbox"],
    .form-check input[type="radio"] {
        width: 1.05rem;
        height: 1.05rem;
        accent-color: var(--color-primary);
    }

/* ===================== Feedback: alerts ===================== */
.alert {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border: 1px solid;
    border-radius: var(--radius-md);
    font-size: var(--font-size-sm);
}

.alert-icon {
    flex-shrink: 0;
    width: 1.125rem;
    height: 1.125rem;
    margin-top: 1px;
}

.alert-content {
    flex: 1;
}

.alert-title {
    font-weight: var(--font-weight-semibold);
    margin-bottom: 2px;
}

.alert-success {
    background: var(--color-success-bg);
    border-color: var(--color-success-border);
    color: var(--color-success);
}

.alert-warning {
    background: var(--color-warning-bg);
    border-color: var(--color-warning-border);
    color: var(--color-warning);
}

.alert-error {
    background: var(--color-error-bg);
    border-color: var(--color-error-border);
    color: var(--color-error);
}

.alert-info {
    background: var(--color-info-bg);
    border-color: var(--color-info-border);
    color: var(--color-info);
}

/* ===================== Badges ===================== */
.badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: 2px var(--space-2);
    border-radius: var(--radius-pill);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    line-height: 1.5;
    border: 1px solid transparent;
}

.badge-neutral {
    background: var(--color-surface-alt);
    color: var(--color-text-secondary);
    border-color: var(--color-border);
}

.badge-success {
    background: var(--color-success-bg);
    color: var(--color-success);
    border-color: var(--color-success-border);
}

.badge-warning {
    background: var(--color-warning-bg);
    color: var(--color-warning);
    border-color: var(--color-warning-border);
}

.badge-error {
    background: var(--color-error-bg);
    color: var(--color-error);
    border-color: var(--color-error-border);
}

.badge-info {
    background: var(--color-info-bg);
    color: var(--color-info);
    border-color: var(--color-info-border);
}

/* ===================== Estrutura: card / panel / section / divider ===================== */
.card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    padding: var(--space-5);
}

.card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin-bottom: var(--space-4);
    padding-bottom: var(--space-3);
    border-bottom: 1px solid var(--color-border);
}

    .card-header h2, .card-header h3 {
        margin: 0;
    }

.panel {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--space-4);
}

.section + .section {
    margin-top: var(--space-7);
}

/* Pilha vertical de seções principais de uma página de cadastro/perfil (cards/panels que
   representam assuntos distintos, ex.: Dados cadastrais / Endereço / Documentos / Atendimentos).
   Não usar para linhas de campo dentro de um mesmo formulário nem para grids lado a lado — o
   espaçamento aqui é entre assuntos, não dentro de um assunto. */
.page-section-stack {
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
}

@media (max-width: 767.98px) {
    .page-section-stack {
        gap: var(--space-4);
    }
}

.divider {
    border: none;
    border-top: 1px solid var(--color-border);
    margin: var(--space-5) 0;
}

.page-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--space-4);
    margin-bottom: var(--space-6);
}

    .page-header h1 {
        margin: 0;
    }

    .page-header p {
        margin: var(--space-1) 0 0 0;
        color: var(--color-text-secondary);
    }

.page-header-actions {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
}

/* ===================== Dados: tabela ===================== */
.table-wrapper {
    overflow-x: auto;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    /* DEF-03: sem isto, o conteúdo intrínseco da tabela (mais largo que a wrapper em telas estreitas)
       ainda contribuía para document.documentElement.scrollWidth, mesmo a wrapper já clicando/rolando
       corretamente o próprio conteúdo (scrollWidth/clientWidth internos corretos, overflow-x:auto já
       funcionando) — abrindo uma barra de rolagem de página inteira sem cortar nada. `overflow-x:hidden`
       em qualquer ancestral, incluindo a própria wrapper, não resolve (testado e descartado); apenas
       `contain: paint` isola de fato o layout/pintura da wrapper do cálculo de overflow do documento raiz.
       Não têm elementos com position:fixed/absolute que precisem "escapar" desta caixa nesta ou em
       nenhuma outra página que reaproveita .table-wrapper (nenhum dropdown/tooltip posicionado fora do
       fluxo dentro de uma tabela); os `<dialog>` de resumo/histórico ficam fora da wrapper no DOM e,
       de qualquer forma, renderizam na top layer nativa do navegador, imune a `contain` de ancestrais. */
    contain: paint;
}

table.table {
    width: 100%;
    min-width: 32rem;
    border-collapse: collapse;
    font-size: var(--font-size-sm);
}

    table.table th {
        text-align: left;
        padding: var(--space-3) var(--space-4);
        background: var(--color-surface-alt);
        color: var(--color-text-secondary);
        font-weight: var(--font-weight-semibold);
        border-bottom: 1px solid var(--color-border);
        white-space: nowrap;
    }

    table.table td {
        padding: var(--space-3) var(--space-4);
        border-bottom: 1px solid var(--color-border);
        color: var(--color-text-primary);
    }

    table.table tbody tr:last-child td {
        border-bottom: none;
    }

    table.table tbody tr:hover {
        background: var(--color-surface-alt);
    }

/* Linha clicável (listagens de pacientes e, desde T10, procedimentos — mesmo padrão de UX):
   affordance discreta — só cor de fundo e cursor, sem transform/scale numa linha de tabela.
   ":focus-within" cobre a navegação por teclado (o link real do nome recebe foco, ":focus-visible"
   global já desenha o contorno em cima dele) sem precisar tornar a própria <tr> focável. */
table.table tbody tr.patient-row,
table.table tbody tr.procedure-row {
    cursor: pointer;
    transition: background-color var(--transition-fast);
}

    table.table tbody tr.patient-row:hover,
    table.table tbody tr.patient-row:focus-within,
    table.table tbody tr.procedure-row:hover,
    table.table tbody tr.procedure-row:focus-within {
        background: var(--color-surface-alt);
    }

    .patient-row-chevron {
        color: var(--color-text-secondary);
        width: 1.5rem;
    }

        .patient-row-chevron svg {
            width: 1rem;
            height: 1rem;
        }

/* ===================== Estado vazio ===================== */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--space-2);
    padding: var(--space-8) var(--space-5);
    color: var(--color-text-secondary);
}

    .empty-state svg {
        width: 40px;
        height: 40px;
        opacity: 0.55;
        margin-bottom: var(--space-2);
    }

    .empty-state h3 {
        color: var(--color-text-primary);
    }

/* ===================== Paginação (placeholder visual, sem lógica) ===================== */
.pagination {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-2);
    margin-top: var(--space-4);
}

    .pagination button {
        min-width: 2rem;
        height: 2rem;
        padding: 0 var(--space-2);
        border-radius: var(--radius-sm);
        border: 1px solid var(--color-border-strong);
        background: var(--color-surface);
        color: var(--color-text-primary);
        font-size: var(--font-size-sm);
        cursor: pointer;
    }

        .pagination button[aria-current="page"] {
            background: var(--color-primary);
            border-color: var(--color-primary);
            color: var(--color-primary-contrast);
        }

        .pagination button:disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }

/* ===================== Modal / diálogo ===================== */
dialog.ds-modal {
    border: none;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: var(--space-6);
    width: min(480px, calc(100vw - var(--space-6)));
    max-height: calc(100vh - var(--space-6));
    color: var(--color-text-primary);
}

    /* display:flex só qualificado por [open]: o <dialog> nativo já esconde a versão fechada via
       "display: none" da folha de estilo do navegador — sobrescrever "display" incondicionalmente
       aqui tornaria o modal sempre visível, mesmo fechado. */
    dialog.ds-modal[open] {
        display: flex;
        flex-direction: column;
    }

    dialog.ds-modal::backdrop {
        background: rgba(46, 36, 28, 0.5);
    }

/* Variante mais larga (T08): formulário de paciente tem campos demais para o modal padrão de
   480px — mesma linguagem visual, só a largura muda. */
dialog.ds-modal.ds-modal-wide {
    /* Ligeiramente mais largo que os 720px originais (T08): com os campos pareados em 2 colunas
       (refinamento de UX), um pouco mais de espaço evita que cada coluna fique apertada — ainda
       longe de tela cheia, e cai para a largura da viewport normalmente em telas menores. */
    width: min(800px, calc(100vw - var(--space-5)));
}

.ds-modal-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-3);
    margin-bottom: var(--space-4);
    flex-shrink: 0;
}

.ds-modal-body {
    overflow-y: auto;
    min-height: 0;
}

    .ds-modal-header h2 {
        margin: 0;
    }

/* Botão de fechar compartilhado por TODOS os modais (<dialog class="ds-modal">) — Patients,
   Procedures, Appointments e o componente Modal.razor do Design System usam exatamente este mesmo
   markup/classe (<button class="ds-modal-close" aria-label="Fechar"><Icon Name="close" /></button>),
   nunca uma versão própria por página. Bug real corrigido aqui (T11, achado transversal na validação
   manual): o "X" não aparecia em NENHUM modal — só o contorno do botão ficava visível. Causa raiz:
   o <svg> de Icon.razor não define width/height própria (só viewBox="0 0 24 24"), e nenhuma regra
   "<seletor> svg { width; height }" existia para ".ds-modal-close" (diferente de todo outro uso de
   <Icon> no projeto — compare com ".app-sidebar-link svg"/".empty-state svg"/
   ".dashboard-shortcut-link svg" logo abaixo/acima, cada um com sua própria regra de tamanho). Sem
   width/height explícitos, um elemento SVG substituído assume o tamanho intrínseco padrão do
   navegador (300×150px) — gigantesco e desproporcional dentro de um botão pequeno, efetivamente
   invisível/cortado. "font-size"/"line-height" no botão nunca afetariam isso: o conteúdo é um <svg>
   com stroke vetorial, não um caractere de texto/glifo de fonte — não há "caractere ausente" nem
   pseudo-elemento envolvido, e nenhum CSS de terceiros sobrescrevia nada aqui; a regra de tamanho do
   ícone simplesmente nunca existiu para este seletor. Corrigido com as mesmas duas peças que todo
   outro consumidor de <Icon> já usa: (1) tamanho explícito do <svg> interno; (2) o próprio botão
   correto para clique (Requisito de acessibilidade: rótulo acessível já correto, aria-label="Fechar"
   no <button>, nunca dependente do glifo visual — o <Icon> já é aria-hidden="true"/focusable="false").
   Área de clique de 2rem/32px (mesmo tamanho de ".app-header-menu-toggle") — confortável ao toque,
   maior que o antigo padding solto em torno de um ícone sem tamanho definido. */
.ds-modal-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    background: none;
    border: none;
    cursor: pointer;
    color: var(--color-text-secondary);
    padding: 0;
    border-radius: var(--radius-sm);
}

    .ds-modal-close svg {
        width: 1.25rem;
        height: 1.25rem;
        flex-shrink: 0;
    }

    .ds-modal-close:hover {
        background: var(--color-surface-alt);
        color: var(--color-text-primary);
    }

.ds-modal-footer {
    display: flex;
    /* DEF-04 (T18, checkpoint corretivo): sem a quebra de linha abaixo, ações que não cabem lado a
       lado em viewports estreitos (ex.: "Criar nova versão a partir desta" + "Fechar" em 390px)
       transbordavam sem reorganizar — como o container é alinhado por "justify-content: flex-end", o
       excesso "vazava" para fora do modal pela esquerda (não pela direita, onde seria ao menos
       visível/rolável), cortando texto sem nenhuma forma de acesso. Permitir quebra resolve
       reorganizando as ações em múltiplas linhas — cada uma continua alinhada à direita — sem afetar
       desktop/tablet, onde já cabem numa linha só. */
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--space-3);
    margin-top: var(--space-6);
    flex-shrink: 0;
    /* Suporte simples de "footer sticky" (T08, refinamento de UX): quando o formulário do modal
       precisa de scroll interno (".ds-modal-body"), Cancelar/Cadastrar continuam visíveis sem
       precisar rolar até o fim — CSS puro, sem JS. O padding negativo/positivo compensa o padding
       do próprio <dialog>, para o footer "colar" na borda inferior real do modal. */
    position: sticky;
    bottom: calc(-1 * var(--space-6));
    background: var(--color-surface);
    /* padding-bottom soma "env(safe-area-inset-bottom)" (DEF-04): em telas com barra de gestos/notch
       inferior (iOS), garante que os botões não fiquem colados/parcialmente sob a área do sistema. */
    padding: var(--space-4) 0 max(var(--space-6), env(safe-area-inset-bottom));
}

/* Divisor simples entre seções dentro de um ".ds-modal-body" (T11: separa a área de status dos
   campos de edição no modal de agendamento) — utilitário do Design System, não específico de
   Appointment; qualquer modal futuro com o mesmo tipo de seção pode reaproveitar. */
.ds-modal-divider {
    border: none;
    border-top: 1px solid var(--color-border);
    margin: var(--space-5) 0;
}

/* ===================== Dropdown (via <details>/<summary>, acessível sem JS) ===================== */
details.dropdown {
    position: relative;
    display: inline-block;
}

    details.dropdown > summary {
        list-style: none;
        cursor: pointer;
    }

        details.dropdown > summary::-webkit-details-marker {
            display: none;
        }

.dropdown-menu {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    min-width: 200px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    padding: var(--space-2);
    z-index: var(--z-dropdown);
}

.dropdown-item {
    display: block;
    width: 100%;
    text-align: left;
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
    color: var(--color-text-primary);
    background: none;
    border: none;
    cursor: pointer;
}

    .dropdown-item:hover {
        background: var(--color-surface-alt);
    }

/* ===================== Utilitários de layout genéricos ===================== */
/* Usados sobretudo pela página /design-system, mas são utilitários simples e reutilizáveis. */
.ds-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    align-items: center;
}

.ds-row-stretch {
    align-items: stretch;
}

.ds-stack {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.ds-form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: var(--space-4);
    margin-bottom: var(--space-4);
}

.ds-swatch-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: var(--space-4);
}

.ds-swatch {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.ds-swatch-color {
    height: 56px;
    border-radius: var(--radius-md);
}

.ds-swatch-bordered .ds-swatch-color {
    border: 1px solid var(--color-border);
}

.ds-swatch-label {
    font-size: var(--font-size-xs);
    color: var(--color-text-secondary);
}

/* ===================== Dashboard (T07) ===================== */
.dashboard-greeting {
    margin-bottom: var(--space-6);
}

.dashboard-greeting-name {
    margin: 0 0 var(--space-1);
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-medium);
    color: var(--color-text-primary);
}

.dashboard-quick-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
}

.dashboard-quick-action {
    gap: var(--space-2);
}

.dashboard-widgets {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: var(--space-5);
}

.dashboard-widget-body .empty-state {
    padding: var(--space-6) var(--space-4);
}

.dashboard-shortcuts-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: var(--space-3);
}

.dashboard-shortcut-link {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-4);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    color: var(--color-text-primary);
    text-align: center;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    transition: background-color var(--transition-fast), border-color var(--transition-fast);
}

    .dashboard-shortcut-link:hover {
        background: var(--color-surface-alt);
        border-color: var(--color-border-strong);
        text-decoration: none;
    }

    .dashboard-shortcut-link svg {
        width: 1.5rem;
        height: 1.5rem;
        color: var(--color-primary);
    }

/* ===================== Patients (T08) ===================== */

/* Busca, status e o grupo de ações ("Buscar"/"Limpar"/"Novo paciente") ficam em um grid de largura
   determinística (T08, correção de bug): flex-wrap sem "flex-grow" deixava o <form> encolher para o
   tamanho mínimo do seu próprio conteúdo (shrink-to-fit) em vez de usar a largura disponível na
   barra, fazendo "Novo paciente" quebrar linha mesmo com espaço de sobra no desktop. Colunas fixas
   eliminam essa imprevisibilidade. ".patients-search" usa "display: contents" para que seus dois
   campos participem diretamente das colunas do grid do pai (o <form> em si não vira uma "caixa" que
   encolhe); o grupo de ações fica em uma única coluna "auto" com um flex interno, então "Limpar"
   aparecer/desaparecer não desloca nada — só encolhe/cresce o conteúdo daquela coluna. */
.patients-toolbar {
    display: grid;
    grid-template-columns: minmax(240px, 440px) 9rem auto;
    grid-template-areas: "search status actions";
    align-items: end;
    gap: var(--space-3);
    margin-bottom: var(--space-6);
}

.patients-search {
    display: contents;
}

.patients-search-field {
    grid-area: search;
    min-width: 0;
    margin-bottom: 0;
}

.patients-search-status {
    grid-area: status;
    margin-bottom: 0;
}

.patients-toolbar-actions {
    grid-area: actions;
    display: flex;
    align-items: flex-end;
    gap: var(--space-2);
}

.patients-toolbar-new {
    white-space: nowrap;
}

/* Tablet: quebra intencional em duas linhas (busca+status / ações), não wrap implícito. */
@media (max-width: 1023.98px) and (min-width: 768px) {
    .patients-toolbar {
        grid-template-columns: minmax(220px, 1fr) 9rem;
        grid-template-areas:
            "search status"
            "actions actions";
    }
}

/* Mobile: pilha vertical — busca, status, depois o grupo de ações; "Buscar"/"Limpar" lado a lado e
   "Novo paciente" em largura inteira na linha seguinte (permanece fácil de encontrar, sem disputar
   espaço com os outros dois). Sem scroll horizontal. */
@media (max-width: 767.98px) {
    .patients-toolbar {
        grid-template-columns: 1fr;
        grid-template-areas:
            "search"
            "status"
            "actions";
    }

    .patients-search-field {
        max-width: none;
    }

    .patients-toolbar-actions {
        flex-wrap: wrap;
    }

    .patients-toolbar-new {
        flex: 1 1 100%;
    }
}

/* No mobile, colunas secundárias da tabela de pacientes (e, T09, da tabela de documentos; T10, da
   tabela de procedimentos) somem (T08 § Tabela responsiva) — evita scroll horizontal como solução
   principal; Nome/Status/Ações continuam sempre visíveis. */
@media (max-width: 767.98px) {
    .patients-table .col-secondary,
    .patient-documents-table .col-secondary,
    .procedures-table .col-secondary {
        display: none;
    }
}

/* ===================== Documentos do paciente (T09) ===================== */
.patient-documents-actions {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}

/* O <form> de inativar/reativar por linha não deve virar um bloco de largura inteira — só o botão
   dentro dele precisa ficar ao lado do link "Baixar". */
.patient-document-status-form {
    display: contents;
}

/* ===================== Procedimentos (T10) ===================== */
/* Toolbar com busca incremental (mesmo padrão de Patients, refinamento de UX pós-validação manual;
   ver PatientsList.razor/MainLayout.razor.js): flexbox com "flex-grow" nos campos evita o mesmo bug
   de shrink-to-fit já documentado/corrigido para ".patients-toolbar" (T08) — técnica diferente
   (flex-basis por campo em vez de grid-area), mesmo resultado, sem precisar duplicar o layout em
   grid de Patients aqui. */
.procedures-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--space-3);
    margin-bottom: var(--space-6);
}

.procedures-search {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--space-3);
    flex: 1 1 480px;
}

.procedures-search-field {
    flex: 1 1 220px;
    min-width: 0;
    margin-bottom: 0;
}

.procedures-search-status {
    flex: 0 0 9rem;
    margin-bottom: 0;
}

.procedures-toolbar-actions {
    display: flex;
    align-items: flex-end;
    gap: var(--space-2);
    flex-wrap: wrap;
}

.procedures-actions {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}

/* Mesmo racional de ".patient-document-status-form": o <form> de inativar/reativar por linha não
   deve virar um bloco de largura inteira. */
.procedure-status-form {
    display: contents;
}

.procedure-code-readonly {
    margin: 0;
}

.pagination a.btn.disabled {
    pointer-events: none;
    opacity: 0.5;
}

.patient-profile-fields {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: var(--space-4);
    margin: 0;
}

    .patient-profile-fields dt {
        font-size: var(--font-size-xs);
        font-weight: var(--font-weight-semibold);
        color: var(--color-text-secondary);
        text-transform: uppercase;
        letter-spacing: 0.03em;
        margin-bottom: 2px;
    }

    .patient-profile-fields dd {
        margin: 0;
        color: var(--color-text-primary);
    }

.patients-profile-sections {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: var(--space-4);
}

.patients-profile-placeholder h3 {
    margin-bottom: var(--space-1);
}

.patient-form-section-title {
    margin: var(--space-6) 0 var(--space-4);
    font-size: var(--font-size-sm);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--color-text-secondary);
}

    .patient-form-section-title:first-child {
        margin-top: 0;
    }

/* Linha de 2 campos pareados (nascimento+CPF, telefone+e-mail, CEP+UF, número+complemento,
   bairro+cidade) — cada ".form-field" já tem margin-bottom próprio (base.css), então não repete
   aqui; "gap" cuida do espaço horizontal entre os dois. Campos de largura inteira (nome,
   logradouro) ficam FORA desta classe, como blocos diretos — largura total do formulário. */
.patient-form-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
}

    .patient-form-row > .form-field {
        flex: 1 1 200px;
    }

.patient-form-postal-code-field {
    flex-grow: 2;
}

.patient-form-state-field {
    flex: 0 0 5.5rem;
    max-width: 6rem;
}

/* Consulta de CEP (ajuste de UX): status discreto (nunca um toast) sob o campo, cor conforme
   "data-variant" (definido pelo JS em MainLayout.razor.js) usando os mesmos tokens de
   Alert/ValidationMessage do Design System — nenhuma cor nova. */
.postal-code-lookup-status {
    margin: 0;
    font-size: var(--font-size-xs);
}

    .postal-code-lookup-status[data-variant="info"] {
        color: var(--color-info);
    }

    .postal-code-lookup-status[data-variant="success"] {
        color: var(--color-success);
    }

    .postal-code-lookup-status[data-variant="warning"] {
        color: var(--color-warning);
    }

    .postal-code-lookup-status[data-variant="error"] {
        color: var(--color-error);
    }

/* ===================== Tooltip (CSS puro, uso pontual) ===================== */
[data-tooltip] {
    position: relative;
}

    [data-tooltip]:hover::after,
    [data-tooltip]:focus-visible::after {
        content: attr(data-tooltip);
        position: absolute;
        bottom: calc(100% + 6px);
        left: 50%;
        transform: translateX(-50%);
        background: var(--color-text-primary);
        color: var(--color-text-inverse);
        font-size: var(--font-size-xs);
        padding: 4px 8px;
        border-radius: var(--radius-sm);
        white-space: nowrap;
        z-index: var(--z-dropdown);
    }

/* ===================== Agenda (T11) ===================== */
/* Toolbar com formulário GET simples (data + status) — sem live search: a agenda filtra por dia
   inteiro, não por texto digitado, então o ganho de busca incremental seria marginal (ver TASK.md §
   Busca). "flex-wrap" evita overflow horizontal em telas estreitas sem exigir a técnica de grid-area
   de Patients (não há um botão oculto para Enter aqui, "Aplicar" fica sempre visível). */
.appointments-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--space-3);
    margin-bottom: var(--space-4);
}

.appointments-date-form {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--space-3);
}

.appointments-date-field {
    flex: 0 0 10rem;
    margin-bottom: 0;
}

.appointments-status-field {
    flex: 0 0 9rem;
    margin-bottom: 0;
}

.appointments-date-nav {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}

.appointments-day-heading {
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text-secondary);
    text-transform: capitalize;
    margin: 0 0 var(--space-4);
}

/* Lista vertical por horário (T11 § Tabela/visualização) — nunca uma tabela larga: em mobile uma
   tabela de agenda com paciente/procedimento/duração/status exigiria scroll horizontal; cards
   empilham naturalmente em qualquer largura. */
.appointment-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.appointment-card {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    padding: var(--space-4);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

    .appointment-card:hover,
    .appointment-card:focus-within {
        background: var(--color-surface-alt);
        border-color: var(--color-primary);
    }

.appointment-card-time {
    flex: 0 0 4.5rem;
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text-primary);
}

.appointment-card-main {
    flex: 1 1 auto;
    min-width: 0;
}

.appointment-card-patient {
    display: inline-block;
    font-weight: var(--font-weight-semibold);
    color: var(--color-text-primary);
    text-decoration: none;
}

    .appointment-card-patient:hover,
    .appointment-card-patient:focus-visible {
        text-decoration: underline;
    }

.appointment-card-meta {
    font-size: var(--font-size-sm);
    color: var(--color-text-secondary);
}

.appointment-card-notes {
    margin-top: var(--space-1);
    font-size: var(--font-size-xs);
    color: var(--color-text-secondary);
    font-style: italic;
}

.appointment-card-status {
    flex: 0 0 auto;
}

@media (max-width: 480px) {
    .appointment-card {
        flex-wrap: wrap;
    }

    .appointment-card-time {
        flex-basis: 100%;
    }
}

.appointment-form-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
}

    .appointment-form-row > .form-field {
        flex: 1 1 160px;
    }

.appointment-patient-readonly {
    margin: 0;
    font-weight: var(--font-weight-semibold);
}

.appointment-status-actions {
    margin-top: var(--space-6);
    padding-top: var(--space-4);
    border-top: 1px solid var(--color-border);
}

.appointment-status-actions-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-top: var(--space-2);
}

/* Mesmo racional de ".procedure-status-form"/".patient-document-status-form": cada <form> de
   transição de status não deve virar um bloco de largura inteira. */
.appointment-status-form {
    display: contents;
}

/* Widgets do Dashboard (T07/T11) preenchidos com agenda real. */
.dashboard-appointment-list {
    list-style: none;
    margin: 0 0 var(--space-3);
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.dashboard-appointment-item {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--font-size-sm);
}

.dashboard-appointment-time {
    flex: 0 0 auto;
    font-weight: var(--font-weight-semibold);
    color: var(--color-text-primary);
}

.dashboard-appointment-patient {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--color-text-secondary);
}

.dashboard-widget-link {
    display: inline-block;
}

/* ===================== Atendimentos/evolução clínica (T12) ===================== */
.encounter-patient-readonly {
    margin: 0 0 var(--space-2);
    font-weight: var(--font-weight-semibold);
}

.encounter-form-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
}

    .encounter-form-row > .form-field {
        flex: 1 1 160px;
    }

/* Cada linha de procedimento realizado — mesma técnica de "flex-wrap" já usada em
   ".appointment-status-actions-buttons"/".appointment-form-row" para nunca forçar uma fila
   horizontal apertada em mobile. */
.encounter-procedure-row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--space-3);
    padding: var(--space-3) 0;
    border-bottom: 1px solid var(--color-border);
}

    .encounter-procedure-row .form-field {
        flex: 2 1 220px;
        margin-bottom: 0;
    }

.encounter-procedure-tooth {
    flex: 1 1 100px !important;
}

.encounter-procedure-region {
    flex: 1 1 160px !important;
}

.encounter-procedure-notes {
    flex: 2 1 200px !important;
}

.encounter-procedure-remove {
    flex: 0 0 auto;
}

.encounter-textarea {
    min-height: 8rem;
    resize: vertical;
}

.encounter-form-actions {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-3);
    margin: var(--space-6) 0;
}

/* ===================== Templates de anamnese (T13) ===================== */
.anamnesis-templates-toolbar {
    display: flex;
    justify-content: flex-end;
    margin-bottom: var(--space-4);
}

.anamnesis-templates-actions,
.anamnesis-template-header {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.anamnesis-template-header {
    justify-content: space-between;
    margin-bottom: var(--space-4);
}

.anamnesis-version-row-selected {
    font-weight: var(--font-weight-semibold);
}

/* Mesma técnica de "flex-wrap" já usada em ".appointment-form-row"/".encounter-form-row" — nunca
   forçar uma fila horizontal apertada em mobile (T13 § Responsividade). */
.anamnesis-form-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
    align-items: flex-end;
}

    .anamnesis-form-row > .form-field {
        flex: 1 1 220px;
    }

.anamnesis-inline-form-actions {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-3);
    margin-top: var(--space-3);
}

.anamnesis-version-detail-card {
    margin-top: var(--space-6);
}

@media (max-width: 767.98px) {
    .anamnesis-version-detail-card {
        margin-top: var(--space-4);
    }
}

.anamnesis-section-card {
    margin-top: var(--space-4);
}

    .anamnesis-section-card .card-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        flex-wrap: wrap;
        gap: var(--space-2);
    }

.anamnesis-section-actions,
.anamnesis-question-actions {
    display: flex;
    gap: var(--space-2);
}

.anamnesis-question-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.anamnesis-question-item {
    padding: var(--space-3) 0;
    border-bottom: 1px solid var(--color-border);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

    .anamnesis-question-item:last-child {
        border-bottom: none;
    }

.anamnesis-question-main {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
}

.anamnesis-question-code {
    color: var(--color-text-secondary);
}

.anamnesis-question-options {
    margin: 0;
    padding-left: var(--space-5);
    color: var(--color-text-secondary);
    font-size: var(--font-size-sm);
}

.anamnesis-declaration-readonly {
    white-space: pre-wrap;
}

/* T19: conteúdo de documento clínico — sempre texto puro (nunca HTML/markup), "pre-wrap" preserva as
   quebras de linha/parágrafo digitadas no modelo sem precisar de nenhum parser/sanitizador de HTML. */
.clinical-document-content-readonly {
    white-space: pre-wrap;
    line-height: 1.6;
    overflow-wrap: anywhere;
}

.clinical-document-content-textarea {
    min-height: 220px;
}

.anamnesis-inline-form {
    display: inline-flex;
}

/* Anamnese do paciente (T14) */

.patient-anamnesis-section {
    border: none;
    margin: var(--space-4) 0;
    padding: var(--space-4);
}

    .patient-anamnesis-section legend {
        padding: 0;
        width: 100%;
    }

    .patient-anamnesis-section[disabled] {
        opacity: 1;
    }

.patient-anamnesis-question {
    padding: var(--space-3) 0;
    border-bottom: 1px solid var(--color-border);
}

    .patient-anamnesis-question:last-child {
        border-bottom: none;
    }

.patient-anamnesis-question-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    margin-bottom: var(--space-2);
}

.patient-anamnesis-options {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
}

.patient-anamnesis-detail-field {
    margin-top: var(--space-2);
}

.patient-anamnesis-actions {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-3);
}

.patients-profile-alerts ul,
.encounter-alerts-banner {
    margin-bottom: var(--space-6);
}

.encounter-alerts-banner ul {
    list-style: none;
    margin: var(--space-2) 0 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

/* Mesma técnica já usada em ".encounter-procedure-row"/".appointments-date-form"/
   ".procedures-search" (T10–T12): o botão ao lado do campo só alinha pela base do control quando o
   ".form-field" perde a margem inferior padrão (--space-4) dentro da linha flex — sem isso, o botão
   (sem label acima) fica mais alto que o control, porque a margem do campo o empurra para baixo. */
.patient-anamnesis-start-form {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--space-3);
}

    .patient-anamnesis-start-form .form-field {
        flex: 1 1 260px;
        margin-bottom: 0;
    }

/* Odontograma (T15) */

.odontogram-dentition-toggle {
    display: flex;
    gap: var(--space-2);
    margin-bottom: var(--space-4);
}

.odontogram-chart-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
}

.odontogram-arch-label {
    display: block;
    margin-bottom: var(--space-2);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--color-text-secondary);
}

.odontogram-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

.odontogram-tooth {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.5rem;
    height: 2.5rem;
    padding: 0 var(--space-2);
    background: var(--color-surface);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-md);
    color: var(--color-text-primary);
    font-weight: var(--font-weight-medium);
    text-decoration: none;
}

    .odontogram-tooth:hover {
        background: var(--color-surface-alt);
    }

    .odontogram-tooth:focus-visible {
        outline: none;
        border-color: var(--color-primary);
        box-shadow: 0 0 0 3px var(--color-primary-soft);
    }

.odontogram-tooth-has-condition {
    border-color: var(--color-primary);
    background: var(--color-primary-soft);
}

.odontogram-tooth-selected {
    border-width: 2px;
    border-color: var(--color-primary);
}

.odontogram-tooth-badge {
    position: absolute;
    top: -6px;
    right: -6px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.125rem;
    height: 1.125rem;
    padding: 0 3px;
    border-radius: var(--radius-pill);
    background: var(--color-primary);
    color: var(--color-primary-contrast);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
}

.odontogram-tooth-panel {
    margin-top: var(--space-5);
}

.odontogram-condition-list {
    list-style: none;
    margin: 0 0 var(--space-4);
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.odontogram-condition-item {
    padding: var(--space-3) 0;
    border-bottom: 1px solid var(--color-border);
}

    .odontogram-condition-item:last-child {
        border-bottom: none;
    }

.odontogram-condition-main {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
}

.odontogram-condition-notes {
    margin: var(--space-2) 0 0;
    color: var(--color-text-secondary);
    font-size: var(--font-size-sm);
    white-space: pre-wrap;
}

.odontogram-condition-actions {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-top: var(--space-2);
}

.odontogram-inline-form {
    display: inline-flex;
}

.odontogram-surfaces-fieldset {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin: 0 0 var(--space-4);
    padding: var(--space-3);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
}

    .odontogram-surfaces-fieldset legend {
        padding: 0 var(--space-1);
        font-size: var(--font-size-sm);
        font-weight: var(--font-weight-medium);
        color: var(--color-text-secondary);
    }

.odontogram-inline-form-actions {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-3);
    margin-top: var(--space-3);
}

/* Histórico do odontograma (T16) */

.odontogram-history-filter {
    margin-bottom: var(--space-4);
}

.odontogram-history-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.odontogram-history-item-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.odontogram-history-datetime {
    font-weight: var(--font-weight-medium);
}

.odontogram-history-type {
    margin: var(--space-2) 0 0;
    color: var(--color-text-secondary);
}

.odontogram-history-before-after {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
    margin-top: var(--space-2);
}

    .odontogram-history-before-after > div {
        flex: 1 1 200px;
    }

    .odontogram-history-before-after p {
        margin: 0;
    }

.odontogram-history-meta {
    margin-top: var(--space-2);
    font-size: var(--font-size-sm);
}

/* Plano de tratamento (T17) */

.treatment-plan-item-list {
    list-style: none;
    margin: 0 0 var(--space-4);
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.treatment-plan-item-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.treatment-plan-item-procedure {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-weight: var(--font-weight-medium);
}

.treatment-plan-item-note {
    margin: var(--space-2) 0 0;
    color: var(--color-text-secondary);
}

.treatment-plan-item-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    margin-top: var(--space-2);
}

.treatment-plan-inline-form {
    display: inline-flex;
}

.treatment-plan-form-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
}

    .treatment-plan-form-row > .form-field {
        flex: 1 1 160px;
    }

.treatment-plan-inline-form-actions {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-3);
    margin-top: var(--space-3);
}

.treatment-plan-add-item {
    margin-top: var(--space-4);
    padding-top: var(--space-4);
    border-top: 1px solid var(--color-border);
}

.treatment-plan-complete-actions {
    margin-top: var(--space-6);
}

/* T18B: "Baixar PDF" + "Criar nova versão" lado a lado num orçamento emitido. */
.budget-issued-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
}

/* T18C: filtro de consulta do histórico ("Filtrar por plano") — controle independente do seletor de
   criação, deliberadamente compacto (não reutiliza ".patients-toolbar", que é maior/com busca). */
.budget-history-filter {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--space-3);
    margin-bottom: var(--space-4);
}

.budget-history-filter .form-field {
    margin-bottom: 0;
    min-width: 200px;
}

@media (max-width: 640px) {
    .budget-history-filter {
        flex-direction: column;
        align-items: stretch;
    }
}

/* Orçamentos (T18) */

.budget-item-table td {
    vertical-align: middle;
}

.budget-item-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

.budget-inline-form {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

/* Card de totais (T18A — refinamento de layout): tudo dentro do mesmo card, alinhamento consistente
   entre subtotal/desconto/total (nunca uma <dl>/formulário soltos com estruturas diferentes — ver
   TASK.md § Correção visual do card de totais). */
.budget-totals-card {
    max-width: 420px;
}

.budget-totals-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-2) 0;
}

.budget-totals-label {
    color: var(--color-text-secondary);
}

.budget-total-row {
    border-top: 1px solid var(--color-border);
    margin-top: var(--space-2);
    padding-top: var(--space-3);
}

.budget-total-row .budget-totals-label,
.budget-total-row .budget-totals-value {
    font-weight: var(--font-weight-medium);
    font-size: 1.125rem;
    color: var(--color-text-primary);
}

/* Formulário de desconto: tipo + valor + ação sempre na mesma linha em telas largas, empilhando em
   mobile — nunca um botão "solto" fora da estrutura do card (ver TASK.md § Evitar botão flutuante). */
.budget-discount-fieldset {
    border: 0;
    margin: var(--space-2) 0;
    padding: 0;
}

.budget-discount-fields {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--space-3);
}

.budget-discount-type-field {
    flex: 1 1 140px;
}

.budget-discount-value-field {
    flex: 1 1 140px;
}

.budget-discount-value-input {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.budget-discount-affix {
    color: var(--color-text-secondary);
    font-weight: var(--font-weight-medium);
    min-width: 1.5rem;
}

.budget-discount-submit {
    flex: 0 0 auto;
}

@media (max-width: 640px) {
    .budget-discount-fields {
        flex-direction: column;
        align-items: stretch;
    }

    .budget-discount-submit {
        width: 100%;
    }
}

@media (max-width: 640px) {
    .budget-item-table thead {
        display: none;
    }

    .budget-item-table,
    .budget-item-table tbody,
    .budget-item-table tr,
    .budget-item-table td {
        display: block;
        width: 100%;
    }

    .budget-item-table tr {
        margin-bottom: var(--space-4);
        border-bottom: 1px solid var(--color-border);
        padding-bottom: var(--space-3);
    }

    .budget-item-table td::before {
        content: attr(data-label);
        display: block;
        font-size: 0.75rem;
        color: var(--color-text-secondary);
        margin-bottom: var(--space-1);
    }
}

/* Linha/versão acionável abrindo um modal de resumo (T18A — navegação de versões de TreatmentPlan/
   Budget). Botão real (não link — não há navegação, só abertura de modal, ver TASK.md § Modal como
   fluxo principal de consulta), redesenhado para não parecer um botão convencional: mesma cor/
   sublinhado de um link (".row-action-trigger" reseta a aparência nativa de <button>), ocupando toda
   a célula para maximizar a área de clique/toque — "data-row-link-target" generalizado em
   MainLayout.razor.js para também reconhecer botões (além de <a>), então a linha inteira
   (".table tbody tr[data-row-link]") continua clicável, exatamente como em Patients/Procedures. */
.row-action-trigger {
    display: block;
    width: 100%;
    background: none;
    border: 0;
    padding: 0;
    margin: 0;
    font: inherit;
    text-align: left;
    color: var(--color-primary);
    cursor: pointer;
}

    .row-action-trigger:hover {
        text-decoration: underline;
    }

/* Modal de resumo de versão (TreatmentPlan/Budget): conteúdo de leitura + uma ação contextual no
   rodapé (Draft: "Continuar editando"; versão mais recente concluída/emitida: "Criar nova versão").
   Reaproveita a infraestrutura de <dialog data-auto-open> já usada pelos modais de Patient (T08) —
   nenhum modal/JS novo criado. */
.version-modal-item-list {
    list-style: none;
    margin: 0 0 var(--space-4);
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.version-modal-item {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-2) 0;
    border-bottom: 1px solid var(--color-border);
}

    .version-modal-item:last-child {
        border-bottom: none;
    }

.version-modal-item-secondary {
    color: var(--color-text-secondary);
    font-size: 0.875rem;
}

.version-modal-meta {
    color: var(--color-text-secondary);
    font-size: 0.875rem;
    margin: 0 0 var(--space-4);
}

.version-modal-totals {
    margin-top: var(--space-3);
    padding-top: var(--space-3);
    border-top: 1px solid var(--color-border);
}
