/*
 * TagFlow — camada propria sobre o Bootstrap 5.3 vendorizado.
 *
 * Sem build step (arquitetura §4): tudo aqui e CSS nativo. As cores do tenant
 * chegam como custom properties injetadas pelo servidor, ja validadas como
 * #rrggbb e com contraste conferido — CSS nao calcula contraste, e escapar HTML
 * nao protege dentro de <style>.
 */

/* ==========================================================================
   1. Tokens
   ========================================================================== */

:root {
    /* Sobrescritos por layouts/partials/branding.php quando ha tenant. */
    --tf-primary: #0d6efd;
    --tf-on-primary: #ffffff;
    --tf-primary-hover: #0b5ed7;
    --tf-primary-active: #0a58ca;
    --tf-primary-subtle: #cfe2ff;
    --tf-primary-text: #0d6efd;

    --tf-sidebar-width: 15.5rem;
    --tf-topbar-height: 3.5rem;

    /* Neutro escuro das superficies de comando (cabecalho de tabela, botao de
       filtro). Deliberadamente NAO e a cor do tenant: se a marca fosse aplicada
       aqui, cada empresa teria uma tabela de legibilidade diferente, e a barra
       competiria com os botoes de acao que carregam a marca de verdade. */
    --tf-ink: #1b2130;
    --tf-ink-soft: #2b3348;
    --tf-on-ink: #f8f9fb;

    --tf-surface: #ffffff;
    --tf-surface-muted: #f6f7fb;
    --tf-border: rgba(20, 24, 35, .10);
    --tf-shadow: 0 1px 2px rgba(20, 24, 35, .05), 0 8px 24px -16px rgba(20, 24, 35, .28);

    /* Tons de apoio dos cartoes de indicador e das medidas de ocupacao. Fixos,
       nao derivados da marca: sao semanticos (ocupacao, aberto, em andamento) e
       precisam significar a mesma coisa em qualquer tenant. */
    --tf-tone-teal: #0f9b8e;
    --tf-tone-green: #1a9d5a;
    --tf-tone-blue: #2f6fdb;
    --tf-tone-amber: #b06f00;

    /* Area minima de toque. Nao e preferencia estetica: o sistema e operado no
       balcao do evento, com pressa, sob sol e as vezes de luva. */
    --tf-touch-target: 44px;

    --tf-radius: .5rem;
    --tf-radius-lg: .875rem;
    --tf-transition: 150ms ease;
}

/* No tema escuro as superficies invertem, mas a barra de comando NAO fica mais
   escura que o fundo — ela deixaria de se destacar. Clareia. */
[data-bs-theme="dark"] {
    --tf-ink: #2b3348;
    --tf-ink-soft: #39435c;
    --tf-on-ink: #f8f9fb;

    /* Hierarquia no escuro: pagina mais funda, cartao um degrau acima, topo e
       lateral no tom do Bootstrap. Cartao mais escuro que a pagina inverteria a
       leitura de profundidade. */
    --tf-surface: #1e222a;
    --tf-surface-muted: #15181e;
    --tf-border: rgba(255, 255, 255, .12);
    --tf-shadow: 0 1px 2px rgba(0, 0, 0, .35), 0 8px 24px -16px rgba(0, 0, 0, .6);

    --tf-tone-teal: #2dd4bf;
    --tf-tone-green: #4ade80;
    --tf-tone-blue: #7ba9ff;
    --tf-tone-amber: #facc15;
}

/* ==========================================================================
   2. Base e acessibilidade
   ========================================================================== */

body.tf-app {
    /* Pilha nativa do SO: nenhuma fonte baixada, LCP imediato. */
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    min-height: 100vh;
    background: var(--bs-body-bg);
}

/* Foco visivel e obrigatorio: e o unico rastro de posicao para quem navega por
   teclado. :focus-visible nao aparece em clique de mouse, entao nao ha o custo
   estetico que costuma levar times a removerem o outline. */
:focus-visible {
    outline: 3px solid var(--tf-primary);
    outline-offset: 2px;
    border-radius: 2px;
}

.btn:focus-visible,
.form-control:focus-visible,
.form-select:focus-visible {
    outline: 3px solid var(--tf-primary);
    outline-offset: 2px;
    box-shadow: none;
}

/* Alvos de toque. `min-height` em vez de `height` para o conteudo poder crescer. */
.btn,
.nav-link,
.dropdown-item,
.form-control,
.form-select,
.page-link {
    min-height: var(--tf-touch-target);
}

.btn-sm,
.form-control-sm,
.form-select-sm {
    /* Mesmo os "pequenos" respeitam o minimo: a densidade vem do padding
       horizontal, nunca de encolher o alvo. */
    min-height: var(--tf-touch-target);
    padding-block: .375rem;
}

/* Botao-icone: quadrado, nunca menor que o alvo minimo. */
.tf-icon-btn {
    min-width: var(--tf-touch-target);
    min-height: var(--tf-touch-target);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* Atalho para quem navega por teclado pular a navegacao repetida. */
.tf-skip-link {
    position: absolute;
    left: -999px;
    top: .5rem;
    z-index: 1100;
    background: var(--tf-primary);
    color: var(--tf-on-primary);
    padding: .75rem 1rem;
    border-radius: var(--tf-radius);
}

.tf-skip-link:focus {
    left: .5rem;
}

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

/* ==========================================================================
   3. Marca aplicada ao Bootstrap
   ========================================================================== */

.btn-primary {
    --bs-btn-bg: var(--tf-primary);
    --bs-btn-border-color: var(--tf-primary);
    --bs-btn-color: var(--tf-on-primary);
    --bs-btn-hover-bg: var(--tf-primary-hover);
    --bs-btn-hover-border-color: var(--tf-primary-hover);
    --bs-btn-hover-color: var(--tf-on-primary);
    --bs-btn-active-bg: var(--tf-primary-active);
    --bs-btn-active-border-color: var(--tf-primary-active);
    --bs-btn-disabled-bg: var(--tf-primary);
    --bs-btn-disabled-border-color: var(--tf-primary);
    --bs-btn-disabled-color: var(--tf-on-primary);
}

.btn-outline-primary {
    --bs-btn-color: var(--tf-primary-text);
    --bs-btn-border-color: var(--tf-primary);
    --bs-btn-hover-bg: var(--tf-primary);
    --bs-btn-hover-border-color: var(--tf-primary);
    --bs-btn-hover-color: var(--tf-on-primary);
}

/* Usa o tom derivado, nao a cor bruta: a cor da marca pode ser ilegivel como
   texto sobre o fundo da pagina. */
.text-primary {
    color: var(--tf-primary-text) !important;
}

/* ==========================================================================
   4. App Shell
   ========================================================================== */

.tf-topbar {
    position: sticky;
    top: 0;
    z-index: 1030;
    height: var(--tf-topbar-height);
    background: var(--bs-body-bg);
    border-bottom: 1px solid var(--bs-border-color);
}

.tf-topbar__inner {
    height: 100%;
    display: flex;
    align-items: center;
    gap: .75rem;
    padding-inline: .75rem;
}

.tf-topbar__toggle,
.tf-topbar__icon {
    min-width: var(--tf-touch-target);
    min-height: var(--tf-touch-target);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--bs-body-color);
    font-size: 1.25rem;
    text-decoration: none;
}

.tf-topbar__brand {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    color: inherit;
    text-decoration: none;
    font-weight: 600;
}

.tf-topbar__mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: var(--tf-radius);
    background: var(--tf-primary);
    color: var(--tf-on-primary);
}

.tf-topbar__logo {
    max-height: 2rem;
    max-width: 8rem;
    object-fit: contain;
}

.tf-topbar__context {
    flex: 1 1 auto;
    min-width: 0;
}

.tf-topbar__actions {
    display: flex;
    align-items: center;
    gap: .25rem;
    margin-left: auto;
}

/* Contexto de empresa: precisa ser legivel de relance, sem competir com o
   conteudo. */
.tf-context-chip {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    max-width: 100%;
    padding: .25rem .625rem;
    border: 1px solid var(--bs-border-color);
    border-radius: 2rem;
    font-size: .8125rem;
    color: var(--bs-secondary-color);
}

.tf-context-chip__value {
    font-weight: 600;
    color: var(--bs-body-color);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.tf-context-chip__action {
    color: var(--tf-primary-text);
    font-size: .75rem;
}

.tf-user {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    min-height: var(--tf-touch-target);
    border: 0;
    background: transparent;
    color: var(--bs-body-color);
}

.tf-user__avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    background: var(--tf-primary);
    color: var(--tf-on-primary);
    font-weight: 600;
    text-transform: uppercase;
}

.tf-user__info {
    display: none;
    flex-direction: column;
    align-items: flex-start;
    line-height: 1.15;
}

.tf-user__name { font-size: .875rem; font-weight: 600; }

/* O papel ativo explica por que certas telas nao aparecem no menu. */
.tf-user__role {
    font-size: .6875rem;
    color: var(--bs-secondary-color);
    text-transform: uppercase;
    letter-spacing: .03em;
}

@media (min-width: 768px) {
    .tf-user__info { display: flex; }
    .tf-topbar__inner { padding-inline: 1rem; }
}

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

.tf-shell {
    display: flex;
    min-height: calc(100vh - var(--tf-topbar-height));
}

.tf-sidebar {
    position: fixed;
    top: var(--tf-topbar-height);
    bottom: 0;
    left: 0;
    z-index: 1035;
    width: var(--tf-sidebar-width);
    padding: .75rem;
    overflow-y: auto;
    background: var(--bs-body-bg);
    border-right: 1px solid var(--bs-border-color);
    /* Mobile-first: recolhida por padrao abaixo de 992px. */
    transform: translateX(-100%);
    transition: transform var(--tf-transition);
}

.tf-sidebar.is-open {
    transform: translateX(0);
}

.tf-sidebar-backdrop {
    position: fixed;
    inset: var(--tf-topbar-height) 0 0 0;
    z-index: 1034;
    background: rgba(0, 0, 0, .4);
}

.tf-sidebar__titulo {
    padding: 1rem .75rem .25rem;
    font-size: .6875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--bs-secondary-color);
}

.tf-sidebar__link {
    position: relative;
    display: flex;
    align-items: center;
    gap: .625rem;
    padding: .625rem .75rem;
    border-radius: var(--tf-radius);
    color: var(--bs-body-color);
}

.tf-sidebar__link i { font-size: 1.05rem; width: 1.25rem; text-align: center; }

.tf-sidebar__link:hover {
    background: var(--bs-secondary-bg);
    color: var(--bs-body-color);
}

/* Ativo em tom suave, nao em bloco chapado: a marca preenchida disputava
   atencao com o botao de acao primaria da propria pagina — o unico lugar onde
   o preenchimento solido deve aparecer. O fallback existe porque color-mix
   ainda falha em navegador embarcado antigo de coletor. */
.tf-sidebar__link.active {
    background: var(--tf-primary-subtle);
    background: color-mix(in srgb, var(--tf-primary) 14%, transparent);
    color: var(--tf-primary-text);
    font-weight: 600;
}

/* A barra a esquerda repete o estado sem depender de cor — quem nao distingue
   o tom suave do fundo ainda enxerga a posicao. */
.tf-sidebar__link.active::before {
    content: "";
    position: absolute;
    inset-block: .375rem;
    left: 0;
    width: 3px;
    border-radius: 0 3px 3px 0;
    background: var(--tf-primary);
}

.tf-main {
    flex: 1 1 auto;
    min-width: 0;
    padding: 1rem;
}

@media (min-width: 992px) {
    .tf-sidebar {
        position: sticky;
        top: var(--tf-topbar-height);
        height: calc(100vh - var(--tf-topbar-height));
        transform: none;
        flex: 0 0 var(--tf-sidebar-width);
    }

    .tf-sidebar-backdrop { display: none !important; }

    .tf-main { padding: 1.5rem 2rem; }
}

/* ==========================================================================
   5. Padroes de dominio
   ========================================================================== */

/* Estados que aparecem em varias telas e precisam ler igual em todas. */
.tf-status {
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .02em;
    text-transform: uppercase;
}

.tf-status--present  { color: var(--bs-success-text-emphasis); }
.tf-status--absent   { color: var(--bs-danger-text-emphasis); }
.tf-status--pending  { color: var(--bs-warning-text-emphasis); }
.tf-status--canceled { color: var(--bs-secondary-color); }

/* Vigencia de bloqueio (RN-BLK-04). A cor sozinha nao comunica: o texto do
   badge carrega o significado, para quem nao distingue as cores. */
.tf-badge-vigente    { background: var(--bs-danger); color: #fff; }
.tf-badge-programado { background: var(--bs-primary); color: #fff; }
.tf-badge-expirado   { background: var(--bs-secondary); color: #fff; }
.tf-badge-revogado   { background: var(--bs-success); color: #fff; }

/* Numero grande de KPI: legivel do outro lado do balcao. */
.tf-kpi {
    display: flex;
    flex-direction: column;
    gap: .125rem;
}

.tf-kpi__valor {
    font-size: clamp(1.75rem, 4vw, 2.5rem);
    font-weight: 700;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.tf-kpi__rotulo {
    font-size: .8125rem;
    color: var(--bs-secondary-color);
}

/* Valor estimado, nao apurado (RN-CHR-02): precisa ser distinguivel do numero
   real, senao vira decisao tomada sobre estimativa sem que ninguem perceba. */
.tf-estimado {
    border-bottom: 1px dashed var(--bs-warning);
    cursor: help;
}

/* Codigo de credencial: lido em voz alta e digitado — sem ambiguidade. */
.tf-credential-code {
    font-family: var(--bs-font-monospace);
    font-size: 1.25rem;
    letter-spacing: .12em;
}

/* Area de leitura de tag: alvo grande, legivel a distancia. */
.tf-scan-target {
    min-height: 12rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 2px dashed var(--bs-border-color);
    border-radius: var(--bs-border-radius-lg);
}

.tf-scan-target:focus-within { border-color: var(--tf-primary); }

/* O cabecalho fixo de listagem longa esta em §6, junto do resto do padrao de
   tabela: `.tf-table-card.tf-table-sticky`. Manter uma segunda versao aqui
   deixaria duas regras disputando o fundo do <th>. */

.font-monospace-sm { font-family: var(--bs-font-monospace); font-size: .875rem; }

/* ==========================================================================
   6. Componentes de tela
   --------------------------------------------------------------------------
   Toda listagem do sistema monta a mesma sequencia, nesta ordem:

       cabecalho -> indicadores -> barra de acao e filtros -> tabela -> rodape

   Isso nao e preferencia visual. O operador troca de tela dezenas de vezes por
   turno; se o botao de criar, o filtro e a acao da linha mudarem de lugar a
   cada modulo, ele reaprende a interface toda vez. As classes abaixo existem
   para que nenhuma tela precise inventar a sua propria versao.
   ========================================================================== */

.tf-main { background: var(--tf-surface-muted); }

/* Cartoes com a mesma pele em todo lugar (o Bootstrap entrega quadrado e sem
   profundidade; a lista precisa parecer uma folha sobre a mesa). */
.card {
    --bs-card-bg: var(--tf-surface);
    --bs-card-border-color: var(--tf-border);
    border-radius: var(--tf-radius-lg);
    box-shadow: var(--tf-shadow);
}

/* --- Cabecalho de pagina -------------------------------------------------- */

.tf-page-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: .75rem;
    margin-bottom: 1.25rem;
}

.tf-page-head__title {
    margin: 0 0 .125rem;
    font-size: 1.375rem;
    font-weight: 700;
    letter-spacing: -.01em;
}

/* Resumo do conjunto que esta na tela. Fica no cabecalho, e nao dentro da
   tabela, porque responde antes da rolagem a pergunta "quanto tem aqui?". */
.tf-page-head__meta {
    margin: 0;
    font-size: .8125rem;
    color: var(--bs-secondary-color);
}

.tf-page-head__tools {
    display: flex;
    align-items: center;
    gap: .25rem;
}

/* --- Indicadores ---------------------------------------------------------- */

.tf-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: 1rem;
    margin-bottom: 1rem;
}

.tf-stat {
    display: flex;
    align-items: center;
    gap: .875rem;
    padding: 1rem 1.125rem;
    background: var(--tf-surface);
    border: 1px solid var(--tf-border);
    border-radius: var(--tf-radius-lg);
    box-shadow: var(--tf-shadow);
}

.tf-stat__icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: var(--tf-radius);
    font-size: 1.25rem;
    /* Tom de fundo derivado do proprio icone: um unico token por variante
       define fundo e simbolo, e nenhuma combinacao nova pode nascer torta. */
    color: var(--tf-stat-tone, var(--tf-primary));
    background: color-mix(in srgb, var(--tf-stat-tone, var(--tf-primary)) 14%, transparent);
}

.tf-stat--marca { --tf-stat-tone: var(--tf-primary); }
.tf-stat--verde { --tf-stat-tone: var(--tf-tone-green); }
.tf-stat--azul  { --tf-stat-tone: var(--tf-tone-blue); }
.tf-stat--teal  { --tf-stat-tone: var(--tf-tone-teal); }
.tf-stat--ambar { --tf-stat-tone: var(--tf-tone-amber); }

.tf-stat__corpo { min-width: 0; flex: 1 1 auto; }

.tf-stat__label {
    display: block;
    font-size: .8125rem;
    font-weight: 600;
    line-height: 1.2;
}

.tf-stat__hint {
    display: block;
    font-size: .75rem;
    color: var(--bs-secondary-color);
}

.tf-stat__value {
    margin-left: auto;
    font-size: 1.75rem;
    font-weight: 700;
    line-height: 1;
    /* Numeros de mesma largura: em coluna, o olho compara sem reler. */
    font-variant-numeric: tabular-nums;
}

/* --- Barra de acao e filtros ---------------------------------------------- */

.tf-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: 1rem;
    margin-bottom: 1rem;
}

/* A acao primaria fica FORA do cartao de filtros e antes dele: criar nao e
   filtrar, e o alvo mais clicado da tela nao pode depender de o operador
   varrer a barra de busca primeiro. */
.tf-toolbar__cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    min-height: var(--tf-touch-target);
    padding: 1rem 1.5rem;
    border: 0;
    border-radius: var(--tf-radius-lg);
    background: var(--tf-primary);
    color: var(--tf-on-primary);
    font-weight: 600;
    text-decoration: none;
    box-shadow: var(--tf-shadow);
    transition: background var(--tf-transition);
}

.tf-toolbar__cta:hover,
.tf-toolbar__cta:focus { background: var(--tf-primary-hover); color: var(--tf-on-primary); }

.tf-filtros {
    flex: 1 1 22rem;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .625rem;
    margin: 0;
    padding: .75rem 1rem;
    background: var(--tf-surface);
    border: 1px solid var(--tf-border);
    border-radius: var(--tf-radius-lg);
    box-shadow: var(--tf-shadow);
}

.tf-filtros__campo { flex: 1 1 12rem; min-width: 0; }

/* Busca com a lupa dentro do campo: o rotulo externo custava uma linha em
   todas as listagens e o placeholder ja diz o que se busca. O rotulo continua
   existindo para o leitor de tela, so nao ocupa espaco. */
.tf-search { position: relative; }

.tf-search .form-control { padding-right: 2.5rem; }

.tf-search__icone {
    position: absolute;
    top: 50%;
    right: .875rem;
    transform: translateY(-50%);
    color: var(--bs-secondary-color);
    pointer-events: none;
}

/* Aplicar o filtro e um comando neutro, nao a acao principal da tela: usa o
   tom escuro, para nao competir com o botao da marca ao lado. */
.btn-ink {
    --bs-btn-bg: var(--tf-ink);
    --bs-btn-border-color: var(--tf-ink);
    --bs-btn-color: var(--tf-on-ink);
    --bs-btn-hover-bg: var(--tf-ink-soft);
    --bs-btn-hover-border-color: var(--tf-ink-soft);
    --bs-btn-hover-color: var(--tf-on-ink);
    --bs-btn-active-bg: var(--tf-ink-soft);
    --bs-btn-active-border-color: var(--tf-ink-soft);
    --bs-btn-active-color: var(--tf-on-ink);
    padding-inline: 1.5rem;
    font-weight: 600;
}

/* --- Tabela --------------------------------------------------------------- */

.tf-table-card {
    background: var(--tf-surface);
    border: 1px solid var(--tf-border);
    border-radius: var(--tf-radius-lg);
    box-shadow: var(--tf-shadow);
    /* Segura os cantos do cabecalho escuro dentro do raio do cartao. */
    overflow: hidden;
}

.tf-table-card .table { margin-bottom: 0; }

.tf-table-card .table > :not(caption) > * > * { padding: .875rem 1rem; }

.tf-table-card thead th {
    background: var(--tf-ink);
    color: var(--tf-on-ink);
    border-bottom: 0;
    font-size: .8125rem;
    font-weight: 600;
    letter-spacing: .01em;
    white-space: nowrap;
}

/* Cabecalho ordenavel: o link herda a cor da barra, senao sai azul-padrao
   sobre o fundo escuro e some. O sublinhado aparece no hover para que o
   "isto e clicavel" nao dependa so da cor. */
.tf-table-card thead th a {
    color: inherit;
    text-decoration: none;
}

.tf-table-card thead th a:hover,
.tf-table-card thead th a:focus-visible {
    color: inherit;
    text-decoration: underline;
}

/* O cabecalho escuro tambem e o cabecalho fixo: some da tela e a coluna perde
   o nome no meio de uma lista longa. */
.tf-table-card.tf-table-sticky thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--tf-ink);
}

.tf-table-card tbody tr:last-child > * { border-bottom-width: 0; }

.tf-table-card .table > tbody > tr:hover > * {
    /* `--bs-table-*` em vez de background direto: o Bootstrap pinta a celula,
       e sobrescrever por fora deixaria a borda com o tom antigo. */
    --bs-table-bg-state: var(--tf-surface-muted);
}

/* Medida de ocupacao de vagas. Acompanha SEMPRE um numero — barra sozinha nao
   diz quantas vagas restam, e essa e a pergunta real de quem olha. */
.tf-meter {
    height: 4px;
    margin-top: .375rem;
    border-radius: 2px;
    background: var(--bs-secondary-bg);
    overflow: hidden;
}

.tf-meter__barra {
    display: block;
    height: 100%;
    border-radius: inherit;
    background: var(--tf-meter-tone, var(--tf-tone-teal));
}

.tf-meter--cheio { --tf-meter-tone: var(--tf-tone-amber); }

/* Badge de situacao em tom suave. O texto carrega o significado; a cor so
   acelera o reconhecimento de quem ja sabe ler a tela. */
.tf-badge {
    display: inline-block;
    padding: .3125rem .625rem;
    border-radius: 2rem;
    font-size: .75rem;
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
    color: var(--tf-badge-tone, var(--bs-secondary-color));
    background: color-mix(in srgb, var(--tf-badge-tone, var(--bs-secondary-color)) 14%, transparent);
}

.tf-badge--success { --tf-badge-tone: var(--tf-tone-green); }
.tf-badge--info    { --tf-badge-tone: var(--tf-tone-blue); }
.tf-badge--warning { --tf-badge-tone: var(--tf-tone-amber); }
.tf-badge--danger  { --tf-badge-tone: var(--bs-danger); }
.tf-badge--primary { --tf-badge-tone: var(--tf-primary-text); }
.tf-badge--secondary { --tf-badge-tone: var(--bs-secondary-color); }
.tf-badge--dark { --tf-badge-tone: var(--bs-emphasis-color); }

/* --- Acoes de linha ------------------------------------------------------- */

.tf-rowactions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: .25rem;
}

/* Icone sozinho, mas nunca sem nome: o rotulo vai no title E no aria-label. A
   coluna de acoes repete em toda linha — texto ali roubaria a largura das
   colunas que realmente diferenciam uma linha da outra. */
.tf-rowaction {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: var(--tf-touch-target);
    min-height: var(--tf-touch-target);
    padding: 0;
    border: 1px solid var(--tf-border);
    border-radius: var(--tf-radius);
    background: var(--tf-surface);
    color: var(--bs-secondary-color);
    text-decoration: none;
    transition: color var(--tf-transition), border-color var(--tf-transition);
}

.tf-rowaction:hover {
    color: var(--tf-primary-text);
    border-color: var(--tf-primary);
}

.tf-rowaction--danger:hover {
    color: var(--bs-danger-text-emphasis);
    border-color: var(--bs-danger);
}

/* --- Rodape da tabela ----------------------------------------------------- */

.tf-table-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: .75rem;
    padding: .625rem 1rem;
    border-top: 1px solid var(--tf-border);
    font-size: .8125rem;
    color: var(--bs-secondary-color);
}

.tf-table-foot__pagina { font-variant-numeric: tabular-nums; }

.tf-table-foot__nav { display: flex; align-items: center; gap: .25rem; }

.tf-table-foot .form-select {
    width: auto;
    min-height: 2.25rem;
    padding-block: .25rem;
    font-size: .8125rem;
}

/* Vazio nao e erro: diz o que aconteceu e qual e o proximo passo. */
.tf-vazio {
    padding: 3rem 1.5rem;
    text-align: center;
    color: var(--bs-secondary-color);
}

.tf-vazio__icone {
    font-size: 2rem;
    color: var(--bs-secondary-color);
    opacity: .5;
}

@media (max-width: 575.98px) {
    /* No celular a acao primaria ocupa a linha inteira: e o alvo mais provavel
       e o polegar alcanca a largura toda. */
    .tf-toolbar__cta { width: 100%; }
    .tf-table-foot { justify-content: space-between; }
}

@media print {
    .tf-no-print, .tf-topbar, .tf-sidebar, .tf-toolbar, .tf-table-foot { display: none !important; }
    .tf-main { padding: 0; background: #fff; }
    .tf-table-card { border: 0; box-shadow: none; }
    /* Cabecalho chapado gasta tinta e sai cinza no laser. */
    .tf-table-card thead th { background: transparent; color: #000; border-bottom: 2px solid #000; }
}
