/* ============================================================
   Design tokens (approved direction: docs/ui-mockups/4-combined.html).
   Every pre-existing variable name is kept -- templates and the rules
   below reference them -- and the new ones are additive.

   Two accent-ink tokens, deliberately distinct:
     --accent-ink  teal-tinted TEXT on a light/dark page surface
                   (links, active nav, selected segments)
     --on-accent   text sitting ON a solid --accent fill (buttons, CTA,
                   avatar). Dark ink: #04211d on #0f9d8c is ~5:1, where
                   white on the same teal was ~3.4:1 and failed AA.
   ============================================================ */
:root {
    --ink: #111827;
    --ink-2: #374151;
    --muted: #6b7280;
    --faint: #9ca3af;
    --border: #e7e9ee;
    --border-2: #d5d9e2;
    --accent: #0f9d8c;
    --accent-dark: #0b7c6f;
    --accent-ink: #065f56;
    --on-accent: #04211d;
    --bg: #f3f4f7;
    --panel: #ffffff;
    --panel-2: #f8f9fb;
    --tint: rgba(15, 157, 140, .10);

    /* Raw status hues for dots/markers (not text). */
    --red: #dc2626; --amber: #f59e0b; --blue: #3b82f6;

    /* Radii, spacing, elevation, control heights. */
    --r-sm: 6px; --r-md: 8px; --r-lg: 12px;
    --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 20px; --s-6: 24px; --s-8: 32px;
    --shadow: 0 1px 2px rgba(17, 24, 39, .04), 0 1px 3px rgba(17, 24, 39, .06);
    --shadow-2: 0 4px 12px rgba(17, 24, 39, .06);
    --ctl: 34px;        /* the one control height: buttons, inputs, selects */
    --ctl-sm: 28px;     /* in-row compact actions */

    /* App shell. The page is offset by the COLLAPSED rail width only; the
       expanded rail overlays content rather than pushing it. */
    --rail-w: 64px;
    --rail-expanded: 236px;
    --rail-t: .18s;        /* open/close duration */
    --rail-intent: .12s;   /* hover-intent: wait this long before opening */
    --rail-shadow: 10px 0 30px rgba(17, 24, 39, .14), 1px 0 0 var(--border-2);

    /* Notice/banner tints — theme-aware. Each has an explicit readable ink
       color so banners never inherit body text onto a pale tint (the old
       dark-mode bug: light text on a hardcoded light background). */
    --ok-bg: #ecfdf5;     --ok-border: #a7f3d0;     --ok-ink: #065f46;
    --warn-bg: #fffbeb;   --warn-border: #fde68a;   --warn-ink: #92400e;
    --danger-bg: #fef2f2; --danger-border: #fecaca; --danger-ink: #991b1b;
    --info-bg: #eff6ff;   --info-border: #bfdbfe;   --info-ink: #1d4ed8;

    /* Solid fill for the sidebar "waiting on you" count, which carries white
       text. Deliberately its own variable rather than reusing --danger-ink:
       that one flips to a pale red in dark mode for use as *text*, and white
       on pale red is unreadable. */
    --badge-bg: #c0392b;
}

/* Dark mode -- toggled via <html data-theme="dark">, set from the logged-in
   user's theme_preference (accounts.User), not a cookie or localStorage.
   Everything else in this file is built on the CSS variables above, so
   most of the UI re-themes for free; a handful of rules below use literal
   colors (status pills, urgency accents) and need explicit dark variants. */
[data-theme="dark"] {
    --ink: #f1f5f9;
    --ink-2: #cbd5e1;
    --muted: #94a3b8;
    --faint: #64748b;
    --border: #283449;
    --border-2: #334155;
    --accent: #14b8a6;
    --accent-dark: #2dd4bf;
    --accent-ink: #5eead4;
    --on-accent: #04211d;   /* dark ink still reads on the brighter dark-mode teal */
    --bg: #0b1220;
    --panel: #151f33;
    --panel-2: #1b2740;
    --tint: rgba(20, 184, 166, .16);

    --red: #f87171; --amber: #fbbf24; --blue: #60a5fa;
    --shadow: 0 1px 2px rgba(0, 0, 0, .4);
    --shadow-2: 0 4px 16px rgba(0, 0, 0, .4);
    --rail-shadow: 10px 0 34px rgba(0, 0, 0, .55), 1px 0 0 var(--border-2);

    /* Dark notice tints: low-alpha accent wash + pale ink for contrast. */
    --ok-bg: rgba(16, 185, 129, .13);   --ok-border: rgba(16, 185, 129, .38);   --ok-ink: #34d399;
    --warn-bg: rgba(245, 158, 11, .13);  --warn-border: rgba(245, 158, 11, .38);  --warn-ink: #fbbf24;
    --danger-bg: rgba(248, 113, 113, .13); --danger-border: rgba(248, 113, 113, .40); --danger-ink: #f87171;
    --info-bg: rgba(96, 165, 250, .13);  --info-border: rgba(96, 165, 250, .38);  --info-ink: #60a5fa;

    /* Brighter in dark mode so the chip reads against the dark rail, still
       high-contrast under white text. */
    --badge-bg: #dc2626;
}

[data-theme="dark"] .pill { background: #374151; color: #d1d5db; }
[data-theme="dark"] .pill-pending { background: #452f06; color: #fbbf24; }
[data-theme="dark"] .pill-active { background: #1e3a5f; color: #60a5fa; }
[data-theme="dark"] .pill-closed { background: #0f3d2e; color: #34d399; }
[data-theme="dark"] .pill-draft { background: #374151; color: #d1d5db; }
[data-theme="dark"] .pill-withdrawn,
[data-theme="dark"] .pill-canceled { background: #4c1d1d; color: #f87171; }
[data-theme="dark"] .pill-needed { background: #4c1d1d; color: #f87171; }
[data-theme="dark"] .pill-received { background: #452f06; color: #fbbf24; }
[data-theme="dark"] .pill-reviewed { background: #0f3d2e; color: #34d399; }

[data-theme="dark"] .task-bucket-overdue h2 { color: #f87171; }
[data-theme="dark"] .task-bucket-today h2 { color: #fbbf24; }
[data-theme="dark"] .task-overdue { color: #f87171; }

[data-theme="dark"] .task-bucket-attention h2 { color: #fbbf24; }
[data-theme="dark"] .task-bucket-attention { border-color: #78350f; background: #1c1917; }

[data-theme="dark"] .delete-btn:hover { color: #f87171; }

[data-theme="dark"] .due-date-input:hover,
[data-theme="dark"] .due-date-input:focus { background: #111827; }

* { box-sizing: border-box; }

html, body { margin: 0; }
body {
    font: 14px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    color: var(--ink);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
}

a { color: var(--accent-ink); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Keyboard focus ring for anything not already given the tinted
   box-shadow ring further down (links, rail rows, custom controls). */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* One heading scale: page 28 / section 15 / sub 14. Component rules
   (.panel h2 label style, .task-bucket h2, .auth-card h1) still win on
   specificity, so this only sets the baseline for unstyled headings. */
h1 { font-size: 28px; font-weight: 700; letter-spacing: -.025em; line-height: 1.15; }
h2 { font-size: 15px; font-weight: 600; line-height: 1.3; }
h3 { font-size: 14px; font-weight: 600; line-height: 1.3; }

/* ============================================================
   App shell — fixed icon rail that expands as an OVERLAY.

   The rail is position:fixed and the page carries a CONSTANT 64px left
   padding (--rail-w). Hovering widens the rail only; it floats over the
   content and never pushes it (the old in-flow flex-sibling rail
   reflowed the whole page on every hover).

   Layout trick: everything inside the rail is laid out at the expanded
   width (236px) all the time; the rail itself clips at 64px and the clip
   widens on hover. Nothing inside reflows or re-centres, so open/close is
   a single width transition and the icons never jitter. Labels fade with
   opacity in step with the width.

   Open only: on the way IN the width transition waits --rail-intent, so a
   cursor crossing the rail to reach the page never flickers it open; on
   the way OUT it closes immediately. :focus-within opens it for keyboard
   users. .pinned (pin button) docks it open and widens the page offset
   via .app.rail-pinned (toggled together in base.html's script).

   Safari-safe: only :hover / :focus-within / :not(), transitions and
   custom properties. None of the Safari-unsafe selector features (parent
   matching, container queries, color mixing, nested rules) are used.
   ============================================================ */
.app { min-height: 100vh; padding-left: var(--rail-w); }
.app.rail-pinned { padding-left: var(--rail-expanded); }

.rail {
    position: fixed;
    left: 0; top: 0; bottom: 0;
    z-index: 20;
    width: var(--rail-w);
    background: var(--panel);
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    --d: 0s;    /* transition delay: 0 on the way out */
    transition: width var(--rail-t) ease var(--d), box-shadow var(--rail-t) ease var(--d);
}
.rail:hover { --d: var(--rail-intent); }
.rail:hover,
.rail:focus-within,
.rail.pinned {
    width: var(--rail-expanded);
    box-shadow: var(--rail-shadow);
    border-right-color: transparent;
}
/* Pinned = docked, not floating: page is offset instead, so no shadow. */
.rail.pinned { box-shadow: none; border-right-color: var(--border); }

/* Inner columns always laid out at the expanded width. */
.rail-top, .rail-scroll, .rail-foot { width: var(--rail-expanded); flex-shrink: 0; }

/* Text that only exists when expanded fades in step with the width. These
   are spans, not tab stops; the pin and the two foot buttons are the
   exception, and tabbing to them triggers :focus-within, which opens the
   rail and reveals them. */
.rail .rail-name, .rail .grp-label, .rail .lbl, .rail .tag, .rail .cta span, .rail .who, .rail .pin, .rail-foot .mini {
    opacity: 0;
    transition: opacity var(--rail-t) ease var(--d);
}
.rail:hover .rail-name,  .rail:focus-within .rail-name,  .rail.pinned .rail-name,
.rail:hover .grp-label,  .rail:focus-within .grp-label,  .rail.pinned .grp-label,
.rail:hover .lbl,        .rail:focus-within .lbl,        .rail.pinned .lbl,
.rail:hover .tag,        .rail:focus-within .tag,        .rail.pinned .tag,
.rail:hover .cta span,   .rail:focus-within .cta span,   .rail.pinned .cta span,
.rail:hover .who,        .rail:focus-within .who,        .rail.pinned .who,
.rail:hover .pin,        .rail:focus-within .pin,        .rail.pinned .pin,
.rail:hover .rail-foot .mini, .rail:focus-within .rail-foot .mini, .rail.pinned .rail-foot .mini { opacity: 1; }

/* Every icon column is centred on x=32px, the middle of the 64px rail. */
.rail-top { display: flex; align-items: center; gap: 10px; padding: 14px 17px 10px; height: 56px; }
.rail-brand { display: flex; align-items: center; gap: 10px; min-width: 0; color: var(--ink); }
.rail-brand:hover { text-decoration: none; }
.rail-logo {
    width: 30px; height: 30px; flex: 0 0 30px;
    border-radius: 9px;
    background: linear-gradient(135deg, var(--accent), var(--accent-dark));
    display: grid; place-items: center;
    color: var(--on-accent); font-weight: 800; font-size: 15px;
}
.rail-name { font-size: 17px; font-weight: 700; letter-spacing: -.02em; white-space: nowrap; color: var(--ink); }

.pin {
    margin-left: auto;
    background: transparent; border: none;
    color: var(--muted); cursor: pointer;
    padding: 4px; border-radius: var(--r-sm);
}
.pin:hover { background: var(--panel-2); color: var(--ink); }
.pin svg { width: 16px; height: 16px; display: block; }
.rail.pinned .pin { color: var(--accent-ink); background: var(--tint); }

/* Rows (CTA + links) are 40px pills when collapsed and grow to the full
   212px (236 - 2*12) when expanded, so highlights never look sliced off
   at the rail's clip edge. Width animates in step with the rail. */
.rail .cta {
    width: 40px;
    margin: 2px 12px 10px;
    display: flex; align-items: center; gap: 10px;
    background: var(--accent); color: var(--on-accent); font-weight: 700;
    border-radius: 10px; height: 38px; padding: 0 11px; font-size: 13.5px;
    white-space: nowrap; overflow: hidden;
    box-shadow: var(--shadow);
    transition: width var(--rail-t) ease var(--d), background .12s;
}
.rail .cta:hover { background: var(--accent-dark); color: var(--on-accent); text-decoration: none; }
.rail .cta svg { width: 18px; height: 18px; flex: 0 0 18px; }
.rail:hover .cta, .rail:focus-within .cta, .rail.pinned .cta,
.rail:hover .link, .rail:focus-within .link, .rail.pinned .link { width: 212px; }

/* Scroll container is already the full expanded width, so nothing
   positioned inside it (the badge chip) can be clipped at the 64px edge. */
.rail-scroll { flex: 1 1 auto; overflow-y: auto; overflow-x: hidden; padding: 0 12px 10px; }
.rail-scroll::-webkit-scrollbar { width: 6px; }
.rail-scroll::-webkit-scrollbar-thumb { background: var(--border); border-radius: 6px; }

.grp { padding: 10px 0 4px; border-top: 1px solid var(--border); }
.grp:first-child { border-top: none; padding-top: 2px; }
.grp-label {
    font-size: 10.5px; font-weight: 700; letter-spacing: .08em;
    text-transform: uppercase; color: var(--faint);
    padding: 4px 8px 6px; white-space: nowrap;
}

.rail .link {
    width: 40px;
    display: flex; align-items: center; gap: 11px;
    height: 36px; padding: 0 11px; margin: 1px 0;
    border-radius: var(--r-md); color: var(--ink-2); font-size: 13.5px;
    position: relative; white-space: nowrap;
    transition: width var(--rail-t) ease var(--d);
}
.rail .link:hover { background: var(--panel-2); color: var(--ink); text-decoration: none; }
.rail .link svg { width: 18px; height: 18px; flex: 0 0 18px; color: var(--muted); }
.rail .link .lbl { flex: 1; overflow: hidden; text-overflow: ellipsis; }
.rail .link .tag {
    font-size: 9px; font-weight: 700; color: var(--faint);
    border: 1px solid var(--border); border-radius: 4px; padding: 1px 5px;
}
.rail .link.active { background: var(--tint); color: var(--accent-ink); font-weight: 600; }
.rail .link.active svg { color: var(--accent-ink); }

/* "Waiting on you" count. Deliberately NOT following the .tag fade-out
   pattern above: a badge that vanishes when the rail is collapsed would be
   invisible in the rail's default state -- exactly when it needs to be seen.
   Expanded, it sits inline at the right of the row; collapsed, it rides the
   top-right corner of the icon as a small count chip. */
.nav-badge {
    font-size: 10.5px; font-weight: 700; line-height: 1;
    color: #fff; background: var(--badge-bg);
    border-radius: 999px; padding: 3px 6px; min-width: 18px; text-align: center;
}
.rail:not(:hover):not(:focus-within):not(.pinned) .link .nav-badge {
    position: absolute; top: 2px; left: 26px;
    box-shadow: 0 0 0 2px var(--panel);
}

.rail-foot {
    border-top: 1px solid var(--border);
    padding: 10px 16px;
    display: flex; align-items: center; gap: 10px;
}
.avatar {
    width: 32px; height: 32px; flex: 0 0 32px;
    border-radius: 9px;
    background: linear-gradient(135deg, var(--accent), var(--accent-dark));
    display: grid; place-items: center;
    color: var(--on-accent); font-weight: 800; font-size: 12px;
}
.who { flex: 1; min-width: 0; line-height: 1.2; }
.who b { display: block; font-size: 12.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--ink); }
.who span { font-size: 11px; color: var(--muted); }

/* Logout / theme-toggle forms in the foot. */
.theme-toggle-form { display: inline-flex; margin: 0; }
.rail-foot .mini, .rail-foot .theme-toggle-btn { width: 30px; height: 30px; flex: 0 0 30px; padding: 0; font-size: 15px; }
.rail-foot .mini svg { width: 15px; height: 15px; }

@media (prefers-reduced-motion: reduce) {
    .rail, .rail .cta, .rail .link,
    .rail .rail-name, .rail .grp-label, .rail .lbl, .rail .tag, .rail .cta span, .rail .who, .rail .pin, .rail-foot .mini { transition-duration: 0s; }
}

/* Mobile top bar + drawer backdrop — hidden on desktop */
.mobile-bar { display: none; }
.rail-backdrop { display: none; }

/* ------------------------------------------------------------
   .mini — compact secondary action, global. Used in the rail foot
   (icon-only, forced square above) AND as a text button in
   _task_bucket.html / transaction_detail.html ("Send request",
   "Record & unlock"), so the base shape must fit text. Previously it
   was only styled as .rail .mini and rendered unstyled elsewhere.
   .theme-toggle-btn is kept as an alias with the same look.
   ------------------------------------------------------------ */
.mini, .theme-toggle-btn {
    background: transparent;
    border: 1px solid var(--border-2);
    color: var(--muted);
    border-radius: 7px;
    height: var(--ctl-sm);
    min-width: var(--ctl-sm);
    padding: 0 8px;
    display: inline-flex; align-items: center; justify-content: center; gap: 4px;
    cursor: pointer;
    font: inherit; font-size: 12.5px; font-weight: 600; line-height: 1;
    white-space: nowrap;
    text-decoration: none;
}
.mini:hover, .theme-toggle-btn:hover { color: var(--ink); border-color: var(--accent); background: var(--panel-2); text-decoration: none; }
.mini svg { width: 14px; height: 14px; }



.page {
    max-width: 1180px;
    margin: 0 auto;
    padding: var(--s-6) var(--s-8) var(--s-8);
}

.page-header h1 {
    margin: 0 0 4px 0;
    font-size: 28px;
    font-weight: 700;
    letter-spacing: -.025em;
    line-height: 1.15;
}

.page-header .subhead {
    color: var(--muted);
    margin: 0 0 24px 0;
    font-size: 13.5px;
}

.back-link {
    display: inline-block;
    margin-bottom: 8px;
    font-size: 14px;
}

.data-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
}

.data-table th {
    text-align: left;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--muted);
    background: var(--bg);
    padding: 10px 16px;
    border-bottom: 1px solid var(--border);
}

.data-table td {
    padding: 12px 16px;
    border-bottom: 1px solid var(--border);
    font-size: 14px;
}

.data-table tr:last-child td { border-bottom: none; }
.data-table tr.task-done { opacity: 0.55; }

.empty-state {
    color: var(--muted);
    text-align: center;
    padding: 24px !important;
}

.pill {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    background: #e5e7eb;
    color: #374151;
}

.pill-pending { background: #fef3c7; color: #92400e; }
.pill-active { background: #dbeafe; color: #1e40af; }
.pill-closed { background: #d1fae5; color: #065f46; }
.pill-draft { background: #e5e7eb; color: #374151; }
.pill-withdrawn, .pill-canceled { background: #fee2e2; color: #991b1b; }

.pill-needed { background: #fee2e2; color: #991b1b; }
.pill-received { background: #fef3c7; color: #92400e; }
.pill-reviewed { background: #d1fae5; color: #065f46; }

.pagination {
    display: flex;
    justify-content: center;
    gap: 16px;
    margin-top: 16px;
    font-size: 14px;
    color: var(--muted);
}

.detail-grid {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: 24px;
    align-items: start;
}

/* Cards: borderless, lifted by shadow, 12px radius. Variants that set
   their own border (.task-bucket-attention, .flag-preview-panel,
   .documents-loaded-panel) keep it -- those rules still apply. */
.panel {
    background: var(--panel);
    border: none;
    border-radius: var(--r-lg);
    box-shadow: var(--shadow);
    padding: 20px;
}

/* Objection-days badge (transaction_detail.html). Promoted from that
   template's inline <style>, which hard-coded light-only hex; the --info-*
   tokens already carry the dark twin. */
.objection-badge {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 7px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    background: var(--info-bg);
    color: var(--info-ink);
    border: 1px solid var(--info-border);
    white-space: nowrap;
    vertical-align: 1px;
}

.panel h2 {
    font-size: 14px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--muted);
    margin: 0 0 12px 0;
}

.panel h2:not(:first-child) { margin-top: 20px; }

.fact-list {
    display: grid;
    grid-template-columns: auto minmax(120px, 1fr);
    align-items: baseline;
    gap: 6px 12px;
    margin: 0;
    font-size: 14px;
}

.fact-list dt {
    color: var(--muted);
    min-width: 0;
    overflow-wrap: break-word;
}
.fact-list dd {
    margin: 0;
    min-width: 0;
    overflow-wrap: break-word;
}

.close-form {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid var(--border);
}

.radio-option {
    font-size: 14px;
    display: flex;
    align-items: center;
    gap: 8px;
}

.close-form button {
    align-self: flex-start;
    padding: 10px 20px;
    background: var(--accent);
    color: var(--on-accent);
    border: none;
    border-radius: 6px;
    font-weight: 600;
    cursor: pointer;
}

.close-form button:hover { background: var(--accent-dark); }

.task-filters {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 24px;
    flex-wrap: wrap;
}

.task-filters input[type="text"] {
    flex: 1;
    min-width: 200px;
    padding: 8px 12px;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 14px;
}

.task-filters select {
    padding: 8px 12px;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 14px;
    background: var(--panel);
}

.task-filters .checkbox-option {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 14px;
    color: var(--muted);
    white-space: nowrap;
}

.task-filters button {
    padding: 8px 16px;
    background: var(--accent);
    color: var(--on-accent);
    border: none;
    border-radius: 6px;
    font-weight: 600;
    cursor: pointer;
}

.task-filters button:hover { background: var(--accent-dark); }

.task-bucket { margin-bottom: 20px; }

.task-bucket h2 {
    font-size: 15px;
    text-transform: none;
    letter-spacing: normal;
    color: var(--ink);
    font-weight: 700;
}

.bucket-count {
    color: var(--muted);
    font-weight: 400;
}

.task-bucket-overdue h2 { color: #991b1b; }
.task-bucket-today h2 { color: #92400e; }

.task-overdue { color: #991b1b; font-weight: 600; }

.toggle-form { display: inline; }

.toggle-btn {
    background: none;
    border: none;
    padding: 0;
    font-size: 16px;
    cursor: pointer;
    color: var(--muted);
    line-height: 1;
}

.toggle-btn:hover { color: var(--accent-dark); }

.task-bucket-attention h2 { color: #92400e; }
.task-bucket-attention { border: 1px solid #fde68a; background: #fffbeb; }

.flag-actions {
    display: flex;
    gap: 8px;
    align-items: center;
}

.flag-action-btn {
    background: none;
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: 3px 8px;
    font-size: 12px;
    cursor: pointer;
    color: var(--muted);
}

.flag-action-btn:hover { border-color: var(--accent); color: var(--accent-dark); }

.due-date-form { display: inline; }

.due-date-input {
    border: 1px solid transparent;
    background: transparent;
    font-size: 14px;
    font-family: inherit;
    color: inherit;
    padding: 2px 4px;
    border-radius: 4px;
}

.due-date-input:hover, .due-date-input:focus { border-color: var(--border); background: var(--bg); }

.delete-btn {
    background: none;
    border: none;
    font-size: 18px;
    line-height: 1;
    color: var(--muted);
    cursor: pointer;
}

.delete-btn:hover { color: #991b1b; }

.add-task-form {
    display: flex;
    gap: 8px;
    margin-top: 12px;
    align-items: center;
}

.add-task-form input[type="text"] {
    flex: 1;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 14px;
}

.add-task-form input[type="date"] {
    padding: 7px 10px;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 14px;
}

.add-task-form button {
    padding: 8px 16px;
    background: var(--accent);
    color: var(--on-accent);
    border: none;
    border-radius: 6px;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
}

.add-task-form button:hover { background: var(--accent-dark); }

.prompt-actions {
    display: flex;
    gap: 10px;
}

/* Critical deadlines: a distinct, always-visible marker independent of
   urgency bucketing by due date -- a critical task due next month should
   still read as "this one matters more" next to an ordinary task due
   tomorrow. */
.task-critical { border-left: 3px solid #b91c1c; }

.critical-badge {
    color: #b91c1c;
    margin-right: 6px;
    font-size: 13px;
}

[data-theme="dark"] .task-critical { border-left-color: #f87171; }
[data-theme="dark"] .critical-badge { color: #f87171; }

.upload-form {
    display: flex;
    align-items: center;
    gap: 6px;
}

.upload-form input[type="file"] {
    font-size: 12px;
    max-width: 140px;
}

.upload-form button {
    padding: 4px 10px;
    background: var(--accent);
    color: var(--on-accent);
    border: none;
    border-radius: 4px;
    font-size: 12px;
    cursor: pointer;
    white-space: nowrap;
}

.upload-form button:hover { background: var(--accent-dark); }

.draggable-row { cursor: grab; }
.draggable-row.dragging { opacity: 0.4; }

.drag-handle {
    width: 20px;
    color: var(--muted);
    cursor: grab;
    user-select: none;
}

[data-theme="dark"] .drag-handle { color: var(--muted); }

/* Shape lived only on .prompt-actions button before -- fine everywhere
   .secondary-btn was used inside a .prompt-actions row, but left every
   .secondary-btn outside one (e.g. the update/create-new buttons in
   .quickadd-candidate rows below) as an unstyled default browser button.
   Giving .secondary-btn its own shape fixes that everywhere at once. */
.secondary-btn {
    background: var(--panel) !important;
    color: var(--ink) !important;
    border: 1px solid var(--border-2) !important;
    padding: 0 14px;
    border-radius: var(--r-md);
    font-weight: 600;
    cursor: pointer;
}

.secondary-btn:hover { background: var(--panel-2) !important; }

/* Generalized off .close-form button so any .prompt-actions block gets the
   same primary-button look without needing a .close-form wrapper --
   used on the contract-review confirm/cancel row below as well as the
   existing checklist-learning prompt. */
.prompt-actions button {
    padding: 10px 20px;
    background: var(--accent);
    color: var(--on-accent);
    border: none;
    border-radius: 6px;
    font-weight: 600;
    cursor: pointer;
}

.prompt-actions button:hover { background: var(--accent-dark); }

.status-choice {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.status-choice-label {
    margin: 0;
    color: var(--muted);
    font-size: 13px;
    width: 100%;
}

.status-tabs {
    display: flex;
    gap: 8px;
    margin-bottom: 20px;
    flex-wrap: wrap;
}

.status-tab {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 14px;
    border-radius: 999px;
    border: 1px solid var(--border);
    color: var(--muted);
    text-decoration: none !important;
    font-weight: 600;
    font-size: 14px;
}

.status-tab:hover { border-color: var(--accent); color: var(--ink); }

.status-tab-active {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--on-accent) !important;
}

.status-tab-count { font-weight: 400; opacity: 0.8; }

.nav-cta {
    background: var(--accent);
    color: var(--on-accent) !important;
    padding: 6px 14px;
    border-radius: 999px;
    font-weight: 600;
    text-decoration: none !important;
}

.nav-cta:hover { background: var(--accent-dark); }

.page-header .nav-cta {
    display: inline-block;
    margin-top: 4px;
}

/* Attention-colored CTA (e.g. pending global-template requests). Amber
   reads the same in both themes; white text stays legible on it. */
.nav-cta.nav-cta--warn { background: #f59e0b; }
.nav-cta.nav-cta--warn:hover { background: #d97706; }

.form-error { color: #b91c1c; }
[data-theme="dark"] .form-error { color: #f87171; }

/* Start New Transaction: upload screen */
.start-panel { max-width: 640px; }

.manual-start-panel { margin-top: 20px; }

/* ============================================================
   Icon-rail sidebar — mobile fallback.
   On narrow screens the rail becomes an off-canvas drawer that
   slides in from the left, triggered by a hamburger in a slim
   top bar. Content flows full width beneath the bar.
   ============================================================ */
@media (max-width: 820px) {
    .mobile-bar {
        display: flex;
        align-items: center;
        gap: 12px;
        position: sticky;
        top: 0;
        z-index: 20;
        height: 52px;
        padding: 0 14px;
        background: var(--panel);
        border-bottom: 1px solid var(--border);
    }
    .mobile-bar .brand { font-weight: 700; font-size: 18px; color: var(--accent-ink); }
    .hamburger {
        background: transparent;
        border: 1px solid var(--border-2);
        border-radius: var(--r-md);
        width: 38px; height: 36px;
        color: var(--ink); cursor: pointer;
        display: grid; place-items: center; padding: 0;
    }
    .hamburger svg { width: 20px; height: 20px; }

    /* No rail offset: content flows full width beneath the top bar. */
    .app, .app.rail-pinned { padding-left: 0; }
    .page { padding: var(--s-5) var(--s-4) var(--s-6); }

    /* The rail becomes an off-canvas drawer, always at the expanded width,
       slid in by .open (hamburger) rather than hover. */
    .rail,
    .rail:hover,
    .rail:focus-within,
    .rail.pinned {
        width: var(--rail-expanded);
        transform: translateX(-100%);
        transition: transform .2s ease;
        box-shadow: var(--rail-shadow);
        border-right-color: var(--border);
        z-index: 40;
    }
    .rail.open { transform: translateX(0); }

    /* Drawer always shows labels/controls (no hover-expand on touch) */
    .rail .rail-name,
    .rail .grp-label,
    .rail .lbl,
    .rail .tag,
    .rail .cta span,
    .rail .who,
    .rail-foot .mini { opacity: 1; }
    .rail .cta, .rail .link { width: 212px; }
    .rail .link .nav-badge,
    .rail:not(:hover):not(:focus-within):not(.pinned) .link .nav-badge { position: static; box-shadow: none; }
    .pin { display: none; }

    .rail-backdrop {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 35;
        background: rgba(0, 0, 0, .4);
        opacity: 0;
        pointer-events: none;
        transition: opacity .2s;
    }
    .rail-backdrop.show { opacity: 1; pointer-events: auto; }
}
@media (max-width: 820px) and (prefers-reduced-motion: reduce) {
    .rail, .rail-backdrop { transition-duration: 0s; }
}

.upload-form-large {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.upload-dropzone {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 40px 20px;
    border: 2px dashed var(--border);
    border-radius: 10px;
    color: var(--muted);
    cursor: pointer;
    text-align: center;
}

.upload-dropzone:hover { border-color: var(--accent); color: var(--ink); }

.upload-dropzone input[type="file"] { margin-bottom: 4px; }

.upload-form-large button {
    align-self: flex-start;
    padding: 10px 20px;
    background: var(--accent);
    color: var(--on-accent);
    border: none;
    border-radius: 6px;
    font-weight: 600;
    cursor: pointer;
}

.upload-form-large button:hover { background: var(--accent-dark); }

.selected-file-list {
    list-style: none;
    padding: 0;
    margin: 4px 0 0;
    font-size: 13px;
    color: var(--muted);
}

.selected-file-list li {
    padding: 2px 0;
}

.selected-file-list li::before {
    content: "\1F4C4  ";
}

/* Review/confirm screen */
.flag-preview-panel { border: 1px solid #fde68a; background: #fffbeb; }
[data-theme="dark"] .flag-preview-panel { border-color: #78350f; background: #1c1917; }

.documents-loaded-panel { border: 1px solid #bfdbfe; background: #eff6ff; }
[data-theme="dark"] .documents-loaded-panel { border-color: #1e3a8a; background: #1c1917; }

.documents-loaded-list {
    list-style: none;
    padding: 0;
    margin: 8px 0 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 13px;
}

.documents-loaded-list .doc-filename { font-weight: 600; }
.documents-loaded-list .doc-identified { color: var(--muted); }

.autofill-badge {
    font-size: 11px;
    font-weight: 600;
    color: var(--accent);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.agent-combobox {
    position: relative;
}

.combobox-results {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 10;
    margin: 2px 0 0;
    padding: 4px 0;
    list-style: none;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 6px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    max-height: 220px;
    overflow-y: auto;
}

.combobox-results li {
    padding: 8px 12px;
    font-size: 14px;
    color: var(--ink);
    cursor: pointer;
}

.combobox-results li:hover {
    background: var(--accent);
    color: var(--on-accent);
}

.link-btn {
    background: none;
    border: none;
    padding: 0;
    color: var(--accent);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    text-decoration: underline;
}

.quickadd-panel {
    margin-top: 8px;
    padding: 14px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--panel);
}

.quickadd-candidate {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 8px 0;
    border-bottom: 1px solid var(--border);
    font-size: 13px;
}

.quickadd-candidate:last-of-type {
    border-bottom: none;
}

/* Agent chips pulled straight from the uploaded document -- pinned above
   the search box rather than replacing it, since the TC always needs a
   way to search or add someone else if none of these are right. */
.suggested-agents {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 8px;
}

/* Same author-vs-user-agent cascade gotcha as .modal-overlay above --
   without this, this container ignores its hidden attribute too. */
.suggested-agents[hidden] {
    display: none;
}

.agent-suggestion-chip {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    padding: 6px 12px;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 8px;
    cursor: pointer;
    text-align: left;
    font-size: 13px;
    color: var(--ink);
    max-width: 260px;
}

.agent-suggestion-chip:hover {
    border-color: var(--accent);
}

.agent-suggestion-chip .chip-role {
    font-size: 11px;
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.agent-suggestion-chip .chip-hint {
    font-size: 12px;
    color: var(--muted);
}

.agent-suggestion-chip[data-match-type="exact"] .chip-hint { color: var(--accent); }
.agent-suggestion-chip[data-match-type="mismatch"] .chip-hint { color: #92400e; }
[data-theme="dark"] .agent-suggestion-chip[data-match-type="mismatch"] .chip-hint { color: #fbbf24; }

/* The app's first true interrupting modal -- everything before this has
   been an inline panel or dropdown. Used specifically because a possible
   duplicate contact is exactly the kind of thing Evan wants impossible to
   accidentally click past (see docs/ai-contract-extraction-proposal.md,
   "Round six"). */
.modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 100;
    padding: 20px;
}

/* An author stylesheet's `display` always beats the browser's own
   `[hidden] { display: none }` default rule, even when a plain class
   selector like .modal-overlay ties on specificity -- origin (author vs.
   user-agent) decides the tie, not specificity. Without this, the modal
   ignores the hidden attribute entirely and shows on every page load,
   and JS setting .hidden = true later has no visual effect either. */
.modal-overlay[hidden] {
    display: none;
}

.modal-dialog {
    background: var(--panel);
    border-radius: 10px;
    padding: 24px;
    max-width: 480px;
    width: 100%;
    max-height: 80vh;
    overflow-y: auto;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.25);
}

.modal-dialog h2 {
    margin-top: 0;
    font-size: 18px;
    font-weight: 700;
    letter-spacing: -.01em;
}

.review-field-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px 20px;
}

.review-field-grid label {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 13px;
    color: var(--muted);
}

.review-field-grid input,
.review-field-grid select {
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 14px;
    color: var(--ink);
    background: var(--panel);
}

.radio-row {
    display: flex;
    gap: 16px;
    align-items: center;
}

.radio-row .radio-option { font-size: 14px; }

.review-form .panel,
.review-form .detail-grid { margin-bottom: 20px; }

.review-form .data-table select,
.review-form .data-table input {
    padding: 6px 8px;
    border: 1px solid var(--border);
    border-radius: 4px;
    font-size: 13px;
    width: 100%;
    background: var(--panel);
    color: var(--ink);
}

/* --- Transaction notes log (transaction_detail.html) --- */

.add-note-form {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
    margin-bottom: 18px;
}

.add-note-form textarea,
.note-edit-form textarea {
    width: 100%;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: 6px;
    font: inherit;
    font-size: 14px;
    color: var(--ink);
    background: var(--panel);
    resize: vertical;
}

.note-edit-form {
    margin: 4px 0 8px 0;
}

.note-edit-form button {
    margin-top: 8px;
    margin-right: 6px;
}

.note-entry {
    padding: 12px 0;
    border-top: 1px solid var(--border);
}

.note-meta {
    margin: 0 0 6px 0;
    font-size: 12px;
    color: var(--muted);
}

.note-body {
    font-size: 14px;
    color: var(--ink);
    white-space: normal;
}

.note-actions {
    margin: 8px 0 0 0;
    display: flex;
    gap: 12px;
    align-items: center;
}

/* --- Verify-value flag source (Needs Attention panels) --- */

.flag-quote {
    margin: 6px 0 4px 0;
    padding-left: 10px;
    border-left: 3px solid var(--border);
    font-style: italic;
    color: var(--muted);
    font-size: 13px;
}

.flag-source-link {
    display: inline-block;
    font-size: 13px;
    font-weight: 600;
}

/* ============================================================
   Shared component system — established in the app-wide visual
   polish pass. Notices, buttons, form fields, and spacing
   utilities that replace the ad-hoc inline styles that had drifted
   across templates. Everything is theme-token based so it reads
   correctly in both light and dark mode.
   ============================================================ */

/* --- Notices / banners --------------------------------------
   Replaces the old hardcoded-hex banner divs (e.g.
   style="border-color:#a7f3d0; background:#ecfdf5"). Those set a
   pale background but let the text follow the theme, so dark mode
   rendered light ink on a light banner. .notice sets background,
   border, AND an explicit readable ink for each tint per theme. */
.notice {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 14px 16px;
    margin-bottom: 16px;
    color: var(--ink);
    font-size: 14px;
}
.notice > :first-child { margin-top: 0; }
.notice > :last-child { margin-bottom: 0; }
.notice--success { background: var(--ok-bg);     border-color: var(--ok-border);     color: var(--ok-ink); }
.notice--warn    { background: var(--warn-bg);   border-color: var(--warn-border);   color: var(--warn-ink); }
.notice--danger  { background: var(--danger-bg); border-color: var(--danger-border); color: var(--danger-ink); }
.notice--info    { background: var(--info-bg);   border-color: var(--info-border);   color: var(--info-ink); }
/* Keep strong/links legible against the tint by inheriting notice ink. */
.notice--success strong, .notice--warn strong,
.notice--danger strong, .notice--info strong { color: inherit; }

/* --- Buttons -------------------------------------------------
   One button system, one control height (--ctl = 34px), one ink rule:
   text on a solid accent fill is --on-accent (dark; ~5:1), never white
   (~3.4:1, failed AA). Every submit/action button in the app reads as
   one of: primary (.btn / bare <button> in form contexts), .btn-outline
   (a.k.a. .secondary-btn), .btn-ghost, .btn-danger, or compact .btn-sm.
   Existing class names are preserved and re-pointed here. */
.btn,
.prompt-actions button,
.close-form button,
.task-filters button,
.add-task-form button,
.upload-form-large button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: var(--ctl);
    padding: 0 14px;
    background: var(--accent);
    color: var(--on-accent);
    border: 1px solid var(--accent);
    border-radius: var(--r-md);
    font-size: 13.5px;
    font-weight: 600;
    font-family: inherit;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
    text-decoration: none;
    transition: background .12s ease, border-color .12s ease, box-shadow .12s ease;
}
.btn:hover,
.prompt-actions button:hover,
.close-form button:hover,
.task-filters button:hover,
.add-task-form button:hover,
.upload-form-large button:hover { background: var(--accent-dark); border-color: var(--accent-dark); color: var(--on-accent); text-decoration: none; }

.btn:active,
.prompt-actions button:active { transform: translateY(1px); }

.btn:focus-visible,
.btn-outline:focus-visible,
.secondary-btn:focus-visible,
.btn-ghost:focus-visible,
.btn-danger:focus-visible,
.btn-sm:focus-visible,
.mini:focus-visible,
.prompt-actions button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px var(--tint);
    border-color: var(--accent);
}

.btn:disabled,
.btn[disabled],
button:disabled { opacity: .55; cursor: not-allowed; }

/* Outline / secondary — reuse .secondary-btn's look, add an alias. */
.btn-outline,
.secondary-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: var(--ctl);
    padding: 0 14px;
    background: var(--panel);
    color: var(--ink);
    border: 1px solid var(--border-2);
    border-radius: var(--r-md);
    font-size: 13.5px;
    font-weight: 600;
    font-family: inherit;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
    text-decoration: none;
    transition: background .12s ease, border-color .12s ease, box-shadow .12s ease;
}
.btn-outline:hover,
.secondary-btn:hover { background: var(--panel-2); border-color: var(--border-2); text-decoration: none; }

/* Ghost — quiet, borderless-ish action. */
.btn-ghost {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: var(--ctl);
    padding: 0 12px;
    background: transparent;
    color: var(--ink);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    font-size: 13.5px;
    font-weight: 600;
    font-family: inherit;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
    text-decoration: none;
}
.btn-ghost:hover { background: var(--panel-2); border-color: var(--accent); text-decoration: none; }

/* Danger — destructive confirm (e.g. Deny). */
.btn-danger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: var(--ctl);
    padding: 0 14px;
    background: transparent;
    color: var(--danger-ink);
    border: 1px solid var(--danger-border);
    border-radius: var(--r-md);
    font-size: 13.5px;
    font-weight: 600;
    font-family: inherit;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
    text-decoration: none;
}
.btn-danger:hover { background: var(--danger-bg); }

/* Compact (28px) in-row action. Standalone it is an outline button;
   .btn-sm.primary (or .btn.btn-sm) gets the accent fill. */
.btn-sm {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: var(--ctl-sm);
    padding: 0 10px;
    background: var(--panel);
    color: var(--ink-2);
    border: 1px solid var(--border-2);
    border-radius: var(--r-sm);
    font-size: 12.5px;
    font-weight: 600;
    font-family: inherit;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
    text-decoration: none;
}
.btn-sm:hover { border-color: var(--accent); color: var(--accent-ink); text-decoration: none; }
.btn-sm.primary, .btn.btn-sm { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.btn-sm.primary:hover, .btn.btn-sm:hover { background: var(--accent-dark); border-color: var(--accent-dark); }
.btn-block { width: 100%; }

/* --- Forms ---------------------------------------------------
   Full-width stacked field: a <label class="field"> wrapping its
   caption text and control, or a bare .field-input control. Mirrors
   the repeated inline "width:100%; padding:8px 10px; border:..."
   pattern that had been copy-pasted across the form templates. */
.field {
    display: block;
    margin-top: 14px;
}
.field:first-child { margin-top: 0; }
.field-input,
.field > input[type="text"],
.field > input[type="email"],
.field > input[type="number"],
.field > input[type="date"],
.field > input[type="password"],
.field > select,
.field > textarea {
    display: block;
    width: 100%;
    margin-top: 4px;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: 6px;
    font: inherit;
    font-size: 14px;
    color: var(--ink);
    background: var(--panel);
}
.field > textarea { resize: vertical; }
.field-help { display: block; margin-top: 4px; }

/* Baseline: give every stray form control a consistent, themed look
   even when it isn't inside a component that already styles it. This
   keeps selects/inputs correct in dark mode (native controls would
   otherwise render light). */
input[type="text"],
input[type="email"],
input[type="number"],
input[type="date"],
input[type="password"],
input[type="search"],
select,
textarea {
    font-family: inherit;
    font-size: 13.5px;
    color: var(--ink);
    background: var(--panel);
    border: 1px solid var(--border-2);
    border-radius: var(--r-md);
}
/* Single-line controls share the button height so a filter bar or an
   inline form lines up without per-screen nudging. Textareas keep their
   own height; the in-row compacts below drop to --ctl-sm. */
input[type="text"],
input[type="email"],
input[type="number"],
input[type="date"],
input[type="password"],
input[type="search"],
select {
    height: var(--ctl);
    padding: 0 10px;
}
textarea { padding: 8px 10px; }
.due-date-input,
.review-form .data-table select,
.review-form .data-table input,
.sched-row select,
.sched-row input[type="number"],
.sched-row input[type="date"],
.objection-editor input[type="number"] { height: var(--ctl-sm); padding: 0 6px; font-size: 13px; }
.due-date-input { border-color: transparent; background: transparent; border-radius: var(--r-sm); }
.due-date-input:hover, .due-date-input:focus { border-color: var(--border); background: var(--panel-2); }
[data-theme="dark"] .due-date-input:hover,
[data-theme="dark"] .due-date-input:focus { background: var(--panel-2); }
input[type="checkbox"],
input[type="radio"] { accent-color: var(--accent); }

/* --- Typography ---------------------------------------------- */
.page > .page-header:first-child { margin-bottom: 24px; }
.section-title {
    font-size: 15px;
    font-weight: 700;
    margin: 0 0 12px 0;
    color: var(--ink);
}

/* --- Spacing / layout utilities ------------------------------
   A small, fixed scale matching the values that were inline across
   templates, so presentational margins live in classes not style="". */
.m-0 { margin: 0 !important; }
.mt-0 { margin-top: 0; }
.mt-neg4 { margin-top: -4px; }
.mt-4  { margin-top: 4px; }   .mb-4  { margin-bottom: 4px; }
.mt-6  { margin-top: 6px; }   .mb-6  { margin-bottom: 6px; }
.mt-8  { margin-top: 8px; }   .mb-8  { margin-bottom: 8px; }
.mt-10 { margin-top: 10px; }  .mb-10 { margin-bottom: 10px; }
.mt-12 { margin-top: 12px; }  .mb-12 { margin-bottom: 12px; }
.mt-14 { margin-top: 14px; }  .mb-14 { margin-bottom: 14px; }
.mt-16 { margin-top: 16px; }  .mb-16 { margin-bottom: 16px; }
.mt-18 { margin-top: 18px; }  .mb-18 { margin-bottom: 18px; }
.mt-20 { margin-top: 20px; }  .mb-20 { margin-bottom: 20px; }
.mt-22 { margin-top: 22px; }  .mb-24 { margin-bottom: 24px; }
.mt-24 { margin-top: 24px; }
.inline-block { display: inline-block; }
.text-left { text-align: left; }
.text-center { text-align: center; }
.text-right { text-align: right; }
.link-right { float: right; font-size: 0.8rem; font-weight: 400; }

/* Inline form wrapper (was style="display:inline"). */
.inline-form { display: inline; }

/* A checkbox/radio sitting inline with its label + hint. */
.check-inline {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* Bordered sub-panel used inside forms (conditional field groups). */
.field-group {
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 12px;
}

/* Horizontal row of buttons/links (Reconnect/Disconnect, etc.). */
.btn-row {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
}

/* Row of side-by-side inputs (contact name/email/phone). */
.field-row {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}

/* Stack radios vertically (modifier on .radio-row). */
.radio-row.radio-col {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
}

.justify-start { justify-self: start; }
.self-end { align-self: end; }
.select-wide { min-width: 260px; }
.select-block { width: 100%; max-width: 420px; }
.maxw-240 { max-width: 240px; }

/* Logout must be a POST (Django's LogoutView is POST-only) -- render the
   agent-portal logout as a link-styled submit button so it matches the nav. */
.logout-inline { display: inline; margin: 0; }
.linklike {
    background: none;
    border: none;
    padding: 0;
    font: inherit;
    color: inherit;
    cursor: pointer;
}
.linklike:hover { text-decoration: underline; }

/* ============================================================
   Task Dashboard (task_dashboard.html + _task_bucket.html) -- slice 2
   of docs/ui-mockups/4-combined.html.

   Everything here is scoped to dashboard-only hook classes (.dash-header,
   .dash-toolbar, .dash-bucket, .dash-table) because .panel, .data-table,
   .task-bucket, .flag-actions etc. are shared with transaction_detail.html
   and ~20 other screens that this slice must not touch. Placed last in the
   file so equal-specificity ties against the older shared rules (incl. the
   [data-theme="dark"] overrides near the top) resolve to these.

   Safari-safe: no parent-matching selectors, container queries, colour
   mixing or nested rules.
   ============================================================ */

/* --- Page header + toolbar --------------------------------- */
.page-header.dash-header h1 { margin: 0; }
.page-header.dash-header .subhead { margin: 4px 0 0; }

.task-filters.dash-toolbar { gap: var(--s-2); margin-bottom: var(--s-5); }

/* Search: magnifier drawn as a data: URI (CSP img-src allows data:), so
   no wrapper element is needed around the input. */
.task-filters.dash-toolbar .dash-search {
    flex: 1 1 240px;
    min-width: 200px;
    height: var(--ctl);
    padding: 0 12px 0 34px;
    border: 1px solid var(--border-2);
    border-radius: var(--r-md);
    font-size: 13.5px;
    color: var(--ink);
    background-color: var(--panel);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: 11px 50%;
    background-size: 15px 15px;
}

/* Selects: flat 34px control with a drawn chevron (theme-aware via
   --muted) instead of the native bevel. */
.task-filters.dash-toolbar select {
    height: var(--ctl);
    padding: 0 30px 0 11px;
    border: 1px solid var(--border-2);
    border-radius: var(--r-md);
    font-size: 13.5px;
    color: var(--ink);
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
    background-color: var(--panel);
    background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%),
                      linear-gradient(135deg, var(--muted) 50%, transparent 50%);
    background-position: calc(100% - 16px) 50%, calc(100% - 11px) 50%;
    background-size: 5px 5px;
    background-repeat: no-repeat;
}

/* Was the template's inline <style> block. */
.sort-field { display: inline-flex; align-items: center; gap: 6px; }
.dash-toolbar .sort-field { font-size: 12.5px; font-weight: 500; color: var(--muted); white-space: nowrap; }

.task-filters.dash-toolbar .checkbox-option { height: var(--ctl); gap: 7px; padding: 0 4px; font-size: 13px; }

/* Sort-by-agent / sort-by-address group label (was inline <style>). */
.task-group-header {
    margin: 28px 0 10px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--border-2);
    color: var(--ink);
    font-size: 17px;
    font-weight: 700;
    letter-spacing: -.01em;
}
.task-group-header:first-of-type { margin-top: 8px; }

/* --- Bucket card: borderless shadow card, header row ------- */
.task-bucket.dash-bucket { padding: 0; overflow: hidden; margin-bottom: var(--s-4); }

.task-bucket.dash-bucket > h2 {
    display: flex;
    align-items: center;
    gap: 9px;
    margin: 0;
    padding: 11px 16px;
    border-bottom: 1px solid var(--border);
    font-size: 15px;
    font-weight: 650;
    line-height: 1.3;
    text-transform: none;
    letter-spacing: normal;
}
/* Status dot, drawn from the existing task-bucket-<key> class. */
.task-bucket.dash-bucket > h2::before {
    content: "";
    width: 8px; height: 8px; flex: 0 0 8px;
    border-radius: 50%;
    background: var(--faint);
}
.task-bucket.dash-bucket.task-bucket-overdue > h2::before { background: var(--red); }
.task-bucket.dash-bucket.task-bucket-today > h2::before,
.task-bucket.dash-bucket.task-bucket-attention > h2::before { background: var(--amber); }
.task-bucket.dash-bucket.task-bucket-this_week > h2::before { background: var(--accent); }

.dash-bucket .bucket-count { font-size: 13px; font-weight: 500; color: var(--muted); font-variant-numeric: tabular-nums; }

/* "Muted flags" link: float is ignored in a flex row, so push it right. */
.dash-bucket > h2 .link-right { float: none; margin-left: auto; font-size: 12.5px; font-weight: 500; }

/* Needs Attention: amber ring + tinted header, white body. Beats the
   older light/dark .task-bucket-attention fills on specificity. */
.task-bucket.dash-bucket.task-bucket-attention { border: 1px solid var(--warn-border); background: var(--panel); }
.task-bucket.dash-bucket.task-bucket-attention > h2 { background: var(--warn-bg); border-bottom-color: var(--warn-border); }

/* --- Table ------------------------------------------------- */
/* table-layout stays auto: the checkbox column has to grow to fit the
   "Send request" control on a gated review task. Percentage widths keep
   Property/Agent/TC/Due aligned across stacked buckets. */
.data-table.dash-table { width: 100%; border: none; border-radius: 0; background: transparent; }
.dash-table th {
    padding: 7px 12px;
    background: var(--panel-2);
    border-bottom: 1px solid var(--border);
    color: var(--muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    white-space: nowrap;
}
.dash-table td {
    height: 40px;
    padding: 6px 12px;
    border-bottom: 1px solid var(--border);
    font-size: 13.5px;
    vertical-align: middle;
}
.dash-table th:first-child, .dash-table td:first-child { padding-left: 16px; }
.dash-table th:last-child,  .dash-table td:last-child  { padding-right: 16px; }
.dash-table tbody tr:hover td { background: var(--panel-2); }

.dash-table .c-chk { width: 1%; white-space: nowrap; padding-right: 4px; }
.dash-table .c-task { font-weight: 500; color: var(--ink); }
.dash-table .c-prop { width: 26%; }
.dash-table .c-agent { width: 15%; color: var(--ink-2); }
.dash-table .c-tc { width: 14%; color: var(--ink-2); }
.dash-table .c-due { width: 1%; white-space: nowrap; }
.dash-table td.c-prop a { color: var(--ink-2); }
.dash-table td.c-prop a:hover { color: var(--accent-ink); }
.dash-table .subhead { margin: 0 0 0 4px; font-size: 12.5px; font-weight: 400; color: var(--muted); }

/* Completion toggle drawn as a 16px checkbox. The glyph stays in the
   button (its accessible name is the aria-label); it is only shown --
   in --on-accent on a filled box -- once the row is done. */
.dash-table .toggle-btn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 16px; height: 16px;
    padding: 0;
    border: 1.5px solid var(--border-2);
    border-radius: 4px;
    background: var(--panel);
    color: transparent;
    font-size: 11px; font-weight: 700; line-height: 1;
    vertical-align: middle;
    overflow: hidden;
}
.dash-table .toggle-btn:hover { border-color: var(--accent); color: transparent; }
.dash-table tr.task-done .toggle-btn,
.dash-table tr.task-done .toggle-btn:hover { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }

/* Review-request gate: "Send request" as a compact in-row action. */
.dash-table .c-chk .mini { height: 24px; padding: 0 8px; font-size: 12px; color: var(--ink-2); background: var(--panel); border-color: var(--border-2); }
.dash-table .c-chk .mini:hover { color: var(--accent-ink); border-color: var(--accent); }

/* Critical: red rail on the row's first cell (inset shadow survives the
   hover fill and doesn't shift content the way a row border-left does). */
.dash-table tr.task-critical { border-left: 0; }
.dash-table tr.task-critical td:first-child { box-shadow: inset 3px 0 0 var(--red); }

/* Done: legible but receded, title struck through (replaces opacity). */
.dash-table tr.task-done { opacity: 1; }
.dash-table tr.task-done td { color: var(--muted); }
.dash-table tr.task-done td.c-task { font-weight: 400; text-decoration: line-through; }
.dash-table tr.task-done td.c-prop a { color: var(--muted); }

/* --- Due-date chip ------------------------------------------
   The editable <input type="date"> itself is the chip, tinted by the
   bucket it sits in (the section already carries task-bucket-<key>). */
.dash-table .due-date-input {
    height: 26px;
    padding: 0 6px;
    border: 1px solid transparent;
    border-radius: var(--r-sm);
    background: transparent;
    color: var(--muted);
    font-size: 12.5px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    cursor: pointer;
}
.dash-table .due-date-input:hover,
.dash-table .due-date-input:focus { border-color: var(--border-2); background: var(--panel-2); }
[data-theme="dark"] .dash-table .due-date-input { color-scheme: dark; }

.dash-bucket.task-bucket-overdue .due-date-input,
.dash-bucket.task-bucket-overdue .due-date-input:hover,
.dash-bucket.task-bucket-overdue .due-date-input:focus { color: var(--danger-ink); background: var(--danger-bg); border-color: var(--danger-border); }
.dash-bucket.task-bucket-today .due-date-input,
.dash-bucket.task-bucket-today .due-date-input:hover,
.dash-bucket.task-bucket-today .due-date-input:focus { color: var(--warn-ink); background: var(--warn-bg); border-color: var(--warn-border); }
.dash-bucket.task-bucket-this_week .due-date-input { color: var(--ink-2); background: var(--bg); border-color: var(--border); }
.dash-bucket.task-bucket-this_week .due-date-input:hover,
.dash-bucket.task-bucket-this_week .due-date-input:focus { border-color: var(--border-2); }
.dash-bucket.task-bucket-overdue .due-date-input:hover,
.dash-bucket.task-bucket-today .due-date-input:hover { border-color: currentColor; }

/* A finished task's date isn't urgent, whatever bucket it's in. */
.dash-bucket .dash-table tr.task-done .due-date-input { color: var(--muted); background: transparent; border-color: transparent; font-weight: 500; }
.dash-bucket .dash-table tr.task-done .due-date-input:hover,
.dash-bucket .dash-table tr.task-done .due-date-input:focus { border-color: var(--border-2); background: var(--panel-2); }

/* --- Needs Attention rows ---------------------------------- */
.dash-flag-table td { height: auto; padding-top: 10px; padding-bottom: 10px; line-height: 1.45; vertical-align: top; }
.dash-flag-table .c-flag { color: var(--ink); }
.dash-flag-table .c-prop { width: 24%; }
.dash-flag-table .c-actions { width: 340px; }
.dash-bucket .flag-quote { margin: 5px 0 3px; padding-left: 9px; border-left: 2px solid var(--warn-border); font-size: 12.5px; }
.dash-flag-table .c-flag .flag-source-link { font-size: 12.5px; }

/* Shared .flag-actions is display:flex, which takes a <td> out of the
   table's row box; restore a real cell and lay the forms out inline. */
.dash-bucket td.flag-actions { display: table-cell; text-align: right; }
.dash-bucket .flag-actions .toggle-form {
    display: inline-flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 4px;
    margin: 0 0 4px 4px;
    vertical-align: top;
}
.dash-bucket .flag-action-btn {
    display: inline-flex; align-items: center;
    height: var(--ctl-sm);
    padding: 0 10px;
    border: 1px solid var(--border-2);
    border-radius: var(--r-sm);
    background: var(--panel);
    color: var(--ink-2);
    font-family: inherit; font-size: 12.5px; font-weight: 600; line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
}
.dash-bucket .flag-action-btn:hover { border-color: var(--accent); color: var(--accent-ink); }
.dash-bucket .flag-action-btn.flag-action-btn--primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.dash-bucket .flag-action-btn.flag-action-btn--primary:hover { background: var(--accent-dark); border-color: var(--accent-dark); color: var(--on-accent); }

/* --- Stat strip (slice 3) -----------------------------------
   Tiles are <a href="#bucket-..."> when their bucket is on the page and
   plain <div>s otherwise (zero count, or task tiles in agent/address sort);
   both look the same, only the link gets hover lift. */
.dash-stats {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--s-3);
    margin-bottom: var(--s-5);
}
.dash-stat {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 14px 16px;
    background: var(--panel);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow);
    color: var(--ink);
    text-decoration: none;
}
a.dash-stat { transition: box-shadow .12s ease; }
a.dash-stat:hover { box-shadow: var(--shadow-2); text-decoration: none; color: var(--ink); }
.dash-stat-k {
    display: flex;
    align-items: center;
    gap: 7px;
    color: var(--muted);
    font-size: 12.5px;
    font-weight: 500;
}
.dash-stat-dot { width: 8px; height: 8px; flex: 0 0 8px; border-radius: 50%; background: var(--faint); }
.dash-stat--overdue .dash-stat-dot { background: var(--red); }
.dash-stat--today .dash-stat-dot { background: var(--amber); }
.dash-stat--this_week .dash-stat-dot { background: var(--accent); }
.dash-stat--attention .dash-stat-dot { background: var(--blue); }
.dash-stat-v {
    font-size: 24px;
    font-weight: 700;
    letter-spacing: -.02em;
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
}
.dash-stat.is-hot .dash-stat-v { color: var(--danger-ink); }

/* Jump targets: leave a little air above the card after a #bucket-* jump. */
.task-bucket.dash-bucket { scroll-margin-top: var(--s-4); }

/* --- Segmented sort (slice 3) -------------------------------
   Real submit buttons in the GET form (name="sort"). Specificity (0,3,0)
   deliberately beats the shared ".task-filters button" primary-button
   rules (0,2,1) so the segments read as a toggle group, not three CTAs. */
.task-filters.dash-toolbar .dash-seg {
    display: inline-flex;
    align-items: stretch;
    gap: 2px;
    height: var(--ctl);
    padding: 3px;
    background: var(--panel);
    border: 1px solid var(--border-2);
    border-radius: var(--r-md);
}
.dash-seg .dash-seg-label {
    align-self: center;
    padding: 0 4px 0 8px;
    color: var(--muted);
    font-size: 12px;
    font-weight: 500;
    white-space: nowrap;
}
.task-filters.dash-toolbar .dash-seg-btn {
    display: inline-flex;
    align-items: center;
    height: auto;
    padding: 0 11px;
    background: transparent;
    border: none;
    border-radius: 5px;
    color: var(--muted);
    font-size: 12.5px;
    font-weight: 600;
    transition: none;
}
.task-filters.dash-toolbar .dash-seg-btn:hover { background: var(--panel-2); color: var(--ink); border-color: transparent; }
.task-filters.dash-toolbar .dash-seg-btn.is-on,
.task-filters.dash-toolbar .dash-seg-btn.is-on:hover { background: var(--tint); color: var(--accent-ink); }

/* The invisible implicit-submission default (see task_dashboard.html):
   rendered but clipped -- not display:none, which some browsers skip when
   choosing the default button for Enter-to-submit. */
.task-filters.dash-toolbar .dash-default-submit {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

/* --- Bucket count chip (slice 3) --------------------------- */
.task-bucket.dash-bucket .bucket-count {
    display: inline-block;
    padding: 1px 8px;
    background: var(--panel-2);
    border: 1px solid var(--border);
    border-radius: 999px;
    color: var(--muted);
    font-size: 12px;
    font-weight: 600;
    line-height: 1.4;
}

/* --- Relative due label ("5d late" / "Today" / "in 3d") ----
   Sits beside the editable date input, outside its form. */
.dash-table .dash-due-rel {
    display: inline-block;
    margin-left: 6px;
    color: var(--muted);
    font-size: 12px;
    font-weight: 500;
    vertical-align: middle;
}
.dash-table .dash-due-rel--overdue { color: var(--danger-ink); font-weight: 600; }
.dash-table .dash-due-rel--today { color: var(--warn-ink); font-weight: 600; }

/* --- Narrow screens: scroll the table inside its card ------ */
@media (max-width: 820px) {
    .task-bucket.dash-bucket { overflow-x: auto; -webkit-overflow-scrolling: touch; }
    .data-table.dash-table { min-width: 620px; }
    .task-filters.dash-toolbar .dash-search { flex-basis: 100%; }
    .dash-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ============================================================
   Authentication screens -- slice 3 of docs/ui-mockups/4-combined.html.
   login, password reset (x4), MFA setup / verify / recovery codes use a
   centred card (.auth-shell > .auth-card); mfa_manage is a normal app page
   (.auth-manage) because it's reached from the sidebar.

   Every rule is scoped to an auth-* hook so no other screen is affected
   (the generic .field / .login-box / .recovery-codes names are avoided:
   .field is already a shared form class with different layout).
   Instructions read in --ink-2; --muted is kept for hints and footnotes.

   Safari-safe: no parent-matching selectors, container queries, colour
   mixing or nested rules. :not() takes a single simple selector only.
   ============================================================ */

/* Logged-out pages have no rail, but the shell keeps its constant rail
   offset, so the centred card would sit half a rail-width right of the
   viewport centre. When signed out, .app is the first element in <body>
   (the icon sprite, mobile bar and backdrop only render when show_chrome is
   true -- not for signed-out users, nor for a password-only session that
   still owes its second factor), so this nudges the auth card back -- and touches nothing else,
   including other logged-out pages such as the public agent onboarding
   form. If base.html ever gains an element before .app, this simply stops
   matching: cosmetic, never broken. Below 821px the offset is already 0. */
@media (min-width: 821px) {
    body > .app:first-child .auth-shell,
    body > .app:first-child .flash-stack { position: relative; left: calc(var(--rail-w) * -0.5); }
}

.auth-shell {
    width: 100%;
    max-width: 420px;
    margin: 0 auto;
    min-height: calc(100vh - 56px);   /* .page top + bottom padding */
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: var(--s-4) 0 var(--s-6);
}
.auth-shell--wide { max-width: 520px; }

.auth-brand {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    margin-bottom: 22px;
    color: var(--ink);
}
.auth-brand .rail-logo { width: 36px; height: 36px; flex-basis: 36px; border-radius: 10px; font-size: 18px; }
.auth-brand .rail-name { font-size: 20px; }

.auth-card {
    background: var(--panel);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-2);
    padding: 32px 32px 28px;
}
.auth-card h1 {
    margin: 0 0 6px;
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -.02em;
    line-height: 1.2;
    color: var(--ink);
}
/* A heading followed straight by a form / notice / button (no lede) still
   needs breathing room. */
.auth-card > h1 + :not(.auth-lede) { margin-top: 18px; }

.auth-lede { margin: 0 0 20px; color: var(--ink-2); font-size: 14px; line-height: 1.5; }

/* --- Alerts: shared .notice tints, tightened for the card -------- */
.auth-card .auth-alert,
.auth-manage .auth-alert { margin: 0 0 16px; padding: 10px 12px; font-size: 13.5px; line-height: 1.45; }
.auth-form .auth-alert { margin: 0; }
.auth-alert p { margin: 0; }
.auth-alert p + p { margin-top: 4px; }
.auth-alert .auth-alert-strong { font-weight: 600; }
/* "Save these now" -- the one warning on these screens that must not be
   skimmed past, so it gets a solid amber edge on top of the warn tint. */
.auth-card .auth-alert--save { padding: 12px 14px; font-size: 14px; box-shadow: inset 4px 0 0 var(--amber); }

/* --- Form ------------------------------------------------------ */
.auth-form { display: flex; flex-direction: column; gap: 14px; margin: 0; }
.auth-field { display: flex; flex-direction: column; gap: 6px; }
.auth-field label { font-size: 13px; font-weight: 600; color: var(--ink-2); }
.auth-card .auth-field input {
    width: 100%;
    height: 40px;
    padding: 0 12px;
    border: 1px solid var(--border-2);
    border-radius: var(--r-md);
    background: var(--panel);
    color: var(--ink);
    font-family: inherit;
    font-size: 14.5px;
}
.auth-card .auth-field input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--tint);
}

/* One-time code: large monospace, spaced, centred. text-indent matches
   the letter-spacing so the trailing gap after the last digit doesn't
   pull the code off-centre. */
.auth-card .auth-field--code input {
    height: 48px;
    font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    font-size: 22px;
    letter-spacing: .35em;
    text-indent: .35em;
    text-align: center;
    font-variant-numeric: tabular-nums;
}
.auth-card .auth-field--code input::placeholder { color: var(--faint); opacity: 1; }

/* Primary action: full width, 40px on these single-column forms. Also
   used on <a class="btn auth-submit"> link-buttons. */
.auth-card .auth-submit { width: 100%; height: 40px; font-size: 14px; }
.auth-form .auth-submit { margin-top: 4px; }

.auth-note {
    margin: 18px 0 0;
    padding-top: 14px;
    border-top: 1px solid var(--border);
    color: var(--muted);
    font-size: 13px;
    line-height: 1.5;
}
.auth-note p { margin: 0; }
.auth-note p + p { margin-top: 6px; }

.auth-foot { margin: 16px 0 0; text-align: center; font-size: 13.5px; font-weight: 500; }

/* --- MFA setup: numbered steps, QR + manual key ---------------- */
.auth-steps {
    list-style: none;
    margin: 0 0 20px;
    padding: 0;
    counter-reset: auth-step;
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.auth-steps > li {
    display: grid;
    grid-template-columns: 26px minmax(0, 1fr);
    gap: 12px;
    color: var(--ink-2);
    font-size: 14px;
    line-height: 1.5;
}
.auth-steps > li::before {
    counter-increment: auth-step;
    content: counter(auth-step);
    width: 26px;
    height: 26px;
    margin-top: -1px;
    border-radius: 50%;
    background: var(--tint);
    color: var(--accent-ink);
    font-size: 12.5px;
    font-weight: 700;
    display: grid;
    place-items: center;
}
.auth-steps strong { color: var(--ink); }

.auth-qr-row { display: flex; align-items: flex-start; gap: 18px; margin-top: 10px; }
/* White in BOTH themes on purpose: the QR is dark modules on a transparent
   background and has to sit on light for a camera to read it. */
.auth-qr {
    flex: 0 0 168px;
    width: 168px;
    height: 168px;
    padding: 8px;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: var(--r-md);
}
.auth-qr img { display: block; width: 100%; height: 100%; }
.auth-secret { flex: 1 1 auto; min-width: 0; }
.auth-hint { margin: 0 0 6px; color: var(--muted); font-size: 12.5px; }
.auth-secret code {
    display: block;
    padding: 8px 10px;
    background: var(--panel-2);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    color: var(--ink);
    font: 13px/1.5 ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    letter-spacing: .04em;
    word-break: break-all;
    -webkit-user-select: all;
    user-select: all;
}
.auth-secret .auth-copy { margin-top: 8px; }
/* .btn-sm sets display, which beats the UA [hidden] rule; without this the
   copy buttons would show (dead) before/without the script. */
.auth-copy[hidden] { display: none; }

/* --- Recovery codes: numbered monospace grid ------------------ */
.auth-codes {
    list-style: none;
    margin: 0 0 10px;
    padding: 12px;
    counter-reset: auth-code;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
    background: var(--panel-2);
    border: 1px dashed var(--border-2);
    border-radius: var(--r-lg);
}
.auth-codes li {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 8px 12px;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
}
.auth-codes li::before {
    counter-increment: auth-code;
    content: counter(auth-code);
    min-width: 1.4em;
    color: var(--faint);
    font-size: 12px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    text-align: right;
}
/* Monospace and spaced so 0/O and 1/l can't be confused when copied by
   hand -- a misread code means a lock-out at the worst possible moment. */
.auth-codes code {
    color: var(--ink);
    font: 15px/1.4 ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    letter-spacing: .08em;
    -webkit-user-select: all;
    user-select: all;
}
.auth-codes-tools { display: flex; justify-content: flex-end; margin: 0 0 18px; }

/* --- mfa_manage: ordinary app page with panels ------------------ */
.auth-manage { max-width: 760px; }
.auth-manage .page-header { margin-bottom: var(--s-5); }
.auth-manage .panel + .panel { margin-top: var(--s-4); }
.auth-manage-count { margin: 0 0 14px; color: var(--ink-2); font-size: 14px; line-height: 1.5; }
.auth-manage-low { display: block; margin-top: 2px; color: var(--warn-ink); font-weight: 600; }
.auth-manage-action { margin: 0; }
.auth-manage-help { margin: 8px 0 0; color: var(--muted); font-size: 13px; line-height: 1.5; }
.auth-manage-text { margin: 0; color: var(--ink-2); font-size: 14px; line-height: 1.5; }

@media (max-width: 820px) {
    /* Top-align on small screens (and under the mobile bar when signed in)
       rather than centring in a viewport the keyboard is about to halve. */
    .auth-shell { min-height: 0; justify-content: flex-start; padding-top: var(--s-2); }
}
@media (max-width: 560px) {
    .auth-card { padding: 24px 20px; }
    .auth-qr-row { flex-direction: column; }
}

/* ---- Flash messages (django.contrib.messages), rendered by base.html ---- */
.flash-stack { display: grid; gap: var(--s-2); max-width: 760px; margin: 0 0 var(--s-4); }
.flash-stack .notice { margin: 0; }
/* On the centred auth screens, line the message up with the card. */
body > .app:first-child .flash-stack { max-width: 420px; margin-left: auto; margin-right: auto; }
/* Pre-2FA sign-out link under the setup/verify card. */
.auth-signout { margin-top: var(--s-4); text-align: center; }
.auth-signout button { background: none; border: 0; padding: 0; color: var(--accent-ink); font: inherit; cursor: pointer; text-decoration: underline; }

/* ============================================================
   Form system -- slice 4a of docs/ui-mockups/4-combined.html.
   The everyday create/edit screens: transaction start / close / date
   edit + confirm, date-change review, agent form, invoicing record,
   checklist-learning prompt, email template form, email compose, and
   the public agent onboarding form + thanks page.

   Everything is scoped to form-* hooks. The older shared form classes
   (.field, .field-input, .review-form, .review-field-grid, .close-form,
   .prompt-actions, .radio-option, .checkbox-option, .field-group,
   .field-row, .form-error) are still used by ~10 screens outside this
   slice and are deliberately left untouched.

   Vocabulary:
     .form-page            width wrapper (+ --narrow / --wide)
     .form-layout          main card + .form-aside column (agent edit)
     .form-card            borderless shadow card; holds sections
     .form-card-head       title block inside a card (public form)
     .form-section         padded block, hairline between siblings
     .form-section-head    .form-section-title + .form-section-help
     .form-stack           vertical rhythm for fields / grids
     .form-grid            2-col (--3 / --4 / --pairs), 1-col <=820px
     .form-field           label + control + help/error stack
     .form-label           13px/600 --ink-2 (--req adds the marker)
     .form-help            muted hint text
     .form-check           checkbox/radio + text on one line
     .form-choices         list of checks (--inline / --cards)
     .form-choice          bordered option card for a radio
     .form-subgroup        tinted conditional group (billing contact)
     .form-actions         footer button row (--sticky); primary first
     .form-diff*           old-vs-new tables and added/removed lists

   Button order (applied everywhere in this slice): primary first on the
   left, then the secondary/cancel. Matches every not-yet-restyled
   .prompt-actions row in the app, keeps DOM = visual = tab order, and
   leaves the browser's implicit Enter-submit default unchanged.

   Safari-safe: no parent-matching selectors, container queries, colour
   mixing or nested rules. :not() takes a single simple selector only.
   ============================================================ */

/* --- Page widths / layout ---------------------------------- */
.form-page { max-width: 820px; }
.form-page--narrow { max-width: 640px; }
.form-page--wide { max-width: 1120px; }
.form-page > .page-header { margin-bottom: var(--s-5); }
.form-page > .page-header .subhead { margin: 4px 0 0; max-width: 72ch; line-height: 1.5; }

.form-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 340px;
    gap: var(--s-5);
    align-items: start;
}
.form-aside { display: flex; flex-direction: column; gap: var(--s-4); }
.form-aside .form-card { margin: 0; }
.form-aside .form-section { padding: var(--s-4) var(--s-5); }

/* Banners sitting between the page header and the card. */
.form-notice-top { margin: 0 0 var(--s-4); padding: 10px 14px; font-size: 13.5px; line-height: 1.5; }
/* Banners inside a card section. */
.form-notice { margin: 0; padding: 10px 12px; font-size: 13.5px; line-height: 1.5; }
.form-notice p { margin: 0; }
.form-notice p + p, .form-notice p + div, .form-notice div + p { margin-top: 8px; }

/* --- Card + sections --------------------------------------- */
/* No overflow:hidden here -- it would stop .form-actions--sticky from
   sticking (a sticky child sticks to its nearest scrolling ancestor). */
.form-card {
    display: block;
    margin: 0 0 var(--s-4);
    background: var(--panel);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow);
}
.form-card--quiet { background: var(--panel-2); box-shadow: none; border: 1px solid var(--border); }

.form-card-head { padding: var(--s-6) var(--s-6) var(--s-5); border-bottom: 1px solid var(--border); }
.form-card-head h1 { margin: 0 0 6px; font-size: 22px; font-weight: 700; letter-spacing: -.02em; line-height: 1.2; color: var(--ink); }
.form-lede { margin: 0; color: var(--ink-2); font-size: 14px; line-height: 1.55; max-width: 72ch; }

.form-section { display: block; margin: 0; padding: var(--s-5) var(--s-6); }
.form-section + .form-section { border-top: 1px solid var(--border); }
.form-section-head { margin: 0 0 var(--s-4); }
.form-card .form-section-title {
    margin: 0;
    color: var(--ink);
    font-size: 15px;
    font-weight: 650;
    letter-spacing: -.005em;
    line-height: 1.3;
    text-transform: none;
}
.form-section-help { margin: 4px 0 0; color: var(--muted); font-size: 13px; line-height: 1.5; max-width: 72ch; }
.form-prose p { margin: 0; color: var(--ink-2); font-size: 14px; line-height: 1.6; }
.form-prose p strong { color: var(--ink); }
/* Short bulleted explainer ("What happens" on Cancel transaction). */
.form-bullets { margin: 0; padding-left: 18px; color: var(--ink-2); font-size: 14px; line-height: 1.6; }
.form-bullets li + li { margin-top: 2px; }
.form-bullets strong { color: var(--ink); }

/* Text + one action side by side (manual-start card). */
.form-split { display: flex; align-items: center; gap: var(--s-5); }
.form-split-text { flex: 1 1 auto; min-width: 0; }
.form-split-action { flex: 0 0 auto; margin: 0; }

/* --- Stacks + grids ---------------------------------------- */
.form-stack { display: flex; flex-direction: column; gap: var(--s-4); }
.form-stack--md { max-width: 420px; }

.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-4) var(--s-5); }
.form-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.form-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-3) var(--s-4); }
/* Checkbox in the left column, its date on the right. */
.form-grid--pairs { grid-template-columns: minmax(0, 1fr) minmax(0, 220px); }

/* --- Field ------------------------------------------------- */
.form-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; margin: 0; }
.form-field--sm { max-width: 240px; }
.form-label { color: var(--ink-2); font-size: 13px; font-weight: 600; line-height: 1.3; }
/* Required marker. Purely visual: the control's own `required` attribute
   is what assistive tech announces. */
.form-label--req::after { content: "*"; margin-left: 3px; color: var(--danger-ink); font-weight: 700; }
.form-optional { color: var(--muted); font-size: 12.5px; font-weight: 400; }
.form-help { margin: 0; color: var(--muted); font-size: 12.5px; line-height: 1.5; }
.form-help strong { color: var(--ink-2); }
.form-field-error { margin: 0; color: var(--danger-ink); font-size: 12.5px; font-weight: 500; line-height: 1.4; }

/* Controls. One height (--ctl), one border, one focus ring. */
.form-card input[type="text"],
.form-card input[type="email"],
.form-card input[type="number"],
.form-card input[type="date"],
.form-card input[type="password"],
.form-card input[type="search"],
.form-card input[type="tel"],
.form-card input[type="url"],
.form-card select,
.form-card textarea {
    width: 100%;
    height: var(--ctl);
    margin: 0;
    padding: 0 10px;
    border: 1px solid var(--border-2);
    border-radius: var(--r-md);
    background-color: var(--panel);
    color: var(--ink);
    font-family: inherit;
    font-size: 13.5px;
    transition: border-color .12s ease, box-shadow .12s ease;
}
.form-card textarea { height: auto; min-height: 96px; padding: 8px 10px; line-height: 1.55; resize: vertical; }
.form-card .form-textarea-mail { min-height: 260px; }
.form-card select:not([multiple]) {
    padding-right: 30px;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
    background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%),
                      linear-gradient(135deg, var(--muted) 50%, transparent 50%);
    background-position: calc(100% - 16px) 50%, calc(100% - 11px) 50%;
    background-size: 5px 5px;
    background-repeat: no-repeat;
}
.form-card select[multiple] { height: auto; padding: 4px; }
.form-card select[multiple] option { padding: 4px 6px; border-radius: 4px; }
.form-card .form-multi { max-width: 420px; }
.form-card input::placeholder,
.form-card textarea::placeholder { color: var(--faint); opacity: 1; }
.form-card input:hover:not(:disabled),
.form-card select:hover,
.form-card textarea:hover { border-color: var(--faint); }
.form-card input:focus,
.form-card select:focus,
.form-card textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--tint); }
.form-card input:disabled,
.form-card input[readonly] { background-color: var(--panel-2); color: var(--ink-2); }
.form-card input:disabled { cursor: not-allowed; }
.form-card input[readonly]:hover { border-color: var(--border-2); }
[data-theme="dark"] .form-card input,
[data-theme="dark"] .form-card select,
[data-theme="dark"] .form-card textarea { color-scheme: dark; }

/* Error state: .form-field.is-invalid, or Django's own markup (an
   errorlist rendered just before its control by as_p / field loops). */
.form-field.is-invalid input,
.form-field.is-invalid select,
.form-field.is-invalid textarea,
.form-card .errorlist + input,
.form-card .errorlist + select,
.form-card .errorlist + textarea { border-color: var(--red); }
.form-field.is-invalid input:focus,
.form-field.is-invalid select:focus,
.form-field.is-invalid textarea:focus,
.form-card .errorlist + input:focus,
.form-card .errorlist + select:focus,
.form-card .errorlist + textarea:focus { border-color: var(--red); box-shadow: 0 0 0 3px var(--danger-bg); }
.form-card ul.errorlist { margin: 0; padding: 0; list-style: none; color: var(--danger-ink); font-size: 12.5px; font-weight: 500; line-height: 1.4; }
.form-card ul.errorlist li + li { margin-top: 2px; }
.form-card ul.errorlist.nonfield {
    margin: 0 0 var(--s-4);
    padding: 10px 12px;
    background: var(--danger-bg);
    border: 1px solid var(--danger-border);
    border-radius: var(--r-md);
    font-size: 13.5px;
}

/* Author display rules beat the UA [hidden] rule; keep JS-toggled
   blocks (#billing-contact*, #share-with-box, #compose-warning) hidden. */
.form-card [hidden],
.form-page [hidden] { display: none !important; }

/* Read-only value + copy button (onboarding link). */
.form-inline { display: flex; align-items: center; gap: var(--s-2); }
.form-inline > input { flex: 1 1 auto; min-width: 0; }
.form-inline > button { flex: 0 0 auto; }

/* --- Checks / radios --------------------------------------- */
.form-check {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    margin: 0;
    color: var(--ink);
    font-size: 13.5px;
    line-height: 1.45;
    cursor: pointer;
}
.form-check input[type="checkbox"],
.form-check input[type="radio"],
.form-choice input[type="radio"] { flex: 0 0 16px; width: 16px; height: 16px; margin: 1px 0 0; accent-color: var(--accent); cursor: pointer; }
/* A checkbox sharing a grid row with a labelled control: line it up with
   that control, not with its label. */
.form-check--field { align-self: end; align-items: center; min-height: var(--ctl); }
.form-check--field input[type="checkbox"] { margin-top: 0; }

.form-choices { display: flex; flex-direction: column; gap: var(--s-2); }
.form-choices--inline { flex-direction: row; flex-wrap: wrap; gap: var(--s-2) var(--s-5); }
.form-choices--cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--s-2); }

/* Option card. The selected outline + tint is drawn by a pseudo-element
   on the text span, positioned against the card -- no parent selector
   needed. z-index 0 on the card makes it a stacking context so the
   z-index:-1 tint paints above the card background, below the text. */
.form-choice {
    position: relative;
    z-index: 0;
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin: 0;
    padding: 10px 12px;
    background: var(--panel);
    border: 1px solid var(--border-2);
    border-radius: var(--r-md);
    cursor: pointer;
    transition: border-color .12s ease;
}
.form-choice:hover { border-color: var(--faint); }
.form-choice-text { display: flex; flex-direction: column; gap: 2px; color: var(--ink); font-size: 13.5px; font-weight: 600; line-height: 1.4; }
.form-choice-hint { color: var(--muted); font-size: 12.5px; font-weight: 400; line-height: 1.45; }
.form-choice input:checked + .form-choice-text { color: var(--accent-ink); }
.form-choice input:checked + .form-choice-text::before {
    content: "";
    position: absolute;
    top: -1px; right: -1px; bottom: -1px; left: -1px;
    z-index: -1;
    border: 1.5px solid var(--accent);
    border-radius: var(--r-md);
    background: var(--tint);
    pointer-events: none;
}
.form-choice input:focus-visible + .form-choice-text::after {
    content: "";
    position: absolute;
    top: -1px; right: -1px; bottom: -1px; left: -1px;
    border-radius: var(--r-md);
    box-shadow: 0 0 0 3px var(--tint);
    pointer-events: none;
}
.form-choice input:focus-visible { outline: none; }

/* Conditional group revealed by a radio choice. */
.form-subgroup {
    padding: var(--s-4);
    background: var(--panel-2);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
}

/* Repeating rows (CC contacts). */
.form-repeat { display: flex; flex-direction: column; }
.form-repeat-row { padding: var(--s-3) 0; border-top: 1px dashed var(--border); }
.form-repeat-row:first-child { padding-top: 0; border-top: none; }
.form-repeat-row:last-child { padding-bottom: 0; }

/* --- Actions footer ---------------------------------------- */
.form-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--s-2);
    margin: 0;
    padding: var(--s-3) var(--s-6);
    background: var(--panel-2);
    border-top: 1px solid var(--border);
    border-radius: 0 0 var(--r-lg) var(--r-lg);
}
/* Long forms: the button row rides the bottom of the viewport until the
   card's own bottom scrolls into view. */
.form-actions--sticky { position: -webkit-sticky; position: sticky; bottom: 0; z-index: 5; }
.form-actions-note { flex: 1 1 260px; margin: 0 0 0 var(--s-2); color: var(--muted); font-size: 12.5px; line-height: 1.45; }
/* Live warning in the compose footer ("No To recipient selected yet."). */
.form-actions-alert { flex: 1 1 260px; margin: 0 0 0 var(--s-2); color: var(--warn-ink); font-size: 12.5px; font-weight: 600; line-height: 1.45; }

/* --- Tables inside form cards ------------------------------ */
.form-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.form-card .data-table { border: 1px solid var(--border); border-radius: var(--r-md); background: var(--panel); }
.form-card .data-table th {
    padding: 7px 12px;
    background: var(--panel-2);
    color: var(--muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    white-space: nowrap;
}
.form-card .data-table td { padding: 9px 12px; font-size: 13.5px; vertical-align: middle; }
.form-card .data-table .empty-state { padding: 18px !important; }
.form-empty { margin: 0; padding: 14px 16px; background: var(--panel-2); border: 1px dashed var(--border-2); border-radius: var(--r-md); color: var(--muted); font-size: 13.5px; text-align: center; }

/* Old vs new: old receded + struck, new as an accent chip. */
.form-diff .form-diff-label { color: var(--ink); font-weight: 500; }
.form-diff .form-diff-date { width: 1%; white-space: nowrap; font-variant-numeric: tabular-nums; }
.form-diff-old { color: var(--muted); text-decoration: line-through; text-decoration-color: var(--faint); }
.form-diff-none { color: var(--faint); font-style: italic; }
.form-diff-new {
    display: inline-block;
    padding: 1px 8px;
    background: var(--tint);
    border-radius: var(--r-sm);
    color: var(--accent-ink);
    font-weight: 600;
}
.form-diff-cleared {
    display: inline-block;
    padding: 1px 8px;
    background: var(--danger-bg);
    border-radius: var(--r-sm);
    color: var(--danger-ink);
    font-weight: 600;
}
.form-diff .form-diff-shift { width: 1%; text-align: right; white-space: nowrap; }
.form-shift { color: var(--faint); font-size: 12.5px; font-weight: 600; font-variant-numeric: tabular-nums; }
.form-shift--later { color: var(--info-ink); }
.form-shift--earlier { color: var(--warn-ink); }

/* Added / removed checklist items (close-out). */
.form-diff-groups { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--s-3) var(--s-5); }
.form-diff-head { margin: 0 0 6px; color: var(--ink-2); font-size: 13px; }
.form-diff-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 4px; }
.form-diff-list li { display: flex; align-items: baseline; gap: 8px; color: var(--ink); font-size: 13.5px; line-height: 1.45; }
.form-diff-list li::before {
    flex: 0 0 18px;
    width: 18px;
    height: 18px;
    border-radius: 5px;
    font-size: 12px;
    font-weight: 700;
    line-height: 18px;
    text-align: center;
}
.form-diff-list--added li::before { content: "+"; background: var(--ok-bg); color: var(--ok-ink); }
.form-diff-list--removed li::before { content: "\2212"; background: var(--danger-bg); color: var(--danger-ink); }
.form-diff-list--removed li { color: var(--ink-2); }

/* --- Upload dropzone (transaction_start) ------------------- */
/* The real file input covers the whole zone (transparent), so a file
   dropped anywhere on it lands in the input instead of the browser
   opening the PDF; clicking anywhere opens the picker. The zone shows
   keyboard focus via :focus-within. */
.upload-dropzone.form-drop {
    position: relative;
    gap: 10px;
    padding: 36px 24px;
    background: var(--panel-2);
    border: 1.5px dashed var(--border-2);
    border-radius: var(--r-lg);
    color: var(--ink-2);
    transition: border-color .12s ease, background .12s ease;
}
.upload-dropzone.form-drop:hover { border-color: var(--accent); background: var(--tint); color: var(--ink); }
.upload-dropzone.form-drop:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--tint); }
.form-drop input[type="file"] {
    position: absolute;
    top: 0; left: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    opacity: 0;
    cursor: pointer;
}
.form-drop-icon { width: 30px; height: 30px; color: var(--accent-ink); }
.form-drop-text { max-width: 40ch; font-size: 14px; font-weight: 500; line-height: 1.5; }
.form-file-list:empty { display: none; }
.form-file-list li { color: var(--ink-2); }

/* --- Email compose ----------------------------------------- */
.form-recipients .c-pick { width: 44px; text-align: center; }
.form-recipients td.c-pick input { width: 16px; height: 16px; margin: 0; vertical-align: middle; }
.form-recipients .c-name { color: var(--ink); font-weight: 500; }
.form-recipients .c-role { color: var(--ink-2); }
.form-recipients .c-email { color: var(--ink-2); }
.form-recipients tr.is-off td { color: var(--muted); }
.form-row-tag { color: var(--muted); font-size: 12.5px; font-weight: 400; }

.form-drafts .c-when { width: 1%; white-space: nowrap; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.form-drafts .c-act { width: 1%; text-align: right; white-space: nowrap; }
/* The row being edited keeps its legacy task-critical class; restyle it
   from a red "critical" rail into a calm "you are here" accent. */
.form-card .form-drafts tr.task-critical { border-left: 0; }
.form-drafts tr.form-row-current td { background: var(--tint); }
.form-drafts tr.form-row-current td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
.form-drafts .toggle-form { display: inline-flex; margin: 0; }
.form-btn-delete:hover { border-color: var(--danger-border); color: var(--danger-ink); background: var(--danger-bg); }

/* --- Public onboarding form (no sidebar) ------------------- */
.form-public { width: 100%; max-width: 880px; margin: 0 auto; padding: var(--s-4) 0 var(--s-6); }
/* Same centring nudge as the auth screens: signed out, the shell still
   carries the rail offset, so pull the column back by half a rail. Only
   matches when .app is <body>'s first child (no chrome rendered). */
@media (min-width: 821px) {
    body > .app:first-child .form-public { position: relative; left: calc(var(--rail-w) * -0.5); }
}

/* Thanks page: reuses .auth-shell / .auth-card, plus a check mark. */
.auth-card.form-done { text-align: center; }
.form-done-mark {
    display: inline-grid;
    place-items: center;
    width: 44px;
    height: 44px;
    margin-bottom: 14px;
    border-radius: 50%;
    background: var(--ok-bg);
    color: var(--ok-ink);
}
.form-done-mark svg { width: 22px; height: 22px; }
.auth-card.form-done .auth-lede { margin-bottom: 0; }

/* --- Vertical rhythm --------------------------------------
   Spacing between the blocks inside a section comes from one sibling
   rule rather than per-element mt-N / mb-N utilities: several components
   above reset margin to 0 and, sitting later in the file, would silently
   override a utility of equal specificity. Placed after them on purpose.
   Sections are block flow, so this collapses with .form-section-head's
   bottom margin instead of doubling it. */
.form-section > * + * { margin-top: var(--s-4); }
.form-section > * + .form-help { margin-top: var(--s-3); }
.form-subgroup > * + * { margin-top: var(--s-3); }
.form-card-head > .form-notice { margin-top: var(--s-4); }
.form-split > * + * { margin-top: 0; }

/* --- Responsive -------------------------------------------- */
@media (max-width: 1100px) {
    .form-layout { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 820px) {
    .form-grid,
    .form-grid--pairs { grid-template-columns: minmax(0, 1fr); }
    .form-grid--3,
    .form-grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .form-check--field { min-height: 0; }
    .form-section { padding: var(--s-4); }
    .form-card-head { padding: var(--s-5) var(--s-4) var(--s-4); }
    .form-actions { padding: var(--s-3) var(--s-4); }
    .form-split { flex-direction: column; align-items: flex-start; }
    .form-public { padding-top: var(--s-2); }
    .form-card .data-table { min-width: 520px; }
}
@media (max-width: 560px) {
    .form-grid--3,
    .form-grid--4 { grid-template-columns: minmax(0, 1fr); }
    .form-actions-note,
    .form-actions-alert { flex-basis: 100%; margin-left: 0; }
}

/* ============================================================
   Settings, admin and approval-queue screens -- slice 4b of
   docs/ui-mockups/4-combined.html. Admin dashboard settings panels,
   time off (calendar + review queue), company holidays, compliance
   build / preview / list, global-template and agent-onboarding review,
   My Calendar, muted flags.

   Built on the slice-4a form vocabulary (.form-page, .form-card,
   .form-section*, .form-grid, .form-field, .form-actions, .form-diff*,
   .form-empty ...). Only what that vocabulary lacks lives here, every
   rule scoped to a set-* hook so no other screen is affected. The three
   pill colours (approved / proposed / denied) were each copy-pasted into
   an inline <style> on the time-off screens; they're global here because
   nothing else in the app renders those status names.

     .set-head             page header with a trailing action button
     .set-split            two cards side by side (--2-1 for 2fr/1fr)
     .set-table            flush table: edge to edge inside a .form-card
     .set-row-actions      compact in-row button group
     .set-btn-danger       .btn-sm in the destructive colour
     .set-bar/.set-yearnav prev / title / next navigator row
     .set-cal*             month grid (My Time Off)
     .set-stats/.set-stat  small number tiles (balance, preview summary)
     .set-queue*           approve/deny queue rows
     .set-list*            two-line name + meta list
     .set-saved            "Saved." confirmation in a card's action row

   Safari-safe: no parent-matching selectors, container queries, colour
   mixing or nested rules. :not() is not used.
   ============================================================ */

/* --- Status pills (were inline <style> on three screens) ---- */
.pill-approved { background: #d1fae5; color: #065f46; }
.pill-proposed { background: #fef3c7; color: #92400e; }
.pill-denied { background: #fee2e2; color: #991b1b; }
[data-theme="dark"] .pill-approved { background: #0f3d2e; color: #34d399; }
[data-theme="dark"] .pill-proposed { background: #452f06; color: #fbbf24; }
[data-theme="dark"] .pill-denied { background: #4c1d1d; color: #f87171; }

/* --- Utilities ---------------------------------------------- */
/* Visually hidden, still announced (empty action-column headers). */
.set-sr {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}
.set-muted { color: var(--faint); }

/* --- Page header with a trailing action --------------------- */
.form-page > .page-header.set-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--s-3) var(--s-5);
}
.set-head-text { flex: 1 1 360px; min-width: 0; }
.set-head > .btn,
.set-head > .btn-outline { flex: 0 0 auto; }

/* --- Card bits ---------------------------------------------- */
/* A section that is only a heading (a table follows it). */
.set-section--tight > .form-section-head:last-child { margin-bottom: 0; }

/* Two small numeric fields side by side. */
.form-grid.set-grid-sm { grid-template-columns: repeat(2, minmax(0, 240px)); }

/* A checkbox whose text carries a second, muted line. */
.set-check .form-help { display: block; margin-top: 2px; }

/* Footer row holding only a note (no buttons). */
.form-actions .set-note { margin-left: 0; }

/* "Saved." next to the Save button that was pressed. */
.form-actions .set-saved {
    flex: 0 1 auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--ok-ink);
    font-weight: 600;
}
.form-actions .set-saved::before {
    content: "\2713";
    display: inline-grid;
    place-items: center;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--ok-bg);
    font-size: 11px;
    font-weight: 700;
}

/* Two cards side by side. */
.set-split {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--s-4);
    align-items: start;
    margin-bottom: var(--s-4);
}
.set-split--2-1 { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
.set-split > .form-card { margin: 0; }

/* Main column beside a .form-aside (My Time Off). */
.set-main { display: flex; flex-direction: column; gap: var(--s-4); min-width: 0; }
.set-main > .form-card { margin: 0; }

/* Link + description list (admin dashboard reports). */
.set-links { margin: 0; }
.set-links dt { margin: 12px 0 0; font-size: 14px; font-weight: 600; line-height: 1.4; }
.set-links dt:first-child { margin-top: 0; }
.set-links dd { margin: 2px 0 0; color: var(--muted); font-size: 13px; line-height: 1.5; }

/* --- Flush table inside a card ------------------------------
   Edge to edge like the dashboard buckets, rather than the bordered
   table-in-a-section that the 4a forms use. The wrapper carries the
   card's corner radius so the header fill and row hover are clipped
   to it (its overflow-x:auto makes the radius clip). */
.form-card .data-table.set-table {
    border: 0;
    border-top: 1px solid var(--border);
    border-radius: 0;
    background: transparent;
}
.form-card > .set-table-wrap:first-child { border-top-left-radius: var(--r-lg); border-top-right-radius: var(--r-lg); }
.form-card > .set-table-wrap:first-child .set-table { border-top: 0; }
.form-card > .set-table-wrap:last-child { border-bottom-left-radius: var(--r-lg); border-bottom-right-radius: var(--r-lg); }
.form-card .set-table th:first-child,
.form-card .set-table td:first-child { padding-left: var(--s-6); }
.form-card .set-table th:last-child,
.form-card .set-table td:last-child { padding-right: var(--s-6); }
.set-table tbody tr:hover td { background: var(--panel-2); }
.set-table .set-c-main { color: var(--ink); font-weight: 500; }
.set-table .set-c-date,
.set-table .set-c-num { white-space: nowrap; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.set-table .set-c-num { text-align: right; }
.set-table .set-c-act { width: 1%; white-space: nowrap; text-align: right; }
.set-table .set-c-act form { display: inline-flex; margin: 0; }
.set-table .set-cell-sub { margin-top: 2px; color: var(--muted); font-size: 12.5px; font-weight: 400; }
/* Proposed (not yet approved) holidays recede. */
.set-table tr.unapproved td.set-c-date,
.set-table tr.unapproved td.set-c-main { color: var(--muted); }

.set-row-actions { display: inline-flex; align-items: center; justify-content: flex-end; gap: 6px; }
.set-row-actions form { display: inline-flex; margin: 0; }

/* Compact destructive action (Reset, Delete, Reject, Cancel). */
.btn-sm.set-btn-danger { color: var(--danger-ink); border-color: var(--danger-border); }
.btn-sm.set-btn-danger:hover { color: var(--danger-ink); border-color: var(--danger-ink); background: var(--danger-bg); }

/* --- Prev / title / next navigator row ---------------------- */
.form-section.set-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--s-3);
    padding-top: var(--s-4);
    padding-bottom: var(--s-4);
}
.set-bar > * + * { margin-top: 0; }
.set-yearnav { display: flex; align-items: center; gap: var(--s-3); }
.set-yearnav .form-section-title { text-align: center; font-variant-numeric: tabular-nums; }
.set-bar-action { margin: 0; }

/* --- Month calendar (My Time Off) --------------------------- */
.form-section.set-cal-wrap { padding: var(--s-4) var(--s-5) var(--s-5); }
.set-cal { width: 100%; border-collapse: separate; border-spacing: 0; table-layout: fixed; }
.set-cal th {
    padding: 0 0 6px;
    color: var(--muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    text-align: center;
}
.set-cal td {
    height: 78px;
    padding: 5px 6px;
    vertical-align: top;
    background: var(--panel);
    border-right: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    overflow: hidden;
}
.set-cal td:first-child { border-left: 1px solid var(--border); }
.set-cal tbody tr:first-child td { border-top: 1px solid var(--border); }
.set-cal tbody tr:first-child td:first-child { border-top-left-radius: var(--r-md); }
.set-cal tbody tr:first-child td:last-child { border-top-right-radius: var(--r-md); }
.set-cal tbody tr:last-child td:first-child { border-bottom-left-radius: var(--r-md); }
.set-cal tbody tr:last-child td:last-child { border-bottom-right-radius: var(--r-md); }
.set-cal td.wknd,
.set-cal td.out { background: var(--panel-2); }
.set-cal-day {
    display: inline-grid;
    place-items: center;
    min-width: 22px;
    height: 22px;
    padding: 0 4px;
    border-radius: 999px;
    color: var(--ink-2);
    font-size: 12px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.set-cal td.out .set-cal-day { color: var(--faint); font-weight: 500; }
.set-cal td.out .set-cal-tag { opacity: .6; }
.set-cal td.is-today .set-cal-day { background: var(--accent); color: var(--on-accent); }
.set-cal-tag {
    display: block;
    margin-top: 3px;
    padding: 1px 6px;
    border: 1px solid transparent;
    border-radius: 5px;
    font-size: 11px;
    font-weight: 600;
    line-height: 1.45;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.set-cal-tag--approved { background: var(--ok-bg); border-color: var(--ok-border); color: var(--ok-ink); }
.set-cal-tag--pending { background: var(--warn-bg); border-color: var(--warn-border); color: var(--warn-ink); }
.set-cal-tag--holiday { background: var(--info-bg); border-color: var(--info-border); color: var(--info-ink); }
/* No violet token exists; light + dark pair kept together here. */
.set-cal-tag--others { background: #f5f3ff; border-color: #ddd6fe; color: #5b21b6; }
[data-theme="dark"] .set-cal-tag--others { background: rgba(139, 92, 246, .16); border-color: rgba(139, 92, 246, .40); color: #c4b5fd; }

.set-cal-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 6px var(--s-4);
    margin-top: var(--s-3);
    color: var(--muted);
    font-size: 12.5px;
}
.set-cal-key { display: inline-flex; align-items: center; gap: 6px; }
.set-cal-key::before {
    content: "";
    width: 12px;
    height: 12px;
    border: 1px solid transparent;
    border-radius: 3px;
}
.set-cal-key--approved::before { background: var(--ok-bg); border-color: var(--ok-border); }
.set-cal-key--pending::before { background: var(--warn-bg); border-color: var(--warn-border); }
.set-cal-key--holiday::before { background: var(--info-bg); border-color: var(--info-border); }
.set-cal-key--others::before { background: #f5f3ff; border-color: #ddd6fe; }
[data-theme="dark"] .set-cal-key--others::before { background: rgba(139, 92, 246, .16); border-color: rgba(139, 92, 246, .40); }

/* --- Number tiles ------------------------------------------- */
.set-stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-2); margin: 0; }
.set-stats--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.set-stat {
    padding: 10px 12px;
    background: var(--panel-2);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
}
.set-stat dt { color: var(--muted); font-size: 12px; font-weight: 500; line-height: 1.35; }
.set-stat dd {
    margin: 2px 0 0;
    color: var(--ink);
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -.02em;
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
}
.set-stat--accent dd { color: var(--accent-ink); }

/* --- Approve / deny queue ----------------------------------- */
.set-count {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 8px;
    background: var(--panel-2);
    border: 1px solid var(--border);
    border-radius: 999px;
    color: var(--muted);
    font-size: 12px;
    font-weight: 600;
    line-height: 1.4;
    vertical-align: 1px;
    font-variant-numeric: tabular-nums;
}
.set-queue { margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--border); }
.set-queue-item { display: flex; align-items: center; gap: var(--s-4); padding: 14px var(--s-6); }
.set-queue-item + .set-queue-item { border-top: 1px solid var(--border); }
.set-queue-body { flex: 1 1 auto; min-width: 0; }
.set-queue-title { color: var(--ink); font-size: 14px; font-weight: 600; line-height: 1.4; }
.set-queue-meta { margin-top: 2px; color: var(--ink-2); font-size: 13px; line-height: 1.5; }
.set-queue-warn {
    margin-top: 6px;
    padding-left: 8px;
    border-left: 2px solid var(--warn-border);
    color: var(--warn-ink);
    font-size: 12.5px;
    font-weight: 500;
    line-height: 1.45;
}
.set-queue-actions { display: flex; flex: 0 0 auto; gap: var(--s-2); }
.set-queue-actions form { display: inline-flex; margin: 0; }

/* --- Two-line list ------------------------------------------ */
.set-list { margin: 0; padding: 0; list-style: none; }
.set-list li { display: flex; flex-direction: column; gap: 2px; padding: 9px 0; border-top: 1px solid var(--border); }
.set-list li:first-child { padding-top: 0; border-top: 0; }
.set-list li:last-child { padding-bottom: 0; }
.set-list-main { color: var(--ink); font-size: 13.5px; font-weight: 600; }
.set-list-main .pill { margin-left: 6px; padding: 1px 8px; font-size: 11px; vertical-align: 1px; }
.set-list-meta { color: var(--muted); font-size: 12.5px; line-height: 1.45; }

/* --- Notice with a heading and a list (compliance conflicts) - */
.notice .set-notice-title { margin: 0; color: inherit; font-size: 14px; font-weight: 650; line-height: 1.4; }
.notice > .set-notice-title + p { margin-top: 4px; }
.set-notice-list { margin: 8px 0 0; padding-left: 18px; }
.set-notice-list li + li { margin-top: 2px; }

/* --- Decision form below read-only sections ----------------- */
.set-decision { margin: 0; }
.set-decision > .form-section { border-top: 1px solid var(--border); }

/* --- Connection status line (My Calendar) ------------------- */
.set-status { display: flex; align-items: flex-start; gap: 10px; }
.set-status-dot {
    flex: 0 0 8px;
    width: 8px;
    height: 8px;
    margin-top: 7px;
    border-radius: 50%;
    background: var(--ok-ink);
    box-shadow: 0 0 0 3px var(--ok-bg);
}
.set-status-text { margin: 0; color: var(--ink-2); font-size: 14px; line-height: 1.55; }
.set-status-text strong { color: var(--ink); }

/* --- Responsive --------------------------------------------- */
@media (max-width: 820px) {
    .set-split,
    .set-split--2-1 { grid-template-columns: minmax(0, 1fr); }
    .form-card .set-table th:first-child,
    .form-card .set-table td:first-child { padding-left: var(--s-4); }
    .form-card .set-table th:last-child,
    .form-card .set-table td:last-child { padding-right: var(--s-4); }
    .set-queue-item { padding-left: var(--s-4); padding-right: var(--s-4); }
    .form-section.set-cal-wrap { padding: var(--s-3); }
    .set-cal td { height: 64px; padding: 4px; }
    .set-cal-tag { padding: 0 4px; font-size: 10px; }
}
@media (max-width: 560px) {
    .form-grid.set-grid-sm { grid-template-columns: minmax(0, 1fr); }
    .set-stats--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .set-queue-item { flex-direction: column; align-items: flex-start; gap: var(--s-3); }
    .set-cal th { font-size: 10px; letter-spacing: .02em; }
    .set-cal td { height: 56px; }
}

/* ============================================================
   Lists and reports -- slice 5 of docs/ui-mockups/4-combined.html.
   Transactions, Agents, Brokerages, Email Templates, Agent Onboarding;
   Invoicing, Workload, AI Usage, Agent Activity, Agent Financials
   (report + detail).

   No new card or table component: these screens use the list card the
   4b screens established -- .form-card > .form-table-wrap.set-table-wrap
   > table.data-table.set-table (flush, edge-to-edge, compact uppercase
   headers, row hover, .set-c-main / -num / -date / -act columns) -- under
   a .form-page--wide + .set-head header, the dashboard's .dash-toolbar
   (34px controls) and .dash-seg segments, and the .dash-stat tiles. This
   section adds only what that vocabulary lacks, every rule scoped to an
   lst-* hook (all on .lst-card or a slice-5 template), so no existing
   screen renders differently.

     .lst-card             opt-in marker on a list card (+ --secondary)
     .lst-head-actions     several trailing header actions (.set-head)
     .lst-btn-warn         amber outline action (pending requests)
     .lst-seg/-seg-count   segmented control made of links + counts
     .lst-c-sub/-meta      secondary columns (ink-2 / muted, smaller)
     .lst-c-tab            nowrap + tabular figures (phone etc.)
     .lst-c-money          emphasised money column
     .lst-c-total          row-total columns (matrix report)
     .lst-grp-*            column-group dividers / grouped headers
     .lst-sticky           first column pinned while a wide table scrolls
     .lst-table--report    header labels may wrap (10-column report)
     .lst-table--matrix    dense two-row-header matrix (agent activity)
     .lst-inline-form      compact select + button in a row (merge)
     .lst-bucket/.lst-dot  status dot on a sectioned list (invoicing)
     .lst-summary/-kicker  stat-tile strip with a small label
     .lst-stats            3-up .dash-stats built on a <dl>
     .lst-kv               label / value rows (by-year totals)
     .lst-pager            pagination row
     .lst-footnote         muted note under a report

   Safari-safe: no parent-matching selectors, container queries, colour
   mixing or nested rules. :not() is not used.
   ============================================================ */

/* --- Header ------------------------------------------------- */
.set-head > .lst-head-actions {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--s-2);
}
.btn-outline.lst-btn-warn { background: var(--warn-bg); border-color: var(--warn-border); color: var(--warn-ink); }
.btn-outline.lst-btn-warn:hover { background: var(--warn-bg); border-color: var(--warn-ink); color: var(--warn-ink); }

/* Pill sitting in running text (legend in a subhead). */
.pill.lst-pill-inline { padding: 1px 8px; font-size: 11.5px; vertical-align: 1px; }

/* --- Segmented control of links (status tabs) ---------------
   Same look as the dashboard's sort segments; these are <a>s, so drop
   the global link underline. */
.task-filters.dash-toolbar .lst-seg .dash-seg-btn,
.task-filters.dash-toolbar .lst-seg .dash-seg-btn:hover { gap: 6px; text-decoration: none; }
.lst-seg-count {
    color: var(--faint);
    font-size: 11.5px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.task-filters.dash-toolbar .lst-seg .dash-seg-btn.is-on .lst-seg-count { color: var(--accent-ink); }

/* --- List card ---------------------------------------------- */
.form-card.lst-card--secondary { margin-top: var(--s-6); }

.lst-card .set-table td { height: 40px; }
.lst-card .set-table .pill { white-space: nowrap; }
.lst-card .set-table .set-c-main a { color: var(--ink); }
.lst-card .set-table .set-c-main a:hover { color: var(--accent-ink); }
.lst-card .set-table .lst-c-sub { color: var(--ink-2); }
.lst-card .set-table .lst-c-meta { color: var(--muted); font-size: 12.5px; }
.lst-card .set-table .lst-c-tab { white-space: nowrap; font-variant-numeric: tabular-nums; }
.lst-card .set-table .lst-c-money { color: var(--ink); font-weight: 600; }
.lst-card .set-table .lst-c-total { color: var(--ink); font-weight: 600; }

/* Current-load warnings (workload). The shared .task-overdue is a
   light-only hex and loses to .set-c-num's colour; re-state it with the
   theme-aware danger ink. */
.lst-card .set-table td.task-overdue { color: var(--danger-ink); font-weight: 600; }

/* Empty state: roomier than the 4b default, and no hover tint. */
.lst-card .set-table td.empty-state {
    padding: 32px 16px !important;
    color: var(--muted);
    font-size: 13.5px;
    text-align: center;
}
.lst-card .set-table tbody tr:hover td.empty-state { background: transparent; }

/* --- Column groups + wide reports --------------------------- */
.lst-card .set-table .lst-grp-start { border-left: 1px solid var(--border); }

/* Long numeric headers may wrap instead of forcing a scroll. */
.lst-card .lst-table--report th { white-space: normal; vertical-align: bottom; line-height: 1.3; }

/* Agent activity: 19 columns, two header rows. Tighter cells; the
   group label spans and centres over its Active / Closed pair. The
   second header row has no first/last column of the table, so it must
   not inherit the card's 24px edge padding. */
.lst-card .lst-table--matrix th,
.lst-card .lst-table--matrix td { padding-left: 10px; padding-right: 10px; }
.form-card.lst-card .lst-table--matrix thead tr + tr th { padding-left: 10px; padding-right: 10px; }
.lst-card .lst-table--matrix th[rowspan] { vertical-align: bottom; }
.lst-card .lst-table--matrix th.lst-grp-head { text-align: center; white-space: normal; line-height: 1.3; }

/* First column stays put while the table scrolls sideways inside its
   .form-table-wrap. Opaque fill so scrolled cells pass beneath it. */
.lst-card .set-table .lst-sticky {
    position: -webkit-sticky;
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--panel);
    box-shadow: inset -1px 0 0 var(--border);
}
.lst-card .set-table th.lst-sticky { z-index: 2; background: var(--panel-2); }
.lst-card .set-table tbody tr:hover td.lst-sticky { background: var(--panel-2); }

/* --- Compact in-row form (brokerage merge) ------------------ */
.lst-card .set-table .lst-inline-form { display: inline-flex; align-items: center; gap: 6px; margin: 0; }
.lst-card .lst-inline-form select {
    height: var(--ctl-sm);
    max-width: 220px;
    padding: 0 26px 0 8px;
    border: 1px solid var(--border-2);
    border-radius: var(--r-sm);
    font-size: 12.5px;
    color: var(--ink);
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
    background-color: var(--panel);
    background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%),
                      linear-gradient(135deg, var(--muted) 50%, transparent 50%);
    background-position: calc(100% - 14px) 50%, calc(100% - 9px) 50%;
    background-size: 5px 5px;
    background-repeat: no-repeat;
}
[data-theme="dark"] .lst-card .lst-inline-form select { color-scheme: dark; }

/* --- Sectioned list: status dot in the card heading --------- */
.lst-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    margin-right: 9px;
    border-radius: 50%;
    background: var(--faint);
    vertical-align: 1px;
}
.lst-bucket--needs .lst-dot { background: var(--amber); }
.lst-bucket--awaiting .lst-dot { background: var(--blue); }
.lst-bucket--done .lst-dot { background: var(--accent); }

/* --- Summary tiles ------------------------------------------ */
.lst-summary { margin: 0 0 var(--s-5); }
.lst-kicker {
    margin: 0 0 var(--s-2);
    color: var(--muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    line-height: 1.3;
    text-transform: uppercase;
}
.dash-stats.lst-stats { grid-template-columns: repeat(3, minmax(0, 1fr)); margin: 0; }
.lst-stats dt,
.lst-stats dd { margin: 0; }
.lst-stats .dash-stat-v { overflow-wrap: anywhere; }

/* --- Label / value rows (by-year totals) -------------------- */
.lst-kv { margin: 0; padding: 0 var(--s-6) var(--s-2); border-top: 1px solid var(--border); }
.lst-kv-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s-3);
    padding: 10px 0;
    font-size: 13.5px;
    font-variant-numeric: tabular-nums;
}
.lst-kv-row + .lst-kv-row { border-top: 1px solid var(--border); }
.lst-kv dt { color: var(--ink-2); }
.lst-kv dd { margin: 0; color: var(--ink); font-weight: 600; }
.lst-kv .empty-state { margin: 0; padding: 20px 0 !important; font-size: 13.5px; }

/* --- Pagination + footnote ---------------------------------- */
.pagination.lst-pager { align-items: center; gap: var(--s-3); margin-top: var(--s-2); font-size: 13px; font-variant-numeric: tabular-nums; }
.lst-footnote { margin: var(--s-3) 0 0; max-width: 90ch; color: var(--muted); font-size: 12.5px; line-height: 1.5; }

/* --- Responsive --------------------------------------------- */
@media (max-width: 820px) {
    .lst-kv { padding-left: var(--s-4); padding-right: var(--s-4); }
    .set-head > .lst-head-actions { flex-basis: 100%; }
}
@media (max-width: 560px) {
    .dash-stats.lst-stats { grid-template-columns: minmax(0, 1fr); }
}

/* ============================================================
   Transaction detail -- slice 6a of docs/ui-mockups/4-combined.html.
   The TC's main working screen (transaction_detail.html). Restyled, not
   reorganised: every section keeps its place in the page.

   Layout: one column, in the existing section order. The only two-column
   part is the one that was already there -- Documents beside the
   Dates / People / Commission facts card (.detail-grid) -- which now
   collapses to one column at <=1100px. A main + side column across the
   whole page would have meant moving Parties and Dates out of order.

   Reuses the dashboard vocabulary for every task-like list: the flag
   panel, the urgency buckets and Completed are .dash-bucket cards with
   .dash-table rows (drawn checkbox, critical red rail, struck-through
   done rows, "Send request" .mini), and Needs Attention is the dashboard's
   amber .dash-flag-table. Everything new is scoped to a txn-* hook (all
   under .txn-page), and the rules that lived in this template's three
   inline <style> blocks (schedule editor, objection editor, parties,
   note screenshots) live here now with theme tokens in place of the
   light-only hex they had.

     .txn-page             page wrapper (scope + [hidden] guard)
     .txn-head*            header: title, facts row, action buttons
     .txn-card             borderless card with a header bar (.dash-bucket look)
     .txn-card-hint/-body/-foot   card description, padded body, tinted footer form
     .txn-objection        buyer title-objection editor strip
     .txn-parties          contact list (role column + entries)
     .txn-notes            notes log + screenshot attach / paste
     .txn-task-table       per-file task columns, due chip (.txn-due)
     .txn-addtask          quick add-task row
     .txn-grid/.txn-docs/.txn-facts   documents + facts row

   Safari-safe: no parent-matching selectors, container queries, colour
   mixing or nested rules. :not() is not used.
   ============================================================ */

/* JS toggles [hidden] on the note editor / note body / note actions and
   the party typeahead; author display rules below would otherwise beat
   the UA [hidden] rule. */
.txn-page [hidden] { display: none !important; }

/* The template's bare .subhead spans had no rule at all on this page. */
.txn-page .subhead { color: var(--muted); font-size: 12.5px; }

/* --- Page header -------------------------------------------- */
.page-header.txn-head { margin-bottom: var(--s-5); }
.txn-head .back-link { margin-bottom: 6px; font-size: 13px; font-weight: 500; }
.txn-head-row {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--s-3) var(--s-5);
}
.txn-head-text { flex: 1 1 420px; min-width: 0; }
.page-header.txn-head h1 { margin: 0; overflow-wrap: break-word; }
.page-header.txn-head .txn-facts {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px 0;
    margin: 8px 0 0;
    color: var(--ink-2);
    font-size: 13.5px;
}
.txn-facts .pill { margin-right: 4px; }
.txn-fact { display: inline-flex; align-items: center; white-space: nowrap; }
/* Dot separator before every fact (the status pill leads, undotted). */
.txn-fact::before {
    content: "";
    width: 3px;
    height: 3px;
    margin: 0 9px;
    border-radius: 50%;
    background: var(--faint);
}
.txn-fact-k { margin-right: 5px; color: var(--muted); }
.txn-head-actions { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-2); }
.txn-head-actions form { display: inline-flex; margin: 0; }

/* --- Cards: shadow card + header bar ------------------------
   Same header bar as a .dash-bucket so every section on the page reads
   alike. Specificity (0,2,1) beats .panel h2 / .task-bucket h2 /
   .panel h2:not(:first-child). */
.panel.txn-card { padding: 0; margin-bottom: var(--s-4); }
.panel.txn-card > h2 {
    display: flex;
    align-items: center;
    gap: 9px;
    margin: 0;
    padding: 11px 16px;
    border-bottom: 1px solid var(--border);
    color: var(--ink);
    font-size: 15px;
    font-weight: 650;
    line-height: 1.3;
    letter-spacing: normal;
    text-transform: none;
}
.panel.txn-card .bucket-count {
    display: inline-block;
    padding: 1px 8px;
    background: var(--panel-2);
    border: 1px solid var(--border);
    border-radius: 999px;
    color: var(--muted);
    font-size: 12px;
    font-weight: 600;
    line-height: 1.4;
    font-variant-numeric: tabular-nums;
}
.txn-card > .txn-card-hint { margin: 0; padding: 12px 16px 0; color: var(--muted); font-size: 13px; line-height: 1.5; }
.txn-card-body { padding: 12px 16px 16px; }
.txn-page .add-task-form.txn-card-foot {
    flex-wrap: wrap;
    margin: 0;
    padding: 12px 16px;
    background: var(--panel-2);
    border-top: 1px solid var(--border);
    border-radius: 0 0 var(--r-lg) var(--r-lg);
}

/* Empty "no tasks" card. */
.txn-empty .empty-state { margin: 0; font-size: 13.5px; }

/* --- Buyer title-objection editor (was inline <style>) ------- */
.panel.txn-objection { margin-bottom: var(--s-4); padding: 12px 16px; }
.txn-objection .objection-editor { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.txn-objection .objection-editor label { color: var(--ink-2); font-size: 13px; font-weight: 600; }
.txn-objection .objection-editor input[type="number"] { width: 76px; height: var(--ctl); padding: 0 8px; font-size: 13.5px; }
.txn-objection .objection-editor .subhead { flex-basis: 100%; line-height: 1.45; }

/* --- Shared bits: link actions, delete, bare submit buttons -- */
.txn-page .link-btn { color: var(--accent-ink); font-size: 12.5px; font-weight: 600; text-decoration: none; }
.txn-page .link-btn:hover { text-decoration: underline; }

.txn-page .delete-btn {
    display: inline-grid;
    place-items: center;
    width: 26px;
    height: 26px;
    padding: 0;
    border-radius: var(--r-sm);
    color: var(--faint);
    font-size: 17px;
}
.txn-page .delete-btn:hover { color: var(--danger-ink); background: var(--danger-bg); }

/* Bare <button type="submit">s inside this page's forms had no styling
   (native grey buttons). Compact primary look, matching .btn-sm.primary. */
.txn-parties .party-fields button,
.txn-notes .add-note-form > button[type="submit"],
.txn-notes .note-edit-form > button[type="submit"],
.txn-page .sched-actions button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: var(--ctl-sm);
    padding: 0 12px;
    background: var(--accent);
    color: var(--on-accent);
    border: 1px solid var(--accent);
    border-radius: var(--r-sm);
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
}
.txn-parties .party-fields button:hover,
.txn-notes .add-note-form > button[type="submit"]:hover,
.txn-notes .note-edit-form > button[type="submit"]:hover,
.txn-page .sched-actions button:hover { background: var(--accent-dark); border-color: var(--accent-dark); }
.txn-page .sched-actions button.btn-ghost { background: var(--panel); color: var(--ink-2); border-color: var(--border-2); }
.txn-page .sched-actions button.btn-ghost:hover { background: var(--panel-2); color: var(--accent-ink); border-color: var(--accent); }
.txn-notes .note-edit-form .note-cancel-btn { height: var(--ctl-sm); padding: 0 12px; border-radius: var(--r-sm); font-size: 12.5px; }

/* --- Parties: contact list (was inline <style>) -------------- */
.txn-parties .party-slot { display: flex; align-items: flex-start; gap: var(--s-3); padding: 9px 0; border-top: 1px solid var(--border); }
.txn-parties .party-slot:first-of-type { padding-top: 2px; border-top: none; }
.txn-parties .party-role { flex: 0 0 150px; padding-top: 1px; color: var(--muted); font-size: 12.5px; font-weight: 600; line-height: 1.5; }
.txn-parties .party-entries { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.txn-parties .party-line { display: flex; align-items: baseline; flex-wrap: wrap; gap: 3px 10px; width: 100%; font-size: 13.5px; line-height: 1.5; }
.txn-parties .party-name { color: var(--ink); font-weight: 600; }
.txn-parties .party-detail { color: var(--muted); font-size: 12.5px; }
.txn-parties a.party-detail,
.txn-parties summary.party-detail { color: var(--accent-ink); font-weight: 600; cursor: pointer; }
.txn-parties a.party-detail:hover,
.txn-parties summary.party-detail:hover { text-decoration: underline; }
.txn-parties summary { list-style: none; }
.txn-parties summary::-webkit-details-marker { display: none; }
/* An open editor takes its own line under the contact. */
.txn-parties details.party-edit[open] { flex-basis: 100%; }

.party-missing,
.party-client-tag {
    display: inline-block;
    padding: 0 8px;
    border: 1px solid transparent;
    border-radius: 999px;
    font-size: 11.5px;
    font-weight: 600;
    line-height: 1.6;
    white-space: nowrap;
}
.party-missing { background: var(--danger-bg); border-color: var(--danger-border); color: var(--danger-ink); }
.party-client-tag { background: var(--info-bg); border-color: var(--info-border); color: var(--info-ink); }

.txn-parties .party-edit-form,
.txn-parties .party-add-form {
    margin-top: 8px;
    padding: 12px;
    background: var(--panel-2);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
}
.txn-parties .party-add-form { margin-top: var(--s-4); }
.txn-parties .party-add-form strong { color: var(--ink); font-size: 13.5px; }
.txn-parties .party-add-form .subhead { margin: 8px 0 0; }
.txn-parties .party-fields { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.txn-parties .party-fields input[type="text"],
.txn-parties .party-fields input[type="email"],
.txn-parties .party-fields select { height: var(--ctl-sm); padding: 0 8px; border-radius: var(--r-sm); font-size: 13px; }
.txn-parties .party-fields input[type="text"],
.txn-parties .party-fields input[type="email"] { flex: 1 1 140px; min-width: 0; }
.txn-parties .party-fields select { flex: 0 0 auto; max-width: 200px; }

.txn-parties .party-typeahead { position: relative; display: inline-block; flex: 1 1 160px; min-width: 0; }
.txn-parties .party-typeahead input[type="text"] { width: 100%; }
.party-suggestions {
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 30;
    min-width: 260px;
    max-height: 220px;
    margin-top: 2px;
    overflow: auto;
    background: var(--panel);
    border: 1px solid var(--border-2);
    border-radius: var(--r-md);
    box-shadow: var(--shadow-2);
}
.party-suggest-item {
    display: block;
    width: 100%;
    padding: 7px 10px;
    background: none;
    border: none;
    color: var(--ink);
    font-family: inherit;
    font-size: 13px;
    text-align: left;
    cursor: pointer;
}
.party-suggest-item:hover,
.party-suggest-item:focus { background: var(--panel-2); outline: none; }

.txn-parties .inline-form .link-btn { color: var(--muted); font-weight: 500; }
.txn-parties .inline-form .link-btn:hover { color: var(--danger-ink); }

/* --- Notes + screenshots (was inline <style>) ---------------- */
.txn-notes .add-note-form { gap: 8px; margin: 0 0 var(--s-2); }
.txn-notes .add-note-form textarea,
.txn-notes .note-edit-form textarea { border-color: var(--border-2); border-radius: var(--r-md); font-size: 13.5px; line-height: 1.55; }
.txn-notes .add-note-form textarea:focus,
.txn-notes .note-edit-form textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--tint); }

.note-image-controls { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 12px; margin: 0; }
.note-attach-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: var(--ctl-sm);
    padding: 0 10px;
    background: var(--panel);
    border: 1px solid var(--border-2);
    border-radius: var(--r-sm);
    color: var(--ink-2);
    font-size: 12.5px;
    font-weight: 600;
    cursor: pointer;
}
.note-attach-btn:hover { border-color: var(--accent); color: var(--accent-ink); }

.note-previews,
.note-images { display: flex; flex-wrap: wrap; gap: 10px; margin: 8px 0; }
.note-previews:empty { display: none; margin: 0; }
.note-preview,
.note-thumb { position: relative; }
.note-previews img,
.note-images img {
    display: block;
    width: auto;
    height: 88px;
    max-width: 200px;
    object-fit: cover;
    background: var(--panel-2);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
}
.note-images a:hover img { border-color: var(--accent); }
/* White on --badge-bg in both themes (that token is the solid red meant
   for white text; --danger-ink turns pale in dark mode). */
.note-preview-remove,
.note-thumb-remove {
    position: absolute;
    top: -7px;
    right: -7px;
    width: 20px;
    height: 20px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: var(--badge-bg);
    color: #fff;
    box-shadow: 0 0 0 2px var(--panel);
    font-size: 14px;
    line-height: 20px;
    cursor: pointer;
}
.note-thumb form { position: absolute; top: -7px; right: -7px; margin: 0; }
.note-thumb form .note-thumb-remove { position: static; }

.txn-notes .note-entry { padding: 12px 0; border-top: 1px solid var(--border); }
.txn-notes .note-meta { margin: 0 0 4px; color: var(--muted); font-size: 12px; font-weight: 500; }
.txn-notes .note-body { color: var(--ink); font-size: 13.5px; line-height: 1.55; overflow-wrap: break-word; }
.txn-notes .note-edit-form { margin: 4px 0 0; }
.txn-notes .note-edit-form .note-image-controls,
.txn-notes .note-edit-form .note-previews { margin-top: 8px; }
.txn-notes .note-edit-form > button { margin: 8px 6px 0 0; }
/* The older global .note-edit-form button margin also hit the JS-built
   preview remove buttons inside an edit form, nudging them off-corner. */
.txn-notes .note-previews .note-preview-remove { margin: 0; }
.txn-notes .note-actions { display: flex; align-items: center; gap: 14px; margin: 6px 0 0; }
.txn-notes .note-actions .link-btn { color: var(--muted); font-weight: 500; }
.txn-notes .note-actions .link-btn:hover { color: var(--accent-ink); }
.txn-notes .note-actions .note-delete-btn:hover { color: var(--danger-ink); }
.txn-notes .empty-state { margin: 0; padding: 16px 0 4px !important; font-size: 13.5px; }

/* --- Task tables (on top of .dash-table) -------------------- */
.txn-task-table .c-due { white-space: nowrap; }
.txn-task-table .txn-c-who { width: 16%; color: var(--ink-2); }
.txn-task-table .txn-c-vis { width: 1%; white-space: nowrap; color: var(--ink-2); }
.txn-task-table .txn-c-act { width: 1%; text-align: right; }
.txn-task-table td { vertical-align: top; padding-top: 8px; padding-bottom: 8px; }
.txn-task-table td.c-chk { padding-top: 10px; }
.txn-task-table td.c-chk .mini { margin-top: -4px; }
.txn-task-table td.txn-c-act { padding-top: 7px; }
.txn-task-table td.txn-c-who,
.txn-task-table td.txn-c-vis { padding-top: 10px; }
.txn-task-table td.c-task { padding-top: 10px; line-height: 1.45; }
.dash-table .c-task .txn-task-sub { display: block; margin: 2px 0 0; }
.txn-task-table tr.task-done td.c-due { color: var(--muted); font-size: 12.5px; font-variant-numeric: tabular-nums; }
/* Completed bucket: accent dot. Needs the full .task-bucket.dash-bucket
   chain to beat the default faint dot. */
.task-bucket.dash-bucket.txn-bucket--done > h2::before { background: var(--accent); }

/* Schedule editor + review override (was inline <style>). The forms
   expand in flow under their summary (not a popover): the bucket card
   is overflow:hidden, which would clip anything positioned. */
.txn-page details.sched > summary { cursor: pointer; list-style: none; white-space: nowrap; }
.txn-page details.sched > summary::-webkit-details-marker { display: none; }
.sched-anchor { color: var(--muted); font-size: 12px; font-weight: 500; }
.txn-page .sched-form {
    min-width: 260px;
    margin-top: 6px;
    padding: 10px 12px;
    background: var(--panel-2);
    border: 1px solid var(--border-2);
    border-radius: var(--r-md);
    color: var(--ink-2);
    font-size: 12.5px;
    font-weight: 500;
    white-space: normal;
}
.sched-row { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.sched-row label { display: inline-flex; align-items: center; gap: 6px; min-width: 92px; color: var(--ink-2); font-weight: 600; cursor: pointer; }
.sched-row select { max-width: 220px; }
.sched-row input.txn-sched-days { width: 64px; }
.sched-actions { display: flex; flex-wrap: wrap; gap: 6px; }
[data-theme="dark"] .txn-page .sched-form input,
[data-theme="dark"] .txn-page .sched-form select { color-scheme: dark; }

/* Due chip: the summary's date, tinted by the bucket it sits in. */
.txn-task-table .c-due summary .sched-anchor { margin-left: 4px; }
.txn-due {
    display: inline-flex;
    align-items: center;
    height: 24px;
    padding: 0 8px;
    background: var(--panel);
    border: 1px solid var(--border-2);
    border-radius: var(--r-sm);
    color: var(--ink-2);
    font-size: 12.5px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.txn-task-table summary:hover .txn-due { border-color: var(--accent); }
.txn-task-table details[open] > summary .txn-due { border-color: var(--accent); box-shadow: 0 0 0 3px var(--tint); }
.dash-bucket.task-bucket-overdue .txn-due { background: var(--danger-bg); border-color: var(--danger-border); color: var(--danger-ink); }
.dash-bucket.task-bucket-today .txn-due { background: var(--warn-bg); border-color: var(--warn-border); color: var(--warn-ink); }
.dash-bucket.task-bucket-this_week .txn-due { background: var(--bg); border-color: var(--border); }
.dash-bucket.task-bucket-no_due_date .txn-due { border-style: dashed; color: var(--muted); font-weight: 500; }
.dash-bucket.task-bucket-overdue summary:hover .txn-due,
.dash-bucket.task-bucket-today summary:hover .txn-due { border-color: currentColor; }

/* "Already asked another way?" override under a gated review task. */
.txn-review-alt { margin-top: 3px; }
.txn-task-table .txn-review-alt > summary.subhead { margin: 0; color: var(--accent-ink); font-size: 12.5px; font-weight: 600; }
.txn-task-table .txn-review-alt > summary.subhead:hover { text-decoration: underline; }
.txn-review-alt .sched-form { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; max-width: 460px; }
.txn-review-alt .field-input { flex: 1 1 220px; width: auto; height: var(--ctl-sm); margin: 0; padding: 0 8px; border-color: var(--border-2); border-radius: var(--r-sm); font-size: 12.5px; }

/* --- Add-task row ------------------------------------------- */
.panel.txn-addtask { padding: 12px 16px; }
.txn-page .add-task-form { flex-wrap: wrap; gap: 8px; margin: 0; }
.txn-page .add-task-form input[type="text"],
.txn-page .add-task-form input[type="date"],
.txn-page .add-task-form select {
    height: var(--ctl);
    padding: 0 10px;
    border: 1px solid var(--border-2);
    border-radius: var(--r-md);
    background-color: var(--panel);
    color: var(--ink);
    font-size: 13.5px;
}
.txn-page .add-task-form input[type="text"] { flex: 1 1 240px; min-width: 0; }
.txn-page .add-task-form select { max-width: 220px; }
.txn-page .add-task-form .checkbox-option { display: inline-flex; align-items: center; gap: 7px; padding: 0 4px; color: var(--ink-2); font-size: 13px; white-space: nowrap; cursor: pointer; }
.txn-page .add-task-form input[type="file"] { max-width: 230px; color: var(--muted); font-size: 12.5px; }
[data-theme="dark"] .txn-page .add-task-form input,
[data-theme="dark"] .txn-page .add-task-form select { color-scheme: dark; }

/* --- Documents + facts row ---------------------------------- */
.detail-grid.txn-grid { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: var(--s-4); }
.txn-grid > .panel.txn-card { margin-bottom: 0; }

.txn-docs > .txn-card-hint { padding-bottom: 10px; }
.txn-doc-table td { vertical-align: middle; }
.txn-doc-table .txn-c-drag { width: 1%; padding-right: 0; }
.txn-doc-table td.drag-handle { color: var(--faint); font-size: 13px; }
.txn-doc-table tr.draggable-row:hover td.drag-handle { color: var(--ink-2); }
.txn-doc-table tr.draggable-row.dragging td { background: var(--tint); }
.txn-doc-table .txn-c-doc { color: var(--ink); font-weight: 500; }
.txn-doc-table .txn-c-type { color: var(--ink-2); }
.txn-doc-table .txn-c-status { width: 1%; white-space: nowrap; }
.txn-doc-table .txn-c-status .pill { padding: 2px 9px; font-size: 11.5px; }
.txn-doc-table .txn-c-file { width: 1%; white-space: nowrap; }
.txn-doc-table .txn-c-file a { font-weight: 600; }
.txn-doc-table .upload-form { gap: 6px; }
.txn-doc-table .upload-form input[type="file"] { max-width: 150px; color: var(--muted); font-size: 12px; }
.txn-doc-table .upload-form button { height: 26px; padding: 0 10px; border: 1px solid var(--accent); border-radius: var(--r-sm); font-family: inherit; font-weight: 600; }
.txn-doc-table tbody tr:hover td.empty-state { background: transparent; }
.txn-doc-table td.empty-state { font-size: 13.5px; }

/* Facts card: Dates / People / Commission as stacked sections, each a
   label / value grid with hairline rows. */
.txn-facts > * + h2 { border-top: 1px solid var(--border); }
.txn-facts .fact-list {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    gap: 0;
    padding: 4px 16px 10px;
    font-size: 13.5px;
}
.txn-facts .fact-list > dt,
.txn-facts .fact-list > dd { padding: 7px 0; border-top: 1px solid var(--border); line-height: 1.4; }
.txn-facts .fact-list > dt:first-child,
.txn-facts .fact-list > dt:first-child + dd { border-top: 0; }
.txn-facts .fact-list > dt { padding-right: 12px; color: var(--muted); font-size: 13px; }
.txn-facts .fact-list > dd { color: var(--ink); font-weight: 500; font-variant-numeric: tabular-nums; }
.txn-facts > .empty-state { margin: 0; padding: 14px 16px 6px !important; font-size: 13px; text-align: left; }
.txn-facts > .txn-facts-action { margin: 4px 16px 16px; }

/* --- Responsive --------------------------------------------- */
@media (max-width: 1100px) {
    .detail-grid.txn-grid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 820px) {
    .txn-head-actions { flex-basis: 100%; }
    .txn-parties .party-slot { flex-direction: column; gap: 4px; }
    .txn-parties .party-role { flex-basis: auto; }
}

/* Keyboard focus ring for the screenshot attach button (its file input is
   visually hidden but focusable, so Tab + Space opens the picker). */
.note-attach-btn:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ============================================================
   AI extraction review -- slice 6b of docs/ui-mockups/4-combined.html.
   transaction_review.html: the screen where a TC checks what Claude read
   off the contract before the transaction exists. Restyled, not
   reorganised -- same block order as before (errors, documents loaded,
   couldn't-find, transaction fields, Seamless setup, parties, save row).

   Built on the 4a form vocabulary (.form-page, .form-card,
   .form-section*, .form-grid, .form-field, .form-label, .form-choice,
   .form-actions--sticky) and the shared .notice tints. Every rule below
   is scoped to a rev-* hook or to .rev-page, so the legacy review-only
   classes the inline script still builds or toggles (.quickadd-panel,
   .quickadd-candidate, .agent-suggestion-chip, .chip-role, .chip-hint,
   .combobox-results, .modal-overlay, .modal-dialog, .subhead,
   .secondary-btn) are restyled here without touching their older
   global rules.

     .rev-page             page scope (inside .form-page, so [hidden] holds)
     .rev-notice*          banners above the form (errors / docs / missing)
     .rev-doc-list         per-file recognition rows
     .rev-cache-note       "already processed before" line
     .rev-missing*         couldn't-find groups
     .rev-layout           main card + Seamless setup column
     .rev-field            label + "From contract" badge + control grid;
                           an AI-filled control gets a teal edge
     .rev-type-choices     transaction-type option cards
     .rev-agent-search     client-agent search box (magnifier)
     .rev-qa-*             quick-add agent panel
     .rev-confirm          "did they move?" confirmation (JS-filled)
     .rev-inline-error     JS-toggled error lines
     .rev-parties          editable parties table
     .rev-actions          floating sticky save row
     .rev-modal*           possible-duplicate dialog

   Safari-safe: no parent-matching selectors, container queries, colour
   mixing or nested rules. :not() is not used.
   ============================================================ */

.rev-page .page-header h1 { overflow-wrap: break-word; }

/* --- Banners above the form --------------------------------- */
.notice.rev-notice { line-height: 1.5; }
.rev-notice .set-notice-list { color: var(--ink); }
.rev-notice-help { margin: 4px 0 0; color: var(--ink-2); font-size: 13px; line-height: 1.5; max-width: 90ch; }

.rev-cache-note {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin: 10px 0 0;
    padding: 7px 10px;
    background: var(--panel);
    border: 1px solid var(--info-border);
    border-radius: var(--r-md);
    color: var(--ink-2);
    font-size: 13px;
    line-height: 1.45;
}
.rev-cache-note::before { content: "\21BB"; flex: 0 0 auto; color: var(--info-ink); font-weight: 700; }
.notice--info .rev-cache-note strong { color: var(--ink); }

.rev-doc-list {
    display: grid;
    gap: 4px;
    margin: 10px 0 0;
    padding: 0;
    list-style: none;
}
.rev-doc-list li {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 2px 8px;
    padding: 6px 10px 6px 32px;
    background-color: var(--panel);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z'/%3E%3Cpath d='M14 2v6h6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: 10px 50%;
    background-size: 14px 14px;
    border: 1px solid var(--info-border);
    border-radius: var(--r-md);
    font-size: 13px;
    line-height: 1.45;
}
.rev-doc-name { color: var(--ink); font-weight: 600; overflow-wrap: break-word; min-width: 0; }
.rev-doc-sep { color: var(--faint); }
.rev-doc-kind { color: var(--ink-2); }

.rev-missing-groups {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 10px 24px;
    margin-top: 10px;
}
.rev-missing-head { margin: 0; font-size: 12.5px; font-weight: 650; line-height: 1.4; }
.rev-missing-group .set-notice-list { margin-top: 4px; }

/* --- Layout: main card + Seamless setup column -------------- */
.rev-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 360px;
    gap: var(--s-4);
    align-items: start;
    margin-bottom: var(--s-4);
}
.rev-layout > .form-card { margin: 0; }
.form-grid > .rev-span-2 { grid-column: 1 / -1; }

/* --- Field: label + "From contract" badge on one row, control below.
   The badge sits right before the control in the DOM, so an AI-filled
   control can be marked with a sibling selector (no parent matching). */
.form-field.rev-field {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    gap: 6px 8px;
}
.rev-field > .form-label { grid-column: 1; grid-row: 1; }
.rev-field > .autofill-badge { grid-column: 2; grid-row: 1; align-self: center; }
.rev-field > input,
.rev-field > select,
.rev-field > .form-choices { grid-column: 1 / -1; }

.rev-page .autofill-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 18px;
    padding: 0 7px;
    background: var(--tint);
    border-radius: 999px;
    color: var(--accent-ink);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .04em;
    line-height: 1;
    text-transform: uppercase;
    white-space: nowrap;
}
.rev-page .autofill-badge::before {
    content: "";
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--accent);
}
/* AI-filled control: teal inner edge, kept through hover + focus. */
.rev-field > .autofill-badge + input { padding-left: 12px; box-shadow: inset 3px 0 0 var(--accent); }
.rev-field > .autofill-badge + input:focus { box-shadow: inset 3px 0 0 var(--accent), 0 0 0 3px var(--tint); }

/* Transaction type: never pre-picked, so the choice reads as cards. */
.form-choices.rev-type-choices { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.rev-type-choices .form-choice { align-items: center; padding: 8px 12px; }
.rev-type-choices .form-choice input[type="radio"] { margin-top: 0; }

/* --- Seamless setup: client agent ---------------------------- */
.form-card input.rev-agent-search {
    padding-left: 32px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: 10px 50%;
    background-size: 15px 15px;
}
.rev-addlink { margin: 2px 0 0; }
.rev-page .link-btn { color: var(--accent-ink); font-family: inherit; font-size: 12.5px; text-decoration: none; }
.rev-page .link-btn:hover { text-decoration: underline; }

.rev-page .combobox-results {
    z-index: 20;
    margin-top: 4px;
    padding: 4px;
    background: var(--panel);
    border: 1px solid var(--border-2);
    border-radius: var(--r-md);
    box-shadow: var(--shadow-2);
}
.rev-page .combobox-results li { padding: 7px 10px; border-radius: var(--r-sm); font-size: 13px; line-height: 1.4; }
.rev-page .combobox-results li:hover { background: var(--tint); color: var(--accent-ink); }

/* Suggested-agent chips (built by the inline script). One per agent
   named on the contract, coloured by data-match-type:
   exact = green, mismatch = amber, new = blue. */
.rev-page .suggested-agents { flex-direction: column; flex-wrap: nowrap; gap: 6px; margin: 0 0 4px; }
.rev-page .agent-suggestion-chip {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 1px;
    width: 100%;
    max-width: none;
    padding: 8px 12px 8px 14px;
    background: var(--panel);
    border: 1px solid var(--border-2);
    border-radius: var(--r-md);
    box-shadow: inset 3px 0 0 var(--faint);
    color: var(--ink);
    font-family: inherit;
    font-size: 13px;
    line-height: 1.4;
    text-align: left;
    cursor: pointer;
    transition: border-color .12s ease, background .12s ease;
}
.rev-page .agent-suggestion-chip:hover { background: var(--panel-2); border-color: var(--accent); }
.rev-page .agent-suggestion-chip > span:nth-child(2) { color: var(--ink); font-weight: 600; overflow-wrap: break-word; max-width: 100%; }
.rev-page .agent-suggestion-chip .chip-role { color: var(--muted); font-size: 10.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; }
.rev-page .agent-suggestion-chip .chip-hint { margin-top: 1px; color: var(--muted); font-size: 12px; font-weight: 500; }

.rev-page .agent-suggestion-chip[data-match-type="exact"] { box-shadow: inset 3px 0 0 var(--ok-ink); }
.rev-page .agent-suggestion-chip[data-match-type="exact"] .chip-hint { color: var(--ok-ink); }
.rev-page .agent-suggestion-chip[data-match-type="mismatch"] { background: var(--warn-bg); border-color: var(--warn-border); box-shadow: inset 3px 0 0 var(--amber); }
.rev-page .agent-suggestion-chip[data-match-type="mismatch"]:hover { border-color: var(--warn-ink); }
.rev-page .agent-suggestion-chip[data-match-type="mismatch"] .chip-hint { color: var(--warn-ink); }
.rev-page .agent-suggestion-chip[data-match-type="new"] { border-style: dashed; box-shadow: inset 3px 0 0 var(--blue); }
.rev-page .agent-suggestion-chip[data-match-type="new"] .chip-hint { color: var(--info-ink); }

/* --- Quick-add agent panel ---------------------------------- */
.rev-page .quickadd-panel {
    margin: 0;
    padding: var(--s-4);
    background: var(--panel-2);
    border: 1px solid var(--border-2);
    border-top: 3px solid var(--accent);
    border-radius: var(--r-md);
}
.rev-qa-title { margin: 0 0 12px; color: var(--ink); font-size: 13.5px; font-weight: 650; line-height: 1.3; }
.rev-qa-grid { display: flex; flex-direction: column; gap: 12px; }
.rev-qa-pay { margin-top: 14px; }
.rev-qa-pay .form-choices { gap: 6px; }
.rev-qa-pay .form-choice { padding: 8px 10px; }
.rev-qa-billing { margin-top: 12px; background: var(--panel); }
.prompt-actions.rev-qa-actions { flex-wrap: wrap; gap: 8px; margin-top: 14px; }

.rev-page .rev-inline-error {
    margin: 12px 0 0;
    padding: 8px 10px;
    background: var(--danger-bg);
    border: 1px solid var(--danger-border);
    border-radius: var(--r-md);
    color: var(--danger-ink);
    font-size: 13px;
    font-weight: 500;
    line-height: 1.45;
}

/* "Someone with this name is already in the system ..." (JS-filled). */
.rev-confirm {
    margin-top: 12px;
    padding: 10px 12px;
    background: var(--warn-bg);
    border: 1px solid var(--warn-border);
    border-radius: var(--r-md);
}
.rev-confirm > .subhead { margin: 0 0 4px; color: var(--warn-ink); font-size: 13px; font-weight: 600; line-height: 1.45; }
.rev-confirm > .secondary-btn { margin-top: 8px; }

/* Candidate rows (quick-add confirmation and the dialog): text on top,
   its action underneath -- the button labels are long. */
.rev-page .quickadd-candidate {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: 6px;
    padding: 10px 0;
    color: var(--ink);
    font-size: 13px;
    line-height: 1.45;
}
.rev-confirm .quickadd-candidate { border-bottom-color: var(--warn-border); }
.rev-page .quickadd-candidate .secondary-btn,
.rev-confirm > .secondary-btn,
.rev-modal-body > .secondary-btn {
    height: auto;
    min-height: var(--ctl-sm);
    padding: 5px 10px;
    border-radius: var(--r-sm);
    font-size: 12.5px;
    line-height: 1.35;
    text-align: left;
    white-space: normal;
}

/* --- Parties table ------------------------------------------ */
.data-table.rev-parties { min-width: 760px; }
.form-card .rev-parties th { padding: 7px 8px; }
.form-card .rev-parties td { padding: 6px 8px; }
.form-card .rev-parties th:first-child,
.form-card .rev-parties td:first-child { padding-left: 12px; }
.form-card .rev-parties th:last-child,
.form-card .rev-parties td:last-child { padding-right: 12px; }
.rev-parties .rev-c-inc { width: 1%; text-align: center; }
.rev-parties td.rev-c-inc input { width: 16px; height: 16px; margin: 0; vertical-align: middle; }
.rev-parties .rev-c-role { width: 19%; }
.form-card .rev-parties input[type="text"],
.form-card .rev-parties input[type="email"] { height: var(--ctl-sm); padding: 0 8px; border-radius: var(--r-sm); font-size: 13px; }
.form-card .data-table.rev-parties select {
    height: var(--ctl-sm);
    padding: 0 26px 0 8px;
    border-radius: var(--r-sm);
    font-size: 13px;
    background-position: calc(100% - 14px) 50%, calc(100% - 9px) 50%;
}
.form-card .rev-parties td.empty-state { padding: 20px !important; font-size: 13.5px; }

/* --- Save row: floats at the bottom of the viewport while the form
   is on screen. Primary (Active) first, as everywhere in slice 4a. */
.form-actions.rev-actions {
    bottom: var(--s-3);
    margin: var(--s-4) 0 0;
    padding: 12px var(--s-5);
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-2);
}
.rev-actions-label { margin: 0 4px 0 0; color: var(--muted); font-size: 12.5px; font-weight: 600; }
.rev-actions .rev-discard { margin-left: auto; }
.btn-ghost.rev-discard:hover { background: var(--danger-bg); border-color: var(--danger-border); color: var(--danger-ink); }

/* --- Possible-duplicate dialog ------------------------------ */
.rev-page .modal-overlay { padding: var(--s-5); background: rgba(15, 23, 42, .55); }
[data-theme="dark"] .rev-page .modal-overlay { background: rgba(2, 6, 23, .72); }
.rev-page .modal-dialog {
    max-width: 520px;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: 0 24px 48px rgba(15, 23, 42, .28), 0 2px 6px rgba(15, 23, 42, .12);
}
[data-theme="dark"] .rev-page .modal-dialog { box-shadow: 0 24px 48px rgba(0, 0, 0, .6); }
.rev-page .rev-modal-title {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0;
    padding: 18px 20px 14px;
    border-bottom: 1px solid var(--border);
    color: var(--ink);
    font-size: 16px;
    font-weight: 700;
    letter-spacing: -.01em;
    line-height: 1.3;
}
.rev-modal-title::before {
    content: "!";
    flex: 0 0 24px;
    width: 24px;
    height: 24px;
    border: 1px solid var(--warn-border);
    border-radius: 50%;
    background: var(--warn-bg);
    color: var(--warn-ink);
    font-size: 13px;
    font-weight: 800;
    line-height: 22px;
    text-align: center;
}
.rev-modal-body { padding: 14px 20px 0; }
.rev-modal-body > .subhead { margin: 0 0 4px; color: var(--ink-2); font-size: 13.5px; line-height: 1.5; }
.rev-modal-body .quickadd-candidate,
.rev-modal-body .quickadd-candidate:last-of-type {
    margin-top: 8px;
    padding: 10px 12px;
    background: var(--panel-2);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
}
.rev-modal-body > .secondary-btn { margin-top: 12px; }
.rev-page .rev-modal-error { margin: 12px 20px 0; }
.prompt-actions.rev-modal-actions {
    justify-content: flex-end;
    margin-top: 16px;
    padding: 12px 20px;
    background: var(--panel-2);
    border-top: 1px solid var(--border);
    border-radius: 0 0 var(--r-lg) var(--r-lg);
}

/* --- Responsive --------------------------------------------- */
@media (max-width: 1100px) {
    .rev-layout { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 820px) {
    .form-actions.rev-actions { padding: 10px var(--s-4); }
}
@media (max-width: 560px) {
    .rev-actions-label { flex-basis: 100%; }
    .rev-actions .rev-discard { margin-left: 0; }
}

/* ============================================================
   Agent portal -- slice 7 of docs/ui-mockups/4-combined.html.
   agent/base.html, agent/dashboard.html, agent/financials.html: the
   only screens a Role.AGENT account (an external client) can reach.

   agent/base.html is its own standalone shell -- it does not extend
   base.html, so the internal rail and its links never render for an
   agent. In place of the rail: a slim sticky top bar (brand mark from
   registration/_auth_brand.html, Dashboard / Financials, the agent's
   name, Log out as a POST form) over a centred ~960px column. No theme
   toggle: the toggle URL sits outside /agent/, which
   AgentPortalRestrictionMiddleware redirects; the theme still follows
   the account's theme_preference via <html data-theme>, as in base.html.

   The page bodies reuse existing vocabulary only: .dash-stat tiles in a
   .lst-summary strip for the money totals, and .form-card.lst-card list
   cards with flush .set-table tables (+ .lst-dot / .set-count headings,
   .lst-kv by-year rows). What lives here is the shell and a few ap-*
   hooks; nothing outside agent/*.html carries an ap-* class.

     .ap-topbar/-inner     sticky top bar + centred inner row
     .ap-brand/-tag        brand mark + "Agent Portal" label
     .ap-nav/-link         two page links; [aria-current="page"] = active
     .ap-user/-name        avatar initial + name + .ap-logout(-btn)
     .ap-main              centred content column
     .ap-head              page header spacing
     .ap-summary-head      kicker + trailing link above the stat tiles
     .ap-bucket--*         status-dot colour per dashboard list card
     .ap-c-status          status pill column

   Safari-safe: no parent-matching selectors, container queries, colour
   mixing or nested rules. :not() is not used.
   ============================================================ */

/* --- Shell: top bar ----------------------------------------- */
.ap-topbar {
    position: -webkit-sticky;
    position: sticky;
    top: 0;
    z-index: 20;
    background: var(--panel);
    border-bottom: 1px solid var(--border);
}
.ap-topbar-inner {
    display: flex;
    align-items: center;
    gap: var(--s-3) var(--s-6);
    max-width: 1024px;           /* 960px of content + .page's 32px side padding */
    min-height: 56px;
    margin: 0 auto;
    padding: 0 var(--s-8);
}

.ap-brand { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.ap-topbar .auth-brand { margin: 0; justify-content: flex-start; }
.ap-topbar .auth-brand .rail-logo { width: 30px; height: 30px; flex-basis: 30px; border-radius: 9px; font-size: 15px; }
.ap-topbar .auth-brand .rail-name { font-size: 17px; }
.ap-brand-tag {
    padding: 2px 8px;
    border: 1px solid var(--border-2);
    border-radius: 999px;
    color: var(--muted);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .06em;
    line-height: 1.4;
    text-transform: uppercase;
    white-space: nowrap;
}

.ap-nav { display: flex; align-items: center; gap: 2px; flex: 1 1 auto; min-width: 0; }
.ap-nav-link {
    display: inline-flex;
    align-items: center;
    height: 32px;
    padding: 0 12px;
    border-radius: var(--r-md);
    color: var(--ink-2);
    font-size: 13.5px;
    font-weight: 500;
    white-space: nowrap;
}
.ap-nav-link:hover { background: var(--panel-2); color: var(--ink); text-decoration: none; }
.ap-nav-link[aria-current="page"] { background: var(--tint); color: var(--accent-ink); font-weight: 600; }

.ap-user { display: flex; align-items: center; gap: 10px; flex: 0 1 auto; min-width: 0; margin-left: auto; }
.ap-topbar .ap-avatar { width: 28px; height: 28px; flex-basis: 28px; border-radius: 8px; font-size: 12px; }
.ap-user-name {
    min-width: 0;
    max-width: 220px;
    overflow: hidden;
    color: var(--ink);
    font-size: 13px;
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.ap-topbar .logout-inline { display: inline-flex; flex: 0 0 auto; }
/* .btn-sm look. Specificity (0,2,0)+ beats the shared .linklike reset and
   its hover underline, which come later in the file than .btn-sm. */
.ap-topbar .ap-logout-btn {
    display: inline-flex;
    align-items: center;
    height: var(--ctl-sm);
    padding: 0 10px;
    background: var(--panel);
    border: 1px solid var(--border-2);
    border-radius: var(--r-sm);
    color: var(--ink-2);
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
}
.ap-topbar .ap-logout-btn:hover { border-color: var(--accent); color: var(--accent-ink); text-decoration: none; }

/* --- Content column + header -------------------------------- */
.page.ap-main { max-width: 1024px; }
.ap-main > .page-header.ap-head { margin-bottom: var(--s-5); }
.page-header.ap-head h1 { overflow-wrap: break-word; }
.page-header.ap-head .subhead { margin: 4px 0 0; max-width: 72ch; line-height: 1.5; }
.ap-head .back-link { margin-bottom: 6px; font-size: 13px; font-weight: 500; }

/* --- Totals strip: kicker with a trailing link -------------- */
.ap-summary-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--s-2) var(--s-3);
    margin: 0 0 var(--s-2);
}
.ap-summary-head .lst-kicker { margin: 0; }

/* --- Dashboard list cards ----------------------------------- */
.ap-bucket--active .lst-dot { background: var(--blue); }
.ap-bucket--awaiting .lst-dot { background: var(--amber); }
.ap-bucket--invoiced .lst-dot { background: var(--accent); }
/* Same Property / Package column widths in all three stacked cards. */
.ap-bucket .set-table th:first-child { width: 46%; }
.ap-bucket .set-table th:nth-child(2) { width: 26%; }
.lst-card .set-table .ap-c-status { width: 1%; white-space: nowrap; }

/* --- Responsive --------------------------------------------- */
@media (max-width: 820px) {
    .ap-topbar-inner { flex-wrap: wrap; gap: 6px var(--s-3); padding: 8px var(--s-4); }
    /* Links drop to their own row under brand + account. */
    .ap-nav { order: 3; flex-basis: 100%; margin-left: -4px; }
}
@media (max-width: 560px) {
    .ap-user-name { display: none; }
}

/* An agent printing Financials for their tax records: no chrome. */
@media print {
    .ap-topbar { position: static; border-bottom: 0; }
    .ap-nav, .ap-user { display: none; }
    .ap-summary-link { display: none; }
}

/* ============================================================
   Leftover sweep -- slice 7.
   ============================================================ */
/* base.html icon sprite (was style="position:absolute"). */
.svg-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ============================================================
   Payroll -- TC paycheck screens (payroll_overview.html,
   paycheck_detail.html, _paycheck_rows.html).

   Built on the existing vocabulary (.form-card, .set-table list cards,
   .lst-card, .dash-stat tiles, .lst-kv rows, pills, notices). Only what
   that lacks lives here, every rule scoped to a pay-* hook so no other
   screen renders differently. Colours come from the theme tokens, so
   light and dark both work without per-theme rules.

   Safari-safe: no parent-matching selectors, container queries, colour
   mixing or nested rules.
   ============================================================ */

/* Label + control + button on one row (start date, premium, company). */
.pay-inline-form { display: flex; align-items: flex-end; flex-wrap: wrap; gap: var(--s-3); margin: 0; }
.pay-inline-form .form-field { flex: 0 1 220px; }
.pay-inline-form .btn,
.pay-inline-form .btn-outline { flex: 0 0 auto; }
.pay-inline-form .pay-inline-help { flex: 1 1 260px; align-self: center; }
.form-card.pay-company-pick { margin-bottom: var(--s-4); }

/* Summary tiles: four across (the base .dash-stats grid), on a <dl>. */
.dash-stats.pay-stats { margin: 0; }
.pay-stats dt,
.pay-stats dd { margin: 0; }
.pay-stat--net .dash-stat-v { color: var(--accent-ink); }
.pay-stat--past .dash-stat-v { color: var(--muted); }
.dash-stat-v.pay-stat-range { font-size: 20px; }

/* Week / carried-forward subtotal and the overview totals row. */
.form-card .set-table tfoot .pay-total-row td {
    padding-top: 10px;
    padding-bottom: 10px;
    border-top: 1px solid var(--border-2);
    border-bottom: 0;
    background: var(--panel-2);
    color: var(--ink);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* The sheet's ten columns: notes may wrap, everything numeric stays put. */
.lst-card .pay-table td.lst-c-meta { max-width: 220px; white-space: normal; }
.lst-card .pay-table .pill { white-space: nowrap; }

/* Needs attention: amber edge, same cue as the dashboard's attention card. */
.form-card.pay-attention { box-shadow: var(--shadow), inset 3px 0 0 var(--amber); }
.pay-notice-gap { margin-top: var(--s-3); }

/* Adjustment reason: free text, wraps. */
.set-table td.pay-c-reason { min-width: 220px; white-space: normal; line-height: 1.45; }
.pay-c-reason .pill { margin-right: 6px; }

/* Paycheck total row in the totals list. */
.lst-kv .pay-kv-total dt,
.lst-kv .pay-kv-total dd { color: var(--ink); font-size: 15px; font-weight: 700; }

/* Mark paid / Undo row. */
.pay-action-form { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-3); margin: var(--s-3) 0 0; }
.form-section > .pay-action-form:first-child { margin-top: 0; }

@media (max-width: 820px) {
    .dash-stats.pay-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---- Agent fee-method color coding (Evan, 2026-10-02) ----------------------
   One color per fee method, used for the pill on the Agents list and the dot
   on the agent form's option cards, so a method reads the same everywhere.
   Deliberately not red/green: those mean status (overdue/done) elsewhere. */
.pill-fee--invoice            { background: #dbeafe; color: #1e40af; }  /* blue   */
.pill-fee--invoice_team_lead  { background: #ede9fe; color: #5b21b6; }  /* violet */
.pill-fee--invoice_hybrid     { background: #ccfbf1; color: #115e59; }  /* teal   */
.pill-fee--da_title           { background: #fef3c7; color: #92400e; }  /* amber  */
[data-theme="dark"] .pill-fee--invoice           { background: #1e3a5f; color: #93c5fd; }
[data-theme="dark"] .pill-fee--invoice_team_lead { background: #3b2a63; color: #c4b5fd; }
[data-theme="dark"] .pill-fee--invoice_hybrid    { background: #12403d; color: #5eead4; }
[data-theme="dark"] .pill-fee--da_title          { background: #452f06; color: #fbbf24; }

.fee-dot {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    margin-right: 8px;
    vertical-align: 0;
}
.fee-dot--invoice           { background: #2563eb; }
.fee-dot--invoice_team_lead { background: #7c3aed; }
.fee-dot--invoice_hybrid    { background: #0d9488; }
.fee-dot--da_title          { background: #d97706; }
[data-theme="dark"] .fee-dot--invoice           { background: #60a5fa; }
[data-theme="dark"] .fee-dot--invoice_team_lead { background: #a78bfa; }
[data-theme="dark"] .fee-dot--invoice_hybrid    { background: #2dd4bf; }
[data-theme="dark"] .fee-dot--da_title          { background: #fbbf24; }

/* ============================================================
   Staging banner (seamless/environment.py) -- only rendered when
   SEAMLESS_ENVIRONMENT=staging; production never has .env-staging.
   Fixed to the top of every page, above the rail drawer (z 40) and its
   backdrop (z 35). The markup sits at the END of <body> so it never
   becomes body's first child (the auth-screen centring rule above keys
   off ".app:first-child"); position:fixed puts it on top visually.
   body.env-staging reserves the bar's height so it never covers content,
   and pushes the fixed rail / sticky top bars down by the same amount.
   Solid amber + the dark --on-accent ink reads in light and dark themes.
   ============================================================ */
:root { --env-banner-h: 34px; }
.env-banner {
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 50;
    min-height: var(--env-banner-h);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 6px var(--s-4);
    background: var(--amber);
    color: var(--on-accent);
    border-bottom: 2px solid var(--warn-ink);
    font-size: 13px;
    font-weight: 600;
    line-height: 1.35;
    text-align: center;
}
.env-banner strong { font-weight: 800; letter-spacing: .06em; }
body.env-staging { padding-top: var(--env-banner-h); }
body.env-staging .rail { top: var(--env-banner-h); }
body.env-staging .mobile-bar,
body.env-staging .ap-topbar { top: var(--env-banner-h); }
@media (max-width: 600px) {
    /* The sentence wraps to two lines on a phone; reserve room for both. */
    :root { --env-banner-h: 52px; }
}

/* --- AI feedback panel on the upload review screen (ai_feedback.py) ------- */
.aifb-summary { cursor: pointer; list-style: none; }
.aifb-summary::-webkit-details-marker { display: none; }
.aifb-summary .form-section-title::before { content: "\25B8"; display: inline-block; margin-right: 8px; transition: transform .15s; }
.aifb[open] .aifb-summary .form-section-title::before { transform: rotate(90deg); }
.aifb-table td { vertical-align: top; }
.aifb-c-label { white-space: nowrap; font-weight: 600; }
.aifb-c-ai { max-width: 340px; overflow-wrap: anywhere; color: var(--ink-2); }
.aifb-c-verdict select { min-width: 150px; }
.aifb-c-note input { width: 100%; min-width: 220px; }
.aifb-overall { margin-top: var(--s-4); }
.aifb-row-flag td { background: var(--warn-bg, rgba(245, 158, 11, .08)); }

/* --- Quick-add party rows on the review screen ------------------------- */
.party-add { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: var(--s-3); }
.party-add-label { font-size: 12.5px; color: var(--muted); font-weight: 600; }
.party-quick { display: contents; }
.party-c-last { display: flex; gap: 6px; align-items: center; }
.party-c-last input { flex: 1; min-width: 0; }
.party-remove { border: 0; background: transparent; color: var(--muted); font-size: 18px; line-height: 1; cursor: pointer; padding: 2px 4px; }
.party-remove:hover { color: var(--danger-ink); }

/* --- Admin "Reassign to" on a transaction page ------------------------- */
.txn-reassign { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: var(--s-2) 0 var(--s-4); }
.txn-reassign .form-label { margin: 0; }

/* --- Compose: "Fill these in" panel (click-to-fill placeholders) -------- */
.fill-panel { border-left: 4px solid var(--warn-border, #f59e0b); }
.fill-left { font-size: 13px; font-weight: 600; color: var(--muted); margin-left: 6px; }
.fill-rows { display: grid; gap: 10px; }
.fill-row { display: grid; grid-template-columns: minmax(160px, 220px) minmax(0, 1fr) auto auto auto; gap: 10px; align-items: center; padding: 6px 8px; border-radius: 8px; transition: background .3s; }
.fill-label { font-weight: 600; font-size: 13.5px; }
.fill-status { font-size: 12.5px; color: var(--muted); white-space: nowrap; }
.fill-row.is-filled .fill-label { color: var(--muted); }
.fill-row.is-filled .fill-status { color: var(--success-ink, #15803d); }
.fill-row.is-flash { background: var(--warn-bg, rgba(245, 158, 11, .15)); }
@media (max-width: 700px) {
    .fill-row { grid-template-columns: 1fr auto; }
    .fill-label { grid-column: 1 / -1; }
}
.fill-source { display: block; font-weight: 400; font-size: 12px; color: var(--muted); margin-top: 2px; }
.fill-row.is-guess:not(.is-filled) .fill-input { background: var(--warn-bg, rgba(245, 158, 11, .08)); }
#open-gmail.is-disabled { opacity: .5; cursor: not-allowed; }
