/* ---------- Theming ----------
   Only brand/decorative colors are themed (nav bar, card accent borders,
   links/primary buttons) -- status colors (green=good, red=delete/critical,
   yellow=warning) and chart colors deliberately stay fixed across every
   theme, so they keep meaning what they mean regardless of a user's
   preference. See includes/themes.php for the PHP-side list (kept in sync
   with the seed colors below by hand) and account.php for where a user
   picks one; applied via a `data-theme` attribute on <html> in
   includes/header.php.

   Each theme only needs to override the three seed variables below --
   everything else (hover states, light background tints, the home-hero
   gradient) is derived from them with color-mix() so it recomputes
   automatically per theme. */
:root {
    --brand-dark: #1c2733;
    --link: #0056b3;
    --accent: #e67e22;

    --link-hover: color-mix(in srgb, var(--link) 75%, black);
    --link-tint: color-mix(in srgb, var(--link) 8%, var(--surface-bg));
    --link-tint-strong: color-mix(in srgb, var(--link) 15%, var(--surface-bg));
    --link-focus-ring: color-mix(in srgb, var(--link) 15%, transparent);
    --link-on-dark: color-mix(in srgb, var(--link) 45%, white);
    --brand-dark-mid: color-mix(in srgb, var(--brand-dark), white 18%);
    --brand-dark-soft: color-mix(in srgb, var(--brand-dark), white 30%);

    /* Neutral/surface colors -- independent of the brand seeds above, these
       are the light/dark axis (see account.php's Light/Dark picker, applied
       via a `data-mode="dark"` attribute on <html> below). The nav bar is
       NOT included here on purpose: it's already a dark brand color in
       every theme, so it doesn't need to change between light and dark
       page mode. */
    --page-bg: #fff;
    --page-text: #222;
    --surface-bg: #fff;
    --surface-alt: #f7f9fb;
    --surface-border: #e1e6eb;
    --input-border: #ccc;
    --text-muted: #777;
    /* Heading/label text on a card or light surface -- in light mode this is
       the theme's own brand color (so headings pick up a bit of the chosen
       theme's personality, e.g. Steel Blue's headings read as deep blue); in
       dark mode --brand-dark itself is too dark to read against a dark
       surface, so this falls back to the page's own (light) text color
       instead. Never use --brand-dark directly for text color -- use this. */
    --heading-text: var(--brand-dark);
}
html[data-theme="charcoal-teal"] {
    --brand-dark: #263238;
    --link: #0277bd;
    --accent: #00897b;
}
html[data-theme="steel-blue"] {
    --brand-dark: #1e3a5f;
    --link: #1565c0;
    --accent: #f39c12;
}
html[data-theme="forest-rust"] {
    --brand-dark: #1b3a2f;
    --link: #2e7d32;
    --accent: #c0562c;
}
html[data-mode="dark"] {
    color-scheme: dark; /* hints the browser to draw native controls (scrollbars, checkboxes, date pickers) dark too */
    --page-bg: #14181d;
    --page-text: #d7dce2;
    --surface-bg: #1c222b;
    --surface-alt: #232a34;
    --surface-border: #333c48;
    --input-border: #454f5c;
    --text-muted: #98a2ad;
    --heading-text: var(--page-text);
}

/* ---------- Base ---------- */
body {
    font-family: Arial, sans-serif;
    margin: 0;
    background: var(--page-bg);
    color: var(--page-text);
}
.page-content {
    margin: 2rem;
}
a { color: var(--link); }

/* ---------- Top navigation ---------- */
.main-nav {
    display: flex;
    align-items: center;
    gap: 1.5rem;
    background: var(--brand-dark);
    color: #fff;
    padding: 0 1.5rem;
    height: 56px;
    flex-wrap: wrap;
}
.nav-brand {
    font-weight: bold;
    font-size: 1.05rem;
    margin-right: 1rem;
    color: #fff;
    text-decoration: none;
}
.nav-brand:hover { color: var(--link-on-dark); }
.nav-menu {
    list-style: none;
    display: flex;
    gap: 0.25rem;
    margin: 0;
    padding: 0;
    flex: 1;
}
.nav-item { position: relative; }
.nav-link, .nav-toggle {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: #dbe4ee;
    text-decoration: none;
    background: none;
    border: none;
    font-size: 0.95rem;
    font-family: inherit;
    padding: 8px 12px;
    border-radius: 4px;
    cursor: pointer;
}
.nav-link:hover, .nav-toggle:hover { background: rgba(255,255,255,0.08); color: #fff; }
.nav-item.active > .nav-link,
.nav-item.active > .nav-toggle { background: rgba(255,255,255,0.12); color: #fff; }
.nav-caret { font-size: 0.6rem; }
.submenu {
    /* Always laid out but hidden, so opening can fade/slide instead of
       popping (display:none can't be transitioned). visibility (delayed
       until the fade-out finishes) keeps it out of reach of clicks and the
       tab order while closed. */
    display: block;
    visibility: hidden;
    opacity: 0;
    transform: translateY(-10px) scale(0.97);
    transform-origin: top left;
    pointer-events: none;
    transition: opacity 0.22s ease, transform 0.22s cubic-bezier(.2,.8,.3,1), visibility 0s linear 0.22s;
    position: absolute;
    top: 100%;
    left: 0;
    background: var(--surface-bg);
    color: var(--page-text);
    list-style: none;
    margin: 4px 0 0;
    padding: 6px 0;
    min-width: 180px;
    border-radius: 4px;
    box-shadow: 0 6px 18px rgba(0,0,0,0.18);
    z-index: 20;
}
.nav-item.open .submenu {
    visibility: visible; opacity: 1; transform: none; pointer-events: auto;
    transition-delay: 0s;
}
.nav-caret { display: inline-block; transition: transform 0.22s ease; }
.nav-item.open .nav-caret { transform: rotate(180deg); }
.submenu-link {
    display: block;
    padding: 8px 14px;
    color: var(--page-text);
    text-decoration: none;
    font-size: 0.9rem;
}
.submenu-link:hover { background: var(--surface-alt); }
.submenu-link.active { color: var(--link); font-weight: bold; }
.submenu-divider { height: 0; margin: 6px 0; border-top: 1px solid var(--surface-border); }
.nav-user {
    display: flex;
    align-items: center;
    gap: 12px;
    font-size: 0.9rem;
    color: #dbe4ee;
}
.nav-role { color: #93a4b8; font-size: 0.8rem; }
.nav-account-link {
    color: #dbe4ee;
    padding: 6px 10px;
    border-radius: 4px;
    text-decoration: none;
    white-space: nowrap;
}
.nav-account-link:hover, .nav-account-link.active { background: rgba(255,255,255,0.1); color: #fff; }
.nav-logout {
    color: #dbe4ee;
    padding: 6px 10px;
    border: 1px solid rgba(255,255,255,0.3);
    border-radius: 4px;
    text-decoration: none;
}
.nav-logout:hover { background: rgba(255,255,255,0.1); }

/* ---------- Tables (list pages) ---------- */
table {
    border-collapse: separate;
    border-spacing: 0;
    width: 100%;
    max-width: 800px;
    border: 1px solid var(--surface-border);
    border-radius: 6px;
    overflow: hidden;
}
th, td { border-bottom: 1px solid var(--surface-border); border-right: 1px solid var(--surface-border); padding: 9px 12px; text-align: left; }
th:last-child, td:last-child { border-right: none; }
tr:last-child td { border-bottom: none; }
th {
    background: var(--brand-dark);
    color: #fff;
    font-weight: 600;
    border-bottom: 2px solid var(--link);
}
tbody tr:nth-child(even) { background: var(--surface-alt); }
tbody tr:hover { background: var(--link-tint); }
tbody td { transition: background-color 0.12s ease; }
/* A thin accent bar on the hovered row's first cell makes it easy to track
   one record across a wide table. */
tbody tr:hover td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
tr.filter-row td { padding: 4px 6px; background: var(--surface-alt); }
tr.filter-row:hover { background: var(--surface-alt); }
tr.filter-row input { width: 100%; box-sizing: border-box; padding: 4px 6px; font-size: 0.9rem; border: 1px solid var(--input-border); border-radius: 3px; background: var(--surface-bg); color: var(--page-text); }
tr.no-match td { text-align: center; color: var(--text-muted); font-style: italic; background: var(--surface-bg); }

/* ---------- Column visibility + Excel-style per-column value filters ---------- */
/* Wraps each filter-row's text input plus its new value-filter dropdown
   button, so the two sit side by side without disturbing the input's own
   width/behavior. */
.filter-cell { display: flex; gap: 4px; align-items: center; }
.filter-cell input { flex: 1; min-width: 0; }
.filter-dropdown-btn {
    flex-shrink: 0; padding: 4px 7px; font-size: 0.75rem; line-height: 1.2;
    border: 1px solid var(--input-border); border-radius: 3px;
    background: var(--surface-bg); color: var(--text-muted); cursor: pointer;
}
.filter-dropdown-btn:hover { background: var(--surface-alt); }
/* Sized/weighted like the other header-actions buttons it sits next to
   (Export Excel/PDF, + Add Record) -- it was previously sharing the tiny
   .filter-dropdown-btn style above, which made it look like a stray icon
   rather than a real toolbar action and was easy to miss entirely. */
#columnsToggleBtn { white-space: nowrap; }
/* Marks a column whose checkbox list currently excludes at least one value
   -- same idea as Excel's own filled-in funnel icon, so it's obvious at a
   glance which columns have an active value filter. */
.filter-dropdown-btn.filter-active { background: var(--link); color: #fff; border-color: var(--link); }

/* Floating panel shared by both the "Columns" (show/hide) button and every
   per-column value-filter dropdown -- built and positioned in JS
   (table-interactions.js), appended directly to <body> so it's never
   confined by the table's own scrolling/sticky containers. */
.dropdown-panel {
    position: fixed; z-index: 50; background: var(--surface-bg);
    border: 1px solid var(--surface-border); border-radius: 6px;
    box-shadow: 0 10px 30px rgba(0,0,0,0.2);
    padding: 10px; width: 240px; max-width: 90vw;
}
.dropdown-panel .dropdown-search {
    width: 100%; box-sizing: border-box; padding: 5px 8px; margin-bottom: 8px;
    border: 1px solid var(--input-border); border-radius: 3px; background: var(--surface-bg); color: var(--page-text);
}
.dropdown-panel .dropdown-actions { display: flex; gap: 8px; margin-bottom: 8px; }
.dropdown-panel .dropdown-actions button {
    flex: 1; padding: 4px 8px; font-size: 0.8rem; border: 1px solid var(--input-border);
    border-radius: 3px; background: var(--surface-alt); color: var(--page-text); cursor: pointer;
}
.dropdown-panel .dropdown-actions button:hover { background: var(--link-tint); }
.dropdown-panel .checklist-box { max-height: 240px; margin-bottom: 8px; }
.dropdown-panel .checklist-box label { display: block; font-weight: normal; margin-bottom: 4px; font-size: 0.88rem; word-break: break-word; }
.dropdown-panel .dropdown-apply { width: 100%; padding: 6px; }
th .sort-link {
    display: flex; justify-content: space-between; align-items: center;
    color: inherit; text-decoration: none; cursor: pointer; user-select: none;
}
th .sort-link:hover { color: var(--link-on-dark); }
th .sort-arrow { font-size: 0.7rem; margin-left: 6px; color: var(--link-on-dark); }
th.sorted-active { background: var(--link-hover); }

/* Right-justify phase code + currency columns -- both the data cells and
   their header label, so the header sits above the right-justified numbers
   below it instead of drifting to the opposite side. tabular-nums keeps
   digits a fixed width so amounts line up vertically. */
.align-right { text-align: right; font-variant-numeric: tabular-nums; }
th.align-right .sort-link { justify-content: flex-end; }

/* Frozen leading columns ("freeze panes") -- pins the first 4 columns in
   place while the rest scroll underneath horizontally, so Actions/Created/
   Job/PO Number stay visible on a table that's grown too wide to read
   comfortably at a glance (see table-interactions.js's initInteractiveTable
   freezeColumns option, which computes --freeze-left-N to match each
   column's real on-screen width). Each nth-child rule needs its own `left`
   value, so this can't collapse into one :nth-child(-n+4) selector.
   Backgrounds are layered in the same order/specificity as the plain
   (non-frozen) row rules above, so a frozen cell always matches whatever
   its own row would look like unfrozen -- header, even/odd, hover. */
/* (overflow:hidden on the base `table` rule, which would otherwise confine
   position:sticky to the table's own box, is overridden for every table
   inside a .table-scroll-full wrapper -- see that rule further down.) */
/* #dataTable-scoped (not just .freeze-cols) so these outrank the ID
   selector `#dataTable th { position: relative; }` above (line ~330,
   there for the resize-handle's absolute positioning) -- a class selector
   alone loses to an ID selector regardless of source order. */
/* will-change forces each of these onto its own GPU-composited layer.
   Without it, a cell that's sticky on BOTH axes at once (pinned to a
   corner -- exactly what a frozen column's header cell is) is a known
   failure case for position:sticky in tables across browsers, Chrome
   included: during horizontal scroll, the browser can miscalculate which
   region of a double-sticky cell needs repainting and render it
   truncated or blank. This doesn't change layout, only how it's painted. */
#dataTable.freeze-cols th:nth-child(1), #dataTable.freeze-cols td:nth-child(1) { position: sticky; left: var(--freeze-left-0, 0px); will-change: transform; }
#dataTable.freeze-cols th:nth-child(2), #dataTable.freeze-cols td:nth-child(2) { position: sticky; left: var(--freeze-left-1, 0px); will-change: transform; }
#dataTable.freeze-cols th:nth-child(3), #dataTable.freeze-cols td:nth-child(3) { position: sticky; left: var(--freeze-left-2, 0px); will-change: transform; }
#dataTable.freeze-cols th:nth-child(4), #dataTable.freeze-cols td:nth-child(4) { position: sticky; left: var(--freeze-left-3, 0px); will-change: transform; }
/* Higher than the general sticky-header rule's z-index:4 (below) on
   purpose: a frozen header cell and a non-frozen one both being
   position:sticky with EQUAL z-index means whichever comes later in the
   DOM wins any overlap -- and a non-frozen column later in the row (e.g.
   Division, right after PO Number) legitimately slides left, underneath
   the frozen block, as the table scrolls. Without a strictly higher
   z-index here, that later column painted OVER the frozen one instead of
   the other way around, making the frozen column's header text vanish
   mid-scroll. */
#dataTable.freeze-cols th:nth-child(-n+4) { z-index: 5; background: var(--brand-dark); }
#dataTable.freeze-cols td:nth-child(-n+4) { z-index: 2; background: var(--surface-bg); }
/* Visual seam only on the last frozen column, marking where the frozen
   region ends and the horizontally-scrolling columns begin. */
#dataTable.freeze-cols th:nth-child(4), #dataTable.freeze-cols td:nth-child(4) { box-shadow: 1px 0 0 var(--surface-border); }
#dataTable.freeze-cols tbody tr:nth-child(even) td:nth-child(-n+4) { background: var(--surface-alt); }
#dataTable.freeze-cols tbody tr:hover td:nth-child(-n+4) { background: var(--link-tint); }
/* Same overlap issue as the header row's z-index:5 above, and the same
   fix -- a frozen filter-row cell must outrank a non-frozen one (the
   general .table-scroll-full tr.filter-row td rule gives every filter
   cell z-index:4) or it loses the paint order to whichever non-frozen
   column has scrolled underneath it. */
#dataTable.freeze-cols tr.filter-row td:nth-child(-n+4) { z-index: 5; background: var(--surface-alt); }

/* ---------- Report pages (report_*.php) ---------- */
.report-filters { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 16px; margin-bottom: 14px; }
.report-filters .field-inline { margin: 0; }
.report-filters label { font-size: 0.8rem; color: var(--text-muted); margin-bottom: 3px; }
.report-filters select, .report-filters input { width: auto; padding: 6px 8px; }
.report-filters .btn-save, .report-filters .btn-cancel { padding: 7px 14px; }

/* Open PO Aging: how long a PO's been sitting outstanding */
tr.aging-warn td { background: #fff6e0; }
tr.aging-critical td { background: #fdecea; }
.aging-swatch { display: inline-block; width: 12px; height: 12px; border-radius: 2px; vertical-align: middle; margin-right: 4px; }
.aging-swatch.aging-warn { background: #fff6e0; border: 1px solid #e6c568; }
.aging-swatch.aging-critical { background: #fdecea; border: 1px solid #f5c2c0; }

/* Job Cost Summary: grand-total footer row */
.report-totals-row td { border-top: 2px solid var(--link); background: var(--link-tint); font-weight: 600; }

/* Report charts -- collapsed by default (<details>, native/no-JS-required
   toggle) so the table gets the full page by default; same card look as the
   home page's .home-card, auto-fit grid so charts wrap to their own row on
   a narrow screen with no separate breakpoint needed. */
.chart-collapsible {
    margin-bottom: 1.5rem;
    border: 1px solid var(--surface-border);
    border-radius: 6px;
    background: var(--surface-bg);
}
.chart-collapsible summary {
    cursor: pointer;
    padding: 0.7rem 1rem;
    font-weight: 600;
    color: var(--heading-text);
    list-style: none;
    display: flex;
    align-items: center;
    gap: 8px;
    user-select: none;
}
.chart-collapsible summary::-webkit-details-marker { display: none; }
.chart-collapsible summary::before {
    content: '\25B6';
    font-size: 0.7em;
    color: var(--text-muted);
    transition: transform 0.15s ease;
}
.chart-collapsible[open] summary::before { transform: rotate(90deg); }
.chart-collapsible summary:hover { background: var(--surface-alt); }
.chart-collapsible .chart-row {
    margin: 0;
    padding: 0 1rem 1rem;
    border-top: 1px solid var(--surface-border);
    padding-top: 1rem;
}
.chart-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 1.25rem;
    margin-bottom: 1.5rem;
}
.chart-card {
    background: var(--surface-bg);
    border: 1px solid var(--surface-border);
    border-top: 3px solid var(--accent);
    border-radius: 6px;
    padding: 1rem 1.2rem 1.2rem;
    box-shadow: 0 2px 8px rgba(0,0,0,0.04);
}
.chart-card h3 { margin: 0 0 0.75rem; font-size: 0.95rem; color: var(--heading-text); }
.chart-card canvas { max-height: 260px; }

/* ---------- Resizable columns (Excel-style drag handles) ---------- */
#dataTable, #deletedTable { table-layout: fixed; }
#dataTable th, #dataTable td, #deletedTable th, #deletedTable td {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
#dataTable th, #deletedTable th { position: relative; }
.col-resize-handle {
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    width: 6px;
    cursor: col-resize;
    z-index: 5;
}
.col-resize-handle:hover { background: rgba(255,255,255,0.35); }
body.col-resizing { cursor: col-resize; user-select: none; }
body.col-resizing .col-resize-handle { background: rgba(255,255,255,0.5); }

/* Let the main data table (and its header row) use the full page width instead
   of the 800px cap that suits the narrower admin tables.
   (Compound class selectors so this reliably wins over .table-header/.table-scroll
   below regardless of source order.) */
.table-header.table-header-full, .table-scroll.table-scroll-full { max-width: none; }

.btn-edit, .btn-delete {
    display: inline-block; padding: 5px 12px; font-size: 0.85rem; color: #fff;
    border: none; border-radius: 4px; text-decoration: none; cursor: pointer;
}
.btn-edit { background: var(--link); }
.btn-edit:hover { background: var(--link-hover); }
.btn-delete { background: #a83232; }
.btn-delete:hover { background: #832626; }
.delete-form { margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid var(--surface-border); }
.delete-form .btn-delete { padding: 8px 16px; font-size: 0.95rem; }

.table-header {
    display: flex; justify-content: space-between; align-items: center;
    gap: 1rem; max-width: 800px; margin-bottom: 0.75rem;
}
.table-header h2 { margin: 0; }
.header-actions { display: flex; align-items: center; gap: 10px; }
.btn-add {
    display: inline-block; padding: 8px 14px; background: #1e7e34; color: #fff;
    text-decoration: none; border-radius: 4px; font-size: 0.9rem; white-space: nowrap;
}
.btn-add:hover { background: #17652a; }
#searchBox {
    padding: 8px 12px; font-size: 0.95rem; border: 1px solid var(--input-border);
    border-radius: 4px; width: 240px; max-width: 100%;
    background: var(--surface-bg); color: var(--page-text);
}
#searchBox:focus { outline: none; border-color: var(--link); box-shadow: 0 0 0 2px var(--link-focus-ring); }

.flash-success {
    max-width: 800px; margin-bottom: 1rem; padding: 10px 14px; background: #e6f6ec;
    border: 1px solid #b7e4c7; color: #1e7e34; border-radius: 4px;
}
.flash-info {
    max-width: 800px; margin-bottom: 1rem; padding: 10px 14px; background: var(--link-tint);
    border: 1px solid var(--link-on-dark); color: var(--link-hover); border-radius: 4px;
}

/* Live record-count/totals bar above a filterable table -- updated by JS
   (table-interactions.js) as filters/search narrow what's visible. */
.table-status-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
    align-items: center;
    padding: 10px 14px;
    margin-bottom: 14px;
    background: var(--link-tint);
    border: 1px solid var(--link-on-dark);
    border-radius: 4px;
    font-size: 0.9rem;
}
.table-status-bar .stat-label { color: var(--text-muted); margin-right: 4px; }
.table-status-bar .stat-value { font-weight: 600; color: var(--heading-text); font-variant-numeric: tabular-nums; }

/* ---------- Forms (add/edit/login) ---------- */
.form-card { max-width: 480px; }
.field { margin-bottom: 1rem; }
label { display: block; margin-bottom: 4px; font-weight: bold; }
input[type="text"], input[type="password"], input[type="email"], input[type="number"], select, textarea {
    width: 100%; box-sizing: border-box; padding: 8px 10px;
    border: 1px solid var(--input-border); border-radius: 4px; font-size: 0.95rem;
    font-family: inherit;
    background: var(--surface-bg); color: var(--page-text);
}
textarea { resize: vertical; }

.phase-code-toolbar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 8px; }
.phase-code-toolbar select { width: auto; padding: 6px 8px; }
.phase-code-toolbar button { padding: 6px 12px; font-size: 0.85rem; }
/* Generic scrollable checkbox list box (phase codes on job_form.php, jobs on user_form.php) */
.checklist-box {
    max-height: 220px; overflow-y: auto; border: 1px solid var(--surface-border); border-radius: 4px;
    padding: 10px 12px; background: var(--surface-alt);
}
.readonly-field { padding: 8px 10px; background: var(--surface-alt); border: 1px solid var(--surface-border); border-radius: 4px; color: var(--text-muted); }
.actions { margin-top: 1.5rem; display: flex; gap: 10px; }
.btn-save {
    padding: 8px 16px; background: var(--link); color: #fff; border: none;
    border-radius: 4px; cursor: pointer; font-size: 0.95rem;
}
.btn-save:hover { background: var(--link-hover); }
.btn-cancel { padding: 8px 16px; background: var(--surface-alt); color: var(--page-text); text-decoration: none; border-radius: 4px; font-size: 0.95rem; }
/* Export Excel/PDF buttons -- distinct from the neutral .btn-cancel look
   they otherwise share (a plain Cancel action), and forced onto one line
   so "Export Excel"/"Export PDF" don't wrap into two short, hard-to-read
   lines inside their own button. */
.export-link { background: var(--accent); color: #fff; white-space: nowrap; }
.export-link:hover { background: color-mix(in srgb, var(--accent) 80%, black); }
.errors {
    margin-bottom: 1rem; padding: 10px 14px; background: #fdecea;
    border: 1px solid #f5c2c0; color: #a83232; border-radius: 4px; max-width: 480px;
}
.errors ul { margin: 0; padding-left: 1.2rem; }
.field-hint { font-size: 0.8rem; color: var(--text-muted); margin-top: 4px; }

/* ---------- Add PO: quote upload widget ---------- */
.quote-upload-box {
    max-width: 480px; margin-bottom: 1.5rem; padding: 12px 14px;
    border: 1px solid var(--surface-border); border-radius: 6px; background: var(--surface-bg);
}
.quote-upload-box .field-hint { margin: 4px 0 10px; }
.quote-upload-box input[type="file"] { display: block; margin-bottom: 8px; }
.quote-upload-banner {
    margin-top: 10px; padding: 8px 12px; border-radius: 4px; font-size: 0.85rem;
    background: #e9f6ec; border: 1px solid #bfe4c8; color: #2c6b3a;
}
.quote-upload-banner.has-warnings { background: #fff6e0; border-color: #f0d888; color: #8a6a10; }
.quote-upload-banner ul { margin: 4px 0 0; padding-left: 1.1rem; }

/* ---------- Drag-and-drop file upload zones (Add PO quote, Edit PO documents) ---------- */
.drop-zone {
    border: 2px dashed var(--input-border); border-radius: 6px; padding: 10px;
    cursor: pointer; transition: background-color 0.15s, border-color 0.15s;
}
.drop-zone-active {
    background: var(--link-tint, #eef4fb); border-color: var(--link, #0056b3);
}
.drop-zone-hint { font-size: 0.8rem; color: var(--text-muted); margin: 0 0 6px; }

/* ---------- Add/Edit PO: wider page + two-column field layout ---------- */
/* Scoped to add.php/edit.php only (via the .add-page/.edit-page wrapper) --
   other forms (login, My Account, etc.) keep the narrower single-column
   .form-card width, which still suits a short field list better. */
.add-page .form-card, .edit-page .form-card { max-width: 1100px; }
.field-grid {
    display: grid; grid-template-columns: 1fr; gap: 0 24px;
}
@media (min-width: 700px) {
    .field-grid { grid-template-columns: 1fr 1fr; }
}
.field-grid .field-full { grid-column: 1 / -1; }

/* Document upload sub-form: proper spacing between label/control pairs
   (previously bare <label>/<select>/<input> with no wrapping .field divs,
   which is why it looked bunched together with no breathing room), and a
   capped width so the Document Type dropdown doesn't stretch edge-to-edge
   on the wider card. */
.document-upload-form { max-width: 480px; }
.document-upload-form select { max-width: 280px; }
.document-upload-form .actions { margin-top: 0.5rem; }

button:disabled, .btn-save:disabled {
    background: var(--surface-alt); color: var(--text-muted);
    cursor: not-allowed; border: 1px solid var(--surface-border);
}

/* Attached Documents / Change History tables: reuse the same list-page
   table look (assets/style.css "Tables (list pages)" above), just letting
   it fill the wider card instead of staying capped at 800px, and bounding
   height with its own scrollbar once a record accumulates a long history --
   the same purpose the old .change-history ul's max-height served. */
.form-card .scrollable-table-wrap { max-height: 360px; overflow-y: auto; overflow-x: auto; }
.form-card table { max-width: none; }
.form-card td.col-actions { white-space: nowrap; text-align: right; }
.form-card td.col-actions form { display: inline; }
.form-card td.col-actions .btn-delete { padding: 4px 10px; font-size: 0.8rem; }

.change-history { list-style: none; margin: 0; padding: 0; max-height: 320px; overflow-y: auto; }
.change-history li { padding: 8px 0; border-bottom: 1px solid var(--surface-border); font-size: 0.9rem; }
.change-history li:last-child { border-bottom: none; }

/* ---------- Login page (no nav present) ---------- */
.login-wrap {
    position: relative;
    min-height: 100vh;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1.75rem;
    padding: 2rem 1rem 5rem;
    background: linear-gradient(135deg, var(--brand-dark) 0%, var(--brand-dark-mid) 60%, var(--brand-dark-soft) 100%);
}
.login-brand { width: 100%; max-width: 320px; text-align: center; }
.login-brand .home-hero-tagline { font-size: 0.85rem; }
.login-card {
    background: #fff;
    color: #222;
    padding: 2rem 2.25rem 2.25rem;
    border-radius: 10px;
    box-shadow: 0 20px 50px rgba(0,0,0,0.35);
    width: 100%;
    max-width: 340px;
    box-sizing: border-box;
    animation: login-rise 0.5s ease-out 0.2s both;
}
.login-card h1 { margin: 0; font-size: 1.35rem; color: var(--brand-dark); }
.login-sub { margin: 4px 0 1.5rem; font-size: 0.85rem; color: #777; }
.login-card label { color: #222; }
.login-card input { background: #fff; color: #222; }
.input-icon { position: relative; }
.input-icon .icon { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: #8a94a0; pointer-events: none; }
.input-icon input { padding-left: 38px; }
.input-icon input:focus { outline: none; border-color: var(--link); box-shadow: 0 0 0 3px var(--link-focus-ring); }
.btn-login { width: 100%; display: inline-flex; align-items: center; justify-content: center; gap: 8px; padding: 10px 16px; }
.login-pipeline { position: absolute; left: 0; bottom: 24px; opacity: 0.85; }
@keyframes login-rise {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
    .login-card { animation: none; }
}

/* ---------- Simple checkbox grid (menu permission editor) ---------- */
.perm-grid { border-collapse: collapse; max-width: 640px; }
.perm-grid th, .perm-grid td { border: 1px solid var(--input-border); padding: 8px 10px; text-align: center; }
.perm-grid td:first-child, .perm-grid th:first-child { text-align: left; }
.perm-grid td.submenu-row { padding-left: 24px; text-align: left; color: var(--text-muted); }
/* .perm-grid th keeps the generic dark th background — .field-hint's grey
   would be nearly invisible there, so this note gets a light color instead */
.perm-grid-note { font-weight: normal; font-size: 0.75rem; color: var(--link-on-dark); }
.perm-grid input[type="checkbox"]:disabled { cursor: not-allowed; }

/* ---------- Mobile responsiveness ---------- */
/* Lets a wide table scroll horizontally within its own box instead of
   overflowing the whole page (or getting squeezed unreadably). */
.table-scroll {
    max-width: 800px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}
.table-scroll table { max-width: none; }

/* Bounded height + its own vertical scrollbar, paired with a sticky header
   (and, where present, filter) row below -- without this, a long table's
   horizontal scrollbar sits at the very bottom of however many rows there
   are, which can mean scrolling most of the way down the page just to pan
   sideways, and the header scrolls out of view long before that. Only the
   "full" (wide report/log) tables get this -- the app's few narrow,
   short admin tables don't need it. */
.table-scroll-full {
    max-height: 70vh;
    overflow-y: auto;
}
/* Same reason as .freeze-cols's own overflow override above: the base
   `table` rule's overflow:hidden would confine position:sticky to the
   table's own (non-scrolling) box instead of the real scrolling wrapper
   around it, silently breaking every sticky rule below for any table in a
   bounded-height wrapper, not just the PO Log. */
.table-scroll-full table { overflow: visible; }
.table-scroll-full thead tr:first-child th {
    position: sticky;
    top: 0;
    z-index: 4;
    will-change: transform;
}
/* ID-scoped so these outrank `#dataTable th, #deletedTable th { position:
   relative; }` (for the resize-handle's absolute positioning) -- a class
   selector alone loses to an ID selector regardless of source order, same
   issue already hit once for .freeze-cols above. The two report pages'
   tables have no id, so the plain class rule above already wins there
   without needing this. */
#dataTable thead tr:first-child th, #deletedTable thead tr:first-child th {
    position: sticky;
    top: 0;
    z-index: 4;
    will-change: transform;
}
/* Sits directly below the header row -- see table-interactions.js's
   header-row-height measurement, which measures the header row's real
   rendered height (font size, padding, wrapping can all vary it) rather
   than guessing a fixed pixel value. Falls back to a reasonable default
   for the two report pages that don't run that script (they have no
   filter row of their own, so this rule simply never matches there). */
.table-scroll-full tr.filter-row td {
    position: sticky;
    top: var(--header-row-height, 42px);
    z-index: 4;
    will-change: transform;
}
.perm-grid-wrap { max-width: 640px; }
.perm-grid-wrap table { max-width: none; }

@media (max-width: 700px) {
    .page-content { margin: 1rem; }

    /* Stack the title / search box / add button instead of squeezing them into one row */
    .table-header {
        flex-wrap: wrap;
        align-items: stretch;
    }
    .header-actions {
        width: 100%;
        flex-wrap: wrap;
    }
    #searchBox {
        flex: 1 1 auto;
        width: auto;
    }

    /* Filter-row inputs get cramped fast with many columns; shrink them a bit */
    tr.filter-row input {
        min-width: 90px;
        font-size: 0.85rem;
    }
    th, td { padding: 7px 9px; }
}

/* ---------- Home page ---------- */
.home-hero {
    position: relative;
    margin: -2rem -2rem 0;
    padding: 3.5rem 2rem 3rem;
    background: linear-gradient(135deg, var(--brand-dark) 0%, var(--brand-dark-mid) 60%, var(--brand-dark-soft) 100%);
    color: #fff;
    text-align: center;
    overflow: hidden;
}
.home-hero h1 {
    margin: 0;
    font-size: 2.2rem;
    letter-spacing: 0.02em;
}
.home-hero-tagline {
    margin: 10px 0 0;
    color: var(--link-on-dark);
    font-size: 1.05rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
}
/* Wipe-reveal + shine-sweep entrance for the home page logo, adapted from a
   standalone animation prototype (logo-animation.html) the user dropped in.
   The wrap does the clipping/reveal (clip-path starts fully collapsed and
   animates open); the image inside just fades/settles into place; the shine
   is a separate diagonal gradient layer that sweeps across once, after the
   reveal finishes. Plays once per page load -- there's no replay trigger on
   the live page (logo-animation.html's "reload to replay" note was
   demo-only scaffolding, not meant for production). */
.home-logo-wrap {
    position: relative;
    display: block;
    margin: 0 auto;
    max-width: 360px;
    width: 100%;
    border-radius: 4px;
    overflow: hidden;
    clip-path: inset(0 100% 0 0);
    box-shadow: 0 4px 16px rgba(0,0,0,0.35);
    animation: home-logo-wipe-in 1.1s cubic-bezier(.65,0,.35,1) 0.15s forwards;
}
.home-logo {
    display: block;
    width: 100%;
    height: auto;
    opacity: 0;
    transform: scale(1.03);
    animation: home-logo-settle 0.8s ease-out 0.15s forwards;
}
.home-logo-shine {
    position: absolute;
    top: -20%;
    left: -60%;
    width: 40%;
    height: 140%;
    background: linear-gradient(
        75deg,
        rgba(255,255,255,0) 0%,
        rgba(255,255,255,0.55) 50%,
        rgba(255,255,255,0) 100%
    );
    transform: skewX(-20deg);
    opacity: 0;
    animation: home-logo-sweep 1.3s ease-in-out 1.4s 1;
}
@keyframes home-logo-wipe-in {
    to { clip-path: inset(0 0% 0 0); }
}
@keyframes home-logo-settle {
    to { opacity: 1; transform: scale(1); }
}
@keyframes home-logo-sweep {
    0%   { opacity: 0; left: -60%; }
    15%  { opacity: 1; }
    55%  { opacity: 1; }
    100% { opacity: 0; left: 120%; }
}
@media (prefers-reduced-motion: reduce) {
    .home-logo-wrap, .home-logo, .home-logo-shine {
        animation: none !important;
        clip-path: none !important;
        opacity: 1 !important;
        transform: none !important;
    }
}

/* Simple decorative pipeline motif: a horizontal run with flange joints,
   standing in for the graphic the user will supply later. */
.home-pipeline {
    display: block;
    width: 100%;
    height: 28px;
}
.home-pipeline line { stroke: var(--accent); stroke-width: 3; }
.home-pipeline circle { fill: var(--brand-dark); stroke: var(--accent); stroke-width: 3; }

/* ---------- Home-page module dashboards (includes/po_dashboard.php and,
   eventually, one per future module -- see the project-growth-vision memory) ---------- */
.dashboard-section { margin-top: 2rem; }
.dashboard-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem; }
.dashboard-header h2 { margin: 0; color: var(--heading-text); }

.stat-tile-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 1rem;
    margin-bottom: 1.5rem;
}
.stat-tile {
    background: var(--surface-bg);
    border: 1px solid var(--surface-border);
    border-top: 3px solid var(--link);
    border-radius: 6px;
    padding: 1rem 1.2rem;
    box-shadow: 0 2px 8px rgba(0,0,0,0.04);
}
.stat-tile.stat-tile-alert { border-top-color: #d03b3b; }
.stat-tile-value { font-size: 1.7rem; font-weight: 700; color: var(--heading-text); font-variant-numeric: tabular-nums; }
.stat-tile-label { font-size: 0.82rem; color: var(--text-muted); margin-top: 4px; }

.dashboard-section .chart-row { margin-bottom: 1.5rem; }
.dashboard-more-link { display: inline-block; margin-top: 8px; font-size: 0.8rem; color: var(--link); text-decoration: none; }
.dashboard-more-link:hover { text-decoration: underline; }

.dashboard-activity-list { list-style: none; margin: 0; padding: 0; font-size: 0.82rem; }
.dashboard-activity-list li { padding: 6px 0; border-bottom: 1px solid var(--surface-border); line-height: 1.5; }
.dashboard-activity-list li:last-child { border-bottom: none; }
.dashboard-activity-list .activity-by { color: var(--text-muted); }
.dashboard-activity-empty { color: var(--text-muted); font-style: italic; font-size: 0.85rem; }

.dashboard-section h3 { margin: 0 0 0.75rem; font-size: 1rem; color: var(--heading-text); }
.your-jobs-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 1rem;
}
.your-job-card {
    background: var(--surface-bg);
    border: 1px solid var(--surface-border);
    border-top: 3px solid var(--accent);
    border-radius: 6px;
    padding: 1rem 1.2rem;
    box-shadow: 0 2px 8px rgba(0,0,0,0.04);
}
.your-job-card h4 { margin: 0 0 2px; font-size: 1rem; color: var(--heading-text); }
.your-job-card .job-desc { font-size: 0.8rem; color: var(--text-muted); margin-bottom: 8px; }
.your-job-card .job-stats { display: flex; gap: 0.9rem; font-size: 0.82rem; color: var(--page-text); flex-wrap: wrap; }

.home-links {
    margin-top: 2rem;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 1.25rem;
}
.home-card {
    background: var(--surface-bg);
    border: 1px solid var(--surface-border);
    border-top: 3px solid var(--accent);
    border-radius: 6px;
    padding: 1.1rem 1.3rem 1.3rem;
    box-shadow: 0 2px 8px rgba(0,0,0,0.04);
}
.home-card h2 {
    margin: 0 0 0.6rem;
    font-size: 1.05rem;
    color: var(--heading-text);
}
.home-card ul { list-style: none; margin: 0; padding: 0; }
.home-card li { margin-bottom: 6px; }
.home-card a {
    display: block;
    padding: 6px 8px;
    border-radius: 4px;
    text-decoration: none;
    color: var(--link);
}
.home-card a:hover { background: var(--link-tint); color: var(--link-hover); }

@media (max-width: 700px) {
    .home-hero { margin: -1rem -1rem 0; padding: 2.5rem 1rem 2rem; }
    .home-hero h1 { font-size: 1.6rem; }
}

/* ---------- Help page ---------- */
/* HTML twin of the "Purchase Order Tracking System User Guide" PDF -- see
   help.php. Kept in its own section since its styling (TOC, tip/note boxes,
   ADMIN badges, field tables) is specific to this one page. */
.help-page { max-width: 900px; }
.help-toc {
    background: var(--surface-alt);
    border: 1px solid var(--surface-border);
    border-radius: 6px;
    padding: 1.2rem 1.5rem;
    margin-bottom: 2rem;
}
.help-toc h2 { margin-top: 0; }
.help-toc ol { columns: 2; column-gap: 2rem; padding-left: 1.3rem; }
.help-toc li { break-inside: avoid; margin-bottom: 6px; }
.help-toc a { text-decoration: none; }
.help-toc a:hover { text-decoration: underline; }
@media (max-width: 700px) {
    .help-toc ol { columns: 1; }
}

.help-section { margin-bottom: 2.5rem; scroll-margin-top: 1rem; }
.help-section h2 {
    border-bottom: 2px solid var(--link);
    padding-bottom: 6px;
}
.help-section h3 {
    font-size: 1rem;
    color: var(--heading-text);
    background: var(--link-tint);
    padding: 6px 10px;
    border-left: 3px solid var(--accent);
    margin-top: 1.4rem;
}
.help-back-to-top { font-size: 0.8rem; margin-top: 0.5rem; }

.admin-only-badge {
    display: inline-block;
    font-size: 0.65rem;
    font-weight: bold;
    color: #fff;
    background: #6c4fa1;
    padding: 2px 7px;
    border-radius: 3px;
    margin-left: 6px;
    vertical-align: middle;
    letter-spacing: 0.03em;
}

.help-shot { text-align: center; margin: 14px 0; }
.help-shot img {
    max-width: 100%;
    border: 1px solid var(--input-border);
    border-radius: 4px;
}
.help-caption { text-align: center; font-size: 0.8rem; font-style: italic; color: var(--text-muted); margin: 6px 0 0; }

.help-tip, .help-note {
    border-left: 3px solid;
    padding: 8px 12px;
    margin: 12px 0;
    font-size: 0.88rem;
    border-radius: 0 4px 4px 0;
}
.help-tip { background: #eefaf0; border-color: #0ca30c; }
.help-tip strong { color: #0ca30c; }
.help-note { background: #fff8ea; border-color: #fab219; }
.help-note strong { color: #a9740a; }

table.help-fieldtable { border-collapse: collapse; width: 100%; margin: 10px 0; font-size: 0.88rem; }
table.help-fieldtable th { background: var(--brand-dark); color: #fff; text-align: left; padding: 6px 10px; }
table.help-fieldtable td { border-bottom: 1px solid var(--surface-border); padding: 6px 10px; vertical-align: top; }
table.help-fieldtable tr:nth-child(even) td { background: var(--surface-alt); }

/* ---------- My Account page (account.php) ---------- */
.account-section { max-width: 480px; margin-bottom: 2.5rem; }
.theme-options { display: flex; flex-direction: column; gap: 10px; margin-bottom: 1rem; }
.theme-options.mode-options { flex-direction: row; }
.mode-options .theme-option { flex: 1; justify-content: center; }
.theme-option {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 14px;
    border: 1px solid var(--surface-border);
    border-radius: 6px;
    cursor: pointer;
    font-weight: normal;
    margin: 0;
}
.theme-option:has(input:checked) { border-color: var(--link); background: var(--link-tint); }
.theme-option input[type="radio"] { margin: 0; }
.theme-swatch { display: flex; gap: 4px; }
.swatch-dot {
    display: inline-block;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    border: 1px solid rgba(0,0,0,0.15);
}

/* ---------- Visual polish: icons, status pills, elevation, hover-lift ---------- */
:root {
    --shadow-card: 0 1px 2px rgba(16, 24, 40, 0.06), 0 4px 12px rgba(16, 24, 40, 0.06);
    --shadow-card-hover: 0 2px 4px rgba(16, 24, 40, 0.08), 0 10px 24px rgba(16, 24, 40, 0.12);
}
html[data-mode="dark"] {
    --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.4), 0 4px 12px rgba(0, 0, 0, 0.35);
    --shadow-card-hover: 0 2px 4px rgba(0, 0, 0, 0.5), 0 10px 24px rgba(0, 0, 0, 0.5);
}

.icon { flex-shrink: 0; vertical-align: -3px; }
.nav-link .icon, .nav-toggle .icon { margin-right: 6px; opacity: 0.85; vertical-align: 0; }
.btn-add, .export-link, .btn-edit { display: inline-flex; align-items: center; gap: 6px; }
.btn-edit { gap: 4px; }

/* Status pills (PO Log Status / Received columns) */
.pill {
    display: inline-block; padding: 2px 10px; border-radius: 999px;
    font-size: 0.78rem; font-weight: 600; line-height: 1.5; white-space: nowrap;
}
.pill-open     { background: #e3f1e8; color: #1e6b34; }
.pill-closed   { background: #e8ebef; color: #56616d; }
.pill-inactive { background: #fff1d6; color: #8a5a00; }
.pill-yes      { background: #e3f1e8; color: #1e6b34; }
.pill-no       { background: #e8ebef; color: #56616d; }
html[data-mode="dark"] .pill-open, html[data-mode="dark"] .pill-yes { background: #1f3a2a; color: #7fd39a; }
html[data-mode="dark"] .pill-closed, html[data-mode="dark"] .pill-no { background: #2b333d; color: #a9b3be; }
html[data-mode="dark"] .pill-inactive { background: #3d3220; color: #f0c674; }

/* Elevation: one consistent soft shadow on every card-like surface */
.stat-tile, .your-job-card, .home-card, .chart-card { box-shadow: var(--shadow-card); }

/* Hover-lift on the clickable dashboard cards -- short and subtle so it
   reads as polish, not as something that slows anyone down. */
.your-job-card, .home-card, .stat-tile {
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.your-job-card:hover, .home-card:hover, .stat-tile:hover {
    transform: translateY(-2px); box-shadow: var(--shadow-card-hover);
}

/* Stat tiles: icon in the corner */
.stat-tile { position: relative; }
.stat-tile-icon {
    position: absolute; top: 0.9rem; right: 1rem; color: var(--link); opacity: 0.55;
    display: inline-flex;
}
.stat-tile.stat-tile-alert .stat-tile-icon { color: #d03b3b; opacity: 0.8; }

@media (prefers-reduced-motion: reduce) {
    .your-job-card, .home-card, .stat-tile { transition: none; }
    .your-job-card:hover, .home-card:hover, .stat-tile:hover { transform: none; }
}


/* ---------- Empty states ---------- */
.empty-state { text-align: center; padding: 1.5rem 1rem; color: var(--text-muted); font-style: normal; }
.empty-state-icon {
    display: inline-flex; align-items: center; justify-content: center;
    width: 52px; height: 52px; border-radius: 50%;
    background: var(--link-tint); color: var(--link); margin-bottom: 0.6rem;
}
.empty-state-title { font-weight: 600; color: var(--heading-text); font-size: 0.95rem; }
.empty-state-hint { font-size: 0.82rem; margin-top: 3px; }
tr.no-match:hover { background: var(--surface-bg); }

/* ---------- Toast notifications (see assets/toast.js) ---------- */
.toast-stack {
    position: fixed; bottom: 1.25rem; right: 1.25rem; z-index: 1000;
    display: flex; flex-direction: column; gap: 0.6rem; width: min(360px, calc(100vw - 2.5rem));
    pointer-events: none;
}
.toast-stack .flash-success {
    pointer-events: auto; display: flex; align-items: center; gap: 10px;
    max-width: none; margin: 0; padding: 12px 12px 12px 14px;
    background: var(--surface-bg); color: var(--page-text);
    border: 1px solid var(--surface-border); border-left: 4px solid #2e9e57; border-radius: 6px;
    box-shadow: 0 8px 24px rgba(16, 24, 40, 0.18);
    animation: toast-life 5s ease forwards;
}
.toast-stack .flash-success:hover { animation-play-state: paused; }
.toast-icon { display: inline-flex; color: #2e9e57; }
.toast-msg { flex: 1; font-size: 0.92rem; }
.toast-close {
    background: none; border: none; color: var(--text-muted); font-size: 1.3rem; line-height: 1;
    cursor: pointer; padding: 0 4px; border-radius: 4px;
}
.toast-close:hover { color: var(--page-text); background: var(--surface-alt); }
.js main .flash-success { display: none; }
@keyframes toast-life {
    0%   { opacity: 0; transform: translateX(40px); }
    6%   { opacity: 1; transform: translateX(0); }
    92%  { opacity: 1; transform: translateX(0); }
    100% { opacity: 0; transform: translateX(20px); }
}
@keyframes toast-life-fade {
    0%   { opacity: 0; }
    6%   { opacity: 1; }
    92%  { opacity: 1; }
    100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .toast-stack .flash-success { animation-name: toast-life-fade; }
}

/* ---------- "Filters active" flag + Clear filters (see assets/table-interactions.js) ---------- */
.table-status-bar.is-filtered {
    border-left: 4px solid var(--accent);
    background: color-mix(in srgb, var(--accent) 12%, var(--surface-bg));
}
.filter-flag {
    display: inline-block; padding: 2px 10px; border-radius: 999px;
    background: var(--accent); color: #fff; font-size: 0.78rem; font-weight: 700;
    white-space: nowrap;
}
.btn-clear-filters { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.btn-clear-filters[hidden], .filter-flag[hidden] { display: none; }

/* ---------- Motion: dropdown panels (Columns, per-column filters) ---------- */
.dropdown-panel { animation: panel-in 0.22s cubic-bezier(.2,.8,.3,1); transform-origin: top left; }
@keyframes panel-in {
    from { opacity: 0; transform: translateY(-10px) scale(0.97); }
    to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
    .submenu, .nav-caret, tbody td { transition: none; }
    .dropdown-panel { animation: none; }
}

/* List pages that have outgrown the default 800px cap (Manage Users, since its
   Email column was added): without this the wrapper scrolls sideways and the
   Actions column's Delete button sat hidden off the right edge. */
.table-header.wide, .table-scroll.wide { max-width: 1100px; }
.table-scroll.wide td:last-child { white-space: nowrap; }

/* Inline document-type dropdown in the Attached Documents table (changing it saves immediately) */
.doc-type-form { margin: 0; }
.doc-type-select { width: auto; padding: 4px 8px; font-size: 0.9rem; }


/* ---------- Fleet / Employees ---------- */
input[type="date"] {
    width: 100%; box-sizing: border-box; padding: 8px 10px;
    border: 1px solid var(--input-border); border-radius: 4px; font-size: 0.95rem; font-family: inherit;
    background: var(--surface-bg); color: var(--page-text);
}
.pill-v-active { background: #e3f1e8; color: #1e6b34; }
.pill-v-in_shop { background: #fff1d6; color: #8a5a00; }
.pill-v-out_of_service { background: #fbe3e0; color: #a83232; }
.pill-v-sold, .pill-v-scrapped, .pill-v-returned { background: #e8ebef; color: #56616d; }
.pill-overdue { background: #fbe3e0; color: #a83232; }
.pill-soon { background: #fff1d6; color: #8a5a00; }
.pill-ok { background: transparent; color: var(--page-text); font-weight: 400; padding-left: 0; padding-right: 0; }
html[data-mode="dark"] .pill-v-active { background: #1f3a2a; color: #7fd39a; }
html[data-mode="dark"] .pill-v-in_shop, html[data-mode="dark"] .pill-soon { background: #3d3220; color: #f0c674; }
html[data-mode="dark"] .pill-v-out_of_service, html[data-mode="dark"] .pill-overdue { background: #402424; color: #f1a1a1; }
html[data-mode="dark"] .pill-v-sold, html[data-mode="dark"] .pill-v-scrapped, html[data-mode="dark"] .pill-v-returned { background: #2b333d; color: #a9b3be; }

.form-section-title { margin: 1.5rem 0 0.75rem; padding-bottom: 6px; border-bottom: 1px solid var(--surface-border); font-size: 1.05rem; color: var(--heading-text); }
.form-section-title:first-of-type { margin-top: 0.5rem; }
.field-grid-3 { display: grid; grid-template-columns: 1fr; gap: 0 24px; }
@media (min-width: 900px) { .field-grid-3 { grid-template-columns: 1fr 1fr 1fr; } }
.readonly-note { font-size: 0.85rem; color: var(--text-muted); }
.stack-cards { display: grid; gap: 1.25rem; }
.card-head { display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap; }
.card-head h2, .card-head h3 { margin: 0; }
.kv-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 12px 24px; margin: 0; }
.kv-grid dt { font-size: 0.78rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.03em; }
.kv-grid dd { margin: 2px 0 0; font-weight: 600; word-break: break-word; }
.inline-form { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; }
.inline-form .field { margin: 0; }
.inline-form input, .inline-form select { width: auto; min-width: 140px; }
.camera-btn { display: none; cursor: pointer; }
@media (pointer: coarse) { .camera-btn { display: inline-block; } }


.vin-box { max-width: 760px; }
.vin-box .drop-zone input[type="file"] { display: inline-block; }
.ai-filled { background: var(--link-tint) !important; transition: background-color 0.3s; }
[hidden] { display: none !important; }


/* The nav bar has a fixed height, so it must never wrap: the role list next to
   the username is what grows without bound (Admin holds every role), so it is
   truncated (full list stays available as a tooltip) and dropped entirely on
   narrower screens. */
.nav-role { display: inline-block; max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }
.nav-username { white-space: nowrap; }
@media (max-width: 1500px) { .nav-role { display: none; } }
.nav-brand, .nav-menu, .nav-user { flex-wrap: nowrap; }
.inline-check { display: inline-flex; align-items: center; gap: 6px; font-weight: normal; margin: 0; white-space: nowrap; }

/* A menu hidden via menu_visibility.php: only an Admin ever has one of these
   in their nav tree (everyone else's menu query already excludes it), so
   this only ever paints for Admin -- amber to flag "hidden from everyone
   else" without looking like an error or a coming-due warning. */
.nav-item.nav-hidden-from-others > .nav-link,
.nav-item.nav-hidden-from-others > .nav-toggle,
a.submenu-link.nav-hidden-from-others {
    color: #f0c674;
}
.nav-item.nav-hidden-from-others > .nav-link:hover,
.nav-item.nav-hidden-from-others > .nav-toggle:hover,
a.submenu-link.nav-hidden-from-others:hover {
    color: #fff;
}
/* Always-visible reminder of which environment you're looking at -- see
   currentEnvLabel() in includes/env.php. LIVE is red on purpose: it should
   read as "handle with care, this is the real site," not blend in. */
.env-badge {
    display: inline-block;
    font-size: 0.72rem;
    font-weight: bold;
    letter-spacing: 0.06em;
    padding: 3px 10px;
    border-radius: 4px;
    margin-left: 10px;
    vertical-align: middle;
    text-transform: uppercase;
}
.env-badge-live { background: #c0392b; color: #fff; }
.env-badge-demo { background: #5a6b7d; color: #fff; }
.env-badge-login {
    position: fixed;
    top: 14px;
    right: 14px;
    margin-left: 0;
    font-size: 0.8rem;
    padding: 5px 14px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.25);
    z-index: 50;
}

.nav-hidden-badge {
    display: inline-block;
    font-size: 0.62rem;
    font-weight: bold;
    color: #3a2c00;
    background: #f0c674;
    padding: 1px 6px;
    border-radius: 3px;
    margin-left: 6px;
    vertical-align: middle;
    letter-spacing: 0.03em;
}
.inline-check input { width: auto; }
.inline-form .field:has(.inline-check) { align-self: center; margin-bottom: 8px; }


/* A maintenance schedule can run to 16+ rows; the shared 360px scroll box would clip it. */
.form-card .scrollable-table-wrap.tall { max-height: none; overflow-y: visible; }
.inline-form input[type="checkbox"], .inline-form input[type="radio"] { min-width: 0; }


table.coming-due { max-width: none; border: none; border-radius: 0; }
table.coming-due th { background: transparent; color: var(--text-muted); border-bottom: 1px solid var(--surface-border); font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.03em; }
table.coming-due td, table.coming-due th { border-right: none; }
table.coming-due tbody tr:nth-child(even) { background: transparent; }
table.coming-due .icon { color: var(--text-muted); margin-right: 4px; }

.pill-ok { font-size: inherit; line-height: inherit; }
