/* ============================================================================
   SIG4ROAD · camada de desenho
   ----------------------------------------------------------------------------
   Carrega DEPOIS do tema Metronic e por cima dele. Não substitui o tema nem o
   altera: o tema continua a tratar do esqueleto (grelha, barra lateral,
   cabeçalho fixo, componentes do Kendo) e esta folha trata da linguagem visual.

   Foi feita assim de propósito. Editar os ficheiros do tema tornaria qualquer
   atualização futura impossível de aplicar, e reescrever a aplicação de raiz
   deitava fora anos de trabalho que funciona. O que aqui está é a diferença
   entre a aplicação de 2019 e a de hoje — e pode ser lida de uma ponta à outra
   para se perceber exatamente o que mudou.

   O QUE SE PRESERVOU (é isto que torna a aplicação reconhecível)
     · a barra lateral escura #1E1E2D e o logótipo com a vela vermelha e azul;
     · o azul de ação #3699FF, herdado do tema e já aprendido por quem a usa;
     · o verde/amarelo/vermelho da conformidade, que têm significado de negócio;
     · a densidade: isto é uma ferramenta de trabalho com tabelas grandes, não
       uma landing page. Ganhou ar, não ganhou espaço vazio.

   O QUE MUDOU, E PORQUÊ
     1. A raiz passa de 13 px para 14 px — e deixa de encolher para 12 px em
        ecrãs pequenos, que era o contrário do que devia acontecer.
     2. Os números passam a ter algarismos de largura fixa. Esta aplicação é
        feita de colunas de números (RL, PK, percentagens, datas) e em Poppins
        proporcional eles não alinham na vertical. É a alteração que mais faz
        a aplicação parecer um instrumento de medida e não um formulário.
     3. A sombra difusa de 30 px dos cartões dá lugar a um risco de 1 px mais
        uma sombra curta. A sombra larga e clara é a assinatura visual de 2019.
     4. Hierarquia: títulos, corpo e texto secundário passam a ter três pesos e
        três tamanhos distintos, em vez de variarem só de cor.
     5. Estados: foco, hover e ativo passam a existir a sério, com transições de
        140 ms. Antes, metade dos elementos não reagia ao rato.
   ========================================================================== */

/* ----------------------------------------------------------------- 1. tokens */

:root {
    /* Marca ------------------------------------------------------------- */
    --s4-azul: #3699FF;            /* ação: botões, ligações, estado ativo */
    --s4-azul-forte: #187DE4;      /* hover/active do azul */
    --s4-azul-fraco: #E8F3FF;      /* fundos de realce, chips */
    --s4-navy: #1E1E2D;            /* barra lateral e títulos fortes */
    --s4-navy-claro: #2A2A3C;

    /* Sinal — reservados à conformidade. Não usar por decoração: nesta
       aplicação estas três cores QUEREM DIZER alguma coisa. ---------------- */
    --s4-verde: #22A447;          /* verde, não o turquesa do tema: "cumpre" tem de se ler como verde no mapa */
    --s4-amarelo: #FFA800;
    --s4-vermelho: #F64E60;
    --s4-verde-fraco: #E6F5EA;
    --s4-amarelo-fraco: #FFF6E5;
    --s4-vermelho-fraco: #FFEFF1;

    /* Paleta categórica — SÓ para gráficos, onde é preciso distinguir dez
       classes de sinal umas das outras e nenhuma delas é boa nem má. Não usar
       em botões, etiquetas ou fundos: fora de um gráfico, uma cor que não
       significa nada é ruído. Começa no azul da marca e afasta-se em matiz,
       nunca em luminosidade, para as fatias se distinguirem impressas a preto
       e branco e em ecrãs maus. -------------------------------------------- */
    --s4-g1: #3699FF;
    --s4-g2: #1BC5BD;
    --s4-g3: #FFA800;
    --s4-g4: #8950FC;
    --s4-g5: #F64E60;
    --s4-g6: #0BB783;
    --s4-g7: #6993FF;
    --s4-g8: #FF8A4C;
    --s4-g9: #C13A87;
    --s4-g10: #7E8299;

    /* Tinta -------------------------------------------------------------- */
    --s4-tinta: #181C32;           /* títulos */
    --s4-texto: #3F4254;           /* corpo */
    --s4-suave: #6C7293;           /* secundário legível (era #7E8299) */
    --s4-ténue: #A1A5B7;           /* terciário, etiquetas */

    /* Superfícies e linhas ----------------------------------------------- */
    --s4-fundo: #F7F8FA;
    --s4-superficie: #FFFFFF;
    --s4-superficie-2: #F7F8FA;
    --s4-linha: #E9EBF2;
    --s4-linha-forte: #DCDFEA;

    /* Raios — escala curta. Três valores chegam; mais do que isso e a
       aplicação deixa de ter uma forma própria. ---------------------------- */
    --s4-r-sm: 6px;
    --s4-r-md: 10px;
    --s4-r-lg: 14px;
    --s4-r-pill: 999px;

    /* Sombras — curtas e em camadas. A sombra faz o elemento levantar-se um
       milímetro, não flutuar. --------------------------------------------- */
    --s4-sombra-xs: 0 1px 2px rgba(24, 28, 50, .04);
    --s4-sombra-sm: 0 1px 2px rgba(24, 28, 50, .04), 0 2px 6px rgba(24, 28, 50, .05);
    --s4-sombra-md: 0 2px 4px rgba(24, 28, 50, .04), 0 8px 20px rgba(24, 28, 50, .08);
    --s4-sombra-lg: 0 4px 8px rgba(24, 28, 50, .05), 0 16px 40px rgba(24, 28, 50, .12);

    /* Ritmo — múltiplos de 4. Tudo o que for espaçamento sai daqui. ------- */
    --s4-e1: 4px;
    --s4-e2: 8px;
    --s4-e3: 12px;
    --s4-e4: 16px;
    --s4-e5: 24px;
    --s4-e6: 32px;
    --s4-e7: 48px;

    /* Movimento ---------------------------------------------------------- */
    --s4-rapido: 120ms;
    --s4-normal: 160ms;
    --s4-calmo: 240ms;
    --s4-curva: cubic-bezier(.2, .7, .3, 1);
    --s4-curva-saida: cubic-bezier(.4, 0, 1, 1);

    /* Anel de foco — um só, em toda a aplicação. ------------------------- */
    --s4-foco: 0 0 0 3px rgba(54, 153, 255, .28);
}

/* ------------------------------------------------- 2. base e tipografia */

/* 13 px era pequeno demais para leitura prolongada, e o tema ainda descia para
   12 px abaixo dos 992 px — encolher o texto no telemóvel é exatamente o
   contrário do que deve acontecer. Passa a 14 px em toda a parte. */
html, body {
    font-size: 14px !important;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

body {
    background-color: var(--s4-fundo);
    color: var(--s4-texto);
    letter-spacing: -.005em;
}

h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
    color: var(--s4-tinta);
    font-weight: 600;
    letter-spacing: -.02em;
    line-height: 1.3;
}

h1, .h1 { font-size: 1.75rem; font-weight: 700; }
h2, .h2 { font-size: 1.4rem; }
h3, .h3 { font-size: 1.2rem; }
h4, .h4 { font-size: 1rem; }
h5, .h5 { font-size: .88rem; letter-spacing: -.01em; }

p { line-height: 1.65; }

/* --- Algarismos de largura fixa ------------------------------------------
   A alteração de maior efeito neste ficheiro. Esta aplicação é feita de
   colunas de números — RL, PK, percentagens, extensões, datas — e em Poppins
   proporcional o "1" é mais estreito do que o "8", o que desalinha a coluna
   toda e dá um ar de folha de cálculo mal feita. Com tabular-nums as colunas
   ficam a prumo e o produto passa a parecer um instrumento de medida. */
table, .table,
.s4-num, td, th,
.datatable-cell,
input[type="number"],
.font-size-h1, .font-size-h2, .font-size-h3 {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}

/* Ligações: sublinhado só quando interessa, transição sempre. */
a {
    transition: color var(--s4-rapido) var(--s4-curva);
}

a:not(.btn):not(.menu-link):not(.nav-link):hover {
    color: var(--s4-azul-forte);
}

/* ------------------------------------------------------- 3. foco visível */

/* Um anel de foco, um só, e apenas para quem navega por teclado. O tema
   escondia o foco em vários sítios, o que torna a aplicação inutilizável sem
   rato — e é também um requisito de acessibilidade, não um extra. */
*:focus { outline: none; }

.btn:focus-visible,
.form-control:focus-visible,
.custom-select:focus-visible,
select:focus-visible,
textarea:focus-visible,
input:focus-visible,
a:focus-visible,
.menu-link:focus-visible,
[tabindex]:focus-visible {
    outline: none;
    box-shadow: var(--s4-foco) !important;
    border-color: var(--s4-azul) !important;
}

/* Os campos de pesquisa das listagens têm o ícone desenhado por cima do campo,
   em posição absoluta e sem z-index (é o `.input-icon` do tema, usado em
   dezenas de ecrãs). A primeira versão desta folha punha `position: relative;
   z-index: 3` no campo ao ganhar foco — e o campo passava a tapar a lupa
   assim que se clicava nele. O anel de foco não precisava disso; o que precisa
   é que o ícone fique por cima, e isso diz-se aqui, uma vez. */
.input-icon > span,
.input-icon span {
    z-index: 2;
    pointer-events: none;   /* clicar na lupa põe o cursor no campo, como se espera */
}

/* ------------------------------------------------------------ 4. cartões */

/* A sombra difusa de 30 px do tema é a assinatura de 2019: não se percebe de
   onde vem a luz e o cartão parece manchado. Passa a um risco de 1 px com uma
   sombra curta — o cartão assenta na página em vez de pairar. */
.card.card-custom {
    background: var(--s4-superficie);
    border: 1px solid var(--s4-linha);
    border-radius: var(--s4-r-lg);
    box-shadow: var(--s4-sombra-xs);
    transition: box-shadow var(--s4-normal) var(--s4-curva),
                border-color var(--s4-normal) var(--s4-curva);
}

.card.card-custom > .card-header {
    min-height: auto;
    padding: var(--s4-e5) var(--s4-e5) 0;
    border-bottom: 0;
    align-items: center;
}

.card.card-custom > .card-header .card-title {
    margin: 0;
    align-items: baseline;
    flex-wrap: wrap;
    gap: var(--s4-e2);
}

.card.card-custom > .card-header .card-title,
.card.card-custom > .card-header .card-label {
    color: var(--s4-tinta);
    font-size: 1.05rem;
    font-weight: 600;
    letter-spacing: -.015em;
}

/* O subtítulo ao lado do título ("· voltas de medição") é o padrão desta
   aplicação para explicar um ecrã numa linha. Fica com um tamanho próprio. */
.card.card-custom > .card-header .card-title small {
    color: var(--s4-ténue);
    font-size: .82rem;
    font-weight: 400;
    letter-spacing: 0;
}

.card.card-custom > .card-body {
    padding: var(--s4-e5);
}

.card.card-custom > .card-header + .card-body {
    padding-top: var(--s4-e4);
}

.card.card-custom > .card-footer {
    background: transparent;
    border-top: 1px solid var(--s4-linha);
    padding: var(--s4-e4) var(--s4-e5);
}

/* O tema separa cartões com 25px; 24 encaixa no ritmo de 4. */
.gutter-b { margin-bottom: var(--s4-e5) !important; }

/* Cartão escuro — usado nos cabeçalhos de secção da SH. */
.card.card-custom > .card-header.bg-dark {
    background: var(--s4-navy) !important;
    border-radius: var(--s4-r-lg) var(--s4-r-lg) 0 0;
    padding: var(--s4-e4) var(--s4-e5);
}

.card.card-custom > .card-header.bg-dark .card-title {
    color: #FFFFFF;
    letter-spacing: .06em;
    font-size: .82rem;
    font-weight: 600;
}

/* ------------------------------------------------------------- 5. botões */

.btn {
    border-radius: var(--s4-r-sm);
    font-weight: 500;
    letter-spacing: -.005em;
    padding: .55rem 1.1rem;
    transition: background-color var(--s4-rapido) var(--s4-curva),
                border-color var(--s4-rapido) var(--s4-curva),
                color var(--s4-rapido) var(--s4-curva),
                box-shadow var(--s4-rapido) var(--s4-curva),
                transform var(--s4-rapido) var(--s4-curva);
}

/* O "carregar" tem de se sentir. 1 px chega — mais do que isso e o botão
   parece um brinquedo. */
.btn:active:not(:disabled) { transform: translateY(1px); }

/* Desativado tem de se ler como desativado. A opacidade do Bootstrap sozinha
   deixava o botão azul só um pouco mais claro — lia-se como "outro botão". */
.btn:disabled,
.btn.disabled {
    background-color: var(--s4-superficie-2) !important;
    border-color: var(--s4-linha) !important;
    color: var(--s4-ténue) !important;
    box-shadow: none !important;
    opacity: 1;
    cursor: not-allowed;
    pointer-events: auto;
}

.btn.font-weight-bolder, .btn.font-weight-bold { font-weight: 600; }

.btn.btn-primary {
    background-color: var(--s4-azul);
    border-color: var(--s4-azul);
    box-shadow: 0 1px 2px rgba(54, 153, 255, .25);
}

.btn.btn-primary:hover,
.btn.btn-primary:focus {
    background-color: var(--s4-azul-forte);
    border-color: var(--s4-azul-forte);
    box-shadow: 0 2px 8px rgba(54, 153, 255, .32);
}

/* Secundário: contorno em vez de bloco cinzento. A hierarquia entre a ação
   principal e as outras passa a ver-se de relance, que é o que faltava. */
.btn.btn-light,
.btn.btn-secondary {
    background-color: var(--s4-superficie);
    border: 1px solid var(--s4-linha-forte);
    color: var(--s4-texto);
    box-shadow: var(--s4-sombra-xs);
}

.btn.btn-light:hover,
.btn.btn-secondary:hover {
    background-color: var(--s4-superficie-2);
    border-color: #C9CDDC;
    color: var(--s4-tinta);
}

/* Os "light-cor" do tema são chips pastel; ficam, mas com a cor do texto
   corrigida para contraste e com hover a sério. */
.btn[class*="btn-light-"] {
    border: 1px solid transparent;
    box-shadow: none;
}

.btn.btn-light-primary { background-color: var(--s4-azul-fraco); color: var(--s4-azul-forte); }
.btn.btn-light-primary:hover { background-color: #D6E9FF; color: var(--s4-azul-forte); }
.btn.btn-light-success { background-color: var(--s4-verde-fraco); color: #177A35; }
.btn.btn-light-danger { background-color: var(--s4-vermelho-fraco); color: #E03A4D; }
.btn.btn-light-warning { background-color: var(--s4-amarelo-fraco); color: #C98400; }

/* Botões de ícone nas tabelas: eram quadrados de 30 px sem afordância. */
.btn.btn-icon.btn-sm {
    width: 32px;
    height: 32px;
    border-radius: var(--s4-r-sm);
}

.btn.btn-icon.btn-sm i { font-size: .95rem; }

.btn.btn-icon:hover { box-shadow: var(--s4-sombra-sm); }

/* Um grupo de ícones de ação só se revela por completo quando a linha está
   sob o rato: a tabela fica mais calma sem perder nada. */
.table tbody tr .s4-acoes { opacity: .55; transition: opacity var(--s4-rapido) var(--s4-curva); }
.table tbody tr:hover .s4-acoes,
.table tbody tr:focus-within .s4-acoes { opacity: 1; }

/* ------------------------------------------------ 6. formulários e inputs */

.form-control,
.custom-select,
select.form-control {
    border: 1px solid var(--s4-linha-forte);
    border-radius: var(--s4-r-sm);
    color: var(--s4-texto);
    padding: .55rem .85rem;
    height: calc(1.5em + 1.1rem + 2px);
    transition: border-color var(--s4-rapido) var(--s4-curva),
                box-shadow var(--s4-rapido) var(--s4-curva),
                background-color var(--s4-rapido) var(--s4-curva);
}

.form-control::placeholder { color: var(--s4-ténue); }

.form-control:hover:not(:disabled):not(:focus) { border-color: #C9CDDC; }

.form-control:focus {
    border-color: var(--s4-azul);
    box-shadow: var(--s4-foco);
    background-color: var(--s4-superficie);
}

/* O "solid" do tema é um retângulo cinzento sem contorno — lê-se como campo
   desativado. Passa a branco com risco, como os outros. */
.form-control.form-control-solid {
    background-color: var(--s4-superficie);
    border-color: var(--s4-linha-forte);
}

.form-control.form-control-solid:focus {
    background-color: var(--s4-superficie);
    border-color: var(--s4-azul);
}

.form-control:disabled,
.form-control[readonly] {
    background-color: var(--s4-superficie-2);
    color: var(--s4-suave);
    border-color: var(--s4-linha);
}

/* Um campo só de leitura com o aspeto de um campo (S47): a obra em que se está, nos formulários de
   dentro da obra. Era uma <div class="form-control">, com a altura fixa de um campo, e o nome de uma
   obra comprido partia para a segunda linha por cima do campo de baixo. Aqui a altura é a do que lá
   está. */
.form-control.s4-campo-leitura {
    height: auto;
    min-height: calc(1.5em + 1.1rem + 2px);
    background-color: var(--s4-superficie-2);
    border-color: var(--s4-linha);
    color: var(--s4-tinta);
    font-weight: 600;
    white-space: normal;
    overflow-wrap: anywhere;
}

/* Etiquetas: eram do mesmo tamanho e peso do valor, o que baralhava a
   leitura de um formulário. Passam a ser claramente subordinadas. */
label,
.form-group > label {
    color: var(--s4-suave);
    font-size: .82rem;
    font-weight: 500;
    letter-spacing: .01em;
    margin-bottom: var(--s4-e2);
}

.form-group { margin-bottom: var(--s4-e5); }

.form-text, .text-muted { color: var(--s4-suave) !important; }

.invalid-feedback, .text-danger { color: var(--s4-vermelho) !important; }

.form-control.is-invalid, .form-control.error {
    border-color: var(--s4-vermelho);
    background-image: none;
}

.form-control.is-invalid:focus {
    box-shadow: 0 0 0 3px rgba(246, 78, 96, .22);
}

/* Barra de filtros: um padrão que se repete em cinco ecrãs e que em cada um
   estava construído de maneira diferente. */
.s4-filtros {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--s4-e3) var(--s4-e4);
    padding: var(--s4-e4);
    background: var(--s4-superficie-2);
    border: 1px solid var(--s4-linha);
    border-radius: var(--s4-r-md);
    margin-bottom: var(--s4-e5);
}

.s4-filtros .form-group,
.s4-filtros > label { margin-bottom: 0; }

.s4-filtros label { display: block; }

/* Cada campo cresce para ocupar o espaço disponível, mas não desce abaixo do que
   é preciso para se ler o valor escolhido.

   Sem isto o contentor é flex e encolhe cada campo ao seu conteúdo: uma caixa de
   obra fica com a largura da palavra "Todas" e, escolhida uma obra com nome
   comprido, o nome deixa de caber. Vale para todas as barras de filtros de uma
   vez — não se resolve view a view.

   O `w-100` fica de fora porque é como se marca uma linha inteira dentro da barra
   (a explicação por cima dos campos, no ecrã de importação SIG). */
.s4-filtros > div:not(.w-100),
.s4-filtros > .form-group:not(.w-100) {
    flex: 1 1 210px;
    min-width: 190px;
}

/* --------------------------------------------------------- 7. tabelas */

.table {
    color: var(--s4-texto);
    margin-bottom: 0;
}

.table.table-head-custom thead th {
    color: var(--s4-ténue);
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .07em;
    text-transform: uppercase;
    border-bottom: 1px solid var(--s4-linha);
    border-top: 0;
    padding: var(--s4-e3) var(--s4-e3);
    white-space: nowrap;
}

.table td {
    border-top: 1px solid var(--s4-linha);
    padding: var(--s4-e3);
    vertical-align: middle;
}

/* Linhas com hover: numa tabela larga é isto que impede o olho de saltar de
   linha a meio caminho. */
.table tbody tr {
    transition: background-color var(--s4-rapido) var(--s4-curva);
}

.table tbody tr:hover { background-color: var(--s4-superficie-2); }

.table tbody tr:first-child td { border-top: 0; }

/* Colunas de números encostadas à direita, sempre. */
.table .text-right { font-variant-numeric: tabular-nums; }

/* Tabela dentro de um cartão: o cartão já dá a margem. */
.card-body > .table-responsive { margin: 0 calc(-1 * var(--s4-e2)); }

/* ------------------------------------------------- 8. etiquetas e estados */

.label.label-inline {
    border-radius: var(--s4-r-sm);
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .01em;
    height: auto;
    padding: .28rem .6rem;
    line-height: 1.35;
}

.label.label-light-success { background: var(--s4-verde-fraco); color: #177A35; }
.label.label-light-warning { background: var(--s4-amarelo-fraco); color: #B87800; }
.label.label-light-danger { background: var(--s4-vermelho-fraco); color: #DB3547; }
.label.label-light-primary { background: var(--s4-azul-fraco); color: var(--s4-azul-forte); }
.label.label-light { background: var(--s4-superficie-2); color: var(--s4-suave); }

/* Um ponto de sinal antes do texto: lê-se mais depressa do que a cor de fundo
   sozinha, e continua a funcionar para quem não distingue verde de vermelho. */
.s4-sinal::before {
    content: "";
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: var(--s4-r-pill);
    margin-right: .45rem;
    vertical-align: .08em;
    background: currentColor;
}

/* ------------------------------------------------------------ 9. alertas */

.alert {
    border: 1px solid var(--s4-linha);
    border-left-width: 3px;
    border-radius: var(--s4-r-md);
    padding: var(--s4-e4);
    box-shadow: var(--s4-sombra-xs);
}

.alert.alert-custom { align-items: flex-start; }

.alert .alert-icon { padding-right: var(--s4-e3); }

/* O tema desenha estes ícones a 2 rem, o que os põe a competir com o texto.
   Um sinal de severidade é para se ver de canto de olho, não para se ler. */
.alert .alert-icon i { font-size: 1.15rem; }

.alert .alert-icon .svg-icon svg { width: 18px; height: 18px; }

/* O tema desenha estes ícones a 2 rem, o que os põe a competir com o texto.
   Um sinal de severidade é para se ver de canto de olho, não para se ler. */
.alert .alert-icon i,
.alert .alert-icon .svg-icon svg { font-size: 1.15rem; }

.alert .alert-icon .svg-icon svg { width: 18px; height: 18px; }

.alert .alert-text { line-height: 1.6; }

.alert.alert-light-primary, .alert.alert-custom.alert-light-primary {
    background: var(--s4-azul-fraco);
    border-color: var(--s4-linha);
    border-left-color: var(--s4-azul);
    color: #0B4F8F;
}

.alert.alert-light-warning, .alert.alert-custom.alert-light-warning {
    background: var(--s4-amarelo-fraco);
    border-color: #F5E4C2;
    border-left-color: var(--s4-amarelo);
    color: #7A5200;
}

.alert.alert-light-danger, .alert.alert-custom.alert-light-danger,
.alert.alert-danger {
    background: var(--s4-vermelho-fraco);
    border-color: #F6D5D9;
    border-left-color: var(--s4-vermelho);
    color: #A81E2E;
}

.alert.alert-light-success, .alert.alert-custom.alert-light-success,
.alert.alert-success {
    background: var(--s4-verde-fraco);
    border-color: #C6E8CF;
    border-left-color: var(--s4-verde);
    color: #0A6E69;
}

/* Uma mensagem que aparece depois de uma ação deve dar-se a notar sem
   sobressaltar. 240 ms, de cima para baixo, uma vez. */
.alert { animation: s4-entra var(--s4-calmo) var(--s4-curva) both; }

@keyframes s4-entra {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: none; }
}

/* ----------------------------------------- 10. vazios, carregamento, skeleton */

/* O estado vazio é o primeiro ecrã que um utilizador novo vê em quase todas as
   listagens. Deixa de ser uma linha de texto cinzento perdida no meio do nada. */
.s4-vazio {
    text-align: center;
    padding: var(--s4-e7) var(--s4-e5);
    color: var(--s4-suave);
}

.s4-vazio-icone {
    width: 48px;
    height: 48px;
    margin: 0 auto var(--s4-e4);
    border-radius: var(--s4-r-md);
    background: var(--s4-superficie-2);
    border: 1px solid var(--s4-linha);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--s4-ténue);
    font-size: 1.3rem;
}

.s4-vazio-titulo {
    color: var(--s4-tinta);
    font-size: 1rem;
    font-weight: 600;
    margin-bottom: var(--s4-e2);
}

.s4-vazio p {
    margin: 0 auto;
    max-width: 52ch;
    line-height: 1.65;
}

/* O pré-carregador da aplicação passa a usar o azul da marca em vez do azul
   antigo do ficheiro main.css, e deixa de ser um disco a rodar sobre branco. */
#my-preloder { background: var(--s4-fundo); }

/* ---------------------------------------------- 11. barra lateral e cabeçalho */

.aside { border-right: 1px solid rgba(255, 255, 255, .04); }

.aside-menu .menu-nav > .menu-item > .menu-link,
.aside-menu .menu-nav .menu-submenu .menu-item > .menu-link {
    border-radius: var(--s4-r-sm);
    margin: 1px var(--s4-e3);
    padding: .62rem var(--s4-e3);
    transition: background-color var(--s4-rapido) var(--s4-curva),
                color var(--s4-rapido) var(--s4-curva);
}

.aside-menu .menu-nav > .menu-item > .menu-link .menu-text {
    font-weight: 500;
    letter-spacing: -.005em;
}

.aside-menu .menu-nav > .menu-item:not(.menu-item-open):not(.menu-item-active) > .menu-link:hover {
    background-color: rgba(255, 255, 255, .045);
}

/* O item ativo ganha um traço à esquerda. É um aceno ao que a aplicação faz —
   uma marca no pavimento — e, mais prosaicamente, torna óbvio onde se está sem
   depender só de uma mudança de cor de fundo. */
.aside-menu .menu-nav > .menu-item.menu-item-active > .menu-link,
.aside-menu .menu-nav .menu-submenu .menu-item.menu-item-active > .menu-link {
    background-color: rgba(54, 153, 255, .14);
    position: relative;
}

.aside-menu .menu-nav > .menu-item.menu-item-active > .menu-link::before,
.aside-menu .menu-nav .menu-submenu .menu-item.menu-item-active > .menu-link::before {
    content: "";
    position: absolute;
    left: -6px;
    top: 20%;
    bottom: 20%;
    width: 3px;
    border-radius: var(--s4-r-pill);
    background: var(--s4-azul);
}

.aside-menu .menu-nav > .menu-item.menu-item-active > .menu-link .menu-text,
.aside-menu .menu-nav .menu-submenu .menu-item.menu-item-active > .menu-link .menu-text {
    color: #FFFFFF;
    font-weight: 600;
}

/* Os títulos de secção do menu (GERAL, REGISTOS) eram tão claros que quase não
   se liam; ganham peso e espaçamento de letra em vez de tamanho. */
.aside-menu .menu-nav .menu-section .menu-text {
    color: rgba(255, 255, 255, .38);
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .12em;
}

.brand { border-bottom: 1px solid rgba(255, 255, 255, .05); }

.header { border-bottom: 1px solid var(--s4-linha); box-shadow: none; }

/* O subcabeçalho era uma faixa branca com um título de 13 px — ou seja, o
   título da página era do tamanho do texto de uma célula de tabela. */
.subheader {
    background: var(--s4-superficie);
    border-bottom: 1px solid var(--s4-linha);
    box-shadow: none;
}

.subheader h5 {
    font-size: 1.25rem;
    font-weight: 600;
    letter-spacing: -.02em;
    color: var(--s4-tinta);
}

/* ------------------------------------------------------ 12. sobreposições */

.modal-content {
    border: 0;
    border-radius: var(--s4-r-lg);
    box-shadow: var(--s4-sombra-lg);
}

.modal-header, .modal-footer {
    border-color: var(--s4-linha);
    padding: var(--s4-e4) var(--s4-e5);
}

.modal-body { padding: var(--s4-e5); }

.modal.fade .modal-dialog {
    transition: transform var(--s4-calmo) var(--s4-curva), opacity var(--s4-calmo) var(--s4-curva);
    transform: translateY(8px) scale(.99);
}

.modal.show .modal-dialog { transform: none; }

.dropdown-menu {
    border: 1px solid var(--s4-linha);
    border-radius: var(--s4-r-md);
    box-shadow: var(--s4-sombra-md);
    padding: var(--s4-e2);
}

.dropdown-item {
    border-radius: var(--s4-r-sm);
    padding: .5rem .75rem;
    transition: background-color var(--s4-rapido) var(--s4-curva);
}

.dropdown-item:hover { background: var(--s4-superficie-2); }

/* --------------------------------------------------------- 13. separadores */

.nav-tabs {
    border-bottom: 1px solid var(--s4-linha);
    gap: var(--s4-e1);
}

.nav-tabs .nav-link {
    border: 0;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    color: var(--s4-suave);
    font-weight: 500;
    padding: .65rem var(--s4-e3);
    transition: color var(--s4-rapido) var(--s4-curva),
                border-color var(--s4-rapido) var(--s4-curva);
}

.nav-tabs .nav-link:hover { color: var(--s4-tinta); border-bottom-color: var(--s4-linha-forte); }

.nav-tabs .nav-link.active {
    background: transparent;
    border-bottom-color: var(--s4-azul);
    color: var(--s4-tinta);
    font-weight: 600;
}

/* ------------------------------------------------------ 14. responsividade */

/* Abaixo dos 992 px o conteúdo respirava menos do que devia porque o tema
   mantinha as margens de desktop. */
@media (max-width: 991.98px) {
    .card.card-custom > .card-header,
    .card.card-custom > .card-body { padding-left: var(--s4-e4); padding-right: var(--s4-e4); }

    .subheader h5 { font-size: 1.1rem; }

    .s4-filtros { flex-direction: column; align-items: stretch; }

    .s4-filtros .form-control, .s4-filtros select { width: 100%; }
}

/* Tabelas em ecrã estreito: em vez de encolher a tabela até ser ilegível ou de
   a deixar a deslizar às cegas, cada linha passa a um bloco com as etiquetas ao
   lado dos valores. Aplica-se só a quem tiver a classe, para não mexer nas
   tabelas do Kendo. */
@media (max-width: 767.98px) {
    .s4-tabela-empilha thead { display: none; }

    .s4-tabela-empilha tbody tr {
        display: block;
        border: 1px solid var(--s4-linha);
        border-radius: var(--s4-r-md);
        margin-bottom: var(--s4-e3);
        padding: var(--s4-e2) var(--s4-e3);
        background: var(--s4-superficie);
    }

    .s4-tabela-empilha tbody td {
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        gap: var(--s4-e4);
        border: 0;
        border-bottom: 1px dashed var(--s4-linha);
        padding: var(--s4-e2) 0;
        text-align: right !important;
    }

    .s4-tabela-empilha tbody td:last-child { border-bottom: 0; }

    .s4-tabela-empilha tbody td::before {
        content: attr(data-etiqueta);
        color: var(--s4-ténue);
        font-size: .72rem;
        font-weight: 600;
        letter-spacing: .06em;
        text-transform: uppercase;
        text-align: left;
        flex: 0 0 auto;
    }
}

/* ------------------------------------------------------- 15. movimento */

/* Quem pediu menos movimento ao sistema operativo deve receber menos
   movimento. Não é opcional: para algumas pessoas é o que faz a diferença
   entre poder e não poder usar a aplicação. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
}

/* -------------------------------------------- 15b. seletor de entidade */

/* Nomes de entidades reais — "Infraestruturas de Portugal, S.A." — não cabiam
   e ficavam cortados numa caixa estreita de mais. Alarga-se o suficiente para
   a maioria caber, e o que continuar a não caber lê-se ao passar o rato: o
   botão leva o nome completo em `title` (ver sig4road-select.js). */
#selectedEntityDiv .s4-sel {
    min-width: 220px;
}

@media (min-width: 1200px) {
    #selectedEntityDiv .s4-sel { min-width: 290px; }
}

/* Este controlo tem de se ver como controlo em REPOUSO, e não só quando o rato
   lhe passa por cima.

   A primeira versão deixava-o transparente e sem moldura até ao hover — o
   padrão dos controlos de barra superior. Aqui não serve: o cabeçalho é branco,
   um botão branco sobre branco não se distingue de texto, e a seta sozinha não
   chega para dizer que aquilo abre. Quem não soubesse que era um menu não
   descobria sem passar o rato por cima, que é uma forma de esconder uma das
   escolhas mais importantes da aplicação — tudo o que se vê a seguir depende
   da entidade escolhida aqui. */
#selectedEntityDiv .s4-sel-botao {
    background: var(--s4-superficie-2);
    border-color: var(--s4-linha-forte);
    box-shadow: var(--s4-sombra-xs);
    color: var(--s4-tinta);
    font-weight: 600;
}

#selectedEntityDiv .s4-sel-botao:hover:not(:disabled) {
    background: var(--s4-superficie);
    border-color: var(--s4-azul);
}

/* A seta ganha o peso do texto: é ela que diz que há mais por baixo. */
#selectedEntityDiv .s4-sel-seta {
    border-color: var(--s4-suave);
}

#selectedEntityDiv.s4-sel-aberto .s4-sel-botao,
#selectedEntityDiv .s4-sel-aberto .s4-sel-botao {
    background: var(--s4-superficie);
    border-color: var(--s4-azul);
}

@media (max-width: 767.98px) {
    #selectedEntityDiv .s4-sel { min-width: 150px; }
}

/* ---------------------------------------------------------- 16. entrada */

/* O ecrã de entrada é o único que toda a gente vê, e era o mais datado: campos
   de 56 px cinzentos sem contorno (leem-se como desativados), etiquetas do
   mesmo tamanho dos valores, e metade do texto em inglês numa aplicação
   portuguesa. A fotografia da estrada fica — é a melhor coisa que ali havia. */

.s4-login { width: 100%; max-width: 380px; margin: 0 auto; }

/* O logótipo ocupava 150 px de altura e encostava ao formulário. Continua a ser
   a primeira coisa que se vê — é a marca — mas deixa de competir com o campo
   onde a pessoa tem de escrever. */
.s4-login-logo {
    display: block;
    margin: 0 auto var(--s4-e5);
    max-height: 76px;
    width: auto;
}

@media (min-width: 992px) {
    .s4-login-logo { max-height: 92px; }
}

.s4-login-cabeca { margin-bottom: var(--s4-e6); }

.s4-login-cabeca h1 {
    font-size: 1.9rem;
    font-weight: 700;
    letter-spacing: -.025em;
    margin-bottom: var(--s4-e2);
}

.s4-login-cabeca p {
    color: var(--s4-suave);
    margin: 0;
}

.s4-login .form-control {
    height: 46px;
    font-size: .95rem;
}

.s4-login-esqueci {
    color: var(--s4-azul);
    font-size: .82rem;
    font-weight: 500;
}

.s4-login-entrar {
    height: 46px;
    font-size: .95rem;
    margin-top: var(--s4-e2);
}

/* O tema reserva espaço à direita do botão para a bola de processamento
   (.spinner.spinner-right.btn { padding-right: 3.5rem }); com um botão de
   largura total ela fica à direita do texto centrado, sem o tapar. */
#kt_login_signin_submit.spinner.spinner-right { padding-right: 3.5rem !important; }

/* O lema sobre a fotografia dependia de uma sombra de texto de 1 px para se
   ler — o que funciona sobre o céu e falha sobre a folhagem. Passa a ter um
   véu escuro por baixo, que é legível sobre qualquer fotografia que ali
   venha a ser posta. */
.login.login-2 .content {
    background-size: cover;
    background-position: center;
    position: relative;
}

.login.login-2 .content::before {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(12, 16, 32, .72) 0%, rgba(12, 16, 32, .28) 42%, rgba(12, 16, 32, .08) 100%);
    pointer-events: none;
}

.s4-login-lema { position: relative; z-index: 1; }

.s4-login-titulo {
    color: #FFFFFF;
    font-size: 1.65rem;
    font-weight: 600;
    letter-spacing: -.02em;
    line-height: 1.35;
    margin-bottom: var(--s4-e3);
}

.s4-login-sub {
    color: rgba(255, 255, 255, .78);
    font-size: .85rem;
    font-weight: 500;
    letter-spacing: .08em;
    margin: 0;
    text-transform: uppercase;
}

@media (max-width: 991.98px) {
    .s4-login-titulo { font-size: 1.25rem; }
    .s4-login-sub { font-size: .72rem; letter-spacing: .05em; }
    .s4-login-cabeca { margin-bottom: var(--s4-e5); }
}

/* ------------------------------------------- 17. caixa de seleção com pesquisa */

/* O <select> original fica no documento — é ele que o formulário submete — mas
   sai de vista. Não se usa display:none de propósito: um campo com
   display:none deixa de poder receber a mensagem de validação do browser, e a
   caixa passaria a recusar-se em silêncio. */
.s4-sel { position: relative; }

.s4-sel-nativo {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
    opacity: 0;
    pointer-events: none;

    /* O <select> continua no documento, e com ele as suas opções — que o
       browser continua a dispor mesmo estando invisíveis. Numa lista de 5000
       isso são dezenas de milissegundos em cada layout, pagos ao abrir o
       painel. Medido: 68 ms sem isto, 26 ms com isto.
       Onde a propriedade não existir, é ignorada e fica o comportamento de
       antes — não se perde nada. */
    content-visibility: hidden;
}

/* O botão é indistinguível de um campo de formulário: é o mesmo controlo aos
   olhos de quem usa, e a consistência com os campos ao lado é metade do
   trabalho de um componente destes. */
.s4-sel-botao {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s4-e2);
    width: 100%;
    height: calc(1.5em + 1.1rem + 2px);
    padding: .55rem .85rem;
    background: var(--s4-superficie);
    border: 1px solid var(--s4-linha-forte);
    border-radius: var(--s4-r-sm);
    color: var(--s4-texto);
    font-size: 1rem;
    text-align: left;
    transition: border-color var(--s4-rapido) var(--s4-curva),
                box-shadow var(--s4-rapido) var(--s4-curva);
}

.s4-sel-botao:hover:not(:disabled) { border-color: #C9CDDC; }

.s4-sel-botao:focus-visible,
.s4-sel-aberto .s4-sel-botao {
    border-color: var(--s4-azul);
    box-shadow: var(--s4-foco);
    outline: none;
}

.s4-sel-botao:disabled {
    background: var(--s4-superficie-2);
    color: var(--s4-ténue);
    cursor: not-allowed;
}

.s4-sel-valor {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.s4-sel-seta {
    flex: 0 0 auto;
    width: 8px;
    height: 8px;
    margin-right: 2px;
    border-right: 1.5px solid var(--s4-ténue);
    border-bottom: 1.5px solid var(--s4-ténue);
    transform: rotate(45deg) translate(-2px, -2px);
    transition: transform var(--s4-rapido) var(--s4-curva);
}

.s4-sel-aberto .s4-sel-seta { transform: rotate(225deg) translate(-3px, -3px); }

/* O painel vive no <body> e posiciona-se em coordenadas de ecrã. É de propósito:
   dentro do contentor, uma lista aberta numa tabela com overflow ou num cartão
   ficaria cortada pela borda.

   A largura é a dos nomes (S47): max-content, entre a largura do campo e um
   máximo que o sig4road-select.js põe no próprio painel. Até aqui era a do
   campo, e num campo estreito os nomes saíam cortados com reticências. */
.s4-sel-painel {
    position: fixed;
    z-index: 1080;
    width: max-content;
    display: flex;
    flex-direction: column;
    background: var(--s4-superficie);
    border: 1px solid var(--s4-linha-forte);
    border-radius: var(--s4-r-md);
    box-shadow: var(--s4-sombra-lg);
    overflow: hidden;
    animation: s4-sel-entra var(--s4-normal) var(--s4-curva) both;
    transform-origin: top center;
}

@keyframes s4-sel-entra {
    from { opacity: 0; transform: translateY(-6px) scale(.99); }
    to { opacity: 1; transform: none; }
}

/* A procura é o cabeçalho do painel, não um campo dentro dele: sem contorno
   próprio, encostada ao topo, com a lupa por dentro. Um campo com moldura
   dentro de uma caixa que já tem moldura são duas molduras a dizer o mesmo. */
.s4-sel-procura {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--s4-e2);
    padding: 0 var(--s4-e3);
    border-bottom: 1px solid var(--s4-linha);
    flex: 0 0 auto;
}

.s4-sel-lupa {
    flex: 0 0 auto;
    width: 13px;
    height: 13px;
    border: 1.5px solid var(--s4-ténue);
    border-radius: var(--s4-r-pill);
    position: relative;
}

.s4-sel-lupa::after {
    content: "";
    position: absolute;
    right: -4px;
    bottom: -3px;
    width: 5px;
    height: 1.5px;
    background: var(--s4-ténue);
    transform: rotate(45deg);
}

.s4-sel-campo {
    flex: 1 1 auto;
    width: 100%;
    height: 42px;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--s4-texto);
    font-size: .95rem;
}

.s4-sel-campo:focus { outline: none; }

/* A pesquisa é o cabeçalho do painel e o cursor já diz onde está o foco: sem o anel azul dos campos,
   que num campo de texto aparece mesmo com o foco posto por código — e, desde que a pesquisa abre
   sempre (S47), aparecia em todas as listas. */
.s4-sel-campo:focus-visible { box-shadow: none !important; }

.s4-sel-campo::placeholder { color: var(--s4-ténue); }

.s4-sel-lista {
    overflow-y: auto;
    overscroll-behavior: contain;   /* chegar ao fim da lista não faz a página rolar */
    padding: var(--s4-e1);
    flex: 1 1 auto;
}

.s4-sel-op {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s4-e2);
    padding: .5rem .65rem;
    border-radius: var(--s4-r-sm);
    cursor: pointer;
}

/* Um nome que não caiba nem na largura máxima parte para a linha de baixo:
   nunca se corta (S47). Uma opção cortada obrigava a escolher às cegas entre
   duas que começavam da mesma maneira. */
.s4-sel-op-texto {
    min-width: 0;
    white-space: normal;
    overflow-wrap: anywhere;
}

/* O trecho que corresponde ao que se escreveu. Sublinhado e não fundo
   amarelo: numa lista de trinta resultados, trinta manchas de cor tornam a
   lista mais difícil de ler, não mais fácil. */
.s4-sel-realce {
    color: var(--s4-azul-forte);
    font-weight: 600;
    box-shadow: inset 0 -1px 0 var(--s4-azul);
}

/* A marca de escolhida. Um visto desenhado com duas bordas — sem tipo de
   letra de ícones, que este painel não carrega. */
.s4-sel-visto {
    flex: 0 0 auto;
    width: 6px;
    height: 10px;
    margin-right: 3px;
    border-right: 2px solid var(--s4-azul);
    border-bottom: 2px solid var(--s4-azul);
    transform: rotate(45deg);
}

/* Duas marcas distintas de propósito: "ativa" é onde está o teclado, "escolhida"
   é o valor atual. São coisas diferentes e confundi-las torna a navegação por
   teclado impossível de seguir. */
.s4-sel-op-ativa { background: var(--s4-superficie-2); }

.s4-sel-op-escolhida {
    color: var(--s4-azul-forte);
    font-weight: 600;
}

.s4-sel-op-escolhida.s4-sel-op-ativa { background: var(--s4-azul-fraco); }

.s4-sel-op-desativada {
    color: var(--s4-ténue);
    cursor: not-allowed;
}

.s4-sel-vazio {
    padding: var(--s4-e5) var(--s4-e3);
    color: var(--s4-suave);
    font-size: .85rem;
    text-align: center;
    line-height: 1.6;
}

.s4-sel-vazio-titulo {
    color: var(--s4-tinta);
    font-weight: 600;
    margin-bottom: var(--s4-e1);
}

.s4-sel-mais {
    padding: var(--s4-e3) var(--s4-e2);
    color: var(--s4-ténue);
    font-size: .85rem;
    text-align: center;
}

.s4-sel-mais { border-top: 1px dashed var(--s4-linha); }

/* -------------------------------------- 18. campos do Kendo (filtros da SV) */

/* Os filtros da Sinalização Vertical constroem os campos com Kendo, que traz o
   seu próprio aspeto: molduras de 3,5 px de raio, 31 px de altura e etiquetas
   cinzentas quadradas, ao lado de campos da aplicação com 6 px de raio e 38 px.
   Lado a lado pareciam dois produtos diferentes.
   
   Não se trocou o Kendo por outra coisa: seria refazer um ecrã de 1200 linhas
   por razões estéticas, e é precisamente o ecrã que já partiu uma vez. O que
   se faz aqui é vesti-lo com a mesma roupa dos outros campos.

   Sobre o !important: a folha do Kendo é carregada pela PÁGINA, portanto
   depois desta. Sem ele, regras de igual especificidade dele ganham às daqui.
   Está limitado às propriedades da moldura, e não espalhado. */

.filter .k-widget,
.filter .k-multiselect,
.filter .k-dropdown,
.filter .k-datepicker,
.filter .k-numerictextbox,
.filter .k-combobox {
    width: 100%;
}

.filter .k-multiselect-wrap,
.filter .k-dropdown-wrap,
.filter .k-picker-wrap,
.filter .k-numeric-wrap,
.filter .k-dateinput-wrap {
    /* 38 px em número redondo e não em `em`: dentro de .filter o tema reduz o
       tipo de letra para 0,9 rem e a conta relativa dava 36,3 px — dois pixéis
       a menos do que os campos ao lado, que é quanto basta para uma linha de
       filtros parecer mal alinhada. */
    min-height: 38px !important;
    padding: 0 .35rem 0 .5rem !important;
    background: var(--s4-superficie) !important;
    border: 1px solid var(--s4-linha-forte) !important;
    border-radius: var(--s4-r-sm) !important;
    box-shadow: none !important;
    transition: border-color var(--s4-rapido) var(--s4-curva),
                box-shadow var(--s4-rapido) var(--s4-curva);
}

.filter .k-multiselect-wrap:hover,
.filter .k-dropdown-wrap:hover,
.filter .k-picker-wrap:hover,
.filter .k-numeric-wrap:hover {
    border-color: #C9CDDC !important;
}

/* Um anel de foco só, igual ao dos restantes campos da aplicação. */
.filter .k-state-focused .k-multiselect-wrap,
.filter .k-state-focused .k-dropdown-wrap,
.filter .k-state-focused .k-picker-wrap,
.filter .k-state-focused .k-numeric-wrap,
.filter .k-multiselect-wrap.k-state-focused,
.filter .k-dropdown-wrap.k-state-focused,
.filter .k-state-border-down .k-dropdown-wrap,
.filter .k-multiselect.k-state-focused .k-multiselect-wrap {
    border-color: var(--s4-azul) !important;
    box-shadow: var(--s4-foco) !important;
}

.filter .k-input,
.filter .k-dropdown-wrap .k-input,
.filter .k-multiselect-wrap .k-input {
    color: var(--s4-texto);
    font-size: 1rem;
    height: auto;
    padding: .45rem 0;
}

.filter .k-input::placeholder { color: var(--s4-ténue); }

/* As etiquetas das entidades escolhidas. Eram retângulos cinzentos com um X a
   negro; passam a chips da mesma família das etiquetas de estado do resto da
   aplicação, com o X discreto até se lhe passar o rato por cima. */
.filter .k-multiselect-wrap .k-button {
    background: var(--s4-azul-fraco) !important;
    border: 1px solid transparent !important;
    border-radius: var(--s4-r-sm) !important;
    color: var(--s4-azul-forte) !important;
    font-size: .82rem;
    font-weight: 600;
    line-height: 1.4;
    margin: .2rem .25rem .2rem 0 !important;
    padding: .2rem .2rem .2rem .5rem !important;
}

.filter .k-multiselect-wrap .k-button .k-select {
    margin-left: .3rem !important;
    opacity: .55;
    transition: opacity var(--s4-rapido) var(--s4-curva);
}

.filter .k-multiselect-wrap .k-button:hover .k-select { opacity: 1; }

.filter .k-multiselect-wrap .k-button .k-icon { color: var(--s4-azul-forte); }

/* A seta e o calendário à direita, do mesmo cinzento das nossas. */
.filter .k-select,
.filter .k-icon {
    color: var(--s4-ténue);
}

.filter .k-dropdown-wrap .k-select,
.filter .k-picker-wrap .k-select {
    background: transparent !important;
    border: 0 !important;
}

/* As listas que o Kendo abre passam a ter a mesma caixa das nossas. */
.k-animation-container .k-list-container,
.k-animation-container .k-popup {
    border: 1px solid var(--s4-linha-forte) !important;
    border-radius: var(--s4-r-md) !important;
    box-shadow: var(--s4-sombra-lg) !important;
    padding: var(--s4-e1);
}

.k-animation-container .k-list .k-item {
    border-radius: var(--s4-r-sm);
    padding: .45rem .6rem;
}

.k-animation-container .k-list .k-item.k-state-hover,
.k-animation-container .k-list .k-item:hover {
    background: var(--s4-superficie-2) !important;
    color: var(--s4-tinta) !important;
}

.k-animation-container .k-list .k-item.k-state-selected {
    background: var(--s4-azul-fraco) !important;
    color: var(--s4-azul-forte) !important;
    font-weight: 600;
}

/* O cabeçalho de cada bloco de filtros. Era uma linha azul pequena que se lia
   como uma ligação; passa a um título de secção. */
.filter > .card-label,
.filter .card-label.text-primary {
    color: var(--s4-ténue) !important;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
}

.filter .form-group { margin-bottom: var(--s4-e4); }

.filter label,
.filter .control-label {
    color: var(--s4-suave);
    font-size: .82rem;
    font-weight: 500;
}

/* ------------------------------------------------- 19. legendas e caixas de seleção */

/* O tema dá 18 x 18 px a QUALQUER <span> filho direto de .checkbox, e não só ao
   quadradinho. Quem lá puser texto num <span> vê-o espremido em 18 px e a
   entornar por cima do que estiver ao lado — foi o que aconteceu ao interruptor
   de conformidade do mapa, cuja legenda saía por cima da linha dos filtros.
   
   O padrão do tema é escrever o texto solto a seguir ao <span> do quadradinho.
   Quando o texto precisa de marcação por dentro, usa-se esta classe. */
.checkbox > span.s4-etiqueta,
.radio > span.s4-etiqueta {
    /* display normal é a parte que interessa, e não a largura.
       O tema faz destes <span> caixas de seleção a sério: display:flex,
       align-items:center, justify-content:center, flex-wrap:nowrap. Dentro de
       um contentor flex os nós de texto só com espaços são DESCARTADOS — foi
       por isso que "pela" e "conformidade" apareciam colados, sem espaço entre
       eles. E o nowrap impedia a frase de quebrar, atropelando o que estivesse
       ao lado em ecrãs mais estreitos do que a frase.
       Aqui o <span> volta a ser o que é: texto corrido. */
    display: inline;
    align-items: initial;
    justify-content: initial;
    flex-wrap: initial;

    /* O tema põe flex-shrink:0 nestes <span> para o quadradinho nunca encolher.
       Herdado por uma frase, faz com que ela nunca quebre: transborda a coluna
       e atropela o que estiver à direita. Aqui quer-se o contrário — que encolha
       e quebre. O min-width:0 é o que permite a um item flex ficar mais estreito
       do que o seu conteúdo. */
    flex: 1 1 auto;
    min-width: 0;

    width: auto;
    height: auto;
    background: transparent;
    border: 0;
    margin-left: var(--s4-e3);
    line-height: 1.5;
}

/* --- legenda de mapa ou de gráfico ------------------------------------------
   Duas leituras diferentes — o que a cor quer dizer, e o que cada forma é —
   agrupadas e separadas, em vez de uma frase corrida que ninguém lê. */
.s4-legenda {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s4-e3) var(--s4-e6);
    padding: var(--s4-e3) 0 var(--s4-e4);
    border-top: 1px solid var(--s4-linha);
    margin-top: var(--s4-e3);
}

.s4-legenda-grupo {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s4-e2) var(--s4-e4);
}

.s4-legenda-titulo {
    color: var(--s4-ténue);
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
}

.s4-chave {
    display: inline-flex;
    align-items: center;
    gap: var(--s4-e2);
    color: var(--s4-suave);
    font-size: .82rem;
    white-space: nowrap;
}

.s4-chave-ponto {
    width: 10px;
    height: 10px;
    border-radius: var(--s4-r-pill);
    flex: 0 0 auto;
}

.s4-chave-traco {
    width: 16px;
    height: 3px;
    border-radius: var(--s4-r-pill);
    background: #187DE4;
    flex: 0 0 auto;
}

.s4-chave-area {
    width: 14px;
    height: 10px;
    background: rgba(255, 168, 0, .18);
    border: 1px solid var(--s4-amarelo);
    border-radius: 2px;
    flex: 0 0 auto;
}

/* O marcador da SV é uma gota, como no mapa. */
.s4-chave-pino {
    width: 10px;
    height: 10px;
    background: var(--s4-suave);
    border-radius: 50% 50% 50% 0;
    transform: rotate(-45deg);
    flex: 0 0 auto;
}

@media (max-width: 767.98px) {
    .s4-legenda { gap: var(--s4-e3); }
    .s4-legenda-grupo { width: 100%; }
}

/* ------------------------------------------------------------- 20. paginação */

/* São ligações normais, não botões de JavaScript: funcionam com a navegação
   parcial sem saberem que ela existe, abrem noutro separador e entram no
   histórico. O desenho é que tem de parecer um controlo. */
.s4-paginacao {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--s4-e3) var(--s4-e5);
    padding: var(--s4-e4) 0;
    border-top: 1px solid var(--s4-linha);
    margin-top: var(--s4-e2);
    color: var(--s4-suave);
    font-size: .85rem;
}

/* A contagem é um número que se lê a comparar com o de ontem: alinha melhor
   com algarismos de largura fixa. */
.s4-paginacao-conta,
.s4-pagina {
    font-variant-numeric: tabular-nums;
}

.s4-paginacao-conta b { color: var(--s4-tinta); font-weight: 600; }

.s4-paginas,
.s4-paginacao-tamanho {
    display: flex;
    align-items: center;
    gap: var(--s4-e1);
}

.s4-paginacao-tamanho { gap: var(--s4-e1); }

.s4-pagina {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 32px;
    height: 32px;
    padding: 0 var(--s4-e2);
    border-radius: var(--s4-r-sm);
    border: 1px solid transparent;
    color: var(--s4-texto);
    font-weight: 500;
    text-decoration: none;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

a.s4-pagina:hover {
    background: var(--s4-superficie-2);
    border-color: var(--s4-linha-forte);
    color: var(--s4-tinta);
    text-decoration: none;
}

.s4-pagina-atual {
    background: var(--s4-azul);
    border-color: var(--s4-azul);
    color: #fff;
    font-weight: 600;
    cursor: default;
}

/* Desativado tem de LER-SE como desativado, e não apenas não reagir. */
.s4-pagina-inativa {
    color: var(--s4-ténue);
    pointer-events: none;
}

.s4-pagina-corte {
    padding: 0 var(--s4-e1);
    color: var(--s4-ténue);
}

@media (max-width: 575.98px) {
    .s4-paginacao { justify-content: center; }
    /* Num ecrã estreito o que interessa é avançar e recuar; a escolha de
       tamanho é uma afinação que ninguém faz no telemóvel. */
    .s4-paginacao-tamanho { display: none; }
}

/* ------------------------------------------------------ 21. amostra de cor */

/* A cor da tinta escrita por extenso obriga a traduzir; a cor desenhada não.

   O contorno não é opcional e não é o das tabelas: a tinta branca é a mais
   comum de todas, e com a linha clara das grelhas (#E9EBF2) a amostra branca
   sobre fundo branco desaparecia — media-se e lá estava ela, 14 por 14, mas
   invisível. Leva o cinzento das etiquetas, que se vê. */
.s4-amostra-cor {
    display: inline-block;
    width: 14px;
    height: 14px;
    margin-right: var(--s4-e2);
    border: 1px solid var(--s4-ténue);
    border-radius: 3px;
    vertical-align: -2px;
}

/* A amostra e o nome da cor são uma coisa só: sem isto, numa coluna
   apertada o quadrado ficava numa linha e "Amarela" na seguinte. */
.s4-cor-tinta { white-space: nowrap; }

/* ------------------------------------------------------- 22. (vago) */

/* Aqui esteve a grelha de "indicadores" neutros que substituiu os mosaicos
   coloridos da dashboard. Foi um erro e saiu: ver a secção 28. O número fica
   vago de propósito, para as referências às outras secções não mudarem. */

/* ------------------------------------------------- 23. controlo segmentado */

/* Duas ou três opções lado a lado, uma delas ativa. Não é um dropdown: com
   poucas opções, vê-las todas de uma vez custa menos do que abrir uma lista,
   e a ativa fica evidente pelo fundo cheio — não precisa de legenda. */
.s4-segmentado {
    display: inline-flex;
    /* Dentro de um pai em flex ou grid, um inline-flex é "blockificado" para flex
       e esticado à largura toda — medido na pré-visualização: 1232 px de pílula.
       O max-content mantém-no do tamanho do conteúdo seja quem for o pai. */
    width: max-content;
    max-width: 100%;
    align-items: center;
    gap: 2px;
    padding: 3px;
    margin-bottom: var(--s4-e5);
    background: var(--s4-superficie);
    border: 1px solid var(--s4-linha-forte);
    border-radius: var(--s4-r-pill);
}

.s4-segmentado-opcao {
    display: inline-block;
    padding: 6px 16px;
    border-radius: var(--s4-r-pill);
    font-size: .85rem;
    font-weight: 600;
    line-height: 1.4;
    color: var(--s4-suave);
    text-decoration: none;
    transition: background-color var(--s4-rapido) var(--s4-curva),
                color var(--s4-rapido) var(--s4-curva);
}

.s4-segmentado-opcao:hover,
.s4-segmentado-opcao:focus {
    color: var(--s4-azul-forte);
    background: var(--s4-azul-fraco);
    text-decoration: none;
}

.s4-segmentado-opcao.is-ativa,
.s4-segmentado-opcao.is-ativa:hover,
.s4-segmentado-opcao.is-ativa:focus {
    color: #FFFFFF;
    background: var(--s4-azul);
}

.s4-segmentado-opcao:focus-visible {
    outline: none;
    box-shadow: var(--s4-foco);
}

/* --------------------------------------------- 24. estado geral (semáforo) */

/* Uma barra empilhada e a legenda com os números. É o único sítio da primeira
   dobra da dashboard onde a cor manda — e é por isso que manda aqui: aqui ela
   quer dizer alguma coisa. A quarta fatia é cinzenta de propósito: "sem
   medição" não é "não cumpre". */
.s4-semaforo + .s4-semaforo { margin-top: var(--s4-e5); }

.s4-semaforo-titulo {
    font-size: .85rem;
    font-weight: 600;
    color: var(--s4-suave);
    margin-bottom: var(--s4-e3);
}

.s4-semaforo-barra {
    display: flex;
    height: 14px;
    border-radius: var(--s4-r-pill);
    overflow: hidden;
    background: var(--s4-superficie-2);
}

.s4-semaforo-fatia { display: block; height: 100%; }
.s4-semaforo-fatia + .s4-semaforo-fatia { margin-left: 2px; }

.s4-semaforo--verde { background: var(--s4-verde); }
.s4-semaforo--amarelo { background: var(--s4-amarelo); }
.s4-semaforo--vermelho { background: var(--s4-vermelho); }
.s4-semaforo--neutro { background: var(--s4-linha-forte); }

.s4-semaforo-legenda {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s4-e2) var(--s4-e5);
    list-style: none;
    margin: var(--s4-e4) 0 0;
    padding: 0;
    font-size: .85rem;
    color: var(--s4-suave);
}

.s4-semaforo-legenda b {
    color: var(--s4-tinta);
    font-variant-numeric: tabular-nums;
    margin-right: var(--s4-e1);
}

.s4-semaforo-ponto {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    margin-right: var(--s4-e2);
    vertical-align: -1px;
}

/* ----------------------------------------- 25. listas de atenção e recentes */

/* "Precisa de atenção": o quê, quantos, para onde. O tom pinta só o ponto e o
   número — uma linha inteira a vermelho gritava mais do que tinha para dizer. */
.s4-lista-atencao,
.s4-lista-recentes {
    list-style: none;
    margin: 0;
    padding: 0;
}

.s4-lista-atencao-item + .s4-lista-atencao-item,
.s4-lista-recentes-item + .s4-lista-recentes-item {
    border-top: 1px solid var(--s4-linha);
}

.s4-lista-atencao-ligacao {
    display: flex;
    align-items: center;
    gap: var(--s4-e3);
    padding: var(--s4-e3) 0;
    color: var(--s4-texto);
    text-decoration: none;
}

a.s4-lista-atencao-ligacao:hover,
a.s4-lista-atencao-ligacao:focus {
    color: var(--s4-azul-forte);
    text-decoration: none;
}

.s4-lista-atencao-ponto {
    flex: 0 0 auto;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--s4-ténue);
}

.s4-lista-atencao-n {
    flex: 0 0 auto;
    min-width: 2.2ch;
    text-align: right;
    font-variant-numeric: tabular-nums;
    color: var(--s4-tinta);
}

.s4-lista-atencao-texto { flex: 1 1 auto; }

.s4-lista-atencao-seta {
    flex: 0 0 auto;
    color: var(--s4-ténue);
    font-size: 1.2rem;
    line-height: 1;
}

.s4-tom--alerta .s4-lista-atencao-ponto { background: var(--s4-vermelho); }
.s4-tom--alerta .s4-lista-atencao-n { color: var(--s4-vermelho); }
.s4-tom--atencao .s4-lista-atencao-ponto { background: var(--s4-amarelo); }
.s4-tom--bom .s4-lista-atencao-ponto { background: var(--s4-verde); }

/* Recentes: quando à esquerda em coluna fixa e monoespaçada nos números, o quê
   à direita. Cada linha abre a ficha. */
.s4-lista-recentes-item {
    display: flex;
    align-items: baseline;
    gap: var(--s4-e4);
    padding: var(--s4-e3) 0;
}

.s4-lista-recentes-quando {
    flex: 0 0 auto;
    min-width: 11ch;
    font-size: .8rem;
    color: var(--s4-ténue);
    font-variant-numeric: tabular-nums;
}

.s4-lista-recentes-texto {
    flex: 1 1 auto;
    color: var(--s4-texto);
    text-decoration: none;
}

a.s4-lista-recentes-texto:hover,
a.s4-lista-recentes-texto:focus {
    color: var(--s4-azul-forte);
    text-decoration: none;
}

/* O estado vazio dentro de um cartão da dashboard é mais baixo do que o de uma
   listagem inteira: partilha a linha com outros cartões. */
.s4-vazio--compacto { padding: var(--s4-e5) var(--s4-e4); }
.s4-vazio--compacto .s4-vazio-icone { width: 40px; height: 40px; margin-bottom: var(--s4-e3); }

/* "Nada precisa de si" é uma boa notícia e parece uma. */
.s4-vazio--bom .s4-vazio-icone {
    color: var(--s4-verde);
    background: var(--s4-verde-fraco);
    border-color: transparent;
}

@media (max-width: 575.98px) {
    .s4-lista-recentes-item { flex-direction: column; gap: var(--s4-e1); }
}

/* ---------------------------------------------- 26. cartões de gráfico */

/* O cartão é o do tema. O que muda é o cabeçalho poder levar o interruptor das
   vistas à direita do título, e a área do gráfico ter altura mínima para a
   página não saltar enquanto o ApexCharts desenha. */
.s4-cartao-grafico .card-header { flex-wrap: wrap; }

.s4-cartao-grafico .card-label { display: block; }

.s4-cartao-grafico .card-label small {
    display: block;
    margin-top: 2px;
    font-size: .8rem;
    font-weight: 400;
    color: var(--s4-suave);
}

.s4-grafico { min-height: 300px; }

/* A opção do controlo segmentado pode ser uma ligação (o interruptor da página,
   que muda de endereço) ou um botão (o das vistas de um gráfico, que não muda).
   O botão tem de perder o aspeto de botão do browser; o resto herda da secção
   23, incluindo o estado ativo, que ganha por especificidade. */
button.s4-segmentado-opcao {
    border: 0;
    background: transparent;
    font-family: inherit;
    cursor: pointer;
}

/* Dentro de um cabeçalho de cartão o interruptor é mais baixo, e não leva a
   margem de baixo que faz sentido quando separa a página do que vem a seguir. */
.s4-segmentado--compacto {
    margin-bottom: 0;
    padding: 2px;
}

.s4-segmentado--compacto .s4-segmentado-opcao {
    padding: 4px 12px;
    font-size: .8rem;
}

/* O ApexCharts traz tipos de letra e cores próprios. A letra já herda (pedimos
   `fontFamily: inherit`); estas duas regras são o que falta para as legendas e
   os eixos falarem a língua do resto da aplicação. */
.apexcharts-canvas text { font-family: inherit !important; }

.apexcharts-legend-text {
    color: var(--s4-texto) !important;
    font-size: .85rem !important;
}

@media (max-width: 575.98px) {
    .s4-cartao-grafico .card-header { padding-left: var(--s4-e4); padding-right: var(--s4-e4); }
}

/* ------------------------------------------------- 27. mapa da dashboard */

/* O mapa desenha-se DEPOIS da página, e só quando está a chegar ao ecrã. Até
   lá o contentor já tem a altura final: sem isso, a página saltava por baixo
   do cursor no momento em que o mapa entrasse. */
.s4-mapa {
    position: relative;
    /* 560 px. O mapa da dashboard de produção é a peça grande da página e é assim
       que se lê um traçado de via sem ter de o abrir noutro ecrã. */
    height: 560px;
    border-radius: var(--s4-r-md);
    overflow: hidden;
    /* Enquanto não há mapa, uma grelha ténue em vez de um rectângulo cinzento:
       lê-se como "vai aqui um mapa" e não como "isto avariou". Some assim que
       o mapa entra (.is-carregado). */
    background-color: var(--s4-superficie-2);
    background-image:
        linear-gradient(var(--s4-linha) 1px, transparent 1px),
        linear-gradient(90deg, var(--s4-linha) 1px, transparent 1px);
    background-size: 44px 44px, 44px 44px;
}

.s4-mapa.is-carregado { background: none; }

/* "A carregar", "ainda não há nada com coordenadas" e "não foi possível
   carregar" ocupam o mesmo sítio. O erro do mapa não apaga o resto da página:
   é a única parte que depende de um segundo pedido. */
.s4-mapa-estado {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    padding: var(--s4-e5);
    text-align: center;
    font-size: .9rem;
    color: var(--s4-suave);
}

.s4-mapa-estado--erro { color: var(--s4-vermelho); }

@media (max-width: 767.98px) {
    .s4-mapa { height: 340px; }
}

/* --- os balões das obras no mapa (S38) ---------------------------------------
   Com o mapa afastado, uma obra pequena de mais para se ver é um balão: o
   número de marcas no meio e, à volta, o anel com as fatias da conformidade (o
   fundo em conic-gradient vem do sh-render.js). O balão é um elemento normal,
   preso ao mapa pelo sh-render.js; o aspeto é todo daqui. */
.s4-balao {
    position: absolute;
    transform: translate(-50%, -24px);   /* o centro do anel fica em cima do ponto */
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--s4-e1);
    cursor: pointer;
    user-select: none;
}

.s4-balao-anel {
    width: 48px;
    height: 48px;
    padding: 5px;
    box-sizing: border-box;
    border-radius: 50%;
    box-shadow: 0 0 0 2px #fff, var(--s4-sombra-lg);
    transition: transform var(--s4-normal) var(--s4-curva);
}

.s4-balao:hover .s4-balao-anel { transform: scale(1.08); }

.s4-balao-miolo {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background: var(--s4-superficie);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 15px;
    font-weight: 700;
    line-height: 1;
    color: var(--s4-tinta);
}

.s4-balao-nome {
    max-width: 170px;
    padding: 2px 9px;
    border-radius: var(--s4-r-pill);
    background: rgba(255, 255, 255, .94);
    color: var(--s4-tinta);
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    box-shadow: var(--s4-sombra-sm);
}

/* --- a dica ao passar o rato por uma marca (S38) ---------------------------
   Um cartão escuro que segue o rato, por cima de tudo e sem o apanhar: a linha e
   o sentido, o veredicto com o RL, e o tipo e o sublanço mais fracos. */
.s4-dica {
    position: absolute;
    transform: translate(14px, -100%);
    max-width: 320px;
    padding: 6px 10px;
    border-radius: var(--s4-r-sm);
    background: rgba(24, 28, 50, .92);
    color: #fff;
    font-size: 12px;
    line-height: 1.4;
    white-space: nowrap;
    pointer-events: none;
    box-shadow: var(--s4-sombra-md);
}

.s4-dica-titulo { font-weight: 600; }

.s4-dica-fraca {
    opacity: .72;
    font-size: 11px;
    overflow: hidden;
    text-overflow: ellipsis;
}

.s4-dica-ponto {
    display: inline-block;
    width: 8px;
    height: 8px;
    margin-right: 6px;
    border-radius: 50%;
    vertical-align: 1px;
}

/* --- o nome do sublanço junto ao troço (S38) --------------------------------
   Um rótulo claro preso ao meio da linha mais comprida do sublanço, à direita
   dela; some quando a obra é um balão, que já tem o nome. */
.s4-rotulo {
    position: absolute;
    transform: translate(16px, -50%);
    max-width: 320px;
    padding: 2px 9px;
    border-radius: var(--s4-r-pill);
    background: rgba(255, 255, 255, .92);
    color: var(--s4-tinta);
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    pointer-events: none;
    box-shadow: var(--s4-sombra-sm);
}

/* Na legenda, o mesmo anel em ponto pequeno. */
.s4-chave-balao {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: conic-gradient(var(--s4-vermelho) 0 120deg, var(--s4-amarelo) 120deg 200deg, var(--s4-verde) 200deg 300deg, #B5B5C3 300deg 360deg);
    box-shadow: inset 0 0 0 3px #fff;
    flex: 0 0 auto;
}

/* --------------------------------------------------- 28. mosaicos da dashboard */

/* Os mosaicos coloridos da primeira dobra — azul, verde-água, laranja, cinza e
   roxo. São a parte da página que quem a usa há anos reconhece sem ler.

   Cheguei a substituí-los por cartões brancos neutros, com o argumento de que
   "a cor só deve aparecer onde significa alguma coisa". O argumento está certo
   para a cor de SINAL (verde/amarelo/vermelho da conformidade) e errado para
   a cor de IDENTIDADE: tirar-lhes a cor não tornou a página sóbria, tornou-a
   ilegível — cinco cartões brancos iguais em que já não se distingue nada e
   nada chama o olho. Ficam como estavam. */

/* 150 px era a altura fixa do original. Fixa, o mosaico dos sinais ativos
   cortava a linha de contexto ("de 951 registados") a 3 px do fundo — medido.
   Passa a ser mínimo: os mosaicos de uma linha igualam-se pelo mais alto
   (card-stretch) e o que tem contexto cresce o que precisa. */
.s4-mosaico {
    min-height: 150px;
}

.s4-mosaico .card-body {
    padding: 1.75rem;
}

/* A ligação preenche o mosaico todo: o alvo do clique é o cartão, não o texto. */
.s4-mosaico > a {
    display: block;
    height: 100%;
    color: inherit;
    text-decoration: none;
}

.s4-mosaico > a:hover,
.s4-mosaico > a:focus {
    color: inherit;
    text-decoration: none;
}

/* O original não reagia ao rato em lado nenhum. Um milímetro de elevação chega
   para dizer que aquilo se pode carregar. */
.s4-mosaico {
    transition: transform var(--s4-rapido) var(--s4-curva),
                box-shadow var(--s4-rapido) var(--s4-curva);
}

.s4-mosaico:hover {
    transform: translateY(-2px);
    box-shadow: var(--s4-sombra-md);
}

/* "de 951 registados", "3 provisórias" — o contexto que evitou um segundo
   mosaico a dizer quase o mesmo. Branco a 70 %: lê-se, sem competir com o
   número. */
.s4-mosaico-contexto {
    color: rgba(255, 255, 255, .7);
    line-height: 1.3;
    margin-top: 2px;
}

/* Os cartões da primeira dobra partilham a linha com o bloco dos mosaicos, que
   é alto. O conteúdo encosta ao topo em vez de se espalhar pelo meio: uma lista
   de três linhas centrada em 500 px de cartão parece um erro. */
.s4-estado-geral .card-body,
.s4-atencao .card-body,
.s4-recentes .card-body {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
}

/* Com o cartão esticado, as listas ganham ar entre linhas em vez de o deixarem
   todo no fim. */
.s4-atencao .s4-lista-atencao-ligacao { padding: var(--s4-e4) 0; }
.s4-recentes .s4-lista-recentes-item { padding: var(--s4-e4) 0; }

/* ------------------------------------- 29. últimos registos e composição */

/* O cabeçalho cheio do cartão dos últimos registos — a cor, o logótipo e o
   título a branco. Cheguei a trocá-lo por um cabeçalho branco igual aos
   outros; perdeu-se a única coisa que dava cara ao cartão numa fila de
   cartões brancos. */
.s4-recentes-cabecalho {
    display: flex;
    align-items: center;
    gap: var(--s4-e3);
    border-top-left-radius: var(--s4-r-md);
    border-top-right-radius: var(--s4-r-md);
    min-height: 0;
    padding-top: var(--s4-e4);
    padding-bottom: var(--s4-e4);
}

.s4-recentes-cabecalho .svg-icon { line-height: 0; }

/* Cada linha: a data em etiqueta, e à direita as imagens dos sinais — que é o
   que faz reconhecer o registo sem o abrir. */
.s4-lista-recentes-item {
    display: flex;
    align-items: center;
    gap: var(--s4-e4);
    padding: var(--s4-e3) 0;
}

.s4-lista-recentes-quando {
    flex: 0 0 auto;
    font-size: .78rem;
    font-weight: 600;
    color: var(--s4-suave);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.s4-lista-recentes-conteudo {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
    text-decoration: none;
}

a.s4-lista-recentes-conteudo:hover,
a.s4-lista-recentes-conteudo:focus { text-decoration: none; }

.s4-lista-recentes-simbolos {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
}

.s4-lista-recentes-simbolos img {
    height: 26px;
    width: auto;
    max-width: 44px;
    object-fit: contain;
}

a.s4-lista-recentes-conteudo:hover .s4-lista-recentes-simbolos img { opacity: .82; }

.s4-lista-recentes-aviso {
    font-size: .82rem;
    font-style: italic;
    color: var(--s4-azul);
    text-decoration: underline;
}

.s4-lista-recentes-texto {
    color: var(--s4-texto);
    text-decoration: none;
}

a.s4-lista-recentes-conteudo:hover .s4-lista-recentes-texto { color: var(--s4-azul-forte); }

/* A composição: nome, percentagem, quantos, barra. Rola dentro do cartão
   quando é comprida — uma lista de vinte classes não pode empurrar a coluna
   do lado para fora do ecrã. */
.s4-distribuicao-lista {
    list-style: none;
    margin: 0;
    padding: 0 var(--s4-e2) 0 0;
    max-height: 420px;
    overflow-y: auto;
}

.s4-distribuicao-item { padding: var(--s4-e3) 0; }
.s4-distribuicao-item + .s4-distribuicao-item { border-top: 1px solid var(--s4-linha); }

/* As classes a zero ficam, e ficam apagadas: é informação — quer dizer que a
   classe existe e não tem nada. */
.s4-distribuicao-item.is-vazio { opacity: .55; }

.s4-distribuicao-nome {
    display: block;
    font-weight: 600;
    color: var(--s4-tinta);
    text-decoration: none;
}

a.s4-distribuicao-nome:hover,
a.s4-distribuicao-nome:focus { color: var(--s4-azul-forte); text-decoration: none; }

.s4-distribuicao-numeros {
    display: flex;
    justify-content: space-between;
    gap: var(--s4-e3);
    margin: 2px 0 4px;
    font-size: .78rem;
    font-weight: 600;
    color: var(--s4-suave);
    font-variant-numeric: tabular-nums;
}

.s4-distribuicao-barra {
    height: 5px;
    border-radius: var(--s4-r-pill);
    background: var(--s4-superficie-2);
    overflow: hidden;
}

.s4-distribuicao-barra > span {
    display: block;
    height: 100%;
    border-radius: var(--s4-r-pill);
    background: var(--s4-azul);
}

/* O resumo ao lado do título do mapa. */
.s4-cartao-mapa .card-label small {
    display: block;
    margin-top: 2px;
    font-size: .8rem;
    font-weight: 400;
    color: var(--s4-suave);
}

/* -------------------------------------------------- 30. limites de altura */

/* Nenhuma lista da dashboard pode crescer sem fim. Medido a usar: bastou
   duplicar linhas numa delas para o cartão empurrar a linha toda e a página
   ficar desproporcionada — e o pior é que o que interessa (as primeiras
   linhas) continua visível na mesma, só que agora com 900 px de cartão à
   volta.

   A regra é a mesma em todas: o cartão tem uma altura máxima, a lista rola lá
   dentro, e o cabeçalho e o rodapé ficam sempre à vista. Quem tem trinta
   coisas por fazer vê as primeiras e desce — não perde a página por isso. */
.s4-lista-atencao,
.s4-lista-recentes,
.s4-estado-geral .card-body {
    max-height: 420px;
    overflow-y: auto;
}

/* A barra de rolagem interior é discreta: isto acontece dentro de um cartão, e
   uma barra do sistema a toda a largura chamava mais atenção do que o
   conteúdo. */
.s4-lista-atencao,
.s4-lista-recentes,
.s4-distribuicao-lista,
.s4-estado-geral .card-body {
    scrollbar-width: thin;
    scrollbar-color: var(--s4-linha-forte) transparent;
}

.s4-lista-atencao::-webkit-scrollbar,
.s4-lista-recentes::-webkit-scrollbar,
.s4-distribuicao-lista::-webkit-scrollbar,
.s4-estado-geral .card-body::-webkit-scrollbar { width: 6px; }

.s4-lista-atencao::-webkit-scrollbar-thumb,
.s4-lista-recentes::-webkit-scrollbar-thumb,
.s4-distribuicao-lista::-webkit-scrollbar-thumb,
.s4-estado-geral .card-body::-webkit-scrollbar-thumb {
    background: var(--s4-linha-forte);
    border-radius: var(--s4-r-pill);
}

.s4-lista-atencao::-webkit-scrollbar-track,
.s4-lista-recentes::-webkit-scrollbar-track,
.s4-distribuicao-lista::-webkit-scrollbar-track,
.s4-estado-geral .card-body::-webkit-scrollbar-track { background: transparent; }

/* Com o cartão a esticar até ao vizinho mais alto, o corpo não pode ficar mais
   alto do que o cartão: a lista rola dentro do espaço que sobra. */
.s4-estado-geral,
.s4-atencao,
.s4-recentes,
.s4-distribuicao { overflow: hidden; }

/* ------------------------------------- 31. legenda dos gráficos, em foco */

/* O problema que isto resolve: ao passar o rato num item da legenda, o
   ApexCharts realça a fatia e escurece o resto — e a etiqueta da fatia
   realçada, que é o número que se está a tentar ler, perde brilho com ela.
   Ficava-se a saber QUAL era a fatia e não QUANTO valia.

   A resposta não é lutar com o realce do ApexCharts: é pôr a resposta onde o
   rato já está. O item da legenda diz "A — Perigo  9  (2,4%)", e sob o rato
   passa a escuro e a negrito — o mais legível do ecrã, em vez do mais apagado.
   O centro do donut mostra o mesmo, em grande (ver sig4road-graficos.js). */
.apexcharts-legend-series { cursor: pointer; border-radius: var(--s4-r-sm); }

.apexcharts-legend-series:hover .apexcharts-legend-text {
    color: var(--s4-tinta) !important;
    font-weight: 600 !important;
}

/* Os outros itens não mudam: escurecer o resto para realçar um é o que já se
   está a fazer no gráfico, e fazê-lo duas vezes cansa a leitura. */

/* ------------------------- 32. o numero que desaparecia no realce do donut */

/* A CAUSA, lida no codigo do ApexCharts 3.20 (Series.toggleSeriesOnHover):
   ao passar o rato num item da legenda, ele marca com `legend-mouseover-inactive`
   TODOS os `.apexcharts-series` e TODOS os `.apexcharts-datalabels`, e a seguir
   desmarca apenas o `path` da fatia realcada e o pai dele. Para donuts, a
   variavel que desmarcaria o grupo de etiquetas (`n` no codigo dele) e sempre
   `null` — a condicao que a preenche so corre em graficos de eixos.

   Resultado: a fatia realca, e a percentagem DELA fica com a regra que o
   proprio ApexCharts injecta:

       .legend-mouseover-inactive { transition: .15s ease all; opacity: .20 }

   Vinte por cento de opacidade. Realcava-se uma seccao e perdia-se exactamente
   o numero que se estava a tentar ler.

   A correccao: as etiquetas das fatias nunca se apagam. As fatias continuam a
   apagar-se (o realce mantem-se e le-se bem), e todas as percentagens ficam
   legiveis — incluindo as das outras, que e o que se quer quando se esta a
   comparar duas. */
.apexcharts-datalabels.legend-mouseover-inactive,
.apexcharts-datalabels.legend-mouseover-inactive text,
.apexcharts-datalabels.legend-mouseover-inactive tspan {
    opacity: 1 !important;
}


/* ------------------------------------------------------------------ texto de apoio em tabelas

   Uma celula sem limite de largura numa tabela que calcula as colunas pelo conteudo nao estica
   so a si propria: rouba o espaco a todas as outras. Na listagem de obras, uma descricao com
   duas linhas de texto esmagava o nome da obra, o estado e os botoes.

   Duas linhas, e o resto reticencias; o texto inteiro fica no `title`, para se ler com o rato
   por cima sem abrir nada. O `max-width` e o que trava a coluna — sem ele, o line-clamp corta
   na vertical mas a celula continua a esticar na horizontal. */
.s4-texto-apoio {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    max-width: 38ch;
}

@media (min-width: 1400px) {
    .s4-texto-apoio { max-width: 60ch; }
}

/* Os botoes de uma linha sao uma unidade: partidos em duas linhas deixam de se ler como as
   accoes daquele registo. A celula que os tem nunca quebra. */
td.text-right, th.text-right { white-space: nowrap; }
td.text-right .btn-icon { vertical-align: middle; }


/* ------------------------------------------------------------------ visao conjunta

   Na dashboard conjunta cada sinalizacao e um bloco inteiro, com a grelha de sempre. O
   cabecalho e o que diz onde acaba uma e comeca a outra: um titulo e a ligacao para ver so
   essa. Fino, porque separa; nao compete com os cartoes. */
.s4-bloco-cabecalho {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin: 8px 0 20px;
    padding-top: 20px;
    border-top: 1px solid #EBEDF3;
}

.s4-bloco-cabecalho:first-of-type { border-top: 0; padding-top: 0; }

.s4-bloco-titulo {
    margin: 0;
    font-size: 1.2rem;
    font-weight: 600;
    color: #181C32;
    letter-spacing: -.01em;
}


/* ------------------------------------------------------------------ painel da obra

   A fila de numeros do painel. Cada cartao e uma ligacao inteira (para a listagem filtrada ou
   para o separador), por isso levanta-se ao passar o rato como os mosaicos da dashboard. O
   alerta pinta so o contorno: um cartao inteiro vermelho gritava mais do que "2 em atraso". */
/* Os cartões da fila com a mesma altura (S47): a coluna estica até à do cartão mais alto (a .row é
   flex) e o cartão ocupa-a, menos o espaço de baixo (o gutter-b, --s4-e5). Antes o da conformidade,
   com uma linha a mais, ficava mais alto do que os outros e a fila ficava aos degraus. As cores
   passaram às do sistema (eram hexadecimais soltos). */
.s4-painel-numero { display: block; height: calc(100% - var(--s4-e5)); color: inherit; transition: transform .12s ease, box-shadow .12s ease; }
.s4-painel-numero:hover { color: inherit; text-decoration: none; transform: translateY(-2px); box-shadow: 0 6px 18px rgba(0,0,0,.06); }
.s4-painel-numero--alerta { border-left: 4px solid var(--s4-vermelho); }
.s4-painel-valor { font-size: 1.6rem; font-weight: 700; color: var(--s4-tinta); line-height: 1.1; white-space: nowrap; }
.s4-painel-rotulo { font-size: .85rem; font-weight: 600; color: var(--s4-texto); margin-top: 4px; }
.s4-painel-contexto { font-size: .8rem; color: var(--s4-ténue); margin-top: 2px; }

/* Margens laterais mais curtas nestes cartões (S47). Com as do tema (2,25rem) sobravam 113 px para o
   texto num cartão de 176 px (um portátil a 1536 px), e "Campanhas de ensaio" partia em duas linhas. */
.s4-painel-numero > .card-body { padding-left: 1.25rem; padding-right: 1.25rem; }

/* Seis cartões por linha só a partir de 1600 px; abaixo, três (col-md-4). A 1366 px cada um ficava com
   150 px e partiam-se o rótulo, o contexto e quase a data. (S47) */
@media (min-width: 1600px) {
    .s4-col-sexto { flex: 0 0 16.6667%; max-width: 16.6667%; }
}

/* O cabeçalho do cadastro da obra (S47): o título encolhe e parte o nome em linhas, os botões ficam no
   canto. Num telemóvel continuam a descer, porque o título precisa de pelo menos 22rem. */
.s4-cabeca-obra { gap: var(--s4-e3) var(--s4-e5); }
.s4-cabeca-obra-titulo { flex: 1 1 22rem; min-width: 0; }
.s4-cabeca-obra-acoes { flex: 0 0 auto; display: flex; flex-wrap: wrap; gap: var(--s4-e2); }

/* A linha de grupo nas marcas por trabalho de pintura. */
.s4-grupo-linha td { border-top: 2px solid #EBEDF3; }

/* Passos numerados de um assistente (S29, gerador): o número num círculo, o título ao lado, e uma
   linha à esquerda que junta o que pertence ao passo. */
.s4-passo { border-left: 3px solid #E1F0FF; padding-left: 14px; }
.s4-passo-titulo { align-items: center; color: #3F4254; display: flex; font-size: 1.05rem; font-weight: 600; margin-bottom: .4rem; }
.s4-passo-num { align-items: center; background: #3699FF; border-radius: 50%; color: #FFFFFF; display: inline-flex; flex: 0 0 24px; font-size: .85rem; font-weight: 700; height: 24px; justify-content: center; margin-right: .6rem; width: 24px; }
/* S51b: no gerador, afinar a régua com um sítio cujo PK se conhece — uma caixa calma dentro do passo 3 */
.s4-afinar { background: var(--s4-fundo); border: 1px solid var(--s4-linha); border-radius: var(--s4-r-md); padding: .9rem 1rem; }

/* A barra da obra onde se está (S30), no topo dos ecrãs de dentro da obra: o « Obra, o número e o
   nome da obra, e o ecrã. Parte-se em duas linhas no telemóvel em vez de sair da largura. */
.s4-obra-atual { align-items: center; background: #FFFFFF; border: 1px solid #EBEDF3; border-radius: .42rem; display: flex; flex-wrap: wrap; gap: .35rem .6rem; margin-bottom: 1rem; padding: .55rem .9rem; }
.s4-obra-atual-numero { background: var(--s4-azul-fraco); border-radius: .3rem; color: var(--s4-azul-forte); font-weight: 700; padding: .1rem .5rem; }
.s4-obra-atual-nome { color: #3F4254; font-weight: 600; }
.s4-obra-atual-ecra { color: #7E8299; }

/* As páginas de entrada de Gerais (SH) e Entidade (SH) (S44): uma grelha de cartões que se reparte
   por igual em qualquer largura — dois por linha num portátil, quatro num ecrã grande, um no
   telemóvel — em vez de colunas fixas que deixavam buracos ou apertavam o texto. */
.s4-config-grelha { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); margin-bottom: 1rem; }
.s4-config-cartao { border: 1px solid #EBEDF3; border-radius: .42rem; color: inherit; display: flex; flex-direction: column; padding: 1rem 1.15rem; transition: border-color .12s ease, box-shadow .12s ease, transform .12s ease; }
.s4-config-cartao:hover { border-color: var(--s4-azul); box-shadow: 0 6px 18px rgba(0,0,0,.06); color: inherit; text-decoration: none; transform: translateY(-2px); }
.s4-config-cartao-titulo { color: #181C32; font-size: 1.05rem; font-weight: 600; }
.s4-config-cartao-texto { color: #7E8299; font-size: .9rem; margin-top: .25rem; }

/* ------------------------------------------------------------------ S47 · ecrãs da SH

   Filas de campos que partem de linha. Numa .row de formulário cujas colunas passam para baixo num
   ecrã mais estreito, as duas filas ficavam sem espaço entre si: o rótulo de baixo encostava ao campo
   de cima. O espaço passa a ser de cada coluna, e é o mesmo quer a fila parta quer não. */
.s4-linha-campos > [class*="col"] { margin-bottom: var(--s4-e4); }

/* As cores de sinal em texto, fora das etiquetas: os números da conformidade no cadastro da obra. O
   .text-success do tema é o turquesa (#1BC5BD); a conformidade é o verde da plataforma. */
.s4-sinal-verde { color: var(--s4-verde); }
.s4-sinal-amarelo { color: var(--s4-amarelo); }
.s4-sinal-vermelho { color: var(--s4-vermelho); }

/* "Criar nesta obra" em dois grupos: Cadastro e Medição, cada um com o seu título e os seus botões.
   Os grupos seguem-se na mesma linha, separados por um filete; quando não cabem, o segundo desce
   inteiro e alinha pelo título com o primeiro (até aqui partia um botão sozinho para baixo).

   O filete é o border-left de cada grupo, e o do primeiro de cada linha fica escondido: a linha começa
   uma largura de filete e de espaço à esquerda da caixa (margem negativa) e a caixa corta o que lhe sai
   (overflow hidden). Assim não é preciso JavaScript para saber se o grupo partiu ou não. O padding e a
   margem de 4 px deixam caber o contorno de foco dos botões. */
.s4-criar { overflow: hidden; padding: 4px; margin: -4px; }
.s4-criar-linha { display: flex; flex-wrap: wrap; row-gap: var(--s4-e3); margin-left: calc(-1 * var(--s4-e5) - 1px); }
.s4-criar-grupo { display: flex; align-items: flex-start; gap: var(--s4-e3); padding: 0 var(--s4-e5); border-left: 1px solid var(--s4-linha-forte); }
.s4-criar-titulo { flex: 0 0 auto; min-width: 5.2rem; padding-top: .62rem; color: var(--s4-suave); font-size: .75rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; }
.s4-criar-botoes { display: flex; flex-wrap: wrap; gap: var(--s4-e2); }

@media (max-width: 575.98px) {
    .s4-criar-grupo { flex-direction: column; gap: var(--s4-e2); }
    .s4-criar-titulo { padding-top: 0; }
}

/* Os materiais de um trabalho de pintura: um bloco por material, com os campos em duas filas de quatro.
   Numa linha de tabela com oito colunas as listas ficavam com 120 px e os nomes cortados. */
.s4-material { border: 1px solid var(--s4-linha); border-radius: var(--s4-r-md); padding: var(--s4-e4) var(--s4-e4) 0; margin-bottom: var(--s4-e4); background: var(--s4-superficie); }
.s4-material-cabeca { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--s4-e3); }
.s4-material-titulo { color: var(--s4-tinta); font-weight: 600; }
.s4-material-num { color: var(--s4-suave); }

/* ------------------------------------------------------------------ S48 · o tipo do registo

   Os três tipos lado a lado, cada um com o nome e uma linha a dizer o que é; num ecrã estreito,
   uns por baixo dos outros. O escolhido ganha o contorno e o fundo azuis da plataforma — cor de
   identidade e não de sinal: um tipo não é um estado. O seletor leva .s4-tipos-registo à frente
   porque o tema dá 1rem a qualquer label dentro de um .form-group. */
.s4-tipos-registo { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--s4-e3); }
.s4-tipos-registo .s4-tipo-registo {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin: 0;
    padding: var(--s4-e3) var(--s4-e4) var(--s4-e3) calc(var(--s4-e4) + 24px);
    border: 1px solid var(--s4-linha-forte);
    border-radius: var(--s4-r-md);
    background: var(--s4-superficie);
    color: var(--s4-texto);
    font-size: .9rem;
    font-weight: 400;
    cursor: pointer;
    transition: border-color var(--s4-rapido) var(--s4-curva), background-color var(--s4-rapido) var(--s4-curva);
}
.s4-tipos-registo .s4-tipo-registo:hover { border-color: #C9CDDC; }
.s4-tipos-registo .s4-tipo-registo input {
    position: absolute;
    left: var(--s4-e4);
    top: calc(var(--s4-e3) + 3px);
    margin: 0;
    accent-color: var(--s4-azul);
}
.s4-tipos-registo .s4-tipo-registo:has(input:checked) { border-color: var(--s4-azul); background: var(--s4-azul-fraco); }
.s4-tipos-registo .s4-tipo-registo:has(input:focus-visible) { box-shadow: var(--s4-foco); }
.s4-tipo-registo-nome { color: var(--s4-tinta); font-weight: 600; }
.s4-tipo-registo-texto { color: var(--s4-suave); font-size: .82rem; line-height: 1.35; }
/* A explicação por baixo dos cartões: com os 4 px do tema encostava ao contorno deles. */
.s4-tipos-registo + .form-text { margin-top: var(--s4-e2); }

/* ------------------------------------------------------------------ S49 · o planeamento

   A chave "Por pintar" da legenda do mapa: o tracejado azul com que o mapa desenha as linhas novas de
   um planeamento (o azul de ação, que não é cor de estado nenhum da conformidade). */
.s4-chave-por-pintar {
    display: inline-block;
    width: 18px;
    height: 0;
    border-top: 3px dashed var(--s4-azul);
}

/* As caixas de escolha das tabelas (as linhas a repintar, as linhas pintadas): do tamanho de uma linha
   de texto, no azul da plataforma, numa coluna estreita à esquerda. */
.s4-coluna-escolha { width: 40px; text-align: center; }
.s4-escolha { width: 16px; height: 16px; margin: 0; vertical-align: middle; accent-color: var(--s4-azul); cursor: pointer; }
.s4-escolha:focus-visible { outline: none; box-shadow: var(--s4-foco); }

/* ------------------------------------------------------------------ S50 · a vida da marca

   O que aconteceu a uma marca, registo a registo: uma linha do tempo com a data à esquerda e um ponto
   em cima de um fio. O ponto tem a cor do acontecimento, sem cores de sinal (uma pintura não diz se
   cumpre): o azul de ação para o que é planeado, a tinta escura para a pintura, o cinzento para o resto. */
.s4-vida { list-style: none; margin: 0; padding: 0; }
.s4-vida-passo { position: relative; display: flex; gap: var(--s4-e4); padding: 0 0 var(--s4-e4) 0; }
.s4-vida-passo:last-child { padding-bottom: 0; }
.s4-vida-data { flex: 0 0 150px; color: var(--s4-suave); font-variant-numeric: tabular-nums; }
.s4-vida-registado { display: block; color: var(--s4-ténue); font-size: .78rem; white-space: nowrap; }
.s4-vida-texto { position: relative; padding-left: var(--s4-e5); color: var(--s4-texto); }
.s4-vida-texto::before { content: ""; position: absolute; left: 0; top: .45em; width: 10px; height: 10px; border-radius: 50%; background: var(--s4-ténue); box-shadow: 0 0 0 3px var(--s4-superficie); }
.s4-vida-passo:not(:last-child) .s4-vida-texto::after { content: ""; position: absolute; left: 4px; top: 1.2em; bottom: calc(-1 * var(--s4-e4)); width: 2px; background: var(--s4-linha); }
.s4-vida-repinturaprevista .s4-vida-texto::before { background: var(--s4-azul); }
.s4-vida-pintada .s4-vida-texto::before { background: var(--s4-tinta); }
