/* ═══════════════════════════════════════════════════════════════════
   Dimi — style.css
   Drop-in replacement for shared.css.

   Design goals (see the Contracts redesign canvas):
     · neutral hairlines instead of blue-tinted ones, so royal blue is the
       only blue on the page and always means "action"
     · money set in tabular figures on a right edge
     · colour reserved for state that needs a decision (due / overdue /
       unpriced), never for classification
     · one 4px spacing rhythm, one radius pair, no shadows on flat surfaces

   COMPATIBILITY — deliberate constraints, do not "clean up":
     · Every custom property shared.css defined keeps its exact name.
       dashboard.js / contracts.js / expenses.js / staff.js / payroll.js
       emit inline style="color:var(--muted)" into generated markup, so a
       rename silently blanks text at runtime with no error.
     · Every selector shared.css defined still exists here. Pages and JS
       toggle these class names (.active, .open, .visible, .expanded).
     · body stays 15px so every rem value in the app keeps its pixel size.
   ═══════════════════════════════════════════════════════════════════ */

/* IBM Plex Sans / Mono, self-hosted (SIL OFL 1.1, fonts/OFL.txt). This replaces a Google Fonts @import: an
   @import is render-blocking, so a slow or unreachable fonts.googleapis.com (a restaurant tablet on bad wifi) left
   every page unstyled until it timed out, and it sent every visitor's IP to Google. Only the subsets the app
   needs: latin (en/de) + greek for Sans, latin for Mono (figures only). Sans is one variable file per subset.
   font-display: swap shows the fallback stack immediately and swaps when the file arrives. */
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/plex-mono-400-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('fonts/plex-mono-500-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('fonts/plex-mono-600-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal;
    font-weight: 400 600;
    font-display: swap;
    src: url('fonts/plex-sans-var-greek.woff2') format('woff2');
    unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal;
    font-weight: 400 600;
    font-display: swap;
    src: url('fonts/plex-sans-var-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
    color-scheme: dark;

    /* Brand — royal is unchanged, it is the product's blue */
    --royal:    #4169E1;
    --royal-dim:#3355c4;
    --royal-hi: #6B8AEE;   /* royal is only 3.6:1 on dark — use this for TEXT/links */
    --baby:     #89CFF0;
    --success:  #3FB27F;
    --error:    #E0575C;
    --warn:     #D9A036;

    /* Tinted state fills — paired with the *-fg colours below */
    --warn-fg:    #E0AC4A;
    --error-fg:   #ED7A7E;
    --success-fg: #57C593;
    --warn-bg:    rgba(217,160,54,0.14);
    --error-bg:   rgba(224,87,92,0.14);
    --success-bg: rgba(63,178,127,0.14);
    --royal-bg:   rgba(65,105,225,0.16);

    /* Dark palette (default) */
    --bg:            #0E131A;
    --surface:       #151B24;
    --raised:        #1C2430;
    --sidebar-bg:    #121821;
    --head-bg:       #11161E;   /* table header / inset panels */
    --row-hover:     #19212C;
    --fg:            #E9EEF5;
    --fg-soft:       #C7D1DE;
    --white:         #ffffff;
    --muted:         #8B98A9;
    --faint:         #7E8B9C;   /* smallest labels — still 4.7:1 on --surface */
    --border:        #2E3947;   /* control borders (was blue-tinted) */
    --border-subtle: #222B37;   /* hairlines */
    --border-row:    #1B232F;   /* row dividers inside a card */

    --sidebar-w: 220px;
    --header-h:  56px;

    --sans: 'IBM Plex Sans', 'Segoe UI', system-ui, sans-serif;
    --mono: 'IBM Plex Mono', ui-monospace, 'Cascadia Mono', Consolas, monospace;

    --r-card: 12px;
    --r-ctrl: 8px;
    --r-pill: 999px;
}

/* ── Light theme ───────────────────────────────────────────────── */
html[data-theme="light"] {
    color-scheme: light;
    --bg:            #F4F6F9;
    --surface:       #ffffff;
    --raised:        #EDF1F6;
    --sidebar-bg:    #ffffff;
    --head-bg:       #F7F9FC;
    --row-hover:     #F7F9FC;
    --fg:            #10161F;
    --fg-soft:       #33414F;
    --muted:         #5B6878;
    --faint:         #626E7D;
    --baby:          #2E86C9;
    --royal:         #2E56D3;
    --royal-dim:     #1E3EA8;
    --royal-hi:      #2E56D3;
    --border:        #D3DBE5;
    --border-subtle: #E2E8F0;
    --border-row:    #EDF1F6;
    --royal-bg:      rgba(46,86,211,0.08);

    --success:    #17794F;
    --error:      #C0353A;
    --warn:       #B07A0C;
    --warn-fg:    #8A5F08;
    --error-fg:   #A82B30;
    --success-fg: #0F5F3D;
    --warn-bg:    rgba(176,122,12,0.12);
    --error-bg:   rgba(192,53,58,0.10);
    --success-bg: rgba(23,121,79,0.10);
}

/* ── Reset / base ──────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html { -webkit-text-size-adjust: 100%; }

body {
    background: var(--bg);
    color: var(--fg);
    font-family: var(--sans);
    font-size: 15px;            /* unchanged — every rem in the app depends on it */
    min-height: 100svh;
    -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }

::selection { background: rgba(65,105,225,0.3); }

:focus-visible { outline: 2px solid var(--royal); outline-offset: 2px; }

/* ── Layout shell ──────────────────────────────────────────────── */
.layout {
    display: flex;
    min-height: 100svh;
}

.page-body {
    margin-left: var(--sidebar-w);
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 100svh;
    overflow-x: hidden;
}

/* ── Sidebar ───────────────────────────────────────────────────── */
.sidebar {
    /* --imp-banner-h is set only while a super-admin is impersonating a tenant
       (sidebar.js checkImpersonation()). Fixed positioning ignores body padding,
       so the banner height has to be consumed here explicitly. */
    position: fixed;
    top: var(--imp-banner-h, 0px); left: 0;
    width: var(--sidebar-w);
    height: calc(100svh - var(--imp-banner-h, 0px));
    background: var(--sidebar-bg);
    border-right: 1px solid var(--border-subtle);
    display: flex;
    flex-direction: column;
    z-index: 200;
    transition: transform 0.25s ease;
    overflow-y: auto;
    overflow-x: hidden;
}

.sidebar-logo {
    height: var(--header-h);
    display: flex;
    align-items: center;
    padding: 0 1.25rem;
    font-size: 1.15rem;
    font-weight: 600;
    color: var(--royal-hi);
    border-bottom: 1px solid var(--border-subtle);
    letter-spacing: -0.01em;
    flex-shrink: 0;
}

/* M3 Multi-Org, Part B: the org switcher, directly under the logo (design doc §4). Only rendered
   at all when the tenant has the module - a single-org tenant's sidebar never grows this row. */
.sidebar-org-switcher {
    padding: 0.5rem 1.25rem;
    border-bottom: 1px solid var(--border-subtle);
    flex-shrink: 0;
}
.sidebar-org-select {
    width: 100%;
    font: inherit;
    font-size: 0.85rem;
    color: var(--fg);
    background: var(--raised);
    border: 1px solid var(--border);
    border-radius: var(--r-ctrl);
    padding: 0.4rem 0.6rem;
}
.sidebar-org-add {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    background: none;
    border: 1px dashed var(--border);
    border-radius: var(--r-ctrl);
    color: var(--muted);
    font: inherit;
    font-size: 0.85rem;
    padding: 0.45rem 0.6rem;
    cursor: pointer;
}
.sidebar-org-add:hover {
    color: var(--fg);
    border-color: var(--royal);
}

.sidebar-nav {
    flex: 1;
    padding: 0.5rem 0;
    overflow-y: auto;
}

.sidebar-footer {
    border-top: 1px solid var(--border-subtle);
    padding: 0.4rem 0 0.6rem;
    flex-shrink: 0;
}

.nav-item {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    margin: 1px 0.6rem;
    padding: 0.55rem 0.75rem;
    border-radius: var(--r-ctrl);
    color: var(--muted);
    cursor: pointer;
    border-left: 3px solid transparent;
    transition: color 0.15s, background 0.15s, border-color 0.15s;
    user-select: none;
    font-size: 0.9rem;
}

.nav-item:hover {
    color: var(--fg);
    background: var(--raised);
    border-left-color: transparent;
}

.nav-item.active {
    color: var(--white);
    background: var(--royal-bg);
    border-left-color: var(--royal);
    padding-left: calc(0.75rem - 3px);
    font-weight: 600;
}

/* A count on a nav item (Stock: items needing attention). Amber = "look at this", the same state colour as a warning. */
.nav-count {
    margin-left: auto; flex-shrink: 0;
    min-width: 1.35rem; height: 1.35rem; padding: 0 0.4rem;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: var(--r-pill);
    background: var(--warn-bg); color: var(--warn-fg);
    font-size: 0.72rem; font-weight: 600; font-family: var(--mono); font-variant-numeric: tabular-nums;
}
.nav-item.active .nav-count { background: var(--warn-bg); color: var(--warn-fg); }

/* Light mode nav overrides */
html[data-theme="light"] .nav-item:hover  { color: var(--fg); }
html[data-theme="light"] .nav-item.active { color: #14306E; }

.nav-icon { display: inline-flex; align-items: center; justify-content: center; width: 1.25rem; flex-shrink: 0; opacity: 0.9; }
.nav-lock { font-size: 0.75rem; margin-left: auto; opacity: 0.5; }

/* ── Collapsible nav sections (M2 #107/#108) ──────────────────────
   A section header reuses .nav-item; the extra indent stays scoped to
   .nav-section-body so flat top-level items are never affected. */
.nav-chevron { margin-left: auto; display: inline-flex; opacity: 0.5; transition: transform 0.15s; }
.nav-section.expanded .nav-chevron { transform: rotate(90deg); }
.nav-section-body .nav-item { padding-left: 2.4rem; font-size: 0.85rem; }
.nav-section-body .nav-item.active { padding-left: calc(2.4rem - 3px); }

/* ── Top bar ───────────────────────────────────────────────────── */
.top-bar {
    height: var(--header-h);
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0 1.5rem;
    background: var(--sidebar-bg);
    border-bottom: 1px solid var(--border-subtle);
    position: sticky;
    top: 0;
    z-index: 100;
    flex-shrink: 0;
}

.top-bar-title {
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--fg);
    flex: 1;
}

.top-bar-clock {
    color: var(--muted);
    font-size: 0.9rem;
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
}

.hamburger {
    display: none;
    background: none;
    border: none;
    color: var(--fg);
    font-size: 1.4rem;
    cursor: pointer;
    padding: 0.25rem;
    line-height: 1;
    flex-shrink: 0;
}

/* ── Page content wrapper ──────────────────────────────────────── */
.content {
    flex: 1;
    padding: 1.6rem 2rem 2.5rem;
    width: 100%;
    max-width: 1400px;
}

/* ── Buttons ───────────────────────────────────────────────────── */
button, .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
    padding: 0.5rem 1rem;
    border-radius: var(--r-ctrl);
    border: none;
    cursor: pointer;
    font-size: 0.86rem;
    font-weight: 500;
    font-family: inherit;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
    white-space: nowrap;
}

button:active { transform: none; }

.btn-primary, button.primary {
    background: var(--royal);
    color: #ffffff;
    font-weight: 600;
}
.btn-primary:hover, button.primary:hover { background: var(--royal-dim); }

/* Secondary is now a neutral outline — an outlined baby-blue button next to a
   solid royal one read as two competing primaries. */
.btn-secondary, button.secondary {
    background: transparent;
    color: var(--fg-soft);
    border: 1px solid var(--border);
}
.btn-secondary:hover, button.secondary:hover { background: var(--raised); border-color: var(--muted); color: var(--fg); }

.btn-danger, button.danger {
    background: transparent;
    color: var(--error);
    border: 1px solid var(--border);
}
.btn-danger:hover, button.danger:hover { background: var(--error-bg); border-color: var(--error); }

.btn-success, button.success {
    background: transparent;
    color: var(--success);
    border: 1px solid var(--border);
}
.btn-success:hover, button.success:hover { background: var(--success-bg); border-color: var(--success); }

.btn-sm { padding: 0.3rem 0.7rem; font-size: 0.8rem; }

/* ── Icon-only buttons (uniform minimal icon system, see icons.js) ───── */
.btn-icon { padding: 0.5rem; gap: 0; }
.btn-icon.btn-sm { padding: 0.35rem; }
.icon { display: block; flex-shrink: 0; }
.icon-inline { display: inline-block; vertical-align: -3px; flex-shrink: 0; }

/* Shared icon-action button. Several pages declared their own .icon-btn in a
   page <style> block; it lives here now so every page gets the same one. */
/* Written as button.icon-btn (0,2,1) so it outranks button.danger (0,1,1) above —
   an icon-only delete is a quiet action until hovered, not a permanent red box. */
.icon-btn, button.icon-btn {
    width: 32px; height: 32px;
    display: inline-flex; align-items: center; justify-content: center;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 7px;
    color: var(--muted);
    cursor: pointer;
    padding: 0;
    transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.icon-btn:hover, button.icon-btn:hover { background: var(--raised); color: var(--fg); border-color: var(--border); }
.icon-btn.danger:hover, button.icon-btn.danger:hover { background: var(--error-bg); color: var(--error); border-color: var(--error); }
.icon-row { display: flex; gap: 0.25rem; }

/* Row actions stay quiet until the row is hovered — but never disappear for
   keyboard users, hence :focus-within. */
.row-actions { opacity: 0; transition: opacity 0.12s; }
tr:hover .row-actions,
tr:focus-within .row-actions,
.contract-item:hover .row-actions,
.contract-item:focus-within .row-actions,
.row-actions:focus-within { opacity: 1; }
@media (hover: none) { .row-actions { opacity: 1; } }

/* ── Inputs ────────────────────────────────────────────────────── */
input[type="text"],
input[type="password"],
input[type="date"],
input[type="search"],
input[type="number"],
input[type="time"],
input[type="datetime-local"],
input[type="email"],
input[type="tel"],
input[type="file"],
select,
textarea {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-ctrl);
    color: var(--fg);
    padding: 0.5rem 0.7rem;
    font-size: 0.88rem;
    font-family: inherit;
    outline: none;
    transition: border-color 0.15s, box-shadow 0.15s;
    width: 100%;
}

select { cursor: pointer; }
textarea { resize: vertical; min-height: 80px; }

input[type="file"] { padding: 0.4rem 0.5rem; font-size: 0.8rem; color: var(--muted); }

input:focus, select:focus, textarea:focus {
    border-color: var(--royal);
    box-shadow: 0 0 0 3px rgba(65,105,225,0.18);
}

input::placeholder, textarea::placeholder { color: var(--faint); }

/* Numeric inputs read as figures */
input[type="number"], input[inputmode="decimal"], input[type="date"],
input[type="time"], input[type="datetime-local"] {
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
}

/* Date/time input calendar/clock icon colour */
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator,
input[type="datetime-local"]::-webkit-calendar-picker-indicator { filter: invert(0.7); }
html[data-theme="light"] input[type="date"]::-webkit-calendar-picker-indicator,
html[data-theme="light"] input[type="time"]::-webkit-calendar-picker-indicator,
html[data-theme="light"] input[type="datetime-local"]::-webkit-calendar-picker-indicator { filter: none; }

/* ── Stat cards ────────────────────────────────────────────────── */
.stat-row {
    display: flex;
    gap: 1rem;
    margin-bottom: 1.5rem;
    flex-wrap: wrap;
}

.stat-card {
    flex: 1;
    min-width: 130px;
    background: var(--surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--r-card);
    padding: 1rem 1.15rem;
}

/* Numbers are the point of these cards: mono, tabular, and no longer baby-blue
   (colour is reserved for state). */
.stat-card .stat-value {
    font-size: 1.7rem;
    font-weight: 500;
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
    color: var(--fg);
    line-height: 1.1;
}

.stat-card .stat-label {
    font-size: 0.7rem;
    color: var(--faint);
    margin-top: 0.4rem;
    text-transform: uppercase;
    letter-spacing: 0.09em;
    font-weight: 600;
}

/* The Contracts/Upcoming/Receipts summary strip. Was duplicated in four page
   <style> blocks; unified here. */
.stat-card-label {
    font-size: 0.7rem; font-weight: 600; letter-spacing: 0.09em;
    text-transform: uppercase; color: var(--faint); margin-bottom: 0.55rem;
}
.stat-card-value {
    font-size: 1.6rem; font-weight: 500; line-height: 1.1;
    font-family: var(--mono); font-variant-numeric: tabular-nums; letter-spacing: -0.02em;
    color: var(--fg);
}
.stat-card-sub { font-size: 0.78rem; color: var(--muted); margin-top: 0.45rem; }

.stats-row { display: flex; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.5rem; }
.stats-row .stat-card { flex: 1 1 180px; }

/* ── Tables ────────────────────────────────────────────────────── */
.table-wrap {
    overflow-x: auto;
    background: var(--surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--r-card);
}

table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.87rem;
}

thead tr {
    background: var(--head-bg);
    color: var(--faint);
    text-transform: uppercase;
    font-size: 0.68rem;
    letter-spacing: 0.09em;
}

th {
    padding: 0.7rem 0.9rem;
    text-align: left;
    font-weight: 600;
    border-bottom: 1px solid var(--border-subtle);
    white-space: nowrap;
}

td {
    padding: 0.7rem 0.9rem;
    text-align: left;
    border-bottom: 1px solid var(--border-row);
}

tbody tr:last-child td { border-bottom: none; }
tbody tr:hover { background: var(--row-hover); }

/* Any cell holding a figure gets tabular numerals so columns stack. */
td, .num { font-variant-numeric: tabular-nums; }
.money, td.money, .amount {
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.01em;
    text-align: right;
    white-space: nowrap;
}
th.money, th.amount { text-align: right; }

/* ── Section headers ───────────────────────────────────────────── */
.section { margin-bottom: 1.75rem; }

.section-title {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.09em;
    font-weight: 600;
    color: var(--faint);
    margin-bottom: 0.75rem;
}

/* Dashboard: each stacked section is a card (five of them on one page). */
body.dashboard-page .section {
    background: var(--surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--r-card);
    padding: 1.2rem 1.35rem;
    margin-bottom: 1.25rem;
}
body.dashboard-page .section-title {
    font-size: 0.72rem;
    padding-bottom: 0.7rem;
    margin-bottom: 1rem;
    border-bottom: 1px solid var(--border-subtle);
}

/* ── Page header (new) ─────────────────────────────────────────── */
.page-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1.5rem;
    flex-wrap: wrap;
    margin-bottom: 1.4rem;
}
.page-head h1, .page-title {
    font-size: 1.45rem;
    font-weight: 600;
    letter-spacing: -0.015em;
    color: var(--fg);
}
.page-sub { margin-top: 0.3rem; font-size: 0.85rem; color: var(--muted); }
.page-head-actions { display: flex; align-items: center; gap: 0.6rem; flex-shrink: 0; }

/* ── Toolbar (new) ─────────────────────────────────────────────── */
.toolbar {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin-bottom: 0.9rem;
}
.toolbar-search {
    display: flex; align-items: center; gap: 0.5rem;
    width: 280px; max-width: 100%; height: 34px;
    padding: 0 0.7rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-ctrl);
}
.toolbar-search:focus-within { border-color: var(--royal); box-shadow: 0 0 0 3px rgba(65,105,225,0.18); }
.toolbar-search input {
    flex: 1; min-width: 0; height: 100%;
    background: none; border: 0; padding: 0; width: auto;
    color: var(--fg); font-size: 0.85rem; font-family: inherit;
}
.toolbar-search input:focus { box-shadow: none; border: 0; }
.toolbar-search .icon, .toolbar-search svg { color: var(--faint); flex-shrink: 0; }
.toolbar-count { margin-left: auto; font-size: 0.8rem; color: var(--faint); font-variant-numeric: tabular-nums; }
.toolbar select, .toolbar .filter-select { width: auto; min-width: 130px; height: 34px; padding: 0 0.6rem; font-size: 0.82rem; }

/* Filter chip group */
.chip-group { display: flex; gap: 2px; padding: 2px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-ctrl); }
.chip {
    height: 28px; padding: 0 0.75rem;
    border: 0; border-radius: 6px;
    background: transparent; color: var(--muted);
    font-size: 0.8rem; font-weight: 500; font-family: inherit;
    cursor: pointer;
}
.chip:hover { color: var(--fg); }
.chip.active, .chip[aria-pressed="true"] { background: var(--raised); color: var(--fg); font-weight: 600; }

/* ── List card + grid rows (new) ───────────────────────────────── */
.list-card {
    background: var(--surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--r-card);
    overflow: hidden;
}
.list-head {
    display: grid;
    align-items: center;
    height: 38px;
    padding: 0 1.1rem;
    background: var(--head-bg);
    border-bottom: 1px solid var(--border-subtle);
    font-size: 0.68rem; font-weight: 600; letter-spacing: 0.09em;
    text-transform: uppercase; color: var(--faint);
}
.list-head > .ta-right { text-align: right; }

/* ── State pills ───────────────────────────────────────────────── */
.pill {
    display: inline-flex; align-items: center; gap: 0.35rem;
    height: 22px; padding: 0 0.55rem;
    border-radius: var(--r-pill);
    font-size: 0.75rem; font-weight: 600;
    white-space: nowrap;
}
.pill-dot { width: 5px; height: 5px; border-radius: 50%; flex-shrink: 0; background: currentColor; }
.pill-warn    { background: var(--warn-bg);    color: var(--warn-fg); }
.pill-error   { background: var(--error-bg);   color: var(--error-fg); }
.pill-success { background: var(--success-bg); color: var(--success-fg); }
.pill-neutral { background: var(--raised);     color: var(--muted); }

/* A classification is a dot and a word, never a coloured chip. */
.dot { width: 5px; height: 5px; border-radius: 50%; display: inline-block; flex-shrink: 0; }
.dot-fixed    { background: var(--baby); }
.dot-variable { background: var(--royal); }

/* "Estimate" / "Projected" markers: a label, not an alert. */
.tag-quiet {
    font-size: 0.66rem; font-weight: 600; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--faint);
}

/* ── Inline notice ─────────────────────────────────────────────── */
.notice {
    display: flex; align-items: center; gap: 0.6rem;
    padding: 0.65rem 0.9rem;
    border-radius: var(--r-ctrl);
    font-size: 0.85rem;
    margin-bottom: 0.9rem;
}
.notice-warn  { background: var(--warn-bg);  border: 1px solid rgba(217,160,54,0.3); color: var(--warn-fg); }
.notice-error { background: var(--error-bg); border: 1px solid rgba(224,87,92,0.3);  color: var(--error-fg); }
.notice-info  { background: var(--raised);   border: 1px solid var(--border-subtle);  color: var(--muted); }
.notice-success { background: var(--success-bg); border: 1px solid rgba(63,178,127,0.3); color: var(--success-fg); }
.notice > .grow { flex: 1; min-width: 0; }

/* ── Sliding segmented toggle (N options — via --seg-count/--seg-index) ── */
.seg-toggle {
    position: relative;
    display: flex;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-ctrl);
    padding: 3px;
}

.seg-toggle-thumb {
    position: absolute;
    top: 3px; bottom: 3px; left: 3px;
    width: calc(100% / var(--seg-count, 2) - 3px);
    background: var(--royal);
    border-radius: 6px;
    /* Percentage transforms are relative to the thumb's own box, so this lands
       correctly for any option count as long as width matches --seg-count. */
    transform: translateX(calc(var(--seg-index, 0) * 100%));
    transition: transform 0.2s ease;
}

.seg-toggle-opt {
    position: relative;
    z-index: 1;
    flex: 1;
    background: none;
    border: none;
    padding: 0.4rem 0.5rem;
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--muted);
    cursor: pointer;
    transition: color 0.2s ease;
    white-space: nowrap;
    font-family: inherit;
}

.seg-toggle-opt.active { color: #ffffff; font-weight: 600; }

/* ── On/off switch ────────────────────────────────────────────── */
.switch-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
}
.switch-row label { margin: 0; }
.switch {
    position: relative;
    display: inline-block;
    flex-shrink: 0;
    width: 40px;
    height: 22px;
}
.switch input {
    position: absolute;
    opacity: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    cursor: pointer;
}
.switch-track {
    position: absolute;
    inset: 0;
    background: var(--raised);
    border: 1px solid var(--border);
    border-radius: 11px;
    transition: background 0.2s ease, border-color 0.2s ease;
    /* The invisible <input> sits underneath this track in DOM order, so without
       this the track becomes the real click target (pitfall #20). */
    pointer-events: none;
}
.switch-track::before {
    content: '';
    position: absolute;
    top: 2px; left: 2px;
    width: 16px; height: 16px;
    background: var(--muted);
    border-radius: 50%;
    transition: transform 0.2s ease, background 0.2s ease;
}
.switch input:checked + .switch-track {
    background: var(--royal);
    border-color: var(--royal);
}
.switch input:checked + .switch-track::before {
    transform: translateX(18px);
    background: #ffffff;
}
.switch input:focus-visible + .switch-track {
    outline: 2px solid var(--royal);
    outline-offset: 2px;
}

/* ── Inline form row ───────────────────────────────────────────── */
.form-row {
    display: flex;
    gap: 0.6rem;
    align-items: flex-end;
    flex-wrap: wrap;
    margin-bottom: 0.75rem;
}

.form-row .field { display: flex; flex-direction: column; gap: 0.25rem; }
.form-row .field label { font-size: 0.72rem; color: var(--muted); }
.form-row .field.grow { flex: 1; min-width: 140px; }

.error-text { color: var(--error); font-size: 0.82rem; min-height: 1.1rem; }

/* ── Modals (shared; pages used to redeclare these) ────────────── */
.modal-overlay {
    display: none; position: fixed; inset: 0;
    background: rgba(5,8,12,0.65);
    z-index: 500;
    align-items: center; justify-content: center;
    padding: 1rem;
}
.modal-overlay.active { display: flex; }
.modal-box {
    background: var(--surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--r-card);
    padding: 1.6rem;
    width: min(440px, 100%);
    max-height: 88vh;
    overflow-y: auto;
    box-shadow: 0 16px 48px rgba(0,0,0,0.45);
}
.modal-box.wide { width: min(620px, 100%); }
.modal-footer { display: flex; justify-content: flex-end; gap: 0.6rem; margin-top: 1.25rem; }

/* ── Employee grid (terminal) ──────────────────────────────────── */
.emp-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 1rem;
    padding: 1rem;
}

.emp-card {
    position: relative;
    aspect-ratio: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    border-radius: var(--r-card);
    background: var(--surface);
    border: 1px solid var(--border-subtle);
    font-size: 1rem;
    text-align: center;
    padding: 1rem;
    transition: transform 0.1s, border-color 0.15s, background 0.15s;
    user-select: none;
}

.emp-card:hover { border-color: var(--royal); background: var(--raised); }
.emp-card:active { transform: scale(0.97); }

.emp-initial {
    font-size: 2.4rem;
    font-weight: 600;
    color: var(--baby);
    margin-bottom: 0.4rem;
    line-height: 1;
}

.badge-in {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    background: var(--success);
    color: #fff;
    font-size: 0.62rem;
    font-weight: 700;
    padding: 0.15rem 0.45rem;
    border-radius: var(--r-pill);
    letter-spacing: 0.06em;
    display: none;
}

.badge-in.visible { display: block; }

/* ── PIN / feedback overlays ───────────────────────────────────── */
.overlay {
    position: fixed;
    inset: 0;
    background: rgba(5,8,12,0.86);
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 400;
}

.overlay.active { display: flex; }

.modal {
    background: var(--surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--r-card);
    padding: 1.75rem;
    width: 320px;
    max-width: 92vw;
    box-shadow: 0 16px 48px rgba(0,0,0,0.45);
}

.modal-title {
    font-size: 1rem;
    font-weight: 600;
    margin-bottom: 1.1rem;
}
/* The kiosk's PIN modal centres its title; page modals are left-aligned. */
.overlay .modal-title { text-align: center; }

/* PIN display */
.pin-display {
    font-size: 2rem;
    text-align: center;
    letter-spacing: 0.6rem;
    margin: 0.75rem 0;
    min-height: 2.5rem;
    color: var(--baby);
    font-family: var(--mono);
}

/* PIN grid */
.pin-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.5rem;
    margin-top: 0.5rem;
}

.pin-grid button {
    aspect-ratio: 1;
    font-size: 1.4rem;
    font-family: var(--mono);
    background: var(--raised);
    color: var(--fg);
    border: 1px solid var(--border);
    border-radius: var(--r-ctrl);
}

.pin-grid button:hover { background: var(--royal-bg); border-color: var(--royal); }

/* Feedback card */
.feedback-card {
    background: var(--surface);
    border-radius: var(--r-card);
    border: 2px solid transparent;
    padding: 3rem 2rem;
    text-align: center;
    max-width: 92vw;
    width: 320px;
}

.feedback-card.success-in  { border-color: var(--success); }
.feedback-card.success-out { border-color: var(--baby); }
.feedback-card.error       { border-color: var(--error); color: var(--error); }

.feedback-card h3 { margin: 0.5rem 0; font-size: 1.3rem; }

/* ── Responsive ────────────────────────────────────────────────── */
@media (max-width: 768px) {
    .page-body { margin-left: 0; }
    .hamburger { display: flex; }

    .sidebar { transform: translateX(-100%); }

    .sidebar.open {
        transform: translateX(0);
        box-shadow: 4px 0 24px rgba(0,0,0,0.45);
    }

    .sidebar-backdrop {
        display: none;
        position: fixed;
        inset: 0;
        top: var(--imp-banner-h, 0px);
        background: rgba(0,0,0,0.55);
        z-index: 199;
    }

    .sidebar-backdrop.active { display: block; }

    .content { padding: 1rem 1.1rem 2rem; }
    .stat-row { gap: 0.75rem; }
    .page-head { margin-bottom: 1rem; }
    .page-head h1, .page-title { font-size: 1.25rem; }

    /* Touch targets */
    .icon-btn { width: 40px; height: 40px; }
    .chip { height: 34px; }
}

@media (max-width: 480px) {
    .content { padding: 0.75rem 0.75rem 2rem; }
    .emp-grid { grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 0.6rem; padding: 0.6rem; }
    .stat-card .stat-value { font-size: 1.5rem; }
    body.dashboard-page .section { padding: 1rem; }
    .toolbar-search { width: 100%; }
}

/* ── Help page: sidebar becomes a hamburger drawer even on desktop ───── */
body.help-page .hamburger { display: flex; }
body.help-page .sidebar { transform: translateX(-100%); }
body.help-page .sidebar.open { transform: translateX(0); box-shadow: 4px 0 24px rgba(0,0,0,0.45); }
body.help-page .sidebar-backdrop { position: fixed; inset: 0; top: var(--imp-banner-h, 0px); background: rgba(0,0,0,0.55); z-index: 199; display: none; }
body.help-page .sidebar-backdrop.active { display: block; }

/* Help section rail — sits where the sidebar normally would */
.help-rail {
    position: fixed;
    top: 0; left: 0;
    width: var(--sidebar-w);
    height: 100svh;
    background: var(--sidebar-bg);
    border-right: 1px solid var(--border-subtle);
    z-index: 150;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
}

body.help-page .help-toc { display: none; }

@media (max-width: 768px) {
    .help-rail { display: none; }
    body.help-page .help-toc { display: flex; }
}

/* ── Language dropdown ─────────────────────────────────────────── */
.lang-dropdown {
    position: relative;
    flex-shrink: 0;
}

.lang-dropdown-btn {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: var(--r-ctrl);
    color: var(--fg-soft);
    font-size: 0.8rem;
    font-family: inherit;
    padding: 0.3rem 0.6rem;
    cursor: pointer;
    white-space: nowrap;
    transition: border-color 0.15s, background 0.15s;
}

.lang-dropdown-btn:hover  { border-color: var(--muted); background: var(--raised); }
.lang-dropdown-btn:active { transform: none; }

.lang-chevron {
    font-size: 0.6rem;
    opacity: 0.55;
    transition: transform 0.15s;
    margin-left: 0.1rem;
}

.lang-dropdown.open .lang-chevron { transform: rotate(180deg); }

.lang-dropdown-menu {
    display: none;
    position: absolute;
    right: 0;
    top: calc(100% + 5px);
    background: var(--surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--r-ctrl);
    overflow: hidden;
    box-shadow: 0 12px 32px rgba(0,0,0,0.4);
    z-index: 500;
    min-width: 150px;
}

.lang-dropdown.open .lang-dropdown-menu { display: block; }

.lang-dropdown-menu button {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    width: 100%;
    text-align: left;
    padding: 0.55rem 0.9rem;
    background: none;
    border: none;
    border-radius: 0;
    color: var(--fg);
    font-size: 0.85rem;
    cursor: pointer;
    transition: background 0.1s;
    white-space: nowrap;
}

.lang-dropdown-menu button:hover  { background: var(--raised); }
.lang-dropdown-menu button:active { transform: none; }

.lang-flag {
    width: 20px;
    height: 15px;
    object-fit: cover;
    border-radius: 2px;
    flex-shrink: 0;
    display: block;
}

.lang-dropdown-menu button img {
    width: 20px;
    height: 15px;
    object-fit: cover;
    border-radius: 2px;
    flex-shrink: 0;
}

/* ═══════════════════════════════════════════════════════════════════
   CONTRACTS & PAPERWORK — the card-list recipe, unified.
   These four pages each declared their own near-identical copy in a page
   <style> block. The row is now a grid, so Type / Next due / Amount line
   up down the whole list regardless of how long a contract's name is.

   The column count must match the .list-head above it on each page.
   ═══════════════════════════════════════════════════════════════════ */

.contract-block { border-bottom: 1px solid var(--border-row); }
.contract-block:last-child { border-bottom: none; }

/* DOM order emitted by contracts.js renderContractItem():
   avatar · main · tags · due · amount-col(amount + icon-row)
   .contract-amount-col uses display:contents below, which lifts its two children
   into this same grid — so the row really has SIX tracks and the buttons get a
   column of their own. That is what keeps the amounts on one right edge instead
   of drifting with each row's button count, without touching contracts.js.      */
.contract-item {
    display: grid;
    grid-template-columns: 30px minmax(0, 1fr) 170px 132px 140px 112px;
    gap: 0 1rem;
    align-items: center;
    min-height: 64px;
    padding: 0.5rem 1.1rem;
}

/* The identity circle was a name-hash rainbow — the loudest colour on a
   finance screen carrying no information. Neutralised here rather than in
   contracts.js, which sets the colour inline (hence !important). Delete
   these two lines to bring the colours back. */
.entity-avatar {
    width: 30px; height: 30px; border-radius: var(--r-ctrl);
    flex-shrink: 0;
    background: var(--raised) !important;
    color: var(--muted);
    display: flex; align-items: center; justify-content: center;
    font-weight: 600; font-size: 0.78rem;
}

.contract-main { min-width: 0; }
.contract-name {
    font-size: 0.94rem; font-weight: 600; color: var(--fg);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.contract-vendor {
    font-size: 0.78rem; color: var(--muted); margin-top: 0.1rem;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.contract-tags { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; min-width: 0; }

/* Type is a dot + a word. Keeps the .type-pill class the JS emits. */
.type-pill {
    display: inline-flex; align-items: center; gap: 0.35rem;
    font-size: 0.82rem; font-weight: 400; padding: 0;
    border-radius: 0; background: none !important; white-space: nowrap;
}
.type-pill::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: currentColor; flex-shrink: 0; }
.type-pill-fixed    { color: var(--fg-soft); }
.type-pill-fixed::before    { background: var(--baby); }
.type-pill-variable { color: var(--fg-soft); }
.type-pill-variable::before { background: var(--royal); }
.cycle-pill { font-size: 0.75rem; color: var(--muted); white-space: nowrap; }

.doc-count-pill {
    display: inline-flex; align-items: center; gap: 0.25rem;
    font-size: 0.72rem; font-weight: 600;
    padding: 0.15rem 0.45rem;
    border-radius: var(--r-pill);
    border: 1px solid var(--border-subtle);
    background: var(--raised); color: var(--muted);
    cursor: pointer; font-family: inherit;
}
.doc-count-pill:hover, .doc-count-pill.open { color: var(--royal-hi); border-color: var(--royal); }

/* Due state — the one place colour is spent. */
.due-pill {
    display: inline-flex; align-items: center; gap: 0.35rem;
    flex-shrink: 0; font-size: 0.75rem; font-weight: 600;
    padding: 0.2rem 0.55rem; border-radius: var(--r-pill); white-space: nowrap;
}
.due-pill-overdue { background: var(--error-bg); color: var(--error-fg); }
.due-pill-soon    { background: var(--warn-bg);  color: var(--warn-fg); }
.due-pill-later   { background: none; color: var(--muted); border: 0; padding: 0;
                    font-family: var(--mono); font-weight: 400; font-variant-numeric: tabular-nums; }
/* A grid item stretches to fill its track by default, which made the tinted
   pill run the full width of the Next due column. It must hug its text. */
.contract-item > .due-pill { justify-self: start; }

/* See the note on .contract-item: this wrapper deliberately has no box of its own. */
.contract-amount-col { display: contents; }
.contract-amount {
    font-family: var(--mono);
    font-size: 0.95rem; font-weight: 500;
    font-variant-numeric: tabular-nums; letter-spacing: -0.01em;
    white-space: nowrap; text-align: right;
    justify-self: end;
}
.contract-item .icon-row { justify-self: end; }

/* "Estimate" was an amber chip competing with the amber due-today pill
   right beside it. It is a quiet uppercase label now. */
.badge-estimate {
    display: inline-block; margin-left: 0.4rem;
    font-size: 0.64rem; font-weight: 600; letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 0; border-radius: 0;
    background: none !important; color: var(--faint) !important;
}
.badge-fixed    { color: var(--baby); }
.badge-variable { color: var(--royal-hi); }

/* Linked-documents panel (#127) */
.contract-docs-panel { padding: 0 1.1rem 0.9rem 3.6rem; background: var(--head-bg); }
.contract-docs-heading {
    font-size: 0.66rem; font-weight: 600; letter-spacing: 0.09em;
    text-transform: uppercase; color: var(--faint);
    padding-top: 0.7rem; margin-bottom: 0.4rem;
}
.contract-doc-row { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; padding: 0.2rem 0; font-size: 0.83rem; }
.contract-doc-name { color: var(--fg-soft); text-decoration: none; font-weight: 500; word-break: break-all; }
.contract-doc-name:hover { color: var(--royal-hi); text-decoration: underline; }
.contract-doc-meta { color: var(--faint); font-size: 0.75rem; font-family: var(--mono); }
.scan-hint { color: var(--warn); display: inline-flex; vertical-align: -2px; cursor: help; }

.empty-hint { color: var(--muted); font-size: 0.88rem; padding: 1.5rem 0; text-align: center; }

/* Contracts list: stack on narrow screens rather than squeezing 5 tracks.
   Two tracks (avatar | everything else) and four rows: name, tags, due, amount + buttons.
   The name gets the full width — an earlier version put the amount and the three icon
   buttons beside the name, which left ~40-100px for it on a phone and truncated even
   "DEI Power" (measured; the pre-redesign layout gave it 316px). */
@media (max-width: 900px) {
    .contract-item {
        grid-template-columns: 30px minmax(0, 1fr);
        gap: 0.35rem 0.8rem;
        padding: 0.8rem 0.9rem;
        min-height: 0;
    }
    .entity-avatar { grid-column: 1; grid-row: 1; }
    .contract-main { grid-column: 2; grid-row: 1; }
    /* On a phone a long name wraps rather than ellipsising - the name is what identifies the row. */
    .contract-name { white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: anywhere; }
    .contract-tags { grid-column: 2; grid-row: 2; }
    /* The due cell is the 4th child whether it rendered a pill or a plain dash. */
    .contract-item > .due-pill,
    .contract-item > span:nth-child(4) { grid-column: 2; grid-row: 3; justify-self: start; }
    /* Back to one box (it is display:contents on desktop) so the amount and its buttons
       travel together on a row of their own: amount at the left, buttons at the right. */
    .contract-amount-col {
        display: flex; align-items: center; gap: 0.6rem; justify-content: space-between;
        grid-column: 2; grid-row: 4;
        margin-top: 0.15rem;
    }
    .contract-amount { justify-self: auto; }
    .contract-docs-panel { padding-left: 2.6rem; }
    .list-head { display: none; }
}

/* ── Field labels used inside page modals ──────────────────────── */
.field { margin-bottom: 0.85rem; }
.field > label { display: block; font-size: 0.72rem; color: var(--muted); margin-bottom: 0.3rem; }
.field-row { display: flex; gap: 0.7rem; }
.field-row .field { flex: 1; min-width: 0; }

/* ── Print ─────────────────────────────────────────────────────── */
@media print {
    .sidebar, .top-bar, .hamburger, .page-head-actions, .toolbar, .icon-btn { display: none !important; }
    .page-body { margin-left: 0; }
    body { background: #fff; color: #000; }
}

/* ── Shared bits that individual pages used to redeclare ───────── */
.icon-btn:disabled { opacity: 0.35; cursor: default; }
.icon-btn:disabled:hover { background: transparent; border-color: transparent; color: var(--muted); }

/* A stat card whose figure is zero/not applicable reads quieter. */
.stat-card-quiet .stat-card-value { color: var(--muted); }

/* Month stepper (Upcoming Costs, Receipts, Expenses) */
.month-nav { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 1.25rem; }
.month-nav-label {
    font-weight: 600; min-width: 11ch; text-align: center;
    font-variant-numeric: tabular-nums;
}

/* The "Projected" accent (#131) — a distinct, hatched teal so a projection is
   never mistaken for a recorded figure. */
:root { --projected: #3F9FC7; --projected-soft: rgba(63,159,199,0.55); }
html[data-theme="light"] { --projected: #1F6F92; --projected-soft: rgba(31,111,146,0.5); }

tfoot td { font-weight: 600; border-top: 1px solid var(--border); }

/* ═══════════════════════════════════════════════════════════════════
   READABILITY PASS — data display
   Same information on every page, presented so it can be scanned.
   ═══════════════════════════════════════════════════════════════════ */

/* ── 1. Reconciling colours the JS writes inline ─────────────────────
   payroll.js / staff.js / shifts.js / admin.js emit legacy hex colours
   directly into generated cells. Those are inline styles, so only an
   !important author rule can bring them into the palette — and that is
   the whole reason these selectors look unusual. They are the price of
   keeping every .js file byte-identical to production.
   If the JS is ever updated to emit palette tokens instead, delete this block.  */
[style*="color:#94a3b8"], [style*="color:#64748b"] { color: var(--muted) !important; }
[style*="color:#cbd5e1"], [style*="color:#f1f5f9"] { color: var(--fg-soft) !important; }
[style*="color:#f59e0b"], [style*="color:#ca8a04"] { color: var(--warn-fg) !important; }
[style*="color:#ef4444"]                           { color: var(--error-fg) !important; }
[style*="color:#22c55e"]                           { color: var(--success-fg) !important; }
[style*="color:#7c9aff"], [style*="color:#a78bfa"] { color: var(--royal-hi) !important; }
/* #89CFF0 marks the actual-cost column — the number the page exists to show.
   That deserves emphasis, but colour is reserved for state, so it becomes the
   brightest foreground at a heavier weight instead of a blue. */
td[style*="color:#89CFF0"],
td[style*="color:var(--baby)"] { color: var(--fg) !important; font-weight: 600; }
[style*="color:#89CFF0"]:not(td) { color: var(--royal-hi) !important; }
[style*="background:#334155"]                      { background: var(--raised) !important; }

/* NOTE the two spellings below: payroll.js sets the totals row with style.cssText, and the browser then stores the
   attribute normalised ("border-top: 2px solid rgba(65, 105, 225, ...", spaces added), while markup written as an
   HTML string keeps its source text. A [style*="a:b"] hook only sees the spelling it was written for - and the
   first version of this rule silently never matched the totals row. Test hooks like this on the real rendered DOM.
/* The Payroll totals row and the Guest Workers separator are both styled
   inline by payroll.js. Re-expressed as a proper table footer. */
tbody tr:is([style*="border-top:2px solid rgba(65,105,225"], [style*="border-top: 2px solid rgba(65, 105, 225"]) {
    border-top: 1px solid var(--border) !important;
    background: var(--head-bg);
    font-weight: 600;
}
tbody tr:is([style*="border-top:2px solid rgba(65,105,225"], [style*="border-top: 2px solid rgba(65, 105, 225"]) td { padding-top: 0.85rem; padding-bottom: 0.85rem; }
/* .table-wrap scrolls inside itself (section 2 below), so on a long table - or one whose rows wrap onto two
   lines, e.g. German or Greek names - the totals row would sit below the fold of the inner scroll area, and the
   total is the figure Payroll exists to show. Pin it to the bottom edge, as the header is pinned to the top.
   The first-cell selector is longer on purpose: .sticky-col's first-cell rule (surface background) must not win. */
.table-wrap tbody tr:is([style*="border-top:2px solid rgba(65,105,225"], [style*="border-top: 2px solid rgba(65, 105, 225"]) > td,
.table-wrap.sticky-col tbody tr:is([style*="border-top:2px solid rgba(65,105,225"], [style*="border-top: 2px solid rgba(65, 105, 225"]) > td:first-child {
    position: sticky; bottom: 0; z-index: 2;
    background: var(--head-bg);
    box-shadow: inset 0 1px 0 var(--border);       /* the row's own border would scroll away */
}
.table-wrap.sticky-col tbody tr:is([style*="border-top:2px solid rgba(65,105,225"], [style*="border-top: 2px solid rgba(65, 105, 225"]) > td:first-child {
    box-shadow: inset 0 1px 0 var(--border), inset -1px 0 0 var(--border-subtle);
}
td[style*="border-top:2px dashed"] { border-top: 1px solid var(--border-subtle) !important; }

/* ── 2. Tables that can actually be read ─────────────────────────────
   A long table is only scannable if the header stays put, so .table-wrap
   becomes its own scroll area. max-height only engages once the table is
   genuinely long — short tables are unaffected. */
.table-wrap { max-height: 72vh; overflow: auto; }

thead th {
    position: sticky; top: 0; z-index: 2;
    background: var(--head-bg);
    /* a real border would scroll away with the row; a shadow stays put */
    box-shadow: inset 0 -1px 0 var(--border-subtle);
    border-bottom: 0;
}

/* Numbers are the payload of these tables. The app right-aligns every
   numeric cell with an inline text-align, which makes that the one
   reliable hook for "this cell is a figure". */
td[style*="text-align:right"], th[style*="text-align:right"] {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
td[style*="text-align:right"] { font-family: var(--mono); letter-spacing: -0.01em; }
th[style*="text-align:right"] { text-align: right; }

/* Row rhythm: a little more air, and a quieter divider. */
th { padding: 0.75rem 0.9rem; }
td { padding: 0.72rem 0.9rem; }
tbody tr { transition: background 0.1s; }

/* The name column carries the row's identity — keep it anchored while the
   figures scroll sideways. Opt-in per page via .table-wrap.sticky-col. */
.table-wrap.sticky-col thead th:first-child,
.table-wrap.sticky-col tbody td:first-child {
    position: sticky; left: 0; z-index: 1;
    background: var(--surface);
    box-shadow: inset -1px 0 0 var(--border-subtle);
}
.table-wrap.sticky-col thead th:first-child { z-index: 3; background: var(--head-bg); }
.table-wrap.sticky-col tbody tr:hover td:first-child { background: var(--row-hover); }

/* A column group boundary, so 9 columns read as 3 groups of 3.
   Applied per page, where the group starts are known. */
.col-group-start { box-shadow: inset 1px 0 0 var(--border-subtle); }

/* ── 3. Empty and loading states ─────────────────────────────────── */
.empty-hint, tbody td[colspan] { color: var(--muted); }
tbody td[colspan] { padding: 2rem 1rem; text-align: center; }

/* ── 4. Page header, used on every page ──────────────────────────── */
.page-head + .stats-row, .page-head + .stat-row { margin-top: 0; }

/* A toolbar that sits under a page header reads as a filter strip, not a
   second title bar. */
.toolbar-strip {
    display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap;
    padding: 0.7rem 0.9rem;
    background: var(--surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--r-ctrl);
    margin-bottom: 1rem;
}
.toolbar-strip .spacer { flex: 1 1 auto; }
.toolbar-strip label,
.toolbar-label {
    font-size: 0.7rem; font-weight: 600; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--faint);
    margin: 0; white-space: nowrap;
}
.toolbar-strip input, .toolbar-strip select { width: auto; height: 32px; padding: 0 0.55rem; font-size: 0.82rem; }
.toolbar-strip .seg-toggle { flex-shrink: 0; }

/* ── 5. Definition-style key/value lists (modals, detail panels) ──── */
.kv { display: grid; grid-template-columns: max-content 1fr; gap: 0.4rem 1.1rem; font-size: 0.87rem; }
.kv dt { color: var(--muted); }
.kv dd { color: var(--fg); font-variant-numeric: tabular-nums; }

/* ═══════════════════════════════════════════════════════════════════
   CAMERA SCAN (2026-09-20) — the sidebar's camera item, the capture
   overlay it opens (scan-capture.js), and the "what the AI read" block
   shown inside the Add Receipt / Add Contract panels afterwards.
   ═══════════════════════════════════════════════════════════════════ */

/* ── Capture overlay ────────────────────────────────────────────────
   Always dark, whatever the theme: it is a viewfinder, and a light UI
   around a live picture is glare. Sized in dvh so a phone's collapsing
   address bar never pushes the shutter off screen. */
.scan-overlay {
    position: fixed; inset: 0; z-index: 10000;
    background: #000; color: #fff;
    display: flex; flex-direction: column;
    height: 100vh; height: 100dvh;
    overflow: hidden;
}
.scan-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; background: #000; }
.scan-video.hidden { visibility: hidden; }

/* The A4 guide. It IS the crop: what sits inside this rectangle is what gets photographed. The huge box-shadow
   dims everything outside it, which also makes "fit the page in the frame" obvious at a glance. */
.scan-frame {
    position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
    height: min(72vh, calc(86vw * 1.4142)); height: min(72dvh, calc(86vw * 1.4142));
    aspect-ratio: 210 / 297;
    border: 2px solid rgba(255,255,255,0.9); border-radius: 6px;
    box-shadow: 0 0 0 200vmax rgba(0,0,0,0.58);
    pointer-events: none; overflow: hidden;
}
.scan-frame.landscape {
    aspect-ratio: 297 / 210;
    height: auto; width: min(94vw, calc(70vh * 1.4142)); width: min(94vw, calc(70dvh * 1.4142));
}
.scan-frame img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: none; }
.scan-frame.has-still img { display: block; }
/* An uploaded / camera-app image was not cropped to the frame, so show all of it (letterboxed) rather than a slice. */
.scan-frame.contain img { object-fit: contain; background: #000; }
/* A PDF (or an image the browser cannot draw) has no preview: say what it is. */
.scan-file-card { position: absolute; inset: 0; display: none; flex-direction: column; align-items: center; justify-content: center; gap: 0.5rem; padding: 1rem; background: rgba(12,16,22,0.96); color: #fff; text-align: center; }
.scan-frame.has-file .scan-file-card { display: flex; }
.scan-file-name { font-size: 0.9rem; font-weight: 600; overflow-wrap: anywhere; }
.scan-file-size { font-size: 0.78rem; opacity: 0.7; }
.scan-corner { position: absolute; width: 22px; height: 22px; border: 3px solid var(--royal-hi); }
.scan-corner.tl { top: -1px; left: -1px; border-right: 0; border-bottom: 0; border-top-left-radius: 6px; }
.scan-corner.tr { top: -1px; right: -1px; border-left: 0; border-bottom: 0; border-top-right-radius: 6px; }
.scan-corner.bl { bottom: -1px; left: -1px; border-right: 0; border-top: 0; border-bottom-left-radius: 6px; }
.scan-corner.br { bottom: -1px; right: -1px; border-left: 0; border-top: 0; border-bottom-right-radius: 6px; }

.scan-top, .scan-bottom {
    position: relative; z-index: 2;
    display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
    padding: 0.75rem 1rem;
}
.scan-top { padding-top: max(0.75rem, env(safe-area-inset-top)); }
.scan-bottom { margin-top: auto; padding: 1rem 1.25rem max(1.25rem, env(safe-area-inset-bottom)); }
.scan-title { font-size: 0.95rem; font-weight: 600; text-shadow: 0 1px 4px rgba(0,0,0,0.7); }
.scan-cue {
    position: absolute; left: 0; right: 0; z-index: 2; text-align: center; padding: 0 1.5rem;
    bottom: 7.5rem;
    font-size: 0.85rem; text-shadow: 0 1px 4px rgba(0,0,0,0.85); pointer-events: none;
}

.scan-icon-btn {
    width: 44px; height: 44px; padding: 0; border-radius: 50%;
    background: rgba(0,0,0,0.55); color: #fff; border: 1px solid rgba(255,255,255,0.28);
}
.scan-icon-btn:hover { background: rgba(0,0,0,0.75); border-color: rgba(255,255,255,0.6); }
.scan-icon-btn:disabled { opacity: 0.4; cursor: default; }
.scan-shutter {
    width: 74px; height: 74px; padding: 0; border-radius: 50%; flex-shrink: 0;
    background: #fff; border: 5px solid rgba(0,0,0,0.35); background-clip: padding-box;
    box-shadow: 0 0 0 3px rgba(255,255,255,0.9);
    transition: transform 0.1s;
}
.scan-shutter:active:not(:disabled) { transform: scale(0.92); }
.scan-shutter:disabled { opacity: 0.35; cursor: default; }
.scan-alt-btn {
    background: rgba(0,0,0,0.55); color: #fff; border: 1px solid rgba(255,255,255,0.28);
    font-size: 0.8rem; white-space: normal; text-align: center; max-width: 9.5rem; line-height: 1.25; cursor: pointer;
}
.scan-alt-btn:hover { background: rgba(0,0,0,0.75); border-color: rgba(255,255,255,0.6); }
/* Two equal, flexible side slots keep the shutter dead centre without a fixed width that would overflow a phone. */
.scan-side { flex: 1 1 0; min-width: 0; display: flex; }
.scan-side-right { justify-content: flex-end; }   /* the upload icon sits in the bottom-right corner */

/* Status / error sheet: replaces the bottom controls while uploading, reading, or after a failure. */
.scan-panel {
    position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
    padding: 1.25rem 1.25rem max(1.25rem, env(safe-area-inset-bottom));
    background: rgba(12,16,22,0.94); border-top: 1px solid rgba(255,255,255,0.14);
    border-radius: 16px 16px 0 0;
    display: none; flex-direction: column; gap: 0.75rem; align-items: stretch;
}
.scan-panel.show { display: flex; }
.scan-steps { list-style: none; display: flex; flex-direction: column; gap: 0.55rem; font-size: 0.9rem; }
.scan-step { display: flex; align-items: flex-start; gap: 0.6rem; color: rgba(255,255,255,0.55); }
.scan-step.active { color: #fff; }
.scan-step.done { color: var(--success-fg); }
.scan-step-mark { width: 20px; height: 20px; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; }
.scan-spinner {
    width: 16px; height: 16px; border-radius: 50%;
    border: 2px solid rgba(255,255,255,0.25); border-top-color: var(--royal-hi);
    animation: scan-spin 0.8s linear infinite;
}
@keyframes scan-spin { to { transform: rotate(360deg); } }
.scan-msg { font-size: 0.9rem; line-height: 1.4; }
.scan-msg.error { color: var(--error-fg); }
.scan-actions { display: flex; gap: 0.6rem; flex-wrap: wrap; }
.scan-actions button { flex: 1 1 auto; }
.scan-actions .btn-secondary { color: #fff; border-color: rgba(255,255,255,0.35); }
.scan-actions .btn-secondary:hover { background: rgba(255,255,255,0.1); border-color: #fff; }

/* ── "What the AI read" block (inside the Add Receipt / Add Contract panels) ─────────────────────── */
.ai-scan {
    background: var(--raised); border: 1px solid var(--border); border-left: 3px solid var(--royal);
    border-radius: var(--r-ctrl); padding: 0.9rem 1rem; margin-bottom: 1.1rem;
}
.ai-scan-head { display: flex; align-items: center; gap: 0.5rem; font-size: 0.72rem; font-weight: 600; letter-spacing: 0.09em; text-transform: uppercase; color: var(--royal-hi); margin-bottom: 0.6rem; }
.ai-scan-top { display: flex; gap: 0.9rem; align-items: flex-start; }
/* contain, not cover: the whole page is the point of the thumbnail (cover would crop it to a slice of the middle) */
.ai-scan-thumb { flex: 0 0 auto; width: 76px; height: 108px; border-radius: 6px; border: 1px solid var(--border); object-fit: contain; background: var(--head-bg); cursor: zoom-in; }
.ai-scan-main { flex: 1; min-width: 0; }
/* An uploaded PDF cannot be drawn in an <img>: a file tile stands in (click opens it). */
.ai-scan-thumb-file { display: inline-flex; align-items: center; justify-content: center; color: var(--muted); }
.ai-scan-thumb-file:hover { color: var(--royal-hi); border-color: var(--royal); }
.ai-scan-verdict { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 0.6rem; font-size: 0.95rem; font-weight: 600; color: var(--fg); }
.ai-scan-kind { font-weight: 400; color: var(--muted); font-size: 0.85rem; }
.ai-scan-conf { display: inline-flex; align-items: center; height: 22px; padding: 0 0.55rem; border-radius: var(--r-pill); font-size: 0.72rem; font-weight: 600; white-space: nowrap; }
.ai-scan-conf.sure   { background: var(--success-bg); color: var(--success-fg); }
.ai-scan-conf.unsure { background: var(--warn-bg); color: var(--warn-fg); }
.ai-scan-why { margin-top: 0.3rem; font-size: 0.82rem; color: var(--muted); line-height: 1.4; }
.ai-scan-read-title { margin: 0.85rem 0 0.3rem; font-size: 0.68rem; font-weight: 600; letter-spacing: 0.09em; text-transform: uppercase; color: var(--faint); }
.ai-scan-rows { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 0.28rem 1rem; font-size: 0.85rem; }
.ai-scan-rows dt { color: var(--muted); }
.ai-scan-rows dd { color: var(--fg); overflow-wrap: anywhere; }
.ai-scan-rows dd.num { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.ai-scan-rows dd.empty { color: var(--faint); font-style: italic; }
.ai-scan-flag { display: inline-block; margin-left: 0.45rem; font-size: 0.64rem; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; padding: 0.05rem 0.4rem; border-radius: var(--r-pill); background: var(--warn-bg); color: var(--warn-fg); }
.ai-scan-verify { display: inline-flex; vertical-align: -2px; margin-left: 0.4rem; color: var(--warn-fg); cursor: help; }
.ai-scan-legend { display: flex; align-items: center; gap: 0.35rem; margin-top: 0.5rem; font-size: 0.75rem; color: var(--warn-fg); }
.ai-scan-note { display: block; margin-top: 0.1rem; font-size: 0.75rem; color: var(--warn-fg); }
.ai-scan-foot { margin-top: 0.75rem; display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.9rem; }
.ai-scan-foot .disclaimer { flex: 1 1 100%; font-size: 0.75rem; color: var(--muted); }
.ai-scan-switched { margin-top: 0.5rem; font-size: 0.8rem; color: var(--warn-fg); }
@media (max-width: 520px) {
    .ai-scan { padding: 0.8rem 0.85rem; }
    .ai-scan-thumb { width: 62px; height: 88px; }
    .ai-scan-rows { gap: 0.3rem 0.8rem; }
}
