/* =====================================================================
   MyWorks — horas, trabalhos e valores
   Barra lateral em azul-tinta sobre papel quente. O azul frio contra
   o papel creme é o que dá o contraste sem endurecer a página — um
   cinzento neutro por baixo deixava a folha com ar de formulário.

   A regra que atravessa a folha toda: os números são monoespaçados e
   alinhados à direita, com tabular-nums. Uma coluna de euros em que o
   3 é mais estreito do que o 8 não se lê de relance, e esta aplicação
   é feita para se ler de relance.
   ===================================================================== */

:root {
    /* O azul da casa e os dois degraus acima dele. O claro é o do
       item ativo e o do foco; o hover fica a meio caminho, para o
       rato ter resposta sem saltar já para o estado ativo. */
    --azul: #002D57;
    --azul-claro: #0A4478;
    --azul-hover: #14548C;
    --papel: #F4F1EA;
    --carta: #FFFDF9;
    --tinta: #14161A;
    --tinta-suave: #5C6058;
    --filete: #DED7C8;
    /* Decorativo vs. texto: o ocre vivo não chega ao contraste mínimo
       quando é texto pequeno ou leva branco por cima. */
    --ocre: #B4762C;
    --ocre-texto: #8F5C20;
    --perigo: #A33A2A;
    --ok: #2F6B4F;

    --fonte: "Instrument Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    --mono: "JetBrains Mono", ui-monospace, "SF Mono", Consolas, monospace;
    --raio: 4px;
    --sidebar: 250px;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    font-family: var(--fonte);
    font-size: 15px;
    line-height: 1.5;
    color: var(--tinta);
    background: var(--papel);
}

a { color: inherit; }
h1, h2, h3 { margin: 0; font-weight: 600; letter-spacing: -0.01em; }

.mono, .num {
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
}
.num { text-align: right; }

code {
    font-family: var(--mono);
    font-size: 0.85em;
    background: rgba(0, 45, 87, 0.07);
    padding: 1px 5px;
    border-radius: 3px;
}

/* ---------------------------------------------------------------
   Estrutura
   Flex e não grid: uma coluna fixa mais uma elástica é mais difícil
   de partir do que um grid-template que se invalida todo se uma
   medida falhar. O min-width:0 no corpo é o que impede uma tabela
   larga de empurrar a página para fora do ecrã.
   --------------------------------------------------------------- */

.app { display: flex; align-items: flex-start; min-height: 100vh; }

.corpo {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

/* O ar em volta do conteúdo é o mínimo que separa a folha da moldura.
   Era o triplo disto: numa folha de horas com onze colunas, cada píxel
   de margem é um píxel que a tabela não tem. */
.conteudo { padding: 12px 14px 40px; width: 100%; min-width: 0; }

@media (min-width: 1600px) {
    .conteudo { padding-inline: 22px; }
    .topbar { padding-inline: 22px; }
}

/* ---------------------------------------------------------------
   Barra lateral
   --------------------------------------------------------------- */

.sidebar {
    flex: 0 0 var(--sidebar);
    width: var(--sidebar);
    background: var(--azul);
    color: #C7D4E2;
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
    scrollbar-width: thin;
}

.marca { padding: 14px 14px 12px; border-bottom: 1px solid rgba(255, 255, 255, 0.08); }
.marca a { text-decoration: none; display: block; }
/* O nome sai como está escrito (MyWorks): em maiúsculas perdia a
   maiúscula do meio, que é o que o faz ler-se como duas palavras. */
.marca-nome {
    display: block;
    font-size: 17px;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: #fff;
}
.marca small { color: rgba(255, 255, 255, 0.45); font-size: 11.5px; letter-spacing: 0.03em; }

.nav { flex: 1; padding: 8px 8px; }

.nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border-radius: var(--raio);
    color: rgba(255, 255, 255, 0.72);
    text-decoration: none;
    font-size: 14px;
    line-height: 1.25;
    transition: background 0.12s ease, color 0.12s ease;
}
.nav-item svg {
    width: 17px; height: 17px; flex: none;
    fill: none; stroke: currentColor; stroke-width: 1.7;
    stroke-linecap: round; stroke-linejoin: round;
}
.nav-item:hover { background: var(--azul-hover); color: #fff; }
.nav-item.ativo { background: var(--azul-claro); color: #fff; font-weight: 500; }

.nav-grupo { margin-top: 4px; }
.nav-grupo > summary {
    cursor: pointer;
    list-style: none;
    justify-content: space-between;
    font-size: 11.5px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.42);
}
.nav-grupo > summary::-webkit-details-marker { display: none; }
.nav-grupo > summary:hover { background: transparent; color: rgba(255, 255, 255, 0.7); }
.nav-grupo > summary.tem-ativo { color: rgba(255, 255, 255, 0.7); }
.nav-grupo .chevron {
    width: 14px; height: 14px;
    fill: none; stroke: currentColor; stroke-width: 2;
    stroke-linecap: round; stroke-linejoin: round;
    transition: transform 0.15s ease;
}
.nav-grupo[open] .chevron { transform: rotate(90deg); }
.nav-grupo-itens { padding-left: 4px; }

.sidebar-pe { padding: 10px 8px 14px; border-top: 1px solid rgba(255, 255, 255, 0.08); }
.sidebar-pe a {
    display: flex; align-items: center; gap: 9px;
    padding: 7px 10px; border-radius: var(--raio);
    color: rgba(255, 255, 255, 0.6);
    text-decoration: none; font-size: 13.5px;
}
.sidebar-pe a svg {
    width: 16px; height: 16px;
    fill: none; stroke: currentColor; stroke-width: 1.7;
    stroke-linecap: round; stroke-linejoin: round;
}
.sidebar-pe a:hover { background: var(--azul-hover); color: #fff; }

.fundo-menu { display: none; }

/* ---------------------------------------------------------------
   Barra de topo
   --------------------------------------------------------------- */

.topbar {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 14px;
    height: 52px;
    background: var(--carta);
    border-bottom: 1px solid var(--filete);
    position: sticky;
    top: 0;
    z-index: 20;
}
.topbar-titulo { flex: 1; min-width: 0; line-height: 1.2; }
.topbar-titulo strong { display: block; font-size: 15.5px; }
.migalha {
    display: block;
    font-size: 11.5px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--tinta-suave);
}
.migalha a { text-decoration: none; }
.migalha a:hover { text-decoration: underline; }
.migalha em { font-style: normal; opacity: 0.45; margin: 0 5px; }

.topbar-utilizador { display: flex; align-items: center; gap: 9px; font-size: 13.5px; }
.avatar {
    width: 28px; height: 28px; border-radius: 50%;
    background: var(--azul); color: #fff;
    display: grid; place-items: center;
    font-size: 12.5px; font-weight: 600;
}

.menu-movel {
    display: none;
    background: none; border: 0; padding: 6px; cursor: pointer;
    color: var(--tinta);
}
.menu-movel svg {
    width: 22px; height: 22px;
    fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round;
}

/* ---------------------------------------------------------------
   Avisos
   --------------------------------------------------------------- */

.flash {
    padding: 9px 12px;
    border-radius: var(--raio);
    border-left: 3px solid var(--ok);
    background: rgba(47, 107, 79, 0.08);
    margin-bottom: 12px;
    font-size: 14px;
}
.flash.erro { border-left-color: var(--perigo); background: rgba(163, 58, 42, 0.08); }
.flash.aviso { border-left-color: var(--ocre); background: rgba(180, 118, 44, 0.1); }

.vazio {
    padding: 20px 14px;
    text-align: center;
    color: var(--tinta-suave);
    background: var(--carta);
    border: 1px dashed var(--filete);
    border-radius: var(--raio);
}

/* ---------------------------------------------------------------
   Cartões e cabeçalhos de secção
   --------------------------------------------------------------- */

.cartao {
    background: var(--carta);
    border: 1px solid var(--filete);
    border-radius: var(--raio);
    margin-bottom: 12px;
}
.cartao > header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 9px 12px;
    border-bottom: 1px solid var(--filete);
    flex-wrap: wrap;
}
.cartao > header h2 { font-size: 14.5px; }
.cartao > header .nota { font-size: 12.5px; color: var(--tinta-suave); font-weight: 400; }
.cartao-corpo { padding: 12px; }
.cartao-corpo.sem-pad { padding: 0; }

.barra-accoes {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 10px;
    flex-wrap: wrap;
}
.barra-accoes .grupo { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

/* ---------------------------------------------------------------
   Botões
   --------------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 14px;
    border-radius: var(--raio);
    border: 1px solid var(--filete);
    background: var(--carta);
    color: var(--tinta);
    font: inherit;
    font-size: 13.5px;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.12s ease, border-color 0.12s ease;
}
.btn:hover { background: #F0ECE2; }
.btn svg {
    width: 15px; height: 15px;
    fill: none; stroke: currentColor; stroke-width: 1.8;
    stroke-linecap: round; stroke-linejoin: round;
}
.btn-principal { background: var(--azul); border-color: var(--azul); color: #fff; }
.btn-principal:hover { background: var(--azul-claro); }
/* Os dois botões de trabalho de cada fase, por cor: verde os trabalhos
   (o que há a fazer), laranja as horas (o que se fez). Texto branco. */
.btn-verde { background: var(--ok); border-color: var(--ok); color: #fff; }
.btn-verde:hover { background: #255A42; border-color: #255A42; color: #fff; }
.btn-laranja { background: var(--ocre-texto); border-color: var(--ocre-texto); color: #fff; }
.btn-laranja:hover { background: #7A4E1B; border-color: #7A4E1B; color: #fff; }
/* Os restantes botões da fase, cada um com a sua cor para se acharem de
   relance: petróleo os dados, ardósia fechar/reabrir. Todas escuras o
   bastante para o texto branco se ler. */
.btn-petroleo { background: #1F6570; border-color: #1F6570; color: #fff; }
.btn-petroleo:hover { background: #17505A; border-color: #17505A; color: #fff; }
.btn-ardosia { background: #4A5160; border-color: #4A5160; color: #fff; }
.btn-ardosia:hover { background: #3A404C; border-color: #3A404C; color: #fff; }

/* Três ações, três cores, as mesmas em toda a aplicação:
     Ver / Abrir              azul    — entrar no item
     Relatório (sem extras)   vinho   — o PDF só com o trabalho
     Relatório com extras     roxo    — o PDF com os extras do projeto */
.btn-ver { background: var(--azul); border-color: var(--azul); color: #fff; }
.btn-ver:hover { background: var(--azul-claro); border-color: var(--azul-claro); color: #fff; }
.btn-rel { background: #8A2F4E; border-color: #8A2F4E; color: #fff; }
.btn-rel:hover { background: #71263F; border-color: #71263F; color: #fff; }
.btn-rel-extras { background: #5A45A0; border-color: #5A45A0; color: #fff; }
.btn-rel-extras:hover { background: #483683; border-color: #483683; color: #fff; }
/* Apagar: vermelho cheio com letra branca, em toda a aplicação. É o
   único botão desta cor, e é por isso que não se carrega nele sem ver. */
.btn-perigo { background: var(--perigo); border-color: var(--perigo); color: #fff; }
.btn-perigo:hover { background: #87301F; border-color: #87301F; color: #fff; }
.btn-perigo svg { stroke: currentColor; }

/* O botão do modo privado na barra de topo. Ligado, a ocre cheio: é o
   aviso permanente de que há valores escondidos. */
.btn-privado { flex: none; }
.btn-privado.ligado { background: var(--ocre-texto); border-color: var(--ocre-texto); color: #fff; }
.btn-privado.ligado:hover { background: #7A4E1B; border-color: #7A4E1B; color: #fff; }
/* O popup «Visualização»: duas partes, colunas e modo privado, cada uma
   com o seu título pequeno. */
.vis-corpo { display: flex; flex-direction: column; gap: 8px; }
.vis-corpo > .nota { margin: 0; font-size: 12.5px; color: var(--tinta-suave); }
.vis-secao {
    margin-top: 6px;
    font-size: 11.5px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--tinta-suave);
}
.vis-secao:first-child { margin-top: 0; }
.vis-secao + .nota { margin-top: -4px; }
.vis-interruptor { border: 1px solid var(--filete); border-radius: var(--raio); background: var(--carta); }
.vis-corpo .privado-password { margin-top: 6px; }
.aviso-privado .vazio strong { display: block; margin-bottom: 4px; color: var(--ocre-texto); }
@media (max-width: 760px) {
    .btn-privado span, .btn-privado { font-size: 0; gap: 0; }
    .btn-privado svg { width: 18px; height: 18px; }
}
/* Dois botões lado a lado numa célula (Abrir · Apagar): um pouco de ar. */
table.tabela td .btn + .btn { margin-left: 4px; }
.btn-pequeno { padding: 4px 9px; font-size: 12.5px; }

/* Dois formulários de um botão na mesma célula ficam lado a lado, e não
   um por linha como o display:block de um form faria. */
.em-linha { display: inline-block; }

/* O caixote do lixo de uma linha. Discreto até se lhe passar por cima —
   está numa coluna que se vê trinta vezes ao descer uma folha, e a
   vermelho essas trinta vezes eram trinta avisos. */
.btn-apagar {
    display: inline-flex;
    padding: 5px;
    border: 0;
    border-radius: var(--raio);
    background: none;
    color: var(--tinta-suave);
    cursor: pointer;
    transition: background 0.12s ease, color 0.12s ease;
}
.btn-apagar svg {
    width: 16px; height: 16px;
    fill: none; stroke: currentColor; stroke-width: 1.7;
    stroke-linecap: round; stroke-linejoin: round;
}
.btn-apagar:hover { background: rgba(163, 58, 42, 0.1); color: var(--perigo); }
.btn-apagar:focus-visible { outline: 2px solid var(--perigo); outline-offset: 1px; }

/* O botão de voltar, na barra de topo. Está em todas as páginas menos na
   Home, e é por isso que é discreto: um botão que se vê sempre e se usa
   muitas vezes não pode pesar como uma acção principal. */
.btn-voltar { padding: 5px 11px 5px 8px; font-size: 13px; flex: none; }
.btn-voltar svg { width: 16px; height: 16px; }

/* ---------------------------------------------------------------
   Popups
   O que uma fase tem — os trabalhos, as horas, a ficha — abre aqui por
   cima da lista das fases, em vez de numa página com separadores. O
   <dialog> traz a tecla Esc, o fundo escurecido, a prisão do foco e a
   camada de topo, que é a única maneira de isto ficar por cima da barra
   lateral e da barra de topo sem uma guerra de z-index.

   Três larguras: a estreita para um campo, a larga para uma tabela, e a
   da folha, que leva o ecrã todo porque a folha de horas tem onze
   colunas e encolhê-las é deixar de as ler.
   --------------------------------------------------------------- */

dialog.popup {
    display: flex;
    flex-direction: column;
    width: min(1100px, calc(100vw - 20px));
    max-width: none;
    /* Encostado ao TOPO e não centrado. Centrados, o popup dos trabalhos
       e o das horas começavam cada um a uma altura diferente conforme o
       que tinham dentro, e abrir um a seguir ao outro era ver o
       cabeçalho saltar de sítio. */
    margin: 18px auto auto;
    max-height: calc(100vh - 36px);
    padding: 0;
    border: 1px solid var(--filete);
    border-radius: 6px;
    background: var(--carta);
    color: var(--tinta);
    box-shadow: 0 24px 60px rgba(20, 22, 26, 0.3);
    overflow: hidden;
}
/* O display:flex de cima passa por cima do display:none que o browser dá
   a um <dialog> fechado — sem isto, o popup estava sempre aberto. */
dialog.popup:not([open]) { display: none; }
dialog.popup::backdrop { background: rgba(0, 45, 87, 0.5); }

dialog.popup-estreita { width: min(520px, calc(100vw - 20px)); }
/* O tecto é o ponto onde uma linha de texto ainda se lê de uma vez: um
   popup que atravessa um monitor grande de lado a lado obriga a
   percorrer a linha com a cabeça. Esteve nos 1180px, que era estreito
   para a folha de horas, e nos 1560px, que era largo demais. */
dialog.popup-larga    { width: min(1340px, calc(100vw - 20px)); }

.popup-topo {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    flex: none;
    padding: 10px 12px;
    border-bottom: 1px solid var(--filete);
    background: #FAF7F0;
}
.popup-titulo { min-width: 0; }
/* Botões do cabeçalho (o CSV da folha de horas): encostam ao X. */
.popup-accoes { margin-left: auto; display: flex; align-items: center; gap: 6px; flex: none; }.popup-titulo h2 { font-size: 15px; line-height: 1.3; overflow-wrap: anywhere; }
.popup-titulo .nota { margin: 2px 0 0; font-size: 12px; color: var(--tinta-suave); }

.popup-x {
    display: inline-flex;
    flex: none;
    padding: 5px;
    border: 1px solid transparent;
    border-radius: var(--raio);
    background: none;
    color: var(--tinta-suave);
    cursor: pointer;
}
.popup-x svg {
    width: 18px; height: 18px;
    fill: none; stroke: currentColor; stroke-width: 1.8;
    stroke-linecap: round; stroke-linejoin: round;
}
.popup-x:hover { background: #EFE9DC; color: var(--tinta); }

/* O corpo é a única coisa que rola: o cabeçalho fica onde está, para se
   saber sempre de que fase é a folha que está aberta. */
.popup-corpo { flex: 1 1 auto; overflow: auto; -webkit-overflow-scrolling: touch; }

/* Dentro de um popup, o cartão já é o popup: nem moldura nem margem. */
.popup-corpo > .cartao { border: 0; margin: 0; }
.popup-corpo .barra-solta,
.popup-corpo > .barra-accoes { margin: 0; padding: 10px 12px; }
.popup-corpo > .totais-solto { margin: 0; border-radius: 0; border: 0; border-bottom: 1px solid var(--filete); }

/* A tabela rola dentro da sua própria caixa e não arrasta o popup todo
   consigo: assim o cabeçalho das colunas e a linha dos totais ficam
   colados nas bordas dela, e o botão de gravar nunca sai do ecrã. Numa
   folha de quarenta dias, era a descer que se perdia o sítio. */
.popup-corpo .tabela-envolve {
    max-height: min(72vh, 820px);
    overflow: auto;
}
.popup-corpo table.tabela thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background: #F4EFE4;
}
.popup-corpo table.tabela tfoot td {
    position: sticky;
    bottom: 0;
    z-index: 2;
}

/* ---------------------------------------------------------------
   A pergunta antes de apagar
   --------------------------------------------------------------- */

dialog.pergunta {
    width: min(440px, calc(100vw - 32px));
    padding: 24px 26px 20px;
    border: 1px solid var(--filete);
    border-radius: 6px;
    background: var(--carta);
    color: var(--tinta);
    box-shadow: 0 18px 50px rgba(20, 22, 26, 0.22);
}
dialog.pergunta::backdrop { background: rgba(0, 45, 87, 0.45); }
dialog.pergunta h2 { font-size: 16px; line-height: 1.35; }
dialog.pergunta .detalhe {
    margin: 10px 0 0;
    font-size: 13.5px;
    line-height: 1.5;
    color: var(--tinta-suave);
}
/* A password pedida antes de apagar. Fica entre o detalhe e os botões:
   quem a escreve já leu o que se perde. */
.pergunta-password {
    display: block;
    margin-top: 18px;
}
.pergunta-password[hidden] { display: none; }
.pergunta-password span {
    display: block;
    margin-bottom: 6px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--tinta-suave);
}
.pergunta-password input {
    width: 100%;
    height: 38px;
    padding: 0 10px;
    border: 1px solid var(--filete);
    border-radius: 4px;
    background: #fff;
    font: inherit;
    font-size: 14px;
    color: var(--tinta);
}
.pergunta-password input:focus {
    outline: none;
    border-color: var(--azul-claro);
    box-shadow: 0 0 0 3px rgba(10, 68, 120, 0.15);
}
.pergunta-pe .btn[disabled] {
    opacity: 0.45;
    cursor: not-allowed;
}

.pergunta-pe {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 22px;
}
/* Cancelar primeiro e à esquerda: é a saída, e a saída não se procura. */
.pergunta-pe .btn { min-width: 96px; justify-content: center; }
.pergunta-pe .btn-perigo { background: var(--perigo); border-color: var(--perigo); color: #fff; }
.pergunta-pe .btn-perigo:hover { background: #8C3124; }

/* ---------------------------------------------------------------
   Formulários
   --------------------------------------------------------------- */

.grelha-campos {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 10px 14px;
}
.campo { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.campo-larga { grid-column: 1 / -1; }

.campo label { font-size: 12.5px; font-weight: 500; color: var(--tinta-suave); }
.campo .obrig { color: var(--perigo); }
.campo .ajuda { font-size: 11.5px; color: var(--tinta-suave); line-height: 1.35; }

/* UM desenho para todas as caixas de escrever, estejam num formulário,
   num filtro ou dentro de uma tabela. Enquanto as das tabelas ficaram
   de fora desta lista, o browser desenhava-as à maneira dele e a folha
   de horas tinha três alturas de campo na mesma linha. */
.campo input[type="text"],
.campo input[type="email"],
.campo input[type="password"],
.campo input[type="date"],
.campo input[type="number"],
.campo select,
.campo textarea,
.filtro input,
.filtro select,
table.tabela input[type="text"],
table.tabela input[type="date"],
table.tabela input[type="number"],
table.tabela select,
table.tabela textarea {
    width: 100%;
    padding: 7px 10px;
    border: 1px solid var(--filete);
    border-radius: var(--raio);
    background: #fff;
    font: inherit;
    font-size: 14px;
    line-height: 1.35;
    color: var(--tinta);
}
.campo textarea { resize: vertical; line-height: 1.5; }
.campo textarea.fixa { resize: none; }

.campo input:focus, .campo select:focus, .campo textarea:focus,
.filtro input:focus, .filtro select:focus,
table.tabela input:focus, table.tabela select:focus {
    outline: 2px solid var(--azul-claro);
    outline-offset: -1px;
    border-color: var(--azul-claro);
}

/* Dentro de uma tabela os campos são mais baixos e mais apertados: a
   linha é a unidade, e uma folha com trinta dias tem de caber no ecrã. */
table.tabela input[type="text"],
table.tabela input[type="date"],
table.tabela input[type="number"],
table.tabela select,
table.tabela textarea {
    padding: 6px 8px;
    font-size: 13.5px;
}
/* A textarea de uma folha não se redimensiona: a pega do canto puxava
   a linha para baixo e desalinhava-a das vizinhas, e o que se ganhava
   era espaço que a linha mais alta já dava a todas. A letra é um ponto
   mais pequena do que a dos campos ao lado — são notas, não números, e
   assim cabem duas linhas sem a caixa crescer. */
table.tabela textarea {
    resize: none;
    font-size: 12.5px;
    line-height: 1.45;
    min-height: 46px;
}
/* A descrição e as observações de um trabalho são campos de UMA linha.
   Foram caixas de três: liam-se inteiras, mas a linha da tabela ficava
   com 86px de altura e cabiam sete trabalhos no ecrã em vez de vinte —
   numa lista, ver a lista é o que interessa primeiro. Quem precisa de
   ler uma descrição comprida até ao fim tem o título ao passar o rato,
   e o campo desliza com o cursor.

   Ganhou-se de passagem o Enter a saltar para o campo seguinte também na
   descrição: dentro de uma textarea, o Enter é uma linha nova. */
table.tabela .c-desc-larga input[type="text"] { font-size: 12.5px; }
/* As observações de uma linha de horas: campo de uma linha, como a
   descrição de um trabalho. Em caixa de texto davam 46px de altura à
   linha, e uma folha de trinta dias deixava de caber no ecrã. */
table.tabela .c-notas input[type="text"] { font-size: 12.5px; }
/* A folha de horas à letra da lista de trabalhos: a 13,5px, e com os
   números em monoespaçado (que é mais largo à mesma medida), parecia
   escrita um tamanho acima. Os números descem meio ponto mais para
   ficarem, a olho, do tamanho do texto ao lado. */
form[data-folha-horas] table.tabela td,
form[data-folha-horas] table.tabela input[type="text"],
form[data-folha-horas] table.tabela input[type="date"],
form[data-folha-horas] table.tabela input[type="number"] { font-size: 12.5px; }
form[data-folha-horas] table.tabela td.num,
form[data-folha-horas] table.tabela input.num { font-size: 12px; }

/* Os seletores da linha à mesma letra dos campos ao lado. A 13,5px, um
   deles era o texto maior da tabela e puxava o olho para a coisa que
   menos se lê na linha. */
/* A letra dos seletores da linha.
   Ficam abaixo da dos campos ao lado de propósito: o nome de uma fase
   está gravado em MAIÚSCULAS («2. DESENVOLVIMENTO») e, à mesma medida
   de uma frase em minúsculas, lê-se como se fosse maior. É a mesma
   medida dos pills da lista de trabalhos do cartão. */
table.tabela .c-fase select,
table.tabela .c-estado select { font-size: 11.5px; }
table.tabela input.num { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* O input[type=date] do Chrome traz um ícone de calendário que come
   largura e não se desliga — daí esta coluna ser a mais larga das
   estreitas. Os restantes larguras são as da coisa que lá cabe: quatro
   caracteres numas, um valor em euros noutras. */
/* A coluna da data mede-se a si própria (o width:1% encolhe-a ao
   conteúdo) em vez de levar um número fixo: a caixa de data do Chrome
   não tem a mesma largura que a do Firefox, e um valor escrito à mão
   dava-se bem num e atirava o dia da semana para a linha de baixo no
   outro. A caixa também fica do tamanho dela e não da célula. */
table.tabela .c-data  { width: 1%; }
table.tabela .c-data input[type="date"] { width: auto !important; }
/* As colunas de números medem-se pelo NÚMERO e não pelo título: nenhum
   destes passa de seis dígitos. Os títulos é que encurtaram para lhes
   deixar essa medida — «Real c/ desconto» dava à coluna três vezes a
   largura do valor que ela mostra, e o que se lia era o ar entre eles. */
table.tabela .c-hora  { width: 64px; }
table.tabela .c-valor { width: 66px; }

/* As três colunas calculadas medem-se ao conteúdo (o width:1% encolhe a
   coluna até ao que lá cabe). Não se escreve nelas, portanto não há
   caixa nenhuma a pedir uma largura mínima. */
table.tabela .c-calc { width: 1%; white-space: nowrap; }
table.tabela .c-num   { width: 62px; }
table.tabela .c-obs   { width: 150px; }

/* As larguras são as da coisa que lá cabe, e não um número redondo. Um
   select cortado a meio de «Corrigido» é pior do que uma coluna larga:
   a etiqueta existe para se ler de relance, e meia etiqueta não se lê. */
/* O nome de uma fase é «2. DESENVOLVIMENTO» e não «Fase 2»: à largura
   antiga o seletor cortava-o a meio, e meia etiqueta não se lê. O espaço
   sai da descrição, que é a coluna elástica. */
table.tabela .c-fase   { width: 195px; }
table.tabela .c-estado { width: 140px; }
table.tabela .c-euro   { width: 110px; }
table.tabela .c-doc    { width: 130px; }
/* A descrição de um extra tem de deixar as outras colunas caber: sem
   tecto, ficava com a largura toda e empurrava o valor para fora. */
table.tabela .c-desc   { width: 34%; min-width: 220px; max-width: 460px; }
/* As observações de um trabalho merecem o mesmo espaço que as notas de
   uma folha de horas e mais um pouco: é onde fica o porquê de uma
   decisão, e o porquê é sempre mais comprido do que a decisão. */
/* A descrição de um trabalho fica com TODO o espaço que sobra: as
   outras colunas da tabela são um seletor, um seletor e um caixote, e
   esta é a única onde se escreve uma frase. A coluna de observações saiu
   da tabela e foi essa largura que ela herdou. */
table.tabela .c-desc-larga { width: auto; min-width: 240px; }
/* As observações passaram a ser uma coluna só e ganharam espaço: é onde
   vai o «6 Dia 3 Noite» e o «contabilizei menos duas horas», que antes
   andavam em duas caixas apertadas lado a lado. */
table.tabela .c-notas { width: 230px; }
/* Na folha de horas é esta que fica com o que sobrar, agora que as
   colunas de números se encolheram ao que levam. */
form[data-folha-horas] table.tabela .c-notas { width: auto; min-width: 170px; }
table.tabela .c-data, table.tabela .c-hora, table.tabela .c-valor,
table.tabela .c-num, table.tabela .c-obs, table.tabela .c-euro,
table.tabela .c-doc, table.tabela .c-fase, table.tabela .c-estado { white-space: nowrap; }

/* Coluna de caixas de visto: tão estreita quanto o visto, e centrada. */
table.tabela .c-check { width: 1%; white-space: nowrap; text-align: center; }
table.tabela input[type="checkbox"] { accent-color: var(--azul); width: 15px; height: 15px; }

/* O seletor de cor acompanha a altura dos campos ao lado, para a linha
   não ficar com um degrau a meio. */
table.tabela input[type="color"] {
    width: 42px; height: 30px; padding: 2px;
    border: 1px solid var(--filete); border-radius: var(--raio);
    background: #fff; cursor: pointer;
}

.campo .check { flex-direction: row; align-items: center; gap: 8px; display: flex; cursor: pointer; }
.campo .check input { width: auto; accent-color: var(--azul); }
.campo .check span { font-size: 14px; color: var(--tinta); font-weight: 400; }

/* Unidade colada ao campo: o € e o h ficam dentro da caixa, à direita,
   e o texto escreve-se com espaço para não lhe passar por cima. */
.unidade { position: relative; display: block; }
.unidade input { padding-right: 28px !important; text-align: right; }
.unidade i {
    position: absolute;
    right: 9px; top: 50%; transform: translateY(-50%);
    font-style: normal;
    font-size: 12.5px;
    color: var(--tinta-suave);
    pointer-events: none;
}

.cor-par { display: flex; align-items: center; gap: 9px; }
.cor-par input[type="color"] {
    width: 42px; height: 32px; padding: 2px;
    border: 1px solid var(--filete); border-radius: var(--raio);
    background: #fff; cursor: pointer;
}
.cor-par output { font-size: 12.5px; color: var(--tinta-suave); }

.form-pe .grupo { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

.ajuda-solta { margin: 10px 0 0; font-size: 12px; color: var(--tinta-suave); }

/* As notas de ajuda ao lado dos botões ("cada linha é gravada por si…",
   "as linhas sem valor são ignoradas…"). Lêem-se uma vez e depois são
   ruído: ficam pequenas e apagadas, para não competirem com o botão. Os
   totais que vivem no mesmo sítio (o valor da linha, o da fatura) são
   números que se querem ver, e mantêm o tamanho. */
.form-pe .nota,
.fc-bloco > .nota {
    font-size: 11px;
    line-height: 1.4;
    color: var(--tinta-suave);
}
.form-pe [data-total-linha],
.form-pe [data-fc-total] { font-size: 13px; }

/* A lista de projetos a incluir num relatório: uma caixa por projeto,
   em colunas que se ajustam à largura. */
.escolha-projetos {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 8px 18px;
}
.escolha-projetos .check {
    display: flex; align-items: flex-start; gap: 9px;
    cursor: pointer; padding: 6px 0;
}
.escolha-projetos .check input { margin-top: 3px; accent-color: var(--azul); }
.escolha-projetos .check small { display: block; font-size: 11.5px; }

/* Abrir uma fatura: o que vai nela (Horas / Extras / Outros) e, por
   baixo, a parte de cada um. As caixas são pills que se ligam e
   desligam — uma fatura pode levar as três. */
.escolha-tipos {
    display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
    min-height: 38px;
}

/* Abrir fatura: projeto, documento, data e o que vai faturar numa linha;
   a descrição por baixo, com a largura toda. Em ecrã estreito parte-se
   sozinha em linhas. */
.fc-cabeca { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px 14px; }
.fc-cabeca .fc-c-projeto { flex: 0 1 240px; }
.fc-cabeca .fc-c-doc     { flex: 0 1 180px; }
.fc-cabeca .fc-c-data    { flex: 0 1 170px; }
.fc-cabeca .fc-c-tipos   { flex: 1 1 260px; }
.campo .rotulo { font-size: 12.5px; font-weight: 500; color: var(--tinta-suave); }
.fc-c-desc { margin-top: 10px; }
.fc-horas-linha { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px 14px; }
.fc-horas-linha .fc-c-horas,
.fc-horas-linha .fc-c-vh { flex: 0 1 170px; }
.fc-horas-linha .aviso-horas { flex: 1 1 280px; margin-top: 0; padding: 8px 12px; }
.fc-horas-linha .aviso-horas[hidden] { display: none; }
@media (max-width: 760px) {
    .fc-cabeca > .campo { flex: 1 1 100%; }
}
.chip-tipo {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 5px 12px 5px 9px;
    border: 1px solid var(--filete); border-radius: 100px;
    background: var(--carta);
    font-size: 13px; cursor: pointer; user-select: none;
}
.chip-tipo input { margin: 0; accent-color: var(--azul); }
.chip-tipo:has(input:checked) { border-color: var(--azul-claro); background: rgba(0, 45, 87, 0.07); font-weight: 500; }

.fc-bloco { margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--filete); }
.fc-bloco[hidden] { display: none; }
.fc-titulo { font-size: 13px; margin-bottom: 8px; color: var(--tinta); }
.fc-bloco > .nota { margin: 8px 0 0; }

/* A lista dos extras e outros por faturar: uma linha por item, com a
   caixa, o tipo, a descrição e o valor encostado à direita. */
.lista-soltas { display: flex; flex-direction: column; border: 1px solid var(--filete); border-radius: var(--raio); background: var(--carta); }
.check-solta {
    display: flex; align-items: center; gap: 10px;
    padding: 7px 10px; cursor: pointer;
    border-bottom: 1px solid #EDE7DA; font-size: 13px;
}
.check-solta:last-child { border-bottom: 0; }
.check-solta[hidden] { display: none; }
.check-solta:hover { background: #FBF8F2; }
.check-solta:has(input:checked) { background: rgba(47, 107, 79, 0.1); }
.check-solta input { margin: 0; flex: none; accent-color: var(--azul); }
.check-solta .etiqueta { flex: none; }
.check-solta-desc { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.check-solta-desc small { display: block; font-size: 11.5px; }
.check-solta strong { flex: none; font-size: 12.5px; }

/* Um recebimento: a que abate. Três opções grandes, cada uma com a
   explicação por baixo — é uma decisão que se lê antes de se tomar. */
.escolha-abate {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 8px;
    margin: 14px 0 0; padding: 0; border: 0; min-width: 0;
}
.escolha-abate legend { padding: 0; margin-bottom: 6px; font-size: 12.5px; font-weight: 500; color: var(--tinta-suave); }
.opcao-abate {
    display: flex; align-items: flex-start; gap: 9px;
    padding: 9px 11px; cursor: pointer;
    border: 1px solid var(--filete); border-radius: var(--raio); background: var(--carta);
    font-size: 13px;
}
.opcao-abate input { margin: 3px 0 0; flex: none; accent-color: var(--azul); }
.opcao-abate small { display: block; margin-top: 2px; font-size: 11.5px; color: var(--tinta-suave); line-height: 1.35; }
.opcao-abate:has(input:checked) { border-color: var(--azul-claro); background: rgba(0, 45, 87, 0.06); }
.opcao-abate:has(input:disabled) { opacity: 0.5; cursor: not-allowed; }
.lista-abate { margin-top: 10px; }
.lista-abate[hidden] { display: none; }
.campo-notas { margin-top: 12px; }
.check-mini { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--tinta-suave); cursor: pointer; }
.check-mini input { width: auto; margin: 0; }

/* O que um recebimento abateu, na tabela dos recebimentos. */
.lista-abatido { margin: 4px 0 0; padding: 0; list-style: none; font-size: 12px; color: var(--tinta-suave); }
.lista-abatido li { display: flex; justify-content: space-between; gap: 10px; }
.etiqueta.abate-todas  { background: rgba(47, 107, 79, 0.14); color: var(--ok); }
.etiqueta.abate-linhas { background: rgba(0, 45, 87, 0.1); color: var(--azul); }
.etiqueta.abate-conta  { background: rgba(180, 118, 44, 0.16); color: var(--ocre-texto); }

.btn-pdf {
    display: inline-block; padding: 2px 7px;
    border: 1px solid rgba(163, 58, 42, 0.35); border-radius: var(--raio);
    color: var(--perigo); font-size: 11px; font-weight: 600; letter-spacing: 0.04em;
    text-decoration: none;
}
.btn-pdf:hover { background: rgba(163, 58, 42, 0.08); }
table.tabela td.pago-ok { color: var(--ok); font-weight: 500; }
td .btn-pdf { margin-left: 6px; }
.campo-pdf-fatura { margin-top: 12px; }

/* A conta corrente: débitos, créditos e o saldo a correr. */
table.tabela td.debito  { color: var(--tinta); }
table.tabela td.credito { color: var(--ok); }
table.tabela tr.mov-recebimento td { background: rgba(47, 107, 79, 0.04); }
table.tabela td.idade-velha { color: var(--perigo); font-weight: 600; }
/* O tipo de documento na conta corrente. O saldo negativo é dinheiro
   do cliente que ficou do nosso lado — a verde, não a vermelho. */
.etiqueta.doc-fatura      { background: rgba(0, 45, 87, 0.1); color: var(--azul); }
.etiqueta.doc-recebimento { background: rgba(47, 107, 79, 0.14); color: var(--ok); }
table.tabela td.a-favor   { color: var(--ok); }
.etiqueta.doc-saldo       { background: rgba(180, 118, 44, 0.16); color: var(--ocre-texto); }
.etiqueta.origem-saldo    { background: rgba(180, 118, 44, 0.16); color: var(--ocre-texto); margin-left: 4px; }
table.tabela tr.mov-saldo td { background: rgba(180, 118, 44, 0.05); }
.form-pe.saldo-cliente { justify-content: flex-start; background: rgba(47, 107, 79, 0.08); font-size: 13px; }
.escolha-origem { margin-top: 14px; }
/* O dinheiro do cliente que ficou do nosso lado: verde, é dele. */
.totais .saldo-favor { background: var(--ok); }
.totais .saldo-favor dt { color: rgba(255, 255, 255, 0.75); }
.totais .saldo-favor dd { color: #fff; }

/* O total da fatura que se está a abrir, ao lado do botão. */
[data-fc-total] strong { color: var(--tinta); }

/* Na ficha da fatura, os subtotais por tipo antes do total. */
table.tabela tfoot tr.subtotal td { font-weight: 500; background: #FAF7F0; border-top: 1px solid var(--filete); }

.form-pe {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 10px 12px;
    border-top: 1px solid var(--filete);
    background: #FAF7F0;
    flex-wrap: wrap;
}

/* Filtros: uma linha de campos pequenos por cima de uma lista. */
.filtro { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.filtro input, .filtro select { width: auto; min-width: 180px; font-size: 13.5px; padding: 6px 9px; }
.filtro .larga  { min-width: 260px; }
.filtro .estreita { min-width: 110px; }

/* ---------------------------------------------------------------
   Tabelas
   --------------------------------------------------------------- */

.tabela-envolve { overflow-x: auto; }

table.tabela {
    width: 100%;
    border-collapse: collapse;
    font-size: 13.5px;
}
table.tabela th {
    text-align: left;
    padding: 7px 9px;
    background: #FAF7F0;
    border-bottom: 1px solid var(--filete);
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--tinta-suave);
    white-space: nowrap;
}
/* Uma folha com trinta dias lê-se de cima a baixo, e linhas coladas
   umas às outras fazem perder o sítio a meio. O ar vertical é o que
   deixa seguir uma linha até ao fim sem passar para a de baixo. */
table.tabela td {
    padding: 8px 9px;
    border-bottom: 1px solid #EDE7DA;
    vertical-align: top;
}

/* Nas tabelas que são formulários os campos centram-se na linha. Com o
   alinhamento ao topo, uma caixa de 32px numa linha de 70 ficava
   encostada em cima com um palmo de vazio por baixo. Nas tabelas de
   leitura mantém-se o topo, que é onde um texto de várias linhas começa. */
form[data-saltar] table.tabela td { vertical-align: middle; }
table.tabela tbody tr:hover td { background: #FBF8F2; }
table.tabela tbody tr:last-child td { border-bottom: 0; }

table.tabela th.num, table.tabela td.num { text-align: right; }
table.tabela td.num { font-family: var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
table.tabela td.apertado, table.tabela th.apertado { width: 1%; white-space: nowrap; }
table.tabela td a { text-decoration: none; font-weight: 500; }
table.tabela td a:hover { text-decoration: underline; }

/* O sublinhado duplo é a convenção da folha de cálculo para "aqui
   acaba a coluna e começa o total". Vale a pena manter — quem vem do
   Excel reconhece-o sem ter de o aprender. */
table.tabela tfoot td {
    padding: 8px 9px;
    border-top: 2px solid var(--azul);
    background: #FAF7F0;
    font-weight: 600;
    font-size: 13.5px;
}
table.tabela tfoot td.num { font-family: var(--mono); }
table.tabela tfoot tr.destaque td { background: rgba(0, 45, 87, 0.06); }

/* O rodapé que diz o que a fatura vale: é o número que se procura na
   página toda, por isso é o único a azul. */
table.tabela tfoot tr.principal td {
    background: var(--azul);
    color: #fff;
    border-bottom: 0;
}
table.tabela tfoot tr.principal td strong { color: #fff; }

/* A linha que abre o grupo de uma fase dentro da tabela. Não é um
   cabeçalho — é um subtotal com nome, e fica entre as linhas. */
table.tabela tr.grupo-fase td {
    background: rgba(0, 45, 87, 0.05);
    border-bottom: 1px solid var(--filete);
    font-size: 13px;
    padding-top: 7px;
    padding-bottom: 7px;
}
table.tabela tr.grupo-fase:hover td { background: rgba(0, 45, 87, 0.05); }
table.tabela tbody + tbody tr.grupo-fase td { border-top: 1px solid var(--filete); }

table.tabela .c-check input[type=checkbox] {
    width: 16px;
    height: 16px;
    margin: 0;
    accent-color: var(--azul-claro);
    cursor: pointer;
}

/* O visto que grava uma linha, ao lado do caixote que a apaga. Verde
   contra o vermelho: são as duas únicas coisas que a linha faz. */
.btn-guardar {
    display: inline-grid;
    place-items: center;
    width: 26px; height: 26px;
    padding: 0; margin-right: 2px;
    border: 1px solid transparent;
    border-radius: var(--raio);
    background: none;
    color: var(--ok);
    cursor: pointer;
    vertical-align: middle;
}
.btn-guardar svg {
    width: 15px; height: 15px;
    fill: none; stroke: currentColor; stroke-width: 2;
    stroke-linecap: round; stroke-linejoin: round;
}
.btn-guardar:hover { background: rgba(47, 107, 79, 0.1); border-color: rgba(47, 107, 79, 0.3); }
.btn-guardar:focus-visible { outline: 2px solid var(--ok); outline-offset: 1px; }

/* Devolver um extra aos Extras / outros: o mesmo botão, a ocre. */
.btn-devolver {
    display: inline-grid; place-items: center;
    width: 26px; height: 26px; padding: 0; margin-right: 2px;
    border: 1px solid transparent; border-radius: var(--raio);
    background: none; color: var(--ocre-texto);
    cursor: pointer; vertical-align: middle;
}
.btn-devolver svg {
    width: 15px; height: 15px;
    fill: none; stroke: currentColor; stroke-width: 2;
    stroke-linecap: round; stroke-linejoin: round;
}
.btn-devolver:hover { background: rgba(180, 118, 44, 0.12); border-color: rgba(180, 118, 44, 0.35); }
.btn-devolver:focus-visible { outline: 2px solid var(--ocre); outline-offset: 1px; }

/* A conta das horas disponíveis, feita à frente de quem escreve. */
.aviso-horas {
    margin-top: 14px;
    padding: 10px 14px;
    border-left: 3px solid var(--azul-claro);
    border-radius: var(--raio);
    background: rgba(0, 45, 87, 0.05);
}
.aviso-horas .ajuda { margin: 0; }
.aviso-horas strong { font-family: var(--mono); }
.aviso-horas[hidden] { display: none; }
/* Pedir mais horas do que as que há: o servidor recusa à mesma, isto é
   só para não se descobrir depois de carregar no botão. */
.aviso-horas.demais {
    border-left-color: var(--perigo);
    background: rgba(163, 58, 42, 0.08);
    color: var(--perigo);
}

/* Os três tipos de linha. Horas em azul (é o trabalho), extra em ocre
   (é dinheiro que veio de fora), outro neutro. */
.etiqueta.tipo-horas { background: rgba(0, 45, 87, 0.1); color: var(--azul); }
.etiqueta.tipo-extra { background: rgba(180, 118, 44, 0.14); color: var(--ocre-texto); }
.etiqueta.tipo-outro { background: rgba(92, 96, 88, 0.12); color: var(--tinta-suave); }

/* O quadro das horas nos quatro estados: é o primeiro que se lê na
   página, por isso os números são maiores. */
.totais-horas dd { font-size: 20px; }

/* A folha de horas, lida pela cor: verde quando se contabilizou tudo o
   que se trabalhou, laranja quando se ofereceu alguma coisa. São fundos
   de baixa saturação de propósito — a linha inteira pintada compete com
   as etiquetas e com os números, e o que aqui se quer é uma pista, não
   um aviso. A cor NUNCA é a única informação: as duas colunas de horas
   estão ali ao lado a dizer o mesmo em números. */
table.tabela tr.iguais td { background: rgba(47, 107, 79, 0.16); }
table.tabela tr.difere td { background: rgba(180, 118, 44, 0.20); }
table.tabela tr.iguais:hover td { background: rgba(47, 107, 79, 0.23); }
table.tabela tr.difere:hover td { background: rgba(180, 118, 44, 0.28); }

/* Fim de semana: a folha original anotava "Sabado" à mão numa coluna
   de observações. Aqui a data já o diz sozinha. */
tr.fds td.dia { color: var(--ocre-texto); }
tr.fds td:first-child { box-shadow: inset 3px 0 0 var(--ocre); }

/* O dia da semana ao lado da data, e não por baixo. */
td.dia small {
    display: inline;
    margin-left: 8px;
    font-size: 11px;
    color: var(--tinta-suave);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
/* Tem cor própria, por isso não herda a do fim de semana — e é
   justamente ele que ali interessa realçar. */
tr.fds td.dia small { color: var(--ocre-texto); font-weight: 500; }

/* ---------------------------------------------------------------
   Etiquetas
   --------------------------------------------------------------- */

.etiqueta {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 100px;
    font-size: 11.5px;
    font-weight: 500;
    line-height: 1.5;
    white-space: nowrap;
}
.etiqueta-vazia { background: #EDE7DA; color: var(--tinta-suave); }

/* O pill que também é seletor. Herda o desenho da etiqueta e perde o
   das caixas de escrever: a seta do browser fica de fora porque a
   largura é a do texto, e uma seta ali roubava-a toda. O cursor e o
   contorno de foco é que não se dispensam — sem eles ninguém adivinha
   que aquilo se clica. */
select.pill-estado {
    width: auto !important;
    padding: 3px 9px !important;
    border: 0;
    border-radius: 100px;
    font-family: var(--fonte);
    font-size: 11.5px !important;
    font-weight: 500;
    line-height: 1.5;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
    text-align: center;
    text-align-last: center;
}
/* O da fase herda a forma e fica neutro: a cor é linguagem do estado
   do trabalho, e dar-lhe cor aqui era pôr duas coisas a competir pela
   mesma leitura na mesma linha. */
select.pill-fase {
    width: auto !important;
    padding: 3px 9px !important;
    border: 1px solid var(--filete);
    border-radius: 100px;
    background: #FAF7F0;
    color: var(--tinta-suave);
    font-family: var(--fonte);
    font-size: 11.5px !important;
    line-height: 1.5;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
}
select.pill-fase:hover { background: #F0ECE2; color: var(--tinta); }

select.pill-estado:hover { filter: brightness(1.12); }
select.pill-estado:focus-visible {
    outline: 2px solid var(--azul-claro);
    outline-offset: 2px;
}
/* As opções abrem numa lista do sistema: o fundo colorido do pill não
   as acompanha e ficariam ilegíveis. */
select.pill-estado option { background: #fff; color: var(--tinta); }

.estado-aberto   { background: rgba(180, 118, 44, 0.16); color: var(--ocre-texto); }
.estado-fechado  { background: rgba(10, 68, 120, 0.13);  color: var(--azul-claro); }
.estado-faturado { background: rgba(47, 107, 79, 0.16); color: var(--ok); }
.estado-ativo     { background: rgba(47, 107, 79, 0.16); color: var(--ok); }
.estado-suspenso  { background: rgba(180, 118, 44, 0.16); color: var(--ocre-texto); }
.estado-concluido { background: rgba(10, 68, 120, 0.13);  color: var(--azul-claro); }
/* O estado de uma fatura: por receber, recebida em parte, recebida. É
   uma conta e não um campo — a etiqueta só diz o que a soma dos
   recebimentos já disse. */
.fatura-por-receber { background: rgba(163, 58, 42, 0.12); color: var(--perigo); }
.fatura-parcial     { background: rgba(180, 118, 44, 0.16); color: var(--ocre-texto); }
.fatura-pago        { background: rgba(47, 107, 79, 0.16); color: var(--ok); }

/* O estado da conta corrente. O vermelho é para o que ainda não foi
   pedido ao cliente — é o único que pede uma acção. */
.conta-por-faturar { background: rgba(163, 58, 42, 0.12); color: var(--perigo); }
.conta-parcial     { background: rgba(180, 118, 44, 0.16); color: var(--ocre-texto); }
.conta-total       { background: rgba(47, 107, 79, 0.16); color: var(--ok); }
.conta-vazio       { background: #EDE7DA; color: var(--tinta-suave); }

/* Uma fase fechada não é uma fase concluída: fecha-se com itens por
   fazer sempre que eles passam para a seguinte. Daí o cinzento e não o
   verde — é um "não se mexe mais aqui", não um "está tudo feito". */
/* Um trabalho que transitou de fase traz uma linha por baixo a dizer de
   onde veio. Ocre e não vermelho: escorregar de fase é informação, não
   é um erro. */
.transitou {
    display: block;
    margin-top: 3px;
    font-size: 11px;
    color: var(--ocre-texto);
    letter-spacing: 0.02em;
}
span.transitou { display: inline-block; margin: 0; }

.fase-aberta  { background: rgba(180, 118, 44, 0.16); color: var(--ocre-texto); }
.fase-fechada { background: #EDE7DA; color: var(--tinta-suave); }

.tipo-orcamento { background: rgba(10, 68, 120, 0.13); color: var(--azul-claro); }
.tipo-avulso    { background: #EDE7DA; color: var(--tinta-suave); }
.inativo { background: #EDE7DA; color: var(--tinta-suave); }

/* ---------------------------------------------------------------
   Números em destaque
   --------------------------------------------------------------- */

.numeros {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 10px;
    margin-bottom: 12px;
}
.numero {
    background: var(--carta);
    border: 1px solid var(--filete);
    border-radius: var(--raio);
    padding: 11px 13px;
    text-decoration: none;
    display: block;
}
a.numero:hover { border-color: var(--azul-claro); }
.numero b {
    display: block;
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
    font-size: 25px;
    font-weight: 500;
    letter-spacing: -0.02em;
    line-height: 1.15;
}
.numero span {
    display: block;
    margin-top: 3px;
    font-size: 12px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--tinta-suave);
}
.numero.alerta b { color: var(--perigo); }
.numero.bom b { color: var(--ok); }

/* O bloco de totais da folha: o mesmo desenho dos números em
   destaque, mas encostado ao fim da tabela e com o valor a faturar
   a pesar mais do que os outros, porque é o que se procura. */
.totais {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 1px;
    background: var(--filete);
    border-top: 1px solid var(--filete);
}
.totais div { background: #FAF7F0; padding: 9px 12px; }
.totais dt {
    font-size: 11px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--tinta-suave);
    margin: 0 0 3px;
}
.totais dd {
    margin: 0;
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
    font-size: 17px;
    font-weight: 500;
}
/* O escuro é o número que vai à fatura; o azul claro ao lado é o mesmo
   número sem os valores pendentes. Ficam a par, e a diferença entre os
   dois lê-se sem ter de a calcular. */
.totais div.principal { background: var(--azul); }
.totais div.principal dt { color: rgba(255, 255, 255, 0.6); }
.totais div.principal dd { color: #fff; font-size: 19px; }

/* O mesmo quadro, mas solto na página em vez de encostado a uma
   tabela: precisa das bordas de fora e da margem que o cartão dava. */
.totais-solto {
    border: 1px solid var(--filete);
    border-radius: var(--raio);
    overflow: hidden;
    margin-bottom: 12px;
}

.totais div.secundaria { background: var(--azul-claro); }
.totais div.secundaria dt { color: rgba(255, 255, 255, 0.6); }
.totais div.secundaria dd { color: #fff; font-size: 19px; }

/* ---------------------------------------------------------------
   Progresso das fases
   --------------------------------------------------------------- */

.barra {
    height: 6px;
    border-radius: 100px;
    background: #EDE7DA;
    overflow: hidden;
    min-width: 90px;
}
.barra i { display: block; height: 100%; background: var(--ok); border-radius: 100px; }
.barra-fina { display: inline-block; width: 56px; height: 4px; vertical-align: middle; margin-left: 6px; }

/* Uma barra de acções solta dentro de um cartão não precisa da margem
   que tem quando abre uma página. */
.barra-solta { margin: 0; }
.cartao-corpo .barra-solta + .barra-solta { margin-top: 12px; }
.barra-fina i { background: var(--ocre); }

/* Um número que ainda pede alguma coisa lê-se a vermelho. Só esses: se
   a coluna toda fosse vermelha deixava de assinalar nada. */
table.tabela td.em-falta { color: var(--perigo); font-weight: 500; }

.fase-topo { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* O nome de uma fase, editável no sítio. Tem a cara de um título até se
   lhe tocar: uma caixa com moldura ali, entre etiquetas e contagens,
   pesava mais do que o nome que mostra. */
/* As setas de ordenação, coladas uma à outra como um par. */
.setas { display: inline-flex; gap: 2px; }
.btn-seta {
    display: inline-flex;
    padding: 4px;
    border: 1px solid var(--filete);
    border-radius: var(--raio);
    background: var(--carta);
    color: var(--tinta-suave);
    cursor: pointer;
}
.btn-seta svg {
    width: 15px; height: 15px;
    fill: none; stroke: currentColor; stroke-width: 2;
    stroke-linecap: round; stroke-linejoin: round;
}
.btn-seta:hover:not(:disabled) { background: #F0ECE2; color: var(--tinta); }
.btn-seta:disabled { opacity: 0.3; cursor: default; }

.renomear { display: flex; align-items: center; gap: 6px; }
.renomear .fase-numero {
    font-size: 15px;
    font-weight: 600;
    color: var(--tinta-suave);
}
.renomear input[type="text"] {
    width: 220px;
    padding: 5px 8px;
    border: 1px solid transparent;
    border-radius: var(--raio);
    background: transparent;
    font: inherit;
    font-size: 15px;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--tinta);
}
.renomear input[type="text"]:hover { border-color: var(--filete); background: #fff; }
.renomear input[type="text"]:focus {
    border-color: var(--azul-claro);
    background: #fff;
    outline: 2px solid var(--azul-claro);
    outline-offset: -1px;
}
/* O botão só aparece quando se está a mexer no nome: sempre à vista era
   um botão por fase a dizer que há ali trabalho por fazer. */
.renomear .btn { opacity: 0; transition: opacity 0.12s ease; }
.renomear:hover .btn,
.renomear:focus-within .btn { opacity: 1; }
.cartao > header .grupo { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.fase-topo .barra { flex: 1 1 140px; max-width: 260px; }
.fase-conta { font-family: var(--mono); font-size: 12.5px; color: var(--tinta-suave); white-space: nowrap; }

/* ---------------------------------------------------------------
   Entrada
   --------------------------------------------------------------- */

.login {
    position: relative;
    overflow: hidden;
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: 20px 16px;
    background: var(--azul);
}

/* Fundo em mapa de Gantt (desenhado em login.php). Cores chapadas e
   traço fino, sem sombras nem desfoques: tem de parecer uma folha de
   planeamento vista de longe, não uma ilustração. O "slice" corta as
   pontas em ecrãs estreitos e mantém o meio, que é onde está a caixa. */
.login-fundo {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
}
/* Num telemóvel o corte ao centro deixava a linha "hoje" fora do ecrã,
   e é ela que dá sentido ao resto. Aqui o desenho fica à altura do ecrã
   e desliza até o "hoje" (69% da largura do desenho) cair perto da
   margem direita. */
@media (max-width: 640px) {
    .login-fundo {
        inset: 0 auto 0 50%;
        width: auto;
        aspect-ratio: 1440 / 900;
        transform: translateX(calc(-69% + 35vw));
    }
}
.login-fundo .g-semana  { stroke: rgba(255, 255, 255, 0.06); stroke-width: 1; }
.login-fundo .g-topo    { stroke: rgba(255, 255, 255, 0.18); stroke-width: 1; }
.login-fundo .g-rotulo  { fill: rgba(255, 255, 255, 0.38); font: 500 11px var(--mono); letter-spacing: 0.04em; }
.login-fundo .g-barra   { fill: rgba(255, 255, 255, 0.06); stroke: rgba(255, 255, 255, 0.3); stroke-width: 1; }
.login-fundo .g-feito   { fill: rgba(255, 255, 255, 0.26); }
.login-fundo .g-barra.g-atraso { fill: rgba(180, 118, 44, 0.08); stroke: rgba(180, 118, 44, 0.7); }
.login-fundo .g-feito.g-atraso { fill: var(--ocre); }
.login-fundo .g-marco   { fill: var(--azul); stroke: rgba(255, 255, 255, 0.55); stroke-width: 1.5; }
.login-fundo .g-hoje    { stroke: var(--ocre); stroke-width: 1.5; }
.login-fundo .g-hoje-rotulo { fill: var(--ocre); font: 600 11px var(--mono); letter-spacing: 0.12em; }

.login-caixa {
    position: relative;
    width: 100%;
    max-width: 370px;
    background: var(--carta);
    border-radius: 6px;
    padding: 30px 28px;
}
.login-caixa h1 {
    font-size: 20px;
    letter-spacing: -0.01em;
    margin-bottom: 2px;
}
.login-caixa p.sub { margin: 0 0 22px; font-size: 13px; color: var(--tinta-suave); }
.login-caixa .btn { width: 100%; justify-content: center; margin-top: 6px; }

/* ---------------------------------------------------------------
   Separadores
   --------------------------------------------------------------- */

.abas {
    display: flex;
    gap: 2px;
    border-bottom: 1px solid var(--filete);
    margin-bottom: 12px;
    overflow-x: auto;
}
.abas a {
    padding: 7px 12px;
    text-decoration: none;
    font-size: 13.5px;
    color: var(--tinta-suave);
    border-bottom: 2px solid transparent;
    white-space: nowrap;
}
.abas a:hover { color: var(--tinta); }
.abas a.ativo { color: var(--tinta); border-bottom-color: var(--azul); font-weight: 500; }

/* ---------------------------------------------------------------
   Orçamentos
   --------------------------------------------------------------- */

/* Os estados de uma proposta. O aceite a verde e o recusado a vinho são
   os únicos cheios: são decisões, e lêem-se de longe na lista. Os
   outros são a espera, em tons de papel. */
.etiqueta.orc-rascunho    { background: #EDE7DA; color: var(--tinta-suave); }
.etiqueta.orc-enviado     { background: rgba(0, 45, 87, 0.1); color: var(--azul); }
.etiqueta.orc-expirado    { background: rgba(180, 118, 44, 0.16); color: var(--ocre-texto); }
.etiqueta.orc-aceite      { background: var(--ok); color: #fff; }
.etiqueta.orc-recusado    { background: var(--perigo); color: #fff; }
.etiqueta.orc-substituido { background: transparent; color: var(--tinta-suave); border: 1px dashed var(--filete); }

/* O editor tranca-se com um <fieldset disabled>, que desliga todos os
   campos de uma vez; a moldura que o browser lhe põe é que não se quer. */
fieldset.sem-moldura { border: 0; margin: 0; padding: 0; min-width: 0; }
fieldset.sem-moldura:disabled input,
fieldset.sem-moldura:disabled select,
fieldset.sem-moldura:disabled textarea { background: #FAF7F0; color: var(--tinta); }

/* O que o JavaScript esconde tem de ficar escondido: um .campo é flex,
   e o display dele ganhava ao atributo hidden, que é só uma regra do
   browser e das mais fracas. */
[data-mostra-se][hidden],
[data-so-global][hidden],
[data-so-desconto][hidden],
[data-modelos-tranches][hidden],
[data-t-aviso][hidden] { display: none !important; }

.orc-destino { margin-top: 10px; }
table.tabela-orc td { vertical-align: middle; }
.orc-valor { margin-top: 10px; }
.totais-orc { margin-top: 14px; border: 1px solid var(--filete); border-radius: var(--raio); overflow: hidden; }
.orc-condicoes { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }

/* A tabela dos requisitos: o módulo e o requisito são o que se lê, o
   detalhe é uma caixa de duas linhas que o PDF põe por baixo. */
table.tabela-orc .c-fase { width: 170px; }
table.tabela-orc textarea { min-height: 38px; }
table.tabela-orc td.c-check { white-space: nowrap; }
table.tabela-orc .setas { vertical-align: middle; margin-right: 2px; }
table.tabela-orc tbody[data-novas] tr td { background: #FDFBF6; }

/* O «Mais» de um orçamento: uma acção por linha, com a explicação ao
   lado, porque são as que se usam uma vez por outra e se esquece o que
   fazem. */
.lista-accoes { display: flex; flex-direction: column; gap: 10px; }
.accao-linha { display: flex; align-items: center; gap: 12px; }
.accao-linha .btn { flex: none; min-width: 150px; justify-content: center; }
.accao-linha .nota { font-size: 12px; color: var(--tinta-suave); line-height: 1.4; }

/* O botão de gravar fica colado ao fundo do ecrã enquanto se escreve:
   o editor é comprido, e subir e descer para gravar era perder o sítio. */
.form-pe-fixo {
    position: sticky;
    bottom: 0;
    z-index: 5;
    margin-top: 12px;
    border: 1px solid var(--filete);
    border-radius: var(--raio);
    box-shadow: 0 -4px 14px rgba(20, 22, 26, 0.06);
}

/* ---------------------------------------------------------------
   Ecrãs estreitos
   --------------------------------------------------------------- */

@media (max-width: 900px) {
    .sidebar {
        position: fixed;
        z-index: 40;
        left: 0; top: 0;
        transform: translateX(-100%);
        transition: transform 0.2s ease;
    }
    body.menu-aberto .sidebar { transform: none; }
    body.menu-aberto .fundo-menu {
        display: block;
        position: fixed;
        inset: 0;
        background: rgba(20, 22, 26, 0.45);
        z-index: 30;
    }
    .menu-movel { display: block; }
    .conteudo { padding: 10px 10px 32px; }
    .topbar { padding-inline: 10px; }
    .topbar-utilizador .nome { display: none; }
    .grelha-campos { grid-template-columns: 1fr; }

    /* O nome de uma fase ocupa a largura que sobra em vez dos 220px
       fixos, que empurravam as etiquetas para uma linha só delas. */
    .renomear { flex: 1 1 100%; }
    .renomear input[type="text"] { width: auto; flex: 1 1 auto; min-width: 0; }
    .cartao > header { gap: 8px; }
    .cartao > header .grupo { width: 100%; }
    .fase-topo .barra { max-width: none; }
}

/* ---------------------------------------------------------------
   Telemóvel
   Um popup num ecrã de 390px não é uma caixa a flutuar: é o ecrã. Com
   margens e cantos redondos sobrava-lhe metade da largura para a folha
   de horas, e é a folha que se veio aqui ver.

   Vale até aos 900px e não só no telemóvel: num tablet de pé (768,
   820) uma tabela de onze colunas também não cabe, e a alternativa era
   deslizá-la para o lado — que é o que não se quer em ecrã nenhum.
   --------------------------------------------------------------- */

@media (max-width: 900px) {
    dialog.popup,
    dialog.popup-estreita,
    dialog.popup-larga {
        width: 100vw;
        max-width: 100vw;
        height: 100dvh;
        max-height: 100dvh;
        margin: 0;
        border: 0;
        border-radius: 0;
    }
    /* Sem tecto próprio: a tabela cresce e é o corpo do popup que rola,
       que num ecrã desta altura é o mesmo gesto. */
    .popup-corpo .tabela-envolve { max-height: none; }
    .popup-corpo table.tabela thead th { position: static; }
    .popup-corpo table.tabela tfoot td { position: static; }

    /* ------------------------------------------------------------
       As tabelas deixam de ser tabelas.

       Uma tabela de onze colunas num ecrã de 390px não se resolve a
       encolher: ou se lê um terço de cada vez a deslizar para o lado —
       e a deslizar perde-se a linha em que se ia — ou se muda de forma.
       Cada LINHA passa a um bloco, e cada célula a um par
       «nome do campo: valor», um por linha do bloco. Vê-se a linha
       inteira de uma vez e não há deslizar horizontal em sítio nenhum.

       O nome do campo é o título da coluna, copiado para um
       data-rotulo pelo JavaScript e não escrito à mão em cada célula:
       são vinte e tantas tabelas no site, e uma que se esquecesse
       ficava com uma coluna de valores sem nome. Sem JavaScript fica a
       tabela como está no ecrã grande, que ao menos se lê a deslizar.
       ------------------------------------------------------------ */
    .tabela-envolve { overflow-x: visible; }

    table.tabela,
    table.tabela > tbody,
    table.tabela > tfoot,
    table.tabela > tbody > tr,
    table.tabela > tfoot > tr,
    table.tabela > tbody > tr > td,
    table.tabela > tfoot > tr > td {
        display: block;
        width: auto;
    }
    table.tabela > thead { display: none; }

    /* O bloco de uma linha: a moldura é o que diz onde uma acaba e a
       seguinte começa, agora que não há linhas de grelha. */
    table.tabela > tbody > tr {
        margin-bottom: 8px;
        padding: 4px 0;
        border: 1px solid var(--filete);
        border-radius: var(--raio);
        background: var(--carta);
    }
    table.tabela > tbody > tr:hover td { background: none; }

    /* Cada célula é um par: o nome à esquerda, o valor à direita. Em
       grelha e não em flex para os nomes ficarem todos alinhados uns
       com os outros dentro do bloco. */
    table.tabela > tbody > tr > td,
    table.tabela > tfoot > tr > td {
        display: grid;
        /* minmax(0, …) e não 1fr: um 1fr não desce abaixo do conteúdo,
           e um nome de ficheiro ou um e-mail sem espaços alargava a
           célula para fora do ecrã. */
        grid-template-columns: 8.5em minmax(0, 1fr);
        gap: 10px;
        min-width: 0;
        max-width: none;
        align-items: center;
        padding: 5px 10px;
        border: 0;
        text-align: left;
    }
    table.tabela > tbody > tr > td[data-rotulo]::before,
    table.tabela > tfoot > tr > td[data-rotulo]::before {
        content: attr(data-rotulo);
        font-size: 10.5px;
        font-weight: 600;
        letter-spacing: 0.05em;
        text-transform: uppercase;
        color: var(--tinta-suave);
        line-height: 1.3;
    }
    /* Uma célula sem título de coluna (a dos botões) fica com a largura
       toda, sem uma coluna de nome vazia a empurrá-la para o meio. */
    table.tabela > tbody > tr > td:not([data-rotulo]),
    table.tabela > tfoot > tr > td:not([data-rotulo]) { grid-template-columns: minmax(0, 1fr); }
    /* Uma célula vazia não é uma linha do bloco. */
    table.tabela > tbody > tr > td:empty,
    table.tabela > tfoot > tr > td:empty { display: none; }

    /* Os números voltam a alinhar à esquerda: alinhados à direita, num
       bloco, ficavam encostados à margem e longe do nome que lhes
       corresponde. O monoespaçado fica — é o que os mantém comparáveis. */
    table.tabela > tbody > tr > td.num,
    table.tabela > tfoot > tr > td.num { text-align: left; }

    /* As larguras de coluna não querem dizer nada quando cada célula é
       uma linha; os campos passam a ocupar o espaço do valor. */
    table.tabela > tbody > tr > td.c-data,
    table.tabela > tbody > tr > td.c-hora,
    table.tabela > tbody > tr > td.c-valor,
    table.tabela > tbody > tr > td.c-calc,
    table.tabela > tbody > tr > td.c-num,
    table.tabela > tbody > tr > td.c-euro,
    table.tabela > tbody > tr > td.c-doc,
    table.tabela > tbody > tr > td.c-fase,
    table.tabela > tbody > tr > td.c-estado,
    table.tabela > tbody > tr > td.c-desc,
    table.tabela > tbody > tr > td.c-desc-larga,
    table.tabela > tbody > tr > td.c-notas,
    table.tabela > tbody > tr > td.c-notas-larga,
    table.tabela > tbody > tr > td.c-check,
    table.tabela > tbody > tr > td.apertado { width: auto; white-space: normal; }

    table.tabela input[type="text"],
    table.tabela input[type="date"],
    table.tabela input[type="number"],
    table.tabela select,
    table.tabela textarea { width: 100%; }
    /* A caixa de data media-se ao conteúdo para a coluna não crescer;
       aqui não há coluna que cresça. */
    table.tabela > tbody > tr > td.c-data input[type="date"] { width: 100% !important; }

    /* O dia da semana ao lado da data, e o «transitou da fase 1» por
       baixo da descrição, continuam onde estavam dentro do par. */
    table.tabela > tbody > tr > td.dia { grid-template-columns: 8.5em minmax(0, 1fr) auto; }

    /* O rodapé dos totais é um bloco só, com a barra azul em cima que
       na tabela era o sublinhado duplo da folha de cálculo. */
    table.tabela > tfoot {
        display: block;
        border-top: 2px solid var(--azul);
        background: #FAF7F0;
        border-radius: var(--raio);
    }
    table.tabela > tfoot > tr > td { border: 0; }

    /* O verde e o laranja da folha de horas pintam o bloco inteiro, que
       é o que a linha passou a ser. */
    table.tabela > tbody > tr.iguais { background: rgba(47, 107, 79, 0.16); }
    table.tabela > tbody > tr.difere { background: rgba(180, 118, 44, 0.20); }
    table.tabela > tbody > tr.iguais td,
    table.tabela > tbody > tr.difere td { background: none; }
    table.tabela > tbody > tr.fds td:first-child { box-shadow: none; }
    table.tabela > tbody > tr.fds { box-shadow: inset 3px 0 0 var(--ocre); }


    /* O rodapé de um formulário passa a duas linhas, com o botão a
       ocupar a largura toda: é o alvo mais premido do ecrã. */
    .form-pe { flex-direction: column; align-items: stretch; }
    .form-pe .grupo .btn { flex: 1 1 auto; justify-content: center; }
    .filtro { width: 100%; }
    .filtro input, .filtro select { flex: 1 1 160px; min-width: 0; }
    .filtro .larga { min-width: 0; width: 100%; }

    /* Uma fila de botões pequenos num ecrã estreito tem de ser tocável:
       44px é a medida a partir da qual se acerta com o dedo. */
    .cartao > header .grupo .btn,
    .barra-accoes .grupo .btn { min-height: 34px; }
    .btn-apagar { padding: 8px; }

    /* Os separadores partem para uma segunda linha em vez de rolarem
       para o lado: um separador escondido à direita não se sabe que
       existe. */
    .abas { flex-wrap: wrap; overflow-x: visible; }

    /* O «Mais» de um orçamento: o botão em cima, a explicação por baixo. */
    .accao-linha { flex-direction: column; align-items: stretch; gap: 4px; }
    .accao-linha .btn { min-width: 0; }
    table.tabela-orc .c-fase { width: auto; }

    /* Um e-mail, um nome de ficheiro, um n.º de documento comprido: sem
       espaços onde partir, empurravam o cartão para fora do ecrã. */
    .conteudo, dialog.popup { overflow-wrap: anywhere; }
    .etiqueta { white-space: normal; max-width: 100%; }
    .filtro .estreita { min-width: 0; }

    .totais { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); }
    .totais dd { font-size: 15px; }
    .totais-horas dd { font-size: 17px; }
    .numero b { font-size: 21px; }
}

/* Num ecrã de 380px a barra de topo tem quatro coisas e a largura de
   três: a palavra «Voltar» sai e fica a seta, que é o que se reconhece
   sem ler. */
@media (max-width: 460px) {
    .btn-voltar span { display: none; }
    .btn-voltar { padding: 5px 7px; }
    .topbar { gap: 8px; }
}

/* ---- Gravar ao mudar (data-autogravar) ----
   Uma piscadela e mais nada: verde gravou, vermelho não gravou. A cor
   não é a única pista — o erro vem escrito ao lado do campo. */
[data-autogravar].a-gravar { opacity: 0.6; }
[data-autogravar].gravou { animation: piscar-ok 1.2s ease-out; }
[data-autogravar].falhou { animation: piscar-erro 1.6s ease-out; }
@keyframes piscar-ok {
    0%, 35% { background-color: rgba(47, 107, 79, 0.28); border-color: var(--ok); box-shadow: 0 0 0 2px rgba(47, 107, 79, 0.25); }
    100%    { background-color: transparent; box-shadow: 0 0 0 0 transparent; }
}
@keyframes piscar-erro {
    0%, 45% { background-color: rgba(163, 58, 42, 0.2); border-color: var(--perigo); box-shadow: 0 0 0 2px rgba(163, 58, 42, 0.25); }
    100%    { background-color: transparent; box-shadow: 0 0 0 0 transparent; }
}
.autogravar-erro {
    display: block;
    margin-top: 2px;
    font-size: 12px;
    line-height: 1.3;
    color: var(--perigo);
}
@media (prefers-reduced-motion: reduce) {
    [data-autogravar].gravou { animation: none; outline: 2px solid var(--ok); }
    [data-autogravar].falhou { animation: none; outline: 2px solid var(--perigo); }
}
