/* admin-base.css · CSS do shell de admin (templates/base.html).

   Por que este arquivo existe
   ---------------------------
   Estas ~440 linhas viviam num <style> inline do base.html, ou seja: ~36 KB reenviados
   em TODA navegação de admin, sem cache nenhum, porque HTML de página não é cacheável.
   Como arquivo de /static ele é baixado uma vez e reaproveitado, com cache-bust por mtime
   (o `?v=` que o template carimba via sv()) para não servir folha velha após um deploy.
   Nada de sintaxe de template aqui dentro: StaticFiles serve o arquivo cru, sem renderizar.

   Ordem da cascata (não inverter)
   ------------------------------
   tema-tokens.css → sb-menu.css / nav-contexto.css → ESTE arquivo → <style> de marca,
   tema do cliente e tema do projeto (que continuam inline no template porque são Jinja,
   isto é, variam por tenant/sessão). Os temas vêm DEPOIS de propósito: precisam vencer
   na cascata para o white-label funcionar.

   Este arquivo só CONSOME os tokens de tema-tokens.css · cor nova = editar lá, um lugar só.
   Ele é do ADMIN: o SPA tem o seu próprio static/css/dashboard.css. Regras do shell usam
   `.app.collapsed` aqui e `body.sb-collapsed` lá · ver CLAUDE.md antes de mexer.
*/
/* Os tokens de tema saíram daqui para static/css/tema-tokens.css (v604) · fonte única
   compartilhada com o SPA, carregada pelo <link> acima. Este <style> só CONSOME os tokens.
   Cor nova = editar tema-tokens.css, um lugar só. */
*{box-sizing:border-box;margin:0;padding:0}
/* Vidro fosco: cards/overlays que usam --panel (translúcido) ganham desfoque para
   ficarem legíveis sobre o gradiente. Espelha static/css/dashboard.css. */
/* v788 · os CARDS saíram desta lista. `backdrop-filter` custa uma passada de desfoque por
   elemento e por quadro, e numa tela com dezenas de cards a rolagem trava (medido: 75% dos
   quadros perdidos com vidro, 0% sem · ver o bloco longo em dashboard.css). O fundo atrás
   de um card em fluxo é o gradiente da página, que é liso: desfocá-lo devolve quase os
   mesmos pixels · comprovado por foto lado a lado nesta mesma tela, indistinguíveis, com o
   grão de `body::before` incluído. Ficam só as superfícies transitórias, que existem
   enquanto o cursor está sobre elas ou enquanto o menu está aberto. */
.navmenu-pop,
.app.collapsed:not(.nav-open) .nav-self[data-tip]:hover::after,.app.collapsed:not(.nav-open) .nav-leaf[data-tip]:hover::after,
.app.collapsed:not(.nav-open) .sb-item[data-tip]:hover::after,.app.collapsed:not(.nav-open) .sb-user[data-tip]:hover::after,
.app.collapsed:not(.nav-open) .sb-icon-btn[data-tip]:hover::after{
  -webkit-backdrop-filter:var(--card-blur);backdrop-filter:var(--card-blur)}
html{scroll-behavior:smooth}
html{min-height:100vh}
body{min-height:var(--vh-tela)}
body{
  background:var(--bg-layers), var(--bg);
  background-attachment:fixed;
  color:var(--text-on-dark);
  /* base 16px · igual ao dashboard.css e ao protótipo de tema (v606).
     a família morta saiu do fallback (v724): o <link> de fontes do base.html não a pede,
     então o navegador nunca a baixa nesta página · ver tests/test_admin_base_css.py. */
  font-family:'Hanken Grotesk',sans-serif;font-size:16px;line-height:1.6;
  display:flex;flex-direction:column;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
}
body::before{content:"";position:fixed;inset:0;pointer-events:none;z-index:0;opacity:.5;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");}
body>*{position:relative;z-index:1}
::selection{background:rgba(194,59,56,.25)}
a{color:var(--accent-ink);text-decoration:none}
a:hover{text-decoration:underline}

.topbar{position:sticky;top:0;z-index:80;display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:14px 32px;border-bottom:1px solid var(--border-on-dark);
  background:var(--bg);
  background:color-mix(in srgb, var(--bg) 78%, transparent);backdrop-filter:saturate(1.2) blur(14px);}
.brand{display:flex;align-items:center;gap:11px;text-decoration:none}
.brand:hover{text-decoration:none}
.brand .emblem{width:32px;height:32px;border-radius:10px;background:linear-gradient(140deg,var(--good),var(--accent));
  display:inline-flex;align-items:center;justify-content:center;font-family:'Fraunces',serif;font-weight:600;font-size:18px;color:#fff;
  box-shadow:0 6px 16px rgba(194,59,56,.32);flex:0 0 auto}
.brand .lk{display:flex;align-items:baseline;gap:9px}
.brand .mark{font-family:'Fraunces',serif;font-size:19px;font-weight:600;color:var(--text-on-dark);letter-spacing:-.01em}
.brand .by{font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--accent-ink)}
.topbar .who{font-size:12px;color:var(--dim-on-dark);display:flex;gap:8px;align-items:center;flex-wrap:wrap;justify-content:flex-end}

.btn{font-family:'Hanken Grotesk',sans-serif;font-size:13px;font-weight:600;border:1px solid var(--border-on-dark);
  background:rgba(255,255,255,.02);color:var(--text-on-dark);padding:8px 15px;border-radius:9px;cursor:pointer;
  transition:border-color .18s,background .18s,transform .18s;white-space:nowrap}
.btn:hover{border-color:var(--accent);background:rgba(194,59,56,.08);text-decoration:none}
.btn-primary{font-family:'Hanken Grotesk',sans-serif;font-weight:600;background:linear-gradient(180deg,var(--accent),var(--accent-deep));
  border:1px solid var(--accent-deep);color:#fff;padding:10px 18px;border-radius:10px;cursor:pointer;box-shadow:0 6px 18px rgba(194,59,56,.28);
  transition:transform .18s,box-shadow .18s,filter .18s}
.btn-primary:hover{filter:brightness(1.05);transform:translateY(-1px);box-shadow:0 10px 26px rgba(37,99,235,.36);text-decoration:none}
.btn-primary:active{transform:translateY(0)}
.btn-sec{font-family:'Hanken Grotesk',sans-serif;font-weight:600;font-size:14px;background:var(--panel);
  border:1px solid var(--border);color:var(--text);padding:10px 18px;border-radius:10px;cursor:pointer;
  transition:border-color .15s,background .15s,color .15s}
.btn-sec:hover{border-color:var(--accent);color:var(--accent-ink);background:var(--panel);text-decoration:none}
.btn-sec:active{transform:translateY(0)}
/* .btn-pri: alias do botão primário (usado em editores do motor: Gantt, colunas do helpdesk). */
.btn-pri{font-family:'Hanken Grotesk',sans-serif;font-weight:600;background:linear-gradient(180deg,var(--accent),var(--accent-deep));
  border:1px solid var(--accent-deep);color:#fff;padding:10px 18px;border-radius:10px;cursor:pointer;box-shadow:0 6px 18px rgba(194,59,56,.28);
  transition:transform .18s,box-shadow .18s,filter .18s}
.btn-pri:hover{filter:brightness(1.05);transform:translateY(-1px);box-shadow:0 10px 26px rgba(194,59,56,.36);text-decoration:none}
.btn-pri:active{transform:translateY(0)}
/* .btn-ghost: ação secundária leve (Testar conexão, Sincronizar, Remover) — borda sutil,
   fundo transparente, alinhada à identidade (antes caía no estilo default do navegador). */
.btn-ghost{font-family:'Hanken Grotesk',sans-serif;font-weight:600;font-size:14px;background:transparent;
  border:1px solid var(--border);color:var(--text-dim,var(--text));padding:10px 18px;border-radius:10px;cursor:pointer;
  transition:border-color .15s,background .15s,color .15s}
.btn-ghost:hover{border-color:var(--accent);color:var(--accent-ink);background:transparent;text-decoration:none}
.btn-ghost:active{transform:translateY(0)}
/* botão nativo do <input type=file> ("Escolher arquivo") alinhado à identidade (era cinza/quadrado). */
input[type=file]{font-family:'Hanken Grotesk',sans-serif;font-size:13px;color:var(--text-dim,var(--text))}
input[type=file]::file-selector-button{font-family:'Hanken Grotesk',sans-serif;font-weight:600;font-size:13px;
  background:var(--panel);border:1px solid var(--border);color:var(--text);padding:8px 14px;border-radius:9px;cursor:pointer;
  margin-right:10px;transition:border-color .15s,background .15s,color .15s}
input[type=file]::file-selector-button:hover{border-color:var(--accent);color:var(--accent-ink)}

.navmenu{position:relative;display:inline-block}
.navmenu>summary{list-style:none;cursor:pointer}
.navmenu>summary::-webkit-details-marker{display:none}
.navmenu>summary::marker{content:""}
.navmenu-pop{position:absolute;right:0;top:calc(100% + 8px);background:var(--panel);border:1px solid var(--border);border-radius:12px;
  box-shadow:var(--shadow-lg);min-width:190px;padding:7px;z-index:90;display:flex;flex-direction:column;animation:popIn .16s ease both}
.navmenu-pop a{color:var(--text);font-size:13px;font-weight:600;padding:10px 12px;border-radius:8px;text-decoration:none;white-space:nowrap;transition:background .15s}
.navmenu-pop a:hover{background:var(--panel-2);text-decoration:none}
.navmenu-pop .sep{font-family:'JetBrains Mono',monospace;font-size:9px;letter-spacing:.12em;text-transform:uppercase;color:var(--text-faint);padding:7px 12px 3px}

#theme-toggle{width:38px;height:38px;border-radius:50%;border:1px solid var(--border-on-dark);background:var(--panel);color:var(--text);
  cursor:pointer;display:inline-flex;align-items:center;justify-content:center;box-shadow:var(--shadow-sm);
  transition:transform .18s,box-shadow .18s,border-color .18s;flex:0 0 auto}
#theme-toggle:hover{transform:translateY(-1px) rotate(-12deg);box-shadow:var(--shadow-md);border-color:var(--accent)}
#theme-toggle .ico{width:18px;height:18px;display:block}
#theme-toggle .ico-moon{display:none}
:root[data-theme="light"] #theme-toggle .ico-sun{display:none}
:root[data-theme="light"] #theme-toggle .ico-moon{display:block}

/* ===================== Shell: sidebar colapsável + área principal ===================== */
/* align-items:flex-start · sem esticar a sidebar/main à altura do irmão. Sem isto, quando o
   conteúdo é mais alto que a viewport (ex.: galeria do Mirante), o .app não crescia e o range
   do position:sticky da sidebar ficava ~0, fazendo a sidebar rolar junto com a página. */
.app{display:flex;align-items:flex-start;min-height:var(--vh-tela);width:100%}
/* a altura sai de `--vh-tela` (tema-tokens.css) e não de 100vh: sob body{zoom:s} a unidade de
   viewport renderiza s× maior que a janela e empurrava o rodapé (Tema/Tamanho do texto) para
   fora da tela. overflow:hidden + .sb-nav{min-height:0} deixam a NAV rolar por dentro.
   v852 · era `calc(100vh / var(--fs-scale))` aqui; virou token, e o mesmo idioma passou a
   valer para toda gaveta, modal e popover do produto. */
.sidebar{position:fixed;left:0;top:0;height:var(--vh-tela);max-height:var(--vh-tela);overflow:hidden;flex:0 0 var(--sb-w);width:var(--sb-w);z-index:60;display:flex;flex-direction:column;gap:6px;
  padding:16px 14px;border-right:1px solid var(--border-on-dark);background:var(--sb-bg);
  backdrop-filter:saturate(1.3) blur(16px);overflow:hidden;transition:flex-basis .24s cubic-bezier(.4,0,.2,1),width .24s cubic-bezier(.4,0,.2,1)}
.app.collapsed:not(.nav-open) .sidebar{flex-basis:var(--sb-wc);width:var(--sb-wc)}
/* v972 · a coluna NUNCA recorta a gaveta do usuario · espelho da regra do SPA
   (static/css/dashboard.css). O `overflow:hidden` acima recorta os descendentes fixos
   porque o `backdrop-filter` faz da barra o bloco de contencao deles · foi assim que a
   gaveta saiu cortada na largura da coluna sob o "Tamanho do texto". So relaxa o recorte
   ENQUANTO a gaveta esta aberta; a arvore tem rolagem propria e nao passa a vazar. */
.sidebar:has(.sb-user[aria-expanded="true"]){overflow:visible}
.sb-top{display:flex;align-items:center;gap:10px;padding:2px 4px 12px;min-height:46px}
.sb-toggle{flex:0 0 auto;width:40px;height:40px;border-radius:11px;border:1px solid transparent;background:transparent;color:var(--text-on-dark);cursor:pointer;display:grid;place-items:center;transition:background .15s}
.sb-toggle:hover{background:var(--sb-item-hover)}
.sb-toggle svg{width:20px;height:20px}
.sb-brand{display:flex;align-items:center;gap:11px;min-width:0;text-decoration:none}
.sb-brand:hover{text-decoration:none}
.sb-brand .em{flex:0 0 auto;width:34px;height:34px;border-radius:10px;display:grid;place-items:center;background:linear-gradient(150deg,var(--accent),var(--accent-deep));color:#fff;font-family:'Fraunces',serif;font-weight:600;font-size:18px;box-shadow:var(--shadow-sm);overflow:hidden}
.sb-brand .em img{width:100%;height:100%;object-fit:cover}
.sb-brand .lk{display:flex;flex-direction:column;min-width:0}
.sb-brand .lk b{font-family:'Fraunces',serif;font-weight:600;font-size:15px;letter-spacing:-.01em;color:var(--text-on-dark);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sb-brand .lk small{font-family:'JetBrains Mono',monospace;font-size:9px;letter-spacing:.16em;text-transform:uppercase;color:var(--faint-on-dark);white-space:nowrap}
.sb-nav{flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;gap:2px;padding-right:2px}
/* árvore de navegação (Cliente › Projeto › Squads) no menu admin */
.nav-arvore-admin{display:flex;flex-direction:column;gap:1px;margin-bottom:6px}
.nav-arvore-admin:empty{display:none}
.nav-node{display:flex;flex-direction:column}
.nav-row{display:flex;align-items:center;gap:2px;border-radius:10px}
.nav-row:hover{background:var(--sb-item-hover)}
.nav-caret{flex:0 0 auto;width:22px;height:30px;display:grid;place-items:center;border:none;background:transparent;color:var(--faint-on-dark);cursor:pointer;padding:0}
.nav-caret svg{width:13px;height:13px;transition:transform .16s ease}
.nav-node.open>.nav-row>.nav-caret svg{transform:rotate(90deg)}
.nav-self{flex:1 1 auto;display:flex;align-items:center;gap:10px;padding:7px 8px 7px 2px;color:var(--dim-on-dark);cursor:pointer;font-size:13px;min-width:0}
.nav-self .ic{flex:0 0 auto;width:18px;height:18px}.nav-self .ic svg{width:18px;height:18px}
.nav-self .tx{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:600}
.nav-row:hover .nav-self{color:var(--text-on-dark)}
.nav-kids{display:none;margin-left:9px;padding-left:7px;border-left:1px solid var(--border-on-dark);flex-direction:column;gap:1px}
.nav-node.open>.nav-kids{display:flex}
.nav-leaf{display:flex;align-items:center;gap:7px;width:100%;text-align:left;border:none;background:transparent;color:var(--dim-on-dark);cursor:pointer;font-family:inherit;font-size:12.5px;padding:6px 7px;border-radius:9px;text-decoration:none}
.nav-leaf .ic{flex:0 0 auto;width:16px;height:16px}.nav-leaf .ic svg{width:16px;height:16px}
.nav-leaf .tx{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1 1 auto}
.nav-leaf:hover{background:var(--sb-item-hover);color:var(--text-on-dark);text-decoration:none}
.nav-tag{flex:0 0 auto;font-size:8.5px;letter-spacing:.02em;text-transform:uppercase;padding:1px 5px;border-radius:999px;border:1px solid var(--border-on-dark);color:var(--faint-on-dark)}
/* rótulo de grupo/altitude das lentes (modo por tela · Lente x Escopo) */
.nav-telas-grp{font-family:'JetBrains Mono',monospace;font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:var(--faint-on-dark);padding:0 7px 3px;margin-top:11px}
.nav-telas-lista .nav-telas-grp:first-child{margin-top:2px}
/* squad: nome na largura toda (quebra em 2 linhas se preciso, em vez de cortar) + tag
   (scrum/kanban) sempre numa 2ª linha — assim o nome nunca fica truncado, mesmo aninhado. */
.nav-leaf.nav-squad{flex-wrap:wrap;align-items:flex-start;row-gap:1px}
.nav-leaf.nav-squad .ic{margin-top:1px}
.nav-leaf.nav-squad .tx{flex:1 1 0;min-width:0;white-space:normal;overflow:visible;text-overflow:clip;line-height:1.25;word-break:break-word}
.nav-leaf.nav-squad .nav-tag{order:3;margin-left:23px;align-self:flex-start;width:auto;max-width:max-content;box-sizing:border-box}
.nav-leaf.nav-squad::after{content:"";flex-basis:100%;height:0;order:2}
.nav-self.nav-squad-self{align-items:center}
.nav-self.nav-squad-self .tx{flex:0 1 auto;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:600}
.nav-self.nav-squad-self .nav-tag{margin-left:6px}
.app.collapsed:not(.nav-open) .nav-self.nav-squad-self .nav-tag{display:none}
.app.collapsed:not(.nav-open) .nav-leaf.nav-squad .nav-tag{display:none}
.nav-empty{padding:5px 10px;font-size:11.5px;color:var(--faint-on-dark);font-style:italic}
.nav-cli>.nav-row>.nav-self .tx{font-size:13.5px;color:var(--text-on-dark)}
.app.collapsed:not(.nav-open) .nav-self .tx,.app.collapsed:not(.nav-open) .nav-leaf .tx,.app.collapsed:not(.nav-open) .nav-tag,.app.collapsed:not(.nav-open) .nav-caret,.app.collapsed:not(.nav-open) .nav-empty{display:none}
.app.collapsed:not(.nav-open) .nav-kids{display:flex;margin-left:0;padding-left:0;border-left:none}
.app.collapsed:not(.nav-open) .nav-self{justify-content:center;padding:7px 0}.app.collapsed:not(.nav-open) .nav-leaf{justify-content:center;padding:6px 0}
/* ===== refinamento visual do menu: níveis, cartões de squad, selos, item ativo ===== */
.nav-self .ic,.nav-leaf .ic{color:var(--faint-on-dark)}
.nav-cli>.nav-row>.nav-self .ic{color:#5B89C4}
.nav-proj>.nav-row>.nav-self .ic{color:#D29A3A}
.nav-proj>.nav-row>.nav-self .tx{font-weight:700}
.nav-self.nav-squad-self .ic{color:#9B7FC4}
.nav-leaf:hover .ic{color:#5B89C4}
.nav-cli>.nav-kids{border-left-color:rgba(91,137,196,.26)}
/* cartão de squad */
.nav-squad-node>.nav-row{margin:1px 0}
.nav-squad-node>.nav-kids{border-left-color:rgba(155,127,196,.30);margin-left:24px;padding-left:8px}
/* selos scrum/kanban coloridos */
.nav-tag.scrum{color:#bcd4f1;background:rgba(91,137,196,.22);border-color:rgba(91,137,196,.40)}
.nav-tag.kanban{color:#f0d9a8;background:rgba(210,154,58,.20);border-color:rgba(210,154,58,.42)}
:root[data-theme="light"] .nav-tag.scrum{color:#2E5C96;background:rgba(91,137,196,.16);border-color:rgba(91,137,196,.5)}
:root[data-theme="light"] .nav-tag.kanban{color:#7A4E10;background:rgba(210,154,58,.18);border-color:rgba(210,154,58,.55)}
/* item ativo (aba atual) com barra à esquerda */
.nav-leaf.on{background:rgba(91,137,196,.14);color:var(--text-on-dark);font-weight:600;position:relative}
.nav-leaf.on .ic{color:#5B89C4}
.nav-leaf.on::before{content:"";position:absolute;left:-8px;top:6px;bottom:6px;width:3px;border-radius:3px;background:#5B89C4}
/* no modo recolhido, sem cartão nem barra (mantém o ícone centralizado) */
.app.collapsed:not(.nav-open) .nav-squad-node>.nav-row{background:none;border:none;margin:0}
.app.collapsed:not(.nav-open) .nav-leaf.on::before{display:none}
.app.collapsed:not(.nav-open) .nav-leaf.on{background:var(--sb-item-hover)}
/* ===== item 3: cores por item + ícones distintos + tooltip no colapsado ===== */
.nav-leaf[data-tela="dashboard"]{--ic:#5B89C4}
.nav-leaf[data-tela="okrs"]{--ic:#38B2A0}
.nav-leaf[data-tela="visao"]{--ic:#5FAE5C}
.nav-leaf[data-tela="roadmap"]{--ic:#9B7FC4}
.nav-leaf[data-tela="helpdesk"]{--ic:#5BB6D4}
.nav-leaf[data-tela] .ic{color:var(--ic)}
.nav-leaf[data-tela]:hover .ic{color:var(--ic)}
.nav-squads{--ic:#CE7BA6}
.nav-squads>.nav-row>.nav-self .ic{color:var(--ic)}
.nav-squads .nav-squad-self .ic{color:var(--ic)}
.nav-squads .nav-squad-node .nav-leaf .ic{color:var(--ic)}
.nav-squads .nav-squad-node .nav-leaf:hover .ic{color:var(--ic)}
.nav-leaf.on[data-tela]{background:color-mix(in srgb,var(--ic) 16%,transparent)}
.nav-leaf.on[data-tela] .ic{color:var(--ic)}
.nav-leaf.on[data-tela]::before{background:var(--ic)}
.nav-squads .nav-leaf.on{background:color-mix(in srgb,var(--ic) 16%,transparent)}
.nav-squads .nav-leaf.on .ic{color:var(--ic)}
.nav-squads .nav-leaf.on::before{background:var(--ic)}
/* v858 · o mesmo cuidado do SPA: colapsado NAO pode tirar a rolagem quando o menu
   esta aberto como GAVETA no celular · o estado colapsado e lembrado e chega junto. */
.app.collapsed:not(.nav-open) .sidebar{overflow:visible}
/* v972 · A ARVORE VOLTA A ROLAR NO RAIL · espelho exato da regra do SPA
   (static/css/dashboard.css · CLAUDE.md, "duas implementacoes"). O `overflow:visible` que
   estava aqui tirava o conteiner de rolagem do .sb-nav, que continua sendo um item flex
   que ENCOLHE (flex:1 1 auto; min-height:0): a arvore era espremida na altura que sobrava
   e o resto VAZAVA por cima do rodape, um icone em cima do outro · medido no rail de 76px
   com o texto no "Padrao": 734px de conteudo fora da caixa, o ultimo item 721,9px por
   dentro do rodape e 28 pares de alvos clicaveis se cruzando.
   O balao do `data-tip` continua escapando porque quem recorta um conteiner de rolagem e a
   CAIXA DE PADDING: `--sb-dica-folga` estica esse padding para a direita e a margem
   negativa devolve a largura, entao o recorte cresce sem que a coluna cresca. A barra de
   rolagem nativa cairia nessa faixa esticada, fora do rail e por cima do conteudo · por
   isso ela fica oculta aqui. No rail de icones a rolagem e de roda. */
.app.collapsed:not(.nav-open) .sb-nav{overflow-y:auto;overflow-x:hidden;
  padding-right:var(--sb-dica-folga, 240px);margin-right:calc(var(--sb-dica-folga, 240px) * -1);
  scrollbar-width:none}
.app.collapsed:not(.nav-open) .sb-nav::-webkit-scrollbar{width:0;height:0}
.app.collapsed:not(.nav-open) .nav-self[data-tip],.app.collapsed:not(.nav-open) .nav-leaf[data-tip]{position:relative}
.app.collapsed:not(.nav-open) .nav-self[data-tip]:hover::after,.app.collapsed:not(.nav-open) .nav-leaf[data-tip]:hover::after{content:attr(data-tip);position:absolute;left:calc(100% + 12px);top:50%;transform:translateY(-50%);white-space:nowrap;background:var(--panel);color:var(--text);font-size:12.5px;font-weight:600;padding:7px 11px;border-radius:9px;box-shadow:var(--shadow-md);border:1px solid var(--border);z-index:140;pointer-events:none}
.sb-nav::-webkit-scrollbar{width:6px}.sb-nav::-webkit-scrollbar-thumb{background:var(--border-on-dark);border-radius:6px}
.sb-group{display:flex;flex-direction:column;gap:2px;padding:8px 0 2px}
.sb-label{font-family:'JetBrains Mono',monospace;font-size:9px;letter-spacing:.16em;text-transform:uppercase;color:var(--faint-on-dark);padding:0 12px 4px;white-space:nowrap;overflow:hidden}
/* grupos colapsáveis do rodapé (Sistema/Equipe): rótulo vira botão com caret */
.sb-label-toggle{display:flex;align-items:center;gap:6px;width:100%;background:none;border:0;cursor:pointer;text-align:left}
.sb-label-toggle:hover{color:var(--dim-on-dark)}
.sb-label-toggle .grp-caret{width:11px;height:11px;flex:0 0 auto;transition:transform .15s}
.sb-group.grp-fechado .sb-label-toggle .grp-caret{transform:rotate(-90deg)}
/* v694: ponto no rótulo quando a tela atual está dentro do grupo (antes o grupo abria
   sozinho, e o menu mudava de forma ao navegar). Espelhado em static/css/dashboard.css. */
.sb-group.grp-atual>.sb-label-toggle::after{content:"";margin-left:auto;width:5px;height:5px;
  border-radius:50%;background:var(--accent);flex:0 0 auto}
.sb-group.grp-fechado>.sb-item{display:none}
/* v973 · o rail NÃO força mais este grupo aberto (era aqui: `grp-fechado>.sb-item{display:flex}`
   mais `.sb-label-toggle{pointer-events:none}`). O botão do grupo passa a funcionar recolhido,
   e a escolha do usuário vale nos dois estados · ver o bloco "O RODAPÉ PARA DE COMER A COLUNA"
   mais abaixo, que precisa vir DEPOIS da regra que zera os rótulos. Espelha o dashboard.css. */
.sb-item{position:relative;display:flex;align-items:center;gap:13px;padding:10px 12px;border-radius:11px;color:var(--dim-on-dark);cursor:pointer;border:1px solid transparent;background:transparent;text-decoration:none;transition:background .14s,color .14s,border-color .14s}
.sb-item:hover{background:var(--sb-item-hover);color:var(--text-on-dark);text-decoration:none}
.sb-item .ic{flex:0 0 auto;width:21px;height:21px}
.sb-item .ic svg{width:21px;height:21px;display:block}
.sb-item .tx{white-space:nowrap;overflow:hidden;font-weight:600;font-size:13.5px}
.sb-item.on{background:color-mix(in srgb,var(--accent) 14%,transparent);color:var(--text-on-dark);border-color:color-mix(in srgb,var(--accent) 26%,transparent)}
.sb-item.on .ic{color:var(--accent-ink)}
.sb-item.on::before{content:"";position:absolute;left:-14px;top:50%;transform:translateY(-50%);width:4px;height:22px;border-radius:0 4px 4px 0;background:var(--accent)}
.sb-foot{flex:0 0 auto;padding-top:8px;margin-top:4px;border-top:1px solid var(--border-on-dark);display:flex;flex-direction:column;gap:3px}
/* linha compacta do rodapé: usuário + botão de sair lado a lado */
.sb-userrow{display:flex;align-items:center;gap:4px}
.sb-userrow .sb-user{flex:1 1 auto;min-width:0}
.sb-userrow form{margin:0;flex:0 0 auto}
.sb-icon-btn{position:relative;flex:0 0 auto;width:38px;height:38px;border-radius:11px;display:grid;place-items:center;background:transparent;border:1px solid transparent;color:var(--dim-on-dark);cursor:pointer}
.sb-icon-btn:hover{background:var(--sb-item-hover);color:var(--text-on-dark)}
.sb-icon-btn svg{width:19px;height:19px;display:block}
.app.collapsed:not(.nav-open) .sb-userrow{flex-direction:column;gap:2px}
/* item "Tema" dentro do grupo colapsável: alterna os ícones sol/lua como o botão antigo */
.sb-item .ico-moon{display:none}
:root[data-theme="light"] .sb-item .ico-sun{display:none}
:root[data-theme="light"] .sb-item .ico-moon{display:block}
.sb-user{display:flex;align-items:center;gap:11px;padding:8px 10px;border-radius:11px;cursor:pointer;text-decoration:none}
.sb-user:hover{background:var(--sb-item-hover);text-decoration:none}
.sb-user .av{flex:0 0 auto;width:32px;height:32px;border-radius:50%;display:grid;place-items:center;background:linear-gradient(150deg,var(--good),#16264a);color:#fff;font-weight:700;font-size:12px}
.sb-user .uk{display:flex;flex-direction:column;min-width:0;line-height:1.25}
.sb-user .uk b{font-size:12.5px;font-weight:600;color:var(--text-on-dark);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sb-user .uk small{font-size:10.5px;color:var(--faint-on-dark);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sb-ver{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--faint-on-dark);text-align:center;padding:8px 4px 2px;opacity:.75;font-variant-numeric:tabular-nums}
.app.collapsed:not(.nav-open) .sb-ver{display:none}
.theme-toggle{display:flex;align-items:center;gap:13px;padding:9px 11px;border-radius:11px;cursor:pointer;background:transparent;border:1px solid transparent;color:var(--dim-on-dark);width:100%;font-family:inherit}
.theme-toggle:hover{background:var(--sb-item-hover);color:var(--text-on-dark)}
.theme-toggle .ic{width:21px;height:21px;flex:0 0 auto}
.theme-toggle .ic svg{width:21px;height:21px;display:block}
.theme-tx{font-weight:600;font-size:13.5px;white-space:nowrap}
.theme-toggle .ico-moon{display:none}
:root[data-theme="light"] .theme-toggle .ico-sun{display:none}
:root[data-theme="light"] .theme-toggle .ico-moon{display:block}
/* sidebar é position:fixed (fica travada na rolagem, inclusive na galeria alta do Mirante) ·
   o .main compensa a largura dela com margin-left (e a largura do colapsado). */
.main{flex:1 1 auto;display:flex;flex-direction:column;min-width:0;min-height:var(--vh-tela);margin-left:var(--sb-w)}
.app.collapsed:not(.nav-open) .main{margin-left:var(--sb-wc)}
/* No desktop a appbar e uma faixa VAZIA (burger/brand so aparecem <=860px): sem
   superficie, some a "barra azul" no topo (ex.: tela Projetos) e alinha com o visual
   do dashboard SPA · mesmo padrao ja usado nos boards de retro/poker. A superficie
   volta no mobile (media abaixo), onde a barra carrega o menu. */
.appbar{position:sticky;top:0;z-index:40;display:flex;align-items:center;gap:12px;min-height:54px;padding:10px 28px;
  border-bottom:none;background:transparent}
.appbar .appbar-actions{margin-left:auto;display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.appbar .appbar-brand{display:none;font-family:'Fraunces',serif;font-size:17px;font-weight:600;color:var(--text-on-dark);text-decoration:none}
.nav-burger{display:none;width:40px;height:40px;border-radius:11px;border:1px solid var(--border-on-dark);background:var(--sb-item);color:var(--text-on-dark);cursor:pointer;place-items:center}
.nav-burger svg{width:20px;height:20px}
.appbody{flex:1 1 auto}
.nav-backdrop{display:none;position:fixed;inset:0;background:rgba(6,11,22,.5);z-index:110}
.app.collapsed:not(.nav-open) .sb-brand .lk,.app.collapsed:not(.nav-open) .sb-label,.app.collapsed:not(.nav-open) .sb-item .tx,.app.collapsed:not(.nav-open) .sb-user .uk,.app.collapsed:not(.nav-open) .theme-tx{opacity:0;width:0;pointer-events:none;overflow:hidden}
.app.collapsed:not(.nav-open) .sb-brand{display:none}
.app.collapsed:not(.nav-open) .sb-item,.app.collapsed:not(.nav-open) .sb-user,.app.collapsed:not(.nav-open) .theme-toggle{justify-content:center}
.app.collapsed:not(.nav-open) .sb-item{padding:10px}
.app.collapsed:not(.nav-open) .sb-top{justify-content:center}
.app.collapsed:not(.nav-open) .sb-group{align-items:center}
.app.collapsed:not(.nav-open) .sb-item[data-tip]:hover::after,.app.collapsed:not(.nav-open) .sb-user[data-tip]:hover::after,.app.collapsed:not(.nav-open) .sb-icon-btn[data-tip]:hover::after{content:attr(data-tip);position:absolute;left:calc(100% + 14px);top:50%;transform:translateY(-50%);white-space:nowrap;background:var(--panel);color:var(--text);font-size:12.5px;font-weight:600;padding:7px 11px;border-radius:9px;box-shadow:var(--shadow-md);z-index:130;border:1px solid var(--border)}
/* v973 · O RODAPÉ PARA DE COMER A COLUNA NO RAIL · espelho exato do static/css/dashboard.css
   (CLAUDE.md, "duas implementações"). Medido no rail de 76px, texto "Padrão", antes deste
   bloco: o rodapé ocupava 536,9px de uma tela de 720 e sobravam 89,1px de janela para a
   árvore · numa tela de 600 sobrava ZERO. E 430,3px desses 536,9 eram UM elemento: o grupo
   "Sistema"/"Equipe" com os seus 9 atalhos de administração.
   A causa era uma inversão: o grupo é COLAPSÁVEL e nasce fechado (`grp-fechado`, escolha
   lembrada em localStorage pelo script do base.html), mas o rail o forçava aberto porque ali
   o rótulo tem largura zero e o botão estava desligado · sem isso, os 9 atalhos ficariam
   inalcançáveis. Recolher a barra para GANHAR espaço abria 9 itens que o usuário tinha
   fechado. Na mesma tela de 720: expandida, rodapé 126,6px e árvore 491,4px; recolhida,
   536,9px e 89,1px.
   O conserto devolve o botão em vez de forçar o grupo: recolhido, o rótulo vira controle de
   ícone (o caret que já existe e já gira conforme o estado) com o nome do grupo no mesmo
   balão `data-tip` dos outros ícones do rail. O balão vai no `::before` porque o `::after`
   deste botão já é o ponto de "a tela atual está dentro deste grupo fechado" (v694). */
.app.collapsed:not(.nav-open) .sb-label-toggle{opacity:1;width:100%;overflow:visible;
  pointer-events:auto;position:relative;justify-content:center;gap:0;padding:8px 0;
  border-radius:11px;color:var(--faint-on-dark);
  /* o rótulo é nó de texto solto dentro do botão (não há span para esconder): zerar a fonte
     é o que o some. O caret tem width/height próprios e não depende dela. */
  font-size:0}
/* `width:100%` e não `auto` porque o alvo de clique é a coluna inteira: encolhido ao caret
   ele media 20px de largura. Com o fundo do hover, lê-se como controle e não como enfeite. */
.app.collapsed:not(.nav-open) .sb-label-toggle:hover{color:var(--text-on-dark);
  background:var(--sb-item-hover)}
.app.collapsed:not(.nav-open) .sb-label-toggle .grp-caret{width:15px;height:15px}
/* o ponto de "a tela atual está neste grupo" (v694) é posicionado por `margin-left:auto`, que
   num botão de largura cheia empurraria o caret para fora do centro · aqui ele vai para a
   borda, e o caret continua no meio da coluna. */
.app.collapsed:not(.nav-open) .sb-group.grp-atual>.sb-label-toggle::after{position:absolute;
  right:3px;top:50%;transform:translateY(-50%);margin-left:0}
.app.collapsed:not(.nav-open) .sb-label-toggle[data-tip]:hover::before{content:attr(data-tip);
  position:absolute;left:calc(100% + 14px);top:50%;transform:translateY(-50%);white-space:nowrap;
  background:var(--panel);color:var(--text);font-size:12.5px;font-weight:600;padding:7px 11px;
  border-radius:9px;box-shadow:var(--shadow-md);border:1px solid var(--border);z-index:140;
  pointer-events:none}
/* Teto para o caso em que o usuário ABRE o grupo no rail: a escolha é dele, mas abrir 9
   atalhos não pode voltar a zerar a árvore numa tela baixa. A rolagem fica no GRUPO, e não
   no `.sb-foot`, porque a gaveta do usuário é `fixed` e mora no `.sb-userwrap`: um
   `overflow` no rodapé voltaria a recortá-la (o defeito que a v972 acabou de consertar),
   enquanto o grupo não é ancestral dela. `--vh-tela` e não `100vh` por causa do
   `body{zoom}` do "Tamanho do texto" (v852). O `--sb-dica-folga` repete aqui o que a v972
   fez na árvore, para os balões dos 9 atalhos continuarem escapando do recorte. */
.app.collapsed:not(.nav-open) .sb-foot .sb-group{max-height:calc(var(--vh-tela, 100vh) * .34);
  overflow-y:auto;overflow-x:hidden;padding-right:var(--sb-dica-folga, 240px);
  margin-right:calc(var(--sb-dica-folga, 240px) * -1);scrollbar-width:none}
.app.collapsed:not(.nav-open) .sb-foot .sb-group::-webkit-scrollbar{width:0;height:0}
/* v974 · OS ÍCONES DO RAIL FICAM CENTRADOS NA COLUNA · espelho exato do static/css/dashboard.css
   (CLAUDE.md, "duas implementações"). Medido no DOM real, rail de 76px (coluna útil de 47px,
   centro em 37,5px), texto "Padrão": todo `.sb-item` caía 6,5px à ESQUERDA do centro (os 9
   atalhos do grupo, a "Novidades da versão" e a "Lista de projetos" da árvore) e o avatar do
   usuário caía 18,0px, enquanto os nós da árvore (`.nav-self`/`.nav-leaf`) caíam em 0,0px.
   A causa é o que `justify-content:center` centra: a LINHA INTEIRA. O rótulo é escondido com
   `opacity:0;width:0` (e não `display:none`, para a coluna não perder a transição), continua
   sendo item flex e um item de largura zero AINDA consome o `gap` · com `gap:13px` o ícone
   fica meio gap à esquerda. Na árvore o rótulo sai com `display:none`, deixa de ser item flex
   e não sobra gap. No card do usuário a linha era avatar 32 + gap 11 + rótulo 0 + gap 11 +
   chevron 14 = 68px numa caixa de 27px.
   O conserto zera o gap onde o rótulo já está zerado e tira o chevron do rail (o avatar de
   32px deixa 7,5px de folga de cada lado na coluna de 47px · um chevron de 14px não cabe ao
   lado sem cavalgá-lo), como a árvore já faz com o seu `.nav-caret`.
   Os seletores partem de `.sb-nav` e de `.sb-foot >` de propósito: a GAVETA mora em
   `.sb-foot > .sb-userwrap > .sb-menu` e lá o rótulo APARECE (sb-menu.css o restaura), então
   ela precisa do gap de sempre. */
.app.collapsed:not(.nav-open) .sb-nav .sb-item,
.app.collapsed:not(.nav-open) .sb-foot > .sb-item,
.app.collapsed:not(.nav-open) .sb-foot > .sb-group > .sb-item{gap:0}
.app.collapsed:not(.nav-open) .sb-user{gap:0;padding:8px 0}
.app.collapsed:not(.nav-open) .sb-user .sb-user-cev{display:none}
.authshell{flex:1;display:flex;flex-direction:column;min-height:var(--vh-tela)}
.authtop{display:flex;align-items:center;justify-content:space-between;padding:16px 28px}
.authwrap{flex:1;display:flex;flex-direction:column}
@media (max-width:860px){
  /* gaveta mobile: a largura nunca pode exceder a viewport · com zoom (--fs-scale) a
     viewport efetiva encolhe, então limitamos a 86vw (regra compartilhada com o SPA). */
  .sidebar{position:fixed;left:0;top:0;z-index:120;flex-basis:min(var(--sb-w),calc(var(--vw-tela) * .86));width:min(var(--sb-w),calc(var(--vw-tela) * .86));transform:translateX(-100%);box-shadow:var(--shadow-lg)}
  .app.collapsed:not(.nav-open) .sidebar{flex-basis:min(var(--sb-w),calc(var(--vw-tela) * .86));width:min(var(--sb-w),calc(var(--vw-tela) * .86))}
  /* no mobile a sidebar é gaveta sobreposta · o conteúdo ocupa a largura toda (sem margin) */
  .main, .app.collapsed:not(.nav-open) .main{margin-left:0}
  .app.nav-open .sidebar{transform:none}
  .app.nav-open .nav-backdrop{display:block}
  /* v858 · mesma regra do SPA: na gaveta quem rola e o painel inteiro, com o rodape
     no fim · a arvore espremida num visor de poucas centenas de px era o defeito. */
  .app.nav-open .sidebar{overflow-y:auto;overscroll-behavior:contain}
  .app.nav-open .sb-nav{overflow:visible;flex:0 0 auto}
  .sb-toggle{display:none}
  .nav-burger{display:grid}
  .appbar .appbar-brand{display:block}
  .appbar{padding:10px 16px;border-bottom:1px solid var(--border-on-dark);
    background:color-mix(in srgb,var(--bg) 80%,transparent);backdrop-filter:saturate(1.2) blur(14px)}
}

.wrap{flex:1;display:flex;align-items:center;justify-content:center;padding:48px 24px}
.card{background:var(--panel);color:var(--text);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow-lg), inset 0 1px 0 var(--card-hi);padding:40px;width:100%;max-width:430px}
.card .eyebrow{font-family:'JetBrains Mono',monospace;font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--accent-ink);margin-bottom:10px}
.card h1{font-family:'Fraunces',serif;font-weight:500;font-size:29px;letter-spacing:-.02em;margin-bottom:6px;color:var(--text)}
.card p.sub{color:var(--text-dim);font-size:13.5px;margin-bottom:24px}
label{display:block;font-family:'JetBrains Mono',monospace;font-size:10px;font-weight:500;letter-spacing:.07em;text-transform:uppercase;color:var(--text-dim);margin:16px 0 7px}
input[type=text],input[type=email],input[type=password],input[type=number]{width:100%;padding:11px 13px;border:1px solid var(--border);border-radius:10px;font-size:14px;font-family:'Hanken Grotesk',sans-serif;background:var(--panel-2);color:var(--text);transition:border-color .15s,box-shadow .15s}
input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--ring)}
/* Select padronizado em todo o sistema: sem aparência nativa, chevron próprio,
   folga à direita para o texto não encostar na seta, e alinhamento consistente. */
select{
  -webkit-appearance:none;-moz-appearance:none;appearance:none;
  width:auto;max-width:100%;box-sizing:border-box;vertical-align:middle;
  font-family:'Hanken Grotesk',sans-serif;font-size:14px;line-height:1.4;
  padding:11px 38px 11px 13px;
  color:var(--text);background-color:var(--panel-2);
  background-image:var(--sel-chevron);background-repeat:no-repeat;
  background-position:right 13px center;background-size:16px 16px;
  border:1px solid var(--border);border-radius:10px;cursor:pointer;
  transition:border-color .15s,box-shadow .15s}
select:hover{border-color:var(--accent)}
select:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--ring)}
select:disabled{background-color:var(--panel-2);color:var(--text-dim);cursor:not-allowed;opacity:1}
select option{font-family:'Hanken Grotesk',sans-serif;font-size:14px;color:var(--text);background:var(--panel-2)}
.actions{margin-top:24px;display:flex;flex-direction:column;gap:12px}
.actions .btn-primary{width:100%;padding:13px;font-size:14px}
.links{margin-top:18px;font-size:12.5px;color:var(--text-dim);display:flex;justify-content:space-between;gap:10px;flex-wrap:wrap}
.alert{padding:12px 14px;border-radius:10px;font-size:13px;margin-bottom:10px}
/* v700: o rosa claro cravado era calibrado p/ fundo escuro · no tema claro media 1,68:1,
   e esta é a mensagem de erro de TODA tela admin. A tinta --bad-ink é mode-aware, como já
   faziam .alert.ok (--pos-ink) e .alert.warn (--warn-ink) logo abaixo. */
.alert.err{background:color-mix(in srgb, var(--bad) 13%, transparent);color:var(--bad-ink);border:1px solid color-mix(in srgb, var(--bad) 32%, transparent)}
.alert.ok{background:color-mix(in srgb, var(--br-green) 13%, transparent);color:var(--pos-ink);border:1px solid color-mix(in srgb, var(--br-green) 32%, transparent)}
.alert.warn{background:color-mix(in srgb, var(--warn) 13%, transparent);color:var(--warn-ink);border:1px solid color-mix(in srgb, var(--warn) 32%, transparent)}

footer{padding:22px 32px;font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--faint-on-dark);text-align:center;border-top:1px solid var(--border-on-dark)}

@keyframes riseIn{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@keyframes popIn{from{opacity:0;transform:translateY(-6px) scale(.98)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion: no-preference){
  .card{animation:riseIn .5s cubic-bezier(.22,.7,.25,1) both}
  .reveal{animation:riseIn .55s cubic-bezier(.22,.7,.25,1) both}
  .stagger>*{animation:riseIn .55s cubic-bezier(.22,.7,.25,1) both}
  .stagger>*:nth-child(2){animation-delay:.06s}
  .stagger>*:nth-child(3){animation-delay:.12s}
  .stagger>*:nth-child(4){animation-delay:.18s}
  .stagger>*:nth-child(5){animation-delay:.24s}
  .stagger>*:nth-child(6){animation-delay:.30s}
  .stagger>*:nth-child(7){animation-delay:.36s}
  .stagger>*:nth-child(n+8){animation-delay:.42s}
}

@media (max-width:720px){
  .topbar{padding:12px 18px}
  .brand .by{display:none}
  .brand .mark{font-size:17px}
  .topbar .who{gap:6px}
  .btn{padding:7px 11px;font-size:12.5px}
  .wrap{padding:32px 18px}
  .card{padding:28px 22px}
  footer{padding:18px}
}
@media (max-width:420px){
  .brand .mark{display:none}
}

/* ===================== Telas de admin (clientes/projetos): forma padronizada ===================== */
/* As telas de admin usam o MESMO fundo do dashboard: o gradiente do tema (body
   --bg-layers) com cards/painéis brancos por cima — honrando o tema (claro/escuro).
   .main fica transparente (mostra o gradiente do tema); cabeçalhos/abas/textos usam as
   variáveis *-on-dark do tema (claras no escuro, escuras no claro), como no dashboard. */
/* Larguras e cabeçalhos uniformes */
.cl-wrap,.cfg-wrap{max-width:min(1200px,94vw);margin:0 auto;padding:42px 28px 84px;width:100%}
@media(max-width:720px){.cl-wrap,.cfg-wrap{padding:30px 16px 64px}}
/* Cards padronizados (clientes.html .cl-card, cliente_detail .card, config_projetos .pcard/.cfg-card) */
.cl-card,.cl-pane .card,.pcard,.cfg-card{padding:26px 28px}
/* os cards de admin não devem herdar o max-width:430px do card de login */
.cl-wrap .card,.cfg-wrap .card,.cl-card,.pcard,.cfg-card{max-width:none;width:100%}
.cl-card h2,.cl-pane .card h2,.cfg-card h2{font-family:'Fraunces',serif;font-size:20px;font-weight:600;margin-bottom:6px}
.cl-card h3,.cl-pane .card h3,.cfg-card h3{font-family:'Fraunces',serif;font-size:16px;font-weight:600}
.cl-card .hint,.cl-pane .card .hint,.cfg-card .hint,.pcard .hint{font-size:13.5px;color:var(--text-dim);line-height:1.55;margin-bottom:16px}
/* Rótulos legíveis (antes eram 10px) */
.ff label,.cl-pane .card label,.adminform label,.afield label{display:block;font-family:'Hanken Grotesk',sans-serif;font-size:12.5px;font-weight:600;letter-spacing:.01em;text-transform:none;color:var(--text-dim);margin:16px 0 7px}
/* Controles de formulário maiores e consistentes dentro dos cards de admin */
.cl-card input:not([type=color]):not([type=checkbox]):not([type=radio]):not([type=file]):not([type=submit]):not([type=button]),.cl-card select,.cl-card textarea,
.cl-pane .card input:not([type=color]):not([type=checkbox]):not([type=radio]):not([type=file]):not([type=submit]):not([type=button]),.cl-pane .card select,.cl-pane .card textarea,
.cfg-card input:not([type=color]):not([type=checkbox]):not([type=radio]):not([type=file]):not([type=submit]):not([type=button]),.cfg-card select,.cfg-card textarea{
  width:100%;box-sizing:border-box;font-family:'Hanken Grotesk',sans-serif;font-size:15px;line-height:1.4;
  padding:11px 13px;border:1px solid var(--border);border-radius:10px;background:var(--panel-2);color:var(--text);transition:border-color .15s,box-shadow .15s}
.cl-card input:focus,.cl-card select:focus,.cl-card textarea:focus,
.cl-pane .card input:focus,.cl-pane .card select:focus,.cl-pane .card textarea:focus,
.cfg-card input:focus,.cfg-card select:focus,.cfg-card textarea:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--ring)}
/* Selects nos cards de admin: mesma altura dos inputs (15px) + chevron e folga à direita */
.cl-card select,.cl-pane .card select,.cfg-card select{
  width:100%;height:auto;font-size:15px;line-height:1.4;
  padding:11px 40px 11px 13px;
  background-color:var(--panel-2);background-image:var(--sel-chevron);
  background-repeat:no-repeat;background-position:right 14px center;background-size:16px 16px}
.cl-card input[disabled],.cfg-card input[disabled]{background:var(--panel-2);color:var(--text-dim)}
/* Grade padronizada de campos */
.afield{display:flex;flex-direction:column}
.agrid{display:grid;grid-template-columns:1fr 1fr;gap:4px 18px}
@media(max-width:680px){.agrid{grid-template-columns:1fr}}
/* Botões um pouco maiores nessas telas */
.cl-wrap .btn,.cfg-wrap .btn{font-size:13.5px;padding:9px 16px}
.cl-wrap .btn-primary,.cfg-wrap .btn-primary{font-size:14.5px;padding:11px 20px}
/* Componente de upload de logo */
.logo-up{display:flex;gap:16px;align-items:center;flex-wrap:wrap}
.logo-up .lp{width:72px;height:72px;border-radius:14px;border:1px solid var(--border);background:var(--panel-2);display:flex;align-items:center;justify-content:center;overflow:hidden;flex:0 0 auto}
.logo-up .lp img{width:100%;height:100%;object-fit:contain}
.logo-up .lp .ph{font-family:'Fraunces',serif;font-size:26px;color:var(--text-faint)}
.logo-drop{flex:1;min-width:220px;border:1.5px dashed var(--border);border-radius:12px;padding:14px 16px;cursor:pointer;transition:border-color .15s,background .15s;display:flex;flex-direction:column;gap:3px}
.logo-drop:hover,.logo-drop.drag{border-color:var(--accent);background:rgba(194,59,56,.04)}
.logo-drop .t{font-weight:600;font-size:14px;color:var(--text)}
.logo-drop .s{font-size:12px;color:var(--text-dim)}
.logo-up .rm{font-size:12.5px;color:var(--accent-ink);background:none;border:none;cursor:pointer;padding:4px}
/* Acessibilidade (item 16) */
.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(--accent);outline-offset:2px;border-radius:4px}
/* utilitário compartilhado: envolve tabelas largas para rolarem na horizontal no
   celular em vez de estourar a viewport (agravado pelo zoom de texto --fs-scale). */
.tbl-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;max-width:100%}
/* ===== Endurecimento mobile das telas de admin (estreito + zoom de texto) ===== */
@media(max-width:640px){
  /* o uploader de logo empilha em vez de forçar 220px e transbordar */
  .logo-drop{min-width:0;flex-basis:100%}
  /* nada nas telas de admin deve provocar scroll horizontal na página */
  .cl-wrap,.cfg-wrap{padding-left:14px;padding-right:14px}
}
@media(max-width:360px){
  .cl-wrap,.cfg-wrap{padding-left:11px;padding-right:11px}
  .cl-card,.cl-pane .card,.pcard,.cfg-card{padding:18px 16px}
  /* botões da barra do topo não empurram o título para fora sob zoom */
  .appbar{padding-left:12px;padding-right:12px}
  .appbar .appbar-actions{gap:6px}
}
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;transition-duration:.001ms !important;scroll-behavior:auto !important}
}

/* v736/S-22 · grupo de menu "nu" (sem borda/padding), que era style= inline no base.html. */
.sb-group.sb-grp-nu{border:0;padding:0 0 4px;margin:0}
