/* ==========================================================================
   APP UI — SAVE PORTAL
   Arquivo: app-ui.css
   Descrição: Padrão visual das telas de conteúdo (listagens, filtros, tabelas).
              É a contraparte "clara" do menu lateral (css/modern-menu.css):
              mesma tinta, mesma tipografia, mesmo ritmo de espaçamento.

   Princípios
     1. Densidade com hierarquia — o dado é o herói; o enfeite sai da frente.
     2. Acento escasso — o degradê violeta→rosa aparece UMA vez por tela
        (o traço ao lado do título). Nos demais lugares, cor é significado.
     3. Trilho de status — cada linha da tabela tem uma borda esquerda de 3px
        que codifica o status do registro. A lista vira uma coluna de cor
        legível antes da leitura.

   Uso mínimo em uma tela:
     <link rel="stylesheet" href="css/app-ui.css">   (depois de head.php)
     <div class="app-page"> … </div>

   Observação de cascata: datatable.php carrega Bootstrap 4 no fim do <body>,
   ou seja, DEPOIS deste arquivo. Por isso todo seletor que disputa espaço com
   o Bootstrap é escopado em `.app-page` — dois níveis de classe vencem a
   especificidade de `.table`, `.btn` e afins sem precisar de `!important`.

   O escopo é duplo: `:is(.app-page, .app-modal)`. Modais ficam fora da casca
   da página (são irmãos dela no DOM), então `.app-modal` no elemento `.modal`
   dá ao seu interior exatamente o mesmo tratamento — campos, botões, tabelas —
   sem duplicar uma linha de CSS. `:is()` assume a especificidade do argumento
   mais específico; como os dois são classes, a especificidade não muda.
   ========================================================================== */

:root {
    /* Tinta — derivada do menu lateral */
    --ui-ink: #211d45;
    --ui-ink-2: #56537a;
    --ui-ink-3: #8a87a6;

    /* Superfícies */
    --ui-canvas: #f4f4f9;
    --ui-surface: #ffffff;
    --ui-surface-2: #fafaff;
    --ui-hover: #f6f4ff;

    /* Linhas */
    --ui-line: #e7e5f1;
    --ui-line-soft: #f0eff7;

    /* Noite — os mesmos tons do menu lateral (css/modern-menu.css) */
    --ui-night-top: #241f4d;
    --ui-night-bottom: #171335;
    --ui-night-glow: rgba(139, 92, 246, 0.35);
    --ui-night-line: rgba(255, 255, 255, 0.10);

    /* Acento */
    --ui-accent: #6d43e8;
    --ui-accent-ink: #4c2bb5;
    --ui-accent-soft: #f1ecff;
    --ui-grad: linear-gradient(180deg, #a78bfa 0%, #f472b6 100%);

    /* Semântica — usada no trilho de status e nos selos */
    --ui-ok: #0f9d76;
    --ui-ok-soft: #e6f6f1;
    --ui-info: #2f74d0;
    --ui-info-soft: #eaf1fc;
    --ui-warn: #b8790b;
    --ui-warn-soft: #fdf3e2;
    --ui-danger: #d64550;
    --ui-danger-soft: #fdedee;
    --ui-neutral: #8a87a6;
    --ui-neutral-soft: #f1f0f6;

    /* Forma e movimento */
    --ui-radius: 10px;
    --ui-radius-sm: 7px;
    --ui-shadow: 0 1px 2px rgba(33, 29, 69, 0.04), 0 6px 20px -12px rgba(33, 29, 69, 0.18);
    --ui-ease: cubic-bezier(0.4, 0, 0.2, 1);
    --ui-speed: 150ms;

    --ui-font: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

/* --------------------------------------------------------------------------
   1. Casca da página
   -------------------------------------------------------------------------- */

.app-page {
    padding: 1.25rem 1.5rem 2.5rem;
    font-family: var(--ui-font);
    color: var(--ui-ink);
    -webkit-font-smoothing: antialiased;
}

/* A topbar compartilhada já traz `mb-4`; sem isso sobram ~48px mortos. */
.topbar + .app-page {
    padding-top: 0.25rem;
}

/* Para embutir o padrão dentro de uma tela que ainda não foi convertida —
   por exemplo uma aba de cadastro. Só ativa o escopo, sem casca própria. */
.app-page--inline,
.topbar + .app-page--inline {
    padding: 0;
}

:is(.app-page, .app-modal) ::selection {
    background: var(--ui-accent-soft);
}

/* Cabeçalho: eyebrow + título + ações, tudo em uma faixa de ~52px */
.app-page__head {
    display: flex;
    align-items: center;
    gap: 0.875rem;
    margin-bottom: 1rem;
}

/* O traço — único uso do degradê da marca na área de conteúdo.
   Ecoa a barra do item ativo do menu lateral. */
.app-page__tick {
    flex: 0 0 auto;
    width: 3px;
    align-self: stretch;
    min-height: 40px;
    border-radius: 3px;
    background: var(--ui-grad);
}

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

.app-page__eyebrow {
    display: block;
    margin-bottom: 0.125rem;
    color: var(--ui-ink-3);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    line-height: 1.2;
}

.app-page__title {
    margin: 0;
    color: var(--ui-ink);
    font-size: 1.25rem;
    font-weight: 600;
    letter-spacing: -0.02em;
    line-height: 1.25;
}

.app-page__meta {
    display: block;
    margin-top: 0.125rem;
    color: var(--ui-ink-3);
    font-size: 0.75rem;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}

.app-page__meta strong {
    color: var(--ui-ink-2);
    font-weight: 600;
}

.app-page__actions {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

/* --------------------------------------------------------------------------
   2. Botões

   `.app-btn` é global de propósito: não exige `.app-page` nem `.app-modal` em
   volta, então serve em modais, em parciais compartilhadas e em telas que
   ainda não foram convertidas (desde que a tela carregue este arquivo).

   Logo abaixo há uma camada de compatibilidade que dá o mesmo desenho às
   classes de botão do Bootstrap. Ela é escopada em `:is(.app-page, .app-modal)`
   porque só queremos alcançar o conteúdo que já é nosso — os modais legados
   que o menu.php renderiza em toda página ficam intocados.
   -------------------------------------------------------------------------- */

.app-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4375rem;
    min-height: 34px;
    padding: 0.4375rem 0.875rem;
    border: 1px solid var(--ui-line);
    border-radius: var(--ui-radius-sm);
    background: var(--ui-surface);
    color: var(--ui-ink-2);
    font-family: var(--ui-font);
    font-size: 0.78125rem;
    font-weight: 500;
    line-height: 1.2;
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--ui-speed) var(--ui-ease),
                border-color var(--ui-speed) var(--ui-ease),
                color var(--ui-speed) var(--ui-ease);
}

.app-btn:hover {
    border-color: #d9d5ea;
    background: var(--ui-hover);
    color: var(--ui-ink);
    text-decoration: none;
}

.app-btn:focus {
    outline: none;
}

.app-btn:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(109, 67, 232, 0.28);
}

.app-btn .fas,
.app-btn .far,
.app-btn .fab {
    font-size: 0.8125rem;
}

/* Ação principal — a tinta escura da marca */
.app-btn--primary {
    border-color: var(--ui-ink);
    background: var(--ui-ink);
    color: #fff;
}

.app-btn--primary:hover {
    border-color: #2e2860;
    background: #2e2860;
    color: #fff;
}

.app-btn--accent {
    border-color: var(--ui-accent);
    background: var(--ui-accent);
    color: #fff;
}

.app-btn--accent:hover {
    border-color: var(--ui-accent-ink);
    background: var(--ui-accent-ink);
    color: #fff;
}

/* Ação destrutiva confirmada (excluir) */
.app-btn--danger {
    border-color: var(--ui-danger);
    background: var(--ui-danger);
    color: #fff;
}

.app-btn--danger:hover {
    border-color: #bd3944;
    background: #bd3944;
    color: #fff;
}

.app-btn--quiet {
    border-color: transparent;
    background: transparent;
    color: var(--ui-ink-3);
}

.app-btn--quiet:hover {
    border-color: transparent;
    background: var(--ui-neutral-soft);
    color: var(--ui-ink-2);
}

.app-btn--sm {
    min-height: 30px;
    padding: 0.3125rem 0.625rem;
    font-size: 0.75rem;
}

/* Só ícone — o rótulo vai no `title`. É o formato das ações de linha. */
.app-btn--icon {
    width: 30px;
    min-width: 30px;
    min-height: 30px;
    height: 30px;
    padding: 0;
}

.app-btn--block {
    display: flex;
    width: 100%;
}

.app-btn[disabled],
.app-btn.is-disabled,
.app-btn:disabled {
    border-color: var(--ui-line-soft);
    background: var(--ui-surface-2);
    color: #c3c1d4;
    cursor: default;
    pointer-events: none;
}

/* --------------------------------------------------------------------------
   2.1 Compatibilidade: classes de botão do Bootstrap

   O markup existente (e o que `components/action-buttons.php` gera) usa
   `btn btn-outline-primary`, `btn btn-secondary` e afins. Em vez de reescrever
   dezenas de arquivos, essas classes recebem aqui o mesmo desenho.

   As variantes de cor do Bootstrap que não codificam significado nenhum
   (`success`, `info`, `warning`, `dark` em botões de ação) caem todas no botão
   neutro: nesta tela a cor não distingue nada, quem distingue é o rótulo.
   -------------------------------------------------------------------------- */

:is(.app-page, .app-modal) .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4375rem;
    min-height: 34px;
    padding: 0.4375rem 0.875rem;
    border: 1px solid var(--ui-line);
    border-radius: var(--ui-radius-sm);
    background: var(--ui-surface);
    color: var(--ui-ink-2);
    font-family: var(--ui-font);
    font-size: 0.78125rem;
    font-weight: 500;
    line-height: 1.2;
    white-space: nowrap;
    text-decoration: none;
    box-shadow: none;
    transition: background-color var(--ui-speed) var(--ui-ease),
                border-color var(--ui-speed) var(--ui-ease),
                color var(--ui-speed) var(--ui-ease);
}

:is(.app-page, .app-modal) .btn:hover {
    border-color: #d9d5ea;
    background: var(--ui-hover);
    color: var(--ui-ink);
    text-decoration: none;
}

:is(.app-page, .app-modal) .btn:focus,
:is(.app-page, .app-modal) .btn.focus {
    outline: none;
    box-shadow: 0 0 0 3px rgba(109, 67, 232, 0.28);
}

:is(.app-page, .app-modal) .btn-sm {
    min-height: 30px;
    padding: 0.3125rem 0.625rem;
    font-size: 0.75rem;
}

:is(.app-page, .app-modal) .btn-block {
    display: flex;
    width: 100%;
}

/* Ação principal */
:is(.app-page, .app-modal) .btn-primary {
    border-color: var(--ui-ink);
    background: var(--ui-ink);
    color: #fff;
}

:is(.app-page, .app-modal) .btn-primary:hover {
    border-color: #2e2860;
    background: #2e2860;
    color: #fff;
}

/* Neutros e variantes sem significado -> botão neutro com realce no acento */
:is(.app-page, .app-modal) .btn-secondary,
:is(.app-page, .app-modal) .btn-light,
:is(.app-page, .app-modal) .btn-outline-secondary,
:is(.app-page, .app-modal) .btn-outline-primary,
:is(.app-page, .app-modal) .btn-outline-success,
:is(.app-page, .app-modal) .btn-outline-info,
:is(.app-page, .app-modal) .btn-outline-warning,
:is(.app-page, .app-modal) .btn-outline-dark {
    border-color: var(--ui-line);
    background: var(--ui-surface);
    color: var(--ui-ink-2);
}

:is(.app-page, .app-modal) .btn-secondary:hover,
:is(.app-page, .app-modal) .btn-light:hover,
:is(.app-page, .app-modal) .btn-outline-secondary:hover,
:is(.app-page, .app-modal) .btn-outline-primary:hover,
:is(.app-page, .app-modal) .btn-outline-success:hover,
:is(.app-page, .app-modal) .btn-outline-info:hover,
:is(.app-page, .app-modal) .btn-outline-warning:hover,
:is(.app-page, .app-modal) .btn-outline-dark:hover {
    border-color: #d3ccf5;
    background: var(--ui-accent-soft);
    color: var(--ui-accent-ink);
}

/* Destrutivo: preenchido quando confirma, contornado quando só oferece */
:is(.app-page, .app-modal) .btn-danger {
    border-color: var(--ui-danger);
    background: var(--ui-danger);
    color: #fff;
}

:is(.app-page, .app-modal) .btn-danger:hover {
    border-color: #bd3944;
    background: #bd3944;
    color: #fff;
}

:is(.app-page, .app-modal) .btn-outline-danger {
    border-color: var(--ui-line);
    background: var(--ui-surface);
    color: var(--ui-ink-2);
}

:is(.app-page, .app-modal) .btn-outline-danger:hover {
    border-color: #f3c2c6;
    background: var(--ui-danger-soft);
    color: var(--ui-danger);
}

:is(.app-page, .app-modal) .btn:disabled,
:is(.app-page, .app-modal) .btn.disabled {
    border-color: var(--ui-line-soft);
    background: var(--ui-surface-2);
    color: #c3c1d4;
    opacity: 1;
}

/* --------------------------------------------------------------------------
   3. Barra de filtros
   -------------------------------------------------------------------------- */

.app-toolbar {
    margin-bottom: 0.875rem;
    padding: 0.875rem 1rem;
    border: 1px solid var(--ui-line);
    border-radius: var(--ui-radius);
    background: var(--ui-surface);
    box-shadow: var(--ui-shadow);
}

.app-toolbar__row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.app-toolbar__row + .app-toolbar__row {
    margin-top: 0.75rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--ui-line-soft);
}

.app-toolbar__row--fields {
    align-items: flex-end;
    flex-wrap: wrap;
}

.app-toolbar__label {
    flex: 0 0 auto;
    width: 8.5rem;
    padding-top: 0.125rem;
    color: var(--ui-ink-3);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    line-height: 1.3;
}

/* Campos */
.app-field {
    flex: 0 0 auto;
    min-width: 0;
}

.app-field--grow {
    flex: 1 1 16rem;
}

.app-field__label {
    display: block;
    margin-bottom: 0.3125rem;
    color: var(--ui-ink-3);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

:is(.app-page, .app-modal) .app-input {
    display: block;
    width: 100%;
    height: 36px;
    padding: 0.4375rem 0.625rem;
    border: 1px solid var(--ui-line);
    border-radius: var(--ui-radius-sm);
    background: var(--ui-surface);
    color: var(--ui-ink);
    font-family: inherit;
    font-size: 0.8125rem;
    line-height: 1.3;
    transition: border-color var(--ui-speed) var(--ui-ease),
                box-shadow var(--ui-speed) var(--ui-ease);
}

/* Selects nativos usam a mesma seta do seletor de páginas do DataTables. */
:is(.app-page, .app-modal) select.app-input {
    padding-right: 1.75rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%238a87a6'%3E%3Cpath d='M8 11 3.5 6h9z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.5rem center;
    background-size: 12px;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    cursor: pointer;
}

:is(.app-page, .app-modal) .app-input:focus {
    outline: none;
    border-color: var(--ui-accent);
    box-shadow: 0 0 0 3px rgba(109, 67, 232, 0.16);
}

/* Chips de filtro — ativo recebe a tinta escura do menu lateral */
.app-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
    /* Ocupa o espaço livre da linha para que uma ação seguinte ("Limpar
       filtros") vá para a direita da barra, e não cole nos chips. */
    flex: 1 1 auto;
    min-width: 0;
}

:is(.app-page, .app-modal) .app-chip {
    display: inline-flex;
    align-items: center;
    margin: 0;
    padding: 0.3125rem 0.75rem;
    border: 1px solid var(--ui-line);
    border-radius: 999px;
    background: var(--ui-surface);
    color: var(--ui-ink-2);
    font-family: inherit;
    font-size: 0.75rem;
    font-weight: 500;
    line-height: 1.35;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color var(--ui-speed) var(--ui-ease),
                border-color var(--ui-speed) var(--ui-ease),
                color var(--ui-speed) var(--ui-ease);
}

:is(.app-page, .app-modal) .app-chip:hover {
    border-color: #d3ccf5;
    background: var(--ui-accent-soft);
    color: var(--ui-accent-ink);
}

:is(.app-page, .app-modal) .app-chip:focus-within {
    outline: none;
    box-shadow: 0 0 0 3px rgba(109, 67, 232, 0.28);
}

:is(.app-page, .app-modal) .app-chip.is-active {
    border-color: var(--ui-ink);
    background: var(--ui-ink);
    color: #fff;
}

:is(.app-page, .app-modal) .app-chip.is-active:hover {
    border-color: #2e2860;
    background: #2e2860;
    color: #fff;
}

:is(.app-page, .app-modal) .app-chip input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
    pointer-events: none;
}

/* --------------------------------------------------------------------------
   4. Cartão de dados
   -------------------------------------------------------------------------- */

.app-card {
    border: 1px solid var(--ui-line);
    border-radius: var(--ui-radius);
    background: var(--ui-surface);
    box-shadow: var(--ui-shadow);
    overflow: hidden;
}

.app-card__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    min-height: 44px;
    padding: 0.5rem 0.875rem;
    border-bottom: 1px solid var(--ui-line);
    background: var(--ui-surface-2);
}

.app-card__title {
    margin: 0;
    color: var(--ui-ink);
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: -0.01em;
}

.app-card__tools {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.app-card__body {
    padding: 1.25rem;
}

.app-card__body--flush {
    padding: 0;
}

/* --------------------------------------------------------------------------
   5. Tabela de dados
   -------------------------------------------------------------------------- */

.app-tablescroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

:is(.app-page, .app-modal) table.app-table {
    width: 100%;
    margin: 0;
    border-collapse: separate;
    border-spacing: 0;
    color: var(--ui-ink);
    font-size: 0.8125rem;
}

:is(.app-page, .app-modal) .app-table thead th {
    padding: 0.5625rem 0.75rem;
    border: 0;
    border-bottom: 1px solid var(--ui-line);
    background: var(--ui-surface-2);
    color: var(--ui-ink-3);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    text-align: left;
    white-space: nowrap;
    vertical-align: middle;
}

:is(.app-page, .app-modal) .app-table tbody td {
    padding: 0.4375rem 0.75rem;
    border: 0;
    border-bottom: 1px solid var(--ui-line-soft);
    background: var(--ui-surface);
    vertical-align: middle;
    line-height: 1.35;
    transition: background-color 120ms var(--ui-ease);
}

:is(.app-page, .app-modal) .app-table tbody tr.even td {
    background: #fcfcfe;
}

:is(.app-page, .app-modal) .app-table tbody tr:hover > td {
    background: var(--ui-hover);
}

:is(.app-page, .app-modal) .app-table tbody tr:last-child td {
    border-bottom: 0;
}

/* Rodapé da tabela — a linha de total de uma tabela que soma */
:is(.app-page, .app-modal) .app-table tfoot th,
:is(.app-page, .app-modal) .app-table tfoot td {
    padding: 0.5625rem 0.75rem;
    border: 0;
    border-top: 1px solid var(--ui-line);
    background: var(--ui-surface-2);
    color: var(--ui-ink);
    font-size: 0.8125rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    vertical-align: middle;
}

/* O rótulo do total é discreto; o número é que tem de saltar */
:is(.app-page, .app-modal) .app-table tfoot .app-total__label {
    color: var(--ui-ink-3);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
}

/* A primeira célula abriga o trilho de status */
:is(.app-page, .app-modal) .app-table tbody td:first-child {
    position: relative;
    padding-left: 0.9375rem;
}

/* O trilho — assinatura da tela. Cor = status comercial do registro. */
.app-rail {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    width: 3px;
    background: var(--ui-line);
    transition: width 120ms var(--ui-ease);
}

:is(.app-page, .app-modal) .app-table tbody tr:hover .app-rail {
    width: 5px;
}

.app-rail--ok { background: var(--ui-ok); }
.app-rail--info { background: var(--ui-info); }
.app-rail--warn { background: var(--ui-warn); }
.app-rail--danger { background: var(--ui-danger); }
.app-rail--accent { background: var(--ui-accent); }
.app-rail--neutral { background: var(--ui-line); }

:is(.app-page, .app-modal) .app-table thead th.c-right {
    text-align: right;
}

/* Conteúdo das células ------------------------------------------------- */

.c-stack {
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.c-strong {
    color: var(--ui-ink);
    font-weight: 600;
    letter-spacing: -0.01em;
}

.c-meta {
    color: var(--ui-ink-3);
    font-size: 0.6875rem;
    font-weight: 500;
    line-height: 1.3;
}

/* Números, CNPJ, datas e valores alinham por dígito */
.c-num {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}

.c-right {
    text-align: right;
}

.c-nowrap {
    white-space: nowrap;
}

.c-truncate {
    display: block;
    /* O teto em vw impede que uma célula longa empurre a tabela para além da
       tela: #content-wrapper usa `overflow-x: clip`, então o excesso ficaria
       cortado e inalcançável.
       O piso é igualmente necessário: `overflow: hidden` zera a largura
       mínima da célula, e sem ele o DataTables entende que tudo cabe e
       espreme as colunas em vez de recolhê-las (Responsive). */
    min-width: 7rem;
    max-width: min(15rem, 44vw);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* A coluna-âncora comporta nomes longos antes de cortar — sem isso ela
   consome a largura das demais e o Responsive recolhe colunas úteis. */
.c-truncate--wide {
    min-width: 12rem;
    max-width: min(22rem, 56vw);
}

:is(.app-page, .app-modal) .c-link {
    color: var(--ui-ink-2);
    text-decoration: none;
    border-bottom: 1px solid transparent;
}

:is(.app-page, .app-modal) .c-link:hover {
    color: var(--ui-accent-ink);
    border-bottom-color: rgba(109, 67, 232, 0.35);
    text-decoration: none;
}

.c-empty {
    color: #c3c1d4;
}

/* Sigla de UF — tag quadrada, largura fixa, para varredura vertical */
.app-uf {
    display: inline-block;
    min-width: 1.75rem;
    padding: 0.0625rem 0.25rem;
    border: 1px solid var(--ui-line);
    border-radius: 4px;
    background: var(--ui-surface-2);
    color: var(--ui-ink-2);
    font-size: 0.625rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-align: center;
}

/* Selos — tinta suave, para não competir com o trilho */
.app-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.3125rem;
    padding: 0.1875rem 0.5rem;
    border-radius: 999px;
    background: var(--ui-neutral-soft);
    color: var(--ui-ink-2);
    font-size: 0.6875rem;
    font-weight: 600;
    line-height: 1.3;
    white-space: nowrap;
}

.app-badge::before {
    content: "";
    flex: 0 0 auto;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: currentColor;
}

.app-badge--plain::before {
    display: none;
}

.app-badge--ok { background: var(--ui-ok-soft); color: #0b7a5c; }
.app-badge--info { background: var(--ui-info-soft); color: #245ea8; }
.app-badge--warn { background: var(--ui-warn-soft); color: #96620a; }
.app-badge--danger { background: var(--ui-danger-soft); color: #b2333d; }
.app-badge--accent { background: var(--ui-accent-soft); color: var(--ui-accent-ink); }

/* Botões de ação dentro da tabela */
:is(.app-page, .app-modal) .app-table .btn-group {
    display: inline-flex;
    gap: 4px;
}

:is(.app-page, .app-modal) .app-table .btn-group > .btn,
:is(.app-page, .app-modal) .app-rowactions > .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.3125rem;
    min-width: 30px;
    /* Anula o `min-height` do botão padrão: a ação de linha é mais baixa. */
    min-height: 30px;
    height: 30px;
    padding: 0 0.5rem;
    border: 1px solid var(--ui-line);
    border-radius: var(--ui-radius-sm);
    background: var(--ui-surface);
    color: var(--ui-ink-2);
    font-family: inherit;
    font-size: 0.75rem;
    font-weight: 500;
    line-height: 1;
    box-shadow: none;
}

:is(.app-page, .app-modal) .app-rowactions {
    display: inline-flex;
    gap: 4px;
    /* Reserva a largura dos botões (quantos forem), senão a coluna encolhe e
       eles transbordam da célula. */
    min-width: max-content;
}

:is(.app-page, .app-modal) .app-table .btn-group > .btn:hover,
:is(.app-page, .app-modal) .app-rowactions > .btn:hover {
    border-color: #d3ccf5;
    background: var(--ui-accent-soft);
    color: var(--ui-accent-ink);
}

:is(.app-page, .app-modal) .app-table .btn-group > .btn.btn-outline-danger:hover,
:is(.app-page, .app-modal) .app-rowactions > .btn.btn-outline-danger:hover {
    border-color: #f3c2c6;
    background: var(--ui-danger-soft);
    color: var(--ui-danger);
}

:is(.app-page, .app-modal) .app-table .btn-group > .btn:focus-visible,
:is(.app-page, .app-modal) .app-rowactions > .btn:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(109, 67, 232, 0.28);
}

/* --------------------------------------------------------------------------
   6. Integração com DataTables
   Layout esperado no `dom`:
     "<'app-tablebar'<'app-tablebar__start'l><'app-tablebar__end'fB>>
      r<'app-tablescroll't>
      <'app-tablefoot'<'app-tablefoot__start'i><'app-tablefoot__end'p>>"
   -------------------------------------------------------------------------- */

:is(.app-page, .app-modal) .dataTables_wrapper {
    position: relative;
}

.app-tablebar,
.app-tablefoot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.5rem 0.75rem;
    padding: 0.5rem 0.875rem;
    background: var(--ui-surface-2);
}

.app-tablebar {
    min-height: 44px;
    border-bottom: 1px solid var(--ui-line);
}

.app-tablefoot {
    border-top: 1px solid var(--ui-line);
}

.app-tablebar__start,
.app-tablebar__end,
.app-tablefoot__start,
.app-tablefoot__end {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
}

:is(.app-page, .app-modal) .dataTables_length,
:is(.app-page, .app-modal) .dataTables_filter,
:is(.app-page, .app-modal) .dataTables_info,
:is(.app-page, .app-modal) .dataTables_paginate,
:is(.app-page, .app-modal) .dt-buttons {
    margin: 0;
    padding: 0;
    float: none;
    text-align: left;
}

:is(.app-page, .app-modal) .dataTables_length label,
:is(.app-page, .app-modal) .dataTables_filter label {
    display: inline-flex;
    align-items: center;
    gap: 0.4375rem;
    margin: 0;
    white-space: nowrap;
    color: var(--ui-ink-3);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
}

:is(.app-page, .app-modal) .dataTables_length select {
    height: 30px;
    min-width: 4.25rem;
    padding: 0 1.5rem 0 0.5rem;
    border: 1px solid var(--ui-line);
    border-radius: var(--ui-radius-sm);
    background-color: var(--ui-surface);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%238a87a6'%3E%3Cpath d='M8 11 3.5 6h9z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.375rem center;
    background-size: 12px;
    color: var(--ui-ink);
    font-family: inherit;
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0;
    text-transform: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    cursor: pointer;
}

:is(.app-page, .app-modal) .dataTables_filter input {
    width: 16rem;
    max-width: 45vw;
    height: 30px;
    padding: 0 0.625rem;
    border: 1px solid var(--ui-line);
    border-radius: var(--ui-radius-sm);
    background: var(--ui-surface);
    color: var(--ui-ink);
    font-family: inherit;
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0;
    text-transform: none;
}

:is(.app-page, .app-modal) .dataTables_length select:focus,
:is(.app-page, .app-modal) .dataTables_filter input:focus {
    outline: none;
    border-color: var(--ui-accent);
    box-shadow: 0 0 0 3px rgba(109, 67, 232, 0.16);
}

/* Botões de exportação */
/* Os `!important` existem por causa de listing-pages.css, que estiliza
   `.dt-button` sem escopo e com `!important`. Enquanto houver telas usando os
   dois arquivos (ex.: empresas-edit.php, em migração), é o que mantém os
   botões coerentes. Podem sair quando listing-pages.css for aposentado. */
:is(.app-page, .app-modal) .dt-buttons .dt-button {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    height: 30px;
    margin: 0 !important;
    padding: 0 0.6875rem !important;
    border: 1px solid var(--ui-line) !important;
    border-radius: var(--ui-radius-sm) !important;
    background: var(--ui-surface) !important;
    color: var(--ui-ink-2) !important;
    font-family: inherit;
    font-size: 0.75rem;
    font-weight: 500 !important;
    line-height: 1;
    letter-spacing: 0 !important;
    text-transform: none !important;
    box-shadow: none !important;
    transform: none !important;
}

:is(.app-page, .app-modal) .dt-buttons .dt-button:hover:not(.disabled) {
    border-color: #d3ccf5 !important;
    background: var(--ui-accent-soft) !important;
    color: var(--ui-accent-ink) !important;
    transform: none !important;
    box-shadow: none !important;
}

:is(.app-page, .app-modal) .dt-buttons .dt-button:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(109, 67, 232, 0.28);
}

/* Rodapé: contagem e paginação */
:is(.app-page, .app-modal) .dataTables_info {
    color: var(--ui-ink-3);
    font-size: 0.75rem;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}

:is(.app-page, .app-modal) .dataTables_paginate .pagination {
    margin: 0;
    gap: 2px;
}

:is(.app-page, .app-modal) .dataTables_paginate .page-item .page-link {
    min-width: 30px;
    height: 30px;
    padding: 0 0.5rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid transparent;
    border-radius: var(--ui-radius-sm);
    background: transparent;
    color: var(--ui-ink-2);
    font-size: 0.75rem;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

:is(.app-page, .app-modal) .dataTables_paginate .page-item .page-link:hover {
    background: var(--ui-hover);
    color: var(--ui-accent-ink);
}

:is(.app-page, .app-modal) .dataTables_paginate .page-item.active .page-link {
    border-color: var(--ui-ink);
    background: var(--ui-ink);
    color: #fff;
}

:is(.app-page, .app-modal) .dataTables_paginate .page-item.disabled .page-link {
    background: transparent;
    color: #c3c1d4;
}

:is(.app-page, .app-modal) .dataTables_paginate .page-item .page-link:focus {
    outline: none;
    box-shadow: 0 0 0 3px rgba(109, 67, 232, 0.28);
}

/* Indicador de carregamento — chip discreto no topo da tabela */
:is(.app-page, .app-modal) .dataTables_processing {
    position: absolute;
    display: block;
    top: 52px;
    left: 50%;
    z-index: 5;
    width: auto;
    margin: 0;
    padding: 0.3125rem 0.75rem;
    border: 1px solid var(--ui-line);
    border-radius: 999px;
    background: var(--ui-surface);
    box-shadow: var(--ui-shadow);
    color: var(--ui-ink-2);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-align: center;
    transform: translateX(-50%);
}

:is(.app-page, .app-modal) .dataTables_empty {
    padding: 2.5rem 1rem;
    color: var(--ui-ink-3);
    font-size: 0.8125rem;
    text-align: center;
}

/* Indicadores de ordenação — ícones Font Awesome no lugar das setas padrão.
   Só aparecem em tabelas que realmente ordenam. */
:is(.app-page, .app-modal) .app-table thead th.sorting,
:is(.app-page, .app-modal) .app-table thead th.sorting_asc,
:is(.app-page, .app-modal) .app-table thead th.sorting_desc {
    position: relative;
    padding-right: 1.5rem;
    cursor: pointer;
}

:is(.app-page, .app-modal) .app-table thead th.sorting::before,
:is(.app-page, .app-modal) .app-table thead th.sorting_asc::before,
:is(.app-page, .app-modal) .app-table thead th.sorting_desc::before {
    display: none;
}

:is(.app-page, .app-modal) .app-table thead th.sorting::after,
:is(.app-page, .app-modal) .app-table thead th.sorting_asc::after,
:is(.app-page, .app-modal) .app-table thead th.sorting_desc::after {
    position: absolute;
    right: 0.5rem;
    bottom: auto;
    top: 50%;
    display: block;
    font-family: "Font Awesome 5 Free";
    font-size: 0.6875rem;
    font-weight: 900;
    opacity: 1;
    transform: translateY(-50%);
}

:is(.app-page, .app-modal) .app-table thead th.sorting::after {
    content: "\f0dc";
    color: #c3c1d4;
}

:is(.app-page, .app-modal) .app-table thead th.sorting_asc::after {
    content: "\f0de";
    color: var(--ui-accent);
}

:is(.app-page, .app-modal) .app-table thead th.sorting_desc::after {
    content: "\f0dd";
    color: var(--ui-accent);
}

/* Responsive: controle de expansão e linha de detalhes.
   O CSS do Responsive/Bootstrap 4 qualifica as linhas com `tr[role="row"]`
   e é carregado depois deste arquivo — por isso os seletores abaixo repetem
   esse atributo: sem ele há empate de especificidade e o padrão vence. */
:is(.app-page, .app-modal) table.app-table.dtr-inline.collapsed > tbody > tr[role="row"] > td:first-child {
    position: relative;
    padding-left: 2.25rem;
    cursor: pointer;
}

:is(.app-page, .app-modal) table.app-table.dtr-inline.collapsed > tbody > tr[role="row"] > td:first-child::before {
    content: "\f067";
    top: 50%;
    left: 0.6875rem;
    height: 17px;
    width: 17px;
    margin: 0;
    border: 1px solid var(--ui-line);
    border-radius: 5px;
    background-color: var(--ui-surface);
    box-shadow: none;
    box-sizing: border-box;
    color: var(--ui-accent);
    font-family: "Font Awesome 5 Free";
    font-size: 0.5rem;
    font-weight: 900;
    line-height: 15px;
    text-align: center;
    text-indent: 0;
    transform: translateY(-50%);
}

:is(.app-page, .app-modal) table.app-table.dtr-inline.collapsed > tbody > tr.parent[role="row"] > td:first-child::before {
    content: "\f068";
    border-color: var(--ui-accent);
    background-color: var(--ui-accent);
    color: #fff;
}

:is(.app-page, .app-modal) table.app-table > tbody > tr.child > td {
    padding: 0.625rem 0.9375rem;
    background: var(--ui-canvas);
}

:is(.app-page, .app-modal) table.app-table > tbody > tr.child:hover > td {
    background: var(--ui-canvas);
}

:is(.app-page, .app-modal) table.app-table > tbody > tr.child ul.dtr-details {
    display: block;
    width: 100%;
    margin: 0;
    padding: 0;
    list-style: none;
}

:is(.app-page, .app-modal) table.app-table > tbody > tr.child ul.dtr-details > li {
    display: flex;
    align-items: baseline;
    gap: 0.625rem;
    padding: 0.25rem 0;
    border: 0;
    border-bottom: 1px solid var(--ui-line);
}

:is(.app-page, .app-modal) table.app-table > tbody > tr.child ul.dtr-details > li:last-child {
    border-bottom: 0;
}

:is(.app-page, .app-modal) table.app-table > tbody > tr.child ul.dtr-details > li > .dtr-title {
    flex: 0 0 9rem;
    min-width: 9rem;
    color: var(--ui-ink-3);
    font-size: 0.625rem;
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
}

/* Na linha expandida há espaço para ler o valor inteiro — o truncamento
   existe para a célula da tabela, não para cá. */
:is(.app-page, .app-modal) table.app-table > tbody > tr.child .c-truncate {
    max-width: none;
    white-space: normal;
    overflow: visible;
}

:is(.app-page, .app-modal) table.app-table > tbody > tr.child ul.dtr-details > li > .dtr-data {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 0.78125rem;
}

/* --------------------------------------------------------------------------
   7. Integração com Select2
   O dropdown é anexado ao <body>, então usa uma variante própria (--app)
   aplicada via `selectionCssClass`/`dropdownCssClass` ou globalmente.
   -------------------------------------------------------------------------- */

:is(.app-page, .app-modal) .select2-container--default .select2-selection--single,
:is(.app-page, .app-modal) .select2-container--default .select2-selection--multiple {
    min-height: 36px;
    border: 1px solid var(--ui-line);
    border-radius: var(--ui-radius-sm);
    background: var(--ui-surface);
}

:is(.app-page, .app-modal) .select2-container--default .select2-selection--single {
    height: 36px;
}

:is(.app-page, .app-modal) .select2-container--default .select2-selection--single .select2-selection__rendered {
    padding-left: 0.625rem;
    color: var(--ui-ink);
    font-size: 0.8125rem;
    line-height: 34px;
}

:is(.app-page, .app-modal) .select2-container--default .select2-selection--single .select2-selection__arrow {
    height: 34px;
}

:is(.app-page, .app-modal) .select2-container--default.select2-container--focus .select2-selection--multiple,
:is(.app-page, .app-modal) .select2-container--default.select2-container--open .select2-selection--single {
    border-color: var(--ui-accent);
    box-shadow: 0 0 0 3px rgba(109, 67, 232, 0.16);
}

:is(.app-page, .app-modal) .select2-container--default .select2-selection--multiple {
    padding: 0.125rem 0.25rem;
}

:is(.app-page, .app-modal) .select2-container--default .select2-selection--multiple .select2-selection__choice {
    margin: 3px 3px 0 0;
    padding: 0.125rem 0.5rem;
    border: 1px solid #ddd5f8;
    border-radius: 999px;
    background: var(--ui-accent-soft);
    color: var(--ui-accent-ink);
    font-size: 0.6875rem;
    font-weight: 500;
}

:is(.app-page, .app-modal) .select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
    margin-right: 0.25rem;
    color: var(--ui-accent-ink);
    font-weight: 600;
}

:is(.app-page, .app-modal) .select2-container--default .select2-search--inline .select2-search__field {
    margin-top: 6px;
    font-family: inherit;
    font-size: 0.8125rem;
}

.select2-dropdown {
    border-color: var(--ui-line);
    border-radius: var(--ui-radius-sm);
    box-shadow: 0 12px 32px -12px rgba(33, 29, 69, 0.28);
    font-family: var(--ui-font);
    font-size: 0.8125rem;
}

.select2-container--default .select2-results__option--highlighted[aria-selected] {
    background: var(--ui-accent);
}

/* --------------------------------------------------------------------------
   8. Estado vazio
   -------------------------------------------------------------------------- */

.app-empty {
    padding: 2.5rem 1.25rem;
    text-align: center;
}

.app-empty__title {
    margin: 0 0 0.25rem;
    color: var(--ui-ink);
    font-size: 0.875rem;
    font-weight: 600;
}

.app-empty__text {
    margin: 0 0 0.875rem;
    color: var(--ui-ink-3);
    font-size: 0.8125rem;
}

/* --------------------------------------------------------------------------
   9. Responsivo
   -------------------------------------------------------------------------- */

@media (max-width: 991.98px) {
    .app-toolbar__row {
        flex-direction: column;
        align-items: stretch;
    }

    .app-toolbar__label {
        width: auto;
        padding-top: 0;
    }

    .app-field,
    .app-field--grow {
        flex: 1 1 auto;
        width: 100%;
    }

    .app-toolbar__row--fields > .app-btn {
        width: 100%;
    }

    /* Empilhados, os campos não têm mais rótulo irmão para acompanhar: o
       recuo de alinhamento viraria um vão solto. */
    :is(.app-page, .app-modal) .app-toolbar .app-form__aligned {
        padding-top: 0;
    }
}

@media (max-width: 767.98px) {
    .app-page {
        padding: 1rem 1rem 2rem;
    }

    .app-page__head {
        flex-wrap: wrap;
    }

    /* Com a quebra ligada, a base `auto` faz o bloco de título pedir a largura
       do seu texto inteiro e descer sozinho para a linha de baixo, deixando o
       traço órfão em cima. Base zero o mantém ao lado do traço; quem desce é o
       bloco de ações, como se quer. */
    .app-page__id {
        flex: 1 1 0;
    }

    .app-page__actions {
        width: 100%;
    }

    .app-page__actions .app-btn {
        flex: 1 1 auto;
    }

    /* Os chips ganham rolagem horizontal em vez de empilhar em quatro linhas */
    .app-chips {
        flex-wrap: nowrap;
        overflow-x: auto;
        padding-bottom: 0.25rem;
        scrollbar-width: thin;
    }

    .app-tablebar__start,
    .app-tablebar__end,
    .app-tablefoot__start,
    .app-tablefoot__end {
        flex: 1 1 100%;
        justify-content: space-between;
    }

    :is(.app-page, .app-modal) .dataTables_filter input {
        width: 100%;
        max-width: none;
    }

    :is(.app-page, .app-modal) table.app-table > tbody > tr.child ul.dtr-details > li {
        flex-direction: column;
        align-items: flex-start;
        gap: 1px;
    }

    :is(.app-page, .app-modal) table.app-table > tbody > tr.child ul.dtr-details > li > .dtr-title {
        flex: 0 0 auto;
        min-width: 0;
    }
}

@media (prefers-reduced-motion: reduce) {
    .app-page *,
    .app-page *::before,
    .app-page *::after {
        transition-duration: 0.01ms !important;
        animation-duration: 0.01ms !important;
    }
}

/* --------------------------------------------------------------------------
   10. Formulários (telas de cadastro e edição)

   Estilizam-se as classes do próprio Bootstrap (`form-control`, `form-group`,
   `form-row`, `label`) dentro do escopo `.app-page`. Assim converter um
   formulário é trocar só a casca: os campos, ids, names e ganchos de JS ficam
   exatamente como estão.
   -------------------------------------------------------------------------- */

:is(.app-page, .app-modal) .app-form {
    margin: 0;
}

/* Título de seção — mesmo tratamento dos rótulos de filtro e das seções do menu */
:is(.app-page, .app-modal) .app-form__section-title {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin: 0 0 0.875rem;
    color: var(--ui-ink-3);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    line-height: 1.3;
}

:is(.app-page, .app-modal) .app-form__section-title::after {
    content: "";
    flex: 1 1 auto;
    height: 1px;
    background: var(--ui-line);
}

:is(.app-page, .app-modal) .app-form__section + .app-form__section {
    margin-top: 1.5rem;
}

/* Grade — mantém `form-row`/`form-group` do Bootstrap, só ajusta o ritmo */
:is(.app-page, .app-modal) .form-row {
    margin-right: -0.5rem;
    margin-left: -0.5rem;
}

:is(.app-page, .app-modal) .form-row > [class*="col-"] {
    padding-right: 0.5rem;
    padding-left: 0.5rem;
}

:is(.app-page, .app-modal) .form-group {
    margin-bottom: 0.875rem;
}

:is(.app-page, .app-modal) .form-group > label,
:is(.app-page, .app-modal) .app-form label {
    display: block;
    margin-bottom: 0.3125rem;
    color: var(--ui-ink-2);
    font-size: 0.75rem;
    font-weight: 500;
    line-height: 1.3;
}

/* Campos */
:is(.app-page, .app-modal) .form-control,
:is(.app-page, .app-modal) textarea.form-control,
:is(.app-page, .app-modal) select.form-control {
    height: 36px;
    padding: 0.4375rem 0.625rem;
    border: 1px solid var(--ui-line);
    border-radius: var(--ui-radius-sm);
    background-color: var(--ui-surface);
    color: var(--ui-ink);
    font-family: inherit;
    font-size: 0.8125rem;
    line-height: 1.3;
    box-shadow: none;
    transition: border-color var(--ui-speed) var(--ui-ease),
                box-shadow var(--ui-speed) var(--ui-ease);
}

:is(.app-page, .app-modal) textarea.form-control {
    height: auto;
    min-height: 72px;
    line-height: 1.45;
}

:is(.app-page, .app-modal) .form-control:focus {
    border-color: var(--ui-accent);
    background-color: var(--ui-surface);
    color: var(--ui-ink);
    box-shadow: 0 0 0 3px rgba(109, 67, 232, 0.16);
}

:is(.app-page, .app-modal) .form-control::placeholder {
    color: #b7b4c8;
}

:is(.app-page, .app-modal) .form-control:disabled,
:is(.app-page, .app-modal) .form-control[readonly] {
    background-color: var(--ui-surface-2);
    color: var(--ui-ink-3);
}

:is(.app-page, .app-modal) select.form-control:not([multiple]) {
    padding-right: 1.75rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%238a87a6'%3E%3Cpath d='M8 11 3.5 6h9z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.5rem center;
    background-size: 12px;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    cursor: pointer;
}

/* Campo inválido depois de uma tentativa de envio */
:is(.app-page, .app-modal) .form-control.is-invalid,
:is(.app-page, .app-modal) .was-validated .form-control:invalid {
    border-color: var(--ui-danger);
    box-shadow: 0 0 0 3px rgba(214, 69, 80, 0.14);
}

:is(.app-page, .app-modal) .app-form__hint {
    display: block;
    margin-top: 0.25rem;
    color: var(--ui-ink-3);
    font-size: 0.6875rem;
    line-height: 1.35;
}

/* Marcador de obrigatório */
:is(.app-page, .app-modal) .app-req {
    color: var(--ui-accent);
    font-weight: 600;
}

/* Checkbox no formato de botão (padrão `btn-check` já usado nas telas) */
:is(.app-page, .app-modal) .btn-check {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

:is(.app-page, .app-modal) .btn-check + .btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4375rem;
    height: 36px;
    padding: 0 0.875rem;
    border: 1px solid var(--ui-line);
    border-radius: var(--ui-radius-sm);
    background: var(--ui-surface);
    color: var(--ui-ink-2);
    font-family: inherit;
    font-size: 0.78125rem;
    font-weight: 500;
    line-height: 1;
    cursor: pointer;
    transition: background-color var(--ui-speed) var(--ui-ease),
                border-color var(--ui-speed) var(--ui-ease),
                color var(--ui-speed) var(--ui-ease);
}

:is(.app-page, .app-modal) .btn-check + .btn:hover {
    border-color: #d3ccf5;
    background: var(--ui-accent-soft);
    color: var(--ui-accent-ink);
}

:is(.app-page, .app-modal) .btn-check:checked + .btn {
    border-color: var(--ui-ok);
    background: var(--ui-ok-soft);
    color: #0b7a5c;
}

:is(.app-page, .app-modal) .btn-check:focus-visible + .btn {
    box-shadow: 0 0 0 3px rgba(109, 67, 232, 0.28);
}

/* Rodapé de ações — separado do formulário por uma linha, ação principal à direita */
:is(.app-page, .app-modal) .app-form__footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.5rem;
    margin-top: 1.25rem;
    padding-top: 1rem;
    border-top: 1px solid var(--ui-line);
}

:is(.app-page, .app-modal) .app-form__footer--split {
    justify-content: space-between;
}

:is(.app-page, .app-modal) .app-form__footer .app-btn {
    min-width: 6rem;
}

@media (max-width: 575.98px) {
    :is(.app-page, .app-modal) .app-form__footer {
        flex-direction: column-reverse;
        align-items: stretch;
    }

    :is(.app-page, .app-modal) .app-form__footer .app-btn {
        width: 100%;
    }
}

/* Alinha um controle sem rótulo com os campos rotulados da mesma linha
   (altura do rótulo + a margem abaixo dele). */
:is(.app-page, .app-modal) .app-form__aligned {
    padding-top: 1.4375rem;
}

/* --------------------------------------------------------------------------
   11. Modais

   `.app-modal` vai no elemento `.modal` do Bootstrap. Além de desenhar a
   moldura do diálogo, ele é o segundo escopo do arquivo: tudo que está dentro
   recebe o mesmo tratamento de campos, botões e tabelas da casca da página.
   Os atributos do Bootstrap (`data-dismiss`, `data-toggle`, `fade`) continuam
   onde estão — quem abre e fecha o modal é o JS dele.
   -------------------------------------------------------------------------- */

.app-modal .modal-content {
    border: 1px solid var(--ui-line);
    border-radius: 12px;
    background: var(--ui-surface);
    box-shadow: 0 24px 60px -20px rgba(33, 29, 69, 0.45);
    font-family: var(--ui-font);
    color: var(--ui-ink);
    overflow: hidden;
}

/* O cabeçalho repete a superfície do menu lateral: o modal é uma camada
   acima da página, e a noite da marca é o que diz isso. */
.app-modal .modal-header {
    align-items: center;
    gap: 0.75rem;
    min-height: 52px;
    padding: 0.75rem 1.25rem;
    border-bottom: 1px solid var(--ui-night-line);
    background-color: var(--ui-night-bottom);
    background-image:
        radial-gradient(120% 180% at 0% 0%, var(--ui-night-glow) 0%, transparent 62%),
        linear-gradient(135deg, var(--ui-night-top) 0%, var(--ui-night-bottom) 100%);
}

.app-modal .modal-title {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
    color: #fff;
    font-size: 0.875rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    line-height: 1.3;
}

.app-modal .modal-title .fas,
.app-modal .modal-title .far,
.app-modal .modal-title .fab {
    color: rgba(255, 255, 255, 0.7);
    font-size: 0.8125rem;
}

/* Botão de fechar do Bootstrap 4 (`<button class="close">&times;</button>`) */
.app-modal .modal-header .close {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    margin: 0 0 0 auto;
    padding: 0;
    border: 1px solid transparent;
    border-radius: var(--ui-radius-sm);
    background: transparent;
    color: rgba(255, 255, 255, 0.65);
    font-size: 1.125rem;
    font-weight: 400;
    line-height: 1;
    opacity: 1;
    text-shadow: none;
    cursor: pointer;
    transition: background-color var(--ui-speed) var(--ui-ease),
                color var(--ui-speed) var(--ui-ease);
}

.app-modal .modal-header .close:hover {
    background: rgba(255, 255, 255, 0.12);
    color: #fff;
    opacity: 1;
}

.app-modal .modal-header .close:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(167, 139, 250, 0.55);
}

.app-modal .modal-body {
    padding: 1.25rem;
}

/* Pares rótulo/valor de um modal de detalhes ficam em ritmo de leitura, não
   com a margem de parágrafo do Bootstrap. */
.app-modal .modal-body p {
    margin-bottom: 0.4375rem;
    font-size: 0.8125rem;
    line-height: 1.45;
}

.app-modal .modal-body p strong {
    color: var(--ui-ink);
    font-weight: 600;
}

.app-modal .modal-footer {
    justify-content: flex-end;
    gap: 0.5rem;
    padding: 0.875rem 1.25rem;
    border-top: 1px solid var(--ui-line);
    background: var(--ui-surface-2);
}

/* O Bootstrap põe margem em cada filho do rodapé; o `gap` já resolve o espaço */
.app-modal .modal-footer > * {
    margin: 0;
}

.app-modal .modal-footer .app-btn {
    min-width: 6rem;
}

/* Modal enxuto (uma confirmação, um campo só) */
.app-modal--sm .modal-body {
    padding: 1.125rem 1.25rem;
}

.app-modal--sm .modal-body p {
    margin: 0;
    color: var(--ui-ink-2);
    font-size: 0.8125rem;
    line-height: 1.5;
}

/* Dentro de um modal o formulário não repete a moldura do cartão */
.app-modal .app-form__footer {
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
}

/* --------------------------------------------------------------------------
   12. Ação ao lado de um rótulo ("+ adicionar categoria")
   -------------------------------------------------------------------------- */

:is(.app-page, .app-modal) .app-field__row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
}

:is(.app-page, .app-modal) .app-field__action {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    margin-bottom: 0.3125rem;
    color: var(--ui-accent);
    font-size: 0.6875rem;
    font-weight: 500;
    line-height: 1.3;
    text-decoration: none;
    white-space: nowrap;
}

:is(.app-page, .app-modal) .app-field__action:hover {
    color: var(--ui-accent-ink);
    text-decoration: underline;
}

:is(.app-page, .app-modal) .app-field__action:focus-visible {
    outline: none;
    border-radius: 4px;
    box-shadow: 0 0 0 3px rgba(109, 67, 232, 0.28);
}

/* Avatar/identidade no cabeçalho de uma tela de edição */
.app-page__avatar {
    flex: 0 0 auto;
    width: 46px;
    height: 46px;
    border-radius: 10px;
    object-fit: cover;
    object-position: center;
    border: 1px solid var(--ui-line);
    background: var(--ui-surface-2);
}

/* Bloco de apoio dentro de um formulário (um grupo de opções, um aviso) */
:is(.app-page, .app-modal) .app-form__panel {
    padding: 0.875rem 1rem;
    border: 1px solid var(--ui-line);
    border-radius: var(--ui-radius-sm);
    background: var(--ui-canvas);
}

:is(.app-page, .app-modal) .app-form__panel > p {
    margin: 0 0 0.75rem;
    color: var(--ui-ink-3);
    font-size: 0.75rem;
    line-height: 1.45;
}

/* Checkbox padrão do Bootstrap dentro do escopo */
:is(.app-page, .app-modal) .custom-control-label {
    color: var(--ui-ink-2);
    font-size: 0.8125rem;
    font-weight: 500;
}

:is(.app-page, .app-modal) .custom-control-input:checked ~ .custom-control-label::before {
    border-color: var(--ui-accent);
    background-color: var(--ui-accent);
}

/* --------------------------------------------------------------------------
   13. Barra de progresso (avanço de uma operação, de uma meta)
   -------------------------------------------------------------------------- */

:is(.app-page, .app-modal) .app-progress {
    min-width: 8rem;
}

:is(.app-page, .app-modal) .app-progress__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.25rem;
    color: var(--ui-ink-3);
    font-size: 0.6875rem;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}

:is(.app-page, .app-modal) .app-progress__head strong {
    color: var(--ui-ink-2);
    font-weight: 600;
}

:is(.app-page, .app-modal) .app-progress__track {
    height: 5px;
    border-radius: 999px;
    background: var(--ui-line);
    overflow: hidden;
}

:is(.app-page, .app-modal) .app-progress__bar {
    height: 100%;
    border-radius: 999px;
    background: var(--ui-ok);
}

:is(.app-page, .app-modal) .app-progress__bar--info { background: var(--ui-info); }
:is(.app-page, .app-modal) .app-progress__bar--warn { background: var(--ui-warn); }

/* Progresso indeterminado — para a espera que não tem percentual, só duração.
   A faixa percorre o trilho para dizer "ainda trabalhando", sem prometer um
   avanço que o servidor não informa. */
:is(.app-page, .app-modal) .app-progress--wait .app-progress__track {
    position: relative;
    /* Separado do texto acima: colado, o trilho vira sublinhado do parágrafo. */
    margin-top: 1rem;
}

:is(.app-page, .app-modal) .app-progress--wait .app-progress__bar {
    position: absolute;
    width: 35%;
    background: var(--ui-accent);
    animation: app-progress-wait 1.4s var(--ui-ease) infinite;
}

@keyframes app-progress-wait {
    0% { left: -35%; }
    100% { left: 100%; }
}

@media (prefers-reduced-motion: reduce) {
    :is(.app-page, .app-modal) .app-progress--wait .app-progress__bar {
        left: 0;
        width: 100%;
        animation: none;
        opacity: 0.5;
    }
}

/* Agrupa ações dentro do rodapé de um formulário, sem repetir a linha
   divisória (que já é do `.app-form__footer`). */
:is(.app-page, .app-modal) .app-form__footer-group {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

/* --------------------------------------------------------------------------
   14. Lista de definição — pares rótulo/valor de uma tela ou modal de detalhes
   -------------------------------------------------------------------------- */

:is(.app-page, .app-modal) .app-deflist__label {
    display: flex;
    align-items: center;
    gap: 0.3125rem;
    margin: 0 0 0.125rem;
    color: var(--ui-ink-3);
    font-size: 0.625rem;
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    line-height: 1.3;
}

:is(.app-page, .app-modal) .app-deflist__value {
    margin: 0 0 0.875rem;
    color: var(--ui-ink);
    font-size: 0.8125rem;
    font-weight: 500;
    line-height: 1.45;
    word-break: break-word;
}

/* Variante em grade: vários pares lado a lado, para os canais de contato de
   um registro (WhatsApp, telefone, e-mail) sem virar três caixinhas coloridas. */
:is(.app-page, .app-modal) .app-deflist--grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: 0.5rem 1.25rem;
    margin-top: 0.5rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--ui-line-soft);
}

:is(.app-page, .app-modal) .app-deflist--grid .app-deflist__value {
    margin-bottom: 0;
}

/* Cada par rótulo/valor é UM item da grade — sem o item, o rótulo cai numa
   coluna e o valor na seguinte. */
:is(.app-page, .app-modal) .app-deflist__item {
    min-width: 0;
}

:is(.app-page, .app-modal) .app-deflist__item--wide {
    grid-column: 1 / -1;
}

/* Um registro apresentado como bloco dentro de uma única célula da tabela */
:is(.app-page, .app-modal) .app-recordblock {
    display: block;
    min-width: 0;
    padding: 0.125rem 0;
}

:is(.app-page, .app-modal) .app-recordblock__top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
}

:is(.app-page, .app-modal) .app-deflist__value:empty::before {
    content: "—";
    color: #c3c1d4;
}

/* --------------------------------------------------------------------------
   15. Métricas — um número que precisa ser lido, não uma frase

   Percentuais, contagens e valores que hoje aparecem como texto corrido
   ("Hon. Grupo Portal: 12,00%") passam a ter rótulo e número separados, com
   algarismos tabulares. Numa tabela, a grade fixa faz os números da mesma
   posição se alinharem de uma linha para a outra — que é o que permite
   comparar.
   -------------------------------------------------------------------------- */

:is(.app-page, .app-modal) .app-metrics {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(5.25rem, 1fr));
    gap: 0.375rem 0.875rem;
    align-items: end;
    min-width: 0;
}

:is(.app-page, .app-modal) .app-metric {
    min-width: 0;
}

:is(.app-page, .app-modal) .app-metric__label {
    display: block;
    margin-bottom: 1px;
    color: var(--ui-ink-3);
    font-size: 0.625rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

:is(.app-page, .app-modal) .app-metric__value {
    display: block;
    color: var(--ui-ink);
    font-size: 0.875rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
    letter-spacing: -0.01em;
    line-height: 1.2;
    white-space: nowrap;
}

/* A unidade acompanha o número sem competir com ele */
:is(.app-page, .app-modal) .app-metric__unit {
    margin-left: 1px;
    color: var(--ui-ink-3);
    font-size: 0.6875rem;
    font-weight: 500;
}

/* Um valor zerado não merece o mesmo peso de um valor real */
:is(.app-page, .app-modal) .app-metric--zero .app-metric__value {
    color: #b7b4c8;
}

/* Separa um número de natureza diferente dos anteriores (um desconto no meio
   de repasses, por exemplo) */
:is(.app-page, .app-modal) .app-metric--apart {
    padding-left: 0.875rem;
    border-left: 1px solid var(--ui-line);
}

@media (max-width: 575.98px) {
    :is(.app-page, .app-modal) .app-metric--apart {
        padding-left: 0;
        border-left: 0;
    }
}

/* --------------------------------------------------------------------------
   16. Estimativa — o resultado calculado a partir dos campos acima

   Uma linha de resposta (quantos registros os filtros alcançam) com a ação de
   recalcular ao lado. O número vem do JS dentro de um <strong>, e é o <strong>
   que recebe o tratamento de métrica — assim o contrato com o JS continua
   sendo "escreva uma frase curta com o número em negrito".
   -------------------------------------------------------------------------- */

:is(.app-page, .app-modal) .app-estimate {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.875rem;
}

:is(.app-page, .app-modal) .app-estimate__text {
    min-width: 0;
    color: var(--ui-ink-2);
    font-size: 0.8125rem;
    line-height: 1.4;
}

:is(.app-page, .app-modal) .app-estimate__text strong {
    color: var(--ui-ink);
    font-size: 1.0625rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.01em;
}

/* Seção do formulário que deixou de valer por causa de uma escolha acima.
   Substitui o `opacity` + `pointer-events` que o JS aplicava inline. */
:is(.app-page, .app-modal) .app-form__section--off {
    opacity: 0.45;
    pointer-events: none;
}

/* Alternador de conteúdo extra (o "mostrar mais filtros") */
:is(.app-page, .app-modal) .app-disclosure {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--ui-accent);
    font-family: inherit;
    font-size: 0.75rem;
    font-weight: 500;
    text-decoration: none;
    cursor: pointer;
}

:is(.app-page, .app-modal) .app-disclosure:hover {
    color: var(--ui-accent-ink);
    text-decoration: underline;
}

:is(.app-page, .app-modal) .app-disclosure .fa-chevron-down {
    font-size: 0.625rem;
    transition: transform var(--ui-speed) var(--ui-ease);
}

:is(.app-page, .app-modal) .app-disclosure[aria-expanded="true"] .fa-chevron-down {
    transform: rotate(180deg);
}

/* --------------------------------------------------------------------------
   17. Subtabela — o detalhe que abre dentro de uma linha
   -------------------------------------------------------------------------- */

:is(.app-page, .app-modal) .app-subtable {
    padding: 0.75rem 0.875rem 0.875rem;
    border-left: 3px solid var(--ui-accent);
    border-radius: var(--ui-radius-sm);
    background: var(--ui-surface);
}

:is(.app-page, .app-modal) .app-subtable__title {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    margin: 0 0 0.5rem;
    color: var(--ui-ink);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.02em;
}

:is(.app-page, .app-modal) .app-subtable .app-table thead th {
    background: transparent;
    border-bottom-color: var(--ui-line);
}

:is(.app-page, .app-modal) .app-subtable .app-table tbody td {
    background: transparent;
}

:is(.app-page, .app-modal) .app-subtable .app-table tbody td:first-child {
    padding-left: 0.75rem;
}

/* --------------------------------------------------------------------------
   18. Métrica de destaque e faixa de indicadores

   Quando uma tela abre com um número que é a pergunta dela (a cobertura de uma
   base, o avanço de uma meta), esse número lidera e os demais ficam de apoio.
   É o contrário dos quatro quadradinhos coloridos de peso igual: ali a cor
   distingue "caixa 1, 2, 3 e 4", o que não é informação.
   -------------------------------------------------------------------------- */

:is(.app-page, .app-modal) .app-metric--lead .app-metric__value {
    font-size: 1.75rem;
    font-weight: 600;
    letter-spacing: -0.02em;
    line-height: 1.1;
}

:is(.app-page, .app-modal) .app-metric--lead .app-metric__label {
    font-size: 0.6875rem;
}

/* Faixa: a métrica que lidera ao lado do que a explica (uma barra, um gráfico) */
:is(.app-page, .app-modal) .app-statline {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.875rem 1.5rem;
}

/* A barra tem uma medida legível: esticada por toda a largura do cartão, ela
   viraria um fio de 1.200px para descrever um número só. */
:is(.app-page, .app-modal) .app-statline__fill {
    flex: 1 1 14rem;
    min-width: 0;
    max-width: 30rem;
}

/* Os indicadores de apoio, separados da métrica que lidera */
:is(.app-page, .app-modal) .app-metrics--support {
    margin-top: 0.875rem;
    padding-top: 0.875rem;
    border-top: 1px solid var(--ui-line-soft);
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
}

/* --------------------------------------------------------------------------
   19. Registro de versões — a calha de números como espinha da página

   A forma vem dos dados: das 39 versões registradas, 30 trouxeram uma única
   mudança. Dar cabeçalho, contador e lista a cada uma delas encheria a página
   de vão; por isso a versão de mudança única ocupa uma linha só, e a calha
   mantém todos os números alinhados de cima a baixo.
   -------------------------------------------------------------------------- */

:is(.app-page, .app-modal) .app-releases {
    display: flex;
    flex-direction: column;
}

:is(.app-page, .app-modal) .app-release {
    display: grid;
    grid-template-columns: 5rem minmax(0, 1fr);
    gap: 0 1.5rem;
    padding: 0.875rem 0;
}

:is(.app-page, .app-modal) .app-release + .app-release {
    border-top: 1px solid var(--ui-line-soft);
}

:is(.app-page, .app-modal) .app-release:first-child {
    padding-top: 0;
}

:is(.app-page, .app-modal) .app-release:last-child {
    padding-bottom: 0;
}

/* O número é o elemento focal: algarismos tabulares e caixa apertada para que
   1.8.6 e 2.32 formem uma coluna legível de cima a baixo. */
:is(.app-page, .app-modal) .app-release__version {
    margin: 0;
    color: var(--ui-ink);
    font-size: 1.0625rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
    line-height: 1.35;
}

:is(.app-page, .app-modal) .app-release--current .app-release__version {
    color: var(--ui-accent);
}

:is(.app-page, .app-modal) .app-release__body {
    min-width: 0;
    max-width: 68ch;
}

/* Linha de apoio do cabeçalho: só aparece quando há algo a dizer (a marca de
   versão atual, ou a contagem quando o lote é grande o bastante para ela
   informar alguma coisa). */
:is(.app-page, .app-modal) .app-release__meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}

:is(.app-page, .app-modal) .app-release__count {
    color: var(--ui-ink-3);
    font-size: 0.75rem;
    font-variant-numeric: tabular-nums;
}

:is(.app-page, .app-modal) .app-release__list {
    margin: 0;
    padding: 0;
    list-style: none;
}

:is(.app-page, .app-modal) .app-release__list li,
:is(.app-page, .app-modal) .app-release__text {
    position: relative;
    margin: 0;
    padding-left: 1rem;
    color: var(--ui-ink-2);
    font-size: 0.8125rem;
    line-height: 1.6;
}

:is(.app-page, .app-modal) .app-release__list li + li {
    margin-top: 0.4375rem;
}

/* Marcador discreto — um traço curto no lugar do ponto, na mesma linguagem
   das reticências e dos filetes do resto do sistema. Só as listas o recebem:
   numa versão de mudança única ele seria o marcador de uma lista que não
   existe. O recuo fica de pé nas duas, para a coluna de texto alinhar. */
:is(.app-page, .app-modal) .app-release__list li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.6875rem;
    width: 6px;
    height: 1px;
    background: var(--ui-line);
}

@media (max-width: 575.98px) {
    /* Sem largura para a calha, o número passa a encabeçar o bloco. */
    :is(.app-page, .app-modal) .app-release {
        grid-template-columns: minmax(0, 1fr);
        gap: 0.375rem;
    }
}
