:root{
 --bg:#F4F5F8;--surface:#FFFFFF;--surface-2:#F1F3F6;--surface-hover:#E9ECF1;--border:#E1E5EB;--control-border:#818A99;
 --text:#141821;--muted:#626B7A;--accent:#FFD400;--accent-hover:#F2C800;--accent-ink:#1A1600;--accent-text:#7A6200;--accent-soft:#FFF6C2;
 --success:#15803D;--success-soft:#DCFCE7;--warning:#92400E;--warning-soft:#FEF3C7;--danger:#B91C1C;--danger-soft:#FEE2E2;--info:#1D4ED8;--info-soft:#DBEAFE;
 --focus:#1A1600;--sidebar-bg:#FFFFFF;--shadow:0 1px 2px rgba(20,24,33,.06),0 8px 24px rgba(20,24,33,.10);--overlay:rgba(6,8,12,.45);
 --radius:12px;--radius-sm:8px;--radius-lg:16px;--space-1:4px;--space-2:8px;--space-3:12px;--space-4:16px;--space-5:20px;--space-6:24px;--space-8:32px;--space-10:40px;
 --duration:160ms;--ease:cubic-bezier(.2,.7,.3,1);--sidebar-width:264px;--sidebar-collapsed:76px;--header-height:64px;
 --font:"Manrope",system-ui,"Segoe UI",sans-serif;--mono:"JetBrains Mono",ui-monospace,Consolas,monospace;
 color-scheme:light;
}
@media (prefers-color-scheme: dark){:root:not([data-theme="light"]){
 --bg:#0C0E12;--surface:#13161B;--surface-2:#1A1E25;--surface-hover:#222731;--border:#252A33;--control-border:#606C80;
 --text:#F3F5F8;--muted:#98A2B3;--accent:#FFD400;--accent-hover:#FFE24D;--accent-ink:#171400;--accent-text:#FFD400;--accent-soft:#2B2710;
 --success:#3DDC84;--success-soft:#11291C;--warning:#F5B82E;--warning-soft:#2E2510;--danger:#FF7A7A;--danger-soft:#33191D;--info:#7AB0FF;--info-soft:#15243A;
 --focus:#FFE24D;--sidebar-bg:#0F1216;--shadow:0 1px 2px rgba(0,0,0,.4),0 12px 32px rgba(0,0,0,.45);--overlay:rgba(0,0,0,.6);
 color-scheme:dark;
}}
:root[data-theme="dark"]{
 --bg:#0C0E12;--surface:#13161B;--surface-2:#1A1E25;--surface-hover:#222731;--border:#252A33;--control-border:#606C80;
 --text:#F3F5F8;--muted:#98A2B3;--accent:#FFD400;--accent-hover:#FFE24D;--accent-ink:#171400;--accent-text:#FFD400;--accent-soft:#2B2710;
 --success:#3DDC84;--success-soft:#11291C;--warning:#F5B82E;--warning-soft:#2E2510;--danger:#FF7A7A;--danger-soft:#33191D;--info:#7AB0FF;--info-soft:#15243A;
 --focus:#FFE24D;--sidebar-bg:#0F1216;--shadow:0 1px 2px rgba(0,0,0,.4),0 12px 32px rgba(0,0,0,.45);--overlay:rgba(0,0,0,.6);
 color-scheme:dark;
}
*{box-sizing:border-box}
[hidden]{display:none!important}
html{height:100%}
body{margin:0;min-height:100%;font:15px/1.5 var(--font);color:var(--text);background:var(--bg);-webkit-font-smoothing:antialiased}
button,input,select,textarea{font:inherit}
button,a,input,select,textarea,summary{-webkit-tap-highlight-color:transparent}
a{color:var(--accent-text);text-underline-offset:3px}
a:hover{text-decoration-thickness:2px}
svg{width:20px;height:20px;flex:none;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
img,video,audio{max-width:100%}
h1,h2,h3,p{overflow-wrap:anywhere}
h1{font-size:clamp(1.4rem,2vw,1.75rem);font-weight:800;letter-spacing:-.02em;line-height:1.2;margin:0 0 8px;text-wrap:balance}
h2{font-size:1.05rem;line-height:1.35;letter-spacing:-.01em;margin:0 0 10px;font-weight:700}
h3{font-size:.95rem;margin:0 0 6px;font-weight:700}
p{margin:0 0 14px;max-width:78ch}
small,.muted{color:var(--muted);font-size:.875rem}
.small{font-size:.8125rem}
.num{font-variant-numeric:tabular-nums}
.eyebrow{color:var(--muted);font-size:.6875rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;margin:0 0 6px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
:focus-visible{outline:2px solid var(--focus);outline-offset:3px}
:target{scroll-margin-top:calc(var(--header-height) + 16px)}
.skip{position:fixed;left:16px;top:-100px;z-index:100;color:var(--accent-ink);background:var(--accent);padding:12px 20px;border-radius:var(--radius-sm)}
.skip:focus{top:12px}
button,.button{min-height:44px;display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:8px 14px;border:1px solid transparent;border-radius:var(--radius-sm);background:var(--accent);color:var(--accent-ink);text-decoration:none;font-weight:700;font-size:.9rem;line-height:1.4;cursor:pointer;white-space:nowrap;transition:background var(--duration),border-color var(--duration),transform 100ms}
button:hover,.button:hover{background:var(--accent-hover);text-decoration:none}
button:active,.button:active{transform:translateY(1px)}
button.secondary,.button.secondary,a.secondary{background:var(--surface);color:var(--text);border-color:var(--control-border)}
button.secondary:hover,.button.secondary:hover{background:var(--surface-hover)}
button.quiet,.button.quiet{background:transparent;color:var(--muted)}
button.quiet:hover,.button.quiet:hover{background:var(--surface-hover);color:var(--text)}
button.danger,.button.danger{background:var(--danger-soft);color:var(--danger);border-color:var(--danger)}
button.danger:hover,.button.danger:hover{background:var(--surface-hover)}
button.sm,.button.sm{min-height:36px;padding:4px 10px;font-size:.8125rem}
/* aria-disabled, e não disabled, é o que a guarda de envio duplo marca no botão clicado: a lista de
   entradas do formulário é montada depois do submit e um controle desabilitado não entra nela, de
   modo que o par name/value do próprio botão sumiria do POST. O desenho tem de ser o mesmo nos dois. */
button:disabled,button[aria-disabled="true"],.button[aria-disabled="true"]{background:var(--surface-2);color:var(--muted);border-color:var(--border);opacity:.6;cursor:not-allowed;transform:none}
.icon-button,.btn-icon{width:44px;height:44px;padding:8px;color:var(--text);background:transparent;border-color:transparent}
.icon-button:hover,.btn-icon:hover{background:var(--surface-hover)}
/* .field-label é o rótulo de um grupo que não tem um controle único para apontar (chips, por
   exemplo): um <label for> mentiria, então o <span> recebe o mesmo desenho do rótulo de campo. */
label,.field-label{display:block;font-size:.8125rem;font-weight:700;margin:14px 0 6px}
input,select,textarea{display:block;max-width:100%;width:100%;min-height:44px;border:1px solid var(--control-border);border-radius:var(--radius-sm);padding:10px 12px;color:var(--text);background:var(--surface);transition:border-color var(--duration),box-shadow var(--duration)}
input:hover,textarea:hover,select:hover{border-color:var(--muted)}
input:focus,textarea:focus,select:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
input::placeholder,textarea::placeholder{color:var(--muted);opacity:.8}
input[type="hidden"]{display:none}
input[type="checkbox"],input[type="radio"]{width:18px;height:18px;min-height:18px;flex:none;padding:0;margin:2px 0;accent-color:var(--accent)}
input:disabled,select:disabled,textarea:disabled{color:var(--muted);cursor:not-allowed;opacity:.65}
textarea{resize:vertical;min-height:140px;line-height:1.55}
fieldset{min-width:0;border:0;margin:0;padding:0}
legend{font-weight:700;font-size:.8125rem;padding:0 0 6px}
.check{display:flex;gap:10px;align-items:flex-start;min-height:44px;font-weight:500;font-size:.9rem;line-height:1.5}
.field{display:grid;gap:0;margin:0 0 16px}
.field .hint{font-size:.8125rem;color:var(--muted);margin-top:6px}
/* Duas colunas quando cabem, uma quando não cabem. O min(100%,…) é o mesmo cuidado das grades do
   Painel: sem ele o mínimo da trilha ultrapassa o contêiner e o celular ganha rolagem horizontal. */
.field-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,200px),1fr));gap:12px;align-items:start}
.field-pair{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px}
.field-pair > div,.inline-fields > div{min-width:0}
.inline-fields{display:flex;gap:12px;align-items:end;margin-bottom:12px}
.inline-fields > div{flex:1}
.actions{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
.toolbar{display:flex;gap:16px;justify-content:space-between;align-items:center;margin-bottom:20px;flex-wrap:wrap}
/* Item de flex não encolhe além do mínimo do que segura: é a mesma rede das trilhas minmax(0,1fr).
   O bloco de título da barra leva <h1> e subtítulo, e um nome de empresa que não quebra empurraria a
   barra inteira — e com ela a página — para fora da janela do celular. */
.toolbar > *{min-width:0}
.toolbar h1{margin-bottom:0}
.card,.empty{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:18px 20px}
.card-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:14px}
.card-head h2{margin:0}
.card-head .sub{font-size:.8125rem;color:var(--muted);margin:2px 0 0}
.empty{padding:32px 20px;text-align:center;display:grid;gap:8px;justify-items:center}
.empty p{color:var(--muted);margin:0}
.message{padding:12px 14px;margin:14px 0;border:1px solid var(--border);border-left:3px solid var(--warning);border-radius:var(--radius-sm);background:var(--warning-soft);color:var(--text);font-size:.9rem;overflow-wrap:anywhere}
.message[role="alert"],.validation-summary-errors{background:var(--danger-soft);border-left-color:var(--danger)}
.message[role="status"]{border-left-color:var(--accent)}
.validation-summary-valid,.field-validation-valid{display:none}
.field-validation-error,.field-error{display:block;color:var(--danger);font-size:.8125rem;margin-top:6px}
.input-validation-error,[aria-invalid="true"]{border-color:var(--danger)}
.message ul{margin:0;padding-left:20px}
.toast-message,.toast{position:fixed;z-index:70;right:20px;bottom:20px;width:min(440px,calc(100vw - 32px));padding:14px 56px 14px 16px;margin:0;border-radius:10px;background:var(--surface);border:1px solid var(--border);box-shadow:var(--shadow);animation:toast-enter var(--duration) var(--ease)}
.toast-close{position:absolute;top:6px;right:6px;width:44px;height:44px;padding:4px;background:transparent;border-color:transparent;color:var(--text);font-size:22px}
.toast-close:hover{background:var(--surface-hover)}
@keyframes toast-enter{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
.pill{display:inline-flex;gap:6px;align-items:center;font-size:.75rem;font-weight:700;line-height:1.5;padding:3px 9px;border-radius:999px;background:var(--surface-2);color:var(--muted);white-space:nowrap}
.pill .dot{width:7px;height:7px;border-radius:50%;background:currentColor;flex:none}
.pill.ok{background:var(--success-soft);color:var(--success)}
.pill.muted{background:var(--surface-2);color:var(--muted)}
.pill.warn{background:var(--warning-soft);color:var(--warning)}
.pill.bad{background:var(--danger-soft);color:var(--danger)}
.pill.info{background:var(--info-soft);color:var(--info)}
.pill.accent{background:var(--accent-soft);color:var(--accent-text)}
.tag{display:inline-flex;align-items:center;gap:4px;font-size:.75rem;font-weight:600;padding:2px 8px;border-radius:6px;border:1px solid var(--border);color:var(--muted)}
.success{color:var(--success)}
.pending,.warning{color:var(--warning)}
.error{color:var(--danger)}
/* Linha de revisão: nasceu em "Precisa de atenção" no Painel e o passo 4 do editor mostra os mesmos
   quatro itens com o mesmo desenho, então há uma definição só, aqui. */
.attn-list{display:grid;gap:8px}
.attn{display:flex;gap:12px;align-items:flex-start;padding:12px;border-radius:var(--radius-sm);background:var(--surface-2)}
.attn > svg{color:var(--warning);margin-top:2px}
.attn .body{flex:1;min-width:0}
.attn .body b{display:block;font-size:.9rem}
.attn .body span{display:block;font-size:.8125rem;color:var(--muted)}
.attn .body .attn-label{color:var(--warning);font-weight:700}
/* Só os disparadores de popover perdem o triângulo nativo: um <details> comum de conteúdo (as
   configurações de voz do editor, o "Último resultado" de um aviso) precisa do marcador para
   anunciar que abre. Os disparadores estão nomeados um a um, aqui e na linha de cadastro
   (.row-panel, .row-confirm): "Editar nome", "Alterar nome" e "Redefinir senha" deixaram de ser
   <details> de conteúdo na fase 4 e viraram item de menu, painel e confirmação. */
summary{cursor:pointer;min-height:44px;padding:10px 0;font-weight:700;color:var(--text)}
.context-summary,.userbox-summary,[data-menu] > summary{list-style:none;display:flex;align-items:center;gap:8px}
.context-summary::-webkit-details-marker,.userbox-summary::-webkit-details-marker,[data-menu] > summary::-webkit-details-marker{display:none}
details > summary:hover{color:var(--accent-text)}
.tabs{display:inline-flex;gap:2px;padding:3px;border-radius:10px;background:var(--surface-2);flex-wrap:wrap}
.tabs a,.tabs button{min-height:36px;padding:6px 12px;border-radius:8px;border:0;background:transparent;font-weight:700;font-size:.85rem;color:var(--muted);display:inline-flex;gap:6px;align-items:center;text-decoration:none}
.tabs a span,.tabs button span{font-size:.7rem;font-weight:800;padding:0 6px;border-radius:999px;background:var(--surface);color:var(--muted)}
.tabs .on,.tabs [aria-current="page"]{background:var(--surface);color:var(--text);box-shadow:0 1px 2px rgba(0,0,0,.12),0 0 0 1px var(--border)}
/* A aba escolhida tem o mesmo fundo do emblema: sem esta troca o número da única aba que o usuário
   está lendo perde a forma de pílula e vira dígitos soltos ao lado do rótulo. */
.tabs .on span,.tabs [aria-current="page"] span{background:var(--surface-2);color:var(--text)}
.chips{display:flex;flex-wrap:wrap;gap:8px}
.chip{display:inline-flex;align-items:center;gap:6px;min-height:36px;padding:6px 12px;border-radius:999px;border:1px solid var(--border);background:var(--surface);font-size:.8125rem;font-weight:600;color:var(--text);text-decoration:none}
.chip:hover{background:var(--surface-hover);text-decoration:none}
.chip.on,.chip[aria-pressed="true"]{background:var(--accent-soft);border-color:transparent;color:var(--accent-text)}
/* Um chip que é <button> é alvo de toque de verdade e segue os 44 px do projeto; os chips
   decorativos (<span>, <a> de filtro) continuam com 36 px. */
button.chip{min-height:44px}
button.chip:disabled{background:var(--surface-2);color:var(--muted);border-color:var(--border)}
.chip small{color:var(--muted);font-size:.75rem;font-weight:600}
.chip.on small,.chip[aria-pressed="true"] small{color:inherit}
.table-wrap{overflow-x:auto;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface)}
/* Com overflow-x:auto o eixo vertical também vira auto (CSS Overflow 3): a caixa de rolagem corta
   o menu ⋯ e a confirmação de exclusão que abrem para baixo da última linha. A tabela de Avisos é
   table-layout:fixed a 100% e empilha abaixo de 1023 px, então ela nunca precisou rolar. */
.table-wrap-flow{overflow:visible}
table{width:100%;border-collapse:collapse;text-align:left}
th{font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);background:var(--surface-2);padding:12px 16px;border-bottom:1px solid var(--border)}
td{padding:14px 16px;border-bottom:1px solid var(--border);vertical-align:top;overflow-wrap:anywhere}
tr:last-child td{border-bottom:0}
td:first-child{font-weight:600}
td.actions{width:52px;text-align:right}
/* Segunda linha dentro de uma célula: o detalhe que explica o número da linha ("1 conectado ·
   1 desligado" ao lado da contagem de computadores). É irmã da .card-head .sub, mas a célula da
   tabela tem o seu próprio peso e o seu próprio espaçamento, e a folha da página não pode declarar
   componente compartilhado. Empilhada abaixo de 1023 px ela continua sob o valor, não ao lado. */
.cell-sub{display:block;margin-top:2px;font-size:.8125rem;font-weight:400;color:var(--muted)}
form{margin:0}
.rowmenu{position:relative;display:inline-block}
.menu{position:absolute;right:0;top:calc(100% + 4px);min-width:200px;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow);padding:6px;z-index:35;display:grid;gap:2px;text-align:left}
/* Com script, o item do menu ⋯ É o alvo de clique do padrão da linha — o <summary> irmão some
   justamente porque este item o duplica —, então ele segue os 44 px do projeto como qualquer outro
   alvo de toque. Medido a 390 px: o menu continua com a mesma largura e cabe na janela. */
.menu a,.menu button{display:flex;align-items:center;justify-content:flex-start;gap:10px;min-height:44px;padding:8px 10px;border-radius:8px;border:0;background:transparent;font-size:.875rem;font-weight:600;color:var(--text);width:100%;text-align:left;text-decoration:none}
.menu a:hover,.menu button:hover{background:var(--surface-hover);text-decoration:none}
.menu .sep{height:1px;background:var(--border);margin:4px 0}
.menu .danger{color:var(--danger);background:transparent}
/* ── Linha de cadastro: menu ⋯, painel de edição e confirmação de ação perigosa ─────────────────
   O mesmo trio nas seis páginas de estrutura, escrito uma vez só. Quem ancora os três popovers é a
   célula (.row-actions{position:relative}) e nunca o gatilho: ancorado ao gatilho, o popover nasceria
   fora da janela na coluna empilhada abaixo de 1023 px. A /Notices ainda declara a sua própria cópia
   de .row-actions em notices.css, com estes mesmos valores, até adotar as classes compartilhadas. */
.row-actions-cell{text-align:right;white-space:nowrap}
.row-actions{position:relative;display:flex;align-items:center;justify-content:flex-end;gap:4px;flex-wrap:wrap}
.row-panel,.row-confirm{white-space:normal}
/* Os dois <details> da linha são disparadores de popover, não conteúdo: perdem o triângulo como os
   da casca. Dentro da célula de ações o menu ⋯ já oferece a mesma ação quando há script, e aí o
   <summary> da linha sobra: some com a casca marcada, que é o sinal de que o app.js assumiu; sem
   script ele é o único gatilho e continua lá. Fora da célula — o painel de criação na .toolbar, que
   não tem menu nenhum — o <summary> é o gatilho dos dois mundos e nunca some. */
.row-panel > summary{list-style:none}
.row-panel > summary::-webkit-details-marker{display:none}
/* Os 36 px de .sm valem onde a classe é enfeite de tabela. Aqui ela veste o ÚNICO gatilho de quem
   não tem script — com script o menu ⋯ o duplica e ele some —, e um gatilho que é a única porta da
   ação segue os 44 px do projeto. A /Device já fazia o mesmo na folha dela para o rodapé do cartão. */
.row-panel > summary.button.sm{min-height:44px}
.shell-enhanced .row-actions .row-panel > summary{display:none}
/* Alvo de toque inteiro em toda largura, e não só abaixo de 1023 px: este é o gatilho destrutivo das
   seis páginas ("Excluir", "Desativar", "Rejeitar") e um notebook ou tablet com toque entre 1024 e
   1366 px ficava com 36 px. Ao lado do ⋯, que já é 44x44, o alvo maior não estica nada: medido a
   1440 px com script, a linha da tabela continua com 73 px antes e depois. */
.row-confirm > summary{display:inline-flex;align-items:center;list-style:none;color:var(--danger);font-weight:600;font-size:.8rem;min-height:44px;padding:6px 10px;border-radius:var(--radius-sm)}
.row-confirm > summary::-webkit-details-marker{display:none}
.row-confirm > summary:hover{color:var(--danger);background:var(--surface-hover)}
/* A mesma confirmação em página serve a ações que não destroem nada — "Aprovar" um pedido de
   vinculação, "Ativar acesso" de uma conta —, e nelas o vermelho do gatilho mentiria sobre o que o
   botão faz. A variante é do gatilho, não do componente: o painel, a caixa obrigatória e a âncora
   continuam sendo os mesmos, e o botão de dentro do formulário é que diz o tom da ação. */
.row-confirm.neutral > summary{color:var(--text)}
.row-confirm.neutral > summary:hover{color:var(--accent-text)}
/* A folga da trava é de 40 px, e não dos 32 px do recuo da página: ancorado à direita de um CARTÃO,
   o popover nasce de uma caixa que já está recuada da janela — medido a 390 px, a borda direita da
   âncora fica a 100vw - 33px (16 px de recuo do conteúdo + 1 px de borda + 16 px de recuo do cartão)
   — e uma trava de 100vw - 32px o punha em x = -1, um pixel fora da tela, em 320, 360, 390 e 414 px.
   As DUAS travas seguem a mesma folga: só no max-width, numa janela estreita o min-width venceria e
   o pixel voltaria. */
.row-confirm form{position:absolute;right:0;top:calc(100% + 6px);z-index:45;display:grid;gap:12px;width:max-content;min-width:min(280px,calc(100vw - 40px));max-width:min(360px,calc(100vw - 40px));padding:14px;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);box-shadow:var(--shadow);text-align:left}
.row-confirm .check{margin:0;font-size:.85rem}
.row-confirm .check + button{justify-self:end}
/* Sem script o painel fica em fluxo dentro do <details> aberto, e a coluna de ações tem pouco mais de
   cem pixels: em fluxo o formulário estouraria a tabela. Ancorado à célula ele abre com a mesma
   geometria da confirmação, e com a casca marcada nada disto vale — lá o painel é lateral e fixo. */
.app-shell:not(.shell-enhanced) .row-actions .drawer{position:absolute;right:0;top:calc(100% + 6px);z-index:45;width:max-content;min-width:min(320px,calc(100vw - 40px));max-width:min(420px,calc(100vw - 40px));box-shadow:var(--shadow)}
/* O painel de criação fica na .toolbar, que é flex: aberto sem script, ele toma a linha inteira em
   vez de espremer o formulário ao lado do título. Com script o <details> nunca abre. */
.toolbar .row-panel[open]{flex-basis:100%}
/* Faixa de atenção no topo do conteúdo (os pedidos de vinculação à espera). É irmã da .message, que
   é o recado de uma ação concluída, mas leva título, texto e um botão, e fica no fluxo da página. */
.banner{display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding:14px 16px;margin:0 0 20px;border:1px solid var(--border);border-left:3px solid var(--warning);border-radius:var(--radius);background:var(--warning-soft);color:var(--text)}
.banner > svg{color:var(--warning)}
.banner .body{flex:1;min-width:0}
.banner b{display:block;font-size:.9rem}
.banner p{margin:0;font-size:.8125rem}
/* Quadrado tingido que abre um cartão ou uma linha: o ícone do computador, da unidade, da empresa. */
.icon-box{width:40px;height:40px;flex:none;display:grid;place-items:center;border-radius:var(--radius-sm);background:var(--surface-2);color:var(--muted)}
.icon-box.ok{background:var(--success-soft);color:var(--success)}
.icon-box.warn{background:var(--warning-soft);color:var(--warning)}
.icon-box.bad{background:var(--danger-soft);color:var(--danger)}
.icon-box.accent{background:var(--accent-soft);color:var(--accent-text)}
/* O painel é o filho .drawer de um <details class="row-panel">, um por linha da tabela. Sem script o
   <details> abre e o painel aparece na própria linha; com position:fixed sem guarda, cada linha
   aberta poria um painel fixo à direita, um sobre o outro e sem gatilho de fechar. O fixo é do mundo
   com script, como a .shell-enhanced .context-pop e o .shell-enhanced .userbox .menu — mas a guarda
   aqui não pode ser descendente de .shell-enhanced: o app.js iça o painel para <body>, ou seja, para
   FORA da .app-shell que leva a marca, e um seletor descendente deixaria de alcançá-lo justo quando
   ele precisa ser fixo. A condição é a casca marcada em qualquer lugar do documento. Se o :has()
   faltar, o painel continua em fluxo — a queda é a mesma de quem não tem script. */
.drawer{display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius)}
body:has(.shell-enhanced) .drawer{position:fixed;top:0;right:0;bottom:0;width:min(440px,100%);border:0;border-left:1px solid var(--border);border-radius:0;box-shadow:var(--shadow);z-index:50}
.drawer[hidden]{display:none}
.drawer .d-head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:16px 20px;border-bottom:1px solid var(--border)}
.drawer .d-head h2{margin:0}
.drawer .d-body{padding:20px;overflow:auto;flex:1;display:grid;gap:14px;align-content:start}
/* Fixo, o rodapé encosta no fim da tela: o mesmo respiro da barra do editor para a faixa do gesto
   de início do celular, senão o botão de salvar fica sob ela. */
.drawer .d-foot{display:flex;gap:8px;justify-content:flex-end;padding:14px 20px;padding-bottom:calc(14px + env(safe-area-inset-bottom,0px));border-top:1px solid var(--border)}
/* Fechar o painel é ação só do script: o único consumidor de [data-panel-close] é o app.js, e sem ele
   o "✕" do cabeçalho e o "Cancelar" do rodapé ficariam na tela sem fazer nada — dois cliques mortos
   por painel nas seis páginas. É a mesma porta do "Recolher menu" e dos gatilhos do drawer. Sem
   script o painel continua DENTRO da .app-shell (só o app.js o iça para <body>), então o seletor
   descendente alcança exatamente o mundo que precisa alcançar; e quem fecha ali é o <summary> que
   abriu, que nunca some quando a casca não está marcada. */
.app-shell:not(.shell-enhanced) [data-panel-close]{display:none}
dialog.modal{width:min(460px,calc(100% - 32px));border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--surface);color:var(--text);box-shadow:var(--shadow);padding:22px}
dialog.modal::backdrop{background:var(--overlay)}
dialog.modal .actions{justify-content:flex-end;margin-top:12px}
.overlay,.drawer-overlay{position:fixed;inset:0;background:var(--overlay);z-index:35;border:0;border-radius:0;padding:0;width:100%;min-height:0}
.overlay:hover,.drawer-overlay:hover{background:var(--overlay)}
.back-link{display:inline-flex;align-items:center;gap:6px;min-height:44px;color:var(--muted);font-size:.875rem;margin-bottom:8px}
.back-link:hover{color:var(--text)}
.connection{border:1px solid var(--border);border-left:3px solid var(--accent);border-radius:var(--radius);background:var(--surface);padding:16px 20px}
.connection-label{color:var(--success);font-weight:700}
/* Passos do editor. O <form> não é a grade: quem é grade é a .editor-layout (notice-editor.css) e a
   barra é irmã dela, senão a área de grade da barra teria a altura dela mesma e não sobraria curso
   para o position:sticky. Sem JavaScript a barra de passos não navega, por isso a marcação a entrega
   com data-requires-js hidden e o script a revela. */
.steps{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;margin-bottom:20px}
.step{display:flex;align-items:center;justify-content:flex-start;gap:10px;min-height:44px;padding:10px 12px;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface);color:var(--muted);font-weight:700;font-size:.85rem;text-align:left;white-space:normal}
.step:hover{background:var(--surface-hover)}
.step .n{display:grid;place-items:center;flex:none;width:26px;height:26px;border-radius:50%;background:var(--surface-2);color:var(--muted);font-size:.8rem;font-weight:800}
.step[aria-current="step"]{border-color:var(--accent);color:var(--text)}
.step[aria-current="step"] .n{background:var(--accent);color:var(--accent-ink)}
.step.done{color:var(--text)}
.step.done .n{background:var(--success-soft);color:var(--success)}
/* A barra acompanha a rolagem e sangra o padding do .app-content, que tem três degraus (24 / 20 /
   20px 16px): um valor único a deixaria para dentro em duas faixas de largura. z-index 20 a mantém
   sob o cabeçalho (30) e sob o véu da gaveta (35), que é onde ela deve ficar quando a gaveta abre. */
.editor-bar{position:sticky;bottom:0;z-index:20;display:flex;gap:10px;align-items:center;justify-content:space-between;margin:8px -24px -24px;padding:12px 24px;padding-bottom:calc(12px + env(safe-area-inset-bottom,0px));border-top:1px solid var(--border);background:color-mix(in srgb,var(--bg) 90%,transparent);backdrop-filter:blur(10px)}
.editor-bar .grp{display:flex;gap:8px;min-width:0}
/* Enter num campo envia pelo primeiro botão de envio do formulário: sem este, seria um botão da
   agenda. Fica fora da tela, mas continua sendo um controle de envio — nada de display:none. */
.default-submit{position:absolute;width:1px;height:1px;min-height:0;padding:0;margin:-1px;border:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.pair-code{display:block;width:fit-content;max-width:100%;padding:16px 20px;font:700 clamp(1.4rem,4vw,1.9rem) var(--mono);letter-spacing:.12em;border:1px dashed var(--accent);border-radius:var(--radius-sm);background:var(--accent-soft);color:var(--accent-text);overflow-wrap:anywhere;user-select:all}
.auth-submit svg{transform:rotate(180deg)}
/* Lista de horários: o cartão "Hoje" do Painel e os sete dias da Agenda desenham a mesma linha.
   O nome do aviso não quebra (fica com reticências), então a linha tem uma largura mínima grande:
   sem a trilha minmax(0,1fr) e sem o min-width:0 da linha, essa mínima empurraria a coluna da
   página inteira e o celular ganharia rolagem horizontal. */
.list{display:grid;grid-template-columns:minmax(0,1fr);gap:2px;padding:0;margin:0;list-style:none}
.list-row{display:flex;align-items:center;gap:12px;padding:10px 8px;border-radius:var(--radius-sm);min-width:0}
.list-row .t{font:700 .95rem var(--mono);color:var(--muted);width:52px;flex:none;letter-spacing:-.02em}
.list-row .body{min-width:0;flex:1}
.list-row .body a{display:block;font-weight:700;font-size:.9rem;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.list-row .body span{display:block;font-size:.78rem;color:var(--muted)}
/* "Passou" é informação, não ruído. A opacidade de 55% compunha a linha inteira com o cartão e
   derrubava o horário e a regra para 2,2:1 no tema claro; o silêncio vem do token, que mantém
   4,5:1 nos dois temas, e a pílula "passou" continua legível porque não é afetada. */
.list-row.past .t,.list-row.past .body a,.list-row.past .body span{color:var(--muted)}
.list-row.next{background:var(--accent-soft)}
.list-row.next .t{color:var(--accent-text)}
/* Rodapé de atualização: mesma faixa no Painel e na lista de Avisos, com os mesmos controles. */
.dashboard-footer,.notices-footer{display:flex;flex-wrap:wrap;gap:8px 16px;align-items:center;padding:12px 4px;border-top:1px solid var(--border)}
.refresh-controls{display:flex;gap:4px}
.refresh-controls button{min-height:40px;padding:6px 10px;font-size:.8rem}
.refresh-toggle::before{content:"";display:inline-block;width:6px;height:6px;margin-right:6px;border-radius:50%;background:var(--success)}
.refresh-toggle[aria-pressed="false"]::before{background:var(--muted)}
/* Shell */
.app-shell{min-height:100dvh;padding-left:var(--sidebar-width)}
.app-sidebar{width:var(--sidebar-width);position:fixed;inset:0 auto 0 0;display:flex;flex-direction:column;gap:6px;z-index:40;background:var(--sidebar-bg);border-right:1px solid var(--border);padding:16px 12px;overflow-y:auto;transition:width var(--duration) var(--ease),transform 200ms var(--ease)}
.brand{display:flex;align-items:center;gap:10px;color:var(--text);text-decoration:none;padding:4px 8px 12px;min-height:48px;font-weight:800;letter-spacing:-.01em}
.brand:hover{text-decoration:none}
.brand-mark{width:34px;height:34px;flex:none;border-radius:9px;background:var(--accent);color:var(--accent-ink);display:grid;place-items:center}
.brand-mark svg{width:20px;height:20px;stroke-width:2.4}
.brand-name{font-size:.95rem;line-height:1.1}
.brand-name > span{display:block;font-size:.7rem;font-weight:600;color:var(--muted);margin-top:2px}
.context{position:relative}
.context-summary{display:grid;gap:2px;padding:10px;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);min-height:44px;font-weight:500}
.context-summary:hover{background:var(--surface-hover);color:var(--text)}
.context-summary .eyebrow{margin:0;font-size:.625rem}
.context-row{display:flex;align-items:center;gap:8px;min-width:0}
.context-row strong{flex:1;min-width:0;font-size:.85rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.context-row svg{width:16px;height:16px;color:var(--muted)}
.context-crumb{display:flex;align-items:center;gap:6px;font-size:.78rem;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.context-crumb .dot{width:6px;height:6px;border-radius:50%;background:var(--muted);flex:none}
.context-crumb .dot.is-online{background:var(--success)}
.context-crumb .dot.is-offline{background:var(--danger)}
.context-pop{display:grid;gap:10px;padding:14px;margin-top:6px;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);box-shadow:var(--shadow)}
.context-pop label{margin:0 0 4px}
.context-pop optgroup{font-weight:700}
.context-companies{display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.context-companies > .tag,.context-companies > .button{min-width:0;max-width:100%;white-space:normal;overflow-wrap:anywhere}
.shell-enhanced .context-pop{position:absolute;left:0;right:0;top:100%;z-index:45}
.app-nav{display:grid;gap:2px}
.nav-group{display:grid;gap:2px;margin-top:8px}
.nav-group .eyebrow{padding:8px 10px 2px;margin:0}
.app-nav a,.nav-button{display:flex;align-items:center;justify-content:flex-start;gap:10px;padding:9px 10px;min-height:44px;font-size:.9rem;font-weight:600;color:var(--muted);background:transparent;border:1px solid transparent;border-radius:var(--radius-sm);text-decoration:none;position:relative;text-align:left}
.app-nav a:hover,.nav-button:hover{background:var(--surface-hover);color:var(--text);text-decoration:none}
.app-nav a.active,.app-nav a[aria-current="page"]{background:var(--accent-soft);border-color:transparent;color:var(--accent-text)}
.app-nav a .count{margin-left:auto;font-size:.7rem;font-weight:800;padding:1px 7px;border-radius:999px;background:var(--danger-soft);color:var(--danger)}
.sidebar-bottom{margin-top:auto;padding-top:16px;display:grid;gap:6px}
.nav-button{width:100%}
.userbox{position:relative}
.userbox-summary{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:var(--radius);border:1px solid var(--border);background:var(--surface);min-height:52px;font-weight:500}
.userbox-summary:hover{background:var(--surface-hover);color:var(--text)}
.userbox-summary > span:not(.avatar){min-width:0;flex:1}
.userbox-summary b{display:block;font-size:.85rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.userbox-summary small{display:block;font-size:.72rem;color:var(--muted)}
.userbox-summary svg{width:16px;height:16px;color:var(--muted)}
.userbox .menu{position:static;margin-top:6px}
.shell-enhanced .userbox .menu{position:absolute;left:0;right:0;bottom:calc(100% + 6px);top:auto}
.avatar,.user-avatar{width:32px;height:32px;border-radius:50%;background:var(--accent);color:var(--accent-ink);display:grid;place-items:center;font-weight:800;font-size:.85rem;flex:none}
.signout-form button{width:100%}
/* Recolher o menu é uma ação só do script, como os gatilhos do drawer: sem JavaScript o botão
   não teria efeito nenhum, então ele só aparece depois que app.js marca a casca. */
.sidebar-collapse,.collapse-btn{display:none;color:var(--muted);font-size:.8125rem;font-weight:600;border-top:1px solid var(--border);border-radius:0;padding-top:14px}
.shell-enhanced .sidebar-collapse,.shell-enhanced .collapse-btn{display:flex}
.sidebar-is-collapsed{--sidebar-width:var(--sidebar-collapsed)}
.sidebar-is-collapsed .app-sidebar{padding-inline:10px}
.sidebar-is-collapsed .brand{padding:4px 2px 12px}
.sidebar-is-collapsed .brand-name,.sidebar-is-collapsed .context,.sidebar-is-collapsed .nav-group .eyebrow,.sidebar-is-collapsed .app-nav a > span,.sidebar-is-collapsed .nav-button > span,.sidebar-is-collapsed .userbox-summary > span:not(.avatar),.sidebar-is-collapsed .userbox-summary svg,.sidebar-is-collapsed .app-nav a .count{display:none}
.sidebar-is-collapsed .app-nav a,.sidebar-is-collapsed .nav-button{justify-content:center;padding:10px}
.sidebar-is-collapsed .userbox-summary{justify-content:center;padding:8px}
.sidebar-is-collapsed .sidebar-collapse svg{transform:rotate(180deg)}
.app-workspace{min-width:0;min-height:100dvh;display:flex;flex-direction:column}
.app-header{position:sticky;top:0;z-index:30;display:flex;align-items:center;gap:12px;min-height:var(--header-height);padding:10px 24px;border-bottom:1px solid var(--border);background:color-mix(in srgb,var(--bg) 88%,transparent);backdrop-filter:blur(10px)}
.header-context,.header-actions{display:flex;align-items:center;gap:12px;min-width:0}
.header-context{flex:1}
.topbar-title{min-width:0}
.topbar-title h1,.topbar-title .header-title{font-size:1.1rem;font-weight:800;letter-spacing:-.01em;line-height:1.2;margin:0}
.topbar-sub,.header-date{font-size:.8125rem;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.theme-form button{width:44px;padding:8px}
.app-content{width:100%;max-width:1280px;margin:0 auto;padding:24px;flex:1}
.app-content:focus{outline:none}
.app-footer{display:flex;justify-content:space-between;gap:20px;padding:20px 24px;color:var(--muted);font-size:.75rem;border-top:1px solid var(--border)}
.auth-content{min-height:100dvh;display:grid;align-content:center;padding:24px}
.drawer-toggle,.drawer-close,.hamburger{display:none}
@media(max-width:1180px){.header-date{display:none}.app-content{padding:20px}.editor-bar{margin:8px -20px -20px;padding-inline:20px}}
@media(max-width:1023px){
 .app-shell{padding-left:0}
 .app-sidebar{position:static;width:100%;min-height:auto;padding:16px}
 .app-sidebar .brand{margin-bottom:8px}
 .sidebar-bottom{padding-top:12px}
 .app-nav{grid-template-columns:1fr 1fr}
 .sidebar-collapse,.collapse-btn,.shell-enhanced .sidebar-collapse,.shell-enhanced .collapse-btn{display:none}
 .shell-enhanced .app-sidebar{position:fixed;width:min(300px,calc(100vw - 48px));height:100dvh;overflow-y:auto;transform:translateX(-105%)}
 .shell-enhanced.drawer-open .app-sidebar{transform:translateX(0)}
 .shell-enhanced .app-nav{grid-template-columns:1fr}
 .shell-enhanced .sidebar-bottom{margin-top:auto}
 .shell-enhanced .drawer-toggle,.shell-enhanced .drawer-close,.shell-enhanced .hamburger{display:inline-flex}
 .drawer-close{position:absolute;right:10px;top:14px}
 .drawer-overlay{display:block}
 body.drawer-open{overflow:hidden}
 .sidebar-is-collapsed .brand-name,.sidebar-is-collapsed .context,.sidebar-is-collapsed .nav-group .eyebrow,.sidebar-is-collapsed .app-nav a > span,.sidebar-is-collapsed .nav-button > span,.sidebar-is-collapsed .userbox-summary > span:not(.avatar),.sidebar-is-collapsed .userbox-summary svg,.sidebar-is-collapsed .app-nav a .count{display:revert}
 .sidebar-is-collapsed .app-nav a,.sidebar-is-collapsed .nav-button{justify-content:flex-start;padding:9px 10px}
 .topbar-sub{display:none}
 .header-context,.header-actions{gap:8px}
 .app-header{padding:8px 16px;min-height:60px}
 .newbtn > span{display:none}
 .newbtn{width:44px;padding:8px}
 .app-content{padding:20px 16px}
 .editor-bar{margin:8px -16px -20px;padding-inline:16px}
 .app-footer{padding:16px;flex-direction:column;gap:4px}
 .field-pair{grid-template-columns:1fr;gap:0}
 .inline-fields{flex-wrap:wrap}
 .inline-fields > div{flex-basis:40%}
 .card{padding:16px}
 table.stack,table.stack tbody,table.stack tr,table.stack td{display:block}
 table.stack thead{display:none}
 table.stack tr{padding:12px 0;border-bottom:1px solid var(--border)}
 table.stack td{border:0;padding:8px 16px}
 table.stack td::before{content:attr(data-label);display:block;color:var(--muted);font-size:.8125rem;font-weight:400;margin-bottom:4px}
 /* Empilhada, a célula de ações começa na margem da página: ancorados só à direita, os três
    popovers da linha nasceriam fora da janela. E o alvo de toque volta a ser inteiro.
    A inversão é da CÉLULA de tabela, e por isso o seletor pede uma <td> — vale para a
    .row-actions-cell das páginas de estrutura e para a .notice-actions de /Notices. Numa
    .row-actions que fica no canto DIREITO de um cartão (o rodapé de um computador em /Device, a
    faixa de pedidos, o cartão de /Voices) inverter joga o popover para fora da tela: medido a
    390 px, o menu abria em 247..447 e a confirmação em 247..527, com rolagem horizontal na página
    e "Excluir computador" 122 px fora da janela. Ancorado à direita ele cresce para dentro. */
 .row-actions-cell{text-align:left;white-space:normal}
 td .row-actions{justify-content:flex-start}
 td .row-actions .menu{left:0;right:auto}
 .row-confirm > summary{min-height:44px;padding:10px}
 td .row-confirm form{left:0;right:0;width:auto;max-width:none}
 /* Rede que não depende da âncora: seja qual for o lado, nenhum popover da linha passa da janela. */
 .row-actions .menu,.row-actions .row-confirm form{max-width:calc(100vw - 40px)}
 .app-shell:not(.shell-enhanced) td .row-actions .drawer{left:0;right:0;width:auto;max-width:none}
 .app-shell:not(.shell-enhanced) .row-actions .drawer{max-width:calc(100vw - 40px)}
 body:has(.shell-enhanced) .drawer{width:100%}
}
@media(max-width:860px){.steps{grid-template-columns:repeat(2,minmax(0,1fr))}}
/* Abaixo de 560 px os três botões da barra não cabem lado a lado com o alvo de 44 px: em vez de
   espremer o alvo, a barra quebra em duas linhas. */
@media(max-width:560px){.editor-bar{flex-wrap:wrap}.editor-bar .grp{flex-wrap:wrap}.step{font-size:.8rem;padding:8px 10px}}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}
