/* =============================================================================================
   Horas — design system ("Chronos")
   A calm, precise look inspired by chronographs: deep navy instrument panels, a cyan accent like
   a luminous watch hand, tabular numerals for every time value, and the original WinForms
   background (gears + clock face) behind glass surfaces.
   All colours, radii and shadows are tokens below, so the whole app can be re-themed here.
   ============================================================================================= */

/* ---- Fonts (self-hosted, SIL Open Font License: free for commercial use) ---- */
@font-face {
    font-family: 'Inter';
    src: url('fonts/inter.woff2') format('woff2');
    font-weight: 400 700;
    font-display: swap;
}

@font-face {
    font-family: 'Space Grotesk';
    src: url('fonts/space-grotesk.woff2') format('woff2');
    font-weight: 500 700;
    font-display: swap;
}

@font-face {
    font-family: 'JetBrains Mono';
    src: url('fonts/jetbrains-mono.woff2') format('woff2');
    font-weight: 500;
    font-display: swap;
}

/* ---- Tokens ---- */
:root {
    --cr-ink-950: #050d1c;
    --cr-ink-900: #0a1830;
    --cr-ink-800: #102445;
    --cr-ink-700: #19345f;
    --cr-blue-600: #2a5bea;
    --cr-blue-500: #4778f0;
    --cr-blue-100: #e6edff;
    --cr-cyan-400: #4778f0;
    --cr-cyan-300: #8aa9ff;
    --cr-text: #0f2440;
    --cr-text-2: #4b607d;
    --cr-text-3: #7a8ca5;
    --cr-line: rgba(15, 36, 64, 0.12);
    --cr-line-strong: rgba(15, 36, 64, 0.22);
    --cr-surface: rgba(255, 255, 255, 0.84);
    --cr-surface-solid: #ffffff;
    --cr-surface-2: rgba(240, 246, 253, 0.9);
    --cr-success: #138a5a;
    --cr-warning: #b86e00;
    --cr-danger: #c42b3b;
    --cr-radius: 14px;
    --cr-radius-sm: 9px;
    --cr-shadow: 0 1px 2px rgba(10, 24, 48, 0.06), 0 10px 30px rgba(10, 24, 48, 0.08);
    --cr-shadow-lg: 0 2px 4px rgba(10, 24, 48, 0.06), 0 24px 60px rgba(10, 24, 48, 0.18);
    --cr-glow: 0 0 0 3px rgba(30, 198, 227, 0.28);
    /* Semantic colours that change with the theme: accent text (titles, links, active items) and
       strong text (figures). The ink/blue scale above stays for the navy surfaces in both themes. */
    --cr-accent: var(--cr-blue-600);
    --cr-strong: var(--cr-ink-800);
    /* Line art of the animated background (FundoRelogio). */
    --fr-traco: rgba(255, 255, 255, 0.8);
    --fr-traco-fraco: rgba(255, 255, 255, 0.6);
    --cr-font: 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;
    --cr-font-display: 'Space Grotesk', 'Inter', 'Segoe UI', sans-serif;
    --cr-font-mono: 'JetBrains Mono', ui-monospace, 'Cascadia Mono', Consolas, monospace;
    /* Bootstrap hooks */
    --bs-body-font-family: var(--cr-font);
    --bs-body-color: var(--cr-text);
    --bs-primary: var(--cr-blue-600);
    --bs-primary-rgb: 42, 91, 234;
    --bs-link-color: var(--cr-blue-600);
    --bs-link-color-rgb: 42, 91, 234;
    --bs-link-hover-color: var(--cr-ink-700);
    --bs-border-radius: var(--cr-radius-sm);
}

html, body {
    font-family: var(--cr-font);
    font-size: 15.5px;
    color: var(--cr-text);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    background: var(--cr-ink-950);
}

/* Text cursor (I-beam) of our own over every field: the system one follows the Windows pointer
   scheme and the page's colour scheme and could come out white on the light fields, invisible
   (reported 2026-09-26). A navy bar with a white outline shows on light and dark fields alike. */
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="button"]):not([type="submit"]):not([type="reset"]):not([type="file"]):not(:disabled),
textarea:not(:disabled),
[contenteditable="true"] {
    cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='24' viewBox='0 0 16 24'%3E%3Cpath d='M5 2.5h6M8 2.5v19M5 21.5h6' fill='none' stroke='%23fff' stroke-width='3.6' stroke-linecap='round'/%3E%3Cpath d='M5 2.5h6M8 2.5v19M5 21.5h6' fill='none' stroke='%230f2440' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E") 8 12, text;
}

/* Every number in tables and figures lines up in columns. */
table, .num, .valor-grande {
    font-variant-numeric: tabular-nums;
}

.mono {
    font-family: var(--cr-font-mono);
}

h1, h2, h3, h4, h5, .display {
    font-family: var(--cr-font-display);
    letter-spacing: -0.01em;
    color: var(--cr-text);
}

h1:focus {
    outline: none;
}

a {
    text-decoration: none;
}

/* ---- Background of every screen: the animated clock (FundoRelogio.razor), redrawn from the
   WinForms Background.jpg. The page's own content sits above it. ---- */
.fundo-app {
    position: relative;
    background: #cfe2f7;
    min-height: 100vh;
}

    .fundo-app > :not(.fundo-relogio) {
        position: relative;
        z-index: 1;
    }

.fundo-relogio {
    position: absolute;
    inset: 0;
    z-index: 0;
    overflow: hidden;
    pointer-events: none;
    background: linear-gradient(170deg, #e4dffb 0%, #d6e0fa 30%, #b9daf6 65%, #93cbf1 100%);
}

/* A light veil over the line art: keeps the background present but quiet, so text on top stays easy to read. */
.fundo-relogio::after {
    content: "";
    position: absolute;
    inset: 0;
    background: rgba(246, 249, 255, 0.12);
}

/* Soft light slowly drifting across the sky, like the haze of the original picture. */
.fundo-relogio .luz {
    position: absolute;
    border-radius: 50%;
    will-change: transform;
}

.fundo-relogio .luz-1 {
    width: 55vw;
    height: 55vw;
    left: 12%;
    top: -22%;
    background: radial-gradient(circle, rgba(196, 184, 255, 0.45) 0%, rgba(196, 184, 255, 0) 65%);
    animation: fr-deriva-1 40s ease-in-out infinite alternate;
}

.fundo-relogio .luz-2 {
    width: 45vw;
    height: 45vw;
    right: 18%;
    bottom: -18%;
    background: radial-gradient(circle, rgba(111, 226, 244, 0.38) 0%, rgba(111, 226, 244, 0) 65%);
    animation: fr-deriva-2 52s ease-in-out infinite alternate;
}

@keyframes fr-deriva-1 {
    to { transform: translate(18vw, 14vh) scale(1.15); }
}

@keyframes fr-deriva-2 {
    to { transform: translate(-22vw, -10vh) scale(.9); }
}

/* The corner clock (gears inside a dial arc), top-left. */
.fr-canto {
    position: absolute;
    width: clamp(270px, 28vw, 500px);
    opacity: .9;
}

.fr-canto-sup {
    left: 0;
    top: 0;
}

.fr-engrenagens {
    display: block;
    width: 100%;
    height: auto;
}

.fr-defs {
    position: absolute;
}

/* Everything that turns: rotates about its own centre (each group holds an invisible circle centred
   on its axis, so its box centre is the axis). */
.fr-rodar {
    transform-box: fill-box;
    transform-origin: center;
    animation: fr-rodar 60s linear infinite;
}

@keyframes fr-rodar {
    to { transform: rotate(360deg); }
}

/* Meshing gears: speed in proportion to the number of teeth, neighbours turning the other way. */
.fr-eng-a { animation-duration: 48s; }
.fr-eng-b { animation-duration: 40s; animation-direction: reverse; }
.fr-eng-c { animation-duration: 20s; animation-direction: reverse; }

.fr-invisivel { fill: none; stroke: none; }
.fr-linha { fill: none; stroke: var(--fr-traco); stroke-width: 2; }
.fr-fina { stroke-width: 1.2; }
.fr-marca { stroke: var(--fr-traco); stroke-width: 1.2; }
.fr-marca-forte { stroke-width: 2.4; }
.fr-engrenagem { fill: url(#fr-grad-engrenagem); stroke: var(--fr-traco); stroke-width: 1.5; }
.fr-raio { stroke: var(--fr-traco-fraco); stroke-width: 7; stroke-linecap: round; }
.fr-furo { fill: none; stroke: var(--fr-traco); stroke-width: 1.5; }

/* ---- Page header ---- */
.cabecalho-pagina {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .75rem 2rem;
    margin-bottom: .9rem;
}

/* Title of every page ("PAINEL PRINCIPAL" on Início, the module name on the others): one shared
   style, so it has the same size and weight on every screen. */
.rotulo-modulo {
    margin: 0;
    font-family: var(--cr-font-display);
    font-size: 2.1rem;
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--cr-accent);
}

.cabecalho-pagina .acoes {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .6rem;
}

/* ---- Summary figures next to the page title (like the totals strip of Harvest/Clockify reports) ---- */
.kpis {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: .6rem;
}

.kpi {
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-width: 8.5rem;
    padding: .4rem .9rem;
    border-radius: var(--cr-radius-sm);
    background: var(--cr-surface);
    border: 1px solid rgba(255, 255, 255, 0.75);
    box-shadow: var(--cr-shadow);
}

.kpi-rotulo {
    font-family: var(--cr-font-mono);
    font-size: .64rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--cr-text-2);
}

.kpi-valor {
    font-family: var(--cr-font-display);
    font-size: 1.2rem;
    font-weight: 700;
    line-height: 1.2;
    color: var(--cr-strong);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

    .kpi-valor small {
        font-family: var(--cr-font);
        font-size: .78rem;
        font-weight: 500;
        color: var(--cr-text-2);
    }

.kpi.destaque {
    background: linear-gradient(180deg, var(--cr-ink-800), var(--cr-ink-900));
    border-color: rgba(111, 226, 244, 0.25);
}

    .kpi.destaque .kpi-rotulo { color: rgba(111, 226, 244, 0.75); }
    .kpi.destaque .kpi-valor { color: #fff; }
    .kpi.destaque .kpi-valor small { color: rgba(226, 236, 250, 0.7); }

/* ---- Filter bar: every filter of a screen on one compact strip above the table ----
   A light glass strip in light mode, the navy of the period readout in dark mode. The colours of the
   filter controls (period, segmented, pills, Firma) are the --barra-* tokens, set on :root so the
   same controls also work outside the bar (the period on the home page), and redefined for dark
   mode. Thin vertical lines separate the groups (Período | Horas | Firma | options). Labels keep the
   name of the WinForms panel (Horas, Firma, ...), in the colour of the active buttons.
   No backdrop-filter here: it would trap the Firma list's click-outside layer inside the bar. */
:root {
    --barra-recesso: rgba(15, 36, 64, 0.06);            /* sunken controls: period, segmented */
    --barra-recesso-borda: rgba(15, 36, 64, 0.1);
    --barra-campo: var(--cr-surface-solid);             /* buttons and pills */
    --barra-sep: rgba(15, 36, 64, 0.14);
    --barra-destaque: var(--cr-blue-600);               /* labels, dates, active option */
    --barra-ativo-fundo: var(--cr-surface-solid);
    --barra-ativo-borda: rgba(42, 91, 234, 0.3);
    --barra-ativo-sombra: 0 1px 3px rgba(10, 24, 48, 0.14);
    --barra-hover: rgba(42, 91, 234, 0.08);
    --barra-foco-borda: rgba(42, 91, 234, 0.5);
}

.barra-filtros {
    position: relative;
    z-index: 5;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem 0;          /* the space between groups comes from the separators (SeparadorBarra) */
    padding: .45rem .7rem;
    margin-bottom: .75rem;
    border-radius: var(--cr-radius);
    background: rgba(255, 255, 255, 0.9);
    border: 1px solid rgba(255, 255, 255, 0.8);
    box-shadow: var(--cr-shadow);
    color: var(--cr-text);
}

    .barra-filtros .espaco {
        flex: 1 1 0;
    }

    /* Separator between two groups (SeparadorBarra): takes an equal part of the free space and draws a
       short thin vertical line in its middle (period | Horas | Firma | options | buttons | search).
       The groups keep their natural width, so they are spread evenly across the bar (asked
       2026-09-27, "respirar mais"). "fixo": narrow, does not grow — the group before the search
       (PDF/Excel…) stays next to it. */
    .barra-filtros .barra-sep {
        flex: 1 1 .8rem;
        align-self: stretch;
        display: flex;
        justify-content: center;
        min-width: .8rem;
    }

        .barra-filtros .barra-sep::before {
            content: "";
            margin: .4rem 0;
            border-left: 1px solid var(--barra-sep);
        }

    .barra-filtros .barra-sep.fixo {
        flex: 0 0 1.4rem;
    }

    /* Option and button texts in capitals, like the labels (NÃO PAGAS, DETALHE, PDF, FECHAR PERÍODO…). */
    .barra-filtros .segmentado button,
    .barra-filtros .alternar,
    .barra-filtros .btn {
        text-transform: uppercase;
        letter-spacing: .03em;
        font-size: .8rem;
        font-weight: 600;
    }

    .barra-filtros .form-check-input:checked {
        background-color: var(--cr-blue-500);
        border-color: var(--cr-blue-500);
    }

.controlo {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
}

.controlo-rotulo {
    font-family: var(--cr-font-display);
    font-size: .8rem;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--barra-destaque, var(--cr-accent));
}

/* Segmented control (Horas: Não Pagas / Pagas / Totais), recessed like the period readout. */
.segmentado {
    display: inline-flex;
    padding: 3px;
    gap: 2px;
    border-radius: 10px;
    background: var(--barra-recesso);
    box-shadow: inset 0 0 0 1px var(--barra-recesso-borda);
}

    .segmentado button {
        border: none;
        border-radius: 7px;
        padding: .22rem .7rem;
        background: transparent;
        color: var(--cr-text-2);
        font-size: .86rem;
        font-weight: 500;
        white-space: nowrap;
        transition: background-color .12s, color .12s;
    }

        .segmentado button:hover:not(.ativo) {
            color: var(--cr-text);
            background: var(--barra-hover);
        }

        .segmentado button.ativo {
            background: var(--barra-ativo-fundo);
            color: var(--barra-destaque);
            font-weight: 600;
            box-shadow: var(--barra-ativo-sombra), inset 0 0 0 1px var(--barra-ativo-borda);
        }

        .segmentado button:focus-visible {
            outline: none;
            box-shadow: var(--cr-glow);
        }

/* On/off options as small toggle pills (e.g. "Detalhe diário"). */
.alternar {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    height: 2rem;
    padding: 0 .65rem;
    border-radius: 999px;
    border: 1px solid var(--cr-line-strong);
    background: var(--barra-campo);
    font-size: .85rem;
    color: var(--cr-text-2);
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}

    .alternar .form-check-input {
        margin: 0;
    }

    .alternar:has(input:checked) {
        color: var(--barra-destaque);
        border-color: var(--barra-ativo-borda);
        background: var(--cr-blue-100);
    }

/* Button that opens a list of choices (Firma). */
.menu-filtro {
    position: relative;
}

.btn-filtro {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    height: 2rem;
    max-width: 16rem;
    padding: 0 .6rem 0 .75rem;
    border-radius: var(--cr-radius-sm);
    border: 1px solid var(--cr-line-strong);
    background: var(--barra-campo);
    color: var(--cr-text);
    font-size: .86rem;
    font-weight: 500;
}

    .btn-filtro:hover, .btn-filtro[aria-expanded="true"] {
        border-color: var(--barra-foco-borda);
    }

    .btn-filtro:focus-visible {
        outline: none;
        box-shadow: var(--cr-glow);
    }

    .btn-filtro .icone {
        color: var(--cr-text-3);
    }

.btn-filtro-texto {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.menu-fundo {
    position: fixed;
    inset: 0;
    z-index: 29;
}

.menu-lista {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: 30;
    min-width: 17rem;
    max-height: min(60vh, 26rem);
    overflow: auto;
    padding: .45rem;
    border-radius: 12px;
    background: var(--cr-surface-solid);
    border: 1px solid var(--cr-line);
    box-shadow: var(--cr-shadow-lg);
}

.menu-lista-topo {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .25rem .55rem .45rem;
    margin-bottom: .25rem;
    border-bottom: 1px solid var(--cr-line);
}

.menu-opcao {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .4rem .55rem;
    border-radius: 7px;
    font-size: .93rem;
    white-space: nowrap;
    cursor: pointer;
}

    .menu-opcao:hover {
        background: var(--cr-blue-100);
    }

    .menu-opcao .form-check-input {
        margin: 0;
        flex-shrink: 0;
    }

    .menu-opcao .num {
        font-family: var(--cr-font-mono);
        font-size: .85rem;
        color: var(--cr-text-2);
    }

/* Small label above the login / setup titles. */
.eyebrow-conta {
    font-family: var(--cr-font-mono);
    font-size: .7rem;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--cr-accent);
    margin-bottom: .5rem;
}

/* ---- Panels: grouped controls on glass (Home, Parâmetros, Utilizadores) ---- */
.painel {
    position: relative;
    background: var(--cr-surface);
    border: 1px solid rgba(255, 255, 255, 0.75);
    border-radius: var(--cr-radius);
    padding: 1.15rem 1.35rem 1.25rem;
    box-shadow: var(--cr-shadow);
    backdrop-filter: blur(10px) saturate(1.2);
    -webkit-backdrop-filter: blur(10px) saturate(1.2);
}

.painel-titulo {
    display: flex;
    align-items: center;
    gap: .55rem;
    font-family: var(--cr-font-mono);
    font-weight: 500;
    font-size: .74rem;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--cr-text-2);
    margin-bottom: .95rem;
}

    /* A small "index marker" before every panel title, like the hour marks on a dial. */
    .painel-titulo::before {
        content: "";
        width: 3px;
        height: 14px;
        border-radius: 2px;
        background: linear-gradient(180deg, var(--cr-cyan-400), var(--cr-blue-600));
    }

/* Radio buttons and checkboxes inside panels: one per line, with room between them. */
.painel .form-check {
    font-size: 1rem;
    margin-bottom: .55rem;
    padding-left: 1.85em;
}

    .painel .form-check:last-child {
        margin-bottom: 0;
    }

.form-check-input {
    width: 1.15em;
    height: 1.15em;
    margin-top: .18em;
    border-color: var(--cr-line-strong);
    cursor: pointer;
}

.painel .form-check-input {
    margin-left: -1.85em;
}

.form-check-input:checked {
    background-color: var(--cr-blue-600);
    border-color: var(--cr-blue-600);
}

.form-check-input:focus {
    box-shadow: var(--cr-glow);
    border-color: var(--cr-cyan-400);
}

.form-check-label {
    cursor: pointer;
}

/* ---- Forms ---- */
.form-control, .form-select {
    border-radius: var(--cr-radius-sm);
    border-color: var(--cr-line-strong);
    background-color: rgba(255, 255, 255, 0.92);
    color: var(--cr-text);
}

    .form-control:focus, .form-select:focus {
        border-color: var(--cr-cyan-400);
        box-shadow: var(--cr-glow);
    }

.form-label {
    font-weight: 500;
    color: var(--cr-text-2);
}

/* ---- Buttons ---- */
.btn {
    border-radius: var(--cr-radius-sm);
    font-weight: 500;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .45rem;
}

.btn-primary {
    color: #fff;
    background: linear-gradient(135deg, var(--cr-blue-500) 0%, var(--cr-blue-600) 60%, #1a4ea6 100%);
    border: 1px solid #184a9e;
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.25) inset, 0 6px 16px rgba(42, 91, 234, 0.28);
}

    .btn-primary:hover, .btn-primary:focus-visible {
        background: linear-gradient(135deg, #3a82e8 0%, var(--cr-blue-500) 60%, var(--cr-blue-600) 100%);
        border-color: #184a9e;
        color: #fff;
    }

    .btn-primary:disabled {
        background: var(--cr-text-3);
        border-color: var(--cr-text-3);
        box-shadow: none;
    }

.btn-outline-primary {
    color: var(--cr-accent);
    border-color: rgba(42, 91, 234, 0.35);
    background: rgba(255, 255, 255, 0.7);
}

    .btn-outline-primary:hover {
        background: var(--cr-blue-100);
        color: var(--cr-accent);
        border-color: var(--cr-blue-600);
    }

.btn-outline-secondary {
    color: var(--cr-text-2);
    border-color: var(--cr-line-strong);
    background: rgba(255, 255, 255, 0.7);
}

    .btn-outline-secondary:hover {
        background: var(--cr-surface-solid);
        color: var(--cr-text);
        border-color: var(--cr-text-3);
    }

.btn-fantasma {
    background: transparent;
    border: 1px solid transparent;
    color: var(--cr-text-2);
}

    .btn-fantasma:hover {
        background: rgba(255, 255, 255, 0.7);
        border-color: var(--cr-line);
        color: var(--cr-text);
    }

.btn:focus-visible, .btn-link:focus-visible {
    box-shadow: var(--cr-glow);
    outline: none;
}

.icone {
    width: 1.15em;
    height: 1.15em;
    flex-shrink: 0;
}

/* Export buttons with the Excel/PDF images, as on the WinForms forms (small, in the filter bar). */
.exportar {
    display: inline-flex;
    gap: .4rem;
}

.btn-exportar {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    height: 2rem;
    padding: 0 .65rem;
    background: var(--barra-campo);
    border: 1px solid var(--cr-line-strong);
    color: var(--cr-text);
    font-size: .85rem;
    white-space: nowrap;
}

    .btn-exportar img {
        width: 18px;
        height: 18px;
        object-fit: contain;
    }

    .btn-exportar .icone {
        color: var(--barra-destaque);
    }

    .btn-exportar:hover:not(:disabled) {
        border-color: var(--barra-foco-borda);
        background: var(--cr-blue-100);
        color: var(--cr-text);
    }

    .btn-exportar:disabled {
        opacity: .45;
    }

/* ---- Data-grid frame: table area and pager in one card ----
   Solid, no backdrop blur: a blur over the animated background had to be recomputed on every frame
   while the table scrolled sideways (the "lag" reported on 2026-09-26). */
.grelha-cartao {
    display: flex;
    flex-direction: column;
    background: var(--cr-surface-solid);
    border: 1px solid var(--cr-line);
    border-radius: var(--cr-radius);
    box-shadow: var(--cr-shadow);
    overflow: hidden;
}

/* ---- Data tables (Colaboradores, Obras, Recibos, the day detail): one web design for all ----
   Light header in capitals, clear grid lines (asked for bolder twice: keep them visible), the
   category colours of the WinForms screens as tints on the header and every cell of the column
   (they carry meaning: Horas green, Ajustes orange/pink/yellow, Saturday, Sunday, subsidy; in the
   day detail start/end/duration/code), a light TOTAL row pinned at the bottom.
   Row hover is a background-image overlay: cheap to paint (a CSS filter on every cell was not). */
:root {
    --tb-fundo: #ffffff;
    --tb-zebra: #d3e4fb;                            /* even rows: light blue (Obras, Recibos) */
    --tb-zebra-sombra: rgba(30, 105, 225, 0.18);   /* even rows, a light-blue layer over any column colour */
    --tb-linha: rgba(15, 36, 64, 0.24);
    --tb-coluna: rgba(15, 36, 64, 0.17);
    --tb-cab-fundo: #c6daf6;                       /* headers without a colour of their own: bluish */
    --tb-cab-texto: #1d3f73;
    --tb-cab-linha: rgba(15, 36, 64, 0.32);
    --tb-cab-coluna: rgba(15, 36, 64, 0.3);       /* stronger dividers between header cells */
    --tb-hover: rgba(42, 91, 234, 0.08);
    --tb-total-fundo: #dbe7f8;
    --tb-total-texto: var(--cr-strong);
    /* category tints: header / cell / header text */
    --tb-dias-cab: #d3e3fa;      --tb-dias-texto: #1a55b3;
    --tb-horas-cab: #bfe8cb;     --tb-horas-cel: #e0f4e5;     --tb-horas-texto: #135c33;
    --tb-ajustes-cab: #f7cfab;   --tb-ajustes-texto: #86420c;
    --tb-desconto-cab: #f5c6d2;  --tb-desconto-cel: #f9dfe6;  --tb-desconto-texto: #8e2445;
    --tb-acum-cel: #fbefc0;
    --tb-sabado-cab: #ffd28f;    --tb-sabado-cel: #ffeccb;    --tb-sabado-texto: #734a00;
    --tb-domingo-cab: #ffbcbc;   --tb-domingo-cel: #fddede;   --tb-domingo-texto: #93212c;
    --tb-subsidio-cab: #b3e2ea;  --tb-subsidio-cel: #d3eff3;  --tb-subsidio-texto: #0f5a66;
    /* day detail (EditarDia): start, end, duration */
    --tb-ini-cab: #c3d9f5;       --tb-ini-cel: #e3eefc;       --tb-ini-texto: #1a55b3;
    --tb-fim-cab: #d9d2f5;       --tb-fim-cel: #eeeafc;       --tb-fim-texto: #4b3a9e;
    --tb-duracao-cab: #fad7a8;   --tb-duracao-cel: #fdefd9;   --tb-duracao-texto: #7a4a06;
    --tb-selecionada: #cfe0fa;   --tb-selecionada-texto: var(--cr-strong);
    --tb-alterado-cel: #b4eabf;  --tb-alterado-texto: #0b6b2c;   /* day edited by hand: a vivid green, stronger than the Horas columns */
}

/* Search box: last in the bar, pushed to its right end, 18rem on every screen (asked for uniform
   search boxes, 2026-09-26) — it can go down to 12rem so a bar with many groups (Gestão de
   Colaboradores) still fits on one line: it takes the free space first (grow 100), up to 18rem, and
   the separators share the rest. The "/" key hint hides while there's text in it. */
.procura {
    position: relative;
    flex: 100 1 9rem;
    max-width: 18rem;
    margin-left: auto;
}

/* Lower resolutions (laptops, ~1366px): the groups can't share one line, so the bar wraps. The separators
   only make sense on one line (they would dangle at the end of a row), so they go away and the groups get
   a gap instead; the search stays at the right of the last row. */
@media (min-width: 641px) and (max-width: 1500px) {
    .barra-filtros { gap: .5rem 1.1rem; }
    .barra-filtros .barra-sep { display: none; }
}

/* One line (asked 2026-09-27). The bar only wraps when the groups don't fit even with the search at
   9rem and the separators at .8rem (their flex-basis: wrapping is decided on it, then they grow — the
   search first, up to 18rem). On windows narrower than 1880px (bar under ~1560px next to the side
   menu), the buttons with an icon (Fechar período, Reprocessar, PDF, Excel) show only the icon — the
   text stays in the title — so Gestão de Colaboradores, the fullest bar, still fits on one line.
   (A window media query, not a container query: a container would trap the menus' position:fixed
   backdrop inside the bar, and clicking outside would no longer close them.) */
@media (min-width: 641px) and (max-width: 1879.98px) {
    .barra-filtros .btn-texto { display: none; }
    .barra-filtros .btn-exportar { padding-inline: .5rem; }
}

    .procura .icone {
        position: absolute;
        left: .7rem;
        top: 50%;
        transform: translateY(-50%);
        color: var(--cr-text-3);
        pointer-events: none;
    }

    .procura input {
        height: 2rem;
        padding-left: 2.2rem;
        padding-right: 2rem;
        font-size: .88rem;
    }

.procura-atalho {
    position: absolute;
    right: .5rem;
    top: 50%;
    transform: translateY(-50%);
    padding: .05rem .4rem;
    border-radius: 5px;
    border: 1px solid var(--cr-line-strong);
    background: transparent;
    color: var(--cr-text-3);
    font-family: var(--cr-font-mono);
    font-size: .72rem;
    pointer-events: none;
}

    .procura input:not(:placeholder-shown) + .procura-atalho {
        display: none;
    }

/* ---- Reloading data already on screen (a filter or the period changed) ----
   The old figures stay where they are (no placeholders, nothing jumps) and are dimmed only if the
   load takes more than a quarter of a second, so quick reloads show no flicker at all. When the
   class goes away the content comes back at once (no transition on the way out). */
.a-carregar {
    opacity: .6;
    pointer-events: none;
    transition: opacity .2s ease .25s;
}

/* ---- Loading placeholders: grey blocks with a slow shimmer, only the first time a page loads ---- */
.esqueleto {
    border-radius: var(--cr-radius-sm);
    background: linear-gradient(90deg, rgba(15, 36, 64, 0.06) 25%, rgba(15, 36, 64, 0.12) 50%, rgba(15, 36, 64, 0.06) 75%);
    background-size: 200% 100%;
    animation: esqueleto 1.4s ease-in-out infinite;
}

@keyframes esqueleto {
    from { background-position: 100% 0; }
    to { background-position: -100% 0; }
}

.estado-vazio {
    padding: 3rem 1rem;
    text-align: center;
    color: var(--cr-text-2);
}

    .estado-vazio .estado-vazio-icone {
        width: 2.4rem;
        height: 2.4rem;
        color: var(--cr-text-3);
        margin-bottom: .6rem;
    }

.estado-vazio-texto {
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--cr-text);
}

.estado-vazio-dica {
    margin-top: .35rem;
    font-size: .92rem;
}

.esqueleto-tabela {
    padding: 1rem;
    display: flex;
    flex-direction: column;
    gap: .45rem;
}

.esqueleto-cabecalho { height: 2.6rem; margin-bottom: .3rem; }
.esqueleto-linha { height: 1.9rem; }

/* Simple table style for lists (Utilizadores). */
.tabela-lista {
    width: 100%;
    border-collapse: collapse;
}

    .tabela-lista th {
        font-family: var(--cr-font-mono);
        font-size: .72rem;
        letter-spacing: .12em;
        text-transform: uppercase;
        color: var(--cr-text-3);
        font-weight: 500;
        padding: .6rem .75rem;
        border-bottom: 1px solid var(--cr-line-strong);
        text-align: left;
    }

    .tabela-lista td {
        padding: .75rem;
        border-bottom: 1px solid var(--cr-line);
        vertical-align: middle;
    }

    .tabela-lista tr:last-child td {
        border-bottom: none;
    }

.distintivo {
    display: inline-block;
    padding: .15rem .55rem;
    border-radius: 999px;
    font-size: .78rem;
    font-weight: 600;
}

.distintivo-ok { background: rgba(19, 138, 90, 0.12); color: var(--cr-success); }
.distintivo-aviso { background: rgba(184, 110, 0, 0.12); color: var(--cr-warning); }
.distintivo-info { background: var(--cr-blue-100); color: var(--cr-blue-600); }

/* ---- Alerts ---- */
.alert {
    border-radius: var(--cr-radius-sm);
    border: 1px solid transparent;
}

.alert-success { background: #e7f6ef; border-color: #bfe6d3; color: #0d5c3d; }
.alert-danger { background: #fdecee; border-color: #f5c2c8; color: #8e1e2a; }
.alert-warning { background: #fff5e3; border-color: #f7ddaa; color: #7a4a00; }

/* ---- Modals (EditarDia, ConfirmDialog, Parâmetros date) ---- */
.modal {
    backdrop-filter: blur(3px);
}

.modal-content {
    border: none;
    border-radius: 18px;
    box-shadow: var(--cr-shadow-lg);
    overflow: hidden;
}

.modal-header {
    border-bottom: 1px solid var(--cr-line);
    padding: 1.1rem 1.4rem;
}

.modal-title {
    font-family: var(--cr-font-display);
    font-weight: 600;
}

.modal-body {
    padding: 1.25rem 1.4rem;
}

.modal-footer {
    border-top: 1px solid var(--cr-line);
    background: var(--cr-surface-2);
    padding: .85rem 1.4rem;
}

/* ---- Progress ---- */
.progress {
    background: rgba(15, 36, 64, 0.08);
    border-radius: 999px;
}

.progress-bar {
    background: linear-gradient(90deg, var(--cr-blue-600), var(--cr-cyan-400));
    font-family: var(--cr-font-mono);
    font-size: .78rem;
}

/* ---- Blazor/template leftovers ---- */
.content {
    padding-top: 1rem;
    padding-bottom: 1rem;
}

/* On desktop every page fits the window: the content area takes the height left under the top bar
   (scrolling inside only if the window is really too small), and a data grid takes whatever height is
   left under the header and filter bar. Its table area (data-linhas-auto) fills the card, and the pager
   works out how many rows fit in it ("Ajustar ao ecrã"). */
@media (min-width: 641px) {
    .content {
        flex: 1 1 0;
        min-height: 0;
        overflow: auto;
        display: flex;
        flex-direction: column;
    }

        .content > * {
            flex-shrink: 0;
        }

        .content > .grelha-cartao {
            flex: 1 1 0;
            min-height: 16rem;
        }

    .grelha-cartao > [data-linhas-auto] {
        flex: 1 1 0;
        min-height: 0;
    }
}

@media (max-width: 640.98px) {
    .grelha-cartao > [data-linhas-auto] {
        max-height: 70vh;
    }
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid var(--cr-danger);
}

.validation-message {
    color: var(--cr-danger);
    font-size: .88rem;
    margin-top: .25rem;
}

.blazor-error-boundary {
    background: #b32121;
    padding: 1rem 1rem 1rem 1.5rem;
    color: white;
    border-radius: var(--cr-radius-sm);
}

    .blazor-error-boundary::after {
        content: "Ocorreu um erro."
    }

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation: none !important;
        transition: none !important;
    }
}

/* Toast when "Atualizar Base de Dados" finishes (AvisoAtualizacao), bottom-left so it never covers the other alerts. */
.toast-atualizacao {
    position: fixed;
    left: 1.5rem;
    bottom: 1.5rem;
    z-index: 1060;
    display: flex;
    align-items: center;
    gap: .65rem;
    max-width: 440px;
    padding: .75rem 1rem;
    border-radius: var(--cr-radius-sm);
    background: var(--cr-surface-solid);
    border: 1px solid var(--cr-line-strong);
    border-left: 4px solid var(--cr-success);
    box-shadow: var(--cr-shadow-lg);
    color: var(--cr-text);
}

    .toast-atualizacao.erro { border-left-color: var(--cr-danger); }
    .toast-atualizacao .icone { color: var(--cr-success); }
    .toast-atualizacao.erro .icone { color: var(--cr-danger); }

/* Keyboard shortcuts list ("?" or the keyboard button in the top bar). */
.ajuda-atalhos {
    position: fixed;
    right: 1.5rem;
    top: 4.2rem;
    z-index: 1070;
    min-width: 300px;
    padding: 1rem 1.2rem;
    border-radius: var(--cr-radius);
    background: var(--cr-surface-solid);
    border: 1px solid var(--cr-line-strong);
    box-shadow: var(--cr-shadow-lg);
    color: var(--cr-text);
    cursor: pointer;
}

.ajuda-atalhos-titulo {
    font-family: var(--cr-font-display);
    font-weight: 700;
    margin-bottom: .6rem;
}

.ajuda-atalhos-linha {
    display: flex;
    align-items: center;
    gap: .8rem;
    padding: .25rem 0;
    font-size: .92rem;
    color: var(--cr-text-2);
}

    .ajuda-atalhos-linha kbd {
        min-width: 5.5rem;
        text-align: center;
        font-family: var(--cr-font-mono);
        font-size: .8rem;
        background: var(--cr-blue-100);
        color: var(--cr-accent);
        border-radius: 6px;
        padding: .15rem .4rem;
    }

/* Banner shown when the period on screen is closed (PeriodosFechados). */
.aviso-fecho {
    display: flex;
    align-items: center;
    gap: .55rem;
    margin: -.25rem 0 .75rem;
    padding: .5rem .9rem;
    border-radius: var(--cr-radius-sm);
    border: 1px solid rgba(184, 110, 0, 0.35);
    background: rgba(255, 245, 227, 0.92);
    color: #7a4a00;
    font-size: .92rem;
}

/* ---- Phones: the data grids become one card per row, each value with its column name (data-label) ---- */
@media (max-width: 640.98px) {
    .grelha-cartao .grelha, .grelha-cartao .grelha tbody, .grelha-cartao .grelha tfoot { display: block; width: 100%; min-width: 0; }
    .grelha-cartao .grelha thead, .grelha-cartao .grelha colgroup { display: none; }
    .grelha-cartao .grelha tr { display: block; margin: .6rem; border-radius: var(--cr-radius-sm); overflow: hidden; border: 1px solid var(--cr-line-strong); }
    .grelha-cartao .grelha td {
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: 1rem;
        position: static !important;
        text-align: right !important;
        white-space: normal !important;
        border-right: none !important;
    }
    .grelha-cartao .grelha td[data-label]::before {
        content: attr(data-label);
        font-weight: 600;
        text-align: left;
        color: var(--cr-text-2);
    }
    .grelha-cartao .grelha td:not([data-label]):empty,
    .grelha-cartao .grelha td.dia-cell { display: none; }
    .grelha-cartao .grelha td.nome { max-width: none !important; }
}

/* Title with arrows on both sides (employee page: previous / next employee of Mapa de Horas). */
.titulo-com-navegacao {
    display: flex;
    align-items: center;
    gap: .6rem;
    min-width: 0;
}

.btn-navegar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.2rem;
    height: 2.2rem;
    flex: 0 0 auto;
    border-radius: 50%;
    border: 1px solid var(--barra-borda, rgba(15, 36, 64, 0.18));
    background: var(--cr-surface, #fff);
    color: var(--cr-accent);
    cursor: pointer;
    transition: background-color .15s, color .15s;
}

    .btn-navegar:hover:not(:disabled) {
        background: var(--cr-accent);
        color: #fff;
    }

    .btn-navegar:disabled {
        opacity: .35;
        cursor: default;
    }
