/* ============================================================================
   SignalCoast OS — sistema de design
   ----------------------------------------------------------------------------
   Escuro por omissão, claro por preferência do sistema. A inversão face à
   versão anterior (clara por omissão) é deliberada: esta é uma ferramenta de
   operação usada durante turnos longos, muitas vezes em armazém com pouca luz.
   O modo claro continua totalmente suportado — em campo, ao sol, é o único
   legível — e resolve-se todo por tokens, sem duplicar regras.

   Todos os nomes de classe da versão anterior foram preservados: isto é uma
   nova pele e um novo layout, não uma reescrita de markup. As 19 páginas e os
   ~8600 linhas de JS continuam a funcionar sem alterações.
   ========================================================================== */

:root {
  /* Superfícies — escala de elevação, não tons ao acaso. O quase-preto tem
     ponta de azul, amostrado do fundo do material de marca (#000105), para as
     superfícies assentarem na mesma família da identidade em vez de num
     cinzento neutro que a faria parecer colada por cima. */
  --bg: #00040a;
  --surface: #0a1120;
  --surface-2: #101a2d;
  --surface-3: #16233a;
  --border: #1c2c47;
  --border-forte: #27395a;

  --text: #e8eef7;
  --text-forte: #ffffff;
  --muted: #8697b0;
  --muted-fraco: #5a6b85;

  /* Ciano da marca, amostrado do logótipo: é a cor do brilho das fibras
     (#03a4ef) sobre o azul profundo do corpo do "S" (#104080). Substituiu um
     teal escolhido antes de eu ter visto a identidade. Continua a distinguir-se
     dos estados semânticos (verde/âmbar/vermelho), que é o que interessa para
     nunca se confundir uma ação com um estado — mas agora é a cor da empresa. */
  --accent: #03a4ef;
  --accent-forte: #0b7fc4;
  --accent-fraco: rgba(3, 164, 239, 0.14);
  --accent-texto: #00121f;
  --accent-profundo: #104080;

  /* Estados semânticos */
  --ok: #34d399;
  --ok-bg: rgba(52, 211, 153, 0.12);
  --aviso: #fbbf24;
  --aviso-bg: rgba(251, 191, 36, 0.12);
  --erro: #f87171;
  --erro-bg: rgba(248, 113, 113, 0.12);
  --info: #60a5fa;
  --info-bg: rgba(96, 165, 250, 0.12);

  --radius: 12px;
  --radius-sm: 8px;
  --radius-lg: 16px;

  --sombra: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px -12px rgba(0, 0, 0, 0.6);
  --sombra-modal: 0 24px 64px -16px rgba(0, 0, 0, 0.7);

  --nav-largura: 244px;

  --fonte: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  /* Números de série, OTs e contas de serviço são identificadores que se leem
     carácter a carácter e se comparam entre linhas — em monoespaçada, com
     algarismos de largura fixa, o alinhamento vertical faz esse trabalho. */
  --fonte-mono: "JetBrains Mono", "SF Mono", ui-monospace, "Cascadia Code", Consolas, monospace;
}

/* O tema segue a preferência do sistema por omissão, mas o utilizador pode
   forçá-lo pelo botão no rodapé da navegação (guardado em localStorage — ver
   aplicarTema() em auth-comum.js). O seletor de atributo tem especificidade
   (0,2,0) contra os (0,1,0) de `:root`, por isso a escolha explícita vence
   sempre a media query, independentemente da ordem no ficheiro. */
:root[data-tema="light"] {
  --bg: #f4f6fa;
  --surface: #ffffff;
  --surface-2: #f8fafc;
  --surface-3: #eef2f7;
  --border: #e2e8f0;
  --border-forte: #cbd5e1;
  --text: #0f172a;
  --text-forte: #000000;
  --muted: #64748b;
  --muted-fraco: #94a3b8;
  --accent: #0b5fa8;
  --accent-forte: #084a85;
  --accent-fraco: rgba(11, 95, 168, 0.1);
  --accent-texto: #ffffff;
  --accent-profundo: #104080;
  --ok: #059669;
  --ok-bg: rgba(5, 150, 105, 0.1);
  --aviso: #b45309;
  --aviso-bg: rgba(180, 83, 9, 0.1);
  --erro: #dc2626;
  --erro-bg: rgba(220, 38, 38, 0.08);
  --info: #2563eb;
  --info-bg: rgba(37, 99, 235, 0.08);
  --sombra: 0 1px 2px rgba(15, 23, 42, 0.04), 0 8px 24px -16px rgba(15, 23, 42, 0.2);
  --sombra-modal: 0 24px 64px -16px rgba(15, 23, 42, 0.25);
  color-scheme: light;
}

:root[data-tema="dark"] {
  --bg: #00040a;
  --surface: #0a1120;
  --surface-2: #101a2d;
  --surface-3: #16233a;
  --border: #1c2c47;
  --border-forte: #27395a;
  --text: #e8eef7;
  --text-forte: #ffffff;
  --muted: #8697b0;
  --muted-fraco: #5a6b85;
  --accent: #03a4ef;
  --accent-forte: #0b7fc4;
  --accent-fraco: rgba(3, 164, 239, 0.14);
  --accent-texto: #00121f;
  --accent-profundo: #104080;
  --ok: #34d399;
  --ok-bg: rgba(52, 211, 153, 0.12);
  --aviso: #fbbf24;
  --aviso-bg: rgba(251, 191, 36, 0.12);
  --erro: #f87171;
  --erro-bg: rgba(248, 113, 113, 0.12);
  --info: #60a5fa;
  --info-bg: rgba(96, 165, 250, 0.12);
  --sombra: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px -12px rgba(0, 0, 0, 0.6);
  --sombra-modal: 0 24px 64px -16px rgba(0, 0, 0, 0.7);
  color-scheme: dark;
}

@media (prefers-color-scheme: light) {
  :root {
    --bg: #f4f6fa;
    --surface: #ffffff;
    --surface-2: #f8fafc;
    --surface-3: #eef2f7;
    --border: #e2e8f0;
    --border-forte: #cbd5e1;

    --text: #0f172a;
    --text-forte: #000000;
    --muted: #64748b;
    --muted-fraco: #94a3b8;

    /* Modo claro usa o azul profundo da marca (#104080 → #0b5fa8), não o ciano:
       o ciano das fibras é brilhante por desenho e não tem contraste suficiente
       sobre branco. Mesma família da identidade, legibilidade preservada. */
    --accent: #0b5fa8;
    --accent-forte: #084a85;
    --accent-fraco: rgba(11, 95, 168, 0.1);
    --accent-texto: #ffffff;
    --accent-profundo: #104080;

    --ok: #059669;
    --ok-bg: rgba(5, 150, 105, 0.1);
    --aviso: #b45309;
    --aviso-bg: rgba(180, 83, 9, 0.1);
    --erro: #dc2626;
    --erro-bg: rgba(220, 38, 38, 0.08);
    --info: #2563eb;
    --info-bg: rgba(37, 99, 235, 0.08);

    --sombra: 0 1px 2px rgba(15, 23, 42, 0.04), 0 8px 24px -16px rgba(15, 23, 42, 0.2);
    --sombra-modal: 0 24px 64px -16px rgba(15, 23, 42, 0.25);
  }
}

* { box-sizing: border-box; }

/* Mantido da versão anterior, e pelo mesmo motivo: sem isto, uma classe de
   igual especificidade que defina display:flex/grid (.campo, .modal-overlay)
   vence o atributo [hidden] e o elemento fica visível. */
[hidden] { display: none !important; }

html { color-scheme: dark light; }

body {
  margin: 0;
  font-family: var(--fonte);
  font-size: 14px;
  line-height: 1.5;
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
}

::selection { background: var(--accent-fraco); color: var(--text-forte); }

/* Scrollbars discretas — o cromado por omissão em escuro é ruidoso */
* { scrollbar-width: thin; scrollbar-color: var(--border-forte) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: var(--border-forte); border-radius: 99px; border: 3px solid transparent; background-clip: content-box; }
*::-webkit-scrollbar-thumb:hover { background: var(--muted-fraco); background-clip: content-box; }

/* ============================================================================
   LAYOUT — barra lateral + conteúdo
   A classe `com-nav` é posta no <body> por montarCabecalho() (auth-comum.js).
   As páginas sem sessão (login, definir-password) não a têm e ficam centradas.
   ========================================================================== */

body.com-nav { padding-left: var(--nav-largura); }

.app {
  max-width: 1400px;
  margin: 0 auto;
  padding: 28px 32px 72px;
}

/* ============================================================================
   NAVEGAÇÃO LATERAL
   Substitui a barra horizontal de 12 links sem hierarquia. Os links passam a
   estar agrupados por área de trabalho — ver a definição dos grupos em
   auth-comum.js, que é onde a organização vive.
   ========================================================================== */

.nav-lateral {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: var(--nav-largura);
  background: var(--surface);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  z-index: 40;
}

.nav-marca {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 20px 20px 18px;
  font-weight: 700;
  font-size: 15px;
  letter-spacing: -0.01em;
  color: var(--text-forte);
  border-bottom: 1px solid var(--border);
}

/* O logótipo real, extraído do material de marca. Substituiu um quadrado com
   as iniciais "SC" que eu tinha inventado antes de ver a identidade. */
.nav-marca-sigla {
  width: 34px;
  height: 34px;
  object-fit: contain;
  flex-shrink: 0;
  /* O "S" tem brilho próprio no original; em modo claro, sobre branco, esse
     brilho desaparece e a marca fica a flutuar — a sombra devolve-lhe assento. */
  filter: drop-shadow(0 1px 3px rgba(3, 164, 239, 0.35));
}

/* Marca denominativa em maiúsculas espaçadas, como no material original —
   é o traço mais reconhecível da identidade depois do símbolo. */
.nav-marca-nome {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.2;
}

.nav-marca-sub {
  display: block;
  font-size: 9.5px;
  font-weight: 500;
  color: var(--muted);
  letter-spacing: 0.13em;
  text-transform: uppercase;
  margin-top: 2px;
}

.nav-grupos {
  flex: 1;
  overflow-y: auto;
  padding: 14px 12px;
}

.nav-grupo + .nav-grupo { margin-top: 18px; }

.nav-grupo-titulo {
  padding: 0 10px 7px;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--muted-fraco);
}

.nav-lateral a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  margin-bottom: 1px;
  border-radius: var(--radius-sm);
  color: var(--muted);
  text-decoration: none;
  font-size: 13.5px;
  font-weight: 500;
  transition: background 0.12s, color 0.12s;
}

.nav-lateral a:hover { background: var(--surface-3); color: var(--text); }

.nav-lateral a.ativo {
  background: var(--accent-fraco);
  color: var(--accent);
  font-weight: 600;
}

/* Barra de acento à esquerda do item ativo — dá a leitura da posição sem
   depender só da cor, que é o que falha a quem tem daltonismo. */
.nav-lateral a.ativo::before {
  content: "";
  position: absolute;
  left: 0;
  width: 3px;
  height: 20px;
  border-radius: 0 3px 3px 0;
  background: var(--accent);
}

.nav-lateral a { position: relative; }

.nav-icone {
  width: 17px;
  height: 17px;
  flex-shrink: 0;
  stroke: currentColor;
  stroke-width: 1.8;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.nav-rodape {
  border-top: 1px solid var(--border);
  padding: 12px;
}

.nav-utilizador {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px 10px;
  font-size: 13px;
}

.nav-avatar {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--surface-3);
  border: 1px solid var(--border-forte);
  color: var(--text);
  font-size: 11px;
  font-weight: 700;
  flex-shrink: 0;
}

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

.nav-utilizador-nome {
  display: block;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.nav-utilizador-papel {
  display: block;
  font-size: 11px;
  color: var(--muted);
  text-transform: capitalize;
}

.nav-rodape-acoes { display: flex; gap: 6px; }
.nav-rodape-acoes button { flex: 1; font-size: 12px; padding: 7px 8px; }

/* Alternador de tema — quadrado, para não roubar largura aos dois botões
   de texto que já ocupam a linha. */
.nav-rodape-acoes .btn-tema {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 32px;
  padding: 0;
}
.btn-tema svg { width: 15px; height: 15px; stroke: currentColor; stroke-width: 1.8; fill: none; stroke-linecap: round; }

/* Alternador para ecrãs pequenos */
.nav-alternar {
  display: none;
  position: fixed;
  top: 12px;
  left: 12px;
  z-index: 50;
  width: 40px;
  height: 40px;
  place-items: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  cursor: pointer;
  box-shadow: var(--sombra);
}

.nav-fundo { display: none; }

@media (max-width: 1000px) {
  body.com-nav { padding-left: 0; }
  .app { padding: 64px 18px 56px; }
  .nav-alternar { display: grid; }
  .nav-lateral { transform: translateX(-100%); transition: transform 0.2s ease; box-shadow: var(--sombra-modal); }
  .nav-lateral.aberta { transform: translateX(0); }
  .nav-fundo.aberta {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 35;
  }
}

/* ============================================================================
   CABEÇALHO DE PÁGINA
   ========================================================================== */

.app > header { margin-bottom: 24px; }

header h1 {
  margin: 0 0 3px;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--text-forte);
}

/* Marca ao lado do título de cada página. Feito por pseudo-elemento e não por
   um <img> em cada ficheiro: apanha as 17 páginas autenticadas de uma vez e
   não há como alguém criar uma página nova e esquecer-se dele.
   O seletor é `.app > header` de propósito — o ecrã de entrada e o de definir
   password têm o logótipo próprio, maior e centrado, e ficam de fora. */
.app > header h1 {
  display: flex;
  align-items: center;
  gap: 11px;
}

.app > header h1::before {
  content: "";
  width: 27px;
  height: 27px;
  flex-shrink: 0;
  background: url("/marca.png") center / contain no-repeat;
  filter: drop-shadow(0 1px 4px rgba(3, 164, 239, 0.4));
}

.subtitle {
  margin: 0 0 22px;
  color: var(--muted);
  font-size: 13.5px;
}

.app > header .subtitle { margin-bottom: 0; }

h2 { font-size: 16px; font-weight: 650; letter-spacing: -0.01em; }
h3 { font-size: 14px; font-weight: 650; }

/* ============================================================================
   CONTROLOS
   ========================================================================== */

.toolbar {
  display: flex;
  gap: 10px;
  margin-bottom: 18px;
  flex-wrap: wrap;
}

.toolbar input[type="text"] { flex: 1; min-width: 240px; }

input, select, textarea {
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 13.5px;
  font-family: inherit;
  background: var(--surface-2);
  color: var(--text);
  transition: border-color 0.12s, box-shadow 0.12s;
}

input::placeholder, textarea::placeholder { color: var(--muted-fraco); }

input:hover, select:hover, textarea:hover { border-color: var(--border-forte); }

input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-fraco);
}

select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 16px) 50%, calc(100% - 11px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 32px;
}

.btn-primary, .btn-secondary {
  border: 1px solid transparent;
  padding: 9px 15px;
  border-radius: var(--radius-sm);
  font-size: 13.5px;
  font-family: inherit;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, transform 0.06s;
  white-space: nowrap;
}

.btn-primary:active, .btn-secondary:active { transform: translateY(1px); }

.btn-primary { background: var(--accent); color: var(--accent-texto); }
.btn-primary:hover { background: var(--accent-forte); }

.btn-secondary {
  background: var(--surface-2);
  border-color: var(--border);
  color: var(--text);
}
.btn-secondary:hover { background: var(--surface-3); border-color: var(--border-forte); }

/* Ação destrutiva e sem retorno (apagar uma conversa de suporte). Fica em
   contorno e não em vermelho cheio: não é a ação principal de nenhum ecrã, e
   a cor serve para fazer parar antes de clicar, não para atrair o clique. */
.btn-perigo {
  background: transparent;
  border-color: var(--erro);
  color: var(--erro);
}
.btn-perigo:hover { background: var(--erro-bg); }

button:disabled { opacity: 0.5; cursor: not-allowed; }
button:disabled:active { transform: none; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ============================================================================
   PAINÉIS E TABELAS
   ========================================================================== */

.table-wrap {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--sombra);
}

.table-scroll { max-height: 65vh; overflow: auto; }

table { width: 100%; border-collapse: collapse; }

th, td {
  text-align: left;
  padding: 11px 16px;
  border-bottom: 1px solid var(--border);
  font-size: 13.5px;
}

th {
  background: var(--surface-2);
  color: var(--muted);
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  position: sticky;
  top: 0;
  z-index: 1;
  white-space: nowrap;
  border-bottom-color: var(--border-forte);
}

tbody tr { transition: background 0.1s; }
tbody tr:hover { background: var(--surface-2); }
tbody tr:last-child td { border-bottom: none; }

/* Identificadores em monoespaçada — ver nota em --fonte-mono. Classe
   utilitária, aplicada célula a célula por quem monta a tabela: aplicada até
   agora ao nº de série em app.js. Vale a pena estendê-la aos restantes
   identificadores (numero_ot, conta_servico) à medida que se tocar em cada
   página — as tabelas de consultas.js/pesquisa.js montam as células por um
   caminho genérico, sem saber que coluna é qual, por isso não dá para as
   converter todas de uma vez sem lhes mudar a estrutura. */
td.mono, .mono { font-family: var(--fonte-mono); font-size: 12.5px; letter-spacing: -0.01em; }

th.ordenavel { cursor: pointer; user-select: none; }
th.ordenavel:hover { color: var(--text); background: var(--surface-3); }

/* Estados de linha. Barra lateral colorida além do fundo: em modo claro os
   fundos são muito ténues e, sozinhos, não sobrevivem a um monitor mal
   calibrado nem à impressão. */
tr.linha-alerta { background: var(--erro-bg); box-shadow: inset 3px 0 0 var(--erro); }
tr.linha-alerta:hover { background: var(--erro-bg); filter: brightness(1.15); }
tr.linha-aviso { background: var(--aviso-bg); box-shadow: inset 3px 0 0 var(--aviso); }
tr.linha-aviso:hover { background: var(--aviso-bg); filter: brightness(1.15); }
tr.linha-info td { color: var(--info); font-weight: 600; }
tr.linha-ok td { color: var(--ok); font-weight: 600; }

td.celula-ok { background: var(--ok-bg); box-shadow: inset 2px 0 0 var(--ok); }
td.celula-alerta { background: var(--erro-bg); box-shadow: inset 2px 0 0 var(--erro); }

.vazio {
  text-align: center;
  color: var(--muted);
  padding: 44px 32px;
  margin: 0;
  font-size: 13.5px;
}

/* ============================================================================
   CARTÕES, FILTROS, ABAS
   ========================================================================== */

.filtros, .resultado-bloco, .ot-foto-cartao, .scanner-form-col form, .leitor-fisico {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.filtros {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-end;
  padding: 16px;
  margin-bottom: 18px;
}

.filtros .campo, .ot-foto-cartao .campo { display: flex; flex-direction: column; gap: 5px; }

.filtros .campo label, .ot-foto-cartao .campo label {
  font-size: 11px;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.resultado-bloco { padding: 20px; margin-bottom: 18px; box-shadow: var(--sombra); }
.resultado-bloco h2 { margin: 0 0 14px; }

.resultado-bloco h3 {
  margin: 22px 0 10px;
  font-size: 11px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 700;
}

.resultado-resumo {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
  margin-bottom: 10px;
  font-size: 14px;
}

.resultado-resumo > div {
  background: var(--surface-2);
  padding: 12px 14px;
  font-weight: 600;
  color: var(--text-forte);
}

.resultado-resumo strong {
  display: block;
  font-size: 10px;
  color: var(--muted);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  margin-bottom: 3px;
}

.abas {
  display: flex;
  gap: 2px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
}

.abas button {
  border: none;
  background: none;
  padding: 10px 14px;
  font-size: 13.5px;
  font-family: inherit;
  font-weight: 500;
  color: var(--muted);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  white-space: nowrap;
  transition: color 0.12s, border-color 0.12s;
}

.abas button:hover { color: var(--text); }
.abas button.ativo { color: var(--accent); border-bottom-color: var(--accent); font-weight: 650; }

/* ============================================================================
   ESTADO
   ========================================================================== */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 650;
  border: 1px solid transparent;
}

.badge::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
}

.badge-novo { background: var(--ok-bg); color: var(--ok); border-color: var(--ok); }
.badge-usado { background: var(--surface-3); color: var(--muted); border-color: var(--border-forte); }
.badge-recolhido { background: var(--aviso-bg); color: var(--aviso); border-color: var(--aviso); }

.contagem-alerta {
  display: inline-grid;
  place-items: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  margin-left: auto;
  background: var(--erro);
  color: #fff;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
}

.erro { color: var(--erro); font-size: 13px; margin: 0; }
.sucesso { color: var(--ok); font-size: 13px; margin: 0; }

/* Cabeçalho de dia na lista de OTs por confirmar (tecnico.js). Fica colado ao
   topo ao rolar: numa lista comprida, saber a que dia pertence a linha que se
   está a ver é metade da razão de existir o agrupamento. */
tr.grupo-dia td {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border-forte);
  box-shadow: inset 3px 0 0 var(--accent);
  padding: 8px 14px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text-forte);
}

/* Só a inicial — `capitalize` transformaria "Sem data" em "Sem Data". */
tr.grupo-dia td::first-letter { text-transform: uppercase; }

/* Sem realce ao passar o rato: não é uma linha clicável, ao contrário das OTs. */
tbody tr.grupo-dia:hover { background: transparent; }

/* Barra de pesquisa de listas já montadas no ecrã — criada por
   `criarBarraPesquisa()` em auth-comum.js. O campo estica e a contagem fica
   encostada à direita, para o número não dançar conforme o que se escreve. */
.barra-pesquisa {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 12px;
  flex-wrap: wrap;
}

.barra-pesquisa input[type='search'] {
  flex: 1 1 260px;
  min-width: 0;
}

.barra-pesquisa-contagem {
  font-size: 13px;
  color: var(--muted);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* Enquanto há filtro ativo o número deixa de ser informação de fundo e passa
   a ser a explicação de porque é que a lista está mais curta. */
.barra-pesquisa-contagem.a-filtrar {
  color: var(--accent);
  font-weight: 600;
}

/* Aviso de lista truncada — inserido por `mostrarAvisoLimite()` em
   auth-comum.js, em qualquer página cuja listagem tenha batido no teto de
   registos. Fixo no fundo em vez de no topo da tabela: as páginas têm
   estruturas de cabeçalho diferentes e não há um sítio comum onde encaixar,
   e assim continua visível depois de se rolar por 500 linhas. */
.aviso-limite {
  position: fixed;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 60;
  max-width: min(680px, calc(100vw - 32px));
  padding: 10px 16px;
  border: 1px solid var(--aviso);
  border-radius: 8px;
  background: var(--aviso-bg);
  color: var(--aviso);
  font-size: 13px;
  line-height: 1.4;
  text-align: center;
  backdrop-filter: blur(6px);
}

.indicador-producao {
  display: inline-block;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 2px solid var(--border-forte);
  cursor: default;
  flex-shrink: 0;
}

/* ============================================================================
   LINHAS DE TEMPO E LISTAS
   ========================================================================== */

.timeline { list-style: none; margin: 0; padding: 0; }
.timeline li { padding: 12px 0 12px 16px; border-bottom: 1px solid var(--border); position: relative; }
.timeline li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 18px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
}
.timeline li:last-child { border-bottom: none; }
.timeline .timeline-data { font-size: 11.5px; color: var(--muted); font-family: var(--fonte-mono); }
.timeline .timeline-evento { font-weight: 600; color: var(--text-forte); }

.lista-simples { list-style: none; padding: 0; margin: 8px 0; }

.lista-simples li {
  padding: 8px 12px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  margin-bottom: 5px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 13.5px;
}

.row-actions { display: flex; gap: 2px; }

.row-actions button {
  border: none;
  background: none;
  cursor: pointer;
  font-size: 12.5px;
  font-family: inherit;
  padding: 5px 9px;
  border-radius: 6px;
  color: var(--muted);
  transition: background 0.12s, color 0.12s;
}
.row-actions button:hover { background: var(--surface-3); color: var(--text); }
.row-actions .del:hover { background: var(--erro-bg); color: var(--erro); }

/* ============================================================================
   MODAIS
   ========================================================================== */

.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(5, 7, 12, 0.7);
  backdrop-filter: blur(3px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 100;
}

.modal {
  background: var(--surface);
  border: 1px solid var(--border-forte);
  border-radius: var(--radius-lg);
  padding: 24px;
  width: 100%;
  max-width: 480px;
  max-height: 90vh;
  overflow-y: auto;
  box-shadow: var(--sombra-modal);
}

.modal h2 { margin: 0 0 18px; }
.modal form { display: flex; flex-direction: column; gap: 13px; }

.modal label {
  display: flex;
  flex-direction: column;
  gap: 5px;
  font-size: 11px;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.modal label input, .modal label select, .modal label textarea {
  font-size: 13.5px;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  color: var(--text);
}

.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 8px; }

/* ============================================================================
   AUTENTICAÇÃO
   ========================================================================== */

.login-wrap {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  position: relative;
  overflow: hidden;
}

/* Halo de acento por trás do cartão — a única decoração puramente estética do
   sistema, e fica confinada ao ecrã de entrada. Ecoa o brilho que o logótipo
   tem no material de marca, onde o "S" irradia sobre fundo escuro. */
.login-wrap::before {
  content: "";
  position: absolute;
  width: 760px;
  height: 760px;
  border-radius: 50%;
  background: radial-gradient(circle, var(--accent-fraco) 0%, transparent 65%);
  pointer-events: none;
}

.login-marca {
  display: block;
  width: 78px;
  height: 78px;
  object-fit: contain;
  margin: 0 auto 18px;
  filter: drop-shadow(0 4px 18px rgba(3, 164, 239, 0.45));
}

/* Denominativo do ecrã de entrada, no registo do material de marca:
   maiúsculas, muito espaçadas, peso leve. */
.login-box h1 {
  font-size: 19px;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  text-align: center;
  margin: 0 0 6px;
}

.login-box .subtitle {
  text-align: center;
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  margin: 0 0 26px;
}

/* Fio de acento no topo do cartão — a linha de fibra da identidade. */
.login-box::before {
  content: "";
  position: absolute;
  top: 0;
  left: 22%;
  right: 22%;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
}

.login-box {
  position: relative;
  width: 100%;
  max-width: 380px;
  background: var(--surface);
  border: 1px solid var(--border-forte);
  border-radius: var(--radius-lg);
  padding: 32px;
  box-shadow: var(--sombra-modal);
}

.login-box h1 { margin: 0 0 3px; font-size: 21px; }
.login-box .subtitle { margin: 0 0 24px; }
.login-box form { display: flex; flex-direction: column; gap: 14px; }

.login-box label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 11px;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.login-box input, .login-box .btn-primary { width: 100%; }
.login-box input { font-size: 14px; font-weight: 400; text-transform: none; letter-spacing: 0; }
.login-box .btn-primary { padding: 11px; margin-top: 4px; }

/* ============================================================================
   IMPORTAÇÃO POR FOTO
   ========================================================================== */

.ot-foto-cartao { padding: 18px; margin-bottom: 14px; }

.ot-foto-cartao .ot-foto-campos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
}

.ot-foto-cartao .ot-foto-topo {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 14px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}

.ot-foto-cartao .ot-foto-topo strong { font-size: 15px; color: var(--text-forte); font-family: var(--fonte-mono); }

/* ============================================================================
   SCANNER / ENTRADAS
   ========================================================================== */

.scanner-wrap { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }

@media (max-width: 900px) { .scanner-wrap { grid-template-columns: 1fr; } }

.scanner-video-col video {
  width: 100%;
  border-radius: var(--radius);
  background: #000;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border: 1px solid var(--border-forte);
}

.scanner-acoes { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }

.scanner-form-col form { display: flex; flex-direction: column; gap: 14px; padding: 20px; }

.scanner-form-col label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 11px;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.scanner-form-col label input, .scanner-form-col label select, .scanner-form-col label textarea {
  font-size: 13.5px; font-weight: 400; text-transform: none; letter-spacing: 0; color: var(--text);
}

/* Campo de leitor de código de barras — destacado porque é o único elemento
   da página que tem de ter o foco do teclado em permanência. */
.leitor-fisico {
  padding: 14px;
  margin-bottom: 16px;
  border-color: var(--accent);
  background: var(--accent-fraco);
}

.leitor-fisico input {
  font-size: 16px;
  font-weight: 600;
  font-family: var(--fonte-mono);
  letter-spacing: 0.02em;
}

.previa-documento {
  width: 100%;
  border-radius: var(--radius);
  margin-bottom: 12px;
  border: 1px solid var(--border);
}

#confUltimaLeitura {
  font-weight: 650;
  padding: 11px 14px;
  border-radius: var(--radius-sm);
  font-size: 14px;
  border: 1px solid transparent;
}

#confUltimaLeitura.leitura-ok { color: var(--ok); background: var(--ok-bg); border-color: var(--ok); }
#confUltimaLeitura.leitura-repetida { color: var(--aviso); background: var(--aviso-bg); border-color: var(--aviso); }
#confUltimaLeitura.leitura-erro { color: var(--erro); background: var(--erro-bg); border-color: var(--erro); }

/* ============================================================================
   COMPATIBILIDADE
   A barra horizontal antiga (.nav-topo/.nav-links) já não é gerada, mas as
   regras ficam para o caso de alguma página a construir à mão.
   ========================================================================== */

.nav-topo {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 12px 24px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}

.nav-links { display: flex; gap: 3px; flex: 1; flex-wrap: wrap; }

.nav-links a {
  padding: 6px 11px;
  border-radius: var(--radius-sm);
  color: var(--muted);
  text-decoration: none;
  font-size: 13.5px;
}

.nav-links a:hover { background: var(--surface-3); color: var(--text); }
.nav-links a.ativo { background: var(--accent-fraco); color: var(--accent); font-weight: 600; }

@media print {
  .nav-lateral, .nav-alternar, .nav-fundo, .toolbar, .row-actions { display: none !important; }
  body.com-nav { padding-left: 0; }
  .app { max-width: none; padding: 0; }
  .table-wrap, .resultado-bloco { border: 1px solid #ccc; box-shadow: none; }
  .table-scroll { max-height: none; overflow: visible; }
}

/* ============================================================================
   SUPORTE — conversa técnico ↔ admin
   ========================================================================== */

.suporte-wrap {
  display: grid;
  grid-template-columns: 300px 1fr;
  gap: 16px;
  align-items: start;
}

.suporte-lista { position: sticky; top: 24px; }

.suporte-item {
  display: flex;
  flex-direction: column;
  gap: 3px;
  width: 100%;
  text-align: left;
  padding: 12px 14px;
  margin-bottom: 6px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text);
  font-family: inherit;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}

.suporte-item:hover { background: var(--surface-2); border-color: var(--border-forte); }
.suporte-item.ativo { border-color: var(--accent); background: var(--accent-fraco); }
/* Resolvida — presente na lista, mas sem competir com o que está por tratar. */
.suporte-item.fechada { opacity: 0.6; }

.suporte-item-topo { display: flex; align-items: center; gap: 8px; }
.suporte-item-topo strong { flex: 1; font-size: 13.5px; }
.suporte-item-meta { font-size: 11px; color: var(--muted); }

.suporte-item-previa {
  font-size: 12px;
  color: var(--muted-fraco);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.suporte-detalhe {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px;
  box-shadow: var(--sombra);
}

/* Os botões do cabeçalho ("Marcar como resolvida" e "Apagar") num grupo só,
   para não separarem quando o assunto é comprido. */
.suporte-cabecalho-acoes {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}

.suporte-cabecalho {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  padding-bottom: 14px;
  margin-bottom: 14px;
  border-bottom: 1px solid var(--border);
}

.suporte-mensagens {
  max-height: 52vh;
  overflow-y: auto;
  padding-right: 6px;
  margin-bottom: 16px;
}

.suporte-balao {
  max-width: 78%;
  margin-bottom: 12px;
  padding: 10px 13px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

/* As próprias à direita, com o acento — a convenção de qualquer app de
   mensagens, e dispensa ler o nome para saber quem falou. */
.suporte-balao.propria {
  margin-left: auto;
  background: var(--accent-fraco);
  border-color: var(--accent);
}

.suporte-balao-meta { font-size: 10.5px; color: var(--muted); margin-bottom: 5px; }
.suporte-balao-texto { margin: 0; font-size: 13.5px; white-space: pre-wrap; word-break: break-word; }

.suporte-anexo-img {
  display: block;
  max-width: 100%;
  max-height: 320px;
  margin-top: 8px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-forte);
}

.suporte-anexo-ficheiro { margin-top: 8px; font-size: 12px; }

@media (max-width: 900px) {
  .suporte-wrap { grid-template-columns: 1fr; }
  .suporte-lista { position: static; }
  .suporte-mensagens { max-height: none; }
}
