:root {
  --bg: #071018;
  --bg-soft: #0e1823;
  --panel: rgba(9, 16, 24, 0.88);
  --panel-solid: #ffffff;
  --panel-muted: #f4f7fb;
  --text: #13212d;
  --text-soft: #66778a;
  --white: #ffffff;
  --line: #e5ebf2;
  --primary: #11adb4;
  --primary-strong: #0e9aa0;
  --accent: #8fcb3a;
  /* Gradiente da marca (verde → ciano). REGRA: textos/botões de destaque usam
     este gradiente, nunca ciano sólido. Texto: classe .brand-grad-text. */
  --brand-grad: linear-gradient(118deg, #8fcb3a 0%, #8fcb3a 42%, #5cbf7e 64%, #16b1b3 92%, #11adb4 100%);
  --brand-grad-strong: linear-gradient(118deg, #7bbf2e 0%, #7bbf2e 50%, #11adb4 100%);
  --danger: #e3525b;
  --warning: #f0ad39;
  --shadow: 0 18px 50px rgba(5, 14, 24, 0.12);
  --radius: 18px;
  --radius-sm: 12px;
  --sidebar-width: 344px;
  --sidebar-collapsed-width: 88px;
  --sidebar-padding-inline: 18px;
  --sidebar-padding-block: 22px;
  --nav-item-icon-col: 20px;
  --nav-item-icon-col-collapsed: 18px;
  --nav-item-action-col: 18px;
  --nav-item-col-gap: 12px;
  --nav-item-pad-inline: 12px;
  --nav-item-pad-block: 11px;
  --topbar-height: 92px;
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; min-height: 100%; font-family: 'Inter', sans-serif; background: linear-gradient(180deg, #edf2f8 0%, #f7f9fc 100%); color: var(--text); }
a { text-decoration: none; color: inherit; }
button, input, select { font: inherit; }
input, select { width: 100%; height: 44px; border-radius: 12px; border: 1px solid var(--line); background: #fff; padding: 0 14px; color: var(--text); }
/* Radio/checkbox NUNCA são width:100%/height:44px — a regra genérica acima os
   inflava virando um "botão/círculo gigante" (e espremia o texto ao lado até
   quebrar palavra-por-palavra) em qualquer modal/lista. Reset pro tamanho nativo. */
input[type="radio"], input[type="checkbox"] {
  width: auto; height: auto; min-width: 0; padding: 0; border: 0;
  border-radius: 0; background: none; accent-color: #16a34a;
}
/* ════════════ MOBILE-FIRST GUARDRAILS ════════════════════════════════════
   Regra nº1 do retrabalho de mobile: inputs date/number/select têm min-width
   INTRÍNSECO e NÃO encolhem em flex/grid → estouram o container → scroll lateral.
   `min-width:0` global nos controles mata isso no app INTEIRO (≈226 inputs +
   futuros) de uma vez. Ver project_conferencia_deck_turbinada / feedback_mobile_first_sempre. */
input, select, textarea { min-width: 0; max-width: 100%; box-sizing: border-box; }
/* ⚠️ O campo de data do iPhone mora em `css/controles.css` (chamado #33 da J&M):
   é regra das TRÊS camadas — app, portal e hub —, e o portal e o hub não
   carregam este arquivo. */
/* Primitivos responsivos pra FEATURE NOVA usar (em vez de re-inventar grid/flex
   com largura fixa, que é o que quebra no celular). Mobile-first: a base já é o
   layout de celular; telas largas só ADICIONAM colunas. */
.v-grid  { display: grid; gap: 12px; grid-template-columns: 1fr; min-width: 0; }       /* 1 col no celular */
@media (min-width: 560px) { .v-grid { grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); } }
.v-grid > * { min-width: 0; }                                                          /* filhos encolhem */
.v-2col  { display: grid; gap: 12px; grid-template-columns: 1fr; min-width: 0; }
@media (min-width: 480px) { .v-2col { grid-template-columns: minmax(0,1fr) minmax(0,1fr); } }
.v-2col > * { min-width: 0; }
.v-row   { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; min-width: 0; } /* toolbar/form-row que QUEBRA */
.v-row > * { min-width: 0; flex: 1 1 auto; }
/* Shell de modal mobile-first: tela quase cheia no celular, centrado no desktop;
   nunca gera scroll lateral. Use .v-modal (overlay) + .v-modal-card (conteúdo). */
.v-modal { position: fixed; inset: 0; z-index: 3000; display: flex; align-items: flex-end; justify-content: center; padding: 0; background: rgba(10,16,20,.55); }
/* O atributo [hidden] precisa vencer o display:flex acima (senão o modal aparece
   aberto/vazio na carga quando escondido só via `hidden`). */
.v-modal[hidden] { display: none !important; }
@media (min-width: 560px) { .v-modal { align-items: center; padding: 16px; } }
.v-modal-card { background: #fff; width: 100%; max-width: 560px; max-height: 92vh; overflow-y: auto; overflow-x: hidden; border-radius: 16px 16px 0 0; padding: 18px; box-sizing: border-box; }
@media (min-width: 560px) { .v-modal-card { border-radius: 16px; } }
.v-modal-card * { max-width: 100%; }
/* ══════════════════════════════════════════════════════════════════════════ */
/* iOS dá ZOOM automático ao focar campo com fonte < 16px. Forçar 16px em telas
   touch (≤820px) mata o zoom automático em TODO o app — mantendo o pinch-zoom
   manual (não usamos maximum-scale, que prejudica acessibilidade). */
@media (max-width: 820px) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
  select, textarea { font-size: 16px !important; }
}
label { display: grid; gap: 8px; font-size: 14px; color: var(--text-soft); font-weight: 600; }
.app-shell { --sidebar-current-width: var(--sidebar-width); display: grid; grid-template-columns: var(--sidebar-current-width) minmax(0, 1fr); min-height: 100vh; align-items: stretch; transition: grid-template-columns .28s ease; }
body.sidebar-collapsed .app-shell { --sidebar-current-width: var(--sidebar-collapsed-width); }
.sidebar { width: var(--sidebar-current-width); min-width: var(--sidebar-current-width); max-width: var(--sidebar-current-width); background: radial-gradient(circle at 20% 0%, rgba(17,173,180,.22), transparent 25%), radial-gradient(circle at 100% 20%, rgba(143,203,58,.16), transparent 20%), linear-gradient(180deg, #071018 0%, #0d1721 100%); color: rgba(255,255,255,.92); padding: var(--sidebar-padding-block) var(--sidebar-padding-inline) 20px; display: flex; flex-direction: column; justify-content: flex-start; gap: 12px; position: sticky; top: 0; height: 100dvh; min-height: 100vh; border-right: 1px solid rgba(255,255,255,.07); overflow: visible; transition: width .28s ease, padding .28s ease; }
.sidebar-scroll { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; scrollbar-width: none; -ms-overflow-style: none; }
.sidebar-scroll::-webkit-scrollbar { width: 0; height: 0; display: none; }
/* Collapsed: flyout precisa escapar lateralmente, então liberamos overflow-x */
body.sidebar-collapsed .sidebar-scroll { overflow-x: visible; }
.sidebar-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.brand-block { display: flex; align-items: center; gap: 14px; margin-bottom: 18px; min-width: 0; }
.brand-copy { min-width: 0; overflow: hidden; transition: opacity .22s ease, transform .22s ease; }
.brand-mark-wrap { width: 56px; height: 56px; border-radius: 16px; background: rgba(255,255,255,.04); display: grid; place-items: center; border: 1px solid rgba(255,255,255,.08); overflow: hidden; flex: 0 0 auto; }
.brand-mark { width: 38px; max-width: 38px; height: auto; }
.brand-title { font-size: 28px; font-weight: 800; letter-spacing: .04em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.brand-subtitle { color: rgba(255,255,255,.62); font-size: 12px; text-transform: uppercase; letter-spacing: .12em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sidebar-toggle { width: 38px; height: 38px; border-radius: 11px; border: 1px solid rgba(255,255,255,.16); background: rgba(255,255,255,.04); color: rgba(255,255,255,.92); cursor: pointer; display: grid; place-items: center; transition: .22s ease; flex: 0 0 auto; }
.sidebar-toggle:hover { background: rgba(255,255,255,.12); border-color: rgba(255,255,255,.28); }
.sidebar-toggle-icon { font-size: 15px; transition: transform .24s ease; }
body.sidebar-collapsed .sidebar-toggle-icon { transform: rotate(180deg); }
.sidebar-nav { display: grid; gap: 6px; margin-top: 10px; min-width: 0; }
.nav-group { position: relative; min-width: 0; }
.nav-item { position: relative; display: grid; grid-template-columns: var(--nav-item-icon-col) minmax(0, 1fr) var(--nav-item-action-col); align-items: center; column-gap: var(--nav-item-col-gap); padding: var(--nav-item-pad-block) var(--nav-item-pad-inline); border-radius: 14px; color: rgba(255,255,255,.75); transition: .2s ease; min-height: 44px; width: 100%; }
.nav-item::before { content: ''; position: absolute; left: 0; top: 8px; bottom: 8px; width: 3px; border-radius: 999px; background: transparent; transition: .2s ease; }
.nav-group-toggle { width: 100%; border: none; background: transparent; font: inherit; cursor: pointer; text-align: left; }
.nav-item:hover { background: rgba(255,255,255,.05); color: #fff; }
.nav-item.active { background: linear-gradient(90deg, rgba(17,173,180,.22), rgba(143,203,58,.08)); color: #fff; border: 1px solid rgba(17,173,180,.2); }
.nav-item.active::before, .nav-group.active-group > .nav-item::before { background: linear-gradient(180deg, #2ed6dc, #8fcb3a); box-shadow: 0 0 14px rgba(17,173,180,.45); }
.nav-icon { width: var(--nav-item-icon-col); height: var(--nav-item-icon-col); display: inline-flex; color: rgba(255,255,255,.95); }
.nav-icon svg { width: 100%; height: 100%; fill: currentColor; }
.nav-label { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nav-action-slot { width: var(--nav-item-action-col); display: inline-flex; align-items: center; justify-content: center; }
.nav-group-caret { font-size: 13px; opacity: .9; transition: transform .2s ease; }
.nav-group-toggle[aria-expanded="true"] .nav-group-caret { transform: rotate(0deg); }
.nav-group-toggle[aria-expanded="false"] .nav-group-caret { transform: rotate(-90deg); }
.nav-subitems { display: grid; gap: 4px; margin-top: 4px; padding-left: calc(var(--nav-item-pad-inline) + var(--nav-item-icon-col) + var(--nav-item-col-gap)); padding-right: var(--nav-item-pad-inline); max-height: 0; overflow: hidden; opacity: 0; transition: max-height .24s ease, opacity .2s ease; }
.nav-subitems.open { max-height: 600px; opacity: 1; }
.nav-subitem { display: block; padding: 10px 14px; border-radius: 12px; color: rgba(255,255,255,.66); font-size: 14px; transition: .2s ease; }
.nav-subitem:hover { background: rgba(255,255,255,.05); color: #fff; }
.nav-subitem.active { background: rgba(17,173,180,.18); border: 1px solid rgba(17,173,180,.22); color: #fff; }
.nav-subitem-heading { padding: 8px 14px 2px; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .06em; color: rgba(255,255,255,.35); }
.mbn-drawer-heading { padding: 10px 18px 2px; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .06em; color: rgba(0,0,0,.4); }
.nav-flyout { position: absolute; top: 0; left: calc(100% + 10px); width: 280px; padding: 12px; border-radius: 14px; background: #0f1c28; border: 1px solid rgba(255,255,255,.12); box-shadow: 0 20px 36px rgba(0,0,0,.28); opacity: 0; transform: translateX(-8px); pointer-events: none; transition: opacity .18s ease, transform .18s ease; z-index: 25; }
.nav-flyout-title { font-size: 12px; text-transform: uppercase; letter-spacing: .08em; color: rgba(255,255,255,.6); margin: 2px 8px 8px; }
.nav-flyout-items { display: grid; gap: 4px; }
.sidebar-footer { display: grid; gap: 10px; transition: opacity .2s ease; flex-shrink: 0; width: 100%; overflow: hidden; min-width: 0; }

/* ── Botão Portal Central ─────────────────────────────────────────────────── */
.portal-central-btn { display: flex; align-items: center; gap: 8px; padding: 9px 14px; border-radius: 12px; color: rgba(255,255,255,.6); font-size: 13px; font-weight: 500; text-decoration: none; border: 1px solid rgba(255,255,255,.1); background: rgba(255,255,255,.04); transition: .2s ease; }
.portal-central-btn:hover { background: rgba(255,255,255,.1); color: #fff; border-color: rgba(255,255,255,.22); }
body.sidebar-collapsed .portal-central-btn span, body.sidebar-collapsed .portal-central-btn { justify-content: center; }
body.sidebar-collapsed .portal-central-btn span:last-child { display: none; }

.status-card { background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.07); border-radius: 16px; padding: 14px; overflow: hidden; box-sizing: border-box; width: 100%; }
.status-card.compact { display: flex; align-items: center; gap: 8px; }
/* Info area da status-card vira <a> quando PORTAL_CENTRAL_URL setada — leva ao Portal Central. */
.status-card-link { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; overflow: hidden; text-decoration: none; color: inherit; transition: opacity .15s ease; }
.status-card-link:hover { opacity: 0.78; }
.status-label { font-size: 12px; color: rgba(255,255,255,.55); margin-bottom: 6px; text-transform: uppercase; letter-spacing: .08em; }
.status-value { font-size: 14px; font-weight: 600; }
.status-online { color: #88f0b7; }
.logout-link { color: #9fdcff; font-weight: 600; }
body.sidebar-collapsed .brand-copy,
body.sidebar-collapsed .sidebar-footer,
body.sidebar-collapsed .nav-group-caret,
body.sidebar-collapsed .nav-subitems { opacity: 0; pointer-events: none; max-height: 0; margin: 0; padding-top: 0; padding-bottom: 0; }
body.sidebar-collapsed .sidebar { padding-left: 12px; padding-right: 12px; }
body.sidebar-collapsed .sidebar-top { flex-direction: column; align-items: center; }
body.sidebar-collapsed .brand-block { justify-content: center; margin-bottom: 8px; }
body.sidebar-collapsed .brand-mark-wrap { width: 50px; height: 50px; border-radius: 14px; }
body.sidebar-collapsed .brand-mark { width: 34px; max-width: 34px; }
body.sidebar-collapsed .nav-item { grid-template-columns: var(--nav-item-icon-col-collapsed); justify-content: center; justify-items: center; column-gap: 0; padding-left: 8px; padding-right: 8px; width: 100%; min-height: 42px; border-radius: 12px; }
body.sidebar-collapsed .nav-item::before { left: 4px; top: 10px; bottom: 10px; }
body.sidebar-collapsed .nav-label,
body.sidebar-collapsed .nav-action-slot { display: none; }
body.sidebar-collapsed .nav-icon { width: var(--nav-item-icon-col-collapsed); height: var(--nav-item-icon-col-collapsed); margin: 0 auto; }
body.sidebar-collapsed .nav-group:hover > .nav-flyout,
body.sidebar-collapsed .nav-group.flyout-open > .nav-flyout,
body.sidebar-collapsed .nav-group:focus-within > .nav-flyout { opacity: 1; transform: translateX(0); pointer-events: auto; }
body.sidebar-collapsed .nav-item[data-tooltip]::after,
body.sidebar-collapsed .nav-item[data-tooltip]::before { opacity: 0; pointer-events: none; transition: opacity .16s ease; }
body.sidebar-collapsed .nav-item[data-tooltip]::after { content: attr(data-tooltip); position: absolute; left: calc(100% + 12px); top: 50%; transform: translateY(-50%); background: rgba(7,16,24,.96); color: #fff; border: 1px solid rgba(255,255,255,.16); border-radius: 10px; font-size: 12px; padding: 6px 10px; white-space: nowrap; z-index: 30; }
body.sidebar-collapsed .nav-item[data-tooltip]::before { content: ''; position: absolute; left: calc(100% + 7px); top: 50%; transform: translateY(-50%) rotate(45deg); width: 9px; height: 9px; background: rgba(7,16,24,.96); border-left: 1px solid rgba(255,255,255,.16); border-top: 1px solid rgba(255,255,255,.16); z-index: 29; }
body.sidebar-collapsed .nav-item[data-tooltip]:hover::after,
body.sidebar-collapsed .nav-item[data-tooltip]:hover::before { opacity: 1; }
.main-area { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.topbar { min-height: var(--topbar-height); padding: 26px 30px 18px; display: flex; justify-content: space-between; gap: 18px; align-items: flex-start; }
.breadcrumb { font-size: 12px; color: #6b7a8a; text-transform: uppercase; letter-spacing: .1em; margin-bottom: 8px; }
.page-title { margin: 0; font-size: 31px; font-weight: 800; color: #0d1c27; }
.page-subtitle { color: #66778a; margin-top: 6px; }
/* Páginas com hero/card próprio: topbar mostra só o breadcrumb, sem duplicar título */
.topbar-head.is-compact .breadcrumb { margin-bottom: 0; }
.topbar-actions { display: flex; align-items: center; gap: 12px; }

/* ── Botão "▶ Tutorial" (ajuda contextual por aba) ───────────────────────── */
.topbar-head { flex: 1; display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.topbar-head-text { min-width: 0; }
.tutorial-btn { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 8px; height: 40px;
  padding: 0 16px; border: none; border-radius: 12px; cursor: pointer; font-weight: 700; font-size: .9rem;
  color: #fff; background: var(--brand-grad); background-size: 220% 100%; animation: brandFlow 7s ease-in-out infinite;
  box-shadow: 0 8px 22px rgba(17,173,180,.22); transition: .2s ease; }
.tutorial-btn:hover { transform: translateY(-1px); filter: brightness(1.06); }
.tutorial-btn svg { flex: 0 0 auto; }
/* variante só-ícone (barra mobile) */
.tutorial-btn--icon { width: 38px; height: 38px; padding: 0; border-radius: 11px; justify-content: center; }
@media (prefers-reduced-motion: reduce) { .tutorial-btn { animation: none; } }

/* ── Modal do tutorial ───────────────────────────────────────────────────── */
.tutorial-modal-box { width: min(880px, 100%); background: #fff; border-radius: 16px; padding: 16px 20px 24px; }
.tutorial-bar { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.tutorial-controls { display: flex; gap: 4px; flex: 0 0 auto; }
.tut-ctl { width: 30px; height: 30px; border: none; border-radius: 8px; background: #eef2f5; color: #33485a;
  font-size: 1rem; line-height: 1; cursor: pointer; display: grid; place-items: center; transition: .15s ease; }
.tut-ctl:hover { background: #dde6ec; }
.tut-ctl-close:hover { background: var(--danger, #cf222e); color: #fff; }
.tutorial-modal-head { margin: 0 2px 16px; }
.tutorial-eyebrow { font-size: .72rem; font-weight: 800; letter-spacing: .16em; text-transform: uppercase; }
.tutorial-modal-head h3 { margin: 0; font-size: 1.3rem; font-weight: 800; color: #0d1c27; }
.tutorial-desc { margin: 8px 0 0; color: #5a6b7b; font-size: .92rem; line-height: 1.45; }
.tutorial-player { position: relative; width: 100%; aspect-ratio: 16 / 9; border-radius: 14px; overflow: hidden;
  background: #0e1822; box-shadow: 0 12px 32px rgba(7,16,24,.28); }
.tutorial-player iframe, .tutorial-poster { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; object-fit: cover; }
.tutorial-play { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 84px; height: 84px; border-radius: 50%; border: none; cursor: pointer; color: #0e1822;
  background: var(--brand-grad); display: grid; place-items: center; padding-left: 6px;
  box-shadow: 0 14px 36px rgba(17,173,180,.45); transition: .2s ease; }
.tutorial-play:hover { transform: translate(-50%, -50%) scale(1.06); }

/* Janela flutuante: backdrop vira click-through; a caixa ancora num canto,
   é arrastável pela barra e redimensionável. Pra "fazer enquanto assiste". */
.tutorial-modal.is-float { background: transparent !important; pointer-events: none; }
.tutorial-modal.is-float .tutorial-modal-box { pointer-events: auto; position: fixed; right: 18px; bottom: 18px;
  width: 420px; max-width: 92vw; min-height: 0; max-height: none; height: auto; margin: 0; padding: 8px 12px 12px;
  border-radius: 16px; resize: horizontal; overflow: hidden; box-shadow: 0 22px 55px rgba(7,16,24,.5); }
.tutorial-modal.is-float .tutorial-bar { cursor: move; margin-bottom: 6px; touch-action: none; }
.tutorial-modal.is-float .tutorial-modal-head { margin: 0 2px 8px; }
.tutorial-modal.is-float .tutorial-modal-head h3 { font-size: 1rem; }
.tutorial-modal.is-float .tutorial-desc { display: none; }
.tutorial-modal.is-float .tutorial-play { width: 56px; height: 56px; }
.tutorial-modal-box.is-dragging { user-select: none; }
/* Minimizado: só a barra (esconde título + player). */
.tutorial-modal.is-min .tutorial-modal-head, .tutorial-modal.is-min .tutorial-player { display: none; }
.tutorial-modal.is-min .tutorial-modal-box { width: 260px; resize: none; padding-bottom: 8px; }

@media (max-width: 680px) {
  .tutorial-modal-box { padding: 12px 14px 20px; }
  .tutorial-play { width: 64px; height: 64px; }
  /* Controles maiores p/ toque. */
  .tut-ctl { width: 36px; height: 36px; font-size: 1.05rem; }
  /* Flutuante no mobile: card colado embaixo, largura quase cheia, sem resize
     (handle de redimensionar é ruim no toque). Arrasto só reposiciona. */
  .tutorial-modal.is-float .tutorial-modal-box { right: 3vw; left: auto; bottom: 12px;
    width: 94vw; max-width: 94vw; resize: none; }
  .tutorial-modal.is-float .tutorial-play { width: 60px; height: 60px; }
  /* Minimizado no mobile: vira uma barrinha compacta no canto (não 94vw). */
  .tutorial-modal.is-min .tutorial-modal-box { width: auto; min-width: 0; max-width: 72vw; }
  .tutorial-modal.is-min .tutorial-bar { margin-bottom: 0; }
}
.search-box input { width: 300px; background: rgba(255,255,255,.92); }
.user-pill { height: 44px; min-width: 86px; padding: 0 16px; display: grid; place-items: center; border-radius: 12px; background: #fff; border: 1px solid var(--line); color: #273746; font-weight: 700; }

/* Card de usuário compacto no topbar — visível só em mobile (sidebar é hidden lá).
   Espelha as informações que o sidebar-footer mostra no desktop (full_name, company, Sair). */
.topbar-user-mobile { display: none; }
@media (max-width: 768px) {
    .topbar-user-mobile {
        display: flex;
        align-items: center;
        gap: 10px;
        margin-top: 12px;
        padding: 10px 14px;
        background: rgba(255,255,255,.85);
        border: 1px solid var(--line);
        border-radius: 12px;
    }
    /* Info area vira <a> quando PORTAL_CENTRAL_URL setada — clica e vai pro Portal Central */
    .topbar-user-mobile-link {
        display: flex;
        align-items: center;
        gap: 10px;
        flex: 1;
        min-width: 0;
        text-decoration: none;
        color: inherit;
        transition: opacity .15s ease;
    }
    .topbar-user-mobile-link:hover { opacity: 0.78; }
    .topbar-user-mobile-dot {
        width: 8px; height: 8px; border-radius: 50%;
        background: #16a34a;
        flex-shrink: 0;
    }
    .topbar-user-mobile-text {
        flex: 1;
        min-width: 0;
        line-height: 1.2;
    }
    .topbar-user-mobile-name {
        font-size: 0.88rem;
        font-weight: 700;
        color: #0d1c27;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .topbar-user-mobile-company {
        font-size: 0.72rem;
        color: #6b7a8a;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        margin-top: 2px;
    }
    .topbar-user-mobile-logout {
        flex-shrink: 0;
        font-size: 0.82rem;
        font-weight: 600;
        color: #dc2626;
        text-decoration: none;
        padding: 6px 10px;
        border-radius: 8px;
        border: 1px solid rgba(220,38,38,.2);
    }
    .topbar-user-mobile-logout:hover { background: rgba(220,38,38,.06); }
}
.content-area { padding: 0 30px 30px; min-width: 0; }
/* Modo modal (chromeless): sem sidebar/topbar, conteúdo ocupa tudo dentro do iframe */
.app-shell.is-modal { display: block; min-height: 0; }
.content-area--modal { padding: 18px; }
/* Página carregada dentro de iframe (modal do Quadro): esconde o shell mesmo
   após redirects que perdem o ?modal=1. */
html.embedded .sidebar, html.embedded .topbar, html.embedded .brand-splash { display: none !important; }
html.embedded .app-shell { display: block !important; min-height: 0; }
html.embedded .content-area { padding: 16px !important; }
html.embedded .back-to-board { display: none !important; }  /* o ✕ do modal fecha */

/* ── Modal do Quadro de Compras (iframe overlay) ───────────────────────────── */
.compras-modal { position: fixed; inset: 0; z-index: 1200; display: none; }
.compras-modal.open { display: block; }
.compras-modal__backdrop { position: absolute; inset: 0; background: rgba(10,16,20,.55); }
.compras-modal__panel {
  position: absolute; inset: 24px; margin: auto; max-width: 1100px; background: #fff;
  border-radius: 16px; overflow: hidden; box-shadow: 0 24px 70px rgba(0,0,0,.35);
  display: flex; flex-direction: column;
}
.compras-modal__close {
  position: absolute; top: 12px; right: 14px; z-index: 2; width: 36px; height: 36px;
  border-radius: 50%; border: 1px solid #e2e8f0; background: #fff; font-size: 1.1rem;
  cursor: pointer; line-height: 1; box-shadow: 0 2px 8px rgba(0,0,0,.12);
}
.compras-modal__frame { flex: 1; width: 100%; border: 0; background: #f7f9fb; }
@media (max-width: 760px) { .compras-modal__panel { inset: 0; border-radius: 0; max-width: none; } }

/* ── Filtro de status por coluna do Quadro ─────────────────────────────────── */
.kanban-col__filterwrap { position: relative; display: inline-flex; }
.kanban-col__filter {
  border: 1px solid transparent; background: none; cursor: pointer; font-size: .8rem;
  color: #94a3b8; padding: 2px 5px; border-radius: 6px; line-height: 1;
}
.kanban-col__filter:hover { background: rgba(148,163,184,.15); color: #475569; }
.kanban-col__filter.is-active { color: #0f7a82; background: #e6f7f8; border-color: #b7e6e8; }
.kanban-col__filter-menu {
  position: absolute; top: calc(100% + 4px); right: 0; z-index: 30; min-width: 180px;
  background: #fff; border: 1px solid var(--line, #e2e8f0); border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0,0,0,.14); padding: 5px; max-height: 320px; overflow: auto;
}
.kanban-col__filter-opt {
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  padding: 7px 10px; border: 0; background: none; border-radius: 7px; cursor: pointer;
  font-size: .84rem; color: #334155;
}
.kanban-col__filter-opt:hover { background: #f1f5f9; }
.kanban-col__filter-opt.active { background: #e6f7f8; color: #0f7a82; font-weight: 700; }
.kanban-col__filter-opt .dot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; }
.card, .hero-card { background: rgba(255,255,255,.9); border: 1px solid rgba(221,228,238,.95); border-radius: var(--radius); box-shadow: var(--shadow); }
.card { padding: 22px; }
.hero-card { padding: 28px; display: flex; align-items: center; justify-content: space-between; gap: 20px; background: linear-gradient(135deg, #0b1520 0%, #101f2c 55%, #0b1b21 100%); color: #fff; border-color: rgba(17,173,180,.14); }
.hero-card h2 { margin: 0 0 8px; font-size: 28px; }
.hero-card p { margin: 0; color: rgba(255,255,255,.72); max-width: 760px; }
/* Botão(ões) do hero nunca encolhem abaixo do próprio texto — senão o label
   vaza pra fora do botão (problema crônico em vários heros). */
.hero-card .btn { flex: 0 0 auto; white-space: nowrap; }
/* ── CONTADORES DO HERO ─────────────────────────────────────────────────────
   ⚠️ Nasceram inline na lista de Orçamentos: um `display:flex;gap:16px` com
   CINCO contadores e nada que quebrasse. São ~404px de conteúdo numa tela de
   390 — e como `.transport-hero` tem `overflow:hidden`, eles não vazavam a
   página: SUMIAM pela borda. *"Textos e botões saindo das bordas"* (Marcos,
   chamado #30, 14/09/2026).
   Contador no hero é coisa de várias telas, então é componente: quebra
   sozinho, encolhe sem empurrar o hero, e no celular divide a linha. */
.hero-acoes { display: flex; flex-direction: column; align-items: flex-end;
  gap: 10px; min-width: 0; max-width: 100%; }
.hero-nums { display: flex; flex-wrap: wrap; gap: 10px 18px;
  justify-content: flex-end; min-width: 0; }
.hero-num { text-align: center; min-width: 0; }
.hero-num b { display: block; font-size: 18px; font-weight: 800; line-height: 1.15; }
.hero-num span { display: block; font-size: 10px; color: rgba(255,255,255,.62);
  text-transform: uppercase; letter-spacing: .06em; }
@media (max-width: 680px) {
  .hero-acoes { width: 100%; align-items: stretch; }
  .hero-nums { justify-content: space-between; gap: 8px 10px; }
}
.transport-hero, .settings-hero { position: relative; overflow: hidden; }
.transport-hero::after, .settings-hero::after { content: ''; position: absolute; inset: auto -120px -140px auto; width: 320px; height: 320px; background: radial-gradient(circle, rgba(17,173,180,.22), transparent 60%); pointer-events: none; }
.grid { display: grid; gap: 18px; }
.grid-kpis { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.kpi-card { position: relative; overflow: hidden; }
.kpi-card::before { content: ''; position: absolute; inset: 0 auto auto 0; height: 3px; width: 100%; background: linear-gradient(90deg, var(--primary), var(--accent)); opacity: .85; }
.kpi-title { color: #627385; font-size: 13px; text-transform: uppercase; letter-spacing: .08em; margin-bottom: 12px; }
.kpi-value { font-size: 31px; font-weight: 800; color: #0d1c27; }
.kpi-delta { margin-top: 8px; color: #18a163; font-weight: 600; font-size: 14px; }
.two-col { display: grid; gap: 18px; grid-template-columns: 1.25fr .95fr; margin-top: 18px; }
.three-col { display: grid; gap: 18px; grid-template-columns: 1fr 1fr .9fr; }
.wide-split { grid-template-columns: 1.1fr .9fr; }
.tight-right { grid-template-columns: 1.2fr .95fr; }
.stack, .module-stack { display: grid; gap: 18px; min-width: 0; }
/* Grid items default to min-content sizing, então quando uma <article class="card">
   tem conteúdo intrínsecamente largo (ex: tabela "Relatório de vendas do dia" no PDV),
   o track da grid infla até o min-content do filho — o que faz o .stack inteiro crescer
   além do flex:1 do pai (.sales-layout > .stack), empurrando .summary-panel pra fora
   do viewport. min-width:0 nos filhos quebra esse comportamento. */
.stack > *, .module-stack > * { min-width: 0; }
.section-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 14px; margin-bottom: 18px; }
.section-head h3 { margin: 0; font-size: 22px; }
.section-head p { margin: 6px 0 0; color: #6a7a8d; }
.section-head.split { align-items: center; }
.quick-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.quick-action { min-height: 108px; border-radius: 16px; background: linear-gradient(180deg, #f8fbff 0%, #eef4fa 100%); border: 1px solid #dfe8f1; display: flex; align-items: end; padding: 18px; font-weight: 700; color: #173144; transition: transform .2s ease, box-shadow .2s ease; }
.quick-action:hover { transform: translateY(-2px); box-shadow: 0 16px 32px rgba(13, 28, 39, .08); }
.alert-list { display: grid; gap: 12px; }
.alert-row { padding: 14px 16px; border-radius: 14px; display: flex; justify-content: space-between; align-items: center; font-weight: 600; }
.alert-row.warning { background: #fff7e9; color: #915f0b; }
.alert-row.danger { background: #ffedf0; color: #b12f48; }
.alert-row.info { background: #edf8fb; color: #0d7180; }
.alert-row.success { background: #ecfbf3; color: #0b8653; }
.timeline { display: grid; gap: 16px; }
.timeline-item { display: grid; grid-template-columns: 18px 1fr; gap: 14px; align-items: start; }
.timeline-dot { width: 10px; height: 10px; border-radius: 999px; background: linear-gradient(180deg, var(--primary), var(--accent)); margin-top: 8px; box-shadow: 0 0 16px rgba(17,173,180,.4); }
.timeline-title { font-weight: 700; color: #11212e; }
.timeline-time { color: #708091; margin-top: 4px; }
.fake-chart { min-height: 290px; display: grid; align-content: end; gap: 20px; }
.chart-line { height: 140px; border-radius: 18px; background: linear-gradient(180deg, rgba(143,203,58,.18), rgba(17,173,180,.08)); position: relative; overflow: hidden; }
.chart-line::after { content: ''; position: absolute; inset: 24px 20px auto 20px; height: 80px; border-radius: 100px; border: 2px solid rgba(17,173,180,.65); border-color: rgba(17,173,180,.65) transparent transparent transparent; transform: skewX(-16deg); }
.chart-bars { display: grid; grid-template-columns: repeat(6, 1fr); gap: 14px; align-items: end; }
.chart-bars span { background: linear-gradient(180deg, rgba(143,203,58,.72), rgba(17,173,180,.72)); border-radius: 12px 12px 4px 4px; height: 52px; }
.chart-bars span:nth-child(2) { height: 86px; }
.chart-bars span:nth-child(3) { height: 68px; }
.chart-bars span:nth-child(4) { height: 115px; }
.chart-bars span:nth-child(5) { height: 78px; }
.chart-bars span:nth-child(6) { height: 124px; }
.module-grid { display: grid; gap: 18px; }
.module-grid > * { min-width: 0; }
.sales-layout, .consolidation-layout { grid-template-columns: 1.55fr .78fr; }
.sales-layout { display: flex; align-items: flex-start; gap: 18px; }
.sales-layout > .stack { flex: 1; min-width: 0; }
.sales-layout > .summary-panel { width: 320px; flex-shrink: 0; position: sticky; top: 18px; }
.consolidation-layout { display: grid; }
.summary-panel { align-self: start; }
.sticky-panel { position: sticky; top: 18px; }
.summary-list { display: grid; gap: 12px; }
.summary-list > div { display: flex; justify-content: space-between; gap: 14px; color: #617285; }
.summary-list strong { color: #0e1f2c; }
.summary-total { margin-top: 6px; padding-top: 14px; border-top: 1px solid var(--line); font-size: 18px; }
/* Linhas de soma do resumo: o sinal e a cor dizem o que ENTRA e o que SAI do
   total — sem isso a coluna vira uma pilha de números iguais. */
.summary-list > div.sum-add strong { color: #15803d; }
.summary-list > div.sum-sub strong { color: #b91c1c; }
.summary-list > div.sum-info { color: #8090a2; }
.summary-list > div.sum-info strong { color: #61748a; font-weight: 600; }
.summary-list .sum-sign { display: inline-flex; align-items: center; justify-content: center;
    width: 15px; height: 15px; margin-right: 6px; border-radius: 5px;
    font-size: 11px; font-weight: 800; line-height: 1; vertical-align: 1px; }
.summary-list > div.sum-add .sum-sign { background: rgba(21, 128, 61, .12); color: #15803d; }
.summary-list > div.sum-sub .sum-sign { background: rgba(185, 28, 28, .1); color: #b91c1c; }
/* Subtotal do bloco (Total calculado): fecha a conta de cima */
.summary-list > div.sum-result { margin-top: 2px; padding-top: 10px; border-top: 1px dashed var(--line); }
.summary-list > div.sum-result strong { color: #0e1f2c; font-weight: 800; }
.form-grid { display: grid; gap: 16px; }
.form-grid.one { grid-template-columns: 1fr; }
.form-grid.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.form-grid.three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.form-grid.four { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.form-grid.five { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.form-grid .full { grid-column: 1 / -1; }
.transport-sections-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.customer-search { position: relative; }
.customer-search-input { background: #fff; border: 1px solid var(--line); transition: border-color .18s ease, box-shadow .18s ease; }
/* ⚠️⚠️ **A RESERVA DA DIREITA É DO COMPONENTE, E PRECISA GANHAR DA TELA.**
   Ela morava em `.customer-search-input` (0,1,0) e qualquer tela que estilizasse
   os próprios campos com `.algo input` (0,1,1) a apagava — o `padding`
   shorthand zera os quatro lados de uma vez. Foi o que a conciliação fez com
   `.fila-resp input { padding: 8px 10px }`: o placeholder "Buscar por código ou
   nome…" passava POR BAIXO da lupa, e o campo parecia fora do padrão da casa
   (chamado #23, 14/09/2026 — *"a lupa está em cima de um texto pronto"*).
   Com o pai no seletor são duas classes (0,2,0), que nenhuma regra de tela com
   uma classe e um tipo alcança.
   ⚠️ E a reserva é MEDIDA, não chutada: quem diz quantos botões existem é o
   próprio widget (`--cs-botoes`, posto pelo `autocomplete.js` depois de montá-
   los). 94px fixos sobravam no campo que só tem lupa e faltavam no que ganhou
   o quarto botão — e sobra, num campo estreito, é placeholder cortado à toa. */
.customer-search .customer-search-input {
    padding-right: calc(16px + var(--cs-botoes, 3) * 26px);
}
.customer-search-input:focus { border-color: rgba(143,203,58,.52); box-shadow: 0 0 0 3px rgba(143,203,58,.14); outline: none; }
.customer-search-lupa { position: absolute; right: 10px; top: 50%; transform: translateY(-50%); border: none; background: none; color: #7990a6; font-size: 17px; cursor: pointer; padding: 4px 5px; line-height: 1; border-radius: 6px; transition: color .15s; }
.customer-search-lupa:hover { color: #3b7ec4; }
.customer-search-clear { position: absolute; right: 36px; top: 50%; transform: translateY(-50%); border: none; background: none; color: #aab8c6; font-size: 15px; cursor: pointer; padding: 4px 5px; line-height: 1; border-radius: 6px; transition: color .15s; display: none; }
.customer-search-clear:hover { color: #ef4444; }
.customer-search.has-value .customer-search-clear { display: block; }
/* Botão refresh (↺) — discreto, sempre visível exceto quando travado */
/* "Trazer do catálogo" — o slot seguinte ao ↻ na barra do campo. Só aparece
   onde faz sentido (hoje, o item do Almoxarifado): é opt-in por markup.
   ⚠️ O input precisa RECUAR junto: com quatro botões, o `padding-right: 94px`
   do padrão deixa o placeholder passando POR BAIXO do ícone novo (visto no
   navegador antes de subir). Quem tem o botão declara `data-tem-adotar`. */
/* ⚠️ O quarto botão não precisa mais de regra própria: `--cs-botoes` o conta.
   A largura de antes (120px) é exatamente `16 + 4*26`, e é assim que se confere
   que a conta acima está certa. */
.customer-search-adotar { position: absolute; right: 88px; top: 50%; transform: translateY(-50%); border: none; background: none; color: #aab8c6; font-size: 13px; cursor: pointer; padding: 4px 5px; line-height: 1; border-radius: 6px; transition: color .15s; display: flex; align-items: center; justify-content: center; }
.customer-search-adotar:hover { color: #11adb4; background: #eef6fb; }
.customer-search-adotar svg { width: 15px; height: 15px; }
.customer-search-refresh { position: absolute; right: 62px; top: 50%; transform: translateY(-50%); border: none; background: none; color: #aab8c6; font-size: 13px; cursor: pointer; padding: 4px 5px; line-height: 1; border-radius: 6px; transition: color .15s; display: flex; align-items: center; justify-content: center; }
.customer-search-refresh:hover { color: #22c08b; }
.customer-search-refresh svg { width: 13px; height: 13px; }
@keyframes cs-spin { to { transform: rotate(360deg); } }
.customer-search-refresh.spinning svg { animation: cs-spin .7s linear infinite; }
/* Campo travado: ocultar todos os botões de ação */
.customer-search.is-locked .customer-search-lupa,
.customer-search.is-locked .customer-search-clear,
.customer-search.is-locked .customer-search-refresh { display: none !important; }
/* position: fixed + z-index altíssimo + posicionamento via JS — escapa de
   QUALQUER overflow:hidden e stacking context de ancestral. Vale pra todos
   os dropdowns do widget (cliente, produto, conta corrente, motorista, etc). */
/* z-index 10050: o dropdown é portado pro <body> (autocomplete.js), então
   compete com os overlays de modal no mesmo nível. Precisa vencer a faixa de
   modais do app (topo em 10010 = .fem-modal) mas ficar ABAIXO da faixa
   "sempre no topo" (toast/vAlert/loader/splash = 99999+). Sem isso, o dropdown
   abre ATRÁS de modais como "Trocar cliente" (z-index 10001). */
.customer-search-dropdown { position: fixed; top: 0; left: 0; width: auto; border-radius: 14px; border: 1px solid #dce6f2; background: rgba(255,255,255,.98); box-shadow: 0 18px 34px rgba(11, 28, 43, .16); padding: 8px; z-index: 10050; display: none; }
.customer-search.open .customer-search-dropdown { display: block; }
.customer-search-status { padding: 10px 12px; font-size: 13px; color: #6a7f93; }
.customer-search-results { display: grid; gap: 6px; max-height: 320px; overflow: auto; padding: 2px; }
.customer-search-item { border: 1px solid transparent; border-radius: 12px; background: #fff; padding: 10px 11px; text-align: left; cursor: pointer; display: grid; gap: 4px; transition: border-color .15s ease, background .15s ease; }
.customer-search-item:hover,
.customer-search-item.active { border-color: #cde3f9; background: linear-gradient(90deg, rgba(17,173,180,.1), rgba(143,203,58,.07)); }
.customer-search-item strong { font-size: 14px; color: #102434; }
.customer-search-meta { display: flex; gap: 10px; flex-wrap: wrap; font-size: 12px; color: #678095; }
/* Linha resultado + lápis de edição do cadastro (window.Vectra.lapisCadastro).
   O botão fica FORA do resultado: botão dentro de botão não é HTML válido, e o
   dedo que ia editar acabaria selecionando. Alvo de 40px — é dedo, não mouse. */
/* ── STEPPER −/+ (o contador de dedo) ──────────────────────────────────────
   Nasceu na contagem de dinheiro do Fechamento de Caixa (17/07/2026) e virou
   componente em 06/09/2026, quando o Marcos apontou o seletor de quantidade do
   Almoxarifado subindo de CENTÉSIMO em centésimo: *"esse seletor de quantidade
   aumentando decimais não é nada útil. se for ter um, deve ser no estilo do
   contador de dinheiro da caixinha, com botões grandes e aumento em unidade"*.

   O spinner nativo do `input[type=number]` é do MOUSE: 12px de alvo e passo
   igual ao `step`, que num campo decimal quer dizer 0,01. Aqui o alvo é de
   dedo (40px) e o passo é 1.

   ⚠️ Comportamento genérico (+1/−1 em inteiro) mora no app.js e liga por
   `data-vstep` no wrapper. A contagem de dinheiro mantém o handler PRÓPRIO
   dela (cédula × moeda têm passos diferentes e recalculam o total) — por isso
   ela usa as classes SEM o `data-vstep`. */
.vstep { display: flex; align-items: stretch; }
.vstep input { flex: 1; min-width: 0; border-radius: 0 !important; text-align: center;
  border-left: none; border-right: none; }
.vstep-btn { flex: 0 0 auto; width: 40px; min-height: 40px; border: 1px solid #cbd5e1;
  background: #f1f5f9; color: #334155; font-size: 22px; font-weight: 700; line-height: 1;
  cursor: pointer; user-select: none; touch-action: manipulation; }
.vstep-btn:first-child { border-radius: 9px 0 0 9px; }
.vstep-btn:last-child { border-radius: 0 9px 9px 0; }
.vstep-btn:active { background: #e2e8f0; }
/* O spinner nativo some: com os botões grandes ao lado, ele é um segundo
   controle pra mesma coisa — e é justamente o que subia de 0,01. */
.vstep input::-webkit-outer-spin-button,
.vstep input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.vstep input[type=number] { -moz-appearance: textfield; appearance: textfield; }

.customer-search-row { display: flex; align-items: stretch; gap: 2px; }
.customer-search-edit { flex: 0 0 auto; min-width: 40px; display: inline-flex; align-items: center;
  justify-content: center; border: 1px solid transparent; border-radius: 12px; background: none;
  cursor: pointer; color: #678095; padding: 0 10px; }
.customer-search-edit:hover { background: #f0f4f8; color: #102434; }
.customer-search-edit svg { width: 16px; height: 16px; }
.customer-search-meta span { white-space: nowrap; }
.customer-search-chip { display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 999px; font-size: 11px; background: #edf4fb; color: #3b5d7c; }
/* Mesma faixa do dropdown (10050): a busca expandida (lupa) também é portada
   pro <body> e pode ser aberta de dentro de um modal (ex.: "Trocar cliente"). */
.search-modal-overlay { display: none; position: fixed; inset: 0; background: rgba(6,18,32,.52); z-index: 10050; align-items: flex-start; justify-content: center; padding: 60px 16px 0; }
.search-modal-overlay.open { display: flex; }
.search-modal-box { background: #fff; border-radius: 18px; padding: 18px; width: min(640px, 100%); max-height: 80vh; display: flex; flex-direction: column; gap: 10px; box-shadow: 0 28px 56px rgba(0,0,0,.22); }
.search-modal-header { display: flex; align-items: center; gap: 10px; }
.search-modal-title { font-size: 13px; color: #678095; flex: 1; font-style: italic; }
.search-modal-close { border: none; background: none; font-size: 22px; cursor: pointer; color: #7990a6; padding: 2px 8px; line-height: 1; border-radius: 8px; }
.search-modal-close:hover { background: #f0f4f8; color: #1e293b; }
.search-modal-results { display: grid; gap: 6px; max-height: 55vh; overflow: auto; padding: 2px; }
/* min-width: 0 é crítico em flex/grid layouts: sem isso, o table-wrap herda
   o min-content da tabela (que pode ser 560px+ via "table { min-width: 560px }"
   ou pelo conteúdo de colunas com white-space:nowrap), inflando o flex item
   pai e empurrando outros elementos pra fora do viewport (ex: .summary-panel
   do PDV ficando deslocado à direita). Com min-width:0 + overflow:auto, o
   wrap encolhe pra caber no espaço alocado e a tabela rola dentro dele. */
.table-wrap { overflow: auto; min-width: 0; border: 1px solid var(--line); border-radius: 16px; background: #fcfdff; }
table { width: 100%; border-collapse: collapse; min-width: 560px; }
th, td { padding: 14px 16px; text-align: left; border-bottom: 1px solid var(--line); }
th { background: #f7fafe; color: #687a8d; font-size: 13px; text-transform: uppercase; letter-spacing: .06em; }
tbody tr:hover { background: #f4faf8; }
/* min-height (não height fixo) + inline-flex: texto longo QUEBRA e o botão cresce,
   em vez de vazar. inline-flex também conserta <a class="btn"> (inline puro ignorava
   height). gap dá o respiro entre ícone .ic e o rótulo. */
.btn { min-height: 44px; border: none; border-radius: 12px; padding: 8px 18px; font-weight: 700; cursor: pointer; transition: .2s ease;
  display: inline-flex; align-items: center; justify-content: center; gap: .4em;
  max-width: 100%; min-width: 0; text-align: center; overflow-wrap: break-word; }
.btn:hover { transform: translateY(-1px); }
/* CTAs: gradiente verde→ciano FLUINDO (se move devagar; acelera no hover) */
.btn-primary, .btn-accent { background: var(--brand-grad); background-size: 220% 100%; animation: brandFlow 7s ease-in-out infinite; }
.btn-primary { color: #fff; box-shadow: 0 10px 28px rgba(17,173,180,.22); }
.btn-accent { color: #fff; }
.btn-primary:hover, .btn-accent:hover { filter: brightness(1.06); animation-duration: 3.2s; }
@keyframes brandFlow { 0%, 100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } }
@media (prefers-reduced-motion: reduce) { .btn-primary, .btn-accent { animation: none; } }
.btn-secondary { background: #fff; color: #1c3040; border: 1px solid var(--line); }
.btn-danger   { background: linear-gradient(90deg, #cf4250, var(--danger)); color: #fff; }
/* ⚠️ **`.btn-ok` ERA UMA CLASSE QUE NÃO EXISTIA** (achado em 01/09/2026). Ela
   estava em três botões — "Aprovar e executar", "Assinar e pagar" (a barra do
   lote) e "Decidir" (a linha da fila) — e nenhum tinha desenho nenhum: saíam
   cinza do navegador, com o texto azul de link. *"Botão de aprovar
   completamente apagado"* (Marcos), na tela em que ele é a ação principal e
   está ao lado de um "Recusar" vermelho e cheio — o botão perigoso parecia o
   único vivo. Verde de confirmação, não o gradiente da marca: aqui ele divide a
   linha com o Recusar, e os dois precisam se distinguir de relance. */
.btn-ok { background: linear-gradient(90deg, #128a53, #17a866); color: #fff;
  box-shadow: 0 10px 26px rgba(18,138,83,.24); }
.btn-ok:hover { filter: brightness(1.06); }
.btn-ok:disabled { background: #e6ebf0; color: #94a3b8; box-shadow: none; cursor: not-allowed; }
.btn-ok:disabled:hover { transform: none; filter: none; }
.btn-warning  { background: linear-gradient(90deg, #d97706, #f59e0b); color: #fff; box-shadow: 0 8px 20px rgba(217,119,6,.22); }
.signature-wrap { border: 1.5px solid var(--line); border-radius: var(--radius-sm); overflow: hidden; background: #fff; cursor: crosshair; touch-action: none; }
.signature-canvas { display: block; width: 100%; height: 160px; background: #fff; }
.btn-block { width: 100%; }
.btn-plus { margin-top: 12px; background: var(--brand-grad); color: #fff; border: none; box-shadow: 0 10px 22px rgba(17,173,180,.24); width: fit-content; }
.btn-plus:hover { filter: brightness(1.06); }
.small { min-height: 38px; padding: 4px 14px; }
.stack-actions { display: grid; gap: 12px; }
.credit-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.credit-row input { flex: 1 1 160px; max-width: 220px; }
.grow { flex: 1 1 300px; }
.helper { margin: 0; font-size: 13px; }
.muted { color: #6b7d91; }

.stock-tabs { display: inline-flex; gap: 8px; padding: 6px; border-radius: 12px; background: #f2f6fb; border: 1px solid #dce6f1; width: fit-content; }
.stock-tab { border: 0; background: transparent; color: #5f7388; font-weight: 700; border-radius: 10px; padding: 10px 14px; cursor: pointer; }
.stock-tab.is-active { background: #fff; color: #0f2434; box-shadow: 0 8px 16px rgba(13, 28, 39, .08); }

tr.is-selected { background: linear-gradient(90deg, rgba(17,173,180,.12), rgba(143,203,58,.08)); }
[data-stock-locations-body] tr,
[data-stock-products-body] tr { cursor: pointer; }
[data-stock-locations-body] tr:focus,
[data-stock-products-body] tr:focus { outline: 2px solid rgba(143,203,58,.35); outline-offset: -2px; }
.field-with-button { display: grid; align-content: end; }
.purchase-log { min-height: 180px; max-height: 320px; overflow: auto; padding: 12px; border: 1px solid var(--line); border-radius: 14px; background: #f9fbff; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; white-space: pre-wrap; line-height: 1.45; }
[data-purchase-pcs-body] tr,
[data-purchase-installments-body] tr { cursor: pointer; }
.purchase-module-shell { max-width: 1280px; margin: 0 auto; }
.purchase-module-shell .two-col.wide-split { grid-template-columns: 1fr; }

.form-inline { display: flex; gap: 10px; align-items: center; }
.form-inline input { max-width: 180px; }
.inline-actions { display: flex; flex-wrap: wrap; gap: 12px; }
.period-chips { display: flex; flex-wrap: wrap; gap: 10px; }
.period-chip { height: 38px; border: 1px solid var(--line); border-radius: 999px; background: #fff; color: #42566a; padding: 0 14px; font-weight: 700; cursor: pointer; }
.period-chip.active { background: linear-gradient(90deg, rgba(17,173,180,.14), rgba(143,203,58,.14)); border-color: rgba(17,173,180,.35); color: #0f5e41; }
.statement-meta { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.statement-meta > div { border: 1px solid var(--line); border-radius: 14px; background: #f9fcff; padding: 12px 14px; display: grid; gap: 6px; }
.statement-meta span { color: #6b7d91; font-size: 13px; text-transform: uppercase; letter-spacing: .05em; font-weight: 700; }
.statement-meta strong { color: #0f2536; }
.statement-kpis { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.kpi-mini { border-radius: 14px; border: 1px solid var(--line); background: #fff; padding: 14px; display: grid; gap: 8px; }
.kpi-mini span { color: #6a7b8d; text-transform: uppercase; font-size: 12px; letter-spacing: .06em; font-weight: 700; }
.kpi-mini strong { font-size: 26px; color: #0f2334; }
.kpi-mini.balance { background: linear-gradient(180deg, #effaf4 0%, #f8fffc 100%); border-color: #caefd8; }
.statement-tables { grid-template-columns: 1fr 1fr; margin-top: 0; }
.table-panel { display: grid; gap: 10px; }
.table-panel h4 { margin: 0; font-size: 16px; color: #193145; }
.mt16 { margin-top: 16px; }
/* Toast: fica fixo no topo-direito mesmo com scroll, não desaparece sozinho
   pra erros/warnings (o usuário precisa fechar pra confirmar que viu). */
.flash-stack {
    position: fixed;
    top: 16px;
    right: 16px;
    z-index: 9999;
    display: grid;
    gap: 10px;
    max-width: min(440px, calc(100vw - 32px));
    pointer-events: none;  /* eventos chegam aos filhos, não ao container */
}
.flash {
    pointer-events: auto;
    display: grid;
    grid-template-columns: 1fr auto auto;
    align-items: start;
    gap: 8px;
    padding: 12px 14px;
    border-radius: 12px;
    font-weight: 600;
    line-height: 1.35;
    box-shadow: 0 8px 24px rgba(0, 0, 0, .12), 0 2px 6px rgba(0, 0, 0, .06);
    border: 1px solid transparent;
    transition: opacity .3s ease, transform .3s ease;
    animation: flashSlideIn .25s ease-out;
}
@keyframes flashSlideIn {
    from { opacity: 0; transform: translateX(20px); }
    to   { opacity: 1; transform: translateX(0); }
}
.flash.hide { opacity: 0; transform: translateX(20px); }
.flash-msg { user-select: text; word-break: break-word; }
.flash-btn {
    pointer-events: auto;
    appearance: none;
    border: none;
    background: rgba(0, 0, 0, .06);
    color: inherit;
    font-size: 14px;
    font-weight: 700;
    cursor: pointer;
    padding: 2px 8px;
    border-radius: 8px;
    line-height: 1.2;
    flex-shrink: 0;
    transition: background .15s ease;
}
.flash-btn:hover { background: rgba(0, 0, 0, .12); }
.flash-close { font-size: 18px; padding: 0 8px; }
.flash-copy.copied { background: rgba(0, 128, 0, .15); }
/* ⚠️ O DEFAULT DO `.flash` É O DE ERRO, de propósito (01/09/2026). Antes ele era
   transparente com cor herdada: categoria sem regra (`'error'`, usada em 63
   lugares) saía com cara de parágrafo da página, e "nada foi salvo" ficava
   igual a "salvo". O `partials/flash.html` já normaliza a categoria; isto aqui
   é a segunda rede — aviso que ninguém estilizou tem que aparecer ALTO. */
.flash         { background: #ffedf0; color: #b12f48; border-color: #fbc8d0; }
.flash-error   { background: #ffedf0; color: #b12f48; border-color: #fbc8d0; }
.flash-success { background: #ecfbf3; color: #0f8b58; border-color: #bfeccc; }
.flash-danger  { background: #ffedf0; color: #b12f48; border-color: #fbc8d0; }
.flash-warning { background: #fff7e9; color: #915f0b; border-color: #fde2bf; }
.flash-info    { background: #edf8fb; color: #0d7180; border-color: #bfe1ea; }
@media (max-width: 600px) {
    .flash-stack { top: 8px; right: 8px; left: 8px; max-width: none; }
}
.sale-success-card { display: grid; grid-template-columns: auto 1fr; gap: 16px; padding: 18px 20px; border-radius: 16px; border: 1px solid #bfeccc; background: linear-gradient(95deg, #ecfbf3 0%, #f3fffb 65%, #eefdff 100%); box-shadow: 0 14px 32px rgba(16, 127, 79, .12); }
.sale-success-icon { width: 44px; height: 44px; border-radius: 999px; background: linear-gradient(180deg, #22c55e, #16a34a); color: #fff; display: grid; place-items: center; font-weight: 800; font-size: 20px; box-shadow: 0 8px 18px rgba(16, 127, 79, .26); }
.sale-success-content h3 { margin: 0 0 6px; color: #0f2a1f; font-size: 22px; }
.sale-success-content p { margin: 0; color: #2f5b47; }
.sale-success-content p + p { margin-top: 6px; }
.sale-success-kicker { margin: 0 0 4px; color: #127d4f; text-transform: uppercase; letter-spacing: .08em; font-weight: 700; font-size: 12px; }
.sale-success-actions { margin-top: 14px; display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.sale-success-actions .ssa-group { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.sale-success-actions .ssa-sep { flex: none; width: 1px; align-self: stretch; min-height: 22px; background: #bfe8cf; margin: 0 4px; }
.sale-success-actions .btn .ic { width: 15px; height: 15px; vertical-align: -.16em; }
@media (max-width: 680px) {
  .sale-success-actions .ssa-sep { display: none; }
  .sale-success-actions .ssa-group { width: 100%; }
  .sale-success-actions .ssa-group .btn { flex: 1 1 auto; justify-content: center; }
}
.login-shell { min-height: 100vh; display: grid; grid-template-columns: 1.15fr .85fr; background: radial-gradient(circle at 20% 10%, rgba(17,173,180,.12), transparent 30%), radial-gradient(circle at 100% 0%, rgba(143,203,58,.09), transparent 25%), linear-gradient(180deg, #071018 0%, #0b131c 100%); }
.login-panel { position: relative; padding: 48px; }
.visual-panel { color: #fff; display: grid; align-content: center; }
.glow { position: absolute; border-radius: 999px; filter: blur(70px); }
.glow-a { width: 220px; height: 220px; background: rgba(17,173,180,.18); top: 90px; left: 80px; }
.glow-b { width: 260px; height: 260px; background: rgba(143,203,58,.12); bottom: 90px; left: 180px; }
.login-logo { width: 136px; margin-bottom: 14px; }
.visual-panel h1 { margin: 0; font-size: 84px; letter-spacing: .06em; }
.tagline { margin: 10px 0 18px; font-size: 24px; letter-spacing: .22em; text-transform: uppercase; color: rgba(255,255,255,.72); }
.tagline span { color: #2ed6dc; }
.lead { max-width: 560px; color: rgba(255,255,255,.78); font-size: 18px; line-height: 1.7; }
.feature-list { display: grid; gap: 12px; padding: 0; margin: 26px 0 0; list-style: none; }
.feature-list li { padding-left: 18px; position: relative; color: rgba(255,255,255,.82); }
.feature-list li::before { content: ''; width: 8px; height: 8px; border-radius: 999px; background: linear-gradient(180deg, var(--primary), var(--accent)); position: absolute; left: 0; top: 9px; }
.form-panel { background: rgba(255,255,255,.96); margin: 24px; border-radius: 28px; box-shadow: 0 24px 70px rgba(0,0,0,.22); display: grid; align-content: center; }
.form-header h2 { margin: 0 0 8px; font-size: 34px; color: #0e1f2c; }
.form-header p { margin: 0 0 24px; color: #6b7b8d; }
.login-form { display: grid; gap: 16px; }
.check-row { display: flex; align-items: center; gap: 10px; }
.check-row input { width: 16px; height: 16px; }
.login-hint { margin-top: 20px; color: #5f7185; padding: 16px; border-radius: 14px; background: #f6f9fc; border: 1px solid var(--line); }
.sync-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 1440px) { .grid-kpis { grid-template-columns: repeat(3, minmax(0, 1fr)); } .sync-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 1200px) { .app-shell { grid-template-columns: var(--sidebar-current-width) minmax(0, 1fr); } .sidebar { position: sticky; z-index: 20; } .consolidation-layout, .consolidation-config-grid, .three-col, .two-col { grid-template-columns: 1fr; } .quick-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .form-grid.five, .form-grid.four, .form-grid.three { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 900px) { .sales-layout { flex-direction: column; } .sales-layout > .summary-panel { width: 100%; position: static; } }
/* Utilitário: some no mobile (espaçadores de grid que só fazem sentido no desktop) */
@media (max-width: 900px) { .hide-mobile { display: none !important; } }
/* ≤900px o .form-grid vira 1 coluna — mas os campos com `grid-column:1/3` inline
   (Motorista no Relatório por Motorista, Fornecedor no recebimento manual, etc.)
   continuavam pedindo DUAS colunas, e o grid criava uma coluna implícita: o campo
   ficava ~2× mais largo que a tela e empurrava scroll lateral. Com 1 coluna, todo
   filho deve ocupar a linha inteira — daí o span forçado. */
@media (max-width: 900px) {
  .form-grid.two > *, .form-grid.three > *,
  .form-grid.four > *, .form-grid.five > * { grid-column: 1 / -1; }
}
@media (max-width: 900px) { .login-shell { grid-template-columns: 1fr; } .visual-panel { padding-bottom: 20px; } .visual-panel h1 { font-size: 58px; } .app-shell, body.sidebar-collapsed .app-shell { grid-template-columns: 1fr; } .sidebar, body.sidebar-collapsed .sidebar { position: relative; width: 100%; height: auto; min-height: auto; padding: 18px; } body.sidebar-collapsed .brand-copy, body.sidebar-collapsed .sidebar-footer { opacity: 1; pointer-events: auto; } body.sidebar-collapsed .nav-label, body.sidebar-collapsed .nav-group-caret { display: inline; opacity: 1; } body.sidebar-collapsed .nav-item { grid-template-columns: var(--nav-item-icon-col) minmax(0, 1fr) var(--nav-item-action-col); justify-content: initial; column-gap: var(--nav-item-col-gap); } body.sidebar-collapsed .nav-action-slot { display: inline-flex; } .nav-flyout { display: none; } .topbar { flex-direction: column; } .search-box input { width: 100%; } .grid-kpis, .sync-grid, .quick-grid, .form-grid.two, .form-grid.three, .form-grid.four, .form-grid.five { grid-template-columns: 1fr; } .content-area, .topbar { padding-left: 18px; padding-right: 18px; } .form-panel { margin: 0; border-radius: 0; } }

@media (max-width: 900px) {
  .sale-success-card { grid-template-columns: 1fr; }
  .card { min-width: 0; max-width: 100%; box-sizing: border-box; }
  .module-stack { min-width: 0; }
  .section-head.split { flex-wrap: wrap; gap: 10px; }
  .section-head.split .inline-actions { flex-wrap: wrap; }
  .consolidation-config-grid { grid-template-columns: 1fr; }
  .summary-panel { width: 100%; }
  .stock-tabs { display: flex; flex-wrap: wrap; width: 100%; box-sizing: border-box; }
  .stock-tab { flex: 1 1 auto; text-align: center; }
}


textarea { width: 100%; border-radius: 12px; border: 1px solid var(--line); background: #fff; padding: 10px 14px; color: var(--text); resize: vertical; min-height: 94px; }
.consolidation-config-grid { grid-template-columns: 1.35fr .8fr; align-items: start; }
.consolidation-table-wrap { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.consolidation-table { min-width: 900px; width: 100%; }
.consolidation-table tbody tr { cursor: pointer; transition: background .15s ease; }
.consolidation-table tbody tr:hover { background: #f0faf5; }
.consolidation-table tbody tr.row-selected { background: #d4f5e3; }
.consolidation-table tbody tr.row-selected td { color: #1a5c38; font-weight: 500; }
.consolidation-table .row-checkbox-cell { display: none; }
.credit-balance { margin: 14px 0 0; color: #2f7a4f; font-weight: 600; background: #eefaf3; border: 1px solid #caeeda; border-radius: 12px; padding: 10px 12px; }
.consol-history-table code { font-size: 12px; background: #f0f4fa; padding: 2px 6px; border-radius: 6px; color: #2b4a72; }

.freight-receivable-layout { display: grid; gap: 18px; }
.freight-tabs { display: inline-flex; gap: 8px; padding: 6px; border-radius: 12px; background: #f2f6fb; border: 1px solid #dce6f1; width: fit-content; }
.freight-tab { border: 0; background: transparent; color: #5f7388; font-weight: 700; border-radius: 10px; padding: 10px 14px; cursor: pointer; }
.freight-tab.is-active { background: #fff; color: #0f2434; box-shadow: 0 8px 16px rgba(13, 28, 39, .08); }
.freight-header-grid { display: grid; grid-template-columns: 1.2fr .8fr; gap: 14px; }
.freight-total-card { border: 1px solid #d8e9dd; border-radius: 16px; padding: 18px; background: linear-gradient(135deg, #effaf4, #f8fefd); display: grid; gap: 8px; }
.freight-total-card span { font-size: 12px; text-transform: uppercase; letter-spacing: .08em; color: #5f7c6a; font-weight: 700; }
.freight-total-card strong { font-size: 38px; line-height: 1; color: #0f5d3a; }
.freight-total-card small { color: #587067; }
.freight-shortcuts { display: grid; gap: 10px; align-content: start; }
.freight-action-form { display: grid; gap: 18px; }
.freight-eligible-table { min-width: 980px; }

@media (max-width: 1200px) {
  .freight-header-grid { grid-template-columns: 1fr; }
  .transport-sections-grid { grid-template-columns: 1fr; }
}


.nf-omie-details {
  grid-template-columns: 1.1fr .9fr;
}

.nf-omie-payload {
  margin: 0;
  padding: 14px;
  border-radius: 12px;
  border: 1px solid #dce6f1;
  background: #f8fbff;
  color: #1f3040;
  max-height: 360px;
  overflow: auto;
  font-size: 12px;
  line-height: 1.45;
}

.nf-charge-box {
  border: 1px dashed #bfd2e6;
  border-radius: 10px;
  padding: 12px;
  background: #f8fbff;
  color: #334b63;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
  font-size: 12px;
}

/* ── Responsividade mobile: Sangria ─────────────────────────────────── */
@media (max-width: 900px) {
  .statement-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 680px) {
  .statement-kpis { grid-template-columns: 1fr; }
  .statement-meta { grid-template-columns: 1fr; }
  /* Section-head com botão: empilha verticalmente */
  .section-head { flex-wrap: wrap; }
  .section-head > .btn { width: 100%; }
  /* Hero: empilha conteúdo + botão no mobile (botão full-width, sem espremer o
     texto pra fora do botão — corrige o vazamento crônico dos heros). */
  .hero-card { flex-wrap: wrap; padding: 20px; gap: 14px; }
  .hero-card h2 { font-size: 22px; }
  .hero-card .btn { width: 100%; }
}

/* ── Responsividade mobile: Vendas & Transportes ────────────────────── */

/* Botões de ação em linha (flex-wrap) no mobile */
@media (max-width: 900px) {
  .stack-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
  }
  .stack-actions .btn { flex: 1 1 auto; text-align: center; }
  .stack-actions .form-inline {
    flex: 1 1 auto;
    min-width: 200px;
    flex-wrap: wrap;
    gap: 8px;
  }
  .stack-actions .form-inline input { flex: 1 1 100px; max-width: 100%; }
  .form-inline { flex-wrap: wrap; }
  .form-inline input { flex: 1 1 100%; max-width: 100%; }
  /* Botões do formulário de transporte */
  .transport-form-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
  }
  .transport-form-actions .btn { flex: 1 1 auto; text-align: center; }
}

/* Tabelas de itens/pagamentos viram cards em telas pequenas */
@media (max-width: 680px) {
  /* table+tbody como BLOCO 100% — senão a <table> encolhe pro conteúdo (grid de
     1fr com texto curto) e ocupa só metade da tela. Vale p/ TODA card-table. */
  .mobile-card-table { min-width: 0 !important; display: block; width: 100%; }
  .mobile-card-table > tbody { display: block; width: 100%; }
  .mobile-card-table thead { display: none; }
  .mobile-card-table tbody tr {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 6px 10px;
    padding: 12px;
    border-bottom: 2px solid var(--line);
  }
  .mobile-card-table tbody tr td {
    padding: 0;
    border: none;
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
  }
  .mobile-card-table tbody tr td::before {
    content: attr(data-label);
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--text-soft);
  }
  /* Primeira célula (produto/data) ocupa a linha toda */
  .mobile-card-table tbody tr td:first-child { grid-column: 1 / -1; }

  /* Tabela de pagamentos: 2 colunas; conta corrente ocupa linha toda */
  .mobile-card-table.payments-table tbody tr { grid-template-columns: 1fr 1fr; }
  .mobile-card-table.payments-table tbody tr td:nth-child(2) { grid-column: 1 / -1; }

  /* Tabela de viagens do transporte: 2 colunas; linha toda p/ 1ª e 3ª células */
  .mobile-card-table.trips-table tbody tr { grid-template-columns: 1fr 1fr; }
  .mobile-card-table.trips-table tbody tr td:nth-child(1),
  .mobile-card-table.trips-table tbody tr td:nth-child(3) { grid-column: 1 / -1; }

  /* Relatório de vendas: 2 colunas. 3 colunas espremiam demais — o rótulo e o
     valor quebravam caractere a caractere ("VALO R TOTA L", "Math eus Torre s") e
     ainda sobrava branco. Com 2 col os campos fluem em pares (Nota|Cliente,
     Qtds|Valor, Forma|Motorista, Quem|Status); só Produtos e Ações ocupam a linha. */
  .mobile-card-table.report-table tbody tr { grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 9px 12px; padding: 12px 14px; }
  .mobile-card-table.report-table tbody tr td:nth-child(3) { grid-column: 1 / -1; }  /* Produtos: linha toda */
  /* Célula de ações (último td, sem data-label): linha inteira, botões em linha
     que quebra e se ajustam ao texto — sem espremer numa coluna de 1/3 (o que
     cortava "Reenviar NF" / "Reemitir boleto"). */
  .mobile-card-table.report-table tbody tr td:last-child {
    grid-column: 1 / -1;
    flex-direction: row;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 4px;
  }
  .mobile-card-table.report-table tbody tr td:last-child::before { display: none; }
  .mobile-card-table.report-table tbody tr td:last-child > .btn {
    flex: 0 0 auto; width: auto; white-space: nowrap;
  }

  /* Sangria: 2 colunas; documento/nota ocupa linha toda */
  .mobile-card-table.sangria-table tbody tr { grid-template-columns: 1fr 1fr; }
  .mobile-card-table.sangria-table tbody tr td:nth-child(1) { grid-column: 1 / -1; }

  /* Viagens de fretes a receber e a pagar: 2 colunas; cliente/fornecedor, material e rota ocupam linha toda */
  .mobile-card-table.freight-trips-table tbody tr { grid-template-columns: 1fr 1fr; }
  .mobile-card-table.freight-trips-table tbody tr td:nth-child(3) { grid-column: 1 / -1; }
  .mobile-card-table.freight-trips-table tbody tr td:nth-child(5) { grid-column: 1 / -1; }
  .mobile-card-table.freight-trips-table tbody tr td:nth-child(6) { grid-column: 1 / -1; }

  /* Contas elegíveis (medições de itens carregados): 2 colunas; checkbox, cliente e produtos ocupam linha toda */
  .mobile-card-table.consol-eligible-table tbody tr { grid-template-columns: 1fr 1fr; }
  .mobile-card-table.consol-eligible-table tbody tr td:nth-child(1) { grid-column: 1 / -1; }
  .mobile-card-table.consol-eligible-table tbody tr td:nth-child(3) { grid-column: 1 / -1; }
  .mobile-card-table.consol-eligible-table tbody tr td:nth-child(9) { grid-column: 1 / -1; }

  /* Medições de estoque: 2 colunas; produto ocupa linha toda, código fica em coluna */
  .mobile-card-table.stock-measurements-table tbody tr { grid-template-columns: 1fr 1fr; }
  .mobile-card-table.stock-measurements-table tbody tr td:first-child { grid-column: auto; }
  .mobile-card-table.stock-measurements-table tbody tr td:nth-child(2) { grid-column: 1 / -1; }

  /* Histórico de consolidações: 2 colunas; código e cliente ocupam linha toda */
  .mobile-card-table.consol-history-table tbody tr { grid-template-columns: 1fr 1fr; }
  .mobile-card-table.consol-history-table tbody tr td:first-child { grid-column: auto; }
  .mobile-card-table.consol-history-table tbody tr td:nth-child(2) { grid-column: 1 / -1; }
  .mobile-card-table.consol-history-table tbody tr td:nth-child(3) { grid-column: 1 / -1; }

  /* Produtos do local: 2 colunas; produto ocupa linha toda, botão PEND também */
  .mobile-card-table.stock-products-table tbody tr { grid-template-columns: 1fr 1fr; }
  .mobile-card-table.stock-products-table tbody tr td:first-child { grid-column: auto; }
  .mobile-card-table.stock-products-table tbody tr td:nth-child(3) { grid-column: 1 / -1; font-weight: 600; }
  .mobile-card-table.stock-products-table tbody tr td:last-child  { grid-column: 1 / -1; }

  /* Fechamento (pendentes + histórico): 2 colunas; entidade e ações em linha cheia,
     botões sem corte (ex: "Realizar fechamento") */
  /* table/tbody como bloco pra que o tr (display:grid) estique a 100% da largura —
     sem isso o grid encolhe pro conteúdo e ocupa só metade da tela */
  .mobile-card-table.fech-table, .mobile-card-table.fech-detail-table { display: block; width: 100%; }
  .mobile-card-table.fech-table > tbody, .mobile-card-table.fech-detail-table > tbody { display: block; width: 100%; }
  /* `> tbody > tr >` de propósito: as sub-tabelas de itens moram DENTRO da
     linha-detalhe e têm layout próprio (deck no fechamento.html) — sem o escopo
     estas regras vazavam pra elas (2026-07-20). */
  .mobile-card-table.fech-table > tbody > tr { grid-template-columns: 1fr 1fr; row-gap: 8px; }
  .mobile-card-table.fech-table > tbody > tr > td.fech-cell-entity,
  .mobile-card-table.fech-table > tbody > tr > td.fech-cell-actions { grid-column: 1 / -1; }
  /* 1ª célula (selecionar + expandir): linha cheia, alvos espaçados e maiores
     pra não clicar no errado sem querer */
  .mobile-card-table.fech-table > tbody > tr > td:first-child {
    grid-column: 1 / -1; width: auto !important; overflow: visible !important;
    display: flex; flex-direction: row !important; align-items: center;
    gap: 22px; padding: 2px 4px 6px;
  }
  .mobile-card-table.fech-table > tbody > tr > td:first-child::before { display: none; }
  .mobile-card-table.fech-table > tbody > tr > td:first-child input[type="checkbox"] {
    width: 22px !important; height: 22px !important;
  }
  .mobile-card-table.fech-table > tbody > tr > td:first-child > button {
    font-size: 14px !important; line-height: 1; color: #1d4ed8 !important;
    background: #eff6ff !important; border: 1px solid #bfdbfe !important;
    border-radius: 8px !important; padding: 7px 14px !important; flex: 0 0 auto;
  }
  .mobile-card-table.fech-table > tbody > tr > td:first-child input[type="checkbox"] { flex: 0 0 auto; }
  /* linha de detalhe expandida: vira BLOCO full-width (sem grid) e sem o recuo de 44px */
  /* sem !important no display: o fechToggle colapsa setando display:none inline,
     que precisa vencer este CSS. A especificidade (.fech-table tr[id^=detail-])
     já ganha do grid base sem !important. */
  .mobile-card-table.fech-table > tbody > tr[id^="detail-"] { display: block; width: 100%; }
  .mobile-card-table.fech-table > tbody > tr[id^="detail-"] > td { display: block !important; width: 100% !important; max-width: none !important; grid-column: 1 / -1 !important; padding: 0 8px 14px 8px !important; box-sizing: border-box; }
  /* o .content-area .card table td:first-child{max-width:180px} (p/ outras tabelas)
     estava prendendo a célula de detalhe em 180px — libera nas tabelas do fechamento */
  .mobile-card-table.fech-table td:first-child,
  .mobile-card-table.fech-detail-table td { max-width: none !important; }
  .mobile-card-table.fech-table tbody tr td.fech-cell-actions::before { display: none; }
  .fech-cell-actions .inline-actions { justify-content: flex-start; flex-wrap: wrap; gap: 8px; }
  .fech-cell-actions .inline-actions .btn { flex: 1 1 auto; min-width: 150px; padding: 9px 14px; white-space: nowrap; }
  /* Ações do histórico (PDF / ⟳ Omie / ↻ Refazer / ✕ Cancelar): botões COMPACTOS
     em grade 2-up (flex calc, sem min-width 150) — cabem em ~2 linhas curtas em
     vez de 4 botões full-width empilhados. Cancelar vem dentro de <form>. */
  .fech-cell-actions .inline-actions.fech-actions-compact { justify-content: stretch; gap: 6px; }
  .fech-cell-actions .inline-actions.fech-actions-compact > .btn,
  .fech-cell-actions .inline-actions.fech-actions-compact > form { flex: 1 1 calc(50% - 3px); min-width: 0; }
  .fech-cell-actions .inline-actions.fech-actions-compact > form .btn { width: 100%; min-width: 0; }
  .fech-cell-actions .inline-actions.fech-actions-compact .btn {
    padding: 8px 8px; font-size: 12px; line-height: 1.1; white-space: nowrap;
  }

  /* Tabelas internas de itens (ao expandir um card): o layout mobile ("deck" de
     cards estilo Pagamentos do Fluxo de Caixa, com campos configuráveis via
     card_fields.js) mora no <style> de modules/fechamento.html — os "CARDS
     DENSOS" antigos que viviam aqui foram aposentados (2026-07-20). Aqui fica
     só a estrutura block/thead que qualquer modo card precisa. */
  .mobile-card-table.fech-detail-table { display: block !important; width: 100% !important; min-width: 0 !important; }
  .mobile-card-table.fech-detail-table > thead { display: none; }
  .mobile-card-table.fech-detail-table > tbody { display: block; width: 100%; }
}

/* ── Mobile: hambúrguer + menu em tela cheia ──────────────────────────────── */
.mobile-menu { display: none; }
.mobile-menu[hidden] { display: none !important; }
.topbar-mobile-bar { display: none; }

@media (max-width: 768px) {
  /* Esconde a sidebar de desktop */
  .sidebar { display: none !important; }

  /* Sem barra inferior: padding de baixo normal. Respiro no topo (a barra fixa
     não traz mais margem inferior, pra conteúdo deslizar limpo por baixo). */
  .content-area { padding-top: 14px; padding-bottom: calc(28px + env(safe-area-inset-bottom, 0px)); }

  /* STICKY, igual ao LineUp (`.glass-nav` em `intermed-vite/src/index.css` +
     `App.jsx`: <header className="sticky top-0 z-40 glass-nav">), que é a
     referência que o Marcos apontou como funcionando.
     Sticky OCUPA espaço em repouso e fica pregada ao rolar — ou seja, o
     conteúdo passa POR BAIXO dela do mesmo jeito, sem precisar de `fixed` +
     contentInset (que no iOS ainda treme com o teclado aberto).
     Quem faz a barra alcançar o topo FÍSICO da tela é o
     `padding-top: env(safe-area-inset-top)` dela + a tríade de metas do
     base.html: sem as metas o iOS começa a webview abaixo do relógio e nada
     disso acontece.
     topbar-head é oculto no mobile, então zeramos o padding desktop. */
  .topbar {
    position: sticky;
    top: 0;
    z-index: 150;
    padding: 0;
    min-height: 0;
  }
  /* Barra ENXUTA: sem folgas verticais nem gaps largos (feedback 2026-07-26 —
     o header ocupava espaço demais e sobrava vazio entre os itens). */
  .topbar-mobile-bar {
    display: flex;
    align-items: center;
    align-self: stretch;   /* topbar é column flex com align-items:flex-start */
    gap: 8px;
    margin: 0;
    padding: calc(6px + env(safe-area-inset-top, 0px)) 12px 6px;
    /* O `env(safe-area-inset-top)` só vale mais que zero com o
       `viewport-fit=cover` + a tríade de metas do base.html — sem eles a barra
       pára embaixo do relógio e sobra a tarja da theme-color por cima. */
    /* ⚠️ NO NAVEGADOR A BARRA É CHAPADA — E TEM QUE SER.
       No Safari a faixa do relógio é cromo do NAVEGADOR: a página não pinta lá,
       quem pinta é a `theme-color`, que é uma cor FIXA. Vidro é a média do que
       passa por baixo, então ele muda de cor o tempo todo — medido na foto do
       Marcos: faixa #242b33 (a theme-color, certinha) e barra #141d24, porque
       naquele instante o hero escuro estava atrás dela. Cor fixa NUNCA casa com
       vidro variável; insistir nisso era só empurrar a diferença de um tom pra
       outro. Então, no navegador, a barra usa exatamente a cor da faixa. */
    background: #242b33;
    border-bottom: 1px solid rgba(255,255,255,.10);
  }
  /* ⚠️ O VIDRO SÓ ENTRA QUANDO A PÁGINA É DONA DO TOPO DA TELA — e quem diz
     isso é a sonda do base.html (`html.tem-area-segura`), não o display-mode.
     `display-mode: standalone` era o proxy errado: um ícone instalado antes das
     metas roda em standalone E com a webview começando abaixo do relógio, então
     a faixa continuava chapada (theme-color) e o vidro por baixo dela virava
     duas cores coladas — medido na foto do Marcos: faixa #242b33 uniforme, do
     lado do LineUp variando (#22150f→#130a0b, que é conteúdo pelo vidro).
     Com a régua certa: barra dona do topo = vidro cobrindo a faixa do relógio,
     conteúdo passando por baixo. Sem ela = chapada, na cor exata da faixa. */
  html.tem-area-segura .topbar-mobile-bar {
    background: rgba(9, 16, 24, 0.88);
    -webkit-backdrop-filter: blur(20px) saturate(140%);
    backdrop-filter: blur(20px) saturate(140%);
  }
  /* sem backdrop-filter o "vidro" seria só transparência — texto ilegível por
     cima do conteúdo. Aí volta a ser a chapada. */
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    html.tem-area-segura .topbar-mobile-bar { background: #242b33; }
  }
  .topbar-hamburger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 9px;
    border: 1px solid rgba(255,255,255,.12);
    background: rgba(255,255,255,.05);
    color: #e8f3ee;
    cursor: pointer;
    flex: 0 0 auto;
    order: 9;   /* hambúrguer à DIREITA do topbar mobile */
    -webkit-tap-highlight-color: transparent;
  }
  .topbar-hamburger svg { width: 18px; height: 18px; }
  .topbar-hamburger:active { background: rgba(255,255,255,.12); }
  .topbar-mobile-logo { width: 24px; height: auto; flex: 0 0 auto; display: block; }
  .topbar-mobile-page {
    font-size: 14.5px;
    font-weight: 700;
    letter-spacing: .01em;
    color: #f2f8f5;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex: 1 1 auto;
    min-width: 0;
  }
  /* HUD de XP compacto na barra (a pílula cheia sobrava espaço vazio) */
  .topbar-mobile-bar .game-hud { gap: 6px; padding: 3px 8px; }
  .topbar-mobile-bar .game-hud .ghud-bar { width: 44px; }
  /* Aba/subaba já está na topbar → não repete breadcrumb/título no corpo. */
  .topbar-head { display: none; }

  /* Overlay do menu */
  .mobile-menu {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 500;
  }
  .mobile-menu-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(8,14,20,.42);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    opacity: 0;
    transition: opacity .25s ease;
  }
  .mobile-menu.open .mobile-menu-backdrop { opacity: 1; }

  .mobile-menu-sheet {
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    left: auto;
    /* deixa uma folga à esquerda mostrando o fundo borrado (visual profissional) */
    width: min(86%, 420px);
    display: flex;
    flex-direction: column;
    background: linear-gradient(180deg, #071018 0%, #0d1721 100%);
    border-left: 1px solid rgba(255,255,255,.1);
    transform: translateX(100%);
    transition: transform .28s cubic-bezier(.32,.72,0,1);
  }
  .mobile-menu.open .mobile-menu-sheet { transform: translateX(0); }

  .mobile-menu-head {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: calc(16px + env(safe-area-inset-top, 0px)) 16px 12px;
    border-bottom: 1px solid rgba(255,255,255,.08);
    flex: 0 0 auto;
  }
  .mm-head-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
  .mobile-menu-title { font-size: 16px; font-weight: 800; letter-spacing: .04em; color: #f2f8f5; }
  .mobile-menu-close {
    width: 38px; height: 38px;
    display: inline-flex; align-items: center; justify-content: center;
    border: none; background: rgba(255,255,255,.06); color: rgba(255,255,255,.8);
    border-radius: 10px; font-size: 18px; cursor: pointer;
  }
  .mobile-menu-close:active { background: rgba(255,255,255,.14); }

  .mobile-menu-nav {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 10px 12px calc(28px + env(safe-area-inset-bottom, 0px));
  }

  /* Item simples (Fechamento, Tarefas) */
  .mm-item, .mm-group-toggle {
    display: flex;
    align-items: center;
    gap: 13px;
    width: 100%;
    padding: 14px 14px;
    color: rgba(255,255,255,.78);
    font-size: 15px;
    font-weight: 600;
    text-decoration: none;
    text-align: left;
    border: none;
    background: none;
    border-radius: 12px;
    cursor: pointer;
  }
  .mm-item.active, .mm-group-toggle.active { color: #88f0b7; }
  .mm-item:active, .mm-group-toggle:active { background: rgba(255,255,255,.06); }
  .mm-icon { width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; }
  .mm-icon svg { width: 100%; height: 100%; fill: currentColor; }
  .mm-label { flex: 1; min-width: 0; }
  .mm-caret { font-size: 12px; color: rgba(255,255,255,.45); transition: transform .2s ease; }
  .mm-group.open .mm-caret { transform: rotate(180deg); }

  /* Sub-itens — colapsáveis */
  .mm-subitems {
    max-height: 0;
    overflow: hidden;
    transition: max-height .26s ease;
    padding-left: 18px;
  }
  .mm-group.open .mm-subitems { max-height: 720px; }
  .mm-subitem {
    display: block;
    padding: 11px 14px;
    color: rgba(255,255,255,.6);
    font-size: 14px;
    font-weight: 500;
    text-decoration: none;
    border-radius: 10px;
    border-left: 2px solid rgba(255,255,255,.08);
    margin: 2px 0;
  }
  .mm-subitem.active { color: #88f0b7; border-left-color: #88f0b7; background: rgba(136,240,183,.08); font-weight: 600; }
  .mm-subitem:active { background: rgba(255,255,255,.07); }
  .mm-subheading { padding: 12px 14px 4px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: rgba(255,255,255,.4); }

  /* Bloco do usuário no topo do menu — Portal Central + usuário + sair */
  .mobile-menu-foot {
    flex: 0 0 auto;
    border-bottom: 1px solid rgba(255,255,255,.09);
    padding: 10px 14px 12px;
    display: flex;
    flex-direction: column;
    gap: 6px;
  }
  .mm-portal {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    align-self: flex-start;          /* não ocupa a linha toda */
    color: rgba(255,255,255,.72);
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    padding: 6px 13px;
    border: 1px solid rgba(255,255,255,.12);
    border-radius: 999px;
    background: rgba(255,255,255,.04);
  }
  .mm-portal:active { color: #88f0b7; background: rgba(255,255,255,.08); }
  .mm-user {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 4px;
  }
  .mm-user-dot { width: 8px; height: 8px; border-radius: 50%; background: #88f0b7; flex: 0 0 auto; }
  .mm-user-text { flex: 1; min-width: 0; }
  .mm-user-name { font-size: 14px; font-weight: 700; color: #f2f8f5; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .mm-user-company { font-size: 11px; color: rgba(255,255,255,.55); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .mm-logout {
    flex: 0 0 auto;
    color: #fca5a5;
    font-size: 13px;
    font-weight: 700;
    text-decoration: none;
    padding: 8px 14px;
    border: 1px solid rgba(248,113,113,.3);
    border-radius: 10px;
  }
  .mm-logout:active { background: rgba(248,113,113,.12); }
}

/* ── Page tabs ──────────────────────────────────────────────────────── */
.page-tabs {
  display: flex;
  gap: 4px;
  border-bottom: 2px solid var(--line);
  margin-bottom: 18px;
}
.page-tab {
  display: inline-block;
  padding: 8px 20px;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-muted);
  text-decoration: none;
  border-radius: 8px 8px 0 0;
  border: 1px solid transparent;
  border-bottom: none;
  margin-bottom: -2px;
  transition: color .14s, background .14s;
  white-space: nowrap;
}
.page-tab:hover { color: var(--fg); background: rgba(255,255,255,.6); }
.page-tab.active {
  color: var(--fg);
  background: rgba(255,255,255,.95);
  border-color: var(--line);
  border-bottom-color: rgba(255,255,255,.95);
}


/* ─────────────────────────────────────────────────────────────────────
 * Dashboard — Responsividade mobile
 * Cobre 8 sub-abas (resumo, visao-geral, fluxo-caixa, dre, departamento,
 * receitas, custos, despesas) + drill universal + detalhe de movimento +
 * árvore de decomposição.
 * ───────────────────────────────────────────────────────────────────── */

/* Saldo hero — escala progressiva por viewport */
.saldo-hero { transition: padding .15s; }
.saldo-hero-value { transition: font-size .15s; }

@media (max-width: 1024px) {
  .saldo-hero-value { font-size: 3.6rem !important; }
}

@media (max-width: 768px) {
  .saldo-hero { padding: 22px 16px !important; }
  .saldo-hero-label { font-size: 0.72rem !important; }
  .saldo-hero-value { font-size: 2.8rem !important; }
  .saldo-hero-meta { font-size: 0.74rem !important; gap: 10px !important; }
}

@media (max-width: 480px) {
  .saldo-hero { padding: 18px 12px !important; border-radius: 10px !important; }
  .saldo-hero-label { font-size: 0.66rem !important; letter-spacing: 0.08em !important; }
  .saldo-hero-value { font-size: 2.1rem !important; line-height: 1 !important; }
  .saldo-hero-meta {
    flex-direction: column !important;
    gap: 4px !important;
    font-size: 0.7rem !important;
  }
  .saldo-hero-meta span { display: block; }
}

/* Cards KPI — denser em mobile */
@media (max-width: 768px) {
  .grid-kpis { grid-template-columns: 1fr 1fr !important; gap: 10px !important; }
  .kpi-card { padding: 12px !important; }
  .kpi-title { font-size: 0.72rem !important; }
  .kpi-value { font-size: 1.1rem !important; }
  .kpi-delta { font-size: 0.7rem !important; }
}

@media (max-width: 480px) {
  .grid-kpis { grid-template-columns: 1fr !important; }
  .kpi-value { font-size: 1.3rem !important; }
}

/* Tabelas DRE / drill / multidim — scroll horizontal preservando UX */
.table-wrap, .dash-table-wrap, .drill-table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}

@media (max-width: 768px) {
  .dash-table, .drill-table, .dre-table, .multidim-table,
  .table-wrap > table {
    font-size: 0.78rem !important;
    min-width: 100%;
  }
  .dash-table th, .dash-table td,
  .drill-table th, .drill-table td,
  .dre-table th, .dre-table td,
  .multidim-table th, .multidim-table td,
  .table-wrap th, .table-wrap td {
    padding: 6px 8px !important;
    white-space: nowrap;
  }
  /* Primeira coluna (label da linha) sticky — fica visível durante scroll */
  .dash-table th:first-child, .dash-table td:first-child,
  .drill-table th:first-child, .drill-table td:first-child,
  .dre-table th:first-child, .dre-table td:first-child {
    position: sticky;
    left: 0;
    background: #fff;
    z-index: 1;
    box-shadow: 2px 0 4px rgba(0,0,0,0.04);
  }
}

/* Filtros de período / regime — wrap vertical em mobile */
.periodo-filtros, .regime-toggle, .dash-filters, .dash-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

@media (max-width: 768px) {
  .periodo-filtros, .regime-toggle, .dash-filters, .dash-toolbar {
    flex-direction: column;
    align-items: stretch !important;
  }
  .periodo-filtros > *, .regime-toggle > *,
  .dash-filters > *, .dash-toolbar > * { width: 100%; }
  .periodo-filtros select, .periodo-filtros input,
  .dash-filters select, .dash-filters input {
    min-height: 44px;   /* touch-friendly Apple guideline */
    font-size: 16px;    /* evita zoom auto do iOS */
  }
}

/* Gauges (Resumo Executivo) — 2 colunas em tablet, 1 em phone */
@media (max-width: 768px) {
  .gauges-grid { grid-template-columns: 1fr 1fr !important; gap: 6px !important; }
}

@media (max-width: 480px) {
  .gauges-grid { grid-template-columns: 1fr !important; }
}

/* SVG charts (sparklines, waterfall, projeção) — full width */
@media (max-width: 768px) {
  .dash-chart, .dash-chart svg,
  .sparkline, .waterfall, .projecao-chart {
    width: 100% !important;
    height: auto;
    max-width: 100vw;
  }
}

/* Heading e subtitle — escalas reduzidas */
@media (max-width: 768px) {
  .page-title, h1 { font-size: 1.4rem !important; }
  .page-subtitle { font-size: 0.85rem !important; }
  .page-tabs { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .page-tab { padding: 8px 14px; font-size: 13px; }
}

/* Drill-down: form de rateio inline — empilha em mobile */
@media (max-width: 768px) {
  .rateio-form .rateio-row {
    flex-direction: column !important;
    gap: 6px !important;
    padding: 8px !important;
  }
  .rateio-form input, .rateio-form select { width: 100% !important; }
  .rateio-form button { min-height: 40px; width: 100%; }
}

/* Detalhe do movimento — header em coluna única */
@media (max-width: 768px) {
  .movimento-header, .movimento-info {
    grid-template-columns: 1fr !important;
    gap: 8px !important;
  }
  .movimento-actions { flex-direction: column; gap: 6px; }
  .movimento-actions a, .movimento-actions button {
    width: 100%; min-height: 44px; text-align: center;
  }
}

/* Árvore de decomposição — nodes em scroll horizontal */
@media (max-width: 768px) {
  .arvore-container { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .arvore-nivel { font-size: 0.8rem; }
  .arvore-node { padding: 8px 10px; font-size: 0.75rem; }
}

/* Botões — touch-friendly em mobile */
@media (max-width: 768px) {
  .btn, button.btn, a.btn, .button {
    min-height: 44px;
    padding: 10px 16px;
  }
  .btn-sm { min-height: 36px; padding: 6px 12px; }
}

/* Mensagens flash — não dominar tela em mobile */
@media (max-width: 480px) {
  .flash-message, .alert {
    font-size: 0.85rem;
    padding: 10px 12px;
    margin-bottom: 10px;
  }
}

/* Card geral — padding interno menor em mobile pra dar mais conteúdo */
@media (max-width: 480px) {
  .card { padding: 14px !important; border-radius: 16px !important; }
  .card .card-title, .card h3 { font-size: 1rem; margin-bottom: 8px; }
}

/* Sidebar mobile — adiciona safe-area pra iPhone X+ */
@media (max-width: 900px) {
  .sidebar { padding-bottom: max(18px, env(safe-area-inset-bottom)); }
  .content-area { padding-bottom: max(20px, env(safe-area-inset-bottom)); }
}

/* Tipografia base mobile — evita zoom auto em inputs do iOS */
@media (max-width: 768px) {
  input[type="text"], input[type="number"], input[type="date"],
  input[type="search"], select, textarea {
    font-size: 16px;
  }
}

/* ═════════════════════════════════════════════════════════════════════
 * Dashboard mobile — overrides FORTES de inline styles
 * Os templates do dashboard usam muito `style="..."` inline. Pra evitar
 * reescrever 11 arquivos, usamos !important em mobile e seletores
 * específicos pra:
 *  - empilhar toolbars/filtros verticalmente
 *  - colapsar grids inline pra 1 coluna
 *  - dar overflow horizontal a TODA tabela dentro de .card
 *  - encolher fonts/paddings de tabelas
 *  - tornar o modal de drill fullscreen
 * ═══════════════════════════════════════════════════════════════════ */

@media (max-width: 768px) {

  /* ── Cards / toolbars topo de cada sub-aba: força wrap vertical ──── */
  /* Pega `<section class="card" style="...display:flex;..justify-content:space-between..">`
     que é o padrão das toolbars (DRE / Fluxo / Departamento / Multidim) */
  .content-area .card[style*="display:flex"][style*="space-between"] {
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 10px !important;
  }
  .content-area .card[style*="display:flex"][style*="space-between"] > * {
    width: 100% !important;
  }

  /* ── Formulários de filtro (period, regime, usuário): empilha labels ── */
  .content-area .card form[method="get"],
  .content-area .card form[action*="dashboard"] {
    display: flex !important;
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 8px !important;
    width: 100% !important;
  }
  .content-area .card form[method="get"] label,
  .content-area .card form[action*="dashboard"] label {
    width: 100% !important;
  }
  /* ⚠️ CHECKBOX E RADIO FICAM DE FORA. A regra existe pra empilhar campo de
     texto e select do filtro; aplicada com `!important` a TODO input, ela
     inflava a caixinha de marcar num retângulo de 100% × 40px — que estourava
     o rótulo ao lado e saía cortado pela direita (o "descartadas" da busca de
     Transportes, 18/08/2026). É o mesmo acidente que o reset lá em cima já
     tinha consertado pro caso geral; aqui o `!important` passava por cima. */
  .content-area .card form[method="get"] select,
  .content-area .card form[method="get"] input:not([type="checkbox"]):not([type="radio"]),
  .content-area .card form[action*="dashboard"] select,
  .content-area .card form[action*="dashboard"] input:not([type="checkbox"]):not([type="radio"]) {
    width: 100% !important;
    min-width: 0 !important;
    min-height: 40px;
    padding: 8px 10px !important;
  }
  .content-area .card form button[type="submit"] {
    width: 100%;
    min-height: 42px;
  }

  /* Grupo de botões PDF/CSV/Atualizar na toolbar — ocupam linha total */
  .content-area .card > div[style*="display:flex"][style*="gap"] {
    flex-wrap: wrap !important;
    width: 100%;
  }
  .content-area .card > div[style*="display:flex"][style*="gap"] > a,
  .content-area .card > div[style*="display:flex"][style*="gap"] > button {
    flex: 1 1 auto;
    text-align: center;
  }

  /* ── Grids inline (style="grid-template-columns:repeat(N,...)") ──── */
  /* Em mobile, FORÇA 1 coluna em qualquer grid criado via inline style */
  .content-area section[style*="grid-template-columns"],
  .content-area .grid[style*="grid-template-columns"],
  .content-area article[style*="grid-template-columns"],
  .content-area div[style*="grid-template-columns"]:not([data-keep-grid]) {
    grid-template-columns: 1fr !important;
  }
  /* Exceção: KPIs ficam 2 colunas em ≤768px (já tratado), 1 col em ≤480px */
  .content-area .grid-kpis,
  .content-area .grid-kpis[style*="grid-template-columns"] {
    grid-template-columns: 1fr 1fr !important;
  }

  /* Layout two-col que existe no visao_geral / fluxo */
  .content-area .two-col { grid-template-columns: 1fr !important; gap: 14px !important; }

  /* ── Tabelas dentro de .card: scroll horizontal + fonte/padding menor ── */
  /* Wrapper: força overflow:auto no .card que contém uma <table> SEM rolagem
     própria (qualquer profundidade — cobre Dashboard, drills, etc.).
     ## ⚠️⚠️ SÓ A TABELA SEM `.table-wrap` — O CARD INTEIRO ROLANDO DE LADO FOI O #33
     Esta regra valia pra TODO card com tabela, e com `!important`. A tabela que
     já mora num `.table-wrap` rola dentro dele; no card dela, a rolagem do card
     só servia pra outra coisa — o que mais passasse da borda (o campo de data do
     iPhone, uma linha de botões) arrastava o CARD INTEIRO de lado. Foi o modal
     do relatório de vendas do dia (chamado #33 da J&M, 16/09/2026: *"já é a
     terceira vez que eu peço"*): ele declarava `overflow-x:hidden` em três
     lugares, com comentário explicando por quê, e o computado era `auto` — esta
     linha ganhava de todos. Quarta vez da família da regra que perde calada
     (#23, #31, #25).
     ⚠️ `mobile-card-table` NÃO sai daqui: ela só vira bloco abaixo de 680px, e
     esta regra vale até 768 — entre os dois ela ainda é tabela e precisa rolar. */
  .content-area .card:has(table:not(.table-wrap table)),
  .content-area .card[style*="padding:0"] {
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch;
  }
  /* contêineres de rolagem internos (ex.: #dre-view-tradicional, .table-wrap) */
  .content-area .card .table-wrap,
  .content-area .card [style*="overflow-x:auto"],
  .content-area .card [style*="overflow-x: auto"] {
    -webkit-overflow-scrolling: touch;
  }
  /* Mais robusto: aplica overflow no parent direto da tabela */
  .content-area .card table {
    font-size: 0.78rem !important;
    width: 100% !important;
    min-width: 0 !important;
  }
  .content-area .card table th,
  .content-area .card table td {
    padding: 6px 8px !important;
    white-space: nowrap !important;
  }
  /* PRIMEIRA coluna (label / cliente / categoria / linha do DRE): pode quebrar em
     palavras, mas NUNCA esmaga a ponto de quebrar letra-a-letra — tem largura
     mínima. Quando as demais colunas (nowrap) não cabem, a tabela rola na
     horizontal (o card tem overflow-x:auto) em vez de espremer a 1ª coluna. */
  .content-area .card table th:first-child,
  .content-area .card table td:first-child {
    white-space: normal !important;
    min-width: 150px;
    max-width: 240px;
    word-break: break-word;
  }

  /* DRE indentação: reduz pra caber em mobile */
  .content-area .card table td[style*="padding-left:54px"],
  .content-area .card table td[style*="padding-left:76px"] {
    padding-left: 16px !important;
  }
  .content-area .card table td[style*="padding-left:32px"] {
    padding-left: 10px !important;
  }

  /* ── DRE Árvore: reduz fonte / padding dos <details> ───────────── */
  .content-area details summary {
    padding: 8px 10px !important;
    font-size: 0.82rem !important;
  }
  .content-area details summary > div {
    min-width: 0 !important;
    flex-wrap: wrap !important;
  }
  /* Barras de progresso dentro da árvore: encolhe */
  .content-area details summary div[style*="width:60px"],
  .content-area details summary div[style*="width:80px"],
  .content-area details summary div[style*="width:100px"] {
    width: 36px !important;
  }
  .content-area details summary span[style*="min-width:100px"],
  .content-area details summary span[style*="min-width:110px"] {
    min-width: 70px !important;
    font-size: 0.78rem;
  }

  /* ── Subtotais da DRE (divs gigantes): encolhe padding/fonte ─── */
  .content-area .card div[style*="border-left:4px solid"][style*="border-radius:8px"] {
    padding: 8px 12px !important;
  }
  .content-area .card div[style*="border-left:4px solid"][style*="border-radius:8px"] span[style*="font-size:1.4rem"] {
    font-size: 1rem !important;
  }

  /* ── Cards KPI hero (saldo gigante) ───────────────────────────── */
  .content-area .card[class*="saldo-hero"] div[style*="font-size:4.5rem"],
  .content-area .card[class*="saldo-hero"] div[style*="font-size:4.2rem"] {
    font-size: 2.4rem !important;
  }
  .content-area .card[class*="saldo-hero"] div[style*="font-size:2.2rem"] {
    font-size: 1.6rem !important;
  }

  /* ── Hero do resumo executivo (receber/pagar) ─────────────────── */
  .content-area section[style*="grid-template-columns:1fr 1fr"][style*="margin-bottom"] {
    grid-template-columns: 1fr !important;
  }

  /* ── Waterfall chart (composição DRE): mantém colunas mas reduz fonte ── */
  .content-area .card div[style*="grid-template-columns:repeat(9,1fr)"] {
    height: 160px !important;
    gap: 3px !important;
  }
  .content-area .card div[style*="grid-template-columns:repeat(9,1fr)"] div[style*="font-size:0.7rem"] {
    font-size: 0.55rem !important;
    line-height: 1.1 !important;
  }

  /* ── Editor de rateio inline: ajusta grid 4 colunas pra empilhar ─ */
  .rateio-row,
  .rateio-row[style*="grid-template-columns"] {
    grid-template-columns: 1fr 60px 70px 28px !important;
    gap: 3px !important;
  }
  .rateio-form {
    min-width: 0 !important;
    width: calc(100vw - 32px) !important;
    max-width: 380px;
    left: 8px;
    right: 8px;
  }
  /* Editor de categoria (re-classificar): mesmo tratamento */
  .cat-editor > details > form,
  details.cat-editor form {
    min-width: 0 !important;
    width: calc(100vw - 32px) !important;
    max-width: 380px;
  }

  /* ── Texto explicativo / muted: shrink na fonte ───────────────── */
  .content-area .card p,
  .content-area .card .muted {
    font-size: 0.8rem;
  }

  /* ── Mensagens flash / banners de aviso ───────────────────────── */
  .content-area .card[style*="background:linear-gradient"][style*="border-left"] {
    padding: 10px 12px !important;
  }
  .content-area .card[style*="background:linear-gradient"] strong {
    font-size: 0.88rem;
  }

  /* ── Headers das seções (section-head) ───────────────────────── */
  .content-area .section-head { gap: 6px !important; }
  .content-area .section-head h3 { font-size: 1rem !important; }
  .content-area .section-head p { font-size: 0.78rem !important; }

  /* ── Drill modal — TELA CHEIA em mobile ───────────────────────── */
  #drill-modal {
    padding: 0 !important;
  }
  #drill-modal > div[role="dialog"] {
    border-radius: 0 !important;
    max-width: 100% !important;
    min-height: 100dvh;
  }
  #drill-modal #drill-modal-close {
    top: 6px !important;
    right: 6px !important;
    width: 40px !important;
    height: 40px !important;
  }
  #drill-modal #drill-modal-back {
    top: 6px !important;
    left: 6px !important;
    padding: 8px 12px !important;
  }
  #drill-modal #drill-modal-content {
    padding: 52px 10px 16px !important;
  }

  /* ── Movimento detalhe: header em coluna + auditoria empilhada ──── */
  .content-area .card .audit-block div[style*="grid-template-columns"] {
    grid-template-columns: 1fr !important;
    gap: 8px !important;
  }

  /* ── Fluxo de Caixa: cabeçalho de "Resumo por Conta" + linhas ─── */
  /* Grid "1fr auto" do cabeçalho e linhas de CC vira 1 coluna em mobile */
  .content-area .card div[style*="grid-template-columns:1fr auto"] {
    grid-template-columns: 1fr !important;
    gap: 4px !important;
  }
  /* Sub-grid de 3 valores (Entradas/Saídas/Saldo) compacta */
  .content-area .card span[style*="grid-template-columns:100px 100px 130px"],
  .content-area .card div[style*="grid-template-columns:100px 100px 130px"] {
    grid-template-columns: 1fr 1fr 1fr !important;
    gap: 4px !important;
    font-size: 0.78rem !important;
  }

  /* ── Tabela de hoje/semana do Resumo (a receber/pagar) ─────────── */
  /* Ocupa largura total do card mesmo quando dentro de <a> link */
  .content-area a[href*="dashboard/drill"] > article.card { width: 100% !important; }
}

/* Detalhe do movimento: editor de rateio com grid 4 colunas larger (110px) */
@media (max-width: 768px) {
  /* Cabeçalho do rateio + linhas do <main> editor inline (não confundir com drill) */
  .content-area #rateio-rows .rateio-row,
  .content-area div[style*="grid-template-columns:1fr 110px 110px 40px"] {
    grid-template-columns: 1fr 70px 70px 32px !important;
    gap: 4px !important;
    font-size: 0.78rem !important;
  }
  /* Tabela de NFe / Pedido: trunca CFOP/Cód/Un em mobile reduzindo padding */
  .content-area .card table th,
  .content-area .card table td {
    overflow: hidden;
    text-overflow: ellipsis;
  }
  /* Permite descrição do produto quebrar linha */
  .content-area .card table td:nth-child(2) {
    white-space: normal !important;
    word-break: break-word;
  }
}

/* Phone pequenos (≤480px): refinamento extra */
@media (max-width: 480px) {
  .content-area .card { padding: 12px !important; border-radius: 16px !important; }
  .content-area .card table { font-size: 0.72rem !important; }
  .content-area .card table th,
  .content-area .card table td {
    padding: 4px 6px !important;
  }
  /* Saldo hero ainda menor */
  .content-area .card[class*="saldo-hero"] div[style*="font-size:4.5rem"],
  .content-area .card[class*="saldo-hero"] div[style*="font-size:4.2rem"] {
    font-size: 1.9rem !important;
  }
  /* KPIs ficam 1 coluna */
  .content-area .grid-kpis,
  .content-area .grid-kpis[style*="grid-template-columns"] {
    grid-template-columns: 1fr !important;
  }
  /* Atalhos rápidos: 1 botão por linha */
  .content-area .quick-grid { grid-template-columns: 1fr !important; }
  /* Pílulas Tradicional/Árvore: ocupam linha total e ficam lado a lado */
  .dre-view-btn { font-size: 0.78rem; padding: 6px 10px; }
  /* Breadcrumb do drill: encolhe */
  .drill-breadcrumb { font-size: 0.75rem !important; gap: 4px !important; }
}

/* ───────────────────────────────────────────────────────────────────────
   Polish visual — pills de status, zebra, tabular nums, hierarquia do drill
   ─────────────────────────────────────────────────────────────────────── */

/* Pills de status (PAGO / A VENCER / VENCIDO / CANCELADO / etc.) */
.status-pill {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  line-height: 1.5;
  border: 1px solid transparent;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.status-pill.is-pago,
.status-pill.is-liquidado,
.status-pill.is-conciliado    { background: rgba(34,197,94,.12);  color: #15803d; border-color: rgba(34,197,94,.28); }
.status-pill.is-vencido       { background: rgba(239,68,68,.10);  color: #b91c1c; border-color: rgba(239,68,68,.28); }
.status-pill.is-vencer,
.status-pill.is-aberto        { background: rgba(245,158,11,.14); color: #b45309; border-color: rgba(245,158,11,.32); }
.status-pill.is-cancelado     { background: rgba(148,163,184,.15); color: #475569; border-color: rgba(148,163,184,.32); }
.status-pill.is-previsto      { background: rgba(99,102,241,.12);  color: #4338ca; border-color: rgba(99,102,241,.28); }

/* Tabular numbers — alinha vírgula e dígitos em colunas R$ / quantidades.
   Pega tanto classes nomeadas quanto inline style="text-align:right" (padrão
   das tabelas atuais do dashboard, que ainda não migraram pra classe). */
.dre-table td, .dre-table th,
.drill-table td, .drill-table th,
.dash-table td, .dash-table th,
.multidim-table td, .multidim-table th,
td[align="right"], th[align="right"],
td[style*="text-align:right"], th[style*="text-align:right"],
td[style*="text-align: right"], th[style*="text-align: right"],
.brl, .num, .tabular { font-variant-numeric: tabular-nums; }

/* Tabela do drill — zebra sutil + hover */
.drill-table tbody tr:nth-child(even) > td { background: rgba(15, 23, 42, .025); }
.drill-table tbody tr:hover > td           { background: rgba(17,173,180,.06); }
.drill-table tbody tr                       { transition: background .12s ease; }
.drill-table thead th { font-weight: 600; font-size: .75rem; text-transform: uppercase; letter-spacing: .05em; color: #475569; }

/* Header do drill — eyebrow + título grande + meta line */
.drill-header { display:flex; justify-content:space-between; align-items:flex-end; flex-wrap:wrap; gap:14px; padding:18px 22px; margin-bottom:14px; border-radius:14px; background:#fff; border:1px solid #e6ecf2; box-shadow:0 1px 2px rgba(15,23,42,.03); }
.drill-header-text { min-width: 0; flex: 1; }
.drill-eyebrow { font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .12em; margin: 0 0 4px;
  background: var(--brand-grad); -webkit-background-clip: text; background-clip: text; color: transparent; }
/* Utilitário: texto com o gradiente da marca (verde→ciano). REGRA do app. */
.brand-grad-text { background: var(--brand-grad); -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent; }
.drill-title { margin: 0; font-size: 1.45rem; font-weight: 700; color: #0d1c27; line-height: 1.2; letter-spacing: -.01em; }
.drill-meta { margin: 6px 0 0; font-size: .82rem; color: #6b7d91; display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.drill-meta .chip { display:inline-flex; align-items:center; gap:5px; padding: 2px 9px; background:#f1f5f9; border-radius:999px; font-size:.75rem; color:#334155; font-weight:600; font-variant-numeric: tabular-nums; }
.drill-meta .chip.success { background: rgba(34,197,94,.12); color:#15803d; }
.drill-back { font-size: .8rem; }

@media (max-width: 768px) {
  .drill-title { font-size: 1.15rem; }
  .drill-header { padding: 14px 16px; }
}

/* ⚠️ O CARREGADOR DA MARCA, o véu de navegação e o VISOR DE PDF mudaram de
   arquivo: `static/css/carregadores.css`. Eles são das DUAS camadas (app e
   portal do cliente), e o portal não carrega este arquivo — ver o cabeçalho de
   lá. Não recrie nada disto aqui. */

/* ── Estado vazio branded (escudo marca-d'água) ─────────────────────────── */
.vectra-empty { display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:10px; padding:34px 20px; text-align:center; color:var(--text-soft); font-size:.92rem; line-height:1.5; }
.vectra-empty::before { content:''; width:48px; height:48px; flex:0 0 auto;
  background:url("../img/brand/vectra_shield_flat.svg") center/contain no-repeat; opacity:.16; }
.vectra-empty.sm { padding:20px 14px; font-size:.85rem; gap:8px; }
.vectra-empty.sm::before { width:34px; height:34px; }

/* ── Compras · Cotação ───────────────────────────────────────────────────── */
.cotacao-page .btn-xs { padding: 5px 10px; font-size: 12px; border-radius: 8px; min-height: 0; }
/* spinner inline pequeno dentro de botões (default é 60px) */
.cotacao-page .btn .vectra-spinner { width: 16px; height: 16px; vertical-align: middle; margin-right: 4px; }

.cotacao-page .cot-supplier-dropdown,
.cotacao-page #supplierDropdown {
  position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 30;
  background: #fff; border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 12px 30px rgba(15,30,45,.14); max-height: 320px; overflow-y: auto; padding: 6px;
}
.cotacao-page .cot-supplier-opt {
  display: block; width: 100%; text-align: left; border: 0; background: none;
  padding: 8px 10px; border-radius: 8px; cursor: pointer; font-size: 13px; color: #1c3040;
}
.cotacao-page .cot-supplier-opt:hover { background: #f1f7f4; }
.cotacao-page .cot-supplier-opt.muted { cursor: default; }

.cotacao-page .cot-sugestoes-list,
.cotacao-page .cot-suppliers { display: grid; gap: 10px; }
.cotacao-page .cot-sugestao-card,
.cotacao-page .cot-supplier-card {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 14px; border: 1px solid var(--line); border-radius: 12px; background: #fbfdfe;
}
.cotacao-page .cot-supplier-card { flex-direction: column; align-items: stretch; }
.cotacao-page .cot-supplier-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.cotacao-page .cot-supplier-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.cotacao-page .cot-supplier-contact { display: flex; gap: 12px; flex-wrap: wrap; font-size: 12px; color: #6b7d91; margin-top: 6px; }
.cotacao-page .cot-sugestao-tags { margin: 4px 0; display: flex; gap: 4px; flex-wrap: wrap; }
.cotacao-page .cot-sugestao-contact { font-size: 12px; margin-top: 2px; }

.cotacao-page .cot-status {
  display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 11px; font-weight: 700;
  background: #eef2f7; color: #51637a; margin-left: 6px;
}
.cotacao-page .cot-status-enviado { background: #dbeafe; color: #1d4ed8; }
.cotacao-page .cot-status-respondido { background: #dcfce7; color: #15803d; }
.cotacao-page .cot-status-vencedor { background: var(--brand-grad); color: #fff; }
.cotacao-page .cot-status-perdedor,
.cotacao-page .cot-status-recusado { background: #fee2e2; color: #b91c1c; }

.cotacao-page .cot-resposta-bloco {
  border: 1px solid var(--line); border-radius: 12px; padding: 0; margin-bottom: 12px; background: #fff;
}
.cotacao-page .cot-resposta-bloco > summary {
  cursor: pointer; padding: 12px 16px; font-size: 14px; list-style: none;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.cotacao-page .cot-resposta-bloco > summary::-webkit-details-marker { display: none; }
/* Botão de seta (expandir/recolher) — claro, à direita do nome do fornecedor */
.cotacao-page .cot-bloco-chevron {
  margin-left: auto; display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; flex-shrink: 0; border-radius: 9px;
  border: 1px solid var(--teal, #11ADB4); color: var(--teal, #11ADB4); background: #fff;
  transition: transform .18s ease, background .18s ease, color .18s ease;
}
.cotacao-page .cot-resposta-bloco > summary:hover .cot-bloco-chevron { background: rgba(17,173,180,.10); }
.cotacao-page .cot-resposta-bloco[open] > summary .cot-bloco-chevron {
  transform: rotate(180deg); background: var(--teal, #11ADB4); color: #fff;
}
.cotacao-page .cot-resposta-form { padding: 0 16px 16px; }

.cotacao-page .cot-itens-table-wrap,
.cotacao-page .cot-mtx-wrap { overflow-x: auto; }
.cotacao-page .cot-itens-table,
.cotacao-page .cot-mtx-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.cotacao-page .cot-itens-table th,
.cotacao-page .cot-itens-table td { padding: 8px 8px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
.cotacao-page .cot-input { width: 100%; min-width: 0; box-sizing: border-box; padding: 6px 8px; border: 1px solid var(--line); border-radius: 8px; }
.cotacao-page .cot-input-sm { max-width: 90px; }

.cotacao-page .cot-mtx-table th,
.cotacao-page .cot-mtx-table td { padding: 10px 10px; border: 1px solid var(--line); vertical-align: top; text-align: center; }
.cotacao-page .cot-mtx-prod { text-align: left; min-width: 160px; background: #f8fafc; }
.cotacao-page .cot-mtx-forn { min-width: 130px; }
.cotacao-page .cot-mtx-sub { font-size: 11px; font-weight: 400; }
.cotacao-page .cot-mtx-preco { font-weight: 700; }
.cotacao-page .cot-mtx-best { background: linear-gradient(90deg, rgba(143,203,58,.16), rgba(17,173,180,.16)); }
.cotacao-page .cot-mtx-venc { background: rgba(143,203,58,.12); }
.cotacao-page .cot-mtx-indisp { color: #b91c1c; font-size: 12px; }
.cotacao-page .cot-mtx-extras { font-size: 11px; }
.cotacao-page .cot-mtx-totalrow td { background: #f1f5f9; }

/* mobile-first: tabela de itens vira cards ≤680px */
@media (max-width: 680px) {
  .cotacao-page .cot-itens-table,
  .cotacao-page .cot-itens-table thead,
  .cotacao-page .cot-itens-table tbody,
  .cotacao-page .cot-itens-table tr,
  .cotacao-page .cot-itens-table td { display: block; width: 100%; box-sizing: border-box; }
  .cotacao-page .cot-itens-table thead { display: none; }
  .cotacao-page .cot-itens-table tr {
    border: 1px solid var(--line); border-radius: 12px; padding: 8px; margin-bottom: 10px; background: #fbfdfe;
  }
  .cotacao-page .cot-itens-table td { border: 0; padding: 5px 4px; display: flex; gap: 10px; align-items: center; }
  .cotacao-page .cot-itens-table td::before {
    content: attr(data-label); font-weight: 700; color: #51637a; font-size: 12px; flex: 0 0 92px;
  }
  .cotacao-page .cot-itens-table td:first-child::before { content: ''; flex: 0; }
  .cotacao-page .cot-itens-table td:first-child { display: block; }
  .cotacao-page .cot-input-sm { max-width: none; }
  .cotacao-page .cot-sugestao-card { flex-direction: column; align-items: stretch; }
}


/* ⚠️ O Card Wizard (`.wiz-*`) SAIU daqui em 31/08/2026 → `static/css/card_wizard.css`,
   porque o HUB passou a usá-lo e não carrega este arquivo. O base.html linka os
   dois. Não traga de volta. */

/* ── Modal de "do dia" reutilizável (igual relatório do PDV) ─────────────── */
.report-modal-overlay { position: fixed; inset: 0; z-index: 1500; background: rgba(0,0,0,.55);
  display: none; align-items: flex-start; justify-content: center; padding: 24px 16px; overflow-y: auto; }
.report-modal-overlay.open { display: flex; }
/* min-width:0 = box (flex item do overlay) encolhe até o viewport; sem isso o
   min-width:auto a infla até o min-content (botões nowrap) e estoura a tela. */
.report-modal-box { position: relative; width: min(1100px, 100%); min-width: 0; max-height: 92vh; overflow-y: auto; margin: auto; }
.report-modal-close { position: absolute; top: 12px; right: 12px; width: 34px; height: 34px; border-radius: 9px;
  border: 1px solid var(--line); background: #fff; color: var(--text-muted, #627385); font-size: 1rem; cursor: pointer; z-index: 2; }
.report-modal-close:hover { background: var(--danger, #cf222e); color: #fff; }
@media (max-width: 680px) {
  /* Só rolagem VERTICAL no mobile — nada de scroll lateral.
     html/body com overflow-x:hidden mata o scroll lateral da PÁGINA (iOS Safari
     não respeita só o overflow do modal quando o documento é mais largo que a
     viewport). 100vw vaza no iOS (ignora a viewport real) → usar 100%. */
  html, body { overflow-x: clip; }
  .report-modal-overlay { padding: 0; overflow-x: hidden; }
  .report-modal-box { max-height: 100vh; min-height: 100vh; border-radius: 0; width: 100%; max-width: 100%; min-width: 0; overflow-x: hidden; }
  .report-modal-box .table-wrap { overflow-x: hidden; }
  .report-modal-box .report-table tbody tr td { white-space: normal !important; overflow-wrap: anywhere; min-width: 0; }
  .report-modal-box .report-table tbody tr td[data-omie-cr-cell],
  .report-modal-box .report-table tbody tr td:last-child {
    grid-column: 1 / -1; flex-direction: row; flex-wrap: wrap; align-items: center; gap: 6px;
  }
  .report-modal-box .report-table tbody tr td[data-omie-cr-cell] .btn,
  .report-modal-box .report-table tbody tr td:last-child .btn { flex: 0 0 auto; }
  .report-modal-box .report-table tbody tr td[data-omie-cr-cell]::before,
  .report-modal-box .report-table tbody tr td:last-child::before { flex: 1 0 100%; }
}

/* ── Fix mobile: tabelas com 1ª coluna = DATA/HORA (almoxarifado/cautela) ──────
   A regra genérica `.content-area .card table td:first-child` (≤768px) deixa a 1ª
   coluna quebrar (assume rótulo curto) e mantém as demais em nowrap. Quando a 1ª
   coluna é a data e a 2ª é um nome longo, a data colapsava e quebrava letra a
   letra. Aqui invertemos: a data fica numa linha; Colaborador/Item é que quebram. */
@media (max-width: 768px) {
  .content-area .card table.hist-table--dt th:first-child,
  .content-area .card table.hist-table--dt td:first-child {
    white-space: nowrap !important; max-width: none !important; word-break: normal !important;
  }
  .content-area .card table.hist-table--dt td:nth-child(2),
  .content-area .card table.hist-table--dt td:nth-child(3) {
    white-space: normal !important; word-break: break-word;
  }
}

/* ── Checkbox mobile-safe (.vk-check) — PADRÃO do app ─────────────────────────
   Substitui o antigo "checkbox + texto ao lado" que estourava no celular. A
   caixa tem tamanho fixo (flex:0 0 auto) e o rótulo quebra normalmente
   (min-width:0). Use SEMPRE este padrão pra checkboxes com rótulo.
   Markup:
     <label class="vk-check">
       <input type="checkbox" id="..">
       <span class="vk-check-box" aria-hidden="true"></span>
       <span class="vk-check-label">Rótulo…</span>
     </label> */
.vk-check { display: flex; align-items: flex-start; gap: 10px; cursor: pointer; width: 100%; min-width: 0; }
.vk-check > input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.vk-check-box { flex: 0 0 auto; width: 20px; height: 20px; margin-top: 1px; border-radius: 6px;
  border: 2px solid var(--line, #cbd5e1); background: #fff; display: inline-flex;
  align-items: center; justify-content: center; transition: background .15s, border-color .15s; }
.vk-check > input:checked + .vk-check-box { background: var(--brand-grad); border-color: transparent; }
.vk-check > input:checked + .vk-check-box::after { content: '✓'; color: #fff; font-size: 13px; font-weight: 800; line-height: 1; }
.vk-check > input:focus-visible + .vk-check-box { outline: 2px solid #5b8def; outline-offset: 2px; }
.vk-check-label { min-width: 0; font-size: .9rem; line-height: 1.3; color: var(--text, #1f2937); }

/* ── mobile-card-table dentro de .content-area ────────────────────────────────
   A regra mobile genérica (.content-area .card table td { white-space:nowrap })
   força nowrap; em modo card (≤680px) os valores precisam quebrar. */
@media (max-width: 680px) {
  .content-area .card .mobile-card-table tbody tr td,
  .content-area .card .mobile-card-table tbody tr td:first-child {
    white-space: normal !important; max-width: none !important; word-break: break-word;
  }
  /* Regras cadastradas: célula de ações ocupa a linha toda. */
  .mobile-card-table.cr-rules-table tbody tr td.cr-actions-cell { grid-column: 1 / -1; }
  .mobile-card-table.cr-rules-table tbody tr td.cr-actions-cell::before { display: none; }
  .mobile-card-table.cr-rules-table tbody tr td.cr-actions-cell .inline-actions { width: 100%; }
}

/* Wizard de Regras Comerciais: cada passo contém um ou mais <article class="card">
   próprios — então o painel usa padding enxuto e empilha os cards com gap. */
.cr-wizard .wiz-panel { padding: 10px; }
/* :not([hidden]) é essencial: display:flex sem isso vence o .wiz-panel[hidden]
   (mesma especificidade, vem depois) e mostrava TODOS os painéis ao mesmo tempo. */
.cr-wizard .wiz-panel:not([hidden]) { display: flex; flex-direction: column; gap: 12px; }
.cr-wizard .wiz-panel-nav { margin-top: 2px; }

/* Nav do wizard: prev/next sempre LADO A LADO (não empilha). No mobile cada um
   ocupa metade e o texto trunca com … se não couber — em vez de escapar/quebrar. */
.wiz-panel-nav .btn { white-space: nowrap; }
/* botão "+ Adicionar …" cresce em vez de deixar o texto escapar por baixo */
.btn-plus { height: auto; min-height: 40px; white-space: normal; line-height: 1.2; max-width: 100%; }

/* Card de opção (estilo do passo Restrições): checkbox + título + descrição numa
   caixa com borda — usado nas permissões fiscais do passo Avançado. */
.cr-opt-card { padding: 12px 14px; border: 1px solid var(--line, #e2e8f0);
  border-left: 3px solid var(--primary, #11adb4); border-radius: 10px; background: #f8fbff; align-items: flex-start; }
.cr-opt-card .vk-check-label { display: flex; flex-direction: column; gap: 2px; }
.cr-opt-card .vk-check-label strong { font-size: 14px; }
.cr-opt-card .vk-check-label small { font-size: 12px; color: #6b7280; line-height: 1.35; }

@media (max-width: 680px) {
  /* nav: metade/metade, trunca se preciso */
  .wiz-panel-nav .btn { flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis;
    padding: 10px 8px; font-size: .82rem; }
  /* Tabela de materiais (Regras Comerciais): empilha cada campo em largura total
     no mobile — cabe o "Preço Omie", o preço e o "% desc." sem espremer. */
  .cr-mat-table.mobile-card-table tbody tr { grid-template-columns: 1fr; }
  .cr-mat-table input:not([type="checkbox"]) { width: 100% !important; }
}

/* ⚠️ O modo Cards (`.tbl-cards`, `.tbl-view-toggle`) mudou pra `css/tabela_rica.css`
   em 16/09/2026 — o hub usa o kit e não carrega este arquivo. */

/* DRE: ocultar colunas de comparativo (M-1 / Δ MoM / M-12 / Δ YoY = 3ª em diante)
   quando o usuário desmarca "Mostrar comparativo". Vale na tabela e no card-view. */
.dre-table.dre-hide-compare th:nth-child(n+3),
.dre-table.dre-hide-compare td:nth-child(n+3) { display: none !important; }

/* Árvores/hierarquias no mobile (DRE árvore, página Árvore, Departamento):
   as linhas (summary) quebram em vez de espremer e o % verboso some — fica o valor. */
@media (max-width: 680px) {
  .content-area .card details > summary { flex-wrap: wrap; }
  .content-area .card details > summary > div { min-width: 0; }
  .dre-pct { display: none !important; }
  /* Departamento: nome em cima, valores (receita/custo/resultado) embaixo. */
  .dept-row { grid-template-columns: 1fr !important; gap: 4px 8px !important; }
  .dept-row > div:last-child { grid-template-columns: repeat(4, minmax(0, 1fr)) !important; font-size: .8rem !important; }
}

/* Overlay de navegação (brand_loaders.js): aparece ao clicar num link interno
   e fica até a página nova carregar — cobre páginas lentas (Fluxo de Caixa/DRE
   que renderizam batendo no Omie). */
/* Paginador de tabela dentro de cards (table_paginate.js) */
.tbl-pager { display: flex; align-items: center; justify-content: center; gap: 12px; padding: 10px; }
.tbl-pager button { border: 1px solid var(--line, #d1d9e0); background: #fff; color: #1c3040;
  width: 32px; height: 32px; border-radius: 8px; cursor: pointer; font-size: 1rem; line-height: 1; }
.tbl-pager button:disabled { opacity: .4; cursor: default; }
.tbl-pager .tbl-pager-info { font-size: .8rem; color: #6b7d91; font-variant-numeric: tabular-nums; }

/* ── Placa Mercosul (componente reutilizável) ─────────────────────────────────
   Plaquinha de veículo inline. EM-BASED: escala com o font-size do contexto e
   não estoura o layout (width:max-content, line-height:1). Use via macro Jinja
   placa() ou via JS window.Vectra.placaHTML(). Modificador .placa--sm p/ células
   apertadas. Markup: .placa > (.placa-strip > .placa-pais + .placa-br) + .placa-num */
.placa {
  display: inline-flex;
  flex-direction: column;
  vertical-align: middle;
  width: max-content;
  max-width: 100%;
  line-height: 1;
  background: #fff;
  color: #111827;
  border: 0.18em solid #1f2937;          /* ~3px @ 16px — borda escura arredondada */
  border-radius: 0.34em;
  overflow: hidden;
  font-family: "DejaVu Sans Mono", "SFMono-Regular", Menlo, Consolas, monospace;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.12);
  user-select: text;
}
.placa .placa-strip,
.placa-input .placa-strip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.4em;
  background: #1551b5;                    /* faixa azul Mercosul */
  color: #fff;
  padding: 0.06em 0.34em;
  font-size: 0.42em;                      /* faixa minúscula relativa ao número */
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1.1;
  text-transform: uppercase;
}
.placa .placa-pais,
.placa-input .placa-pais { white-space: nowrap; }
.placa .placa-br,
.placa-input .placa-br { white-space: nowrap; opacity: 0.95; }
.placa .placa-num {
  display: block;
  padding: 0.1em 0.4em 0.14em;
  font-size: 1em;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-align: center;
  color: #111827;
}
/* Modificador compacto p/ células de tabela apertadas */
.placa--sm { border-width: 0.14em; border-radius: 0.28em; }
.placa--sm .placa-strip { font-size: 0.4em; padding: 0.05em 0.28em; }
.placa--sm .placa-num { letter-spacing: 0.1em; padding: 0.08em 0.3em 0.1em; }

/* ── Placa Mercosul: INPUT editável ───────────────────────────────────────────
   Mesma linguagem visual da .placa (display), mas a área do número é um <input>
   real: os dígitos vão preenchendo a placa conforme o usuário digita. O wrapper
   .placa-input desenha a placa (faixa azul BRASIL/BR + borda) e o input interno
   .placa-input-num é o número (bold, espaçado, monospace, MAIÚSCULO, centrado).
   Progressive enhancement via window.Vectra.initPlacaInputs() — o <input> original
   (mesmo name/id/handlers) é movido pra dentro do wrapper, valor limpo intacto. */
.placa-input {
  display: inline-flex;
  flex-direction: column;
  vertical-align: middle;
  width: max-content;
  max-width: 100%;
  line-height: 1;
  background: #fff;
  border: 0.18em solid #1f2937;
  border-radius: 0.34em;
  overflow: hidden;
  font-family: "DejaVu Sans Mono", "SFMono-Regular", Menlo, Consolas, monospace;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.12);
  font-size: 1.5rem;                       /* placa grande/legível; filhos em em escalam */
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.placa-input:focus-within {
  border-color: #1551b5;                   /* foco = azul Mercosul */
  box-shadow: 0 0 0 0.18em rgba(21, 81, 181, 0.22);
}
/* Placa fora do padrão brasileiro ([data-placa-strict]). A borda da PRÓPRIA placa
   fica vermelha — o campo é a placa, então o erro tem que aparecer nela, não numa
   mensagem que rola pra fora da tela no celular. */
.placa-input:has(.placa-input-ruim) { border-color: #dc2626; }
.placa-input:has(.placa-input-ruim):focus-within {
  border-color: #dc2626;
  box-shadow: 0 0 0 0.18em rgba(220, 38, 38, 0.22);
}
.placa-aviso {
  margin-top: 0.3rem;
  font-size: 0.78rem;
  font-weight: 600;
  color: #b91c1c;
  line-height: 1.35;
}
.placa-aviso[hidden] { display: none !important; }   /* [hidden] perde pra display de classe */
.placa-input .placa-input-num {
  display: block;
  width: 100%;
  box-sizing: border-box;
  min-width: 6.2em;                        /* cabe 7 caracteres confortavelmente */
  margin: 0;
  border: 0;
  outline: 0;
  background: transparent;
  padding: 0.1em 0.3em 0.14em;
  font-family: inherit;
  font-size: 1em;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-indent: 0.16em;                     /* compensa o letter-spacing à direita = centro real */
  text-transform: uppercase;
  text-align: center;
  color: #111827;
  border-radius: 0;
}
.placa-input .placa-input-num::placeholder {
  color: #cdd4dd;                          /* slot fantasma (ex.: ABC0D00) — mostra forma/qtde */
  font-weight: 800;
  letter-spacing: 0.16em;
  opacity: 1;
}
/* readOnly/disabled ainda parece placa (sem cara de campo travado cinza) */
.placa-input .placa-input-num:read-only,
.placa-input .placa-input-num:disabled {
  background: transparent;
  color: #111827;
  -webkit-text-fill-color: #111827;
  cursor: default;
}

/* ═══════════════════════════════════════════════════════════════════════════
   card_draw.js — camada de desenho à mão sobre cards de deck (Fluxo, Conferência)
   + "mesa" / perspectiva 3D como OPÇÃO de visualização (default OFF).
   ═══════════════════════════════════════════════════════════════════════════ */
.vdraw-canvas { z-index: 8; }               /* acima do conteúdo do card */
.vdraw-on { user-select: none; -webkit-user-select: none; }

/* Faixa sticky no RODAPÉ do card: pina no fundo da viewport ao rolar (não cobre
   o valor da conta, que fica no topo). Quando inativa (barra hidden) tem altura 0.
   pointer-events:none pra não roubar clique; filhos reativam. */
.vdraw-chrome {
  position: sticky; bottom: 8px; z-index: 12;
  display: flex; justify-content: center; gap: 8px; pointer-events: none;
}
/* ⚠️ display explícito acima VENCE o [hidden] do navegador — sem estas regras o
   estojo aparecia SEMPRE (mesmo sem desenhar), porque chrome.hidden/bar.hidden
   não tinham efeito visual. Estojo só aparece com o lápis ATIVO. */
.vdraw-chrome[hidden], .vdraw-bar[hidden] { display: none !important; }
.vdraw-chrome > * { pointer-events: auto; }
/* Variante FORA do card: estojo numa faixa própria do deck (não sticky).
   ⚠️ position:relative + z-index ALTO é o que faz o estojo ser clicável: os cards do
   deck são posicionados (o ativo z-index:30, e os empilhados atrás ficam deslocados
   ~9-18px pra baixo, invadindo o topo da faixa). Como esta faixa ficava `static`, o
   z-index era ignorado e os cards pintavam POR CIMA dela → interceptavam os cliques
   nas cores/ferramentas. Positioned + z-index acima dos cards resolve o hit-testing. */
.vdraw-chrome-ext { position: relative; z-index: 60; bottom: auto; margin: 4px auto 12px; width: fit-content; }

/* Lápis FAB (fallback quando não há botão-gatilho no card). */
.vdraw-pencil {
  width: 38px; height: 38px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--line, #e2e8ed); background: rgba(255,255,255,0.94);
  box-shadow: 0 2px 8px rgba(16,24,40,0.14); cursor: pointer; font-size: 1rem;
  backdrop-filter: blur(4px); touch-action: manipulation;
  transition: transform .1s, box-shadow .14s, background .18s;
}
.vdraw-pencil:active { transform: scale(0.92); }
.vdraw-pencil.has-ink { box-shadow: inset 0 0 0 2px var(--accent, #8fcb3a), 0 2px 8px rgba(16,24,40,0.18); }
.vdraw-pencil.on { background: var(--brand-grad); border-color: transparent; color: #fff; }

/* Botão-gatilho externo (ex.: ✏️ Desenhar na barra de ações) — abre o estojo.
   Estados de marca: gradiente quando ATIVO (nunca ciano sólido), anel verde quando
   tem tinta. touch-action pra tirar o delay de clique no toque. */
.vdraw-trigger { touch-action: manipulation; transition: box-shadow .15s, transform .08s, background .2s, color .2s, border-color .2s; }
.vdraw-trigger:active { transform: scale(0.97); }
.vdraw-trigger.has-ink { box-shadow: inset 0 0 0 1.5px var(--accent, #8fcb3a); }
.vdraw-trigger.on {
  background: var(--brand-grad); background-size: 200% 100%; animation: brandFlow 7s ease-in-out infinite;
  border-color: transparent; color: #fff; box-shadow: 0 6px 16px rgba(17,173,180,0.30);
}
.vdraw-trigger.on:hover { color: #fff; }

/* ── ESTOJO (toolbox) — só visível no modo ativo. Cartão vertical, arrastável. ── */
.vdraw-bar.vdraw-estojo {
  display: flex; flex-direction: column; gap: 9px;
  width: min(320px, 92vw); padding: 10px 12px 12px;
  border-radius: var(--radius, 18px);
  border: 1px solid var(--line, #e5ebf2);
  background: rgba(255,255,255,0.98);
  box-shadow: 0 20px 46px -14px rgba(16,24,40,0.38), 0 2px 8px rgba(16,24,40,0.12);
  backdrop-filter: blur(10px);
}
.vdraw-chrome-ext.vdraw-dragging .vdraw-estojo { box-shadow: 0 26px 56px -12px rgba(16,24,40,0.5); }

/* Cabeçalho = zona de arraste (punho + título + fechar). */
.vdraw-head {
  display: flex; align-items: center; gap: 8px;
  margin: -2px -4px 2px; padding: 3px 4px;
  cursor: grab; touch-action: none; user-select: none; -webkit-user-select: none;
}
.vdraw-chrome-ext.vdraw-dragging .vdraw-head { cursor: grabbing; }
.vdraw-head .vdraw-grip { color: #b6c1cf; font-size: 0.7rem; letter-spacing: 1px; line-height: 1; }
.vdraw-head .vdraw-title { font-weight: 800; font-size: 0.82rem; letter-spacing: 0.2px; }
.vdraw-head .vdraw-x {
  margin-left: auto; width: 26px; height: 26px; border-radius: 8px;
  border: 1px solid var(--line, #e5ebf2); background: #fff; color: var(--text-soft, #66778a);
  cursor: pointer; font-size: 0.72rem; line-height: 1; display: grid; place-items: center;
  transition: background .12s, color .12s, border-color .12s;
}
.vdraw-head .vdraw-x:hover { background: #fdecec; border-color: #f5b5b5; color: #dc2626; }
/* Minimizar/maximizar: hover neutro (marca), não vermelho como o Fechar. Fica
   colado no ✕ (o próximo irmão herda o alinhamento à direita). */
.vdraw-head .vdraw-x[data-act="minmax"] { margin-left: auto; font-size: 1.05rem; font-weight: 800; }
.vdraw-head .vdraw-x[data-act="close"] { margin-left: 0; }
.vdraw-head .vdraw-x[data-act="minmax"]:hover { background: #f1f5f9; border-color: var(--accent, #8fcb3a); color: var(--text, #13212d); }
/* Estojo MINIMIZADO: recolhe os grupos e ações, deixa só o cabeçalho (pílula
   compacta, ainda arrastável). O canvas/desenho não é afetado. */
.vdraw-estojo.vdraw-min { width: auto; gap: 0; padding: 6px 8px; }
.vdraw-estojo.vdraw-min .vdraw-grp,
.vdraw-estojo.vdraw-min .vdraw-foot { display: none; }
.vdraw-estojo.vdraw-min .vdraw-head { margin: 0; }

/* Grupos rotulados (Pincel / Traço / Cor). */
.vdraw-grp { display: flex; flex-direction: column; gap: 5px; }
.vdraw-lbl {
  font-size: 0.62rem; font-weight: 700; letter-spacing: 0.7px; text-transform: uppercase;
  color: var(--text-soft, #66778a);
}
.vdraw-row { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.vdraw-row.vdraw-foot { margin-top: 2px; gap: 8px; }
.vdraw-estojo .vdraw-sep { width: 1px; height: 24px; background: var(--line, #e5ebf2); margin: 0 1px; }

/* Botões de pincel + borracha. */
.vdraw-estojo .vdraw-tool {
  width: 40px; height: 36px; border-radius: 11px;
  border: 1px solid var(--line, #e5ebf2); background: #fff; color: var(--text, #13212d);
  cursor: pointer; font-size: 1rem; display: flex; align-items: center; justify-content: center;
  touch-action: manipulation; transition: transform .1s, box-shadow .14s, background .18s, border-color .12s;
}
.vdraw-estojo .vdraw-tool:hover { border-color: var(--accent, #8fcb3a); }
.vdraw-estojo .vdraw-tool:active { transform: scale(0.94); }
.vdraw-estojo .vdraw-tool.on {
  background: var(--brand-grad); background-size: 200% 100%;
  border-color: transparent; color: #fff; box-shadow: 0 6px 14px rgba(17,173,180,0.28);
}

/* Espessuras (dot que cresce). */
.vdraw-estojo .vdraw-size {
  width: 38px; height: 32px; border-radius: 10px;
  border: 1px solid var(--line, #e5ebf2); background: #fff; color: var(--text, #13212d);
  cursor: pointer; display: flex; align-items: center; justify-content: center;
  touch-action: manipulation; transition: transform .1s, box-shadow .14s, background .18s, border-color .12s;
}
.vdraw-estojo .vdraw-size:hover { border-color: var(--accent, #8fcb3a); }
.vdraw-estojo .vdraw-size:active { transform: scale(0.94); }
.vdraw-estojo .vdraw-size i { display: block; border-radius: 50%; background: currentColor; }
.vdraw-estojo .vdraw-size[data-size="fino"] i { width: 4px; height: 4px; }
.vdraw-estojo .vdraw-size[data-size="medio"] i { width: 8px; height: 8px; }
.vdraw-estojo .vdraw-size[data-size="grosso"] i { width: 13px; height: 13px; }
.vdraw-estojo .vdraw-size.on {
  background: var(--brand-grad); background-size: 200% 100%; border-color: transparent; color: #fff;
  box-shadow: 0 6px 14px rgba(17,173,180,0.28);
}

/* Cores da paleta — anel limpo (branco + verde-marca) no selecionado, sem "pulo" de borda. */
.vdraw-estojo .vdraw-color {
  width: 24px; height: 24px; border-radius: 50%; padding: 0; cursor: pointer;
  border: 2px solid #fff; box-shadow: 0 0 0 1px var(--line, #e5ebf2);
  touch-action: manipulation; transition: transform .1s, box-shadow .14s;
}
.vdraw-estojo .vdraw-color:hover { transform: scale(1.08); }
.vdraw-estojo .vdraw-color.on { transform: scale(1.06); box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--accent, #8fcb3a); }

/* Cor personalizada — mascarada num círculo; a borda vira anel verde quando é a cor ativa. */
.vdraw-estojo .vdraw-custom {
  position: relative; width: 26px; height: 26px; border-radius: 50%; overflow: hidden;
  border: 2px dashed var(--line, #c9d3de); cursor: pointer; display: inline-grid; place-items: center;
  transition: box-shadow .14s, border-color .12s;
}
.vdraw-estojo .vdraw-custom::after {
  content: ''; width: 13px; height: 13px; pointer-events: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235f7388' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 22a1 1 0 0 1 0-20 10 9 0 0 1 10 9 5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z'/%3E%3Ccircle cx='13.5' cy='6.5' r='.5' fill='%235f7388'/%3E%3Ccircle cx='17.5' cy='10.5' r='.5' fill='%235f7388'/%3E%3Ccircle cx='6.5' cy='12.5' r='.5' fill='%235f7388'/%3E%3Ccircle cx='8.5' cy='7.5' r='.5' fill='%235f7388'/%3E%3C/svg%3E") center/contain no-repeat;
}
.vdraw-estojo .vdraw-custom input {
  position: absolute; inset: -8px; width: calc(100% + 16px); height: calc(100% + 16px);
  border: 0; padding: 0; margin: 0; cursor: pointer; opacity: 0;
}
.vdraw-estojo .vdraw-custom.on { border-style: solid; border-color: transparent; box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--accent, #8fcb3a); }
.vdraw-estojo .vdraw-custom.on::after { content: ''; }

/* Ações (Desfazer / Limpar). */
.vdraw-estojo .vdraw-act {
  flex: 1; min-height: 34px; border-radius: 10px;
  border: 1px solid var(--line, #e5ebf2); background: #fff; color: var(--text, #13212d);
  cursor: pointer; font-size: 0.78rem; font-weight: 700; letter-spacing: 0.2px;
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  touch-action: manipulation; transition: transform .1s, background .14s, border-color .12s, color .12s;
}
.vdraw-estojo .vdraw-act:hover:not([disabled]) { border-color: var(--accent, #8fcb3a); }
.vdraw-estojo .vdraw-act:active:not([disabled]) { transform: scale(0.97); }
.vdraw-estojo .vdraw-act[disabled] { opacity: 0.42; cursor: default; }
.vdraw-estojo .vdraw-act[data-act="clear"]:hover:not([disabled]) { border-color: #f5b5b5; background: #fdecec; color: #dc2626; }

@media (max-width: 680px) {
  .vdraw-bar.vdraw-estojo { width: min(300px, 94vw); padding: 9px 10px 11px; gap: 8px; }
  .vdraw-estojo .vdraw-tool { width: 38px; height: 34px; }
}

/* ── "Mesa" (opção de visualização) — moldura de escrivaninha sob o deck ──
   Ligada por classe no wrapper do deck (data-deck-mesa / .deck-mesa). Default OFF. */
.deck-mesa {
  position: relative;
  z-index: 0;                          /* stacking context: a foto (::before) fica atrás do deck */
  border-radius: 16px;
  padding: 30px 16px 34px;             /* mostra a mesa em volta do card (largura toda) */
  /* sem overflow:hidden — o card "voa" (translateX 125%) pra fora no swipe (tinder). */
  perspective: 1200px;                 /* habilita o 3D do card se .deck-3d também estiver on */
  perspective-origin: 50% -12%;        /* ponto de fuga acima → visão "de cima pra frente" */
}
/* Foto de MESA de escritório (madeira + cadeira + plantinha) cobrindo a largura toda;
   o card fica apoiado sobre ela. webp com fallback jpg. */
.deck-mesa::before {
  content: ''; position: absolute; inset: 0; z-index: -1; border-radius: 16px;
  background-image: url("../img/brand/mesa_desk.jpg");
  background-image: -webkit-image-set(url("../img/brand/mesa_desk.webp") type("image/webp"), url("../img/brand/mesa_desk.jpg") type("image/jpeg"));
  background-image: image-set(url("../img/brand/mesa_desk.webp") type("image/webp"), url("../img/brand/mesa_desk.jpg") type("image/jpeg"));
  background-size: cover;
  background-position: center 28%;
  box-shadow: inset 0 0 60px rgba(0,0,0,0.28);
}
/* O card ativo parece POUSADO na mesa (sombra projetada forte) mesmo sem o 3D. */
.deck-mesa .fcdeck-card.is-active {
  box-shadow: 0 26px 42px -16px rgba(0,0,0,0.55), 0 8px 18px rgba(0,0,0,0.28);
}

/* ── Perspectiva 3D do card (opção separada) — o card parece APOIADO na mesa em ângulo.
   NÃO usa position:fixed aninhado (pegadinha do card_wizard): só transform no card.
   `:not(.is-drag)` → durante o arraste o transform inline (translateX) volta a
   valer, senão o card não seguiria o dedo. Sem !important pra não brigar com o
   inline; o seletor de 4 classes perde pro inline durante o drag (transform inline).
   O ângulo/origem casam com a perspectiva do trapézio da Mesa: pivô perto da base
   (origin 88%) e rotateX maior que antes, sem prejudicar a leitura dos números. */
/* `:not(.vdraw-on)` → enquanto DESENHA o card fica PLANO: o canvas é filho do card,
   então em 3D o CSS já deforma o traço (quadrado→trapézio) de graça na EXIBIÇÃO; mas
   pra o INPUT do desenho bater (clique→pixel), o card precisa estar reto na hora de
   rabiscar. Ao parar (vdraw-on sai), o 3D volta e o desenho plano aparece em perspectiva
   — retrocompatível nos dois sentidos, sem warpar PNG. */
.deck-3d .fcdeck-card.is-active:not(.is-drag):not(.vdraw-on),
.deck-3d .confdeck-card:first-child:not(.is-drag):not(.vdraw-on) {
  transform: perspective(1100px) rotateX(11deg) scale(0.985);
  transform-origin: center 88%;
  box-shadow: 0 34px 54px -20px rgba(0,0,0,0.58), 0 10px 20px rgba(0,0,0,0.26);
}

/* Botões do toggle de visualização (mesa / 3D). Ficam na barra de view do deck. */
.deck-viewopt {
  display: inline-flex; gap: 4px; margin-left: 8px;
}
/* ⚠️ MESMO defeito que a barra de ações tinha (`.fcdeck-act`): item de flex
   encolhe por padrão, e no celular "Mesa" virava "Me sa" e "3D" virava "3 D".
   Largura natural + rótulo inteiro; quem cede é o container, que rola. */
.deck-viewopt button {
  border: 1px solid var(--line, #e2e8ed); background: #fff; color: #475569;
  border-radius: 7px; font-size: 0.74rem; padding: 4px 9px; cursor: pointer;
  flex: 0 0 auto; white-space: nowrap;
}
@media (max-width: 680px) {
  .deck-viewopt { max-width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  /* ⚠️ **"Ações ao lado" NÃO EXISTE NO CELULAR — e ele estava lá, ocupando o
     maior botão da barra.** O que ele faz é pôr os botões à DIREITA do card em
     vez de embaixo, e isso só cabe em tela larga: no celular ele é um botão que
     não muda nada visível. *"Esse botão de ações do lado nem sei o que faz"*
     (Marcos, 01/09/2026) — e a resposta honesta é: aí, nada. Sumir é melhor que
     explicar, porque a explicação continuaria terminando em "aqui não". */
  .deck-viewopt button[data-deckopt="acoes-lado"] { display: none; }
}
.deck-viewopt button.on { background: var(--primary, #11ADB4); border-color: var(--primary, #11ADB4); color: #fff; }

/* ── "Cobranças geradas" (credit_transactions) — 13 colunas estouravam a largura.
   Wrapper .table-wrap já rola no x; aqui compactamos pra CABER no desktop sem cortar:
   fonte menor, códigos que quebram e coluna de Ações estreita com botões que embrulham.
   No mobile (≤768px) a tabela vira cards via .mobile-card-table (regras existentes). */
@media (min-width: 769px) {
  .charges-table { width: 100%; table-layout: fixed; font-size: 0.8rem; }
  .charges-table th, .charges-table td {
    padding: 6px 8px; vertical-align: top; word-break: break-word; overflow-wrap: anywhere;
  }
  .charges-table code { word-break: break-all; font-size: 0.74rem; }
  /* colunas de código (nCodTitulo / Código integ.) e Contrato: largura contida + quebra */
  .charges-table td[data-label="nCodTitulo"],
  .charges-table td[data-label="Código"] { max-width: 110px; }
  .charges-table td[data-label="Contrato"] { max-width: 130px; }
  .charges-table td[data-label="Entidade"] { max-width: 150px; }
  /* Ações: os botões embrulham em vez de forçar a tabela a crescer */
  .charges-table td[data-label="Ações"] { width: 150px; }
  .charges-table td[data-label="Ações"] .btn {
    font-size: 0.7rem; padding: 3px 7px; white-space: normal;
  }
  .charges-table td[data-label="Ações"] form { display: inline-block; }
}

/* ═════════════════════════════════════════════════════════════════════
 * Ícones SVG — sprite inline (partials/_icons.html, gerado por
 * scripts/build_icons.py a partir do Lucide). Substituem os emojis.
 *   Jinja: {{ icon('check') }} · {{ icon('trash-2', 'ic-lg') }}
 *   JS:    el.innerHTML = vIcon('check') + ' Salvar';
 * Cor via currentColor; tamanho via font-size do contexto (1em).
 * pointer-events:none → clique num ícone dentro de <button> mantém
 * e.target no botão (handlers delegados do app.js dependem disso).
 * ═══════════════════════════════════════════════════════════════════ */
.ic { width: 1em; height: 1em; display: inline-block; vertical-align: -0.145em; flex: none; pointer-events: none; }
.ic-sm { width: .85em; height: .85em; }
.ic-lg { width: 1.3em; height: 1.3em; vertical-align: -0.26em; }
.ic-xl { width: 1.6em; height: 1.6em; vertical-align: -0.35em; }
.ic-spin { animation: ic-spin 1s linear infinite; }
@keyframes ic-spin { to { transform: rotate(360deg); } }
/* Ícone "bolinha de status" (ex-🟢/🔴/🟡): cor sólida via classe utilitária */
.ic-ok { color: #16a34a; } .ic-err { color: #dc2626; } .ic-warn { color: #d97706; }

/* ── Guarda global anti-vazamento (mobile): botão nunca passa do container.
     white-space:normal derruba nowrap herdado/inline — texto quebra em 2 linhas
     em vez de estourar a lateral do card. ── */
@media (max-width: 768px) {
  button, .btn, a.btn, .button {
    max-width: 100%; min-width: 0; white-space: normal; overflow-wrap: break-word;
  }
}

/* ⚠️ O painel de filtros do `card_filter.js` (`.fcfilter*`, `.cf-host`) mudou pra
   `css/tabela_rica.css` em 16/09/2026. */

/* ── .form-grid: o filho tem que caber na coluna ───────────────────────────
   Item de GRID nasce com `min-width:auto` — não encolhe abaixo do próprio
   min-content, e então ESTOURA a coluna em vez de se ajustar. Como o
   `.wiz-viewport` do wizard clipa (`overflow-x:hidden`), o que sobra do lado
   direito não fica só feio: some da tela e do alcance do dedo. Foi assim que o
   × de remover parcela ficou 23px fora do iPhone — a linha media 327 numa
   coluna de 263 (Marcos, 18/08/2026: "o botão está fora da largura da tela").
   Os inputs já tinham `min-width:0` global (lá em cima); faltava o do item.
   Mesma regra que `.v-grid > *`/`.v-2col > *` já aplicam. */
.form-grid > * { min-width: 0; }
/* e o botão de remover parcela nunca encolhe até sumir */
.installment-row > button[data-remove-installment] { flex: 0 0 28px; }

/* ══════════════════════════════════════════════════════════════════════════
   A NOTA DE TREINO (DANFE didático) — `partials/_danfe_didatica.html`
   ═══════════════════════════════════════════════════════════════════════════
   O papel é uma reprodução do documento oficial e por isso NÃO É RESPONSIVO
   por dentro: tem 820px fixos e é escalado inteiro pelo `danfe_didatica.js`.
   Deixar as colunas quebrarem no celular devolveria uma lista de campos — e o
   DANFE se reconhece pela FORMA, não pelo conteúdo. Quem precisa ler um campo
   toca nele: o JS amplia e centraliza.

   As cores do papel são literais (preto sobre branco), não tokens: é papel
   impresso, não superfície do app. O que está em volta é que usa os tokens. */

.danfe-viewport { background: #101b26; border: 1px solid var(--line); border-radius: 14px;
  padding: 14px; overflow: auto; max-height: 74vh;
  -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
.danfe-stage { position: relative; margin: 0 auto; }
.danfe { width: 820px; transform-origin: top left; background: #fff; color: #111a22;
  border: 1px solid #2a3742; position: relative;
  font-family: 'Archivo Narrow', 'Arial Narrow', Arial, sans-serif;
  font-size: 11px; line-height: 1.25; font-variant-numeric: tabular-nums;
  box-shadow: 0 14px 40px rgba(0, 0, 0, .3); }
.danfe-marca { position: absolute; inset: 0; display: flex; align-items: center;
  justify-content: center; pointer-events: none; z-index: 5; overflow: hidden; }
.danfe-marca span { transform: rotate(-24deg); font-size: 52px; font-weight: 700;
  letter-spacing: .06em; color: rgba(200, 60, 60, .1); white-space: nowrap;
  border: 5px solid rgba(200, 60, 60, .1); padding: 10px 26px; border-radius: 8px; }

.danfe .drow { display: flex; align-items: stretch; }
.danfe .dbox { border-right: 1px solid #2a3742; border-bottom: 1px solid #2a3742;
  padding: 2px 5px 3px; min-width: 0; display: flex; flex-direction: column;
  justify-content: flex-start; position: relative; }
.danfe .drow > .dbox:last-child { border-right: 0; }
.danfe .dlab { font-size: 8px; line-height: 1.2; letter-spacing: .02em; color: #41505c;
  text-transform: uppercase; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.danfe .dval { font-size: 12px; font-weight: 500; min-height: 14px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.danfe .dval-num .dval, .danfe .dval-num { text-align: right; }
.danfe .dbox--forte .dval { font-weight: 700; font-size: 13px; }
.danfe .dval--forte { font-weight: 700; }
.danfe .dsec { margin: 0; padding: 2px 5px; font-size: 8px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; color: #41505c;
  border-bottom: 1px solid #2a3742; background: #fff; }

.danfe .drow--canhoto .dbox--recibo { padding: 0; }
.danfe .drow--canhoto .dbox--recibo > .dlab { padding: 4px 6px 6px; white-space: normal; font-size: 8.5px; }
.danfe .dcanhoto-linhas { display: flex; border-top: 1px solid #2a3742; }
.danfe .dcanhoto-linhas .dbox { border-bottom: 0; }
.danfe .dbox--nfcanhoto { align-items: center; justify-content: center; gap: 1px;
  text-align: center; font-size: 12px; }
.danfe-serrilha { border-top: 2px dashed #8b98a4; height: 0; }

.danfe .dbox--emit { padding: 3px 6px; }
.danfe .dbox--emit > .dlab { white-space: normal; font-weight: 600; font-size: 9px;
  color: #111a22; margin-bottom: 4px; }
.danfe .demit { display: flex; gap: 10px; align-items: flex-start; }
.danfe .demit-logo { flex: 0 0 116px; padding-top: 2px; }
.danfe .demit-logo strong { display: block; font-size: 19px; font-weight: 700;
  letter-spacing: -.01em; line-height: 1; }
.danfe .demit-logo small { display: block; font-size: 7.5px; letter-spacing: .18em;
  color: #41505c; margin-top: 2px; }
.danfe .demit-end { font-size: 10px; line-height: 1.5; color: #1d2a35; }
.danfe .dbox--danfe { align-items: center; text-align: center; padding: 4px 6px; gap: 2px; }
.danfe .ddanfe-titulo { font-size: 22px; font-weight: 700; letter-spacing: .02em; line-height: 1; }
.danfe .ddanfe-sub { font-size: 9px; color: #41505c; line-height: 1.3; }
.danfe .ddanfe-tipo { display: flex; gap: 6px; align-items: center; justify-content: center;
  margin-top: 2px; padding: 2px 4px; position: relative; }
.danfe .ddanfe-tipo-txt { font-size: 9px; text-align: left; line-height: 1.35; }
.danfe .ddanfe-tipo-cx { width: 17px; height: 17px; border: 1px solid #2a3742; display: flex;
  align-items: center; justify-content: center; font-size: 11px; font-weight: 700; }
.danfe .ddanfe-num { margin-top: 2px; font-size: 13px; font-weight: 700; line-height: 1.25;
  padding: 2px 6px; position: relative; }
.danfe .ddanfe-num small { display: block; font-size: 8px; font-weight: 400; color: #41505c; }
.danfe .dbox--chave { padding: 0; }
.danfe .dbarcode { padding: 5px 6px 2px; border-bottom: 1px solid #2a3742; position: relative; }
.danfe .dbarcode svg { display: block; width: 100%; height: 38px; fill: #0b1218; }
.danfe .dbarcode-num { display: block; font-size: 7px; letter-spacing: .02em; color: #41505c;
  text-align: center; margin-top: 1px; }
.danfe .dbox--flat { border-right: 0; border-bottom: 1px solid #2a3742; }
.danfe .dbox--consulta { border-bottom: 0; justify-content: center; }
.danfe .dval--chave { font-size: 12.5px; font-weight: 600; text-align: center; }
.danfe .dval--centro { text-align: center; font-size: 9px; white-space: normal; line-height: 1.35; }
.danfe .dfrete-linha { display: flex; gap: 6px; align-items: center; }
.danfe .dfrete-txt { font-size: 8px; line-height: 1.35; }

.danfe .dprod { width: 100%; border-collapse: collapse; position: relative; }
.danfe .dprod th { font-size: 7.5px; font-weight: 600; letter-spacing: .02em; color: #41505c;
  text-transform: uppercase; border: 1px solid #2a3742; border-top: 0; padding: 2px 3px;
  vertical-align: middle; line-height: 1.15; position: relative; }
.danfe .dprod td { border: 1px solid #2a3742; padding: 3px; font-size: 10.5px;
  vertical-align: top; text-align: center; }
.danfe .dprod .dprod-desc { text-align: left; line-height: 1.3; }
.danfe .dprod .dprod-desc small { font-size: 9px; color: #41505c; }
.danfe .dprod .dval-num { text-align: right; }
.danfe .dprod-vazio td { height: 96px; border-top: 0; }
.danfe .dprod th:first-child, .danfe .dprod td:first-child { border-left: 0; }
.danfe .dprod th:last-child, .danfe .dprod td:last-child { border-right: 0; }

.danfe .drow--rodape .dbox { min-height: 150px; }
.danfe .dadic { font-size: 9.5px; line-height: 1.45; margin-top: 2px; }
.danfe-rodape { padding: 3px 6px; font-size: 8px; color: #41505c; letter-spacing: .02em; }

/* ── o que torna a nota anotável ─────────────────────────────────────────── */
.danfe [data-nf] { cursor: pointer; position: relative; }
.danfe [data-nf]:hover { background: rgba(240, 173, 57, .1); }
.danfe [data-nf]:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
.danfe [data-nf].is-alvo { background: rgba(240, 173, 57, .3);
  box-shadow: inset 0 0 0 2px #e08c0b; z-index: 4; }
.danfe .dpin { position: absolute; top: 0; left: 0; z-index: 6; display: none;
  min-width: 15px; height: 15px; padding: 0 3px; border-radius: 0 0 6px 0;
  background: var(--primary); color: #fff; font-family: inherit; font-size: 9px;
  font-weight: 700; font-style: normal; line-height: 15px; text-align: center;
  pointer-events: none; }
.danfe.mostra-legenda .dpin { display: block; }

/* ── o painel que explica o campo tocado ─────────────────────────────────── */
.nf-painel { position: sticky; bottom: 0; z-index: 25; margin-top: 14px;
  background: var(--panel-solid); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 14px 16px 16px; box-shadow: 0 -10px 30px rgba(6, 14, 22, .1); }
.nf-painel[hidden] { display: none; }
.nf-painel-topo { display: flex; gap: 10px; align-items: baseline; justify-content: space-between; }
.nf-painel-n { font-size: .72rem; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--primary); }
.nf-painel h2 { font-size: 1.2rem; margin: 2px 0 6px; letter-spacing: -.01em; }
.nf-painel p { font-size: 1rem; line-height: 1.6; margin: 0; color: var(--text); max-width: 62ch; }
.nf-painel-nav { display: flex; gap: 8px; margin-top: 12px; align-items: center; }

.nf-indice { display: grid; gap: 10px; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  padding: 0; margin: 16px 0 0; list-style: none; }
.nf-indice li { background: var(--panel-solid); border: 1px solid var(--line);
  border-radius: var(--radius-sm); padding: 12px 14px; display: grid;
  grid-template-columns: 26px 1fr; gap: 4px 10px; cursor: pointer; }
.nf-indice li:hover { border-color: var(--primary); }
.nf-indice .n { grid-row: span 2; font-size: .78rem; font-weight: 700; color: #fff;
  background: var(--primary); border-radius: 7px; height: 24px; display: flex;
  align-items: center; justify-content: center; }
.nf-indice h3 { margin: 0; font-size: .95rem; font-weight: 600; }
.nf-indice p { margin: 0; font-size: .92rem; line-height: 1.5; color: var(--text-soft); }

@media (max-width: 680px) {
  .danfe-viewport { padding: 8px; max-height: 62vh; }
  .nf-painel { padding: 12px 13px 14px; }
  /* Com o professor em cena o balão mora neste canto: o painel larga o rodapé
     e volta pro fluxo, senão os dois disputam o mesmo pedaço de tela. */
  html.vtutor-on .nf-painel { position: static; box-shadow: var(--shadow); }
}
.nf-barra { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 12px; }
.nf-barra .nf-conta { margin-left: auto; font-size: .8rem; color: var(--text-soft); }
.nf-btn { min-height: 38px; padding: 6px 14px; font-size: .85rem; }
.nf-barra .btn[aria-pressed="true"] { background: var(--warning); border-color: var(--warning); color: #231703; }
.nf-aviso { display: flex; gap: 10px; align-items: flex-start; border-radius: 14px; padding: 12px 14px;
  background: rgba(240, 173, 57, .1); border: 1px solid rgba(240, 173, 57, .5); color: #4a3608;
  font-size: .86rem; line-height: 1.5; }

/* ── Laboratório de cobrança bancária (partials/_bank_lab.html) ─────────────
   Mesma tela pra qualquer banco: diagnóstico, candidatas, dry-run, liquidados
   e criação da CR do piloto. Mobile-first — no celular vira uma coluna e as
   tabelas viram cards pelo kit rico. */
.bank-lab .lab-abas { display: flex; gap: 6px; background: #fff; border: 1px solid var(--line);
  border-radius: 14px; padding: 5px; overflow-x: auto; margin-bottom: 18px; }
.bank-lab .lab-abas button { flex: 1 0 auto; border: 1px solid transparent; background: transparent;
  color: var(--text-muted, #627385); border-radius: 10px; padding: 10px 14px; font-weight: 700;
  font-size: 13.5px; cursor: pointer; white-space: nowrap; min-height: 40px; }
.bank-lab .lab-abas button[aria-selected="true"] { background: var(--brand-grad); color: #fff;
  box-shadow: 0 6px 16px rgba(17,173,180,.22); }
.bank-lab .lab-barra { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end; margin-bottom: 14px; }
.bank-lab .lab-campo { display: grid; gap: 6px; font-size: 12.5px; font-weight: 600;
  color: var(--text-soft); min-width: 0; }
.bank-lab .lab-campo input, .bank-lab .lab-campo select { height: 40px; max-width: 220px; }
.bank-lab .lab-hint { font-size: 12.5px; color: var(--text-soft); align-self: center; }
.bank-lab .lab-vazio { color: var(--text-soft); font-size: 13.5px; text-align: center; padding: 22px 12px; }
.bank-lab .lab-sub { display: block; color: var(--text-soft); font-size: 12px; }
.bank-lab .lab-num { text-align: right; font-variant-numeric: tabular-nums; }

.bank-lab .lab-diag { display: grid; grid-template-columns: repeat(auto-fit, minmax(232px, 1fr)); gap: 12px; }
.bank-lab .lab-diag-item { border: 1px solid var(--line); border-radius: 14px; padding: 14px;
  background: #fcfdff; display: flex; gap: 12px; align-items: flex-start; }
.bank-lab .lab-ponto { width: 10px; height: 10px; border-radius: 50%; margin-top: 6px; flex: none;
  background: #b9c4d1; }
.bank-lab .lab-diag-item[data-estado="ok"] .lab-ponto { background: #2f9e5e; box-shadow: 0 0 0 4px rgba(47,158,94,.14); }
.bank-lab .lab-diag-item[data-estado="atencao"] .lab-ponto { background: var(--warning); box-shadow: 0 0 0 4px rgba(240,173,57,.16); }
.bank-lab .lab-diag-item[data-estado="erro"] .lab-ponto { background: var(--danger); box-shadow: 0 0 0 4px rgba(227,82,91,.16); }
.bank-lab .lab-diag-item h4 { margin: 0 0 3px; font-size: 12px; text-transform: uppercase;
  letter-spacing: .06em; color: #7b8b9d; }
.bank-lab .lab-diag-valor { font-weight: 700; font-size: 15px; }
.bank-lab .lab-diag-detalhe { font-size: 12.5px; color: var(--text-soft); margin-top: 3px; }

.bank-lab .lab-pill { font-size: 11.5px; font-weight: 700; padding: 3px 9px; border-radius: 999px; white-space: nowrap; }
.bank-lab .lab-pill-ok { background: rgba(47,158,94,.13); color: #237247; }
.bank-lab .lab-pill-bad { background: rgba(227,82,91,.14); color: #a8323b; }
.bank-lab .lab-motivo { font-size: 12px; color: #a8323b; margin-top: 3px; }

.bank-lab .lab-resumo { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 12px; margin-bottom: 14px; }
.bank-lab .lab-resumo > div { border: 1px solid var(--line); border-radius: 12px; padding: 12px; background: #fcfdff; }
.bank-lab .lab-resumo span { display: block; font-size: 11.5px; text-transform: uppercase;
  letter-spacing: .06em; color: #7b8b9d; margin-bottom: 3px; }
.bank-lab .lab-resumo b { font-size: 14px; font-variant-numeric: tabular-nums; word-break: break-word; }
.bank-lab .lab-busca-campo { max-width: 280px; height: 38px; margin-bottom: 10px; }
.bank-lab .lab-campos { display: grid; grid-template-columns: repeat(auto-fill, minmax(268px, 1fr));
  gap: 0 18px; border: 1px solid var(--line); border-radius: 14px; background: #fcfdff;
  padding: 12px 16px; max-height: 340px; overflow: auto; }
.bank-lab .lab-campos p { display: flex; justify-content: space-between; gap: 12px; margin: 0;
  padding: 5px 0; border-bottom: 1px dotted #e8eef5; font-family: ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 12.5px; }
.bank-lab .lab-campos p b { font-weight: 600; color: #4a5b6d; }
.bank-lab .lab-campos p i { font-style: normal; color: var(--text); font-weight: 600;
  font-variant-numeric: tabular-nums; word-break: break-all; text-align: right; }
.bank-lab .lab-campos p.vazio i { color: #b0bcc9; }
.bank-lab .lab-campos p.destaque { background: rgba(143,203,58,.12); border-radius: 6px; padding-inline: 6px; }

.bank-lab .lab-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
  gap: 14px; align-items: start; }
.bank-lab .lab-form .lab-form-full { grid-column: 1 / -1; }
.bank-lab .lab-alerta { border-left: 4px solid var(--warning); background: #fffdf6; border-radius: 12px;
  padding: 12px 14px; font-size: 13.5px; margin: 14px 0; }
.bank-lab .lab-alerta-erro { border-left-color: var(--danger); background: #fff6f6; }
.bank-lab .btn.is-busy { opacity: .6; cursor: progress; }

@media (max-width: 680px) {
  .bank-lab .lab-campo input, .bank-lab .lab-campo select { max-width: none; width: 100%; }
  .bank-lab .lab-barra { gap: 8px; }
  .bank-lab .lab-barra > .btn { width: 100%; }
  .bank-lab .lab-campos { max-height: none; }
}

/* ── Aprovações (fila + decisão) ────────────────────────────────────────────
   A tela onde alguém autoriza dinheiro a sair. O visual carrega peso de
   propósito: o alerta de irreversibilidade é vermelho e vem ANTES dos campos. */
.aprovacoes .apr-fila { display: grid; gap: 12px; }
.aprovacoes .apr-pedido { border: 1px solid var(--line); border-radius: 16px; background: #fcfdff;
  padding: 16px; display: grid; grid-template-columns: 1fr auto; gap: 14px; align-items: start;
  text-decoration: none; color: inherit; transition: .15s ease; }
.aprovacoes .apr-pedido:hover { border-color: #bfe6e8; background: #fbfeff; }
.aprovacoes .apr-pedido.urgente { border-left: 4px solid var(--warning); }
/* Pedido que morreu e espera correção: vermelho na borda, não no card inteiro —
   é trabalho a fazer, não alarme. */
.aprovacoes .apr-pedido.apr-morto { border-left: 4px solid var(--danger); cursor: default; }
.aprovacoes .apr-morto .apr-lado { display: grid; gap: 6px; justify-items: end; }
@media (max-width: 680px) { .aprovacoes .apr-morto .apr-lado { justify-items: start; } }
.aprovacoes .apr-pedido h4 { margin: 0 0 4px; font-size: 16px; display: flex; gap: 8px;
  align-items: center; flex-wrap: wrap; }
.aprovacoes .apr-quem { font-size: 13px; color: var(--text-soft); }
.aprovacoes .apr-lado { text-align: right; }
.aprovacoes .apr-valor { font-size: 22px; font-weight: 800; font-variant-numeric: tabular-nums; white-space: nowrap; }
.aprovacoes .apr-prazo { font-size: 12px; color: #8a5b06; margin-top: 2px; }
.aprovacoes .apr-vazio { color: var(--text-soft); font-size: 13.5px; padding: 18px 0; }
.aprovacoes .apr-num { text-align: right; font-variant-numeric: tabular-nums; }

.aprovacoes .apr-pill { font-size: 11.5px; font-weight: 700; padding: 3px 9px; border-radius: 999px;
  white-space: nowrap; display: inline-block; }
.aprovacoes .apr-tipo { background: rgba(17,173,180,.12); color: #0e7f85; }
.aprovacoes .apr-neutro, .aprovacoes .apr-expirado { background: #eef2f7; color: #5d6d7e; }
.aprovacoes .apr-pendente { background: rgba(240,173,57,.18); color: #8a5b06; }
.aprovacoes .apr-executado, .aprovacoes .apr-aprovado { background: rgba(47,158,94,.13); color: #237247; }
.aprovacoes .apr-recusado, .aprovacoes .apr-falhou { background: rgba(227,82,91,.14); color: #a8323b; }

.aprovacoes .apr-grade { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 12px; margin: 16px 0; }
.aprovacoes .apr-grade > div { border: 1px solid var(--line); border-radius: 12px; padding: 12px; background: #fcfdff; }
.aprovacoes .apr-grade span { display: block; font-size: 11.5px; text-transform: uppercase;
  letter-spacing: .06em; color: #7b8b9d; margin-bottom: 3px; }
.aprovacoes .apr-grade b { font-size: 15px; font-variant-numeric: tabular-nums; word-break: break-word; }
.aprovacoes .apr-motivo { border-left: 3px solid var(--line); padding-left: 12px; color: var(--text-soft);
  font-size: 13.5px; margin: 0; }

/* A ficha do favorecido escolhido no cadastro. Nome e documento deixaram de ser
   campos de texto livre — mas quem vai pedir o pagamento precisa LER os dois
   antes de mandar, e o documento é o que faz o banco conferir o dono da chave. */
.aprovacoes .apr-ficha { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px; border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px;
  background: var(--panel-muted); }
.aprovacoes .apr-ficha span { display: block; font-size: 11px; text-transform: uppercase;
  letter-spacing: .06em; color: #7b8b9d; margin-bottom: 2px; }
.aprovacoes .apr-ficha b { font-size: 14px; font-variant-numeric: tabular-nums; word-break: break-word; }

.aprovacoes .apr-alerta { border-left: 4px solid var(--danger); background: #fff6f6; border-radius: 12px;
  padding: 13px 15px; font-size: 13.5px; margin: 0 0 16px; }
.aprovacoes .apr-alerta b { display: block; margin-bottom: 3px; }
.aprovacoes .apr-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 14px; }
.aprovacoes .apr-form label { display: grid; gap: 6px; font-size: 12.5px; font-weight: 600; color: var(--text-soft); }
.aprovacoes .apr-form .apr-full { grid-column: 1 / -1; }

/* ── Assinar é uma SEQUÊNCIA, e a tela lê como sequência ───────────────────
   ⚠️ Isto era `.apr-form`, um grid `auto-fit minmax(230px)`: em tela larga os
   dois fatores caíam LADO A LADO, e "1 —" ficava à esquerda de "2 —" como se
   fossem alternativas. Uma coluna só, no celular e no computador — a numeração
   vem do `<ol>`, não de texto digitado no rótulo (que dessincroniza quando um
   passo some, e o passo do PIN some pra quem tem biometria). */
.aprovacoes .apr-passos { list-style: none; counter-reset: passo; margin: 0; padding: 0;
  display: grid; grid-template-columns: 1fr; gap: 18px; }
.aprovacoes .apr-passo { counter-increment: passo; position: relative;
  padding-left: 40px; min-width: 0; }
.aprovacoes .apr-passo::before { content: counter(passo); position: absolute; left: 0; top: 0;
  width: 27px; height: 27px; border-radius: 50%; background: var(--brand-grad); color: #fff;
  font-size: 13px; font-weight: 800; display: grid; place-items: center; }
.aprovacoes .apr-passo::after { content: ""; position: absolute; left: 13px; top: 31px; bottom: -18px;
  width: 2px; background: var(--line); }
.aprovacoes .apr-passo:last-child::after { display: none; }
.aprovacoes .apr-passo > label,
.aprovacoes .apr-codigo { display: grid; gap: 7px; font-size: 12.5px; font-weight: 600;
  color: var(--text-soft); }
.aprovacoes .apr-codigo > b, .aprovacoes .apr-passo > label { font-size: 13px; color: var(--text); }
.aprovacoes .apr-opcional { font-weight: 500; color: var(--text-soft); }
.aprovacoes .apr-codigo .btn { justify-self: start; }
.aprovacoes .apr-codigo [data-apr-codigo-campo] { display: grid; gap: 6px; }
.aprovacoes .apr-codigo input { letter-spacing: .3em; font-weight: 700; text-align: center;
  font-size: 19px; max-width: 190px; }
/* O reenvio DERRUBA o código que a pessoa tem na mão — ele não pode competir
   em peso com o campo onde ela vai digitar. */
.aprovacoes .apr-reenviar { font-size: 12.5px; padding: 6px 12px; }

@media (max-width: 680px) {
  .aprovacoes .apr-codigo input { max-width: none; }
  .aprovacoes .apr-codigo .btn { justify-self: stretch; }
}
.aprovacoes .apr-hint { font-size: 12px; color: var(--text-soft); font-weight: 500; }
.aprovacoes .apr-hint.ok { color: #237247; }
.aprovacoes .apr-barra { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 18px; align-items: center; }

/* ⚠️ **O PASSO DE ASSINAR DEIXOU DE SER UM `<ol>` em 01/09/2026.** *"Nem deve
   ter essa divisão em tópico 1 e 2; esse tópico 1 está ocupando um espaço
   enorme sem exigir nenhuma ação"* (Marcos). O item 1 era um parágrafo de cinco
   linhas dizendo que a biometria vem DEPOIS — o passo mais visível da tela era
   o que não acontece nela. Hoje o passo mostra só o que se preenche ali; a
   biometria é uma NOTA de uma linha. */
.aprovacoes .apr-campo { display: grid; gap: 7px; font-size: 13px; font-weight: 600;
  color: var(--text); margin: 0 0 14px; }
/* ⚠️ O tracking largo é dos CÓDIGOS de 6 dígitos — ele existe pra a pessoa
   conferir dígito a dígito o que o autenticador mostrou. No PIN ele estraga
   até o texto de ajuda do campo ("o P I N q u e v o c ê d e f i n i u"), que é
   frase, não número. */
.aprovacoes .apr-campo input[data-apr-codigo],
.aprovacoes .apr-campo input[data-apr-totp] { letter-spacing: .3em; font-weight: 700;
  text-align: center; font-size: 19px; max-width: 190px; }
.aprovacoes .apr-campo input[data-apr-pin] { font-size: 17px; font-weight: 700; max-width: 260px; }
@media (max-width: 680px) { .aprovacoes .apr-campo input { max-width: none; } }
.aprovacoes .apr-nota-bio { display: flex; gap: 8px; align-items: flex-start; flex-wrap: wrap;
  margin: 0 0 14px; font-size: 12.5px; line-height: 1.4; color: var(--text-soft); }
.aprovacoes .apr-nota-bio .ic { flex: 0 0 auto; color: #17794a; }

/* ⚠️ **APROVAR EM CIMA, RECUSAR EMBAIXO, UM POR LINHA.** Lado a lado num
   celular os dois ficam do mesmo tamanho e a poucos pixels um do outro, na tela
   que move dinheiro. E a Observação vem DEPOIS dos dois — *"observação deve vir
   por último, por ser um passo opcional"* (Marcos, 01/09/2026): ela abria o
   painel e empurrava a ação pra baixo. */
.aprovacoes .apr-barra-decidir { display: grid; gap: 10px; margin-top: 0; }
.aprovacoes .apr-barra-decidir .btn { width: 100%; }
.aprovacoes .apr-decidir-wiz .apr-obs { margin-top: 18px; }

/* A coluna "Desfecho" de "Seus pedidos" — o que sobrou da tela de detalhe. */
.apr-desfecho { display: inline-block; font-size: .78rem; font-weight: 700; }
.apr-desfecho.is-ok { color: #17794a; }
.apr-desfecho.is-falha { color: #a8323b; }
/* ⚠️ Cor própria de propósito: em verde (o "fim") a pessoa lê como pago e não
   vai autorizar o que está preso no painel do provedor. */
.apr-desfecho.is-espera { color: #b45309; }
/* A frase do provedor — é ela que diz a QUEM cabe destravar o pagamento. */
.apr-espera { color: #92400e; font-size: .74rem; }
/* A linha que precisa de trabalho se distingue DENTRO da tabela — era uma lista
   artesanal à parte, com os mesmos registros. */
.aprovacoes tbody tr.apr-linha-corrigir > td:first-child { box-shadow: inset 3px 0 0 var(--danger, #cf4250); }
.fcdeck-card.apr-linha-corrigir { border-color: #f3b6bb; }

.aprovacoes .apr-trilha { border-left: 2px solid var(--line); margin-left: 10px; padding-left: 20px;
  display: grid; gap: 18px; }
.aprovacoes .apr-trilha .item { position: relative; }
.aprovacoes .apr-trilha .item::before { content: ""; position: absolute; left: -27px; top: 4px;
  width: 12px; height: 12px; border-radius: 50%; background: #fff; border: 2px solid var(--primary); }
.aprovacoes .apr-trilha .item.fim::before { background: #2f9e5e; border-color: #2f9e5e; }
.aprovacoes .apr-trilha .item.falha::before { background: var(--danger); border-color: var(--danger); }
.aprovacoes .apr-trilha h5 { margin: 0 0 3px; font-size: 14.5px; }
.aprovacoes .apr-trilha .meta { font-size: 12.5px; color: var(--text-soft); }
.aprovacoes .apr-trilha code { font-family: ui-monospace, 'SF Mono', Menlo, monospace; font-size: 12px;
  background: #f1f5f9; padding: 2px 7px; border-radius: 6px; word-break: break-all; }
.aprovacoes .apr-erro { color: #a8323b; }

@media (max-width: 680px) {
  .aprovacoes .apr-pedido { grid-template-columns: 1fr; }
  .aprovacoes .apr-lado { text-align: left; }
  .aprovacoes .apr-barra > .btn { width: 100%; }
  .aprovacoes .apr-codigo-linha { flex-direction: column; }
}

/* ⚠️ `.apr-form` é grid, e `display:grid` VENCE o atributo `hidden` (que é só
   `display:none` da folha do navegador). Sem isto, o bloco de agência/conta do
   pedido de PIX aparece sempre — inclusive quando a chave é CPF, pedindo seis
   campos que não têm nada a ver com o caminho escolhido. É a mesma pegadinha
   que já mordeu o painel do Suporte. */
.aprovacoes [hidden] { display: none !important; }

/* ════════════ ASSINATURA DE PAGAMENTO ═══════════════════════════════════
   Minha assinatura (/minha-assinatura) + o bloco de biometria na tela de
   aprovar. Mobile-first: tudo nasce em 1 coluna e só ganha colunas em tela
   larga (ver os guardrails no topo do arquivo). */
.aprovacoes .apr-assinar { display: grid; gap: 6px; border: 1px dashed var(--line);
  border-radius: 12px; padding: 12px 14px; background: var(--panel-muted); }
.aprovacoes .apr-assinar b { font-size: 12.5px; color: var(--text-soft); }
.aprovacoes .apr-hint.ok, .asg .asg-status.ok { color: #17794a; }

/* ⚠️ As regras `.asg` (a tela Minha assinatura) SAÍRAM daqui em 31/08/2026:
   elas viraram `static/css/assinatura.css`, porque a MESMA tela passou a ser
   servida pelo HUB — que não carrega este arquivo. Não traga de volta. */
/* Controle dual: o selo de quórum na tela do pedido. Âmbar, não vermelho — não
   é erro, é "ainda falta gente". */
.aprovacoes .apr-pill.apr-dual { background: #fdf3e0; color: #8a5a08; }
.aprovacoes .apr-alerta.apr-morno { border-left-color: var(--warning); background: #fffaf0; }

/* ════════════ LOTE DE PAGAMENTO ═════════════════════════════════════════
   ⚠️ Escopo `.aprovacoes`, NÃO `.lote`: a barra "Assinar e pagar" e o painel
   de progresso passaram a viver TAMBÉM na fila (a lista virou a mesma das
   duas telas). Preso em `.lote`, o rodapé fixo aparecia sem estilo nenhum na
   tela inicial de Aprovações — que é justamente a que se abre no celular. */
.aprovacoes .lote-motivo { font-size: 11.5px; color: var(--text-soft); margin-top: 2px; }
.aprovacoes .apr-pill.apr-urgente { background: #fdeced; color: #a8323b; margin-left: 6px; }

/* Barra de seleção: fixa no rodapé, como a do Fechamento. Ela some quando nada
   está marcado — barra vazia é ruído no celular, onde a tela já é pequena. */
.aprovacoes .lote-barra {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 12px 18px; background: var(--panel-solid);
  border-top: 1px solid var(--line); box-shadow: 0 -8px 28px rgba(5, 14, 24, .12);
}
@media (min-width: 900px) { .aprovacoes .lote-barra { left: var(--sidebar-width); } }
/* ⚠️ O widget de suporte (#supw) é fixo no canto: 52px + 18px de margem, com
   z-index 10040. Sem esta folga ele fica POR CIMA do botão que assina o lote —
   o único botão da tela que tira dinheiro, cortado ao meio. Medido, não
   chutado. */
.aprovacoes .lote-barra { padding-right: 88px; }
.aprovacoes .lote-barra-info { display: flex; flex-direction: column; min-width: 0; }
.aprovacoes .lote-barra-info b { font-size: 14px; }
.aprovacoes .lote-barra-info span { font-size: 18px; font-weight: 700;
  font-variant-numeric: tabular-nums; }
.aprovacoes .lote-barra > .btn { margin-left: auto; }
@media (max-width: 680px) {
  .aprovacoes .lote-barra > .btn { width: 100%; margin-left: 0; }
}

.aprovacoes .lote-placar { display: grid; gap: 12px; grid-template-columns: repeat(3, 1fr);
  margin-bottom: 14px; }
.aprovacoes .lote-placar div { border: 1px solid var(--line); border-radius: 14px;
  padding: 12px 14px; min-width: 0; }
.aprovacoes .lote-placar span { display: block; font-size: 11px; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-soft); }
.aprovacoes .lote-placar b { font-size: 22px; font-variant-numeric: tabular-nums; }

.aprovacoes .lote-linhas { display: grid; gap: 8px; }
.aprovacoes .lote-linha { display: flex; justify-content: space-between; gap: 12px;
  flex-wrap: wrap; border-left: 3px solid var(--line); padding: 9px 12px;
  background: var(--panel-muted); border-radius: 10px; font-size: 13.5px; min-width: 0; }
.aprovacoes .lote-linha span { color: var(--text-soft); font-size: 12.5px; word-break: break-word; }
.aprovacoes .lote-linha.ok { border-left-color: var(--accent); }
.aprovacoes .lote-linha.processando { border-left-color: var(--warning); }
.aprovacoes .lote-linha.falha { border-left-color: var(--danger); }
.aprovacoes .lote-linha.falha span { color: #a8323b; }

/* Espaço pra barra fixa não cobrir a última linha da tabela.
   ⚠️ Só onde a barra EXISTE (`tem-barra-lote`), não em `.aprovacoes` inteiro:
   a tela de detalhe não tem rodapé fixo e ficaria com 96px de vazio no fim. */
.aprovacoes.tem-barra-lote { padding-bottom: 96px; }

/* ════════════ COMPROVANTE DA BELLY (anexo do pedido de pagamento) ═════════ */
.apr-anexos { margin-top: 14px; border-top: 1px solid var(--border); padding-top: 12px; }
.apr-anexos h4 { margin: 0 0 8px; font-size: 13px; text-transform: uppercase;
                 letter-spacing: .04em; color: var(--muted); }
.apr-anexos .apr-foto { display: block; max-width: 340px; }
.apr-anexos .apr-foto img { width: 100%; height: auto; border-radius: 10px;
                            border: 1px solid var(--border); display: block; }
.apr-anexos .apr-fala { margin: 0 0 10px; padding: 10px 12px; border: 0;
                        border-left: 3px solid var(--brand); border-radius: 8px;
                        background: rgba(255,255,255,.04); }
.apr-anexos .apr-fala > span { font-size: 12px; color: var(--muted); }
.apr-anexos .apr-fala p { margin: 4px 0 8px; font-size: 15px; line-height: 1.45; }
.apr-anexos .apr-fala audio { width: 100%; max-width: 320px; }
.apr-anexos .apr-legenda { margin: 6px 0 0; font-size: 13px; color: var(--muted); }
@media (max-width: 680px) { .apr-anexos .apr-foto { max-width: 100%; } }

/* ═══════════ RECEPÇÃO DO ALMOXARIFADO — Vitrine (prateleiras + cards) ═══════ */
.almox-prateleira .section-head h3 { display: flex; align-items: center; gap: 8px; }
.almox-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
              gap: 14px; margin-top: 6px; padding-top: 14px;
              border-top: 3px solid transparent; border-image: var(--brand-grad) 1; }
.almox-card { border: 1px solid var(--line); border-radius: var(--radius-sm);
              padding: 14px; background: var(--panel-muted); display: flex;
              flex-direction: column; gap: 8px; }
.almox-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.almox-card-head strong { font-size: 14px; line-height: 1.3; }
.almox-qtd { font-weight: 700; font-size: 15px; padding: 2px 10px; border-radius: 999px;
             background: rgba(143,203,58,.16); color: #4c7a12; white-space: nowrap; }
.almox-qtd-zero { background: rgba(227,82,91,.14); color: var(--danger); }
.almox-attrs { display: flex; flex-wrap: wrap; gap: 6px; }
.almox-card .chip { display: inline-flex; align-items: center; gap:5px; padding: 2px 9px;
                     background: #eef2f7; border-radius: 999px; font-size: .72rem;
                     color: #334155; font-weight: 600; }
.almox-card-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.almox-unidades { font-size: 13px; }
.almox-unidades summary { cursor: pointer; color: var(--text-soft); }
.almox-unidades ul { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.almox-unidades li { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.almox-unidades code { font-size: 12px; background: #eef2f7; padding: 1px 6px; border-radius: 6px; }

.almox-modal-overlay { position: fixed; inset: 0; background: rgba(7,16,24,.55);
                        display: flex; align-items: center; justify-content: center; z-index: 1000; }
.almox-modal-box { background: var(--panel-solid); border-radius: var(--radius);
                    padding: 20px; width: min(420px, 92vw); box-shadow: var(--shadow); }

/* ═══════════ RECEPÇÃO DO ALMOXARIFADO — formulário de entrada/tipos ═══════ */
.checkbox-line { display: flex; align-items: center; gap: 8px; font-weight: 500; }
.checkbox-line input { width: auto; }
.almox-attr-row { display: grid; grid-template-columns: 2fr 1fr 1fr 1.4fr auto auto;
                   gap: 8px; align-items: center; margin-bottom: 8px; }
.almox-unidade-row { border: 1px solid var(--line); border-radius: var(--radius-sm);
                      padding: 10px; margin-bottom: 8px; display: grid;
                      grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)) auto;
                      gap: 8px; align-items: end; }
@media (max-width: 680px) {
  .almox-attr-row { grid-template-columns: 1fr 1fr; }
  .almox-unidade-row { grid-template-columns: 1fr 1fr; }
}

/* ═══════════ O HERO DE SALDO ═════════════════════════════════════════════
   ⚠️ AQUI MORAVA O SWITCHER "Banco" × "Banco + Omie" (removido 30/08/2026).
   As telas de saldo renderizavam DUAS leituras e este CSS mostrava a da vez,
   pelo `data-saldo-fonte` do `<html>`. Com o saldo do Omie fora do app, existe
   uma leitura só — e renderizar duas era também deixar o número errado no HTML
   esperando uma regra de CSS pra reaparecer. Saíram junto: `.saldo-fonte`,
   `[data-saldo-v]`, `[data-saldo-so]` e os pares `data-sinal-tudo/banco`.

   A paleta segue o SINAL do único número que existe. Fundo verde com número
   vermelho seria pior que feio: seria uma leitura errada de relance. */
.saldo-hero { padding: 28px 24px; text-align: center; border: none;
              border-radius: 14px; box-shadow: 0 2px 12px rgba(0,0,0,.06);
              --sh-a:#dcfce7; --sh-b:#a7f3d0; --sh-num:#15803d; --sh-txt:#166534;
              background: linear-gradient(135deg, var(--sh-a), var(--sh-b)); }
.saldo-hero.is-neg { --sh-a:#fee2e2; --sh-b:#fecaca; --sh-num:#dc2626; --sh-txt:#991b1b; }
/* ⚠️ "NÃO SEI" NÃO PODE SER VERDE. Sem leitura de banco nenhuma o hero mostra
   R$ 0,00 — e no verde do saldo positivo isso se lê de relance como "está tudo
   certo, só não tem dinheiro agora", que são duas afirmações e nenhuma é
   verdade. Âmbar: o mesmo tom do resto do app pra "confira isto". */
.saldo-hero.is-desconhecido { --sh-a:#fffbeb; --sh-b:#fde68a; --sh-num:#92400e; --sh-txt:#92400e; }
.saldo-hero .saldo-hero-label { font-size: .78rem; letter-spacing: .12em; font-weight: 700;
                                text-transform: uppercase; color: var(--sh-txt); opacity: .85; }
.saldo-hero .saldo-hero-value { font-size: 4.2rem; font-weight: 900; margin-top: 4px;
                                line-height: 1.05; color: var(--sh-num);
                                font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.saldo-hero .saldo-hero-meta { display: flex; gap: 18px; justify-content: center; flex-wrap: wrap;
                               margin-top: 12px; font-size: .82rem; color: var(--sh-txt); opacity: .85; }
/* O Resumo Executivo é a tela de trinta segundos: número um pouco maior. */
.saldo-hero--xl { padding: 32px 24px; }
.saldo-hero--xl .saldo-hero-value { font-size: 4.5rem; }

/* A NOTA DAS CONTAS SEM LEITURA (partials/_sem_leitura.html) — o rodapé que
   impede o total de parecer o dinheiro todo da empresa.

   ⚠️ NÃO É FLEX. Era, e cada trecho inline do aviso (o número, o "conta(s)",
   cada nome) virava um ITEM de flex com quebra própria — o parágrafo saía
   picado em pedaços desalinhados. Aviso que se lê torto é aviso que não se lê,
   e este é justamente o que impede alguém de achar que sumiu dinheiro. */
.saldo-fonte-nota { margin: 10px 0 0; font-size: .78rem; line-height: 1.45;
                    color: var(--text-soft, #6b7d91); max-width: 78ch; }
.saldo-fonte-nota svg { width: 14px; height: 14px; vertical-align: -2px; margin-right: 4px; }
/* Dentro do hero (que centraliza) o aviso precisa se centralizar junto. */
.saldo-hero .saldo-fonte-nota { color: var(--sh-txt); opacity: .9; margin-inline: auto; }

/* ── Seletor de banco do Laboratório bancário (modules/bancos_lab.html) ─────
   O laboratório era um painel dentro da aba de cada banco; virou aba única com
   seletor em 28/08/2026. Cada pastilha diz o nome, o ambiente e o que aquele
   banco sabe fazer — "produção" precisa ser lido ANTES do clique, não depois.
   Mobile-first: no celular a fila rola de lado em vez de espremer. */
.lab-bancos { display: flex; gap: 10px; overflow-x: auto; padding: 2px; margin: 0 -2px;
  -webkit-overflow-scrolling: touch; }
.lab-banco { flex: 0 0 auto; min-width: 148px; text-align: left; cursor: pointer;
  border: 1px solid var(--line); border-radius: 14px; background: #fff; padding: 11px 13px;
  display: grid; gap: 4px; min-height: 44px; }
.lab-banco[aria-selected="true"] { border-color: transparent; background: var(--brand-grad);
  color: #fff; box-shadow: 0 6px 16px rgba(17,173,180,.22); }
.lab-banco-nome { font-weight: 800; font-size: 14px; }
.lab-banco-faz { font-size: 11.5px; opacity: .8; }
.lab-banco[aria-selected="true"] .lab-banco-faz { opacity: .92; }
.lab-selo { font-size: 10px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase;
  padding: 2px 7px; border-radius: 999px; }
.lab-selo--prod { background: rgba(220,38,38,.12); color: #b91c1c; }
.lab-selo--homolog { background: rgba(217,119,6,.14); color: #b45309; }
.lab-selo--off { background: rgba(107,114,128,.14); color: #4b5563; }
/* No cartão escolhido o fundo é o gradiente: os selos precisam de contraste
   próprio, senão o vermelho de "produção" some no ciano. */
.lab-banco[aria-selected="true"] .lab-selo { background: rgba(255,255,255,.22); color: #fff; }
@media (max-width: 680px) {
  .lab-banco { min-width: 132px; }
}

/* Link pro monitor de boletos, no cartão do seletor de bancos.
   ⚠️ Fora do <button> de escolher o banco: <a> dentro de <button> é markup
   inválido, e no celular o toque vira loteria entre trocar de banco e sair da
   tela. */
.lab-telas { margin: 12px 2px 0; font-size: 13px; color: var(--text-soft); }
.lab-telas a { font-weight: 700; color: var(--brand-2, #11adb4); text-decoration: none;
  padding: 2px 0; }
.lab-telas a:hover { text-decoration: underline; }
.lab-telas small { color: var(--text-soft); font-size: 12px; }

/* "Corrigir e reenviar" — o pedido que falhou deixa de ser um beco.
   ⚠️ O aviso fica JUNTO do botão, não num tooltip: a pessoa precisa saber
   ANTES do clique que isto abre um pedido novo, que vai pedir assinatura de
   novo. Descobrir isso depois é descobrir que o pagamento não saiu. */
.apr-acoes-falha { display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
  margin-top: 12px; }
.apr-acoes-falha .lab-hint { flex: 1 1 240px; font-size: 12.5px; }
.apr-refeito { margin-top: 10px; }
.apr-refeito .apr-chip { font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; padding: 2px 8px; border-radius: 999px;
  background: rgba(107,114,128,.14); color: #4b5563; margin-left: 6px; }
.apr-refaz { border-left-color: var(--brand-2, #11adb4); background: #f2fbfc; }

/* O comprovante do pagamento, no detalhe do pedido.
   ⚠️ Separado do e2e de propósito: um é identificador de transação, o outro é
   o documento. Quem precisa provar pro fornecedor precisa do segundo. */
.apr-comprovante { margin-top: 8px; display: flex; gap: 10px; align-items: baseline;
  flex-wrap: wrap; }
.apr-comprovante a { color: var(--brand-2, #11adb4); text-decoration: none; }
.apr-comprovante a:hover { text-decoration: underline; }

/* "Aguardando confirmação" — nem sucesso nem falha.
   ⚠️ Cor própria de propósito: em verde (o "fim") a pessoa lê como pago e não
   vai autorizar o que está preso no painel do provedor. */
.apr-trilha .item.espera .apr-espera { color: #92400e; }
.apr-trilha .item.espera h5 { color: #b45309; }

/* ⚠️ **O VISOR DE ARQUIVO NÃO MORA AQUI — ele injeta o próprio CSS.**
   `file_export.js` está nos TRÊS layouts (silo, portal e hub), e portal e hub
   **não carregam o `app.css`**. Um visor estilizado só no silo seria o mesmo
   defeito que o `.fc-viewtoggle` custou hoje de manhã: componente reusável com
   desenho de uma casa só. Como o visor é inteiramente construído por JS, o
   estilo viaja junto — igual ao `apr_deck.js`. */

/* ════════════ A MOLDURA DO CARD DO FLUXO (o que faltou vir junto) ════════
   ⚠️ **A MUDANÇA DE 29/08/2026 TROUXE O CARD E DEIXOU A MOLDURA PRA TRÁS.**
   O bloco `fcdeck` desceu pra cá, mas o alternador Tabela/Cards, os chips da
   coluna Docs, o modal do Detalhe e os sub-modais dos SEIS LÁPIS continuaram
   dentro de um `<style>` de `main/dashboard_fluxo_caixa.html`.

   Consequência medida na tela das Aprovações (01/09/2026, print do Marcos):
     · **Tabela/Cards saía sem estilo nenhum** — dois botões crus do navegador,
       nada parecidos com os do Fluxo de Caixa, que é de onde o card veio;
     · os lápis abriam modais **sem desenho**, e o Detalhe abria um iframe sem
       moldura por cima da página;
     · os chips de NF/boleto/anexo apareciam como texto solto.

   Regra que vale pra sempre: **se `fluxo_card.js` desenha, o CSS mora aqui.**
   Script global + CSS de uma página só é um card que só funciona numa tela. */
.fc-viewtoggle { display: inline-flex; gap: 4px; margin: 8px 0 2px; background: #f4f6f8; border-radius: 9px; padding: 3px; }
.fc-viewtoggle button { border: none; background: transparent; padding: 5px 11px; border-radius: 7px; font-size: 0.8rem;
  font-weight: 600; color: #475569; cursor: pointer; }
.fc-viewtoggle button.active { background: var(--brand-grad, #11ADB4); color: #fff; }

/* Badge de departamento (rateio) nas listas Recebimentos & Pagamentos */
.fc-badge { display: inline-block; border: 1px solid #e2e8ed; background: #f8fafc; color: #475569; border-radius: 5px;
  padding: 1px 6px; font-size: 0.7rem; line-height: 1.5; max-width: 100%; white-space: normal; word-break: break-word; }
/* Chips lazy da coluna "Docs" (NF / boleto / anexos / produtos) */
.fc-chip { display: inline-flex; align-items: center; gap: 3px; border: 1px solid #d1d9e0; background: #f8fafc;
  color: #334155; border-radius: 999px; padding: 1px 8px; font-size: 0.7rem; line-height: 1.5; cursor: pointer;
  white-space: nowrap; font-weight: 600; }
.fc-chip:hover { background: #eef2f7; }
.fc-chip-nf { border-color: #bfdbfe; background: #eff6ff; color: #1d4ed8; }
.fc-chip-nf:hover { background: #dbeafe; }
.fc-chip-bol { border-color: #fde68a; background: #fffbeb; color: #92400e; }
.fc-chip-bol:hover { background: #fef3c7; }
.fc-chip-ok { border-color: #bbf7d0 !important; background: #f0fdf4 !important; color: #15803d !important; }
.fc-chip-err { border-color: #fecaca !important; background: #fef2f2 !important; color: #b91c1c !important; }
/* Lupa "Detalhe" na linha da tabela (abre o molde do movimento). */
.fc-mov-btn { border: 1px solid #d1d9e0; background: #f8fafc; border-radius: 6px; padding: 2px 7px;
  cursor: pointer; line-height: 1; color: #475569; }
.fc-mov-btn:hover { background: #eef2f7; }

/* O molde do movimento, por cima da página (iframe). */
.fcmov-modal { position: fixed; inset: 0; z-index: 1200; display: flex; align-items: center; justify-content: center; }
.fcmov-modal[hidden] { display: none; }
.fcmov-bd { position: absolute; inset: 0; background: rgba(15,23,42,0.62); }
.fcmov-panel { position: relative; width: min(960px,96vw); height: min(90vh,900px); background: #fff;
  border-radius: 14px; box-shadow: 0 18px 60px rgba(0,0,0,0.35); overflow: hidden; display: flex; flex-direction: column; }
.fcmov-x { position: absolute; top: 8px; right: 10px; z-index: 2; border: none; background: rgba(255,255,255,0.9);
  border-radius: 999px; width: 34px; height: 34px; font-size: 1.1rem; cursor: pointer; box-shadow: 0 1px 6px rgba(0,0,0,0.2); }
.fcmov-frame { border: 0; width: 100%; height: 100%; flex: 1 1 auto; }

/* Sub-modais dos lápis (categoria, projeto, conta, cliente, rateio, produtos). */
.fcsub-x { position: absolute; top: 8px; right: 10px; border: none; background: transparent; font-size: 1.1rem; cursor: pointer; color: #64748b; }
.fcsub-err { background: #fef2f2; color: #b91c1c; border: 1px solid #fecaca; border-radius: 8px; padding: 8px 10px; font-size: 0.8rem; margin: 0 0 8px; }
.fcsub-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; flex-wrap: wrap; }
.fcrat-rows { display: flex; flex-direction: column; gap: 8px; }
.fcrat-row { display: grid; grid-template-columns: 1fr 84px 34px; gap: 8px; align-items: start; }
.fcrat-pct { padding: 7px 8px; border: 1px solid #d1d9e0; border-radius: 8px; font-size: 0.85rem; }
.fcrat-rm { border: 1px solid #fecaca; background: #fee2e2; color: #991b1b; border-radius: 8px; cursor: pointer; font-size: 1rem; }
.fcrat-tools { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.fcrat-soma { font-size: 0.85rem; font-weight: 700; color: #b45309; }
.fcprod-table { width: 100%; border-collapse: collapse; font-size: 0.82rem; }
.fcprod-table th, .fcprod-table td { padding: 6px 8px; border-bottom: 1px solid #eef2f7; text-align: left; }
.fcprod-table th.num, .fcprod-table td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.fcprod-table thead th { border-bottom: 2px solid var(--border); font-size: 0.72rem; text-transform: uppercase; color: #64748b; }

/* ⚠️ O DECK DE CARDS (`.fcdeck-*`, o card do Fluxo) mudou pra `css/deck.css` em
   16/09/2026 — o hub usa o baralho e não carrega este arquivo. */

/* ── PLACAR DO RESUMO DAS APROVAÇÕES ──────────────────────────────────────────
   O primeiro painel do wizard da fila. Três ou quatro números, e cada um muda
   uma decisão diferente: quantos esperam, quanto somam, quantos expiram já, e
   quantos pedidos SEUS voltaram pra corrigir.

   ⚠️ A SOMA está aqui de propósito, ao lado da contagem: catorze pedidos de
   R$ 50 e catorze de R$ 5.000 são filas muito diferentes, e o número de linhas
   sozinho não distingue as duas — quem abre a tela pra decidir prioridade
   precisa dos dois. */
.apr-placar { display:flex; flex-wrap:wrap; gap:10px; margin-top:4px; }
.apr-placar-item { flex:1 1 150px; min-width:0; border:1px solid var(--line,#e2e8ed);
    border-radius:12px; padding:12px 14px; background:#fff; }
.apr-placar-num { display:block; font-size:1.9rem; font-weight:800; line-height:1.1;
    color:#1c3040; font-variant-numeric:tabular-nums; letter-spacing:-.02em; }
.apr-placar-lbl { display:block; font-size:.76rem; color:var(--text-soft,#6b7d91);
    margin-top:2px; }
/* Os dois que pedem AÇÃO se distinguem — sem cor, os quatro números viram um
   bloco só e o urgente passa junto com o resto. */
.apr-placar-item.is-urgente { border-color:#fcd34d; background:#fffbeb; }
.apr-placar-item.is-urgente .apr-placar-num { color:#b45309; }
.apr-placar-item.is-corrigir { border-color:#fecaca; background:#fef2f2; }
.apr-placar-item.is-corrigir .apr-placar-num { color:#b91c1c; }
/* ⚠️ No celular a soma é o número mais longo; deixar os quatro em duas colunas
   quebra "R$ 12.345,67" no meio. Ela ocupa a linha inteira. */
/* ⚠️⚠️ **E A REGRA ACIMA PRODUZIA TRÊS LINHAS, não duas colunas** (01/09/2026).
   `50%` em cada item e `100%` no segundo: com TRÊS itens o 1º fica sozinho
   (o 2º não cabe ao lado), o 2º ocupa a linha, o 3º fica sozinho. *"Um número
   ocupando linhas inteiras"* (Marcos, na aba Fora da fila, onde são exatamente
   três). A faixa abaixo resolve os dois lados: números lado a lado numa moldura
   só, corpo menor pra "R$ 254.466,33" caber, e rolagem lateral quando não
   couber — o que não pode é o placar empurrar a lista pra fora da tela. */
@media (max-width:680px) {
  .apr-placar { flex-wrap:nowrap; overflow-x:auto; -webkit-overflow-scrolling:touch;
    gap:0; border:1px solid var(--line,#e2e8ed); border-radius:12px; background:#fff; }
  .apr-placar-item { flex:1 0 auto; min-width:33%; border:0; border-radius:0;
    padding:10px 12px; background:transparent; }
  .apr-placar-item + .apr-placar-item { border-left:1px solid var(--line,#e2e8ed); }
  .apr-placar-num { font-size:1.15rem; }
  .apr-placar-lbl { font-size:.7rem; }
  /* O destaque dos que pedem ação vira só a COR do número — pintar o fundo de
     uma fatia da faixa faz o item parecer um card solto no meio dela. */
  .apr-placar-item.is-urgente, .apr-placar-item.is-corrigir { background:transparent; }
}

/* ── O BOTÃO DE DICA (`partials/_macros.html::dica`) ────────────────────────
   O texto explicativo de uma tela vive AQUI dentro, não empilhado acima da
   lista. Ver o comentário do macro: a tela abre com o TRABALHO, a explicação
   fica a um toque — visível pra quem chega a primeira vez, fora do caminho de
   quem já sabe. */
.tela-dica { margin:0 0 12px; }
.tela-dica-sum { display:inline-flex; align-items:center; gap:6px; cursor:pointer;
  list-style:none; font-size:.78rem; font-weight:700; color:var(--text-soft,#627385);
  border:1px solid var(--line,#e6ebf0); background:#fff; border-radius:999px;
  padding:6px 13px; min-height:34px; }
.tela-dica-sum::-webkit-details-marker { display:none; }
.tela-dica-sum:hover { background:#f4f8fa; color:var(--text,#13212d); }
.tela-dica[open] .tela-dica-sum { border-bottom-left-radius:0; border-bottom-right-radius:0;
  background:#f3f8f9; color:var(--text,#13212d); }
.tela-dica-corpo { margin-top:-1px; font-size:.82rem; line-height:1.45;
  color:var(--text-soft,#627385); background:#f3f8f9;
  border:1px solid var(--line,#e6ebf0); border-left:3px solid var(--primary,#11ADB4);
  border-radius:0 10px 10px 10px; padding:10px 13px; }

/* O wizard da fila não repete a moldura de card dos painéis internos. */
.apr-wizard .wiz-panel { padding:0; }

/* ── CONFERÊNCIA DO PEDIDO DE PAGAMENTO (painel 4 do wizard) ────────────────
   ⚠️ É a última coisa que a pessoa lê antes de mandar dinheiro pra fila, e por
   isso ela é DESENHADA e não uma lista: o valor grande, o resto em grade e o
   motivo por último, porque é o que a outra pessoa vai ler.
   Mobile-first — a grade colapsa em uma coluna abaixo de 680px. */
.apr-confere { border:1px solid var(--line,#e2e8ed); border-radius:12px;
  padding:16px; background:var(--card,#fff); }
.apr-confere-valor { display:flex; flex-wrap:wrap; align-items:baseline; gap:8px;
  padding-bottom:12px; border-bottom:1px solid var(--line,#e2e8ed); }
.apr-confere-valor span { font-size:.8rem; font-weight:700; letter-spacing:.02em;
  text-transform:uppercase; color:var(--muted,#64748b); }
.apr-confere-valor b { font-size:2rem; font-weight:800; line-height:1.05;
  color:var(--text,#0f172a); }
.apr-confere-grade { display:grid; gap:10px 18px; padding:14px 0;
  grid-template-columns:repeat(auto-fit,minmax(180px,1fr)); }
.apr-confere-grade > div { min-width:0; }
.apr-confere-grade span { display:block; font-size:.72rem; font-weight:700;
  text-transform:uppercase; letter-spacing:.02em; color:var(--muted,#64748b); }
.apr-confere-grade b { display:block; font-size:.95rem; font-weight:600;
  overflow-wrap:anywhere; }
.apr-confere-motivo { padding-top:12px; border-top:1px solid var(--line,#e2e8ed); }
.apr-confere-motivo span { display:block; font-size:.72rem; font-weight:700;
  text-transform:uppercase; letter-spacing:.02em; color:var(--muted,#64748b); }
.apr-confere-motivo b { display:block; margin-top:3px; font-size:1rem;
  font-weight:600; overflow-wrap:anywhere; }
/* ⚠️ A pendência é AMARELA, não vermelha: nada deu errado ainda — falta
   preencher. Vermelho aqui treina a pessoa a ignorar vermelho de verdade. */
.apr-confere-faltas { margin-top:12px; padding:10px 12px; border-radius:9px;
  background:#fff8e6; border:1px solid #f0d79a; color:#7a5a11; font-size:.86rem; }
.apr-falta-link { background:none; border:0; padding:0; cursor:pointer;
  font:inherit; font-weight:800; color:#7a5a11; text-decoration:underline; }
@media (max-width:680px) {
  .apr-confere { padding:13px; }
  .apr-confere-valor b { font-size:1.7rem; }
  .apr-confere-grade { grid-template-columns:1fr; gap:9px; }
}

/* ── CONTRAPROVA DE CONCILIAÇÃO (banco ao vivo × Omie) ──────────────────────
   ⚠️ O NÃO EXPLICADO manda na cor da tela: verde SÓ quando fecha. Pintar de
   verde um "quase fechou" é o que faz alguém parar de procurar.
   Mobile-first: tudo colapsa em uma coluna abaixo de 680px. */
.cp-contas { display:grid; gap:10px;
  grid-template-columns:repeat(auto-fill,minmax(260px,1fr)); }
.cp-conta { display:grid; gap:3px; text-align:left; cursor:pointer;
  border:1px solid var(--line,#e2e8ed); border-radius:11px; padding:12px 14px;
  background:var(--card,#fff); font:inherit; }
.cp-conta:hover { border-color:#9fd4b6; box-shadow:0 4px 14px rgba(0,0,0,.07); }
.cp-conta.is-sempar { border-color:#f0ad39; background:#fffaf0; }
.cp-conta-nome { font-weight:800; font-size:.95rem; overflow-wrap:anywhere; }
.cp-conta-id { font-size:.75rem; color:var(--muted,#64748b); }
.cp-conta-saldo { font-size:1.15rem; font-weight:800; }
.cp-tag { justify-self:start; border-radius:999px; padding:2px 9px;
  font-size:.7rem; font-weight:800; white-space:nowrap; }
.cp-tag.ok     { background:#e8f6ee; color:#17794a; }
.cp-tag.aviso  { background:#fff4de; color:#8a5b00; }
.cp-tag.alerta { background:#fdeaea; color:#a52222; }
.cp-tag.neutro { background:#eef2f6; color:#51606f; }

.cp-det-head { display:flex; flex-wrap:wrap; gap:8px 14px; align-items:center;
  margin-bottom:14px; }
.cp-det-head strong { font-size:1.05rem; }
.cp-erro { border:1px solid #f0c0c0; background:#fdeaea; color:#8a1f1f;
  border-radius:9px; padding:10px 12px; font-size:.88rem; margin:8px 0; }

/* A equação — o produto da ferramenta. */
.cp-eq { border:1px solid #f0ad39; border-radius:12px; overflow:hidden;
  margin-bottom:16px; background:var(--card,#fff); }
.cp-eq.is-ok { border-color:#7ec9a3; }
.cp-eq-topo { padding:14px 16px; background:#fffaf0; display:grid; gap:2px; }
.cp-eq.is-ok .cp-eq-topo { background:#eefaf3; }
.cp-eq-topo span { font-size:.74rem; font-weight:800; text-transform:uppercase;
  letter-spacing:.03em; color:#8a5b00; }
.cp-eq.is-ok .cp-eq-topo span { color:#17794a; }
.cp-eq-topo b { font-size:2rem; font-weight:800; line-height:1.05; color:#7a4a00; }
.cp-eq.is-ok .cp-eq-topo b { color:#146b41; }
.cp-eq-topo small { font-size:.78rem; color:var(--muted,#64748b); }
.cp-eq-conta { padding:10px 16px 14px; }
.cp-eq-conta hr { border:0; border-top:1px dashed var(--line,#e2e8ed); margin:8px 0; }
.cp-eq-linha { display:flex; justify-content:space-between; gap:14px;
  align-items:baseline; padding:4px 0; }
.cp-eq-linha span { display:flex; flex-direction:column; min-width:0;
  font-size:.86rem; font-weight:600; }
.cp-eq-linha small { font-size:.72rem; font-weight:400; color:var(--muted,#64748b); }
.cp-eq-linha b { font-variant-numeric:tabular-nums; white-space:nowrap; }
.cp-lacuna { margin:0; padding:10px 16px 14px; font-size:.82rem;
  color:var(--muted,#64748b); border-top:1px solid var(--line,#e2e8ed); }

.cp-placar { display:flex; flex-wrap:wrap; gap:8px 18px; margin:0 0 12px;
  font-size:.82rem; color:var(--muted,#64748b); }
.cp-placar b { font-size:1.05rem; color:var(--text,#0f172a); }

.cp-sub { margin:22px 0 10px; font-size:.95rem; }
.cp-linhas { display:grid; gap:10px; }
.cp-linha { border:1px solid var(--line,#e2e8ed); border-radius:11px;
  padding:12px 14px; background:var(--card,#fff); }
.cp-linha.is-respondida { border-left:4px solid #7ec9a3; }
.cp-linha.is-omie { background:#fbfcfd; }
.cp-linha-topo { display:flex; flex-wrap:wrap; gap:8px 12px; align-items:center; }
.cp-linha-data { font-size:.8rem; color:var(--muted,#64748b); }
.cp-linha-valor { margin-left:auto; font-size:1.1rem; font-weight:800;
  font-variant-numeric:tabular-nums; color:#146b41; }
.cp-linha-valor.neg { color:#a52222; }
.cp-linha-desc { margin:7px 0 0; font-size:.9rem; overflow-wrap:anywhere; }
.cp-linha-motivo, .cp-linha-par { margin:5px 0 0; font-size:.79rem;
  color:var(--muted,#64748b); }
.cp-cands { margin-top:8px; font-size:.79rem; }
.cp-cands span { font-weight:700; color:var(--muted,#64748b); }
.cp-cands ul { margin:4px 0 0; padding-left:18px; }
/* ⚠️ Cada candidato em UMA linha. É onde a pessoa escolhe entre dois, e dois
   parágrafos de `[PDV] nota=… | cliente=… | departamento=…` são indistinguíveis
   de relance — que é o oposto do que a pergunta precisa. */
.cp-cands li { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.cp-resposta { display:flex; flex-wrap:wrap; gap:8px 10px; align-items:flex-end;
  margin-top:11px; padding-top:11px; border-top:1px dashed var(--line,#e2e8ed); }
.cp-resposta label { display:flex; flex-direction:column; gap:3px; min-width:0;
  font-size:.74rem; font-weight:700; color:var(--muted,#64748b); }
.cp-resposta label:first-child { flex:0 1 260px; }
.cp-resposta label:nth-child(2) { flex:1 1 240px; }
.cp-resposta select, .cp-resposta input { font:inherit; font-size:.86rem;
  font-weight:400; color:var(--text,#0f172a); padding:6px 9px;
  border:1px solid var(--line,#e2e8ed); border-radius:8px; background:#fff;
  min-width:0; width:100%; }
.cp-quem { flex:1 1 100%; font-size:.72rem; color:var(--muted,#64748b); }
@media (max-width:680px) {
  .cp-contas { grid-template-columns:1fr; }
  .cp-eq-topo b { font-size:1.7rem; }
  .cp-eq-linha { flex-wrap:wrap; }
  .cp-resposta label { flex:1 1 100% !important; }
}

/* ── O EXTRATO DE DOIS LADOS (Fase 2, 06/09/2026) ───────────────────────────
   ⚠️ A ESQUERDA É DO BANCO, A DIREITA É NOSSA — e a linha vertical entre elas
   é o desenho da regra. Antes, fato e leitura moravam no mesmo bloco, um
   embaixo do outro, e lidos em sequência viravam uma frase só.
   ⚠️ No CELULAR viram duas faixas empilhadas, com a do banco em cima: a ordem
   é a mesma da leitura (primeiro o que aconteceu, depois o que entendemos), e
   inverter faria a conclusão chegar antes do fato. */
.cp-dois-lados { display:grid; grid-template-columns:1fr 1fr; gap:0; }
.cp-lado { display:grid; gap:6px; align-content:start; padding:2px 14px 2px 0; }
.cp-lado-nosso { padding:2px 0 2px 14px; border-left:1px solid var(--line,#e2e8ed); }
.cp-lado-tit { font-size:.66rem; font-weight:800; text-transform:uppercase;
  letter-spacing:.06em; color:var(--muted,#64748b); display:flex; gap:5px;
  align-items:center; }
.cp-lado-banco .cp-lado-tit { color:#1f4e63; }
.cp-lado-nosso .cp-lado-tit { color:#6b4e9e; }
/* O texto do banco é MONOESPAÇADO de propósito: ele não é prosa nossa, é o
   registro como veio — e a fonte diz isso antes de qualquer rótulo. */
.cp-cru { margin:0; font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:.82rem; line-height:1.45; overflow-wrap:anywhere; }
.cp-nada { margin:0; font-size:.84rem; font-style:italic;
  color:var(--muted,#64748b); }
.cp-lado.is-vazio { opacity:.75; }
.cp-bruto { font-size:.76rem; }
.cp-bruto summary { cursor:pointer; color:var(--muted,#64748b);
  font-weight:700; }
.cp-bruto dl { display:grid; grid-template-columns:auto 1fr; gap:2px 10px;
  margin:6px 0 0; }
.cp-bruto dt { color:var(--muted,#64748b); }
.cp-bruto dd { margin:0; font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  overflow-wrap:anywhere; }
.cp-par { margin:0; display:grid; gap:1px; font-size:.78rem;
  color:var(--muted,#64748b); }
.cp-par b { font-size:.88rem; color:var(--text,#0f172a); overflow-wrap:anywhere; }
.cp-par .cp-dif { color:#8a5b00; font-weight:700; }
/* A observação do Omie: presente, e no seu lugar. Ela é uma linha de máquina no
   PDV (`[PDV] nota=738 | …`) — em duas linhas ela ainda entrega o número da
   nota sem ocupar o card inteiro. */
.cp-par .cp-obs { font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:.72rem; overflow-wrap:anywhere; display:-webkit-box;
  -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.cp-humano { margin:0; font-size:.8rem; color:#17794a; font-weight:700;
  overflow-wrap:anywhere; }
@media (max-width:680px) {
  .cp-dois-lados { grid-template-columns:1fr; gap:11px; }
  .cp-lado { padding:0; }
  .cp-lado-nosso { padding:11px 0 0; border-left:0;
    border-top:1px dashed var(--line,#e2e8ed); }
}

/* ── A PROPOSTA DO AGENTE (Fase 3, 07/09/2026) ──────────────────────────────
   ⚠️ A borda VERDE é reservada pra proposta que de fato escreve no Omie. A que
   é só leitura fica neutra — pintar as duas igual faria o "Aprovar" e o "isto
   é só leitura" parecerem o mesmo tipo de coisa, que é exatamente a confusão
   que o botão explícito existe pra evitar. */
.cp-proposta { margin-top:11px; padding:10px 12px; border-radius:10px;
  background:#f7f9fb; border:1px solid var(--line,#e2e8ed); display:grid; gap:6px; }
.cp-proposta.is-escreve { background:#f2fbf6; border-color:#9fd4b6; }
.cp-prop-cab { display:flex; justify-content:space-between; gap:10px;
  align-items:center; flex-wrap:wrap; }
.cp-prop-tit { font-size:.7rem; font-weight:800; text-transform:uppercase;
  letter-spacing:.06em; color:#17794a; display:flex; gap:5px; align-items:center; }
.cp-proposta:not(.is-escreve) .cp-prop-tit { color:var(--muted,#64748b); }
/* De onde veio a proposta. Confiar numa que aprendeu com você é diferente de
   confiar numa regra fixa — e a tela tem que deixar as duas distinguíveis. */
.cp-prop-de { font-size:.68rem; font-weight:700; color:var(--muted,#64748b);
  background:#eef2f6; border-radius:999px; padding:1px 8px; white-space:nowrap; }
.cp-prop-o-que { margin:0; font-size:.9rem; }
.cp-prop-porque { margin:0; font-size:.79rem; color:var(--muted,#64748b); }
.cp-prop-so-leitura { margin:0; font-size:.76rem; color:var(--muted,#64748b); }
.cp-prop-acoes { display:flex; flex-wrap:wrap; gap:8px; align-items:flex-end; }
.cp-prop-motivo { display:flex; flex-direction:column; gap:3px; flex:1 1 240px;
  min-width:0; font-size:.72rem; font-weight:700; color:var(--muted,#64748b); }
.cp-prop-motivo input { font:inherit; font-size:.84rem; font-weight:400;
  color:var(--text,#0f172a); padding:6px 9px; border-radius:8px;
  border:1px solid var(--line,#e2e8ed); background:#fff; width:100%; min-width:0; }

/* Escolher o par: um clique, e reversível. */
.cp-escolher { font:inherit; font-size:.79rem; text-align:left; cursor:pointer;
  background:#fff; border:1px solid var(--line,#e2e8ed); border-radius:8px;
  padding:5px 9px; width:100%; }
.cp-escolher:hover { border-color:#9fd4b6; background:#f2fbf6; }
.cp-cands li { margin-bottom:4px; }
.cp-desfazer { font:inherit; font-size:.76rem; background:none; border:0;
  padding:0; cursor:pointer; color:var(--muted,#64748b);
  text-decoration:underline; }
.cp-escrito { margin:0; font-size:.8rem; font-weight:700; color:#17794a; }
.cp-recusa { margin:0; font-size:.78rem; color:#8a5b00; overflow-wrap:anywhere; }
@media (max-width:680px) {
  .cp-prop-acoes { flex-direction:column; align-items:stretch; }
  .cp-prop-motivo { flex:1 1 100%; }
}

/* ── "FORA DA FILA": as contas que iam sair sem passar por ninguém ──────────
   ⚠️ Atrasada é a que mais dói e a que menos aparece — ela já venceu e continua
   saindo por fora. Por isso ela tem borda própria, e não só um selo. */
.oc-lista { display:grid; gap:10px;
  grid-template-columns:repeat(auto-fill,minmax(280px,1fr)); }
.oc-item { border:1px solid var(--line,#e2e8ed); border-radius:11px;
  padding:12px 14px; background:var(--card,#fff); }
.oc-item.is-atrasada { border-color:#f0ad39; background:#fffaf0; }
.oc-item.is-trazida { border-color:#7ec9a3; background:#f4fbf7; }
.oc-topo { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.oc-valor { margin-left:auto; font-size:1.15rem; font-weight:800;
  font-variant-numeric:tabular-nums; color:#a52222; }
.oc-nome { margin:8px 0 0; font-weight:700; font-size:.95rem;
  overflow-wrap:anywhere; }
.oc-meta { margin:3px 0 0; font-size:.75rem; color:var(--muted,#64748b); }
.oc-obs { margin:6px 0 0; font-size:.79rem; color:var(--muted,#64748b);
  overflow-wrap:anywhere; }
.oc-acoes { display:flex; flex-wrap:wrap; gap:8px; align-items:center;
  margin-top:11px; }
.oc-estado { flex:1 1 100%; font-size:.78rem; }
.oc-estado.is-ok { color:#146b41; }
.oc-estado.is-erro { color:#a52222; }
@media (max-width:680px) { .oc-lista { grid-template-columns:1fr; } }
/* O "mostrar mais" da lista paginada — largo e centralizado, porque no celular
   ele é o fim visível da lista e precisa parecer o próximo passo, não um
   detalhe do rodapé. */
.oc-mais { display:flex; justify-content:center; margin:14px 0 4px; }
.oc-mais .btn { min-height:44px; padding:0 22px; }
.oc-contas { display:flex; flex-wrap:wrap; gap:8px; margin:0 0 12px; }
.oc-conta { border:1px solid var(--line,#e2e8ed); border-radius:999px;
  padding:4px 12px; font-size:.76rem; color:var(--muted,#64748b);
  background:var(--card,#fff); }
.oc-conta b { color:var(--text,#0f172a); }
/* ⚠️ O que ficou fora da janela é DITO, não escondido — ver o comentário em
   `aprovacoes_omie_cash.js`. Cinza de propósito: é informação, não alarme. */
.oc-fora { margin:14px 0 0; padding:10px 12px; border-radius:9px;
  background:#f6f8fa; border:1px solid var(--line,#e2e8ed);
  font-size:.8rem; color:var(--muted,#64748b); }

/* ── AGENDA (compromissos) ──────────────────────────────────────────────────
   ⚠️ No celular o MÊS vira lista por dia (o JS decide): uma grade 7×6 em 390px
   dá células de 50px, onde não cabe o nome de um compromisso — e agenda que
   não mostra o nome não responde à única pergunta que se faz a ela. */
.ag-nav { display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.ag-nav strong { font-size:1.05rem; min-width:9ch; }
.ag-modos { display:inline-flex; border:1px solid var(--line,#e2e8ed);
  border-radius:999px; overflow:hidden; background:var(--card,#fff); }
.ag-modos button { border:0; background:none; font:inherit; font-size:.82rem;
  font-weight:700; padding:6px 14px; cursor:pointer; color:var(--muted,#64748b); }
.ag-modos button.on { background:#e8f6ee; color:#17794a; }

/* grade do mês (computador) */
.ag-mes-cab, .ag-mes-grade { display:grid; grid-template-columns:repeat(7,1fr); }
.ag-mes-cab span { padding:6px 4px; font-size:.72rem; font-weight:800;
  text-transform:uppercase; color:var(--muted,#64748b); text-align:center; }
.ag-mes-grade { gap:1px; background:var(--line,#e2e8ed);
  border:1px solid var(--line,#e2e8ed); border-radius:10px; overflow:hidden; }
.ag-cel { background:var(--card,#fff); min-height:104px; padding:5px 5px 7px;
  display:flex; flex-direction:column; gap:3px; cursor:pointer; }
.ag-cel.e-fora { background:#fafbfc; }
.ag-cel.e-fora .ag-cel-num { color:#b6c2cd; }
.ag-cel.e-hoje { box-shadow:inset 0 0 0 2px #7ec9a3; }
.ag-cel-num { font-size:.78rem; font-weight:800; color:var(--muted,#64748b); }

/* lista por dia (celular, semana, dia) */
.ag-dia { border:1px solid var(--line,#e2e8ed); border-radius:11px;
  padding:11px 13px; margin-bottom:10px; background:var(--card,#fff); }
.ag-dia.e-hoje { border-color:#7ec9a3; }
.ag-dia h4 { margin:0 0 8px; font-size:.85rem; font-weight:700;
  color:var(--muted,#64748b); text-transform:lowercase; }
.ag-dia h4 em { color:#17794a; font-style:normal; font-weight:800; }
.ag-dia-num { font-size:1.25rem; font-weight:800; color:var(--text,#0f172a); }
.ag-add { border:1px dashed var(--line,#e2e8ed); background:none; width:100%;
  border-radius:8px; padding:7px; margin-top:7px; cursor:pointer;
  font:inherit; font-size:.78rem; color:var(--muted,#64748b); }

/* o compromisso */
.ag-chip { display:block; width:100%; text-align:left; border:0; cursor:pointer;
  font:inherit; border-radius:7px; padding:5px 8px; margin-top:3px;
  background:#e8f6ee; border-left:3px solid #17794a; }
.ag-chip.e-de-outro { background:#eef2fb; border-left-color:#3b62b5; }
.ag-chip-hora { display:block; font-size:.68rem; font-weight:800;
  color:var(--muted,#64748b); }
.ag-chip-nome { display:block; font-size:.82rem; font-weight:600;
  overflow-wrap:anywhere; }
.ag-chip-onde { display:block; font-size:.7rem; color:var(--muted,#64748b); }

/* A SALA DESENHADA NO COMPROMISSO (03/09/2026).
   ⚠️ O link é IRMÃO do botão (`<a>` dentro de `<button>` é inválido e o
   navegador desmonta), então o compromisso é uma linha de dois: o chip que
   abre, e a sala em que se entra. `align-items:stretch` faz o botão da sala ter
   a altura do compromisso — no celular ele é alvo de dedo, não de mouse. */
.ag-item { display:flex; align-items:stretch; gap:4px; margin-top:3px; }
.ag-item .ag-chip { flex:1 1 auto; min-width:0; margin-top:0; }
.ag-meet { flex:0 0 auto; display:inline-flex; align-items:center; gap:5px;
  border:0; cursor:pointer; font:inherit; font-size:.68rem; font-weight:800;
  text-decoration:none; border-radius:7px; padding:0 9px;
  background:#17794a; color:#fff; }
.ag-meet .ic { width:14px; height:14px; }
/* ⚠️ Pedida e não criada NÃO é verde: quem vê verde entra. O âmbar é o mesmo
   do convite que não saiu, logo abaixo — na casa, âmbar quer dizer "isto
   depende de alguém". */
.ag-meet.e-pendente { background:#fff4e2; color:#8a5a12;
  box-shadow:inset 0 0 0 1px #f0d3a0; }
/* ⚠️⚠️ **NO MÊS A SALA NÃO OCUPA LARGURA NENHUMA.** A célula da grade tem
   ~140px; um botão ao lado do chip come 28px deles e o NOME do compromisso
   quebra em mais uma linha — e nome que não aparece é a única coisa que a
   agenda não pode perder (é a razão de a grade virar lista no celular). Por
   isso aqui ele sai do fluxo e pousa em cima da linha da HORA, que é curta e
   sempre sobra espaço. O `padding-right` protege só essa primeira linha; o
   nome, que vem abaixo, continua com a largura inteira. */
.ag-mes .ag-item { position:relative; }
.ag-mes .ag-meet { position:absolute; top:3px; right:3px; padding:3px 5px; }
.ag-mes .ag-meet-txt { display:none; }
.ag-mes .tem-sala .ag-chip-hora { padding-right:26px; }

/* o formulário */
.ag-modal { position:fixed; inset:0; z-index:900; display:flex;
  align-items:center; justify-content:center; padding:16px; }
/* ⚠️⚠️ **`display:flex` SOBREPÕE O ATRIBUTO `hidden`.** O `hidden` só esconde
   porque o estilo do navegador diz `display:none`, e qualquer `display` do
   autor ganha dele — então o modal nascia ABERTO por cima do calendário. É o
   mesmo defeito que o painel do Suporte já teve (ver `camadaPorCima` no motor
   do tutor), e ele engana quem testa por JS: a PROPRIEDADE `hidden` é `true`
   enquanto a tela mostra o diálogo. Quem pega é o olho, não o `assert`. */
.ag-modal[hidden] { display:none; }
.ag-modal-fundo { position:absolute; inset:0; background:rgba(9,16,24,.45); }
.ag-modal-card { position:relative; width:min(620px,100%);
  max-height:90vh; overflow:auto; }
.ag-form { display:grid; gap:10px 14px;
  grid-template-columns:repeat(auto-fit,minmax(170px,1fr)); }
.ag-form label { display:flex; flex-direction:column; gap:3px; min-width:0;
  font-size:.74rem; font-weight:700; color:var(--muted,#64748b); }
.ag-form label.ag-full { grid-column:1/-1; }
.ag-form input, .ag-form select, .ag-form textarea { font:inherit;
  font-size:.9rem; font-weight:400; color:var(--text,#0f172a); padding:7px 9px;
  border:1px solid var(--line,#e2e8ed); border-radius:8px; background:#fff;
  width:100%; min-width:0; }
.ag-form small { font-weight:400; font-size:.7rem; }
.ag-modal-acoes { display:flex; gap:8px; align-items:center; flex-wrap:wrap;
  margin-top:14px; padding-top:12px; border-top:1px solid var(--line,#e2e8ed); }
.ag-erro, .ag-erro-bloco { border:1px solid #f0c0c0; background:#fdeaea;
  color:#8a1f1f; border-radius:9px; padding:9px 12px; font-size:.85rem;
  margin:10px 0 0; }

@media (max-width:680px) {
  .ag-nav strong { flex:1 1 100%; order:-1; }
  .ag-modos { width:100%; }
  .ag-modos button { flex:1; }
  .ag-form { grid-template-columns:1fr; }
  .ag-modal { padding:0; align-items:flex-end; }
  .ag-modal-card { width:100%; max-height:92vh; border-radius:14px 14px 0 0; }
}

/* A faixa do espelho no Google, no topo da Agenda. */
.ag-google { display:flex; flex-wrap:wrap; gap:10px; align-items:center;
  justify-content:space-between; border:1px solid var(--line,#e2e8ed);
  border-radius:11px; padding:10px 14px; margin-bottom:12px;
  background:var(--card,#fff); font-size:.85rem; }
.ag-google.is-on { border-color:#7ec9a3; background:#f4fbf7; }
.ag-google.is-alerta { border-color:#f0ad39; background:#fffaf0; }
.ag-google em { font-style:normal; color:var(--muted,#64748b); }

/* O que vale SEMPRE: a faixa de preferências, logo abaixo da do Google. */
.ag-prefs { display:flex; flex-wrap:wrap; gap:8px 18px; align-items:center;
  border:1px solid var(--line,#e2e8ed); border-radius:11px;
  padding:8px 14px; margin-bottom:12px; background:var(--card,#fff);
  font-size:.82rem; }
.ag-prefs label { display:flex; align-items:center; gap:7px; min-width:0; }
.ag-prefs select { font:inherit; padding:3px 6px; border-radius:7px;
  border:1px solid var(--line,#e2e8ed); }
.ag-prefs-ok { color:#2b7a55; font-size:.75rem; }

/* Sala do Meet e convidados por telefone (02/09/2026).
   ⚠️ O `.ag-check` quebra a coluna do `.ag-form` de propósito: caixa de
   marcar com rótulo em cima (o padrão do grid) fica com o quadradinho solto
   longe do texto, e no celular ninguém acerta o alvo. */
.ag-form label.ag-check { flex-direction:row; align-items:center;
  flex-wrap:wrap; gap:8px; }
.ag-form label.ag-check input { width:auto; flex:0 0 auto; }
.ag-form label.ag-check small,
.ag-form label.ag-check a { flex-basis:100%; }
.ag-form label.ag-check a { font-size:.78rem; }
.ag-convidados { display:flex; flex-wrap:wrap; gap:6px; align-items:center;
  font-size:.78rem; color:var(--muted,#64748b); }
/* ⚠️⚠️ **O convidado é `.ag-convidados .ag-chip`, e o escopo NÃO é enfeite.**
   Sem ele estas duas regras alcançavam o chip do CALENDÁRIO — mesmo nome de
   classe, mais abaixo no arquivo, mesma especificidade — e o compromisso
   perdia o `display:block`, a largura, o fundo verde e o tamanho da letra pra
   virar uma pílula cinza. Nada quebra, nada avisa: só a tela fica errada. */
.ag-convidados .ag-chip { display:inline-block; width:auto; padding:2px 9px;
  border-radius:999px; background:#eef4f9; color:#31465c; font-size:.75rem;
  border-left:0; margin-top:0; }
/* ⚠️ Pendente é VISÍVEL: convite que não saiu é gente que não aparece, e a
   diferença entre "convidei" e "quis convidar" tem que estar na tela. */
.ag-convidados .ag-chip.is-pendente { background:#fff4e2; color:#8a5a12; }
/* O convite em arquivo (.ics) — o que se manda pra quem não tem conta aqui. */
.ag-convite { display:flex; flex-wrap:wrap; gap:8px 12px; align-items:center;
  padding:8px 10px; border:1px dashed var(--line,#e2e8ed); border-radius:9px;
  font-size:.8rem; }
.ag-convite small { flex-basis:100%; color:var(--muted,#64748b); }

/* ── DETALHE DO PEDIDO: card + modal de decidir (31/08/2026) ──────────────────
   ⚠️ A tela era uma pilha de caixas rótulo/valor e uma seção "Decidir" aberta
   com tudo à mostra. Virou: o card do Fluxo no topo, os dados da transferência
   recolhidos, e a decisão num modal com wizard. */
.aprovacoes .apr-card-um { margin: 4px 0 10px; }
/* Um pedido só: nem alternador de modo nem setas fazem sentido aqui. */
/* ⚠️ O deck é feito pra LISTA; aqui é um pedido só. Some tudo que só faz
   sentido com vários: o alternador, o filtro, o placar "1 título", as setas de
   navegar, e a barra de ações com a dica "arraste pra marcar conferida" — essa
   última era ativamente ERRADA, porque não há nada pra conferir nesta tela.
   O que fica é o CARD. */
.aprovacoes .apr-card-um .fc-viewtoggle,
.aprovacoes .apr-card-um .fcfilter,
.aprovacoes .apr-card-um .fcdeck-top,
.aprovacoes .apr-card-um .fcdeck-actions,
.aprovacoes .apr-card-um .fcdeck-drawbar,
.aprovacoes .apr-card-um .fcdeck-hint { display: none !important; }
/* Sem a barra de cima, a pilha não precisa da margem que a compensava. */
.aprovacoes .apr-card-um .fcdeck-wrap { margin-top: 0; }

.aprovacoes .apr-tecnico { border: 1px solid var(--line); border-radius: 12px;
  padding: 0 12px; margin: 10px 0; }
.aprovacoes .apr-tecnico > summary { cursor: pointer; padding: 10px 0; font-size: .86rem;
  font-weight: 600; color: var(--text-soft); list-style: none; }
.aprovacoes .apr-tecnico > summary::-webkit-details-marker { display: none; }
.aprovacoes .apr-tecnico > summary::before { content: '▸ '; }
.aprovacoes .apr-tecnico[open] > summary::before { content: '▾ '; }
.aprovacoes .apr-tecnico .apr-grade { padding-bottom: 12px; }

.aprovacoes .apr-decidir-chamada { display: flex; gap: 12px; align-items: center;
  flex-wrap: wrap; }
.aprovacoes .apr-decidir-chamada .btn { flex: 0 0 auto; }

/* O wizard dentro do modal: a caixa já é o card, o wizard não precisa de outra. */
.aprovacoes .apr-decidir-wiz { position: relative; margin: 0; }

/* ⚠️ A SAÍDA DO MODAL. Ela é `sticky` no topo do card porque o passo 2 é
   comprido (dois fatores, alerta de quórum, observação): rolando até o fim, um
   botão só no cabeçalho sai de vista e a pessoa fica presa de novo — foi o
   defeito que o Marcos achou no iPhone. Fundo opaco porque ele passa POR CIMA
   do conteúdo que rola por baixo. */
.aprovacoes .apr-modal-topo { position: sticky; top: 0; z-index: 3;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 14px; background: var(--card, #fff);
  border-bottom: 1px solid var(--line); border-radius: 14px 14px 0 0; }
.aprovacoes .apr-modal-topo strong { font-size: .95rem; }
/* Alvo de dedo: 44px é o mínimo da Apple, e este botão é o que tira a pessoa
   de uma tela que move dinheiro. */
.aprovacoes .apr-modal-sair { flex: 0 0 auto; min-height: 44px; padding: 0 18px; }
.aprovacoes .apr-resumo { display: grid; gap: 8px; margin-bottom: 12px; }
.aprovacoes .apr-resumo > div { display: flex; justify-content: space-between;
  gap: 12px; border-bottom: 1px dashed var(--line); padding-bottom: 6px; }
.aprovacoes .apr-resumo span { color: var(--text-soft); font-size: .82rem; }
.aprovacoes .apr-resumo b { text-align: right; }
/* ⚠️ 16px: abaixo disso o Safari do iPhone amplia a página ao focar o campo — e
   não desfaz depois. Mesma regra da tela de assinatura. */
.aprovacoes .apr-decidir-wiz input[type="text"],
.aprovacoes .apr-decidir-wiz input[type="password"] { font-size: 16px; padding: 11px 13px; }
@media (max-width: 680px) {
  /* No celular o modal é a tela inteira — meia tela pra decidir pagamento é
     onde o polegar erra o botão. */
  .aprovacoes .report-modal-box { width: 100%; max-height: 96vh; }
  .aprovacoes .apr-barra { display: grid; gap: 8px; }
  .aprovacoes .apr-barra .btn { width: 100%; }
}

/* ── ajustes do modal de decidir (medidos no navegador, 31/08/2026) ────────── */
/* O × precisa ficar ACIMA da barra de abas, que é o primeiro filho do wizard. */
.aprovacoes .report-modal-box > .report-modal-close { z-index: 5; }
/* A barra de abas cede espaço pro × — senão a 3ª aba fica embaixo dele. */
.aprovacoes .apr-decidir-wiz > .wiz-switch { padding-right: 44px; }
.aprovacoes .apr-obs { display: grid; gap: 6px; font-size: .86rem; font-weight: 600;
  color: var(--text-soft); margin-bottom: 14px; }
.aprovacoes .apr-obs .apr-opcional { font-weight: 400; }
/* Os dois botões da decisão em linha, sem vazar a caixa. */
.aprovacoes .apr-decidir-wiz .apr-barra { display: flex; gap: 10px; flex-wrap: wrap; margin: 0; }
.aprovacoes .apr-decidir-wiz .apr-barra .btn { flex: 1 1 auto; }
/* O ROSTO DA VIA (`.vface`) mora em `static/css/via_rosto.css` desde 18/09/2026:
   o console do hub também desenha a Via e não carrega este arquivo. */


/* O ALVO DO ATALHO DA NOTIFICAÇÃO (`?pedido=<id>` → `aprovacoes_atalho.js`).
   ⚠️ Some sozinho depois de alguns segundos: destaque permanente vira ruído na
   próxima vez que a pessoa abrir a fila pelo caminho normal. */
.apr-atalho-alvo {
    animation: apr-atalho-pulso 1.1s ease-out 2;
    scroll-margin-block: 96px;
}
@keyframes apr-atalho-pulso {
    0%   { box-shadow: inset 0 0 0 9999px rgba(92, 194, 228, 0.28); }
    100% { box-shadow: inset 0 0 0 9999px rgba(92, 194, 228, 0); }
}
@media (prefers-reduced-motion: reduce) {
    .apr-atalho-alvo { animation: none; outline: 2px solid var(--neon, #5cc2e4); }
}

/* ══════════════════════════════════════════════════════════════════════════
   O QUADRO DAS CONTAS (06/09/2026) — `partials/_quadro_contas.html`
   --------------------------------------------------------------------------
   ⚠️ MORA AQUI, e não no template, porque o markup é COMPARTILHADO: o painel
   "O banco × o Omie" do Fluxo de Caixa e o quadro da Auditoria de Conciliação
   chamam o MESMO macro. CSS inline num dos dois faria o outro renderizar cru —
   foi exatamente assim que o card das Aprovações saiu pela metade, em silêncio.
   ══════════════════════════════════════════════════════════════════════════ */
.qc-selo {
  display: inline-block; padding: 1px 8px; border-radius: 999px;
  font-size: .72rem; font-weight: 700; white-space: nowrap;
  background: #f1f5f9; color: #475569;
}
/* Verde só pra quem está mesmo lendo agora. Os outros três estados são
   graduações do problema — e o "provedor" é neutro, porque não há credencial
   nossa a sincronizar (no Omie.CASH o Omie É o banco). */
.qc-selo.qc-lendo     { background: #dcfce7; color: #15803d; }
.qc-selo.qc-parada    { background: #fef3c7; color: #92400e; }
.qc-selo.qc-erro      { background: #fee2e2; color: #991b1b; }
.qc-selo.qc-nunca     { background: #fee2e2; color: #991b1b; }
.qc-selo.qc-omie_cash { background: #e0f2fe; color: #075985; }
.qc-selo.qc-sem-vinculo { background: #fee2e2; color: #991b1b; }
.qc-selo.qc-pend      { background: #fef3c7; color: #92400e; }

/* ── O que impede a sede de fechar em 100% ─────────────────────────────────
   Fica ACIMA da tabela de propósito: a mesma diferença de milhões já morou num
   rodapé por semanas sem ninguém ver. */
.qc-alertas {
  margin-top: 12px; padding: 12px 14px; border-radius: 12px;
  background: #fff7ed; border: 1px solid #fed7aa;
}
.qc-alertas h4 { margin: 0 0 8px; font-size: .88rem; color: #9a3412; }
.qc-alertas ul { margin: 0; padding-left: 18px; display: grid; gap: 6px; }
.qc-alertas li { font-size: .82rem; line-height: 1.5; color: #7c2d12; }
.qc-alertas li.qc-critico::marker { color: #dc2626; }
.qc-alertas li.qc-atencao::marker { color: #d97706; }

/* Os três números do quadro: banco, Omie, divergência. */
.qc-numeros { display: flex; flex-wrap: wrap; gap: 24px; margin-top: 12px; }
.qc-numeros .lbl {
  font-size: .72rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted, #66778a); font-weight: 700;
}
.qc-numeros .val {
  font-size: 1.7rem; font-weight: 800; font-variant-numeric: tabular-nums;
}

/* ═══════════════════════════════════════════════════════════════════════════
   A FILA DA CONCILIAÇÃO (09/09/2026 · redesenhada em 10/09/2026)
   ---------------------------------------------------------------------------
   ⚠️⚠️ **O CARD DA FILA É UM `.fcdeck-card`, E NÃO EXISTE OUTRO MODELO.**

   A primeira versão entregou ao baralho um `<article class="cp-linha
   fila-card">` — a classe de LINHA DE LISTA da contraprova — e ESTE bloco
   ainda lhe tirava borda, fundo e padding, com o comentário "quem dá a moldura
   é o deck". A moldura do deck é `.fcdeck-card`, que o card nunca teve. Foto do
   Marcos (10/09/2026): *"estado claramente ridículo de produção… sem formato de
   cards condizendo com o resto, tudo bagunçado, espaçado, cortado que nem chega
   ao final"*. Eram três coisas de uma vez, e todas saem daquela classe:

     · `position:absolute; inset:0` — sem ele os 273 cartões ficam em FLUXO
       NORMAL, um embaixo do outro; a pilha nunca existiu e os invisíveis
       continuavam ocupando a página;
     · fundo/borda/raio/sombra/padding — sem eles o card não parece card;
     · `overflow:hidden` — sem ele o `is-tall` que o motor marca não vira
       rolagem interna, e o conteúdo sai pela parte de baixo da tela.

   Aqui mora só o que é DA FILA: a barra de números, o que o card acrescenta
   DENTRO da anatomia da casa (`.fcdeck-head` · `.fcdeck-cli` · `.fcdeck-grid`)
   e a barra de responder — que fica FORA do card, porque ação dentro de card
   compete com o arraste e porque numa fila de 273 o controle tem que estar
   sempre no mesmo lugar.
   ═════════════════════════════════════════════════════════════════════════ */
.fila-barra {
    display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
    margin: 10px 0 14px; padding: 10px 12px;
    border: 1px solid var(--line); border-radius: 10px; background: #fff;
}
.fila-num { display: flex; align-items: baseline; gap: 8px; padding-right: 14px; }
.fila-num + .fila-num { border-left: 1px solid var(--line); padding-left: 14px; }
.fila-num b {
    font-size: 1.45rem; font-weight: 700; line-height: 1;
    font-variant-numeric: tabular-nums; color: var(--ink, #16261f);
}
.fila-num span { font-size: .74rem; color: #6b7d91; line-height: 1.3; }
.fila-num small { color: #93a3b3; }
.fila-barra .btn { margin-left: auto; }
.fila-barra .btn + .btn { margin-left: 8px; }
.fila-carregando { padding: 18px 4px; line-height: 1.5; max-width: 62ch; }

/* ── O CARTÃO ──────────────────────────────────────────────────────────────
   Nada aqui redefine a moldura: ela vem de `.fcdeck-card`. */

/* ⚠️ **A CONTA VIAJA NO CARD.** Em ordem cronológica dois cartões seguidos são
   de bancos diferentes, e um card que não diz de qual conta é vira uma decisão
   tomada no escuro. Por isso ela é uma LINHA logo abaixo do cabeçalho, e não
   um selo perdido no meio do texto. */
.fila-card .fila-conta {
    display: flex; align-items: center; gap: 5px 10px; flex-wrap: wrap;
    margin: 0 0 7px; min-width: 0;
}
.fila-conta-quem {
    flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere;
    font-size: .78rem; font-weight: 700; color: #1f4e63;
}
.fila-conta-quem span {
    font-weight: 400; font-size: .73rem; color: var(--muted, #64748b);
    font-variant-numeric: tabular-nums; margin-left: 5px;
}
.fila-selos { display: flex; flex-wrap: wrap; gap: 4px; flex: 0 1 auto; }
.fila-selos .cp-tag { font-size: .68rem; padding: 1px 8px; }

/* O que a instituição mandou, em letra de máquina e sem tradução — a manchete
   do cartão. ⚠️ Duas linhas, não uma: o `.fcdeck-cli` da casa corta em
   `nowrap` porque lá é um nome de cliente, e aqui é a frase do banco, que é o
   único texto conferível contra o extrato. */
.fila-card .fila-cru {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: .82rem; font-weight: 600; letter-spacing: -.01em;
    white-space: normal; overflow: hidden; text-overflow: initial;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    margin-bottom: 9px;
}

/* ⚠️ **A PROPOSTA É UMA FAIXA, NÃO UM BLOCO DE PROSA.** O texto "isto é
   leitura, não lançamento — o agente só escreve sozinho tarifa e transferência
   entre contas nossas" era IDÊNTICO em toda linha muda: quatro linhas
   repetidas centenas de vezes, empurrando pra baixo da dobra o que só existe
   naquele cartão. Isso é da DICA da aba, que se lê uma vez. */
.fila-prop {
    margin: 0 0 9px; padding: 7px 10px; border-radius: 9px;
    border: 1px solid var(--line, #e2e8ed); background: #f8fafc;
}
.fila-prop.is-escreve { background: #f2fbf6; border-color: #9fd4b6; }
.fila-prop-cab { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.fila-prop-tit {
    font-size: .63rem; font-weight: 800; text-transform: uppercase;
    letter-spacing: .05em; color: #17794a; margin-right: auto;
}
.fila-prop:not(.is-escreve) .fila-prop-tit { color: var(--muted, #64748b); }
.fila-prop-de {
    font-size: .63rem; font-weight: 700; color: var(--muted, #64748b);
    background: #fff; border: 1px solid var(--line, #e2e8ed);
    border-radius: 999px; padding: 1px 8px; white-space: nowrap;
}
.fila-prop-o-que { margin: 3px 0 0; font-size: .84rem; overflow-wrap: anywhere; }
/* ⚠️ A classificação tem LINHA PRÓPRIA — ela vinha emendada na natureza e
   sumia no meio da frase, e é justamente o pedaço que se confere. */
.fila-prop-classe {
    margin: 3px 0 0; font-size: .8rem; overflow-wrap: anywhere; color: #1f4e63;
}
.fila-prop-classe small { color: var(--muted, #64748b); font-weight: 400; }
/* ⚠️ **CORTADO EM DUAS LINHAS, E ABRE NO TOQUE.** Inteiro ele media quatro
   linhas em toda linha muda e empurrava pra baixo da dobra os campos
   conferíveis; escondido de vez, a proposta deixa de saber se explicar — e uma
   proposta que não se explica é uma que ninguém deveria aprovar. O `title`
   resolve no computador e não existe no celular, que é onde esta fila se
   trabalha: por isso o toque também abre (`is-aberto`, no `conciliacao_fila.js`). */
.fila-prop-porque {
    margin: 2px 0 0; font-size: .74rem; line-height: 1.35;
    color: var(--muted, #64748b); cursor: pointer;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
}
.fila-prop-porque.is-aberto { -webkit-line-clamp: unset; }

/* Os campos da grade da casa carregam mais de uma linha aqui (o par no Omie
   traz nome, número, data, valor e categoria) — o valor vira coluna. */
.fila-card .fcdeck-val { display: flex; flex-direction: column; gap: 1px; }
.fila-card .fcdeck-val b { font-size: .84rem; color: var(--text, #0f172a); }
.fila-sub { font-size: .72rem; color: var(--muted, #64748b); }
.fila-dif { font-size: .72rem; font-weight: 700; color: #8a5b00; }
.fila-mono {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: .71rem; overflow-wrap: anywhere;
}

/* ── A BARRA DE RESPONDER ──────────────────────────────────────────────────
   ⚠️⚠️ **FORA DO CARD, DE PROPÓSITO.** Regra da casa (botão dentro compete com
   o arraste), e aqui ela vale por três razões somadas: o `<select>` + os dois
   campos de texto + os quatro botões faziam o cartão medir mais que a tela — é
   literalmente o "cortado que nem chega ao final" —, e numa fila de 273
   cartões a pessoa precisa que o controle esteja SEMPRE no mesmo lugar, não
   rolando junto com o conteúdo de cada um. Ela age sobre o card ATIVO. */
.fila-resp {
    margin-top: 18px; padding: 12px 14px; border-radius: 12px;
    border: 1px solid var(--line, #e2e8ed); background: #fff;
    box-shadow: 0 4px 14px rgba(15, 23, 42, .05);
}
.fila-resp[hidden] { display: none; }
.fila-resp-campos { display: flex; flex-wrap: wrap; gap: 8px 12px; }
.fila-campo {
    display: flex; flex-direction: column; gap: 3px; min-width: 0;
    flex: 1 1 220px;
}
.fila-campo-larga { flex: 1 1 100%; }
.fila-rot {
    font-size: .74rem; font-weight: 700; color: var(--muted, #64748b);
}
.fila-rot small { font-weight: 400; }
/* O autocomplete da casa se posiciona sozinho; aqui ele só precisa poder
   encolher dentro do flex (senão o `min-width:auto` do item estoura a barra). */
.fila-campo .customer-search { min-width: 0; width: 100%; }

/* ⚠️ **A SUGESTÃO DO AGENTE É UMA OFERTA, NÃO UM PREENCHIMENTO.** Ela só
   aparece quando a linha JÁ tem resposta de gente: aí os campos mostram o que a
   pessoa escolheu, e sobrescrever isso com o palpite da máquina desfaria a
   decisão dela na cara dela. Enquanto ninguém respondeu, o palpite já vem nos
   campos e esta faixa nem existe. */
.fila-resp-sug {
    display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
    margin-top: 10px; padding: 7px 10px; border-radius: 9px;
    border: 1px dashed var(--line, #e2e8ed); background: #f8fafc;
    font-size: .8rem;
}
.fila-resp-sug[hidden] { display: none; }
.fila-resp-sug > span { flex: 1 1 200px; min-width: 0; overflow-wrap: anywhere; }
.fila-resp-sug small { color: var(--muted, #64748b); }
.fila-resp-cands[hidden] { display: none; }
.fila-resp select, .fila-resp input {
    font: inherit; font-size: .86rem; font-weight: 400;
    padding: 8px 10px; border: 1px solid var(--line, #e2e8ed);
    border-radius: 9px; background: #fff; min-width: 0; width: 100%;
    box-sizing: border-box;
}
.fila-resp-botoes { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.fila-resp-motivo {
    display: flex; flex-direction: column; gap: 3px; margin-top: 10px;
    font-size: .74rem; font-weight: 700; color: #8a5b00;
}
.fila-resp-motivo[hidden] { display: none; }
.fila-resp-cands { margin-bottom: 10px; font-size: .78rem; }
.fila-resp-cands > span { font-weight: 700; color: var(--muted, #64748b); }
.fila-resp-cands ul { margin: 5px 0 0; padding: 0; list-style: none; display: grid; gap: 5px; }
.fila-aviso {
    margin: 10px 0 0; font-size: .8rem; font-weight: 700;
    overflow-wrap: anywhere;
}
.fila-aviso[hidden] { display: none; }
.fila-aviso.is-bom { color: #17794a; }
.fila-aviso.is-ruim { color: #a52222; }

@media (max-width: 680px) {
    /* ⚠️⚠️ **A BARRA DE NÚMEROS NÃO PODE EMPURRAR O TRABALHO PRA BAIXO DA
       DOBRA.** Ela media ~200px em 390px de tela (três blocos empilhados com a
       legenda em duas linhas cada, mais um botão de 44px numa linha só pra
       ele) — ou seja, metade da altura útil gasta ANTES do primeiro cartão. Ela
       diz o tamanho da fila, que se lê uma vez; o cartão é o que se trabalha
       273 vezes. No celular ela vira uma linha de números com a legenda curta. */
    .fila-barra { gap: 6px 10px; padding: 8px 10px; }
    .fila-num { flex-direction: column; align-items: flex-start; gap: 0;
        padding-right: 8px; }
    .fila-num + .fila-num { padding-left: 8px; }
    .fila-num b { font-size: 1.15rem; }
    .fila-num span { font-size: .68rem; }
    .fila-num small { display: none; }        /* o detalhe fica no computador */
    .fila-barra .btn { margin-left: auto; min-height: 32px; padding: 4px 10px;
        font-size: .78rem; }
    .fila-barra .btn + .btn { margin-left: 6px; }

    /* ⚠️ Uma coluna nos CAMPOS: dois lado a lado em 390px espremem o `<select>`
       a ponto de o rótulo da natureza (que é uma FRASE) não caber. */
    .fila-campo { flex: 1 1 100% !important; }
    /* ⚠️ **A AÇÃO PRINCIPAL OCUPA A LINHA; AS OUTRAS DIVIDEM.** Quatro botões
       de 44px empilhados são 176px de barra — mais alto que a metade do card
       que eles decidem. O primeiro é o que a proposta autoriza (Aprovar quando
       ela lança, Guardar quando não), e é o único que merece a linha inteira. */
    .fila-resp-botoes .btn { flex: 1 1 44%; }
    .fila-resp-botoes .btn:first-child { flex: 1 1 100%; }
    /* ⚠️ **A GRADE CONTINUA COM DUAS COLUNAS**, como em todo card da casa.
       Empilhar em uma só fazia "Tipo no banco / Documento / Saldo depois / Id"
       ocuparem quatro linhas pra quatro valores curtos — o card ficava alto e
       vazio, que é a metade "espaçado" da queixa. */
}

/* ═══════════════════════════════════════════════════════════════════════════
   A MARCA DO BANCO (10/09/2026)
   ---------------------------------------------------------------------------
   *"O nome dos bancos está pouco aparente, coloque svg ou png das logos pra
   ajudar a identificar, além das razões sociais explícitas junto com o CNPJ.
   Não só aqui, mas em todos os lugares que aparece banco no dashboard"*
   (Marcos, 10/09/2026).

   ⚠️ **UM DESENHO SÓ, DUAS MÃOS.** O macro `partials/_banco.html` (servidor) e
   o `static/js/banco_marca.js` (cliente) emitem ESTE markup — `.bmark` e
   `.bconta`. Componente é JS, CSS **e markup**: foi separar as três coisas que
   fez o card do Fluxo chegar pela metade nas Aprovações.

   ⚠️ **O QUADRADO TEM TAMANHO FIXO E A LOGO SE ENCAIXA DENTRO** (`object-fit:
   contain`): logos de banco têm proporções que não conversam (o Itaú é
   quadrado, o Bradesco é largo), e deixar cada uma mandar na altura faria as
   linhas da tabela dançarem.
   ═════════════════════════════════════════════════════════════════════════ */
/* ⚠️⚠️ **ALTURA FIXA, LARGURA PELA PROPORÇÃO MEDIDA — é o que separa a logo
   legível da logo "meio borrada".** A maioria das logos de banco é o WORDMARK,
   não o símbolo: o Bradesco mede 5,3:1, o Santander 4,4:1, o Asaas 5,9:1; só o
   Itaú, o BB e o Mercado Pago são quadrados. Espremer todas num quadrado de
   20px deixaria as largas com 4px de altura útil.

   ⚠️ A proporção vem do `viewBox` do arquivo, calculada no SERVIDOR
   (`marca_do_banco`), e chega como `--bmark-p`. O navegador só conheceria a
   proporção depois de baixar a imagem — e até lá a linha da tabela mudaria de
   largura na frente da pessoa. */
.bmark {
    --bmark-h: 26px;
    --bmark-p: 1;
    flex: 0 0 auto; display: inline-grid; place-items: center;
    height: var(--bmark-h); width: calc(var(--bmark-h) * var(--bmark-p));
    border-radius: 7px;
    background: var(--bmark-bg, #51606f); color: var(--bmark-fg, #fff);
    overflow: hidden; vertical-align: -.35em;
}
.bmark b {
    font-size: calc(var(--bmark-h) * .34); font-weight: 800;
    letter-spacing: -.02em; font-variant-numeric: tabular-nums; line-height: 1;
}
/* ⚠️⚠️ **COM LOGO DE VERDADE, O FUNDO DA MARCA SOME.** A cor do banco existe
   pro caso SEM logo (o código Compe precisa de contraste). Mantê-la debaixo de
   um wordmark colorido — o Bradesco é vermelho sobre transparente, o Itaú vem
   com o próprio quadrado laranja — pintaria a moldura errada em volta da marca
   da instituição. Aqui o fundo é branco, que é sobre o que toda logo de banco é
   desenhada pra funcionar. */
.bmark.has-logo { background: #fff; }
/* ⚠️⚠️ **LOGO BRANCA MANTÉM O FUNDO DO BANCO.** A do Asaas é branca sobre
   transparente (é o header-logo do site deles, que tem fundo escuro) e sobre
   branco ela SOME — um retângulo vazio na linha da conta, sem erro nenhum. Quem
   descobre isso é `_logo_e_clara()`, LENDO o arquivo: pelo nome do banco não
   dava. */
.bmark.has-logo.logo-clara { background: var(--bmark-bg, #51606f); }
/* ⚠️ Respiro curto: logo que traz o PRÓPRIO fundo (o Itaú vem com o quadrado
   laranja) ganharia uma moldura branca em volta com padding folgado. */
.bmark img { width: 100%; height: 100%; object-fit: contain;
    padding: calc(var(--bmark-h) * .06); box-sizing: border-box; }
.bmark-sm { --bmark-h: 20px; border-radius: 5px; vertical-align: -.28em; }
.bmark-lg { --bmark-h: 34px; border-radius: 8px; }

/* A identidade inteira: marca + banco/conta em cima, titular + CNPJ embaixo. */
/* ⚠️ **A MARCA ALINHA COM A PRIMEIRA LINHA, não com o meio do bloco.** Com
   `center` e três linhas de texto (banco/conta, razão social, CNPJ) ela
   centralizava na SEGUNDA — parecia solta, ao lado do nada. Visto em produção
   no quadro das contas da sede 1 (10/09/2026). */
.bconta { display: flex; align-items: flex-start; gap: 8px; min-width: 0; }
.bconta > .bmark { margin-top: 1px; }
.bconta-txt { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.bconta-l1 { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap;
    min-width: 0; font-size: .84rem; }
.bconta-l1 b { color: var(--text, #0f172a); }
.bconta-num { font-size: .76rem; color: var(--muted, #64748b);
    font-variant-numeric: tabular-nums; white-space: nowrap; }
/* ⚠️ A razão social pode ser longa e ela NÃO é cortada em `nowrap`: é ela que
   distingue as sedes desta casa, que compartilham prefixo ("São Lázaro …").
   Cortar em uma linha apagaria justamente a parte que diferencia. */
.bconta-l2 { font-size: .72rem; color: var(--muted, #64748b); min-width: 0;
    overflow-wrap: anywhere; }
.bconta-l2 i { opacity: .8; }
.bconta-cnpj { font-variant-numeric: tabular-nums; white-space: nowrap;
    color: #93a3b3; }

/* ⚠️ O aviso que OCUPA o lugar dos campos de classificação quando a natureza
   escolhida não tem categoria (transferência entre contas próprias, estorno).
   Sumir sem uma palavra faria a pessoa achar que a tela esqueceu de perguntar. */
.fila-sem-classe {
    margin: 8px 0 0; padding: 8px 10px; border-radius: 9px;
    border: 1px dashed var(--line, #e2e8ed); background: #f8fafc;
    font-size: .78rem; line-height: 1.4; color: var(--muted, #64748b);
}
.fila-sem-classe[hidden] { display: none; }

/* ═══════════════════════════════════════════════════════════════════════════
   A PAREDE DO ALMOXARIFADO  (`modules/cautela.html` · aba Parede)
   ───────────────────────────────────────────────────────────────────────────
   *"uma parede de pendurar separada por tipo, com todos os itens como
   figurinhas"* (Marcos, chamado #29, 10/09/2026).

   ⚠️ O CSS mora AQUI, e não no `<style>` do template, pela régua de
   *Componente = JS, CSS e markup*: quem desenha é `static/js/parede_almox.js`,
   que é global — deixar o desenho numa página só é ter um componente que só
   funciona numa tela.

   ⚠️ O painel perfurado é DESENHADO (gradiente radial repetido), não imagem: o
   furo é a grade em que as figurinhas se penduram, e o gancho de cada uma
   encosta num furo de verdade em qualquer largura de tela.
   ═════════════════════════════════════════════════════════════════════════ */
.pr-wrap { display: flex; flex-direction: column; gap: 14px; }

/* ── a barra ─────────────────────────────────────────────────────────────── */
.pr-barra { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.pr-modos { display: inline-flex; gap: 4px; }
.pr-chip {
    border: 1px solid var(--line, #e5ebf2); background: #fff; color: var(--text, #13212d);
    border-radius: 999px; padding: 7px 14px; font-size: 13px; font-weight: 600;
    cursor: pointer; display: inline-flex; align-items: center; gap: 7px; line-height: 1;
    /* ⚠️ **NÃO ENCOLHE.** Num flex, o padrão é `shrink: 1` — e um chip menor
       que o próprio rótulo corta a palavra sem avisar (medido: "Nada" saindo
       4px da caixa em 390px). A linha JÁ quebra (`flex-wrap: wrap`), então o
       que falta é ele ir pra linha de baixo em vez de espremer. */
    flex-shrink: 0;
}
.pr-chip:hover { border-color: var(--primary, #11adb4); }
/* ⚠️ **TEXTO BRANCO SOBRE O GRADIENTE, SEMPRE.** Este chip nasceu com texto
   escuro (`#08222a`, herdado do rascunho) e foi vetado na hora: *"já não gostei
   desses textos em preto dentro das formas em verde"* (Marcos, 11/09/2026). A
   casa inteira é `color:#fff` sobre `--brand-grad` — `.btn-primary`,
   `.tbl-view-toggle button.active`, a aba do laboratório bancário. E o
   `brandFlow` junto, que é o que faz o verde ANDAR como no resto do app. */
.pr-chip[aria-pressed="true"] {
    border-color: transparent; color: #fff;
    background: var(--brand-grad); background-size: 220% 100%;
    animation: brandFlow 7s ease-in-out infinite;
}
.pr-chip[aria-pressed="true"] .pr-n { opacity: .85; }
.pr-n { font-size: 11.5px; font-weight: 700; opacity: .72; font-variant-numeric: tabular-nums; }
.pr-busca { flex: 1; min-width: 190px; position: relative; display: block; }
.pr-busca input {
    width: 100%; height: 38px; border-radius: 999px; border: 1px solid var(--line, #e5ebf2);
    background: #fff; color: var(--text, #13212d); padding: 0 14px 0 36px; font-size: 13.5px;
}
.pr-busca svg { position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
    color: var(--text-soft, #66778a); }

/* ── o seletor de local ──────────────────────────────────────────────────── */
.pr-locais { position: relative; }
.pr-locais > summary {
    list-style: none; cursor: pointer; border: 1px solid var(--line, #e5ebf2);
    background: #fff; border-radius: 999px; padding: 7px 14px; font-size: 13px;
    font-weight: 600; display: inline-flex; align-items: center; gap: 7px; line-height: 1;
}
.pr-locais > summary::-webkit-details-marker { display: none; }
.pr-locais[open] > summary { border-color: var(--primary, #11adb4); }
.pr-locais-lista {
    position: absolute; z-index: 30; top: calc(100% + 6px); left: 0; min-width: 260px;
    max-width: min(92vw, 360px); max-height: 46vh; overflow: auto; padding: 8px;
    background: #fff; border: 1px solid var(--line, #e5ebf2); border-radius: 12px;
    box-shadow: 0 12px 30px rgba(9, 22, 38, .14);
}
.pr-locais-lista label {
    display: flex; gap: 8px; align-items: center; padding: 7px 8px; border-radius: 8px;
    font-size: 13px; cursor: pointer;
}
.pr-locais-lista label:hover { background: var(--panel-muted, #f4f7fb); }
.pr-locais-lista .pr-pad { font-size: 10.5px; font-weight: 700; text-transform: uppercase;
    letter-spacing: .05em; color: var(--primary, #11adb4); margin-left: auto; }
.pr-locais-ok { position: absolute; z-index: 31; top: calc(100% + 6px); left: 0;
    transform: translateY(calc(46vh + 8px)); display: none; }
.pr-locais[open] .pr-locais-ok { display: inline-flex; position: static; transform: none;
    margin-top: 6px; }

/* ── o resumo ────────────────────────────────────────────────────────────── */
.pr-resumo { display: grid; gap: 10px; margin: 0;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 158px), 1fr)); }
.pr-tile { background: #fff; border: 1px solid var(--line, #e5ebf2);
    border-radius: var(--radius-sm, 12px); padding: 12px 14px; }
.pr-tile dt { margin: 0; font-size: 11px; font-weight: 700; letter-spacing: .06em;
    text-transform: uppercase; color: var(--text-soft, #66778a); }
.pr-tile dd { margin: 5px 0 0; font-size: 23px; font-weight: 700; letter-spacing: -.02em;
    font-variant-numeric: tabular-nums; }
.pr-tile dd small { font-size: 12.5px; font-weight: 600; color: var(--text-soft, #66778a);
    margin-left: 4px; letter-spacing: 0; }
.pr-tile.is-alerta dd { color: var(--danger, #e3525b); }

.pr-avisos { display: flex; flex-direction: column; gap: 6px; }
.pr-aviso { border: 1px solid #f3d998; background: #fdf1d6; color: #7a5406;
    border-radius: 10px; padding: 9px 12px; font-size: 12.5px; line-height: 1.45; }

/* ── a parede ────────────────────────────────────────────────────────────── */
.pr-parede { border: 1px solid var(--line, #e5ebf2); border-radius: var(--radius, 18px);
    overflow: hidden; background: #fff; margin-bottom: 14px; }
.pr-parede-cab { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
    padding: 13px 16px; border-bottom: 1px solid var(--line, #e5ebf2); }
.pr-parede-cab h3 { margin: 0; font-size: 14px; font-weight: 700; letter-spacing: .05em;
    text-transform: uppercase; }
.pr-parede-cab .pr-conta { font-size: 12.5px; color: var(--text-soft, #66778a);
    font-variant-numeric: tabular-nums; }
.pr-parede-cab .pr-risco { margin-left: auto; font-size: 12px; font-weight: 600;
    color: var(--danger, #e3525b); }
.pr-board { --pr-passo: 22px; padding: 26px 16px 20px;
    background:
      radial-gradient(circle at 6px 6px, #aebbc9 0 2px, transparent 2.4px) 0 0/var(--pr-passo) var(--pr-passo),
      linear-gradient(160deg, #dfe7ef 0%, #d4dde7 100%); }
.pr-prateleira { display: grid; gap: 16px 12px;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 140px), 1fr)); }
.pr-vazio { padding: 26px 4px; text-align: center; color: var(--text-soft, #66778a);
    font-size: 13.5px; }

/* ── a figurinha ─────────────────────────────────────────────────────────── */
.pr-sticker {
    position: relative; display: flex; flex-direction: column; text-align: left;
    background: #fff; border: 1px solid #dbe3ec; border-radius: 14px; padding: 0;
    cursor: pointer; font: inherit; color: inherit;
    box-shadow: 0 2px 4px rgba(9, 22, 38, .06), 0 10px 22px rgba(9, 22, 38, .07);
    transition: transform .16s ease, box-shadow .16s ease; transform-origin: 50% -10px;
}
.pr-sticker:hover { transform: rotate(-1.1deg) translateY(-2px);
    box-shadow: 0 4px 8px rgba(9, 22, 38, .09), 0 16px 30px rgba(9, 22, 38, .12); }
/* o gancho: é ele que faz a figurinha parecer pendurada no furo */
.pr-sticker::before { content: ""; position: absolute; left: 50%; top: -11px;
    width: 11px; height: 13px; transform: translateX(-50%);
    border: 2px solid #95a5b6; border-bottom: 0; border-radius: 6px 6px 0 0; }
.pr-foto { position: relative; aspect-ratio: 1/1; max-width: 100%;
    border-radius: 13px 13px 0 0; overflow: hidden; background: var(--panel-muted, #f4f7fb);
    display: grid; place-items: center; }
.pr-foto svg { width: 46%; height: 46%; color: var(--text-soft, #66778a); opacity: .55; }
.pr-foto img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pr-sem-foto { position: absolute; left: 6px; bottom: 6px; font-size: 10px; font-weight: 700;
    letter-spacing: .04em; text-transform: uppercase; color: var(--text-soft, #66778a);
    background: #fff; border: 1px solid #dbe3ec; border-radius: 999px; padding: 2px 7px; }
.pr-nome { font-size: 12.5px; font-weight: 600; line-height: 1.25; padding: 9px 10px 0;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.pr-pe { display: flex; align-items: center; justify-content: space-between; gap: 6px;
    padding: 7px 10px 9px; }
.pr-qtd { font-size: 19px; font-weight: 700; font-variant-numeric: tabular-nums;
    letter-spacing: -.02em; line-height: 1; }
.pr-qtd small { font-size: 11px; font-weight: 600; color: var(--text-soft, #66778a); margin-left: 3px; }
.pr-selo { font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
    padding: 3px 7px; border-radius: 999px; white-space: nowrap; }
.pr-selo.is-zerado { background: #fdeaec; color: #a8323b; border: 1px solid #f3c2c6; }
.pr-selo.is-baixo { background: #fdf3de; color: #8a6206; border: 1px solid #f2ddab; }
.pr-selo.is-fora { background: var(--panel-muted, #f4f7fb); color: var(--text-soft, #66778a);
    border: 1px solid var(--line, #e5ebf2); }
.pr-faixa { position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
    border-radius: 14px 0 0 14px; background: var(--danger, #e3525b); }

/* ── a gaveta ────────────────────────────────────────────────────────────── */
.pr-fundo { position: fixed; inset: 0; background: rgba(6, 16, 25, .5); z-index: 1040; }
/* ⚠️⚠️ **`display:flex` GANHA DO `[hidden]` DO NAVEGADOR.** A gaveta nasce com
   o atributo `hidden` no template e ainda assim apareceu aberta, vazia, na
   primeira carga em produção — meio metro de painel branco com dois travessões,
   comendo a lateral da parede. A regra do agente de usuário (`[hidden]{display:none}`)
   é vencida por qualquer seletor de classe que declare `display`. */
.pr-gaveta[hidden], .pr-fundo[hidden] { display: none !important; }
.pr-gaveta {
    position: fixed; z-index: 1041; background: #fff; color: var(--text, #13212d);
    display: flex; flex-direction: column; right: 0; top: 0; bottom: 0;
    width: min(420px, 100%); border-left: 1px solid var(--line, #e5ebf2); overflow-y: auto;
}
@media (max-width: 680px) {
    .pr-gaveta { right: 0; left: 0; top: auto; width: auto; max-height: 88vh;
        border-left: 0; border-top: 1px solid var(--line, #e5ebf2);
        border-radius: 20px 20px 0 0; }
}
.pr-gaveta-cab { display: flex; align-items: flex-start; gap: 10px; padding: 16px 16px 12px;
    border-bottom: 1px solid var(--line, #e5ebf2); position: sticky; top: 0; background: #fff; z-index: 1; }
.pr-gaveta-cab h3 { margin: 0; font-size: 16px; line-height: 1.25; flex: 1; min-width: 0; }
.pr-cod { margin: 3px 0 0; font-size: 11.5px; color: var(--text-soft, #66778a);
    font-variant-numeric: tabular-nums; }
.pr-fechar { border: 1px solid var(--line, #e5ebf2); background: #fff; color: var(--text, #13212d);
    border-radius: 10px; width: 32px; height: 32px; flex: 0 0 auto; cursor: pointer;
    font-size: 16px; line-height: 1; }
.pr-gaveta-corpo { padding: 16px; display: flex; flex-direction: column; gap: 18px; }
/* ⚠️ A LINHA DE ESTADO DA GAVETA. Vazia não ocupa espaço; o erro é vermelho.
   Ela nasceu do dia (12/09/2026) em que a parede NÃO disse que o ajuste de
   inventário tinha falhado — o `avisar()` procurava um toast inexistente e
   caía no console. */
.pr-estado:empty { display: none; }
.pr-estado { margin: 0 16px 8px; font-weight: 600; font-size: 13px; }
.pr-estado.is-ok { color: #16a34a; }
.pr-estado.is-erro { color: #dc2626; }
.pr-secao > h4 { margin: 0 0 8px; font-size: 11px; font-weight: 700; letter-spacing: .07em;
    text-transform: uppercase; color: var(--text-soft, #66778a); }
.pr-moldura { aspect-ratio: 4/3; max-width: 100%; border-radius: var(--radius-sm, 12px);
    background: var(--panel-muted, #f4f7fb); border: 1px dashed var(--line, #e5ebf2);
    display: grid; place-items: center; gap: 8px; text-align: center; padding: 14px;
    overflow: hidden; }
.pr-moldura img { width: 100%; height: 100%; object-fit: contain; }
.pr-moldura p { margin: 0; font-size: 12.5px; color: var(--text-soft, #66778a);
    max-width: 32ch; line-height: 1.45; }
.pr-acoes-foto { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.pr-stepper { display: flex; align-items: center; border: 1px solid var(--line, #e5ebf2);
    border-radius: 12px; overflow: hidden; max-width: 230px; }
.pr-stepper button { border: 0; background: var(--panel-muted, #f4f7fb); color: var(--text, #13212d);
    width: 46px; height: 46px; font-size: 20px; cursor: pointer; line-height: 1; }
.pr-stepper input { flex: 1; min-width: 0; border: 0; height: 46px; text-align: center;
    font-size: 19px; font-weight: 700; background: #fff; color: var(--text, #13212d);
    font-variant-numeric: tabular-nums; }
.pr-local-linha { display: flex; align-items: center; justify-content: space-between;
    gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--line, #e5ebf2); font-size: 13px; }
.pr-local-linha:last-child { border-bottom: 0; }
.pr-nota { margin: 8px 0 0; font-size: 12px; color: var(--text-soft, #66778a); line-height: 1.5; }
.pr-nota.is-alerta { color: #8a6206; }
.pr-quem { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.pr-quem li { display: flex; justify-content: space-between; gap: 10px; font-size: 13px;
    padding: 7px 0; border-bottom: 1px solid var(--line, #e5ebf2); }
.pr-quem li:last-child { border-bottom: 0; }
.pr-quem span { color: var(--text-soft, #66778a); font-variant-numeric: tabular-nums;
    white-space: nowrap; }
.pr-caract-linha { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr) 32px;
    gap: 8px; align-items: center; margin-bottom: 8px; }
.pr-caract-linha > span { font-size: 12.5px; font-weight: 600; }
.pr-caract-linha select, .pr-caract-linha input { width: 100%; height: 38px; border-radius: 10px;
    border: 1px solid var(--line, #e5ebf2); background: #fff; color: var(--text, #13212d);
    padding: 0 10px; font-size: 13px; }
.pr-caract-tirar { border: 1px solid var(--line, #e5ebf2); background: #fff; border-radius: 9px;
    width: 32px; height: 32px; cursor: pointer; color: var(--text-soft, #66778a); }
/* ⚠️ O switcher Parede/Tabela. As duas vistas são o padrão da casa (o PILAR
   das *duas visualizações*): a parede é pra RECONHECER a peça, a tabela é pra
   CRUZAR número com número. Nenhuma é "a de verdade". */
.pr-vistas { display: inline-flex; gap: 4px; margin: 0 0 2px; }
.pr-mini { width: 34px; height: 34px; border-radius: 8px; object-fit: cover;
    display: block; border: 1px solid var(--line, #e5ebf2); }
/* O drill da parede: a trilha e o card que é GRUPO. */
.pr-trilha { display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
    font-size: 12.5px; color: var(--text-soft, #66778a); }
.pr-trilha button { border: 1px solid var(--line, #e5ebf2); background: #fff;
    color: var(--text, #13212d); border-radius: 999px; padding: 4px 11px;
    font-size: 12.5px; font-weight: 600; cursor: pointer; }
.pr-trilha span { opacity: .6; }
.pr-sticker.is-grupo { background:
    linear-gradient(180deg, #fff 0%, #fff 84%, var(--panel-muted, #f4f7fb) 100%); }
/* ⚠️ As duas bordas deslocadas são a PILHA: um grupo tem que parecer vários
   cartões antes de alguém tocar nele, senão ele passa por um item só e o
   número agregado é lido como o de uma peça. */
.pr-sticker.is-grupo::after { content: ""; position: absolute; inset: 6px -5px -5px 6px;
    border: 1px solid #cfd9e4; border-radius: 14px; z-index: -1; background: #fff; }
.pr-quantos { font-size: 10px; font-weight: 700; letter-spacing: .04em;
    text-transform: uppercase; padding: 3px 7px; border-radius: 999px;
    background: var(--panel-muted, #f4f7fb); color: var(--text-soft, #66778a);
    border: 1px solid var(--line, #e5ebf2); white-space: nowrap; }
.pr-dim { display: inline-flex; align-items: center; gap: 6px; }
.pr-dim button { border: 0; background: transparent; cursor: pointer;
    color: var(--text-soft, #66778a); font-size: 13px; line-height: 1; }

/* ── ARRUMAR: a pasta e o arraste (a pastinha do iPhone) ──────────────────────
   *"colocar um dentro do outro ou tirar e por aí vai"* (Marcos, 11/09/2026).
   ⚠️ O modo existe porque são TRÊS gestos no mesmo dedo — rolar, tocar pra abrir
   e arrastar. `touch-action:none` só vale DENTRO do modo, senão o arraste rouba
   a rolagem da parede, que é a única forma de navegar 38 cartões no celular. */
.pr-wrap.is-arrumando .pr-sticker { touch-action: none; cursor: grab; }
.pr-wrap.is-arrumando .pr-sticker { animation: prTremer 1.1s ease-in-out infinite; }
.pr-wrap.is-arrumando .pr-sticker:nth-child(2n) { animation-delay: -.35s; }
.pr-wrap.is-arrumando .pr-sticker:nth-child(3n) { animation-delay: -.7s; }
@keyframes prTremer {
    0%, 100% { transform: rotate(-.7deg); }
    50%      { transform: rotate(.7deg); }
}
/* ⚠️ Quem pediu menos movimento não recebe a parede inteira tremendo: o modo
   continua existindo, só não balança. */
@media (prefers-reduced-motion: reduce) {
    .pr-wrap.is-arrumando .pr-sticker { animation: none; }
    .pr-wrap.is-arrumando .pr-sticker { outline: 2px dashed var(--primary, #11adb4);
        outline-offset: 2px; }
}
.pr-sticker.is-levando { opacity: .35; }
/* ⚠️ `pointer-events:none` NO FANTASMA: sem isso o `elementFromPoint` devolve
   sempre ele mesmo e nenhum alvo é encontrado — o arraste vira um cartão
   flutuando que nunca solta em lugar nenhum. */
.pr-fantasma {
    position: fixed; z-index: 1060; pointer-events: none; margin: 0;
    box-shadow: 0 10px 20px rgba(9, 22, 38, .18), 0 30px 60px rgba(9, 22, 38, .22);
    transform-origin: 50% 50%; animation: none !important;
}
.pr-sticker.is-alvo, [data-pr-voltar].is-alvo {
    outline: 3px solid var(--primary, #11adb4); outline-offset: 2px;
}
.pr-sticker.is-pasta .pr-foto {
    background: repeating-linear-gradient(135deg, #e7edf4 0 8px, #dfe7ef 8px 16px);
}
.pr-sticker.is-pasta .pr-foto::after {
    content: "📁"; position: absolute; left: 6px; top: 6px; font-size: 15px;
}
.pr-pasta-lapis {
    position: absolute; right: -7px; top: -7px; width: 24px; height: 24px;
    border-radius: 50%; background: #fff; border: 1px solid var(--line-strong, #d3dde8);
    display: grid; place-items: center; font-size: 12px; cursor: pointer;
    box-shadow: 0 2px 6px rgba(9, 22, 38, .18); z-index: 2;
}
.pr-renome { width: 100%; font: inherit; border: 1px solid var(--line, #e5ebf2);
    border-radius: 8px; padding: 4px 6px; }
.pr-apagar-pasta { margin-top: 6px; width: 100%; font-size: 11px; font-weight: 600;
    border: 1px solid #f3c2c6; background: #fdeaec; color: #a8323b;
    border-radius: 8px; padding: 4px 6px; cursor: pointer; }
.pr-secao select[data-pr-mover] { width: 100%; height: 38px; border-radius: 10px;
    border: 1px solid var(--line, #e5ebf2); background: #fff; padding: 0 10px;
    font-size: 13px; color: var(--text, #13212d); }
/* ⚠️ Acrescentar característica fica num `<details>` FECHADO: a gaveta é
   estreita (celular), e um formulário de três campos sempre aberto empurraria
   pra baixo da dobra o que a pessoa veio ver — o valor das que o item já tem. */
.pr-caract-nova { margin-top: 10px; border-top: 1px solid var(--line, #e5ebf2);
    padding-top: 10px; }
.pr-caract-nova > summary { cursor: pointer; font-size: 12.5px; font-weight: 600;
    color: var(--primary, #11adb4); list-style: none; }
.pr-caract-nova > summary::-webkit-details-marker { display: none; }
.pr-caract-nova select, .pr-caract-nova input { width: 100%; height: 38px;
    border-radius: 10px; border: 1px solid var(--line, #e5ebf2); background: #fff;
    color: var(--text, #13212d); padding: 0 10px; font-size: 13px; }
.pr-caract-nova input[hidden] { display: none; }

/* ── A LINHA DO "COMO VER": vista + juntar por ────────────────────────────────
   *"ainda não está legal esse agrupamento nem intuitivo nem fluido"* (Marcos,
   11/09/2026). Era um `<details>` chamado "Agrupar" no fim de uma fileira de
   oito chips iguais, com "Primeira palavra do nome" escondido dentro. Agora os
   níveis ficam À VISTA — um toque escolhe, um toque desfaz. */
.pr-comover { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; }
.pr-juntar { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.pr-juntar-linha { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.pr-juntar-rot { font-size: 11px; font-weight: 700; letter-spacing: .06em;
    text-transform: uppercase; color: var(--text-soft, #66778a); margin-right: 2px; }
/* ⚠️ O nível EXTRA é mais quieto: ele é uma oferta, não uma escolha pendente.
   Com o mesmo peso do primeiro, a parede pareceria ter dois agrupamentos. */
.pr-juntar-linha[data-pr-nivel-extra] { opacity: .72; }
.pr-juntar-linha[data-pr-nivel-extra]:hover,
.pr-juntar-linha[data-pr-nivel-extra]:focus-within { opacity: 1; }
.pr-juntar .pr-chip { padding: 5px 11px; font-size: 12.5px; }
@media (max-width: 680px) {
    /* No celular a fileira rola de lado em vez de embrulhar: três linhas de
       chips empurrariam a parede pra baixo da dobra. */
    .pr-juntar-linha { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
    .pr-juntar-linha::-webkit-scrollbar { display: none; }
}

/* ── O CATÁLOGO DE CARACTERÍSTICAS, ciente do produto ────────────────────────
   *"deve começar mostrando nesse caso aqui só a parte de tamanhos numéricos, o
   resto todas deveriam estar recolhidas expansíveis, e em cada uma delas deve
   ter botão de desassociar ao produto e trazer pro produto"* (Marcos,
   11/09/2026). O modal listava as dezenas do Omie inteiro em pé de igualdade —
   e a que interessava estava perdida no meio. */
.crcat-secao { margin-bottom: 14px; }
.crcat-secao > h5, .crcat-outras > summary {
    margin: 0 0 8px; font-size: 11px; font-weight: 700; letter-spacing: .06em;
    text-transform: uppercase; color: var(--text-soft, #66778a);
}
.crcat-secao > h5 span, .crcat-outras > summary span {
    display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: 999px;
    background: var(--panel-muted, #f4f7fb); border: 1px solid var(--line, #e5ebf2);
    font-size: 10.5px; letter-spacing: 0; font-variant-numeric: tabular-nums;
}
.crcat-outras > summary { cursor: pointer; list-style: none; color: var(--primary, #11adb4); }
.crcat-outras > summary::-webkit-details-marker { display: none; }
.crcat-outras > summary::before { content: "▸ "; }
.crcat-outras[open] > summary::before { content: "▾ "; }
/* ⚠️ Trazer/tirar é OUTRO ESCOPO que renomear e apagar (aqueles valem pra
   empresa inteira; este, só pra este produto) — por isso o botão é separado
   visualmente dos outros dois. */
.crcat-vinculo { border-color: var(--primary, #11adb4) !important;
    color: var(--primary, #11adb4) !important; }

/* ══════════ ORÇAMENTOS — o menu de ações e o modal de e-mail ══════════════
   ⚠️ Isto morava inline no template, junto com o JS e com `onclick=` em cada
   linha. Componente desta casa são TRÊS coisas — JS, CSS e markup —, e o CSS
   de tela mora aqui, no arquivo único. */
.orc-dropdown { position: absolute; right: 0; top: 100%; margin-top: 4px;
  background: #fff; border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0,0,0,.12); z-index: 50; min-width: 180px;
  overflow: hidden; }
/* ⚠️ `[hidden]` do HTML perde pra `display` de classe — a lição do badge que
   mostrava "0" no widget de Suporte. Aqui a classe não declara display, mas a
   trava fica escrita: quem acrescentar um `display:` acima não reabre o bug. */
.orc-dropdown[hidden] { display: none !important; }
.orc-menu-item { display: block; width: 100%; text-align: left; padding: 9px 16px;
  font: inherit; font-size: 13px; background: none; border: none; cursor: pointer;
  color: var(--text); text-decoration: none; }
.orc-menu-item:hover { background: var(--panel-muted); }
.orc-menu-perigo { color: #dc2626; }
.orc-dropdown hr { margin: 2px 0; border: none; border-top: 1px solid var(--line); }

.orc-overlay { position: fixed; inset: 0; background: rgba(0,0,0,.48);
  z-index: 200; display: flex; align-items: center; justify-content: center;
  padding: 20px; }
.orc-overlay[hidden] { display: none !important; }
.orc-modal { background: #fff; border-radius: 18px; padding: 24px;
  width: 100%; max-width: 520px; max-height: 90vh; overflow: auto;
  box-shadow: 0 20px 60px rgba(0,0,0,.2); }
.orc-modal-head { display: flex; justify-content: space-between;
  align-items: center; gap: 12px; margin-bottom: 18px; }
.orc-modal-head h3 { margin: 0; font-size: 17px; }
.orc-modal-x { background: none; border: none; font-size: 22px; cursor: pointer;
  color: #627385; line-height: 1; padding: 0 4px; }
.orc-email-fb { margin-top: 12px; font-size: 13px; }
.orc-email-fb[hidden] { display: none !important; }
@media (max-width: 680px) { .orc-overlay { padding: 12px; } .orc-modal { padding: 18px; } }

/* ══════════ O FORMULÁRIO DE ORÇAMENTO ════════════════════════════════════
   ⚠️ Os itens e as parcelas eram `<table>` com o kit de tabela rica — filtrar
   e ordenar uma tabela que se EDITA não faz sentido, e o modo Cards dele
   brigava com os campos. Aqui cada linha é uma GRADE que vira CARTÃO no
   celular: o mesmo dado, sem duas engines disputando o mesmo markup. */
.orc-linhas { display: grid; gap: 10px; margin-top: 12px; }
.orc-linha {
  position: relative; display: grid; gap: 8px 10px; align-items: end;
  padding: 12px 40px 12px 12px; border: 1px solid var(--line);
  border-radius: 12px; background: #fff;
  grid-template-columns: minmax(0,2.4fr) 64px minmax(0,1.4fr) 80px 110px 80px 110px;
}
.orc-linha-pag { grid-template-columns: minmax(0,1.6fr) 90px 120px 150px minmax(0,1.4fr); }
.orc-col { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.orc-rot { font-size: .68rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .03em; color: var(--muted, #64748b); }
.orc-col input, .orc-col select { width: 100%; min-width: 0; box-sizing: border-box; }
.orc-col-total b { font-size: .95rem; font-weight: 800; color: #064e3b;
  padding: 9px 0; display: block; text-align: right; }
.orc-col-qtd input, .orc-col-descpct input { text-align: center; }
.orc-col-preco input { text-align: right; }
/* ⚠️ O remover fica FORA da grade, no canto: dentro dela ele virava uma coluna
   de 40px que empurrava tudo, e no celular sobrava um botão solto no meio dos
   campos sem dizer de que linha era. */
.orc-remover { position: absolute; top: 8px; right: 8px; width: 28px; height: 28px;
  border: none; background: none; color: #dc2626; font-size: 18px; line-height: 1;
  cursor: pointer; border-radius: 8px; }
.orc-remover:hover { background: #fee2e2; }
.orc-vazio { padding: 24px; text-align: center; color: #9ca3af; font-size: .9rem; }
.orc-vazio[hidden] { display: none !important; }

.orc-aviso { border: 1px solid #f0d79a; background: #fff8e6; color: #7a5a11;
  border-radius: 12px; padding: 12px 14px; font-size: .86rem; }
.orc-aviso ul { margin: 6px 0; padding-left: 18px; }
.orc-aviso span { display: block; margin-top: 4px; opacity: .9; }
.orc-hint { display: block; margin-top: 4px; font-size: .76rem; color: var(--muted, #64748b); }
.orc-hint[hidden] { display: none !important; }
.orc-hint.is-ruim { color: #b45309; font-weight: 700; }

.orc-resumo { margin-top: 12px; margin-left: auto; max-width: 460px; }
.orc-resumo-linha { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.orc-resumo-linha > span { color: var(--muted, #64748b); font-size: .9rem; }
.orc-resumo-linha input { width: 130px; text-align: right; }
.orc-resumo-total { border-bottom: none; padding-top: 14px; }
.orc-resumo-total span { font-size: 1rem; font-weight: 800; color: #064e3b; }
.orc-resumo-total b { font-size: 1.4rem; font-weight: 800; color: #064e3b; }
.orc-desconto { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  justify-content: flex-end; }
.orc-desconto input { width: 110px; }
.orc-desconto small { width: 100%; text-align: right; font-size: .74rem;
  color: var(--muted, #64748b); }
/* O par %/R$ — a unidade do desconto fica VISÍVEL o tempo todo: é ela que diz
   se "300" são trezentos reais ou trezentos por cento. */
.orc-unidade { display: inline-flex; border: 1px solid var(--line); border-radius: 9px;
  overflow: hidden; }
.orc-unidade button { border: none; background: #fff; color: var(--muted, #64748b);
  font: inherit; font-weight: 700; font-size: .82rem; padding: 7px 12px; cursor: pointer; }
.orc-unidade button.is-on { background: var(--brand-grad, linear-gradient(135deg,#8fcb3a,#11adb4));
  color: #fff; }

.orc-previa { margin-top: 12px; border: 1px solid var(--line); border-radius: 12px;
  padding: 12px 14px; background: var(--panel-muted, #f7fafc); font-size: .86rem; }
.orc-previa[hidden] { display: none !important; }
.orc-previa ol { margin: 8px 0 6px; padding: 0; list-style: none; display: grid; gap: 5px; }
.orc-previa li { display: flex; justify-content: space-between; gap: 12px;
  border-bottom: 1px dashed var(--line); padding-bottom: 4px; }
.orc-previa small { color: var(--muted, #64748b); }
.orc-previa-ruim { color: #b91c1c; }
/* ⚠️ `.field` desta casa é GRID, não flex — então `flex-direction` nele não
   faz nada, e a caixinha ficava em cima do rótulo ("Dias úteis" embaixo de um
   quadradinho solto). Medido em produção. Aqui ele vira flex de verdade. */
.orc-check { display: flex !important; flex-direction: row !important;
  align-items: center; gap: 8px; }
.orc-check input { width: auto; flex: 0 0 auto; }
.orc-check span { font-size: .84rem; }
.orc-area { resize: vertical; height: auto; padding: 10px 14px; border-radius: 12px;
  border: 1px solid var(--line); font: inherit; width: 100%; }
.orc-acoes { display: flex; gap: 10px; flex-wrap: wrap; justify-content: flex-end;
  align-items: center; padding: 16px 22px; }

@media (max-width: 900px) {
  /* ⚠️ Uma coluna por campo, com o rótulo em cima — é o cartão. Sem isto, sete
     colunas num celular viram sete campos de 40px, e o nome do produto não
     cabe em nenhum. */
  .orc-linha, .orc-linha-pag { grid-template-columns: 1fr 1fr; }
  .orc-col-produto, .orc-col-desc { grid-column: 1 / -1; }
  .orc-col-total b { text-align: left; }
  .orc-resumo { max-width: none; }
  .orc-acoes { justify-content: stretch; }
  .orc-acoes .btn { flex: 1 1 140px; }
}

/* Nota do que a Receita NÃO informa (espelho de cadastro). Cinza e pequena:
   é contexto, não erro — vermelho aqui treinaria a pessoa a ignorar vermelho. */
.esp-nota { margin-top: 6px; font-size: .78rem; color: var(--muted, #64748b);
  padding-left: 2px; }

/* ══════════ O PAPEL E A VOZ NO PEDIDO DE PAGAMENTO ════════════════════════
   ⚠️ Fica ACIMA do wizard e RECOLHIDO: é atalho, não pedágio. Quem tem o dado
   na cabeça digita e segue — abrir isto na cara de todo mundo faria a tela
   parecer que exige um papel que nem sempre existe. */
.apr-papel { border: 1px solid var(--line, #e2e8ed); border-radius: 12px;
  background: var(--panel-muted, #f7fafc); margin-bottom: 12px; }
.apr-papel > summary { cursor: pointer; padding: 11px 14px; display: flex;
  align-items: center; gap: 8px; flex-wrap: wrap; font-size: .9rem; }
.apr-papel > summary span { color: var(--muted, #64748b); font-size: .82rem;
  flex: 1 1 240px; min-width: 0; }
.apr-papel-corpo { padding: 0 14px 14px; }
.apr-papel-botoes { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.apr-papel-botoes .btn { cursor: pointer; }
.apr-papel-estado { font-size: .82rem; color: var(--muted, #64748b); }
.apr-papel-estado.is-ruim { color: #b91c1c; font-weight: 700; }
.apr-papel-faixa { margin-top: 10px; border: 1px solid #cfe3ea; background: #f2fbfd;
  border-radius: 10px; padding: 10px 12px; font-size: .85rem; display: grid; gap: 6px; }
.apr-papel-faixa[hidden] { display: none !important; }
.apr-papel-aviso { color: #b45309; }
.apr-papel-nota { color: var(--muted, #64748b); }
.apr-papel-troca { display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  justify-content: space-between; border-top: 1px dashed #cfe3ea; padding-top: 6px; }
.apr-papel-troca span { flex: 1 1 200px; min-width: 0; }
/* Gravando: vermelho e pulsando — é o único estado da tela em que o microfone
   do aparelho está ligado, e isso não pode ser discreto. */
.is-gravando { background: #fee2e2 !important; border-color: #fecaca !important;
  color: #b91c1c !important; animation: apr-pulsa 1.1s ease-in-out infinite; }
@keyframes apr-pulsa { 50% { opacity: .62; } }

/* ══════════ ANEXOS DO CONTRATO (chamado #22) ══════════════════════════════
   ⚠️ Mesma família visual dos aditivos (`.cte-adit-*`): são as duas listas do
   mesmo modal, e desenhá-las diferente faria parecer que uma é mais oficial
   que a outra. */
.cte-anx-list { display: grid; gap: 6px; }
.cte-anx-item { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  border: 1px solid var(--line, #e5ebf2); border-radius: 10px; padding: 8px 10px;
  background: #fff; }
.cte-anx-nome { font-weight: 600; color: var(--primary, #11adb4);
  text-decoration: none; min-width: 0; overflow-wrap: anywhere; }
.cte-anx-meta { font-size: .75rem; color: var(--text-muted, #627385);
  margin-left: auto; }
.cte-anx-selo { font-size: .68rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; background: #eef6fb; color: #11707a; border-radius: 6px;
  padding: 2px 6px; }
.cte-anx-add { display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  margin-top: 10px; }
.cte-anx-btn { cursor: pointer; font-size: .8rem; font-weight: 700;
  border: 1px solid var(--line, #e5ebf2); border-radius: 10px; padding: 7px 12px;
  background: #fff; }
.cte-anx-estado { font-size: .78rem; color: var(--text-muted, #627385); }
@media (max-width: 680px) {
  .cte-anx-meta { margin-left: 0; width: 100%; }
  .cte-anx-add { flex-direction: column; align-items: stretch; }
}

/* O contrato de onde o preço veio, na linha da regra comercial. */
.rc-contrato { display: inline-flex; align-items: center; gap: 6px;
  font-size: .74rem; font-weight: 700; border-radius: 999px; padding: 2px 9px;
  background: #eef6fb; color: #11707a; border: 1px solid #cfe3ea; }
.rc-contrato.is-vazio { background: #f8fafc; color: #64748b; border-color: #e2e8f0;
  font-weight: 600; }

/* ═══════════════════════════════════════════════════════════════════════════
   O ALVO DE TOQUE — chamado #32 (15/09/2026)
   ═══════════════════════════════════════════════════════════════════════════

   *"Um monte de bug ao clicar nos botões no iPad, praticamente inutilizável de
   tão grave e mal feito"* (Marcos, sobre a aba de fechamento).

   ⚠️⚠️ MEDIDO, não suposto: `node scripts/medir_largura.mjs /modulos/fechamento
   --largura 820 --toque` devolveu a caixa de seleção de CADA LINHA com
   **15x15 px**, a seta de expandir com **22x18**, o nome do cliente clicável
   com 23 de altura e os botões da barra da tabela com 25–27. O mínimo do guia
   da Apple é **44x44** — e o dedo não tem a precisão do cursor.

   ## ⚠️⚠️ EXPANDIR POR PSEUDO-ELEMENTO NÃO FUNCIONA EM TABELA DENSA

   A primeira versão deste bloco estendia o alvo com um `::after` invisível, pra
   não refluir uma tabela de 40 linhas. A régua (corrigida) provou que não
   funciona: o pseudo fica no fundo da pilha e **perde o ponto pro vizinho
   pintado depois**. Pra ganhar precisaria de `z-index` positivo — e aí passaria
   a roubar o toque do controle ao lado, que é o defeito que isto conserta, ao
   contrário.

   Então o controle **cresce de verdade**, e só onde se toca:
   `@media (pointer: coarse)`. No computador nada muda — estas tabelas são
   densas de propósito, e aumentar tudo lá pioraria a tela que está certa. No
   tablet a linha fica mais alta, que é o que toda interface de toque faz.

   ⚠️ Lista NOMEADA, de propósito: regra cega em todo clicável estenderia alvo
   dentro de menu denso e faria um roubar o toque do outro. Alvo novo pequeno é
   achado pela régua, não por adivinhação.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (pointer: coarse) {
    /* caixa de seleção: `padding` não vale em `input[type=checkbox]` (o
       navegador desenha o controle no tamanho da caixa), então é width/height
       mesmo. 44 é grande — e é o tamanho de um dedo. */
    /* ⚠️⚠️ TAMANHO DE VERDADE, e a régua é quem decidiu isso. Tentei antes
       `width: 26px` + `transform: scale(1.7)` — a ideia era crescer o alvo sem
       ocupar espaço na linha, já que `transform` entra no teste de acerto. A
       medição devolveu **26x26**: não pegou. Em vez de teorizar por que, a
       régua julgou e o caminho é o simples. 44 é grande numa tabela — e é o
       tamanho de um dedo. */
    .fech-merge-chk,
    #fech-merge-all,
    .fech-pending-wrap input[type="checkbox"] {
        /* ⚠️⚠️ `!important` E ELE É NECESSÁRIO — medido, não por gosto. O reset
           global `input[type="checkbox"] { width: auto }` (linha 43) existe
           porque um `.form-control` genérico inflava a caixa em qualquer modal,
           e no caminho deste elemento ele venceu até o seletor de ID. O
           `!important` já é o recurso usado pra ESTA MESMA caixa na tabela-card
           do celular (busque `td:first-child input[type="checkbox"]`), pela
           mesma razão. Fica contido dentro do `pointer: coarse`: no computador
           nada disto existe. */
        width: 44px !important;
        height: 44px !important;
    }
    .fech-caret,
    .xcols-btn,
    .xcols-minus,
    .rf-btn,
    .fech-chip-btn,
    .logout-link,
    .sidebar-toggle,
    .freight-tab,
    .flash-btn,
    .fcfilter-tools .btn {
        min-width: 44px;
        min-height: 44px;
    }
    /* o nome do cliente é um <strong> clicável dentro da célula: altura vem do
       padding, senão a linha de texto tem 23px e mais nada. */
    .fech-entity-name {
        display: inline-flex;
        align-items: center;
        min-height: 44px;
    }
    /* o <select> do filtro por coluna tinha 38 de largura. ⚠️ `select.rf-op`
       com a TAG: a regra de origem é `.rf-th .rf-op` e sem subir a
       especificidade a largura de lá continuava valendo — a mesma lição do
       #25, no mesmo dia. */
    .rf-th select.rf-op,
    .rf-th .rf-fwrap input {
        min-height: 44px !important;
        min-width: 44px !important;
    }
}

/* ===== A NF DO FECHAMENTO (static/js/fech_nf.js) =====================
   O modal de conferir, emitir e acompanhar a NF das vendas de um fechamento.
   ⚠️ `[hidden]` com !important: o display:flex da classe ganha do [hidden]
   do navegador (a família do .pr-gaveta e do .supw-rate-row). */
.fnf-overlay{position:fixed;inset:0;z-index:10050;background:rgba(15,23,42,.5);
  display:flex;align-items:flex-start;justify-content:center;padding:32px 16px;overflow-y:auto;}
.fnf-overlay[hidden]{display:none !important;}
html.fnf-aberto{overflow:hidden;}
.fnf-card{background:#fff;border-radius:14px;width:100%;max-width:600px;display:flex;flex-direction:column;
  box-shadow:0 24px 64px rgba(0,0,0,.3);max-height:calc(100vh - 64px);min-width:0;}
.fnf-head{display:flex;align-items:flex-start;gap:12px;padding:16px 20px 10px;border-bottom:1px solid var(--line,#e5ebf2);}
.fnf-head-main{min-width:0;flex:1;}
.fnf-titulo{margin:0;font-size:1.05rem;font-weight:800;color:var(--text,#13212d);}
.fnf-sub{margin:3px 0 0;font-size:12.5px;color:var(--text-soft,#66778a);overflow-wrap:anywhere;}
.fnf-x{flex:none;background:none;border:none;cursor:pointer;color:var(--text-soft,#66778a);font-size:20px;line-height:1;padding:4px;border-radius:8px;}
.fnf-x:hover{background:#f1f5f9;color:var(--text,#13212d);}
.fnf-corpo{padding:12px 20px;overflow-y:auto;flex:1;min-height:80px;}
.fnf-aviso{background:#f0fdfa;border:1px solid #99f6e4;border-radius:10px;padding:10px 12px;margin-bottom:12px;
  font-size:12.5px;color:#134e4a;line-height:1.45;}
.fnf-aviso p{margin:0;}
.fnf-aviso p + p{margin-top:4px;color:#3f6f6a;}
.fnf-aviso:empty{display:none;}
.fnf-todas{display:flex;align-items:center;gap:8px;font-size:12.5px;font-weight:600;color:#334155;margin:0 0 8px 2px;cursor:pointer;}
.fnf-todas[hidden]{display:none !important;}
.fnf-lista{display:flex;flex-direction:column;gap:8px;}
.fnf-linha{border:1px solid var(--line,#e5ebf2);border-radius:10px;padding:10px 12px;background:#fff;}
.fnf-linha.is-off{background:#f8fafc;}
.fnf-l-sel{display:flex;align-items:flex-start;gap:10px;cursor:pointer;min-width:0;}
.fnf-linha.is-off .fnf-l-sel{cursor:default;}
.fnf-l-sel input{margin-top:2px;width:17px;height:17px;flex:none;accent-color:#0f766e;}
.fnf-l-main{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1;}
.fnf-l-top{font-size:13px;color:var(--text,#13212d);overflow-wrap:anywhere;}
.fnf-l-prod{font-size:12px;color:var(--text-soft,#66778a);overflow-wrap:anywhere;}
.fnf-l-valor{flex:none;font-weight:700;font-size:13px;color:var(--text,#13212d);white-space:nowrap;}
.fnf-l-estado{margin-top:6px;font-size:12px;display:flex;flex-wrap:wrap;align-items:center;gap:6px;}
.fnf-chip{display:inline-flex;align-items:center;padding:2px 8px;border-radius:999px;font-size:11px;font-weight:700;
  border:1px solid transparent;white-space:nowrap;}
.fnf-chip--sem{background:#fff7ed;color:#9a3412;border-color:#fed7aa;}
.fnf-chip--ok{background:#f0fdf4;color:#166534;border-color:#bbf7d0;}
.fnf-chip--fila{background:#eff6ff;color:#1d4ed8;border-color:#bfdbfe;}
.fnf-chip--atencao{background:#fffbeb;color:#92400e;border-color:#fde68a;}
.fnf-chip--erro{background:#fef2f2;color:#b91c1c;border-color:#fecaca;}
.fnf-chip--cinza{background:#f1f5f9;color:#475569;border-color:#e2e8f0;}
.fnf-motivo{flex-basis:100%;color:#475569;line-height:1.4;overflow-wrap:anywhere;}
.fnf-cand{flex-basis:100%;display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap;
  background:#fffbeb;border:1px solid #fde68a;border-radius:8px;padding:6px 8px;}
.fnf-link{background:none;border:none;padding:0;color:#b45309;text-decoration:underline;cursor:pointer;font-size:12px;}
.fnf-danfe{font-size:12px;font-weight:600;color:#0f766e;}
.fnf-mini{display:inline-flex;width:14px;height:14px;color:#1d4ed8;}
.fnf-mini svg{width:14px;height:14px;animation:fnf-gira 1.2s linear infinite;}
@keyframes fnf-gira{to{transform:rotate(360deg);}}
@media (prefers-reduced-motion: reduce){.fnf-mini svg{animation-duration:3s;}}
.fnf-vazio,.fnf-erro{padding:18px 4px;text-align:center;font-size:13px;color:var(--text-soft,#66778a);}
.fnf-erro{color:#b91c1c;}
.fnf-rodape{border-top:1px solid var(--line,#e5ebf2);padding:10px 20px 14px;display:flex;flex-direction:column;gap:8px;}
.fnf-email{display:flex;align-items:flex-start;gap:8px;font-size:12.5px;color:#334155;cursor:pointer;}
.fnf-email input{margin-top:2px;accent-color:#0f766e;flex:none;}
.fnf-email small{color:var(--text-soft,#66778a);}
.fnf-rodape-linha{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;}
.fnf-resumo{font-size:12.5px;color:#334155;min-width:0;flex:1 1 180px;}
.fnf-botoes{display:flex;gap:8px;margin-left:auto;}
@media (max-width: 680px){
  .fnf-overlay{padding:0;align-items:stretch;}
  .fnf-card{max-width:none;border-radius:0;max-height:none;min-height:100%;
    padding-bottom:env(safe-area-inset-bottom);}
  .fnf-head{padding:14px 16px 10px;}
  .fnf-corpo{padding:12px 16px;}
  .fnf-rodape{padding:10px 16px 14px;position:sticky;bottom:0;background:#fff;}
  .fnf-botoes{width:100%;}
  .fnf-botoes .btn{flex:1;}
}
@media (pointer: coarse){
  .fnf-botoes .btn{min-height:44px;}
  .fnf-l-sel input,.fnf-todas input,.fnf-email input{width:22px !important;height:22px !important;}
  .fnf-x{min-width:44px;min-height:44px;}
  .fnf-cand .btn{min-height:40px;}
}

/* ═══ O SELO "STATUS OMIE" DO FECHAMENTO ═══════════════════════════════════
   Quatro estados, um desenho. O markup mora em `partials/_status_omie.html`
   e o vocabulário em `closing_service.rotulo_status_cr` — aqui é só a cor.

   ⚠️ O estilo era INLINE, repetido em três templates (chamado jm #38): mudar
   a cor de um estado exigia achar as três cópias, e o dia em que um estado
   novo nascesse ele nasceria em uma só. O roxo do crédito é o MESMO do badge
   `CRÉDITO DE CLIENTE` do PDF do fechamento (`pdf_fechamento.py`) — o mesmo
   fato não pode ter duas cores conforme a tela. */
.fech-selo-omie{display:inline-flex;align-items:center;gap:3px;padding:2px 8px;
  border-radius:20px;font-size:11px;font-weight:600;white-space:nowrap;}
.fech-selo-omie.is-pago{background:#f0fdf4;color:#166534;border:1px solid #bbf7d0;}
.fech-selo-omie.is-credito{background:#f5f3ff;color:#5b21b6;border:1px solid #ddd6fe;}
.fech-selo-omie.is-cancelado{background:#f1f5f9;color:#475569;border:1px solid #cbd5e1;}
