/* ============================================================
   PRQ — Base Styles (Bar-All brand)

   Colors + fonts per the official Bar-All brand sheet
   (Branding/Bar-All_Inc_Branding.pdf):
     - PMS 2736C #162da7  — primary blue
     - PMS Cool Gray 6C #a8a8aa  — brand gray
     - Berthold Akzidenz-Grotesk BE Bold Extended (display)
     - Helvetica Light (body)

   Both brand fonts are commercial-license. We prefer them in the
   stack (so Mac/Windows users with Helvetica Neue installed see
   the real thing) and fall back to Montserrat + Inter (both on
   Google Fonts, already used by barallinc.com) when the licensed
   faces aren't available.

   Typography still hybrid:
     - --font-display for headings + brand
     - --font-body for UI chrome, forms, body copy
     - --font-mono retained for tabular data
       (.mono, code, kbd, pre, .status-badge, tbody td)
   ============================================================ */

@import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&family=Montserrat:wght@500;700;800;900&family=PT+Mono&display=swap");

/* ---------- Design Tokens (Light mode default) ---------- */
:root {
    /* Fonts — prefer Berthold Akzidenz / Helvetica when licensed, fall
       through to the Google-Fonts substitutes used by barallinc.com. */
    --font-display: "Akzidenz-Grotesk BE", "Akzidenz-Grotesk", "Helvetica Neue", Montserrat, Arial, sans-serif;
    --font-body: "Helvetica Neue", Helvetica, Inter, Arial, sans-serif;
    --font-mono: "PT Mono", "Courier New", "SF Mono", monospace;
    /* Back-compat alias so any stragglers still resolve. Prefer --font-body. */
    --font-family: var(--font-body);
    --font-size-base: 14px;
    --font-size-small: 12px;
    --font-size-h3: 16px;
    --font-size-h2: 20px;
    --font-size-h1: 24px;
    --font-weight-light: 300; /* Helvetica Light spec weight */
    --font-weight-normal: 400;
    --font-weight-medium: 500;
    --font-weight-bold: 600;
    --font-weight-heading: 700;
    --line-height-body: 1.5;
    --line-height-heading: 1.25;

    /* Bar-All palette — official values from the brand PDF. */
    --bg-primary: #ffffff;
    --bg-secondary: #f8fafc; /* slate-50 — UI neutral, not brand */
    --bg-sidebar: #f1f5f9;   /* slate-100 — UI neutral, separates sidebar from page */
    --text-primary: #0f172a; /* slate-900 — near-black (brand PMS Black is #000 but pure black is harsh on screens) */
    --text-muted: #64748b;   /* slate-500 — UI muted. Brand spec is #a8a8aa, reserved for brand-critical gray (see --brand-gray) */
    --border: #e2e8f0;       /* slate-200 */
    --accent: #162da7;       /* PMS 2736C — Bar-All primary blue */
    --accent-hover: #0e1f7a; /* ~15% darker for hover states */
    --accent-soft: #e3e7fa;  /* tinted background for active nav, callouts */
    --brand-gray: #a8a8aa;   /* PMS Cool Gray 6C — brand-specific usage (logo, tagline) */
    --success: #16a34a;
    --success-hover: #15803d; /* ~15% darker for filled-button hover (mirrors --accent-hover) */
    --warning: #ca8a04;
    --error: #dc2626;
    --info: #162da7;         /* reuse accent — single-blue system */
    --focus-ring: #162da7;

    /* Spacing */
    --spacing-xs: 4px;
    --spacing-sm: 8px;
    --spacing-md: 12px;
    --spacing-lg: 16px;
    --spacing-xl: 24px;
    --spacing-2xl: 32px;
    --spacing-3xl: 48px;

    /* Radii. 0.5rem matches the Bar-All site; buttons + inputs at 6px. */
    --radius: 6px;
    --radius-pill: 9999px;
}

/* ---------- Dark mode tokens ---------- */
@media (prefers-color-scheme: dark) {
    :root {
        --bg-primary: #0f172a; /* slate-900 */
        --bg-secondary: #1e293b; /* slate-800 */
        --bg-sidebar: #1e293b;
        --text-primary: #f8fafc;
        --text-muted: #94a3b8; /* slate-400 */
        --border: #334155;     /* slate-700 */
        /* Lift the blue in dark mode for contrast against the slate bg. */
        --accent: #6366f1;     /* indigo-500 */
        --accent-hover: #818cf8; /* indigo-400 */
        --accent-soft: #1e1b4b; /* indigo-950 tint */
        --success: #22c55e;
        --success-hover: #4ade80; /* lighter in dark mode, mirror of --accent-hover lift */
        --warning: #eab308;
        --error: #ef4444;
        --info: #6366f1;
        --focus-ring: #6366f1;
    }
}

/* ---------- Reset & base ---------- */
*,
*::before,
*::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html {
    font-size: var(--font-size-base);
    line-height: var(--line-height-body);
}

body {
    font-family: var(--font-body);
    font-weight: var(--font-weight-normal);
    min-height: 100vh;
    background: var(--bg-primary);
    color: var(--text-primary);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* ---------- Links ---------- */
a {
    color: var(--accent);
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}

/* ---------- Typography ---------- */
h1,
h2,
h3,
h4,
h5,
h6 {
    font-family: var(--font-display);
    font-weight: var(--font-weight-heading);
    line-height: var(--line-height-heading);
    letter-spacing: -0.01em;
}

h1 {
    font-size: var(--font-size-h1);
    font-weight: 800;
}

h2 {
    font-size: var(--font-size-h2);
    font-weight: 700;
}

h3 {
    font-size: var(--font-size-h3);
    font-weight: 700;
}

small,
.text-muted {
    font-size: var(--font-size-small);
    color: var(--text-muted);
}

/* PT Mono is reserved for character-grid data. Apply to any cell that
   benefits from column-alignment: IDs, totals, quantities, timestamps,
   status-badge text. */
.mono,
code,
kbd,
pre,
.status-badge,
table tbody td {
    font-family: var(--font-mono);
}

/* ---------- Layout helpers ---------- */
.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: var(--spacing-lg);
}

/* ---------- Sidebar layout ---------- */
.layout {
    display: flex;
    min-height: 100vh;
}

.sidebar {
    width: 260px;
    flex-shrink: 0;
    background: var(--bg-sidebar);
    border-right: 1px solid var(--border);
    padding: var(--spacing-lg) 0;
    overflow-y: auto;
}

/* Sidebar header / brand block. Padded to the same left-inset as the nav
   items below so the lockup visually aligns with the nav column. */
.sidebar-header {
    padding: 0 var(--spacing-lg);
    margin-bottom: var(--spacing-xl);
}

/* Hamburger toggle. Hidden by default; the mobile breakpoint below
   flips it on and rearranges .sidebar-header so the button sits beside
   the brand. JS in base.html toggles .sidebar.is-open on click. */
.sidebar-toggle {
    display: none;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--text-primary);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    transition: background-color 120ms ease, border-color 120ms ease;
}

.sidebar-toggle:hover {
    background: color-mix(in srgb, var(--text-muted) 8%, transparent);
    border-color: var(--text-muted);
}

.sidebar-toggle:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
}

.sidebar-header .brand {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--spacing-sm);
    text-decoration: none;
    color: var(--text-primary);
}

.sidebar-header .brand:hover {
    text-decoration: none;
}

/* Inline Bar-All stacked lockup. Fills are theme-driven so the wordmark
   can lighten in dark mode and the icon + INC bars pick up --accent
   (which itself shifts to a brighter indigo in dark mode). */
.brand-svg {
    display: block;
    width: 100%;
    max-width: 140px;
    height: auto;
}

.brand-svg .primary {
    fill: var(--accent);
}

.brand-svg .secondary {
    fill: var(--brand-gray);
}

@media (prefers-color-scheme: dark) {
    /* Brand gray (#a8a8aa) reads dim against slate-900. Lift the
       wordmark to a light slate so it stays legible. */
    .brand-svg .secondary {
        fill: #e2e8f0;
    }
}

/* App identifier under the lockup. Sized to visually balance with the
   lockup above; any smaller and it reads as a caption, any larger and
   it upstages the brand mark. Centered via the brand's flex column
   alignment above. */
.brand-app-label {
    font-family: var(--font-body);
    font-size: 16px;
    font-weight: 700;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--brand-gray);
}

@media (prefers-color-scheme: dark) {
    .brand-app-label {
        color: #94a3b8; /* slate-400 — same lift treatment as the wordmark */
    }
}

.main-content {
    flex: 1;
    padding: var(--spacing-xl);
    min-width: 0;
}

/* ---------- Buttons ---------- */
button,
.btn {
    font-family: var(--font-body);
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-medium);
    padding: var(--spacing-sm) var(--spacing-lg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-primary);
    color: var(--text-primary);
    cursor: pointer;
    transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
}

button:hover,
.btn:hover {
    background: var(--bg-secondary);
    border-color: color-mix(in srgb, var(--accent) 35%, var(--border));
}

button:focus-visible,
.btn:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
}

.btn-primary {
    border-color: var(--accent);
    background: var(--accent);
    color: #ffffff;
}

.btn-primary:hover {
    background: var(--accent-hover);
    border-color: var(--accent-hover);
    color: #ffffff;
}

/* ---------- Inputs ---------- */
input[type="text"],
input[type="email"],
input[type="password"],
input[type="number"],
input[type="date"],
select,
textarea {
    font-family: var(--font-body);
    font-size: var(--font-size-base);
    padding: var(--spacing-sm) var(--spacing-md);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-primary);
    color: var(--text-primary);
    width: 100%;
    transition: border-color 120ms ease, box-shadow 120ms ease;
}

input:focus,
select:focus,
textarea:focus {
    outline: none;
    border-color: var(--focus-ring);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--focus-ring) 18%, transparent);
}

label {
    display: block;
    font-family: var(--font-body);
    font-size: var(--font-size-small);
    font-weight: var(--font-weight-medium);
    color: var(--text-muted);
    margin-bottom: var(--spacing-xs);
}

.form-group {
    margin-bottom: var(--spacing-md);
}

.error-message {
    font-family: var(--font-body);
    font-size: var(--font-size-small);
    color: var(--error);
    margin-top: var(--spacing-xs);
    margin-bottom: var(--spacing-lg);
}

/* ---------- Cards / Panels ---------- */
.card {
    background: var(--bg-primary);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: var(--spacing-lg);
    margin-bottom: var(--spacing-lg);
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}

@media (prefers-color-scheme: dark) {
    .card {
        box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
    }
}

/* ---------- Tables ---------- */
table {
    width: 100%;
    border-collapse: collapse;
}

thead th {
    font-weight: var(--font-weight-bold);
    text-align: left;
    padding: var(--spacing-sm) var(--spacing-md);
    border-bottom: 1px solid var(--border);
}

table.sortable thead th[data-col] {
    cursor: pointer;
    user-select: none;
}

table.sortable thead th[data-col]:hover {
    background: color-mix(in srgb, var(--text-muted) 6%, transparent);
}

table.sortable .sort-indicator {
    display: inline-block;
    min-width: 1ch;
    color: var(--text-muted);
}

tbody td {
    padding: var(--spacing-sm) var(--spacing-md);
    border-bottom: 1px solid var(--border);
}

tbody tr:nth-child(even) {
    background: color-mix(in srgb, var(--text-muted) 3%, transparent);
}

tbody tr.row-clickable:hover {
    background: color-mix(in srgb, var(--text-muted) 8%, transparent);
    cursor: pointer;
}

/* Row-link cells render an anchor that fills the td so the whole cell
   is clickable, but the text stays unstyled (no blue / no underline). */
td > a.row-link {
    display: block;
    color: inherit;
    text-decoration: none;
    margin: calc(-1 * var(--spacing-sm)) calc(-1 * var(--spacing-md));
    padding: var(--spacing-sm) var(--spacing-md);
}

/* ---------- Focus visibility for accessibility ---------- */
*:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
}

/* ---------- Page header (title + action button) ---------- */
.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: var(--spacing-xl);
    gap: var(--spacing-md);
}

.page-header h1 {
    margin: 0;
}

/* ---------- Status badges ---------- */
.status-badge {
    display: inline-block;
    padding: var(--spacing-xs) var(--spacing-sm);
    border-radius: var(--radius);
    font-size: var(--font-size-small);
    font-weight: var(--font-weight-bold);
    text-transform: capitalize;
}

.status-badge.status-pending {
    color: var(--warning);
    border: 1px solid var(--warning);
}

.status-badge.status-approved {
    color: var(--success);
    border: 1px solid var(--success);
}

.status-badge.status-rejected {
    color: var(--error);
    border: 1px solid var(--error);
}

.status-badge.status-needs_more_info {
    color: var(--info);
    border: 1px solid var(--info);
}

/* Deferred shares the info palette with needs_more_info — both
   are "parked, waiting on a future event," not a terminal outcome.
   Distinct from approved/rejected so the deferred state reads as
   in-progress. */
.status-badge.status-deferred {
    color: var(--info);
    border: 1px solid var(--info);
}

.status-badge.status-completed,
.status-badge.status-inactive {
    color: var(--text-muted);
    border: 1px solid var(--text-muted);
}

/* Account / company / on-off binary states. Distinct from approved/rejected
   so a deactivated user doesn't read as a rejected request. See design.md
   "Status badges" — neutral palette, not semantic. */
.status-badge.status-active {
    color: var(--text-primary);
    border: 1px solid var(--border);
}

/* ---------- Request form specific ---------- */
.item-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: var(--spacing-md);
}

.item-fields {
    display: flex;
    gap: var(--spacing-md);
}

.total-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: var(--font-size-h2);
    font-weight: var(--font-weight-bold);
}

.form-actions {
    display: flex;
    justify-content: flex-end;
    gap: var(--spacing-md);
    margin-top: var(--spacing-xl);
}

/* ---------- Request detail page ---------- */
.request-meta {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
    margin-bottom: var(--spacing-md);
}

.created-at {
    font-size: var(--font-size-small);
    color: var(--text-muted);
}

.manager-notes {
    margin-top: var(--spacing-lg);
    border-color: var(--info);
}

tfoot td {
    padding: var(--spacing-sm) var(--spacing-md);
    border-top: 2px solid var(--border);
}

/* ---------- Sidebar navigation ---------- */
.sidebar-nav .sidebar-section {
    margin-bottom: var(--spacing-xl);
}

.sidebar-nav .sidebar-section h3 {
    font-family: var(--font-body);
    font-size: 10px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.18em;
    margin-bottom: var(--spacing-sm);
    padding: 0 var(--spacing-lg);
}

.sidebar-nav ul {
    list-style: none;
    padding: 0;
    margin: 0;
}

.sidebar-nav li a {
    display: block;
    padding: var(--spacing-sm) var(--spacing-lg);
    font-family: var(--font-body);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
    text-decoration: none;
    border-left: 3px solid transparent;
    transition: background 120ms ease, color 120ms ease;
}

.sidebar-nav li a:hover {
    background: color-mix(in srgb, var(--accent) 6%, transparent);
    color: var(--accent);
    text-decoration: none;
}

.sidebar-nav li a.active {
    background: var(--accent-soft);
    color: var(--accent);
    border-left-color: var(--accent);
}

/* Logout is a POST form (defeats CSRF via <img src=/logout>); render the
   submit button so it's visually identical to the sibling /settings link.
   Mirrors `.sidebar-nav li a` exactly — keep the two rule blocks in sync. */
.sidebar-nav li .logout-form {
    margin: 0;
    padding: 0;
}
.sidebar-nav li .logout-form button {
    appearance: none;
    background: transparent;
    border: none;
    cursor: pointer;
    text-align: left;
    width: 100%;
    display: block;
    padding: var(--spacing-sm) var(--spacing-lg);
    font-family: var(--font-body);
    font-size: inherit;
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
    text-decoration: none;
    border-left: 3px solid transparent;
    transition: background 120ms ease, color 120ms ease;
}
.sidebar-nav li .logout-form button:hover {
    background: color-mix(in srgb, var(--accent) 6%, transparent);
    color: var(--accent);
}

/* ---------- Dashboard specific ---------- */
/* Counts-and-deltas summary card. Cells flex into a row on desktop and
   wrap as needed on narrow widths. .summary-value is the headline
   number; .summary-secondary downshifts to muted weight for the
   accompanying age strings ("2h ago", "3d ago"). Replaces the old
   .user-info "Welcome, {name} / Role: admin" card per gstack #8 — the
   dashboard's prime real estate now answers "what's pending?". */
.dashboard-summary {
    margin-bottom: var(--spacing-xl);
}

.summary-grid {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-xl);
}

.summary-cell {
    min-width: 140px;
}

.summary-label {
    font-size: var(--font-size-small);
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: var(--spacing-xs);
}

.summary-value {
    font-family: var(--font-mono);
    font-size: var(--font-size-h2);
    font-weight: 600;
    color: var(--text-primary);
    line-height: 1.1;
}

.summary-value.summary-secondary {
    font-family: var(--font-body);
    font-size: var(--font-size-base);
    font-weight: 400;
    color: var(--text-muted);
}

.quick-actions {
    margin-bottom: var(--spacing-xl);
}

.quick-actions h2 {
    margin-bottom: var(--spacing-md);
}

.action-buttons {
    display: flex;
    gap: var(--spacing-md);
    flex-wrap: wrap;
}

.recent-requests h2 {
    margin-bottom: var(--spacing-md);
}

/* ---------- Filter bar ---------- */
.filter-bar {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
    margin-bottom: var(--spacing-lg);
}

.filter-group {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
}

.filter-group label {
    margin-bottom: 0;
    white-space: nowrap;
}

.filter-group select {
    width: auto;
    min-width: 180px;
}

/* ---------- Audit timeline (History card) ---------- */
.audit-timeline {
    list-style: none;
    padding: 0;
    margin: 0;
}

.audit-entry {
    padding: var(--spacing-sm) 0;
    border-bottom: 1px solid var(--border);
}

.audit-entry:last-child {
    border-bottom: none;
    padding-bottom: 0;
}

.audit-entry:first-child {
    padding-top: 0;
}

.audit-line {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
    flex-wrap: wrap;
}

.audit-badge {
    font-size: var(--font-size-small);
    padding: var(--spacing-xs) var(--spacing-sm);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-muted);
    white-space: nowrap;
}

.audit-entry.audit-approved .audit-badge {
    border-color: var(--success);
    color: var(--success);
}

.audit-entry.audit-rejected .audit-badge {
    border-color: var(--error);
    color: var(--error);
}

.audit-entry.audit-requested_more_info .audit-badge,
.audit-entry.audit-resubmitted .audit-badge {
    border-color: var(--info);
    color: var(--info);
}

.audit-time {
    color: var(--text-muted);
    font-size: var(--font-size-small);
    margin-left: auto;
}

.audit-note {
    margin: var(--spacing-xs) 0 0;
    padding-left: var(--spacing-md);
    border-left: 2px solid var(--border);
    color: var(--text-muted);
}

/* ---------- Action buttons in table ---------- */
.action-cell {
    white-space: nowrap;
}

.action-form {
    display: inline-flex;
    gap: var(--spacing-xs);
}

/* ---------- Manager scope panel (admin user-edit) ---------- */
/* Sits below the user form card; visually distinct as its own card so
   the admin reads "scopes are a separate concern from the user's basic
   fields." Hidden entirely for non-manager target users. */
.scope-panel {
    margin-top: var(--spacing-lg);
}

.scope-list {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: var(--spacing-md);
}

.scope-add-form {
    margin-top: var(--spacing-md);
}

/* ---------- Small buttons ---------- */
.btn-sm {
    font-size: var(--font-size-small);
    padding: var(--spacing-xs) var(--spacing-sm);
}

/* ---------- Action button colors ---------- */
/* Constructive action — filled, mirrors .btn-primary's weight so the
   constructive choice in any action row reads as the natural next click.
   Reject/More Info stay bordered (lighter) for the destructive vs.
   constructive separation. See design.md "Action button tier system". */
.btn-approve {
    border-color: var(--success);
    background: var(--success);
    color: #ffffff;
}

.btn-approve:hover {
    background: var(--success-hover);
    border-color: var(--success-hover);
    color: #ffffff;
}

.btn-reject {
    border-color: var(--error);
    color: var(--error);
}

.btn-reject:hover {
    background: var(--error);
    color: var(--bg-primary);
}

.btn-more-info {
    border-color: var(--info);
    color: var(--info);
}

.btn-more-info:hover {
    background: var(--info);
    color: var(--bg-primary);
}

/* ---------- Management show page action form ---------- */
.management-show .action-form .form-group {
    margin-bottom: var(--spacing-lg);
}

.management-show .action-form .form-actions {
    display: flex;
    gap: var(--spacing-md);
    flex-wrap: wrap;
}

.management-show .action-form .form-actions .btn {
    flex: 1;
    min-width: 140px;
    text-align: center;
}

/* ---------- Upload page ---------- */
.upload-drop-zone {
    border: 2px dashed var(--border);
    border-radius: var(--radius);
    padding: var(--spacing-2xl);
    text-align: center;
    cursor: pointer;
    margin-bottom: var(--spacing-md);
}

.upload-drop-zone:hover {
    border-color: var(--accent);
}

.upload-drop-zone input[type="file"] {
    display: none;
}

.file-selected {
    padding: var(--spacing-sm) var(--spacing-md);
    border: 1px solid var(--success);
    border-radius: var(--radius);
    color: var(--success);
    font-size: var(--font-size-small);
}

.success-message {
    font-size: var(--font-size-small);
    color: var(--success);
    margin-bottom: var(--spacing-lg);
    padding: var(--spacing-sm) var(--spacing-md);
    border: 1px solid var(--success);
    border-radius: var(--radius);
}

.page-actions {
    display: flex;
    gap: var(--spacing-md);
}

/* ---------- Admin landing — card grid ---------- */
/* /admin's hub page reuses the same hub-card pattern other landing
   pages use: a 2x2 grid of clickable cards rather than a bullet
   list. Cards inherit .card geometry; the wrapper switches to a
   block link with hover lift so the entire surface is the click
   target. */
.admin-card-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--spacing-lg);
}

.admin-card {
    display: block;
    background: var(--bg-primary);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: var(--spacing-lg);
    text-decoration: none;
    color: inherit;
    transition: transform 120ms ease, box-shadow 120ms ease, border-color 120ms ease;
}

.admin-card:hover {
    transform: translateY(-1px);
    border-color: var(--accent);
    box-shadow: 0 2px 8px color-mix(in srgb, var(--text-primary) 8%, transparent);
}

.admin-card h2 {
    margin: 0 0 var(--spacing-xs);
    font-size: var(--font-size-h3);
}

.admin-card p {
    margin: 0;
    color: var(--text-muted);
    font-size: var(--font-size-small);
}

@media (max-width: 640px) {
    .admin-card-grid {
        grid-template-columns: 1fr;
    }
}

/* ---------- Login brand mark ---------- */
/* Wayfinding lockup at the top of the login card. The .brand-svg
   primary/secondary rules already handle dark-mode lift; this rule
   centers the mark and sizes it for a card-width context. */
.login-brand {
    display: flex;
    justify-content: center;
    margin-bottom: var(--spacing-lg);
}

.login-brand .brand-svg {
    max-width: 260px;
}

/* ---------- Google sign-in primary action ---------- */
/* Wraps the "Sign in with Google" button so it stretches across the
   card the same way the password submit button does. The button itself
   is .btn .btn-primary; this wrapper just owns spacing so the
   disclosure underneath has room to breathe. */
.login-google {
    margin-bottom: var(--spacing-lg);
}

.login-google .btn-primary {
    display: block;
    width: 100%;
    text-align: center;
}

/* ---------- Admin sign-in disclosure ---------- */
/* When Google OAuth is enabled, the password form lives behind a
   <details> so the day-to-day user sees a clean "Sign in with Google"
   page; admins clicking the summary expose the password form
   underneath. The summary is small + muted because it's the
   exception path. */
.login-admin-disclosure {
    margin-top: var(--spacing-md);
    padding-top: var(--spacing-md);
    border-top: 1px solid var(--border);
}

.login-admin-disclosure summary {
    cursor: pointer;
    color: var(--text-muted);
    font-size: 0.9em;
    margin-bottom: var(--spacing-md);
}

/* ---------- Inline-form wrapper ---------- */
/* For toggle-button forms inside table cells where the form should
   collapse to its content's width and flow next to siblings. */
.form-inline {
    display: inline;
}

/* ---------- Form row + cell ---------- */
/* Two-or-three-column form layouts (filter bars, settings sections).
   .form-row is the flex container; .form-cell is the default child
   (grow to fill, but never shrink narrower than 220px so labels +
   inputs stay readable on the wrap-down). */
.form-row {
    display: flex;
    gap: var(--spacing-lg);
    align-items: flex-end;
    flex-wrap: wrap;
}

.form-cell {
    flex: 1;
    min-width: 220px;
}

/* ---------- Helper text under fields ---------- */
/* Small muted note that explains a field. Pair with .text-muted on
   the <p> for the muted color; this class adds the spacing + size. */
.help-text {
    margin-top: var(--spacing-xs);
    font-size: var(--font-size-small);
}

/* ---------- Checkbox label ---------- */
/* Apply to the <label> wrapping a checkbox + its caption so the
   checkbox sits inline with normal-weight text. Defeats the default
   bold label weight inherited from the form-group rules. */
.checkbox-label {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    font-weight: normal;
}

/* ---------- Total row ---------- */
/* Use on the <tr> in a table's <tfoot>. All cells go bold; the
   leading colspan label cell right-aligns so the label hugs the
   value to its right. */
.row-total td {
    font-weight: 600;
}

.row-total td:first-child {
    text-align: right;
}

/* ---------- Callout — warning variant ---------- */
/* For .card variants that flag advisory copy ("Heads up", etc.).
   Keeps card geometry; adds a left rail in the warning palette and
   a default bottom margin so the callout breathes from following
   content. */
.callout-warning {
    margin-bottom: var(--spacing-lg);
    border-left: 3px solid var(--warning);
}

/* ---------- Responsive ---------- */
@media (max-width: 1024px) {
    .sidebar {
        width: 220px;
    }
}

@media (max-width: 640px) {
    .layout {
        flex-direction: column;
    }

    .sidebar {
        width: 100%;
        border-right: none;
        border-bottom: 1px solid var(--border);
        padding: var(--spacing-md) 0;
    }

    /* Brand + hamburger sit on one row at the top of the page; nav is
       hidden until .is-open. The brand collapses to a horizontal lockup
       (icon + label inline) so the row stays compact. */
    .sidebar-header {
        display: flex;
        flex-direction: row;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 0;
    }

    .sidebar-header .brand {
        flex-direction: row;
        gap: var(--spacing-sm);
    }

    .brand-svg {
        max-width: 64px;
    }

    .sidebar-toggle {
        display: inline-flex;
    }

    #sidebar-nav-container {
        display: none;
        padding-top: var(--spacing-md);
        margin-top: var(--spacing-md);
        border-top: 1px solid var(--border);
    }

    .sidebar.is-open #sidebar-nav-container {
        display: block;
    }

    .main-content {
        padding: var(--spacing-lg);
    }

    .page-header {
        flex-direction: column;
        align-items: flex-start;
    }

    .item-fields {
        flex-direction: column;
        gap: 0;
    }

    .form-actions {
        flex-direction: column;
    }

    .form-actions .btn,
    .form-actions a.btn {
        width: 100%;
        text-align: center;
    }
}
