/* TEMA — o desenho das páginas, num ficheiro só (23/09).

   Porque existe: cada página tinha as suas caixas, com as suas classes (ag-*, dr-*, tp-*,
   inv-*, infra-*…) e as mesmas decisões repetidas cinco vezes com números ligeiramente
   diferentes. Mudar o aspecto era percorrer cinquenta páginas. Aqui estão as DECISÕES (variáveis
   --t-*) e as PEÇAS (classes .t-*); os componentes em Components/Tema escrevem o HTML delas.

   Para trocar de template: muda-se este ficheiro. As páginas não sabem de cores nem de raios —
   só dizem «isto é um cartão em estado mau», e o tema decide como isso se vê.

   As cores de base (--panel, --line, --green…) continuam no app.css, com o tema claro e o
   escuro; aqui só se decide COMO se usam. */

:root {
    /* Superfícies */
    --t-fundo-cartao: var(--panel);
    --t-fundo-interior: var(--panel2);
    --t-borda: var(--line);
    --t-borda-forte: var(--line2);
    --t-texto: var(--text);
    --t-texto-fraco: var(--muted);

    /* Estados — significado, não enfeite. */
    --t-bom: var(--green);
    --t-aviso: var(--amber);
    --t-mau: var(--red);
    --t-info: var(--cyan);
    --t-neutro: var(--line2);

    /* Forma */
    --t-raio: 14px;
    --t-raio-interior: 10px;
    --t-raio-pastilha: 999px;
    --t-acento: 4px;              /* o fio de cor no topo de um cartão */
    --t-sombra-hover: 0 8px 22px rgba(0,0,0,.12);

    /* Espaço */
    --t-espaco: 14px;             /* entre cartões */
    --t-folga: 16px;              /* dentro de um cartão */
    --t-folga-interior: 10px;     /* dentro de uma linha */

    /* Letra */
    --t-titulo: 1rem;
    --t-numero: 1.25rem;
    /* O valor de uma métrica dentro de um cartão. Era o --t-numero, pensado para os números do
       topo: com «agora mesmo» ou «25/09 07:47» numa coluna estreita ficava enorme e partia em
       duas linhas (25/09). */
    --t-metrica: 1.05rem;
    --t-rotulo: .64rem;
    --t-pequeno: .76rem;
}

/* ==== versões do design 19/10 ==================================================================================
   TRÊS ASPECTOS DA MESMA APLICAÇÃO (decisão do dono, a partir das quatro propostas de 18/10): cada pessoa escolhe o seu em
   Segurança › Aspecto (DesignDaConta; vai no <html data-design="…"> escrito pelo servidor). O desenho das páginas NÃO
   muda — o Cockpit continua o mesmo, com as caixas KPI —; muda o que aqui se decide: as cores de base, a letra e a
   moldura (o menu e a barra do telemóvel). Cada versão tem claro e escuro.

     actual       o aspecto de sempre (as cores de base continuam no app.css; aqui só os tokens novos)
     cadeia-viva  a 4.ª proposta: moldura azul-noite, área de trabalho limpa, laranja só para agir; Public Sans + IBM Plex Mono
     industrial   a 3.ª proposta: grafite e âmbar, cantos rectos, títulos condensados; Barlow + JetBrains Mono

   As letras servem-se DAQUI (wwwroot/letras, licença OFL ao lado): os locais vivem atrás de VPN e uma letra de fora que
   não carrega abria o cockpit torto. O browser só as descarrega quando a versão que as usa está escolhida.

   Os tokens novos (--t-moldura*, --t-accao*, --t-ed-*) valem nas três: o ECRÃ DO EDITOR é o das propostas em todas as
   versões (barra escura com o que se edita, «Publicar» na cor de agir, tela pontilhada, caixa e configuração lisas). */
@font-face { font-family: "Public Sans"; src: url("letras/public-sans.woff2") format("woff2"); font-weight: 100 900; font-display: swap; }
@font-face { font-family: "IBM Plex Mono"; src: url("letras/ibm-plex-mono-400.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "IBM Plex Mono"; src: url("letras/ibm-plex-mono-600.woff2") format("woff2"); font-weight: 600 700; font-display: swap; }
@font-face { font-family: "Barlow"; src: url("letras/barlow-400.woff2") format("woff2"); font-weight: 400 500; font-display: swap; }
@font-face { font-family: "Barlow"; src: url("letras/barlow-600.woff2") format("woff2"); font-weight: 600 800; font-display: swap; }
@font-face { font-family: "Barlow Condensed"; src: url("letras/barlow-condensed-600.woff2") format("woff2"); font-weight: 500 600; font-display: swap; }
@font-face { font-family: "Barlow Condensed"; src: url("letras/barlow-condensed-700.woff2") format("woff2"); font-weight: 700 900; font-display: swap; }
@font-face { font-family: "JetBrains Mono"; src: url("letras/jetbrains-mono.woff2") format("woff2"); font-weight: 100 800; font-display: swap; }

/* -- Os tokens novos com os valores da versão ACTUAL (quem não escolhe nada só vê diferença no ecrã do editor). -- */
:root {
    --t-moldura: #0b1726;            /* a barra escura: a do editor nas três versões; nas outras duas também o menu */
    --t-moldura-texto: #eef5fb;
    --t-moldura-fraco: #a9bccc;
    --t-moldura-linha: #22384f;
    --t-moldura-activo: #17304a;
    --t-moldura-marca: #29b6ff;      /* o traço do item escolhido e o que está activo na barra escura */
    --t-accao: #0879c9;              /* agir: «Publicar» no editor */
    --t-accao-texto: #ffffff;
    --t-primario: #0879c9;
    --t-primario-texto: #ffffff;
    --t-ed-tela: var(--bg);
    --t-ed-ponto: color-mix(in srgb, var(--line2) 75%, transparent);
    --t-letra-numeros: var(--mono);
    --t-moldura-aviso: #ffc46b;      /* «N por configurar» na barra escura */
    --t-moldura-bom: #7fe0a8;
}

/* -- CADEIA VIVA ---------------------------------------------------------------------------------------------- */
:root[data-design="cadeia-viva"], .t-design-amostra[data-design="cadeia-viva"] {
    color-scheme: dark;
    --bg: #0b1522; --panel: #111e2f; --panel2: #0e1a29; --line: #22344d; --line2: #2f4663;
    --text: #e9eef5; --ink: #d7e0ec; --muted: #9db0c9;
    --cyan: #6aaef5; --green: #4cc38a; --amber: #f0954f; --red: #f26b6f; --purple: #a98bf0;
    --shadow: 0 10px 30px rgba(0,0,0,.28);
    --mono: "IBM Plex Mono", ui-monospace, Consolas, monospace;
    --t-moldura: #07101b; --t-moldura-texto: #ffffff; --t-moldura-fraco: #b9c6d8; --t-moldura-linha: #1d2f46;
    --t-moldura-activo: #1b3352; --t-moldura-marca: #f08c4a;
    --t-accao: #c2410c; --t-accao-texto: #ffffff;
    --t-primario: #2a6fb8; --t-primario-texto: #ffffff;
    --t-letra: "Public Sans", "Segoe UI Variable Text", "Segoe UI", system-ui, sans-serif;
    --t-letra-titulos: var(--t-letra);
}
:root[data-design="cadeia-viva"][data-theme="light"], :root[data-theme="light"] .t-design-amostra[data-design="cadeia-viva"] {
    color-scheme: light;
    --bg: #f6f7f9; --panel: #ffffff; --panel2: #f1f3f6; --line: #dde2ea; --line2: #cdd4de;
    --text: #141a23; --ink: #1f2937; --muted: #566173;
    --cyan: #0b5cad; --green: #1e7b34; --amber: #a84b00; --red: #c92a2a; --purple: #6741b8;
    --shadow: 0 1px 2px rgba(16,24,40,.06);
    --t-moldura: #0e1b2c; --t-moldura-activo: #1b3352; --t-moldura-linha: #22344d;
    --t-primario: #0b5cad;
}

/* -- INDUSTRIAL ------------------------------------------------------------------------------------------------ */
:root[data-design="industrial"], .t-design-amostra[data-design="industrial"] {
    color-scheme: dark;
    --bg: #141619; --panel: #1c1f23; --panel2: #202328; --line: #2e3238; --line2: #4a5059;
    --text: #e8e6e1; --ink: #c9cdd2; --muted: #a3abb4;
    --cyan: #8cc0e3; --green: #74d9a0; --amber: #ffd467; --red: #ff8e82; --purple: #b9a6ff;
    --shadow: none;
    --mono: "JetBrains Mono", ui-monospace, Consolas, monospace;
    --t-moldura: #0f1113; --t-moldura-texto: #e8e6e1; --t-moldura-fraco: #b3bac2; --t-moldura-linha: #2e3238;
    --t-moldura-activo: #22262b; --t-moldura-marca: #f2a900;
    --t-accao: #f2a900; --t-accao-texto: #141619;
    --t-primario: #f2a900; --t-primario-texto: #141619;
    --t-letra: "Barlow", "Bahnschrift", "Segoe UI", system-ui, sans-serif;
    --t-letra-titulos: "Barlow Condensed", "Bahnschrift SemiCondensed", "Arial Narrow", sans-serif;
}
:root[data-design="industrial"][data-theme="light"], :root[data-theme="light"] .t-design-amostra[data-design="industrial"] {
    color-scheme: light;
    --bg: #eeefef; --panel: #ffffff; --panel2: #f3f3f2; --line: #d3d6da; --line2: #b6bbc1;
    --text: #16181b; --ink: #23272c; --muted: #50565e;
    --cyan: #24597d; --green: #1d6b3f; --amber: #875800; --red: #b3261e; --purple: #5b3fb0;
    --shadow: none;
    --t-moldura: #16181b; --t-moldura-activo: #26292e;
}

/* -- A versão actual, só para as amostras da escolha (as de verdade estão no app.css). -- */
.t-design-amostra[data-design="actual"] {
    --bg: #050a11; --panel: #0b1420; --panel2: #0f1b29; --line: #1d3348; --line2: #294863; --text: #f2f9ff; --muted: #93a9bd;
    --cyan: #00c8ff; --green: #25e47b; --amber: #ffb020; --red: #ff435d;
    --t-moldura: #070f19; --t-moldura-fraco: #89a0b3; --t-moldura-marca: #00c8ff; --t-accao: #0879c9;
    --t-letra: "Segoe UI Variable Text", "Segoe UI", system-ui, sans-serif; --t-letra-titulos: var(--t-letra);
}
:root[data-theme="light"] .t-design-amostra[data-design="actual"] {
    --bg: #eef2f7; --panel: #ffffff; --panel2: #f3f7fb; --line: #d7e0ea; --line2: #c3d2df; --text: #10202e; --muted: #566a7d;
    --cyan: #006ea8; --green: #0b7d45; --amber: #a15c00; --red: #c8102e;
    --t-moldura: #ffffff; --t-moldura-fraco: #566a7d; --t-moldura-marca: #006ea8;
}


/* ---- Resumo: os números da página numa linha --------------------------------------- */
.t-topo { display: flex; justify-content: space-between; align-items: center; gap: 12px 20px;
          flex-wrap: wrap; margin: 4px 0 18px; }
/* A BARRA DE NÚMEROS (01/10). Eram pastilhas soltas, redondas e espaçadas — o utilizador achou-as
   pesadas, e com seis ou sete lado a lado liam-se como botões. Agora são uma barra só: uma moldura
   discreta, divisórias finas, o número em cima e o rótulo por baixo. O que pede atenção leva um fio
   de cor à esquerda e um fundo ligeiro, não uma pastilha colorida. Fora da barra, um número sozinho
   fica numa caixa da mesma família. */
.t-resumo { display: flex; flex-wrap: wrap; gap: 0; border: 1px solid var(--t-borda); border-radius: 6px;
            background: var(--t-fundo-cartao); overflow: hidden; }
.t-resumo:empty { display: none; }
.t-accoes { display: flex; flex-wrap: wrap; gap: 8px; }
.t-num { display: inline-flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 2px;
         min-width: 86px; padding: 7px 16px 6px; border: 1px solid var(--t-borda); border-radius: 6px;
         background: var(--t-fundo-cartao); font-size: .68rem; line-height: 1.2; letter-spacing: .05em;
         text-transform: uppercase; color: var(--t-texto-fraco); text-decoration: none; text-align: left; }
.t-resumo .t-num { border: 0; border-right: 1px solid var(--t-borda); border-radius: 0; background: transparent; }
.t-resumo .t-num:last-child { border-right: 0; }
.t-num b { font-size: 1.2rem; font-weight: 700; line-height: 1.1; letter-spacing: 0; text-transform: none;
           color: var(--t-texto); font-variant-numeric: tabular-nums; }
.t-num.bom b { color: var(--t-bom); }
.t-num.aviso { background: color-mix(in srgb, var(--t-aviso) 9%, var(--t-fundo-cartao)); box-shadow: inset 3px 0 0 var(--t-aviso); }
.t-num.aviso b { color: var(--t-aviso); }
.t-num.mau { background: color-mix(in srgb, var(--t-mau) 8%, var(--t-fundo-cartao)); box-shadow: inset 3px 0 0 var(--t-mau); }
.t-num.mau b { color: var(--t-mau); }
button.t-num { cursor: pointer; font-family: inherit; }
button.t-num:hover, a.t-num:hover { background: color-mix(in srgb, var(--t-info) 7%, var(--t-fundo-cartao)); }
.t-num.activo { box-shadow: inset 0 -2px 0 var(--t-info); }
button.t-num:focus-visible, a.t-num:focus-visible { outline: 2px solid var(--t-info); outline-offset: -2px; }

/* ---- Grelha ------------------------------------------------------------------------ */
.t-grelha { display: grid; gap: var(--t-espaco); align-items: start;
            grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--t-min, 320px)), 1fr)); }
.t-grelha.esticar { align-items: stretch; }
/* FLUXO: cartões de alturas muito diferentes enchem colunas de cima a baixo, sem deixar buracos
   (um cartão com onze linhas ao lado de um com uma deixava meio ecrã em branco). */
.t-grelha.fluxo { display: block; columns: var(--t-min, 320px); column-gap: var(--t-espaco); }
.t-grelha.fluxo > * { break-inside: avoid; margin-bottom: var(--t-espaco); }

/* ---- Cartão ------------------------------------------------------------------------ */
.t-cartao { box-sizing: border-box; display: flex; flex-direction: column; gap: 10px; min-width: 0;
            padding: var(--t-folga); border-radius: var(--t-raio); background: var(--t-fundo-cartao);
            border: 1px solid var(--t-borda); border-top: var(--t-acento) solid var(--t-cor, var(--t-neutro));
            color: var(--t-texto); text-align: left; }
.t-cartao.bom { --t-cor: var(--t-bom); }
.t-cartao.aviso { --t-cor: var(--t-aviso); }
.t-cartao.mau { --t-cor: var(--t-mau); }
.t-cartao.info { --t-cor: var(--t-info); }
.t-cartao.incerto { border-top-style: dashed; }
button.t-cartao, a.t-cartao { font: inherit; cursor: pointer; text-decoration: none;
                              transition: transform .12s, box-shadow .12s, border-color .12s; }
button.t-cartao:hover, a.t-cartao:hover { transform: translateY(-2px); box-shadow: var(--t-sombra-hover); }
button.t-cartao:focus-visible, a.t-cartao:focus-visible { outline: 2px solid var(--t-info); outline-offset: 2px; }
button.t-cartao { width: 100%; }

.t-cab { display: flex; align-items: center; gap: 10px; min-width: 0; }
.t-cab-texto { display: flex; flex-direction: column; min-width: 0; flex: 1; }
/* O lado direito do cabeçalho é UM grupo: no telemóvel desce inteiro para baixo do título. */
.t-cab-dir { display: flex; align-items: center; gap: 10px; flex: none; }
.t-titulo { font-size: var(--t-titulo); font-weight: 700; overflow-wrap: anywhere; margin: 0; }
.t-sub { font-size: var(--t-pequeno); color: var(--t-texto-fraco); }
.t-sinal { font-size: .68rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
           white-space: nowrap; color: var(--t-cor, var(--t-texto-fraco)); }
.t-cartao.bom .t-sinal { color: var(--t-bom); }
.t-contagem { min-width: 26px; height: 26px; padding: 0 8px; border-radius: var(--t-raio-pastilha);
              display: grid; place-items: center; font-size: .78rem; font-weight: 700;
              background: var(--t-fundo-interior); border: 1px solid var(--t-borda); color: var(--t-texto-fraco); }
.t-logo { width: 32px; height: 32px; border-radius: 8px; object-fit: contain; flex: none; }
.t-logo.sigla { display: grid; place-items: center; font-size: .72rem; font-weight: 800;
                background: color-mix(in srgb, var(--t-cor, var(--t-info)) 14%, transparent);
                color: var(--t-cor, var(--t-info)); }
.t-aviso { padding: 7px 10px; border-radius: 8px; font-size: .78rem;
           background: color-mix(in srgb, var(--t-aviso) 9%, transparent);
           border: 1px solid color-mix(in srgb, var(--t-aviso) 35%, transparent); }
.t-aviso.mau { background: color-mix(in srgb, var(--t-mau) 8%, transparent);
               border-color: color-mix(in srgb, var(--t-mau) 35%, transparent); }

/* ---- Métricas: números pequenos lado a lado dentro de um cartão --------------------- */
.t-metricas { display: grid; gap: 8px; grid-template-columns: repeat(var(--t-colunas, 3), minmax(0, 1fr)); }
.t-metrica { display: flex; flex-direction: column; gap: 2px; padding: 8px 10px; min-width: 0;
             border-radius: var(--t-raio-interior); background: var(--t-fundo-interior); border: 1px solid var(--t-borda); }
.t-metrica small { font-size: var(--t-rotulo); font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
                   color: var(--t-texto-fraco); line-height: 1.3; }
.t-metrica b { font-size: var(--t-metrica); font-weight: 650; font-variant-numeric: tabular-nums; overflow-wrap: break-word; line-height: 1.25; }
.t-metrica span { font-size: .72rem; color: var(--t-texto-fraco); overflow-wrap: anywhere; line-height: 1.35; }
.t-metrica.bom b { color: var(--t-bom); }
.t-metrica.aviso b { color: var(--t-aviso); }
.t-metrica.mau b { color: var(--t-mau); }
@media (max-width: 520px) { .t-metricas { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ---- Linhas: itens dentro de um cartão ---------------------------------------------- */
.t-linhas { display: flex; flex-direction: column; gap: 6px; }
.t-linha { box-sizing: border-box; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center;
           gap: 12px; padding: var(--t-folga-interior) 12px; border-radius: var(--t-raio-interior);
           border: 1px solid transparent; background: var(--t-fundo-interior); color: var(--t-texto);
           text-align: left; min-width: 0; }
button.t-linha, a.t-linha { font: inherit; cursor: pointer; width: 100%; text-decoration: none;
                            transition: border-color .12s; }
button.t-linha:hover, a.t-linha:hover { border-color: var(--t-borda-forte); }
button.t-linha:focus-visible, a.t-linha:focus-visible { outline: 2px solid var(--t-info); outline-offset: 1px; }
.t-linha-texto { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.t-linha-texto b { font-size: .9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.t-linha-texto small { font-size: .74rem; color: var(--t-texto-fraco); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.t-linha.aviso .t-linha-texto small { color: var(--t-aviso); }
.t-linha.mau .t-linha-texto small { color: var(--t-mau); }
.t-linha-dir { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
/* Uma pastilha com uma frase dentro («11 PCs calados: …» com a lista dos nomes) não parte (nowrap) e esticava a coluna
   da direita até aos 1871 px em qualquer largura acima do telemóvel: parte em linhas sempre (26/10, varrimento a 768 px). */
.t-linha-dir { min-width: 0; }
.t-linha-dir .badge { max-width: 100%; white-space: normal; overflow-wrap: anywhere; }
.t-ponto { width: 10px; height: 10px; border-radius: 50%; background: var(--t-neutro); flex: none; }
.t-linha.bom .t-ponto, .t-ponto.bom { background: var(--t-bom); box-shadow: 0 0 0 3px color-mix(in srgb, var(--t-bom) 18%, transparent); }
.t-linha.aviso .t-ponto, .t-ponto.aviso { background: var(--t-aviso); box-shadow: 0 0 0 3px color-mix(in srgb, var(--t-aviso) 18%, transparent); }
.t-linha.mau .t-ponto, .t-ponto.mau { background: var(--t-mau); box-shadow: 0 0 0 3px color-mix(in srgb, var(--t-mau) 18%, transparent); }
.t-seta { color: var(--t-texto-fraco); font-size: 1.2rem; line-height: 1; }

/* ---- Barras ------------------------------------------------------------------------- */
.t-barras { display: flex; gap: 10px; }
.t-barra { display: grid; grid-template-columns: auto auto; column-gap: 4px; row-gap: 3px; width: 58px; }
.t-barra small { font-size: .58rem; font-weight: 700; letter-spacing: .06em; color: var(--t-texto-fraco); }
.t-barra b { font-size: .72rem; text-align: right; font-variant-numeric: tabular-nums; }
.t-barra i { grid-column: 1 / -1; height: 4px; border-radius: 999px; background: var(--t-borda); overflow: hidden; }
.t-barra i u { display: block; height: 100%; background: var(--t-info); border-radius: 999px; }
.t-barra.aviso b { color: var(--t-aviso); }
.t-barra.aviso i u { background: var(--t-aviso); }
.t-barra.mau b { color: var(--t-mau); }
.t-barra.mau i u { background: var(--t-mau); }
.t-barra.larga { width: auto; flex: 1; }
@media (max-width: 520px) {
    .t-linha.com-barras { grid-template-columns: auto minmax(0, 1fr); }
    .t-linha.com-barras .t-barras { grid-column: 1 / -1; }
}

/* ---- Pastilhas ---------------------------------------------------------------------- */
.t-pastilhas { display: flex; flex-wrap: wrap; gap: 5px; }
.t-pastilha { font-size: .68rem; padding: 3px 8px; border-radius: var(--t-raio-pastilha);
              border: 1px solid var(--t-borda); background: var(--t-fundo-interior); color: var(--t-texto); }
.t-pastilha.bom { color: var(--t-bom); border-color: color-mix(in srgb, var(--t-bom) 40%, transparent); }
.t-pastilha.aviso { color: var(--t-aviso); border-color: color-mix(in srgb, var(--t-aviso) 45%, transparent); }
.t-pastilha.mau { color: var(--t-mau); border-color: color-mix(in srgb, var(--t-mau) 45%, transparent); }
/* Informativo (15/10): um estado combinado que não é avaria — a estação em manutenção. */
.t-pastilha.info { color: var(--t-info); border-color: color-mix(in srgb, var(--t-info) 45%, transparent); }
/* Pastilha com um ponto de estado à frente (08/10): «● no ar». O ponto é o .t-ponto, mais pequeno. */
.t-pastilha.com-ponto { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; flex: none; }
.t-pastilha.com-ponto .t-ponto { width: 7px; height: 7px; }

/* ---- Janela (o detalhe que abre por cima) ------------------------------------------- */
.modal.t-janela { position: relative; max-width: min(var(--t-janela, 820px), 96vw); width: 96vw;
                  overflow-y: auto; padding: 0; }
.t-janela-corpo { padding: 22px 26px; display: flex; flex-direction: column; gap: 12px; }
.t-janela-cab { padding-right: 40px; }
.t-janela-cab h3 { margin: 0 0 2px; }
.t-janela-fechar { position: absolute; top: 14px; right: 14px; z-index: 3; }

/* ---- Vazio -------------------------------------------------------------------------- */
.t-vazio { padding: 28px; text-align: center; color: var(--t-texto-fraco); border: 1px dashed var(--t-borda);
           border-radius: var(--t-raio); background: var(--t-fundo-cartao); }
.t-vazio b { display: block; color: var(--t-texto); margin-bottom: 4px; }

/* ---- Secção dentro de uma página ---------------------------------------------------- */
.t-seccao { margin: 22px 0 10px; display: flex; align-items: baseline; gap: 10px; }
.t-seccao h2 { margin: 0; font-size: .82rem; letter-spacing: .08em; text-transform: uppercase; color: var(--t-texto-fraco); }

/* ---- Peças pedidas pelas páginas (23/09) -------------------------------------------------
   Cinco páginas escreveram cada uma a sua versão destas; ficam aqui uma vez. */

/* Botões em linha no fundo de um cartão ou de uma janela. */
.t-cartao-accoes { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.t-cartao-accoes.separado { border-top: 1px solid var(--t-borda); padding-top: 10px; }
/* Campos numa linha de acções (filtros): à largura do conteúdo, não da linha toda. */
.t-cartao-accoes .in, .t-cartao-accoes select, .t-cartao-accoes input { width: auto; min-width: 0; max-width: 100%; }
.t-cartao-accoes label { display: inline-flex; align-items: center; gap: 6px; }

/* Nota neutra — explica, não avisa (o t-aviso é âmbar e lê-se como problema). */
.t-nota { padding: 8px 12px; border-radius: 8px; font-size: .8rem; line-height: 1.5;
          background: color-mix(in srgb, var(--t-info) 6%, transparent);
          border: 1px solid color-mix(in srgb, var(--t-info) 25%, transparent); }

/* Sinal e título de secção com estado. */
.t-sinal.mau { color: var(--t-mau); }
.t-sinal.aviso { color: var(--t-aviso); }
.t-seccao.bom h2 { color: var(--t-bom); }
.t-seccao.aviso h2 { color: var(--t-aviso); }
.t-seccao.mau h2 { color: var(--t-mau); }

/* Pares rótulo / valor (fichas de um PC, de um modelo, de um cliente). */
.t-campos { display: grid; grid-template-columns: minmax(90px, max-content) 1fr; gap: 4px 14px; margin: 0; font-size: .84rem; }
.t-campos dt { color: var(--t-texto-fraco); }
.t-campos dd { margin: 0; overflow-wrap: anywhere; }

/* Escolhas em mosaico (caixas de marcar). */
.t-escolhas { display: grid; gap: 6px; grid-template-columns: repeat(auto-fill, minmax(min(200px, 100%), 1fr)); }
.t-escolha { display: flex; gap: 8px; align-items: center; padding: 7px 10px; border: 1px solid var(--t-borda);
             border-radius: 8px; background: var(--t-fundo-cartao); font-size: .8rem; cursor: pointer; }
.t-escolha:hover { border-color: var(--t-borda-forte); }

/* No tema claro, a cor própria de uma estação (muitas vezes um azul ou um verde claros) só serve
   de texto escurecida: a sigla e o sinal («offline») ficavam a 2,1:1 sobre o próprio tingido (07/10). */
:root[data-theme="light"] .t-logo.sigla,
:root[data-theme="light"] .t-sinal { color: color-mix(in srgb, var(--t-cor, var(--t-texto-fraco)) 60%, #000); }

/* O selector do período: um grupo de botões ligados, da família da barra de números. Nasceu na
   página VPN (01/10) e passou ao tema quando a segunda página precisou dele (07/10). */
.t-periodo { display: inline-flex; flex-wrap: wrap; border: 1px solid var(--t-borda); border-radius: 6px; overflow: hidden;
             background: var(--t-fundo-cartao); }
.t-periodo a { padding: 7px 14px; font-size: .82rem; color: var(--t-texto-fraco); text-decoration: none;
               border-right: 1px solid var(--t-borda); white-space: nowrap; }
.t-periodo a:last-child { border-right: 0; }
.t-periodo a:hover { background: color-mix(in srgb, var(--t-info) 7%, var(--t-fundo-cartao)); }
.t-periodo a.on { background: color-mix(in srgb, var(--t-info) 16%, var(--t-fundo-cartao)); color: var(--t-texto); font-weight: 600; }

/* Um cartão seguido de uma grelha (ou o contrário) respira. */
.t-cartao + .t-grelha, .t-grelha + .t-cartao, .t-grelha + .t-grelha { margin-top: var(--t-espaco); }

/* Barra larga (um disco, uma quota): traço mais grosso. */
.t-barra.larga i { height: 8px; }

/* No telemóvel o lado direito de uma linha desce para debaixo do título: ao lado, um estado
   comprido (ou três pastilhas) empurrava a linha para fora do ecrã. Medido a 390 px (23/09). */
@media (max-width: 520px) {
    .t-linha { grid-template-columns: auto minmax(0, 1fr); }
    .t-linha > .t-linha-dir { grid-column: 2 / -1; justify-content: flex-start; min-width: 0; }
    /* E uma pastilha com uma frase dentro («12 registados · sem falar: …») parte em linhas: a
       pastilha não parte (nowrap) e saía do cartão até aos 1600 px. Apanhado pelo validador (07/10). */
    .t-linha-dir .badge { white-space: normal; max-width: 100%; overflow-wrap: anywhere; border-radius: 10px; line-height: 1.45; }
    /* E o título e o detalhe partem em linhas em vez de reticências. No desktop a reticência tem
       o `title` por baixo do rato; num ecrã de toque não há rato, e o que ficava cortado era
       precisamente o dado — «não respondeu desde qu…», «a maior…», «configurado, aind…» (07/10). */
    .t-linha-texto b, .t-linha-texto small { white-space: normal; overflow-wrap: anywhere; }
    /* O cabeçalho de um cartão com um botão à direita espremia o nome a uma palavra por linha
       («RDS / Monsanto») e o subtítulo a três: o título fica com pelo menos 150 px, e o que não
       couber ao lado desce, em grupo, para a linha de baixo, encostado à direita (07/10). */
    .t-cab { flex-wrap: wrap; }
    .t-cab-texto { flex: 1 1 150px; }
    .t-cab-dir { margin-left: auto; }
}

/* ---- Peças do Cockpit redesenhado (09/10) ----------------------------------------------------
   Nasceram para o Cockpit e são genéricas: qualquer página pode ter uma faixa de indicadores, um painel com
   cabeçalho, filtros em pastilhas, um gráfico de série ou uma cadeia em fio. Só variáveis do tema — as cores do
   claro e do escuro vêm de lá. */

/* Indicadores: o topo da página em cartões, cada um com ícone, valor, sub-texto e barra ou mini-gráfico. */
.t-indicadores { display: grid; gap: var(--t-espaco); margin-bottom: var(--t-espaco);
                 grid-template-columns: repeat(var(--t-colunas, 5), minmax(0, 1fr)); }
@media (max-width: 1180px) { .t-indicadores { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 760px)  { .t-indicadores { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; } }
.t-indicador { box-sizing: border-box; display: flex; flex-direction: column; justify-content: space-between; gap: 8px;
               min-width: 0; padding: 12px 14px; border-radius: var(--t-raio); text-align: left; color: var(--t-texto);
               background: var(--t-fundo-cartao); border: 1px solid var(--t-borda); text-decoration: none; font: inherit;
               --t-cor-i: var(--t-info); }
.t-indicador.bom { --t-cor-i: var(--t-bom); }
.t-indicador.aviso { --t-cor-i: var(--t-aviso); }
.t-indicador.mau { --t-cor-i: var(--t-mau); }
button.t-indicador, a.t-indicador { cursor: pointer; transition: border-color .12s, box-shadow .12s; }
button.t-indicador:hover, a.t-indicador:hover { border-color: var(--t-borda-forte); box-shadow: var(--t-sombra-hover); }
button.t-indicador:focus-visible, a.t-indicador:focus-visible { outline: 2px solid var(--t-info); outline-offset: 2px; }
.t-indicador-topo { display: flex; align-items: center; gap: 12px; min-width: 0; }
.t-indicador-icone { width: 46px; height: 46px; flex: none; display: grid; place-items: center; border-radius: 12px;
                     color: var(--t-cor-i); background: color-mix(in srgb, var(--t-cor-i) 14%, transparent); }
.t-indicador-icone svg { width: 25px; height: 25px; }
/* Em duas colunas o ícone encolhe: ao lado de um cartão de 170 px comia metade do valor. */
@media (max-width: 760px) { .t-indicador-icone { width: 36px; height: 36px; border-radius: 10px; } .t-indicador-icone svg { width: 20px; height: 20px; } }
.t-indicador-texto { display: flex; flex-direction: column; min-width: 0; gap: 1px; }
.t-indicador-texto small { font-size: var(--t-rotulo); font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
                           color: var(--t-texto-fraco); overflow-wrap: anywhere; }
.t-indicador-texto b { font-size: 1.55rem; line-height: 1.15; font-weight: 700; letter-spacing: -.02em;
                       font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.t-indicador-texto span { font-size: var(--t-pequeno); color: var(--t-texto-fraco); line-height: 1.35; overflow-wrap: anywhere; }
.t-indicador-barra { display: flex; align-items: center; gap: 8px; }
.t-indicador-barra i { flex: 1; display: block; height: 6px; border-radius: 999px; background: var(--t-borda); overflow: hidden; }
.t-indicador-barra u { display: block; height: 100%; border-radius: 999px; background: var(--t-cor-i); text-decoration: none; }
.t-indicador-barra em { font-style: normal; font-size: .72rem; font-weight: 700; color: var(--t-texto-fraco);
                        font-variant-numeric: tabular-nums; min-width: 2.6em; text-align: right; }
.t-indicador-mini { display: block; height: 26px; color: var(--t-cor-i); }
.t-indicador-mini .spark { height: 26px; margin: 0; color: inherit; }

/* Painel: uma moldura com cabeçalho (título, contagem, texto fraco, acções). */
.t-painel { box-sizing: border-box; min-width: 0; display: flex; flex-direction: column; gap: 12px; padding: var(--t-folga);
            border-radius: var(--t-raio); background: var(--t-fundo-cartao); border: 1px solid var(--t-borda); color: var(--t-texto); }
.t-painel-cab { display: flex; align-items: center; justify-content: space-between; gap: 8px 12px; flex-wrap: wrap; }
.t-painel-titulo { display: flex; flex-direction: column; min-width: 0; flex: 1 1 160px; }
.t-painel-titulo h3 { margin: 0; font-size: 1.08rem; font-weight: 700; display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; }
.t-painel-titulo h3 .t-contagem { align-self: center; }
.t-painel-nota { font-size: var(--t-pequeno); font-weight: 400; color: var(--t-texto-fraco); }
.t-painel-titulo small { font-size: var(--t-pequeno); color: var(--t-texto-fraco); }
.t-painel-dir { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* Uma tabela dentro de um painel não precisa de uma segunda moldura. */
.t-painel .estacoes-geral { margin: 0; padding: 0; background: none; border: 0; box-shadow: none; }

/* Filtros e separadores: pastilhas que escolhem uma de várias vistas. */
.t-filtros { display: flex; flex-wrap: wrap; gap: 6px; }
.t-filtro { font: inherit; font-size: .78rem; display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
            padding: 5px 12px; border-radius: var(--t-raio-pastilha); cursor: pointer; color: var(--t-texto);
            background: var(--t-fundo-cartao); border: 1px solid var(--t-borda); }
.t-filtro:hover { border-color: var(--t-borda-forte); }
.t-filtro.activo { background: color-mix(in srgb, var(--t-info) 16%, var(--t-fundo-cartao));
                   border-color: color-mix(in srgb, var(--t-info) 55%, transparent); font-weight: 650; }
.t-filtro:focus-visible { outline: 2px solid var(--t-info); outline-offset: 1px; }
.t-filtro .t-ponto { width: 8px; height: 8px; box-shadow: none; }
.t-filtro-n { color: var(--t-texto-fraco); font-variant-numeric: tabular-nums; }
.t-filtros.separadores .t-filtro { border-radius: 8px; border-color: transparent; background: var(--t-fundo-interior); }
.t-filtros.separadores .t-filtro.activo { background: color-mix(in srgb, var(--t-info) 16%, var(--t-fundo-cartao));
                                          border-color: color-mix(in srgb, var(--t-info) 55%, transparent); }
.t-pesquisa { font: inherit; font-size: .8rem; width: 190px; max-width: 100%; padding: 6px 12px; border-radius: var(--t-raio-pastilha);
              background: var(--t-fundo-cartao); border: 1px solid var(--t-borda); color: var(--t-texto); }
.t-seleccao { font: inherit; font-size: .78rem; padding: 5px 10px; border-radius: 8px; width: auto; min-height: 0;
              background: var(--t-fundo-cartao); border: 1px solid var(--t-borda); color: var(--t-texto); }
@media (max-width: 520px) { .t-pesquisa { width: 100%; } }

/* Gráfico de série: eixo do valor, área, horas. */
.t-grafico { display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-rows: var(--t-alt, 150px) auto; column-gap: 8px;
             --t-cor-g: var(--t-info); }
.t-grafico.bom { --t-cor-g: var(--t-bom); }
.t-grafico.aviso { --t-cor-g: var(--t-aviso); }
.t-grafico.mau { --t-cor-g: var(--t-mau); }
.t-grafico-y { position: relative; min-width: 2.2em; font-size: .64rem; color: var(--t-texto-fraco); font-variant-numeric: tabular-nums; }
.t-grafico-y span { position: absolute; right: 0; transform: translateY(50%); line-height: 1; }
.t-grafico-svg { width: 100%; height: 100%; display: block; overflow: visible; }
.t-grafico-grade { stroke: var(--t-borda); stroke-width: 1; vector-effect: non-scaling-stroke; }
.t-grafico-area { fill: color-mix(in srgb, var(--t-cor-g) 16%, transparent); }
.t-grafico-linha { fill: none; stroke: var(--t-cor-g); stroke-width: 2; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.t-grafico-x { grid-column: 2; display: flex; justify-content: space-between; margin-top: 6px; font-size: .64rem; color: var(--t-texto-fraco);
               font-variant-numeric: tabular-nums; }
/* Num gráfico estreito (uma peça de 3 colunas num painel a 768 px) as horas não cabiam numa linha e saíam da peça («21:07»
   cortado, 26/10): a largura do PRÓPRIO gráfico decide quantas se mostram — uma sim, uma não; abaixo de 170 px só a
   primeira e a última, que dizem a janela inteira. */
.t-grafico { container-type: inline-size; }
@container (max-width: 320px) { .t-grafico-x span:nth-child(even):not(:last-child) { display: none; } }
@container (max-width: 170px) { .t-grafico-x span:not(:first-child):not(:last-child) { display: none; } }
.t-grafico-vazio { height: var(--t-alt, 150px); display: grid; place-items: center; text-align: center; padding: 0 12px;
                   font-size: .82rem; color: var(--t-texto-fraco); border: 1px dashed var(--t-borda); border-radius: var(--t-raio-interior); }

/* Cadeia em fio: os elos lado a lado, ligados por setas, cada um com estado e valores. */
.t-fio { display: flex; flex-wrap: wrap; align-items: stretch; gap: 8px 0; }
.t-fio-no { box-sizing: border-box; flex: 1 1 118px; min-width: 112px; display: flex; flex-direction: column; align-items: flex-start; gap: 5px;
            padding: 10px; border-radius: var(--t-raio-interior); text-align: left; font: inherit; color: var(--t-texto);
            background: var(--t-fundo-cartao); border: 1px solid var(--t-borda); --t-cor-f: var(--t-bom); }
.t-fio-no.aviso { --t-cor-f: var(--t-aviso); border-color: color-mix(in srgb, var(--t-aviso) 55%, transparent); background: color-mix(in srgb, var(--t-aviso) 7%, var(--t-fundo-cartao)); }
.t-fio-no.mau { --t-cor-f: var(--t-mau); border-color: color-mix(in srgb, var(--t-mau) 55%, transparent); background: color-mix(in srgb, var(--t-mau) 7%, var(--t-fundo-cartao)); }
.t-fio-no.incerto { --t-cor-f: var(--t-texto-fraco); border-style: dashed; }
button.t-fio-no { cursor: pointer; transition: border-color .12s, box-shadow .12s; }
button.t-fio-no:hover { border-color: var(--t-borda-forte); box-shadow: var(--t-sombra-hover); }
button.t-fio-no:focus-visible { outline: 2px solid var(--t-info); outline-offset: 1px; }
.t-fio-icone { width: 34px; height: 34px; display: grid; place-items: center; border-radius: 9px; color: var(--t-cor-f);
               background: color-mix(in srgb, var(--t-cor-f) 13%, transparent); }
.t-fio-icone svg { width: 22px; height: 22px; }
.t-fio-nome { font-size: .8rem; line-height: 1.25; overflow-wrap: anywhere; }
.t-fio-estado { font-size: .62rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; padding: 2px 7px; border-radius: 999px;
                color: var(--t-cor-f); background: color-mix(in srgb, var(--t-cor-f) 13%, transparent); }
.t-fio-valor { font-size: .8rem; font-weight: 600; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; line-height: 1.3; }
.t-fio-valor small { display: block; font-size: .6rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--t-texto-fraco); }
.t-fio-seta { flex: none; width: 22px; display: grid; place-items: center; color: var(--t-bom); font-size: 1rem; }
.t-fio-seta.mau { color: var(--t-mau); }
.t-fio-seta.incerto { color: var(--t-texto-fraco); opacity: .6; }
/* Compacta: só ícone, nome e estado — para varrer três estações de uma vez. */
.t-fio.compacto .t-fio-no { flex-basis: 96px; min-width: 92px; align-items: center; text-align: center; padding: 8px 6px; }
.t-fio.compacto .t-fio-nome { font-size: .72rem; }
@media (max-width: 760px) {
    .t-fio { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
    .t-fio-seta { display: none; }
    .t-fio-no, .t-fio.compacto .t-fio-no { min-width: 0; }
}

/* Duas colunas de página: o principal e o lado. Abaixo de 1700 px o lado desce para debaixo do que se olha
   primeiro (a classe «primeiro» do principal) e organiza-se em colunas próprias. */
.t-colunas { display: grid; gap: var(--t-espaco); grid-template-columns: minmax(0, 1fr); align-items: start; }
.t-colunas-principal, .t-colunas-lado { display: grid; gap: var(--t-espaco); min-width: 0; align-content: start; }
@media (min-width: 1700px) { .t-colunas { grid-template-columns: minmax(0, 1fr) 360px; } }
@media (max-width: 1699px) {
    .t-colunas-principal { display: contents; }
    .t-colunas > *, .t-colunas-principal > * { order: 3; min-width: 0; }
    .t-colunas-principal > .primeiro { order: 1; }
    .t-colunas-lado { order: 2; grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr)); }
}
/* Dois painéis lado a lado que passam a um quando não cabem. */
.t-par { display: grid; gap: var(--t-espaco); grid-template-columns: repeat(auto-fit, minmax(min(100%, 430px), 1fr)); align-items: stretch; }

/* Itens numerados (acções recomendadas, ranking de risco): número · texto · o que vai à direita. */
.t-itens { display: flex; flex-direction: column; gap: 8px; }
.t-item { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 12px; padding: 10px 12px;
          border-radius: var(--t-raio-interior); background: var(--t-fundo-interior); min-width: 0; }
.t-item-n { width: 30px; height: 30px; display: grid; place-items: center; border-radius: 50%; font-size: .8rem; font-weight: 700;
            background: var(--t-fundo-cartao); border: 1px solid var(--t-borda); }
.t-item-texto { display: flex; flex-direction: column; min-width: 0; gap: 1px; }
.t-item-texto b { font-size: .86rem; overflow-wrap: anywhere; }
.t-item-texto small { font-size: .74rem; color: var(--t-texto-fraco); overflow-wrap: anywhere; }
.t-item-dir { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
@media (max-width: 520px) { .t-item { grid-template-columns: auto minmax(0, 1fr); } .t-item-dir { grid-column: 2; justify-content: flex-start; } }
/* A acção proposta dentro de um item ocupa a largura toda, por baixo. */
.t-item .proposta { grid-column: 1 / -1; margin: 4px 0 0; }

/* Estações no mapa: o mapa e a legenda lado a lado quando há largura. */
.t-mapa { display: grid; gap: 12px; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 560px) and (max-width: 1699px) { .t-mapa { grid-template-columns: minmax(0, 190px) minmax(0, 1fr); align-items: start; } }
.t-legenda { display: flex; flex-wrap: wrap; gap: 6px 12px; font-size: .72rem; color: var(--t-texto-fraco); }
.t-legenda span { display: inline-flex; align-items: center; gap: 5px; }
.t-legenda .t-ponto { width: 8px; height: 8px; box-shadow: none; }

/* A estação seleccionada: cabeçalho com pastilhas de números. */
.t-detalhe-cab { display: flex; align-items: center; gap: 10px 14px; flex-wrap: wrap; }
.t-detalhe-cab h3 { margin: 0; font-size: 1.2rem; }
.t-fichas { display: flex; flex-wrap: wrap; gap: 6px; }
.t-ficha { display: inline-flex; align-items: center; gap: 5px; font-size: .76rem; padding: 3px 10px; border-radius: var(--t-raio-pastilha);
           border: 1px solid var(--t-borda); background: var(--t-fundo-interior); font-variant-numeric: tabular-nums; white-space: nowrap; }
.t-ficha small { color: var(--t-texto-fraco); font-size: .66rem; text-transform: uppercase; letter-spacing: .04em; }

/* Um item que se carrega (o ranking de risco): o mesmo desenho, como botão. */
button.t-item { font: inherit; color: inherit; text-align: left; width: 100%; border: 0; cursor: pointer; }
button.t-item:hover { background: color-mix(in srgb, var(--t-info) 8%, var(--t-fundo-interior)); }
button.t-item:focus-visible { outline: 2px solid var(--t-info); outline-offset: 1px; }

/* A linha da lista de estações que se escolhe: carrega-se, e a escolhida leva um fio à esquerda. */
.estacoes-table tr.escolhivel { cursor: pointer; }
.estacoes-table tr.seleccionada > td { background: color-mix(in srgb, var(--t-info) 9%, transparent) !important; }
.estacoes-table tr.seleccionada > td:first-child { box-shadow: inset 4px 0 0 var(--t-info); }

/* Cadeias prioritárias: uma faixa por estação, com o fio de cor do estado à esquerda. */
.t-prioridade { display: grid; gap: 10px; padding: 12px; border-radius: var(--t-raio-interior); background: var(--t-fundo-interior);
                border: 1px solid var(--t-borda); border-left: 4px solid var(--t-cor, var(--t-neutro)); min-width: 0; }
.t-prioridade.bom { --t-cor: var(--t-bom); }
.t-prioridade.aviso { --t-cor: var(--t-aviso); }
.t-prioridade.mau { --t-cor: var(--t-mau); }
.t-prioridade-cab { display: flex; align-items: center; gap: 8px 12px; flex-wrap: wrap; }
.t-prioridade-cab b { font-size: .95rem; }
.t-prioridade-cab small { color: var(--t-texto-fraco); }

/* Tabelas dentro de painéis (diário, linha de tempo): cabeçalho discreto, linhas respiradas. Em ecrã estreito
   levam também `tab-cartoes` e viram uma ficha por linha (a etiqueta vem do `data-col`). */
.t-tabela { width: 100%; border-collapse: collapse; font-size: .82rem; }
.t-tabela th { text-align: left; padding: 6px 10px; color: var(--t-texto-fraco); font-weight: 700; font-size: .64rem;
               letter-spacing: .06em; text-transform: uppercase; border-bottom: 1px solid var(--t-borda); white-space: nowrap; }
.t-tabela td { padding: 9px 10px; border-bottom: 1px solid var(--t-borda); vertical-align: middle; overflow-wrap: anywhere; }
.t-tabela tr:last-child td { border-bottom: 0; }
.t-tabela td.hora { white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--t-texto-fraco); }
.t-tabela td.fraco { color: var(--t-texto-fraco); }

/* ==== novodesign 09/10 ==========================================================================
   As correcções do utilizador ao Cockpit redesenhado (C:\dev\novodesign.docx): caixas do topo compactas, lista de
   estações com acordeão, mapa compacto. Tudo em variáveis do tema — vale no claro e no escuro. Este bloco vai
   no FIM do ficheiro de propósito: quem mexe nas variáveis de base (no início) não o toca.
   Medidas em rem e em fracções, não em pixéis de altura: a letra pode crescer uns 6 % sem partir nada. */

/* Seis caixas compactas: o valor grande, a legenda por baixo (em minúsculas, como nas maquetas) e a barra ou o
   mini-gráfico no fundo. A ordem visual troca-se com `order` — o HTML do Indicador continua o de sempre. */
.t-indicadores.compactos .t-indicador { gap: 10px; padding: 12px; }
.t-indicadores.compactos .t-indicador-icone { width: 42px; height: 42px; border-radius: 11px;
                                              background: color-mix(in srgb, var(--t-cor-i) 16%, transparent); }
.t-indicadores.compactos .t-indicador-icone svg { width: 23px; height: 23px; }
.t-indicadores.compactos .t-indicador-texto small { order: 2; text-transform: none; letter-spacing: 0; font-size: .8rem;
                                                    font-weight: 500; line-height: 1.25; }
.t-indicadores.compactos .t-indicador-texto b { order: 1; font-size: 1.45rem; }
.t-indicadores.compactos .t-indicador-texto span { order: 3; font-size: .7rem; }
.t-indicadores.compactos .t-indicador-mini, .t-indicadores.compactos .t-indicador-mini .spark { height: 22px; }
@media (max-width: 760px) {
    .t-indicadores.compactos .t-indicador-icone { width: 34px; height: 34px; border-radius: 9px; }
    .t-indicadores.compactos .t-indicador-icone svg { width: 19px; height: 19px; }
    .t-indicadores.compactos .t-indicador-texto b { font-size: 1.3rem; }
}

/* Um pequeno chip no cabeçalho de um painel: um número e o que ele conta, clicável (os sintomas absorvidos). */
.t-chip { font: inherit; font-size: .72rem; display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; cursor: pointer;
          padding: 4px 10px; border-radius: var(--t-raio-pastilha); color: var(--t-texto-fraco);
          background: var(--t-fundo-interior); border: 1px solid var(--t-borda); }
.t-chip b { color: var(--t-texto); font-variant-numeric: tabular-nums; }
.t-chip:hover { border-color: var(--t-borda-forte); }
.t-chip:focus-visible { outline: 2px solid var(--t-info); outline-offset: 1px; }

/* O contador de um painel que pede acção (as acções recomendadas): vermelho enquanto houver pendentes. */
.t-painel.com-pendentes .t-painel-titulo h3 .t-contagem { background: color-mix(in srgb, var(--t-mau) 80%, #000);
                                                         border-color: transparent; color: #fff; }

/* «● RDS Coimbra 92,6 MHz» no cabeçalho das tendências: a estação a que o gráfico se refere. */
.t-ponto.info { background: var(--t-info); box-shadow: none; }
.t-de-estacao { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 4px 7px; font-size: .84rem; font-weight: 650; }
.t-de-estacao small { font-weight: 400; color: var(--t-texto-fraco); font-size: .76rem; }

/* A lista de estações: compacta, uma linha por estação; carregar nela abre o resumo por baixo. */
.t-estacoes-caixa .tabela-wrap { overflow: visible; }   /* o menu «…» abre por cima da tabela */
.t-estacoes td { padding: 6px 10px; }
.t-estacoes th.num, .t-estacoes td.num { text-align: left; font-variant-numeric: tabular-nums; }
.t-estacoes th.acoes { text-align: right; }
.t-estacoes td.t-est-acoes { text-align: right; white-space: nowrap; width: 1%; }
.t-estacoes td.t-est-acoes > * + * { margin-left: 6px; }
.t-est-linha { cursor: pointer; }
.t-est-linha:hover > td { background: color-mix(in srgb, var(--t-info) 6%, transparent); }
.t-est-linha.aberta > td { background: color-mix(in srgb, var(--t-info) 10%, transparent); border-bottom-color: transparent; }
.t-est-linha.aberta > td:first-child { box-shadow: inset 4px 0 0 var(--t-info); }
.t-est-nome { display: inline-flex; align-items: center; gap: 10px; min-width: 0; padding: 0; border: 0; background: none;
              font: inherit; color: inherit; text-align: left; cursor: pointer; }
.t-est-nome b { font-size: .92rem; }
.t-est-nome:focus-visible { outline: 2px solid var(--t-info); outline-offset: 3px; border-radius: 6px; }
.t-est-nome .t-logo { width: 30px; height: 30px; }
.t-est-linha.por-instalar .t-est-nome b { color: var(--t-texto-fraco); }
.t-est-freq { font-variant-numeric: tabular-nums; white-space: nowrap; }
.t-est-idade { display: block; margin-top: 2px; font-size: .68rem; line-height: 1.3;
               color: color-mix(in srgb, var(--t-aviso) 55%, var(--t-texto)); }
.t-est-ultimo { white-space: nowrap; }
.t-est-vazia { text-align: center; color: var(--t-texto-fraco); padding: 22px; }

/* Saúde: uma bolinha por elo da cadeia (verde bom · âmbar aviso · vermelho falha · cinzento sem dados). */
.t-saude { display: inline-flex; align-items: center; gap: 5px; }
.t-saude .t-ponto { width: 11px; height: 11px; box-shadow: none; cursor: help; }   /* +10 % (09/10); o resto da linha não muda */

/* Botões de ícone da linha (estatísticas, abrir, «…»). */
.t-icone-btn { box-sizing: border-box; width: 34px; height: 34px; display: inline-grid; place-items: center; padding: 0; vertical-align: middle;
               border-radius: 9px; cursor: pointer; text-decoration: none; font: inherit;
               color: color-mix(in srgb, var(--t-info) 70%, var(--t-texto)); background: var(--t-fundo-cartao); border: 1px solid var(--t-borda); }
.t-icone-btn svg { width: 18px; height: 18px; display: block; }
.t-icone-btn:hover { border-color: var(--t-borda-forte); background: color-mix(in srgb, var(--t-info) 8%, var(--t-fundo-cartao)); }
.t-icone-btn:focus-visible { outline: 2px solid var(--t-info); outline-offset: 1px; }

/* O menu «…»: aberto por estado do componente; o fundo transparente apanha o clique fora. */
.t-menu { position: relative; display: inline-block; vertical-align: middle; }
.t-menu-fundo { position: fixed; inset: 0; z-index: 40; padding: 0; border: 0; background: transparent; cursor: default; }
.t-menu-lista { position: absolute; right: 0; top: calc(100% + 4px); z-index: 41; min-width: 230px; display: flex; flex-direction: column;
                padding: 6px; text-align: left; white-space: normal; border-radius: var(--t-raio-interior);
                background: var(--t-fundo-cartao); border: 1px solid var(--t-borda-forte); box-shadow: var(--t-sombra-hover); }
.t-menu-lista > a, .t-menu-lista > button { display: block; width: 100%; box-sizing: border-box; padding: 8px 10px; border: 0; border-radius: 7px;
                                            background: none; color: var(--t-texto); font: inherit; font-size: .82rem; text-align: left;
                                            text-decoration: none; cursor: pointer; }
.t-menu-lista > a:hover, .t-menu-lista > button:hover, .t-menu-lista > a:focus-visible, .t-menu-lista > button:focus-visible
    { background: color-mix(in srgb, var(--t-info) 10%, transparent); outline: none; }

/* O resumo que abre por baixo da linha: cabeçalho com pastilhas e a cadeia em fio. */
.t-estacoes tr.t-est-resumo > td { padding: 0 0 8px; border-bottom: 0; }
.t-resumo-est { display: grid; gap: 10px; padding: 12px; min-width: 0; border-radius: var(--t-raio-interior);
                background: var(--t-fundo-interior); border: 1px solid var(--t-borda); border-left: 4px solid var(--t-info); }
@media (max-width: 1024px) {
    /* A tabela vira fichas (tab-cartoes): o resumo é a continuação da ficha da estação, não outra ficha. */
    .t-estacoes tbody tr.t-est-resumo { padding: 0; border: 0; box-shadow: none; margin-top: -4px; }
    .t-estacoes tbody tr.t-est-resumo td:first-child { padding: 0; margin: 0; border: 0; font-weight: 400; }
    .t-estacoes tbody td.t-est-acoes { display: flex; align-items: center; justify-content: flex-start; gap: 6px; padding-top: 8px; width: auto; }
    .t-estacoes td.t-est-acoes > * + * { margin-left: 0; }
    .t-menu-lista { right: auto; left: 0; max-width: calc(100vw - 56px); }
}

/* O mapa compacto: Portugal GRANDE (é o que se vê de relance) e, ao lado, as estações em caixas pequenas — o
   utilizador pediu o mapa maior e as caixas mais pequenas (09/10). */
.t-mapa.compacto { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); align-items: center; gap: 10px; }
.t-mapa.compacto .map { max-width: none; width: 100%; }
@media (min-width: 560px) and (max-width: 1699px) {
    .t-mapa.compacto { grid-template-columns: minmax(0, 250px) minmax(0, 1fr); }
    .t-mapa.compacto .map { max-width: 250px; }
}
@media (max-width: 440px) {
    .t-mapa.compacto { grid-template-columns: minmax(0, 1fr); }
    .t-mapa.compacto .map { max-width: 230px; margin: 0 auto; }
}
.t-mapa-lista { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.t-mapa-item { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 7px; width: 100%; min-width: 0;
               box-sizing: border-box; padding: 3px 7px; border: 0; border-left: 3px solid var(--cor-estacao, transparent); border-radius: 8px; text-align: left; font: inherit; color: inherit;
               cursor: pointer; background: var(--t-fundo-interior); }
.t-mapa-item:hover { background: color-mix(in srgb, var(--t-info) 9%, var(--t-fundo-interior)); }
.t-mapa-item:focus-visible { outline: 2px solid var(--t-info); outline-offset: 1px; }
.t-mapa-item .t-ponto { width: 9px; height: 9px; box-shadow: none; }
.t-mapa-nome { display: flex; flex-direction: column; min-width: 0; line-height: 1.2; }
.t-mapa-nome b { font-size: .76rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.t-mapa-nome small { font-size: .64rem; color: var(--t-texto-fraco); }
/* Segunda linha de cada item: a frequência à esquerda e a pastilha do estado à direita (numa coluna de 360 px o
   nome e a pastilha lado a lado não cabem). */
.t-mapa-linha2 { display: flex; align-items: center; justify-content: space-between; gap: 6px; min-width: 0; margin-top: 2px; }
.t-mapa-item .t-pastilha { font-size: .58rem; padding: 1px 6px; white-space: nowrap; }
/* A legenda do mapa numa linha só quando cabe, sem partir nenhuma entrada ao meio; quando não cabe, a entrada que sobra
   passa para baixo inteira (19/10: em alemão, a 390 px, «auf Sendung · Problem · nicht auf Sendung · Ohne FMDX» numa linha
   só saía 11 px do ecrã). */
.t-mapa + .t-legenda, .t-legenda { flex-wrap: wrap; gap: 4px 10px; white-space: nowrap; }
/* A borda da cor da estação nas linhas da tabela de Estações (a cor vem da ficha da estação). */
.t-tabela tbody tr[style*="--cor-estacao"] > td:first-child { box-shadow: inset 4px 0 0 var(--cor-estacao); }

/* ---- Tendências: a visão geral do sistema (09/10) ---------------------------------------------------------------
   Várias linhas no mesmo gráfico, uma por estação, na cor da ficha dela. As estações sem cor usam estas seis, feitas
   só com as cores do tema (valem no claro e no escuro). A legenda é o interruptor: um botão por estação. */
:root {
    --t-serie-1: var(--t-info);
    --t-serie-2: var(--t-aviso);
    --t-serie-3: var(--t-bom);
    --t-serie-4: color-mix(in srgb, var(--t-info) 55%, var(--t-bom));
    --t-serie-5: color-mix(in srgb, var(--t-aviso) 55%, var(--t-mau));
    --t-serie-6: color-mix(in srgb, var(--t-texto-fraco) 80%, var(--t-info));
}
.t-grafico-multi { display: grid; gap: 10px; min-width: 0; }
.t-grafico-multi .t-grafico-linha { stroke-width: 2; }
.t-serie-legenda { display: flex; flex-wrap: wrap; gap: 6px; }
.t-serie-item { font: inherit; display: inline-flex; align-items: center; gap: 6px; max-width: 100%; min-width: 0; cursor: pointer;
                padding: 3px 10px 3px 8px; border-radius: var(--t-raio-pastilha); color: var(--t-texto);
                background: var(--t-fundo-interior); border: 1px solid var(--t-borda); }
.t-serie-item i { flex: none; width: 10px; height: 10px; border-radius: 3px; background: var(--t-cor-s); }
.t-serie-item b { font-size: .76rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.t-serie-item small { font-size: .68rem; color: var(--t-texto-fraco); font-variant-numeric: tabular-nums; white-space: nowrap; }
.t-serie-item:hover:not(:disabled) { border-color: var(--t-borda-forte); }
.t-serie-item:focus-visible { outline: 2px solid var(--t-info); outline-offset: 1px; }
.t-serie-item.oculta { opacity: .55; }
.t-serie-item.oculta i { background: transparent; box-shadow: inset 0 0 0 2px var(--t-cor-s); }
.t-serie-item:disabled { cursor: default; }

/* ---- Infraestrutura compacta (09/10) -----------------------------------------------------------------------------
   Dentro da caixa «Estações» do Cockpit: um grupo por estação (borda de cima na cor da estação), um PC por LINHA.
   Antes, cada PC era uma barra de duas linhas (~62 px) e cada cartão ocupava ~225 px para dois PCs. As colunas vêm da
   largura do próprio grupo (container query), não do ecrã: a caixa pode ter 600 ou 1100 px. */
.t-infra-topo { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px 14px; margin: 0 0 10px; }
.t-infra-topo .t-num { flex-direction: row; align-items: baseline; gap: 6px; min-width: 0; padding: 5px 12px; }
.t-infra-topo .t-num b { font-size: 1.05rem; }
.t-infra-grupo { container-type: inline-size; gap: 6px; padding-top: 10px; padding-bottom: 10px; }
.t-infra-grupo .t-logo { width: 26px; height: 26px; }
.t-infra-grupo .t-cab { gap: 8px; flex-wrap: nowrap; }
.t-infra-grupo .t-cab-texto { flex-direction: row; align-items: baseline; flex-wrap: wrap; gap: 0 8px; }
.t-infra-grupo .t-titulo { font-size: .92rem; }
.t-infra-grupo .t-cab-dir { gap: 6px; }
.t-infra-pcs { display: flex; flex-direction: column; }
.t-infra-pc { display: flex; align-items: center; flex-wrap: wrap; gap: 2px 8px; min-height: 30px; padding: 4px 4px;
              border-top: 1px solid var(--t-borda); font-size: .8rem; min-width: 0; }
.t-infra-pc:first-child { border-top: 0; }
.t-infra-pc .t-ponto { width: 9px; height: 9px; box-shadow: none; }
.t-infra-nome { font-size: .84rem; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1 1 18ch; order: 1; }
.t-infra-papel { order: 3; }
.t-infra-versao { order: 4; }
.t-infra-papel, .t-infra-versao { color: var(--t-texto-fraco); font-size: .72rem; white-space: nowrap; }
.t-infra-estado { color: var(--t-texto-fraco); font-size: .74rem; white-space: nowrap; margin-left: auto; order: 2; }
.t-infra-pc.calado .t-infra-estado { color: var(--t-mau); font-weight: 650; }
.t-infra-pc.atencao .t-infra-estado { color: var(--t-aviso); font-weight: 650; }
.t-infra-pc.vivo .t-infra-estado { color: var(--t-bom); }
.t-infra-leituras { order: 5; display: inline-flex; gap: 8px; font-size: .7rem; font-variant-numeric: tabular-nums; color: var(--t-texto-fraco); white-space: nowrap; }
.t-infra-leituras .aviso { color: var(--t-aviso); font-weight: 650; }
.t-infra-leituras .mau { color: var(--t-mau); font-weight: 650; }
/* Em grupos largos tudo cabe numa linha só; nos estreitos as leituras descem para baixo do nome, a toda a largura. */
@container (max-width: 380px) { .t-infra-leituras { flex-basis: 100%; padding-left: 17px; } }

/* As caixas das estações do mapa em DUAS linhas (nome; frequência + estado) e nunca três (09/10). */
.t-mapa-nome { display: flex; flex-direction: column; }
.t-mapa-linha2 { flex-wrap: nowrap; gap: 5px; }
.t-mapa-linha2 small { white-space: nowrap; }
.t-mapa-item .t-pastilha { font-size: .56rem; padding: 1px 5px; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
/* O fundo de cada estação na tabela, MUITO suave, na cor dela (09/10). */
.t-tabela tbody tr.t-est-linha[style*="--cor-estacao"] { background: color-mix(in srgb, var(--cor-estacao) 6%, transparent); }
.t-tabela tbody tr.t-est-linha[style*="--cor-estacao"]:hover { background: color-mix(in srgb, var(--cor-estacao) 11%, transparent); }
.t-tabela tbody tr.t-est-linha.por-instalar[style*="--cor-estacao"] { background: none; }

/* ==== mobile 09/10 ============================================================================================
   Auditoria do telemóvel (pedido do utilizador: «500 % mobile, mais de metade dos acessos vai ser mobile»).
   Medido num iframe de 390 px com sessão (getBoundingClientRect, não scrollWidth: o html/body têm overflow-x: clip,
   que corta em vez de acusar). O que isto garante, em todas as páginas:
     1. alvos de toque >= 44 px (botões, filtros, separadores, selects, campos, summary);
     2. nada abaixo de 12 px de letra;
     3. input/select/textarea a 16 px (menos, e o iOS faz zoom ao focar e não volta);
     4. as barras fixas e as janelas respeitam o entalhe (env(safe-area-inset-*)).
   Fica tudo dentro de media queries: o desktop não muda. O MENU (gaveta, .nav-*, .hamburger) não está aqui. */

/* 1. Alvos de toque. `(pointer: coarse)` apanha também o tablet; o ecrã estreito apanha uma janela pequena no PC.
      Até 1024 px (19/10, «500 % mobile»): o tablet a 768 px tinha letra de 10 px e alvos de 17 px. */
@media (max-width: 1024px), (pointer: coarse) {
    html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
    /* Sem o atraso do duplo-toque-para-ampliar nos controlos (o zoom por pinça continua a existir). */
    a, button, summary, select, label, input, [role="button"] { touch-action: manipulation; }

    /* O summary vale em toda a .main e não só na .content (20/10): o dashboard minimalista abre o local numa folha
       (.mn-painel) fora da .content, e o «O QUE FAZER» de um incidente ficava com 18 px de altura. */
    .content button, .main summary, .modal button, .modal summary,
    .content a.btn, .modal a.btn, .content a.t-icone-btn,
    .btn, .btn.sm, .t-filtro, .t-chip, .t-serie-item, .t-mapa-item, .t-est-nome, .op-aba { min-height: 44px; }
    .main summary, .modal summary { padding-block: 12px; }
    .icon-btn, .t-icone-btn, .tu-logout button, .modal-head button, .t-janela-fechar { min-width: 44px; min-height: 44px; }
    .t-icone-btn { display: inline-grid; place-items: center; }
    .t-periodo a { min-height: 44px; display: inline-flex; align-items: center; }
    .t-filtros { gap: 8px; }
    .t-menu-lista > a, .t-menu-lista > button { display: flex; align-items: center; min-height: 44px; padding-block: 8px; }
    .t-chip, .t-serie-item { padding-block: 8px; }
    .content button, .modal button { min-width: 44px; }

    /* Campos: 44 px de altura e 16 px de letra (o iOS faz zoom ao focar um campo com menos). */
    html body select, html body textarea,
    html body input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):not([type="color"]):not([type="hidden"]) {
        font-size: 16px !important; min-height: 44px !important; }
    html body textarea { min-height: 88px !important; }
    html body input[type="file"], html body input[type="color"] { min-height: 44px; }
    html body input[type="checkbox"], html body input[type="radio"] { width: 22px; height: 22px; flex: none; }
    .t-seleccao, .t-pesquisa { padding-block: 8px; }
}

/* 2. Nada abaixo de 12 px. As regras abaixo são as do app.css/tema.css que tinham letra mais pequena, repetidas
      aqui só com o tamanho (geradas a partir dos dois ficheiros; ao acrescentar uma classe com letra < 12 px, juntá-la). */
@media (max-width: 1024px) {
    :root { --t-rotulo: .76rem; --t-pequeno: .76rem; }
    /* O <small> e o <code> sem regra própria encolhem pelo browser (83 %) a partir de um texto que já era pequeno. */
    html body small { font-size: max(12px, .833em); }
    html body code, html body kbd, html body .manual code { font-size: max(12px, .9em); }
    html body .eyebrow, html body .notif-count, html body .avatar-sm, html body .tu-id b, html body .tu-id small, html body .chip, html body .kpi .label,
        html body .kpi .foot, html body .kpi-meia small, html body .station-head small, html body .badge, html body .chain-node .kind, html body .node-state,
        html body .chain-node .mini small, html body .chain-node .mini b, html body .km-label, html body .km-simtag, html body .km-value small,
        html body .panel-title .sim, html body .stereo, html body .rds-row span, html body .rds-row b.rt, html body .rds-flags .flag, html body .tile .metric,
        html body .tile .when, html body .camara figcaption, html body .device-group, html body .incident .since, html body .symptoms .cap,
        html body .symptoms li, html body .runbook summary, html body .alert-row span, html body .alert-row time, html body .panel-title span,
        html body .empty small, html body .map-note, html body .station-item small, html body .st-state, html body .btn.sm, html body .cat-body span,
        html body .cat-body .tag, html body .cat-upload, html body .field-grid label, html body .field-grid small, html body .form-subhead p,
        html body .confirm-q, html body .model-pick-label, html body .model-chip b, html body .model-chip small, html body .et-cloud,
        html body .estado-saida small, html body .subblock .hint, html body .kv-head span, html body .ac-sala span, html body .mode-note,
        html body .cfg-row .grow span, html body .cfg-row .avatar, html body .freq, html body .warn-txt, html body .login-foot, html body .login-copy,
        html body .risk-tag, html body .grid-table th, html body .grid-table code, html body .lig-existente, html body .sr-amostra, html body .sr-codigo,
        html body .dev-table td.vals, html body .dev-table .tag, html body .dev-table time, html body .walk-list td.vals, html body .cloud-item small,
        html body .order-arrows button, html body .chain-picked .dim, html body .chain-chip, html body .chain-chip b, html body .chain-chip button,
        html body .filter-bar label, html body .hist-table td small.dim, html body .sev-pill, html body .muted-count, html body .muted, html body .inline-lbl,
        html body .agent-ver, html body .dev-icon, html body .dev-sub, html body .dev-state span:last-child, html body .dev-tabs .pill,
        html body .dev-cell .metric, html body .dev-cell small.vals, html body .dev-cell small.parou, html body .dev-cell small.tipico, html body .wtag,
        html body .estacoes-table th.col-elo, html body .est-logo.ph, html body .est-id span, html body .estacoes-table .idade, html body .log-row time,
        html body .log-row div span, html body .bar-wrap span, html body .kpi-strip .kpi span, html body .pill, html body .plugin-body p,
        html body .copilot-who, html body .live-tag, html body .fmdx-sig, html body .rds-row .tx, html body .tile-add, html body .tile-add-line,
        html body .mono, html body .btn.live-now, html body .fmdx-note, html body .rds-loop, html body .status-overall time, html body .status-site small,
        html body .status-pill, html body .status-foot, html body .estacoes-table th.col-icons, html body .registos-table time, html body .registos-table .det,
        html body .kpi.green .foot, html body .kpi.red .foot, html body .kpi.amber .foot, html body .tag, html body .ouvir-nota, html body .equip-modal .det,
        html body .diario-table .det, html body .diario-table time, html body .fixo-linha small, html body .av-tipo, html body .av-onde, html body .av-expl,
        html body .av-mais, html body .station-item .grow small, html body .station-item .st-state, html body .dev-site-id small, html body .dev-site-count,
        html body .aud-table .det, html body .uz-nota, html body .upload-campos label, html body .uv-titulo, html body .vpn-srv .tag,
        html body .vpn-lig-titulo, html body .vpn-cli .vals, html body .vpn-num small, html body .vpn-peer-ip, html body .grid-table .det.cod,
        html body .vpn-peer-ping, html body .destaque-tranca small, html body .reg-leg, html body .avisou, html body .avisou-pop, html body .ap-nota,
        html body .app-chip b, html body .saida-cloud small, html body .plugin-body .in-sm, html body .rr-item span, html body .rl-id small,
        html body .rl-limpo, html body .rl-motivo, html body .rl-estado b, html body .rl-estado small, html body .te-chip, html body .te-nota,
        html body .tarefa-accoes .in-sm, html body .cap, html body .papel-sel, html body .param-id small, html body .param-id small.dim,
        html body .param-id .pill, html body .param-un, html body .estacoes-table td[data-col]::before, html body .diario-table td.vals,
        html body .dev-table tbody td:nth-child(3)::before, html body .tab-cartoes tbody td[data-col]::before, html body .gc-nome small,
        html body .gc-num span, html body .gc-meta, html body .perfis-table td:first-child small, html body .manual-indice b, html body .manual-indice a .n,
        html body .manual th, html body .descobertos-toggle, html body .descoberta-agente .da-cab .det, html body .cmd-id small, html body .cmd-args label,
        html body .cmd-accao .tag.risco, html body .ac-titulo, html body .act-nome, html body .fixo-linha .fixo-que-faz, html body .fixo-linha .fixo-aviso,
        html body .recolhe .cap, html body .agentes-estado .badge, html body .agentes-tabela .recolhe .cap, html body .agentes-tabela .agentes-estado .badge,
        html body .reconecta-caixa small, html body .duas-verdades .rotulo, html body .op-live, html body .op-ouvintes small, html body .op-etq span,
        html body .op-rodape, html body .op-instalador summary, html body .op-play-ic, html body .au-bloco-cab p, html body .au-passo-n,
        html body .au-passo-n.sm, html body .au-e, html body .au-passo-corpo label, html body .au-nota, html body .au-marca, html body .au-dias-lbl,
        html body .au-dias-nota, html body .au-dia, html body .au-resumo-linha b, html body .au-ensaio-passos li, html body .au-ensaio-res, html body .au-res,
        html body .au-modelo-desc, html body .au-cel-quando, html body .au-cel-faz, html body .au-erro, html body .au-tag-ensaio, html body .qb-kpi span,
        html body .qb-abas button .n, html body .qb-cab, html body .qb-hora, html body .qb-causa, html body .qb-causa b, html body .qb-local,
        html body .qb-local-erro, html body .qb-prova-rot b, html body .qb-prova-rot small, html body .qb-prova-quem, html body .qb-de,
        html body .qb-prova-sem, html body .qb-prova-leitura, html body .qb-marca, html body .qb-num::before, html body .qb-quem,
        html body .gl-form label small, html body .gl-leitor .rot, html body .ev-periodo label, html body .aviso-audio, html body .cv-estado,
        html body .cv-estado + .det, html body .lt-erro, html body .lt-cab .det, html body .lt-troco-nome, html body .lt-rot b, html body .lt-rot small,
        html body .lt-num small, html body .lt-ausentes, html body .lt-ausentes small, html body .gl-est small, html body .t-num, html body .t-sinal,
        html body .t-logo.sigla, html body .t-metrica span, html body .t-linha-texto small, html body .t-barra small, html body .t-barra b,
        html body .t-pastilha, html body .t-indicador-barra em, html body .t-grafico-y, html body .t-grafico-x, html body .t-fio-estado,
        html body .t-fio-valor small, html body .t-fio.compacto .t-fio-nome, html body .t-item-texto small, html body .t-legenda, html body .t-ficha small,
        html body .t-tabela th, html body .t-indicadores.compactos .t-indicador-texto span, html body .t-chip, html body .t-est-idade,
        html body .t-mapa-nome small, html body .t-mapa-item .t-pastilha, html body .t-serie-item small, html body .t-infra-papel, html body .t-infra-versao,
        html body .t-infra-estado, html body .t-infra-leituras, html body .t-pp-conta small, html body .gv-y, html body .gv-x, html body .gv-nota, html body .ag-programas small,
        html body .cv-agora small, html body .es-nome small, html body .op-aba small, html body .op-n
    { font-size: 12px; }
}

/* 3. O alerta crítico ao vivo no telemóvel: ocupava ~190 px (22 % do ecrã) POR CIMA do que se lia. Agora é o título,
      onde é, e dois botões de 44 px; a explicação completa está no cartão do incidente (Alertas/Cockpit). Fica por baixo
      da barra do menu e do entalhe, e nunca por cima da gaveta (regra do app.css). */
@media (max-width: 760px) {
    .alerta-vivo { top: calc(60px + env(safe-area-inset-top)); width: calc(100vw - 20px - env(safe-area-inset-left) - env(safe-area-inset-right));
                   display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: start; gap: 8px 10px; padding: 10px 12px; border-radius: 12px; }
    .alerta-vivo .av-pulso { margin-top: 5px; }
    .alerta-vivo .av-titulo { font-size: 1rem; line-height: 1.25; }
    .alerta-vivo .av-expl { display: none; }
    .alerta-vivo .av-acoes { grid-column: 1 / -1; flex-direction: row; align-items: center; gap: 8px; }
    .alerta-vivo .av-acoes .btn { flex: 1 1 0; min-height: 44px; }
    .alerta-vivo .av-mais { order: 3; flex: none; padding: 0 4px; }
}

/* 4. Entalhe e barra do iPhone (viewport-fit=cover + barra de estado translúcida): nada fica por baixo. */
@media (max-width: 1024px) {
    .content { padding-left: max(14px, env(safe-area-inset-left)); padding-right: max(14px, env(safe-area-inset-right));
               padding-bottom: calc(48px + env(safe-area-inset-bottom)); }
    .modal-scrim { padding-top: max(10px, env(safe-area-inset-top)); padding-bottom: max(10px, env(safe-area-inset-bottom));
                   padding-left: max(10px, env(safe-area-inset-left)); padding-right: max(10px, env(safe-area-inset-right));
                   overscroll-behavior: contain; }
    /* A barra do menu: o conteúdo dela não pode ficar por baixo da hora e do entalhe quando a app está instalada. */
    .mobile-bar { padding-top: env(safe-area-inset-top); height: calc(56px + env(safe-area-inset-top));
                  padding-left: max(14px, env(safe-area-inset-left)); padding-right: max(14px, env(safe-area-inset-right)); }
}

/* 5. Janelas e formulários com o teclado aberto: a janela cabe em dvh (a altura que sobra com o teclado), rola por
      dentro, e o rodapé com o botão principal fica à vista. */
@media (max-width: 760px) {
    .modal, .modal.t-janela, .modal.form-modal { max-height: calc(100dvh - 20px); display: flex; flex-direction: column; }
    .modal .modal-body { flex: 1 1 auto; min-height: 0; max-height: none; overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
    .modal.t-janela { overflow-y: auto; }
    .t-janela-corpo { padding: 16px 14px; }
    .modal-foot { padding-bottom: calc(12px + env(safe-area-inset-bottom)); flex-wrap: wrap; }
    .modal-foot .btn { flex: 1 1 auto; }
}
@media (max-width: 1024px) { .copilot { height: calc(100dvh - 200px); } }

/* 6. A barra de cima (TopBar): três linhas de ícones soltos comiam ~134 px. Agora uma grelha de cinco colunas — o
      título e a pílula do sistema na primeira linha, os botões em duas — com todos os alvos a 44 px. Até 1024 px (19/10):
      no tablet a fila dos botões passava do ecrã. */
@media (max-width: 1024px) {
    .topbar { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); align-items: center; justify-items: center; gap: 6px 4px; padding: 8px 10px; }
    .topbar-actions, .topbar .topbar-user { display: contents; }
    .topbar-left { grid-column: 1 / span 3; justify-self: start; min-width: 0; }
    .topbar-title { font-size: 1.25rem; }
    .topbar .eyebrow { display: none; }
    .topbar .avatar-sm { width: 44px; height: 44px; font-size: .85rem; }
    .topbar .tu-logout { margin: 0; }
    /* A pílula do sistema, em ponto + «N/M»: o utilizador também vê no telemóvel se o sistema está bem. */
    .topbar .chip.live.sistema { display: inline-flex; grid-column: 4 / span 2; justify-self: end; min-height: 44px; gap: 8px; padding: 6px 12px; border-radius: 12px; }
    .topbar .chip.live.sistema .sis-texto b, .topbar .chip.live.sistema .sis-det, .topbar .chip.live.sistema .sis-rot { display: none; }
    .topbar .chip.live.sistema .sis-texto small { font-size: 1rem; font-weight: 700; max-width: none; }
}

/* 7. As páginas públicas (Login, Ouvir, Estado): são as que um ouvinte abre no telefone, sem menu nem sessão. */
@media (max-width: 1024px), (pointer: coarse) {
    .login-page, .ouvir-publico { min-height: 100vh; min-height: 100dvh; }
    .login-page { padding-left: max(20px, env(safe-area-inset-left)); padding-right: max(20px, env(safe-area-inset-right));
                  padding-bottom: calc(60px + env(safe-area-inset-bottom)); }
    .ouvir-publico { padding-left: max(20px, env(safe-area-inset-left)); padding-right: max(20px, env(safe-area-inset-right));
                     padding-bottom: calc(40px + env(safe-area-inset-bottom)); }
    .login-copy { bottom: calc(16px + env(safe-area-inset-bottom)); }
    .field-icon .peek { width: 44px; height: 44px; right: 2px; }
    .remember, .login-ouvir, .op-entrar { min-height: 44px; }
    .op-entrar { display: inline-flex; align-items: center; }
    .remember input { width: 22px; height: 22px; }
    .op-instalador summary { display: block; padding: 12px 0; min-height: 44px; box-sizing: border-box; }
    .op-play { min-height: 44px; }
    .ouvir-publico audio { height: 44px; }
    .op-instalador button { min-height: 44px; }
}

/* ==== minimalista 09/10 ========================================================================================
   O dashboard minimalista (`DashboardMinimalista.razor`): só o mapa, grande e ao centro; ao escolher uma estação o
   mapa encosta à esquerda e à direita abre a página dela. No telemóvel o painel é uma folha que sobe do fundo.
   Só variáveis do tema, por isso vale no claro e no escuro. O desenho de dentro do painel (`EstacaoDetalhe`) responde
   à largura do PAINEL (container query), não à da janela — o painel é mais estreito do que ela. */

/* A página ocupa a altura do ecrã e não rola: o mapa usa o que sobra por baixo da barra de cima. Sem números
   mágicos para a altura da barra — a coluna reparte-a. No telemóvel (menu em barra própria) desconta-se essa barra. */
.main:has(> .mn) { display: flex; flex-direction: column; height: 100vh; height: 100dvh; }
@media (max-width: 1024px) {
    .main:has(> .mn) { height: calc(100vh - 56px - env(safe-area-inset-top)); height: calc(100dvh - 56px - env(safe-area-inset-top)); }
}

.mn { flex: 1 1 auto; min-height: 0; position: relative; display: grid; align-items: stretch;
      grid-template-columns: 1fr 0fr; grid-template-rows: minmax(0, 1fr); column-gap: 0; padding: 8px 20px 16px;
      transition: grid-template-columns .25s ease, column-gap .25s ease; }
/* Com a estação aberta, o mapa encosta-se e encolhe (14/10, pedido do utilizador: «menos margem à esquerda e à
   direita do mapa, e a janela da direita com mais espaço»): o Portugal é alto e estreito, e numa coluna mais
   estreita perde pouco; o painel ganha a largura. */
.mn.com-painel { grid-template-columns: minmax(220px, 3fr) 9fr; column-gap: 10px; padding-left: 6px; padding-right: 8px; }
.mn > * { min-width: 0; min-height: 0; }

.mn-mapa { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; }
.mn .map-wrap { flex: 1 1 0; min-height: 0; width: 100%; justify-content: center; }
.mn .map-wrap svg.map { width: 100%; height: 100%; max-width: none; }
.mn .map-note { display: none; }   /* as sem posição têm botões por baixo (.mn-sem-posicao) */
.mn .t-legenda.mn-legenda { flex: none; justify-content: center; flex-wrap: wrap; white-space: normal; text-align: center; max-width: 100%; }
.mn-sem-posicao { flex: none; display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 6px 8px;
                  font-size: .75rem; color: var(--t-texto-fraco); }
.mn-vazio { max-width: 460px; }

/* O ponto escolhido leva um anel (uma forma, não só uma cor); o nome e a frequência aparecem ao passar o rato, com o
   foco do teclado e no escolhido. Em toque não há rato: tocar escolhe, e o painel diz quem é. */
.map-rot { display: none; }
/* Escondida com visibility e não só opacity (19/10): uma etiqueta invisível perto da borda contava como «passa do ecrã». */
.mn .map-rot { display: inline; opacity: 0; visibility: hidden; pointer-events: none; transition: opacity .12s, visibility .12s; }
.mn .map-rot text { font-size: 12px; font-weight: 700; fill: var(--t-texto); paint-order: stroke; stroke: var(--t-fundo-cartao);
                    stroke-width: 4px; stroke-linejoin: round; }
.mn .map-rot .map-rot-f { font-weight: 600; fill: var(--t-texto-fraco); }
.mn .map-rot .map-rot-f:empty { display: none; }
.mn .map-rot.esq text { text-anchor: end; }
.mn .map-pin:hover .map-rot, .mn .map-pin:focus-visible .map-rot, .mn .map-pin.sel .map-rot { opacity: 1; visibility: visible; }
.mn .map-wrap svg.map { overflow: visible; }
.map-sel { fill: none; stroke: var(--t-info); stroke-width: 2.4; }
.mn .map-pin:focus-visible { outline: 2px solid var(--t-info); outline-offset: 2px; }

/* O painel da estação. */
.mn-painel { display: flex; flex-direction: column; background: var(--t-fundo-cartao); border: 1px solid var(--t-borda);
             border-radius: var(--t-raio); overflow: hidden; outline: none; animation: mn-entra .25s ease backwards; }
.mn-painel:focus-visible { box-shadow: 0 0 0 2px var(--t-info); }
.mn-cab { flex: none; display: flex; align-items: center; flex-wrap: wrap; gap: 8px 10px; padding: 12px 14px;
          border-bottom: 1px solid var(--t-borda); }
.mn-pega { display: none; }
.mn-id { flex: 1 1 160px; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.mn-id b { font-size: var(--t-titulo); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mn-id2 { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; }
.mn-id2 small { font-size: .75rem; color: var(--t-texto-fraco); font-variant-numeric: tabular-nums; }
.mn-corpo { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
            padding: 14px; }
/* Só para quem usa leitor de ecrã. */
.mn-vivo { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* `backwards`: o `both` deixava um transform no painel e uma janela lá dentro não cobria o ecrã (ver MOVIMENTO, 18/10). */
@keyframes mn-entra { from { opacity: 0; transform: translateX(14px); } to { opacity: 1; transform: none; } }
@keyframes mn-sobe { from { opacity: .4; transform: translateY(40px); } to { opacity: 1; transform: none; } }

/* Tablet: lado a lado, com o painel a ~55 %. */
@media (min-width: 761px) and (max-width: 1100px) {
    .mn.com-painel { grid-template-columns: 9fr 11fr; column-gap: 14px; }
}

/* Telemóvel: sem espaço para dois lados. O mapa fica inteiro e o painel é uma folha de ~85 % da altura da área do
   mapa (assim não tapa a barra de cima nem o menu), com pega e ✕. */
@media (max-width: 760px) {
    .mn, .mn.com-painel { grid-template-columns: minmax(0, 1fr); column-gap: 0; padding: 6px 10px 10px; transition: none; }
    .mn-painel { position: absolute; left: 0; right: 0; bottom: 0; height: 85%; z-index: 5;
                 border-radius: 18px 18px 0 0; border-bottom: 0; box-shadow: 0 -10px 30px rgba(0,0,0,.22);
                 padding-bottom: env(safe-area-inset-bottom); animation: mn-sobe .25s ease backwards; }
    .mn-pega { display: block; flex: 0 0 100%; width: 40px; height: 4px; margin: 0 auto 2px; border-radius: 99px;
               background: var(--t-borda-forte); }
    .mn-cab { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; padding: 8px 12px 8px; }
    .mn-pega { grid-column: 1 / -1; }
    .mn-id { grid-column: 1; grid-row: 2; }
    .mn-abrir { grid-column: 2; grid-row: 2; justify-content: center; text-align: center; white-space: nowrap; padding-inline: 10px; }
    .mn-fechar { grid-column: 3; grid-row: 2; }
    .mn-corpo { padding: 12px; }
}

/* Alvos de toque de 44 px dentro do minimalista (o bloco do telemóvel só os garante dentro de `.content`). */
@media (max-width: 760px), (pointer: coarse) {
    .mn button, .mn a.btn, .mn .t-filtro { min-height: 44px; }
    .mn .map-pin { outline-offset: 0; }
}

@media (prefers-reduced-motion: reduce) {
    .mn, .mn-painel, .mn .map-rot { transition: none; animation: none; }
}

/* O interruptor na barra de cima. */
.mn-btn.activo { border-color: var(--t-info); color: var(--t-info); background: color-mix(in srgb, var(--t-info) 12%, transparent); }
.mn-btn svg { display: block; margin: auto; }
.mn-anel { opacity: .85; }

/* ============ fichas das estações no telemóvel 09/10 ============
   A ficha era uma pilha de linhas «etiqueta valor» coladas à esquerda, com metade do cartão vazio. Agora é uma
   grelha de duas colunas: o nome por cima (a toda a largura), os valores em pares com a etiqueta por cima, e
   os três botões à direita da última linha. A altura cai quase para metade. */
@media (max-width: 1024px) {
    .t-estacoes.tab-cartoes tbody tr.t-est-linha {
        display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 12px; row-gap: 6px;
        align-items: start; padding: 12px;
    }
    .t-estacoes.tab-cartoes tbody tr.t-est-linha > td { padding: 0; min-width: 0; margin: 0; border: 0; }
    .t-estacoes.tab-cartoes tbody tr.t-est-linha > td.t-est-id { grid-column: 1 / -1; padding-bottom: 8px; border-bottom: 1px solid var(--t-borda); }
    .t-estacoes.tab-cartoes tbody tr.t-est-linha > td[data-col]::before { display: block; margin: 0 0 2px; }
    .t-estacoes.tab-cartoes tbody tr.t-est-linha > td.t-est-ultimo { grid-column: 1; }
    .t-estacoes.tab-cartoes tbody tr.t-est-linha > td.t-est-acoes {
        grid-column: 2; display: flex; justify-content: flex-end; align-items: flex-end; align-self: end; gap: 6px; padding: 0;
    }
    /* O menu «…» abre para dentro do ecrã: a ficha é larga, a lista cresce para a esquerda. */
    .t-estacoes .t-menu-lista { right: 0; left: auto; max-width: calc(100vw - 48px); }
}
@media (max-width: 340px) {
    .t-estacoes.tab-cartoes tbody tr.t-est-linha { grid-template-columns: minmax(0, 1fr); }
    .t-estacoes.tab-cartoes tbody tr.t-est-linha > td.t-est-acoes { grid-column: 1; justify-content: flex-start; }
}

/* ---- O painel da estação em SEPARADORES (09/10) -----------------------------------------------------------------
   `EstacaoPainel.razor`: por baixo do cabeçalho do painel, uma barra de separadores que rola na horizontal (fixa no
   topo da folha do telemóvel) e, por baixo, o corpo que rola. O conteúdo responde à largura do PAINEL (container
   queries), não à da janela — o painel é uma fatia do ecrã. Só variáveis do tema: vale no claro e no escuro. */
.sep-raiz { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
.mn-painel { min-height: 0; max-height: 100%; }
.sep-corpo { overflow-y: auto; }
/* Separadores que SE VÊEM (13/10, queixa do utilizador: «muito fracos, não se percebe que existem»). Cada um tem
   moldura e fundo próprios, como as pastas de um arquivo; o escolhido junta-se ao conteúdo (o mesmo fundo, sem
   linha por baixo) e leva uma barra de cor em cima. */
.sep-barra { flex: none; display: flex; flex-wrap: nowrap; align-items: flex-end; gap: 4px; padding: 8px 8px 0; overflow-x: auto; overflow-y: hidden;
             overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch; scrollbar-width: thin;
             background: var(--t-fundo-interior); border-bottom: 1px solid var(--t-borda-forte); }
.sep { flex: none; display: inline-flex; align-items: center; gap: 6px; padding: 0 14px; min-height: 44px; margin-bottom: -1px;
       border: 1px solid var(--t-borda-forte); border-bottom: 0; border-top: 3px solid transparent;
       border-radius: var(--t-raio-interior) var(--t-raio-interior) 0 0;
       background: color-mix(in srgb, var(--t-fundo-cartao) 55%, var(--t-fundo-interior)); font: inherit; font-size: .9rem;
       font-weight: 600; white-space: nowrap; color: var(--t-texto); cursor: pointer; }
.sep:hover { background: var(--t-fundo-cartao); border-top-color: color-mix(in srgb, var(--t-info) 45%, transparent); }
.sep.activo { background: var(--t-fundo-cartao); border-top-color: var(--t-info); color: var(--t-info); font-weight: 700;
              box-shadow: 0 1px 0 var(--t-fundo-cartao); position: relative; z-index: 1; }
.sep:focus-visible { outline: 2px solid var(--t-info); outline-offset: -3px; border-radius: var(--t-raio-interior); }
.sep-marca { position: relative; display: inline-grid; place-items: center; min-width: 18px; height: 18px; padding: 0 5px;
             border-radius: var(--t-raio-pastilha); font-size: .68rem; font-weight: 700; line-height: 1; color: var(--t-texto);
             background: var(--t-fundo-interior); border: 1px solid var(--t-borda); }
.sep-marca.bom { background: color-mix(in srgb, var(--t-bom) 22%, transparent); border-color: color-mix(in srgb, var(--t-bom) 55%, transparent); }
.sep-marca.aviso { background: color-mix(in srgb, var(--t-aviso) 26%, transparent); border-color: color-mix(in srgb, var(--t-aviso) 60%, transparent); }
.sep-marca.mau { background: color-mix(in srgb, var(--t-mau) 24%, transparent); border-color: color-mix(in srgb, var(--t-mau) 60%, transparent); }
.sep-marca .sr-so { font-size: 12px; position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.sep-corpo:focus-visible { outline: 2px solid var(--t-info); outline-offset: -3px; }

.sep-fichas { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.sep-atalhos { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
/* O CONTENTOR DAS REGRAS POR LARGURA É A CAIXA DA TABELA, NÃO O SEPARADOR (18/10). `container-type` faz de bloco
   contentor para o que é `position: fixed`: com ele no `.sep-cont`, qualquer janela aberta dentro de um separador
   («+ Novo equipamento», os «Modelos» do desenho, as Gravações) ficava presa à caixa do separador — a 390 px abria
   fora do ecrã. A tabela de um separador vai sempre numa `.tabela-wrap` à largura toda dele, por isso a medida é a
   mesma. Nenhuma janela pode viver DENTRO de uma `.tabela-wrap`. */
.sep-cont .tabela-wrap { container-type: inline-size; }

/* A janela da estação, embutida: o fundo e a moldura são do painel; responde à largura do painel. As regras globais
   desta página seguem a JANELA (colunas das leituras sem quebra acima de 1000 px, câmaras lado a lado, o FMDX em três
   colunas) e num painel de 40 % do ecrã esmagavam tudo. O `:root` empata a especificidade com o fundo do tema claro. */
:root .mn .station.embutida { border: 0; background: none; box-shadow: none; padding: 0; margin: 0; border-radius: 0; container-type: inline-size; }
.station.embutida .station-head { padding-bottom: 10px; gap: 8px 12px; }
/* Os cinzentos fixos do desenho antigo (feitos para o escuro) ficavam a 2,7:1 no cartão claro: no painel leem-se pelo tema. */
.station.embutida .km-label, .station.embutida .tile .metric, .station.embutida .chain-node .kind,
.station.embutida .chain-node .mini small, .station.embutida .rds-row span { color: var(--t-texto-fraco); }
.station.embutida .tiles { flex-wrap: wrap; }
.station.embutida .tiles > * { flex: 1 1 112px; }
.station.embutida .camaras { flex-wrap: wrap; }
.station.embutida .camaras > * { flex: 1 1 200px; }
@container (max-width: 1150px) {
    .station.embutida .fmdx-grid { grid-template-columns: minmax(0, 1fr); }
}
@container (max-width: 520px) {
    .station.embutida .station-id { flex: 1 1 100%; }
    .station.embutida .estado-central { margin-left: 0; }
}

/* As tabelas das listas viram fichas quando o PAINEL é estreito (as regras globais de `tab-cartoes` seguem a janela). */
@container (max-width: 640px) {
    .sep-cont .grid-table { min-width: 0; table-layout: auto; border-spacing: 0; }
    .sep-cont .grid-table thead { display: none; }
    .sep-cont .grid-table tbody { display: grid; gap: 8px; }
    .sep-cont .grid-table tbody tr { display: block; padding: 11px 12px; border-radius: var(--t-raio-interior); border: 1px solid var(--t-borda); }
    .sep-cont .grid-table tbody td { display: block; padding: 3px 0; border: 0; text-align: left; white-space: normal;
                                     overflow: visible; overflow-wrap: anywhere; background: none; width: auto; }
    .sep-cont .grid-table tbody td.num { text-align: left; }
    .sep-cont .grid-table tbody td[data-col]::before { content: attr(data-col) " "; font-size: .72rem; text-transform: uppercase;
                                                         letter-spacing: .05em; color: var(--t-texto-fraco); font-weight: 650; margin-right: 7px; }
    .sep-cont .grid-table tbody td:first-child { font-weight: 650; padding-bottom: 6px; margin-bottom: 4px; border-bottom: 1px solid var(--t-borda); }
    .sep-cont .grid-table tbody td:empty { display: none; }
}
.sep-cont .tabela-wrap { overflow-x: auto; }
.sep-cont td .det { margin-left: 6px; }
.sep-cont .janela-filtros { flex-wrap: wrap; }
.sep-cont .janela-rodape { margin-top: 10px; font-size: .78rem; color: var(--t-texto-fraco); }
.sep-cont .ouvir-corpo { padding: 0; }

@media (max-width: 760px), (pointer: coarse) {
    .mn .sep { min-height: 44px; }
}
@media (max-width: 760px) {
    /* Os separadores ficam fixos no topo da folha; só o corpo rola. */
    .sep-barra { padding: 0 4px; }
    .mn .sep { padding: 0 11px; }
}

/* ============ minimalista: equipamentos compactos e janela mais larga 09/10 ============
   Os equipamentos (as caixas com os valores) cabem todos no painel sem rolar, nem que fiquem mais pequenos: grelha
   de caixas de ~92 px, sem a hora nem o mini-gráfico (a hora de uma leitura velha continua no `title` da caixa). A
   janela abre mais: o painel passa de 8/12 a 13/20 da largura e o mapa perde a margem das laterais. */
.mn { padding-inline: 8px; }
.mn.com-painel { grid-template-columns: 7fr 13fr; column-gap: 10px; }
.station.embutida .zona-equipamento { padding: 6px 8px; margin: 0 0 6px; }
.station.embutida .device-group { margin: 0; padding: 0 0 3px; font-size: .74rem; }
.station.embutida .tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(92px, 1fr)); gap: 4px; margin-top: 4px; }
.station.embutida .tiles > * { min-width: 0; }
.station.embutida .tile { min-height: 0; padding: 4px 7px; border-radius: 8px; }
.station.embutida .tile .metric { font-size: .56rem; letter-spacing: .03em; }
.station.embutida .tile .value { margin-top: 1px; font-size: .92rem; letter-spacing: 0; }
.station.embutida .tile .when, .station.embutida .tile .spark { display: none; }
@media (min-width: 761px) and (max-width: 1100px) {
    .mn.com-painel { grid-template-columns: 8fr 12fr; column-gap: 8px; }
}
@media (max-width: 760px) {
    .mn, .mn.com-painel { grid-template-columns: minmax(0, 1fr); column-gap: 0; padding-inline: 6px; }
    .station.embutida .tiles { grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); }
}
/* As caixas dos equipamentos seguem o tema (traziam o fundo escuro fixo: no claro o rótulo ficava a 2,7:1). */
.station.embutida .tile { background: var(--t-fundo-interior); border-color: var(--t-borda); }
.station.embutida .tile.warn { background: color-mix(in srgb, var(--t-aviso) 12%, var(--t-fundo-interior)); border-color: color-mix(in srgb, var(--t-aviso) 55%, transparent); }
.station.embutida .tile.bad { background: color-mix(in srgb, var(--t-mau) 12%, var(--t-fundo-interior)); border-color: color-mix(in srgb, var(--t-mau) 55%, transparent); }
.station.embutida .tile .value { color: var(--t-texto); }
/* A cadeia em fio compacta no painel: o desenho do aparelho fica pequeno e as caixas mais estreitas, para os elos e
   os equipamentos caberem sem rolar. */
.station.embutida .chain { padding: 6px 0 4px; }
.station.embutida .chain-node { flex: 1 0 118px; padding: 8px 9px 7px; }
.station.embutida .chain-node .name { margin: 2px 0 4px; }
.station.embutida .device-img { padding: 3px 6px; }
.station.embutida .device-img svg { max-height: 34px; min-height: 0; }
.station.embutida .chain-node .mini { margin-top: 4px; padding-top: 5px; gap: 8px; }
@media (max-width: 760px) {
    /* No telemóvel nada abaixo de 12 px (regra da revisão mobile): as caixas compactas ficam só com menos espaço. */
    .station.embutida .tile .metric, .station.embutida .device-group { font-size: .75rem; }
    .station.embutida .tile .value { font-size: .95rem; }
}

/* ONDE ESTOU (13/10): o trilho por cima do título da página — Cockpit › cliente › estação › separador. Pequeno e
   discreto: diz onde se está e leva para trás num clique, sem competir com o título. Também no telemóvel. */
.trilho { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; margin-bottom: 4px;
    font-size: .74rem; line-height: 1.3; color: var(--t-texto-fraco); min-width: 0; }
.trilho a { color: var(--t-info); text-decoration: none; }
.trilho a:hover { text-decoration: underline; }
.trilho [aria-current="page"] { color: var(--t-texto); font-weight: 600; }
.trilho-sep { opacity: .6; }

/* ---- A PÁGINA DA ESTAÇÃO (13/10) — `Pages/Estacao.razor` -----------------------------------------------------------
   O mesmo painel de separadores do cockpit minimalista, numa página inteira: aqui a página rola como qualquer outra
   (o painel lateral é que precisa do seu próprio scroll). À direita do nome, os botões do que se faz à estação. */
.est-pagina .sep-raiz, .est-pagina .sep-corpo { overflow: visible; }
.est-pagina .sep-raiz { background: var(--t-fundo-cartao); border: 1px solid var(--t-borda); border-radius: var(--t-raio); }
.est-pagina .sep-corpo { padding: 14px; }
.est-cab { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 10px 16px; margin-bottom: 12px; }
.est-id h2 { margin: 0; font-size: 1.25rem; color: var(--t-texto); }
.est-id .t-sub { display: flex; flex-wrap: wrap; gap: 4px 12px; color: var(--t-texto-fraco); font-size: .82rem; }
.est-accoes { display: flex; flex-wrap: wrap; gap: 8px; margin-left: auto; }
@media (max-width: 760px) {
    .est-accoes { margin-left: 0; }
    .est-pagina .sep-corpo { padding: 10px; }
}

/* ESCONDER O MENU LATERAL (13/10): o botão vive no topo de cada página; a escolha está em <html data-menu>. */
.topbar .menu-alternar { flex: none; margin-right: 10px; }
/* A BARRA DE CIMA A 1440 px (14/10, apanhado pelo validador): as acções (pesquisa de 260 px, estado, seis botões,
   relógio, utilizador) comiam a largura toda, o lado esquerdo encolhia a ~40 px e o lema e o trilho partiam-se
   palavra a palavra, por cima da própria barra. O título fica com um mínimo, a pesquisa é que encolhe, e o que não
   cabe corta-se numa linha com reticências. */
@media (min-width: 1025px) {
    .topbar-left { flex: 1 1 auto; min-width: 160px; overflow: hidden; }
    .topbar-left .eyebrow, .topbar-left .topbar-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .topbar-left .trilho { flex-wrap: nowrap; white-space: nowrap; overflow: hidden; }
    .topbar-actions { flex: 0 1 auto; min-width: 0; }
    .topbar-actions .topbar-search { width: auto; flex: 0 1 260px; min-width: 130px; }
    .topbar-actions .topbar-search input { min-width: 0; width: 100%; }
    /* A pílula não encolhe (18/10): com as acções a encolher, ela ia ao tamanho mínimo (a largura do título) e o
       «N/M no ar» cortava-se mesmo a 1920 px, em alemão com uma peça em falha. Quem cede é a pesquisa e o título. */
    .topbar .chip.live.sistema { flex-shrink: 0; }
}
/* A BARRA DE CIMA ENTRE 1025 E 1440 px (18/10, medida na bancada com getBoundingClientRect, pt e de): com a lista do
   cliente, as acções pediam ~1070 px (de) e só havia 694 (1200) a 934 (1440) — o utilizador, o sair e o relógio
   ficavam para lá da borda direita, cortados sem erro (o html tem overflow-x: clip). E as acções encolhiam (min-width:
   0) por baixo do próprio conteúdo em vez de ser o lado esquerdo a ceder. Aqui as acções não encolhem: quem cede é o
   título/trilho, que já corta com reticências. Os botões ficam todos; saem primeiro o que se repete noutro sítio
   (pesquisa, relógio, nome por extenso — o avatar diz quem é no título), depois a pílula fica no ponto e «N/M no ar»
   (como no telemóvel; o título dela diz o resto) e, até 1300, só «N/M» e tudo um pouco mais junto. Acima de 1440 nada
   muda. A verificação está no validador (Fluxos.BarraDeCimaCabe). */
@media (min-width: 1025px) and (max-width: 1440px) {
    .topbar-actions .topbar-search, .topbar .chip.clock, .topbar-user .tu-id { display: none; }
    .topbar .topbar-actions { flex-shrink: 0; }
    .topbar .topbar-actions > * { flex-shrink: 0; }
    .topbar .topbar-actions .topbar-cliente { max-width: 160px; }
}
@media (min-width: 1025px) and (max-width: 1380px) {
    .topbar .chip.live.sistema .sis-texto b, .topbar .chip.live.sistema .sis-det { display: none; }
}
@media (min-width: 1025px) and (max-width: 1300px) {
    .topbar { padding: 0 16px; }
    .topbar .menu-alternar { margin-right: 6px; }
    .topbar-actions, .topbar-user { gap: 6px; }
    .topbar-actions .icon-btn { width: 34px; height: 34px; }
    .topbar .chip.live.sistema .sis-rot { display: none; }
}
@media (min-width: 1025px) {
    :root[data-menu="escondido"] .shell { grid-template-columns: minmax(0, 1fr); }
    :root[data-menu="escondido"] .shell > .sidebar { display: none; }
}
@media (max-width: 1024px) {
    .topbar .menu-alternar { display: none; }
}
/* ENTRE 761 E 1024 px, COM UMA PEÇA EM FALHA (18/10, medido na bancada com getBoundingClientRect): as acções ficam numa
   linha só (só quebram abaixo de 520 px) e, com a pílula a dizer «Sistema com problemas · Ingestão · 0/3 no ar» e a
   lista do cliente, acabavam 21 px para lá da borda direita — o utilizador e o sair cortados. Sai primeiro o que se
   repete noutro sítio, como entre 1025 e 1440: o relógio; e a lista das peças, como entre 1025 e 1380 (o vermelho diz
   que há problema e o título da pílula diz quais). */
@media (min-width: 761px) and (max-width: 1024px) {
    .topbar .chip.clock, .topbar .chip.live.sistema .sis-det { display: none; }
}

/* A ESTAÇÃO NUMA JANELA (13/10, «Ver detalhes» no cockpit): a 90% do ecrã, com o mesmo conteúdo da página. A janela
   rola por dentro; o cabeçalho (trilho, nome, botões) fica no topo dela. */
.modal.est-modal { width: 90vw; max-width: 90vw; height: auto; max-height: 90vh; overflow-y: auto; padding: 16px 18px; }
.est-janela .est-id h2 { margin: 2px 0 0; font-size: 1.3rem; color: var(--t-texto); }
.est-janela .est-cab { align-items: flex-start; }
@media (max-width: 760px) {
    .modal.est-modal { width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh; border-radius: 0; padding: 10px; }
}
@media (max-width: 1024px) {
    /* No telemóvel e no tablet o trilho lê-se (≥ 12 px) e cada passo é um alvo para o dedo (44 px de altura). */
    .trilho { font-size: .8rem; margin-bottom: 0; }
    .trilho a { display: inline-flex; align-items: center; min-height: 44px; padding: 0 4px; }
}

/* O FORMULÁRIO DA ESTAÇÃO EM SEPARADORES e a grelha dos contactos da ficha técnica (13/10). */
.form-separadores { margin: 4px 0 14px; border-radius: var(--t-raio-interior) var(--t-raio-interior) 0 0; }
.contactos-editor { display: grid; gap: 8px; }
.contacto-linha { display: grid; grid-template-columns: minmax(130px, 1fr) minmax(120px, 1.3fr) minmax(110px, 1fr) minmax(120px, 1fr)
                  minmax(140px, 1.3fr) minmax(110px, 1.2fr) auto; gap: 6px; align-items: center; }
@media (max-width: 900px) {
    .contacto-linha { grid-template-columns: 1fr 1fr; padding: 8px; border: 1px solid var(--t-borda); border-radius: var(--t-raio-interior); }
    .contacto-linha > button { justify-self: start; }
}

/* A FICHA TÉCNICA, para ler (13/10): secções em cartões lado a lado, rótulo à esquerda e valor à direita. */
.ficha-topo { display: flex; justify-content: flex-end; margin-bottom: 10px; }
.ficha-grelha { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 12px; }
.ficha-sec { background: var(--t-fundo-interior); border: 1px solid var(--t-borda); border-radius: var(--t-raio-interior); padding: 12px 14px; }
.ficha-sec h4 { margin: 0 0 8px; font-size: .9rem; color: var(--t-texto); }
.ficha-sec dl { display: grid; grid-template-columns: minmax(110px, 38%) 1fr; gap: 6px 12px; margin: 0; font-size: .86rem; }
.ficha-sec dt { color: var(--t-texto-fraco); }
.ficha-sec dd { margin: 0; color: var(--t-texto); white-space: pre-line; overflow-wrap: anywhere; }
.ficha-contactos { margin-bottom: 12px; }
.ficha-notas { margin: 0; white-space: pre-line; color: var(--t-texto); font-size: .88rem; }
/* A janela de editar a estação é larga: oito separadores e a grelha dos contactos não cabiam num formulário estreito. */
.modal.form-modal.site-modal { width: min(1120px, 94vw); max-width: min(1120px, 94vw); }

/* MOVIMENTO (13/10, pedido do utilizador: «animação ao mudar de conteúdo ou página… ligação entre conteúdos»).
   As janelas entram a crescer do centro sobre um fundo que escurece; uma janela por cima de outra sobe um pouco
   mais (parece que sai da de baixo). O conteúdo de um separador novo desliza para o lugar. Curto de propósito
   (≤ 0,24 s): é para ligar uma coisa à outra, não para fazer esperar. Quem pediu ao sistema menos movimento não
   tem nenhum.
   `backwards` e não `both` nas que mexem no `transform` (18/10): com `both` o fim da animação ficava preso no elemento
   como `matrix(1, 0, 0, 1, 0, 0)` — um transform, que faz de bloco contentor para o que é `position: fixed`. Uma
   janela aberta dentro de um separador (`.anima-entra`) ou dentro de outra janela (`.modal`) ficava presa à caixa
   dela em vez de cobrir o ecrã. O fim das animações é o estado normal do elemento, por isso não há nada a reter. */
@keyframes ricentra-fundo-entra { from { opacity: 0; } to { opacity: 1; } }
@keyframes ricentra-janela-entra { from { opacity: 0; transform: translateY(10px) scale(.965); } to { opacity: 1; transform: none; } }
@keyframes ricentra-conteudo-entra { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.modal-scrim { animation: ricentra-fundo-entra .18s ease-out both; }
.modal-scrim > .modal { animation: ricentra-janela-entra .24s cubic-bezier(.2, .8, .2, 1) backwards; }
.anima-entra { animation: ricentra-conteudo-entra .22s cubic-bezier(.2, .8, .2, 1) backwards; }
@media (prefers-reduced-motion: reduce) {
    .modal-scrim, .modal-scrim > .modal, .anima-entra { animation: none; }
}

/* A janela de editar a estação ajusta-se ao conteúdo (13/10): cresce até caber a barra dos separadores inteira, sem
   scroll nela; no telemóvel os separadores passam à linha seguinte em vez de esconderem os do fim. */
.modal.form-modal.site-modal { width: fit-content; min-width: min(760px, 94vw); max-width: min(1180px, 96vw); }
.form-separadores { flex-wrap: wrap; overflow-x: visible; }

/* EDITAR NO LUGAR DO CONTEÚDO (13/10): o formulário da estação dentro da janela/página da estação. */
.editar-na-estacao { background: var(--t-fundo-cartao); border: 1px solid var(--t-borda); border-radius: var(--t-raio); padding: 14px 16px; }
.editar-cab { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.editar-cab h3 { margin: 0; font-size: 1.05rem; color: var(--t-texto); }
.editar-pe { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--t-borda); }

/* A janela da estação vai até 95% do ecrã (13/10, pedido do utilizador) — e só cresce enquanto está aberta (ricentra.js). */
.modal.est-modal { width: 95vw; max-width: 95vw; max-height: 95vh; }

/* A JANELA DA ESTAÇÃO NUNCA PASSA DOS 95% DA ALTURA (13/10, pedido do utilizador): o cabeçalho e os separadores ficam
   sempre à vista e só o conteúdo do separador rola — uma barra de deslocamento, não duas (antes rolava a janela
   e, por cima, o fundo, porque a janela mais o espaço de cima passavam a altura do ecrã). */
.modal-scrim:has(> .est-modal) { align-items: center; padding: 2.5vh 2.5vw; }
.modal.est-modal { display: flex; flex-direction: column; overflow: hidden; height: auto; max-height: 95vh; }
.est-janela { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.est-janela .est-cab { flex: none; }
.est-janela .sep-raiz { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
.est-janela .sep-corpo { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.est-janela .editar-na-estacao { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
@media (max-width: 760px) {
    .modal-scrim:has(> .est-modal) { padding: 0; }
    .modal.est-modal { max-height: 100dvh; }
}

/* EDITAR TAMBÉM COM O CABEÇALHO FIXO (14/10, pedido do utilizador: «aplicar a funcionalidade em tudo — ao editar a
   estação o scroll está em tudo e os tabs desaparecem»). Dentro da janela da estação o título fica em cima e o
   Guardar/Cancelar em baixo, sempre à vista; só os campos rolam. E em QUALQUER janela, os separadores de um
   formulário colam-se ao topo da zona que rola (sticky), para nunca desaparecerem ao descer. */
.est-janela .editar-na-estacao { display: flex; flex-direction: column; overflow: hidden; }
.est-janela .editar-na-estacao > .editar-cab, .est-janela .editar-na-estacao > .editar-pe { flex: none; }
.est-janela .editar-na-estacao > .editar-corpo { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.modal .form-separadores, .editar-corpo .form-separadores { position: sticky; top: 0; z-index: 3; margin-top: 0; }
.modal .modal-body > .sep-barra:first-child { position: sticky; top: 0; z-index: 3; }
/* No corpo de uma janela há 14 px de margem por cima: a barra cola-se ao bordo de cima, sem deixar ver o conteúdo a
   passar por trás dela. As tabs da ficha do equipamento também ficam (Valores, Falhas, Registo, Comandos). */
.modal .modal-body .form-separadores { top: -14px; }
.modal .modal-body .dev-tabs { position: sticky; top: -14px; z-index: 3; background: var(--panel); padding-top: 6px; }

/* O LIMITE e A FALHA no gráfico (14/10): o máximo configurado tracejado a vermelho; o intervalo do incidente
   sombreado por trás da linha, para se ver o que a medição fazia antes, durante e depois. */
.t-grafico-limite { stroke: var(--t-mau); stroke-width: 1.2; stroke-dasharray: 4 3; vector-effect: non-scaling-stroke; fill: none; }
.t-grafico-marca { fill: color-mix(in srgb, var(--t-mau) 16%, transparent); }

/* A TENDÊNCIA DE UM EQUIPAMENTO (14/10): os separadores das medições e o período por cima; os números (agora, mínimo,
   média, máximo, limite) e o gráfico por baixo; a legenda do tracejado e da faixa da falha no fim. */
/* minmax(0, 1fr): sem isto a coluna da grelha cresce até ao conteúdo — com as medições numa linha a barra de cima
   esticava a 1600 px numa janela de 980, e os períodos e o fim do gráfico (a marca da falha) ficavam fora da vista. */
.tend { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; }
.tend-topo { min-width: 0; }
.tend-topo { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 8px; }
.tend-medidas { flex: 1 1 320px; border-radius: var(--t-raio-interior) var(--t-raio-interior) 0 0; }
.tend-periodos { display: flex; flex-wrap: wrap; gap: 6px; }
.tend-numeros { display: flex; flex-wrap: wrap; gap: 6px; }
.tend-passou { border-color: var(--t-mau); color: var(--t-mau); }
.tend-legenda { display: flex; flex-wrap: wrap; gap: 4px 16px; font-size: .78rem; color: var(--t-texto-fraco); }
.tend-legenda i { display: inline-block; width: 18px; height: 10px; margin-right: 6px; vertical-align: middle; }
.tend-l-limite { border-top: 2px dashed var(--t-mau); height: 0 !important; }
.tend-l-falha { background: color-mix(in srgb, var(--t-mau) 22%, transparent); border-radius: 2px; }

/* O INCIDENTE (14/10): os factos em fichas por cima do gráfico; as linhas do diário dizem que se abrem. */
.inc-factos, .inc-equipamentos { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
tr.linha-clicavel { cursor: pointer; }
tr.linha-clicavel:hover > td, tr.linha-clicavel:focus-visible > td { background: color-mix(in srgb, var(--t-info) 8%, transparent); }

/* A FICHA DO EQUIPAMENTO mais larga (14/10): leva agora o gráfico de tendência, que precisa de largura para se ler. */
.modal.dev-modal { width: min(1040px, 94vw); max-width: min(1040px, 94vw); }

/* A TENDÊNCIA NUM CARTÃO SÓ (14/10, queixa do utilizador: «os tabs e os filtros de dias estão péssimos, desligados
   do gráfico»). Uma barra em cima, colada ao gráfico: as medições como separadores à esquerda e o período como um
   interruptor de segmentos à direita; por baixo, no mesmo cartão, os números e o gráfico. */
.tend { gap: 0; border: 1px solid var(--t-borda-forte); border-radius: var(--t-raio); background: var(--t-fundo-cartao); overflow: hidden; }
.tend-topo { align-items: flex-end; gap: 6px 12px; padding: 6px 8px 0; background: var(--t-fundo-interior);
             border-bottom: 1px solid var(--t-borda-forte); }
.tend-topo .tend-medidas { flex: 1 1 260px; padding: 0; background: none; border: 0; border-radius: 0; }
/* Os períodos na linha dos números (14/10, o utilizador: «ao nível do agora, mínimo, média… menos arredondados e
   mais compactos»); a barra de cima fica só para os separadores. */
.tend-linha { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 12px; }
.tend-periodos { display: inline-flex; gap: 0; margin: 0 0 0 auto; border: 1px solid var(--t-borda-forte);
                 border-radius: 4px; overflow: hidden; background: var(--t-fundo-cartao); }
.tend-periodos .t-filtro { border: 0; border-radius: 0; margin: 0; padding: 3px 9px; min-height: 0; font-size: .76rem;
                           line-height: 1.3; background: none; }
.tend-periodos .t-filtro + .t-filtro { border-left: 1px solid var(--t-borda); }
.tend-periodos .t-filtro.activo { background: var(--t-info); color: var(--t-fundo-cartao); font-weight: 700; }
.tend-corpo { display: grid; gap: 10px; padding: 12px 14px 12px; }

/* A legenda das quebras fecha-se num «?» (14/10). */
.legenda-quebras > summary { cursor: pointer; list-style: none; display: inline-flex; align-items: center; gap: 8px;
                             font-weight: 600; color: var(--t-texto); }
.legenda-quebras > summary::-webkit-details-marker { display: none; }
.legenda-quebras[open] > summary { margin-bottom: 10px; }
/* Alvos de toque das quebras (19/10, validação a 390 px: o «?» tinha 20 px e o filtro 21 px de altura). Explícitos aqui
   e não só pelo `.content summary`: embutida no separador do local, a página abre `.embutida` e não `.content`. */
.quebra-filtros label { display: inline-flex; align-items: center; gap: 8px; }
@media (max-width: 760px), (pointer: coarse) {
    .legenda-quebras > summary, .quebra-filtros label { min-height: 44px; }
}
.ajuda-icone { display: inline-grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; font-size: .78rem;
               font-weight: 700; background: var(--t-info); color: var(--t-fundo-cartao); }
/* O valor do limite no eixo, à altura do tracejado (14/10). */
.t-grafico-y .t-grafico-limite-txt { color: var(--t-mau); font-weight: 700; background: var(--t-fundo-cartao); padding: 0 2px; z-index: 1; }

/* A lista do cliente no topo (14/10). Escondida no telemóvel estreito, onde o topo não tem lugar para ela. */
.topbar .topbar-cliente { max-width: 200px; }
@media (max-width: 760px) { .topbar .topbar-cliente { display: none; } }

/* O DIÁRIO DE INCIDENTES (14/10): os em curso com fundo vermelho suave e em primeiro, os resolvidos verde suave. */
.t-tabela tr.inc-em-curso > td { background: color-mix(in srgb, var(--t-mau) 9%, transparent); }
.t-tabela tr.inc-resolvido > td { background: color-mix(in srgb, var(--t-bom) 7%, transparent); }
.t-tabela tr.inc-em-curso:hover > td { background: color-mix(in srgb, var(--t-mau) 15%, transparent); }
.t-tabela tr.inc-resolvido:hover > td { background: color-mix(in srgb, var(--t-bom) 13%, transparent); }

/* A caixa do copiloto no cockpit (14/10): só a linha para escrever; a conversa abre numa janela. */
.cockpit-copilot { display: flex; gap: 8px; }
.cockpit-copilot input { flex: 1 1 auto; min-width: 0; }
.t-janela .copilot { max-width: none; }
.t-janela .copilot-thread { max-height: 60vh; overflow-y: auto; }
.cockpit-copilot .t-icone-btn { flex: 0 0 auto; align-self: center; }

/* O COPILOTO INTEIRO (14/10): a conversa à esquerda e a ajuda (como funciona, perguntas, comandos) ao lado; abaixo de
   1100 px a ajuda desce. A mesma peça na página /copilot e na janela do cockpit (CopilotCompleto). */
.cop-lado { display: grid; gap: var(--t-espaco); align-items: start;
            grid-template-columns: minmax(0, 900px) minmax(300px, 1fr); }
.cop-lado .copilot { max-width: none; }
.cop-ajuda { display: flex; flex-direction: column; gap: var(--t-espaco); min-width: 0; }
.cop-ajuda .t-seccao { margin: 14px 0 6px; }
/* A ajuda é para ler: o texto parte em linhas em vez de reticências (numa coluna estreita cortava o «Como funciona»). */
.cop-ajuda .t-linha-texto b, .cop-ajuda .t-linha-texto small { white-space: normal; overflow-wrap: anywhere; }
.cop-filtros { display: flex; flex-direction: column; gap: 8px; margin-bottom: 4px; }
.cop-filtros .t-pesquisa { width: 100%; box-sizing: border-box; }
.cop-escolha { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; padding: 10px 12px;
               border-radius: 8px; border: 1px dashed var(--t-borda-forte); background: var(--t-fundo-interior); }
.cop-escolha small { color: var(--t-texto-fraco); font-size: .8rem; }
/* CADA COLUNA COM O SEU DESLOCAMENTO (14/10, o utilizador: «o scroll tem de andar dentro da conversa e o outro para os
   conteúdos do lado; não faz sentido procurar comandos e desaparecer a caixa de escrever»). O conjunto tem a altura do
   ecrã; a conversa rola por dentro, com a caixa de escrever sempre em baixo; a ajuda rola por si. */
@media (min-width: 1101px) {
    .cop-lado { align-items: stretch; grid-template-rows: minmax(0, 1fr); height: calc(100dvh - 230px); min-height: 460px; }
    .cop-lado > .copilot { height: auto; min-height: 0; }
    .cop-lado > .cop-ajuda { min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding-right: 4px; }
    /* Na janela do cockpit a área ocupa o espaço que a janela tem, e não uma altura fixa: com 78vh mais o cabeçalho e a
       margem passava do máximo da janela e aparecia um segundo deslocamento, o da janela inteira (visto na produção). */
    .t-janela:has(.cop-lado) { height: min(88vh, 900px); overflow: hidden; }
    .t-janela:has(.cop-lado) .t-janela-corpo { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
    .t-janela .cop-lado { flex: 1 1 auto; height: auto; min-height: 0; }
    .t-janela .cop-lado .copilot-thread { max-height: none; }
}
@media (max-width: 1100px) { .cop-lado { grid-template-columns: minmax(0, 1fr); } }
/* No telemóvel: a seta das perguntas fica na mesma linha (o lado direito só tem a seta, não empurra nada para fora), e
   a caixa da conversa ocupa a linha toda — ao lado de «Enviar» e «Submeter» ficava com 50 px. */
@media (max-width: 520px) {
    .cop-ajuda .t-linha { grid-template-columns: auto minmax(0, 1fr) auto; }
    .cop-ajuda .t-linha > .t-linha-dir { grid-column: auto; }
    .copilot > .copilot-input input { flex-basis: 100%; }
}

/* HÁ MAIS SEPARADORES — QUE SE VEJA (14/10, queixa do utilizador: «o scroll das tabs devia ser mais grosso, ou uma
   apresentação em que se perceba que há mais»). As barras que tenham de rolar têm a barra de deslocamento grossa e a
   ponta direita esbatida, a dizer que o resto continua para lá. As medições das tendências também: partiam para
   outra linha e ficavam umas por cima das outras (o utilizador, 14/10: «deviam estar corridas»). */
.tend-topo .tend-medidas { flex-wrap: nowrap; overflow-x: auto; min-width: 0; }
.sep-barra { scrollbar-width: auto; scrollbar-color: color-mix(in srgb, var(--t-info) 55%, transparent) transparent; }
.sep-barra::-webkit-scrollbar { height: 8px; }
.sep-barra::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--t-info) 55%, transparent); border-radius: 8px; }
.sep-barra:not(.form-separadores) {
    mask-image: linear-gradient(to right, black calc(100% - 28px), transparent);
    -webkit-mask-image: linear-gradient(to right, black calc(100% - 28px), transparent);
}
@media (min-width: 1200px) { .sep-barra:not(.form-separadores) { mask-image: none; -webkit-mask-image: none; } }

/* A configuração de um aparelho da VPN de um cliente (14/10): o QR centrado e o texto do ficheiro. */
.vpn-qr { display: flex; justify-content: center; margin: 8px 0; }
.vpn-qr svg { width: min(260px, 70vw); height: auto; background: white; padding: 8px; border-radius: var(--t-raio-interior); }
.vpn-conf { white-space: pre-wrap; overflow-wrap: anywhere; font-size: .78rem; background: var(--t-fundo-interior);
            border: 1px solid var(--t-borda); border-radius: var(--t-raio-interior); padding: 10px; }
/* ==== diagrama 14/10 ===========================================================================================
   O DIAGRAMA DA APLICAÇÃO (/diagrama): desenhos em SVG feitos no servidor (Components/Diagrama). Só variáveis do
   tema — o mesmo desenho no claro e no escuro. A letra dos desenhos fica a 12–13 px no tamanho natural; num ecrã
   estreito a moldura rola na horizontal em vez de encolher o desenho. */
.dg-indice { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 16px; }
.dg-indice a { text-decoration: none; }
.dg-seccao { margin: 0 0 22px; scroll-margin-top: 80px; }
.dg-seccao > p { max-width: 980px; margin: 4px 0 10px; color: var(--t-texto-fraco); line-height: 1.5; }
.dg-seccao ul.dg-notas { max-width: 980px; margin: 10px 0 0; padding-left: 20px; color: var(--t-texto-fraco); line-height: 1.5; }
.dg-moldura { overflow-x: auto; overflow-y: hidden; border: 1px solid var(--t-borda); border-radius: var(--t-raio);
              background: var(--t-fundo-interior); padding: 10px; -webkit-overflow-scrolling: touch; }
.dg-moldura:focus-visible { outline: 2px solid var(--t-info); outline-offset: 2px; }
.dg-svg { display: block; max-width: none; margin: 0 auto; font-family: inherit; }
.dg-zona rect { fill: color-mix(in srgb, var(--t-texto-fraco) 5%, transparent); stroke: var(--t-borda-forte);
                stroke-width: 1.2; stroke-dasharray: 6 4; }
.dg-zona.info rect { fill: color-mix(in srgb, var(--t-info) 6%, transparent); stroke: var(--t-info); }
.dg-zona.bom rect { fill: color-mix(in srgb, var(--t-bom) 6%, transparent); stroke: var(--t-bom); }
.dg-zona.aviso rect { fill: color-mix(in srgb, var(--t-aviso) 6%, transparent); stroke: var(--t-aviso); }
.dg-zona.mau rect { fill: color-mix(in srgb, var(--t-mau) 6%, transparent); stroke: var(--t-mau); }
.dg-zona-titulo { font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; fill: var(--t-texto-fraco); }
.dg-caixa rect { fill: var(--t-fundo-cartao); stroke: var(--t-borda-forte); stroke-width: 1.4; }
.dg-caixa.info rect { fill: color-mix(in srgb, var(--t-info) 10%, var(--t-fundo-cartao)); stroke: var(--t-info); }
.dg-caixa.bom rect { fill: color-mix(in srgb, var(--t-bom) 10%, var(--t-fundo-cartao)); stroke: var(--t-bom); }
.dg-caixa.aviso rect { fill: color-mix(in srgb, var(--t-aviso) 12%, var(--t-fundo-cartao)); stroke: var(--t-aviso); }
.dg-caixa.mau rect { fill: color-mix(in srgb, var(--t-mau) 10%, var(--t-fundo-cartao)); stroke: var(--t-mau); }
.dg-caixa.fraco rect { fill: var(--t-fundo-interior); stroke-dasharray: 5 4; }
.dg-caixa text { text-anchor: middle; }
.dg-caixa-titulo { font-size: 13px; font-weight: 700; fill: var(--t-texto); }
.dg-caixa-sub { font-size: 12px; fill: var(--t-texto-fraco); }
.dg-seta { stroke: var(--t-texto-fraco); stroke-width: 1.6; fill: none; }
.dg-seta.tracejada { stroke-dasharray: 6 5; }
.dg-seta.mau { stroke: var(--t-mau); stroke-width: 2; }
.dg-ponta { fill: var(--t-texto-fraco); }
.dg-ponta.mau { fill: var(--t-mau); }
.dg-legenda rect { fill: var(--t-fundo-interior); stroke: var(--t-borda); stroke-width: 1; }
.dg-legenda text { font-size: 12px; text-anchor: middle; fill: var(--t-texto); }
.dg-legenda.mau text { fill: var(--t-mau); font-weight: 700; }
/* ==== publicação 14/10 =========================================================================================
   A FAIXA DO TOPO (Components/BarraDaPublicacao.razor): «Nova versão a caminho · a testar (passo 3 de 6) · faltam
   ~12 min», com uma barra a encher. Peça genérica: uma faixa fina por cima da página, com um tom (info/bom/aviso),
   um texto, um progresso opcional e um ✕. Não tapa nada (está no fluxo, não é fixa). No telemóvel o progresso desce
   para uma linha própria e o ✕ ganha os 44 px de toque. */
.t-faixa { display: flex; align-items: center; gap: 6px 14px; flex-wrap: wrap; padding: 4px 8px 4px 16px;
           border-bottom: 1px solid var(--t-borda); box-shadow: inset 3px 0 0 var(--t-info);
           background: color-mix(in srgb, var(--t-info) 8%, var(--t-fundo-cartao));
           font-size: .8rem; line-height: 1.35; color: var(--t-texto); }
.t-faixa.bom { box-shadow: inset 3px 0 0 var(--t-bom); background: color-mix(in srgb, var(--t-bom) 8%, var(--t-fundo-cartao)); }
.t-faixa.aviso { box-shadow: inset 3px 0 0 var(--t-aviso); background: color-mix(in srgb, var(--t-aviso) 9%, var(--t-fundo-cartao)); }
/* 15/10: a faixa dos serviços em falha no Cockpit. */
.t-faixa.mau { box-shadow: inset 3px 0 0 var(--t-mau); background: color-mix(in srgb, var(--t-mau) 9%, var(--t-fundo-cartao)); }
.t-faixa-texto { flex: 1 1 260px; min-width: 0; overflow-wrap: anywhere; font-weight: 600; }
.t-faixa-progresso { flex: 0 1 240px; min-width: 80px; height: 6px; border-radius: var(--t-raio-pastilha);
                     background: var(--t-borda); overflow: hidden; }
.t-faixa-progresso u { display: block; height: 100%; border-radius: var(--t-raio-pastilha); background: var(--t-info);
                       transition: width 1s linear; }
.t-faixa.bom .t-faixa-progresso u { background: var(--t-bom); }
.t-faixa-fechar { flex: none; width: 28px; height: 28px; display: inline-grid; place-items: center; padding: 0;
                  border: 0; border-radius: 6px; background: transparent; color: var(--t-texto-fraco);
                  font: inherit; font-size: 1.1rem; line-height: 1; cursor: pointer; }
.t-faixa-fechar:hover { background: color-mix(in srgb, var(--t-texto) 8%, transparent); color: var(--t-texto); }
.t-faixa-fechar:focus-visible { outline: 2px solid var(--t-info); outline-offset: 1px; }
@media (prefers-reduced-motion: reduce) { .t-faixa-progresso u { transition: none; } }
@media (max-width: 760px), (pointer: coarse) {
    .t-faixa { display: grid; grid-template-columns: minmax(0, 1fr) auto; padding: 2px 2px 8px 14px; }
    .t-faixa-progresso { grid-column: 1 / -1; grid-row: 2; min-width: 0; margin-right: 12px; }
    .t-faixa-fechar { min-width: 44px; min-height: 44px; }
}

/* O MARKDOWN DO COPILOT (14/10): as respostas e os pedidos de ajuda que as trazem mostram-se formatados
   (MarkdownSeguro). Sem o pre-wrap, que com parágrafos em HTML duplicava as linhas; margens curtas, que isto é uma
   conversa e não um documento. */
.copilot-body.copilot-md, .pedido-texto.copilot-md { white-space: normal; }
.copilot-md > :first-child { margin-top: 0; }
.copilot-md > :last-child { margin-bottom: 0; }
.copilot-md p, .copilot-md ul, .copilot-md ol, .copilot-md blockquote, .copilot-md pre, .copilot-md table { margin: 0 0 8px; }
.copilot-md ul, .copilot-md ol { padding-left: 20px; }
.copilot-md li { margin: 2px 0; }
.copilot-md li > p { margin: 0; }
.copilot-md h1, .copilot-md h2, .copilot-md h3, .copilot-md h4 { margin: 12px 0 6px; font-size: .95rem; font-weight: 700; color: var(--t-texto); }
.copilot-md hr { border: 0; border-top: 1px solid var(--t-borda); margin: 10px 0; }
.copilot-md code { font-size: .8rem; padding: 1px 5px; border-radius: 4px; background: var(--t-fundo-interior); }
.copilot-md pre { padding: 8px 10px; border-radius: 6px; background: var(--t-fundo-interior); overflow-x: auto; }
.copilot-md pre code { padding: 0; background: none; }
.copilot-md blockquote { padding: 2px 10px; border-left: 3px solid var(--t-borda-forte); color: var(--t-texto-fraco); }
.copilot-md table { border-collapse: collapse; display: block; max-width: 100%; overflow-x: auto; font-size: .8rem; }
.copilot-md th, .copilot-md td { padding: 4px 8px; border-bottom: 1px solid var(--t-borda); text-align: left; }

/* AS FOTOS E ANEXOS DA FICHA (15/10): miniaturas ao lado de cada campo e a zona do local. */
.anexos-campo { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.anexos-zona { display: grid; gap: 10px; padding: 12px; border: 1px dashed var(--t-borda-forte); border-radius: var(--t-raio-interior); background: var(--t-fundo-interior); }
.anexos-accoes { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.anexo-input { display: none; }
.anexos-lista { display: inline-flex; flex-wrap: wrap; gap: 6px; vertical-align: middle; }
.anexos-lista.grande { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 10px; }
.anexo { position: relative; display: inline-flex; flex-direction: column; gap: 3px; color: var(--t-texto); text-decoration: none; }
.anexo > a { display: flex; flex-direction: column; gap: 3px; color: inherit; text-decoration: none; }
.anexo img, .anexo-pdf { width: 44px; height: 44px; object-fit: cover; border-radius: 6px; border: 1px solid var(--t-borda); background: var(--t-fundo-cartao); }
.anexos-zona .anexo img, .anexos-zona .anexo-pdf, .anexos-lista.grande .anexo img, .anexos-lista.grande .anexo-pdf { width: 100%; height: 90px; }
.anexo-pdf { display: grid; place-items: center; font-size: .72rem; font-weight: 700; color: var(--t-mau); }
.anexo small { font-size: .7rem; color: var(--t-texto-fraco); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
.anexos-zona .anexos-lista { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 10px; }
.anexo .anexo-apagar { position: absolute; top: -6px; right: -6px; width: 20px; height: 20px; padding: 0; border-radius: 50%;
    border: 1px solid var(--t-borda-forte); background: var(--t-fundo-cartao); color: var(--t-mau); font-size: .7rem; line-height: 1; cursor: pointer; }
/* A confirmação de apagar fica por baixo da miniatura, no fluxo: por cima dela ficava atrás da barra dos separadores. */
.anexo .confirm-inline { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.anexo-erro { color: var(--t-mau); }
.ficha-sec dd .anexos-lista { margin-left: 6px; }

/* O ECRÃ DA LICENÇA (15/10): sem licença válida é o único que o cockpit mostra. Um cartão do tema, ao centro. */
.licenca-ecra { box-sizing: border-box; max-width: 720px; margin: 48px auto; display: flex; flex-direction: column; gap: 14px;
                padding: var(--t-folga); border-radius: var(--t-raio); background: var(--t-fundo-cartao);
                border: 1px solid var(--t-borda); border-top: var(--t-acento) solid var(--t-aviso); color: var(--t-texto); }
.licenca-ecra h2 { margin: 0; }
.licenca-ecra .licenca-frase { font-size: 1.05rem; font-weight: 600; margin: 0; }
.licenca-ecra .licenca-id { display: flex; flex-direction: column; gap: 2px; padding: 12px 14px; border-radius: 8px;
                            background: color-mix(in srgb, var(--t-texto) 5%, transparent); }
.licenca-ecra .licenca-id b { font-family: ui-monospace, Consolas, monospace; font-size: 1.15rem; letter-spacing: .04em; }
.licenca-ecra textarea { width: 100%; box-sizing: border-box; font-family: ui-monospace, Consolas, monospace; font-size: .8rem; }
.licenca-ecra label { display: flex; flex-direction: column; gap: 6px; }
/* O modo de emergência (18/10): à parte do resto, separado por um traço, porque é o último recurso e não o caminho normal. */
.licenca-ecra .licenca-emergencia { display: flex; flex-direction: column; gap: 10px; padding-top: 14px; border-top: 1px solid var(--t-borda); }
.licenca-ecra .licenca-emergencia h3 { margin: 0; font-size: 1rem; }

/* ==== painéis 15/10 ============================================================================================
   O CONSTRUTOR DE PAINÉIS (Components/Paineis/GrelhaDoPainel.razor, páginas /paineis e /painel/p/…). Uma grelha de 12
   colunas em CSS Grid; cada peça diz o seu lugar em VARIÁVEIS (--c coluna, --r linha, --w largura, --h altura) e é
   aqui que se transformam em grid-column/grid-row. Por isso o telemóvel consegue desfazer o lugar: abaixo de 760 px a
   grelha passa a UMA coluna e as peças empilham pela ordem de leitura (o painel grava-as por linha e coluna). Escrever
   grid-column no style da peça ganhava a esta regra e o painel saía da largura do ecrã. Cada peça é um t-cartao: o fio
   do topo diz o estado (bom/aviso/mau), como em todo o lado. Só variáveis do tema. */
.t-painel-grelha { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); grid-auto-rows: 7.5rem;
                   gap: var(--t-espaco); align-items: stretch; }
.t-painel-peca { grid-column: var(--c) / span var(--w); grid-row: var(--r) / span var(--h);
                 position: relative; min-height: 0; overflow: hidden; gap: 6px; padding: 12px 14px; }
.t-painel-peca.velho .t-peca-numero b, .t-painel-peca.velho .t-semaforo b { color: var(--t-texto-fraco); }
.t-peca-cab { display: flex; align-items: center; gap: 8px; min-width: 0; }
.t-peca-titulo { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
                 font-size: .8rem; font-weight: 650; letter-spacing: .03em; color: var(--t-texto-fraco); }
.t-peca-corpo { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; justify-content: center; gap: 4px; overflow: hidden; }
.t-peca-numero { display: flex; align-items: baseline; gap: 2px; min-width: 0; }
.t-peca-numero b { font-size: clamp(1.6rem, 3.2vw, 2.6rem); font-weight: 700; line-height: 1.05; font-variant-numeric: tabular-nums;
                   overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.t-peca-numero small { font-size: .95rem; color: var(--t-texto-fraco); }
.t-painel-peca.bom .t-peca-numero b { color: var(--t-bom); }
.t-painel-peca.aviso .t-peca-numero b { color: var(--t-aviso); }
.t-painel-peca.mau .t-peca-numero b { color: var(--t-mau); }
.t-peca-nota { font-size: .78rem; color: var(--t-texto-fraco); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.t-peca-texto { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; line-height: 1.5; overflow: auto; }
.t-painel-peca .t-vazio { padding: 10px; }

/* O semáforo: um ponto grande e a palavra. Sem dados o ponto é cinzento (t-ponto sem tom) — nunca verde. */
.t-semaforo { display: flex; align-items: center; gap: 12px; min-width: 0; }
.t-semaforo .t-ponto { width: 22px; height: 22px; }
.t-semaforo b { font-size: clamp(1.2rem, 2.4vw, 1.8rem); font-weight: 700; line-height: 1.1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.t-semaforo.bom b { color: var(--t-bom); }
.t-semaforo.aviso b { color: var(--t-aviso); }
.t-semaforo.mau b { color: var(--t-mau); }

/* O mostrador (Tema/Mostrador.razor): meia-lua em SVG; as zonas dos limites a cor suave, o valor no tom do estado. */
.t-mostrador { display: grid; justify-items: center; gap: 0; min-height: 0; }
.t-mostrador-svg { width: 100%; max-width: 220px; max-height: 100%; display: block; }
.t-mostrador-svg path { fill: none; stroke-width: 9; stroke-linecap: butt; }
.t-mostrador-fundo { stroke: var(--t-borda); }
.t-mostrador-zona.aviso { stroke: color-mix(in srgb, var(--t-aviso) 35%, transparent); }
.t-mostrador-zona.mau { stroke: color-mix(in srgb, var(--t-mau) 35%, transparent); }
.t-mostrador-valor { stroke: var(--t-info); stroke-width: 9; }
.t-mostrador-valor.bom { stroke: var(--t-bom); }
.t-mostrador-valor.aviso { stroke: var(--t-aviso); }
.t-mostrador-valor.mau { stroke: var(--t-mau); }
.t-mostrador-texto { margin-top: -1.6rem; text-align: center; }
.t-mostrador-texto b { font-size: 1.35rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.t-mostrador-texto small { font-size: .85rem; color: var(--t-texto-fraco); }
.t-mostrador.bom .t-mostrador-texto b { color: var(--t-bom); }
.t-mostrador.aviso .t-mostrador-texto b { color: var(--t-aviso); }
.t-mostrador.mau .t-mostrador-texto b { color: var(--t-mau); }
.t-mostrador-escala { display: flex; justify-content: space-between; width: 100%; max-width: 220px; font-size: .78rem; color: var(--t-texto-fraco); }

/* O modo de editar: a barra de cada peça, a pega (o cabeçalho) e o canto de redimensionar. */
.t-painel-grelha.a-editar .t-painel-peca { overflow: visible; outline: 1px dashed var(--t-borda-forte); outline-offset: 2px; }
.t-painel-grelha.a-editar .t-painel-peca:focus-visible { outline: 2px solid var(--t-info); }
.t-peca-pega { cursor: grab; touch-action: none; user-select: none; }
.t-painel-peca.a-arrastar { z-index: 5; opacity: .85; box-shadow: var(--t-sombra-hover); cursor: grabbing; }
.t-peca-edicao { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; padding-top: 6px; border-top: 1px solid var(--t-borda); }
.t-peca-edicao .t-icone-btn { width: 30px; height: 30px; font-size: .95rem; }
.t-peca-tamanho { font-size: .78rem; color: var(--t-texto-fraco); font-variant-numeric: tabular-nums; margin: 0 4px; }
.t-peca-redim { position: absolute; right: 2px; bottom: 2px; width: 16px; height: 16px; cursor: nwse-resize; touch-action: none;
                border-right: 3px solid var(--t-borda-forte); border-bottom: 3px solid var(--t-borda-forte); border-radius: 0 0 6px 0; }

/* O ecrã de parede: sem menu, a largura toda, o nome em cima. */
.t-painel-parede { box-sizing: border-box; padding: 14px 16px; display: grid; gap: 12px; min-height: 100dvh; background: var(--bg); }
.t-painel-parede-topo { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.t-painel-parede-topo h1 { margin: 0; font-size: 1.3rem; }

/* TELEMÓVEL: uma coluna, as peças pela ordem de leitura, altura pelo conteúdo (com um mínimo para o gráfico respirar).
   No modo de editar fica a barra de botões (o arrastar desliga-se sozinho com uma coluna). */
@media (max-width: 760px) {
    .t-painel-grelha { grid-template-columns: minmax(0, 1fr); grid-auto-rows: auto; }
    .t-painel-peca { grid-column: 1 / -1; grid-row: auto; min-height: 7rem; }
    .t-painel-peca.peca-grafico, .t-painel-peca.peca-mostrador, .t-painel-peca.peca-incidentes { min-height: 12rem; }
    .t-peca-edicao .t-icone-btn { width: 44px; height: 44px; }
    .t-peca-redim { display: none; }
    .t-painel-parede { padding: 10px max(12px, env(safe-area-inset-left)) calc(10px + env(safe-area-inset-bottom)); }
}

/* ── línguas 18/10 ─────────────────────────────────────────────────────────────────────────────────────────────────
   A escolha da língua (EscolhaDaLingua): ligações em linha, a actual marcada. Os nomes vão na própria língua. Parte em
   linhas em vez de rolar; no telemóvel cada uma tem o alvo de toque de 44 px. */
.t-linguas { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 6px; margin-top: 12px; font-size: .82rem; }
.t-linguas a { color: var(--t-texto-fraco); text-decoration: none; padding: 3px 8px; border-radius: var(--t-raio-pastilha);
               border: 1px solid transparent; }
.t-linguas a:hover, .t-linguas a:focus-visible { color: var(--t-texto); border-color: var(--t-borda); }
.t-linguas a[aria-current="true"] { color: var(--t-texto); border-color: var(--t-borda-forte); font-weight: 600; }
.t-linguas.a-esquerda { justify-content: flex-start; margin-top: 4px; }
@media (max-width: 760px), (pointer: coarse) {
    .t-linguas a { min-height: 44px; display: inline-flex; align-items: center; padding: 0 12px; }
}

/* ---- Herança e etiquetas (17/10) ----------------------------------------------------------------------------------
   O campo herdado mostra SEMPRE o valor em vigor e de onde vem (o PRTG esconde-o). A etiqueta é uma pastilha com a cor
   dela num ponto e num fundo muito claro: a cor é um dado (escolhida pela pessoa), o texto fica na cor do tema e lê-se
   nos dois temas qualquer que seja a escolha. Nada aqui abaixo de 12 px. */
.t-caminho { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; margin: 0 0 10px; font-size: .84rem; color: var(--t-texto-fraco); }
.t-caminho > * + *::before { content: "›"; margin-right: 6px; color: var(--t-texto-fraco); }
.t-caminho b { color: var(--t-texto); }
.t-caminho a { color: inherit; text-decoration: none; }
.t-caminho a:hover b { text-decoration: underline; }
.t-herdados { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); gap: 10px; }
.t-herdado { display: grid; gap: 6px; align-content: start; padding: 10px 12px; border: 1px solid var(--t-borda);
             border-radius: var(--t-raio-interior); background: var(--t-fundo-interior); min-width: 0; }
.t-herdado.proprio { box-shadow: inset 3px 0 0 var(--t-info); }
.t-herdado-cab { display: flex; justify-content: space-between; align-items: baseline; gap: 4px 10px; flex-wrap: wrap; }
.t-herdado-cab b { font-size: .86rem; color: var(--t-texto); }
.t-herdado-vigor { font-size: .8rem; color: var(--t-texto-fraco); white-space: nowrap; }
.t-herdado-vigor b { font-variant-numeric: tabular-nums; }
.t-herdado-linha { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.t-herdado-linha input { width: 9em; max-width: 100%; }
.t-herdado-unidade, .t-herdado-ajuda { font-size: .78rem; color: var(--t-texto-fraco); }
.t-herdado-origem { font-size: .8rem; color: var(--t-texto-fraco); }
.t-herdado-origem.proprio { color: var(--t-texto); font-weight: 600; }

.t-etiquetas { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.t-etiqueta { display: inline-flex; align-items: center; gap: 5px; font-size: .78rem; line-height: 1.25; padding: 2px 9px 2px 7px;
              border-radius: var(--t-raio-pastilha); color: var(--t-texto); white-space: nowrap; max-width: 100%;
              border: 1px solid color-mix(in srgb, var(--t-cor, var(--t-neutro)) 50%, var(--t-borda));
              background: color-mix(in srgb, var(--t-cor, var(--t-neutro)) 12%, var(--t-fundo-cartao)); }
.t-etiqueta::before { content: ""; width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--t-cor, var(--t-neutro)); }
button.t-etiqueta { cursor: pointer; font-family: inherit; }
.t-etiqueta.desligada { background: transparent; border-style: dashed; }
.t-etiqueta.activa { box-shadow: 0 0 0 2px color-mix(in srgb, var(--t-cor, var(--t-info)) 55%, transparent); }
.t-cores { display: flex; flex-wrap: wrap; gap: 6px; }
.t-cor { width: 26px; height: 26px; border-radius: 50%; border: 2px solid var(--t-fundo-cartao); background: var(--t-cor);
         box-shadow: 0 0 0 1px var(--t-borda); cursor: pointer; padding: 0; }
.t-cor[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--t-texto); }
@media (max-width: 760px) {
    .t-cor { width: 44px; height: 44px; }
    .t-herdado-linha input { flex: 1 1 8em; width: auto; min-width: 0; }
}

/* ==== relatórios 18/10 ===========================================================================
   O centro de relatórios: números à direita nas tabelas (alinhados pela casa decimal), a célula que pede atenção no
   tom do estado, e a barra de filtros por cima do relatório. Só variáveis do tema. */
.t-tabela th.n, .t-tabela td.n { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.t-tabela td.mau { color: var(--t-mau); font-weight: 600; }
.t-tabela td.aviso { color: var(--t-aviso); font-weight: 600; }
.t-tabela td.bom { color: var(--t-bom); }
.t-relatorio-filtros { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 10px 14px; align-items: end;
                       padding: 12px; margin-bottom: 12px; border-radius: var(--t-raio-interior); background: var(--t-fundo-interior);
                       border: 1px solid var(--t-borda); }
.t-relatorio-filtros label { display: grid; gap: 4px; font-size: .78rem; color: var(--t-texto-fraco); min-width: 0; }
.t-relatorio-filtros select, .t-relatorio-filtros input { width: 100%; min-width: 0; }
.t-relatorio-desc { margin: 0 0 10px; color: var(--t-texto-fraco); font-size: .86rem; line-height: 1.45; }
.t-relatorio-accoes { display: flex; flex-wrap: wrap; gap: 6px; margin-top: auto; padding-top: 8px; }
@media (max-width: 760px) {
    .tab-cartoes tbody td.n { text-align: left; }
    .t-relatorio-filtros { grid-template-columns: minmax(0, 1fr); }
}

/* ==== editor visual 18/10 ======================================================================================
   O EDITOR COMUM (Components/Editor/EditorVisual.razor): os painéis e o desenho da cadeia. A tela é a grelha dos
   painéis com um <svg> por cima onde o ricentraEditor desenha as setas a partir das posições reais das peças; as
   peças ficam por cima das setas (as setas vêem-se nos intervalos e acabam na borda da peça). O TIPO da ligação é o
   traço — alimenta (cheio e grosso), fluxo de regra (tracejado), lido por (pontilhado) — e o TOM é a cor do estado do
   que passa por ela; «suprimido» é o cinzento tracejado a jusante de um elo caído (o incidente-mãe desenhado). Ao
   lado, o painel de propriedades da peça escolhida; abaixo de 1100 px desce para baixo da tela. Só variáveis do tema. */
.t-editor { display: grid; gap: var(--t-espaco); min-width: 0; }
.t-editor.com-lado { grid-template-columns: minmax(0, 1fr) minmax(260px, 340px); align-items: start; }
.t-editor-barra { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.t-editor-tela { position: relative; min-width: 0; }
.t-editor-setas { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; z-index: 0; }
.t-editor-tela > .t-painel-grelha > .t-painel-peca { z-index: 1; }
.t-seta { fill: none; stroke: var(--t-texto-fraco); stroke-width: 2; }
.t-seta.alimenta { stroke-width: 3; }
.t-seta.fluxo { stroke: var(--t-info); stroke-dasharray: 7 5; }
.t-seta.le { stroke-dasharray: 2 5; stroke-linecap: round; }
.t-seta.bom { stroke: var(--t-bom); }
.t-seta.aviso { stroke: var(--t-aviso); }
.t-seta.mau { stroke: var(--t-mau); }
.t-seta.suprimido { stroke: var(--t-borda-forte); stroke-dasharray: 6 6; }
.t-seta-provisoria { stroke: var(--t-info); stroke-dasharray: 4 4; }
.t-seta-ponta { fill: var(--t-texto-fraco); }
.t-seta-ponta.fluxo { fill: var(--t-info); }
.t-seta-rotulo { font-size: 12px; fill: var(--t-texto-fraco); paint-order: stroke; stroke: var(--bg); stroke-width: 4px; }
.t-seta-rotulo.fluxo { fill: var(--t-info); }
.t-editor-lado { display: grid; gap: 10px; padding: 12px 14px; border: 1px solid var(--t-borda); border-radius: var(--t-raio);
                 background: var(--t-fundo-cartao); position: sticky; top: 12px; max-height: calc(100dvh - 24px); overflow: auto; }
.t-editor-lado h3 { margin: 0; font-size: 1rem; }
.t-editor-portas { display: flex; flex-wrap: wrap; gap: 4px; }
.t-porta { font: inherit; font-size: .78rem; line-height: 1.2; padding: 3px 8px; border-radius: 999px; cursor: crosshair; touch-action: none;
           border: 1px solid var(--t-borda-forte); background: var(--t-fundo-cartao); color: var(--t-texto-fraco); }
.t-porta.fluxo { border-color: color-mix(in srgb, var(--t-info) 55%, var(--t-borda)); color: var(--t-info); }
.t-porta.activa { background: color-mix(in srgb, var(--t-info) 18%, var(--t-fundo-cartao)); border-color: var(--t-info); }
.t-painel-grelha.a-editar .t-painel-peca.escolhida { outline: 2px solid var(--t-info); }

/* A cadeia desenhada: mais espaço entre peças (é aí que passam as setas) e peças mais baixas. */
.t-painel-grelha.t-cadeia-grelha { grid-auto-rows: 5.25rem; gap: 34px 44px; }
.t-cadeia-peca { padding: 10px 12px; }
.t-cadeia-peca.regra { border-style: dashed; }
.t-cadeia-peca.suprimido { opacity: .72; }
.t-cadeia-peca .t-peca-titulo { font-size: .85rem; color: var(--t-texto); }
.t-cadeia-estado { display: flex; align-items: center; gap: 8px; min-width: 0; font-size: .85rem; }
.t-cadeia-estado span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Na cadeia as peças são baixas: a barra de edição e as portas só aparecem na peça ESCOLHIDA — as portas dentro dela,
   numa linha, e a barra por baixo, a flutuar por cima do que lá estiver (sem empurrar a grelha nem tapar o vizinho
   para sempre). */
.t-cadeia-grelha .t-peca-edicao, .t-cadeia-grelha .t-editor-portas { display: none; }
.t-cadeia-grelha .t-painel-peca.escolhida { z-index: 4; }
.t-cadeia-grelha .t-painel-peca.escolhida .t-editor-portas { display: flex; flex-wrap: nowrap; overflow: visible; }
.t-cadeia-grelha .t-painel-peca.escolhida .t-peca-edicao {
    display: flex; position: absolute; left: -1px; right: -1px; top: calc(100% + 6px); min-width: 260px;
    padding: 6px; border: 1px solid var(--t-borda-forte); border-radius: var(--t-raio-interior);
    background: var(--t-fundo-cartao); box-shadow: var(--t-sombra-hover); }
.t-editor-lado label { display: grid; gap: 4px; }
.t-editor-lado small { display: block; }
.t-cadeia-paleta { display: flex; flex-wrap: wrap; gap: 6px; }
.t-cadeia-paleta .btn { font-size: .85rem; }
.t-cadeia-ensaio { white-space: pre-wrap; font-size: .85rem; margin: 0; }

/* OS BLOCOS DO EDITOR-BANDEIRA (18/10, fatia 0): cada fatia escreve só no seu, para correrem em paralelo sem se
   cruzarem. Só variáveis do tema, como o resto. */
/* [editor:tela] — fatia C: a tela de 24 colunas, o zoom, o mini-mapa, a multi-selecção e as molduras desenhadas. */
/* A TELA (18/10, fatia C; Components/Editor/EditorVisual.razor com Tela="true" — os painéis não a pedem). A grelha passa
   a 24 colunas de largura FIXA numa folha que rola dentro da vista; o zoom é um transform na grelha (variável --zoom,
   posta pelo ricentraEditor) e a folha ocupa o tamanho escalado (--folha-w/--folha-h), para a vista rolar o que se vê.
   À esquerda o inventário do local, à direita as propriedades; por cima, as ferramentas da tela. Abaixo de 760 px, onde
   o editor o pede (data-so-ler-movel), só se lê: uma coluna como os painéis, sem zoom, sem barra, sem portas. */
.t-editor.t-editor-com-tela.com-inventario { grid-template-columns: minmax(170px, 210px) minmax(0, 1fr); }
.t-editor.t-editor-com-tela.com-inventario.com-lado { grid-template-columns: minmax(170px, 210px) minmax(0, 1fr) minmax(250px, 320px); }
.t-editor-inventario { align-self: start; position: sticky; top: 12px; max-height: calc(100dvh - 24px); overflow: auto; min-width: 0;
                       padding: 10px 12px; border: 1px solid var(--t-borda); border-radius: var(--t-raio); background: var(--t-fundo-cartao); }
.t-inventario h3 { margin: 0 0 4px; font-size: .95rem; }
.t-inventario-grupo h4 { margin: 10px 0 4px; font-size: .75rem; font-weight: 650; text-transform: uppercase; letter-spacing: .04em; color: var(--t-texto-fraco); }
.t-inventario ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.t-inventario-item { width: 100%; min-width: 0; display: grid; gap: 1px; text-align: left; font: inherit; padding: 6px 8px; cursor: grab;
                     border: 1px solid var(--t-borda); border-radius: var(--t-raio-interior); background: var(--t-fundo-interior); color: var(--t-texto); }
.t-inventario-item b { font-size: .84rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.t-inventario-item small { font-size: .75rem; color: var(--t-texto-fraco); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.t-inventario-item.por-configurar { border-style: dashed; }
.t-inventario-item.desenhado { cursor: default; opacity: .62; }
.t-inventario-item:hover:not(:disabled), .t-inventario-item:focus-visible { border-color: var(--t-info); }
.t-cadeia-paleta [draggable="true"] { cursor: grab; }

.t-tela-area { position: relative; min-width: 0; display: grid; gap: 8px; align-content: start; }
.t-tela-ferramentas { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; }
.t-tela-ferramentas .t-icone-btn { width: 30px; height: 30px; }
.t-tela-zoom { min-width: 3.6em; text-align: center; font-size: .82rem; font-variant-numeric: tabular-nums; color: var(--t-texto-fraco); }
.t-tela-sep { width: 1px; height: 22px; background: var(--t-borda); margin: 0 4px; }
.t-tela-conta { font-size: .82rem; color: var(--t-texto-fraco); }
.t-tela-grupo { display: inline-flex; gap: 2px; }
.t-tela-aviso { margin: 0; }
.t-tela-vista { position: relative; overflow: auto; max-height: min(72vh, 900px); min-height: 360px; padding: 14px; outline: none;
                border: 1px solid var(--t-borda); border-radius: var(--t-raio); background-color: var(--t-fundo-interior);
                background-image: radial-gradient(var(--t-borda) 1px, transparent 1px); background-size: 22px 22px; }
.t-tela-vista:focus-visible { box-shadow: 0 0 0 2px var(--t-info); }
.t-editor-com-tela .t-tela-vista > .t-editor-tela { width: calc(var(--folha-w) * var(--zoom, 1)); height: calc(var(--folha-h) * var(--zoom, 1)); }
.t-painel-grelha.t-tela-grelha { grid-template-columns: repeat(24, 3.5rem); width: max-content; column-gap: 16px;
                                 transform: scale(var(--zoom, 1)); transform-origin: 0 0; }
.t-tela-grelha .t-painel-peca.seleccionada { outline: 2px solid var(--t-info); outline-offset: 3px;
                                             box-shadow: 0 0 0 5px color-mix(in srgb, var(--t-info) 16%, transparent); }
.t-tela-caixa { fill: color-mix(in srgb, var(--t-info) 10%, transparent); stroke: var(--t-info); stroke-width: 1; stroke-dasharray: 4 3; }
.t-seta-alvo { fill: none; stroke: transparent; stroke-width: 18; pointer-events: none; }
.t-seta-alvo.activo { stroke: color-mix(in srgb, var(--t-info) 32%, transparent); }
.t-moldura { fill: color-mix(in srgb, var(--t-texto-fraco) 5%, transparent); stroke: var(--t-borda-forte); stroke-width: 1.5; stroke-dasharray: 6 4; }
.t-moldura.bom { stroke: var(--t-bom); }
.t-moldura.aviso { stroke: var(--t-aviso); }
.t-moldura.mau { stroke: var(--t-mau); }
.t-moldura-titulo { font-size: 12px; font-weight: 650; fill: var(--t-texto-fraco); paint-order: stroke; stroke: var(--t-fundo-interior); stroke-width: 4px; }
.t-tela-mapa { position: absolute; right: 14px; bottom: 14px; z-index: 6; width: 180px; cursor: pointer; touch-action: none;
               border: 1px solid var(--t-borda); border-radius: var(--t-raio-interior); box-shadow: var(--t-sombra-hover);
               background: color-mix(in srgb, var(--t-fundo-cartao) 94%, transparent); }
.t-tela-mapa-peca { fill: var(--t-borda-forte); }
.t-tela-mapa-peca.aviso { fill: var(--t-aviso); }
.t-tela-mapa-peca.mau { fill: var(--t-mau); }
.t-tela-mapa-vista { fill: color-mix(in srgb, var(--t-info) 12%, transparent); stroke: var(--t-info); stroke-width: 1.5; }
.t-tela-ajuda, .t-tela-paleta { position: absolute; z-index: 9; display: grid; gap: 8px; padding: 12px 14px; border: 1px solid var(--t-borda-forte);
                                border-radius: var(--t-raio); background: var(--t-fundo-cartao); box-shadow: var(--t-sombra-hover); }
.t-tela-ajuda { right: 0; top: 44px; width: min(440px, 100%); }
.t-tela-ajuda-cab { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.t-tela-ajuda dl { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 6px 12px; margin: 0; font-size: .85rem; }
.t-tela-ajuda dt { margin: 0; }
.t-tela-ajuda dd { margin: 0; color: var(--t-texto-fraco); }
.t-tela-ajuda kbd { font: inherit; font-size: .78rem; padding: 1px 6px; border: 1px solid var(--t-borda-forte); border-radius: 4px; background: var(--t-fundo-interior); }
.t-tela-paleta { width: min(360px, calc(100% - 16px)); left: clamp(0px, var(--x, 0px), calc(100% - min(360px, calc(100% - 16px))));
                 top: var(--y, 44px); }
.t-tela-so-ler { display: none; }
@media (max-width: 760px) {
    .t-editor[data-so-ler-movel] .t-editor-barra, .t-editor[data-so-ler-movel] .t-editor-inventario, .t-editor[data-so-ler-movel] .t-editor-lado,
    .t-editor[data-so-ler-movel] .t-peca-edicao, .t-editor[data-so-ler-movel] .t-editor-portas, .t-editor[data-so-ler-movel] .t-peca-redim,
    .t-editor[data-so-ler-movel] .t-tela-ferramentas, .t-editor[data-so-ler-movel] .t-tela-mapa,
    .t-editor[data-so-ler-movel] .t-tela-ajuda, .t-editor[data-so-ler-movel] .t-tela-paleta, .t-tela-editar { display: none !important; }
    .t-editor.t-editor-com-tela, .t-editor.t-editor-com-tela.com-inventario, .t-editor.t-editor-com-tela.com-inventario.com-lado { grid-template-columns: minmax(0, 1fr); }
    .t-tela-vista { overflow: visible; max-height: none; min-height: 0; padding: 0; border: 0; background: none; }
    .t-editor-com-tela .t-tela-vista > .t-editor-tela { width: auto; height: auto; }
    .t-painel-grelha.t-tela-grelha { grid-template-columns: minmax(0, 1fr); width: auto; transform: none; }
    .t-editor[data-so-ler-movel] .t-painel-grelha.a-editar .t-painel-peca { outline: none; }
    .t-editor[data-so-ler-movel] .t-tela-so-ler { display: block; margin: 0; }
    /* A nota dos gestos que o desenho põe por cima do editor também não serve a quem só lê. */
    .t-nota:has(+ .t-editor[data-so-ler-movel]) { display: none; }
}
/* [/editor:tela] */
/* [editor:naturezas] — fatia A: a cor e o traço de cada natureza de ligação (.t-seta.natureza-…), os valores dentro
   das peças e o significado das molduras. */
/* A NATUREZA de uma ligação «alimenta» (o que passa: áudio, MPX, RF, rede, energia, dados) é o traço e uma cor
   categórica — esta só quando a seta não tem estado: o tom (bom/aviso/mau/suprimido) diz mais e ganha sempre. As cores
   são misturas das do tema longe das do estado (nem verde nem âmbar puros), para uma natureza não se ler como estado. */
.t-cadeia-grelha, .t-editor-tela {
    --t-nat-audio: var(--t-info);
    --t-nat-mpx: color-mix(in srgb, var(--t-info) 55%, var(--t-mau));
    --t-nat-rf: color-mix(in srgb, var(--t-info) 45%, var(--t-texto));
    --t-nat-rede: color-mix(in srgb, var(--t-info) 55%, var(--t-bom));
    --t-nat-energia: color-mix(in srgb, var(--t-aviso) 55%, var(--t-texto));
    --t-nat-dados: color-mix(in srgb, var(--t-texto-fraco) 80%, var(--t-info));
}
.t-seta.alimenta:not(.bom, .aviso, .mau, .suprimido).natureza-audio { stroke: var(--t-nat-audio); }
.t-seta.alimenta:not(.bom, .aviso, .mau, .suprimido).natureza-mpx { stroke: var(--t-nat-mpx); }
.t-seta.alimenta:not(.bom, .aviso, .mau, .suprimido).natureza-rf { stroke: var(--t-nat-rf); }
.t-seta.alimenta:not(.bom, .aviso, .mau, .suprimido).natureza-rede { stroke: var(--t-nat-rede); }
.t-seta.alimenta:not(.bom, .aviso, .mau, .suprimido).natureza-energia { stroke: var(--t-nat-energia); }
.t-seta.alimenta:not(.bom, .aviso, .mau, .suprimido).natureza-dados { stroke: var(--t-nat-dados); }
/* O traço fica com qualquer tom (menos o suprimido, que é o seu tracejado): vê-se o que passa mesmo a vermelho. */
.t-seta.alimenta.natureza-rede:not(.suprimido) { stroke-dasharray: 10 3 2 3; }
.t-seta.alimenta.natureza-energia:not(.suprimido) { stroke-dasharray: 14 4; }
.t-seta.alimenta.natureza-dados:not(.suprimido) { stroke-dasharray: 3 4; stroke-linecap: round; }
.t-seta-rotulo.alimenta { fill: var(--t-texto); font-weight: 600; }
/* Os números ao vivo dentro de cada peça (os mesmos da cadeia em fio). */
/* A célula da cadeia (5.25rem) só dá para o título e o estado: a peça COM números cresce para baixo o que precisa, para o
   espaço entre linhas (as setas desenham-se pelas posições reais), sem mexer na grelha nem nas vizinhas — a peça sem
   números fica como era. Numa peça de várias linhas continua a encher a área (min-height: 100% é a área da grelha).
   Os números ficam numa linha só (a crescer duas, a peça chegava à de baixo); o que não couber encolhe o RÓTULO em «…»,
   nunca o número. No telemóvel (só se lê, sem arrastar) a linha da grelha cresce com a peça, para não tapar o de baixo. */
.t-cadeia-grelha .t-cadeia-peca:has(> .t-cadeia-valores) { align-self: start; min-height: 100%; }
.t-cadeia-valores { display: flex; flex-wrap: nowrap; gap: 2px 12px; min-width: 0; overflow: hidden; margin-top: 4px; font-size: .78rem; }
.t-cadeia-valores span { flex: 0 1 auto; display: inline-flex; gap: 4px; align-items: baseline; min-width: 0; white-space: nowrap; }
.t-cadeia-valores span small { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.t-cadeia-valores span b { flex: none; }
.t-cadeia-valores small { color: var(--t-texto-fraco); }
.t-cadeia-valores b { color: var(--t-texto); font-variant-numeric: tabular-nums; }
/* A reserva e a moldura: a reserva com o contorno duplo dos caminhos que junta; a moldura é um cabeçalho de área, de
   fundo interior, com o botão de recolher à direita do nome. */
.t-cadeia-peca.peca-reserva { border-style: double; border-width: 3px; }
.t-cadeia-peca.peca-grupo { background: var(--t-fundo-interior); border-style: dashed; }
.t-cadeia-peca.peca-grupo .t-peca-cab { display: flex; align-items: center; gap: 6px; }
.t-cadeia-peca.peca-grupo .t-peca-titulo { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.t-moldura-recolher { flex: none; }
.t-moldura-membros { margin: 0; padding-left: 1.1rem; display: grid; gap: 4px; }
.t-moldura-membros li { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
/* As ligações em texto: a natureza e o rótulo de cada «alimenta», a editar. */
.t-ligacao-natureza { display: inline-flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.t-ligacao-natureza select, .t-ligacao-natureza input { max-width: 11rem; min-width: 0; }
/* «E se isto cair?» por baixo do desenho, para a peça escolhida. */
.t-esecair { display: grid; gap: 4px; margin-top: var(--t-espaco); padding: 10px 14px; border: 1px solid var(--t-borda);
             border-radius: var(--t-raio-interior); background: var(--t-fundo-interior); }
.t-esecair h3 { margin: 0; font-size: .95rem; }
.t-esecair p { margin: 0; }
@media (max-width: 760px) {
    .t-ligacao-natureza select, .t-ligacao-natureza input { max-width: 100%; }
    .t-painel-grelha.t-cadeia-grelha { grid-auto-rows: minmax(5.25rem, auto); }
}
/* [/editor:naturezas] */
/* [editor:rede] — fatia E: a vista de rede de locais, as peças de painel no desenho e a parede da cadeia. */
/* A rede (/rede, /painel/r/…) é a grelha da cadeia: os locais são peças da cadeia com o título a ligar ao local. As peças
   de painel lá dentro são as dos painéis (número, semáforo, mostrador, texto), com o mesmo fio de estado. */
.t-rede-local a.t-peca-titulo { color: var(--t-texto); text-decoration: none; }
.t-rede-local a.t-peca-titulo:hover, .t-rede-local a.t-peca-titulo:focus-visible { text-decoration: underline; }
.t-rede-grelha .t-rede-painel { padding: 10px 12px; }
.t-rede-grelha .t-rede-painel .t-peca-numero b { font-size: clamp(1.3rem, 2.2vw, 1.9rem); }
.t-rede-grelha .t-rede-painel .t-semaforo { gap: 8px; }
.t-rede-grelha .t-rede-painel .t-semaforo .t-ponto { width: 14px; height: 14px; }
.t-rede-grelha .t-rede-painel .t-semaforo b { font-size: 1.05rem; }
.t-rede-grelha .t-rede-painel .t-peca-corpo { gap: 2px; }
.t-rede-propriedades { display: grid; gap: 10px; }
.t-rede-propriedades h3 { margin: 0; font-size: .95rem; }
.t-rede-propriedades label { display: grid; gap: 4px; }
.t-rede-propriedades label.t-escolha { display: flex; gap: 8px; align-items: flex-start; }
.t-rede-propriedades input:not([type=checkbox]), .t-rede-propriedades select, .t-rede-propriedades textarea { width: 100%; min-width: 0; }
/* A peça «Cadeia de um local» dos painéis: o desenho publicado em ponto pequeno, cada peça no seu lugar (as mesmas
   variáveis --c/--r/--w/--h, numa grelha de 24) e com a cor do estado dela. */
.t-mini-cadeia { display: grid; grid-template-columns: repeat(24, minmax(0, 1fr)); grid-auto-rows: 1.35rem; gap: 4px;
                 min-height: 0; overflow: hidden; }
.t-mini-peca { grid-column: var(--c) / span var(--w); grid-row: var(--r) / span var(--h); min-width: 0; overflow: hidden;
               text-overflow: ellipsis; white-space: nowrap; font-size: .7rem; line-height: 1.35rem; padding: 0 6px;
               border: 1px solid var(--t-borda); border-left: 4px solid var(--t-neutro); border-radius: 6px;
               background: var(--t-fundo-interior); color: var(--t-texto); }
.t-mini-peca.bom { border-left-color: var(--t-bom); }
.t-mini-peca.aviso { border-left-color: var(--t-aviso); }
.t-mini-peca.mau { border-left-color: var(--t-mau); }
.t-mini-peca.suprimido { border-style: dashed; color: var(--t-texto-fraco); }
/* A parede de um desenho: a tela ocupa a largura toda, e o topo não se estica até meio do ecrã (a grelha da parede
   tem min-height de um ecrã inteiro). */
.t-desenho-parede { align-content: start; }
.t-desenho-parede .t-editor { min-width: 0; }
@media (max-width: 760px) {
    /* No telemóvel o nome do local (que abre o desenho dele) é um alvo de toque inteiro, 44 px. */
    .t-rede-local a.t-peca-titulo { display: inline-flex; align-items: center; min-height: 44px; }
    /* No telemóvel a parede empilha as peças: o mini-mapa ficava por cima delas. */
    .t-desenho-parede .t-tela-mapa { display: none; }
    /* No telemóvel a mini-cadeia vira uma lista: uma peça por linha, pela ordem de leitura. */
    .t-mini-cadeia { grid-template-columns: minmax(0, 1fr); }
    .t-mini-peca { grid-column: auto; grid-row: auto; }
}
/* [/editor:rede] */
/* [editor:regras] — fatia B: o ensaio pintado nas peças («×12») e o caminho mais usado, e os problemas clicáveis. */
.t-ensaio-vezes { position: absolute; top: 6px; right: 8px; font-size: .75rem; font-weight: 600; line-height: 1.2;
                  font-variant-numeric: tabular-nums; padding: 1px 7px; border-radius: 999px; pointer-events: auto;
                  color: var(--t-info); border: 1px solid color-mix(in srgb, var(--t-info) 45%, var(--t-borda));
                  background: color-mix(in srgb, var(--t-info) 10%, var(--t-fundo-cartao)); }
.t-ensaio-vezes.zero { color: var(--t-texto-fraco); border-color: var(--t-borda); background: var(--t-fundo-cartao); }
.t-cadeia-peca.ensaio-caminho { box-shadow: 0 0 0 2px color-mix(in srgb, var(--t-info) 55%, transparent); }
.t-seta.fluxo.ensaio-caminho { stroke-width: 3.5; stroke-dasharray: none; }
.t-regra-problemas { display: grid; gap: 4px; }
.t-regra-problemas .btn { justify-content: flex-start; text-align: left; white-space: normal; height: auto; }
/* [/editor:regras] */
/* [fluxos:formas] — FX-E do motor de fluxos: a forma de cada tipo de peça de fluxo (losango, círculo, ampulheta, pessoa),
   só em CSS, e os conectores com rótulo. */
/* A peça de fluxo é um cartão da tela (t-cadeia-peca); a forma diz o que ela é antes de se ler o nome. As formas vivem
   por trás do conteúdo (::before/::after com isolation), para o título, as portas e os botões de edição ficarem iguais. */
.t-fluxo-peca { isolation: isolate; justify-content: center; }
.t-fluxo-peca .t-fluxo-frase { font-size: .78rem; color: var(--t-texto-fraco); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.t-fluxo-peca.com-erro { box-shadow: 0 0 0 2px color-mix(in srgb, var(--t-mau) 65%, transparent); }
.t-fluxo-peca .t-fluxo-erro { position: absolute; top: 4px; right: 6px; color: var(--t-mau); font-weight: 700; font-size: .8rem; }
/* Início e fim: círculo (uma pílula numa casa larga). O fim tem o traço duplo, como no BPMN. */
.t-fluxo-peca.forma-circulo { border-radius: 999px; border-top-width: 1px; text-align: center; padding-inline: 18px; }
.t-fluxo-peca.forma-circulo .t-peca-cab { justify-content: center; }
.t-fluxo-peca.forma-circulo.peca-fx-inicio { border-color: color-mix(in srgb, var(--t-bom) 60%, var(--t-borda)); }
.t-fluxo-peca.forma-circulo.peca-fx-fim { border: 3px double var(--t-borda-forte); }
/* SE e escolher: losango desenhado por trás (a borda é o ::before, o fundo o ::after um pouco mais pequeno). */
.t-fluxo-peca.forma-losango { background: transparent; border-color: transparent; text-align: center; padding-inline: 22%; }
.t-fluxo-peca.forma-losango .t-peca-cab { justify-content: center; }
.t-fluxo-peca.forma-losango::before, .t-fluxo-peca.forma-losango::after {
    content: ""; position: absolute; z-index: -1; clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%); }
.t-fluxo-peca.forma-losango::before { inset: 0; background: color-mix(in srgb, var(--t-info) 55%, var(--t-borda-forte)); }
.t-fluxo-peca.forma-losango::after { inset: 2px 4px; background: var(--t-fundo-cartao); }
/* As esperas: uma ampulheta à esquerda e o fio da esquerda na cor de «espera». */
.t-fluxo-peca.forma-ampulheta { padding-left: 34px; border-left: 3px solid var(--t-aviso); border-top-width: 1px; }
.t-fluxo-peca.forma-ampulheta::before { content: ""; position: absolute; left: 10px; top: 50%; width: 14px; height: 20px;
    transform: translateY(-50%); background: var(--t-aviso); clip-path: polygon(0 0, 100% 0, 55% 50%, 100% 100%, 0 100%, 45% 50%); }
/* As pessoas: uma figura (cabeça e ombros) à esquerda. */
.t-fluxo-peca.forma-pessoa { padding-left: 38px; border-left: 3px solid var(--t-info); border-top-width: 1px; }
.t-fluxo-peca.forma-pessoa::before { content: ""; position: absolute; left: 11px; top: calc(50% - 12px); width: 10px; height: 10px;
    border-radius: 50%; background: var(--t-info); }
.t-fluxo-peca.forma-pessoa::after { content: ""; position: absolute; left: 7px; top: calc(50% + 0px); width: 18px; height: 10px;
    border-radius: 9px 9px 2px 2px; background: var(--t-info); }
/* Os conectores dos fluxos: a direito (traçado ortogonal), com o rótulo legível por cima do traço. */
.t-fluxo-grelha + .t-editor-setas .t-seta-rotulo, .t-editor-tela:has(.t-fluxo-grelha) .t-seta-rotulo { font-weight: 600; }
.t-editor-tela:has(.t-fluxo-grelha[data-rotulos-editaveis]) .t-seta-alvo { cursor: text; }
/* A lista dos problemas, as variáveis e as raias ao lado do editor de fluxos. */
.t-fluxo-problemas { display: grid; gap: 4px; }
.t-fluxo-problemas .btn { justify-content: flex-start; text-align: left; white-space: normal; height: auto; }
.t-fluxo-lado { display: grid; gap: 12px; align-content: start; }
.t-fluxo-lado h3 { margin: 0; font-size: .85rem; }
.t-fluxo-uso { display: flex; flex-wrap: wrap; gap: 4px; }
.t-fluxo-linha { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.t-fluxo-linha > input, .t-fluxo-linha > select { flex: 1 1 8rem; min-width: 0; }
/* [/fluxos:formas] */
/* [fluxos:raias] — FX-E do motor de fluxos: as raias (swimlanes) do desenho de um fluxo. */
/* Uma faixa da altura da folha à volta das colunas das peças da raia, alternando o tom, com o nome no topo. */
.t-raia { fill: color-mix(in srgb, var(--t-info) 5%, transparent); stroke: color-mix(in srgb, var(--t-info) 30%, var(--t-borda)); stroke-width: 1; }
.t-raia.par { fill: color-mix(in srgb, var(--t-texto-fraco) 6%, transparent); }
.t-raia-titulo { font-size: 12px; font-weight: 650; fill: var(--t-texto-fraco); letter-spacing: .03em; paint-order: stroke;
                 stroke: var(--t-fundo-interior); stroke-width: 4px; }
.t-fluxo-grelha { padding-top: 22px; }
/* [/fluxos:raias] */

@media (max-width: 1100px) {
    .t-editor.com-lado { grid-template-columns: minmax(0, 1fr); }
    .t-editor-lado { position: static; max-height: none; }
}
@media (max-width: 760px) {
    .t-painel-grelha.t-cadeia-grelha { gap: 30px; }
    .t-painel-grelha.t-cadeia-grelha .t-cadeia-peca { min-height: 5rem; }
    .t-porta { min-height: 44px; padding: 6px 12px; }
}
/* [editor:ecra] — o ECRÃ PRÓPRIO DO EDITOR (18/10, noite — pedido do dono, modelo Nintex): a janela inteira, sem o menu
   (EditorLayout), com a barra de acções em cima, a caixa de ferramentas à esquerda, a tela ao centro, a configuração do
   passo escolhido à direita e o rodapé. Só tokens do tema: as cores e o claro/escuro vêm de lá. */
.t-ecra-editor { display: flex; flex-direction: column; height: 100dvh; }
.t-ecra-editor-msg { margin: 48px auto; max-width: 520px; }
.t-casca { display: grid; grid-template-rows: auto auto minmax(0, 1fr) auto; flex: 1 1 auto; min-height: 0;
           --caixa: 272px; --lado: 360px; }
.t-casca.caixa-fechada { --caixa: 46px; }
.t-casca.sem-caixa { --caixa: 0px; }
.t-casca.sem-lado { --lado: 0px; }
.t-casca-barra { grid-row: 1; display: flex; align-items: center; gap: 8px 14px; flex-wrap: wrap; padding: 8px 14px;
                 background: var(--t-fundo-cartao); border-bottom: 1px solid var(--t-borda); }
.t-casca-id { display: grid; min-width: 0; max-width: 22rem; line-height: 1.25; }
.t-casca-tipo { font-size: .76rem; color: var(--t-texto-fraco); text-transform: uppercase; letter-spacing: .05em; }
.t-casca-titulo { font-size: 1.02rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.t-casca-accoes { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; flex: 1 1 auto; min-width: 0; }
.t-casca-fim { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.t-casca-sep { width: 1px; height: 24px; background: var(--t-borda); margin: 0 2px; }
.t-casca-barra .btn.ghost.activo { border-color: var(--t-info); color: var(--t-info); background: color-mix(in srgb, var(--t-info) 10%, var(--t-fundo-cartao)); }
.t-casca-problemas { display: inline-flex; align-items: center; gap: 4px; color: var(--t-aviso); font-weight: 600; font-size: .86rem; white-space: nowrap; }
.t-casca-ok { color: var(--t-bom); font-weight: 600; font-size: .86rem; white-space: nowrap; }
.t-casca-avisos { grid-row: 2; display: grid; gap: 6px; padding: 8px 14px 0; }
.t-casca-avisos:empty { display: none; }
.t-casca-avisos > * { margin: 0; }
.t-casca-corpo { grid-row: 3; display: grid; grid-template-columns: var(--caixa) minmax(0, 1fr) var(--lado); min-height: 0; }
.t-casca-caixa { grid-column: 1; min-height: 0; overflow: auto; padding: 10px; display: grid; gap: 8px; align-content: start;
                 background: var(--t-fundo-cartao); border-right: 1px solid var(--t-borda); }
.t-casca-recolher { justify-self: end; width: 28px; height: 28px; }
.t-casca.caixa-fechada .t-casca-caixa { padding: 10px 8px; }
.t-casca-tela { grid-column: 2; min-width: 0; min-height: 0; overflow: auto; padding: 10px 12px; display: flex; flex-direction: column; gap: 10px; }
/* A tela enche o que sobra da janela (a linha do tempo, quando se pede, fica por baixo dela). */
.t-casca-tela > .t-editor { flex: 1 1 auto; min-height: 320px; display: flex; flex-direction: column; }
.t-casca-tela > .t-editor > .t-tela-area { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.t-casca-tela .t-tela-vista { flex: 1 1 auto; max-height: none; min-height: 280px; }
.t-casca .t-tela-so-ler { display: none !important; }
.t-casca-lado .t-linha { grid-template-columns: auto minmax(0, 1fr); }
.t-casca-lado .t-linha-dir { grid-column: 1 / -1; justify-content: flex-start; }
.t-casca-lado .t-linha-texto b { white-space: normal; }
.t-casca-tela .t-tela-grelha { padding-bottom: 56px; }
.t-casca-lado { grid-column: 3; min-height: 0; overflow: auto; background: var(--t-fundo-cartao); border-left: 1px solid var(--t-borda); }
.t-casca-lado-cab { position: sticky; top: 0; z-index: 2; display: flex; align-items: flex-start; justify-content: space-between; gap: 8px;
                    padding: 12px 14px; background: var(--t-fundo-cartao); border-bottom: 1px solid var(--t-borda);
                    box-shadow: inset 3px 0 0 var(--t-info); }
.t-casca-lado-cab > div { display: grid; min-width: 0; }
.t-casca-lado-cab b { font-size: 1rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.t-casca-lado-cab small { color: var(--t-texto-fraco); font-size: .8rem; }
.t-casca-lado-corpo { display: grid; gap: 12px; align-content: start; padding: 12px 14px 24px; }
.t-casca-lado-corpo label { display: grid; gap: 4px; }
.t-casca-resumo { display: flex; flex-wrap: wrap; gap: 6px; }
/* A PROPOSTA DO COPILOT (19/10): no painel da direita só o resumo; os dois desenhos numa folha larga por cima, cada grelha
   só com as colunas que os desenhos usam (--prop-cols) e intervalos à medida, para as peças se lerem. */
.t-proposta-resumo { display: grid; gap: 10px; }
.t-proposta-folha { display: grid; gap: 14px; }
.t-proposta-par { grid-template-columns: repeat(auto-fit, minmax(min(100%, 480px), 1fr)); }
.t-proposta-par > section { min-width: 0; display: grid; gap: 8px; align-content: start; padding: 10px; border: 1px solid var(--t-borda);
                            border-radius: var(--t-raio-interior); background: var(--t-fundo-interior); }
.t-proposta-par > section > h4 { margin: 0; }
.t-proposta-par .t-painel-grelha.t-proposta-grelha { grid-template-columns: repeat(var(--prop-cols, 12), minmax(0, 1fr)); gap: 26px 12px;
                                                      grid-auto-rows: minmax(4.5rem, auto); }
.t-proposta-par .t-proposta-grelha .t-peca-titulo { white-space: normal; overflow-wrap: anywhere; }
.t-casca-rodape { grid-row: 4; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 0; padding: 6px 14px; font-size: .8rem;
                  color: var(--t-texto-fraco); background: var(--t-fundo-cartao); border-top: 1px solid var(--t-borda); }
.t-casca-rodape > span + span { border-left: 1px solid var(--t-borda); margin-left: 12px; padding-left: 12px; }
.t-casca-por-publicar { color: var(--t-aviso); font-weight: 600; }
.t-casca-so-ler { grid-row: 5; display: none; }
.t-casca-problemas-da-peca { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.t-casca-problemas-da-peca li { padding: 6px 10px; border-radius: var(--t-raio-interior); font-size: .86rem; border-left: 3px solid var(--t-aviso);
                                background: color-mix(in srgb, var(--t-aviso) 8%, var(--t-fundo-cartao)); }
.t-casca-problemas-da-peca li.mau { border-left-color: var(--t-mau); background: color-mix(in srgb, var(--t-mau) 7%, var(--t-fundo-cartao)); }
/* No ecrã, a peça por baixo do rato (ou com o foco) fica por cima das vizinhas: a barra dela (Configurar, Apagar) não fica tapada. */
.t-casca .t-painel-grelha.a-editar .t-painel-peca:hover, .t-casca .t-painel-grelha.a-editar .t-painel-peca:focus-within { z-index: 6; }
.t-painel-ecra, .t-rede-ecra { display: grid; gap: var(--t-espaco); align-content: start; }
.t-configuracao-no-lado { display: grid; gap: 10px; }
.t-configuracao-no-lado .field-grid { grid-template-columns: minmax(0, 1fr); }
.t-cadeia-entrada { display: grid; gap: 6px; margin-bottom: 14px; }
.t-ligacao { background: none; border: 0; padding: 0; font: inherit; color: var(--t-info); text-decoration: underline; cursor: pointer; }
/* A caixa de ferramentas: pesquisa e categorias que abrem e fecham. */
.t-caixa { display: grid; gap: 8px; align-content: start; }
.t-caixa-pesquisa input { width: 100%; }
.t-caixa-cat { border: 1px solid var(--t-borda); border-radius: var(--t-raio-interior); background: var(--t-fundo-interior); overflow: hidden; }
.t-caixa-cab { width: 100%; display: flex; align-items: center; gap: 6px; padding: 8px 10px; border: 0; background: none;
               color: var(--t-texto); font: inherit; font-weight: 600; font-size: .88rem; text-align: left; cursor: pointer; }
.t-caixa-cab small { margin-left: auto; color: var(--t-texto-fraco); font-weight: 400; font-size: .78rem; }
.t-caixa-seta { width: 1em; color: var(--t-texto-fraco); }
.t-caixa-cat ul { list-style: none; margin: 0; padding: 0 6px 6px; display: grid; gap: 4px; }
.t-caixa-item { width: 100%; display: flex; align-items: center; gap: 8px; padding: 6px 8px; border: 1px solid var(--t-borda);
                border-radius: 8px; background: var(--t-fundo-cartao); color: var(--t-texto); font: inherit; text-align: left; cursor: grab; }
.t-caixa-item:hover:not(:disabled), .t-caixa-item:focus-visible { border-color: var(--t-info); }
.t-caixa-item.desactivada { opacity: .55; cursor: default; }
.t-caixa-icone { flex: none; width: 26px; height: 26px; display: grid; place-items: center; border-radius: 6px;
                 color: var(--t-info); background: color-mix(in srgb, var(--t-info) 13%, var(--t-fundo-interior)); }
.t-caixa-nome { display: grid; min-width: 0; line-height: 1.25; }
.t-caixa-nome b { font-weight: 600; font-size: .86rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.t-caixa-nome small { font-size: .76rem; color: var(--t-texto-fraco); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Os «+» na tela: entre peças (a meio de cada ligação) e por baixo das saídas livres. */
/* A grelha fica por cima das setas e tapava os «+» (nos intervalos entre peças é a grelha que está debaixo do rato): com «+»,
   só as peças da grelha apanham o rato — os eventos delas continuam a subir pela grelha até quem os ouve. */
.t-tela-grelha[data-mais] { pointer-events: none; }
.t-tela-grelha[data-mais] > * { pointer-events: auto; }
.t-mais { pointer-events: all; cursor: pointer; }
.t-mais:focus { outline: none; }
.t-mais circle { fill: var(--t-fundo-cartao); stroke: var(--t-borda-forte); stroke-width: 1.5; transition: r .12s ease; }
.t-mais .t-mais-cruz { fill: none; stroke: var(--t-texto-fraco); stroke-width: 2; stroke-linecap: round; }
.t-mais:hover circle, .t-mais:focus-visible circle, .t-mais.activo circle { stroke: var(--t-info); fill: color-mix(in srgb, var(--t-info) 14%, var(--t-fundo-cartao)); }
.t-mais:hover .t-mais-cruz, .t-mais:focus-visible .t-mais-cruz, .t-mais.activo .t-mais-cruz { stroke: var(--t-info); }
.t-mais.activo circle { r: 14px; }
.t-mais-rotulo { font-size: 12px; font-weight: 600; fill: var(--t-texto-fraco); paint-order: stroke; stroke: var(--t-fundo-interior); stroke-width: 3px; }
.t-mais-fio { fill: none; stroke: var(--t-borda-forte); stroke-width: 1.5; stroke-dasharray: 3 3; }
/* A arrumação automática: as peças não se arrastam nem mudam de tamanho (o lugar é do editor); apagar continua. */
.arrumacao-auto .t-peca-pega { cursor: pointer; }
.arrumacao-auto .t-peca-edicao { display: none !important; }
.t-aviso-flutuante { position: fixed; left: 50%; bottom: 44px; transform: translateX(-50%); z-index: 60; max-width: min(640px, 92vw);
                     margin: 0; box-shadow: var(--t-sombra-hover); cursor: pointer; }
.t-casca-apagar { margin-top: 4px; }
.arrumacao-auto .t-peca-redim, .arrumacao-auto .t-peca-edicao .t-icone-btn, .arrumacao-auto .t-peca-tamanho { display: none; }
/* Os problemas ao lado do passo: um sinal no canto da peça, com o porquê na dica e no painel da direita. */
.t-peca-problema { position: absolute; top: 4px; right: 6px; z-index: 2; padding: 0 6px; border-radius: 999px; font-size: .78rem; font-weight: 700;
                   color: var(--t-aviso); background: color-mix(in srgb, var(--t-aviso) 14%, var(--t-fundo-cartao)); }
.t-peca-problema.mau { color: var(--t-mau); background: color-mix(in srgb, var(--t-mau) 12%, var(--t-fundo-cartao)); }
/* O estado vazio que guia. */
.t-comeco { max-width: 900px; margin: 18px auto; display: grid; gap: 18px; }
.t-comeco.so-opcoes { margin: 0; }
.t-comeco-cab h2 { margin: 0 0 6px; font-size: 1.3rem; }
.t-comeco-cab p { margin: 0 0 10px; color: var(--t-texto-fraco); }
.t-comeco-passos { margin: 0; padding-left: 1.3em; display: grid; gap: 6px; }
.t-comeco-passos span { color: var(--t-texto-fraco); }
.t-comeco-opcoes { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 10px; }
.t-comeco-opcao { display: grid; gap: 4px; align-content: start; padding: 14px 16px; text-align: left; font: inherit; cursor: pointer;
                  color: var(--t-texto); background: var(--t-fundo-cartao); border: 1px solid var(--t-borda); border-radius: var(--t-raio); }
.t-comeco-opcao span { color: var(--t-texto-fraco); font-size: .86rem; }
.t-comeco-opcao:hover:not(:disabled), .t-comeco-opcao:focus-visible { border-color: var(--t-info); box-shadow: var(--t-sombra-hover); }
.t-comeco-opcao.recomendada { border-color: color-mix(in srgb, var(--t-bom) 55%, var(--t-borda)); box-shadow: inset 0 3px 0 var(--t-bom); }
.t-comeco-opcao:disabled { opacity: .55; cursor: not-allowed; }
/* Publicar e as versões em janela por cima (VersoesDoDesenho NaJanela). */
.modal.t-janela.t-janela-cartao { max-width: min(760px, 96vw); padding: 0; }
.modal.t-janela.t-janela-cartao > .t-cartao { margin: 0; border: 0; }
@media (max-width: 1180px) {
    .t-casca { --caixa: 220px; --lado: 300px; }
}
@media (max-width: 760px) {
    .t-casca { height: auto; min-height: 100dvh; --caixa: 0px; --lado: 0px; }
    .t-casca-corpo { grid-template-columns: minmax(0, 1fr); }
    .t-casca-caixa, .t-casca-lado, .t-casca-accoes, .t-casca-avisos .t-nota { display: none; }
    .t-casca-tela { grid-column: 1; overflow: visible; }
    .t-casca-tela .t-tela-vista { flex: none; height: auto; min-height: 0; }
    .t-ecra-editor { height: auto; min-height: 100dvh; }
    .t-casca-so-ler { display: block; margin: 0; padding: 8px 14px; color: var(--t-texto-fraco); font-size: .86rem; }
    .t-casca-id { max-width: 60vw; }
}
/* [/editor:ecra] */

/* [paineis:pecas] ==== peças dos painéis 18/10 ===================================================================
   As peças novas dos painéis (Components/Paineis: tabela, barras, linhas, área empilhada, mapa de calor, lista de estados,
   contador, mapa de locais, imagem com pontos, cronologia, disponibilidade, top N, texto com valores, filtros e botão) e o
   que as condições lhes põem (ícone, piscar, esbatida quando escondida). Posições e intensidades vêm em VARIÁVEIS
   (--t-pct, --k, --x, --y, --w) e as cores são só do tema: as páginas não escolhem cores. */
.t-pp-icone { font-style: normal; margin-right: 4px; }
/* As peças altas (gráficos com legenda, listas, tabelas) começam em cima: centradas, uma que não cabe cortava o topo — e
   no gráfico o topo é onde estão os valores mais altos. */
.t-painel-peca:is(.peca-linhas, .peca-areaempilhada, .peca-tabela, .peca-barras, .peca-listadeestados, .peca-cronologia,
    .peca-mapadecalor, .peca-topn, .peca-textorico) .t-peca-corpo { justify-content: flex-start; }
.t-painel-peca.piscar, .t-pp-tabela td.piscar, .t-pp-barra.piscar, .t-pp-valor.piscar { animation: t-pp-pisca 1.1s ease-in-out infinite; }
@keyframes t-pp-pisca { 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) {
    .t-painel-peca.piscar, .t-pp-tabela td.piscar, .t-pp-barra.piscar, .t-pp-valor.piscar { animation: none; outline: 2px solid currentColor; outline-offset: -2px; }
}
.t-painel-peca.escondida { opacity: .55; border-style: dashed; }
.t-pp-escondida { font-size: .75rem; color: var(--t-texto-fraco); font-style: italic; }
.t-painel-peca .bom { --t-pp-cor: var(--t-bom); }
.t-painel-peca .aviso { --t-pp-cor: var(--t-aviso); }
.t-painel-peca .mau { --t-pp-cor: var(--t-mau); }
.t-painel-peca .info { --t-pp-cor: var(--t-info); }
.t-peca-numero.bom b { color: var(--t-bom); }
.t-peca-numero.aviso b { color: var(--t-aviso); }
.t-peca-numero.mau b { color: var(--t-mau); }

/* Tabela: rola dentro da peça; a primeira coluna fica presa. */
.t-pp-tabela { overflow: auto; min-height: 0; flex: 1 1 auto; }
.t-pp-tabela table { border-collapse: collapse; width: 100%; font-size: .85rem; font-variant-numeric: tabular-nums; }
.t-pp-tabela th, .t-pp-tabela td { padding: 4px 8px; border-bottom: 1px solid var(--t-borda); text-align: right; white-space: nowrap; }
.t-pp-tabela th:first-child { text-align: left; position: sticky; left: 0; background: var(--t-fundo-cartao); }
.t-pp-tabela thead th { font-size: .74rem; font-weight: 650; color: var(--t-texto-fraco); position: sticky; top: 0; background: var(--t-fundo-cartao); }
.t-pp-tabela td.bom, .t-pp-tabela td.aviso, .t-pp-tabela td.mau, .t-pp-tabela td.info { color: var(--t-pp-cor); font-weight: 700;
    background: color-mix(in srgb, var(--t-pp-cor) 9%, transparent); }
.t-pp-tabela a { color: inherit; }

/* Barras (deitadas) e colunas (em pé): o traço mede --t-pct. */
.t-pp-barras { display: grid; gap: 4px; overflow: auto; min-height: 0; align-content: start; }
.t-pp-barra { display: grid; grid-template-columns: minmax(4rem, 34%) minmax(0, 1fr) auto; align-items: center; gap: 8px; font-size: .82rem; }
.t-pp-barra-nome { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.t-pp-barra-traco { height: 10px; border-radius: 5px; background: var(--t-fundo-interior); overflow: hidden; }
.t-pp-barra-traco i { display: block; height: 100%; width: var(--t-pct); border-radius: 5px; background: var(--t-pp-cor, var(--t-info)); }
.t-pp-barra b { font-variant-numeric: tabular-nums; }
.t-pp-barra.bom b, .t-pp-barra.aviso b, .t-pp-barra.mau b { color: var(--t-pp-cor); }
.t-pp-barras.colunas { display: flex; align-items: stretch; gap: 8px; overflow-x: auto; }
.t-pp-barras.colunas .t-pp-barra { display: flex; flex-direction: column-reverse; align-items: center; flex: 1 0 3rem; min-width: 3rem; }
.t-pp-barras.colunas .t-pp-barra-traco { width: 14px; height: auto; flex: 1 1 auto; min-height: 3rem; display: flex; align-items: flex-end; }
.t-pp-barras.colunas .t-pp-barra-traco i { width: 100%; height: var(--t-pct); }
.t-pp-barras.colunas .t-pp-barra-nome { max-width: 100%; font-size: .74rem; }

/* Área empilhada: as camadas com a cor de série do tema, meio transparentes. */
.t-pp-camada { fill: color-mix(in srgb, var(--t-cor-s) 55%, transparent); stroke: var(--t-cor-s); stroke-width: .4; vector-effect: non-scaling-stroke; }

/* Mapa de calor: 24 horas por coluna; --k de 0 a 1 diz a intensidade. Uma hora sem leituras é tracejada, nunca «baixa». */
.t-pp-calor { display: grid; grid-template-columns: 3rem repeat(24, minmax(0, 1fr)); gap: 2px; font-size: .68rem; overflow: auto; min-height: 0; }
.t-pp-calor-h, .t-pp-calor-d { color: var(--t-texto-fraco); white-space: nowrap; }
.t-pp-calor i { display: block; min-height: 12px; border-radius: 2px;
    background: color-mix(in srgb, var(--t-info) calc(12% + var(--k) * 88%), var(--t-fundo-interior)); }
.t-pp-calor i.vazio { background: repeating-linear-gradient(45deg, var(--t-fundo-interior) 0 3px, transparent 3px 6px); border: 1px solid var(--t-borda); }

/* Lista de estados e contador. */
.t-pp-estado { font-size: .8rem; font-weight: 650; }
.t-pp-estado.bom, .t-pp-estado.aviso, .t-pp-estado.mau { color: var(--t-pp-cor); }
.t-pp-contador { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.t-pp-contas { display: flex; gap: 6px; flex-wrap: wrap; }
.t-pp-conta { display: inline-grid; justify-items: center; min-width: 3.4rem; padding: 4px 8px; border-radius: var(--t-raio-interior);
              background: var(--t-fundo-interior); border: 1px solid var(--t-borda); }
.t-pp-conta b { font-size: 1.1rem; font-variant-numeric: tabular-nums; }
.t-pp-conta small { font-size: .7rem; color: var(--t-texto-fraco); }
.t-pp-conta.aviso, .t-pp-conta.mau, .t-pp-conta.info { border-color: var(--t-pp-cor); }
.t-pp-conta.aviso b, .t-pp-conta.mau b, .t-pp-conta.info b { color: var(--t-pp-cor); }

/* Mapa de locais e imagem com pontos: pontos postos por --x/--y (em %). */
.t-pp-mapa { position: relative; flex: 1 1 auto; min-height: 8rem; border-radius: var(--t-raio-interior);
             background: radial-gradient(circle, var(--t-borda) 1px, transparent 1px) 0 0 / 18px 18px, var(--t-fundo-interior); }
.t-pp-mapa-ponto, .t-pp-ponto { position: absolute; left: var(--x); top: var(--y); transform: translate(-6px, -6px); display: inline-flex;
                   align-items: center; gap: 4px; color: var(--t-texto); text-decoration: none; font-size: .74rem; white-space: nowrap; }
.t-pp-mapa-ponto i, .t-pp-ponto i { width: 12px; height: 12px; border-radius: 50%; background: var(--t-pp-cor, var(--t-neutro));
                   box-shadow: 0 0 0 3px color-mix(in srgb, var(--t-pp-cor, var(--t-neutro)) 25%, transparent); flex: none; }
.t-pp-mapa-ponto span, .t-pp-ponto b { background: color-mix(in srgb, var(--t-fundo-cartao) 88%, transparent); padding: 0 4px; border-radius: 3px;
                   font-variant-numeric: tabular-nums; }
.t-pp-planta { position: relative; flex: 1 1 auto; min-height: 0; align-self: center; max-width: 100%; }
.t-pp-planta img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }

/* Cronologia: uma faixa por local; cada incidente é uma barra de --x a --x + --w. Aberto = às riscas. */
.t-pp-crono { display: grid; gap: 4px; overflow: auto; min-height: 0; }
.t-pp-crono-faixa { display: grid; grid-template-columns: minmax(4rem, 9rem) minmax(0, 1fr); gap: 8px; align-items: center; }
.t-pp-crono-nome { font-size: .78rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.t-pp-crono-pista { position: relative; height: 14px; border-radius: 3px; background: var(--t-fundo-interior); }
.t-pp-crono-pista i { position: absolute; top: 2px; bottom: 2px; left: var(--x); width: var(--w); border-radius: 2px; background: var(--t-pp-cor, var(--t-info)); }
.t-pp-crono-pista i.aberto { background: repeating-linear-gradient(45deg, var(--t-pp-cor) 0 4px, color-mix(in srgb, var(--t-pp-cor) 55%, transparent) 4px 8px); }
.t-pp-crono-eixo { display: flex; justify-content: space-between; font-size: .7rem; color: var(--t-texto-fraco); }

/* Texto com valores. */
.t-pp-rico { overflow: auto; min-height: 0; line-height: 1.5; }
.t-pp-rico h4 { margin: 0 0 4px; font-size: 1rem; }
.t-pp-rico p { margin: 0 0 4px; overflow-wrap: anywhere; }
.t-pp-rico .t-pp-item::before { content: "• "; color: var(--t-texto-fraco); }
.t-pp-valor { font-weight: 700; font-variant-numeric: tabular-nums; }
.t-pp-valor.bom, .t-pp-valor.aviso, .t-pp-valor.mau, .t-pp-valor.info { color: var(--t-pp-cor); }

/* Filtros e botão. */
.t-pp-filtro { width: 100%; }
.t-pp-intervalo { display: flex; flex-wrap: wrap; gap: 6px; align-items: end; font-size: .78rem; }
.t-pp-intervalo input { min-width: 0; }
.t-pp-botao { align-self: flex-start; }

/* A configuração de uma peça (ConfiguracaoDaPeca). */
.t-pp-lista { border: 1px solid var(--t-borda); border-radius: var(--t-raio-interior); padding: 8px 10px; display: grid; gap: 6px; min-width: 0; }
.t-pp-lista legend { font-size: .82rem; padding: 0 4px; }
/* No field-grid uma etiqueta é uma grelha de duas linhas (rótulo em cima, campo em baixo): as escolhas e as caixas de
   marcar da configuração ficam numa linha, e as listas ocupam a largura toda. */
.field-grid > fieldset.wide { grid-column: 1 / -1; }
.t-pp-config label.t-escolha, .t-pp-regra label.t-escolha, .t-pp-lista label.t-escolha { display: flex; grid-template-rows: none;
    align-items: center; gap: 8px; color: var(--t-texto); font-size: .8rem; font-weight: 500; }
.t-pp-lista .t-escolhas { grid-template-columns: repeat(auto-fill, minmax(min(170px, 100%), 1fr)); }
.t-pp-linha-cfg, .t-pp-regra, .t-pp-escolha { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-width: 0; }
.t-pp-linha-cfg > span { flex: 1 1 12rem; min-width: 0; }
.t-pp-linha-cfg input[type=number] { width: 5.5rem; }
/* Os pontos da planta postos na imagem (19/10): carregar, arrastar, setas. Os pontos são botões numerados (o número é o
   da lista por baixo); o escolhido leva o anel de foco do tema. */
.t-pp-linha-cfg.activo > span { font-weight: 600; color: var(--t-info); }
.t-pp-planta-editar { position: relative; border: 1px solid var(--t-borda); border-radius: var(--t-raio-interior); overflow: hidden;
                      cursor: crosshair; touch-action: none; user-select: none; background: var(--t-fundo-interior); }
.t-pp-planta-editar img { display: block; width: 100%; height: auto; pointer-events: none; }
.t-pp-ponto-editar { position: absolute; transform: translate(-50%, -50%); min-width: 26px; height: 26px; padding: 0 6px; border-radius: 999px;
                     border: 2px solid var(--t-fundo-cartao); background: var(--t-info); color: var(--t-fundo-cartao); font: inherit; font-size: .78rem;
                     font-weight: 700; line-height: 1; cursor: grab; touch-action: none; box-shadow: var(--t-sombra-hover); }
.t-pp-ponto-editar.activo { background: var(--t-fundo-cartao); color: var(--t-texto); border-color: var(--t-info);
                            outline: 3px solid color-mix(in srgb, var(--t-info) 45%, transparent); }
.t-pp-ponto-editar:focus-visible { outline: 3px solid var(--t-info); outline-offset: 2px; }
.t-pp-planta-ajuda { color: var(--t-texto-fraco); }
.t-pp-regra { padding: 6px 0; border-bottom: 1px dashed var(--t-borda); }
.t-pp-regra input[type=number] { width: 6.5rem; }
.t-pp-regra > select, .t-pp-regra > input, .t-pp-escolha select { width: auto; flex: 0 1 10rem; min-width: 0; max-width: 100%; }
.t-pp-regra > input[type=number] { flex-basis: 6.5rem; }

@media (max-width: 760px) {
    .t-painel-peca.peca-tabela, .t-painel-peca.peca-barras, .t-painel-peca.peca-linhas, .t-painel-peca.peca-areaempilhada,
    .t-painel-peca.peca-mapadecalor, .t-painel-peca.peca-listadeestados, .t-painel-peca.peca-mapadelocais,
    .t-painel-peca.peca-planta, .t-painel-peca.peca-cronologia, .t-painel-peca.peca-topn, .t-painel-peca.peca-textorico { min-height: 12rem; }
    .t-pp-crono-faixa { grid-template-columns: minmax(3rem, 6rem) minmax(0, 1fr); }
}
/* [/paineis:pecas] */
/* ==== versões do design 19/10: as regras (os tokens e as letras estão no início do ficheiro) ==================== */
/* -- O que as duas versões novas mudam no esqueleto: letra, raios, fundo liso, moldura escura. ------------------- */
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) {
    --t-raio: 10px; --t-raio-interior: 7px; --t-sombra-hover: 0 6px 18px rgba(16,24,40,.10);
}
:root[data-design="industrial"] { --t-raio: 4px; --t-raio-interior: 3px; --t-raio-pastilha: 3px; --t-acento: 3px; }
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) body { font-family: var(--t-letra); background-image: none; }
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) :is(button, input, select, textarea) { font-family: inherit; }
/* A Public Sans é mais larga do que a Segoe: um caminho ou endereço sem espaços que cabia à justa passava dos 390 px. */
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) :is(.hint, .t-nota, .t-sub, .t-aviso) { overflow-wrap: anywhere; }

/* A moldura: o menu escuro nos dois temas (o claro é a área de trabalho, não a moldura). As cores de base redefinem-se
   DENTRO dela, para o que lá mora (ícones, contagens, versão) se ler sobre o escuro sem regras próprias. */
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .sidebar {
    background: var(--t-moldura); border-right-color: var(--t-moldura-linha);
    --text: var(--t-moldura-texto); --muted: var(--t-moldura-fraco); --line: var(--t-moldura-linha);
}
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .sidebar .light-only { display: none; }
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .sidebar .dark-only { display: block; }
/* O logótipo escuro é um PNG com fundo preto: «screen» apaga o preto sobre a moldura (como no ecrã de estado). */
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) :is(.sidebar, .mobile-bar) .dark-only { mix-blend-mode: screen; }
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .nav-menu a { color: var(--t-moldura-fraco); border-radius: var(--t-raio-interior); }
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .nav-menu a:hover,
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .nav-acordeao-cab:hover { color: var(--t-moldura-texto); background: var(--t-moldura-activo); }
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .nav-menu a.active {
    color: var(--t-moldura-texto); background: var(--t-moldura-activo); border-color: transparent;
    box-shadow: inset 3px 0 var(--t-moldura-marca);
}
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .nav-acordeao-cab { color: var(--t-moldura-fraco); border-radius: var(--t-raio-interior); }
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .nav-acordeao-itens { border-left-color: var(--t-moldura-linha); }
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .versao-app,
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .versao-app b { color: var(--t-moldura-fraco); }
/* No telemóvel a barra de cima é a moldura, como o menu. */
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .mobile-bar { background: var(--t-moldura); border-bottom-color: var(--t-moldura-linha); }
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .mobile-bar .light-only { display: none; }
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .mobile-bar .dark-only { display: block; }
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .hamburger { background: var(--t-moldura-activo); border-color: var(--t-moldura-linha); }
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .hamburger span { background: var(--t-moldura-texto); }

/* A barra de cima da página: lisa, da cor dos cartões, sem o título em gradiente. */
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .topbar { background: var(--panel); backdrop-filter: none; }
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .topbar-title {
    background: none; -webkit-background-clip: border-box; background-clip: border-box; color: var(--text);
    font-family: var(--t-letra-titulos);
}
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) :is(.topbar-search, .topbar-user, .icon-btn, .chip) { background: var(--panel2); }
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .icon-btn { color: var(--text); }
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .avatar-sm { background: var(--t-moldura); color: var(--t-moldura-texto); }

/* Superfícies lisas: os gradientes do azul-noite saem. */
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) :is(.panel, .kpi, .station, .km-card, .tile) {
    background: var(--panel); border-radius: var(--t-raio); box-shadow: var(--shadow);
}
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) :is(input, select, textarea) { background: var(--panel); border-radius: var(--t-raio-interior); }
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) :is(.t-cartao, .t-painel) { box-shadow: var(--shadow); }

/* Os botões: o primário liso na cor da versão; os outros como estão (verde confirma, vermelho destrói). */
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .btn { border-radius: var(--t-raio-interior); }
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .btn:where(:not(.ghost, .outline, .ok, .warn, .danger, .crit, .live-now)) {
    background: var(--t-primario); border-color: var(--t-primario); color: var(--t-primario-texto); box-shadow: none;
}
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .btn.ghost:hover { background: color-mix(in srgb, var(--cyan) 10%, var(--panel2)); }

/* Os números em letra fixa, como nas propostas. */
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) :is(.t-indicador .t-indicador-texto > b, .km-value, .chip.clock) {
    font-family: var(--mono); font-variant-numeric: tabular-nums; letter-spacing: -.01em;
}

/* INDUSTRIAL: títulos condensados em maiúsculas. */
:root[data-design="industrial"] :is(.t-painel-titulo h3, .t-titulo, .panel-title h3, .t-seccao h2, .t-casca-titulo, .t-casca-lado-cab b) {
    font-family: var(--t-letra-titulos); font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
}
:root[data-design="industrial"] .topbar-title { text-transform: uppercase; letter-spacing: .08em; font-weight: 700; }
:root[data-design="industrial"] .nav-menu a { font-family: var(--t-letra-titulos); text-transform: uppercase; letter-spacing: .07em; font-weight: 600; font-size: .92rem; }
:root[data-design="industrial"] :is(.nav-ic, .t-indicador-icone, .t-filtros.separadores .t-filtro, .t-filtro, .t-contagem, .icon-btn, .chip,
    .topbar-user, .topbar-search, .hamburger, .t-logo, .tag, .badge) { border-radius: 3px; }
:root[data-design="industrial"] :is(.t-cartao, .t-painel, .panel) { border-radius: var(--t-raio); }

/* -- O ECRÃ DO EDITOR como nas propostas (as três versões) ---------------------------------------------------- */
.t-casca-barra {
    background: var(--t-moldura); border-bottom-color: var(--t-moldura-linha); color: var(--t-moldura-texto);
    --text: var(--t-moldura-texto); --muted: var(--t-moldura-fraco); --line: var(--t-moldura-linha);
    --line2: var(--t-moldura-linha); --panel2: var(--t-moldura-activo); --panel: var(--t-moldura-activo);
    --t-texto: var(--t-moldura-texto); --t-texto-fraco: var(--t-moldura-fraco); --t-borda: var(--t-moldura-linha);
    --t-fundo-cartao: var(--t-moldura-activo); --t-fundo-interior: var(--t-moldura-activo);
}
.t-casca-id { padding-right: 14px; margin-right: 2px; border-right: 1px solid var(--t-moldura-linha); }
.t-casca-tipo { color: var(--t-moldura-fraco); font-family: var(--t-letra-numeros); letter-spacing: .08em; }
.t-casca-titulo { color: var(--t-moldura-texto); }
.t-casca-barra .btn { color: var(--t-moldura-texto); }
.t-casca-barra .btn.ghost { background: transparent; border-color: transparent; }
.t-casca-barra .btn.ghost:hover:not(:disabled) { background: var(--t-moldura-activo); border-color: var(--t-moldura-linha); }
.t-casca-barra .btn.ghost.activo { color: var(--t-moldura-texto); border-color: var(--t-moldura-marca);
                                   background: color-mix(in srgb, var(--t-moldura-marca) 18%, var(--t-moldura)); }
.t-casca-barra .btn[data-editor="publicar"] {
    background: var(--t-accao); border-color: var(--t-accao); color: var(--t-accao-texto); box-shadow: none; padding-inline: 16px;
}
:root .t-casca-barra .btn.t-casca-fechar { background: transparent; border-color: var(--t-moldura-linha); color: var(--t-moldura-texto); box-shadow: none; }
.t-casca-barra .t-casca-problemas { color: var(--t-moldura-aviso); }
.t-casca-barra .t-casca-ok { color: var(--t-moldura-bom); }
.t-casca-barra .t-casca-sep { background: var(--t-moldura-linha); }
/* A tela pontilhada (o papel das propostas); a caixa e a configuração lisas dos dois lados. */
.t-casca-tela { background-color: var(--t-ed-tela); background-image: radial-gradient(var(--t-ed-ponto) 1px, transparent 1px); background-size: 20px 20px; }
:root[data-design="industrial"] .t-casca-tela {
    background-image: linear-gradient(var(--t-ed-ponto) 1px, transparent 1px), linear-gradient(90deg, var(--t-ed-ponto) 1px, transparent 1px);
    background-size: 24px 24px; --t-ed-ponto: color-mix(in srgb, var(--line) 70%, transparent);
}
.t-casca-caixa { padding: 0; gap: 0; background: var(--panel); }
.t-casca-caixa > .t-casca-recolher { margin: 6px 6px 0 auto; }
.t-casca-caixa .t-caixa { gap: 0; }
.t-casca-caixa .t-caixa-pesquisa { padding: 10px 12px; }
.t-casca-caixa .t-caixa-cat { border: 0; border-bottom: 1px solid var(--t-borda); border-radius: 0; background: transparent; }
.t-casca-caixa .t-caixa-cab { padding: 10px 12px; font-weight: 700; }
.t-casca-caixa .t-caixa-cat ul { padding: 0 0 8px; gap: 0; }
.t-casca-caixa .t-caixa-item { border: 0; border-radius: 0; padding: 7px 12px; background: transparent; }
.t-casca-caixa .t-caixa-item:hover:not(:disabled), .t-casca-caixa .t-caixa-item:focus-visible {
    background: color-mix(in srgb, var(--t-info) 8%, var(--panel)); box-shadow: inset 2px 0 var(--t-info); }
.t-casca-caixa .t-caixa-icone { width: 28px; height: 28px; }
.t-casca-lado { background: var(--panel); }
.t-casca-lado-cab { box-shadow: inset 0 -2px 0 var(--t-moldura-marca); background: var(--panel); }
.t-casca-lado-cab b { font-size: 1.06rem; }
.t-casca-rodape { font-family: var(--t-letra-numeros); font-size: .76rem; background: var(--panel); }
/* As peças da tela: cartões lisos com a borda forte, como os nós das propostas. */
.t-casca .t-cadeia-peca { background: var(--panel); border-color: var(--line2); border-radius: var(--t-raio-interior); box-shadow: var(--shadow); }
.t-casca .t-painel-grelha.a-editar .t-painel-peca.escolhida { outline: 2px solid var(--t-info); box-shadow: 0 0 0 5px color-mix(in srgb, var(--t-info) 16%, transparent); }

/* -- A escolha em Segurança › Aspecto: uma amostra de cada versão, com as cores dela. -------------------------- */
.t-designs { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; }
.t-design-opcao { display: grid; gap: 8px; align-content: start; padding: 10px; text-decoration: none; color: var(--t-texto);
                  border: 1px solid var(--t-borda); border-radius: var(--t-raio-interior); background: var(--t-fundo-interior); }
.t-design-opcao:hover, .t-design-opcao:focus-visible { border-color: var(--t-info); }
.t-design-opcao[aria-current="true"] { border-color: var(--t-info); box-shadow: inset 0 0 0 1px var(--t-info); }
.t-design-opcao b { font-size: .95rem; display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.t-design-desc { font-size: .8rem; color: var(--t-texto-fraco); line-height: 1.4; }
/* A amostra: um cockpit em miniatura (menu, barra, três números e a cadeia de um local), só com as variáveis da versão. */
.t-design-amostra { display: grid; grid-template-columns: 22% 1fr; height: 116px; border-radius: 6px; overflow: hidden;
                    border: 1px solid var(--line); background: var(--bg); font-family: var(--t-letra); color: var(--text); }
.t-da-menu { background: var(--t-moldura); display: grid; align-content: start; gap: 5px; padding: 8px 6px; border-right: 1px solid var(--line); }
.t-da-menu i { display: block; height: 5px; border-radius: 2px; background: var(--t-moldura-fraco); opacity: .55; }
.t-da-menu i:first-child { opacity: 1; background: var(--t-moldura-marca); }
.t-da-area { display: grid; grid-template-rows: 16px auto 1fr; gap: 6px; padding: 0 0 8px; min-width: 0; }
.t-da-topo { background: var(--panel); border-bottom: 1px solid var(--line); }
.t-da-numeros { display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px; padding: 0 8px; }
.t-da-numeros i { height: 26px; border-radius: 4px; background: var(--panel); border: 1px solid var(--line); }
.t-da-numeros i:nth-child(2) { box-shadow: inset 0 -3px 0 var(--red); }
.t-da-cadeia { display: flex; gap: 3px; align-items: center; margin: 0 8px; padding: 7px; border-radius: 4px; background: var(--panel); border: 1px solid var(--line); }
.t-da-cadeia i { flex: 1; height: 7px; border-radius: 2px; background: var(--green); }
.t-da-cadeia i.aviso { background: var(--amber); }
.t-da-cadeia i.mau { background: var(--red); }
.t-da-cadeia i.nada { background: var(--line2); }
.t-da-cadeia u { flex: 0 0 auto; width: 18px; height: 9px; border-radius: 2px; background: var(--t-accao); }
/* [/versões do design 19/10] */

/* ==== cockpit modular 19/10 ==== (docs/cockpit-modular.md) O Cockpit é um painel de widgets. A LER desenha-se em fluxo
   (t-colunas, t-par — as peças de sempre) e um widget traz a moldura dele, o t-painel: não há aqui nada para isso. A EDITAR
   (o editor do cockpit pessoal) cada widget vive num quadrado da grelha dos painéis: sem segunda moldura, e o que não cabe
   rola por dentro em vez de ser cortado. Uma peça de painel posta no cockpit, a ler, é o cartão dos painéis com a altura do
   que tem. Só variáveis do tema. */
.t-painel-peca.peca-widget { padding: 6px; }
.t-painel-peca.peca-widget > .t-peca-corpo { justify-content: flex-start; overflow: auto; }
.t-painel-peca.peca-widget > .t-peca-corpo > .t-painel { border: 0; background: transparent; padding: 4px; }
.t-painel-peca.no-fluxo { min-height: 7.5rem; }
/* Os botões da própria página na barra de cima (TopBar Accoes — o «Personalizar o Cockpit»): um a mais entre 1025 e 1440 px
   punha o utilizador fora da janela em alemão a 1366 px (medido pelo validador, Fluxos.BarraDeCimaCabe). Quem cede é a
   lista do cliente, que já corta com reticências. */
.topbar-pagina { display: contents; }
@media (min-width: 1025px) and (max-width: 1440px) {
    .topbar:has(.topbar-pagina > *) .topbar-actions .topbar-cliente { max-width: 112px; }
}
/* [/cockpit modular 19/10] */

/* ==== estrutura das propostas 19/10 ============================================================================
   DECISÃO DO DONO (19/10): «aplica o design que propuseste em toda a aplicação». A Cadeia viva deixa de ser só cores e
   letra: o cabeçalho de página, a barra de acções, os cartões, as listas, as tabelas, os formulários, os separadores, os
   estados vazios e a moldura azul-noite do local passam a ter a ESTRUTURA das propostas — em todas as páginas, porque
   vivem nas peças. Vale nas três versões (cada uma com os seus tokens); só a Cadeia viva é a omissão.

   O COCKPIT FICA COMO ESTÁ (decisão do dono): estas regras só valem dentro de `.main[data-ecra="pagina"]` (o
   `MainLayout` escreve «cockpit» na página inicial). Nada aqui escolhe cores: só tokens.

   As margens da área de trabalho são variáveis (--t-margem-x/-y) para as faixas (cabeçalho escuro do local, barra de
   acções) chegarem às bordas com margens negativas, sem medir nada. */
.main[data-ecra="pagina"] { --t-margem-x: 26px; --t-margem-y: 24px; --t-folga: 18px; --t-espaco: 16px; }
@media (max-width: 1024px) { .main[data-ecra="pagina"] { --t-margem-x: 14px; --t-margem-y: 16px; --t-folga: 14px; --t-espaco: 12px; } }
@media (max-width: 560px)  { .main[data-ecra="pagina"] { --t-margem-x: 12px; --t-margem-y: 14px; } }
.main[data-ecra="pagina"] > .content { padding: var(--t-margem-y) var(--t-margem-x) 60px; }

/* -- Cabeçalho de página: o trilho pequeno e fraco por cima, o título forte (h1 de 24 px nas propostas). -- */
.main[data-ecra="pagina"] .topbar { border-bottom-color: var(--t-borda); }
.main[data-ecra="pagina"] .trilho { font-size: .8rem; color: var(--t-texto-fraco); margin-bottom: 3px; }
.main[data-ecra="pagina"] .trilho a { color: var(--t-texto-fraco); text-decoration: underline; text-decoration-color: transparent; }
.main[data-ecra="pagina"] .trilho a:hover { color: var(--t-texto); text-decoration-color: currentColor; }
.main[data-ecra="pagina"] .trilho [aria-current="page"] { color: var(--t-texto-fraco); font-weight: 500; }
.main[data-ecra="pagina"] .topbar-title { font-size: 1.5rem; font-weight: 700; letter-spacing: -.01em; }

/* -- A barra de acções: o Topo que abre a página é uma faixa da largura toda, colada ao cabeçalho (os números à
      esquerda, os botões à direita), como a barra de filtros das propostas. -- */
.main[data-ecra="pagina"] > .content > .t-topo:first-child {
    margin: calc(-1 * var(--t-margem-y)) calc(-1 * var(--t-margem-x)) var(--t-espaco);
    padding: 12px var(--t-margem-x); background: var(--t-fundo-cartao); border-bottom: 1px solid var(--t-borda);
}
.main[data-ecra="pagina"] .t-accoes { gap: 8px; align-items: center; }

/* -- Botões: o primário liso, o secundário branco com contorno (nada de gradientes nem relevo). -- */
.main[data-ecra="pagina"] .btn { font-weight: 600; box-shadow: none; }
/* As alturas só no rato: no telemóvel manda o bloco «mobile 09/10» (alvos de 44 px), e estas ganhavam-lhe. */
@media (min-width: 761px) and (pointer: fine) {
    .main[data-ecra="pagina"] .btn { min-height: 38px; }
    .main[data-ecra="pagina"] .btn.sm { min-height: 32px; }
    .main[data-ecra="pagina"] :is(input:not([type=checkbox], [type=radio], [type=range], [type=color]), select) { min-height: 38px; }
    .main[data-ecra="pagina"] .t-filtro { min-height: 34px; }
}
.main[data-ecra="pagina"] .btn:not(.ghost):not(.outline):hover { transform: none; }
.main[data-ecra="pagina"] .btn.ghost { background: var(--t-fundo-cartao); border-color: var(--t-borda-forte); color: var(--t-texto); }
.main[data-ecra="pagina"] .btn.ghost:hover:not(:disabled) { background: var(--t-fundo-interior); border-color: var(--t-texto-fraco); }

/* -- Cartões: borda fina, sem fio de cor quando não há estado; o cabeçalho separado do corpo por um traço. -- */
.main[data-ecra="pagina"] .t-cartao { padding: var(--t-folga); gap: 12px; border-top: 1px solid var(--t-borda); }
.main[data-ecra="pagina"] .t-cartao:is(.bom, .aviso, .mau, .info) { border-top: 3px solid var(--t-cor); }
.main[data-ecra="pagina"] .t-cartao[style*="--t-cor"] { border-top: 3px solid var(--t-cor); }
.main[data-ecra="pagina"] .t-cartao.incerto { border-top: 3px dashed var(--t-neutro); }
.main[data-ecra="pagina"] .t-cartao > .t-cab:not(:last-child) {
    margin: calc(-1 * var(--t-folga)) calc(-1 * var(--t-folga)) 2px; padding: 14px var(--t-folga);
    border-bottom: 1px solid var(--t-borda);
}
.main[data-ecra="pagina"] .t-titulo { font-size: .95rem; }
.main[data-ecra="pagina"] :is(button, a).t-cartao:hover { transform: none; border-color: var(--t-borda-forte); }
/* O painel e o painel antigo (.panel) com o mesmo cabeçalho. */
.main[data-ecra="pagina"] .t-painel { padding: var(--t-folga); }
.main[data-ecra="pagina"] .t-painel > .t-painel-cab:not(:last-child) {
    margin: calc(-1 * var(--t-folga)) calc(-1 * var(--t-folga)) 0; padding: 14px var(--t-folga);
    border-bottom: 1px solid var(--t-borda);
}
.main[data-ecra="pagina"] .t-painel-titulo h3 { font-size: .95rem; }
.main[data-ecra="pagina"] .panel { padding: var(--t-folga); background: var(--t-fundo-cartao); border-radius: var(--t-raio); }
.main[data-ecra="pagina"] .panel > .panel-title {
    margin: calc(-1 * var(--t-folga)) calc(-1 * var(--t-folga)) 14px; padding: 14px var(--t-folga);
    border-bottom: 1px solid var(--t-borda);
}
.main[data-ecra="pagina"] .panel-title span { color: var(--t-texto-fraco); }

/* -- Listas: linhas separadas por um traço, sem caixas (as «ligações» das propostas). -- */
.main[data-ecra="pagina"] .t-linhas { gap: 0; }
.main[data-ecra="pagina"] .t-linha { background: transparent; border: 0; border-bottom: 1px solid var(--t-borda);
                                      border-radius: 0; padding: 10px 6px; min-height: 44px; }
.main[data-ecra="pagina"] .t-linhas > .t-linha:last-child { border-bottom: 0; }
.main[data-ecra="pagina"] :is(button, a).t-linha:hover { background: color-mix(in srgb, var(--t-info) 6%, transparent); }
.main[data-ecra="pagina"] :is(button, a).t-linha:focus-visible { outline-offset: -2px; }

/* -- Números: a barra de números fica, com os valores em letra fixa. -- */
.main[data-ecra="pagina"] .t-num b, .main[data-ecra="pagina"] .t-metrica b { font-family: var(--t-letra-numeros); }
.main[data-ecra="pagina"] .t-metrica { background: transparent; }

/* -- Tabelas: cabeçalho fraco em letra normal, linhas respiradas, a linha acende ao passar. -- */
.main[data-ecra="pagina"] :is(.grid-table, .t-tabela) th {
    font-size: .76rem; font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--t-texto-fraco);
    padding: 10px 12px; border-bottom: 1px solid var(--t-borda);
}
.main[data-ecra="pagina"] :is(.grid-table, .t-tabela) td { padding: 10px 12px; }
.main[data-ecra="pagina"] :is(.grid-table, .t-tabela) tbody tr:hover > td { background: color-mix(in srgb, var(--t-info) 4%, transparent); }
.main[data-ecra="pagina"] :is(.grid-table, .t-tabela) :is(td.num, td.n, td.hora) { font-family: var(--t-letra-numeros); }

/* -- Formulários: o rótulo em letra normal e forte (era pequeno e apagado), campos de 38 px, foco na cor primária. -- */
.main[data-ecra="pagina"] .field-grid label { font-size: .8rem; font-weight: 600; color: var(--t-texto); }
.main[data-ecra="pagina"] .field-grid small { color: var(--t-texto-fraco); opacity: 1; font-weight: 400; }
.main[data-ecra="pagina"] :is(input, select, textarea):not([type=checkbox], [type=radio]) { border-color: var(--t-borda-forte); }
.main[data-ecra="pagina"] :is(input, select, textarea):focus-visible { outline: 2px solid var(--t-primario); outline-offset: 0; }
.main[data-ecra="pagina"] .form-subhead { margin-top: 22px; padding-top: 16px; border-top-color: var(--t-borda); }
.main[data-ecra="pagina"] .form-subhead h4 { font-size: .95rem; font-weight: 700; }
.main[data-ecra="pagina"] .form-subhead p { font-size: .8rem; color: var(--t-texto-fraco); }

/* -- Separadores: um traço por baixo do escolhido, sem pastas (as propostas). Os filtros em pastilhas: o escolhido
      cheio na cor da moldura. -- */
.main[data-ecra="pagina"] .sep-barra { gap: 0; padding: 0 4px; background: transparent; border-bottom: 1px solid var(--t-borda); }
.main[data-ecra="pagina"] .sep { border: 0; border-bottom: 3px solid transparent; border-radius: 0; margin-bottom: -1px;
                                  background: transparent; color: var(--t-texto-fraco); font-weight: 600; }
.main[data-ecra="pagina"] .sep:hover { background: transparent; color: var(--t-texto); border-bottom-color: var(--t-borda-forte); }
.main[data-ecra="pagina"] .sep.activo { background: transparent; color: var(--t-texto); border-bottom-color: var(--t-primario); box-shadow: none; }
.main[data-ecra="pagina"] .t-filtro { padding: 5px 14px; font-weight: 600; }
.main[data-ecra="pagina"] :is(.t-filtro.activo, .t-filtros.separadores .t-filtro.activo) {
    background: var(--t-moldura); border-color: var(--t-moldura); color: var(--t-moldura-texto);
}
.main[data-ecra="pagina"] .t-filtro.activo .t-filtro-n { color: var(--t-moldura-fraco); }
.main[data-ecra="pagina"] .t-periodo a.on { background: var(--t-moldura); color: var(--t-moldura-texto); }

/* Um aviso ou uma nota no meio da página respira do que vem a seguir (colavam-se à grelha de baixo). */
.main[data-ecra="pagina"] > .content > :is(.t-aviso, .t-nota) { margin-bottom: var(--t-espaco); }

/* -- Secções e estados vazios. -- */
.main[data-ecra="pagina"] .t-seccao { margin: 26px 0 12px; }
.main[data-ecra="pagina"] .t-seccao h2 { font-size: .75rem; font-weight: 700; letter-spacing: .07em; }
.main[data-ecra="pagina"] .t-vazio { border-style: solid; padding: 32px 24px; line-height: 1.5; }
.main[data-ecra="pagina"] .t-vazio b { font-size: 1rem; margin-bottom: 6px; }
.main[data-ecra="pagina"] .empty { border-style: solid; border-color: var(--t-borda); background: var(--t-fundo-cartao); border-radius: var(--t-raio); }
.main[data-ecra="pagina"] .empty strong { font-size: 1.4rem; color: var(--t-texto-fraco); }

/* -- A PÁGINA DO LOCAL NA MOLDURA AZUL-NOITE: a barra de cima, o cabeçalho do local e os separadores são uma faixa
      escura só (como nas propostas), com as cores de base redefinidas lá dentro para o que lá mora se ler. -- */
.main[data-ecra="pagina"] .topbar.moldura,
.main[data-ecra="pagina"] > .est-pagina > .est-cab,
.main[data-ecra="pagina"] > .est-pagina > .sep-raiz > .sep-barra {
    background: var(--t-moldura); color: var(--t-moldura-texto);
    --text: var(--t-moldura-texto); --muted: var(--t-moldura-fraco); --line: var(--t-moldura-linha); --line2: var(--t-moldura-linha);
    --panel: var(--t-moldura-activo); --panel2: var(--t-moldura-activo);
    --t-texto: var(--t-moldura-texto); --t-texto-fraco: var(--t-moldura-fraco); --t-borda: var(--t-moldura-linha);
    --t-borda-forte: var(--t-moldura-linha); --t-fundo-cartao: var(--t-moldura-activo); --t-fundo-interior: var(--t-moldura-activo);
    --t-info: var(--t-moldura-marca);
}
.main[data-ecra="pagina"] .topbar.moldura { border-bottom-color: var(--t-moldura); backdrop-filter: none; }
.main[data-ecra="pagina"] .topbar.moldura .topbar-title { background: none; -webkit-background-clip: border-box; background-clip: border-box; color: var(--t-moldura-texto); }
.main[data-ecra="pagina"] .topbar.moldura :is(.topbar-search, .topbar-user, .icon-btn, .chip:not(.sistema), .t-seleccao) {
    background: var(--t-moldura-activo); border-color: var(--t-moldura-linha); color: var(--t-moldura-texto);
}
.main[data-ecra="pagina"] .topbar.moldura .topbar-search input { color: var(--t-moldura-texto); }
.main[data-ecra="pagina"] .topbar.moldura .topbar-search input::placeholder { color: var(--t-moldura-fraco); }
.main[data-ecra="pagina"] .topbar.moldura .chip.live.sistema { background: var(--t-moldura-activo); color: var(--t-moldura-texto); }
.main[data-ecra="pagina"] > .est-pagina > .est-cab {
    margin: calc(-1 * var(--t-margem-y)) calc(-1 * var(--t-margem-x)) 0; padding: 4px var(--t-margem-x) 14px; align-items: center;
}
.main[data-ecra="pagina"] > .est-pagina > .est-cab .t-sub { color: var(--t-moldura-fraco); font-family: var(--t-letra-numeros); font-size: .82rem; }
.main[data-ecra="pagina"] > .est-pagina > .est-cab .btn:not(.ghost) { background: var(--t-accao); border-color: var(--t-accao); color: var(--t-accao-texto); }
.main[data-ecra="pagina"] > .est-pagina > .est-cab .btn.ghost { background: transparent; border-color: var(--t-moldura-fraco); color: var(--t-moldura-texto); }
.main[data-ecra="pagina"] > .est-pagina > .est-cab .btn.ghost:hover { background: var(--t-moldura-activo); }
.main[data-ecra="pagina"] > .est-pagina > .sep-raiz { background: transparent; border: 0; border-radius: 0; }
.main[data-ecra="pagina"] > .est-pagina > .sep-raiz > .sep-barra {
    margin: 0 calc(-1 * var(--t-margem-x)); padding: 0 calc(var(--t-margem-x) - 14px); border-bottom: 0;
    -webkit-mask-image: none; mask-image: none;
}
.main[data-ecra="pagina"] > .est-pagina > .sep-raiz > .sep-barra .sep { color: var(--t-moldura-fraco); min-height: 46px; }
.main[data-ecra="pagina"] > .est-pagina > .sep-raiz > .sep-barra .sep:hover { color: var(--t-moldura-texto); border-bottom-color: var(--t-moldura-linha); }
.main[data-ecra="pagina"] > .est-pagina > .sep-raiz > .sep-barra .sep.activo { color: var(--t-moldura-texto); border-bottom-color: var(--t-moldura-marca); }
.main[data-ecra="pagina"] > .est-pagina > .sep-raiz > .sep-barra .sep:focus-visible { outline-color: var(--t-moldura-marca); }
.main[data-ecra="pagina"] > .est-pagina > .sep-raiz > .sep-corpo { padding: 20px 0 0; }
/* A cadeia compacta por cima dos outros separadores. */
.est-cadeia { display: flex; flex-direction: column; gap: 8px; margin-bottom: 18px; padding: 12px 14px;
              background: var(--t-fundo-cartao); border: 1px solid var(--t-borda); border-radius: var(--t-raio); }
.est-cadeia-rotulo { font-size: .75rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--t-texto-fraco); }
.main[data-ecra="pagina"] .topbar.moldura .tu-logout button { background: var(--t-moldura-activo); border-color: var(--t-moldura-linha); }
/* No telemóvel a cadeia compacta fica em três colunas e sem os ícones: é um resumo, não pode empurrar o conteúdo. */
@media (max-width: 760px) {
    .est-cadeia .t-fio { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
    .est-cadeia .t-fio-icone { display: none; }
    .est-cadeia .t-fio.compacto .t-fio-no { padding: 6px 4px; gap: 3px; }
}
/* [/estrutura das propostas 19/10] */

/* ==== editor: definições em modal 19/10 ==== */
/* As definições de uma peça abrem numa janela (DefinicoesDaPeca) e a tela fica com a largura toda; o que era do desenho todo
   abre-se numa gaveta por cima da tela (o Lado da casca). Só tokens do tema. */
.t-casca { --lado: 0px; }
.t-casca-corpo { position: relative; }
/* Num grid, a área de um filho absoluto é a da coluna dele (a 3.ª, agora com 0 px): a gaveta ocupa a linha toda. */
.t-casca-gaveta { grid-column: 1 / -1; grid-row: 1; position: absolute; top: 0; right: 0; bottom: 0; z-index: 30; width: min(420px, 100%);
                  display: flex; flex-direction: column;
                  border-left: 1px solid var(--t-borda); box-shadow: var(--t-sombra-hover); }
.t-casca-gaveta > .t-casca-lado-corpo { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.t-gaveta-regra { display: grid; gap: 8px; padding-bottom: 12px; border-bottom: 1px solid var(--t-borda); }
.t-gaveta-regra h3 { margin: 0; }
/* A janela: cabeça e botões fixos, o corpo é que rola. */
.modal.t-janela.t-definicoes { --t-janela: 640px; display: flex; flex-direction: column; overflow: hidden; padding: 0;
                               max-height: min(90vh, 920px); }
.t-definicoes:focus { outline: none; }
.t-definicoes-cab { flex: none; display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
                    padding: 18px 22px 12px; border-bottom: 1px solid var(--t-borda); }
.t-definicoes-cab h2 { margin: 0; font-size: 1.12rem; overflow-wrap: anywhere; }
.t-definicoes-cab .t-sub { margin: 2px 0 0; color: var(--t-texto-fraco); font-size: .86rem; }
.t-definicoes-cab .t-janela-fechar { position: static; flex: none; }
.t-definicoes-corpo { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 16px 22px;
                      display: grid; gap: 12px; align-content: start; }
.t-definicoes-corpo label { display: grid; gap: 4px; }
.t-definicoes-corpo .t-editor-lado-corpo { display: grid; gap: 12px; }
.t-definicoes-corpo .field-grid { grid-template-columns: minmax(0, 1fr); }
.t-definicoes-rodape { flex: none; display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: 8px;
                       padding: 12px 22px; border-top: 1px solid var(--t-borda); background: var(--t-fundo-cartao); }
.t-definicoes-extra { margin-right: auto; display: flex; align-items: center; gap: 8px; }
@media (max-width: 760px) {
    /* No telemóvel o editor só lê: a gaveta e o botão dela escondem-se, como o painel da direita antes (e o botão alargava
       a barra para lá do ecrã). */
    .t-casca-fim [data-editor=abrir-gaveta] { display: none; }
    /* Ecrã inteiro, com o Guardar/Cancelar sempre à vista e de 44 px. */
    .modal-scrim.t-definicoes-fundo { padding: 0; align-items: stretch; justify-content: stretch; }
    .modal.t-janela.t-definicoes { width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh; border-radius: 0;
                                   min-width: 0 !important; min-height: 0 !important; }
    .t-definicoes-cab { padding: max(12px, env(safe-area-inset-top)) 14px 10px; }
    .t-definicoes-corpo { padding: 14px; }
    .t-definicoes-rodape { padding: 10px 14px calc(10px + env(safe-area-inset-bottom)); }
    .t-definicoes-rodape > .btn { flex: 1 1 0; min-height: 44px; }
    .t-definicoes-extra { flex-basis: 100%; }
    .t-definicoes-extra .btn { min-height: 44px; }
}
/* ==== /editor: definições em modal 19/10 ==== */

/* ==== widgets: estilos e biblioteca 19/10 ==== (OpcoesDosWidgets, DeclaracoesDosWidgets — pedido do dono: «criar todo o tipo
   de widgets e poder definir, em cada widget, qual o design que quero usar»). Os estilos de cada widget são classes
   «estilo-…» na peça; o estilo de sempre não tem classe (e por isso o Cockpit de origem e os painéis de antes ficam iguais
   ao píxel). Só tokens do tema: um estilo diz COMO se arruma, nunca que cor tem um estado. */

/* -- O formulário genérico das opções (OpcoesDaPeca) -- */
.t-op { display: grid; gap: var(--t-folga-interior); margin-top: var(--t-folga-interior); }
.t-op-grupo { border: 1px solid var(--t-borda); border-radius: var(--t-raio-interior); padding: 8px 10px 10px; margin: 0; min-width: 0; }
.t-op-grupo legend { font-size: var(--t-pequeno); font-weight: 650; color: var(--t-texto-fraco); padding: 0 4px; }
.t-op-grupo legend small { font-weight: 400; }
.t-op-estilos { display: flex; flex-wrap: wrap; gap: 6px; }
.t-op-estilo { display: inline-flex; align-items: center; gap: 6px; padding: 5px 10px 5px 6px; border: 1px solid var(--t-borda);
    border-radius: var(--t-raio-interior); background: var(--t-fundo-interior); color: var(--t-texto); font: inherit; font-size: .82rem; cursor: pointer; }
.t-op-estilo:hover { border-color: var(--t-borda-forte); }
.t-op-estilo.activo { border-color: var(--t-info); box-shadow: inset 0 0 0 1px var(--t-info); font-weight: 650; }
/* A pré-visualização pequena de cada estilo: três traços que dizem a forma (lista, mosaicos, número, faixa…). */
.t-op-previa { display: inline-grid; grid-template-columns: 1fr; gap: 2px; width: 22px; height: 18px; padding: 2px; border-radius: 4px;
    background: var(--t-fundo-cartao); border: 1px solid var(--t-borda); flex: 0 0 auto; }
.t-op-previa i { display: block; border-radius: 1px; background: var(--t-texto-fraco); opacity: .55; min-height: 2px; }
.t-op-previa:is(.previa-mosaicos, .previa-cartoes, .previa-grelha) { grid-template-columns: 1fr 1fr; }
.t-op-previa:is(.previa-mosaicos, .previa-cartoes, .previa-grelha) i:nth-child(3) { grid-column: 1 / -1; }
.t-op-previa:is(.previa-numero, .previa-so-numero, .previa-numeros, .previa-titulo) i:first-child { min-height: 8px; opacity: .9; }
.t-op-previa:is(.previa-numero, .previa-so-numero, .previa-numeros, .previa-titulo) i:not(:first-child) { display: none; }
.t-op-previa:is(.previa-faixa, .previa-compacto, .previa-compacta, .previa-pastilha) { grid-template-rows: 1fr; align-content: center; }
.t-op-previa:is(.previa-faixa, .previa-compacto, .previa-compacta, .previa-pastilha) i:not(:first-child) { display: none; }
.t-op-previa:is(.previa-faixa, .previa-pastilha) i:first-child { min-height: 6px; border-radius: 3px; }
.t-op-previa:is(.previa-barra, .previa-barras) i { width: calc(100% - var(--k, 0) * 1%); }
.t-op-previa:is(.previa-barra, .previa-barras) i:nth-child(2) { width: 70%; }
.t-op-previa:is(.previa-barra, .previa-barras) i:nth-child(3) { width: 40%; }
.t-op-campos { margin: 0; }
.t-op-lista, .t-op-colunas { display: grid; gap: 4px; }
.t-op-item, .t-op-coluna { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; min-width: 0; }
.t-op-item > .t-escolha:first-child, .t-op-coluna > .t-escolha:first-child { flex: 1 1 9rem; min-width: 0; }
.t-op-item.fora, .t-op-coluna.fora { opacity: .7; }
.t-op-abre { font-size: var(--t-pequeno); color: var(--t-texto-fraco); }
.t-op-coluna-titulo { flex: 1 1 7rem; min-width: 0; }
.t-op-coluna-largura { width: 4.5rem; }

/* -- Os estilos das peças de painel -- */
.t-painel-peca.estilo-compacto .t-peca-numero b { font-size: clamp(1.15rem, 2vw, 1.5rem); }
.t-painel-peca.estilo-compacto .t-peca-corpo { flex-direction: row; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.t-painel-peca.estilo-faixa .t-peca-corpo { flex-direction: row; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.t-painel-peca.estilo-faixa:is(.bom, .aviso, .mau) { border-left: var(--t-acento) solid var(--t-pp-cor, var(--t-borda)); }
.t-painel-peca.estilo-faixa.bom { --t-pp-cor: var(--t-bom); } .t-painel-peca.estilo-faixa.aviso { --t-pp-cor: var(--t-aviso); } .t-painel-peca.estilo-faixa.mau { --t-pp-cor: var(--t-mau); }
.t-painel-peca.estilo-faixa .t-semaforo:is(.bom, .aviso, .mau) { background: color-mix(in srgb, var(--t-pp-cor) 12%, transparent); border-radius: var(--t-raio-interior); padding: 6px 10px; }
.t-painel-peca.estilo-pastilha .t-semaforo { display: inline-flex; align-self: flex-start; padding: 4px 12px; border-radius: var(--t-raio-pastilha);
    background: color-mix(in srgb, var(--t-pp-cor, var(--t-neutro)) 14%, transparent); }
.t-painel-peca.estilo-pastilha .t-semaforo .t-ponto { width: 12px; height: 12px; }
.t-painel-peca.estilo-pastilha .t-semaforo b { font-size: 1rem; }
.t-painel-peca.estilo-so-numero .t-pp-contas { display: none; }
.t-pp-disp-barra { display: block; margin-top: 6px; }
.t-painel-peca.estilo-compacta .t-linhas { gap: 2px; }
.t-painel-peca.estilo-compacta .t-linha-texto small { display: none; }
.t-painel-peca.estilo-titulo .t-peca-texto { font-size: clamp(1.2rem, 2.4vw, 1.8rem); font-weight: 700; line-height: 1.2; }
.t-painel-peca.estilo-nota .t-peca-texto { font-size: var(--t-pequeno); color: var(--t-texto-fraco); }

/* -- Os estilos dos widgets do Cockpit -- */
/* As caixas do topo: só os números (sem o ícone, a frase e a barra) e uma faixa estreita (o rótulo ao lado do número). */
.t-indicadores.estilo-numeros .t-indicador-icone, .t-indicadores.estilo-numeros .t-indicador-texto span,
.t-indicadores.estilo-numeros .t-indicador-barra, .t-indicadores.estilo-numeros .t-indicador-mini { display: none; }
.t-indicadores.estilo-numeros .t-indicador { justify-content: center; }
.t-indicadores.estilo-faixa .t-indicador { padding: 8px 12px; gap: 4px; }
.t-indicadores.estilo-faixa .t-indicador-icone { width: 28px; height: 28px; border-radius: 8px; }
.t-indicadores.estilo-faixa .t-indicador-icone svg { width: 16px; height: 16px; }
.t-indicadores.estilo-faixa .t-indicador-texto { flex-direction: row; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.t-indicadores.estilo-faixa .t-indicador-texto b { font-size: 1.1rem; }
.t-indicadores.estilo-faixa .t-indicador-texto span, .t-indicadores.estilo-faixa .t-indicador-mini { display: none; }
.t-indicadores.estilo-faixa .t-indicador-barra { height: 4px; }
/* O mapa sem a lista (o mapa ocupa a caixa) e a lista sem o mapa. */
.t-mapa.compacto.so-mapa, .t-mapa.compacto.so-lista { grid-template-columns: minmax(0, 1fr); }
.t-mapa.compacto.so-mapa .map { max-width: 520px; margin: 0 auto; }
/* A lista dos locais compacta: linhas mais baixas e sem o logótipo. */
.t-estacoes-caixa.estilo-compacta .t-tabela td, .t-estacoes-caixa.estilo-compacta .t-tabela th { padding-top: 3px; padding-bottom: 3px; }
.t-estacoes-caixa.estilo-compacta .t-logo { display: none; }
/* Os locais em mosaicos: um cartão por local, a cor do estado na borda; no telemóvel dois por linha. */
.t-mosaicos { display: grid; gap: 8px; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
.t-mosaico { display: grid; gap: 4px; align-content: start; text-align: left; padding: 9px 10px; min-width: 0;
    border: 1px solid var(--t-borda); border-left: var(--t-acento) solid var(--t-pp-cor, var(--t-neutro)); border-radius: var(--t-raio-interior);
    background: var(--t-fundo-interior); color: var(--t-texto); font: inherit; cursor: pointer; }
.t-mosaico.bom { --t-pp-cor: var(--t-bom); } .t-mosaico.aviso { --t-pp-cor: var(--t-aviso); } .t-mosaico.mau { --t-pp-cor: var(--t-mau); }
.t-mosaico:hover { border-color: var(--t-borda-forte); }
.t-mosaico:focus-visible { outline: 2px solid var(--t-info); outline-offset: 1px; }
.t-mosaico-nome { display: flex; align-items: center; gap: 6px; min-width: 0; }
.t-mosaico-nome b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: .86rem; }
.t-mosaico-estado { font-size: var(--t-pequeno); color: var(--t-pp-cor, var(--t-texto-fraco)); font-weight: 650; }
.t-mosaico small { font-size: .7rem; color: var(--t-texto-fraco); }
.t-mosaico .t-saude .t-ponto { width: 8px; height: 8px; }
@media (max-width: 760px) { .t-mosaicos { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* O piquete numa linha. */
.t-piquete-linha { display: flex; align-items: center; gap: 8px; margin: 0; font-size: .86rem; overflow-wrap: anywhere; }

/* -- A biblioteca (as peças novas e os estilos das de antes) -- */
.t-painel-peca:is(.peca-quebras, .peca-tickets, .peca-anomalias, .peca-energia, .peca-temperatura, .peca-fmdx, .peca-ouvir) .t-peca-corpo { justify-content: flex-start; }
.t-pp-grandezas { margin-bottom: 4px; }
.t-pp-mosaicos { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); overflow: auto; min-height: 0; }
.t-pp-mosaicos .t-mosaico { text-decoration: none; }
.t-pp-pontos { display: flex; flex-wrap: wrap; gap: 6px 10px; align-content: flex-start; overflow: auto; min-height: 0; }
.t-pp-pontinho { display: inline-flex; flex-direction: column; align-items: center; gap: 2px; max-width: 5.5rem; color: var(--t-texto); text-decoration: none; }
.t-pp-pontinho .t-ponto { width: 14px; height: 14px; }
.t-pp-pontinho small { font-size: .68rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; color: var(--t-texto-fraco); }
.t-pp-cadeia-fio { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin-top: 6px; }
.t-pp-elo { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border-radius: var(--t-raio-pastilha); font-size: .74rem;
    border: 1px solid var(--t-borda); background: var(--t-fundo-interior); white-space: nowrap; }
.t-pp-elo + .t-pp-elo::before { content: "›"; margin: 0 4px 0 -2px; color: var(--t-texto-fraco); }
.t-pp-elo .t-ponto { width: 8px; height: 8px; }
.t-pp-fmdx { display: grid; gap: 6px; min-width: 0; }
.t-pp-fmdx-cab { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.t-pp-fmdx-cab b { font-size: 1.3rem; font-variant-numeric: tabular-nums; }
.t-pp-fmdx-cab small { color: var(--t-texto-fraco); font-size: var(--t-pequeno); }
.t-pp-fmdx dl { display: grid; grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr)); gap: 6px; margin: 0; }
.t-pp-fmdx-linha { padding: 6px 8px; border-radius: var(--t-raio-interior); background: var(--t-fundo-interior); border-left: 3px solid var(--t-pp-cor, var(--t-borda)); min-width: 0; }
.t-pp-fmdx-linha dt { font-size: var(--t-rotulo); text-transform: uppercase; letter-spacing: .04em; color: var(--t-texto-fraco); }
.t-pp-fmdx-linha dd { margin: 0; font-weight: 700; font-variant-numeric: tabular-nums; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.t-pp-fmdx.faixa dl { grid-template-columns: repeat(auto-fit, minmax(5.5rem, 1fr)); }
.t-pp-fmdx.faixa .t-pp-fmdx-linha { padding: 4px 6px; }
.t-pp-ouvir { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.t-pp-ouvir audio, .t-painel-peca.peca-ouvir audio { width: 100%; max-width: 420px; }
.t-pp-relogio { display: flex; flex-direction: column; justify-content: center; min-width: 0; }
.t-pp-relogio time { font-size: clamp(1.6rem, 3.4vw, 2.6rem); font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1.05; }
.t-pp-relogio small { color: var(--t-texto-fraco); font-size: var(--t-pequeno); }
.t-painel-peca.estilo-grande .t-pp-relogio time { font-size: clamp(2.4rem, 6vw, 4.4rem); }
.t-painel-peca.estilo-compacto .t-pp-relogio { flex-direction: row; align-items: baseline; gap: 10px; }
.t-painel-peca.estilo-compacto .t-pp-relogio time { font-size: 1.3rem; }
.t-painel-peca.estilo-compacta .t-pp-tabela td, .t-painel-peca.estilo-compacta .t-pp-tabela th { padding: 2px 6px; font-size: .8rem; }
.t-grafico-limite.aviso { stroke: var(--t-aviso); }
.t-grafico-limite-txt.aviso { color: var(--t-aviso); }

/* -- A pré-visualização pequena na caixa de ferramentas e no formulário (as formas que faltavam) -- */
.t-caixa-previa { margin-left: auto; }
.t-op-previa.previa-grafico { grid-template-columns: repeat(3, 1fr); align-items: end; }
.t-op-previa.previa-grafico i:nth-child(1) { height: 40%; } .t-op-previa.previa-grafico i:nth-child(2) { height: 85%; } .t-op-previa.previa-grafico i:nth-child(3) { height: 60%; }
.t-op-previa.previa-grafico i { border-radius: 2px 2px 0 0; }
.t-op-previa.previa-tabela { grid-template-columns: 1fr 1fr 1fr; grid-template-rows: 1fr 1fr; }
.t-op-previa.previa-tabela i:nth-child(1) { grid-column: 1 / -1; opacity: .9; }
.t-op-previa.previa-tabela i:nth-child(3) { grid-column: 2 / -1; }
.t-op-previa.previa-mapa { place-items: center; position: relative; }
.t-op-previa.previa-mapa i { position: absolute; width: 4px; height: 4px; border-radius: 50%; opacity: .9; }
.t-op-previa.previa-mapa i:nth-child(1) { left: 5px; top: 4px; } .t-op-previa.previa-mapa i:nth-child(2) { left: 12px; top: 9px; } .t-op-previa.previa-mapa i:nth-child(3) { left: 7px; top: 12px; }
.t-op-previa.previa-mostrador { place-items: center; }
.t-op-previa.previa-mostrador i:first-child { width: 14px; height: 7px; border-radius: 7px 7px 0 0; border: 2px solid var(--t-texto-fraco); border-bottom: 0; background: none; }
.t-op-previa.previa-mostrador i:not(:first-child) { display: none; }
/* [/widgets: estilos e biblioteca 19/10] */

/* ==== design fiel às propostas 19/10 ===========================================================================
   QUEIXA DO DONO (19/10, tarde): «onde estão os novos modelos que propuseste?». Os tokens e a estrutura das páginas não
   chegavam: o Cockpit, o menu, a página do local e o telemóvel continuavam com a cara antiga. Este bloco põe a Cadeia viva
   (4.ª proposta) e a Industrial (3.ª) como as propostas as desenharam, NAS PEÇAS (widgets do cockpit, EstacoesGeral,
   CadeiaEmFio, menu, barra de cima) e só com tokens.

   TUDO AQUI ESTÁ PRESO A data-design: a versão «actual» não muda um píxel — a barra de baixo do telemóvel existe no HTML
   de todas mas só as versões novas a mostram. Prova: o retrato da actual antes/depois (docs/tema.md, «design fiel»).
   20/10 (dono): o «Agora» saiu de todas as versões; a cadeia à vista na lista dos locais deixou de depender da versão — é
   a opção «Saúde» do widget dos locais que a escolhe (por omissão, as bolinhas). */

/* -- 0. As peças novas, escondidas na actual. -- */
.barra-baixo { display: none; }

/* -- 1. O MENU LATERAL ------------------------------------------------------------------------------------------- */
/* Cadeia viva: os grupos como rótulos em letra fixa (EMISSÃO, AGIR…), os ícones a traço na cor do texto (sem a caixa
   tingida de cada secção), o escolhido com o fundo azul da moldura. */
:root[data-design="cadeia-viva"] .sidebar { padding-inline: 12px; }
:root[data-design="cadeia-viva"] .nav-menu { gap: 2px; }
:root[data-design="cadeia-viva"] .nav-menu a { font-weight: 500; font-size: .875rem; padding: 7px 12px; gap: 11px; border-radius: 7px; }
:root[data-design="cadeia-viva"] .nav-menu a i.nav-ic { width: 20px; height: 20px; padding: 0; background: transparent; color: currentColor; transform: none; }
:root[data-design="cadeia-viva"] .nav-menu a:hover .nav-ic,
:root[data-design="cadeia-viva"] .nav-menu a.active .nav-ic { background: transparent; color: currentColor; transform: none; }
:root[data-design="cadeia-viva"] .nav-menu a.active { box-shadow: none; }
:root[data-design="cadeia-viva"] .nav-acordeao-cab {
    font-family: var(--mono); font-size: .75rem; font-weight: 600; letter-spacing: .12em; padding: 14px 12px 6px; color: var(--t-moldura-fraco);
}
:root[data-design="cadeia-viva"] .nav-acordeao-itens { margin-left: 0; padding-left: 0; border-left: 0; }

/* Industrial: no ecrã largo o menu é a BARRA DE CIMA (as propostas): o logótipo, as entradas em maiúsculas condensadas e
   o grupo aberto a seguir ao seu nome, numa faixa escura. Rola com a página; a barra da página fica presa por baixo. No
   telemóvel continua a gaveta de sempre. */
@media (min-width: 1025px) {
    :root[data-design="industrial"] .shell { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto 1fr; }
    :root[data-design="industrial"] .shell > .sidebar {
        position: relative; height: auto; overflow: visible; flex-direction: row; flex-wrap: wrap; align-items: stretch; gap: 0 18px;
        padding: 0 16px; border-right: 0; border-bottom: 1px solid var(--t-moldura-linha);
    }
    :root[data-design="industrial"] .sidebar .brand { padding: 8px 0; min-height: 52px; }
    :root[data-design="industrial"] .sidebar .brand-logo { height: 30px; width: auto; max-width: none; }
    :root[data-design="industrial"] .sidebar .nav-menu { display: flex; flex-wrap: wrap; align-items: stretch; gap: 0; margin: 0; flex: 1 1 auto; min-width: 0; }
    :root[data-design="industrial"] .sidebar .nav-menu a {
        min-height: 52px; padding: 0 12px; border: 0; border-bottom: 2px solid transparent; border-radius: 0; background: transparent;
        font-size: .95rem; letter-spacing: .06em; box-shadow: none;
    }
    :root[data-design="industrial"] .sidebar .nav-menu a i.nav-ic { display: none; }
    :root[data-design="industrial"] .sidebar .nav-menu a:hover { background: var(--t-moldura-activo); }
    :root[data-design="industrial"] .sidebar .nav-menu a.active { color: var(--t-moldura-marca); border-bottom-color: var(--t-moldura-marca); background: transparent; box-shadow: none; }
    :root[data-design="industrial"] .sidebar .nav-acordeao { display: flex; align-items: stretch; }
    :root[data-design="industrial"] .sidebar .nav-acordeao-cab {
        min-height: 52px; padding: 0 10px 0 14px; border-radius: 0; font-family: var(--t-letra-titulos); font-size: .95rem; font-weight: 600;
        letter-spacing: .06em; color: var(--t-moldura-fraco);
    }
    :root[data-design="industrial"] .sidebar .nav-acordeao[open] > .nav-acordeao-cab { color: var(--t-moldura-texto); background: var(--t-moldura-activo); }
    :root[data-design="industrial"] .sidebar .nav-acordeao-itens {
        display: flex; flex-wrap: wrap; gap: 0; margin: 0; padding: 0 6px 0 0; border-left: 0; background: var(--t-moldura-activo);
    }
    :root[data-design="industrial"] .sidebar .nav-acordeao-itens a { font-size: .88rem; color: var(--t-moldura-texto); }
    :root[data-design="industrial"] .sidebar .versao-app { display: none; }
}

/* -- 2. A BARRA DE CIMA DA PÁGINA -------------------------------------------------------------------------------- */
:root[data-design="cadeia-viva"] .topbar { border-bottom-color: var(--line); }
:root[data-design="cadeia-viva"] :is(.icon-btn, .topbar-user, .topbar-search, .chip) { border-color: var(--line2); border-radius: 7px; }
:root[data-design="cadeia-viva"] .topbar-search { border-radius: 8px; background: var(--bg); }
:root[data-design="cadeia-viva"] .chip.clock { font-family: var(--mono); font-size: 1rem; font-weight: 600; border: 0; background: transparent; }
:root[data-design="cadeia-viva"] .topbar-user { border-radius: 999px; }
/* Industrial: a barra da página é a segunda faixa (a dos números e do nome do local), e o relógio é o âmbar grande. */
:root[data-design="industrial"] .topbar { background: var(--panel); border-bottom-color: var(--line); }
:root[data-design="industrial"] .chip.clock { font-family: var(--mono); font-size: 1.3rem; font-weight: 700; color: var(--t-moldura-marca);
                                              border: 0; background: transparent; padding-inline: 6px; }
:root[data-design="industrial"][data-theme="light"] .chip.clock { color: var(--amber); }

/* -- 3. O COCKPIT ------------------------------------------------------------------------------------------------ */
/* 3.2 Os números. Cadeia viva: cartões lisos, rótulo por cima, o número grande em letra fixa, a nota por baixo. */
:root[data-design="cadeia-viva"] .t-indicadores.compactos .t-indicador { padding: 14px 16px; gap: 6px; box-shadow: var(--shadow); }
:root[data-design="cadeia-viva"] .t-indicadores.compactos .t-indicador-icone { display: none; }
:root[data-design="cadeia-viva"] .t-indicadores.compactos .t-indicador-texto small { order: 1; font-size: .78rem; font-weight: 500; letter-spacing: 0; text-transform: none; color: var(--t-texto-fraco); }
:root[data-design="cadeia-viva"] .t-indicadores.compactos .t-indicador-texto b { order: 2; font-family: var(--mono); font-size: 1.75rem; font-weight: 600; letter-spacing: -.02em; }
:root[data-design="cadeia-viva"] .t-indicadores.compactos .t-indicador-texto span { order: 3; font-size: .78rem; }
:root[data-design="cadeia-viva"] .t-indicadores.compactos .t-indicador.bom .t-indicador-texto b { color: var(--t-texto); }
:root[data-design="cadeia-viva"] .t-indicadores.compactos .t-indicador:is(.aviso, .mau) .t-indicador-texto b { color: var(--t-cor-i); }
:root[data-design="cadeia-viva"] .t-indicador-barra i { height: 4px; }
/* Industrial: uma faixa de células separadas por traços, rótulo condensado em maiúsculas e o número em letra fixa. */
:root[data-design="industrial"] .t-indicadores.compactos {
    gap: 0; background: var(--panel); border: 1px solid var(--line); border-radius: var(--t-raio);
}
:root[data-design="industrial"] .t-indicadores.compactos .t-indicador {
    border: 0; border-right: 1px solid var(--line); border-radius: 0; background: transparent; box-shadow: none; padding: 10px 14px; gap: 6px;
}
:root[data-design="industrial"] .t-indicadores.compactos .t-indicador:last-child { border-right: 0; }
:root[data-design="industrial"] .t-indicadores.compactos .t-indicador::before { display: none; }
:root[data-design="industrial"] .t-indicadores.compactos .t-indicador-icone { display: none; }
:root[data-design="industrial"] .t-indicadores.compactos .t-indicador-texto small {
    order: 1; font-family: var(--t-letra-titulos); font-size: .78rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--t-texto-fraco);
}
:root[data-design="industrial"] .t-indicadores.compactos .t-indicador-texto b { order: 2; font-family: var(--mono); font-size: 1.65rem; font-weight: 700; }
:root[data-design="industrial"] .t-indicadores.compactos .t-indicador:is(.aviso, .mau, .bom) .t-indicador-texto b { color: var(--t-cor-i); }
:root[data-design="industrial"] .t-indicadores.compactos .t-indicador-texto span { order: 3; font-family: var(--mono); font-size: .75rem; }
:root[data-design="industrial"] .t-indicador-barra i { height: 3px; border-radius: 0; }
:root[data-design="industrial"] .t-indicador-barra u { border-radius: 0; }

/* 3.3 A CADEIA DE CADA LOCAL (opção «Saúde: cadeia com valores» do widget dos locais, 20/10 — a omissão são as bolinhas):
   a cadeia elo a elo, com o nome e o número. A tabela ganha «com-cadeia» só com a opção, por isso sem ela nada aqui
   pega. Na actual e na Cadeia viva, segmentos ligados por um traço; na Industrial, a «matriz da cadeia». */
.t-estacoes.com-cadeia .t-saude { display: flex; width: 0; min-width: 100%; }   /* não alarga a coluna: os nomes encolhem com reticências */
.t-estacoes.com-cadeia .t-est-saude { width: 40%; min-width: 260px; }
.t-estacoes.com-cadeia .t-est-id { min-width: 11rem; }
.t-estacoes.com-cadeia .t-est-nome b { white-space: nowrap; }
.t-elos { display: flex; align-items: stretch; flex: 1 1 auto; min-width: 0; }
.t-elo { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; justify-content: center; gap: 1px; padding: 5px 6px;
         font-size: .75rem; line-height: 1.2; color: var(--t-texto); background: var(--t-fundo-interior); }
.t-elo b, .t-elo span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.t-elo b { font-weight: 600; font-size: .75rem; }
.t-elo span { font-family: var(--mono); font-size: .75rem; }
.t-elo span:empty { display: none; }
/* Actual e Cadeia viva: segmentos de fundo claro do tom, ligados por um traço; o elo caído cheio a vermelho. */
:root:not([data-design="industrial"]) .t-elo { border-radius: 5px; }
:root:not([data-design="industrial"]) .t-elo + .t-elo { margin-left: 8px; position: relative; }
:root:not([data-design="industrial"]) .t-elo + .t-elo::before { content: ""; position: absolute; left: -8px; top: 50%; width: 8px; height: 2px; background: var(--line2); }
:root:not([data-design="industrial"]) .t-elo.bom { background: color-mix(in srgb, var(--green) 13%, var(--panel)); }
:root:not([data-design="industrial"]) .t-elo.aviso { background: color-mix(in srgb, var(--amber) 15%, var(--panel)); }
:root:not([data-design="industrial"]) .t-elo.mau { background: var(--red); color: var(--panel); }
:root:not([data-design="industrial"]) .t-elo:not(.bom, .aviso, .mau) { color: var(--t-texto-fraco); }
/* Industrial: as células da matriz — quadradas, coladas, o texto ao centro. */
:root[data-design="industrial"] .t-elos { gap: 3px; }
:root[data-design="industrial"] .t-elo { border-radius: 2px; align-items: center; text-align: center; }
:root[data-design="industrial"] .t-elo b { font-family: var(--t-letra-titulos); letter-spacing: .06em; text-transform: uppercase; font-size: .75rem; }
:root[data-design="industrial"] .t-elo.bom { background: color-mix(in srgb, var(--green) 20%, var(--panel)); color: var(--green); }
:root[data-design="industrial"] .t-elo.aviso { background: color-mix(in srgb, var(--amber) 22%, var(--panel)); color: var(--amber); }
:root[data-design="industrial"] .t-elo.mau { background: color-mix(in srgb, var(--red) 28%, var(--panel)); color: var(--red); }
:root[data-design="industrial"] .t-elo:not(.bom, .aviso, .mau) { background: var(--panel2); color: var(--t-texto-fraco); }
:root[data-theme="light"][data-design="industrial"] .t-elo:is(.bom, .aviso, .mau) { color: var(--text); }
/* No telemóvel e no tablet (as fichas) a cadeia é uma barra fina por elo, sem texto (as propostas), a toda a largura. */
@media (max-width: 1024px) {
    .t-estacoes.com-cadeia .t-est-saude { width: auto; min-width: 0; }
    .t-estacoes.com-cadeia.tab-cartoes tbody tr.t-est-linha > td.t-est-saude { grid-column: 1 / -1; }
    .t-estacoes.com-cadeia .t-elo { height: 8px; padding: 0; }
    .t-estacoes.com-cadeia .t-elo :is(b, span) { display: none; }
    .t-estacoes.com-cadeia .t-elo + .t-elo { margin-left: 3px; }
    .t-estacoes.com-cadeia .t-elo + .t-elo::before { display: none; }
    .t-estacoes.com-cadeia .t-elo.bom { background: var(--green); }
    .t-estacoes.com-cadeia .t-elo.aviso { background: var(--amber); }
    .t-estacoes.com-cadeia .t-elo.mau { background: var(--red); }
}

/* 3.4 Os painéis do cockpit com o cabeçalho das propostas (nas páginas já o têm, pelo bloco da estrutura). */
:root[data-design="cadeia-viva"] .main[data-ecra="cockpit"] .t-painel > .t-painel-cab:not(:last-child) {
    margin: calc(-1 * var(--t-folga)) calc(-1 * var(--t-folga)) 0; padding: 14px var(--t-folga); border-bottom: 1px solid var(--t-borda);
}
:root[data-design="cadeia-viva"] .main[data-ecra="cockpit"] .t-painel-titulo h3 { font-size: .95rem; }
:root[data-design="industrial"] .t-painel > .t-painel-cab:not(:last-child) {
    margin: calc(-1 * var(--t-folga)) calc(-1 * var(--t-folga)) 0; padding: 8px 12px; background: var(--panel2); border-bottom: 1px solid var(--line);
}
:root[data-design="industrial"] .t-painel-titulo h3 { font-size: .9rem; letter-spacing: .1em; }
:root[data-design="industrial"] :is(.t-tabela, .grid-table) th {
    font-family: var(--t-letra-titulos); font-size: .78rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--t-texto-fraco);
}
:root[data-design="industrial"] :is(.t-tabela, .grid-table) :is(td.num, td.hora, td.n) { font-family: var(--mono); }

/* -- 4. A PÁGINA DO LOCAL ---------------------------------------------------------------------------------------- */
/* Cadeia viva: cada elo um cartão numerado (01, 02…) com o ponto do estado ao canto, o nome, o número em letra fixa. */
:root[data-design="cadeia-viva"] .t-fio:not(.compacto) { counter-reset: elo; }
:root[data-design="cadeia-viva"] .t-fio:not(.compacto) .t-fio-no { counter-increment: elo; position: relative; padding: 12px; gap: 4px; border-radius: 9px; }
:root[data-design="cadeia-viva"] .t-fio:not(.compacto) .t-fio-no::before {
    content: counter(elo, decimal-leading-zero); font-family: var(--mono); font-size: .75rem; color: var(--t-texto-fraco);
}
:root[data-design="cadeia-viva"] .t-fio:not(.compacto) .t-fio-icone { display: none; }
:root[data-design="cadeia-viva"] .t-fio:not(.compacto) .t-fio-nome { font-size: .875rem; font-weight: 700; }
:root[data-design="cadeia-viva"] .t-fio:not(.compacto) .t-fio-estado {
    position: absolute; top: 12px; right: 12px; width: 10px; height: 10px; padding: 0; border-radius: 50%;
    overflow: hidden; white-space: nowrap; text-indent: 200%; font-size: .75rem; background: var(--t-cor-f, var(--green)); border: 0;
    color: var(--t-fundo-cartao);   /* o texto fica escondido no ponto, mas lê-se se aparecer (e o validador mede-o) */
}
:root[data-design="cadeia-viva"] .t-fio:not(.compacto) .t-fio-valor { font-family: var(--mono); font-size: 1rem; font-weight: 500; }
:root[data-design="cadeia-viva"] .t-fio:not(.compacto) .t-fio-valor small { font-family: var(--t-letra); font-size: .75rem; font-weight: 400; letter-spacing: 0; text-transform: none; }
:root[data-design="cadeia-viva"] .t-fio-seta { color: var(--t-texto-fraco); }
/* A cadeia do local (EstacaoInformacao, a que se vê no separador Cadeia sem desenho e na janela do cockpit): os elos como
   nas propostas — sem o desenho do aparelho (que fica na ficha), numerados, o estado num ponto ao canto, o número grande. */
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .chain { counter-reset: elo; gap: 0; padding-top: 6px; }
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .chain-node .device-img { display: none; }
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .chain-node::before { display: none; }
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .chain-node .mini { border-top: 0; padding-top: 0; margin-top: 2px; }
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .chain-node .mini small { font-size: .75rem; color: var(--t-texto-fraco); font-weight: 400; }
:root:is([data-design="cadeia-viva"], [data-design="industrial"]) .chain-node .mini b { font-size: 1rem; font-weight: 500; }
:root[data-design="cadeia-viva"] .chain-node {
    counter-increment: elo; flex: 1 1 0; min-width: 118px; max-width: none; padding: 12px; border-radius: 9px;
    background: var(--panel); border: 1px solid var(--line); box-shadow: none;
}
:root[data-design="cadeia-viva"] .chain-node.bad { border-color: var(--red); background: color-mix(in srgb, var(--red) 6%, var(--panel)); }
:root[data-design="cadeia-viva"] .chain-node.warn { border-color: var(--amber); background: color-mix(in srgb, var(--amber) 7%, var(--panel)); }
:root[data-design="cadeia-viva"] .chain-node .node-head { flex-direction: row; }
:root[data-design="cadeia-viva"] .chain-node .kind::before { content: counter(elo, decimal-leading-zero) " · "; }
:root[data-design="cadeia-viva"] .chain-node .kind { font-family: var(--mono); font-size: .75rem; font-weight: 500; letter-spacing: .04em; color: var(--t-texto-fraco); }
:root[data-design="cadeia-viva"] .chain-node .node-state {
    width: 10px; height: 10px; padding: 0; border-radius: 50%; overflow: hidden; white-space: nowrap; text-indent: 200%; font-size: .75rem;
    background: var(--green); color: var(--panel);
}
:root[data-design="cadeia-viva"] .chain-node .node-state.warn { background: var(--amber); }
:root[data-design="cadeia-viva"] .chain-node .node-state.bad { background: var(--red); }
:root[data-design="cadeia-viva"] .chain-node .node-state.unknown { background: var(--line2); }
:root[data-design="cadeia-viva"] .chain-node .name { font-size: .875rem; font-weight: 700; margin: 4px 0 2px; }
:root[data-design="cadeia-viva"] .chain-link { flex: 0 0 22px; color: var(--t-texto-fraco); }
:root[data-design="cadeia-viva"] .chain-link span { background: var(--bg); }
:root[data-design="cadeia-viva"] .chain-link.bad { color: var(--red); }
:root[data-design="industrial"] .chain-node {
    counter-increment: elo; flex: 1 1 0; min-width: 112px; max-width: none; padding: 10px 8px; border-radius: 3px; text-align: center;
    background: var(--panel2); border: 2px solid var(--green); box-shadow: none;
}
:root[data-design="industrial"] .chain-node.warn { border-color: var(--amber); }
:root[data-design="industrial"] .chain-node.bad { border-color: var(--red); }
:root[data-design="industrial"] .chain-node.unknown { border-color: var(--line2); }
:root[data-design="industrial"] .chain-node .node-head { justify-content: center; }
:root[data-design="industrial"] .chain-node .kind { font-family: var(--mono); font-size: .75rem; letter-spacing: .06em; }
:root[data-design="industrial"] .chain-node .node-state { display: none; }
:root[data-design="industrial"] .chain-node .name { font-family: var(--t-letra-titulos); font-size: 1rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; margin: 2px 0; }
:root[data-design="industrial"] .chain-node .mini { justify-content: center; }
:root[data-design="industrial"] .chain-node .mini b { color: var(--green); }
:root[data-design="industrial"] .chain-node.warn .mini b { color: var(--amber); }
:root[data-design="industrial"] .chain-node.bad .mini b { color: var(--red); }
:root[data-design="industrial"] .chain-link { flex: 0 0 22px; color: var(--green); }
:root[data-design="industrial"] .chain-link i { height: 4px; opacity: 1; width: 100%; }
:root[data-design="industrial"] .chain-link span { display: none; }
:root[data-design="industrial"] .chain-link.bad span { display: inline; background: var(--bg); color: var(--red); }
/* Industrial: os blocos do sinóptico — moldura de 2 px na cor do estado, nome condensado, número em letra fixa. */
:root[data-design="industrial"] .t-fio-no { border-width: 2px; border-radius: 3px; text-align: center; align-items: center; background: var(--panel2); }
:root[data-design="industrial"] .t-fio-no.bom { border-color: var(--green); }
:root[data-design="industrial"] .t-fio-nome { font-family: var(--t-letra-titulos); font-size: .95rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; }
:root[data-design="industrial"] .t-fio-valor { font-family: var(--mono); }
:root[data-design="industrial"] .t-fio:not(.compacto) .t-fio-icone { display: none; }
:root[data-design="industrial"] .t-fio-seta { color: var(--green); font-weight: 700; }
/* Industrial: o cabeçalho do local é a faixa do painel (não a moldura escura) e os separadores são caixas, o escolhido
   cheio a âmbar. */
:root[data-design="industrial"] .main[data-ecra="pagina"] > .est-pagina > .est-cab :is(h1, h2, .t-titulo) {
    font-family: var(--t-letra-titulos); text-transform: uppercase; letter-spacing: .06em;
}
:root[data-design="industrial"] .main[data-ecra="pagina"] > .est-pagina > .sep-raiz > .sep-barra { gap: 4px; padding-block: 10px; }
:root[data-design="industrial"] .main[data-ecra="pagina"] .sep {
    border: 1px solid var(--t-borda); border-radius: 3px; background: var(--t-fundo-interior); min-height: 40px; margin: 0;
    font-family: var(--t-letra-titulos); text-transform: uppercase; letter-spacing: .08em;
}
:root[data-design="industrial"] .main[data-ecra="pagina"] .sep.activo,
:root[data-design="industrial"] .main[data-ecra="pagina"] > .est-pagina > .sep-raiz > .sep-barra .sep.activo {
    background: var(--t-accao); border-color: var(--t-accao); color: var(--t-accao-texto);
}

/* -- 5. O TELEMÓVEL E O TABLET --------------------------------------------------------------------------------- */
@media (max-width: 1024px) {
    /* A barra da página no telemóvel e no tablet: o título e a pílula numa linha, os botões numa fila só que rola de lado (com o sinal
       nas pontas) — eram três linhas de ícones (~150 px) por cima de tudo. Na Cadeia viva é a moldura escura, como nas
       propostas (a barra do menu, esta e o «Agora» são um cabeçalho só). */
    :root:is([data-design="cadeia-viva"], [data-design="industrial"]) .topbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
    :root:is([data-design="cadeia-viva"], [data-design="industrial"]) .topbar .topbar-left { flex: 1 1 0; min-width: 0; }
    :root:is([data-design="cadeia-viva"], [data-design="industrial"]) .topbar .menu-alternar { display: none; }
    :root:is([data-design="cadeia-viva"], [data-design="industrial"]) .topbar .topbar-actions {
        display: flex; flex: 1 1 100%; order: 3; flex-wrap: nowrap; justify-content: flex-start; gap: 6px; overflow-x: auto; overflow-y: hidden;
        max-width: 100%; padding-bottom: 2px; overscroll-behavior-x: contain; scrollbar-width: none; --t-rola: 1;
        -webkit-mask-image: linear-gradient(to right, black calc(100% - 28px), transparent); mask-image: linear-gradient(to right, black calc(100% - 28px), transparent);
    }
    :root:is([data-design="cadeia-viva"], [data-design="industrial"]) .topbar .topbar-actions > * { flex: none; }
    :root:is([data-design="cadeia-viva"], [data-design="industrial"]) .topbar .topbar-user { display: flex; gap: 6px; padding: 0; border: 0; background: transparent; }
    :root:is([data-design="cadeia-viva"], [data-design="industrial"]) .topbar .chip.live.sistema { order: 2; }
    :root[data-design="cadeia-viva"] .topbar {
        background: var(--t-moldura); border-bottom-color: var(--t-moldura); color: var(--t-moldura-texto);
        --text: var(--t-moldura-texto); --muted: var(--t-moldura-fraco); --line: var(--t-moldura-linha); --line2: var(--t-moldura-linha);
        --panel: var(--t-moldura-activo); --panel2: var(--t-moldura-activo);
        --t-texto: var(--t-moldura-texto); --t-texto-fraco: var(--t-moldura-fraco); --t-borda: var(--t-moldura-linha);
    }
    :root[data-design="cadeia-viva"] .topbar .topbar-title { color: var(--t-moldura-texto); }
    :root[data-design="cadeia-viva"] .topbar :is(.icon-btn, .t-seleccao, .tu-logout button) { background: var(--t-moldura-activo); border-color: var(--t-moldura-linha); color: var(--t-moldura-texto); }
    :root[data-design="cadeia-viva"] .topbar .trilho a, :root[data-design="cadeia-viva"] .topbar .trilho { color: var(--t-moldura-fraco); }

}
/* -- 5. O TELEMÓVEL ---------------------------------------------------------------------------------------------- */
@media (max-width: 760px) {
    /* A barra de baixo das propostas: Cockpit · Locais · Alertas · Menu, na moldura, ao alcance do polegar. */
    :root:is([data-design="cadeia-viva"], [data-design="industrial"]) .barra-baixo {
        display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 42; justify-content: space-around; gap: 4px;
        padding: 4px 8px calc(6px + env(safe-area-inset-bottom)); background: var(--t-moldura); border-top: 1px solid var(--t-moldura-linha);
    }
    .barra-baixo :is(a, button) {
        position: relative; flex: 1 1 0; min-width: 44px; min-height: 52px; display: flex; flex-direction: column; align-items: center;
        justify-content: center; gap: 3px; padding: 0; border: 0; background: transparent; cursor: pointer; text-decoration: none;
        color: var(--t-moldura-fraco); font: 600 .75rem/1.1 var(--t-letra, inherit);
    }
    .barra-baixo :is(a, button).activo { color: var(--t-moldura-texto); }
    .barra-baixo .count { position: absolute; top: 4px; left: calc(50% + 6px); min-width: 18px; padding: 1px 5px; border-radius: 999px;
                          background: var(--red); color: var(--panel); font-size: .75rem; line-height: 1.2; text-align: center; }
    :root[data-design="industrial"] .barra-baixo :is(a, button) { font-family: var(--t-letra-titulos); letter-spacing: .08em; text-transform: uppercase; }
    :root[data-design="industrial"] .barra-baixo :is(a, button).activo { color: var(--t-moldura-marca); }
    :root:is([data-design="cadeia-viva"], [data-design="industrial"]) .main { padding-bottom: calc(68px + env(safe-area-inset-bottom)); }

    /* Industrial: três células por linha. */
    :root[data-design="industrial"] .t-indicadores.compactos { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    :root[data-design="industrial"] .t-indicadores.compactos .t-indicador { padding: 8px 10px; }
    :root[data-design="industrial"] .t-indicadores.compactos .t-indicador-texto b { font-size: 1.25rem; }
    :root[data-design="industrial"] .t-indicadores.compactos .t-indicador { border-bottom: 1px solid var(--line); }
}
/* [/design fiel às propostas 19/10] */

/* ==== telemóvel em todas as larguras 19/10 =====================================================================
   «500 % mobile» (dono, 19/10): o validador passa agora TODAS as páginas a 360, 390, 414 e 768 px, claro e escuro, nas
   três versões do design e em português e alemão (MovelEmTodas.cs) — e o que falha é FALHA, não aviso. O que aqui está
   são as correcções que essa passagem pediu e que valem para todas as versões. Só no telemóvel e no tablet (até 1024 px,
   ou com o dedo): o desktop não muda. */
@media (max-width: 1024px), (pointer: coarse) {
    /* Uma caixa de marcar dentro da etiqueta: a etiqueta é o alvo, com 44 px (eram 28–32). :where() — uma etiqueta que
       a página já arruma (flex, block…) fica como está, só ganha a altura. */
    :where(label:has(> input:is([type="checkbox"], [type="radio"]))) { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; }
    label:has(> input:is([type="checkbox"], [type="radio"])) { min-height: 44px; }
    /* As caixas soltas numa tabela (perfis): a etiqueta à volta delas é o alvo do dedo. */
    .t-marca { display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; cursor: pointer; }
    /* «1 h» tinha 43 px de largura. */
    .t-periodo a { min-width: 44px; justify-content: center; box-sizing: border-box; }
    /* O nome de uma peça da rede (liga ao local) e a caixa de ferramentas do editor (o cockpit também se edita no tablet). */
    /* 52 e não 44: a tela da rede encolhe para caber (zoom), e o alvo tem de ter 44 px DEPOIS de encolher. */
    a.t-peca-titulo { display: inline-flex; align-items: center; min-height: 52px; }
    .t-caixa-cab, .t-caixa-item { min-height: 44px; }
    .t-mapa-item { min-width: 44px; }
    /* ▲/▼ de ordenar (tinham 24 px de largura na folha do minimalista): lado a lado, 44 px cada. */
    .order-arrows { grid-auto-flow: column; }
    .order-arrows button { min-width: 44px; min-height: 44px; }
}
@media (max-width: 1024px) {
    /* UMA TABELA QUE ROLA DIZ QUE ROLA: sombras nas pontas enquanto há mais para ver (a técnica das sombras «local»/«scroll»:
       a cobertura rola com o conteúdo e tapa a sombra quando se chega à ponta). O validador confere o --t-rola. */
    :is(.tabela-wrap, .t-peca-corpo, .panel, .t-rola):has(table) {
        --t-rola: 1;
        background:
            linear-gradient(to right, var(--t-fundo-cartao) 30%, transparent) left / 32px 100% no-repeat local,
            linear-gradient(to left, var(--t-fundo-cartao) 30%, transparent) right / 32px 100% no-repeat local,
            radial-gradient(farthest-side at 0 50%, color-mix(in srgb, var(--text) 24%, transparent), transparent) left / 12px 100% no-repeat scroll,
            radial-gradient(farthest-side at 100% 50%, color-mix(in srgb, var(--text) 24%, transparent), transparent) right / 12px 100% no-repeat scroll,
            var(--t-fundo-cartao);
    }
}
@media (max-width: 760px) {
    /* Uma pastilha de estado comprida em alemão («Auf Sendung · mit Problem») parte em duas linhas em vez de sair da ficha. */
    .t-estacoes .t-pastilha, .t-infra-grupo .t-pastilha { white-space: normal; overflow-wrap: anywhere; max-width: 100%; }
    /* A legenda do mapa parte em linhas (em alemão «Ohne FMDX» saía do ecrã a 360 px). */
    .t-mapa + .t-legenda, .t-legenda { flex-wrap: wrap; white-space: normal; }
}
@media (max-width: 1024px) {
    /* O texto fraco que era fraco demais no escuro (2,4–2,9:1). */
    .param-id small.dim { color: var(--muted); }
}
/* [/telemóvel em todas as larguras 19/10] */

/* [tendências livres 25/10] As Tendências com separadores, séries e tabela escolhidos por quem monta (TendenciasDaPeca,
   GraficoDasTendencias, EditorDasTendencias). Só peças do tema e tokens: nenhuma cor escrita aqui. */
.t-tend { display: grid; gap: 8px; min-width: 0; }
.t-tend-separadores { flex-wrap: wrap; }
/* O segundo eixo (unidades diferentes no mesmo gráfico): a coluna dos tiques à direita, com o texto encostado à esquerda. */
.t-grafico.com-eixo-dir { grid-template-columns: auto minmax(0, 1fr) auto; }
.t-grafico.com-eixo-dir .t-grafico-x { grid-column: 2; }
.t-tend-y2 span { right: auto; left: 0; }
/* Os tiques com sinal e casa decimal («−48,7», «1 900») cortavam-se na coluna estreita de sempre (2,2em). */
.t-tend-grafico .t-grafico-y { min-width: 3.6em; }
.t-tend-grafico .t-grafico-y span { white-space: nowrap; }
.t-tend-eixo { color: var(--t-texto-fraco); }
.t-tend-cor { display: inline-block; flex: none; width: 10px; height: 10px; border-radius: 3px; background: var(--t-cor-s, var(--t-neutro)); margin-right: 6px; vertical-align: baseline; }
.t-tend-tabela-caixa { max-height: 16rem; overflow: auto; border: 1px solid var(--t-borda); border-radius: var(--t-raio-interior); }
.t-tend-tabela { width: 100%; border-collapse: collapse; font-size: var(--t-pequeno); font-variant-numeric: tabular-nums; }
.t-tend-tabela th, .t-tend-tabela td { padding: 4px 8px; text-align: right; white-space: nowrap; border-bottom: 1px solid var(--t-borda); }
.t-tend-tabela th:first-child { text-align: left; }
.t-tend-tabela thead th { position: sticky; top: 0; background: var(--t-fundo-interior); color: var(--t-texto-fraco); font-weight: 600; z-index: 1; }
.t-tend-tabela tfoot th, .t-tend-tabela tfoot td { background: var(--t-fundo-interior); font-weight: 600; }
.t-tend-tabela tbody th { font-weight: 400; color: var(--t-texto-fraco); }

/* O editor: a lista dos separadores à esquerda, o separador escolhido à direita; numa coluna abaixo de 760 px. */
.t-tend-editor { min-width: 0; }
.t-tend-ed-grelha { display: grid; grid-template-columns: minmax(10rem, 15rem) minmax(0, 1fr); gap: var(--t-espaco); align-items: start; }
.t-tend-ed-seps { display: grid; gap: 6px; min-width: 0; }
.t-tend-ed-sep { display: flex; align-items: center; gap: 4px; min-width: 0; border: 1px solid var(--t-borda); border-radius: var(--t-raio-interior);
    background: var(--t-fundo-cartao); padding: 2px 4px; }
.t-tend-ed-sep.activo { border-color: var(--t-info); box-shadow: inset 3px 0 0 var(--t-info); }
.t-tend-ed-nome { flex: 1 1 auto; min-width: 0; display: grid; text-align: left; font: inherit; color: inherit; background: none; border: 0;
    padding: 6px; cursor: pointer; min-height: 44px; }
.t-tend-ed-nome b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.t-tend-ed-nome small { color: var(--t-texto-fraco); }
.t-tend-ed-accoes { display: inline-flex; flex-wrap: wrap; gap: 2px; align-items: center; }
.t-tend-ed-corpo { display: grid; gap: 10px; min-width: 0; }
.t-tend-ed-titulo { margin: 6px 0 0; font-size: var(--t-titulo); }
.t-tend-ed-serie, .t-tend-ed-limite { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px; min-width: 0; padding: 8px;
    border: 1px solid var(--t-borda); border-radius: var(--t-raio-interior); background: var(--t-fundo-interior); }
.t-tend-ed-serie { border-left: 4px solid var(--t-cor-s, var(--t-borda)); }
.t-tend-ed-serie > .t-tend-cor { display: none; }
.t-tend-ed-serie label, .t-tend-ed-limite label { display: grid; gap: 2px; flex: 1 1 9rem; min-width: 0; }
.t-tend-ed-serie select, .t-tend-ed-serie input, .t-tend-ed-limite select, .t-tend-ed-limite input { width: 100%; min-width: 0; box-sizing: border-box; }
.t-tend-ed-serie .form-error { flex-basis: 100%; }
.t-tend-cores { display: inline-flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.t-tend-cor-btn { width: 28px; height: 28px; border-radius: 50%; border: 2px solid var(--t-borda); background: var(--t-cor-s, var(--t-fundo-cartao));
    cursor: pointer; padding: 0; font: inherit; font-size: var(--t-rotulo); color: var(--t-texto); }
.t-tend-cor-btn.activo { border-color: var(--t-texto); box-shadow: 0 0 0 2px var(--t-fundo-cartao) inset; }
.t-tend-ed-colunas { margin-top: 2px; }
@media (max-width: 760px) {
    .t-tend-ed-grelha { grid-template-columns: minmax(0, 1fr); }
    .t-tend-ed-serie label, .t-tend-ed-limite label { flex-basis: 100%; }
}
@media (pointer: coarse), (max-width: 760px) {
    .t-tend-cor-btn { width: 44px; height: 44px; }
}
/* [/tendências livres 25/10] */

/* ==== cadeia e centro 25/10 =============================================================================
   O separador «Cadeia» do local (EstacaoPainel → .sep-cadeia) e as LIGAÇÕES AO CENTRO (CentroNoDesenho, LegendaDoCentro,
   CentroSemDesenho, PecaDoCentro). Só tokens: vale nas três versões do design, no claro e no escuro.
   · o separador: os botões numa fila, a cadeia e o desenho numa tela pontilhada (a do editor das propostas);
   · as setas «centro»: CONTAS (pontos redondos), nunca um fio — o fio é o sinal da cadeia; a cor é o contacto
     (bom/aviso/mau), e sem tom é neutro: «sem dados» nunca é vermelho;
   · a casa (o centro) na cor da moldura, os agentes a tracejado (com o contacto no rebordo);
   · abaixo de 760 px o desenho é uma coluna: as contas e os nós acrescentados escondem-se e aparece a lista compacta. */
.sep-cadeia { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.sep-cadeia > * { flex: 1 1 100%; min-width: 0; }
.sep-cadeia > .t-cartao-accoes { flex: 0 0 auto; margin: 0; padding: 0; border: 0; }
.sep-cadeia > .t-cartao-accoes:has([data-desenho="desenhar"]) { order: -1; }
.sep-cadeia > .t-topo { margin: 0; }

/* A tela: a cadeia dos elos e o desenho assentam numa folha pontilhada, como no editor. */
.sep-cadeia :is(.station.embutida, .t-editor-tela, .t-centro-bloco) {
    background-color: var(--t-ed-tela, var(--bg));
    background-image: radial-gradient(var(--t-ed-ponto, var(--t-borda)) 1px, transparent 1px);
    background-size: 20px 20px;
    border: 1px solid var(--t-borda); border-radius: var(--t-raio);
}
.sep-cadeia .station.embutida { padding: 18px 18px 12px; }
.sep-cadeia .t-editor-tela { padding: 18px; box-sizing: border-box; }
.sep-cadeia .t-tela-area .t-editor-tela { border: 0; border-radius: 0; }
:root[data-design="industrial"] .sep-cadeia :is(.station.embutida, .t-editor-tela, .t-centro-bloco) {
    background-image: linear-gradient(var(--t-ed-ponto, var(--t-borda)) 1px, transparent 1px),
                      linear-gradient(90deg, var(--t-ed-ponto, var(--t-borda)) 1px, transparent 1px);
    background-size: 24px 24px;
}

/* Os elos sem desenho: mais presença, e a seta diz o que se sabe — fio inteiro entre elos bons, tracejado onde não se sabe,
   partido (vermelho) onde caiu. A Industrial pintava de verde a ligação entre dois «sem dados». */
.sep-cadeia .chain { gap: 0; padding: 6px 0 4px; }
.sep-cadeia .chain-node { min-height: 7.5rem; }
.sep-cadeia .chain-node .name { font-size: .95rem; }
.sep-cadeia .chain-link.unknown { color: var(--t-borda-forte); }
.sep-cadeia .chain-link.bad { color: var(--t-mau); }
:root[data-design="industrial"] .sep-cadeia .chain-link.unknown { color: var(--t-borda-forte); }
:root[data-design="industrial"] .sep-cadeia .chain-link.unknown i { height: 0; background: none; border-top: 3px dashed currentColor; }
:root[data-design="industrial"] .sep-cadeia .chain-node.unknown .mini b { color: var(--t-texto-fraco); }
.sep-cadeia .t-fio { gap: 10px 0; }
.sep-cadeia .t-fio-no { min-height: 6.5rem; }
.sep-cadeia .t-fio-seta.incerto { color: var(--t-borda-forte); }
:root[data-design="industrial"] .sep-cadeia .t-fio-seta.incerto { color: var(--t-borda-forte); }

/* As peças do desenho a ler: um pouco de relevo; o estado continua no rebordo de cima (o t-cartao pinta-o). */
.sep-cadeia .t-cadeia-grelha:not(.a-editar) .t-cadeia-peca { box-shadow: 0 1px 3px color-mix(in srgb, var(--t-texto) 12%, transparent); }
.sep-cadeia .t-cadeia-grelha .t-cadeia-peca .t-peca-titulo { font-size: .9rem; font-weight: 700; }

/* ---- As ligações ao centro ---- */
.t-seta.centro { stroke: var(--t-borda-forte); stroke-width: 3.5; stroke-dasharray: 0 8; stroke-linecap: round; }
.t-seta.centro.bom { stroke: var(--t-bom); }
.t-seta.centro.aviso { stroke: var(--t-aviso); }
.t-seta.centro.mau { stroke: var(--t-mau); stroke-width: 4.5; }
.t-seta.centro.pelo-agente { stroke-dasharray: 0 6; }

.t-centro-no { justify-content: center; }
.t-centro-cab { display: flex; align-items: center; gap: 8px; min-width: 0; }
.t-centro-icone { flex: none; display: inline-grid; place-items: center; width: 30px; height: 30px; border-radius: var(--t-raio-interior);
                  color: var(--t-info); background: color-mix(in srgb, currentColor 13%, transparent); }
.t-cadeia-peca.peca-centro-ricentra { background: var(--t-moldura); border-color: var(--t-moldura-linha); border-top-color: var(--t-moldura-marca);
                                      color: var(--t-moldura-texto); }
.t-cadeia-peca.peca-centro-ricentra .t-peca-titulo { color: var(--t-moldura-texto); font-size: .95rem; letter-spacing: .01em; }
.t-cadeia-peca.peca-centro-ricentra .t-cadeia-estado { color: var(--t-moldura-fraco); }
.t-cadeia-peca.peca-centro-ricentra .t-centro-icone { color: var(--t-moldura-marca); }
.t-cadeia-peca.peca-agente-do-local { border-style: dashed; border-top-style: solid; background: var(--t-fundo-interior); }
.t-cadeia-peca.peca-agente-do-local.mau { border-color: var(--t-mau); background: color-mix(in srgb, var(--t-mau) 7%, var(--t-fundo-cartao)); }
.t-cadeia-peca.peca-agente-do-local.aviso { border-color: var(--t-aviso); }
:root[data-design="industrial"] .t-cadeia-peca.peca-centro-ricentra .t-peca-titulo { font-family: var(--t-letra-titulos); text-transform: uppercase; letter-spacing: .06em; }

/* A barra por cima: o interruptor, a legenda e o que pede atenção. */
.t-centro-barra { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; margin: 0 0 12px; }
.t-centro-interruptor { display: inline-flex; align-items: center; gap: 8px; }
.t-centro-interruptor-marca { width: 28px; height: 16px; border-radius: 999px; background: var(--t-borda-forte); position: relative; flex: none; }
.t-centro-interruptor-marca::after { content: ""; position: absolute; top: 2px; left: 2px; width: 12px; height: 12px; border-radius: 50%;
                                     background: var(--t-fundo-cartao); transition: transform .15s; }
.t-centro-interruptor.activo .t-centro-interruptor-marca { background: var(--t-bom); }
.t-centro-interruptor.activo .t-centro-interruptor-marca::after { transform: translateX(12px); }
.t-centro-legenda { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px; margin: 0; padding: 0; list-style: none;
                    font-size: .8rem; color: var(--t-texto-fraco); }
.t-centro-legenda li { display: inline-flex; align-items: center; gap: 6px; }
.t-centro-traco { display: inline-block; width: 26px; height: 0; }
.t-centro-traco.sinal { border-top: 3px solid var(--t-texto-fraco); }
.t-centro-traco.contas { height: 4px; background: radial-gradient(circle, var(--t-texto-fraco) 1.75px, transparent 2px) 0 50% / 8px 4px repeat-x; }
.t-centro-resumo { font-size: .8rem; font-weight: 700; color: var(--t-mau); }
.t-centro-bloco { padding: 14px 18px 18px; }
.t-centro-bloco .t-editor-tela { background: none; border: 0; padding: 0; }
/* O estado das peças das ligações parte em duas linhas em vez de se cortar («sem resposta há 13 min»). */
.t-painel-grelha.t-centro-grelha { grid-auto-rows: minmax(5.25rem, auto); }
.t-centro-grelha .t-cadeia-estado span, .t-cadeia-peca.t-centro-no .t-cadeia-estado span,
.t-centro-grelha .t-peca-titulo, .t-cadeia-peca.t-centro-no .t-peca-titulo { white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: anywhere; }
.sep-cadeia .chain-node .mini b { overflow-wrap: anywhere; }
/* Sem desenho, as ligações são um EditorVisual sem tela (não há a vista que rola): a 768 px os 11 intervalos de 44 px da
   grelha da cadeia já não cabiam e o bloco esticava a página até aos 1046 px (26/10, varrimento --movel). Entre o telemóvel e
   o ecrã largo os intervalos estreitam (as contas descem na vertical até à casa, não precisam deles), e se ainda não couber
   o bloco rola em vez de alargar a página. */
.t-centro-sem-desenho { overflow-x: auto; }
@media (min-width: 761px) and (max-width: 1100px) {
    .t-painel-grelha.t-cadeia-grelha.t-centro-grelha { column-gap: 14px; }
}

/* A forma compacta: só no telemóvel (no ecrã largo o desenho diz o mesmo). */
.t-centro-lista { display: none; margin: 0; padding: 0; list-style: none; }
.t-centro-lista ul { margin: 0 0 0 12px; padding: 0 0 0 16px; list-style: none; border-left: 3px dotted var(--t-borda-forte); }
.t-centro-lista-casa { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-radius: var(--t-raio-interior);
                       background: var(--t-moldura); color: var(--t-moldura-texto); }
.t-centro-lista-casa .t-centro-icone { color: var(--t-moldura-marca); }
.t-centro-lista-grupo { margin-top: 10px; }
.t-centro-lista-linha { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 8px; min-height: 44px; }
.t-centro-lista-linha small { color: var(--t-texto-fraco); font-size: .8rem; flex-basis: 100%; padding-left: 18px; }
.t-centro-lista-linha[data-contacto="SemResposta"] > span, .t-centro-lista-grupo[data-contacto="SemResposta"] > .t-centro-lista-linha > b { color: var(--t-mau); }

@media (max-width: 760px) {
    .t-seta.centro { display: none; }
    .t-cadeia-grelha .t-centro-no { display: none; }
    .t-centro-sem-desenho { display: none; }
    .t-centro-lista { display: block; }
    .t-centro-legenda li:nth-child(-n+2) { display: none; }
    .t-centro-bloco { padding: 12px; }
    .sep-cadeia .chain-node, .sep-cadeia .t-fio-no { min-height: 0; }
}
/* [/cadeia e centro 25/10] */
=======
/* ==== formulário de equipamento por secções 25/10 ===========================================================================
   «O formulário de equipamento está péssimo» (o dono, 25/10). Peças genéricas, só com variáveis do tema (valem nas três
   versões do design, claro e escuro): passos de um assistente (t-passos), uma secção com título e frase (t-form-seccao),
   um campo com rótulo, marca de obrigatório e o erro ou a ajuda por baixo (t-campo, componente CampoComAjuda), o bloco
   do teste da ligação (t-teste) e a lista das medições com herança (t-medicoes, sobre o t-herdado). t-parte é um
   contentor neutro (display: contents) para as partes de um formulário que se mostram em secções diferentes. */
.t-parte { display: contents; }

.modal.form-modal.t-form-equip { max-width: 860px; height: min(88vh, 900px); }
.t-form-equip-titulo { display: grid; gap: 2px; min-width: 0; }
.t-form-equip-titulo h3 { margin: 0; overflow-wrap: anywhere; }
.t-form-equip-titulo small { color: var(--t-texto-fraco); font-size: .8rem; }
.t-form-equip-nav { padding: 8px 16px; border-bottom: 1px solid var(--t-borda); overflow-x: auto; flex-wrap: nowrap; flex: none; }
.t-form-equip-nav .t-filtro { flex: none; }   /* rola a fila; nunca encolhe o nome do separador */
.t-form-equip-erros { min-width: 1.4em; padding: 0 5px; border-radius: 999px; text-align: center; font-weight: 700;
                      color: var(--t-mau); background: color-mix(in srgb, var(--t-mau) 12%, transparent); }
.modal.t-form-equip .modal-body { flex: 1 1 auto; }

/* Os passos do assistente: número + nome; o actual cheio, os feitos com o traço do bom, os da frente esbatidos. */
.t-passos { list-style: none; margin: 0; padding: 10px 16px; display: flex; gap: 6px; overflow-x: auto; flex: none;
            border-bottom: 1px solid var(--t-borda); }
.t-passo { flex: 1 0 auto; }
.t-passo button { font: inherit; width: 100%; display: flex; align-items: center; gap: 8px; padding: 6px 10px; cursor: pointer;
                  border: 1px solid var(--t-borda); border-radius: var(--t-raio-interior); background: var(--t-fundo-interior);
                  color: var(--t-texto-fraco); font-size: .82rem; white-space: nowrap; }
.t-passo button:disabled { cursor: default; }
.t-passo-n { display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; flex: none;
             font-weight: 700; font-size: .78rem; border: 1px solid var(--t-borda-forte); color: var(--t-texto); }
.t-passo.actual button { color: var(--t-texto); border-color: var(--t-info);
                         background: color-mix(in srgb, var(--t-info) 12%, var(--t-fundo-cartao)); font-weight: 700; }
.t-passo.actual .t-passo-n { background: var(--t-info); border-color: var(--t-info); color: var(--t-fundo-cartao); }
.t-passo.feito .t-passo-n { border-color: var(--t-bom); color: var(--t-bom); }
.t-passo.com-erros button { border-color: var(--t-mau); }
.t-passo.com-erros .t-passo-n { border-color: var(--t-mau); color: var(--t-mau); }
.t-passo.actual.com-erros .t-passo-n { background: var(--t-mau); color: var(--t-fundo-cartao); }
.t-passo button:focus-visible { outline: 2px solid var(--t-info); outline-offset: 1px; }

/* Uma secção: título, uma frase do que é, e o corpo. */
.t-form-seccao { display: grid; gap: 14px; grid-template-columns: minmax(0, 1fr); }
.t-form-seccao > *, .t-form-sub > *, .t-campos-grelha > * { min-width: 0; }   /* a fila de modelos rola dentro, não alarga a janela */
.t-form-seccao-cab { display: grid; gap: 4px; padding-bottom: 10px; border-bottom: 1px solid var(--t-borda); }
.t-form-seccao-cab h4 { margin: 0; font-size: 1.02rem; color: var(--t-texto); }
.t-form-seccao-cab p { margin: 0; font-size: .84rem; line-height: 1.5; color: var(--t-texto-fraco); }
.t-form-sub { display: grid; gap: 10px; padding: 12px; border: 1px solid var(--t-borda); border-radius: var(--t-raio-interior);
              background: var(--t-fundo-interior); min-width: 0; }
.t-form-sub h5, .t-form-resumo h5 { margin: 0; font-size: .86rem; color: var(--t-texto); }
.t-form-sub h4 { color: var(--t-texto); }   /* os subtítulos dos formulários de cada tipo, sobre o fundo interior */

/* Os campos: grelha de duas colunas que passa a uma; o erro em vez da ajuda, a vermelho, com o campo contornado. */
.t-campos-grelha { display: grid; gap: 12px 16px; grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); }
.t-campos-grelha > label { display: grid; gap: 4px; align-content: start; font-weight: 600; font-size: .86rem; color: var(--t-texto); }
.t-campos-grelha > label small { font-weight: 400; font-size: .8rem; line-height: 1.45; color: var(--t-texto-fraco); }
.t-campo { display: grid; gap: 4px; align-content: start; min-width: 0; }
.t-campo > label { display: grid; gap: 4px; }
.t-campo-rotulo { font-weight: 600; font-size: .86rem; color: var(--t-texto); }
.t-obrigatorio { color: var(--t-mau); font-weight: 700; margin-left: 3px; }
.t-campo-ajuda { font-size: .8rem; line-height: 1.45; color: var(--t-texto-fraco); }
.t-campo-erro { font-size: .8rem; line-height: 1.45; color: var(--t-mau); font-weight: 600; }
.t-campo.com-erro input, .t-campo.com-erro select { border-color: var(--t-mau);
                                                    box-shadow: 0 0 0 1px color-mix(in srgb, var(--t-mau) 40%, transparent); }

/* Testar a ligação. */
.t-teste { display: grid; gap: 10px; padding: 12px; border: 1px dashed var(--t-borda-forte); border-radius: var(--t-raio-interior); }
.t-teste-cab { display: flex; gap: 10px 16px; align-items: center; justify-content: space-between; flex-wrap: wrap; }
.t-teste-cab > div { display: grid; gap: 2px; min-width: 0; flex: 1 1 240px; }
.t-teste-cab small { color: var(--t-texto-fraco); font-size: .8rem; line-height: 1.45; }
.t-teste-resultado .t-linha b { font-weight: 500; white-space: normal; overflow-wrap: anywhere; }

/* As medições e a sua herança. */
.t-medicoes { display: grid; gap: 10px; }
.t-medicao code { font-size: .78rem; color: var(--t-texto-fraco); overflow-wrap: anywhere; }
.t-medicao.escondida { border-style: dashed; }
.t-medicao-campos input:not([type="checkbox"]) { width: 16em; flex: 1 1 12em; }
.t-medicao-campos input.t-medicao-unidade { width: 7em; flex: 0 1 7em; }
.t-medicao-mostrar { display: inline-flex; align-items: center; gap: 6px; font-size: .84rem; width: auto; justify-content: flex-start; flex: none; }
.t-medicao-limiares { margin-top: 2px; }

/* O fim: interruptores, o resumo antes de gravar e a legenda do obrigatório. */
.t-form-interruptores { grid-template-columns: 1fr; }
.t-form-interruptores label { display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; border: 1px solid var(--t-borda);
                              border-radius: var(--t-raio-interior); background: var(--t-fundo-interior); }
.t-form-interruptores label span { display: grid; gap: 2px; }
.t-form-interruptores small { color: var(--t-texto-fraco); font-size: .8rem; line-height: 1.45; }
.t-form-resumo { display: grid; gap: 10px; }
.t-form-equip-pe { flex-wrap: wrap; align-items: center; }
.t-form-equip-legenda { margin-right: auto; font-size: .8rem; color: var(--t-texto-fraco); }

@media (max-width: 760px) {
    .modal.form-modal.t-form-equip { height: 100%; max-height: none; }
    .t-passo-nome { display: none; }
    .t-passo.actual .t-passo-nome { display: inline; }
    .t-passo { flex: 0 0 auto; }
    .t-passo.actual { flex: 1 0 auto; }
    .t-form-equip-pe .btn { flex: 1 1 auto; }
    .t-form-equip-legenda { flex-basis: 100%; }
    .t-medicao-campos input:not([type="checkbox"]), .t-medicao-campos input.t-medicao-unidade { width: 100%; flex-basis: 100%; }
}
@media (max-width: 1024px), (pointer: coarse) {
    .t-passo button { min-height: 44px; }
    .t-form-interruptores label, .t-medicao-mostrar { min-height: 44px; }
}
/* [/formulário de equipamento por secções 25/10] */
