/******************************************** Variáveis ***************************************************/
/* Ajuste de hover para ambos os temas */
html[data-bs-theme="dark"] .table {
    --bs-table-hover-bg: rgba(255, 255, 255, 0.075) !important;
}

html[data-bs-theme="light"] .table {
    --bs-table-hover-bg: rgba(0, 0, 0, 0.075) !important;
}

/* Interface CLÁSSICA — linhas com status (table-success/danger/warning/…) no tema
   ESCURO: apenas o TEXTO ganha a cor do status, SEM o fundo tingido (igual à Nova
   UI). O sistema marca a linha com uma variante Bootstrap conforme o estado do
   registro. Essas variantes foram feitas p/ fundo CLARO: o Bootstrap fixa
   --bs-table-color em #000 (texto preto) e --bs-table-bg num tom pastel dentro da
   própria .table-*. No dark isso deixava o texto ilegível E pintava um fundo claro
   que destoa. Devolvemos a cor do texto ao TOKEN de tema do status (paleta única
   em palette.css: --nui-accent/--nui-danger/--nui-warn-tx/--nui-info) e ZERAMOS o
   fundo (regra .table-* > td/th abaixo), deixando só o texto colorido — a
   diferenciação de status passa a ser a cor da fonte, não o preenchimento. Só no
   dark — no light o texto preto está correto. Mesma cor e mesmo tratamento de
   fundo da Nova UI (nova-ui.css): paleta e comportamento unificados nas duas
   interfaces. Os ícones das células herdam via currentColor. */
html[data-bs-theme="dark"] .table > tbody > tr.table-success {
    --bs-table-color: var(--nui-accent);
    --bs-table-color-state: var(--nui-accent);
}
html[data-bs-theme="dark"] .table > tbody > tr.table-danger {
    --bs-table-color: var(--nui-danger);
    --bs-table-color-state: var(--nui-danger);
}
html[data-bs-theme="dark"] .table > tbody > tr.table-warning {
    --bs-table-color: var(--nui-warn-tx);
    --bs-table-color-state: var(--nui-warn-tx);
}
html[data-bs-theme="dark"] .table > tbody > tr.table-info {
    --bs-table-color: var(--nui-info);
    --bs-table-color-state: var(--nui-info);
}
html[data-bs-theme="dark"] .table > tbody > tr.table-primary,
html[data-bs-theme="dark"] .table > tbody > tr.table-secondary,
html[data-bs-theme="dark"] .table > tbody > tr.table-light,
html[data-bs-theme="dark"] .table > tbody > tr.table-dark {
    --bs-table-color: var(--nui-text);
    --bs-table-color-state: var(--nui-text);
}
/* Zera o fundo tingido das variantes (só texto colorido, igual à Nova UI). O
   Bootstrap aplica o fundo por --bs-table-bg E pelo box-shadow inset (accent-bg);
   sobrescrever direto na célula (não via variável) vence a variante .table-*.
   Espelha nova-ui.css (.table > * > * { background-color: transparent }), mas
   escopado às linhas de status p/ não mexer no fundo das linhas normais. */
html[data-bs-theme="dark"] .table > tbody > tr.table-success > td,
html[data-bs-theme="dark"] .table > tbody > tr.table-success > th,
html[data-bs-theme="dark"] .table > tbody > tr.table-danger > td,
html[data-bs-theme="dark"] .table > tbody > tr.table-danger > th,
html[data-bs-theme="dark"] .table > tbody > tr.table-warning > td,
html[data-bs-theme="dark"] .table > tbody > tr.table-warning > th,
html[data-bs-theme="dark"] .table > tbody > tr.table-info > td,
html[data-bs-theme="dark"] .table > tbody > tr.table-info > th,
html[data-bs-theme="dark"] .table > tbody > tr.table-primary > td,
html[data-bs-theme="dark"] .table > tbody > tr.table-primary > th,
html[data-bs-theme="dark"] .table > tbody > tr.table-secondary > td,
html[data-bs-theme="dark"] .table > tbody > tr.table-secondary > th,
html[data-bs-theme="dark"] .table > tbody > tr.table-light > td,
html[data-bs-theme="dark"] .table > tbody > tr.table-light > th,
html[data-bs-theme="dark"] .table > tbody > tr.table-dark > td,
html[data-bs-theme="dark"] .table > tbody > tr.table-dark > th {
    background-color: transparent;
}

/* LINHAS DE AGRUPAMENTO na interface CLÁSSICA (paridade com a Nova UI). O sistema
   monta cada cabeçalho de grupo como <tr class="table-primary group"> — a classe
   Bootstrap .table-primary dá um azul cru (e no dark some contra o fundo). A Nova
   UI já realça o grupo com superfície de ACENTO SUAVE + texto de acento; a clássica
   não tinha regra própria e, com o zerar-fundo das table-* acima (table-primary
   entra nele), o grupo ficava branco e sem faixa. Aqui damos à clássica o MESMO
   realce da Nova UI. !important vence a regra de fundo transparente acima (a linha
   de grupo também é table-primary). Vale nos 2 temas; a Nova UI tem regra própria
   com especificidade maior, então não há conflito. */
.table tbody tr.group > td,
.table tbody tr.group > th {
    background-color: var(--nui-accent-soft-bg) !important;
    color: var(--nui-accent-soft-tx) !important;
    font-weight: 600;
    border-top: 1px solid var(--nui-border);
    border-bottom: 1px solid var(--nui-border);
}
.table tbody tr.group > td b,
.table tbody tr.group > td strong {
    color: var(--nui-accent-soft-tx);
}

/************************************************** Base **************************************************/
html,
body {
    width: 100%;
    height: 100%;
    padding: 0px;
    margin: 0px;
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    overflow: hidden;
}

a,
tr,
td,
li,
button,
i {
    cursor: pointer;
}

textarea {
    resize: none;
}

/************************************************ Styles ************************************************/
.frames {
    display: flex;
    width: 100%;
    max-height: -webkit-fill-available;
    height: -webkit-fill-available;
    padding: .25rem;
    gap: .25rem;
    background-image: var(--app-background-image, url(../../img/Background.jpg));
    background-size: cover;
}

.window {
    display: flex;
    width: 100%;
    max-height: -webkit-fill-available;
    height: -webkit-fill-available;
    padding: .25rem;
    align-items: stretch;
    justify-content: stretch;
    background-image: var(--app-background-image, url(../../img/Background.jpg));
    background-size: cover;
}

.window>* {
    width: 100%;
    height: 100%;
}

/* Papel de parede no TEMA ESCURO: a mesma foto clara servia aos dois temas e
   "estourava" no escuro. Aqui um véu uniforme entra como PRIMEIRA camada de
   background-image, escurecendo só a imagem — cards, texto e ícones ficam
   intactos (um `filter` atingiria o elemento renderizado inteiro, e um overlay
   em ::before exigiria hierarquia de z-index num container usado por muitas
   telas). A 2ª camada continua sendo a var(--app-background-image), então cada
   derivado preserva a arte própria e nenhum binário é tocado.

   O !important existe por uma razão só: vencer o `style` inline que o layout
   repete no #appContent (layouts/home.blade.php). Não é preferência.

   Escopado a body:not(.nova-ui-shell) porque a Nova UI já remove o papel de
   parede em tema nenhum (nova-ui.css) — sem isso, pintaríamos um véu sobre nada.

   A intensidade sai de um TOKEN em vez de um número cravado na regra, para que
   um ajuste futuro não exija reescrevê-la. O valor foi calibrado contra as NOVE
   artes reais da família (07/08/2026), que vão de 800×300 a 1920×1200 e de
   quase-branca a quase-preta: abaixo de .80 as artes claras (Tekton.DockPass,
   Forth.Comercial, Metha.Telemarketing) continuavam claras demais e o texto
   branco não firmava; acima disso as escuras (Niagro.Portaria, ComissionPro)
   perdem identidade sem ganho de legibilidade. .86 é o ponto em que todas as
   nove ficam legíveis. */
html[data-bs-theme="dark"] body:not(.nova-ui-shell) .frames,
html[data-bs-theme="dark"] body:not(.nova-ui-shell) .window {
    background-image:
        linear-gradient(rgba(var(--bs-secondary-bg-rgb), var(--app-background-veil, .86)),
            rgba(var(--bs-secondary-bg-rgb), var(--app-background-veil, .86))),
        var(--app-background-image, url(../../img/Background.jpg)) !important;
}

.janela {
    overflow: hidden;
    grid-template-rows: 1fr;
}

.janela>.frame {
    min-height: 0;
    overflow: hidden;
}

/************************************************ Tabelas ************************************************/
/* Cabeçalho de tabelas - usando cores do tema */
/* Z-index hierarchy para elementos sticky: thead/tfoot = 3 (highest), groups = 2 (middle), content = default (lowest) */
.table thead.sticky-top {
    z-index: 3;
    position: sticky;
}

.table thead th {
    position: sticky;
    top: 0;
    z-index: 3;
    background-color: var(--bs-secondary-bg);
    color: var(--bs-emphasis-color);
    border-color: var(--bs-border-color);
}

.table tbody tr.group.sticky-top {
    z-index: 2;
}

.table tfoot.sticky-bottom {
    z-index: 3;
    position: sticky;
}

.table>thead>tr>th:has(i.bi-plus-lg) {
    border-left: 1px solid var(--bs-border-color);
    text-align: center;
}

/* Ordenação de colunas */
.table thead th.sortable {
    cursor: pointer;
    user-select: none;
    position: relative;
    padding-right: 2rem;
}

.table thead th.sortable:hover {
    background-color: var(--bs-tertiary-bg);
}

.table thead th.sortable::after {
    content: '⇅';
    position: absolute;
    right: 0.5rem;
    top: 50%;
    transform: translateY(-50%);
    opacity: 0.3;
    font-size: 0.8em;
}

.table thead th.sortable:hover::after {
    opacity: 0.6;
}

.table thead th.sort-asc::after,
.table thead th.sort-desc::after {
    opacity: 1;
    color: var(--bs-primary);
}

.table thead th.sort-asc::after {
    content: '▲';
}

.table thead th.sort-desc::after {
    content: '▼';
}

/* Indicador de ordenação composta (múltiplas colunas) - Badge ao lado da seta */
/* TEXTO SOBRE A COR DO SISTEMA: sempre var(--nui-on-accent), nunca branco fixo. O token é
   branco no tema claro e escuro no tema escuro (onde o acento é claro). Até 10/10/2026 este
   selo, o dia ativo do calendário, o item do campo de vários valores e o botão de tema marcado
   usavam --bs-white/--bs-light e mediam de 1,67 a 2,00 de contraste no tema escuro. */
.table thead th[data-sort-priority]::before {
    content: attr(data-sort-priority);
    position: absolute;
    right: 1.4rem;
    top: 50%;
    transform: translateY(-50%);
    background-color: var(--bs-primary);
    color: var(--nui-on-accent);
    border-radius: 50%;
    width: 0.9rem;
    height: 0.9rem;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.55em;
    font-weight: bold;
    line-height: 1;
}

/* Para títulos alinhados à direita, ajusta posição */
.table thead th.text-end[data-sort-priority]::before {
    right: auto;
    left: 1.4rem;
}

.table thead th.text-end.sortable {
    padding-right: 0.5rem;
    padding-left: 2rem;
}

.table thead th.text-end.sortable::after {
    right: auto;
    left: 0.5rem;
}

/* Esconde badge quando é ordenação única (priority = 1) */
.table thead th[data-sort-priority="1"]::before {
    display: none;
}

/* Corpo das tabelas */
.table tbody td {
    border-color: var(--bs-border-color);
    border-width: 0 1px;
    padding: .25rem .5rem;
}

.table tbody tr.group-total>td {
    border: none;
    padding: .25rem .5rem;
}

.table tbody td:first-child {
    border-left-width: 0;
}

.table tbody td:last-child {
    border-right-width: 0;
}

/*
 * Frames de movimentação (FrotaMovement, VisitanteMovement, etc.): têm muitas colunas
 * (paridade com o legado) e vivem em painéis estreitos — em tablet a última coluna (lápis
 * de Alterar / consultar) ficava fora da área visível, exigindo rolagem horizontal difícil
 * no toque. Fixa a coluna de ação à direita para ficar sempre acessível, sem remover colunas.
 * Escopo restrito aos frames *Movement (não afeta as demais tabelas do sistema).
 */
.table[id$="Movement"] tbody td:last-child,
.table[id$="Movement"] thead th:last-child {
    position: sticky;
    right: 0;
    z-index: 1;
    background-color: var(--bs-body-bg);
}

.table[id$="Movement"] thead th:last-child {
    background-color: var(--bs-tertiary-bg);
}

/* Rodapé das tabelas */
.table tfoot td {
    padding: .25rem .5rem;
    background-color: var(--bs-tertiary-bg);
    color: var(--bs-emphasis-color);
    border-color: var(--bs-border-color);
    font-weight: 500;
}

.table tbody tr.secondary>td {
    color: var(--bs-secondary-color);
}

.table tbody tr.tertiary>td {
    color: var(--bs-tertiary-color);
}

/* LINHA DE STATUS (a `class` que o Model dá ao registro). A cor vem da PALETA, não do
   Bootstrap: o amarelo e o azul do Bootstrap medem 1.63 e 1.96 sobre o cartão do tema
   claro, e o vermelho e o verde, 3.84 sobre o do escuro. Os quatro tokens abaixo são cor
   de texto e passam 4.5 nos dois temas (AparenciaContrasteTest). O segundo valor de cada
   `var()` só vale em página que carrega este arquivo sem a paleta. */
.table tbody tr.danger>td {
    color: var(--nui-st-crit, var(--bs-danger));
}

.table tbody tr.warning>td {
    color: var(--nui-st-warn, var(--bs-warning));
}

.table tbody tr.info>td {
    color: var(--nui-info, var(--bs-info));
}

.table tbody tr.success>td {
    color: var(--nui-st-ok, var(--bs-success));
}

/* Linha selecionada - overlay semi-transparente preserva todas as cores de texto */
.table .selecionado td {
    background-color: rgba(var(--bs-primary-rgb), 0.25) !important;
}

.table .selecionado td i {
    filter: brightness(1.2) saturate(1.3);
}

/* Em light mode, warning e tertiary (amarelos) ficam escuros para contraste no overlay */
html[data-bs-theme="light"] .table tbody tr.selecionado.warning>td {
    color: color-mix(in srgb, var(--bs-warning) 55%, black);
}

html[data-bs-theme="light"] .table tbody tr.selecionado.tertiary>td {
    color: color-mix(in srgb, var(--bs-tertiary-color) 55%, black);
}

td.text-truncate {
    max-width: 0;
}

/************************************************* Alterações *************************************************/
.card-header i,
.offcanvas-body i,
.navbar i,
.btn i:not(:only-child) {
    margin-right: .5rem;
}

/* Alinhamento vertical dos itens da navbar (interface clássica).
   Sem isto, o <ul.navbar-nav> herda align-items:normal e cada link ancora
   seu conteúdo por métrica diferente — o ícone <i> pela baseline do texto,
   o avatar <img> (30px) como replaced —, deixando os ícones ~3px fora do
   centro em relação à foto. Centrar a linha (navbar-nav) e transformar cada
   .nav-link em flex-center alinha <i> e <img> pelo mesmo eixo geométrico,
   independente do tamanho do conteúdo. Restrito a .navbar para não afetar
   as .nav-link de abas de formulário (.tabbed-form-nav) e demais usos. */
.navbar .navbar-nav {
    align-items: center;
}

.navbar .navbar-nav .nav-link {
    display: flex;
    align-items: center;
}

.nav {
    z-index: 1021;
}

.offcanvas-body a {
    text-decoration: none;
    color: var(--bs-heading-color);
}

.frame>.card {
    height: 100%;
}

.frame>.card>.card-body {
    padding: 0px;
    overflow-y: auto;
}

ul.dropdown-menu {
    z-index: 2000;
}

/* Estilos para itens de tema no menu */
.dropdown-item.active {
    position: relative;
    background-color: var(--bs-primary-bg-subtle) !important;
    color: var(--bs-primary-text-emphasis) !important;
}

.dropdown-item.active::after {
    content: "✓";
    position: absolute;
    right: 10px;
    font-weight: bold;
    color: var(--bs-primary);
}

.dropdown-item i {
    margin-right: 8px;
    width: 16px;
    text-align: center;
}

.bootbox.secondary {
    z-index: 1056;
}

/* .modal-body,
.offcanvas-body {
    background-color: #000000;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='250' height='30' viewBox='0 0 1000 120'%3E%3Cg fill='none' stroke='%23222' stroke-width='10' %3E%3Cpath d='M-500 75c0 0 125-30 250-30S0 75 0 75s125 30 250 30s250-30 250-30s125-30 250-30s250 30 250 30s125 30 250 30s250-30 250-30'/%3E%3Cpath d='M-500 45c0 0 125-30 250-30S0 45 0 45s125 30 250 30s250-30 250-30s125-30 250-30s250 30 250 30s125 30 250 30s250-30 250-30'/%3E%3Cpath d='M-500 105c0 0 125-30 250-30S0 105 0 105s125 30 250 30s250-30 250-30s125-30 250-30s250 30 250 30s125 30 250 30s250-30 250-30'/%3E%3Cpath d='M-500 15c0 0 125-30 250-30S0 15 0 15s125 30 250 30s250-30 250-30s125-30 250-30s250 30 250 30s125 30 250 30s250-30 250-30'/%3E%3Cpath d='M-500-15c0 0 125-30 250-30S0-15 0-15s125 30 250 30s250-30 250-30s125-30 250-30s250 30 250 30s125 30 250 30s250-30 250-30'/%3E%3Cpath d='M-500 135c0 0 125-30 250-30S0 135 0 135s125 30 250 30s250-30 250-30s125-30 250-30s250 30 250 30s125 30 250 30s250-30 250-30'/%3E%3C/g%3E%3C/svg%3E");
} */

.bootbox.secondary+.modal-backdrop {
    z-index: 1055;
    opacity: 0.75 !important;
}

.bootbox.secondary .modal-content {
    --bs-bg-opacity: 1;
    background-color: rgba(var(--bs-secondary-bg-rgb), var(--bs-bg-opacity)) !important;
}

.bootbox.tertiary {
    z-index: 1057;
}

.bootbox.tertiary+.modal-backdrop {
    z-index: 1056;
    opacity: 0.85 !important;
}

.bootbox.tertiary .modal-content {
    --bs-bg-opacity: 1;
    background-color: rgba(var(--bs-tertiary-bg-rgb), var(--bs-bg-opacity)) !important;
}

.bootbox.tertiary {
    z-index: 1057;
}

.bootbox.tertiary+.modal-backdrop {
    z-index: 1056;
    opacity: 0.85 !important;
}

.bootbox.tertiary .modal-content {
    color: #000 !important;
    background-color: RGBA(255, 255, 255, var(--bs-bg-opacity, 1)) !important;
}

.bootbox.p-0 .modal-body {
    padding: 0px;
}

.bootbox.p-1 .modal-body {
    padding: .25rem;
}

.bootbox.p-2 .modal-body {
    padding: .5rem;
}

.bootbox.p-3 .modal-body {
    padding: .75rem;
}

.bootbox.p-4 .modal-body {
    padding: 1rem;
}

.bootbox.p-5 .modal-body {
    padding: 1.25rem;
}

.bootbox.pdf .modal-dialog {
    height: 80% !important;
}

.bootbox.pdf .modal-content {
    height: 100% !important;
}

.bootbox.pdf .modal-body {
    padding: 0px;
}

.bootbox.pdf .bootbox-body {
    height: 100% !important;
}

/************************************************* Diversos *************************************************/
.col-minima {
    width: 10px !important;
    white-space: nowrap;
}

.preSelect {
    flex-grow: 5 !important;
}

.preSelect+.form-control {
    flex-grow: 50 !important;
}

input.sem-seletor::-webkit-calendar-picker-indicator,
input.sem-seletor::-webkit-inner-spin-button {
    display: none;
}

input.sem-seletor {
    appearance: textfield;
    -moz-appearance: textfield;
}

.scroll {
    overflow-y: auto;
    white-space: nowrap;
}

.hachura {
    background-color: #000000;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='250' height='30' viewBox='0 0 1000 120'%3E%3Cg fill='none' stroke='%23222' stroke-width='10' %3E%3Cpath d='M-500 75c0 0 125-30 250-30S0 75 0 75s125 30 250 30s250-30 250-30s125-30 250-30s250 30 250 30s125 30 250 30s250-30 250-30'/%3E%3Cpath d='M-500 45c0 0 125-30 250-30S0 45 0 45s125 30 250 30s250-30 250-30s125-30 250-30s250 30 250 30s125 30 250 30s250-30 250-30'/%3E%3Cpath d='M-500 105c0 0 125-30 250-30S0 105 0 105s125 30 250 30s250-30 250-30s125-30 250-30s250 30 250 30s125 30 250 30s250-30 250-30'/%3E%3Cpath d='M-500 15c0 0 125-30 250-30S0 15 0 15s125 30 250 30s250-30 250-30s125-30 250-30s250 30 250 30s125 30 250 30s250-30 250-30'/%3E%3Cpath d='M-500-15c0 0 125-30 250-30S0-15 0-15s125 30 250 30s250-30 250-30s125-30 250-30s250 30 250 30s125 30 250 30s250-30 250-30'/%3E%3Cpath d='M-500 135c0 0 125-30 250-30S0 135 0 135s125 30 250 30s250-30 250-30s125-30 250-30s250 30 250 30s125 30 250 30s250-30 250-30'/%3E%3C/g%3E%3C/svg%3E");
}

.sem-hachura {
    background-color: transparent !important;
    background-image: none !important;
}

/************************************************ Reservas ************************************************/
.reserva-header-acoes {
    display: inline-flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.5rem;
}

.reserva-header-acoes-com-solicitacao {
    min-width: min(38rem, 62vw);
    justify-content: space-between;
    gap: 2rem;
}

.reserva-solicitacoes-icone {
    font-size: 1rem;
}

.reserva-legenda-cores {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    font-size: 0.75rem;
    line-height: 1.2;
}

.reserva-legenda-titulo {
    color: var(--bs-secondary-color);
    font-weight: 600;
}

.reserva-legenda-item {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    white-space: nowrap;
}

.reserva-legenda-cor {
    width: 0.75rem;
    height: 0.75rem;
    border-radius: 50%;
    display: inline-block;
}

.reserva-legenda-ativa {
    background-color: var(--bs-body-color);
    border: 1px solid var(--bs-border-color);
}

.reserva-legenda-autorizada {
    background-color: var(--nui-accent);
}

.reserva-legenda-pendente {
    background-color: var(--nui-warn-tx);
}

.reserva-legenda-cancelada {
    background-color: var(--nui-danger);
}

/******************************************** Ajustes de Tema usando variáveis Bootstrap **************************************************/
/* Usando variáveis CSS nativas do Bootstrap para dark/light mode */

/* Card Headers - usando cores do tema */
.card-header {
    background-color: var(--bs-secondary-bg);
    border-bottom-color: var(--bs-border-color);
    color: var(--bs-emphasis-color);
}

.card-header i {
    color: var(--bs-emphasis-color);
}

/* Ícone DENTRO de botão no cabeçalho segue o texto do botão, não a cor do cabeçalho.
   A regra acima alcançava também o ícone do botão preenchido: o "+" da tela de menus
   saía na cor de ênfase do tema por cima do acento (1,56 de contraste no tema escuro
   com o âmbar, 3,83 no claro) e não acompanhava o botão ao receber o ponteiro. */
.card-header .btn i {
    color: inherit;
}

/* ETIQUETA DE SIGNIFICADO (10/10/2026) — componente `x-etiqueta`.
   Ponto, palavra e fundo suave. Sem `data-status` é neutra; com ele, usa o par
   `--nui-st-*` do palette.css. Vale nas duas interfaces, por isso mora aqui. A cor
   nunca diz sozinha: o texto da etiqueta é obrigatório. Não vai sobre barra
   (`--nui-bg-1`): ali atenção e positivo ficam no limite da régua. */
.nui-etiqueta {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.125rem 0.625rem;
    border-radius: 999px;
    font-size: 0.8125rem;
    font-weight: 600;
    line-height: 1.5;
    white-space: nowrap;
    background: var(--nui-bg-3);
    color: var(--nui-text-soft);
}

.nui-etiqueta::before {
    content: '';
    flex: none;
    width: 0.375rem;
    height: 0.375rem;
    border-radius: 50%;
    background: currentColor;
}

.nui-etiqueta[data-status="positivo"] {
    background: var(--nui-st-ok-bg);
    color: var(--nui-st-ok);
}

.nui-etiqueta[data-status="atencao"] {
    background: var(--nui-st-warn-bg);
    color: var(--nui-st-warn);
}

.nui-etiqueta[data-status="alerta"] {
    background: var(--nui-st-alert-bg);
    color: var(--nui-st-alert);
}

.nui-etiqueta[data-status="critico"] {
    background: var(--nui-st-crit-bg);
    color: var(--nui-st-crit);
}

/* INDICADOR (14/10/2026) — a peça do painel (`x-indicador`, `x-indicadores`; contrato em
   `App\Support\Indicador\Indicador`). Cartão neutro na superfície de cartão, ícone na cor de
   destaque, rótulo, número e microdados. Cor de significado só quando o produto dá um status
   (`data-status`), e sempre com a palavra na etiqueta: a borda esquerda é reforço, não sinal
   único. Sem degradê, sem sombra grande, sem cor de enfeite por cartão — o painel antigo tinha
   seis tons fixos do Bootstrap, um por cartão, que não diziam nada. */
.nui-indicadores {
    display: grid;
    /* Fecha a linha inteira e estica todos à mesma altura (DASHBOARD.md); `min(100%, …)`
       deixa a coluna encolher no celular em vez de rolar para o lado. */
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 13.5rem), 1fr));
    gap: 0.75rem;
    align-items: stretch;
}

.nui-indicador {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    min-width: 0;
    padding: 1rem;
    border-radius: 0.875rem;
    background: var(--nui-bg-2);
    border: 1px solid var(--nui-border-strong);
    color: var(--nui-text);
    font: inherit;
    text-align: left;
    text-decoration: none;
}

a.nui-indicador,
button.nui-indicador {
    cursor: pointer;
    transition: border-color 0.15s ease;
}

a.nui-indicador:hover,
button.nui-indicador:hover {
    border-color: var(--nui-accent);
    color: var(--nui-text);
}

a.nui-indicador:focus-visible,
button.nui-indicador:focus-visible {
    outline: 2px solid var(--nui-accent);
    outline-offset: 2px;
}

.nui-indicador[data-status="positivo"] { border-left: 4px solid var(--nui-st-ok); }
.nui-indicador[data-status="atencao"] { border-left: 4px solid var(--nui-st-warn); }
.nui-indicador[data-status="alerta"] { border-left: 4px solid var(--nui-st-alert); }
.nui-indicador[data-status="critico"] { border-left: 4px solid var(--nui-st-crit); }

.nui-indicador-topo {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

.nui-indicador-rotulo {
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--nui-text-soft);
}

.nui-indicador-icone {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.875rem;
    height: 1.875rem;
    border-radius: 0.625rem;
    background: var(--nui-accent-soft-bg);
    color: var(--nui-accent-soft-tx);
}

.nui-indicador-valor {
    font-size: 1.625rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.1;
    overflow-wrap: anywhere;
}

.nui-indicador-microdados {
    font-size: 0.8125rem;
    line-height: 1.4;
    color: var(--nui-text-soft);
}

.nui-indicador-etiqueta {
    margin-top: auto;
    padding-top: 0.125rem;
}

/* LISTA VAZIA (10/10/2026) — a legenda (`<caption>`) que o `x-table` põe na tabela gerada.
   Nasce escondida e aparece em dois casos:
   1. o `tbody` não tem linha nenhuma. Quem decide é o CSS, por `:has()`, a qualquer
      momento: na carga, depois de a grade ser redesenhada, depois de a última linha sair.
      Navegador sem `:has()` descarta a regra e fica como era antes, sem a frase;
   2. a busca não achou nada: o `filtra`/`filtraAny` marca `data-busca`.
   As duas regras ficam SEPARADAS de propósito: numa lista de seletores, um que o
   navegador não entende derruba a lista inteira. */
.nui-lista-vazia {
    display: none;
    caption-side: bottom;
    padding: 2rem 1rem;
    text-align: center;
    color: var(--nui-text-soft);
}

table.lista:not(:has(> tbody > tr)) > .nui-lista-vazia {
    display: table-caption;
}

.nui-lista-vazia[data-busca] {
    display: table-caption;
}

.nui-lista-vazia > .bi {
    display: block;
    margin-bottom: 0.5rem;
    font-size: 1.75rem;
    line-height: 1;
    color: var(--nui-text-mute);
}

.nui-lista-vazia__frase {
    margin: 0 0 0.5rem;
    font-size: 0.9375rem;
    color: var(--nui-text-soft);
    overflow-wrap: anywhere;
}

.nui-lista-vazia [data-frase="busca"],
.nui-lista-vazia [data-acao="limpar-busca"],
.nui-lista-vazia[data-busca] [data-frase="vazia"],
.nui-lista-vazia[data-busca] [data-acao="incluir"] {
    display: none;
}

.nui-lista-vazia[data-busca] [data-frase="busca"] {
    display: block;
}

.nui-lista-vazia[data-busca] [data-acao="limpar-busca"] {
    display: inline-block;
}

/* QUADRO DE DETALHE VAZIO (19/10/2026) — a frase do frame extra (`'vazio'` no `extraFrames`,
   `frames.blade.php`). Mesma peça da lista vazia: ícone e frase em `--nui-text-soft`, sem
   moldura. Aparece enquanto o corpo do quadro não tem nada dentro e some quando alguém o
   preenche; o corpo vazio sai do caminho para a frase ocupar a altura do quadro. Só `:empty`
   e o irmão seguinte: vale em qualquer navegador, sem `:has()`. */
.nui-quadro-vazio {
    display: none;
}

[data-quadro-com-vazio]:empty {
    display: none;
}

[data-quadro-com-vazio]:empty + .nui-quadro-vazio {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 0;
    padding: 2rem 1rem;
    text-align: center;
    color: var(--nui-text-soft);
}

.nui-quadro-vazio > .bi {
    display: block;
    margin-bottom: 0.5rem;
    font-size: 1.75rem;
    line-height: 1;
    color: var(--nui-text-mute);
}

.nui-quadro-vazio__frase {
    max-width: 28rem;
    margin: 0;
    font-size: 0.9375rem;
    color: var(--nui-text-soft);
    overflow-wrap: anywhere;
}

/* AÇÃO NO CABEÇALHO DO QUADRO (19/10/2026) — os `botoes` do Model (`components/card-header`).
   Eram `<i onclick>`: o teclado não chegava e o leitor de tela não anunciava. Viraram
   `<button>` que, só com ícone, continua com a cara de antes (sem fundo, sem borda, a cor
   vem das regras do ícone no cabeçalho). Com `'texto'`, vira pílula de contorno com o ícone
   e a palavra, porque a ação que só existe no tooltip não é achada. */
.nui-acao-do-quadro {
    display: inline-flex;
    align-items: center;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    line-height: 1;
    cursor: pointer;
}

.nui-acao-do-quadro:focus-visible {
    outline: 2px solid var(--nui-accent);
    outline-offset: 2px;
    border-radius: 999px;
}

.nui-acao-do-quadro--texto {
    gap: 0.375rem;
    padding: 0.25rem 0.75rem;
    border: 1px solid var(--nui-border-strong);
    border-radius: 999px;
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--nui-text);
    white-space: nowrap;
}

.nui-acao-do-quadro--texto:hover {
    background-color: var(--nui-bg-3);
}

.card-header .nui-acao-do-quadro--texto > i {
    margin-right: 0;
}

/* CONTAGEM NA BUSCA (15/10/2026) — "12 de 340" na mesma legenda, enquanto a busca deixa linhas.
   O `filtra`/`filtraAny` escreve o número e marca `data-contagem`. Numa grade longa a legenda
   nasceria depois da última linha, fora da vista (medido em /groups com 340 linhas: 10.912 px
   de conteúdo para 815 visíveis); por isso ela fica presa ao pé da área rolável, com o fundo
   do cartão cobrindo as linhas que passam por baixo, sem empurrar a grade. Informação, não
   aviso: compacta, sem ícone. Regra própria, separada das de exibição acima. */
.nui-busca-contagem {
    display: none;
    margin: 0;
    font-size: 0.8125rem;
    line-height: 1.4;
    color: var(--nui-text-soft);
    font-variant-numeric: tabular-nums;
}

.nui-lista-vazia[data-contagem] {
    display: table-caption;
    position: sticky;
    bottom: 0;
    z-index: 1;
    padding: 0.25rem 0.5rem;
    text-align: left;
    background-color: var(--nui-bg-2);
    border-top: 1px solid var(--nui-border);
}

.nui-lista-vazia[data-contagem] > .bi,
.nui-lista-vazia[data-contagem] [data-frase="vazia"],
.nui-lista-vazia[data-contagem] [data-acao="incluir"] {
    display: none;
}

.nui-lista-vazia[data-contagem] .nui-busca-contagem {
    display: block;
}

/* TROCA DE TELA (10/10/2026). A navegação parcial (`pageManager.js`) marca `aria-busy` no
   `#appContent` enquanto busca a tela seguinte e tira no fim. Até aqui nada na tela dizia
   que algo estava acontecendo. A barra é só CSS sobre esse atributo: nenhum evento da
   navegação muda. Ela espera 0,18 s para aparecer, para não piscar na troca rápida. */
#appContent[aria-busy="true"]::before {
    content: '';
    position: fixed;
    z-index: 2000;
    top: 0;
    left: 0;
    width: 100%;
    height: 3px;
    background-color: var(--nui-accent);
    transform-origin: left center;
    opacity: 0;
    animation: nui-troca-aparece 0.01s linear 0.18s forwards, nui-troca-corre 1.1s ease-in-out 0.18s infinite;
    pointer-events: none;
}

@keyframes nui-troca-aparece {
    to {
        opacity: 1;
    }
}

@keyframes nui-troca-corre {
    0% {
        transform: translateX(-100%) scaleX(0.35);
    }

    60% {
        transform: translateX(40%) scaleX(0.6);
    }

    100% {
        transform: translateX(100%) scaleX(0.35);
    }
}

@media (prefers-reduced-motion: reduce) {
    #appContent[aria-busy="true"]::before {
        animation: nui-troca-aparece 0.01s linear 0.18s forwards;
    }
}

/* AVISO PASSAGEIRO (toastr) PELA PALETA (10/10/2026).
   A folha da biblioteca (2.1.4, servida pela CDN) pinta um bloco de cor fixa com texto
   branco, `opacity: .8` e o ícone por `background-image … !important` em
   `#toast-container > .toast-<tipo>`. Aqui o aviso vira cartão da paleta, nos dois temas
   e nas duas interfaces: superfície `--nui-bg-2`, ícone e barra de tempo na cor do
   significado. Os seletores levam `.toast` a mais para vencer os da biblioteca por
   especificidade (inclusive o `:hover` e as larguras por `@media` dela); só o
   `background-image` precisa de `!important`, porque o dela tem. A sombra fica porque o
   aviso flutua. O texto do aviso continua vindo de quem chama: aqui só muda a pintura. */
#toast-container > .toast {
    --aviso-cor: var(--nui-info);
    width: 340px;
    max-width: calc(100vw - 24px);
    margin: 0 0 8px;
    padding: 17px 16px 20px 56px;
    border: 1px solid var(--nui-border-strong);
    border-radius: var(--bs-border-radius);
    background-color: var(--nui-bg-2);
    background-image: none !important;
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.14);
    color: var(--nui-text);
    opacity: 1;
}

#toast-container > .toast:hover {
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.22);
    opacity: 1;
}

#toast-container > .toast.toast-success {
    --aviso-cor: var(--nui-st-ok);
}

#toast-container > .toast.toast-warning {
    --aviso-cor: var(--nui-st-warn);
}

#toast-container > .toast.toast-error {
    --aviso-cor: var(--nui-st-crit);
}

/* O ícone: um disco na cor do significado, com o sinal vazado (a superfície do cartão
   aparece por ele). É máscara, e não imagem colorida, para a cor vir do token. */
#toast-container > .toast::before {
    content: '';
    position: absolute;
    top: 14px;
    left: 16px;
    width: 28px;
    height: 28px;
    background-color: var(--aviso-cor);
    -webkit-mask: var(--aviso-sinal) center / contain no-repeat;
    mask: var(--aviso-sinal) center / contain no-repeat;
}

#toast-container > .toast {
    --aviso-sinal: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cmask id='m'%3E%3Crect width='24' height='24' fill='white'/%3E%3Cpath d='M12 11v6M12 7.4v.1' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round'/%3E%3C/mask%3E%3Ccircle cx='12' cy='12' r='12' mask='url(%23m)'/%3E%3C/svg%3E");
}

#toast-container > .toast.toast-success {
    --aviso-sinal: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cmask id='m'%3E%3Crect width='24' height='24' fill='white'/%3E%3Cpath d='M6.8 12.6l3.6 3.6 6.8-7.6' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/mask%3E%3Ccircle cx='12' cy='12' r='12' mask='url(%23m)'/%3E%3C/svg%3E");
}

#toast-container > .toast.toast-warning {
    --aviso-sinal: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cmask id='m'%3E%3Crect width='24' height='24' fill='white'/%3E%3Cpath d='M12 6.8v6.4M12 16.9v.1' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round'/%3E%3C/mask%3E%3Ccircle cx='12' cy='12' r='12' mask='url(%23m)'/%3E%3C/svg%3E");
}

#toast-container > .toast.toast-error {
    --aviso-sinal: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cmask id='m'%3E%3Crect width='24' height='24' fill='white'/%3E%3Cpath d='M8.2 8.2l7.6 7.6M15.8 8.2l-7.6 7.6' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round'/%3E%3C/mask%3E%3Ccircle cx='12' cy='12' r='12' mask='url(%23m)'/%3E%3C/svg%3E");
}

/* A barra de tempo: trilho na cor da borda, e por cima a barra da biblioteca, que encolhe
   até o aviso sair, na cor do significado. */
#toast-container > .toast::after {
    content: '';
    position: absolute;
    right: 0;
    bottom: 0;
    left: 0;
    height: 3px;
    background-color: var(--nui-border);
}

#toast-container > .toast > .toast-progress {
    z-index: 1;
    height: 3px;
    background-color: var(--aviso-cor);
    opacity: 1;
}

/* Sozinha, a mensagem é a frase do aviso. Com título, o título é a frase e a mensagem
   passa a ser o detalhe. */
#toast-container > .toast > .toast-title,
#toast-container > .toast > .toast-message {
    font-size: 0.9375rem;
    font-weight: 600;
    line-height: 1.35;
    color: var(--nui-text);
}

#toast-container > .toast > .toast-title + .toast-message {
    margin-top: 2px;
    font-size: 0.8125rem;
    font-weight: 400;
    line-height: 1.4;
    color: var(--nui-text-soft);
}

#toast-container > .toast > .toast-message a,
#toast-container > .toast > .toast-message label {
    color: var(--bs-link-color);
}

#toast-container > .toast > .toast-message a:hover {
    color: var(--nui-text);
    text-decoration: underline;
}

#toast-container > .toast > .toast-close-button,
#toast-container > .toast > .toast-close-button:hover,
#toast-container > .toast > .toast-close-button:focus {
    color: var(--nui-text-soft);
    text-shadow: none;
    opacity: 1;
}

#toast-container > .toast > .toast-close-button:hover,
#toast-container > .toast > .toast-close-button:focus {
    color: var(--nui-text);
}

/* Modal Headers - usando cores do tema */
.modal-header {
    background-color: var(--bs-secondary-bg);
    border-bottom-color: var(--bs-border-color);
    color: var(--bs-emphasis-color);
}

.modal-header .modal-title {
    color: var(--bs-emphasis-color);
}

.modal-header .btn-close {
    opacity: 1;
}

.modal-header i {
    color: var(--bs-emphasis-color);
}

/* Bootbox específico */
.bootbox .modal-header {
    background-color: var(--bs-secondary-bg);
    border-bottom-color: var(--bs-border-color);
    color: var(--bs-emphasis-color);
}

.bootbox .modal-header h5,
.bootbox .modal-header h4 {
    color: var(--bs-emphasis-color) !important;
}

.bootbox .modal-header i {
    color: var(--bs-emphasis-color) !important;
}

/* Tabelas - linha selecionada */
.table .selecionado td {
    background-color: rgba(var(--bs-primary-rgb), 0.25) !important;
}

/* Em light mode, warning e tertiary (amarelos) ficam escuros para contraste no overlay */
html[data-bs-theme="light"] .table tbody tr.selecionado.warning>td {
    color: color-mix(in srgb, var(--bs-warning) 55%, black);
}

html[data-bs-theme="light"] .table tbody tr.selecionado.tertiary>td {
    color: color-mix(in srgb, var(--bs-tertiary-color) 55%, black);
}

/* Select2 com variáveis Bootstrap */
.select2-container--bootstrap-5 .select2-selection {
    background-color: var(--bs-body-bg) !important;
    border-color: var(--bs-border-color);
    color: var(--bs-body-color);
}

.select2-container--bootstrap-5 .select2-selection--single .select2-selection__rendered {
    color: var(--bs-body-color) !important;
}

/* Select2 DESATIVADO (23/10/2026): o mesmo fundo do `.form-control:disabled` do Bootstrap. A regra
   acima pinta a caixa com !important em qualquer estado, e o select2 desativado saía igual ao ativo.
   A Nova UI troca pelos tokens --nui-disabled-* (nova-ui.css, "CAMPO DESATIVADO"). */
.select2-container--bootstrap-5.select2-container--disabled .select2-selection {
    background-color: var(--bs-secondary-bg) !important;
}

.select2-container--bootstrap-5 .select2-selection--multiple .select2-selection__rendered .select2-selection__choice {
    color: var(--nui-on-accent) !important;
    background-color: var(--bs-primary);
    border-color: var(--bs-primary);
}

.select2-container--bootstrap-5 .select2-selection--single .select2-selection__rendered .select2-selection__placeholder {
    color: var(--bs-secondary-color) !important;
}

.select2-container--bootstrap-5 .select2-dropdown .select2-search .select2-search__field {
    background-color: var(--bs-body-bg) !important;
    color: var(--bs-body-color) !important;
    border-color: var(--bs-border-color);
}

.select2-container--bootstrap-5 .select2-dropdown {
    color: var(--bs-body-color) !important;
    border-color: var(--bs-border-color) !important;
    background-color: var(--bs-body-bg);
}

.select2-container--bootstrap-5 .select2-dropdown .select2-results__options .select2-results__option[role=group] .select2-results__group {
    color: var(--bs-secondary-color) !important;
}

.select2-container--bootstrap-5 .select2-dropdown .select2-results__options .select2-results__option--highlighted {
    background-color: var(--bs-primary);
    color: var(--nui-on-accent);
}

.select2-container--bootstrap-5 .select2-dropdown .select2-results__options .select2-results__option--selected {
    background-color: var(--bs-secondary-bg);
}

/* Flexdatalist com variáveis Bootstrap */
.flexdatalist-results li:hover,
.flexdatalist-results li.active {
    background-color: var(--bs-primary);
    color: var(--nui-on-accent);
}

.flexdatalist-multiple li {
    background-color: var(--bs-primary);
    color: var(--nui-on-accent);
}

/* Form controls - ajustes finos */
.form-label {
    font-weight: 500;
}

/* DatePicker com variáveis Bootstrap */
.datepicker {
    background-color: var(--bs-body-bg);
    border-color: var(--bs-border-color);
    color: var(--bs-body-color);
}

.datepicker table tr td.day.today {
    background: var(--bs-info) !important;
    color: var(--bs-emphasis-color);
}

.datepicker table tr td.day.today.active,
.datepicker table tr td.active.highlighted.day {
    background: var(--bs-primary) !important;
    color: var(--nui-on-accent);
}

.datepicker table tr td.day:hover {
    background: var(--bs-secondary-bg) !important;
    color: var(--bs-body-color);
}

/******************************************** Ajustes de largura **************************************************/
form>div:has(.parent-100) {
    width: 100% !important;
}

form>div:has(.parent-75) {
    width: calc(75% - 0.25rem) !important;
}

form>div:has(.parent-50) {
    width: calc(50% - 0.25rem) !important;
}

form>div:has(.parent-25) {
    width: calc(25% - 0.25rem) !important;
}

form>div:has(.d-none) {
    display: none;
}

/* Exceção: permitir exibição de containers com input[type="file"] oculto no formulário de perfil */
#formUser>div:has(input[type="file"].d-none) {
    display: block !important;
}

form>.row:last-of-type {
    margin-bottom: 0px;
}

/************************************************ DatePicker ************************************************/
.datepicker table tr td.range,
.datepicker table tr td.range:hover,
.datepicker table tr td.range.disabled,
.datepicker table tr td.range.disabled:hover,
.datepicker table tr td.day:hover,
.datepicker table tr td.day.focused,
.datepicker table tr td span:hover,
.datepicker table tr td span.focused,
.datepicker .datepicker-switch:hover,
.datepicker .prev:hover,
.datepicker .next:hover,
.datepicker tfoot tr th:hover,
.datepicker table tr td.highlighted {
    color: var(--bs-secondary-text-emphasis);
    background-color: var(--bs-border-color);
}

.datepicker table tr td.day.today {
    background: var(--bs-info) !important;
    color: var(--bs-black);
}

.datepicker table tr td.day.today.active {
    background: var(--bs-primary) !important;
}

.datepicker table tr td.active.highlighted.day {
    background: var(--bs-primary) !important;
    color: var(--nui-on-accent);
}

.datepicker table tr td.day:hover {
    background: var(--bs-secondary) !important;
    color: var(--bs-light);
}

/********************* Estiliza o Flexdatalist com base nas variáveis CSS do Bootstrap **********************/
.flexdatalist-results {
    background-color: var(--bs-body-bg);
    color: var(--bs-body-color);
    border: 1px solid var(--bs-border-color);
    border-radius: 0.375rem;
    box-shadow: var(--bs-box-shadow-sm);
    list-style: none;
    padding: 0;
    margin-top: 0.25rem;
}

.flexdatalist-results li {
    padding: 0.5rem 1rem;
    color: var(--bs-body-color);
    cursor: pointer;
}

.flexdatalist-results li:hover,
.flexdatalist-results li.active {
    background-color: var(--bs-secondary-bg);
    color: var(--bs-body-color);
}

.flexdatalist-multiple {
    background-color: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    color: var(--bs-body-color);
}

.flexdatalist-multiple li {
    background-color: var(--bs-primary);
    color: var(--nui-on-accent);
    border-radius: 0.2rem;
    padding: 0.25rem 0.5rem;
    margin: 0.25rem;
}

/********************* Extensão do  **********************/
.h-0 {
    height: 0 !important;
}

.min-h-0 {
    min-height: 0 !important;
}

.h-none {
    height: auto !important;
}

/********************* Estilização dos botões de tema (Laravel 12 style) **********************/
/* Botões de tema com radio buttons estilizados */
.btn-check:checked+label.btn-outline-secondary {
    background-color: var(--bs-primary) !important;
    border-color: var(--bs-primary) !important;
    color: var(--nui-on-accent) !important;
}

.btn-check:checked+label.btn-outline-secondary i {
    color: var(--nui-on-accent) !important;
}

.btn-outline-secondary:hover {
    background-color: var(--bs-secondary-bg);
}

/* Centralização de modals */
.modal.fade .modal-dialog.modal-dialog-centered {
    display: flex;
    align-items: center;
    min-height: calc(100% - 3.5rem);
}

/* Estilização da foto no perfil */
#photoPreview {
    transition: all 0.3s ease;
}

#photoPreview:hover {
    transform: scale(1.05);
}

/* ─── Tabbed Forms (formulários com abas dentro de modals) ─── */
.modal.tabbed-form-modal .modal-dialog {
    width: min(980px, calc(100vw - 2rem));
    max-width: min(980px, calc(100vw - 2rem));
}

.modal.tabbed-form-modal .modal-content {
    height: min(760px, 86vh);
}

.modal.tabbed-form-modal .modal-body {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-height: 0;
}

.modal.tabbed-form-modal .bootbox-body {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.modal.tabbed-form-modal form:has(.tabbed-form-nav) {
    display: flex;
    flex: 1;
    flex-direction: column;
    min-height: 0;
}

.modal.tabbed-form-modal .tabbed-form-nav {
    position: relative;
    z-index: 10;
    flex: 0 0 auto;
    margin-bottom: 0;
    padding-bottom: .35rem;
    background-color: var(--bs-modal-bg, #212529);
    border-bottom: 1px solid rgba(255, 255, 255, .08);
}

.modal.tabbed-form-modal .tabbed-form-nav::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    background-color: var(--bs-modal-bg, #212529);
}

.modal.tabbed-form-modal .tabbed-form-nav .nav-item,
.modal.tabbed-form-modal .tabbed-form-nav .nav-link {
    background-color: var(--bs-modal-bg, #212529);
}

.modal.tabbed-form-modal .tabbed-form-nav .nav-link,
.modal.tabbed-form-modal .tabbed-form-nav .nav-link.active,
.modal.tabbed-form-modal .tabbed-form-nav .nav-link:hover,
.modal.tabbed-form-modal .tabbed-form-nav .nav-link:focus {
    background-color: var(--bs-modal-bg, #212529);
}

.modal.tabbed-form-modal form:has(.tabbed-form-nav) .tab-content {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    background-color: var(--bs-modal-bg, #212529);
    padding-right: .35rem;
    padding-top: .25rem;
}

.modal.tabbed-form-modal form:has(.tabbed-form-nav) .tab-pane {
    background-color: var(--bs-modal-bg, #212529);
}

@media (max-width: 768px) {
    .modal.tabbed-form-modal .modal-content {
        height: min(90vh, 760px);
    }
}

/********************* Custom Menu Tree View **********************/

/* ── Variáveis ── */
.custom-menu-tree {
    --tree-indent: 1.25rem;
    --tree-line-color: var(--bs-border-color);
    --tree-line-width: 1px;
    --tree-anim-speed: 0.25s;
    --tree-glow-color: var(--bs-primary-rgb);

    padding: 0.5rem;
    position: relative;
}

/* ── Tree Lines (conexão pai → filho) ── */
.tree-children {
    position: relative;
    padding-left: var(--tree-indent) !important;
}

.tree-children::before {
    content: '';
    position: absolute;
    left: 0.6rem;
    top: 0;
    bottom: 0.5rem;
    width: var(--tree-line-width);
    background: var(--tree-line-color);
    opacity: 0.35;
}

.tree-children > .tree-item {
    position: relative;
}

/* ── Divider (separador) ── */
.tree-item-has-divider {
    margin-top: 0.75rem !important;
}

.tree-item-has-divider::before {
    content: '';
    position: absolute;
    top: -0.375rem;
    left: 1rem;
    right: 0.5rem;
    height: 1px;
    background: var(--tree-line-color);
    opacity: 0.5;
}

.tree-children > .tree-item::before {
    content: '';
    position: absolute;
    left: calc(-0.65rem);
    top: 50%;
    width: 0.65rem;
    height: var(--tree-line-width);
    background: var(--tree-line-color);
    opacity: 0.35;
}

/* ── Itens da árvore ── */
.tree-item {
    border: 1px solid transparent;
    user-select: none;
    border-radius: 0.375rem;
    transition: all var(--tree-anim-speed) cubic-bezier(0.4, 0, 0.2, 1);
    position: relative;
}

.tree-item:hover {
    background: linear-gradient(
        135deg,
        rgba(var(--tree-glow-color), 0.06),
        rgba(var(--tree-glow-color), 0.02)
    ) !important;
    border-color: rgba(var(--tree-glow-color), 0.2);
    transform: translateX(2px);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
}

/* Grip icon — aparece suave no hover */
.tree-item .bi-grip-vertical {
    opacity: 0.25;
    transition: opacity var(--tree-anim-speed) ease, transform var(--tree-anim-speed) ease;
}

.tree-item:hover .bi-grip-vertical {
    opacity: 0.7;
    transform: scaleY(1.15);
}

/* ── Ghost drag (item sendo arrastado) ── */
.tree-item.tree-dragging {
    opacity: 0.35 !important;
    transform: scale(0.97);
    border: 1px dashed var(--bs-primary);
    background: transparent !important;
}

/* ── Headers de Parent ── */
.tree-parent-header {
    border-radius: 0.375rem;
    transition: all var(--tree-anim-speed) cubic-bezier(0.4, 0, 0.2, 1);
    border: 1px solid transparent;
    position: relative;
    overflow: hidden;
}

.tree-parent-header::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, transparent, rgba(255,255,255,0.03));
    pointer-events: none;
    opacity: 0;
    transition: opacity var(--tree-anim-speed) ease;
}

.tree-parent-header:hover {
    border-color: rgba(var(--tree-glow-color), 0.15);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
}

.tree-parent-header:hover::after {
    opacity: 1;
}

/* Toggle icon rotation */
.tree-toggle {
    transition: transform var(--tree-anim-speed) cubic-bezier(0.4, 0, 0.2, 1);
    font-size: 0.75rem;
}

.tree-toggle.bi-chevron-right {
    transform: rotate(0deg);
}

.tree-toggle.bi-chevron-down {
    transform: rotate(0deg);
}

/* ── Expand / Collapse animação ── */
.tree-children.tree-collapsing {
    overflow: hidden;
    transition: max-height var(--tree-anim-speed) cubic-bezier(0.4, 0, 0.2, 1),
                opacity var(--tree-anim-speed) ease;
}

.tree-children.tree-collapsed {
    max-height: 0 !important;
    overflow: hidden;
    opacity: 0;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
    margin-top: 0 !important;
}

/* ── Drop Zones ── */
.tree-drop-zone {
    min-height: 8px;
    border-radius: 0.375rem;
    transition: all var(--tree-anim-speed) ease;
    position: relative;
}

/* Glow pulsante quando um item está sobre a drop zone */
.tree-drop-highlight {
    background-color: rgba(var(--tree-glow-color), 0.08) !important;
    border: 1px dashed rgba(var(--tree-glow-color), 0.5) !important;
    box-shadow: inset 0 0 12px rgba(var(--tree-glow-color), 0.08),
                0 0 8px rgba(var(--tree-glow-color), 0.05);
    animation: tree-glow-pulse 1.5s ease-in-out infinite;
}

@keyframes tree-glow-pulse {
    0%, 100% {
        box-shadow: inset 0 0 12px rgba(var(--tree-glow-color), 0.08),
                    0 0 8px rgba(var(--tree-glow-color), 0.05);
    }
    50% {
        box-shadow: inset 0 0 18px rgba(var(--tree-glow-color), 0.15),
                    0 0 14px rgba(var(--tree-glow-color), 0.1);
    }
}

/* Parent header glow quando hover de drag */
.tree-parent-header.tree-drop-highlight {
    border-color: rgba(var(--tree-glow-color), 0.4) !important;
    box-shadow: 0 0 12px rgba(var(--tree-glow-color), 0.15);
}

/* Indicadores de inserção */
.tree-insert-before {
    border-top: 2px solid var(--bs-primary) !important;
    position: relative;
}

.tree-insert-before::after {
    content: '';
    position: absolute;
    top: -5px;
    left: -2px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--bs-primary);
}

.tree-insert-after {
    border-bottom: 2px solid var(--bs-primary) !important;
    position: relative;
}

.tree-insert-after::after {
    content: '';
    position: absolute;
    bottom: -5px;
    left: -2px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--bs-primary);
}

/* ── Root drop zone (arrastar para tornar principal) ── */
.tree-root-zone.border {
    transition: all var(--tree-anim-speed) ease;
    opacity: 0.6;
}

.tree-root-zone.border:hover,
.tree-root-zone.border.tree-drop-highlight {
    opacity: 1;
}

/* ── Badge de tipo (main/sub) — clicável ── */
.tree-type-badge {
    cursor: pointer;
    transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
    font-size: 0.7rem;
    padding: 0.15rem 0.45rem;
    border-radius: 1rem;
    font-weight: 500;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    user-select: none;
}

.tree-type-badge:hover {
    transform: scale(1.1);
    filter: brightness(1.2);
}

.tree-type-badge:active {
    transform: scale(0.95);
}

.tree-type-badge.type-main {
    background: linear-gradient(135deg, var(--bs-info), color-mix(in srgb, var(--bs-info) 70%, var(--bs-primary)));
    color: var(--bs-white);
}

.tree-type-badge.type-sub {
    background: var(--bs-secondary-bg);
    color: var(--bs-secondary-color);
    border: 1px solid var(--bs-border-color);
}

/* Badge de contagem animado */
.tree-count-badge {
    transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.tree-count-badge.badge-pop {
    animation: tree-badge-pop 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}

@keyframes tree-badge-pop {
    0% { transform: scale(1); }
    50% { transform: scale(1.35); }
    100% { transform: scale(1); }
}

/* ── Edição inline de parent label ── */
.tree-parent-label-input {
    background: transparent;
    border: none;
    border-bottom: 2px solid var(--bs-primary);
    color: inherit;
    font-weight: bold;
    font-size: inherit;
    outline: none;
    padding: 0 0.25rem;
    width: auto;
    min-width: 6rem;
    max-width: 100%;
}

/* ── Empty State ── */
.tree-empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 2rem 1rem;
    opacity: 0.55;
    text-align: center;
    gap: 0.75rem;
}

.tree-empty-state i {
    font-size: 2.5rem;
    opacity: 0.4;
}

.tree-empty-state .tree-empty-title {
    font-weight: 600;
    font-size: 0.95rem;
}

.tree-empty-state .tree-empty-subtitle {
    font-size: 0.8rem;
}

/* ── Seção da árvore ── */
.tree-section {
    border-radius: 0.5rem;
    transition: background var(--tree-anim-speed) ease;
}

.tree-section:hover {
    background: rgba(var(--tree-glow-color), 0.015);
}

/* ── Auto-expand indicator ── */
.tree-parent-header.tree-auto-expand-pending {
    border-color: rgba(var(--tree-glow-color), 0.3) !important;
}

.tree-parent-header.tree-auto-expand-pending .tree-toggle {
    animation: tree-expand-hint 0.6s ease-in-out infinite;
}

@keyframes tree-expand-hint {
    0%, 100% { transform: rotate(0deg); }
    50% { transform: rotate(45deg); }
}

/* ── Remove button ── */
.tree-item .btn-outline-danger {
    opacity: 0;
    transition: opacity var(--tree-anim-speed) ease;
}

.tree-item:hover .btn-outline-danger {
    opacity: 1;
}

/* ── Section-level Drag (reordenar seções inteiras) ── */
.tree-sections-container {
    position: relative;
}

.tree-section-draggable {
    position: relative;
    border: 1px solid transparent;
    border-radius: 0.5rem;
    transition: border-color var(--tree-anim-speed) ease, box-shadow var(--tree-anim-speed) ease;
}

.tree-section-draggable.tree-section-dragging {
    opacity: 0.35;
    border: 1px dashed var(--bs-primary);
}

.tree-section-draggable.tree-section-insert-before {
    border-top: 3px solid var(--bs-primary) !important;
}

.tree-section-draggable.tree-section-insert-after {
    border-bottom: 3px solid var(--bs-primary) !important;
}

.tree-section-grip {
    cursor: grab;
    opacity: 0.3;
    transition: opacity var(--tree-anim-speed) ease;
}

.tree-section-draggable:hover .tree-section-grip,
.tree-parent-header:hover .tree-section-grip {
    opacity: 0.8;
}

/* Itens raiz individuais — grip no hover */
.tree-section-draggable[data-section-type="root"] {
    cursor: grab;
}

.tree-section-draggable[data-section-type="root"]:active {
    cursor: grabbing;
}

/* ── Mobile responsive ── */
@media (max-width: 576px) {
    .custom-menu-tree {
        --tree-indent: 0.75rem;
        padding: 0.25rem;
    }

    .tree-item {
        font-size: 0.85rem;
    }

    .tree-parent-header {
        font-size: 0.85rem;
    }
}
/* Centralização do botão + no cabeçalho */
.janela .card-header .btn-primary.d-flex {
    padding: 0;
    line-height: 1;
}

.janela .card-header .btn-primary.d-flex i {
    font-size: 1.1rem;
    width: 100%;
    text-align: center;
}

/********************* Navegação responsiva entre frames (mobile) **********************/
/* Indicador de bolinhas: escondido por padrão (desktop). Só aparece no mobile,
   dentro da media query abaixo. Mantém o desktop 100% inalterado. */
.frame-nav-dots {
    display: none;
}

.frame-nav-dot {
    width: 8px;
    height: 8px;
    padding: 0;
    margin-left: 6px;
    border: none;
    border-radius: 50%;
    background-color: var(--bs-secondary-color, #6c757d);
    opacity: 0.45;
    cursor: pointer;
    vertical-align: middle;
    transition: opacity 0.2s ease, transform 0.2s ease;
}

.frame-nav-dot.active {
    opacity: 1;
    transform: scale(1.25);
    background-color: var(--bs-primary, #0d6efd);
}

.frame-nav-dot.locked {
    opacity: 0.2;
    cursor: default;
    pointer-events: none;
}

/* Toda a troca "um grupo por vez" vive aqui dentro. Fora desta media query,
   nada muda: telas grandes mantêm os frames lado a lado como sempre. */
@media (max-width: 767.98px) {
    /* Itens do menu alinhados à ESQUERDA no mobile (interface clássica).
       O `.navbar .navbar-nav { align-items: center }` lá de cima existe para o DESKTOP,
       onde a lista é flex-direction:row e o eixo cruzado é o VERTICAL — ali o center
       alinha <i> e <img> pelo mesmo eixo geométrico (é a intenção original).
       Mas a navbar é `navbar-expand-md`: abaixo de 768px o Bootstrap colapsa o menu e a
       lista vira flex-direction:column — o eixo cruzado passa a ser o HORIZONTAL e o
       MESMO center centraliza os itens, deixando o menu em escada.
       `stretch` (valor inicial do flex) neutraliza o center herdado: os <li> voltam a
       ocupar a largura toda, o conteúdo do .nav-link assenta à esquerda e o alvo de
       toque passa a ser a linha inteira — não só o texto (o que `flex-start` faria). */
    .navbar .navbar-nav {
        align-items: stretch;
    }

    /* O container .window (pai da janela) é filho flex do <body> que também contém a
       navbar. No mobile, prende a .window ao espaço restante (viewport − navbar) com
       flex:1 + min-height:0 — senão ela toma a viewport inteira e empurra o frame
       ativo para fora da tela embaixo. Escopado ao mobile: não altera o desktop. */
    body > .window {
        flex: 1 1 auto;
        min-height: 0;
    }

    /* Janela navegável vira flex-column no mobile (substitui o grid). Assim, telas
       com layout próprio (grid aninhado de N linhas/colunas) colapsam corretamente:
       containers cujos frames estão todos ocultos não ocupam espaço.
       REGRA: o frame ativo NUNCA ultrapassa a tela — a janela fica presa à altura do
       container pai (.window) e o conteúdo rola DENTRO do .card-body (overflow-y-auto).
       O min-height:0 em toda a cadeia é o que permite o flex encolher e o scroll interno
       ativar (sem ele, o flex item cresce até o conteúdo e transborda a viewport). */
    .janela[data-frame-nav] {
        display: flex !important;
        flex-direction: column !important;
        grid-template-columns: none !important;
        grid-template-rows: none !important;
        flex: 1 1 auto;
        min-height: 0;
        max-height: 100%;
        overflow: hidden;
    }

    /* Containers internos (sub-grids das telas com layout próprio) também viram
       flex-column. Só crescem quando contêm o frame ativo; senão, encolhem a zero. */
    .janela[data-frame-nav] > div {
        display: flex !important;
        flex-direction: column !important;
        grid-template-columns: none !important;
        min-height: 0;
        flex: 0 0 auto;
    }

    .janela[data-frame-nav] > div:has(.frame:not(.frame-group-hidden)) {
        flex: 1 1 auto;
    }

    /* Frame de grupo não-ativo fica oculto; o ativo ocupa a viewport útil. */
    .janela[data-frame-nav] .frame.frame-group-hidden {
        display: none !important;
    }

    /* Frame ativo (e sua cadeia card → card-body) cresce para ocupar a altura,
       vencendo o height:0 que os frames extras carregam (.h-0 no card-body).
       flex-basis 0 → quando o grupo tem 2+ frames empilhados, eles DIVIDEM a altura
       IGUALMENTE (2 = 50%/50%, 3 = 33% cada), independente do conteúdo de cada um.
       Com 1 frame no grupo, ele pega 100%. (Proporção custom por Model fica para depois.) */
    .janela[data-frame-nav] .frame:not(.frame-group-hidden) {
        flex: 1 1 0;
        min-height: 0;
    }

    .janela[data-frame-nav] .frame:not(.frame-group-hidden) > .card {
        display: flex;
        flex-direction: column;
        height: 100%;
        min-height: 0;
    }

    .janela[data-frame-nav] .frame:not(.frame-group-hidden) > .card > .card-body {
        flex: 1 1 auto;
        height: auto !important;
        min-height: 0;
    }

    /* Cabeçalho vira flex no mobile: título cresce e empurra ícones/botões/bolinhas
       para a direita, centralizados verticalmente. As bolinhas ficam por último (DOM),
       portanto à direita dos botões existentes — sem sobreposição. */
    .janela[data-frame-nav] .card-header {
        display: flex;
        align-items: center;
        gap: 0.5rem;
    }

    /* Título ocupa o espaço livre, empurrando o que vier depois para a direita. */
    .janela[data-frame-nav] .card-header > span[id^="headerTitulo"] {
        flex: 1 1 auto;
        min-width: 0;
    }

    /* Ícones/botões do cabeçalho perdem o float (o flex já alinha) e ficam antes das bolinhas. */
    .janela[data-frame-nav] .card-header [id^="headerBotoes"] {
        float: none !important;
        margin: 0 !important;
        order: 1;
    }

    /* Bolinhas: último item da linha, empurradas para a EXTREMA DIREITA via margin-left:auto.
       Isso funciona tanto no cabeçalho padrão (x-card-header, com span de título) quanto no
       cabeçalho HTML custom dos frames extras (que não tem o span p/ flex:1) — em ambos,
       margin-left:auto consome o espaço livre à esquerda e alinha as bolinhas à direita. */
    .janela[data-frame-nav] .frame-nav-dots {
        display: inline-flex;
        align-items: center;
        margin: 0 0 0 auto;
        order: 2;
    }

    .reserva-header-acoes {
        float: none !important;
        display: flex;
        justify-content: flex-start;
        gap: 0.75rem;
        margin-top: 0.35rem;
        width: 100%;
    }

    .reserva-header-acoes-com-solicitacao {
        min-width: 0;
    }

    /* Spinner de carregamento do grupo enquanto o conteúdo (AJAX) não chega. */
    .frame-nav-spinner {
        display: flex;
        align-items: center;
        justify-content: center;
        min-height: 4rem;
    }
}

/* ─── Adorno de unidade do campo (R$ / %) ─────────────────────────────────────
   Marca discreta que anuncia a natureza do campo: R$ à esquerda em campo de
   valor, % à direita em campo percentual. É só sinalização — não formata, não
   valida e não interfere no valor enviado.

   OPT-IN: nenhum campo recebe as classes automaticamente. Aplique caso a caso
   com `'class' => 'adorno-money'` no getFormFromJson, ou pelo comentário da
   coluna no banco (Label:Class:Type:Definition:Order). Projeto que não marcar
   nada renderiza exatamente como antes.

   NÃO reaproveita a classe `.money`: buildExtraClassForType() (Formulario.php)
   atribui `.money` a TODO campo `numeric`, então ali ela significa "tem casas
   decimais", não "é dinheiro" — pendurar o R$ nela marcaria também notas,
   taxas e percentuais, que são numeric igual.

   A marca é pintada como BACKGROUND do próprio input, não como pseudo-elemento
   de um wrapper. <input> é elemento vazio e não aceita ::before/::after, então
   a alternativa seria ancorar no elemento PAI — e ancorar no pai não funciona,
   por três motivos que só aparecem em tela:

   1. LARGURA: o helper dá `w-auto` a todo campo numérico sem `parent-*`, então
      o input fica estreito dentro de um `col-sm-10` de largura cheia e a marca
      ia parar na borda da COLUNA, solta, longe do campo.
   2. PADDING: um `.col-sm-*` tem 12px de padding lateral, então a marca caía
      DENTRO desse padding — do lado de fora da borda do campo.
   3. ALTURA: com label que quebra em várias linhas, a linha da grade fica alta
      e o `top: 50%` do pai joga a marca ABAIXO do campo.

   Como background do input, os três somem: `center` é o centro do campo e
   `left/right` são as bordas do campo, independentemente do container. É o
   mesmo alinhamento que a varinha da IA consegue envolvendo o campo num
   wrapper — aqui sem precisar mexer no HTML.

   O texto vai em SVG porque background-image não aceita texto solto; por isso
   também há uma variante para o tema escuro (data-URI não enxerga var()). */
input.adorno-money.adorno-money,
input.adorno-percent.adorno-percent {
    background-repeat: no-repeat;
}

/* A classe é repetida de propósito (`.adorno-money.adorno-money`): eleva a
   especificidade acima do padding do `.form-control` sem recorrer a
   !important. Sem isso o padding do Bootstrap vence e o valor digitado passa
   POR CIMA da marca — some no campo percentual, que alinha à direita
   (`text-end`) exatamente onde o % fica. */
input.adorno-money.adorno-money {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='12'%3E%3Ctext x='0' y='10' font-size='10' fill='%236c757d' font-family='sans-serif'%3ER$%3C/text%3E%3C/svg%3E");
    background-position: left 0.75rem center;
    padding-left: 2.4rem;
}

input.adorno-percent.adorno-percent {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12'%3E%3Ctext x='0' y='10' font-size='10' fill='%236c757d' font-family='sans-serif'%3E%25%3C/text%3E%3C/svg%3E");
    background-position: right 0.75rem center;
    padding-right: 2rem;
}

html[data-bs-theme="dark"] input.adorno-money.adorno-money {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='12'%3E%3Ctext x='0' y='10' font-size='10' fill='%23adb5bd' font-family='sans-serif'%3ER$%3C/text%3E%3C/svg%3E");
}

html[data-bs-theme="dark"] input.adorno-percent.adorno-percent {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12'%3E%3Ctext x='0' y='10' font-size='10' fill='%23adb5bd' font-family='sans-serif'%3E%25%3C/text%3E%3C/svg%3E");
}

/* Logomarca da navbar do fluxo clássico. Altura e sombra vinham em `height="30"`
   e `style=` na própria tag; saíram para cá porque o `<x-logomarca>` emite duas
   imagens quando o projeto publica a variante escura, e atributo inline só
   alcançaria a primeira — a segunda apareceria no tamanho natural do arquivo.
   A sidebar da nova UI não precisou disto: já tinha classe própria
   (`.nui-sidebar__logo-img`, em nova-ui.css), com o halo por tema. */
.navbar-brand .navbar-logo {
    height: 30px;
    width: auto;
    filter: drop-shadow(1px 1px 2px rgba(0, 0, 0, 0.5));
}

/* Selo de ambiente não-oficial na navbar do fluxo clássico. Par de
   `.nui-topbar__ambiente` (nova-ui.css) — mesma aparência nas duas interfaces,
   de propósito: quem troca de interface no perfil precisa reconhecer a marca.
   Só existe onde `application.ambiente.rotulo` está preenchido.

   `text-shadow: none` porque a `<nav>` declara sombra inline para todo o texto
   que carrega; sobre o âmbar ela sujaria o rótulo. */
.navbar .navbar-ambiente {
    padding: 3px 10px;
    border-radius: 999px;
    background: #fbbf24;
    color: #1c1917;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    white-space: nowrap;
    text-shadow: none;
}

/* ---------------------- Logomarca com variante por tema ----------------------
   Par CSS do componente `<x-logomarca>`. Ele emite duas imagens — a padrão e a
   `Logomarca-dark.png` — e é AQUI que se decide qual aparece.

   Mora em styles.css, e não em login.css, porque o componente é genérico: se a
   regra ficasse presa à tela de acesso, usá-lo em qualquer outra (navbar,
   sidebar da nova UI) mostraria as DUAS imagens empilhadas, sem erro nenhum
   avisando. styles.css carrega incondicionalmente nos dois layouts.

   As classes só existem no HTML quando o projeto publicou a variante escura;
   sem ela, o componente emite uma imagem só e estas regras não encontram nada.

   `revert` em vez de `display: block`: devolve à imagem o display que o
   navegador lhe daria, para que a variante escura se comporte EXATAMENTE como
   a clara se comportaria naquele lugar — dentro do flex do painel de login ou
   no meio de uma linha de navbar. Cravar um valor presumiria o contexto.

   Tema `auto` ainda não resolvido pelo applyTheme não casa com o seletor e cai
   na variante clara — o mesmo fallback de antes deste componente.

   `!important` não é enfeite: os utilitários de display do Bootstrap (`d-flex`,
   `d-inline-block`, `d-block`) trazem `!important` de fábrica, e só `!important`
   vence `!important`. Sem isso, uma classe utilitária na logomarca deixa as DUAS
   marcas visíveis ao mesmo tempo — foi o que aconteceu na navbar, onde a `<img>`
   carregava `d-inline-block` herdado da versão de imagem única. Como a ocultação
   passou a ser `!important`, a exibição precisa ser também: a regra base venceria
   a de tema. */
.logomarca--escura {
    display: none !important;
}

html[data-bs-theme="dark"] .logomarca--clara {
    display: none !important;
}

html[data-bs-theme="dark"] .logomarca--escura {
    display: revert !important;
}

/* ── Aviso de assinatura na janela de tolerância ─────────────────────────────
   Vive aqui, no CSS global, e não no CSS de uma tela: o aviso é renderizado
   pelo layout e aparece em QUALQUER tela do sistema. Preso ao arquivo de uma
   tela só, ele nasceria sem estilo em todas as outras — sem erro nenhum, só
   um texto solto no rodapé. (Regra: componente do Core com CSS vai no global.) */
.aviso-vencimento {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1040;
    display: flex;
    align-items: center;
    gap: .6rem;
    flex-wrap: wrap;
    padding: .55rem 1rem;
    background: #b3261e;
    color: #fff;
    font-size: .92rem;
    line-height: 1.35;
    box-shadow: 0 -2px 10px rgba(0, 0, 0, .25);
}

.aviso-vencimento i {
    flex: 0 0 auto;
    font-size: 1.05rem;
}

.aviso-vencimento span {
    flex: 1 1 auto;
    min-width: 12rem;
}

.aviso-vencimento a {
    flex: 0 0 auto;
    color: #fff;
    font-weight: 600;
    text-decoration: underline;
}

.aviso-vencimento a:hover,
.aviso-vencimento a:focus-visible {
    color: #fff;
    opacity: .85;
}

/* ── Aviso de novidades do sistema ───────────────────────────────────────────
   Global pelo mesmo motivo do aviso de vencimento: o partial é do layout e o
   modal abre em qualquer tela das duas interfaces. Cores pelos tokens do
   Bootstrap para acompanhar o tema claro/escuro. */
.novidades .novidades-dia + .novidades-dia {
    margin-top: 1.25rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--bs-border-color);
}

.novidades .novidades-data {
    margin: 0 0 .75rem;
    font-weight: 600;
}

.novidades .novidades-tipo {
    margin: .9rem 0 .35rem;
    color: var(--bs-secondary-color);
    font-size: .78rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.novidades .novidades-lista {
    margin: 0;
    padding-left: 1.2rem;
}

.novidades .novidades-item + .novidades-item {
    margin-top: .6rem;
}

.novidades .novidades-titulo {
    display: block;
    font-weight: 600;
}

.novidades .novidades-texto > :last-child {
    margin-bottom: 0;
}

.novidades .novidades-texto img {
    max-width: 100%;
    height: auto;
    border-radius: .375rem;
}

/* Na tela de histórico cada dia é um bloco próprio, com fundo de card; no
   aviso (modal) os dias seguem separados só pelo divisor acima. */
.novidades-historico .novidades-dia {
    padding: 1rem 1.25rem;
    background-color: var(--bs-card-bg, var(--bs-body-bg));
    border: 1px solid var(--bs-border-color-translucent);
    border-radius: var(--bs-border-radius-lg);
}

.novidades-historico .novidades-dia + .novidades-dia {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--bs-border-color-translucent);
}

/* ── Escolha de plano na contratação ─────────────────────────────────────────
   No CSS global, e não no `login.css`, pelo mesmo motivo do aviso de
   vencimento: a tela de contratação é do Core e cada produto herda. Presa a um
   arquivo de tela, a regra nasceria ausente em quem carregasse outro. */
.contratar-planos {
    display: grid;
    gap: .5rem;
    margin-bottom: .75rem;
}

.contratar-plano {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: .1rem .6rem;
    padding: .7rem .9rem;
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: .5rem;
    cursor: pointer;
    transition: border-color .15s ease, background-color .15s ease;
}

.contratar-plano:hover {
    border-color: var(--bs-primary, #0d6efd);
}

/* O cartão inteiro reage à seleção, não só o rádio — é o alvo que a pessoa
   realmente mira, e um rádio de 13px é difícil de acertar no telefone. */
.contratar-plano:has(input:checked) {
    border-color: var(--bs-primary, #0d6efd);
    background-color: color-mix(in srgb, var(--bs-primary, #0d6efd) 8%, transparent);
}

.contratar-plano input {
    grid-row: 1 / span 2;
    margin: 0;
}

.contratar-plano-nome {
    font-weight: 600;
}

.contratar-plano-preco {
    font-weight: 700;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* A franquia ocupa a linha inteira abaixo, fora das colunas do preço: ela é
   explicação, e competir com o valor tira a força de quem decide olhando preço. */
.contratar-plano-inclui {
    grid-column: 2 / -1;
    opacity: .75;
    line-height: 1.3;
}

/******************************************** Barra de rolagem ********************************************/
/* Barra fina em TODA a aplicação — herdeira da classe `scrollJC` do IPE Live, que ali
   precisava ser posta elemento a elemento. Aqui ela é global: qualquer área que role
   (página, card, modal, sidebar, tabela) ganha o trilho transparente de 5px, sem classe.
   O polegar só aparece com o mouse EM CIMA da área que rola (como no Projetor.css do
   IPE Live). O trilho continua reservado com a barra escondida: esconder o trilho
   inteiro (display:none) mudaria a largura útil e o conteúdo pularia a cada hover.
   Como o hover num filho também vale para os ancestrais, a barra do container aparece
   enquanto o mouse estiver em qualquer ponto dentro dele.
   Em tela de toque não existe hover, então lá a barra fica sempre visível — senão quem
   usa o celular nunca veria que a área rola.
   O polegar usa `currentColor` como no original: pega a cor do texto do próprio
   elemento, então clareia no tema escuro, escurece no claro e acompanha um card
   colorido sem regra extra. Regras com seletor próprio (#messagesArea, #chatMessages)
   seguem valendo, porque são mais específicas.
   Chrome/Edge/Safari leem os pseudo-elementos ::-webkit-scrollbar. O Chrome 121+ os
   IGNORA quando o elemento tem `scrollbar-width`/`scrollbar-color`, então as
   propriedades padrão ficam só para quem não tem o pseudo-elemento (Firefox). */
::-webkit-scrollbar {
    width: 5px;
    height: 5px;
}

::-webkit-scrollbar-track,
::-webkit-scrollbar-corner,
::-webkit-scrollbar-thumb {
    background: transparent;
}

/* O Chrome não redesenha a barra quando só a cor do polegar muda com o hover — a
   barra ficava invisível mesmo com o mouse em cima. Mudar a largura em 0,01px força
   o redesenho sem mexer no layout do conteúdo. */
:hover::-webkit-scrollbar {
    width: 5.01px;
    height: 5.01px;
}

:hover::-webkit-scrollbar-thumb {
    background: color-mix(in srgb, currentColor 50%, transparent);
}

::-webkit-scrollbar-thumb:hover {
    background: currentColor;
}

@media (hover: none) {
    ::-webkit-scrollbar-thumb {
        background: color-mix(in srgb, currentColor 50%, transparent);
    }
}

@supports not selector(::-webkit-scrollbar) {
    * {
        scrollbar-width: thin;
        scrollbar-color: transparent transparent;
    }

    :hover {
        scrollbar-color: color-mix(in srgb, currentColor 50%, transparent) transparent;
    }

    @media (hover: none) {
        * {
            scrollbar-color: color-mix(in srgb, currentColor 50%, transparent) transparent;
        }
    }
}

/* Bolha de espera da conversa com a IA (15/10/2026, proposta 10): a mesma peça da resposta
   (`.ai-message .message-bubble`: fundo, borda e raio dos tokens), com uma lista curta de etapas.
   A consulta feita leva a marca de "ok"; a atual, o aro no acento. Só tokens de `palette.css`:
   nenhum rgba nem hexadecimal aqui. */
.nui-ia-espera {
    background: var(--nui-bg-2);
    color: var(--nui-text);
    border: 1px solid var(--nui-border);
    border-radius: 1rem 1rem 1rem 0.2rem;
}

.nui-ia-espera-lista {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
}

.nui-ia-espera-item {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    font-size: 0.875em;
    line-height: 1.45;
}

.nui-ia-espera-sinal {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1rem;
    height: 1.45em;
}

.nui-ia-espera-atual {
    color: var(--nui-text);
}

.nui-ia-espera-feito {
    color: var(--nui-text-soft);
}

.nui-ia-espera-feito .nui-ia-espera-sinal {
    color: var(--nui-st-ok);
}

@media (prefers-reduced-motion: reduce) {
    .nui-ia-espera .spinner-border {
        --bs-spinner-animation-speed: 2s;
    }
}

/* LINHA DE ESTADO DO CNPJ NA RECEITA (22/10/2026) — componente `bootstrapForm/cnpj`, escrita pelo
   `preencherPelaReceita` do funcoes.js. Mora aqui, e não numa tela, porque o campo serve a todo
   formulário (clássica e nova UI). Cor de significado pelos pares `--nui-st-*` do palette.css,
   que existem nos dois temas; o segundo valor de cada `var()` só vale em página sem a paleta.
   A cor nunca diz sozinha: a frase vem junto. Vazia, a linha não ocupa espaço — sem `.d-none`,
   que dentro de formulário apaga a linha inteira (`form > div:has(.d-none)`), e sem
   `display: none`, para o `aria-live` anunciar o que entrar. Nada aqui desabilita o Salvar. */
.receita-estado {
    font-size: 0.875em;
    line-height: 1.45;
    color: var(--nui-text-soft, var(--bs-secondary-color));
}

.receita-estado:not(:empty) {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    column-gap: 0.5rem;
    margin-top: 0.25rem;
}

.receita-estado--ativo .receita-estado-texto {
    color: var(--nui-st-ok, var(--bs-success-text-emphasis));
}

.receita-estado--irregular .receita-estado-texto,
.receita-estado--invalido .receita-estado-texto {
    color: var(--nui-st-crit, var(--bs-danger-text-emphasis));
}

.receita-estado--nao-encontrado .receita-estado-texto {
    color: var(--nui-st-alert, var(--bs-warning-text-emphasis));
}

.receita-estado--limite .receita-estado-texto {
    color: var(--nui-st-warn, var(--bs-warning-text-emphasis));
}

.receita-estado-divergencia {
    color: var(--nui-st-warn, var(--bs-warning-text-emphasis));
}

.receita-estado .receita-estado-usar {
    padding: 0;
    font-size: inherit;
    vertical-align: baseline;
}
