﻿/*
 * Estilos do sistema Tenace Manutenção (tema claro único).
 * Tokens de marca/layout ficam no :root abaixo — alterar uma variável reflete
 * em todo o sistema. As seções seguem a ordem das telas (login, app-shell,
 * sidebar, topbar, cards, tabelas, badges, dashboard, fotos, etc.).
 */
:root {
    /* Brand */
    --brand-accent: #1C7BB6;            /* AZUL DE MARCA — amostrado da logo da Tenace. Trocar AQUI re-skin todo o sistema. */
    --brand-accent-dim: color-mix(in srgb, var(--brand-accent) 10%, transparent);
    --brand-accent-border: color-mix(in srgb, var(--brand-accent) 25%, transparent);
    --brand-accent-dark: #06497C;       /* tom escuro da marca (hover/gradiente) — 2ª tinta da logo */
    /* Acento quando vira TEXTO. É a cor da marca escurecida 5% — o mínimo para
       passar 4,5:1 (AA) sobre --bg/--sidebar-bg, que são #f0f4fa. O #1C7BB6 puro
       dá 4,17:1 ali e REPROVA: a sidebar tem o mesmo fundo da página, e é onde o
       acento mais aparece como texto. Os PREENCHIMENTOS seguem com --brand-accent
       exato, para não destoar da logo ao lado. */
    --brand-accent-text: #1B75AD;
    --brand-gold: #b8860b;              /* destaque dourado: IDs notificados, "Admin notificado", ícone do gráfico */
    --btn-blue: var(--brand-accent);    /* botões seguem a cor de marca */
    --btn-blue-dark: var(--brand-accent-dark);

    /* Layout — tema CLARO (único tema do sistema) */
    --bg: #f0f4fa;
    --card-bg: #ffffff;
    --card-bg-soft: #e8edf6;
    --input-bg: #f8fafc;
    --sidebar-bg: #f0f4fa;
    --panel-bg: rgba(255, 255, 255, 0.98);
    --border-color: rgba(0, 0, 0, 0.08);

    --primary: #0C3552;                 /* azul-petróleo — texto principal e botões neutros */
    --primary-dark: #0C3552;
    --accent: var(--brand-accent);
    --success: #22c55e;
    --danger: #ef4444;
    --warning: #f59e0b;
    --text: #0C3552;
    --muted: #64748b;
    /* ── Tipografia e toque (trazidos do sistema irmão da HF, 08/08/2026) ─────
       PISO de 12px para texto que se LÊ. A medição feita lá achou 69 textos
       abaixo de 14px por tela no celular, o menor com 9,6px — ilegível de luva,
       em pé, sob a luz do galpão. Vale igual aqui: o chamado é aberto no chão
       de fábrica. Texto NOVO usa estes tokens; nada de font-size solto abaixo
       de --fs-caption.

       EXCEÇÃO consciente: contador dentro de bolinha (sino, foto) fica menor —
       é numeral que se olha, não texto que se lê, e crescer a fonte quebraria
       o círculo.

       Os tokens entram ANTES das regras que os usarão: por ora quase nada os
       consome, e isso é proposital — a adoção é tela a tela, sem big bang. */
    --fs-caption: 0.75rem;   /* 12px — piso absoluto */
    --tap: 44px;             /* alvo mínimo de toque no celular */
    --shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
    --radius: 14px;
    --sidebar-transition: left 0.26s cubic-bezier(0.4, 0, 0.2, 1);
}

* {
    box-sizing: border-box;
}

html, body {
    margin: 0;
    /* Contém rolagem lateral no celular. NÃO remova: sem isto, tabela larga
       empurra a página para os lados no telefone. */
    overflow-x: hidden;
}

/* No DESKTOP troca `hidden` por `clip`. Parecem iguais, mas não são:
   `overflow: hidden` transforma o elemento em CONTÊINER DE ROLAGEM, e isso
   MATAVA o `position: sticky` da `.sidebar` — o menu rolava junto com a página
   e sobrava uma área branca enorme nas telas longas (auditoria, chamados).
   Medido em 06/08/2026: ao rolar 1500px, `sidebar.top` ia para -1116 em vez de 0.
   `clip` corta igual mas NÃO cria contêiner de rolagem, então o sticky volta a
   funcionar. Falha silenciosa clássica: nada quebrava, o menu só não grudava.

   Por que dentro de @media e não trocando a regra de cima: abaixo de 992px a
   `.sidebar` já é `fixed` (vira gaveta), então o `clip` não traria ganho nenhum
   no celular — e `overflow: clip` só existe no Safari 16+. Assim o telefone
   segue EXATAMENTE como está hoje e o risco de regressão em campo é zero. */
@media (min-width: 992px) {
    html, body {
        overflow-x: clip;
    }
}

body {
    min-height: 100vh;
    background: var(--bg);
    color: var(--text);
    font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

a {
    color: inherit;
    text-decoration: none;
}

/* ── Login split-screen ─────────────────────────────────────── */
.login-body {
    min-height: 100vh;
    background: var(--bg);
}

.login-split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    min-height: 100vh;
}

/* Painel esquerdo — marca */
.login-brand {
    position: relative;
    overflow: hidden;
    background: linear-gradient(145deg, #052F4F 0%, #06497C 50%, #1C7BB6 100%);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 48px 56px;
}

.login-brand-inner {
    position: relative;
    z-index: 2;
    max-width: 420px;
    text-align: center;
}

.login-logo {
    display: block;
    width: 240px;
    height: auto;
    margin: 0 auto 36px;
}

.login-logo svg {
    width: 100%;
    height: auto;
    display: block;
}

.login-brand-inner h2 {
    color: #fff;
    font-size: 1.75rem;
    font-weight: 800;
    margin: 0 0 14px;
    letter-spacing: -0.5px;
}

.login-brand-inner p {
    color: rgba(255, 255, 255, 0.68);
    font-size: 1rem;
    line-height: 1.65;
    margin: 0 0 40px;
}

.login-features {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    gap: 14px;
    text-align: left;
}

.login-features li {
    display: flex;
    align-items: center;
    gap: 14px;
    color: rgba(255, 255, 255, 0.82);
    font-size: 0.9rem;
    font-weight: 600;
}

.lf-icon {
    display: inline-grid;
    place-items: center;
    width: 38px;
    height: 38px;
    background: rgba(255, 255, 255, 0.10);
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 10px;
    flex-shrink: 0;
    color: rgba(255, 255, 255, 0.90);
    font-size: 15px;
}

/* Elementos decorativos */
.login-brand-deco {
    position: absolute;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.04);
    z-index: 1;
}

.login-deco-1 {
    width: 420px;
    height: 420px;
    top: -140px;
    right: -140px;
}

.login-deco-2 {
    width: 260px;
    height: 260px;
    bottom: -80px;
    left: -60px;
}

/* Painel direito — formulário */
.login-form-panel {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg);
    padding: 48px 40px;
}

.login-form-inner {
    width: 100%;
    max-width: 400px;
}

.login-logo-mobile {
    display: none;
    width: 150px;
    max-width: 70%;        /* nunca estoura a largura da tela */
    margin: 0 auto 28px;
}

/* O logo é um SVG inline (logo.svg). Sem isto, o SVG ignora a largura do span
   e renderiza no tamanho natural, estourando a tela no iOS/Android. */
.login-logo-mobile svg {
    width: 100%;
    height: auto;
    display: block;
}

.login-eyebrow {
    /* brand-accent, não #5FB0E2: azul claro sobre painel claro sumia sob luz forte */
    color: var(--brand-accent-text);
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 1px;
    text-transform: uppercase;
    margin: 0 0 10px;
}

.login-title {
    font-size: clamp(1.7rem, 4vw, 2.4rem);
    font-weight: 800;
    color: #f8fafc;
    margin: 0 0 10px;
    letter-spacing: -0.5px;
    line-height: 1.1;
}

html.theme-light .login-title {
    color: #0f172a;
}

.login-sub {
    color: var(--muted);
    font-size: 0.9rem;
    line-height: 1.6;
    margin: 0 0 32px;
}

.login-alert {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 16px;
    border-radius: 10px;
    font-size: 0.88rem;
    font-weight: 600;
    margin-bottom: 20px;
}

/* Cores ESCURAS de texto (mesmas dos badge-status): as claras (#fca5a5/#86efac)
   eram resto do tema escuro — "senha incorreta" ficava quase ilegível no fundo claro. */
.login-alert-danger {
    background: rgba(239, 68, 68, 0.12);
    border: 1px solid rgba(239, 68, 68, 0.28);
    color: #991b1b;
}

.login-alert-success {
    background: rgba(34, 197, 94, 0.12);
    border: 1px solid rgba(34, 197, 94, 0.28);
    color: #166534;
}

.login-form-fields {
    display: grid;
    gap: 20px;
}

.lf-group {
    display: grid;
    gap: 8px;
}

.lf-group label {
    font-size: 0.82rem;
    font-weight: 700;
    color: var(--muted);
    letter-spacing: 0.3px;
}

.lf-input-wrap {
    position: relative;
    display: flex;
    align-items: center;
}

.lf-input-icon {
    position: absolute;
    left: 14px;
    color: var(--muted);
    font-size: 14px;
    pointer-events: none;
}

.lf-input-wrap input {
    padding-left: 42px;
    padding-right: 46px;
    height: 52px;
    border-radius: 12px;
    font-size: 0.95rem;
}

.lf-eye-btn {
    position: absolute;
    right: 12px;
    background: none;
    border: none;
    color: var(--muted);
    cursor: pointer;
    padding: 6px;
    display: flex;
    align-items: center;
    font-size: 15px;
    transition: color 0.15s;
}

.lf-eye-btn:hover {
    color: var(--text);
}

.login-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    width: 100%;
    height: 52px;
    margin-top: 4px;
    background: linear-gradient(135deg, var(--btn-blue-dark), var(--btn-blue));
    border: none;
    border-radius: 12px;
    color: #ffffff;
    font-size: 1rem;
    font-weight: 800;
    cursor: pointer;
    transition: opacity 0.2s, transform 0.15s;
    letter-spacing: 0.2px;
    box-shadow: 0 4px 20px rgba(37, 99, 235, 0.30);
}

.login-btn:hover {
    opacity: 0.92;
    transform: translateY(-1px);
}

.login-btn:active {
    transform: translateY(0);
}

/* .login-remember saiu junto com o checkbox "Lembrar acesso" (16/09/2026) —
   ver o comentário no index.php. Regra sem elemento é peso morto em toda página. */

.login-footer-note {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    margin-top: 28px;
    color: var(--muted);
    font-size: 0.78rem;
}

/* Mobile — login */
@media (max-width: 860px) {
    .login-split {
        grid-template-columns: 1fr;
    }

    .login-brand {
        display: none;
    }

    .login-form-panel {
        padding: 32px 24px;
        align-items: flex-start;
        padding-top: 52px;
    }

    .login-logo-mobile {
        display: block;
    }

    .login-eyebrow {
        text-align: center;
    }

    .login-title {
        text-align: center;
    }

    .login-sub {
        text-align: center;
    }
}

/* ── Sidebar logo ───────────────────────────────────────────── */
.sidebar-logo {
    width: 38px;
    height: 38px;
    object-fit: contain;
    border-radius: 8px;
    flex-shrink: 0;
    transition: width 0.22s, height 0.22s;
}

body.sb-collapsed .sidebar-logo {
    width: 34px;
    height: 34px;
}

/* ── Auth body legado (mantém compatibilidade) ──────────────── */
.auth-body {
    display: grid;
    place-items: center;
    padding: 24px;
    background:
        radial-gradient(circle at top left, rgba(28, 123, 182, 0.18), transparent 28rem),
        radial-gradient(circle at bottom right, rgba(34, 197, 94, 0.10), transparent 24rem),
        var(--bg);
}

.auth-shell {
    width: min(100%, 460px);
}

.auth-panel,
.saas-card {
    background: var(--panel-bg);
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.28), 0 1px 0 rgba(255,255,255,0.03) inset;
}

.auth-panel {
    padding: clamp(28px, 7vw, 44px);
}

/* O 403 carrega SÓ o style.css (sem Bootstrap) — .btn aqui é apenas overlay de
   cor/raio, então o botão saía sem padding, texto colado na borda. Estilo
   autônomo completo; nas páginas com Bootstrap os valores coincidem. */
.auth-panel .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 44px;
    padding: 10px 22px;
    border: 1px solid transparent;
    text-decoration: none;
    cursor: pointer;
}

.brand-mark {
    display: inline-grid;
    place-items: center;
    width: 46px;
    height: 46px;
    border-radius: 14px;
    background: linear-gradient(135deg, var(--primary), #5FB0E2);
    color: #fff;
    font-weight: 800;
    letter-spacing: 0;
}

.eyebrow {
    color: color-mix(in srgb, var(--brand-accent) 55%, transparent);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.5px;
    margin-top: 22px;
    text-transform: uppercase;
}

.auth-panel h1,
.topbar h1 {
    margin: 0;
    /* var(--text), não #f8fafc: o tema é claro único — texto quase branco
       sobre painel branco deixava o h1 do 403 INVISÍVEL. */
    color: var(--text);
    font-weight: 800;
    letter-spacing: 0;
}

.auth-panel h1 {
    margin-top: 8px;
    font-size: clamp(2rem, 8vw, 3.25rem);
    line-height: 1.02;
}

.auth-copy,
.muted {
    color: var(--muted);
}

.auth-copy {
    margin: 18px 0 28px;
    line-height: 1.65;
}

.stack-form {
    display: grid;
    gap: 16px;
}

label span {
    display: block;
    margin-bottom: 8px;
    color: var(--muted);
    font-size: 0.86rem;
    font-weight: 700;
}

input,
select,
textarea {
    width: 100%;
    border: 1px solid var(--border-color);
    border-radius: 12px;
    background: var(--input-bg);
    color: var(--text);
    padding: 13px 14px;
    outline: none;
    transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}

input:focus,
select:focus,
textarea:focus {
    border-color: color-mix(in srgb, var(--brand-accent) 50%, transparent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-accent) 10%, transparent);
}

.btn {
    border-radius: 12px;
    font-weight: 700;
}

.btn-primary {
    border-color: var(--btn-blue);
    background: var(--btn-blue);
    color: #ffffff !important;
}

.btn-primary:hover {
    border-color: var(--btn-blue-dark);
    background: var(--btn-blue-dark);
    color: #ffffff !important;
}

.btn-secondary {
    border-color: var(--border-color);
    background: var(--card-bg-soft);
}

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

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

.app-shell {
    display: grid;
    grid-template-columns: 280px 1fr;
    min-height: 100vh;
    transition: grid-template-columns 0.22s ease;
}

body.sb-collapsed .app-shell {
    grid-template-columns: 72px 1fr;
}

.sidebar {
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    height: 100svh;   /* desconta a barra de endereço do celular (ver gaveta) */
    padding: 20px 12px 0;
    background: var(--sidebar-bg);
    border-right: 1px solid var(--border-color);
    z-index: 20;
    overflow: hidden;
}

/* ── Sidebar logo section ───────────────────────────────────── */
.sidebar-logo-section {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 10px 0 18px;
    margin-bottom: 6px;
    border-bottom: 1px solid var(--border-color);
    flex-shrink: 0;
}

.sidebar-logo-img {
    display: block;
    width: 140px;
    max-width: 100%;
    height: auto;
    flex-shrink: 0;
    transition: width 0.22s;
    text-decoration: none;
    overflow: hidden;
}

.sidebar-logo-img svg {
    width: 100% !important;
    height: auto !important;
    max-width: 100%;
    display: block;
}

body.sb-collapsed .sidebar-logo-img {
    width: 36px;
    overflow: hidden;
}

body.sb-collapsed .sidebar-nav span {
    display: none;
}

body.sb-collapsed .sidebar {
    padding-inline: 10px;
}

body.sb-collapsed .sidebar-nav a {
    justify-content: center;
}

.sidebar-collapse {
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    margin: -8px 0 18px auto;
    border: 1px solid var(--border-color);
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.04);
    color: var(--muted);
}

body.sb-collapsed .sidebar-collapse {
    margin-inline: auto;
}

body.sb-collapsed .sidebar-collapse i {
    transform: rotate(180deg);
}

.sidebar-nav {
    flex: 1;
    overflow-y: auto;
    /* Barra FINA e visível, não escondida. Antes era `none` + o webkit com
       `display:none`: o menu não cabia na tela (976px de itens em 660px úteis)
       e NADA indicava que havia mais abaixo. Pior, com o cursor sobre a sidebar
       a roda rolava o MENU em vez da página, e ele parava mostrando só o rabo.
       Foi o que gerou o print do David em 06/08/2026. Mesma solução do ampla-pcp. */
    scrollbar-width: thin;
    scrollbar-color: rgba(0, 0, 0, 0.16) transparent;
    display: grid;
    gap: 4px;
    align-content: start;
    padding-top: 8px;
}

.sidebar-nav::-webkit-scrollbar       { width: 4px; }
.sidebar-nav::-webkit-scrollbar-track { background: transparent; }
.sidebar-nav::-webkit-scrollbar-thumb {
    background: rgba(0, 0, 0, 0.16);
    border-radius: 4px;
}
.sidebar-nav::-webkit-scrollbar-thumb:hover { background: rgba(0, 0, 0, 0.30); }

/* Recolhida (72px), a barra rouba espaço do ícone e fica feia — some.
   O menu continua rolável pela roda; é o mesmo critério do ampla-pcp. */
body.sb-collapsed .sidebar-nav {
    scrollbar-width: none;
}

body.sb-collapsed .sidebar-nav::-webkit-scrollbar { display: none; }

/* ── Sidebar user section (bottom) ─────────────────────────── */
.sidebar-user-section {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 4px 18px;
    border-top: 1px solid var(--border-color);
    flex-shrink: 0;
    margin-top: 8px;
}

.sidebar-user-avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: linear-gradient(135deg, #0C3552, var(--brand-accent));
    color: #fff;
    display: grid;
    place-items: center;
    font-weight: 800;
    font-size: 0.75rem;
    flex-shrink: 0;
    letter-spacing: 0.5px;
}

.sidebar-user-info {
    flex: 1;
    min-width: 0;
}

.sidebar-user-info strong {
    display: block;
    font-size: 0.83rem;
    font-weight: 700;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: #e2e8f0;
}

.sidebar-user-info span {
    display: block;
    font-size: 0.68rem;
    color: var(--muted);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.3px;
}

html.theme-light .sidebar-user-info strong {
    color: #0C3552;
}

html.theme-light .sidebar-user-info span {
    color: #64748b;
}

body.sb-collapsed .sidebar-user-section {
    justify-content: center;
}

body.sb-collapsed .sidebar-user-info {
    display: none;
}

.sidebar-nav a {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 48px;
    padding: 11px 14px;
    border-radius: 12px;
    color: rgba(148, 163, 184, 0.75);
    font-weight: 600;
    font-size: 0.9rem;
    border-left: 3px solid transparent;
    transition: background 0.18s, color 0.18s, border-color 0.18s;
}

.sidebar-nav a i {
    width: 20px;
    text-align: center;
    flex-shrink: 0;
    font-size: 1rem;
    transition: color 0.18s;
}

.sidebar-nav a:hover {
    background: color-mix(in srgb, var(--brand-accent) 6%, transparent);
    color: #e2e8f0;
    border-left-color: color-mix(in srgb, var(--brand-accent) 25%, transparent);
}

.sidebar-nav a.active {
    background: var(--brand-accent-dim);
    color: var(--brand-accent-text);
    border-left-color: var(--brand-accent-text);
    font-weight: 700;
}

.sidebar-nav a.active i {
    color: var(--brand-accent-text);
}

/* ── Tooltip da sidebar recolhida ───────────────────────────────
   Com a barra só em ícones (body.sb-collapsed), passar o mouse sobre um item
   mostra o nome numa etiqueta flutuante. Ela é anexada ao <body> via JS
   (posição fixa) para não ser cortada pelo overflow da sidebar/nav. */
.sidebar-tooltip {
    position: fixed;
    z-index: 1000;
    background: #0C3552;
    color: #fff;
    padding: 7px 12px;
    border-radius: 8px;
    font-size: 0.82rem;
    font-weight: 600;
    white-space: nowrap;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.28);
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.12s ease;
}
.sidebar-tooltip.show { opacity: 1; }
.sidebar-tooltip::before {
    content: '';
    position: absolute;
    left: -5px;
    top: 50%;
    transform: translateY(-50%);
    border: 5px solid transparent;
    border-right-color: #0C3552;
    border-left: 0;
}

.content {
    padding: 22px;
    min-width: 0;
    overflow-x: hidden;
}

.topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
    margin-bottom: 24px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--border-color);
}

.topbar-left {
    display: flex;
    align-items: center;
    gap: 14px;
}

.topbar-sys-title {
    font-size: 1.05rem;
    font-weight: 800;
    color: var(--text);
    letter-spacing: 0.1px;
}

html.theme-light .topbar-sys-title {
    color: #0C3552;
}

.topbar-right {
    display: flex;
    align-items: center;
    gap: 10px;
}

.topbar h1 {
    font-size: clamp(1.3rem, 4vw, 1.9rem);
    font-weight: 800;
    letter-spacing: -0.3px;
}

/* Notification button */
.notif-btn {
    position: relative;
    width: 42px;
    height: 42px;
    display: grid;
    place-items: center;
    border: 1px solid var(--border-color);
    border-radius: 12px;
    background: var(--card-bg);
    color: var(--text);
    cursor: pointer;
    font-size: 1rem;
    transition: background 0.15s;
}

.notif-btn:hover {
    background: var(--card-bg-soft);
}

.notif-badge {
    position: absolute;
    top: -5px;
    right: -5px;
    min-width: 18px;
    height: 18px;
    padding: 0 4px;
    background: #ef4444;
    color: #fff;
    border-radius: 999px;
    font-size: 0.62rem;
    font-weight: 800;
    display: grid;
    place-items: center;
    border: 2px solid var(--bg);
}

/* Notification wrapper & panel */
.notif-wrapper {
    position: relative;
}

.notif-panel {
    display: none;
    position: fixed;
    top: 70px;
    right: 12px;
    left: auto;
    width: 340px;
    max-width: calc(100vw - 24px);
    background: var(--card-bg);
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    z-index: 9999;
    overflow: hidden;
}

.notif-panel.open {
    display: flex;
    flex-direction: column;
}

.notif-panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border-color);
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--text);
}

.notif-mark-all {
    background: none;
    border: none;
    color: var(--primary);
    font-size: 0.75rem;
    font-weight: 600;
    cursor: pointer;
    padding: 0;
}

.notif-mark-all:hover {
    text-decoration: underline;
}

.notif-panel-body {
    max-height: 380px;
    overflow-y: auto;
}

.notif-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding: 32px 16px;
    color: var(--muted);
    font-size: 0.85rem;
}

.notif-empty i {
    font-size: 1.8rem;
}

.notif-item {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border-color);
    text-decoration: none;
    transition: background 0.12s;
}

.notif-item:hover {
    background: var(--card-bg-soft);
}

.notif-item-icon {
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    background: var(--brand-accent-dim);
    border: 1px solid var(--brand-accent-border);
    border-radius: 8px;
    display: grid;
    place-items: center;
    color: var(--brand-accent-text);
    font-size: 0.85rem;
    position: relative;
}

.notif-item-count {
    position: absolute;
    top: -5px;
    right: -5px;
    background: #dc2626;
    color: #fff;
    font-size: 0.6rem;
    font-weight: 700;
    line-height: 1;
    min-width: 16px;
    height: 16px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 3px;
}

.notif-item-body {
    flex: 1;
    min-width: 0;
}

.notif-item-msg {
    font-size: 0.82rem;
    color: var(--text);
    line-height: 1.4;
    word-break: break-word;
}

.notif-ticket-id {
    font-weight: 800;
    color: var(--brand-accent-text);
}

.notif-item-time {
    font-size: 0.72rem;
    color: var(--muted);
    margin-top: 3px;
}

/* Checkbox "Notificar admin" no formulário de detalhe */
.notif-admin-check {
    background: var(--brand-accent-dim);
    border: 1px solid var(--brand-accent-border);
    border-radius: 10px;
    padding: 10px 14px;
}

.notif-admin-label {
    display: flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    font-size: 0.85rem;
    color: var(--text);
    font-weight: 600;
    margin: 0;
}

.notif-admin-label input[type="checkbox"] {
    width: 16px;
    height: 16px;
    accent-color: var(--brand-accent-text);
    flex-shrink: 0;
}

.notif-admin-label i {
    color: var(--brand-accent-text);
}

/* Logout button */
.logout-btn {
    display: flex;
    align-items: center;
    gap: 6px;
    height: 40px;
    padding: 0 16px;
    border: 1px solid var(--border-color);
    border-radius: 10px;
    background: transparent;
    color: var(--muted);
    font-weight: 600;
    font-size: 0.85rem;
    cursor: pointer;
    transition: all 0.15s;
    white-space: nowrap;
}

.logout-btn:hover {
    background: rgba(239, 68, 68, 0.08);
    border-color: rgba(239, 68, 68, 0.35);
    color: #ef4444;
}

.icon-btn {
    display: inline-grid;
    place-items: center;
    width: 42px;
    height: 42px;
    border: 1px solid var(--border-color);
    border-radius: 12px;
    background: var(--card-bg);
    color: var(--text);
}

.detail-grid {
    display: grid;
    gap: 18px;
    margin-bottom: 18px;
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.saas-card {
    padding: 20px;
    margin-bottom: 18px;
}

.card-heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    margin-bottom: 18px;
}

.card-heading h2 {
    margin: 0;
    color: #f0f4ff;
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: 0.1px;
}

.filter-grid,
.form-grid,
.info-grid {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 12px;
    align-items: stretch;
}

/* ── Filtros recolhíveis no celular ──────────────────────────────────────────
 * TRAZIDO DO SISTEMA IRMÃO DA HF em 08/08/2026, onde já está em produção.
 * Entra INERTE: só age quando uma tela envolver o formulário num
 * <details class="filtros-recolhiveis">. Adoção tela a tela, como o card.
 *
 * O bloco de filtros ocupa a PRIMEIRA TELA INTEIRA no celular: quem abre
 * "Em aberto" quer ver chamado, não formulário.
 *
 * COMO FUNCIONA, e por que é assim:
 * O <details> nasce FECHADO no HTML. No desktop, o CSS o força aberto e esconde
 * o "Filtros" — a tela fica idêntica à de antes. O conteúdo de um <details>
 * fechado é escondido pelo SLOT interno do navegador, não por display no filho:
 * só `::details-content` solta. Por isso o `@supports selector(::details-content)`
 * envolve as DUAS regras do desktop — num navegador sem suporte, esconder o
 * summary sem conseguir abrir o conteúdo deixaria o filtro INALCANÇÁVEL no
 * desktop. Sem suporte, o desktop degrada para um botão "Filtros" que abre:
 * pior que hoje, mas funcional. Suporte: Chrome/Edge 131+, Safari 18.4+, FF 139+.
 *
 * ARMADILHA DE MEDIÇÃO (herdada da HF): `getBoundingClientRect` devolve caixa
 * mesmo para conteúdo escondido por content-visibility — mede "visível" nas
 * duas larguras e quase fez descartarem a técnica. Quem responde certo é
 * `checkVisibility()`.
 */
.filtros-recolhiveis > summary {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: var(--tap);
    padding: 10px 14px;
    margin-bottom: 12px;
    border: 1px solid var(--border-color);
    border-radius: 12px;
    background: var(--card-bg-soft);
    color: var(--text);
    font-weight: 700;
    font-size: 0.9rem;
    cursor: pointer;
    list-style: none;              /* tira o triângulo padrão */
    -webkit-tap-highlight-color: transparent;
}

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

/* Seta própria, que gira ao abrir — o triângulo nativo não segue os tokens */
.filtros-recolhiveis > summary::after {
    content: '\f078';              /* fa-chevron-down */
    font-family: 'Font Awesome 6 Free';
    font-weight: 900;
    margin-left: auto;
    font-size: 0.8rem;
    color: var(--muted);
    transition: transform 0.2s;
}

.filtros-recolhiveis[open] > summary::after { transform: rotate(180deg); }

/* Quantos filtros estão aplicados. Sem isto, o usuário vê a lista já filtrada
   com o bloco fechado e não entende por que "sumiram" registros.
   Usa --brand-accent, então sai no AZUL daqui — a marca do irmão não vem junto. */
.filtros-contador {
    display: inline-grid;
    place-items: center;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: 999px;
    background: var(--brand-accent);
    color: #fff;
    font-size: var(--fs-caption);
    font-weight: 800;
}

@supports selector(::details-content) {
    @media (min-width: 769px) {
        /* Desktop: exatamente como antes — filtro sempre aberto, sem o botão. */
        .filtros-recolhiveis > summary { display: none; }
        .filtros-recolhiveis::details-content { content-visibility: visible !important; }
    }
}

.filter-grid label,
.form-grid label {
    grid-column: span 1;
}

.form-grid .span-2 {
    grid-column: span 3;
}

.app-table {
    margin: 0;
    color: var(--text);
    --bs-table-bg: transparent;
    --bs-table-color: var(--text);
    --bs-table-hover-bg: rgba(28, 123, 182, 0.08);
    --bs-table-border-color: var(--border-color);
}

.app-table th {
    color: color-mix(in srgb, var(--brand-accent) 50%, transparent);
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    font-weight: 700;
    border-bottom: 1px solid var(--border-color) !important;
}

.app-table td,
.app-table th {
    padding: 13px 14px;
    vertical-align: middle;
}

.app-table tbody tr {
    border-bottom: 1px solid rgba(148, 163, 184, 0.06);
    transition: background 0.15s;
}

.app-table tbody tr:hover {
    background: color-mix(in srgb, var(--brand-accent) 4%, transparent) !important;
}

.badge-status {
    display: inline-flex;
    align-items: center;
    min-height: 26px;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 700;
    border: 1.5px solid transparent;
    letter-spacing: 0.2px;
}

/* Status dos chamados — outlined com cor da borda */
.badge-status-open      { background: rgba(245,158,11,0.08);  color: #b45309; border-color: rgba(245,158,11,0.35); }
.badge-status-attending { background: rgba(28,123,182,0.12); color: #06497C; border-color: rgba(28,123,182,0.34); }
.badge-status-success   { background: rgba(34,197,94,0.08);   color: #166534; border-color: rgba(34,197,94,0.35); }
.badge-status-error     { background: rgba(239,68,68,0.08);   color: #991b1b; border-color: rgba(239,68,68,0.30); }

.app-modal {
    background: var(--card-bg);
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    color: var(--text);
}

.modal-header,
.modal-footer {
    border-color: var(--border-color);
}

.info-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-items: stretch;
}

.info-grid div {
    padding: 14px 16px;
    border: 1.5px solid rgba(0,0,0,0.09);
    border-radius: 12px;
    background: rgba(15, 23, 42, 0.38);
    min-width: 0;
    overflow: hidden;
    transition: border-color 0.15s;
}

.info-grid span {
    display: block;
    color: var(--muted);
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.3px;
}

.info-grid strong {
    display: block;
    margin-top: 6px;
    word-break: normal;
    overflow-wrap: break-word;
    font-size: 0.92rem;
    line-height: 1.4;
}

.reason-box {
    margin-top: 16px;
    padding: 14px;
    border-radius: 12px;
    background: rgba(239, 68, 68, 0.12);
    border: 1px solid rgba(239, 68, 68, 0.25);
}

.timeline {
    display: grid;
    gap: 12px;
}

.timeline-item {
    padding: 14px;
    border: 1px solid var(--border-color);
    border-radius: 12px;
    background: rgba(15, 23, 42, 0.36);
}

.timeline-item p {
    margin: 6px 0;
    color: var(--text);
}

.timeline-item span {
    color: var(--muted);
    font-size: 0.82rem;
}

.table-actions {
    white-space: nowrap;
}

.table-actions .btn,
.table-actions form {
    margin: 2px;
}

.check-row {
    display: flex;
    align-items: center;
    gap: 10px;
}

.check-row input {
    width: 18px;
    height: 18px;
}

.check-row span {
    margin: 0;
}

.permission-grid {
    display: grid;
    grid-template-columns: 1fr 110px 110px;
    gap: 10px;
    align-items: center;
}

.permission-grid > div,
.permission-grid > label {
    min-height: 44px;
    padding: 10px 12px;
    border: 1px solid var(--border-color);
    border-radius: 12px;
    background: rgba(15, 23, 42, 0.32);
}

.permission-head {
    color: var(--muted);
    font-size: 0.78rem;
    font-weight: 800;
    text-transform: uppercase;
}

/* Tema claro: caixas brancas como o .info-grid — o rgba(15,23,42,.32) acima
   é resto do tema escuro e virava um cinza-chumbo destoante no modal claro. */
html.theme-light .permission-grid > div,
html.theme-light .permission-grid > label {
    background: #ffffff;
    border-color: #e2e8f0;
}

.check-row.compact {
    justify-content: center;
}

/* Coluna "Editar" dos módulos que são só consulta (Permission::EDITABLE_MODULES).
   Ocupa a célula para o grid não desalinhar, mas fica claramente inativa. */
.perm-na {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--muted);
    font-weight: 700;
}

@media (max-width: 1100px) {
    .detail-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .filter-grid,
    .form-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .filter-grid label,
    .form-grid label,
    .form-grid .span-2 {
        grid-column: span 1;
    }
}

@media (max-width: 991px) {
    /* Sidebar sai do fluxo — conteúdo ocupa tela toda */
    .app-shell {
        display: block;
    }

    .sidebar {
        position: fixed;
        top: 0;
        left: -300px;
        /* `svh` também AQUI, não só na regra base: esta declaração vem DEPOIS e
           vencia, anulando o 100svh de cima. No iPhone o 100vh inclui a área sob
           a barra do Safari, e o rodapé da gaveta (nome e perfil do usuário)
           ficava cortado atrás dela. O 100vh fica como reserva para navegador
           sem suporte a svh. Trazido do sistema irmão da HF em 08/08/2026. */
        height: 100vh;
        height: 100svh;
        width: 272px;
        z-index: 100;
        transition: var(--sidebar-transition);
        box-shadow: none;
    }

    .sidebar.open {
        left: 0;
        box-shadow: 4px 0 32px rgba(0, 0, 0, 0.40);
    }

    .sidebar-logo-img {
        width: 120px;
    }

    .sidebar-collapse {
        display: none;
    }

    /* Conteúdo sempre ocupa 100% no mobile */
    .content {
        width: 100%;
        min-width: 0;
    }

    .topbar {
        align-items: center;
    }
}

@media (max-width: 680px) {
    .content {
        padding: 16px;
    }

    .detail-grid,
    .filter-grid,
    .form-grid,
    .info-grid,
    .permission-grid {
        grid-template-columns: 1fr;
    }

    .card-heading,
    .topbar {
        align-items: stretch;
        flex-direction: column;
    }

    .btn {
        min-height: 44px;
    }

    .modal-dialog {
        margin: 0;
        margin-top: auto;
        max-width: 100%;
    }

    .modal-content.app-modal {
        border-radius: 20px 20px 0 0;
    }
}

/* ── Sidebar backdrop (mobile) ─────────────────────────────── */
.sidebar-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.52);
    z-index: 19;
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}

.sidebar-backdrop.active {
    display: block;
}

/* ── Password eye toggle ────────────────────────────────────── */
.input-wrap {
    position: relative;
}

.input-wrap input {
    padding-right: 46px;
}

/* ── Priority badges ────────────────────────────────────────── */
.badge-priority {
    display: inline-flex;
    align-items: center;
    min-height: 24px;
    padding: 3px 9px;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.3px;
}

/* Prioridades — tema light: cores nítidas e legíveis */
.badge-priority-low    { background: rgba(100,116,139,0.10); color: #64748b; }
.badge-priority-medium { background: color-mix(in srgb, var(--brand-accent) 8%, transparent);   color: var(--brand-accent-text); }
.badge-priority-high   { background: rgba(234,88,12,0.10);  color: #c2410c; }
.badge-priority-urgent { background: rgba(220,38,38,0.10);  color: #dc2626; border: 1.5px solid rgba(220,38,38,0.30); font-weight: 900; }

/* ── Info-grid tema claro — card branco com borda visível ─── */
html.theme-light .info-grid div {
    background: #ffffff;
    border-color: #e2e8f0;
    box-shadow: 0 1px 3px rgba(0,0,0,0.04);
}
html.theme-light .info-grid div:hover {
    border-color: #cbd5e1;
}

/* ── Timeline background ───────────────────────────────────── */
.timeline-item {
    background: rgba(0, 0, 0, 0.06);
}

/* ── Icon-btn respects theme ────────────────────────────────── */
.icon-btn {
    background: var(--card-bg);
}

/* ── Sidebar nav active/hover respects theme ─────────────────  */
html.theme-light .sidebar-collapse {
    background: rgba(255,255,255,0.08);
    border-color: rgba(255,215,0,0.15);
    color: rgba(255,215,0,0.6);
}

/* Alerta urgente */
.alert-urgent {
    display: flex;
    /* flex-wrap: em tela estreita o link desce para a linha de baixo em vez
       de espremer o texto (sem wrap, cada nó de texto vira flex item anônimo
       e quebra palavra por palavra). No desktop cabe em uma linha — sem efeito. */
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    padding: 12px 18px;
    margin-bottom: 18px;
    background: rgba(239, 68, 68, 0.10);
    border: 1px solid rgba(239, 68, 68, 0.30);
    border-radius: 12px;
    /* #991b1b (mesmo do badge-status-error) — #fca5a5 era resto do tema escuro
       e deixava o aviso de chamados urgentes ilegível no fundo claro. */
    color: #991b1b;
    font-size: 0.9rem;
    font-weight: 600;
}

/* Texto do alerta agrupado num único flex item — flui como frase normal.
   Base 160px (não auto): garante que o texto fique SEMPRE ao lado do ícone
   (em 320px, com base auto, o span inteiro descia e o ícone ficava só). */
.alert-urgent-text {
    flex: 1 1 160px;
    min-width: 0;
}

.alert-urgent i {
    font-size: 1.1rem;
    flex-shrink: 0;
    color: #ef4444;
}

.alert-urgent a {
    margin-left: auto;
    /* tom escuro da marca — #93c5fd (azul claro) não tinha contraste no tema claro */
    color: var(--brand-accent-dark);
    text-decoration: underline;
    text-underline-offset: 3px;
    font-weight: 700;
    white-space: nowrap;
}

/* ── Mobile bottom navigation bar ──────────────────────────── */
.mobile-bottom-nav {
    display: none;
}

@media (max-width: 991px) {
    .mobile-bottom-nav {
        display: flex;
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        z-index: 50;
        background: var(--sidebar-bg);
        border-top: 1px solid color-mix(in srgb, var(--brand-accent) 12%, transparent);
        padding: 8px 0;
        padding-bottom: calc(8px + env(safe-area-inset-bottom));
        box-shadow: 0 -4px 24px rgba(0,0,0,0.40);
    }

    .mobile-bottom-nav a {
        flex: 1;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 4px;
        padding: 6px 4px;
        color: rgba(148, 163, 184, 0.65);
        font-size: 0.6rem;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: 0.4px;
        transition: color 0.15s;
        text-decoration: none;
    }

    .mobile-bottom-nav a i {
        font-size: 1.15rem;
    }

    .mobile-bottom-nav a.active,
    .mobile-bottom-nav a:hover {
        color: var(--brand-accent-text);
    }

    /* Itens inativos LEGÍVEIS no tema claro: rgba(148,163,184,.65) sobre
       #f0f4fa dava contraste ~1.9:1 — no sol do chão de fábrica os ícones
       da barra praticamente sumiam. #64748b é o mesmo --muted do sistema. */
    html.theme-light .mobile-bottom-nav a,
    html.theme-light .mobile-bottom-nav button {
        color: #64748b;
    }

    html.theme-light .mobile-bottom-nav a.active {
        color: var(--brand-accent-text);
    }

    .content {
        padding-bottom: calc(80px + env(safe-area-inset-bottom));
    }
}

/* Celular estreito: 6 itens × rótulo "FINALIZADOS" não cabem em 360px
   (rótulo quebrava em 2 linhas e o "Sair" saía da tela). Padrão Material
   "selected label": só o item ATIVO mostra o texto — e ganha fatia maior
   de flex para o rótulo caber numa linha. O ativo fica ainda mais óbvio:
   ícone indigo + único rótulo visível da barra. */
@media (max-width: 560px) {
    .mobile-bottom-nav a,
    .mobile-bottom-nav button {
        min-width: 0;
    }

    .mobile-bottom-nav a span,
    .mobile-bottom-nav button span {
        display: none;
    }

    .mobile-bottom-nav a.active {
        flex: 2 1 0%;
    }

    .mobile-bottom-nav a.active span {
        display: block;
        white-space: nowrap;
        letter-spacing: 0.2px;
    }
}

/* ── Light theme sidebar overrides ──────────────────────────── */
html.theme-light .sidebar {
    border-right-color: rgba(0,0,0,0.08);
    box-shadow: 2px 0 12px rgba(0,0,0,0.04);
}

html.theme-light .sidebar-nav a {
    color: #64748b;
    border-left-color: transparent;
}

html.theme-light .sidebar-nav a:hover {
    background: rgba(26, 45, 92, 0.06);
    color: #0C3552;
    border-left-color: rgba(26, 45, 92, 0.20);
}

html.theme-light .sidebar-nav a.active {
    background: #ffffff;
    color: var(--brand-accent-text);
    border-left-color: var(--brand-accent-text);
    font-weight: 700;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

html.theme-light .sidebar-nav a.active i {
    color: var(--brand-accent-text);
}

html.theme-light .card-heading h2 {
    color: #0C3552;
}

html.theme-light .app-table th {
    color: #64748b;
}

html.theme-light .sidebar-user-section {
    border-top-color: rgba(0,0,0,0.08);
}

html.theme-light .sidebar-collapse {
    background: rgba(0,0,0,0.04);
    border-color: rgba(0,0,0,0.10);
    color: #64748b;
}

/* ── Dashboard greeting ─────────────────────────────────────── */
.dash-greeting-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 16px;
    margin-bottom: 24px;
}

.dash-greeting {
    font-size: 1.55rem;
    font-weight: 800;
    margin: 0 0 4px;
    color: var(--text);
}

html.theme-light .dash-greeting {
    color: #0C3552;
}

.dash-greeting-sub {
    color: var(--muted);
    margin: 0;
    font-size: 0.88rem;
}

.btn-new-ticket {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 12px 22px;
    background: linear-gradient(135deg, var(--btn-blue-dark), var(--btn-blue));
    color: #ffffff;
    border: none;
    border-radius: 12px;
    font-weight: 800;
    font-size: 0.95rem;
    cursor: pointer;
    text-decoration: none;
    white-space: nowrap;
    box-shadow: 0 4px 18px rgba(37, 99, 235, 0.30);
    transition: opacity 0.2s, transform 0.15s, box-shadow 0.2s;
    flex-shrink: 0;
}

.btn-new-ticket:hover {
    opacity: 0.92;
    transform: translateY(-1px);
    box-shadow: 0 6px 22px rgba(37, 99, 235, 0.40);
    color: #ffffff;
}

/* ── KPI cards (novo estilo) ────────────────────────────────── */
.kpi-row {
    display: grid;
    /* minmax(0, 1fr): "1fr" sozinho = minmax(auto, 1fr) e o min-content do
       card ("Visualizado pelo técnico") vence a fatia — a coluna estoura a
       viewport e .content{overflow-x:hidden} DECEPA o card. Mesmo padrão já
       usado em .detail-grid. */
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 16px;
    margin-bottom: 22px;
}

.kpi-card {
    background: var(--card-bg);
    border: 1px solid var(--border-color);
    border-radius: 14px;
    padding: 20px;
    display: flex;
    align-items: flex-start;
    gap: 16px;
    box-shadow: 0 2px 12px rgba(0,0,0,0.12);
    transition: transform 0.2s, box-shadow 0.2s;
}

.kpi-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(0,0,0,0.16);
}

.kpi-icon-circle {
    width: 54px;
    height: 54px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    font-size: 1.3rem;
    flex-shrink: 0;
}

.kpi-icon-circle.kpi-open    { background: rgba(245, 158, 11, 0.14); color: #f59e0b; }
.kpi-icon-circle.kpi-attend  { background: rgba(28, 123, 182, 0.14); color: #1C7BB6; }
.kpi-icon-circle.kpi-done    { background: rgba(34, 197, 94, 0.14);  color: #22c55e; }
.kpi-icon-circle.kpi-cancel  { background: rgba(239, 68, 68, 0.14);  color: #ef4444; }
.kpi-icon-circle.kpi-urgent  { background: rgba(220, 38, 38, 0.14);  color: #dc2626; }

/* Tokens semânticos de cor — substituem hex inline no dashboard e no detalhe do
   chamado. Mesmos hex já usados nos badges/ratings acima — NÃO criar cor nova. */
.kpi-danger      { color: #dc2626; }
.kpi-warning     { color: #b45309; }
.kpi-gold        { color: #ca8a04; }
.kpi-success     { color: #166534; }
.kpi-danger-dim  { background: rgba(220, 38, 38, 0.08); }
.kpi-gold-dim    { background: rgba(234, 179, 8, 0.10); }

.kpi-body {
    flex: 1;
    min-width: 0;
}

.kpi-label {
    font-size: 0.8rem;
    color: var(--muted);
    font-weight: 600;
    margin-bottom: 4px;
}

.kpi-number {
    font-size: 2.1rem;
    font-weight: 800;
    line-height: 1;
    margin-bottom: 10px;
}

.kpi-number.kpi-open-txt    { color: #f59e0b; }
.kpi-number.kpi-attend-txt  { color: #1C7BB6; }
.kpi-number.kpi-done-txt    { color: #22c55e; }
.kpi-number.kpi-cancel-txt  { color: #ef4444; }
.kpi-number.kpi-urgent-txt  { color: #dc2626; }

.kpi-detail-link {
    font-size: 0.75rem;
    font-weight: 700;
    text-decoration: none;
    transition: opacity 0.15s;
}

.kpi-detail-link:hover { opacity: 0.75; }
.kpi-detail-link.kpi-open-link    { color: #f59e0b; }
.kpi-detail-link.kpi-attend-link  { color: #1C7BB6; }
.kpi-detail-link.kpi-done-link    { color: #22c55e; }
.kpi-detail-link.kpi-cancel-link  { color: #ef4444; }
.kpi-detail-link.kpi-urgent-link  { color: #dc2626; }

/* ── Dashboard main 2-col row ───────────────────────────────── */
.dash-main-row {
    display: grid;
    /* minmax(0, Nfr): sem o piso 0, o min-content do canvas do Chart.js
       trava a coluna e o card estoura a viewport no celular (mesma causa
       raiz do .kpi-row) */
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    gap: 18px;
    margin-bottom: 18px;
}

/* ── Recent tickets list (right panel) ──────────────────────── */
.recent-list {
    display: flex;
    flex-direction: column;
}

.recent-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 0;
    border-bottom: 1px solid var(--border-color);
    text-decoration: none;
    transition: background 0.12s;
}

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

.recent-id {
    font-size: 0.78rem;
    font-weight: 800;
    color: var(--primary);
    min-width: 38px;
    flex-shrink: 0;
}

html.theme-light .recent-id { color: #0C3552; }

.recent-info {
    flex: 1;
    min-width: 0;
}

.recent-store {
    font-size: 0.68rem;
    color: var(--muted);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.3px;
}

.recent-title {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.recent-meta {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 3px;
    flex-wrap: wrap;
}

.recent-time {
    font-size: 0.7rem;
    color: var(--muted);
    white-space: nowrap;
}

/* ── Open tickets filters ───────────────────────────────────── */
.open-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 16px;
}

.open-filters select,
.open-filters input[type="date"],
.open-filters input[type="text"] {
    flex: 1;
    min-width: 130px;
    height: 40px;
    padding: 0 12px;
    font-size: 0.84rem;
    border-radius: 10px;
}

/* ── Action icon buttons (table) ────────────────────────────── */
.action-icon-btn {
    width: 34px;
    height: 34px;
    display: inline-grid;
    place-items: center;
    border: 1px solid var(--border-color);
    border-radius: 8px;
    background: transparent;
    color: var(--muted);
    font-size: 0.9rem;
    text-decoration: none;
    transition: border-color 0.15s, color 0.15s, background 0.15s;
    cursor: pointer;
}

.action-icon-btn:hover {
    border-color: var(--primary);
    color: var(--primary);
    background: rgba(28,123,182,0.07);
}

html.theme-light .action-icon-btn:hover {
    border-color: #0C3552;
    color: #0C3552;
    background: rgba(26,45,92,0.06);
}

/* ── Status dot ─────────────────────────────────────────────── */
.status-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    margin-right: 6px;
    flex-shrink: 0;
}

.status-dot-open    { background: #f59e0b; }
.status-dot-attend  { background: #1C7BB6; }
.status-dot-done    { background: #22c55e; }
.status-dot-cancel  { background: #ef4444; }

/* ── Responsive kpi-row ─────────────────────────────────────── */
@media (max-width: 1200px) {
    /* minmax(0,1fr) e não 1fr — ver comentário no .kpi-row base */
    .kpi-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 1100px) {
    .dash-main-row { grid-template-columns: minmax(0, 1fr); }
}

/* Guarda: o canvas do Chart.js recebe width inline no primeiro render;
   sem o teto ele segura a largura antiga ao encolher a tela */
.dash-main-row canvas {
    max-width: 100%;
}

@media (max-width: 680px) {
    .kpi-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .dash-greeting-row { flex-direction: column; align-items: flex-start; }
}

@media (max-width: 480px) {
    /* Em celular estreito, 2 colunas deixam ~46px de texto por card
       (156px − padding 40 − ícone 54 − gap 16): rótulo quebra em 3 linhas
       e "Ver detalhes" vira duas. Uma coluna dá card inteiro e legível. */
    .kpi-row { grid-template-columns: 1fr; }
}

/* ── Delete zone (seção de exclusão de chamado) ─────────────── */
.delete-zone {
    border: 1px solid rgba(239, 68, 68, 0.30) !important;
    background: rgba(239, 68, 68, 0.05) !important;
}

.delete-zone .card-heading h2 {
    /* vermelho legível no claro — #fca5a5 era resto do tema escuro */
    color: #dc2626;
}

/* ── Alert deleted (banner de chamado excluído) ─────────────── */
.alert-deleted {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 16px 20px;
    margin-bottom: 18px;
    background: rgba(239, 68, 68, 0.10);
    border: 1px solid rgba(239, 68, 68, 0.30);
    border-radius: 14px;
    /* #991b1b — o #fca5a5 (tema escuro) sumia no fundo claro */
    color: #991b1b;
    font-size: 0.9rem;
}

.alert-deleted i {
    font-size: 1.25rem;
    flex-shrink: 0;
    margin-top: 2px;
    color: #ef4444;
}

.alert-deleted strong {
    color: #991b1b;
}

.alert-deleted p {
    margin: 4px 0 0;
    color: var(--muted);
    font-size: 0.85rem;
}

/* ── Galeria de fotos ────────────────────────────────────────── */
.foto-section { margin-bottom: 18px; }

.foto-count-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 22px;
    height: 22px;
    padding: 0 6px;
    border-radius: 11px;
    background: var(--brand-accent-dim);
    color: var(--brand-accent-text);
    font-size: 0.72rem;
    font-weight: 800;
    margin-left: 8px;
}

.foto-gallery {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 12px;
    margin-bottom: 8px;
}

.foto-item {
    position: relative;
    border-radius: 12px;
    overflow: hidden;
    border: 1px solid var(--border-color);
    background: var(--card-bg-soft);
}

.foto-thumb {
    display: block;
    aspect-ratio: 1;
    overflow: hidden;
}

.foto-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform .2s;
}

.foto-thumb:hover img { transform: scale(1.04); }

.foto-meta {
    padding: 6px 8px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    font-size: 0.72rem;
    color: var(--muted);
    line-height: 1.3;
}

.foto-delete-btn {
    position: absolute;
    top: 6px;
    right: 6px;
    background: rgba(239,68,68,.85);
    color: #fff;
    border: none;
    border-radius: 8px;
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.75rem;
    cursor: pointer;
    opacity: 0;
    transition: opacity .15s;
}

.foto-item:hover .foto-delete-btn { opacity: 1; }

.foto-delete-form { display: contents; }

@media (max-width: 600px) {
    .foto-gallery { grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); }
}

/* ── Relógio no topbar ───────────────────────────────────── */
.topbar-clock {
    font-size: 0.78rem;
    color: var(--muted);
    font-weight: 500;
    margin-left: 14px;
    white-space: nowrap;
    display: none;
}
.topbar-clock::before {
    content: '·';
    margin-right: 10px;
    color: var(--muted);
    font-size: 1rem;
    font-weight: 400;
    vertical-align: middle;
    opacity: 0.4;
}
@media (min-width: 640px) { .topbar-clock { display: inline; } }

/* ── Grupos da sidebar ───────────────────────────────────── */
.sidebar-group-label {
    font-size: 0.68rem;
    font-weight: 800;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: var(--muted);
    padding: 14px 14px 4px;
    opacity: 0.6;
    transition: opacity 0.2s;
}
body.sb-collapsed .sidebar-group-label {
    display: none;
}

/* ── Sidebar — fundo claro original ─────────────────────── */
html.theme-light {
    --sidebar-bg: #f0f4fa;
}
html.theme-light .sidebar {
    background: var(--sidebar-bg);
    border-right-color: rgba(0,0,0,0.08);
    box-shadow: 2px 0 12px rgba(0,0,0,0.04);
}
html.theme-light .sidebar-nav a {
    color: #64748b;
    border-left-color: transparent;
}
html.theme-light .sidebar-nav a:hover {
    background: rgba(26,45,92,0.06);
    color: #0C3552;
    border-left-color: rgba(26,45,92,0.20);
}
html.theme-light .sidebar-nav a.active {
    background: #ffffff;
    color: var(--brand-accent-text);
    border-left-color: var(--brand-accent-text);
    font-weight: 700;
    box-shadow: 0 2px 8px rgba(0,0,0,0.08);
}
html.theme-light .sidebar-nav a.active i {
    color: var(--brand-accent-text);
}
html.theme-light .sidebar-group-label {
    color: #94a3b8;
}
html.theme-light .sidebar-user-info strong   { color: #0C3552; }
html.theme-light .sidebar-user-info span     { color: #64748b; }
html.theme-light .sidebar-collapse {
    color: #64748b;
    background: rgba(0,0,0,0.04);
    border-color: rgba(0,0,0,0.08);
}
html.theme-light .sidebar-collapse:hover {
    background: rgba(0,0,0,0.08);
    color: #0C3552;
}
html.theme-light .sidebar-user-section {
    border-top-color: rgba(0,0,0,0.08);
}
html.theme-light .sidebar-user-avatar {
    background: linear-gradient(135deg, var(--primary), #5FB0E2);
    color: #fff;
}

/* ── #2 KPI cards com borda colorida superior ────────────── */
.kpi-card {
    border-top-width: 3px !important;
    border-top-style: solid !important;
}
.kpi-card:nth-child(1) { border-top-color: #f59e0b; }
.kpi-card:nth-child(2) { border-top-color: #1C7BB6; }
.kpi-card:nth-child(3) { border-top-color: #22c55e; }
.kpi-card:nth-child(4) { border-top-color: #ef4444; }

/* Variante NEUTRA para as telas de relatório: as cores por posição acima foram
   desenhadas para o dashboard (aberto/visualizado/finalizado/não atendido).
   Nos relatórios a posição não tem esse significado — o card "Vencidos" (número
   vermelho) ganhava tarja VERDE no topo. Mesma especificidade, declarada depois: vence. */
.kpi-row.kpi-flat .kpi-card {
    border-top-color: color-mix(in srgb, var(--primary) 22%, transparent);
}

/* ── Badges de perfil de usuário ─────────────────────────── */
.badge-role {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 0.78rem;
    font-weight: 600;
    white-space: nowrap;
    color: var(--muted);
}
.badge-role::before {
    content: '';
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}
.badge-role-admin   { color: var(--brand-accent-text); }
.badge-role-admin::before   { background: var(--brand-accent); }
.badge-role-gerente { color: #15803d; }
.badge-role-gerente::before { background: #22c55e; }
.badge-role-tecnico { color: #b45309; }
.badge-role-tecnico::before { background: #f59e0b; }

html.theme-light .badge-role-admin   { color: var(--brand-accent-text); }
html.theme-light .badge-role-gerente { color: #15803d; }
html.theme-light .badge-role-tecnico { color: #92400e; }

/* ── Descrição do chamado ────────────────────────────────── */
.ticket-desc {
    color: #374151;
    font-size: 0.93rem;
    line-height: 1.75;
    overflow-wrap: break-word;
    word-break: break-word;
    position: relative;
    margin-bottom: 4px;
}

/* Truncado — só quando JS adicionar a classe .truncated */
.ticket-desc.truncated {
    max-height: 110px;
    overflow: hidden;
    transition: max-height 0.3s ease;
}
.ticket-desc.truncated::after {
    content: '';
    position: absolute;
    bottom: 0; left: 0; right: 0;
    height: 36px;
    background: linear-gradient(transparent, var(--card-bg));
    pointer-events: none;
    transition: opacity 0.25s;
}
.ticket-desc.truncated.expanded { max-height: 2000px; }
.ticket-desc.truncated.expanded::after { opacity: 0; }

.ticket-desc-toggle {
    background: none;
    border: none;
    color: var(--brand-accent-text);
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
    padding: 2px 0 12px;
    display: none;
}
.ticket-desc-toggle.visible { display: inline-flex; align-items: center; gap: 4px; }

/* ── Grid fixo de ações na tabela de usuários ────────────── */
.user-actions-grid {
    display: grid;
    grid-template-columns: repeat(5, 30px);
    gap: 3px;
    align-items: center;
}

/* Cada célula tem tamanho fixo — é ela quem ocupa o grid, não o botão/form */
.ua-cell {
    width: 30px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Botão e form preenchem a célula */
.ua-btn {
    width: 30px !important;
    height: 28px !important;
    padding: 0 !important;
    border-radius: 7px !important;
    font-size: 0.82rem;
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
}

.ua-cell form {
    margin: 0;
    padding: 0;
    display: contents;
}

/* ── Tabelas no celular ──────────────────────────────────────
   Em telas pequenas, a tabela rola na horizontal (dentro de
   .table-responsive) em vez de esmagar/sobrepor as colunas. */
@media (max-width: 768px) {
    .table-responsive {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        /* Sombras de rolagem (scroll shadow, técnica CSS clássica com
           background-attachment local/scroll): uma sombra na borda direita
           avisa que EXISTE mais coluna escondida — sem isso o usuário acha
           que a tabela termina ali e que "faltam dados". Some sozinha quando
           a rolagem chega ao fim. Funciona porque o fundo das linhas da
           .app-table é transparente. */
        background:
            linear-gradient(to right, var(--card-bg) 30%, rgba(255, 255, 255, 0)),
            linear-gradient(to right, rgba(255, 255, 255, 0), var(--card-bg) 70%) 100% 0,
            radial-gradient(farthest-side at 0 50%, rgba(0, 0, 0, 0.16), transparent),
            radial-gradient(farthest-side at 100% 50%, rgba(0, 0, 0, 0.16), transparent) 100% 0;
        background-repeat: no-repeat;
        background-size: 40px 100%, 40px 100%, 14px 100%, 14px 100%;
        background-attachment: local, local, scroll, scroll;
    }
    .app-table {
        min-width: 560px;
    }
}

/* ── Crédito do desenvolvedor (sutil e elegante) ─────────────── */
.dev-credit {
    margin-top: 20px;
    text-align: center;
    font-size: 0.72rem;
    color: var(--muted);
    letter-spacing: 0.3px;
}
.dev-credit a {
    color: var(--brand-accent-text);
    font-weight: 700;
}
.dev-credit a:hover { text-decoration: underline; }

.sidebar-credit {
    text-align: center;
    font-size: 0.66rem;
    color: var(--muted);
    padding: 2px 4px 10px;
    letter-spacing: 0.3px;
}
.sidebar-credit a {
    color: var(--muted);
    font-weight: 700;
    transition: color 0.15s;
}
.sidebar-credit a:hover { color: var(--brand-accent-text); }
/* na sidebar recolhida (só ícones), oculta o crédito */
body.sb-collapsed .sidebar-credit { display: none; }

/* ── SLA badges ──────────────────────────────────────────────────────────── */
.badge-sla {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 0.68rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.3px;
}
.badge-sla-overdue { background: rgba(220,38,38,0.10);  color: #dc2626; border: 1.5px solid rgba(220,38,38,0.30); }
.badge-sla-risk    { background: rgba(234,88,12,0.10);  color: #ea580c; border: 1.5px solid rgba(234,88,12,0.30); }

/* Cores de texto do prazo SLA no detalhe */
.sla-overdue { color: #dc2626; }
.sla-risk    { color: #ea580c; }
.sla-ok      { color: var(--text); }

/* ── Avaliação estrelas ──────────────────────────────────────────────────── */
/* Stars em ordem reversa (CSS hack: input:checked ~ label) */
.rating-stars {
    display: flex;
    flex-direction: row-reverse;
    justify-content: flex-end;
    gap: 4px;
    margin-bottom: 16px;
}
.rating-stars input[type="radio"] { display: none; }
.rating-stars label {
    cursor: pointer;
    font-size: 1.6rem;
    color: #d1d5db;
    transition: color 0.12s;
}
.rating-stars input:checked        ~ label { color: #f59e0b; }
.rating-stars label:hover,
.rating-stars label:hover          ~ label { color: #fbbf24; }

/* Avaliação já registrada — somente leitura */
.rating-display { display: flex; align-items: center; gap: 4px; margin-bottom: 8px; }
.rating-star-display { font-size: 1.3rem; color: #f59e0b; }
.rating-star-display.fa-regular { color: #d1d5db; }
.rating-score { font-size: 1.1rem; font-weight: 800; color: #ca8a04; margin-left: 8px; }
.rating-comment {
    font-size: 0.88rem;
    color: var(--text);
    background: var(--surface-2);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    padding: 10px 14px;
    margin-top: 8px;
}

/* ── Push button no painel de notificações ───────────────────────────────── */
.notif-panel-push {
    padding: 8px 14px;
    border-bottom: 1px solid var(--border-color);
}
.notif-push-btn {
    width: 100%;
    background: var(--brand-accent-dim);
    color: var(--brand-accent-text);
    border: 1px solid var(--brand-accent-border);
    border-radius: 8px;
    padding: 6px 12px;
    font-size: 0.78rem;
    font-weight: 700;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 6px;
    transition: opacity 0.15s;
}
.notif-push-btn:hover { opacity: 0.8; }
.notif-push-btn:disabled { opacity: 0.45; cursor: default; }

/* ── Regra card×tabela no celular (≤768px) ───────────────────────────────────
   TRAZIDO DO SISTEMA IRMÃO DA HF em 08/08/2026, onde já está em produção.
   Aqui entra INERTE: nada muda até uma tela pedir a classe `.table-cards`.
   A adoção é uma tela por vez, com o robô validando cada passo — por isso o
   bloco sobe antes das views, e não junto.

   Quando o usuário decide POR ITEM (abrir, editar, atender), a linha da tabela
   vira um CARD empilhado. Com a rolagem horizontal que existe hoje (min-width
   560px em `.app-table`), Prioridade/Status/SLA e o botão "Abrir" — a ÚNICA
   ação da linha — ficam fora da tela no celular; em usuários, a coluna com
   EXCLUIR PERMANENTE fica invisível. Onde a tarefa é COMPARAR linha com linha
   (relatórios, auditoria), a tabela com rolagem continua sendo o certo.

   É a MESMA <table> colapsada por CSS: classe `.table-cards` na tabela +
   `data-label` nos <td> de metadado (o rótulo sai do ::before). Desktop não
   muda em NADA — tudo vive dentro deste @media. O filtro do dashboard faz
   row.style.display = '' | 'none': o '' devolve o display ao valor DESTA
   folha, então o card sobrevive ao filtro. */
@media (max-width: 768px) {
    /* sem isto a rolagem horizontal continua (herda .app-table 560px acima) */
    .app-table.table-cards { min-width: 0; }

    .table-cards { display: block; }
    .table-cards thead { display: none; }
    .table-cards tbody { display: block; }

    /* Cada linha vira card. Flex com quebra (e não grid): a 1ª linha do card
       junta identificador + badges de larguras imprevisíveis e cada tabela tem
       um número diferente de células — grid exigiria um template por tabela. */
    .table-cards tbody tr {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: 8px 12px;
        padding: 12px 14px;
        margin-bottom: 10px;
        background: var(--card-bg);
        border: 1px solid var(--border-color);
        border-radius: 12px;
    }

    .table-cards td {
        display: block;
        padding: 0;
        border: 0;
        min-width: 0;
    }

    /* Estado vazio ("Nenhum chamado encontrado...") ocupa o card inteiro */
    .table-cards td:only-child { flex: 1 1 100%; }

    /* Linha 1 do card: identificador + badges (prioridade/status) */
    .table-cards td.tc-id     { order: -4; }
    .table-cards td.tc-badges { order: -3; display: inline-flex; align-items: center; gap: 6px; }

    /* Título com no máximo 2 linhas */
    .table-cards td.tc-title {
        order: -2;
        flex: 1 1 100%;
        max-width: none !important; /* dashboard: max-width inline é a verdade do desktop */
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 2;
        line-clamp: 2;
        overflow: hidden;
        font-weight: 600;
        line-height: 1.35;
    }
    /* dashboard: o span do título carrega block+nowrap+ellipsis INLINE no style
       (comportamento do desktop, preservado); só !important devolve a quebra
       em 2 linhas aqui dentro do card. */
    .table-cards td.tc-title > span {
        display: inline !important;
        white-space: normal !important;
    }

    /* Metadados compactos; o rótulo é impresso do data-label */
    .table-cards td.tc-meta { font-size: 0.82rem; }
    .table-cards td[data-label]::before {
        content: attr(data-label) ": ";
        color: var(--muted);
        font-weight: 700;
        font-size: var(--fs-caption);
    }

    /* Ação em largura total na base do card, no alvo mínimo de toque.
       Vários botões (Editar/Desativar/Excluir) dividem a mesma linha. */
    .table-cards td.tc-action {
        order: 10;
        flex: 1 1 100%;
        display: flex;
        gap: 8px;
        white-space: normal; /* .table-actions traz nowrap do desktop */
    }
    /* !important para vencer o display:inline !important do .d-inline */
    .table-cards td.tc-action form { display: contents !important; }
    .table-cards td.tc-action .btn {
        flex: 1 1 auto;
        min-height: var(--tap);
        display: inline-flex;
        align-items: center;
        justify-content: center;
        margin: 0;
    }
    /* Placeholder que só faz sentido em TABELA. Um "—" preenche a célula vazia e
       mantém a grade legível; no card, sem cabeçalho de coluna, ele vira um traço
       solto sem significado. Marque com esta classe e ele some só no card. */
    .table-cards .tc-vazio-no-card {
        display: none;
    }

    /* Linha DESTACADA (`.table-danger` do Bootstrap, usada em relatorio_equipamentos
       e relatorio_preventiva para marcar SLA vencido / preventiva atrasada).
       O Bootstrap pinta o fundo CÉLULA a célula — correto numa linha de tabela,
       mas no card cada campo virava um retângulo rosa solto, com aparência de
       marca-texto torto (visto em screenshot no iPhone em 16/09/2026). Aqui o
       fundo sai das células e vai para o CARD inteiro, com faixa lateral: o
       destaque fica legível e o card continua parecendo um card.
       `!important` porque a regra do Bootstrap usa a variável --bs-table-bg-state
       direto no <td> e vence por especificidade. */
    .table-cards tbody tr.table-danger > td {
        background-color: transparent !important;
    }
    .table-cards tbody tr.table-danger {
        background: rgba(220, 38, 38, 0.06);
        border-color: rgba(220, 38, 38, 0.30);
        border-left: 4px solid #dc2626;
    }

    /* dashboard: os ícones de ação dividem a largura do card.
       `height: auto` + `min-height` é OBRIGATÓRIO aqui: o `.action-icon-btn` tem
       `height: 34px` FIXO na regra base, e a regra do `--tap` logo acima só pega
       `.btn` — o ícone não é `.btn`. Sem isto ele ganhava só LARGURA e ficava com
       34px de altura (medido em 09/09/2026 no iPhone 13 e no Pixel 7), abaixo dos
       44px que o próprio projeto define como alvo mínimo. O dashboard é a única
       tela que usa esta classe, então a lacuna passou despercebida na Etapa 2. */
    .table-cards td.tc-action > div { flex: 1 1 auto; }
    .table-cards td.tc-action .action-icon-btn {
        flex: 1 1 auto;
        height: auto;
        min-height: var(--tap);
    }
    /* usuários: as células fixas (44px) se espalham pela largura do card —
       continuam VISÍVEIS e tocáveis, sem rolagem */
    .table-cards td.tc-action .user-actions-grid {
        width: 100%;
        justify-content: space-between;
    }
}

/* ── Paginação das listas (09/09/2026) ───────────────────────────────────────
   Usada em chamados e usuários. Os botões herdam `.btn` do Bootstrap, então já
   ganham os 44px de alvo de toque pela regra do `--tap` no celular. */
.paginacao {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    flex-wrap: wrap;
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--border-color);
}

.paginacao-info {
    color: var(--muted);
    font-size: 0.85rem;
}

/* Estado "não há para onde ir": mantém o botão no lugar para a barra não pular
   de posição entre páginas, mas sem parecer clicável. */
.paginacao .disabled {
    opacity: 0.45;
    pointer-events: none;
}

/* ── Alvo mínimo de toque no celular (09/09/2026) ────────────────────────────
   Auditoria em iPhone 13 e Pixel 7 emulados achou 7 grupos de link/botão abaixo
   dos 44px que o próprio projeto define em `--tap`. O pior tinha 15px — no
   galpão, de luva, isso não se acerta. Rolagem lateral, elemento fora da tela e
   erro de JS deram ZERO na mesma medição; o problema era só o tamanho do toque.

   SÓ ABAIXO DE 992px, DE PROPÓSITO: no desktop há mouse, 44px é desnecessário e
   esticaria um visual que já está aprovado. É o mesmo critério do `overflow-x:
   clip`, que também vive dentro de um media query.

   A técnica é `min-height` + `inline-flex`, não `padding`: o padding empurraria
   o texto e mexeria no espaçamento dos cards; o min-height cresce só a ÁREA
   CLICÁVEL, deixando a tipografia onde está. */
@media (max-width: 991px) {
    /* KPIs do dashboard: "Ver detalhes →" media 15px, o pior caso do sistema */
    .kpi-detail-link,
    /* "Ver todos" / "Ver todos →" no cabeçalho dos cards: 19px */
    .card-heading a,
    /* "Ver chamados urgentes" na faixa vermelha: 22px */
    .alert-urgent a {
        display: inline-flex;
        align-items: center;
        min-height: var(--tap);
    }

    /* Número do chamado (#123) nas listas em modo card: media 20px e é o link
       PRINCIPAL — é por ele que se abre o chamado no celular. */
    .table-cards td.tc-id a {
        display: inline-flex;
        align-items: center;
        min-height: var(--tap);
    }

    /* Topo: "Abrir menu" e o sino de notificações tinham 42px (faltavam 2px).
       `min-*` vence o `width/height: 42px` das regras base. */
    .icon-btn,
    .notif-btn {
        min-width: var(--tap);
        min-height: var(--tap);
    }

    /* Campos de filtro e ações do menu do usuário: 40px */
    .form-control,
    .form-select,
    .logout-btn {
        min-height: var(--tap);
    }

    /* "Instalar como aplicativo": 24px — e é justamente o botão que leva o
       operador a instalar o PWA, onde o push funciona no iPhone. O `display`
       dele é inline e controlado por JS (nasce `none`, vira `flex`), por isso
       aqui só o min-height: mexer no display brigaria com o script. */
    #headerInstallBtn {
        min-height: var(--tap);
    }

    /* Barra inferior do celular: os itens mediam 65x30. É a navegação MAIS usada
       no aparelho — e 30px é metade do alvo de abas que iOS e Android adotam.
       O <button type=submit> ("Sair") entra junto: mora no mesmo <nav>, com
       estilo inline, e ficaria desalinhado dos vizinhos se crescesse sozinho. */
    .mobile-bottom-nav a,
    .mobile-bottom-nav button {
        min-height: var(--tap);
        justify-content: center;
    }

    /* Filtros do dashboard (div.open-filters): 40px. Não têm as classes do
       Bootstrap, então a regra .form-control/.form-select acima não os alcança. */
    .open-filters select,
    .open-filters input {
        min-height: var(--tap);
    }

    /* Número do chamado nas telas que seguem TABELA de propósito (relatórios,
       auditoria): 20px. Ali não há `.table-cards`, então a regra do `tc-id`
       acima não pega — e o link continua sendo o caminho para abrir o chamado.
       Seletor por href porque esses <a> usam style inline e não têm classe. */
    td > a[href^="chamado_detalhe.php"] {
        display: inline-flex;
        align-items: center;
        min-height: var(--tap);
    }
}

/* ── Impressão (Ctrl+P direto de qualquer tela) ──────────────────────────────
   A fábrica imprime listas para levar ao chão de fábrica. Sem isto, a folha
   saía com sidebar, topbar, botões e a tabela cortada. Só papel: conteúdo. */
@media print {
    .sidebar,
    .sidebar-backdrop,
    .mobile-bottom-nav,
    .topbar,
    .notif-panel,
    .btn,
    .btn-new-ticket,
    .action-icon-btn,
    .foto-delete-btn,
    .dev-credit,
    .sidebar-credit,
    .alert {
        display: none !important;
    }

    body {
        background: #fff;
    }

    .app-shell {
        display: block;
    }

    .content {
        padding: 0;
        overflow: visible;
    }

    .saas-card,
    .kpi-card {
        box-shadow: none;
        border: 1px solid #d1d5db;
        break-inside: avoid;
    }

    /* Tabela inteira no papel — nada de rolagem/corte nem largura mínima */
    .table-responsive {
        overflow: visible !important;
        background: none !important;
    }

    .app-table {
        min-width: 0 !important;
        font-size: 11px;
    }

    a {
        text-decoration: none !important;
    }
}
