/* Folha única, tudo em variáveis. O valor de cada variável chega no <head>,
   vindo do cadastro do tenant — trocar uma cor no painel muda o site inteiro.
   Os fallbacks são a identidade smartprint3d (paleta Bambu Lab). */
:root{
  --primary:#00ae42; --primary-hover:#1aaf5d; --link:#00ae42;
  --bg:#f5f5f5; --surface:#ffffff; --border:#e4e4e4;
  --text-primary:#333333; --text-secondary:#9e9e9e;
  --largura:1100px; --raio:10px;
}
*{box-sizing:border-box;margin:0;padding:0}
/* Fundo de tela: os papéis fundo-tela-1/2 (bgFrom/bgTo) existem para isto. Sem
   eles o degradê fica transparente e sobra a cor sólida de --bg. */
body{font-family:Manrope,system-ui,-apple-system,"Segoe UI",sans-serif;
  background-color:var(--bg);
  background-image:linear-gradient(180deg,var(--bg-0,transparent),var(--bg-1,transparent));
  background-attachment:fixed;
  color:var(--text-primary);line-height:1.6}
main{max-width:var(--largura);margin:0 auto;padding:0 1.25rem 4rem}
a{color:var(--link);text-decoration:none}
a:hover{text-decoration:underline}
h1{font-size:2rem;font-weight:700;line-height:1.2}
h2{font-size:1.4rem;font-weight:700;margin-bottom:1rem}
h3{font-size:1.05rem;font-weight:700}
p{color:var(--text-primary)}
.sec{color:var(--text-secondary)}

.topo{display:flex;align-items:center;gap:1.5rem;max-width:var(--largura);
  margin:0 auto;padding:1rem 1.25rem}
.marca{display:flex;align-items:center;gap:.6rem;color:var(--text-primary);font-size:1.05rem}
.marca-quadro{width:22px;height:22px;border-radius:6px;background:var(--primary);display:inline-block}
/* UM LOGO POR FUNDO. O cadastro tem dois arquivos (o lockup das marcas vem em
   versão clara e escura) e as DUAS imagens vão para o HTML — quem escolhe é
   esta regra, não JavaScript, pela mesma razão dos ícones do alternador: nada
   pisca antes do script rodar. Com um arquivo só, `marcaImg` emite uma imagem
   sem estas classes e ela vale para os dois temas. */
/* ⚠️ O `display` das imagens da marca mora SÓ neste bloco. As regras que
   dimensionam (`.marca-topo .marca-img`, abaixo) têm peso maior; se alguma
   delas declarar `display`, ela vence o `display:none` daqui e as DUAS
   imagens aparecem empilhadas — foi o que aconteceu em 2026-08-14. */
.marca-img{display:block}
.marca-escura{display:none}
.dark .marca-clara{display:none}
.dark .marca-escura{display:block}
.topo .marca-img{height:28px;width:auto}
.topo nav{display:flex;gap:1.25rem;margin-left:auto;flex-wrap:wrap}
.topo nav a{color:var(--text-primary);font-size:.95rem}

/* O gradiente da marca pinta por cima da cor sólida quando o tenant o define.
   Sem gradiente cadastrado, background-image vira "none" e sobra a --primary. */
.btn{display:inline-block;background-color:var(--primary);
  background-image:var(--brand-gradient,none);color:#fff;border:0;
  border-radius:var(--raio);padding:.7rem 1.4rem;font-weight:500;font-size:.95rem;
  cursor:pointer;font-family:inherit}
.btn:hover{background-color:var(--primary-hover);background-image:none;text-decoration:none}
.btn-linha{background:transparent;color:var(--primary);border:1px solid var(--primary);padding:.5rem 1rem}
.btn-linha:hover{background:transparent;text-decoration:none;border-color:var(--primary-hover)}

/* Alternador de tema. Os dois ícones ficam no HTML e o CSS mostra um por vez:
   no claro aparece a lua (clicar escurece) e no escuro, o sol. Fazer isso por
   CSS e não por JavaScript evita o ícone errado aparecer antes do script rodar. */
.btn-tema{display:inline-flex;align-items:center;justify-content:center;
  width:36px;height:36px;padding:0;border-radius:var(--raio);cursor:pointer;
  background:transparent;color:var(--text-primary);
  border:1px solid var(--border);font-family:inherit}
.btn-tema:hover{border-color:var(--primary);color:var(--primary)}
.icone-sol{display:none}
.dark .icone-sol{display:block}
.dark .icone-lua{display:none}

.hero{background:var(--surface);border-radius:var(--raio);padding:3rem 2rem;margin-bottom:2rem}
.hero p{color:var(--text-secondary);margin:.5rem 0 1.5rem;max-width:38rem}

.grade{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:1rem}
.card{background:var(--surface);border:1px solid var(--border);border-radius:var(--raio);
  padding:1.25rem;display:flex;flex-direction:column}
.card .arte{color:var(--text-secondary);margin-bottom:.75rem}
.card .arte svg{width:100%;height:auto;max-height:150px}
.card p{color:var(--text-secondary);font-size:.9rem;margin:.35rem 0 1rem;flex:1}

.ficha{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:2rem;
  background:var(--surface);border-radius:var(--raio);padding:2rem;margin-bottom:2rem}
.ficha .arte{color:var(--text-secondary)}
.ficha .arte svg{width:100%;height:auto;max-height:280px}
.specs{list-style:none;margin:1.25rem 0}
.specs li{display:flex;justify-content:space-between;gap:1rem;
  padding:.6rem 0;border-bottom:1px solid var(--border);font-size:.92rem}
.specs li span:first-child{color:var(--text-secondary)}
.acoes{display:flex;gap:.75rem;flex-wrap:wrap;margin-top:1.25rem}

form{display:grid;gap:.85rem;max-width:32rem}
label{font-size:.9rem;color:var(--text-secondary)}
input,textarea{width:100%;font:inherit;padding:.7rem .9rem;border-radius:var(--raio);
  border:1px solid var(--border);background:var(--surface);color:var(--text-primary)}
textarea{min-height:8rem;resize:vertical}
.aviso{border-radius:var(--raio);padding:.9rem 1rem;font-size:.92rem;
  border:1px solid var(--border);background:var(--surface)}
.aviso-erro{border-color:var(--primary)}

.rodape{border-top:1px solid var(--border);margin-top:2rem;padding:2rem 1.25rem;
  max-width:var(--largura);margin-inline:auto;display:grid;
  grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:1.5rem;
  color:var(--text-secondary);font-size:.9rem}
.rodape strong{color:var(--text-primary)}
.redes{display:flex;gap:1rem;text-transform:capitalize}

/* ===== Entrada (login) =====
   Página SOLTA: sem cabeçalho e sem rodapé, cartão no centro da tela. A marca
   vem na faixa do próprio cartão — ver o comentário em views/login.js. */
body.solta main{max-width:none;padding:0}

/* Grade de fundo, recuperada do login do Argus (ver a nota em views/login.js).
   A máscara radial é o que a impede de virar papel quadriculado: ela existe no
   centro e some nas bordas, funcionando como profundidade e não como textura. */
.grade-fundo{position:fixed;inset:0;z-index:0;pointer-events:none;
  background-image:
    linear-gradient(rgba(var(--hairline-rgb,148,163,184),.13) 1px, transparent 1px),
    linear-gradient(90deg, rgba(var(--hairline-rgb,148,163,184),.13) 1px, transparent 1px);
  background-size:42px 42px;
  -webkit-mask-image:radial-gradient(ellipse 90% 85% at 50% 45%, #000 0%, transparent 92%);
  mask-image:radial-gradient(ellipse 90% 85% at 50% 45%, #000 0%, transparent 92%)}
/* No tema claro a linha precisa ser MAIS FRACA: o papel `fio` já vem escuro
   ali (é a mesma variável), e o alpha do escuro deixaria a grade pesada sobre
   fundo claro. Mesma correção que o Argus fazia com `html.light .grid-bg`. */
html:not(.dark) .grade-fundo{
  background-image:
    linear-gradient(rgba(var(--hairline-rgb,15,23,42),.11) 1px, transparent 1px),
    linear-gradient(90deg, rgba(var(--hairline-rgb,15,23,42),.11) 1px, transparent 1px)}

/* Fundo animado. É ENFEITE e se comporta como tal: nasce invisível e só aparece
   quando a biblioteca confirma que desenhou (.vivo). Sem WebGL, sem rede ou com
   erro, ele nunca aparece e o degradê do tenant continua na tela — ninguém fica
   olhando um retângulo preto por causa de um efeito que falhou.

   `screen` é o que tira o PRETO da jogada: a biblioteca pinta a cena inteira de
   preto por baixo dos tubos, e preto não é cor de marca nenhuma. Com `screen`
   todo pixel preto vira transparente e só o brilho sobra, de modo que o fundo
   visível passa a ser o --bg-0/--bg-1 do tenant. */
#fundo-tubos{position:fixed;inset:0;width:100%;height:100%;z-index:0;
  mix-blend-mode:screen;
  opacity:0;transition:opacity .6s ease;pointer-events:none}
#fundo-tubos.vivo{opacity:1}
/* MODO CLARO — a inversão. `screen` sobre fundo claro clarearia tudo até o
   branco e os tubos sumiriam. `invert(1)` faz o preto da cena virar BRANCO (que
   o `multiply` torna transparente, como o `screen` fazia com o preto) e escurece
   os tubos. O `hue-rotate(180deg)` é o que salva a marca: `invert` sozinho troca
   o MATIZ junto com o brilho, e o ciano do CheckBem sairia laranja. */
html:not(.dark) #fundo-tubos{
  mix-blend-mode:multiply;
  filter:invert(1) hue-rotate(180deg)}
/* Quem pediu menos animação não recebe o efeito — a preferência do sistema vale
   mais que o enfeite. */
@media (prefers-reduced-motion:reduce){ #fundo-tubos{display:none} }

/* Controles flutuantes (tamanho da fonte e tema) no canto INFERIOR direito,
   como no painel. Acima da grade e do fundo animado; o cartão não os cobre. */
.controles-flutuantes{position:fixed;bottom:1.25rem;right:1.25rem;z-index:3;
  display:flex;align-items:center;gap:.5rem}
.controles-flutuantes .btn-tema{background:var(--surface);
  box-shadow:0 6px 18px -10px var(--shadow-color,rgba(0,0,0,.35))}

/* Botão do tamanho da fonte: "A" grande com "A" pequeno ao lado, o mesmo
   desenho do painel. `position:relative` por causa do selo do nível. */
.btn-fonte{position:relative}
.btn-fonte .aa{display:flex;align-items:flex-end;gap:1px;line-height:1;font-weight:700}
.btn-fonte .aa-maior{font-size:1rem}
.btn-fonte .aa-menor{font-size:.72rem}
/* O selo só aparece fora do Normal — selo sempre visível vira enfeite e para
   de comunicar. Quem o esconde é o atributo `hidden`, posto pelo script. */
.fonte-selo{position:absolute;top:-4px;right:-4px;min-width:16px;height:16px;
  padding:0 3px;border-radius:99px;font-size:10px;font-weight:700;line-height:16px;
  text-align:center;background:var(--primary);color:#fff}

/* z-index acima da grade — sem isto o cartão ficaria por baixo dela. */
.entrada{position:relative;z-index:1;
  min-height:100vh;display:flex;align-items:center;justify-content:center;
  padding:2.5rem 1.25rem}
.cartao-entrada{display:block;width:100%;max-width:25rem;
  background:var(--surface);border:1px solid var(--border);border-radius:16px;
  padding:2rem 1.75rem 1.85rem;
  box-shadow:0 18px 40px -18px var(--shadow-color,rgba(0,0,0,.25))}

/* Marca no topo, LADO A LADO e centralizada — símbolo à esquerda, nome à
   direita, no arranjo do lockup do manual.
   Não há faixa de cor: a marca pousa na própria superfície do cartão, como no
   login do Argus. É por isso que o arquivo cadastrado precisa ser a variante
   do tema padrão da loja — a superfície é branca no claro e escura no escuro. */
.marca-topo{display:flex;align-items:center;justify-content:center;gap:.9rem;
  margin-bottom:1.1rem;flex-wrap:wrap}
/* Limitado pelos DOIS lados, e é o que faz um campo só servir a desenhos de
   formatos opostos: o lockup é deitado (340×96) e bate no `max-width`, ficando
   com ~97px de altura; um símbolo quadrado bate no `max-height` e fica 88×88.
   Fixar só a altura esticaria o lockup para além da largura do cartão. */
.marca-topo .marca-img{max-height:88px;max-width:100%;width:auto;height:auto}
.marca-topo strong{font-size:1.25rem;font-weight:700;line-height:1.15;letter-spacing:.01em}

/* Fio separando a marca do texto de boas-vindas. Herdado do login do Argus,
   onde ele entrou justamente para marcar essa transição sem pesar. */
.divisor{height:1px;background:rgba(var(--hairline-rgb,148,163,184),.25);
  margin-bottom:1.1rem}

.corpo-entrada h1{font-size:1.3rem;margin-bottom:.25rem;text-align:center}
.corpo-entrada .sub{color:var(--text-secondary);font-size:.88rem;
  margin-bottom:1.35rem;text-align:center}
.corpo-entrada .aviso{margin-bottom:1.1rem}

.campo{margin-bottom:.9rem}
.campo label{display:block;font-size:.78rem;margin-bottom:.35rem}
/* A moldura fica na .shell, não no input: o ícone e o olho moram dentro dela,
   e é ela que recebe o foco visível. O input perde a borda que a regra global
   dá a todo campo do site. */
.shell{display:flex;align-items:center;gap:.6rem;padding:.55rem .75rem;
  border-radius:var(--raio);background:var(--panel,var(--surface));
  border:1px solid rgba(var(--hairline-rgb,148,163,184),.3)}
.shell:focus-within{border-color:var(--primary);
  box-shadow:0 0 0 3px rgba(var(--hairline-rgb,148,163,184),.14)}
.shell input{border:0;background:transparent;padding:.15rem 0;border-radius:0;flex:1;min-width:0}
.shell input:focus{outline:none}
.shell .ico,.olho{display:flex;color:var(--text-secondary);flex-shrink:0}
.shell .ico svg,.olho svg{width:17px;height:17px}
.olho{border:0;background:transparent;padding:0;cursor:pointer;font:inherit}
.olho:hover{color:var(--text-primary)}
/* Um olho por vez, por CLASSE — o atributo hidden não vale em SVG. Ver a nota
   em views/login.js. */
.olho .olho-fechado{display:none}
.olho.revelado .olho-aberto{display:none}
.olho.revelado .olho-fechado{display:block}

/* So o link sobrou aqui depois que o "lembrar de mim" saiu. */
.linha-entrada{display:flex;justify-content:flex-end;margin:.9rem 0 1.1rem;font-size:.85rem}
.btn-cheio{width:100%;text-align:center;border:0;cursor:pointer}
