/* ======================================================
   Duefy — base stylesheet
   ====================================================== */

/* a11y: skip-to-content (lets screen-reader / keyboard users skip nav and jump to main) */
/* WCAG 2.4.1 skip link — pushed off-screen by default, returns on Tab focus. Outlined style
   (not solid indigo) keeps visual weight low so accidental-Tab users do not think they missed
   the main CTA. Still clearly visible to real keyboard / screen-reader users. */
.skip-link {
    position: absolute; top: 8px; left: 8px;
    background: var(--bg-card); color: var(--primary);
    border: 2px solid var(--primary);
    padding: 6px 14px;
    border-radius: 6px; z-index: 10000;
    text-decoration: none; font-weight: 600; font-size: 13px;
    transform: translateY(calc(-100% - 12px));
    transition: transform .15s;
}
.skip-link:focus {
    transform: translateY(0); outline: none;
    box-shadow: 0 4px 12px rgba(79,70,229,0.25);
}

/* a11y: global keyboard focus-visible style (does not trigger on mouse click; keyboard only) */
:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
    border-radius: 4px;
}
/* In-page anchor jumps (e.g. autopay summary cards → their sections) glide
   instead of snapping. Disabled below for prefers-reduced-motion users. */
html { scroll-behavior: smooth; }

/* a11y: respect prefers-reduced-motion */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

:root {
    --primary:        #4F46E5;
    --primary-dark:   #4338CA;
    --danger:         #DC2626;
    --success:        #16A34A;
    --warning:        #D97706;
    --warning-strong: #F97316;   /* deeper orange — between warning amber and danger red */
    --text:           #1F2937;
    --text-muted:     #6B7280;
    /* alias: referenced across components but was never defined (fell back to
       inherited color). var() resolves at use time, so dark theme's
       --text-muted override applies automatically. */
    --text-secondary: var(--text-muted);
    --border:         #E5E7EB;
    --bg:             #F9FAFB;
    --bg-card:        #FFFFFF;
    --radius:         10px;
    --shadow:         0 1px 3px rgba(0,0,0,.08), 0 1px 2px rgba(0,0,0,.04);
    --space:          16px;
    --font:           -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    /* surface aliases for components */
    --bg-tertiary:    #F3F4F6;
    --accent-light:   #EEF2FF;
    --accent:         var(--primary);
    --ink:            var(--text);
    --bg-secondary:   var(--surface-2);
    --bg-soft:        var(--surface-2);
    --input-bg:       #FFFFFF;
    --radius-sm:      6px;
    /* === Status pill colors (success/warning/danger/info) — utility classes use these,
       so redefining them under [data-theme="dark"] adapts the whole app to dark mode === */
    --status-success-bg:  #DCFCE7;
    --status-success-fg:  #166534;
    --status-warning-bg:  #FEF3C7;
    --status-warning-fg:  #92400E;
    --status-danger-bg:   #FEE2E2;
    --status-danger-fg:   #991B1B;
    --status-info-bg:     #DBEAFE;
    --status-info-fg:     #1E3A8A;
    /* Light-purple border (pairs with accent-light bg): AI cards / op-bar / trust banner */
    --accent-border:      #C7D2FE;

    /* V1 (reaudit 3rd pass): semantic surface aliases + focus ring. Adds
       layering vocabulary on top of the existing bg/bg-card/bg-tertiary
       set so new components can pick a level (page < panel < card-on-panel)
       without re-deciding the hex. Old code stays on bg/bg-card; new code
       should prefer the surface-* names. */
    --surface-1:          #F9FAFB;   /* page background (= --bg) */
    --surface-2:          #F3F4F6;   /* panel on a page (= --bg-tertiary) */
    --surface-3:          #FFFFFF;   /* card on a panel (= --bg-card) */
    --focus-ring:         0 0 0 3px rgba(79, 70, 229, 0.25);
    --toast-bg:           #1F2937;
    --toast-fg:           #FFFFFF;
    --toast-border:       rgba(255, 255, 255, 0.08);
    --toast-action-bg:    #FFFFFF;
    --toast-action-fg:    #1F2937;
    --toast-action-hover: #F3F4F6;
}

/* ===== Dark mode ===== */
[data-theme="dark"] {
    --primary:        #818CF8;
    --primary-dark:   #6366F1;
    --danger:         #F87171;
    --success:        #34D399;
    --warning:        #FBBF24;
    --warning-strong: #FB923C;   /* orange-400 — sits between warning amber and danger red */
    --text:           #F9FAFB;
    --text-muted:     #9CA3AF;
    --border:         #374151;
    --bg:             #111827;
    --bg-card:        #1F2937;
    --bg-tertiary:    #374151;
    --accent-light:   #1E1B4B;
    --input-bg:       #1F2937;
    --shadow:         0 1px 3px rgba(0,0,0,.4), 0 1px 2px rgba(0,0,0,.3);
    /* Dark-mode status pills: deeper bg + brighter fg to keep contrast */
    --status-success-bg: #064E3B;
    --status-success-fg: #6EE7B7;
    --status-warning-bg: #78350F;
    --status-warning-fg: #FCD34D;
    --status-danger-bg:  #7F1D1D;
    --status-danger-fg:  #FCA5A5;
    --status-info-bg:    #1E3A8A;
    --status-info-fg:    #93C5FD;
    --accent-border:     #312E81;   /* dark indigo, pairs with dark accent-light #1E1B4B */
    /* V1: dark-mode surface levels mirror light-mode semantics */
    --surface-1:         #111827;
    --surface-2:         #1F2937;
    --surface-3:         #374151;
    --focus-ring:        0 0 0 3px rgba(129, 140, 248, 0.35);
    --toast-bg:          #1F2937;
    --toast-fg:          #F9FAFB;
    --toast-border:      #4B5563;
    --toast-action-bg:   var(--primary);
    --toast-action-fg:   #FFFFFF;
    --toast-action-hover: var(--primary-dark);
}
[data-theme="dark"] body { color-scheme: dark; }

* { box-sizing: border-box; margin: 0; padding: 0; }

html {
    height: 100%;
    min-height: 100%;
}

body {
    min-height: 100vh;
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    font-family: var(--font);
    color: var(--text);
    background: var(--bg);
    font-size: 15px;
    line-height: 1.5;
}

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

h1 { font-size: 24px; }
h2 { font-size: 18px; }

.muted { color: var(--text-muted); font-weight: 400; }
.link { color: var(--primary); cursor: pointer; }
.link-danger { color: var(--danger); }

/* ---------- Navbar ---------- */
.navbar {
    background: var(--bg-card);
    border-bottom: 1px solid var(--border);
}
.nav-inner {
    max-width: 1080px;
    margin: 0 auto;
    padding: 0 24px;
    display: flex;
    align-items: center;
    height: 60px;
    gap: 28px;
}
.brand {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-weight: 700;
    font-size: 20px;
    color: var(--primary);
}
.brand:hover { text-decoration: none; }
.nav-menu { display: flex; gap: 22px; flex: 1; }
.nav-menu a { color: var(--text-muted); font-weight: 500; }
.nav-menu a:hover { color: var(--text); text-decoration: none; }
.nav-menu a.active { color: var(--primary); }
.nav-user { display: flex; align-items: center; gap: 12px; }

/* ---------- Layout ---------- */
.container {
    width: 100%;
    flex: 1 0 auto;
    max-width: 1080px;
    margin: 0 auto;
    padding: 28px 24px 60px;
}
.page-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;     /* let the action row drop below the title instead of
                            overflowing the viewport on narrow screens */
    gap: 12px;
    margin-bottom: 22px;
}
.head-actions { display: flex; gap: 10px; flex-wrap: wrap; }
/* Optional one-line description stacked under a page title (e.g. Autopay Center).
   Wrap the h1 + p in .page-head-titlewrap so they stack as one flex item. */
.page-head-titlewrap { min-width: 0; }
.page-head-titlewrap h1 { margin: 0; }
.page-head-sub { margin: 4px 0 0; color: var(--text-muted); font-size: 14px; line-height: 1.45; max-width: 720px; }
.footer {
    flex-shrink: 0;
    border-top: 1px solid var(--border);
    background: var(--bg-card);
    color: var(--text-muted);
    font-size: 13px;
    padding: 18px 0;
}
.footer .nav-inner { height: auto; }

/* ---------- Card ---------- */
.card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 22px;
    margin-bottom: 20px;
}
.card-narrow { max-width: 560px; }
.card-medium { max-width: 720px; }
/* h2 directly inside a card: collapse default browser margins to a controlled
   bottom rhythm. Card-head h2 stays 0 (its container handles margin) — see rule below. */
.card > h2 { margin: 0 0 14px; }
.card-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 14px;
}
/* Flex children with default <h2> browser margins push card-head off-center. Reset
   to 0 so card-head's own margin-bottom controls the rhythm. */
.card-head > h2 { margin: 0; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }

/* ---------- Dashboard "Needs action" cards ---------- */
.dash-needs-action { margin: 0 0 22px; }
.dna-head { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.dna-title { display: inline-flex; align-items: center; gap: 10px; margin: 0; font-size: 22px; font-weight: 800; letter-spacing: -.01em; color: var(--text); }
/* Icon in a tinted chip (same language as the Top-priorities row icon) — a bare
   20px outline icon couldn't hold its own next to the 22px/800 title. */
.dna-title-icon {
    display: inline-flex; align-items: center; justify-content: center;
    width: 32px; height: 32px; border-radius: 9px; flex-shrink: 0;
    background: color-mix(in srgb, var(--primary) 12%, transparent);
    color: var(--primary);
}
/* Muted purpose line, pushed to the right edge of the heading row. */
.dna-head-sub { margin-left: auto; color: var(--text-muted); font-size: 13px; }
@media (max-width: 700px) { .dna-head-sub { display: none; } }
/* shell positions the big carousel-style side arrows over the row's edges */
.dna-shell { position: relative; }
/* Edge fades: a hard-clipped card at the container edge reads as broken — fade
   the cut so "there's more" looks intentional. JS toggles dna-can-left/right in
   the same place it shows/hides the arrows. Fades sit under the arrows (z 2<3)
   and don't catch clicks. Gradient runs to the page background (--bg), so dark
   mode follows automatically. */
.dna-shell::before, .dna-shell::after {
    content: ''; position: absolute; top: 0; bottom: 2px; width: 56px;
    z-index: 2; pointer-events: none; opacity: 0; transition: opacity .15s ease;
}
.dna-shell::before { left: 0;  background: linear-gradient(to right, var(--bg), transparent); }
.dna-shell::after  { right: 0; background: linear-gradient(to left,  var(--bg), transparent); }
.dna-shell.dna-can-left::before { opacity: 1; }
.dna-shell.dna-can-right::after { opacity: 1; }
.dna-arrow {
    position: absolute; top: 50%; transform: translateY(-50%); z-index: 3;
    display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; border-radius: 50%;
    border: 1px solid var(--border); background: var(--bg-card); color: var(--text);
    box-shadow: 0 2px 10px rgba(0, 0, 0, .14); cursor: pointer;
    transition: background .12s, box-shadow .12s;
}
.dna-arrow:hover { background: var(--bg-tertiary); box-shadow: 0 3px 14px rgba(0, 0, 0, .2); }
.dna-arrow-prev { left: -8px; }
.dna-arrow-next { right: -8px; }
/* single horizontal row, scroll for the overflow (count of cards can grow) */
.dna-scroll { display: flex; gap: 12px; overflow-x: auto; scroll-snap-type: x proximity; padding-bottom: 2px; -webkit-overflow-scrolling: touch; scrollbar-width: thin; }
.dna-scroll::-webkit-scrollbar { height: 6px; }
.dna-scroll::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
.dna-card {
    flex: 0 0 262px; scroll-snap-align: start;
    display: block; padding: 14px 16px; border: 1px solid var(--border);
    border-left-width: 4px; border-radius: 10px; background: var(--bg-card);
    text-decoration: none; color: inherit;
    transition: box-shadow .12s, transform .12s, border-color .12s;
}
.dna-card:hover { box-shadow: 0 2px 10px rgba(0, 0, 0, .06); transform: translateY(-1px); }
.dna-card-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.dna-card-title { font-size: 15px; font-weight: 700; color: var(--text); }
.dna-card-count {
    min-width: 24px; height: 22px; padding: 0 7px; border-radius: 999px;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 13px; font-weight: 700;
    /* derived from the card's own accent so the pill matches the left border */
    color: var(--acc, var(--primary));
    background: color-mix(in srgb, var(--acc, var(--primary)) 14%, var(--bg-card));
}
.dna-card-desc { margin: 0; font-size: 13px; color: var(--text-muted); line-height: 1.4; }
/* One distinct accent colour per card (no repeats); the left border + count pill
   both derive from --acc. */
.dna-card { border-left-color: var(--acc, var(--primary)); }
.dna-acc-intake          { --acc: #6366F1; }
.dna-acc-review          { --acc: #0891B2; }
.dna-acc-installments    { --acc: #7C3AED; }
.dna-acc-overdue         { --acc: #DC2626; }
.dna-acc-blockers        { --acc: #D97706; }
.dna-acc-broken_promises { --acc: #DB2777; }
.dna-acc-replies         { --acc: #059669; }
.dna-acc-missed_installment { --acc: #EA580C; }
.dna-acc-high_risk          { --acc: #CA8A04; }
[data-theme="dark"] .dna-acc-intake          { --acc: #818CF8; }
[data-theme="dark"] .dna-acc-review          { --acc: #22D3EE; }
[data-theme="dark"] .dna-acc-installments    { --acc: #A78BFA; }
[data-theme="dark"] .dna-acc-overdue         { --acc: #F87171; }
[data-theme="dark"] .dna-acc-blockers        { --acc: #FBBF24; }
[data-theme="dark"] .dna-acc-broken_promises { --acc: #F472B6; }
[data-theme="dark"] .dna-acc-replies         { --acc: #34D399; }
[data-theme="dark"] .dna-acc-missed_installment { --acc: #FB923C; }
[data-theme="dark"] .dna-acc-high_risk          { --acc: #FACC15; }
@media (max-width: 640px) {
    .dna-card { flex-basis: 80%; }            /* peek the next card to signal scrollability */
    .dna-arrow { display: none !important; }  /* mobile = swipe (override the JS inline display) */
}
/* merged-in "Top priorities" list (former "Needs review"), sits under the cards */
.dna-list { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border); }
.dna-list-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
.dna-list-title { margin: 0; font-size: 14px; font-weight: 700; color: var(--text); }

/* ---------- Stat cards ---------- */
.stat-grid {
    display: grid;
    /* minmax(0,…) so tracks can shrink below their content — a bare 1fr let the
       "+N% vs last month" trend line force cards past a 320px viewport. */
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 14px;
    /* Section-level separation before the "Needs action" heading: 24px — bigger
       than the 16px intra-section card rhythm (16 read as cramped once the
       heading row gained its icon chip), well short of the old 40px dead gap.
       align-items:stretch fills the shorter cards to the row so the grid
       doesn't end above them. */
    align-items: stretch;
    margin-bottom: 24px;
}
/* Text/badge-valued stat cards (client Payment profile "Chronic late payer",
   Risk badges): the numeric stat-value size wraps phrases onto huge broken
   lines, and short text rode high against neighbouring 26px numbers. Center
   within the same vertical band as a one-line numeric value (~36px). */
.stat-value.stat-value-text {
    font-size: 17px; line-height: 1.35; font-weight: 700;
    display: flex; align-items: center; gap: 6px; min-height: 36px;
}

/* Reports rows carry 5 cards (KPI row incl. Recovery alerts; aging row incl.
   Not yet due) — on wide screens give them 5 tracks so the last card doesn't
   wrap onto a lonely row. */
@media (min-width: 1100px) {
    .stat-grid-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}
/* Two-card grids (DSO drill-down): two half-width tracks — cramming two cards
   into the 4-col rhythm squeezed their labels and left half the row empty. */
.stat-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* Mid widths can't fit 5 tracks; 3+2 reads balanced where 4+1 left an orphan. */
@media (min-width: 721px) and (max-width: 1099px) {
    .stat-grid-5 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
/* Phones run the base 2-col grid — stretch the 5th card so 2+2+1 doesn't end
   on a half-empty row. */
@media (max-width: 720px) {
    .stat-grid-5 > :nth-child(5) { grid-column: 1 / -1; }
}
.stat-card {
    padding: 16px 18px;
    min-height: 118px;
    /* Cancel the base .card margin — the grid spaces cells with `gap`, and the
       leftover bottom margin was inflating the row height (and the gap before
       the next section). */
    margin-bottom: 0;
    box-shadow: 0 1px 2px rgba(16,24,40,.05);
}
.duefy-impact {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin: 0 0 20px;
    padding: 14px 16px;
    border: 1px solid var(--accent-border);
    border-radius: 10px;
    background: color-mix(in srgb, var(--accent-light) 55%, var(--bg-card));
}
.duefy-impact-main {
    display: flex;
    align-items: center;
    gap: 22px;
    min-width: 0;
    flex: 1;
}
.duefy-impact-title {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    flex: 0 0 auto;
    color: var(--primary);
    font-size: 12px;
    font-weight: 800;
    letter-spacing: .06em;
    text-transform: uppercase;
}
.duefy-impact-window {
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 800;
}
.duefy-impact-items {
    display: flex;
    align-items: center;
    gap: 16px 22px;
    flex-wrap: wrap;
    min-width: 0;
}
.duefy-impact-item {
    display: flex;
    align-items: center;
    gap: 9px;
    min-width: 150px;
}
.duefy-impact-value {
    color: var(--text);
    font-size: 18px;
    font-weight: 800;
    line-height: 1;
    white-space: nowrap;
}
.duefy-impact-item-success .duefy-impact-value { color: var(--success); }
.duefy-impact-item-ai .duefy-impact-value { color: var(--primary); }
.duefy-impact-copy { min-width: 0; }
.duefy-impact-label {
    color: var(--text);
    font-size: 13px;
    font-weight: 700;
    line-height: 1.2;
}
.duefy-impact-note {
    color: var(--text-muted);
    font-size: 12px;
    line-height: 1.25;
    margin-top: 2px;
}
.duefy-impact-dismiss {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    flex: 0 0 auto;
    border: 0;
    border-radius: 7px;
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
}
.duefy-impact-dismiss:hover {
    background: var(--accent-light);
    color: var(--text);
}
/* settings/automation: when the toggle is off the fields below go grey + non-interactive */
.auto-fields { transition: opacity .15s; }
.auto-fields-disabled { opacity: .45; pointer-events: none; }
/* Toggle-gated field rows (Fees & discounts etc.): a full-width 2-col grid so
   inputs line up under the section divider with equal widths, instead of the
   global .form-row flex which sized each <label> to content and left a ragged
   right edge + an awkward 2+1 wrap. */
.form-row.auto-fields {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 340px));
    justify-content: start;          /* cap field width + pack left — a 'days' box shouldn't span the card */
    gap: 18px 24px;
    align-items: start;
    margin-top: 20px;                /* breathing room below the section divider */
}
.form-row.auto-fields > label { display: flex; flex-direction: column; gap: 6px; }
@media (max-width: 768px) { .form-row.auto-fields { grid-template-columns: 1fr; } }
.auto-warn-banner {
    display: flex; align-items: flex-start; gap: 8px;
    background: var(--status-warning-bg); color: var(--status-warning-fg);
    padding: 10px 14px; border-radius: 8px;
    font-size: 13px; line-height: 1.5;
    margin: 0 0 14px;
}
.auto-warn-banner strong { font-weight: 700; }

/* Stage 5 F-10: empty-state card used by the invoice form when the user
   has zero clients (it's the same pattern other empty-state CTAs follow
   so we don't end up with three different "nothing here yet" looks). */
.empty-state-card {
    display: flex; flex-direction: column; align-items: center;
    gap: 8px; padding: 32px 20px;
    text-align: center;
    /* Passive "nothing here yet" state — just a whisper of tint, not the heavy
       filled panel/border that reads as a clickable or drop zone. The action
       always lives elsewhere (a form above, a CTA button, the Feedback button).
       Theme-adaptive low-alpha overlay so it stays faint in both light + dark. */
    background: rgba(0, 0, 0, .02); border-radius: var(--radius);
}
[data-theme="dark"] .empty-state-card { background: rgba(255, 255, 255, .025); }
.empty-state-icon { color: var(--text-muted); opacity: .7; margin-bottom: 4px; }
.empty-state-title { font-size: 15px; font-weight: 600; color: var(--text); }
.empty-state-body { color: var(--text-muted); font-size: 13px; max-width: 360px; }

/* Stage 5 F-09: read-only notice on /settings/reminderSchedule/ when the
   current viewer doesn't have edit permission. */
.reminder-sched-readonly-note {
    display: inline-flex; align-items: center; gap: 6px;
    margin: 4px 0 12px;
    padding: 8px 12px; border-radius: var(--radius);
    background: var(--surface-2); color: var(--text-muted);
    font-size: 13px;
}

/* Stage 5 F-06: dirty-state bar for the automation settings form.
   Sticky to the top of the content column so it's always visible while
   the user is changing toggles. Position is `sticky` not `fixed` so it
   respects the settings layout's existing scroll context. */
.settings-dirty-bar {
    position: sticky; top: 0; z-index: 5;
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    background: var(--status-warning-bg); color: var(--status-warning-fg);
    padding: 10px 14px; border-radius: var(--radius);
    margin: 0 0 14px;
    font-weight: 600; font-size: 13px;
    box-shadow: 0 1px 2px rgba(0,0,0,.04);
}

/* /settings/reminderSchedule/ — sequence editor.
   Design: each step is collapsed by default (one-line summary). Click the
   head to expand. Preview + variable chips are also collapsed (<details>)
   so the page looks calm at first glance. */
.reminder-sched-h2-row {
    display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
}
.reminder-sched-h2-row h2 { margin-bottom: 0; }
.reminder-sched-state-pill {
    display: inline-flex; align-items: center;
    padding: 2px 10px; border-radius: 999px;
    font-size: 11px; font-weight: 600; letter-spacing: 0.02em;
}
.reminder-sched-state-pill-custom  { background: var(--status-success-bg); color: var(--status-success-fg); }
.reminder-sched-state-pill-default { background: var(--bg-tertiary);       color: var(--text-muted); }
.reminder-sched-help-link {
    display: inline-flex; align-items: center; gap: 4px;
    font-size: 13px;
    text-decoration: none;
    margin-left: auto;
}
.reminder-sched-help-link:hover { color: var(--primary); }
.reminder-sched-intro { margin: 8px 0 14px; }
/* Phones: the steps + "How this works" link are self-explanatory — drop the intro
   sentence so the actual schedule starts higher. */
@media (max-width: 640px) { .reminder-sched-intro { display: none; } }

/* Tiny red * to flag required fields on the subject/body labels. */
.form-required { color: var(--status-danger-fg, #b91c1c); font-weight: 600; }

/* AI tone optimization toggle (Pro/Team only). */
.reminder-sched-ai-toggle {
    display: flex; align-items: center; gap: 8px;
    margin: 0 0 12px;
    padding-left: 3px;   /* nudge the option rows a few px in from the fields above */
    font-size: 13px;
    color: var(--text-secondary);
    cursor: pointer;
    user-select: none;
}
.reminder-sched-ai-toggle input { width: auto; margin: 0; }

/* Custom SMS text editor (per step) — revealed when "Also send as SMS" is on.
   Two columns: editor on the left, a phone preview on the right (so the device
   can stand tall). Wraps to a single column on narrow screens. Theme tokens
   throughout → dark mode auto. */
.reminder-sched-sms-config {
    display: flex;
    flex-wrap: wrap;
    gap: 18px;
    margin: 0 0 14px;
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface-2);
}
.reminder-sched-sms-edit { flex: 1 1 280px; min-width: 0; }
.reminder-sched-sms-preview-col { flex: 0 0 auto; }
.reminder-sched-sms-edit > label {
    display: block;
    font-size: 13px;
    font-weight: 600;
    margin-bottom: 6px;
    color: var(--text-secondary);
}
.reminder-sched-sms-input {
    width: 100%;
    font-size: 13px;
    font-family: inherit;
    line-height: 1.5;
    min-height: 96px;
    resize: vertical;
}
.reminder-sched-sms-meta {
    display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: baseline;
    font-size: 12px;
    margin-top: 8px;
}
.reminder-sched-sms-counter { color: var(--text-muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.reminder-sched-sms-counter.rs-sms-warn  { color: var(--status-warning-fg, #92400e); }
.reminder-sched-sms-counter.rs-sms-error { color: var(--status-danger-fg,  #b91c1c); }
.reminder-sched-sms-preview-label {
    display: flex; align-items: center; gap: 5px;
    margin: 0 0 8px;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-secondary);
}

/* Phone-style SMS preview — a mini device so the sample reads unmistakably as a
   text. The bezel is a fixed dark slate (a phone is dark regardless of UI theme);
   the screen follows the theme. color-mix keeps the incoming bubble distinct from
   the screen in both light and dark (the surface tokens collapse together in dark). */
.reminder-sched-sms-phone {
    width: 212px;
    margin: 0;
    padding: 7px;            /* thin bezel */
    border-radius: 30px;
    background: linear-gradient(165deg, #2b3648 0%, #0f172a 100%);
    box-shadow: 0 10px 26px rgba(2, 6, 23, .30), inset 0 0 0 1px rgba(255, 255, 255, .07);
    position: relative;
}
.reminder-sched-sms-phone-screen {
    background: var(--bg-card);
    border-radius: 24px;
    padding: 26px 11px 16px;
    min-height: 300px;        /* taller than wide → reads as a phone */
    position: relative;
    overflow: hidden;
}
.reminder-sched-sms-phone-screen::before {   /* dynamic-island style pill */
    content: "";
    position: absolute;
    top: 7px; left: 50%; transform: translateX(-50%);
    width: 54px; height: 12px; border-radius: 9px;
    background: #0f172a;
}
.reminder-sched-sms-phone-from {
    display: flex; flex-direction: column; align-items: center; gap: 4px;
    text-align: center;
    margin-bottom: 12px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--border);
}
.reminder-sched-sms-phone-avatar {
    width: 30px; height: 30px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: var(--accent-light, #eef2ff);
    color: var(--accent, #4F46E5);
}
.reminder-sched-sms-phone-meta { font-size: 10px; color: var(--text-muted); line-height: 1.3; }
.reminder-sched-sms-phone-meta strong { display: block; font-size: 11px; font-weight: 600; color: var(--text-secondary); }
.reminder-sched-sms-bubble {
    max-width: 92%;
    width: fit-content;
    padding: 8px 11px;
    border-radius: 16px;
    border-bottom-left-radius: 5px;   /* incoming-message tail */
    background: color-mix(in srgb, var(--text) 10%, var(--bg-card));
    color: var(--text);
    font-size: 12px;
    line-height: 1.45;
}
.reminder-sched-sms-bubble-time {
    font-size: 10px;
    color: var(--text-muted);
    margin: 4px 0 0 6px;
}
.reminder-sched-sms-preview-text { word-break: break-word; }
.reminder-sched-sms-preview-text.is-default { color: var(--text-muted); font-style: italic; }

/* "On the due day" pill, shown in place of the before/after select when
   days_offset == 0 (where direction is semantically meaningless). */
.reminder-sched-offset-zero {
    display: inline-flex; align-items: center;
    padding: 8px 12px;
    background: var(--bg-tertiary);
    border-radius: 6px;
    font-size: 13px; font-weight: 500;
    color: var(--text-secondary);
}

.reminder-sched-vars { margin-top: 14px; }

/* "What's working" stats dashboard. Shows per-step send / open / click / paid
   counts over the recent window. Lightweight table — no charts, just data. */
.reminder-sched-stats-card { margin: 20px 0; }
.reminder-sched-stats-h3 {
    display: flex; align-items: center; gap: 6px;
    margin: 0 0 8px; font-size: 15px;
}
.reminder-sched-stats-hint { margin: 0 0 14px; font-size: 13px; }
.reminder-sched-stats-table {
    width: 100%; border-collapse: collapse; font-size: 13px;
}
.reminder-sched-stats-table th,
.reminder-sched-stats-table td {
    padding: 8px 12px;
    border-bottom: 1px solid var(--border);
    text-align: left;
}
.reminder-sched-stats-table th {
    font-size: 11px; font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase; letter-spacing: 0.06em;
    background: var(--bg-tertiary);
}
.reminder-sched-stats-table tbody tr:last-child td { border-bottom: 0; }

/* Per-rate industry-benchmark comparison chip (next to numeric rate) */
.rate-cmp {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 6px;
    border-radius: 4px;
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
}
.rate-cmp.rate-up   { color: #047857; background: #ECFDF5; }
.rate-cmp.rate-down { color: #B91C1C; background: #FEF2F2; }
.rate-cmp.rate-flat { color: var(--text-muted); background: var(--bg-tertiary); }
[data-theme="dark"] .rate-cmp.rate-up   { color: #6EE7B7; background: rgba(16,185,129,.15); }
[data-theme="dark"] .rate-cmp.rate-down { color: #FCA5A5; background: rgba(239,68,68,.15); }
[data-theme="dark"] .rate-cmp.rate-flat { color: var(--text-muted); background: rgba(148,163,184,.16); }
.rate-cmp-delta { margin-left: 3px; }
/* Mobile: drop the verbose delta text — keep just the coloured arrow — and
   tighten the 5-column stats table's cells so the whole row fits a phone.
   Full "+Npp vs industry" stays in each chip's title. */
@media (max-width: 600px) {
    .rate-cmp { margin-left: 3px; padding: 1px 4px; }
    .rate-cmp-delta { display: none; }
    .reminder-sched-stats-table { font-size: 12px; }
    .reminder-sched-stats-table th,
    .reminder-sched-stats-table td { padding: 5px 6px; }
}

.reminder-sched-sendwin-hint {
    margin: 6px 0 0 24px;
    font-size: 12px;
}
.reminder-sched-vars summary {
    cursor: pointer; font-size: 14px; color: var(--text-secondary);
    padding: 6px 0;
}
.reminder-sched-vars summary:hover { color: var(--primary); }
.reminder-sched-var-list {
    list-style: none; padding: 0; margin: 8px 0 0;
    display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    /* A: wider column channel so the two columns read as separate without a divider rule */
    gap: 8px 48px; font-size: 13px;
}
.reminder-sched-var-list li {
    color: var(--text-secondary);
    /* B: fixed chip track aligns every "— description" dash within a column.
       150px clears the widest tag ({{invoice_number}}); minmax grows if a longer
       tag is ever added rather than overflowing into the description. */
    display: grid; grid-template-columns: minmax(150px, max-content) 1fr;
    align-items: center; gap: 6px;
}
.reminder-sched-var-list code {
    background: var(--bg-tertiary); padding: 2px 6px; border-radius: 4px;
    font-size: 12px; color: var(--primary);
}
.reminder-sched-var-name {
    background: var(--bg-tertiary); padding: 2px 6px; border-radius: 4px;
    font-size: 12px; color: var(--primary);
    font-family: ui-monospace, Menlo, Consolas, monospace;
}

/* Per-step chip strip lives inside a <details class="reminder-sched-disclose">
   so it doesn't add visual weight until the user wants to insert a variable. */
.reminder-sched-step-chips {
    display: flex; flex-wrap: wrap; gap: 4px; align-items: center;
    padding: 8px 0 0;
}
.reminder-sched-var-chip {
    background: var(--bg-card);
    border: 1px solid var(--border);
    color: var(--primary);
    font-family: ui-monospace, Menlo, Consolas, monospace;
    font-size: 12px;
    padding: 2px 8px;
    border-radius: 4px;
    cursor: pointer;
    transition: background .1s, border-color .1s, transform .1s;
}
.reminder-sched-var-chip:hover {
    background: var(--accent-light);
    border-color: var(--accent-border);
}
.reminder-sched-var-chip:active { transform: translateY(1px); }

/* Timeline strip — at-a-glance overview of the sequence. Numbered circles
   connected by a thin line, with a small timing label ("3d before due") below
   each node. Click the node to jump + expand the corresponding step. */
.reminder-sched-timeline {
    display: flex; align-items: flex-start;
    margin: 6px 0 6px;
    padding: 8px 0 4px;
    overflow-x: auto;
}
.reminder-sched-timeline-node {
    position: relative;
    background: none; border: 0; cursor: pointer;
    flex: 1 1 0;
    min-width: 60px;
    padding: 0;
    color: var(--text-secondary);
    transition: color .1s;
    width: auto;
    display: flex; flex-direction: column; align-items: center; gap: 6px;
}
/* Connector line — anchored to the circle's vertical center (14px from node
   top = padding 0 + half of 28px circle). Each node owns left + right halves;
   first/last hide the outer half. */
.reminder-sched-timeline-node::before,
.reminder-sched-timeline-node::after {
    content: '';
    position: absolute;
    top: 14px;
    height: 2px;
    width: 50%;
    background: var(--text-muted);
    opacity: 0.35;
}
.reminder-sched-timeline-node::before { left: 0; }
.reminder-sched-timeline-node::after  { right: 0; }
.reminder-sched-timeline-node:first-child::before,
.reminder-sched-timeline-node:last-child::after  { display: none; }
.reminder-sched-timeline-node:hover .reminder-sched-timeline-num {
    background: var(--primary); color: #fff; border-color: var(--primary);
}
.reminder-sched-timeline-num {
    position: relative; z-index: 1;
    display: inline-flex; align-items: center; justify-content: center;
    width: 28px; height: 28px;
    border-radius: 999px;
    background: var(--bg-card);   /* opaque so the connector line is masked behind the circle */
    border: 2px solid var(--border);
    font-weight: 600; font-size: 12px;
    color: var(--text-secondary);
    transition: background .12s, color .12s, border-color .12s;
}
.reminder-sched-timeline-when {
    font-size: 11px; font-weight: 500;
    color: var(--text-muted);
    white-space: nowrap;
}
/* Mobile: the horizontal timeline is a desktop overview/jump aid. On narrow
   screens its nodes overflow the card, and it's redundant anyway — each step
   card's collapsed header already shows "<when> · <tone>" in a vertical list.
   Hide it rather than ship a clipped/scrolling strip. */
@media (max-width: 600px) {
    .reminder-sched-timeline { display: none; }
}

/* Step card — collapsed by default. The toggle <button> is the entire head
   row; clicking it expands/collapses the body. Less chrome when collapsed
   (no padding-bottom card slot etc.) — keeps the page calm. */
.reminder-sched-step { padding: 0; overflow: hidden; position: relative; }
.reminder-sched-step-toggle {
    width: 100%; background: none; border: 0;
    display: flex; align-items: center; gap: 12px;
    padding: 14px 18px;
    cursor: pointer; text-align: left;
    font: inherit; color: inherit;
}
.reminder-sched-step-toggle:hover { background: var(--bg-tertiary); }
.reminder-sched-step.expanded .reminder-sched-step-toggle {
    border-bottom: 1px solid var(--border);
    background: var(--bg-tertiary);
}
.reminder-sched-step-chevron {
    display: inline-flex;
    color: var(--text-muted);
    transition: transform .15s;
}
.reminder-sched-step.expanded .reminder-sched-step-chevron {
    transform: rotate(180deg);
}
.reminder-sched-step-num {
    font-weight: 600; font-size: 14px;
    flex: 0 0 auto;
}
.reminder-sched-step-summary {
    color: var(--text-muted); font-size: 13px;
    flex: 1 1 auto;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rs-summary-sep { margin: 0 4px; opacity: 0.6; }
.reminder-sched-step-flags {
    display: flex; align-items: center; gap: 8px;
    flex: 0 0 auto;
}
.reminder-sched-step-ai-flag {
    display: inline-flex; align-items: center;
    color: var(--primary);
}

/* Step body — visible only when expanded. */
.reminder-sched-step-body {
    padding: 16px 18px 18px;
}
.reminder-sched-badge {
    display: inline-flex; padding: 2px 10px; border-radius: 999px;
    font-size: 11px; font-weight: 600; letter-spacing: 0.02em;
}
.reminder-sched-badge-custom { background: var(--status-success-bg); color: var(--status-success-fg); }

/* Disclosure <details> for Insert variable + Preview. Quiet by default,
   clearer chevron on hover. */
.reminder-sched-disclose {
    margin: 8px 0;
    border: 1px solid var(--border);
    border-radius: 6px;
}
.reminder-sched-disclose > summary {
    cursor: pointer;
    padding: 8px 12px;
    font-size: 13px;
    color: var(--text-secondary);
    list-style: none;
    display: flex; align-items: center; gap: 6px;
}
.reminder-sched-disclose > summary::-webkit-details-marker { display: none; }
.reminder-sched-disclose > summary::after {
    content: '▾';
    margin-left: auto;
    transition: transform .15s;
    color: var(--text-muted);
}
.reminder-sched-disclose[open] > summary::after { transform: rotate(180deg); }
.reminder-sched-disclose[open] > summary {
    border-bottom: 1px solid var(--border);
    color: var(--text-primary, var(--text-secondary));
}
.reminder-sched-disclose > :not(summary) { padding: 10px 12px; }
.reminder-sched-disclose > .reminder-sched-step-chips { padding: 10px 12px; }

/* Bottom-of-body action row — Reset (if custom) + Delete. Outlined buttons
   so they're easy to spot after editing body, not just thin text links. */
.reminder-sched-step-actions-row {
    display: flex; gap: 10px; justify-content: flex-end;
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--border);
}
.reminder-sched-step-actions-row .btn-link {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 13px; font-weight: 500;
    color: var(--text-secondary);
    background: var(--bg-card);
    border: 1px solid var(--border);
    cursor: pointer;
    padding: 6px 12px;
    border-radius: 6px;
    transition: background .12s, border-color .12s, color .12s;
}
.reminder-sched-step-actions-row .btn-link:hover { background: var(--bg-tertiary); }
.reminder-sched-step-delete-btn:not([disabled]):hover {
    color: var(--status-danger-fg, #b91c1c);
    background: var(--status-danger-bg, #fef2f2) !important;
    border-color: var(--status-danger-fg, #b91c1c);
}
.reminder-sched-step-delete-btn[disabled] {
    opacity: 0.4; cursor: not-allowed;
}

/* Body textarea (HTML source mode): monospace + slightly bigger. */
.reminder-sched-body-textarea {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 13px; line-height: 1.55;
    tab-size: 2;
}

/* Body visual editor — contenteditable div that LOOKS like the textarea but
   renders HTML inline. Users edit normal text; we sync innerHTML → textarea. */
.reminder-sched-body-group .reminder-sched-body-label {
    display: flex; align-items: center; gap: 12px;
}
.reminder-sched-body-mode-switch {
    margin-left: auto;
    display: inline-flex; gap: 0;
    background: var(--bg-tertiary);
    border-radius: 6px;
    padding: 2px;
}
.reminder-sched-mode-btn {
    width: auto;            /* defeat global width: 100% */
    background: none; border: 0;
    padding: 4px 12px;
    border-radius: 4px;
    font-size: 12px; font-weight: 500;
    color: var(--text-muted);
    cursor: pointer;
    transition: background .12s, color .12s;
}
.reminder-sched-mode-btn.active {
    background: var(--bg-card);
    color: var(--text-secondary);
    box-shadow: 0 1px 2px rgba(0,0,0,0.06);
}
.reminder-sched-editor-toolbar {
    display: flex; gap: 4px;
    margin-top: 6px;
    padding: 6px 8px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-bottom: 0;
    border-top-left-radius: 6px;
    border-top-right-radius: 6px;
}
.reminder-sched-editor-toolbar button {
    width: 32px; height: 30px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 5px;
    color: var(--text-secondary);
    cursor: pointer;
    font-size: 13px;
    transition: background .12s, border-color .12s;
}
.reminder-sched-editor-toolbar button:hover {
    background: var(--bg-tertiary);
    border-color: var(--text-muted);
}
.reminder-sched-editor-visual {
    border: 1px solid var(--border);
    border-top: 0;
    border-bottom-left-radius: 6px;
    border-bottom-right-radius: 6px;
    background: var(--bg-card);
    padding: 12px 14px;
    min-height: 160px;
    font: 14px/1.6 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    color: var(--text-primary, #111);
    outline: none;
}
.reminder-sched-editor-visual:focus {
    border-color: var(--primary);
    box-shadow: 0 0 0 3px rgba(80,70,229,0.12);
}
.reminder-sched-editor-visual p { margin: 0 0 12px; }
.reminder-sched-editor-visual p:last-child { margin-bottom: 0; }
.reminder-sched-editor-visual a { color: var(--primary); }
.reminder-sched-editor-visual strong { font-weight: 600; }
.reminder-sched-editor-visual:empty::before {
    content: 'Type your message here. Use the toolbar above for Bold / Italic / Link, or "Insert variable" below for merge tags.';
    color: var(--text-muted); font-style: italic;
    pointer-events: none;
}
.reminder-sched-row {
    display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end;
    margin-bottom: 12px;
}
.reminder-sched-row .form-group {
    margin-bottom: 0; display: flex; flex-direction: column; gap: 4px;
}
.reminder-sched-row .form-group > span {
    font-size: 12px; color: var(--text-muted); font-weight: 500;
}
.reminder-sched-days  input  { width: 80px; }
.reminder-sched-offset select { min-width: 180px; }
.reminder-sched-tone   select { min-width: 140px; }
.reminder-sched-actions {
    display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
    position: sticky; bottom: 16px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    box-shadow: 0 -4px 12px rgba(0,0,0,0.04);
}
/* Phones: the fixed .mobile-bottom-nav (72px incl. safe area, shown at the
   same breakpoint) would cover the sticky bar's buttons — lift it clear. */
@media (max-width: 768px) {
    .reminder-sched-actions { bottom: calc(72px + 12px); }
}

/* Add-step button — sits between the last step card and the sticky save bar.
   Outline button, full row, with a small hint to the right. */
.reminder-sched-add-step-wrap {
    display: flex; align-items: center; gap: 10px;
    margin: 0 0 12px;
    padding: 12px;
    border: 1px dashed var(--border);
    border-radius: 8px;
    background: var(--bg-tertiary);
}
.reminder-sched-add-step {
    width: auto;            /* defeat global input/select width: 100% */
    flex: 0 0 auto;
}
.reminder-sched-add-step-hint { font-size: 12px; }

/* Per-step delete button — looks like the other btn-link buttons in step
   actions; disabled (greyed) when only one step remains. */
.reminder-sched-step-delete[disabled] {
    opacity: 0.4; cursor: not-allowed;
}
.reminder-sched-step-delete:not([disabled]):hover {
    color: var(--status-danger-fg, #b91c1c) !important;
}
.reminder-sched-actions .reminder-sched-reset-all { margin-left: auto; }
.reminder-sched-shortcut {
    font-size: 11px;
    font-family: ui-monospace, Menlo, Consolas, monospace;
    padding: 2px 6px;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--bg-tertiary);
}
.reminder-sched-dirty-pill {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 4px 10px;
    border-radius: 999px;
    background: var(--status-warning-bg);
    color: var(--status-warning-fg);
    font-size: 12px; font-weight: 600;
}
/* Subtle pulse on the Save button while changes are pending. */
.btn-attention {
    box-shadow: 0 0 0 0 rgba(80, 70, 229, 0.5);
    animation: rsAttention 2.2s ease-out infinite;
}
@keyframes rsAttention {
    0%   { box-shadow: 0 0 0 0 rgba(80, 70, 229, 0.5); }
    70%  { box-shadow: 0 0 0 8px rgba(80, 70, 229, 0); }
    100% { box-shadow: 0 0 0 0 rgba(80, 70, 229, 0); }
}

/* Inline live email preview — always visible (no <details> wrapper).
   Styled as a compact preview header plus the rendered email body. */
.reminder-sched-preview-wrap {
    margin: 14px 0 4px;
}
/* The label doubles as the <summary> toggle for the collapsible preview.
   Default open; users can fold the (tall) email render away. */
.reminder-sched-preview-label {
    display: inline-flex; align-items: center; gap: 4px;
    font-size: 11px; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.06em;
    margin-bottom: 6px;
    cursor: pointer;
    list-style: none;
}
.reminder-sched-preview-label::-webkit-details-marker { display: none; }
.reminder-sched-preview-chevron {
    color: var(--text-muted);
    transition: transform .15s ease;
}
.reminder-sched-preview-wrap[open] > .reminder-sched-preview-label .reminder-sched-preview-chevron {
    transform: rotate(180deg);
}
.reminder-sched-preview-hint {
    text-transform: none; letter-spacing: 0; font-weight: 400;
    margin-left: 4px;
    cursor: help;
    border-bottom: 1px dotted currentColor;
}
.reminder-sched-preview {
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-card);
    /* Lighter shadow than the email card inside — preview itself is secondary */
    box-shadow: 0 1px 2px rgba(16, 24, 40, 0.03);
    overflow: hidden;
}

/* Hint below body editor explaining the auto-injected invoice card. */
.reminder-sched-auto-card-hint {
    display: flex; align-items: center; gap: 5px;
    margin: 6px 0 0;
    font-size: 12px;
    color: var(--text-muted);
}

/* Subject length counter — green by default, amber > 50 (mobile cutoff
   warning), red > 70. Helps users avoid truncated subjects on phones. */
.reminder-sched-subject-length {
    display: flex; align-items: center; gap: 6px;
    margin-top: 4px;
    font-size: 11px;
}
.reminder-sched-subject-counter {
    font-family: ui-monospace, Menlo, Consolas, monospace;
    font-weight: 600;
    color: var(--status-success-fg, #047857);
}
.reminder-sched-subject-counter.rs-subj-warn  { color: var(--status-warning-fg, #92400e); }
.reminder-sched-subject-counter.rs-subj-error { color: var(--status-danger-fg,  #b91c1c); }
.reminder-sched-subject-len-hint { font-size: 11px; }

/* Optional A/B-test subject variant disclosure. */
.reminder-sched-subject-b-wrap {
    margin-top: 8px;
    border: 1px dashed var(--border);
    border-radius: 6px;
    padding: 0;
}
.reminder-sched-subject-b-wrap > summary {
    cursor: pointer;
    padding: 8px 12px;
    font-size: 13px;
    color: var(--text-secondary);
    list-style: none;
    display: flex; align-items: center; gap: 6px;
}
.reminder-sched-subject-b-wrap > summary::-webkit-details-marker { display: none; }
.reminder-sched-subject-b-wrap[open] > summary { border-bottom: 1px dashed var(--border); }
.reminder-sched-subject-b-wrap > p,
.reminder-sched-subject-b-wrap > input { margin: 8px 12px; width: calc(100% - 24px); display: block; }
.reminder-sched-subject-b-hint { font-size: 12px; margin-bottom: 4px; }

/* Subject "Examples ▾" button + dropdown list — quick-pick suggestions. */
.reminder-sched-subject-examples-btn {
    width: auto;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    color: var(--text-secondary);
    font-size: 11px; font-weight: 500;
    padding: 2px 8px;
    border-radius: 4px;
    cursor: pointer;
    margin-left: 8px;
    transition: background .12s;
}
.reminder-sched-subject-examples-btn:hover { background: var(--bg-card); border-color: var(--text-muted); }
.reminder-sched-subject-examples {
    margin-top: 6px;
    padding: 10px 12px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 6px;
}
.reminder-sched-subject-examples p { margin: 0 0 6px; font-size: 12px; }
.reminder-sched-subject-examples ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 4px; }
.reminder-sched-subject-examples button {
    width: 100%;
    text-align: left;
    background: var(--bg-card);
    border: 1px solid var(--border);
    padding: 6px 10px;
    border-radius: 5px;
    font-size: 13px;
    color: var(--text-secondary);
    font-family: ui-monospace, Menlo, Consolas, monospace;
    cursor: pointer;
    transition: border-color .12s, background .12s;
}
.reminder-sched-subject-examples button:hover {
    border-color: var(--primary);
    background: var(--bg-card);
    color: var(--primary);
}
.reminder-sched-preview-envelope {
    padding: 16px 20px 12px;
    border-bottom: 1px solid #eef0f3;
    background: #fff;
}
.reminder-sched-preview-env-from {
    display: flex; align-items: center; gap: 10px;
    margin-bottom: 8px;
}
.reminder-sched-preview-env-meta {
    flex: 1 1 auto;
    display: flex; flex-direction: column;
    overflow: hidden;
}
.reminder-sched-preview-env-sender {
    font-weight: 600; font-size: 14px;
    color: #1a1a1a;
}
.reminder-sched-preview-env-addr {
    font-size: 12px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.reminder-sched-preview-env-time {
    font-size: 11px; flex: 0 0 auto;
}
.reminder-sched-preview-env-subject {
    font-size: 15px; font-weight: 600;
    color: #1a1a1a;
    word-break: break-word;
}
/* Preview stage — visually secondary on the page. The iframe shows the email
   as it'll arrive, but we desaturate + dim it slightly + add a soft overlay
   so the editor (above) stays the user's focus. The eye reads preview as
   "ambient confirmation", not "primary content". */
.reminder-sched-preview-stage {
    position: relative;
    background: #f4f6f9;
    /* No inner cap/scroll — the iframe auto-sizes (JS) to its full content
       height so the page keeps a single scrollbar; a nested scrollbar inside
       the card reads as broken. overflow:hidden just clips the rounded corner. */
    overflow: hidden;
}
.reminder-sched-preview-body {
    width: 100%;
    min-height: 560px;            /* fallback if JS auto-size fails — comfortable to show body + most of invoice card */
    border: 0; display: block;
    background: #f4f6f9;
    pointer-events: none;
    /* Slight desaturation + opacity so colors don't grab the eye */
    filter: saturate(0.85);
    opacity: 0.94;
}
/* Frosted-glass overlay — translucent white wash that signals "this is a
   read-only preview". Subtle enough to keep content legible. */
.reminder-sched-preview-stage::after {
    content: '';
    position: absolute; inset: 0;
    background: linear-gradient(180deg,
        rgba(244,246,249,0.18) 0%,
        rgba(244,246,249,0.10) 50%,
        rgba(244,246,249,0.22) 100%);
    pointer-events: none;
    z-index: 1;
}
.reminder-sched-preview-watermark {
    position: absolute;
    top: 10px; right: 12px;
    padding: 3px 8px;
    background: rgba(17, 24, 39, 0.45);
    color: #fff;
    font-size: 10px; font-weight: 600;
    letter-spacing: 0.12em;
    border-radius: 4px;
    pointer-events: none;
    user-select: none;
    z-index: 2;
}

/* Team page status badges */
.team-status {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 2px 10px; border-radius: 999px;
    font-size: 12px; font-weight: 600;
}
.team-status-active  { background: var(--status-success-bg); color: var(--status-success-fg); }
.team-status-pending { background: var(--status-warning-bg); color: var(--status-warning-fg); }
.team-role-hint { list-style: none; margin: 12px 0 0; padding: 0; font-size: 13px; }
.team-role-hint li { position: relative; padding-left: 15px; line-height: 1.65; }
.team-role-hint li::before {
    content: ""; position: absolute; left: 2px; top: .66em;
    width: 4px; height: 4px; border-radius: 50%; background: var(--text-muted);
}
.team-table-wrap {
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}
.team-table { table-layout: fixed; min-width: 0; }
.team-col-avatar { width: 50px; }
.team-col-email { width: auto; }
.team-col-role { width: 116px; }
.team-col-status { width: 138px; }
.team-col-invited { width: 84px; }
.team-col-joined { width: 56px; }
.team-col-actions { width: 142px; }
.team-table th,
.team-table td { vertical-align: middle; }
.team-email-cell { overflow-wrap: anywhere; }
.team-role-cell { padding-right: 8px; }
.team-status-cell { padding-left: 20px; }
.team-role-select {
    width: 108px;
    min-width: 108px;
    height: 40px;
    line-height: 1.2;
}
.team-actions-cell { white-space: nowrap; }
.team-row-actions {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 14px;
    min-width: max-content;
}

@media (max-width: 720px) {
    .team-table { min-width: 720px; }
}

/* Organizations table — fixed layout so Slug/Created/Actions stay aligned and
   the actions sit flush-right instead of floating after an over-wide Name col. */
.org-table-wrap {
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}
/* Auto layout so Slug/Created/Actions each shrink to their content (width:1% +
   nowrap is the fit-content trick) and Name absorbs the rest. This guarantees the
   actions column is never clipped — the old fixed 132px column cut off "Delete". */
.org-table { width: 100%; }
.org-col-name    { width: auto; }
.org-col-slug    { width: 1%; }
.org-col-created { width: 1%; }
.org-col-actions { width: 1%; }
.org-table th,
.org-table td { vertical-align: middle; }
.org-name-cell { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.org-name-text { overflow-wrap: anywhere; min-width: 0; }
.org-slug-cell,
.org-created-cell,
.org-actions-cell { white-space: nowrap; }
/* Inline rename pencil next to the org name — subtle until hovered. */
.org-rename-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 2px;
    border: 0;
    background: none;
    cursor: pointer;
    color: var(--text-muted);
    border-radius: 5px;
    transition: color .12s, background-color .12s;
}
.org-rename-btn:hover { color: var(--primary); background: var(--surface-hover, rgba(79,70,229,.08)); }
.org-row-actions {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 14px;
}

@media (max-width: 720px) {
    .org-table { min-width: 520px; }
}

/* Audit log filter bar — lay actor/action/from/to out in one wrapping row
   (defeats the global form-row full-width stacking); buttons bottom-aligned. */
.audit-filters .form-row { align-items: flex-end; gap: 14px; }
.audit-filters .form-row + .form-row { margin-top: 14px; }
.audit-filters .form-group { flex: 1 1 180px; min-width: 150px; margin: 0; }
.audit-filters .audit-filter-actions { display: flex; flex: 0 0 auto; gap: 10px; align-items: center; }
.audit-table-wrap {
    max-width: 100%;
    overflow-x: auto;
    padding-bottom: 4px;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    scrollbar-color: var(--border) transparent;
}
.audit-table-wrap::-webkit-scrollbar { height: 8px; }
.audit-table-wrap::-webkit-scrollbar-thumb { background: var(--border); border-radius: 999px; }
.audit-table { width: 100%; min-width: 0; table-layout: fixed; }
.audit-table th,
.audit-table td { vertical-align: top; overflow-wrap: anywhere; }
.audit-col-date { width: 22%; }
.audit-col-actor { width: 30%; }
.audit-col-action { width: 16%; }
.audit-col-target { width: 12%; }
.audit-col-detail { width: 20%; }
.audit-date { white-space: normal; }
.audit-detail-list {
    display: flex; flex-wrap: wrap; gap: 6px 10px;
    max-width: 100%; min-width: 0;
}
.audit-detail-item {
    display: inline-flex; gap: 4px; min-width: 0; max-width: 100%;
    color: var(--text);
}
.audit-detail-key { flex: 0 0 auto; color: var(--text-muted); font-weight: 700; }
.audit-detail-value { min-width: 0; overflow-wrap: anywhere; color: var(--text-muted); }

@media (max-width: 720px) {
    .audit-table { min-width: 760px; }
    .audit-date { white-space: nowrap; }
}

/* client/view page-head: enlarged avatar variant */
.client-avatar-lg {
    width: 40px; height: 40px;
    font-size: 16px;
    margin-right: 8px; vertical-align: middle;
}

/* === Invoice form payment-terms quick picker (NET 0/7/14/30/60) ===
   Lives on its own row between the label and the date input so it can wrap
   freely on narrow viewports without colliding with the label text. */
.payment-terms-quick {
    display: flex; flex-wrap: wrap; gap: 4px;
    margin: 4px 0 6px;
}
.terms-btn {
    background: var(--bg-tertiary); border: 1px solid var(--border);
    color: var(--text-muted);
    padding: 2px 8px; border-radius: 999px;
    font-size: 11px; font-weight: 500;
    cursor: pointer; transition: all .12s;
}
.terms-btn:hover { color: var(--primary); border-color: var(--primary); }
.terms-btn.active {
    background: var(--accent-light); color: var(--primary);
    border-color: var(--primary); font-weight: 600;
}

/* Brief flash on inputs that just changed silently (e.g. NET button updated due_date) */
@keyframes input-flash-anim {
    0%   { box-shadow: 0 0 0 0 var(--primary); }
    50%  { box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 30%, transparent); }
    100% { box-shadow: 0 0 0 0 var(--primary); }
}
.input-flash { animation: input-flash-anim .6s ease-out; }

/* Inline help text inside form labels — small, muted, on its own line.
   `.form-help-error` flips to danger color when JS validation flags the rule. */
.form-help { display: block; font-weight: 400; font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.form-help-error { color: var(--danger); }
/* Inline field warning (e.g. captured invoice number already in Duefy). */
.form-field-warn { margin: 6px 0 0; font-size: 12.5px; line-height: 1.4; color: var(--status-warning-fg); }
.form-field-warn a { color: inherit; text-decoration: underline; }

/* Invoice add/edit form actions row — primary submit + optional "save and continue" */
.invoice-form-actions { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 8px; }
.invoice-form-card { max-width: 560px; }
.invoice-edit-warning {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    max-width: 500px;
    margin: 0 0 18px;
    padding: 12px 14px;
    border: 1px solid var(--status-warning-bg);
    border-radius: var(--radius);
    background: #FFFBEB;
    color: #92400E;
    font-size: 13px;
    line-height: 1.45;
}
.invoice-edit-warning .icon-inline { flex-shrink: 0; margin-top: 1px; }
.invoice-edit-warning strong {
    display: block;
    color: #78350F;
    font-weight: 700;
    margin-bottom: 2px;
}
.invoice-edit-warning span { color: #92400E; }

/* === Settings nav groups (Account / Workspace / Billing / Integrations / Advanced) === */
.settings-nav-group {
    margin-bottom: 14px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--border);
}
.settings-nav-group:last-child { border-bottom: none; }
.settings-nav-label {
    font-size: 10.5px; font-weight: 700;
    text-transform: uppercase; letter-spacing: .06em;
    color: var(--text-muted);
    padding: 6px 8px;
    margin-top: 4px;
}

/* === Settings page-head breadcrumb (Settings / X) === */
.settings-h1-prefix { color: var(--text-muted); font-weight: 500; }
.settings-h1-sep    { color: var(--text-muted); font-weight: 400; margin: 0 4px; }
.settings-h1-page   { color: var(--text); }

/* === Profile email verify status badge === */
.email-verify-status {
    display: inline-flex; align-items: center; gap: 3px;
    font-size: 11.5px; font-weight: 500;
    padding: 1px 8px;
    border-radius: 999px;
    margin-left: 6px;
    vertical-align: middle;
}
.email-verify-ok       { background: var(--status-success-bg); color: var(--status-success-fg); }
.email-verify-pending  { background: var(--status-warning-bg); color: var(--status-warning-fg); }
.email-verify-pending a { color: inherit; text-decoration: underline; font-weight: 600; }

/* === Billing banner icons (replace emoji ⚠️/🔴/🎁) === */
.billing-banner-icon {
    margin-bottom: 12px;
    color: var(--text-muted);
    display: inline-flex; align-items: center; justify-content: center;
}
.billing-banner-icon-warning { color: var(--warning); }
.billing-banner-icon-danger  { color: var(--danger); }
.billing-banner-icon-success { color: var(--success); }
.billing-banner-h2-warning   { color: var(--status-danger-fg); }
.billing-banner-h2-danger    { color: var(--status-danger-fg); }
.billing-banner-h2-warning-amber { color: var(--status-warning-fg); }
.billing-preview-err {
    text-align: center; padding: 16px;
    color: var(--status-danger-fg);
}

/* Hover tooltip for technical acronyms like CEI / DSO — underline hints they're hoverable */
.info-tip {
    cursor: help;
    border-bottom: 1px dotted var(--text-muted);
    margin-left: 4px;
    font-weight: normal; color: var(--text-muted);
    /* An abbreviation and its icon are one unit — never split them across lines. */
    white-space: nowrap;
}

/* stat-card as an <a> link (whole card clickable, jumps to filtered invoices) */
.stat-card-link {
    text-decoration: none; color: inherit; display: block;
    transition: border-color .12s, box-shadow .12s, transform .12s;
}
.stat-card-link:hover {
    border-color: var(--primary);
    box-shadow: 0 3px 10px rgba(79,70,229,0.09);
    transform: translateY(-1px);
    text-decoration: none;
}
/* Trend pill below stat-value, shows this-month vs last-month delta */
.stat-trend {
    display: flex; align-items: center; gap: 4px;
    margin-top: 6px;
    font-size: 12px; font-weight: 600;
    /* KPI sub-line is always a single line — never let a long descriptor wrap
       to two rows and knock the card taller than its row neighbours. */
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    max-width: 100%;
}
.stat-trend-up   { color: var(--status-success-fg); }
.stat-trend-down { color: var(--status-danger-fg); }
.stat-trend.muted { color: var(--text-muted); font-weight: 400; }

/* Customizer-reorderable Dashboard cards below the stat row */
.dashboard-stack { display: flex; flex-direction: column; }
.dashboard-stack > .card {
    margin-bottom: 16px;
    box-shadow: 0 1px 2px rgba(16,24,40,.05);
}
.dashboard-stack > .card .card-head { margin-bottom: 12px; }
.dashboard-stack > .dashboard-empty-card {
    padding-top: 16px;
    padding-bottom: 16px;
}
.dashboard-stack > .dashboard-empty-card .card-head { margin-bottom: 6px; }
.dashboard-stack [data-card-id="recent_activity"] {
    padding: 20px 22px;
}
.dashboard-stack [data-card-id="recent_activity"] .card-head {
    margin-bottom: 10px;
}
.dashboard-stack [data-card-id="recent_activity"] .table th,
.dashboard-stack [data-card-id="recent_activity"] .table td {
    padding: 9px 12px;
    line-height: 1.3;
}
.dashboard-card-note {
    color: var(--text-muted);
    font-size: 13px;
    font-weight: 600;
}
.dashboard-quiet-state {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 0 2px;
    color: var(--text-muted);
}
.dashboard-empty-card .dashboard-quiet-state { padding: 6px 0 0; }
.dashboard-quiet-state-compact {
    align-items: center;
    padding-top: 4px;
}
.dashboard-quiet-state-compact strong { margin-bottom: 0; }
.dashboard-promises-card.dashboard-empty-card .dashboard-quiet-icon { color: var(--text-muted); }
.dashboard-quiet-state strong {
    display: block;
    color: var(--text);
    margin-bottom: 2px;
}
.dashboard-quiet-icon {
    color: var(--success);
    flex: 0 0 auto;
    margin-top: 1px;
}
.dashboard-action-list {
    border: 1px solid var(--border);
    border-radius: 9px;
    overflow: hidden;
}
.dashboard-action-row {
    display: grid;
    grid-template-columns: 34px minmax(0, 1fr) 22px;
    align-items: center;
    gap: 12px;
    padding: 13px 14px;
    color: inherit;
    text-decoration: none;
    border-bottom: 1px solid var(--border);
    transition: background .12s, border-color .12s;
}
.dashboard-action-row:last-child { border-bottom: 0; }
.dashboard-action-row:hover {
    background: var(--surface-2);
    text-decoration: none;
}
.dashboard-action-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 8px;
    background: var(--accent-light);
    color: var(--primary);
}
.dashboard-action-danger .dashboard-action-icon {
    background: var(--status-danger-bg);
    color: var(--status-danger-fg);
}
.dashboard-action-warning .dashboard-action-icon {
    background: var(--status-warning-bg);
    color: var(--status-warning-fg);
}
.dashboard-action-success .dashboard-action-icon {
    background: var(--status-success-bg);
    color: var(--status-success-fg);
}
.dashboard-action-copy {
    display: grid;
    gap: 2px;
    min-width: 0;
}
.dashboard-action-copy strong {
    color: var(--text);
    font-size: 15px;
    line-height: 1.25;
}
.dashboard-action-copy > span:last-child {
    color: var(--text-muted);
    font-size: 13px;
    line-height: 1.3;
}
.dashboard-action-label {
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 800;
    letter-spacing: .04em;
    text-transform: uppercase;
}
.dashboard-action-danger .dashboard-action-label { color: var(--status-danger-fg); }
.dashboard-action-warning .dashboard-action-label { color: var(--status-warning-fg); }
.dashboard-action-success .dashboard-action-label { color: var(--status-success-fg); }
.dashboard-action-arrow {
    color: var(--text-muted);
    justify-self: end;
}
.forecast-metric-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0;
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
}
.forecast-metric {
    padding: 15px 18px 14px;
    border-right: 1px solid var(--border);
}
/* Clickable forecast metric — jumps to the matching invoice-list filter. */
.forecast-metric-link { display: block; text-decoration: none; color: inherit; cursor: pointer; transition: background .12s; }
.forecast-metric-link:hover { background: var(--accent-light); text-decoration: none; }
.forecast-metric:first-child { padding-left: 0; }
.forecast-metric:last-child {
    border-right: 0;
    padding-right: 0;
}
.forecast-label {
    color: var(--text-muted);
    font-size: 12px;
    font-weight: 800;
    letter-spacing: .04em;
    text-transform: uppercase;
}
.forecast-value {
    color: var(--text);
    font-size: 24px;
    font-weight: 800;
    line-height: 1.1;
    margin-top: 8px;
}
.forecast-sub {
    color: var(--text-muted);
    font-size: 13px;
    margin-top: 5px;
}
.forecast-metric-promise.forecast-metric-has-value .forecast-value { color: var(--primary); }
/* Zero-value metric: keep the number for scanability but mute it — a bold
   "USD 0" reads like a problem when it's actually "nothing due, all good". */
.forecast-metric-zero .forecast-value { color: var(--text-muted); font-weight: 600; }
.forecast-footnote {
    color: var(--text-muted);
    font-size: 13px;
    margin-top: 12px;
}
.dashboard-aging-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 12px;
}
.aging-bucket {
    padding: 14px;
    border: 1px solid var(--border);
    border-radius: 9px;
    background: var(--surface-3);
    min-width: 0;
}
/* Clickable aging bucket — jumps to the matching invoice-list filter. */
.aging-bucket-link { display: block; text-decoration: none; color: inherit; cursor: pointer; transition: border-color .12s, box-shadow .12s; }
.aging-bucket-link:hover { border-color: var(--primary); box-shadow: 0 1px 4px rgba(79,70,229,0.10); text-decoration: none; }
.aging-label {
    color: var(--text-muted);
    font-size: 12px;
    font-weight: 800;
    letter-spacing: .04em;
    text-transform: uppercase;
}
.aging-value {
    color: var(--text);
    font-size: 20px;
    font-weight: 800;
    line-height: 1.1;
    margin-top: 9px;
    overflow-wrap: anywhere;
}
.aging-sub {
    color: var(--text-muted);
    font-size: 13px;
    margin-top: 5px;
}
.aging-bucket-has-balance.aging-bucket-d31_60 .aging-value { color: var(--warning-strong); }
.aging-bucket-has-balance.aging-bucket-d60p .aging-value { color: var(--danger); }
.dashboard-mini-list {
    border: 1px solid var(--border);
    border-radius: 9px;
    overflow: hidden;
}
.dashboard-mini-row {
    display: grid;
    grid-template-columns: 96px minmax(0, 1fr) auto;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    color: inherit;
    text-decoration: none;
    border-bottom: 1px solid var(--border);
}
.dashboard-mini-row:last-child { border-bottom: 0; }
.dashboard-mini-row:hover {
    background: var(--surface-2);
    text-decoration: none;
}
.dashboard-mini-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 24px;
    padding: 3px 9px;
    border-radius: 999px;
    background: var(--accent-light);
    color: var(--primary);
    font-size: 12px;
    font-weight: 800;
    white-space: nowrap;
}
.dashboard-mini-danger .dashboard-mini-badge {
    background: var(--status-danger-bg);
    color: var(--status-danger-fg);
}
.dashboard-mini-warning .dashboard-mini-badge {
    background: var(--status-warning-bg);
    color: var(--status-warning-fg);
}
.dashboard-mini-success .dashboard-mini-badge {
    background: var(--status-success-bg);
    color: var(--status-success-fg);
}
.dashboard-mini-copy {
    display: grid;
    gap: 2px;
    min-width: 0;
}
.dashboard-mini-copy strong {
    color: var(--text);
    font-size: 14px;
    line-height: 1.25;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dashboard-mini-copy span {
    color: var(--text-muted);
    font-size: 13px;
    line-height: 1.25;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dashboard-mini-amount {
    color: var(--text);
    font-size: 14px;
    font-weight: 800;
    white-space: nowrap;
}

/* Row of invoice-related entry points (/invoice/, /invoice/import/, etc. sibling page top toolbar) */
/* Invoice 3-button entry toolbar — separate line below page-head to prevent button wrap when page-head flex is tight */
.invoice-actions-bar {
    display: flex; gap: 7px; flex-wrap: wrap; align-items: center;
    margin-top: -10px; margin-bottom: 22px;
}
/* Phones: the wrapping toolbar otherwise stacks 7-8 "ways to get invoices in"
   buttons into ~1.5 screens before the list. The common ones (Add / Capture /
   Import) are already in the + action sheet, so collapse this into one swipeable
   row and drop the current-page button (dead weight when you're already here).
   Everything stays reachable; the first screen now shows actual invoices. */
@media (max-width: 640px) {
    .invoice-actions-bar {
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        margin-top: 0;
        margin-bottom: 14px;
        padding-bottom: 4px;
    }
    .invoice-actions-bar::-webkit-scrollbar { display: none; }
    .invoice-actions-bar .btn { flex: 0 0 auto; white-space: nowrap; }
    .invoice-actions-bar .btn.is-current { display: none; }
}
/* pdfImport content max-width — matches .card.card-medium (720) used in import.tpl.php,
   otherwise the PDF page upload-zone / results-list fills the 1032 container and looks much wider than the Excel page */
.pdf-import-page { max-width: 720px; }
/* invoice/connect also capped — after extracting the partial there's no settings _nav placeholder, container expands to 1032,
   so cap it to keep visual parity with import/pdf */
.invoice-connect-page { max-width: 720px; }
.invoice-intake-page { max-width: 780px; }

/* Notice card embedded in dashboard AI replies (yellow warning). Previously hard-coded #FEF3C7/#92400E broke in dark mode */
.ai-notice {
    margin-top: 8px; padding: 8px 12px;
    background: var(--status-warning-bg); color: var(--status-warning-fg);
    border-radius: 6px; font-size: 13px;
    display: flex; align-items: center; gap: 6px;
}
/* dashboard quick-activate header icon vertically centered with the title text */
.qa-header-icon { vertical-align: middle; color: var(--primary); }

/* invoice/index undo toast — 5-second undo window after markPaid. Previously JS inlined
   #1f2937 as the background which made the toast nearly invisible on dark surfaces in dark mode.
   Switched to a CSS class + var(--toast-bg) so the contrast auto-inverts. */
.undo-toast {
    position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
    background: var(--toast-bg, #1f2937); color: var(--toast-fg, #fff);
    border: 1px solid var(--toast-border, transparent);
    padding: 12px 20px; border-radius: 8px;
    box-shadow: 0 4px 12px rgba(0,0,0,.2);
    display: flex; align-items: center; gap: 16px;
    font-size: 14px; z-index: 9999;
}
.undo-toast-countdown { opacity: .7; }
.undo-toast-btn {
    background: var(--toast-action-bg, var(--toast-fg, #fff));
    color: var(--toast-action-fg, var(--toast-bg, #1f2937));
    border: none; padding: 6px 14px; border-radius: 6px;
    font-weight: 600; cursor: pointer;
}
.undo-toast-btn:hover { background: var(--toast-action-hover, var(--toast-action-bg, #fff)); }

/* Pro/Team feature-lock visual badge — shown next to locked buttons/sections for non-Pro/Team users,
   triggers Duefy.triggerProSwitch() confirm + one-click switch trial */
.pro-badge {
    display: inline-flex; align-items: center;
    font-size: 10px; font-weight: 700; line-height: 1;
    padding: 3px 7px; border-radius: 999px;
    background: var(--accent-light); color: var(--primary);
    border: 1px solid var(--accent-border);
    text-transform: uppercase; letter-spacing: .05em;
    margin-left: 6px; vertical-align: middle;
}
/* "Tag" variant: tuck the Pro badge up to the word's top-right corner (raised +
   tight) instead of a centred pill that pushes the next item. Used in the top
   nav and the invoice toolbar; other inline pills keep the default .pro-badge. */
.pro-badge-tag {
    font-size: 9px;
    padding: 2px 5px;
    margin-left: -5px;
    vertical-align: top;
    position: relative;
    top: -3px;
}
/* Team-only feature (Team management) — deeper purple to distinguish from the Pro badge */
.pro-badge-team {
    background: #EDE9FE; color: #6D28D9;
    border-color: #C4B5FD;
}
.iv-late-locked-hint { margin: 4px 0 10px; line-height: 1.5; }

/* Dashboard AI assistant Solo-locked state: disabled input + hint copy + Switch CTA */
.ai-assistant-locked .ai-input-row input[disabled] {
    background: var(--bg-tertiary); color: var(--text-muted); cursor: not-allowed;
}
.ai-locked-hint { margin: 8px 0 12px; font-size: 13px; }

/* settings/notifications SMS Pro-lock row: entire row clickable, hover hint + disabled toggle is greyed */
.toggle-row-locked {
    cursor: pointer;
    transition: background .15s;
}
.toggle-row-locked:hover { background: var(--bg-tertiary); }
.toggle-row-locked .switch input:disabled + .slider { opacity: .5; cursor: not-allowed; }

/* choose-plan feature groups — visually consistent with home/_pricing_grid */
.pf-core, .pf-new, .pf-inherited, .pf-inherited-pro {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 8px 0; border-bottom: 1px solid var(--border);
    font-size: 14px; line-height: 1.45;
}
.pf-collapse[open] .pf-inherited:last-of-type,
.pf-collapse[open] .pf-inherited-pro:last-of-type { border-bottom: none; }
.pf-inherited     { opacity: .65; }
.pf-inherited-pro { opacity: .5; }
.pf-inherited .pf-icon-check, .pf-inherited-pro .pf-icon-check { color: var(--text-muted); }
.pf-new          { font-weight: 500; }
.pf-icon-check, .pf-icon-new { flex-shrink: 0; margin-top: 2px; }
.pf-icon-check   { color: var(--success); }
.pf-icon-new     { color: var(--primary); fill: var(--primary); }
.pf-text         { flex: 1; min-width: 0; }
.pf-note         { display: block; color: var(--text-muted); font-size: 12px; margin-top: 1px; }
.pf-divider {
    display: flex; align-items: center; gap: 8px;
    padding: 14px 0 8px;
    font-size: 11px; font-weight: 700;
    color: var(--primary);
    text-transform: uppercase; letter-spacing: .05em;
}
.pf-divider::before, .pf-divider::after {
    content: ""; flex: 1; height: 1px; background: var(--accent-light);
}
.pf-divider span { white-space: nowrap; }

/* Inherited collapsible details: render summary as an outlined chip — more prominent than a plain underline link
   but weaker than a solid button; the eye icon makes 'click to expand' semantics obvious */
.pf-collapse { margin: 8px 0; }
.pf-collapse > summary {
    cursor: pointer; list-style: none;
    display: inline-flex; align-items: center; gap: 6px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    padding: 6px 12px; border-radius: 999px;
    font-size: 12.5px; color: var(--text); font-weight: 500;
    transition: border-color .15s, background .15s, color .15s;
}
.pf-collapse > summary:hover {
    border-color: var(--primary); color: var(--primary);
    background: var(--accent-light);
}
.pf-collapse > summary .icon-inline { opacity: .8; }
.pf-collapse > summary::-webkit-details-marker { display: none; }
.pf-collapse > summary::after {
    content: '▾'; display: inline-block;
    transition: transform .15s; font-size: 10px; margin-left: 2px;
}
.pf-collapse[open] > summary::after { transform: rotate(180deg); }
.pf-collapse[open] > summary {
    background: var(--accent-light); color: var(--primary);
    border-color: var(--primary);
}

/* choose-plan price-area annual-savings hint — same green pill as home/_pricing_grid.
   No nowrap: the pill must wrap inside a narrow plan card instead of poking
   out of the viewport at mid widths. */
.cp-annual-hint {
    display: inline-flex; align-items: center; flex-wrap: wrap; gap: 5px;
    background: var(--status-success-bg); color: var(--status-success-fg);
    font-size: 12.5px; padding: 4px 10px; border-radius: 6px;
    margin-top: 8px; width: fit-content;
}
.cp-annual-hint strong { font-weight: 700; }
.cp-annual-hint .icon-inline { opacity: .7; }

/* Team-card 'Extra seats / Extra orgs' rows — dimmer than features (paid add-ons, not included) */
.plan-card-extra {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 8px 0; border-bottom: 1px solid var(--border);
    font-size: 13px; color: var(--text-muted);
    line-height: 1.45;
}
.plan-card-extra .plan-feature-star { color: var(--warning); flex-shrink: 0; margin-top: 2px; }

/* invoice/view AI reply badges — previously hard-coded inline style colors broke in dark mode */
.badge-sentiment { background: var(--accent-light); color: var(--primary); }
.badge-resolved {
    background: var(--status-success-bg); color: var(--status-success-fg);
    display: inline-flex; align-items: center; gap: 4px;
}
/* Risk level — low green / medium orange / high red (matches the $riskColors PHP map) */
.badge-risk-low    { background: #16A34A; color: #fff; }
.badge-risk-medium { background: #D97706; color: #fff; }
.badge-risk-high   { background: #DC2626; color: #fff; }
/* Compact paddings: with 7 buttons the bar sits at ~1000px — the Solo "Pro"
   badge on Accounting import (+40px) used to push the last button onto a
   second row at the standard 1032px container. ~2px/side per button buys the
   headroom without touching labels. */
.invoice-actions-bar .btn { display: inline-flex; align-items: center; gap: 4px; padding-left: 11px; padding-right: 11px; }
/* "Capture from phone" is pointless on desktop (use file upload / Import PDF) —
   show it only on phone-sized screens, matching the app's 768px mobile break. */
.invoice-actions-bar .invoice-action-capture { display: none; }
@media (max-width: 768px) { .invoice-actions-bar .invoice-action-capture { display: inline-flex; } }
.invoice-actions-bar .btn.is-current {
    background: var(--accent-light);
    border-color: var(--accent-border);
    color: var(--primary);
    /* Stays clickable: on the invoice sub-pages (review / chase / installments)
       "Invoices" is highlighted as the active section but must still link back to
       the list; on the list itself a click is a harmless reload. */
}

/* "Needs action" strip (tpl/invoice/index.tpl.php) — three count-driven cards
   above the Views row for the things that wait on a human. All colours come
   from theme tokens (+ color-mix tints) so dark mode is handled automatically. */
/* Divider under the strip so the cards read as their own zone, separate from the
   page content (Views / metrics / lists) below — otherwise the numbers and buttons
   beneath look like they belong to the cards. */
.needs-action { margin: 0 0 18px; padding-bottom: 16px; border-bottom: 1px solid var(--border); }
.needs-action-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.needs-action-title { font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--text-muted); }
.needs-action-total {
    min-width: 20px; height: 20px; padding: 0 6px; border-radius: 999px;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 12px; font-weight: 700; color: var(--text); background: var(--accent-light);
    transition: background .15s, color .15s;
}
/* When collapsed the count is the only signal that there's work waiting, so make
   it stand out (solid danger pill) instead of the neutral expanded style. */
.needs-action.is-collapsed .needs-action-total {
    color: #fff; background: var(--danger);
}
.needs-action-toggle {
    margin-left: auto; display: inline-flex; align-items: center; justify-content: center;
    width: 28px; height: 28px; border: 1px solid var(--border); border-radius: 6px;
    background: var(--bg-card); color: var(--text-muted); cursor: pointer; transition: color .12s, border-color .12s;
}
.needs-action-toggle:hover { color: var(--text); }
.needs-action-toggle svg { transition: transform .15s; }
.needs-action.is-collapsed .needs-action-cards { display: none; }
.needs-action.is-collapsed .needs-action-toggle svg { transform: rotate(180deg); }
.needs-action-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; }
.needs-action-card {
    display: block; padding: 14px 16px; border: 1px solid var(--border);
    border-left-width: 4px; border-radius: 10px; background: var(--bg-card);
    text-decoration: none; color: inherit;
    transition: box-shadow .12s, transform .12s, border-color .12s;
}
.needs-action-card:hover { box-shadow: 0 2px 10px rgba(0, 0, 0, .06); transform: translateY(-1px); }
.na-card-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.na-card-title { font-size: 15px; font-weight: 700; color: var(--text); }
.na-card-count {
    min-width: 24px; height: 22px; padding: 0 7px; border-radius: 999px;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 13px; font-weight: 700;
}
.na-card-desc { margin: 0; font-size: 13px; color: var(--text-muted); line-height: 1.4; }
.na-review { border-left-color: var(--warning); }
.na-review .na-card-count { color: var(--warning-strong); background: color-mix(in srgb, var(--warning) 16%, transparent); }
.na-chase { border-left-color: var(--danger); }
.na-chase .na-card-count { color: var(--danger); background: color-mix(in srgb, var(--danger) 14%, transparent); }
.na-plans { border-left-color: var(--primary); }
.na-plans .na-card-count { color: var(--primary); background: var(--accent-light); }
.na-intake { border-left-color: var(--status-info-fg); }
.na-intake .na-card-count { color: var(--status-info-fg); background: var(--status-info-bg); }
/* Active card = the sub-page you're currently on (the strip acts as a tab bar):
   a tinted fill + an accent ring so it reads as "you are here". */
.needs-action-card.is-active { transform: none; }
.na-review.is-active { background: color-mix(in srgb, var(--warning) 9%, var(--bg-card)); box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--warning) 45%, transparent); }
.na-chase.is-active  { background: color-mix(in srgb, var(--danger) 9%, var(--bg-card));  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--danger) 45%, transparent); }
.na-plans.is-active  { background: color-mix(in srgb, var(--primary) 9%, var(--bg-card)); box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--primary) 45%, transparent); }
.na-intake.is-active { background: color-mix(in srgb, var(--status-info-fg) 9%, var(--bg-card)); box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--status-info-fg) 45%, transparent); }
@media (max-width: 768px) { .needs-action-cards { grid-template-columns: 1fr; } }

/* Situation chips on "Chase up" (/invoice/recovery/) — one-click presets that
   absorbed the old Collections Playbooks page. Theme tokens → dark-mode safe. */
.recovery-signal-chips { display: flex; flex-wrap: wrap; gap: 7px; margin: 0 0 14px; }
.recovery-chip {
    display: inline-flex; align-items: center; padding: 5px 12px; border-radius: 999px;
    border: 1px solid var(--border); background: var(--bg-card); color: var(--text-muted);
    font-size: 13px; font-weight: 600; text-decoration: none; transition: color .12s, border-color .12s, background .12s;
}
.recovery-chip:hover { color: var(--text); border-color: var(--accent-border); }
.recovery-chip.is-active {
    color: var(--primary); background: var(--accent-light); border-color: var(--accent-border);
}
/* Locked Pro teaser chips + filter on Chase up (shown to Solo). A dashed outline
   marks them as "preview, not active"; clicking pops the upgrade modal. */
.recovery-chip-pro { gap: 6px; border-style: dashed; cursor: pointer; }
.recovery-chip-pro:hover { color: var(--text); border-color: var(--primary); }
.recovery-filter-pro { cursor: pointer; }
.recovery-filter-pro select[disabled] { pointer-events: none; opacity: .6; }
/* Chase up (/invoice/chase/) — summary cards, collapsible filter bar, priority
   queue table. Extracted from the page's inline <style> to share one source. */
.recovery-summary-grid { display:grid; grid-template-columns:repeat(4, minmax(140px, 1fr)); gap:12px; margin:14px 0 18px; }
.recovery-summary { border:1px solid var(--border); border-radius:8px; background:var(--bg-card); padding:14px 16px; }
.recovery-summary-label { color:var(--text-muted); font-size:12px; margin-bottom:4px; }
.recovery-summary strong { display:block; font-size:22px; color:var(--text); }
.recovery-summary-note { margin-top:4px; color:var(--text-muted); font-size:11px; line-height:1.35; }
/* Quiet per-row "View" link in the Priority invoices table. A column of solid
   primary buttons reads as a wall of CTAs and out-shouts the page's real action
   (Export CSV) — and the invoice number already links to the same place. Render
   it as a ghost link: primary text + chevron, faint accent wash only on hover. */
.ri-view {
    display:inline-flex; align-items:center; gap:3px; white-space:nowrap;
    font-size:13px; font-weight:600; color:var(--primary);
    padding:4px 9px; border-radius:6px; transition:background .15s;
}
.ri-view::after { content:'\203A'; font-size:15px; line-height:1; }
.ri-view:hover { background:var(--accent-light); }
.recovery-filters { margin:0 0 18px; }
.recovery-filters-summary { cursor:pointer; list-style:none; display:inline-flex; align-items:center; gap:7px; font-size:13px; font-weight:600; color:var(--text-muted); padding:6px 0; }
.recovery-filters-summary::-webkit-details-marker { display:none; }
.recovery-filters-summary::after { content:'\25BE'; }
.recovery-filters[open] .recovery-filters-summary::after { content:'\25B4'; }
.recovery-filters-on { background:var(--accent-light); color:var(--primary); border-radius:999px; padding:1px 8px; font-size:11px; }
.recovery-filter-bar { display:grid; grid-template-columns:repeat(6, minmax(120px, 1fr)) auto; gap:10px; align-items:end; margin:8px 0 0; padding:12px; border:1px solid var(--border); border-radius:8px; background:var(--bg-card); }
.recovery-filter-bar label { display:flex; flex-direction:column; gap:4px; margin:0; }
.recovery-filter-bar label span { font-size:12px; color:var(--text-muted); font-weight:600; }
.recovery-filter-bar select,
.recovery-filter-bar input { width:100%; min-height:34px; }
.recovery-range-pair { display:grid; grid-template-columns:1fr 1fr; gap:6px; }
.recovery-filter-actions { display:flex; gap:6px; justify-content:flex-end; }
.recovery-head { display:flex; justify-content:space-between; align-items:flex-start; gap:14px; margin-bottom:14px; }
.recovery-head h2 { margin-bottom:4px; }
.recovery-bulk-bar { display:flex; justify-content:space-between; align-items:center; gap:12px; margin:0 0 12px; padding:10px 12px; border:1px solid var(--border); border-radius:8px; background:var(--bg-tertiary); }
.recovery-bulk-bar[hidden] { display:none; }
.recovery-bulk-actions { display:flex; flex-wrap:wrap; justify-content:flex-end; gap:6px; }
.recovery-table-wrap { overflow-x:auto; }
.recovery-table th:last-child,
.recovery-table td:last-child { text-align:right; }
/* Column engine (resize + sort) on the Chase queue: anchor the resize handle to
   each th and keep sort headers on one line. */
.recovery-table thead th { position: relative; }
.recovery-table thead th .sort-link { white-space: nowrap; }
.recovery-check-cell { width:34px; text-align:center; }
.recovery-invoice-no { font-weight:700; }
.recovery-score { display:inline-flex; align-items:center; justify-content:center; min-width:38px; height:28px; border-radius:999px; font-size:12px; font-weight:800; }
.recovery-score-danger { background:var(--status-danger-bg); color:var(--status-danger-fg); }
.recovery-score-warning { background:var(--status-warning-bg); color:var(--status-warning-fg); }
.recovery-score-info { background:var(--status-info-bg); color:var(--status-info-fg); }
.recovery-score-neutral { background:var(--bg-tertiary); color:var(--text-muted); }
.recovery-signal { display:inline-flex; align-items:center; border-radius:999px; padding:2px 8px; font-size:11px; font-weight:700; }
.recovery-signal-danger { background:var(--status-danger-bg); color:var(--status-danger-fg); }
.recovery-signal-warning { background:var(--status-warning-bg); color:var(--status-warning-fg); }
.recovery-signal-info { background:var(--status-info-bg); color:var(--status-info-fg); }
.recovery-signal-neutral { background:var(--bg-tertiary); color:var(--text-muted); }
.recovery-reason { max-width:320px; margin-top:4px; color:var(--text-muted); font-size:12px; line-height:1.35; }
.recovery-next { display:inline-flex; align-items:center; border-radius:999px; padding:2px 8px; font-size:11px; font-weight:700; }
.recovery-next-overdue,
.recovery-next-due_today { background:var(--status-danger-bg); color:var(--status-danger-fg); }
.recovery-next-soon { background:var(--status-warning-bg); color:var(--status-warning-fg); }
.recovery-next-later { background:var(--bg-tertiary); color:var(--text-muted); }
.recovery-actions { white-space:nowrap; }
@media (max-width: 860px) {
    .recovery-summary-grid { grid-template-columns:repeat(2, minmax(140px, 1fr)); }
    .recovery-filter-bar { grid-template-columns:repeat(2, minmax(140px, 1fr)); }
    .recovery-filter-actions { justify-content:flex-start; }
    .recovery-bulk-bar { align-items:flex-start; flex-direction:column; }
    .recovery-bulk-actions { justify-content:flex-start; }
    .recovery-client-cell { display:none; }
}
@media (max-width: 560px) {
    /* Keep the 4 summary cards 2-up (was stacking to a tall single column);
       shrink the value so a wide currency total still fits half-width. */
    .recovery-summary-grid { grid-template-columns:repeat(2, minmax(0,1fr)); gap:10px; }
    .recovery-summary strong { font-size:18px; }
    .recovery-filter-bar { grid-template-columns:1fr; }
    /* Situation filter chips: one scrollable row instead of 3 stacked rows. */
    .recovery-signal-chips { flex-wrap:nowrap; overflow-x:auto; -webkit-overflow-scrolling:touch; scrollbar-width:none; margin-left:-2px; padding:2px; }
    .recovery-signal-chips::-webkit-scrollbar { display:none; }
    .recovery-chip { flex:0 0 auto; }
}

/* ============================================================
   Payment plans / installments — shared by /invoice/installments/ and
   /settings/paymentPlans/ (extracted from those templates' inline <style>).
   ============================================================ */
.payment-plan-tabs { display:flex; flex-wrap:wrap; gap:8px; margin:14px 0 18px; }
.payment-plan-tab { border:1px solid var(--border); border-radius:999px; padding:5px 12px; font-size:13px; color:var(--text-muted); background:var(--bg-card); }
.payment-plan-tab:hover { text-decoration:none; color:var(--text); border-color:var(--primary); }
.payment-plan-tab.is-active { background:var(--accent-light); color:var(--primary); border-color:var(--primary); font-weight:600; }
.payment-plan-metrics { display:grid; grid-template-columns:repeat(4, minmax(150px, 1fr)); gap:12px; margin:0 0 16px; }
.payment-plan-metric { border:1px solid var(--border); border-radius:8px; background:var(--bg-card); padding:12px 14px; min-height:82px; display:flex; flex-direction:column; justify-content:space-between; }
.payment-plan-metric span { color:var(--text-muted); font-size:12px; }
.payment-plan-metric strong { color:var(--text); font-size:24px; line-height:1.15; }
.payment-plan-metric-danger strong { color:var(--status-danger-fg); }
.payment-plan-metric.is-clickable { text-decoration:none; cursor:pointer; transition:border-color .12s, box-shadow .12s, transform .12s; }
.payment-plan-metric.is-clickable:hover { border-color:var(--accent-border); box-shadow:0 2px 10px rgba(0,0,0,.06); transform:translateY(-1px); }
.payment-plan-metric.is-clickable span { color:var(--primary); }
.payment-plan-balance { display:flex; flex-direction:column; gap:2px; }
.payment-plan-balance span { color:var(--text); font-size:16px; font-weight:700; }
.payment-plan-head { display:flex; justify-content:space-between; align-items:flex-start; gap:16px; margin-bottom:16px; }
.payment-plan-head h2 { margin-bottom:4px; }
.payment-plan-policy-summary { display:flex; flex-wrap:wrap; gap:8px; margin:0 0 14px; }
.payment-plan-policy-chip { min-width:112px; border:1px solid var(--border); border-radius:8px; padding:8px 10px; background:var(--bg-card); display:flex; align-items:center; justify-content:space-between; gap:12px; }
.payment-plan-policy-chip span { color:var(--text-muted); font-size:12px; }
.payment-plan-policy-chip strong { color:var(--text); font-size:18px; line-height:1; }
.payment-plan-policy-list { display:flex; flex-direction:column; gap:10px; }
.payment-plan-policy-row { display:grid; grid-template-columns:minmax(220px, 1.2fr) minmax(220px, .9fr) auto; gap:18px; align-items:center; border:1px solid var(--border); border-radius:8px; padding:12px 14px; background:var(--bg-card); }
.payment-plan-policy-reasons { display:flex; flex-wrap:wrap; gap:6px; }
.payment-plan-policy-reasons span { display:inline-flex; align-items:center; border-radius:999px; padding:3px 8px; background:var(--surface-2); color:var(--text-muted); font-size:12px; font-weight:600; }
.payment-plan-calendar { display:flex; flex-direction:column; gap:18px; }
.payment-plan-calendar-group { display:flex; flex-direction:column; gap:8px; }
.payment-plan-calendar-title { font-size:12px; font-weight:700; color:var(--text-muted); text-transform:uppercase; letter-spacing:.04em; }
.payment-plan-calendar-row { display:grid; grid-template-columns:minmax(220px, 1fr) minmax(190px, .8fr) auto; gap:16px; align-items:center; border:1px solid var(--border); border-radius:8px; padding:12px 14px; background:var(--bg-card); }
.payment-plan-calendar-row.is-missed { border-color:var(--status-danger-fg); background:var(--status-danger-bg); }
.payment-plan-calendar-meta { display:flex; flex-direction:column; gap:3px; color:var(--text-muted); font-size:12px; }
.payment-plan-calendar-meta strong { color:var(--text); font-size:15px; }
.payment-plan-future-grid { display:grid; grid-template-columns:repeat(auto-fit, minmax(180px, 1fr)); gap:8px; }
.payment-plan-future-item { display:flex; flex-direction:column; gap:3px; border:1px solid var(--border); border-radius:8px; padding:10px 12px; background:var(--bg-card); color:var(--text); }
.payment-plan-future-item:hover { text-decoration:none; border-color:var(--primary); }
.payment-plan-future-item strong { color:var(--text); }
.payment-plan-future-item small { color:var(--text-muted); }
.payment-plan-list { display:flex; flex-direction:column; gap:12px; }
.payment-plan-row { display:grid; grid-template-columns:minmax(220px, 1.2fr) minmax(240px, 1fr) auto; gap:18px; align-items:center; border:1px solid var(--border); border-radius:8px; padding:14px 16px; background:var(--bg-card); }
.payment-plan-title { display:flex; align-items:center; gap:8px; font-weight:700; }
.payment-plan-client { color:var(--text); margin-top:4px; }
.payment-plan-meta { display:flex; flex-wrap:wrap; gap:8px 12px; color:var(--text-muted); font-size:12px; margin-top:6px; }
.payment-plan-status { display:inline-flex; align-items:center; border-radius:999px; padding:2px 8px; font-size:11px; font-weight:700; }
.payment-plan-status-requested { background:var(--status-warning-bg); color:var(--status-warning-fg); }
.payment-plan-status-approved { background:var(--status-success-bg); color:var(--status-success-fg); }
.payment-plan-status-rejected { background:var(--status-danger-bg); color:var(--status-danger-fg); }
.payment-plan-schedule { display:grid; grid-template-columns:repeat(2, minmax(110px, 1fr)); gap:6px 10px; }
.payment-plan-step { display:flex; justify-content:space-between; gap:8px; font-size:12px; padding:6px 8px; border-radius:6px; background:var(--bg); color:var(--text-muted); }
.payment-plan-step strong { color:var(--text); font-weight:700; }
.payment-plan-step-muted { justify-content:center; color:var(--text-muted); }
.payment-plan-actions { display:flex; flex-wrap:wrap; justify-content:flex-end; gap:6px; min-width:150px; }
/* Recommendations collapsed by default */
.payment-plan-recs > summary { cursor:pointer; list-style:none; display:flex; align-items:flex-start; justify-content:space-between; gap:12px; }
.payment-plan-recs > summary::-webkit-details-marker { display:none; }
.payment-plan-recs > summary h2 { display:inline-block; }
.payment-plan-recs > summary .badge::after { content:' \25BE'; color:var(--text-muted); }
.payment-plan-recs[open] > summary { margin-bottom:14px; }
.payment-plan-recs[open] > summary .badge::after { content:' \25B4'; }
/* Auto-approval policy form on /settings/paymentPlans/ (vertical, width-constrained) */
.payment-plan-policy-form { display:flex; flex-direction:column; gap:18px; margin-top:18px; max-width:480px; }
.payment-plan-policy-form .pp-field { display:flex; flex-direction:column; gap:6px; font-size:13px; font-weight:600; color:var(--text); }
.payment-plan-policy-form .pp-field input,
.payment-plan-policy-form .pp-field select { min-height:40px; max-width:220px; }
.payment-plan-policy-form .pp-field small { font-weight:400; max-width:380px; }
.payment-plan-policy-form > button { align-self:flex-start; }
/* The limit fields only apply while auto-approve is on — dim them when it's off. */
.payment-plan-policy-form.is-disabled .pp-field { opacity:.5; }
@media (max-width: 860px) {
    .payment-plan-metrics { grid-template-columns:repeat(2, minmax(140px, 1fr)); }
    .payment-plan-calendar-row { grid-template-columns:1fr; align-items:start; }
    .payment-plan-row { grid-template-columns:1fr; align-items:start; }
    .payment-plan-policy-row { grid-template-columns:1fr; align-items:start; }
    .payment-plan-actions { justify-content:flex-start; }
}
@media (max-width: 540px) { .payment-plan-metrics { grid-template-columns:1fr; } }

.stat-label { color: var(--text-muted); font-size: 13px; margin-bottom: 6px; }
.stat-value { font-size: 26px; font-weight: 700; line-height: 1.2; }
/* Units and currency codes inside a stat value ("days", "USD") read as context,
   not data — small + muted keeps the number dominant and stops "USD 147,946"
   from wrapping into two equally-loud broken lines in narrow tracks. */
.stat-value small { font-size: 13px; font-weight: 600; color: var(--text-muted); }
.stat-danger .stat-value { color: var(--danger); }
.stat-warning .stat-value { color: var(--warning-strong); }

/* ---------- Forms ---------- */
.form-group { margin-bottom: 16px; }
.form-row { display: flex; gap: 14px; }
.form-row .form-group { flex: 1; }
/* Default amount/currency split. The add-invoice form uses a single-column
   layout, with amount + currency kept together as one compound control. */
.invoice-amount-row { display: grid; grid-template-columns: 3fr 1fr; gap: 14px; }
.invoice-amount-row > .form-group { flex: initial; }
#invoice-form .form-row { gap: 24px; }
#invoice-form .client-select-wrap,
#invoice-form .empty-state-card,
#invoice-form .invoice-number-field input,
#invoice-form .invoice-money-input,
#invoice-form .date-display-wrap,
#invoice-form #recurring_interval,
#invoice-form #notes {
    width: 100%;
    max-width: 500px;
}

.date-display-wrap {
    position: relative;
    width: 100%;
    --date-picker-hit-area: 42px;
}
.date-display-wrap .date-display-input {
    width: 100%;
    padding-right: var(--date-picker-hit-area);
}
.date-display-wrap .date-native-picker {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: var(--date-picker-hit-area);
    height: 100%;
    border: 0;
    background: transparent;
    color: transparent;
    opacity: 0;
    cursor: pointer;
    z-index: 2;
}
.date-display-wrap.date-picker-ready .date-native-picker {
    pointer-events: none;
}
.date-display-wrap::before,
.date-display-wrap::after {
    content: "";
    position: absolute;
    pointer-events: none;
    z-index: 3;
}
.date-display-wrap::before {
    right: 13px;
    top: 50%;
    width: 15px;
    height: 14px;
    border: 1.5px solid var(--text-muted);
    border-radius: 3px;
    transform: translateY(-50%);
    opacity: .72;
}
.date-display-wrap::after {
    right: 13px;
    top: calc(50% - 4px);
    width: 15px;
    border-top: 1.5px solid var(--text-muted);
    opacity: .72;
}
.date-display-wrap:focus-within .date-display-input {
    border-color: var(--primary);
    box-shadow: 0 0 0 3px var(--accent-light);
}
.date-display-wrap.date-picker-open .date-display-input {
    border-color: var(--primary);
    box-shadow: 0 0 0 3px var(--accent-light);
}
.duefy-date-popover {
    position: fixed;
    z-index: 4000;
    width: 292px;
    padding: 10px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-card);
    color: var(--text);
    box-shadow: var(--shadow-lg);
}
.duefy-date-head {
    display: grid;
    grid-template-columns: 32px 1fr 32px;
    align-items: center;
    gap: 6px;
    margin-bottom: 8px;
}
.duefy-date-title {
    font-size: 13px;
    font-weight: 700;
    text-align: center;
}
.duefy-date-nav,
.duefy-date-foot-btn,
.duefy-date-cell {
    border: 0;
    background: transparent;
    color: inherit;
    font-family: var(--font);
    cursor: pointer;
}
.duefy-date-nav {
    width: 32px;
    height: 32px;
    border-radius: 8px;
    font-size: 22px;
    line-height: 1;
    color: var(--text-muted);
}
.duefy-date-nav:hover,
.duefy-date-foot-btn:hover,
.duefy-date-cell:hover:not(:disabled) {
    background: var(--bg-tertiary);
}
.duefy-date-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 3px;
}
.duefy-date-weekdays {
    margin-bottom: 4px;
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 700;
    text-align: center;
}
.duefy-date-cell {
    width: 100%;
    height: 34px;
    border-radius: 8px;
    font-size: 13px;
    line-height: 34px;
    text-align: center;
}
.duefy-date-cell.is-muted {
    color: var(--text-muted);
    opacity: .58;
}
.duefy-date-cell.is-today {
    box-shadow: inset 0 0 0 1px var(--accent-border);
}
.duefy-date-cell.is-selected {
    background: var(--primary);
    color: #fff;
    font-weight: 700;
    box-shadow: none;
}
.duefy-date-cell:disabled {
    color: var(--text-muted);
    cursor: not-allowed;
    opacity: .35;
}
.duefy-date-foot {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    margin-top: 10px;
    padding-top: 8px;
    border-top: 1px solid var(--border);
}
.duefy-date-foot-btn {
    min-height: 30px;
    padding: 0 10px;
    border-radius: 7px;
    color: var(--primary);
    font-size: 12px;
    font-weight: 700;
}
.duefy-date-foot-btn:disabled {
    color: var(--text-muted);
    cursor: not-allowed;
    opacity: .45;
}
#invoice-form .invoice-money-input {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 96px;
    gap: 8px;
}
#invoice-form input[type="number"]::-webkit-outer-spin-button,
#invoice-form input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
#invoice-form input[type="number"] { -moz-appearance: textfield; }
#invoice-form .payment-terms-quick { min-height: 22px; }
#invoice-form .invoice-recurring-toggle {
    margin-top: 20px;
    margin-bottom: 18px;
}
#invoice-form label,
#invoice-form .checkbox-label {
    color: var(--text);
    font-size: 14px;
    font-weight: 500;
    line-height: 1.35;
}
#invoice-form label .muted,
#invoice-form label .text-muted,
#invoice-form .checkbox-label .muted {
    color: var(--text-muted);
    font-size: inherit;
    font-weight: 400;
}
#invoice-form .checkbox-label:focus-within { color: var(--text); }
#invoice-form .checkbox-label input[type="checkbox"]:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}
label {
    display: block;
    font-weight: 500;
    font-size: 14px;
    margin-bottom: 6px;
}
input, select, textarea {
    width: 100%;
    padding: 9px 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 15px;
    font-family: var(--font);
    background-color: var(--input-bg);
    color: var(--text);
}
/* Replace native <select> chrome with Duefy's input styling. Keep multiple
   selects native-like because they behave as listboxes, not dropdowns. */
select:not([multiple]),
select.select-styled {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%236B7280' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
    background-repeat: no-repeat;
    background-position: right 12px center;
    background-size: 14px;
    padding-right: 38px;
    cursor: pointer;
}
select:not([multiple]):disabled,
select.select-styled:disabled {
    cursor: not-allowed;
    opacity: 0.68;
}
input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 3px rgba(79,70,229,.12);
}
textarea { resize: vertical; }

/* ---------- Buttons ---------- */
.btn {
    display: inline-block;
    padding: 9px 16px;
    border-radius: 8px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    border: 1px solid transparent;
    background: var(--border);
    color: var(--text);
    transition: background .15s, opacity .15s;
    /* Align mixed inline button types: a <button> and an <a> sitting side by side
       (e.g. page-head "Ask AI" + "Export CSV") aligned by baseline, leaving the
       two a few px off. middle aligns them regardless of element/baseline. */
    vertical-align: middle;
}
.btn:hover { text-decoration: none; opacity: .9; }
.btn-primary { background: var(--primary); color: #fff; }
.btn-primary:hover { background: var(--primary-dark); }
.btn-danger  { background: var(--danger); color: #fff; }
.btn-outline {
    background: var(--bg-card);
    border-color: var(--border);
    color: var(--text);
}
.btn-outline:hover { border-color: var(--primary); color: var(--primary); }
.btn-block { display: block; width: 100%; text-align: center; }
.btn-sm { padding: 5px 11px; font-size: 13px; }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.action-bar { display: flex; gap: 10px; margin-top: 18px; flex-wrap: wrap; }

/* ---------- mini-list (shared by Calls / Internal notes / Late fees on invoice/view) ---------- */
.mini-list {
    list-style: none;
    padding: 0;
    margin: 0 0 14px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.mini-list li {
    padding: 10px 12px;
    background: var(--bg-soft, #F9FAFB);
    border-radius: 8px;
    border-left: 3px solid var(--border, #E5E7EB);
    font-size: 14px;
    line-height: 1.5;
}
.mini-list li strong { display: block; margin-bottom: 2px; font-weight: 600; }
.mini-list li > div { margin-top: 4px; color: var(--text); }
.mini-list li .muted { font-size: 12px; }

/* Card-bottom form (internal-note-form / late-fees apply block) with spacing below the list */
.internal-note-form {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-top: 12px;
}
.internal-note-form textarea {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--border, #E5E7EB);
    border-radius: 8px;
    font-family: inherit;
    font-size: 14px;
    resize: vertical;
}
.internal-note-form button { align-self: flex-start; }

/* ---------- Table ---------- */
.table { width: 100%; border-collapse: collapse; }
/* Wrap a wide table in this to let it scroll horizontally inside its card on
   narrow screens instead of pushing the whole page wide. */
.table-scroll { overflow-x: auto; }
/* Inline POST form used to turn a state-changing link into a CSRF-safe submit
   without disturbing the surrounding inline/flex layout. */
.inline-form { display: inline; }
button.text-link { background: none; border: 0; padding: 0; font: inherit; cursor: pointer; }
.table th, .table td {
    text-align: left;
    padding: 11px 12px;
    border-bottom: 1px solid var(--border);
}
.table th {
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--text-muted);
}
.table tbody tr:last-child td { border-bottom: none; }
.table tbody tr:hover { background: var(--bg); }
.row-actions { display: flex; gap: 12px; }

/* ---------- Badges ---------- */
.badge {
    display: inline-block;
    padding: 2px 9px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
}
.badge-plan      { background: var(--accent-light); color: var(--primary); }
/* Plan badge wrapper + corner tag — trial users get [Pro] same as paid, with a tiny
   "trial" tag floating top-right (corner-badge / sale-tag pattern). Visual identity of
   "Pro" stays consistent across paid + trial, trial is a non-overlapping modifier. */
.badge-plan-wrap { position: relative; display: inline-flex; }
.badge-plan-corner-tag {
    /* File-folder TAB style: sits flush on top of the Pro chip, aligned to its right edge.
       Tag's bottom corners are square (border-radius: 4 4 0 0) + overlap by 1px so the two
       shapes visually fuse into a single tab-on-pill, not a floating sticker. */
    position: absolute;
    bottom: 100%;
    right: -6px;          /* extends past Pro chip's right edge — looks more "tag-like" */
    margin-bottom: -7px;  /* tag sits lower, ~7px overlap into the plan chip — anchored, not floating */
    background: var(--status-warning-bg);
    color: var(--status-warning-fg);
    font-size: 8px; font-weight: 700;
    line-height: 1; padding: 2px 5px 3px;
    border-radius: 4px 4px 0 0;
    letter-spacing: 0.4px;
    white-space: nowrap;
    pointer-events: none;  /* tooltip on wrap, not on this child */
}
.badge-pending   { background: var(--bg-tertiary); color: var(--text-muted); }
.badge-active    { background: var(--status-info-bg); color: var(--status-info-fg); }
.badge-partial   { background: var(--status-warning-bg); color: var(--status-warning-fg); }
.badge-paid      { background: var(--status-success-bg); color: var(--status-success-fg); }
.badge-paused    { background: var(--status-warning-bg); color: var(--status-warning-fg); }
.badge-cancelled { background: var(--status-danger-bg); color: var(--status-danger-fg); }
.badge-written_off { background: var(--status-danger-bg); color: var(--status-danger-fg); }
/* Late Payment Predictor risk pill — sits beside the status badge on active rows.
   Three buckets (low/med/high) tied to the model's 0..100 risk score; we don't
   show the chip below 40 because anything lower reads as "no signal" and just
   adds noise. */
.badge-risk      { margin-left: 6px; cursor: help; display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.badge-risk .icon-inline { flex-shrink: 0; }
.badge-risk-low  { background: #FEF3C7; color: #92400E; }
.badge-risk-med  { background: #FED7AA; color: #9A3412; }
.badge-risk-high { background: #FECACA; color: #991B1B; }

/* Custom hover tooltip (replaces the plain native title) — a styled, readable
   floating box positioned by app.js's data-tip handler. Dark box reads on both
   themes; pointer-events:none so it never eats the hover. */
.dtip {
    position: absolute; z-index: 9999; max-width: 280px;
    padding: 8px 11px; border-radius: 8px;
    background: #1f2937; color: #fff;
    font-size: 12.5px; line-height: 1.45; font-weight: 500;
    box-shadow: 0 6px 24px rgba(0,0,0,.20);
    pointer-events: none; opacity: 0; transform: translateY(3px);
    transition: opacity .12s ease, transform .12s ease;
}
.dtip.is-visible { opacity: 1; transform: none; }
.dtip-line + .dtip-line { margin-top: 3px; }
/* Bulleted list when the reason has 2+ clauses (JS adds .dtip-list). */
.dtip-list .dtip-line { position: relative; padding-left: 13px; }
.dtip-list .dtip-line::before {
    content: ""; position: absolute; left: 2px; top: 0.55em;
    width: 4px; height: 4px; border-radius: 50%;
    background: currentColor; opacity: 0.55;
}
.dtip-meta {
    margin-top: 6px; padding-top: 5px;
    border-top: 1px solid rgba(255, 255, 255, 0.15);
    font-size: 11px; opacity: 0.65;
}

/* ============================================================
   invoice/view visual overhaul (commit invoice-view-polish)
   ============================================================ */

/* Hero: replaces page-head, emphasises amount + status + due-state */
.invoice-hero {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 24px 28px;
    margin-bottom: 20px;
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 16px;
}
.invoice-hero-main { flex: 1; min-width: 0; }
.invoice-hero-meta {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 13.5px;
    color: var(--text-muted);
    margin-bottom: 8px;
}
.invoice-hero-num { font-weight: 600; color: var(--text); }
.invoice-hero-amount {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin: 4px 0 12px;
}
.hero-currency {
    font-size: 16px;
    color: var(--text-muted);
    font-weight: 500;
}
.hero-amount-num {
    font-size: 38px;
    font-weight: 700;
    color: var(--text);
    letter-spacing: -0.02em;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}
.invoice-hero-due {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-size: 13.5px;
}
.hero-meta-label { color: var(--text-muted); }
.hero-meta-pill {
    display: inline-flex;
    align-items: center;
    padding: 2px 10px;
    border-radius: 999px;
    font-size: 12.5px;
    font-weight: 600;
}
.hero-meta-overdue { background: var(--status-danger-bg); color: var(--status-danger-fg); }
.hero-meta-soon    { background: var(--status-warning-bg); color: var(--status-warning-fg); }
.hero-meta-future  { background: #E0E7FF; color: #4338CA; }
.hero-meta-paid    { background: var(--status-success-bg); color: var(--status-success-fg); }

.invoice-hero-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}
.invoice-hero-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px; height: 38px;
    border: 1px solid var(--border);
    border-radius: 8px;
    color: var(--text-muted);
    transition: all 0.15s;
}
.invoice-hero-icon-btn:hover {
    color: var(--primary);
    border-color: var(--primary);
    background: var(--accent-light);
}

/* Status pill (replaces the old .badge), with dot + punchier colors */
.status-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 11px 3px 9px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.4;
    white-space: nowrap;
}
.status-pill .status-dot {
    width: 7px; height: 7px;
    border-radius: 50%;
    background: currentColor;
}
.status-pill-pending   { background: var(--bg-tertiary); color: var(--text-muted); }
.status-pill-active    { background: var(--status-info-bg); color: var(--status-info-fg); }
.status-pill-paid      { background: var(--status-success-bg); color: var(--status-success-fg); }
.status-pill-paused    { background: var(--status-warning-bg); color: var(--status-warning-fg); }
.status-pill-partial   { background: var(--status-warning-bg); color: var(--status-warning-fg); }
.status-pill-cancelled { background: var(--status-danger-bg); color: var(--status-danger-fg); }
/* Terminal "bad debt" — was unstyled (fell back to a near-invisible grey pill).
   Use the danger palette like cancelled; the label distinguishes the two. */
.status-pill-written_off { background: var(--status-danger-bg); color: var(--status-danger-fg); }

/* Card-fill: card uses flex column so .action-bar-pinned can pin buttons to the bottom */
.card-fill {
    display: flex;
    flex-direction: column;
}
.action-bar-pinned {
    margin-top: auto;
    padding-top: 6px;
}

/* Payment Status — large Outstanding number */
.payment-hero { margin: 4px 0 10px; }
.payment-hero-label {
    font-size: 12px;
    color: var(--text-muted);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin-bottom: 4px;
}
.payment-hero-amount {
    font-size: 32px;
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
    color: var(--text);
}
.payment-hero-paid .payment-hero-amount { color: var(--status-success-fg); }
.payment-hero-sub { font-size: 13px; margin-top: 6px; }

/* Timeline rail — strengthens the vertical line */
.timeline { padding-left: 4px; }
.timeline li {
    border-left: 2px solid var(--border);
    padding: 0 0 18px 18px;
}
.timeline li:last-child {
    border-left-color: transparent;
    padding-bottom: 4px;
}
.timeline li:before {
    width: 11px; height: 11px;
    left: -6.5px;
    box-shadow: 0 0 0 3px var(--bg-card);
}
.timeline-events li:before { background: #9CA3AF; }
.timeline-events li { border-left-color: #E5E7EB; }

/* Step status visualization: 4 states — sent / failed / behind / scheduled */
.timeline li.tl-step-sent:before      { background: var(--success); }   /* solid green */
.timeline li.tl-step-failed:before    { background: var(--danger); }   /* solid red */
.timeline li.tl-step-behind:before {                              /* yellow warning (cron didn't fire) */
    background: var(--warning);
    box-shadow: 0 0 0 3px var(--bg-card);
}
.timeline li.tl-step-scheduled:before {                           /* light-grey hollow ring (not due yet) */
    background: var(--bg-card);
    box-shadow: 0 0 0 2px #E5E7EB, 0 0 0 4px var(--bg-card);
}
.timeline li.tl-step-reply:before {
    background: var(--primary);
    box-shadow: 0 0 0 3px var(--bg-card);
}

/* Step row: time-note + small Send now link */
.iv-step-time-warn {
    color: var(--status-warning-fg); font-weight: 500; font-size: 12px;
    background: var(--status-warning-bg);
    padding: 1px 7px;
    border-radius: 4px;
}
/* Send now / Resend small link — subtle but visible */
.iv-step-link {
    margin-left: auto;
    font-size: 12px;
    color: var(--primary);
    text-decoration: none;
    padding: 2px 8px;
    border: 1px solid transparent;
    border-radius: 5px;
    cursor: pointer;
    transition: all 0.15s;
}
.iv-step-link:hover {
    background: var(--accent-light);
    border-color: var(--primary);
}
/* Per-step action icons grouped at the right; the group holds the auto margin
   and never wraps internally, so adding channels (View SMS) can't orphan a link. */
.iv-step-actions { margin-left: auto; display: inline-flex; align-items: center; gap: 2px; flex-shrink: 0; }
.iv-step-icon { margin-left: 0; padding: 4px; line-height: 0; color: var(--text-muted); }
.iv-step-icon:hover { color: var(--primary); }
/* iv-step-link-disabled used to render the "previous step not sent" greyed state. Now that Send now
   no longer depends on the previous step, the tpl stops rendering the disabled span — style kept for future reuse. */
.iv-step-link-disabled {
    color: var(--text-muted);
    cursor: not-allowed;
}
.iv-step-link-disabled:hover {
    background: transparent;
    border-color: transparent;
}

/* "Edit reminder schedule" inline link at the bottom of the timeline section */
.iv-tl-customize {
    margin: 14px 0 0;
    padding-top: 12px;
    border-top: 1px dashed var(--border);
    font-size: 13px;
}
.iv-tl-customize a {
    color: var(--primary); text-decoration: none; font-weight: 500;
}
.iv-tl-customize a:hover { text-decoration: underline; }

/* Email-body preview modal (timeline "View email" reveal) */
.iv-email-preview-overlay { /* uses base .modal-overlay sizing + backdrop */
    align-items: center; justify-content: center;
}
.iv-email-preview-box {
    background: var(--bg-card); color: var(--text);
    border-radius: 12px;
    width: min(720px, 92vw); max-height: 90vh;
    display: flex; flex-direction: column;
    overflow: hidden;
    box-shadow: 0 24px 48px rgba(0,0,0,0.18);
}
.iv-email-preview-head {
    display: flex; gap: 12px; align-items: flex-start;
    padding: 18px 20px 12px; border-bottom: 1px solid var(--border);
}
.iv-email-preview-meta { flex: 1; min-width: 0; }
.iv-email-preview-subject {
    font-size: 16px; font-weight: 600;
    word-break: break-word;
}
.iv-email-preview-when { font-size: 12px; margin-top: 2px; }
.iv-email-preview-close {
    background: none; border: none; cursor: pointer;
    font-size: 20px; line-height: 1; padding: 4px 8px;
    color: var(--text-muted);
}
.iv-email-preview-disclaimer {
    padding: 8px 20px; font-size: 12px;
    background: var(--status-warning-bg); color: var(--status-warning-fg);
    border-bottom: 1px solid var(--border);
    line-height: 1.5;
}
/* The iframe is sized to its content height in JS (showEmailPreview), so short
   emails show with no inner scrollbar. This wrapper is the single scroll region
   that kicks in only when an email is taller than the modal — header/disclaimer
   stay fixed above it. */
.iv-email-preview-scroll {
    flex: 1 1 auto; min-height: 0;
    overflow-y: auto; overflow-x: hidden;
}
/* Clips + holds the scaled height when the email is shrunk to fit a phone. */
.iv-email-preview-fit { overflow: hidden; }
.iv-email-preview-body {
    display: block; width: 100%; height: 420px;   /* fallback; JS sets it to content height */
    border: 0; background: #fff;   /* email bodies were designed against white client backgrounds */
}

/* === Duefy Quill ✒ — process symbol (Duefy is writing) ============================
   Used on /invoice/view banner (40px) and /invoice list cell (16px) */
.duefy-quill {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--primary) 0%, #6366F1 100%);
    overflow: visible;
    flex-shrink: 0;
    vertical-align: middle;
}
.duefy-quill svg { display: block; width: 100%; height: 100%; }
.duefy-quill-16 { width: 16px; height: 16px; }
.duefy-quill-40 { width: 40px; height: 40px; }
.duefy-quill-80 { width: 80px; height: 80px; }

/* Tone tints (override background) */
.duefy-quill-tone-firm    { background: linear-gradient(135deg, #F59E0B 0%, #FBBF24 100%); }
.duefy-quill-tone-final   { background: linear-gradient(135deg, #DC2626 0%, #EF4444 100%); }
.duefy-quill-tone-formal  { background: linear-gradient(135deg, #6366F1 0%, #818CF8 100%); }
.duefy-quill-tone-paused  { background: linear-gradient(135deg, #9CA3AF 0%, #D1D5DB 100%); }

/* Pen group: slides from left to right while "writing" (only 40 + 80) */
.duefy-quill-40 .quill-pen,
.duefy-quill-80 .quill-pen {
    transform: translateX(-8px);   /* initial state visible at left */
    animation: duefy-quill-pen-slide 3.5s ease-in-out infinite;
    transform-origin: center;
}
.duefy-quill-state-paused .quill-pen,
.duefy-quill-state-paid   .quill-pen { animation: none; transform: none; }
@keyframes duefy-quill-pen-slide {
    0%   { transform: translateX(-8px); opacity: 1; }
    55%  { transform: translateX(0);    opacity: 1; }
    78%  { transform: translateX(0);    opacity: 1; }
    88%  { transform: translateX(0);    opacity: 0; }
    90%  { transform: translateX(-8px); opacity: 0; }
    100% { transform: translateX(-8px); opacity: 1; }
}

/* Writing trail — drawn line synced with pen slide. Only 40 + 80 animate. */
.duefy-quill .quill-trail {
    stroke-dasharray: 10;
    stroke-dashoffset: 10;
    opacity: 0;
}
.duefy-quill-40 .quill-trail,
.duefy-quill-80 .quill-trail {
    animation: duefy-quill-write 3.5s ease-in-out infinite;
}
.duefy-quill-state-paused .quill-trail,
.duefy-quill-state-paid   .quill-trail { animation: none; opacity: 0; }
@keyframes duefy-quill-write {
    0%   { stroke-dashoffset: 10; opacity: 0; }
    8%   { opacity: 1; }
    55%  { stroke-dashoffset: 0; opacity: 1; }
    78%  { stroke-dashoffset: 0; opacity: 1; }
    88%  { opacity: 0; }
    100% { stroke-dashoffset: 10; opacity: 0; }
}

/* Status dot (right-bottom corner) */
.duefy-quill .duefy-dot {
    position: absolute;
    right: -2px; bottom: -2px;
    width: 10px; height: 10px;
    border-radius: 50%;
    background: var(--success);
    border: 2px solid var(--bg-card, #fff);
    box-shadow: 0 0 0 0 rgba(22, 163, 74, 0.55);
    animation: duefy-dot-pulse 1.8s ease-out infinite;
}
.duefy-quill-80 .duefy-dot { width: 14px; height: 14px; border-width: 2.5px; }
.duefy-quill .duefy-dot-paused {
    background: var(--text-muted, #9CA3AF);
    animation: none;
    box-shadow: none;
}
.duefy-quill .duefy-dot-behind { background: var(--warn, #F59E0B); }
@keyframes duefy-dot-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(22, 163, 74, 0.55); }
    70%  { box-shadow: 0 0 0 6px rgba(22, 163, 74, 0); }
    100% { box-shadow: 0 0 0 0 rgba(22, 163, 74, 0); }
}

/* === Quill paid state — bold white check on indigo circle (Y2) ===================
   Replaces the entire envelope+quill SVG with a single white check stroke (.quill-check).
   No fade, no overlay, no coins — paid state is a clean done-stamp on the same indigo bg. */
.duefy-quill .quill-check {
    transform-origin: center;
    transform-box: fill-box;
}
.duefy-quill-40 .quill-check,
.duefy-quill-80 .quill-check {
    animation: duefy-quill-check-pulse 2.4s ease-in-out infinite;
}
@keyframes duefy-quill-check-pulse {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.06); }
}

/* === Combined Quill banner for /invoice/view (replaces the old iv-auto-banner) === */
.iv-quill-banner {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    background: var(--accent-light);
    border: 1px solid var(--accent-border);
    border-left: 3px solid var(--primary);
    border-radius: 8px;
    padding: 14px 16px;
    margin: 0 0 16px;
    font-size: 13.5px;
    line-height: 1.5;
    color: var(--text);
}
.iv-quill-banner-text {
    display: flex;
    flex-direction: column;
    gap: 3px;
    flex: 1;
    min-width: 0;
}
.iv-quill-banner-text strong { color: var(--text); font-weight: 700; }
.iv-quill-banner-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: 8px;
}
.iv-quill-step-dots {
    display: flex;
    gap: 5px;
    margin-top: 8px;
}
.iv-quill-step-dots i {
    width: 7px; height: 7px;
    border-radius: 50%;
    background: var(--border);
    flex-shrink: 0;
    display: block;
}
.iv-quill-step-dots i.done { background: var(--primary); }
.iv-quill-step-dots i.now {
    background: var(--primary);
    box-shadow: 0 0 0 0 rgba(79, 70, 229, 0.5);
    animation: iv-quill-step-now 1.2s ease-out infinite;
}
@keyframes iv-quill-step-now {
    0%   { box-shadow: 0 0 0 0 rgba(79, 70, 229, 0.5); }
    100% { box-shadow: 0 0 0 5px rgba(79, 70, 229, 0); }
}

/* === Quill mini in invoice list cell === */
.inv-quill-cell {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 11px;
    color: var(--text-muted);
    margin-top: 3px;
}
.inv-quill-cell.tone-firm  { color: #B45309; }
.inv-quill-cell.tone-final { color: #B91C1C; }
.inv-quill-cell.tone-paused { color: var(--text-muted); }

@media (prefers-reduced-motion: reduce) {
    .duefy-quill .quill-pen,
    .duefy-quill .quill-trail,
    .duefy-quill .duefy-dot,
    .duefy-quill .quill-check,
    .iv-quill-step-dots i.now { animation: none !important; }
    .duefy-quill .quill-pen   { transform: none; }
    .duefy-quill .quill-trail { stroke-dashoffset: 0; opacity: 0.55; }
}

/* Send now link — secondary small grey text so the Auto-running banner dominates visually */
.iv-step-link-secondary {
    font-size: 12px; color: var(--text-muted) !important;
    text-decoration: underline; text-underline-offset: 2px;
    text-decoration-color: var(--border);
    margin-left: 8px;
}
.iv-step-link-secondary:hover { color: var(--primary) !important; text-decoration-color: var(--primary); }

/* === Turn on auto-reminders sub-copy (pending/paused invoice) === */
/* Caption under the hero action row. Kept OUT of the button row (it's wider than
   the activate button, so inside the row it inflated the button's flex item and
   left an awkward gap). As a standalone line all actions stay on one row above it. */
.iv-activate-hint {
    margin: 6px 0 0;
    font-size: 11.5px; line-height: 1.4;
    padding-left: 2px;
}

/* Prominent invoice-state callout (pending / paused / disputed / promise). Makes
   "this invoice isn't being chased right now" unmistakable at a glance — louder
   than the small hero status pill. Colour-coded by state; information only. */
.iv-state-banner {
    display: flex; align-items: flex-start; gap: 10px;
    /* horizontal padding matches the card content inset (hero 26 / cards 24) so the
       icon lines up with the invoice header above and the timeline below */
    padding: 13px 24px; margin-bottom: 18px;
    border: 1px solid; border-radius: var(--radius);
    font-size: 14px; line-height: 1.45;
}
.iv-state-banner-icon { flex: 0 0 auto; margin-top: 1px; display: inline-flex; }
.iv-state-banner-text strong { display: block; font-size: 15px; margin-bottom: 1px; color: var(--text); }
.iv-state-banner-text span { color: var(--text); opacity: 0.85; }
.iv-state-banner-pending { background: var(--status-info-bg); border-color: var(--primary); }
.iv-state-banner-pending .iv-state-banner-icon,
.iv-state-banner-pending .iv-state-banner-text strong { color: var(--primary); }
.iv-state-banner-paused { background: var(--status-warning-bg); border-color: var(--warning); }
.iv-state-banner-paused .iv-state-banner-icon,
.iv-state-banner-paused .iv-state-banner-text strong { color: var(--warning-strong); }

/* Activity / Upcoming section divider label */
.iv-tl-zone-label {
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.6px;
    margin: 6px 0 10px;
    display: inline-flex;
    align-items: center;
    gap: 5px;
}
.iv-tl-zone-label:not(:first-child) {
    margin-top: 22px;
}

/* .iv-nextaction styles live further down (single source after the wk2 merge). */

/* Blocker side-list rows — token border (was hardcoded #F3F4F6, off in dark). */
.iv-blocker-item { border-bottom: 1px solid var(--border); padding-bottom: 8px; margin-bottom: 8px; }
.iv-blocker-item:last-child { border-bottom: 0; padding-bottom: 0; margin-bottom: 0; }

/* Upcoming-section mini date ruler — places the 4 step dates on a single horizontal line */
.iv-tl-ruler {
    position: relative;
    margin: 8px 14px 18px;
    height: 40px;
}
/* On narrow phones the tick date-labels overlap into an unreadable smear; the
   per-step rows below carry the same dates, so hide the ruler there. */
@media (max-width: 420px) {
    .iv-tl-ruler { display: none; }
}
.iv-tl-ruler-line {
    position: absolute;
    top: 12px;
    left: 0; right: 0;
    height: 2px;
    background: #E5E7EB;
    border-radius: 1px;
}
.iv-tl-ruler-now {
    position: absolute;
    top: 6px;
    width: 2px;
    height: 14px;
    background: var(--primary);
    transform: translateX(-1px);
    z-index: 2;
}
.iv-tl-ruler-now:before {
    content: 'Now';
    position: absolute;
    bottom: 16px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 10px;
    font-weight: 600;
    color: var(--primary);
    white-space: nowrap;
}
.iv-tl-ruler-tick {
    position: absolute;
    top: 0;
    transform: translateX(-50%);
    z-index: 1;
}
.iv-tl-ruler-tick-dot {
    width: 12px; height: 12px;
    border-radius: 50%;
    margin: 7px auto 0;
    background: var(--bg-card);
    border: 2px solid var(--accent-border);
    box-sizing: border-box;
}
.iv-tl-ruler-tick-scheduled .iv-tl-ruler-tick-dot { border-color: var(--accent-border); }
.iv-tl-ruler-tick-behind .iv-tl-ruler-tick-dot    { border-color: var(--warning); background: var(--warning); }
.iv-tl-ruler-tick-label {
    margin-top: 4px;
    font-size: 10px;
    color: var(--text-muted);
    text-align: center;
    white-space: nowrap;
}

/* Custom hover tooltip — replaces native title= for richer content (step tone + full date + time note).
   All variants anchor to left:50% (dot center); the transform direction shifts the tip's edge so it
   never extends past the ruler — edge ticks (pct<15 / pct>85) get tip-left / tip-right modifiers. */
.iv-tl-ruler-tick-tip {
    position: absolute;
    bottom: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%) translateY(2px);
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 7px 10px;
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
    white-space: nowrap;
    text-align: center;
    opacity: 0;
    pointer-events: none;
    transition: opacity 120ms ease, transform 120ms ease;
    z-index: 20;
}
.iv-tl-ruler-tick.tip-left .iv-tl-ruler-tick-tip {
    transform: translateX(0) translateY(2px);
}
.iv-tl-ruler-tick.tip-right .iv-tl-ruler-tick-tip {
    transform: translateX(-100%) translateY(2px);
}
.iv-tl-ruler-tick:hover .iv-tl-ruler-tick-tip {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}
.iv-tl-ruler-tick.tip-left:hover .iv-tl-ruler-tick-tip {
    transform: translateX(0) translateY(0);
}
.iv-tl-ruler-tick.tip-right:hover .iv-tl-ruler-tick-tip {
    transform: translateX(-100%) translateY(0);
}
/* Down-pointing arrow — layered border + fill to match the tooltip's 1px border */
.iv-tl-ruler-tick-tip::before,
.iv-tl-ruler-tick-tip::after {
    content: '';
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    border: 5px solid transparent;
}
.iv-tl-ruler-tick.tip-left .iv-tl-ruler-tick-tip::before,
.iv-tl-ruler-tick.tip-left .iv-tl-ruler-tick-tip::after {
    left: 8px;
    transform: none;
}
.iv-tl-ruler-tick.tip-right .iv-tl-ruler-tick-tip::before,
.iv-tl-ruler-tick.tip-right .iv-tl-ruler-tick-tip::after {
    left: auto;
    right: 8px;
    transform: none;
}
.iv-tl-ruler-tick-tip::before {
    border-top-color: var(--border);
}
.iv-tl-ruler-tick-tip::after {
    margin-top: -1px;
    border-top-color: var(--bg-card);
}
.iv-tl-tip-head {
    font-size: 12px;
    font-weight: 600;
    color: var(--text);
    line-height: 1.3;
}
.iv-tl-tip-date {
    font-size: 11px;
    color: var(--text-muted);
    margin-top: 2px;
    line-height: 1.3;
}
.iv-tl-tip-meta {
    font-size: 11px;
    color: var(--text-muted);
    margin-top: 2px;
    line-height: 1.3;
}
.iv-tl-ruler-tick-behind .iv-tl-tip-meta {
    color: var(--warning);
    font-weight: 500;
}

/* ============================================================
   invoice/view v3 redesign — two-column Main + Sidebar (commit invoice-view-v3)
   ============================================================ */

/* Hero — big amount + inline client info + actions */
.iv-hero {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 22px 26px;
    margin-bottom: 18px;
    display: flex;
    justify-content: space-between;
    gap: 16px;
    align-items: flex-start;
    position: relative;
}
.iv-hero-main { flex: 1; min-width: 0; }
.iv-hero-meta {
    display: flex; align-items: center; gap: 10px;
    font-size: 13.5px; color: var(--text-muted);
    margin-bottom: 6px;
}
.iv-hero-num { font-weight: 700; color: var(--text); font-size: 14px; }
.iv-hero-amount {
    display: flex; align-items: baseline; gap: 8px;
    margin: 4px 0 10px;
}
.iv-hero-amount .hero-currency {
    font-size: 16px; color: var(--text-muted); font-weight: 500;
}
.iv-hero-amount .hero-amount-num {
    font-size: 36px; font-weight: 700;
    color: var(--text);
    letter-spacing: -0.02em; line-height: 1;
    font-variant-numeric: tabular-nums;
}
.iv-hero-context {
    display: flex; flex-wrap: wrap; align-items: center;
    gap: 8px;
    font-size: 13.5px; color: var(--text-muted);
    margin-bottom: 10px;
}
.iv-hero-facts {
    display: grid;
    grid-template-columns: minmax(130px, max-content) minmax(220px, max-content) minmax(220px, 1fr);
    gap: 10px 22px;
    align-items: start;
    margin: 8px 0 10px;
    max-width: 860px;
}
/* With a memo, add a 4th column for it (the others shrink to content so the memo
   takes the slack and truncates rather than pushing the row wide). */
.iv-hero-facts.has-memo {
    grid-template-columns: minmax(110px, max-content) minmax(160px, max-content) max-content minmax(0, 1fr);
    max-width: none;
}
.iv-hero-memo {
    color: var(--text);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.iv-hero-fact {
    min-width: 0;
    display: grid;
    gap: 3px;
}
.iv-hero-fact-label {
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.4px;
}
.iv-hero-client { color: var(--primary); font-weight: 600; }
.iv-hero-email {
    color: var(--text);
    overflow-wrap: anywhere;
}
.iv-hero-due-value {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    color: var(--text);
}
.iv-hero-dot { color: var(--border); }
.iv-hero-actions-row {
    display: flex; gap: 8px; flex-wrap: wrap;
    margin-top: 10px;
}
/* Edit/Back live top-right, pinned out of flow so the hero's left column (and
   the action-button row inside it) gets the full hero width — otherwise this
   column reserves space down the whole hero height and the buttons below wrap.
   Only ever holds Edit/Back (+ an optional reassign icon), so it never wraps. */
.iv-hero-actions {
    display: flex; align-items: center; gap: 8px;
    flex-shrink: 0; flex-wrap: nowrap;
    position: absolute; top: 22px; right: 26px;
}
/* Edit/Back are icon+label links — keep each on one line so the arrow/pencil
   never wraps under its text. */
.iv-hero-actions .btn { white-space: nowrap; }

/* Recurring marker pill in the hero meta row — distinguishes the master series
   from a child invoice it spawned. Token-based so it reads in dark mode. */
.iv-recurring-pill {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 12px; font-weight: 600; line-height: 1.4;
    white-space: nowrap;
    background: var(--accent-light);
    color: var(--primary);
    border: 1px solid var(--accent-border);
}
a.iv-recurring-pill-child { text-decoration: none; transition: background .15s; }
a.iv-recurring-pill-child:hover { background: var(--accent-border); }

.iv-icon-btn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 38px; height: 38px;
    /* Match .btn-outline: without an explicit background the native <button>
       grey (buttonface) shows through next to the white outline buttons. */
    background: var(--bg-card);
    border: 1px solid var(--border); border-radius: 8px;
    color: var(--text-muted); cursor: pointer; transition: all 0.15s;
}
.iv-icon-btn:hover {
    color: var(--primary); border-color: var(--primary);
    background: var(--accent-light);
}
.iv-nextaction {
    display: flex;
    gap: 14px;
    align-items: flex-start;
    padding: 14px 18px;
    margin: 0 0 18px;
    background: var(--accent-light);
    border: 1px solid var(--accent-border);
    border-radius: 12px;
}
.iv-nextaction-icon {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--primary);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.iv-nextaction-copy {
    flex: 1;
    min-width: 0;
}
.iv-nextaction-title {
    font-weight: 700;
    color: var(--primary);
    font-size: 14px;
}
.iv-nextaction-reason {
    font-size: 12px;
    line-height: 1.5;
    margin-top: 2px;
}
.iv-nextaction-cta { flex-shrink: 0; }
@media (max-width: 768px) {
    .iv-hero {
        flex-direction: column;
    }
    .iv-hero-actions {
        position: static;
        width: 100%;
        justify-content: flex-start;
    }
    .iv-hero-facts,
    .iv-hero-facts.has-memo {
        grid-template-columns: 1fr;
        gap: 8px;
    }
    .iv-hero-memo { white-space: normal; }
    .iv-more-action-row {
        grid-template-columns: 1fr;
    }
}

/* Hero-meta pill (Due in N days) — reuses .hero-meta-* added in commit aa6ad0b */

/* Main + Sidebar layout */
.iv-layout {
    display: grid;
    grid-template-columns: 1fr 340px;
    gap: 18px;
    align-items: flex-start;
    margin-bottom: 32px;
}
@media (max-width: 1024px) {
    .iv-layout { grid-template-columns: 1fr; }
}
.iv-main { min-width: 0; }
.iv-side {
    display: flex; flex-direction: column; gap: 14px;
    position: sticky; top: 16px;
}
@media (max-width: 1024px) {
    .iv-side { position: static; }
}

/* Main section (timeline / notes / replies) */
.iv-section {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 18px 22px;
    margin-bottom: 16px;
}
.iv-section-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 14px;
}
.iv-section-head h2 {
    font-size: 16px; margin: 0;
    color: var(--text);
}
.iv-section-sub {
    font-size: 12px; color: var(--text-muted);
    display: inline-flex; align-items: center; gap: 4px;
}
.iv-timeline-scroll {
    overflow: visible;
    padding-right: 0;
}

/* Internal notes — textarea full-width + button right-aligned below (vertical layout) */
.iv-note-form {
    display: flex; flex-direction: column; gap: 8px;
    margin-bottom: 12px;
}
.iv-note-form-actions {
    display: flex; justify-content: flex-end;
}
.iv-note-form textarea {
    flex: 1; min-height: 44px;
    padding: 8px 10px;
    border: 1px solid var(--border); border-radius: 6px;
    font: inherit; font-size: 13.5px;
    background: var(--input-bg); color: var(--text);
    resize: vertical;
}
.iv-note-form textarea:focus {
    outline: none; border-color: var(--primary);
}
.iv-note-list { list-style: none; padding: 0; margin: 0; }
.iv-note-list li {
    padding: 10px 0;
    border-top: 1px solid var(--border);
    min-width: 0;
}
.iv-note-list li:first-child { border-top: none; padding-top: 4px; }
.iv-note-body {
    font-size: 13.5px;
    color: var(--text);
    margin-bottom: 4px;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    word-break: break-word;
}
.iv-note-meta { font-size: 11.5px; }

/* Sidebar card — compact variant */
.iv-side-card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: var(--shadow);
    overflow: hidden;
}
.iv-side-title {
    display: flex; align-items: center; gap: 6px;
    padding: 10px 14px;
    font-size: 13px; font-weight: 600;
    color: var(--text-muted);
    text-transform: none; letter-spacing: 0;
    border-bottom: 1px solid var(--border);
    background: var(--bg-tertiary);
}
.iv-side-title svg { color: var(--text-muted); }
.iv-side-card-ai .iv-side-title { background: var(--accent-light); color: var(--primary); }
.iv-side-card-ai .iv-side-title svg { color: var(--primary); }
.iv-side-card-empty .iv-side-title { background: var(--bg-card); }
.iv-side-card-empty { box-shadow: none; }
.iv-side-body { padding: 12px 14px; }
.iv-side-card-empty .iv-side-body { padding: 10px 14px; }

.iv-side-badge {
    margin-left: auto;
    padding: 1px 7px; border-radius: 999px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    font-size: 11px; font-weight: 600;
    color: var(--text-muted);
    text-transform: none; letter-spacing: 0;
}
.iv-side-badge-warn {
    background: var(--status-warning-bg); color: var(--status-warning-fg);
    border-color: #FCD34D;
}
.iv-side-empty-text { font-size: 13px; padding: 4px 0; }
.iv-side-quote {
    font-size: 13.5px; color: var(--text);
    padding: 8px 10px;
    background: var(--bg-tertiary);
    border-left: 3px solid var(--border);
    border-radius: 4px;
    margin-bottom: 6px;
}
.iv-side-meta { font-size: 12px; margin-bottom: 10px; }
.iv-side-btn-row { display: flex; gap: 6px; flex-wrap: wrap; }
.iv-side-btn-row .btn { font-size: 12.5px; padding: 6px 10px; }

/* iv-kv: Recurring label/value row */
.iv-kv {
    display: flex; justify-content: space-between;
    padding: 4px 0;
    font-size: 13px;
}
.iv-kv span { color: var(--text-muted); }
.iv-kv strong { color: var(--text); }

/* Mini list (calls / late fees / partial payments) */
.iv-mini-list { list-style: none; padding: 0; margin: 8px 0 0; }
.iv-mini-head {
    font-size: 11px; color: var(--text-muted);
    text-transform: uppercase; letter-spacing: 0.5px;
    margin-top: 8px; margin-bottom: 4px;
    font-weight: 600;
}
.iv-mini-row {
    display: flex; justify-content: space-between; gap: 8px;
    font-size: 13px;
    padding: 4px 0;
}
.iv-mini-row-block { padding: 6px 0; border-top: 1px solid var(--border); }
.iv-mini-row-block:first-child { border-top: none; padding-top: 0; }
.iv-mini-note { font-size: 12.5px; margin: 2px 0; color: var(--text); }
.iv-mini-meta { font-size: 11.5px; }

/* Late fee form inline */
.iv-late-form {
    display: grid;
    grid-template-columns: 1fr 1fr auto;
    gap: 6px;
    margin-top: 8px;
}
.iv-late-form select, .iv-late-form input {
    font-size: 12.5px; padding: 5px 8px;
    border: 1px solid var(--border); border-radius: 5px;
    background: var(--input-bg); color: var(--text);
    min-width: 0;
}

/* AI strategy text (old sidebar location, no longer used) */
.iv-ai-strategy {
    font-size: 13px; line-height: 1.55;
    margin: 0; color: var(--text);
    white-space: pre-wrap;
}

/* AI banner — prominent slot below Hero, shown when overdue + Pro/Team */
.iv-ai-banner {
    background: linear-gradient(135deg, #F5F3FF 0%, #EEF2FF 100%);
    border: 1px solid #DDD6FE;
    border-radius: var(--radius);
    padding: 14px 20px;
    margin-bottom: 18px;
    box-shadow: var(--shadow);
}
/* Dark mode: same fix as the stripe nudge — the hardcoded light gradient + light
   border washed out on the dark page. Subtle dark-indigo tint with a token border. */
[data-theme="dark"] .iv-ai-banner {
    background: color-mix(in srgb, var(--primary) 12%, var(--bg-card));
    border-color: var(--accent-border, var(--border));
}
.iv-ai-banner-head {
    display: flex; align-items: center; gap: 8px;
    color: var(--primary);
    font-size: 13px;
    margin-bottom: 4px;
}
.iv-ai-banner-head svg { flex-shrink: 0; }
.iv-ai-banner-head strong { font-weight: 600; }
.iv-ai-banner-body {
    margin: 0;
    font-size: 14px;
    line-height: 1.55;
    color: var(--text);
}
/* Phones: collapse the AI strategy to its one-line head (tap to expand). It's
   useful advice but shouldn't push the timeline + actions down by default.
   Desktop keeps it fully expanded (the body has no clamp outside this query). */
@media (max-width: 640px) {
    .iv-ai-banner-head { cursor: pointer; margin-bottom: 0; }
    .iv-ai-banner-head::after {
        content: ''; margin-left: auto; flex-shrink: 0;
        width: 7px; height: 7px; margin-right: 2px;
        border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
        transform: rotate(45deg); transition: transform .18s ease; opacity: .65;
    }
    .iv-ai-banner.is-expanded .iv-ai-banner-head { margin-bottom: 4px; }
    .iv-ai-banner.is-expanded .iv-ai-banner-head::after { transform: rotate(-135deg); }
    .iv-ai-banner:not(.is-expanded) .iv-ai-banner-body { display: none; }
}

/* btn-block helper (full-width button inside the sidebar) */
.iv-side-card .btn-block { width: 100%; display: block; }
.iv-payment-summary {
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    padding: 8px 0;
    margin: 10px 0;
}

/* Sidebar small-text link (Stripe pay page, etc.) */
.iv-side-link {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 12px;
    color: var(--primary);
    margin-top: 8px;
}
.iv-side-link:hover { text-decoration: underline; }
/* Group secondary payment links into rows with predictable placement instead of
   letting inline-flex links wrap arbitrarily on width (which split the
   open/copy pay-link pair across lines). Each row is a flex line; the column gap
   separates same-row links, and the row's own margin-top spaces the rows. Wraps
   on very narrow cards. */
.iv-side-link-row { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 16px; margin-top: 8px; }
.iv-side-link-row .iv-side-link { margin-top: 0; }
/* `.iv-side-link-btn` — applied to <button> rendered as a sibling to <a>.iv-side-link
   so "Copy payment link" looks identical to "Open Stripe pay page" but is action-only
   (no href). Strips the UA <button> chrome. */
.iv-side-link-btn {
    background: transparent; border: none;
    cursor: pointer;
    padding: 0;
    /* Inherit family/weight from the page (UA buttons default to their own font),
       but re-assert the 12px from .iv-side-link AFTER — the `font` shorthand resets
       font-size, so without this the button rendered at the parent's 15px while the
       sibling <a> stayed 12px (visibly mismatched). */
    font: inherit;
    font-size: 12px;
    line-height: inherit;
    text-align: left;
}
.iv-side-more {
    box-shadow: none;
}
.iv-side-more-summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 10px 14px;
    color: var(--text-muted);
    background: var(--bg-card);
    cursor: pointer;
    font-size: 13px;
    font-weight: 600;
    list-style: none;
}
.iv-side-more-summary::-webkit-details-marker { display: none; }
.iv-side-more-summary > span:first-child {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.iv-more-actions {
    display: flex;
    flex-direction: column;
    gap: 10px;
    border-top: 1px solid var(--border);
}
.iv-more-action-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 10px;
    align-items: center;
}
.iv-more-action-row strong {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    color: var(--text);
    font-size: 13px;
}
.iv-more-action-row span.muted {
    display: block;
    font-size: 12px;
    line-height: 1.35;
    margin-top: 2px;
}
/* Phones: a touch more space between the stacked action rows so a row's
   description doesn't crowd the next row's title (placed after the base rule so
   it wins the cascade). */
@media (max-width: 768px) {
    .iv-more-actions { gap: 16px; }
}
.tag-picker-inline {
    margin-top: -4px;
    padding-top: 0;
}
.iv-late-form-compact {
    margin-top: -2px;
}

/* btn-ai (Generate with AI) — small tweak to center with the lightbulb SVG */
.btn-ai { display: inline-flex; align-items: center; gap: 6px; }

/* Tag chip compact variant (overrides the original invoice-tags-display for sidebar use) */
.iv-side-body .invoice-tags-display {
    display: flex; flex-wrap: wrap; gap: 6px;
    align-items: center;
}
.iv-side-body .tag-chip { font-size: 12px; padding: 3px 9px 3px 10px; }
.iv-side-body .tag-add-btn { font-size: 12px; padding: 3px 9px; }

/* ============================================================
   Concept A/B/C — Journey stepper / Donut / Engagement
   ============================================================ */

/* Hero amount row — single-element after the donut was removed; gap kept at 0
   because the previous gap:16px was tuned to the donut's 64px width to keep
   the amount aligned with the title above it. */
.iv-hero-amount-row {
    display: flex; align-items: center;
    margin: 4px 0 10px;
}

/* Concept A: horizontal Invoice Journey stepper */
.iv-journey {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 18px 24px;
    margin-bottom: 18px;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 6px;
    overflow-x: auto;
}
/* On phones the 6-step journey overflows ~595px into a cramped horizontal scroll
   with no scroll affordance (a label gets cut mid-word, looking broken) and it's
   purely decorative status — the hero status pill + the timeline below already
   convey state. Hide it on phones to reclaim a screenful of height. */
@media (max-width: 640px) {
    .iv-journey { display: none; }
}
.iv-journey-step {
    display: flex; flex-direction: column; align-items: center;
    flex-shrink: 0; min-width: 88px;
    text-align: center;
}
.iv-journey-node {
    width: 36px; height: 36px;
    border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    margin-bottom: 6px;
    transition: all 0.2s;
    flex-shrink: 0;
}
.iv-journey-done .iv-journey-node {
    background: var(--status-success-bg);
    color: var(--status-success-fg);
    border: 2px solid var(--success);
}
.iv-journey-active .iv-journey-node {
    background: var(--accent-light, #EEF2FF);
    color: var(--primary);
    border: 2px solid var(--primary);
    /* No pulse: purely a "where we are" visual marker, not a call-to-action */
}
.iv-journey-paused .iv-journey-node {
    background: var(--bg-tertiary);
    color: var(--text-muted);
    border: 2px solid var(--border);
}
.iv-journey-future .iv-journey-node {
    background: var(--bg-card);
    color: var(--text-muted);
    border: 2px dashed var(--border);
}
.iv-journey-label {
    font-size: 12px; font-weight: 600;
    color: var(--text);
    line-height: 1.2;
    max-width: 96px;
}
.iv-journey-done .iv-journey-label    { color: var(--text); }
.iv-journey-active .iv-journey-label  { color: var(--primary); }
.iv-journey-paused .iv-journey-label  { color: var(--text-muted); }
.iv-journey-future .iv-journey-label  { color: var(--text-muted); }
.iv-journey-when {
    font-size: 11px;
    margin-top: 2px;
}
.iv-journey-line {
    flex: 1; height: 2px;
    background: #E5E7EB;
    margin: 17px 0 0;
    border-radius: 1px;
    min-width: 16px;
    align-self: flex-start;
}
.iv-journey-line-done {
    background: var(--success);
}
@media (max-width: 768px) {
    .iv-journey {
        padding: 14px 12px;
        justify-content: flex-start;
        scrollbar-width: none;
        -ms-overflow-style: none;
    }
    .iv-journey::-webkit-scrollbar { display: none; }
    .iv-journey-step { min-width: 60px; }
    .iv-journey-line {
        flex: 0 0 26px;
        min-width: 26px;
    }
    .iv-journey-when { display: none; }
}

@media (max-width: 640px) {
    .iv-nextaction {
        display: grid !important;
        grid-template-columns: 32px minmax(0, 1fr);
        align-items: flex-start !important;
    }
    .iv-nextaction > .btn {
        grid-column: 1 / -1;
        width: 100%;
        justify-content: center;
    }
}

/* Concept C: small client-engagement panel */
.iv-engagement-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
    text-align: center;
}
.iv-eng-stat {
    background: var(--bg-tertiary);
    border-radius: 6px;
    padding: 8px 4px;
}
.iv-eng-num {
    font-size: 20px;
    font-weight: 700;
    color: var(--text);
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}
.iv-eng-label {
    font-size: 10.5px;
    color: var(--text-muted);
    margin-top: 2px;
    display: inline-flex; align-items: center; gap: 3px;
    justify-content: center;
}
.iv-engagement-foot {
    margin-top: 8px;
    font-size: 12px;
    text-align: center;
}
.iv-engagement-badge {
    text-transform: uppercase;
}
.iv-engagement-low  { background: var(--bg-tertiary); color: var(--text-muted); border-color: var(--border); }
.iv-engagement-med  { background: var(--status-warning-bg); color: var(--status-warning-fg); border-color: #FCD34D; }
.iv-engagement-high { background: var(--status-success-bg); color: var(--status-success-fg); border-color: #86EFAC; }
.badge-log-queued  { background: var(--bg-tertiary); color: var(--text-muted); }
.badge-log-sent    { background: var(--status-info-bg); color: var(--status-info-fg); }
.badge-log-opened  { background: #E0E7FF; color: #4338CA; }
.badge-log-clicked { background: var(--status-success-bg); color: var(--status-success-fg); }
.badge-log-bounced { background: var(--status-danger-bg); color: var(--status-danger-fg); }
.badge-log-failed  { background: var(--status-danger-bg); color: var(--status-danger-fg); }

/* ---------- Detail list ---------- */
.detail-list {
    display: grid;
    /* minmax(0,1fr) so the value column can shrink below its content; pairs with
       overflow-wrap on dd so a long email/URL breaks instead of forcing the row
       (and the card) wider than a narrow phone. */
    grid-template-columns: 130px minmax(0, 1fr);
    gap: 14px 16px;     /* row-gap 8→14, col-gap 14→16 — looser without losing density */
    margin: 4px 0 18px;
    line-height: 1.5;
}
.detail-list dt {
    color: var(--text-muted);
    font-size: 13.5px;
    font-weight: 500;
    letter-spacing: 0.1px;
}
.detail-list dd {
    font-size: 14px;
    color: var(--text);
    overflow-wrap: anywhere;
}
.detail-list dd a { color: var(--primary); }

/* ---------- Timeline ---------- */
.timeline { list-style: none; }
.timeline li {
    border-left: 2px solid var(--border);
    padding: 0 0 16px 16px;
    position: relative;
}
.timeline li:before {
    content: "";
    position: absolute;
    left: -6px; top: 4px;
    width: 10px; height: 10px;
    border-radius: 50%;
    background: var(--primary);
}
.tl-head { display: flex; gap: 10px; align-items: center; }
.tl-date { font-size: 12px; color: var(--text-muted); }
.tl-subject { font-weight: 500; margin: 4px 0; }
.tl-reply-preview {
    margin: 5px 0 4px;
    color: var(--text-muted);
    font-size: 12.5px;
    line-height: 1.45;
}
.tl-ai-label {
    display: inline-flex;
    align-items: center;
    color: var(--text-muted);
    font-weight: 700;
}
.tl-ai-label:after {
    content: ':';
    margin-left: 1px;
}
/* Children = warn/note text + optional "Send now" link; without flex they sit
   inline and squish when both present (active+behind state). */
.tl-meta { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; font-size: 12px; }
.iv-step-plan-note {
    color: var(--text);
    font-weight: 600;
}
.step-tone { font-weight: 600; font-size: 13px; }
.tl-when { font-size: 12px; }
.timeline li .btn-sm { margin-top: 6px; }
/* On touch, .iv-step-link gets a 38px min-height (tap target); in the upcoming-
   steps list that made the secondary "Send now" look like it floats with big gaps
   above/around it. Tighten it: pull it up close under the step text, drop the
   left indent, and trim the box so it reads as attached to its step. */
@media (pointer: coarse) {
    .tl-step .tl-meta { row-gap: 2px; }
    .tl-step .tl-meta .iv-step-link-secondary {
        margin-left: 0; min-height: 0; padding: 3px 0;
    }
}
.reply-body {
    font-size: 14px; color: var(--text, #1F2937);
    background: var(--bg); border-radius: 8px;
    padding: 10px 12px; margin: 6px 0;
    white-space: pre-wrap;
}
.ai-box {
    margin: 10px 0;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg);
    font-size: 13px;
}
.ai-box-label {
    margin-bottom: 6px;
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 700;
    line-height: 1.3;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.ai-box-content {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 7px;
}
.ai-summary {
    color: var(--text-muted, #6B7280);
    line-height: 1.45;
}
.badge-new {
    background: var(--danger); color: #fff;
    font-size: 11px; padding: 2px 7px; border-radius: 10px;
}
.badge-intent {
    background: var(--accent-light); color: var(--primary);
    font-size: 11px; padding: 2px 8px; border-radius: 10px;
    text-transform: capitalize;
}
.reply-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }

/* ---------- Filter tabs ---------- */
/* Status tabs scroll horizontally on narrow screens instead of pushing the page
   wide — a row of 8 tabs is ~600px and overflowed a phone otherwise. */
.filter-tabs { display: flex; gap: 6px; margin-bottom: 16px; overflow-x: auto; scrollbar-width: none; min-width: 0; }
/* Phones: the filter rows (needs-action / views / tabs) are each functional, so
   keep them but tighten the gaps between them to pull the invoice cards up. */
@media (max-width: 640px) {
    .needs-action { margin-bottom: 10px; padding-bottom: 10px; }
    .saved-views-bar { margin-bottom: 8px; }
    .filter-tabs { margin-bottom: 10px; }
}
.filter-tabs::-webkit-scrollbar { display: none; }
.filter-tabs a {
    padding: 6px 14px;
    border-radius: 8px;
    color: var(--text-muted);
    font-weight: 500;
    font-size: 14px;
    flex-shrink: 0;
    white-space: nowrap;
}
.filter-tabs a:hover { background: var(--bg-card); text-decoration: none; }
.filter-tabs a.active { background: var(--primary); color: #fff; }

/* ---------- Misc ---------- */
/* List-page empty state: left-align so the placeholder sits where the first
   column would sit when the table populates — feels less "floating in space". */
.empty { padding: 24px 20px; text-align: left; color: var(--text-muted); }
.empty > p { margin: 0 0 12px; }
.empty-actions-row { display: flex; gap: 10px; flex-wrap: wrap; }
.pagination { display: flex; gap: 12px; align-items: center; justify-content: space-between; flex-wrap: wrap; }
.pagination .pagination-pages { display: flex; gap: 12px; align-items: center; }
.rows-per-page { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; }
.rows-per-page select { width: auto; min-width: 64px; }

/* "Preview only" banner — a Pro page a Solo user may look at but not save. */
.pro-preview-banner {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    padding: 12px 16px; margin-bottom: 18px; border-radius: var(--radius);
    background: var(--accent-light); border: 1px solid var(--accent-border);
    color: var(--text); font-size: 13px;
}
.pro-preview-banner .ppb-icon { color: var(--primary); flex: 0 0 auto; line-height: 0; }
.pro-preview-banner .ppb-text { flex: 1; min-width: 220px; }
.pro-preview-banner .btn { flex: 0 0 auto; }
.integration-pro-preview-banner { margin-top: 10px; }

/* Reports teaser — Solo sees a blurred sample report behind a Switch-to-Pro card. */
.pro-teaser { position: relative; }
.pro-teaser.is-locked .pro-teaser-content {
    filter: blur(3px); pointer-events: none; user-select: none;
}
.pro-teaser-overlay {
    position: absolute; inset: 0; z-index: 5;
    display: flex; align-items: flex-start; justify-content: center;
    padding-top: 32px;
}
.pro-teaser-cta {
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: var(--radius); box-shadow: var(--shadow);
    padding: 28px 32px; max-width: 420px; text-align: center;
}
.pro-teaser-cta .ppb-icon { color: var(--primary); display: inline-flex; margin-bottom: 6px; }
.pro-teaser-cta h3 { margin: 0 0 6px; font-size: 17px; }
.pro-teaser-cta p { margin: 0 0 16px; font-size: 13px; }
.pro-teaser-cta .pro-teaser-footnote { margin: 10px 0 0; }
.code-block {
    background: #1F2937;
    color: #E5E7EB;
    padding: 12px 14px;
    border-radius: 8px;
    font-size: 12px;
    overflow-x: auto;
    margin: 12px 0 16px;
}
.import-errors {
    margin-top: 14px;
    padding: 12px;
    background: var(--status-danger-bg);
    border-radius: 8px;
    font-size: 13px;
}
.import-errors li { margin-left: 18px; }

/* ---------- Auth pages ---------- */
.auth-body {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    padding: 24px;
}
.auth-card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 36px;
    width: 100%;
    max-width: 400px;
}
.auth-brand {
    font-weight: 700;
    font-size: 22px;
    color: var(--primary);
    text-align: center;
    margin-bottom: 18px;
}
.auth-title { font-size: 21px; text-align: center; margin: 0 0 24px; }   /* margin-bottom gives the title breathing room from the button/subtitle below */
/* Generic flash banner (used by the inc._flash partial) — reusable at the top of auth card / dashboard */
.flash-banner {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 10px 14px; margin-bottom: 18px;
    font-size: 14px; font-weight: 500;
    border-radius: 8px;
}
.flash-banner-msg { display: inline-flex; align-items: center; gap: 8px; }
.flash-banner-success { background: var(--status-success-bg); color: var(--status-success-fg); }
.flash-banner-warning { background: var(--status-warning-bg); color: var(--status-warning-fg); }
.flash-banner-error   { background: var(--status-danger-bg);  color: var(--status-danger-fg); }

/* Top-right × close button — matches the banner text color, darkens on hover */
.flash-banner-close {
    flex-shrink: 0;
    background: none; border: none; cursor: pointer;
    padding: 4px; margin: -4px;
    color: inherit; opacity: 0.6;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 4px;
    transition: opacity .15s, background .15s;
}
.flash-banner-close:hover { opacity: 1; background: rgba(0,0,0,0.05); }
.auth-title + .auth-subtitle { margin-top: -16px; }   /* Subtitle hugs the title (title→subtitle 8px, subtitle→form 16px) */
.auth-sub {
    color: var(--text-muted);
    text-align: center;
    font-size: 14px;
    margin: 6px 0 22px;
}
.auth-divider {
    text-align: center;
    margin: 18px 0;
    position: relative;
    color: var(--text-muted);
    font-size: 13px;
}
.auth-divider:before {
    content: "";
    position: absolute;
    top: 50%; left: 0; right: 0;
    height: 1px;
    background: var(--border);
}
.auth-divider span { background: var(--bg-card); padding: 0 10px; position: relative; }
.auth-foot { text-align: center; margin-top: 18px; font-size: 14px; }
.auth-slogan {
    text-align: center;
    font-size: 13px;
    color: var(--primary, var(--primary));
    font-weight: 600;
    margin: 4px 0 14px;
}
.auth-slogan-cta { margin: 12px 0 0; }
.empty-cta { text-align: center; padding: 32px 16px; }
.empty-slogan {
    font-size: 20px;
    font-weight: 700;
    color: var(--text, #1E1B2E);
    margin-bottom: 6px;
}
.empty-cta .btn { margin-top: 14px; }
.form-link {
    display: inline-block;
    margin-top: 6px;
    font-size: 13px;
    color: var(--primary, var(--primary));
    text-decoration: none;
}
.form-link:hover { text-decoration: underline; }
.msg-box {
    padding: 16px;
    border-radius: 8px;
    text-align: center;
    margin: 10px 0;
}
.msg-error   { background: var(--status-danger-bg); color: var(--status-danger-fg); }
.msg-success { background: var(--status-success-bg); color: var(--status-success-fg); }
.msg-warning { background: var(--status-warning-bg); color: var(--status-warning-fg); }
.msg-info    { background: var(--accent-light); color: var(--primary); }

/* ---------- Toast ---------- */
#toast-root {
    position: fixed;
    top: 20px;
    right: 20px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    z-index: 9999;
}
.toast {
    padding: 12px 18px;
    border-radius: 8px;
    border: 1px solid transparent;
    font-size: 14px;
    font-weight: 500;
    box-shadow: var(--shadow);
    animation: toast-in .2s ease;
}
/* Subtle palette — matches inline .form-error / .msg-error / .badge-* across the app
   instead of saturated solid colors. Dark-mode is automatic since the tokens already
   have @media (prefers-color-scheme: dark) overrides at the :root level. */
.toast-success {
    background:   var(--status-success-bg);
    color:        var(--status-success-fg);
    border-color: #BBF7D0;
}
.toast-error {
    background:   var(--status-danger-bg);
    color:        var(--status-danger-fg);
    border-color: #FECACA;
}
.toast-info {
    background:   var(--accent-light);
    color:        var(--primary);
    border-color: #DDD6FE;
}
@keyframes toast-in { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; } }

/* ---------- Hover/click tooltip — `.duefy-tip` ---------- */
/* JS in app.js attaches mouseenter/mouseleave (0ms hover, no native title delay)
   + click (pin until clicked away / Esc) + focus (a11y). Use:
     <span class="duefy-tip" tabindex="0" role="button"
           data-tip-title="..." data-tip-items="A|B|C">(see examples)</span> */
.duefy-tip {
    cursor: help;
    color: var(--text-muted);
    font-size: 12px;
    border-bottom: 1px dotted var(--text-muted);
    text-decoration: none;
    padding-bottom: 1px;
}
.duefy-tip:hover, .duefy-tip:focus-visible {
    color: var(--primary);
    border-bottom-color: var(--primary);
    outline: none;
}
.duefy-tip-popup {
    background: var(--bg-card);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 10px 14px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.12);
    font-size: 13px;
    line-height: 1.6;
    z-index: 10000;
    max-width: 360px;
    min-width: 200px;
    animation: duefy-tip-in .12s ease;
}
.duefy-tip-title {
    font-size: 12px;
    font-weight: 600;
    color: var(--text-muted);
    margin-bottom: 6px;
}
.duefy-tip-list {
    display: grid;
    grid-template-columns: max-content 1fr;
    column-gap: 16px;
    row-gap: 4px;
    margin: 0;
    padding: 0;
    font-size: 13px;
}
.duefy-tip-list dt {
    color: var(--text-muted);
    font-weight: 500;
    white-space: nowrap;
}
.duefy-tip-list dd {
    margin: 0;
    color: var(--text);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12.5px;
}
.duefy-tip-list .duefy-tip-full {
    grid-column: 1 / -1;
    color: var(--text-muted);
}
.duefy-tip-pinned {
    border-color: var(--primary);
}
@keyframes duefy-tip-in {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* ---------- Responsive ---------- */
/* Between the mobile collapse (720) and ~960px the full top nav is wider than
   the viewport (logo + 6 links + search/bell/badge/name ≈ 955px) and pushed a
   horizontal scrollbar onto every app page. Tighten gaps and drop the two
   lowest-value items; everything returns at >=960px. */
@media (min-width: 721px) and (max-width: 959px) {
    .nav-inner { gap: 16px; padding: 0 16px; }
    .nav-menu { gap: 12px; }
    .user-menu-name { display: none; }
    .badge-plan-wrap { display: none; }
}
@media (max-width: 720px) {
    .nav-inner { padding: 0 14px; gap: 14px; justify-content: space-between; }
    .nav-menu { display: none; }
    .navbar:not(.navbar-public) .nav-user { display: none; }
    .user-menu-name { display: none; }
    .container { padding: 20px 14px 50px; }
    .stat-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
    .duefy-impact { align-items: flex-start; }
    .duefy-impact-main { flex-direction: column; align-items: flex-start; gap: 10px; }
    .duefy-impact-items { flex-direction: column; align-items: stretch; gap: 10px; }
    .duefy-impact-item { min-width: 0; }
    .dashboard-action-row { grid-template-columns: 30px minmax(0, 1fr) 18px; padding: 12px; }
    .dashboard-action-icon { width: 30px; height: 30px; }
    /* Keep the three forecast metrics on one row (3 columns) instead of
       stacking; shrink the value/label so even 6-figure amounts fit at 320px. */
    .forecast-metric-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
    .forecast-metric {
        padding: 12px 8px;
        border-right: 1px solid var(--border);
        border-bottom: 0;
    }
    .forecast-metric:first-child { padding-left: 0; }
    .forecast-metric:last-child { padding-right: 0; border-right: 0; }
    .forecast-label { font-size: 10px; letter-spacing: .02em; }
    .forecast-value { font-size: 16px; margin-top: 6px; overflow-wrap: anywhere; }
    .forecast-sub { font-size: 11px; }
    .dashboard-aging-grid { grid-template-columns: 1fr 1fr; }
    .dashboard-mini-row {
        grid-template-columns: 1fr;
        gap: 8px;
    }
    .dashboard-mini-badge {
        justify-self: start;
    }
    .dashboard-mini-amount {
        justify-self: start;
    }
    .grid-2 { grid-template-columns: 1fr; }
    .form-row { flex-direction: column; gap: 0; }
    #invoice-form .form-row { gap: 0; }
    #invoice-form .invoice-money-input { grid-template-columns: minmax(0, 1fr) 96px; }
    .recurring-grid { grid-template-columns: 1fr; }
    .table { font-size: 13px; }
    .table th, .table td { padding: 8px; }
}

/* ======================================================
   Settings pages
   ====================================================== */
.settings-layout {
    display: grid;
    grid-template-columns: 200px 1fr;
    gap: 24px;
}
.settings-nav { display: flex; flex-direction: column; gap: 2px; }
.settings-nav a {
    padding: 10px 14px;
    border-radius: 8px;
    color: var(--text);
    text-decoration: none;
    font-size: 14px;
    font-weight: 500;
    /* `flex` (not inline-flex) so the link stretches to the 200px column width;
       active background then matches column edge instead of hugging content. */
    display: flex;
    align-items: center;
    gap: 8px;
}
.settings-nav a svg { flex-shrink: 0; }
/* Keep the label + Pro/Team badge on one line: longer labels ("Pay-page
   branding", "Sending domain") + a full-size pill were wrapping in the 200px
   column. Don't wrap the text, and use a tighter badge so it fits. */
.settings-nav a { white-space: nowrap; }
.settings-nav .pro-badge {
    font-size: 9px;
    padding: 1px 5px;
    margin-left: 0;
    letter-spacing: .03em;
}

/* Generic: inline alignment of icon + text (used in buttons, hints, etc.) */
.icon-inline {
    display: inline-block;
    vertical-align: -3px;
    margin-right: 4px;
}
.settings-nav a:hover { background: var(--bg-tertiary); }
.settings-nav a.active { background: var(--accent-light); color: var(--primary); }
.settings-nav-danger { color: var(--danger) !important; }
.settings-content { min-width: 0; }
.settings-content .card { margin-bottom: 20px; }
/* Standard rhythm for settings cards: h2 → description → action.
   The h2 margin is global on `.card > h2`; the broader `> p` selector (vs
   `> h2 + p`) is intentional so danger-zone secondary paragraphs and other
   non-first paragraphs in settings cards also get the relaxed line-height. */
.settings-content .card > p { margin: 0 0 18px; line-height: 1.55; }

/* Settings input width — cap single-value fields so a Full name or Email doesn't span
   the whole ~960px card (modern UX: Stripe / Linear / Notion / Vercel).
   Caps applied at the WRAP level (not the input itself) so password input + eye-icon
   sibling stay attached, and so .input-row / .form-row (where multiple controls share
   a line, e.g. mailbox @ domain) aren't touched.
   - `> input`  : direct child of .form-group (no wrap) — profile name, email, etc.
   - `> select` : same for dropdowns
   - `> .input-password-wrap` : caps the whole password input + eye icon group together
   - `> .auth-row-split` : "Current password" label + "Forgot password?" link row —
     must share the same cap so the "Forgot" link sits above the input's right edge
     rather than floating to the card edge.
   Excludes:
   - checkbox / radio (toggle, doesn't need width)
   - .input-wide (explicit opt-out for wide-URL fields)
   - .tfa-code-input (6-digit code has its own narrower width) */
.settings-content .form-group > input:not([type="checkbox"]):not([type="radio"]):not(.input-wide):not(.tfa-code-input),
.settings-content .form-group > select:not(.input-wide),
.settings-content .form-group > .input-password-wrap,
.settings-content .form-group > .auth-row-split,
.settings-content .form-group > .password-strength {
    max-width: 420px;
}
/* Override: when form-group is nested inside a form-row (e.g. settings/api_keys
   "Key name + Generate" on one line), the form-group expects to grow with `flex: 1` to
   fill the remaining row width — capping its input to 420 would leave 400px of
   dead space inside the group before the button. Drop the cap in that case. */
.settings-content .form-row .form-group > input { max-width: none; }
.settings-content .form-row .form-group > select { max-width: none; }
.input-readonly { background: var(--bg); color: var(--text-muted); }

/* Intake page: independent stacked cards (Tags-page style), not one big card.
   The shell is just a max-width column; each .intake-card keeps its own .card
   chrome and stacks via the card's own margin-bottom. */
.intake-shell {
    max-width: 808px;
}
.intake-shell > .intake-page-lede {
    margin-top: 0;
}
.intake-shell .intake-card,
.invoice-intake-page .intake-shell .intake-card {
    max-width: none;
}

/* toggle switch */
.toggle-row {
    display: flex; align-items: center; justify-content: space-between;
    padding: 14px 0; border-bottom: 1px solid var(--border);
    gap: 16px;
}
/* The whole row is a <label> — clicking anywhere toggles the switch. */
label.toggle-row { cursor: pointer; }
/* Section header dividing account toggles from product/marketing ones. A
   brand-colored icon + generous top space anchors it as a real section (no
   top border — that doubled up with the previous row's bottom border). */
.toggle-group-title {
    display: flex; align-items: center; gap: 8px;
    margin: 36px 0 14px;
    font-size: 13px; font-weight: 700; letter-spacing: .06em;
    text-transform: uppercase; color: var(--text);
}
.toggle-group-title svg { color: var(--primary); flex-shrink: 0; }
.toggle-group-title:first-of-type { margin-top: 26px; }
.toggle-title { font-weight: 600; font-size: 14px; }
.toggle-desc  { font-size: 13px; }
.switch { position: relative; display: inline-block; width: 44px; height: 24px; flex-shrink: 0; }
.switch input { opacity: 0; width: 0; height: 0; }
.slider {
    position: absolute; inset: 0; cursor: pointer;
    background: #CBD5E1; border-radius: 24px; transition: background .15s;
}
.slider:before {
    content: ""; position: absolute; height: 18px; width: 18px;
    left: 3px; bottom: 3px; background: var(--bg-card); border-radius: 50%; transition: transform .15s;
}
.switch input:checked + .slider { background: var(--primary); }
.switch input:checked + .slider:before { transform: translateX(20px); }

/* banners / danger zone */
.info-banner {
    background: var(--accent-light); color: #3730A3;
    padding: 14px 16px; border-radius: 8px; font-size: 14px;
}
.info-banner-ok { background: var(--status-success-bg); color: var(--status-success-fg); }
.info-banner-warn { background: var(--status-warning-bg); color: var(--status-warning-fg); }
/* Stripe Connect: action row when connected (manage + disconnect). */
.stripe-connect-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
/* Stripe Connect 2-step setup (connect → turn on payments) */
.stripe-steps { list-style: none; margin: 4px 0 18px; padding: 0; }
.stripe-step { display: flex; gap: 12px; align-items: flex-start; padding: 14px 0; border-bottom: 1px solid var(--border); }
.stripe-step:last-child { border-bottom: 0; }
.stripe-step-mark { flex: 0 0 24px; width: 24px; height: 24px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 700; }
.stripe-step.done .stripe-step-mark { background: var(--status-success-bg); color: var(--status-success-fg); }
.stripe-step.pending .stripe-step-mark { background: var(--status-warning-bg); color: var(--status-warning-fg); }
.stripe-step.unknown .stripe-step-mark { background: var(--surface-2); color: var(--text-muted); }
.stripe-step-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.stripe-step-body strong { font-size: 14px; }
.stripe-step-sub { font-size: 13px; color: var(--text-muted); line-height: 1.5; overflow-wrap: anywhere; }
.stripe-step.pending .stripe-step-body strong { color: var(--text); }
.danger-zone { border: 1px solid #FCA5A5; }
.danger-zone h2 { color: var(--danger); }
/* breathing room before the destructive action so it doesn't read as glued
   to the explanatory text — settings card > p sets 18px below, button adds 6 */
.danger-zone > .btn-danger { margin-top: 6px; }

/* settings/password: 2FA cross-promo sits under the form, visually separated */
.password-2fa-nudge {
    margin-top: 20px !important;
    padding-top: 16px;
    border-top: 1px solid var(--border);
    font-size: 13px;
}

.plan-box {
    display: flex; align-items: center; justify-content: space-between;
    background: var(--bg); border-radius: 8px; padding: 16px 18px; margin-bottom: 16px;
}
.plan-name { font-size: 22px; font-weight: 700; color: var(--text); }

.badge-unread {
    background: var(--danger); color: #fff;
    border-radius: 11px; padding: 2px 8px; font-size: 12px;
    text-decoration: none;
}

/* Notifications bell — single header entry consolidating unread replies +
   intake invoices to review. Calm brand-coloured count (not alarm red), with
   a breakdown panel mirroring the user-menu dropdown. */
.nav-notif { position: relative; display: inline-flex; }
.nav-notif-trigger {
    position: relative;
    display: inline-flex; align-items: center; justify-content: center;
    width: 36px; height: 36px;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 8px;
    color: var(--text-muted);
    cursor: pointer;
}
.nav-notif-trigger:hover,
.nav-notif.is-open .nav-notif-trigger {
    background: var(--bg-tertiary); border-color: var(--border); color: var(--text);
}
.nav-notif-count {
    position: absolute; top: -3px; right: -3px;
    min-width: 17px; height: 17px; padding: 0 4px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--primary); color: #fff;
    font-size: 11px; font-weight: 700; line-height: 1;
    border-radius: 999px;
    border: 2px solid var(--bg-card);
}
.nav-notif-dropdown {
    display: none;
    position: absolute; top: calc(100% + 6px); right: 0;
    min-width: 252px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.08);
    padding: 6px;
    z-index: 100;
}
.nav-notif.is-open .nav-notif-dropdown { display: block; }
.nav-notif-head {
    padding: 6px 10px 8px;
    font-size: 11px; font-weight: 600; letter-spacing: .04em;
    text-transform: uppercase; color: var(--text-muted);
}
.nav-notif-item {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 10px;
    border-radius: 6px;
    color: var(--text); font-size: 14px;
    text-decoration: none;
}
.nav-notif-item:hover { background: var(--bg-tertiary); }
.nav-notif-item strong { font-weight: 700; }
.nav-notif-icon { color: var(--text-muted); flex-shrink: 0; }
.nav-notif-label { flex: 1; }
.nav-notif-arrow { color: var(--text-muted); flex-shrink: 0; }

@media (max-width: 720px) {
    .settings-layout { grid-template-columns: minmax(0, 1fr); }
    /* Grid items default to min-width:auto, so a wide/non-shrinking child (e.g. the
       horizontal nav chip row) blows the single column past the viewport → page-wide
       horizontal scroll. Force the items to be allowed to shrink to the track. */
    .settings-layout > * { min-width: 0; }
    /* Stage 5 F-11: 14+ nav links wrapping at the top of every settings
       page is visual noise. On mobile, show only the group that contains
       the currently-active link, plus a "More" toggle. Implementation:
       use the native <details> tag wrapping the aside (added in the JS
       below) so we don't need a separate state library. CSS :has()
       lets us highlight the group that owns the active link. */
    .settings-nav { flex-direction: column; gap: 4px; }
    .settings-nav-group { padding: 0; border: 0; }
    .settings-nav-group:not(:has(a.active)) {
        display: none;
    }
    .settings-mobile-more {
        display: inline-block;
        margin-top: 8px;
        font-size: 13px;
        color: var(--primary);
        background: none; border: 0; padding: 6px 0;
        cursor: pointer;
    }
    .settings-nav.mobile-expanded .settings-nav-group { display: block; }
    .settings-nav.mobile-expanded .settings-mobile-more { display: none; }

    /* Collapsed (current group only): the 6 sibling links otherwise stack ~6 rows
       deep, pushing the actual settings content off the first screen. Lay the
       current group out as one horizontal scroll chip row instead; "Show all
       settings" still sits below to reach the rest. Expanded state (full vertical
       nav) is untouched. */
    .settings-nav:not(.mobile-expanded) .settings-nav-group:has(a.active) {
        display: flex; flex-direction: row; flex-wrap: nowrap;
        overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none;
        gap: 8px; padding-bottom: 4px;
    }
    .settings-nav:not(.mobile-expanded) .settings-nav-group:has(a.active)::-webkit-scrollbar { display: none; }
    .settings-nav:not(.mobile-expanded) .settings-nav-group:has(a.active) .settings-nav-label { display: none; }
    .settings-nav:not(.mobile-expanded) .settings-nav-group:has(a.active) a {
        flex: 0 0 auto; white-space: nowrap;
        border: 1px solid var(--border); border-radius: 999px; padding: 7px 12px;
    }
    .settings-nav:not(.mobile-expanded) .settings-nav-group:has(a.active) a.active {
        border-color: var(--primary); color: var(--primary); background: var(--accent-light);
    }
}
@media (min-width: 721px) {
    .settings-mobile-more { display: none; }
}

/* ---- auth page header + Google button ---- */
.auth-header {
    max-width: 420px; margin: 0 auto 16px; padding-top: 28px;
    display: flex; align-items: center; justify-content: space-between;
}
.auth-logo { font-size: 20px; font-weight: 800; color: var(--primary); text-decoration: none; }
.auth-back { font-size: 14px; color: var(--text-muted); text-decoration: none; }
.auth-back:hover { color: var(--primary); }
.btn-google {
    display: flex; align-items: center; justify-content: center; gap: 10px;
    background: var(--bg-card); border: 1px solid #ddd; color: #333; font-weight: 500;
}
.btn-google:hover { box-shadow: 0 2px 8px rgba(0,0,0,.15); }
.btn-google svg { flex-shrink: 0; }

/* ---- AI assistant card ---- */
.ai-assistant-card { border: 1px solid var(--accent-border); background: linear-gradient(180deg, var(--bg-card), var(--accent-light)); }
.ai-header { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; }
.ai-icon { font-size: 20px; }
.ai-title { font-weight: 700; font-size: 16px; color: var(--text); }
.ai-badge { background: var(--accent-light); color: var(--primary); font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 10px; }
.ai-suggestions { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.ai-suggestions button {
    background: var(--bg-card); border: 1px solid var(--border); border-radius: 16px;
    padding: 6px 12px; font-size: 13px; color: var(--text); cursor: pointer; width: auto;
}
.ai-suggestions button:hover { border-color: var(--primary); color: var(--primary); }
.ai-input-row { display: flex; gap: 8px; }
.ai-input-row input { flex: 1; }
.ai-input-row button {
    background: var(--primary); color: #fff; border: none; border-radius: 8px;
    padding: 9px 16px; font-weight: 600; cursor: pointer; white-space: nowrap;
}

/* ===== Help center full page (dark-mode compatible) ===== */
.help-page { max-width: 960px; margin: 0 auto; padding: 48px 16px 64px; }
.help-404 { max-width: 560px; margin: 0 auto; padding: 64px 32px; text-align: center; }
.help-404-icon { color: var(--text-muted); display: inline-flex; margin-bottom: 8px; }
.help-404-cta { margin-top: 16px; }
.help-title { text-align: center; margin: 8px 0 28px; font-size: 32px; letter-spacing: -0.02em; }
.help-search {
    display: flex; gap: 8px; max-width: 620px; margin: 0 auto 40px;
}
.help-search input {
    flex: 1; padding: 13px 18px; font-size: 15px;
    border: 1px solid var(--border); border-radius: 10px;
    background: var(--bg-card); color: var(--text);
    box-shadow: 0 1px 2px rgba(0,0,0,.04);
    transition: border-color .15s, box-shadow .15s;
}
.help-search input:focus {
    outline: none; border-color: var(--primary);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent);
}
.help-categories {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 20px;
}
.help-cat-card {
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: 14px; padding: 24px;
    box-shadow: 0 1px 3px rgba(0,0,0,.05);
    transition: box-shadow .15s, transform .15s, border-color .15s;
}
.help-cat-card:hover {
    box-shadow: 0 6px 20px rgba(0,0,0,.08);
    border-color: color-mix(in srgb, var(--primary) 35%, var(--border));
    transform: translateY(-2px);
}
.help-cat-title {
    margin: 0 0 14px; text-transform: capitalize; color: var(--text);
    font-size: 17px; padding-bottom: 12px; border-bottom: 1px solid var(--border);
}
.help-cat-list { list-style: none; padding: 0; margin: 0; }
.help-cat-list li { margin: 0; }
.help-cat-list li a {
    color: var(--text); text-decoration: none;
    display: block; padding: 7px 0; font-size: 14.5px;
    transition: color .12s;
}
.help-cat-list li a:hover { color: var(--primary); }
.help-result-title { color: var(--primary); font-weight: 600; text-decoration: none; }
.help-result-snippet { margin: 6px 0 0; font-size: 13px; }

.help-article {
    max-width: 800px; margin: 40px auto; padding: 44px 52px;
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: 16px; box-shadow: 0 1px 3px rgba(0,0,0,.05);
}
.help-back-link,
.page-back-link {
    color: var(--text-muted); text-decoration: none; font-size: 14px;
    display: inline-flex; align-items: center; gap: 4px; font-weight: 500;
    transition: color .12s;
}
.help-back-link:hover,
.page-back-link:hover { color: var(--primary); }
/* Sits just above an h1 in .page-head so a focused sub-page (e.g. /invoice/review/)
   always has an obvious way back to its parent list. */
.page-back-link { margin-bottom: 6px; }
.help-related {
    margin-top: 40px; padding-top: 24px;
    border-top: 1px solid var(--border);
}
.help-related h3 { font-size: 15px; margin: 0 0 12px; color: var(--text-muted);
    text-transform: uppercase; letter-spacing: .04em; }
.help-related ul { list-style: none; padding: 0; margin: 0; }
.help-related li { margin: 4px 0; }
.help-related li a {
    color: var(--primary); text-decoration: none;
    display: inline-flex; align-items: center; gap: 6px; font-weight: 500;
}
.help-related li a::before { content: "→"; color: var(--text-muted); }
.help-related li a:hover { text-decoration: underline; }
.help-feedback {
    margin-top: 32px; padding: 18px; text-align: center;
    background: var(--bg-tertiary); border-radius: 12px;
    display: flex; align-items: center; justify-content: center; gap: 12px; flex-wrap: wrap;
}
.help-feedback > span:first-child { font-weight: 600; }
.help-feedback-thanks { color: var(--success); }

/* doc-body — render markdown pre/code/table via CSS vars */
.doc-body { line-height: 1.75; margin-top: 20px; color: var(--text); font-size: 15.5px; }
.doc-body > :first-child { margin-top: 0; }
.doc-body h1, .doc-body h2, .doc-body h3, .doc-body h4 {
    scroll-margin-top: 16px; line-height: 1.3; color: var(--text);
}
.doc-body h1 { font-size: 30px; letter-spacing: -0.02em; margin: 0 0 20px; }
.doc-body h2 {
    font-size: 22px; letter-spacing: -0.01em; margin: 40px 0 14px;
    padding-bottom: 8px; border-bottom: 1px solid var(--border);
}
.doc-body h3 { font-size: 18px; margin: 30px 0 10px; }
.doc-body h4 { font-size: 15.5px; margin: 24px 0 8px; }
.doc-body p { margin: 0 0 16px; }
.doc-body ul, .doc-body ol { margin: 0 0 16px; padding-left: 24px; }
.doc-body li { margin: 6px 0; }
.doc-body li > ul, .doc-body li > ol { margin: 6px 0; }
.doc-body a { color: var(--primary); text-decoration: none; }
.doc-body a:hover { text-decoration: underline; }
.doc-body strong { color: var(--text); font-weight: 600; }
.doc-body hr { border: none; border-top: 1px solid var(--border); margin: 32px 0; }
.doc-body blockquote {
    margin: 0 0 16px; padding: 4px 18px;
    border-left: 3px solid var(--primary);
    color: var(--text-muted); background: var(--bg-tertiary);
    border-radius: 0 8px 8px 0;
}
.doc-body blockquote p:last-child { margin-bottom: 0; }
.doc-body img { max-width: 100%; height: auto; border-radius: 8px; }
.doc-body pre {
    background: var(--bg-tertiary); color: var(--text);
    padding: 16px; border-radius: 10px; overflow: auto;
    border: 1px solid var(--border); margin: 0 0 16px;
}
.doc-body :not(pre) > code {
    background: var(--bg-tertiary); color: var(--text);
    padding: 1px 5px; border-radius: 4px;
    font-family: ui-monospace, Menlo, monospace; font-size: .88em;
}
.doc-body table {
    border-collapse: separate; border-spacing: 0; width: 100%;
    margin: 0 0 20px; font-size: 14.5px;
    border: 1px solid var(--border); border-radius: 10px; overflow: hidden;
}
.doc-body thead th { background: var(--bg-tertiary); }
.doc-body th, .doc-body td {
    border-bottom: 1px solid var(--border); padding: 10px 14px;
    text-align: left; vertical-align: top;
}
.doc-body th + th, .doc-body td + td { border-left: 1px solid var(--border); }
.doc-body tbody tr:last-child td { border-bottom: none; }
.doc-body tbody tr:nth-child(even) td { background: color-mix(in srgb, var(--bg-tertiary) 45%, transparent); }

@media (max-width: 600px) {
    .help-article { padding: 28px 22px; margin: 20px auto; border-radius: 12px; }
    .doc-body h1 { font-size: 25px; }
    .doc-body h2 { font-size: 20px; }
}

/* ===== Keyboard shortcuts modal (rendered by shortcuts.js, dark-mode compatible) ===== */
.shortcut-help-overlay {
    z-index: 9999; align-items: center; justify-content: center;
    /* padding/inset are already set on .modal-overlay, share its backdrop */
}
.shortcut-help-box {
    background: var(--bg-card); color: var(--text);
    border-radius: 16px; padding: 22px 24px 18px;
    max-width: 520px; width: 90%; max-height: 88vh; overflow-y: auto;
    border: 1px solid var(--border);
    box-shadow: 0 20px 50px rgba(0,0,0,.25);
}
.shortcut-help-head {
    display: flex; justify-content: space-between; align-items: center;
    margin-bottom: 4px;
}
.shortcut-help-head h2 { margin: 0; font-size: 19px; }
.shortcut-help-close {
    background: none; border: none; font-size: 17px; line-height: 1;
    width: 30px; height: 30px; border-radius: 8px;
    display: inline-flex; align-items: center; justify-content: center;
    cursor: pointer; color: var(--text-muted);
    transition: background .12s ease, color .12s ease;
}
.shortcut-help-close:hover { background: var(--bg-tertiary); color: var(--text); }

.sc-section { margin-top: 14px; }
.sc-section-title {
    font-size: 11px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase;
    color: var(--primary); margin-bottom: 4px;
}
.sc-row {
    display: flex; align-items: center; gap: 14px;
    padding: 4px 8px; border-radius: 8px;
}
.sc-row:hover { background: var(--bg-tertiary); }
.sc-keys { display: inline-flex; align-items: center; gap: 6px; flex: 0 0 138px; }
.sc-join { font-size: 11px; color: var(--text-muted); }
.sc-desc { color: var(--text); font-size: 14px; }
/* Keycap: subtle 2px bottom border reads as a physical key, not a flat pill. */
.shortcut-help-box kbd {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 24px; height: 24px; padding: 0 7px;
    background: var(--bg); color: var(--text);
    border: 1px solid var(--border); border-bottom-width: 2px;
    border-radius: 6px;
    font-family: ui-monospace, Menlo, monospace; font-size: 12px; font-weight: 600;
}
.shortcut-help-foot {
    margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border);
    font-size: 12px; color: var(--text-muted);
    display: flex; align-items: center; gap: 6px;
}
.ai-answer {
    margin-top: 14px; padding: 14px; background: var(--bg-card);
    border: 1px solid var(--border); border-radius: 8px; font-size: 14px; line-height: 1.6;
}

/* Page-contextual AI chat panel (invoice/view + client/view "Ask AI" button) */
.page-ai-panel {
    background: var(--accent-light);
    border: 1px solid var(--accent-border);
    border-left: 3px solid var(--primary);
    border-radius: 10px;
    padding: 14px 16px;
    margin: 0 0 16px;
}
.page-ai-head {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 10px;
}
.page-ai-title {
    font-size: 13px; font-weight: 600; color: var(--text);
    display: inline-flex; align-items: center; gap: 6px;
}
.page-ai-close {
    background: none; border: none; cursor: pointer;
    font-size: 20px; line-height: 1; color: var(--text-muted);
    padding: 0 4px;
}
.page-ai-close:hover { color: var(--text); }
.page-ai-suggestions {
    display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px;
}
.page-ai-suggestions button {
    background: var(--bg-card); color: var(--text-muted);
    border: 1px solid var(--border); border-radius: 999px;
    padding: 4px 12px; font-size: 12.5px; cursor: pointer;
}
.page-ai-suggestions button:hover { color: var(--primary); border-color: var(--primary); }
.page-ai-input-row {
    display: flex; gap: 8px;
}
.page-ai-input-row input[type="text"] {
    flex: 1; padding: 8px 10px;
    border: 1px solid var(--border); border-radius: 6px;
    background: var(--bg-card); color: var(--text);
    font-size: 14px;
}
.page-ai-input-row button {
    padding: 8px 16px; border-radius: 6px;
    background: var(--primary); color: #fff; border: none;
    font-size: 14px; font-weight: 500; cursor: pointer;
    white-space: nowrap;
}
.page-ai-input-row button:hover { filter: brightness(1.08); }
.page-ai-answer {
    margin-top: 10px; padding: 10px 12px;
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: 6px; font-size: 13.5px; line-height: 1.55;
    white-space: pre-wrap;
}
.page-ai-thread {
    margin-top: 10px;
    max-height: 320px;
    overflow-y: auto;
    display: flex; flex-direction: column; gap: 8px;
    padding-right: 4px;
    margin-bottom: 10px;
}
.page-ai-msg {
    padding: 8px 12px;
    border-radius: 10px;
    font-size: 13.5px; line-height: 1.55;
    white-space: pre-wrap;
    max-width: 88%;
}
.page-ai-msg-user {
    align-self: flex-end;
    background: var(--primary);
    color: #fff;
    border-bottom-right-radius: 3px;
}
.page-ai-msg-ai {
    align-self: flex-start;
    background: var(--bg-card);
    color: var(--text);
    border: 1px solid var(--border);
    border-bottom-left-radius: 3px;
}
/* Markdown inside the AI bubble: bold/italic/code/lists */
.page-ai-msg-ai strong { font-weight: 600; }
.page-ai-msg-ai em     { font-style: italic; }
.page-ai-msg-ai code {
    background: var(--bg-tertiary, var(--bg));
    color: var(--text);
    padding: 1px 5px;
    border-radius: 4px;
    font-family: ui-monospace, Menlo, monospace;
    font-size: 12.5px;
}
.page-ai-msg-ai ul, .page-ai-msg-ai ol {
    margin: 6px 0 6px 22px;
    padding: 0;
}
.page-ai-msg-ai li {
    margin: 2px 0;
    white-space: normal;  /* override the bubble's pre-wrap so list items wrap naturally */
}
/* Typing indicator: 3 pulsing dots while waiting for the model to respond */
.page-ai-msg-typing {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 12px 14px;  /* slightly wider so the dots have breathing room */
}
.page-ai-dot {
    width: 6px; height: 6px; border-radius: 50%;
    background: var(--text-muted);
    animation: page-ai-dot-bounce 1.2s ease-in-out infinite;
}
.page-ai-dot:nth-child(2) { animation-delay: 0.15s; }
.page-ai-dot:nth-child(3) { animation-delay: 0.30s; }
@keyframes page-ai-dot-bounce {
    0%, 60%, 100% { opacity: 0.3; transform: translateY(0); }
    30%           { opacity: 1;   transform: translateY(-3px); }
}
.page-ai-clear {
    background: none; border: 1px solid var(--border);
    color: var(--text-muted);
    padding: 6px 10px; border-radius: 6px;
    font-size: 12px; cursor: pointer;
}
.page-ai-clear:hover { color: var(--text); border-color: var(--text-muted); }
.page-ai-followups {
    align-self: flex-start;
    display: flex; flex-wrap: wrap; gap: 6px;
    margin-top: 4px; margin-bottom: 4px;
    max-width: 88%;
}
.page-ai-followup-chip {
    background: var(--bg-card);
    color: var(--text-muted);
    border: 1px dashed var(--border);
    border-radius: 999px;
    padding: 4px 12px;
    font-size: 12.5px;
    cursor: pointer;
    line-height: 1.3;
    text-align: left;
}
.page-ai-followup-chip:hover {
    color: var(--primary);
    border-color: var(--primary);
    border-style: solid;
}
.page-ai-msg-failed {
    color: var(--text-muted);
    font-style: italic;
}
.page-ai-retry-chip {
    color: var(--primary);
    border-style: solid;
    font-weight: 600;
}
.page-ai-rating {
    align-self: flex-start;
    display: flex; gap: 4px;
    margin-top: -2px; margin-bottom: 4px;
}
.page-ai-rate-btn {
    background: none; border: none; cursor: pointer;
    font-size: 14px; padding: 2px 6px; border-radius: 6px;
    opacity: 0.4;
    transition: opacity 100ms ease, background 100ms ease;
    line-height: 1;
}
.page-ai-rate-btn:hover    { opacity: 0.85; background: var(--bg); }
.page-ai-rate-btn.is-active { opacity: 1;    background: var(--accent-light); }
/* Action chip — server-validated nav anchor, distinct from follow-up question chip */
.page-ai-action-chip {
    background: var(--accent-light);
    color: var(--primary);
    border: 1px solid var(--accent-border);
    border-style: solid;
    text-decoration: none;
    font-weight: 500;
}
.page-ai-action-chip:hover {
    background: var(--primary);
    color: #fff;
    border-color: var(--primary);
}
/* AI usage card on settings/billing */
.ai-usage-summary {
    display: flex; align-items: baseline; justify-content: space-between;
    margin: 10px 0 8px;
    flex-wrap: wrap; gap: 8px;
}
.ai-usage-num { font-size: 28px; font-weight: 700; color: var(--text); }
.ai-usage-bar {
    height: 8px; background: var(--bg-tertiary, var(--bg));
    border-radius: 4px; overflow: hidden;
}
.ai-usage-bar-fill {
    height: 100%;
    width: var(--bar-width, 0%);
    background: var(--primary);
    transition: width 0.3s ease;
}
.ai-usage-bar-fill.ai-usage-bar-warn { background: #D97706; }
.ai-usage-bar-fill.ai-usage-bar-full { background: #DC2626; }
.ai-usage-note { margin-top: 8px; }
/* ---- AI risk alert (Dashboard) ---- */
.ai-alert-card { border: 1px solid #FCA5A5; background: var(--status-danger-bg); }
.ai-alert-header { font-size: 15px; color: var(--status-danger-fg); margin-bottom: 12px; }
.ai-alert-row { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-top: 1px solid #FECACA; font-size: 14px; }
.ai-alert-hint { color: var(--text-muted); font-size: 13px; flex: 1; }
/* ---- client score badges ---- */
.score-badge { padding: 2px 8px; border-radius: 12px; font-weight: 700; font-size: 12px; }
.score-a { background: var(--status-success-bg); color: var(--status-success-fg); }
.score-b { background: var(--status-info-bg); color: var(--status-info-fg); }
.score-c { background: var(--status-warning-bg); color: var(--status-warning-fg); }
.score-d { background: var(--status-danger-bg); color: var(--status-danger-fg); }
.score-f { background: #4B0082; color: #fff; }
[data-theme="dark"] .score-f { background: #6D28D9; color: #fff; }   /* lighter indigo for dark bg (was hardcoded, no dark variant) */
/* ---- AI strategy box (invoice view) ---- */
.ai-strategy-box { border: 1px solid var(--accent-border); background: var(--accent-light); border-radius: 10px; padding: 16px; margin: 16px 0; }
.ai-strategy-header { display: flex; align-items: center; gap: 8px; font-size: 14px; margin-bottom: 8px; }
.ai-strategy-text { color: var(--text); font-size: 14px; line-height: 1.6; }
.ai-strategy-actions { display: flex; gap: 8px; margin-top: 10px; }
.btn-ai { background: var(--primary); color: #fff; }

/* HTML5 [hidden] attr is supposed to mean display:none, but class selectors (.modal-overlay /
   .bulk-action-bar) with display:flex have equal specificity and later position, so they win.
   Force !important to lock down hidden semantics globally — matches the spec. */
[hidden] { display: none !important; }

/* Duefy.confirm() custom modal — replaces the ugly native 'dev.duefy.ai says' confirm() dialog */
.duefy-confirm-overlay {
    position: fixed; inset: 0; z-index: 10000;
    background: rgba(17, 24, 39, .55);
    display: flex; align-items: center; justify-content: center;
    padding: 16px;
    animation: duefy-confirm-fade-in .12s ease-out;
}
.duefy-confirm-box {
    background: var(--bg-card); color: var(--text);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 20px 50px rgba(0,0,0,.25);
    width: 100%; max-width: 420px;
    padding: 24px 24px 20px;
    animation: duefy-confirm-pop-in .18s cubic-bezier(.34,1.56,.64,1);
}
.duefy-confirm-title {
    margin: 0 0 8px; font-size: 16px; font-weight: 700;
    color: var(--text);
}
.duefy-confirm-msg {
    font-size: 14px; line-height: 1.5; color: var(--text);
    margin-bottom: 20px;
    white-space: pre-wrap;  /* honor \n line breaks */
}
.duefy-confirm-actions {
    display: flex; justify-content: flex-end; gap: 8px;
}
/* Text-input modal (Duefy.prompt) — shares the confirm-box chrome. */
.duefy-prompt-field { margin: 0 0 20px; }
.duefy-prompt-input {
    width: 100%; min-height: 40px; padding: 9px 11px;
    border: 1px solid var(--border); border-radius: 8px;
    background: var(--bg-card); color: var(--text); font-size: 14px;
}
.duefy-prompt-input:focus { outline: none; border-color: var(--primary); }
textarea.duefy-prompt-input { resize: vertical; line-height: 1.5; }
@keyframes duefy-confirm-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes duefy-confirm-pop-in {
    from { opacity: 0; transform: translateY(-8px) scale(.97); }
    to   { opacity: 1; transform: translateY(0)    scale(1);   }
}

/* Secondary 'Switch trial plan' link next to the trial-banner primary CTA — grey small text, doesn't steal focus */
.trial-banner-secondary {
    margin-left: 12px;
    color: inherit; opacity: .75;
    font-size: 13px; text-decoration: underline; text-underline-offset: 2px;
}
.trial-banner-secondary:hover { opacity: 1; }

/* settings/billing 'Switch to other trial' card — outline button replaces the prior small link for better visibility */
.switch-trial-card {
    margin-top: 20px; padding: 16px 18px;
    background: var(--bg); border: 1px solid var(--border); border-radius: 10px;
    display: flex; align-items: center; gap: 16px;
    text-align: left;
}
.switch-trial-text { flex: 1; }
.switch-trial-text strong { display: block; margin-bottom: 4px; font-size: 14px; }
.switch-trial-text p { margin: 0; font-size: 13px; line-height: 1.5; }
.switch-trial-card .btn { flex-shrink: 0; }

/* Below the trial card: Solo "consider a lighter plan" hint — copy-only, low-key */
.switch-trial-solo-hint {
    margin-top: 12px; text-align: center;
    font-size: 13px; line-height: 1.5;
}

/* settings/billing redesign (a9c…): trial card uses a 3-block layout — hero + primary CTA + options */
.billing-trial-card { text-align: center; padding: 36px 32px 52px; }
/* Simple status states (grace / expired / broken sub) have nothing below them, so
   a full-width card leaves a short message stranded in big empty margins. Cap and
   center those. The trial state is NOT capped — it sits above the full-width SMS
   card, and matching widths reads cleaner. */
.billing-trial-card-compact { max-width: 620px; margin-left: auto; margin-right: auto; padding-bottom: 40px; }
.billing-trial-actions {
    margin-top: 24px;
    display: flex; flex-wrap: wrap; gap: 10px; justify-content: center;
}
/* trial-options grouping: two other trial plans + extension options on a grey background */
.billing-trial-options {
    margin: 24px auto 0; max-width: 520px;
    background: var(--bg-tertiary); border-radius: 10px;
    padding: 14px 18px; text-align: left;
    display: flex; flex-direction: column; gap: 8px;
}
.billing-trial-options-head {
    /* Sentence case, not all-caps — it's a full sentence, and a long uppercase
       string is harder to read than a short label. */
    font-size: 13px; font-weight: 600; color: var(--text);
    padding-bottom: 6px;
}
/* Plan rows: compact inline "Name — desc — $price" with the dashes kept; the
   name sits in a min-width box so the first dash lines up across rows, and the
   action (Switch / Current) is pushed to the right edge. */
.trial-plan-row {
    display: flex; align-items: center; gap: 8px;
    font-size: 13px; color: var(--text);
}
.trial-plan-row .icon-inline { color: var(--text-muted); flex-shrink: 0; }
.trial-plan-row-current .icon-inline { color: var(--primary); }
/* Desktop: name + price + blurb all on one line (price column-aligned via the
   name's min-width). Phones stack the blurb as a muted subline (see ≤560 below)
   so the row doesn't wrap awkwardly. */
.tpr-line { display: flex; flex-direction: row; align-items: baseline; flex-wrap: wrap; gap: 2px 12px; min-width: 0; }
.tpr-main { display: flex; align-items: baseline; gap: 10px; }
.tpr-name { min-width: 48px; font-weight: 700; color: var(--text); }
.tpr-price { font-weight: 700; color: var(--text); }
.tpr-desc { font-size: 13px; color: var(--text-muted); line-height: 1.3; }
@media (max-width: 560px) {
    .tpr-line { flex-direction: column; gap: 1px; }
    .tpr-desc { font-size: 12px; }
}
.tpr-action { margin-left: auto; white-space: nowrap; font-weight: 500; }
.tpr-action.trial-switch-btn { color: var(--primary); background: none; border: none; cursor: pointer; padding: 0; font: inherit; }
.tpr-action.trial-switch-btn:hover { text-decoration: underline; }
.tpr-current { color: var(--text-muted); font-weight: 600; }
.trial-option-row-extra {
    margin-top: 4px; padding-top: 10px;
    border-top: 1px solid var(--border);
}
.trial-option-row {
    display: flex; align-items: center; gap: 8px;
    font-size: 13px; color: var(--text);
}
.trial-option-row .icon-inline { color: var(--text-muted); flex-shrink: 0; }
.trial-option-row > span { color: var(--text-muted); }
/* The plan currently being trialed — subtle highlight + check icon, no Switch. */
.trial-option-row-current .icon-inline { color: var(--primary); }
.trial-current-tag { margin-left: auto; font-weight: 600; }
.trial-option-row > a,
.trial-option-row > .trial-switch-btn { margin-left: auto; color: var(--primary); font-weight: 500; }
.trial-option-row > a:hover,
.trial-option-row > .trial-switch-btn:hover { text-decoration: underline; }
/* Override .btn-link default (text-muted + underline) so the trial Switch button matches
   the sibling <a> link's color/weight; semantic <button> for a JS action, visual parity. */
.trial-switch-btn { padding: 0; font-size: inherit; text-decoration: none; }
/* Single-line extension link in grace state, centered */
.billing-trial-extension-link { margin-top: 12px; text-align: center; font-size: 13px; }

/* ---- AI email modal ---- */
.modal-overlay {
    position: fixed; inset: 0; background: rgba(17,24,39,.55);
    display: flex; justify-content: center;
    /* Center vertically to match the Duefy.confirm dialog (was flex-start/top,
       which looked inconsistent next to centered confirms). `safe center` keeps
       a taller-than-viewport modal from clipping at the top — it falls back to
       start alignment then, and the overlay scrolls. Plain `center` first for
       any engine without `safe`. */
    align-items: center;
    align-items: safe center;
    z-index: 1000; padding: 40px 16px; overflow-y: auto;
}
.modal-box {
    background: var(--bg-card); color: var(--text); border-radius: 12px; padding: 24px;
    width: 100%; max-width: 560px; position: relative;
    box-shadow: 0 20px 50px rgba(0,0,0,.25);
}
.modal-box h3 { margin: 0 0 16px; font-size: 18px; }
.modal-close {
    position: absolute; top: 12px; right: 14px; background: none; border: none;
    font-size: 24px; line-height: 1; color: var(--text-muted); cursor: pointer;
}
.modal-actions { display: flex; gap: 8px; margin-top: 16px; }
.ai-body-edit {
    border: 1px solid var(--border); border-radius: 8px; padding: 12px;
    min-height: 220px; max-height: 360px; overflow-y: auto;
    font-size: 14px; line-height: 1.6; background: var(--bg-card);
}
.ai-body-edit:focus { outline: 2px solid var(--primary); outline-offset: -1px; }
/* The global `* { margin:0 }` reset strips <p> spacing, so AI paragraphs render
   crammed together in the preview even though the email itself (rendered by the
   recipient's mail client) is spaced. Restore paragraph spacing so the preview
   is WYSIWYG. */
.ai-body-edit p { margin: 0 0 0.85em; }
.ai-body-edit p:last-child { margin-bottom: 0; }

/* ---- integrations ---- */
.int-section-title { font-size: 14px; color: var(--text-muted); margin: 22px 0 10px; text-transform: uppercase; letter-spacing: .04em; }
.int-section-title-inline { display: inline; margin: 0; }
.int-comingsoon { margin-top: 14px; }
.int-comingsoon > summary { cursor: pointer; list-style: none; padding: 6px 0; }
.int-comingsoon > summary::-webkit-details-marker { display: none; }
.int-comingsoon > summary::after {
    content: '▸'; display: inline-block; margin-left: 6px;
    color: var(--text-muted); transition: transform .15s;
}
.int-comingsoon[open] > summary::after { transform: rotate(90deg); }
.api-key-masked { letter-spacing: 1px; }

/* settings/billing utility classes */
.billing-center { text-align: center; }

/* settings/billing — trial / paid_but_no_sub / current plan banners */
.billing-trial-explain { max-width: 520px; margin: 8px auto 0; }
.billing-trial-explain-small { font-size: 13px; }
.billing-trial-actions { margin-top: 20px; }
.billing-support-link  { margin-left: 8px; }
.billing-current-h2    { margin-top: 14px; }
.billing-current-desc  { max-width: 480px; margin: 8px auto 0; }

/* settings/billing — Change plan modal (cp-* = change-plan) */
.modal-box-wide { max-width: 720px; }
.cp-step-pick-intro { margin-bottom: 16px; }
/* minmax(0, 1fr) so long plan names can't push the 3rd column past the modal edge */
.cp-plan-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.cp-plan-card {
    border: 1px solid var(--border); border-radius: 8px;
    padding: 14px; text-align: center;
}
.cp-plan-card.is-current { background: var(--bg-tertiary); }
.cp-plan-card-name   { font-weight: 700; margin-bottom: 4px; }
.cp-plan-card-price  { font-size: 20px; font-weight: 800; }
.cp-plan-card-period { font-size: 12px; font-weight: 400; color: var(--text-muted); }
.cp-plan-card-annual { font-size: 11px; margin-bottom: 10px; }
.cp-plan-card-btn    { width: 100%; }
.cp-preview-loading-box { text-align: center; padding: 24px; }

/* Change-plan preview table — wraps the prorated charge / next-charge breakdown.
   Built by renderUpgradePreview / renderDowngradePreview in JS; classes here are the
   sole source of style (previously inline). */
.cp-preview-h3       { margin-top: 0; }
.cp-preview-table    {
    margin: 16px 0; padding: 16px;
    border: 1px solid var(--border); border-radius: 8px;
}
.cp-preview-table-downgrade { background: var(--bg); }
.cp-row              { display: flex; justify-content: space-between; padding: 4px 0; }
.cp-row-total        {
    border-top: 1px solid var(--border);
    padding-top: 8px; margin-top: 8px;
}
.cp-row-total-amount { font-size: 18px; }
.cp-amount-success   { color: var(--success); }

/* settings/profile — delete-account confirmation panel (shown after Delete button click) */
.profile-delete-box { margin-top: 16px; }

/* settings/personal_data — stats / table / import panel layout */
.pdata-stat-row { display: flex; gap: 24px; margin: 16px 0; flex-wrap: wrap; }
.pdata-stat-num { font-size: 22px; }
.pdata-stat-warn { color: var(--warning); }
.pdata-section-head { display: flex; justify-content: space-between; align-items: center; }
.pdata-col-checkbox { width: 36px; }
.pdata-col-num      { text-align: right; }
.pdata-table tr.is-in-team { opacity: 0.55; }
.pdata-amount-warn  { color: var(--warning); font-weight: 600; }
.pdata-import-panel {
    margin-top: 16px; background: var(--bg);
    border-radius: 10px; padding: 16px;
}
.pdata-import-count   { margin: 10px 0; }
.pdata-import-actions { display: flex; gap: 10px; }
.billing-banner-icon { display: flex; justify-content: center; margin-bottom: 12px; color: var(--text-muted); }
.billing-banner-icon-warning { color: var(--status-warning-fg); }
.billing-banner-icon-danger  { color: var(--status-danger-fg); }
.billing-banner-icon-success { color: var(--status-success-fg); }
.billing-banner-icon-info    { color: var(--primary); }
/* Trial days-left countdown under the heading — escalates color as time runs out. */
.billing-trial-countdown { margin: 4px 0 0; font-size: 15px; color: var(--text); }
.billing-trial-countdown strong { font-weight: 700; }
.billing-trial-countdown-info    strong { color: var(--primary); }
.billing-trial-countdown-warning strong { color: var(--status-warning-fg); }
.billing-trial-countdown-danger  strong { color: var(--status-danger-fg); }
.upsell-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }
.upsell-head-title { color: var(--primary); display: inline-flex; align-items: center; gap: 6px; }
.upsell-head-price { font-size: 13px; }


/* settings/referrals */
.referral-how { margin: 16px 0; }
/* Breathing room between the "how it works" blurb and the link/action block. */
.referral-link-group { margin-top: 24px; }
.referral-link-row { display: flex; gap: 8px; }
.referral-link-row > input { flex: 1; }
.referral-share-row {
    display: flex; align-items: center; flex-wrap: wrap;
    gap: 8px;
    margin-top: 10px;
}
.referral-share-row > span { margin-right: 4px; }
.referral-balance {
    display: flex; gap: 32px;
    margin-top: 20px; padding-top: 18px;
    border-top: 1px solid var(--border);
}
.ref-bal-num { font-size: 24px; }
/* Referrals + credits-history tables (.data-table is a hollow base class), given
   their own breathing room: full width so columns spread across the card instead
   of clustering on the left, comfortable cell padding, and quiet row separators. */
.ref-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.ref-table th,
.ref-table td { padding: 12px 14px; text-align: left; vertical-align: middle; border-bottom: 1px solid var(--border); }
.ref-table thead th {
    font-size: 12px; font-weight: 600; color: var(--text-muted);
    text-transform: uppercase; letter-spacing: .03em;
    border-bottom: 1px solid var(--border);
}
.ref-table tbody tr:last-child td { border-bottom: 0; }

/* settings/billing Credits & Activity section */
.billing-credits-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 12px; }
.billing-credits-head h2 { margin: 0; }
.billing-credits-summary { display: flex; flex-wrap: wrap; gap: 32px; align-items: center; padding: 14px 16px; background: var(--bg-tertiary); border-radius: 8px; margin-bottom: 16px; }
.billing-credits-note {
    display: inline-flex; align-items: center; gap: 6px;
    color: var(--status-success-fg); background: var(--status-success-bg);
    padding: 6px 12px; border-radius: 6px; font-size: 13px;
    margin-left: auto;
}
.billing-credits-h3 { margin: 8px 0 8px; font-size: 14px; color: var(--text-muted); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.billing-credits-table { font-size: 13px; }
.billing-credits-foot { margin-top: 10px; text-align: right; }
.credit-amount-pos { color: var(--success); font-weight: 700; }
.credit-amount-neg { color: var(--danger); font-weight: 700; }

/* settings/cancel_flow */
.cancel-detail-textarea {
    width: 100%; margin-top: 16px; padding: 12px;
    border: 1px solid var(--border); border-radius: 8px;
    background: var(--bg-card); color: var(--text);
    font: inherit;
}
.cancel-step-hidden { display: none; }
.cancel-confirm-block { margin-top: 32px; border-top: 1px solid var(--border); padding-top: 24px; display: flex; align-items: center; gap: 14px; }
.cancel-confirm-btn { color: var(--danger); border-color: var(--danger); }
.cancel-goodbye { text-align: center; padding: 40px; }
.cancel-goodbye-emoji { font-size: 48px; margin-bottom: 16px; }
.cancel-goodbye-link { font-size: 14px; }

/* settings/personal_data */
.pdata-migrate-cta {
    background: var(--accent-light); border-radius: 10px;
    padding: 16px; margin-top: 8px;
    display: flex; justify-content: space-between; align-items: center; gap: 16px;
}
.pdata-migrate-title { display: inline-flex; align-items: center; gap: 6px; }
.pdata-warn-icon { color: var(--status-warning-fg); vertical-align: middle; }
.pdata-in-team-mark { color: var(--text-muted); display: inline-flex; }

/* generic: form-group takes the remaining flex space in a row */
.form-group-grow { flex: 1; }

/* settings/automation — escalation senders sub-section heading */
.esc-sender-h4 { margin: 18px 0 8px; font-size: 14px; font-weight: 600; color: var(--text); }
.esc-sender-h4:first-of-type { margin-top: 12px; }
/* Escalation senders are <fieldset>/<legend> for grouping semantics; strip the
   default fieldset chrome so they render exactly like the old <h4> + rows. */
.esc-sender-group { border: 0; margin: 0; padding: 0; min-inline-size: 0; }
.esc-sender-group > legend.esc-sender-h4 { padding: 0; float: none; }
/* legend is :first-of-type within each fieldset, so restore the larger gap
   above the second sender group (matches the old sibling-<h4> spacing). */
.esc-sender-group + .esc-sender-group > legend.esc-sender-h4 { margin-top: 18px; }

/* settings/two_factor */
.tfa-backup-codes { margin-top: 24px; }
.tfa-backup-codes h4 { margin: 0 0 6px; font-size: 15px; }
.tfa-backup-codes > p { margin: 0 0 14px; line-height: 1.55; }
.tfa-qr-area { /* the hidden attribute already implies display:none */ }
.tfa-qr-img {
    display: block; width: 240px; height: 240px;
    border: 1px solid var(--border); border-radius: 8px; padding: 8px;
    background: #fff;                                /* keep QR scannable in dark mode */
}
.tfa-qr-manual { margin-top: 8px; }
.tfa-code-input {
    display: block; margin: 10px 0;
    font-family: monospace; font-size: 20px;
    letter-spacing: 6px; text-align: center;
    width: 100%; padding: 10px 12px;
    border: 1px solid var(--border); border-radius: 8px;
    background: var(--bg-card); color: var(--text);
}

/* Copy button next to the manual setup key */
.tfa-copy-secret {
    display: inline-flex; align-items: center; justify-content: center;
    margin-left: 4px; padding: 2px 4px;
    border: none; background: none; cursor: pointer;
    color: var(--text-muted); border-radius: 4px; vertical-align: middle;
}
.tfa-copy-secret:hover { color: var(--primary); background: var(--bg); }

/* settings/email_domain */
.ed-replyto-note {
    margin-top: 8px;
    max-width: 760px;
    font-size: 14px;
}
.ed-alert { margin: 16px 0; }
.ed-lowercase { text-transform: lowercase; }

.ed-add-section {
    border-top: 1px solid var(--border);
    margin-top: 18px;
    padding-top: 18px;
}
.ed-from-name-group {
    max-width: none;
    margin-bottom: 14px;
}
.ed-from-name-card {
    margin: 16px 0 18px;
    padding: 14px 16px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-tertiary);
}
.ed-from-name-card label {
    margin-bottom: 8px;
}
.ed-from-name-save-row {
    display: flex;
    align-items: center;
    gap: 8px;
    max-width: 560px;
}
.ed-from-name-save-row input {
    flex: 1 1 auto;
    min-width: 0;
}
.ed-from-name-save-row .btn {
    flex-shrink: 0;
}
.ed-from-name-card p {
    margin: 8px 0 0;
}
/* Generic inline alert. The .alert/.alert-warning/.alert-warn classes were
   used by settings/email_domain and integrations/pick_org but never styled —
   the warnings rendered as bare text. */
.alert {
    padding: 10px 14px;
    border: 1px solid var(--border);
    border-radius: 8px;
    margin: 0 0 14px;
    background: var(--bg-tertiary);
    color: var(--text);
    font-size: 13.5px;
    line-height: 1.45;
}
.alert-warning, .alert-warn {
    background: var(--status-warning-bg);
    color: var(--status-warning-fg);
    border-color: color-mix(in srgb, var(--status-warning-fg) 30%, transparent);
}

.ed-setup-steps {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 10px;
    margin-bottom: 18px;
}
.ed-setup-step {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    padding: 8px 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-tertiary);
    color: var(--text-muted);
    font-size: 12.5px;
    font-weight: 600;
}
.ed-setup-step.is-active {
    background: var(--accent-light);
    border-color: var(--accent-border);
    color: var(--text);
}
.ed-setup-step-index {
    width: 18px;
    height: 18px;
    flex: 0 0 18px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--bg-card);
    border: 1px solid var(--border);
    color: var(--text-muted);
    font-size: 10.5px;
    font-weight: 700;
}
.ed-setup-step.is-active .ed-setup-step-index {
    background: var(--primary);
    border-color: var(--primary);
    color: #fff;
}
/* Completed step: neutral pill, green check — enough signal without
   over-coloring the row (status tokens stay readable in dark mode). */
.ed-setup-step.is-done .ed-setup-step-index {
    background: var(--status-success-bg);
    border-color: var(--status-success-fg);
    color: var(--status-success-fg);
}
.ed-sender-composer {
    padding: 16px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg);
}
.ed-sender-composer input {
    background: var(--bg-card);
}
.ed-email-compose {
    display: grid;
    grid-template-columns: minmax(160px, .9fr) 36px minmax(220px, 1.1fr);
    column-gap: 8px;
    row-gap: 6px;
    align-items: center;
}
.ed-email-compose .ed-field-label {
    margin: 0;
    font-weight: 600;
    color: var(--text);
    line-height: 1.25;
}
.ed-mailbox-label { grid-column: 1; grid-row: 1; }
.ed-mailbox-input { grid-column: 1; grid-row: 2; }
.ed-mailbox-error { grid-column: 1; grid-row: 3; }
.ed-domain-label { grid-column: 3; grid-row: 1; }
.ed-domain-input { grid-column: 3; grid-row: 2; }
.ed-domain-error { grid-column: 3; grid-row: 3; }
.ed-at-sep {
    grid-column: 2;
    grid-row: 2;
    align-self: center;
    width: 36px;
    height: 38px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-tertiary);
    color: var(--text-muted);
    font-weight: 600;
    line-height: 1;
}
.ed-preview-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
}
.ed-preview-row .btn { flex-shrink: 0; }
.ed-field-error { display: block; }
.ed-sender-preview {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    color: var(--text-muted);
    font-size: 13px;
}
.ed-sender-preview-label {
    flex: 0 0 auto;
}
/* Read-only chip: tinted + borderless so it can't be mistaken for an input
   (the white+border treatment next to real fields read as editable). */
.ed-sender-preview-pill {
    display: inline-flex;
    align-items: center;
    max-width: 100%;
    min-width: 0;
    padding: 4px 10px;
    border-radius: 999px;
    background: var(--bg-tertiary);
    color: var(--text);
    font-weight: 600;
    font-size: 13px;
    overflow-wrap: anywhere;
}

@media (max-width: 720px) {
    .ed-setup-steps { grid-template-columns: 1fr; }
    .ed-sender-composer {
        padding: 14px;
    }
    .ed-from-name-save-row {
        display: block;
    }
    .ed-from-name-save-row .btn {
        width: 100%;
        margin-top: 8px;
    }
    .ed-email-compose,
    .ed-preview-row {
        display: block;
    }
    .ed-email-compose .ed-field-label { display: block; margin-bottom: 6px; }
    .ed-email-compose input { margin-bottom: 10px; }
    .ed-email-compose .ed-field-error:not([hidden]) { display: block; margin-top: -6px; margin-bottom: 10px; }
    .ed-at-sep { display: none; }
    .ed-sender-preview {
        display: block;
        margin-bottom: 12px;
    }
    .ed-sender-preview-pill {
        margin-top: 6px;
        width: 100%;
        border-radius: 8px;
    }
    .ed-preview-row .btn { width: 100%; }
}

.ed-pending-block { margin-top: 16px; }
.ed-pending-row {
    display: flex; justify-content: space-between; align-items: center;
    margin-bottom: 8px;
}
.ed-pending-badge { margin-left: 8px; display: inline-flex; align-items: center; gap: 4px; }

.ed-records-wrap {
    overflow-x: auto; margin-top: 12px;
    border: 1px solid var(--border); border-radius: 8px;
}
.ed-records-table {
    width: 100%; border-collapse: collapse;
    font-size: 13px;
}
.ed-records-table thead { background: var(--bg); }
.ed-records-table th,
.ed-records-table td { text-align: left; padding: 11px 14px; vertical-align: top; }
.ed-records-table thead th {
    border-bottom: 1px solid var(--border);
    font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); font-weight: 600;
}
.ed-records-table tbody tr + tr td { border-top: 1px solid var(--bg-tertiary); }
/* Only the actual DNS tokens (Host + Value) are monospace; Type / status / TTL stay
   in the UI font so the table doesn't read as a wall of mono text. */
.ed-records-table code { font-family: ui-monospace, Menlo, monospace; font-size: 12.5px; }
.ed-records-table td:first-child strong { font-weight: 700; }
.ed-records-sub { font-size: 11px; margin-top: 3px; }
.ed-records-value { max-width: 460px; }
.ed-records-value code {
    display: inline-block; word-break: break-all; line-height: 1.55;
    background: var(--bg-tertiary); border-radius: 6px; padding: 4px 8px;
}
.ed-records-value-actions { margin-top: 8px; }
.ed-records-table td[data-label="TTL"] { color: var(--text-muted); }

/* Narrow screens: a 5-column DNS table overflows. Stack each record as a
   labelled card (UX audit P2) instead of forcing horizontal scroll. */
@media (max-width: 640px) {
    .ed-records-wrap { overflow-x: visible; border: 0; border-radius: 0; }
    .ed-records-table thead { position: absolute; left: -9999px; }
    .ed-records-table, .ed-records-table tbody, .ed-records-table tr, .ed-records-table td { display: block; width: auto; }
    .ed-records-table tr {
        border: 1px solid var(--border); border-radius: 8px;
        padding: 4px 0; margin-bottom: 10px;
    }
    .ed-records-table tbody tr + tr td { border-top: 0; }
    .ed-records-table td { padding: 6px 12px; }
    .ed-records-table td[data-label]::before {
        content: attr(data-label) "  ";
        display: block;
        font-size: 10px; text-transform: uppercase; letter-spacing: 0.04em;
        color: var(--text-muted); margin-bottom: 2px;
    }
    .ed-records-value { max-width: none; }
    .ed-records-copy .btn { width: 100%; }
}

.ed-empty-records { font-style: italic; }
/* Top-align so a multi-line "still waiting" list lines up with the button's
   top edge instead of centering the button against a tall block. */
.ed-verify-row { display: flex; gap: 12px; margin-top: 16px; align-items: flex-start; }
/* The pending message can be long — let it shrink, never the button
   (otherwise "Verify again in Ns" wraps to two lines). */
.ed-verify-row .btn { flex: 0 0 auto; white-space: nowrap; }
.ed-verify-row #verify-status { flex: 1 1 auto; min-width: 0; align-self: center; }
/* When the checklist renders, it's taller than the button — switch the span
   back to top alignment so its first row sits level with the button. */
.ed-verify-row #verify-status:has(.ed-rec-checklist) { align-self: flex-start; }
#verify-status .ed-waiting-progress {
    display: inline-block; margin-bottom: 6px; padding: 2px 8px;
    border-radius: 999px; font-size: 11.5px; font-weight: 600;
    background: var(--bg-tertiary); color: var(--text);
}
#verify-status .ed-rec-checklist { list-style: none; margin: 4px 0 6px; padding: 0; }
#verify-status .ed-rec-checklist li {
    display: flex; align-items: flex-start; gap: 8px; margin: 1px 0;
}
#verify-status .ed-rec-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
#verify-status .ed-rec-line { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
#verify-status .ed-rec-checklist code {
    font-family: ui-monospace, Menlo, monospace; font-size: 12px;
}
#verify-status .ed-rec-checklist li.is-done code { color: var(--text-muted); }
#verify-status .ed-rec-tag {
    font-size: 10px; font-weight: 600; letter-spacing: .02em; text-transform: uppercase;
    padding: 1px 6px; border-radius: 999px;
    background: var(--status-warning-bg); color: var(--warning-strong, #b45309);
}
#verify-status .ed-rec-diag {
    font-size: 11.5px; line-height: 1.4; color: var(--warning-strong, #b45309);
}
#verify-status .ed-rec-check {
    flex: 0 0 auto; width: 15px; height: 15px; margin-top: 1px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 10px; line-height: 1; font-weight: 700;
    border: 1.5px solid var(--border); color: transparent;
}
#verify-status .ed-rec-checklist li.is-done .ed-rec-check {
    background: var(--success); border-color: var(--success); color: #fff;
}
#verify-status .ed-rec-checklist li.is-detected .ed-rec-check {
    background: var(--warning-strong, #b45309); border-color: var(--warning-strong, #b45309); color: #fff;
}
#verify-status .ed-rec-checklist li.is-fail .ed-rec-check {
    background: var(--danger); border-color: var(--danger); color: #fff;
}
#verify-status .ed-waiting-hint { display: block; margin-top: 4px; }
.ed-state3-box {
    background: var(--status-success-bg); border: 1px solid var(--success);
    border-radius: 8px; padding: 20px; margin-top: 16px;
    color: var(--status-success-fg);
}
.ed-state3-header { display: flex; justify-content: space-between; align-items: flex-start; }
.ed-state3-icon { color: var(--success); }
.ed-state3-title { margin: 8px 0 4px; }
.ed-state3-meta { margin: 0; }

/* Brand-attribution toggle — sits below the verified-state card on /settings/emailDomain/. */
.ed-attribution-row {
    margin-top: 18px; padding: 14px 16px;
    background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px;
}
.ed-attribution-control {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; flex-wrap: wrap;
}
.ed-attribution-toggle {
    display: flex; align-items: center; gap: 10px;
    font-weight: 600; cursor: pointer;
}
.ed-attribution-toggle input[type="checkbox"] {
    width: auto; flex-shrink: 0;
}
.ed-attribution-preview {
    position: relative;
    display: inline-flex;
    flex-shrink: 0;
}
.ed-attribution-preview-trigger {
    gap: 6px;
}
.ed-attribution-popover {
    position: absolute;
    right: 0;
    top: calc(100% + 8px);
    z-index: 30;
    width: min(320px, calc(100vw - 32px));
    padding: 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-card);
    color: var(--text);
    box-shadow: var(--shadow);
    opacity: 0;
    transform: translateY(-4px);
    pointer-events: none;
    transition: opacity .12s ease, transform .12s ease;
}
.ed-attribution-preview:hover .ed-attribution-popover,
.ed-attribution-preview:focus-within .ed-attribution-popover,
.ed-attribution-preview.is-open .ed-attribution-popover {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}
.ed-attribution-popover-label {
    display: block;
    margin-bottom: 8px;
    font-size: 11px;
    font-weight: 700;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: .04em;
}
.ed-footer-preview-card {
    display: block;
    padding: 14px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg);
}
.ed-footer-preview-rule {
    display: block;
    width: 100%;
    height: 1px;
    margin-bottom: 12px;
    background: var(--border);
}
.ed-footer-preview-brand {
    display: block;
    font-size: 13px;
    font-weight: 700;
    color: var(--text);
}
.ed-footer-preview-copy {
    display: block;
    margin-top: 3px;
    font-size: 12px;
    color: var(--text-muted);
}
.ed-attribution-help { margin: 8px 0 0; }
@media (max-width: 640px) {
    .ed-attribution-control {
        align-items: flex-start;
    }
    .ed-attribution-preview {
        display: block;
        width: 100%;
    }
    .ed-attribution-popover {
        position: static;
        display: none;
        width: 100%;
        margin-top: 8px;
        opacity: 1;
        transform: none;
        pointer-events: auto;
    }
    .ed-attribution-preview:hover .ed-attribution-popover,
    .ed-attribution-preview:focus-within .ed-attribution-popover,
    .ed-attribution-preview.is-open .ed-attribution-popover {
        display: block;
    }
}
/* Provider directory: a responsive 2-up grid instead of one long thin column —
   denser and more scannable for a list of logos. auto-fill collapses to 1 column
   when the container is narrow (covers mobile + the /settings/integrations/ panel). */
.integration-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    column-gap: 28px;
}
.integration-item {
    display: flex; align-items: center; gap: 14px;
    padding: 14px 0; border-bottom: 1px solid var(--border);
}
.integration-logo {
    width: 44px; height: 44px; border-radius: 9px;
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0; overflow: hidden;
    /* Official brand icons sit on a neutral tile: full-bleed icons (Xero/Harvest)
       fill it and get rounded by overflow:hidden; mark-on-transparent icons
       (QuickBooks/Square) show against white with a hairline edge. */
    background: #fff; border: 1px solid var(--border);
}
.integration-logo img { width: 100%; height: 100%; object-fit: contain; }
.integration-logo-zap { background: var(--accent-light); color: var(--primary); }
.int-comingsoon-note  { margin: 10px 0 14px; }
.int-zap-note         { margin: 8px 0 0; }
/* The Zapier block carries a tall expandable guide — pin its icon to the top
   (next to the title) instead of vertically centering it mid-content. */
.integration-item-zap { align-items: flex-start; }
/* Setup guide: make the toggle an obvious clickable control (was tiny grey text)
   and give the expanded content room so it doesn't read as a cramped wall. */
.int-zap-guide { margin-top: 10px; }
.int-zap-guide > summary {
    cursor: pointer; list-style: none;
    color: var(--primary); font-weight: 600; font-size: 13px;
    display: inline-flex; align-items: center; gap: 6px;
}
.int-zap-guide > summary::-webkit-details-marker { display: none; }
.int-zap-guide > summary::before { content: "▸"; font-size: 11px; transition: transform .15s; }
.int-zap-guide[open] > summary::before { transform: rotate(90deg); }
/* Separate the expanded guide from the toggle with a hairline above it. */
.int-zap-guide-body { border-top: 1px solid var(--border); margin-top: 10px; padding-top: 12px; }
.int-zap-guide ol { margin: 0 0 10px; padding-left: 20px; }
.int-zap-guide ol li { margin: 5px 0; }
.integration-info { flex: 1; min-width: 0; }
.integration-info strong { color: var(--text); }
.integration-info p { font-size: 13px; margin: 2px 0; }
.integration-status.connected { color: var(--status-success-fg); font-size: 13px; font-weight: 600; margin-right: 8px; }
.integration-info > .muted.small { white-space: nowrap; }
.integration-actions { display: flex; gap: 8px; flex-shrink: 0; flex-wrap: wrap; justify-content: flex-end; }
/* Phones: the nowrap meta + unshrinkable actions pushed rows past the viewport.
   Wrap the buttons onto their own line, aligned with the text column. */
@media (max-width: 540px) {
    .integration-item { flex-wrap: wrap; }
    .integration-info > .muted.small { white-space: normal; }
    .integration-actions {
        /* full row minus the indent — a plain 100% basis plus the margin
           overflowed the viewport by exactly the margin */
        flex-basis: calc(100% - 58px);
        justify-content: flex-start;
        margin-left: 58px;   /* logo 44px + 14px gap — line up under the text */
    }
}
/* "Connect" stays a calm outline at rest (8 in a column shouldn't be a wall of
   purple) but fills on hover, so the primary per-row action still reads clickable. */
.btn-outline.btn-connect { transition: background .15s, border-color .15s, color .15s; }
.btn-outline.btn-connect:hover { background: var(--primary); border-color: var(--primary); color: #fff; }
.integration-item-soon { opacity: .65; }
.badge-coming-soon { background: var(--status-warning-bg); color: var(--status-warning-fg); }

/* Multi-org picker (Zoho / Wave / Sage / MYOB post-OAuth switch) */
.pick-org-list { display: flex; flex-direction: column; gap: 8px; margin: 16px 0 24px; }
.pick-org-row {
    display: flex; align-items: center; gap: 12px;
    padding: 12px 14px; border: 1px solid var(--border);
    border-radius: 8px; cursor: pointer; transition: background .12s;
}
.pick-org-row:hover { background: var(--bg-tertiary); }
.pick-org-row.is-current { border-color: var(--primary); background: var(--accent-light); }
.pick-org-row input[type="radio"] { width: auto; margin: 0; flex-shrink: 0; }
.pick-org-info { flex: 1; display: flex; flex-direction: column; }
.pick-org-info strong { color: var(--text); font-size: 14px; }
.badge-current {
    background: var(--primary); color: #fff;
    font-size: 11px; padding: 3px 8px; border-radius: 4px; font-weight: 600;
}
.webhook-url-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin: 8px 0; }
.webhook-url-row code {
    background: var(--bg); padding: 8px 12px; border-radius: 7px;
    font-size: 12px; word-break: break-all; flex: 1; min-width: 200px;
}

/* ===== Migration page ===== */
.migrate-page { max-width: 1080px; margin: 0 auto; padding: 64px 24px; }
.migrate-hero, .migrate-source-hero { text-align: center; margin-bottom: 48px; }
.migrate-hero h1, .migrate-source-hero h1 {
    font-size: 42px; font-weight: 800; color: var(--text);
    margin: 0 auto 16px; max-width: 760px;
    letter-spacing: -0.02em; line-height: 1.15;
}
.migrate-hero p, .migrate-source-hero p {
    font-size: 17px; color: var(--text-muted);
    max-width: 640px; margin: 0 auto 10px; line-height: 1.55;
}
.migrate-hero p + p, .migrate-source-hero p + p { margin-top: 6px; }

.migrate-section { margin-bottom: 48px; }
.migrate-section h2 { font-size: 22px; font-weight: 700; margin-bottom: 16px; }

/* Source cards */
.migrate-api-grid, .migrate-csv-grid {
    display: grid; gap: 16px; margin-top: 16px;
}
.migrate-api-grid, .migrate-csv-grid { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 900px) { .migrate-api-grid, .migrate-csv-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .migrate-api-grid, .migrate-csv-grid { grid-template-columns: 1fr; } }

.migrate-source-card {
    border: 1px solid var(--border); border-radius: 12px; padding: 20px;
    text-decoration: none; color: var(--text); transition: border-color 0.2s, box-shadow 0.2s;
    display: flex; flex-direction: column; align-items: center; text-align: center;
}
.migrate-source-card:hover { border-color: var(--primary); box-shadow: 0 4px 12px rgba(79,70,229,0.15); }
/* API cards: a softer green cue (1px) for "auto-import" — no heavy 2px border. */
.migrate-card-api { border-color: var(--success); }
/* Brand logo tile — real icon on a neutral white tile (legible in dark mode too). */
.migrate-source-logo {
    width: 48px; height: 48px; margin-bottom: 10px; border-radius: 10px;
    display: flex; align-items: center; justify-content: center; overflow: hidden;
    background: #fff; border: 1px solid var(--border);
}
.migrate-source-logo img { width: 100%; height: 100%; object-fit: contain; }
.migrate-source-name { font-weight: 700; font-size: 16px; }
.migrate-source-desc { font-size: 13px; color: var(--text-muted); margin-top: 4px; }
.migrate-badge { background: var(--accent-light); color: var(--primary); padding: 2px 8px; border-radius: 10px; font-size: 12px; margin-top: 8px; }
.migrate-badge-easy { background: var(--status-success-bg); color: var(--status-success-fg); }

/* Comparison table */
.migrate-compare { display: flex; gap: 16px; align-items: center; margin: 24px 0; }
.migrate-compare-item { flex: 1; border: 2px solid var(--border); border-radius: 12px; padding: 20px; }
.migrate-compare-new  { border-color: var(--primary); background: var(--accent-light); }
.migrate-compare-brand { font-weight: 800; font-size: 18px; margin-bottom: 8px; }
.migrate-compare-price { font-size: 28px; font-weight: 800; color: var(--primary); margin-bottom: 12px; }
.migrate-compare-features { display: flex; flex-direction: column; gap: 6px; font-size: 14px; }
.migrate-compare-arrow { font-size: 32px; color: var(--primary); flex-shrink: 0; }

/* Upload area / connect card */
.migrate-import-box {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: 36px 40px;
    margin: 0 auto 40px;
    max-width: 720px;
    box-shadow: 0 4px 16px rgba(17, 24, 39, .04);
}
.migrate-api-connect { text-align: center; }
.migrate-api-connect h2 {
    font-size: 22px; font-weight: 700;
    color: var(--text); margin-bottom: 6px;
}
.migrate-api-connect > p {
    color: var(--text-muted); font-size: 14px;
    margin-bottom: 22px;
}
.migrate-api-connect .btn { margin-bottom: 12px; }
.migrate-api-connect .text-muted { font-size: 13px; }
.migrate-what-imports {
    margin-top: 28px;
    text-align: left;
    border-top: 1px solid var(--border);
    padding-top: 22px;
}
.migrate-what-imports h3 {
    font-size: 14px; font-weight: 600;
    color: var(--text); margin-bottom: 12px;
    text-transform: uppercase; letter-spacing: 0.4px;
}
.migrate-what-imports ul {
    list-style: none; padding: 0; margin: 0;
    display: flex; flex-direction: column; gap: 8px;
}
.migrate-what-imports li {
    display: flex; align-items: center; gap: 8px;
    font-size: 14px; color: var(--text);
    padding-left: 0;
}
.migrate-dropzone {
    border: 2px dashed var(--border); border-radius: 12px; padding: 40px;
    text-align: center; cursor: pointer; transition: all 0.2s; background: var(--bg-card);
}
.migrate-dropzone:hover, .migrate-dropzone.drag-over {
    border-color: var(--primary); background: var(--accent-light);
}
.migrate-dropzone-icon { font-size: 48px; margin-bottom: 12px; }

/* Preview */
.migrate-stats { display: flex; gap: 24px; margin: 16px 0; }
.migrate-stat { background: var(--bg-card); border-radius: 8px; padding: 12px 16px; font-size: 14px; }
.migrate-stat strong { display: block; font-size: 24px; color: var(--text); }
.migrate-stat-green strong { color: var(--status-success-fg); }
.migrate-stat-blue strong  { color: var(--status-info-fg); }
/* Preview table wraps in a horizontally-scrollable container so wide CSV exports
   (10+ columns like contact / email / phone / invoice / amount / date / status / notes)
   don't bust out of the .migrate-import-box card boundary. */
.migrate-table-wrap {
    overflow-x: auto;
    margin: 0 -8px;
    padding: 0 8px 6px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-card);
}
.migrate-preview-table {
    width: 100%; min-width: 720px;
    border-collapse: collapse; font-size: 13px;
}
.migrate-preview-table th {
    background: var(--bg-tertiary); padding: 8px 12px;
    text-align: left; white-space: nowrap; font-weight: 600;
    position: sticky; top: 0;
}
.migrate-preview-table td {
    padding: 8px 12px; border-bottom: 1px solid #F3F4F6;
    white-space: nowrap; max-width: 220px;
    overflow: hidden; text-overflow: ellipsis;
}
.migrate-warning { background: var(--status-warning-bg); border-left: 4px solid var(--warning); padding: 12px 16px; border-radius: 0 8px 8px 0; margin: 16px 0; font-size: 14px; }

/* Post-preview action area: primary CTA + secondary "Upload Different File" on
   one row, with the 30-day trial note as a single small line below — keeps
   the buttons from squeezing the helper copy between them. */
.migrate-actions { margin-top: 20px; }
.migrate-actions-row { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.migrate-actions-note {
    margin: 12px 0 0; font-size: 13px; color: var(--text-muted);
    display: flex; align-items: center; gap: 6px;
}

/* Export guide */
.migrate-export-guide { background: var(--bg-card); border-radius: 8px; padding: 16px 20px; margin-bottom: 24px; border: 1px solid var(--border); }
.migrate-export-guide h3 { font-size: 16px; margin-bottom: 10px; }
.migrate-export-guide ol { margin: 0; padding-left: 20px; font-size: 14px; line-height: 2; }

/* Privacy note shown beneath the upload zone — reassures anon visitors that files
   are temporary and not associated with any account (matches cron/cleanMigrateUploads.php
   policy of 60-min retention). */
.migrate-upload-privacy {
    margin-top: 18px;
    padding: 10px 14px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 12.5px;
    color: var(--text-muted);
    line-height: 1.5;
    text-align: center;
    display: flex; align-items: center; justify-content: center; gap: 6px;
    flex-wrap: wrap;
}
.migrate-upload-privacy strong { color: var(--text); font-weight: 600; }

/* Guarantee block — softer styling: accent-tint bg, neutral text, only checks stay green */
.migrate-guarantee {
    text-align: center;
    padding: 32px 32px 24px;
    background: var(--accent-light);
    border: 1px solid var(--accent-border);
    border-radius: 12px;
    margin: 0 auto 48px;
    max-width: 720px;
}
.migrate-guarantee h3 {
    font-size: 18px; font-weight: 700;
    color: var(--text); margin-bottom: 8px;
}
.migrate-guarantee > p {
    color: var(--text); font-size: 14px;
    margin: 0 auto 20px; max-width: 540px; line-height: 1.55;
}
.migrate-guarantee-grid {
    display: grid; grid-template-columns: repeat(3, 1fr);
    gap: 10px 18px;
    margin-top: 8px; padding-top: 18px;
    border-top: 1px solid var(--accent-border);
    font-size: 13.5px; color: var(--text);
    text-align: left;
}
.migrate-guarantee-grid > div {
    display: flex; align-items: center; gap: 6px;
}

/* FAQ — use the same .faq pattern as /pricing/ instead of basic migrate-faq */
.migrate-faq { margin: 0 auto 40px; max-width: 720px; }
.migrate-faq h2 {
    font-size: 22px; font-weight: 700;
    margin-bottom: 18px; text-align: center;
}
.migrate-faq details {
    background: #FAFBFD;
    border: 1px solid var(--border);
    border-radius: 11px;
    padding: 16px 20px;
    margin-bottom: 10px;
    transition: background .18s ease, border-color .18s ease;
}
.migrate-faq details[open] {
    background: #fff;
    border-color: var(--primary-soft, #C7D2FE);
}
.migrate-faq summary {
    cursor: pointer; font-weight: 600;
    font-size: 15px; color: var(--text);
    list-style: none;
}
.migrate-faq summary::-webkit-details-marker { display: none; }
.migrate-faq summary::after {
    content: "+"; float: right;
    color: var(--primary); font-size: 20px;
    line-height: 1;
}
.migrate-faq details[open] summary::after { content: "−"; }
.migrate-faq details p {
    margin-top: 12px; padding: 0;
    color: var(--text-muted); font-size: 14px; line-height: 1.6;
}

/* Migration success banner */
.migration-success-banner {
    background: linear-gradient(135deg, var(--primary), #7C3AED);
    color: #fff; border-radius: 12px; padding: 20px 24px;
    display: flex; align-items: center; gap: 16px; margin-bottom: 24px;
}
.migration-success-icon { font-size: 32px; flex-shrink: 0; }
.migration-success-content { flex: 1; }
.migration-success-content strong { display: block; font-size: 16px; margin-bottom: 4px; }
.migration-bonus { display: block; margin-top: 6px; font-size: 13px; opacity: 0.9; }

/* Landing-page migration entry point */
.migrate-cta-section {
    max-width: 900px; margin: 0 auto; padding: 48px 24px; text-align: center;
}
.migrate-cta-section h2 { font-size: 22px; font-weight: 700; color: var(--text); margin-bottom: 8px; }
.migrate-cta-section p { font-size: 16px; color: var(--text-muted); margin-bottom: 24px; }
.migrate-cta-grid {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 12px; max-width: 720px; margin: 0 auto;
}
.migrate-cta-grid a {
    border: 1px solid var(--border); border-radius: 10px; padding: 14px 18px;
    text-decoration: none; color: var(--primary); font-weight: 600; font-size: 14px;
    background: var(--bg-card); transition: all 0.2s;
}
.migrate-cta-grid a:hover {
    border-color: var(--primary); background: var(--accent-light); box-shadow: 0 4px 12px rgba(79,70,229,0.15);
}

/* Migration-history empty state */
.migrate-history-empty { text-align: center; padding: 32px; color: var(--text-muted); }
.migrate-history-empty p { margin-bottom: 16px; }

/* Responsive */
@media (max-width: 768px) {
    .migrate-api-grid { grid-template-columns: 1fr; }
    .migrate-compare   { flex-direction: column; }
    .migrate-compare-arrow { transform: rotate(90deg); }
    .migrate-guarantee-grid { grid-template-columns: 1fr 1fr; }
    .migrate-stats      { flex-direction: column; }
}

/* ========================================================================
   Migration lifecycle — added for migration lifecycle feature
   ======================================================================== */

/* --- Text & badge helpers --- */
.text-warning { color: var(--status-warning-fg); }
.text-muted   { color: var(--text-muted); }

.badge-danger,
.badge-warning,
.badge-info {
    display: inline-block;
    padding: 2px 8px;
    font-size: 12px;
    font-weight: 600;
    border-radius: 8px;
    line-height: 1.6;
}
.badge-danger  { background: var(--status-danger-bg); color: var(--status-danger-fg); }
.badge-warning { background: var(--status-warning-bg); color: var(--status-warning-fg); }
.badge-info    { background: var(--status-info-bg); color: var(--status-info-fg); }
.badge-success { background: var(--status-success-bg); color: var(--status-success-fg); }

/* --- Dual upload (Chaser) --- */
.migrate-dual-upload {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
    margin-top: 8px;
}
.migrate-upload-col label {
    display: block;
    font-size: 14px;
    font-weight: 600;
    color: #374151;
    margin-bottom: 8px;
}
.migrate-dropzone-sm {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 120px;
    padding: 20px;
    text-align: center;
    border: 2px dashed var(--border);
    border-radius: 12px;
    background: var(--bg);
    color: var(--text-muted);
    cursor: pointer;
    transition: border-color .2s, background .2s;
}
.migrate-dropzone-sm:hover,
.migrate-dropzone-sm.drag-over {
    border-color: var(--primary);
    background: var(--accent-light);
}
.migrate-dropzone-sm.has-file {
    border-style: solid;
    border-color: var(--primary);
    background: var(--accent-light);
}
.migrate-dropzone-sm input[type="file"] { display: none; }
.migrate-dropzone-sm-text { font-size: 14px; }
.migrate-dropzone-sm-file {
    font-size: 13px;
    font-weight: 600;
    color: var(--primary);
}
.migrate-dual-upload-actions {
    margin-top: 16px;
}

/* --- Import progress bar --- */
.migrate-progress-box {
    margin-top: 20px;
    padding: 20px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--bg);
}
.migrate-progress-header {
    font-size: 15px;
    font-weight: 600;
    color: #374151;
    margin-bottom: 12px;
}
.migrate-progress-bar-wrap {
    width: 100%;
    height: 10px;
    background: #E5E7EB;
    border-radius: 8px;
    overflow: hidden;
}
.migrate-progress-bar {
    height: 100%;
    width: 0%;
    background: linear-gradient(90deg, #6366F1, var(--primary));
    border-radius: 8px;
    transition: width .3s ease;
}
.migrate-progress-msg {
    margin-top: 10px;
    font-size: 14px;
    color: var(--primary);
    font-weight: 500;
}
.migrate-progress-steps {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    margin-top: 12px;
    font-size: 13px;
    color: var(--text-muted);
}

/* --- Date-format auto-detect / pick result (shown after preview) --- */
.migrate-date-format {
    margin: 16px 0;
    padding: 14px 18px;
    border-radius: 12px;
    font-size: 14px;
}
.migrate-date-format strong { font-weight: 600; }
.migrate-date-format code {
    background: var(--bg-tertiary); padding: 1px 6px; border-radius: 4px;
    font-size: 13px;
}
.migrate-date-format-detected {
    background: var(--status-success-bg); color: var(--status-success-fg);
    border: 1px solid #BBF7D0;
    padding: 10px 14px; border-radius: 8px;
}
.migrate-date-format-warning {
    background: var(--status-danger-bg); color: var(--status-danger-fg);
    border: 1px solid #FECACA;
    padding: 12px 16px; border-radius: 8px; line-height: 1.55;
}
.migrate-date-format-ask {
    background: var(--status-warning-bg); color: var(--status-warning-fg);
    border: 1px solid #FCD34D;
    padding: 14px 18px; border-radius: 8px; line-height: 1.6;
}
.migrate-date-format-choice {
    display: flex; flex-direction: column; gap: 8px;
    margin-top: 10px; padding-left: 4px;
}
.migrate-date-format-choice label {
    display: flex; gap: 8px; align-items: baseline;
    font-weight: normal; cursor: pointer;
}
.migrate-date-format-choice input[type="radio"] {
    /* radio inside flex needs explicit width or it'll be stretched by the global
       input,select,textarea{width:100%} rule (memory note: global-input-width-100). */
    width: auto; flex: 0 0 auto;
}

/* --- Data quality report --- */
.migrate-quality-report {
    margin: 16px 0;
    padding: 16px 20px;
    border: 1px solid #FCD34D;
    border-radius: 12px;
    background: var(--status-warning-bg);
}
.migrate-quality-report h4 {
    margin: 0 0 6px;
    font-size: 15px;
    color: var(--status-warning-fg);
}
.migrate-quality-report p { font-size: 14px; color: var(--text-muted); margin: 6px 0; }
.migrate-quality-report a { color: var(--primary); font-weight: 600; }
.migrate-quality-table {
    width: 100%;
    border-collapse: collapse;
    margin: 12px 0;
    font-size: 13px;
}
.migrate-quality-table th,
.migrate-quality-table td {
    text-align: left;
    padding: 8px 10px;
    border-bottom: 1px solid #FDE68A;
}
.migrate-quality-table th {
    font-weight: 600;
    color: var(--status-warning-fg);
    background: var(--status-warning-bg);
}

/* --- Cancel flow --- */
.cancel-flow-page {
    max-width: 640px;
    margin: 48px auto;
    padding: 0 20px;
}
.cancel-flow-container {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 32px;
}
.cancel-step h1 { font-size: 24px; margin: 0 0 8px; color: var(--text); }
.cancel-step h2 { font-size: 20px; margin: 0 0 8px; color: var(--text); }
.cancel-step p  { color: var(--text-muted); font-size: 14px; }
.cancel-reasons {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-top: 20px;
}
.cancel-reason-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 16px;
    border: 1px solid var(--border);
    border-radius: 8px;
    cursor: pointer;
    font-size: 15px;
    transition: border-color .2s, background .2s;
}
.cancel-reason-item:hover { border-color: var(--primary); background: var(--accent-light); }
/* Selected state — highlight the whole chosen card, not just the radio dot. */
.cancel-reason-item:has(input[type="radio"]:checked) {
    border-color: var(--primary); background: var(--accent-light); box-shadow: inset 0 0 0 1px var(--primary);
}
/* Reset the global `input { width:100% }` rule — without width:auto the radio
   stretches to fill the flex row and squeezes the label to a per-word column. */
.cancel-reason-item input[type="radio"] { width: auto; flex-shrink: 0; margin: 0; accent-color: var(--primary); }
/* Reason-specific follow-up input ("which feature/tool?") — indented so it
   reads as nested under the option it belongs to. */
.cancel-followup { padding-left: 28px; }
.cancel-actions {
    display: flex;
    gap: 12px;
    align-items: center;
    margin-top: 24px;
}
.save-options {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-top: 20px;
}
.save-option {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 16px 18px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg);
}
.save-option strong { color: var(--text); font-size: 15px; }
.save-option p { margin: 4px 0 0; font-size: 13px; color: var(--text-muted); }
/* Keep the option's CTA on one line and a consistent width so the buttons
   line up instead of wrapping / varying. */
.save-option > div { flex: 1 1 auto; min-width: 0; }
.save-option .btn { flex: 0 0 auto; white-space: nowrap; min-width: 168px; text-align: center; }

/* --- Quick activate card --- */
.quick-activate-card {
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 20px;
    background: var(--bg-card);
    margin-bottom: 20px;
}
.qa-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 12px;
    font-weight: 600;
    color: var(--text);
}
.qa-invoices {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.qa-invoice-row {
    display: grid;
    grid-template-columns: 2fr 1fr 1fr auto;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 14px;
}
.qa-client { font-weight: 500; color: var(--text); }
.qa-amount { font-weight: 600; color: var(--text); }
.qa-status { font-size: 13px; color: var(--text-muted); }
.qa-action { text-align: right; }
.qa-footer {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
    font-size: 14px;
    color: var(--text-muted);
}

/* --- Migration ROI card --- */
.migration-roi-card {
    border: 1px solid var(--accent-border);
    border-radius: 12px;
    padding: 24px;
    background: var(--accent-light);
    margin-bottom: 20px;
}
.roi-header {
    font-size: 16px;
    font-weight: 700;
    color: var(--primary);
    margin-bottom: 16px;
}
.roi-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: 16px;
}
.roi-stat {
    text-align: center;
    padding: 12px;
    background: var(--bg-card);
    border-radius: 8px;
}
.roi-value { font-size: 24px; font-weight: 700; color: var(--primary); }
.roi-label { font-size: 13px; color: var(--text-muted); margin-top: 4px; }
.roi-footer {
    margin-top: 16px;
    font-size: 14px;
    color: #4338CA;
}

/* --- Migration banner stats / autoconfig --- */
.migration-stats-row {
    display: flex;
    flex-wrap: wrap;
    gap: 24px;
    margin: 12px 0;
}
.migration-autoconfig {
    margin-top: 12px;
    padding: 16px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg);
}
.migration-config-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 0;
    font-size: 14px;
    color: #374151;
}

/* --- Export data section --- */
.export-data-section {
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 24px;
    background: var(--bg-card);
}
.export-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-top: 16px;
}

/* --- Migration lifecycle responsive --- */
@media (max-width: 768px) {
    .migrate-dual-upload   { grid-template-columns: 1fr; }
    .qa-invoice-row        { grid-template-columns: 1fr 1fr; }
    .cancel-flow-page      { margin: 24px auto; }
    .cancel-flow-container { padding: 20px; }
    .save-option           { flex-direction: column; align-items: flex-start; }
}

/* ===== Onboarding path-selection page ===== */
.onboarding-body { background: var(--bg-tertiary); min-height: 100vh; }
.onboarding-page { max-width: 860px; margin: 0 auto; padding: 40px 24px; }
.onboarding-header { text-align: center; margin-bottom: 40px; }
.onboarding-welcome { text-align: center; margin-bottom: 32px; }
.onboarding-welcome h1 { font-size: 32px; font-weight: 800; }
.onboarding-welcome p  { font-size: 18px; color: var(--text-muted); }

.onboarding-paths {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
}
.onboarding-path-card {
    background: var(--bg-card);
    border: 2px solid var(--border);
    border-radius: 16px;
    padding: 24px;
    text-align: left;
    cursor: pointer;
    transition: all 0.2s;
    position: relative;
}
.onboarding-path-card:hover { border-color: var(--primary); box-shadow: 0 4px 16px rgba(79,70,229,0.1); }
.onboarding-path-card.selected { border-color: var(--primary); background: var(--accent-light); }
.onboarding-path-recommended { border-color: var(--success); }
.path-badge {
    position: absolute; top: 16px; right: 16px;
    background: var(--success); color: #fff;
    padding: 2px 10px; border-radius: 10px;
    font-size: 12px; font-weight: 700;
}
.path-icon  { font-size: 36px; margin-bottom: 12px; }
.path-title { font-size: 17px; font-weight: 700; margin-bottom: 8px; }
.path-desc  { font-size: 14px; color: var(--text-muted); line-height: 1.5; }
.path-time  { font-size: 13px; color: var(--text-muted); margin-top: 12px; }
.onboarding-path-browse { grid-column: span 2; }
.onboarding-skip { text-align: center; margin-top: 24px; color: var(--text-muted); }
.btn-link { background: none; border: none; cursor: pointer;
            color: var(--text-muted); text-decoration: underline; }

/* ===== Dashboard empty state =====
   Layout: hero → migration banner → 2×2 grid of 4 ingestion methods → sample-data CTA.
   Methods are *alternative* paths (pick one), NOT a checklist — visual structure makes that obvious
   (grid instead of stack, no numbering, recommended pair on the top row visually separated by
   the primary border on the CSV card). Container widens to 960px so 2-up cards don't feel cramped. */
/* margin-top tightened from 40 → 16: the onboarding-progress bar above already has 24px
   margin-bottom of its own, so the old 40+24=64px gap was visually excessive. */
.dashboard-empty { max-width: 960px; margin: 16px auto 40px; }
.empty-hero { text-align: center; margin-bottom: 24px; }
.empty-hero h2 { font-size: 28px; font-weight: 800; color: var(--text); margin-bottom: 6px; }
.empty-hero p  { color: var(--text-muted); font-size: 15px; }

/* 2×2 grid on tablet+; single column on phones */
.empty-options { display: grid; grid-template-columns: 1fr; gap: 16px; }
@media (min-width: 768px) {
    .empty-options { grid-template-columns: 1fr 1fr; }
}
.empty-option {
    /* align-items: stretch lets content child fill card height; combined with flex:1 + column on
       .empty-option-content + margin-top:auto on the CTA, buttons always sit at card bottom even
       when one card's body wraps to 2 lines at narrower viewports while its row-mate's stays 1. */
    display: flex; align-items: stretch; gap: 16px;
    background: var(--bg-card); border: 2px solid var(--border);
    border-radius: 12px; padding: 20px;
    /* Hover: subtle lift + soft shadow. Border color is intentionally NOT changed — full
       indigo border on hover was too loud; the 2px lift alone reads as "interactive". */
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.empty-option:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px -6px rgba(79, 70, 229, 0.12);
}
.empty-option-primary { border-color: var(--primary); background: var(--accent-light); }
.empty-option-primary:hover {
    box-shadow: 0 6px 14px -6px rgba(79, 70, 229, 0.20);
}
/* Icons rendered as a chip: 56×56 rounded square, light-indigo bg + dark-indigo stroke;
   primary cards use a solid-indigo bg + white stroke to stand out from the surrounding indigo background */
.empty-option-icon {
    flex-shrink: 0;
    width: 56px; height: 56px;
    display: inline-flex; align-items: center; justify-content: center;
    background: #E0E7FF;            /* indigo-200 */
    border-radius: 12px;
    color: var(--primary);                  /* indigo-600 (stroke=currentColor uses this) */
}
.empty-option-icon svg { display: block }
/* Green-background variant — uses status-success vars for dark-mode support (replaces inline #D1FAE5/#059669) */
.empty-option-icon-success {
    background: var(--status-success-bg) !important;
    color: var(--status-success-fg) !important;
}
.empty-option-primary .empty-option-icon {
    background: var(--primary);
    color: #fff;
}
.empty-option-content {
    min-width: 0;          /* allow text to wrap inside the grid cell */
    flex: 1;               /* take remaining card width after the 56px icon */
    display: flex;
    flex-direction: column; /* stack h3 / p / .btn; combined with margin-top:auto on .btn pushes CTAs to bottom */
}
.empty-option-content .btn { margin-top: auto; align-self: flex-start; }
.empty-option-content h3 { font-size: 17px; font-weight: 700; margin-bottom: 6px; }
.empty-option-content p  { color: var(--text-muted); margin-bottom: 14px; font-size: 14px; line-height: 1.5; }
.empty-option-formats    { font-size: 12px; color: var(--text-muted); margin-top: 8px; }

/* ===== Import hint banner ===== */
.import-hint-banner {
    display: flex; align-items: center; gap: 12px;
    background: var(--accent-light); border: 1px solid var(--accent-border);
    border-radius: 8px; padding: 12px 16px; margin-bottom: 24px;
}
.import-hint-icon { font-size: 18px; }
.import-hint-close {
    margin-left: auto; background: none; border: none;
    cursor: pointer; color: var(--text-muted); font-size: 16px;
}

/* ===== Client dropdown ===== */
.client-select-wrap { display: flex; gap: 8px; align-items: flex-start; }
.client-select-container { flex: 1; position: relative; }
.client-search-input-wrap {
    display: flex; align-items: center;
    border: 1px solid var(--border); border-radius: 8px;
    background: var(--bg-card); cursor: pointer;
}
.client-search-input-wrap input {
    flex: 1; border: none; outline: none;
    padding: 10px 12px; background: transparent; cursor: pointer;
}
.client-search-arrow { padding: 0 12px; color: var(--text-muted); }
.client-dropdown {
    position: absolute; top: 100%; left: 0; right: 0;
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: 8px; box-shadow: 0 4px 16px rgba(0,0,0,0.1);
    z-index: 100; max-height: 280px; overflow-y: auto; margin-top: 4px;
}
.client-dropdown-item {
    display: flex; flex-direction: column;
    padding: 10px 14px; cursor: pointer;
}
.client-dropdown-item:hover { background: var(--bg-tertiary); }
.client-item-name  { font-weight: 600; font-size: 14px; }
.client-item-email { font-size: 12px; }
.client-dropdown-create {
    display: flex; align-items: center; gap: 8px;
    padding: 10px 14px; cursor: pointer;
    background: var(--accent-light); color: var(--primary); font-weight: 600;
}
.client-dropdown-footer {
    padding: 10px 14px; cursor: pointer;
    border-top: 1px solid var(--border);
    color: var(--primary); font-weight: 600; font-size: 14px;
}
.client-dropdown-footer:hover { background: var(--bg-tertiary); }
/* Single-line muted placeholder; padding matches .client-dropdown-item so it
   sits at the same x as where real clients would appear. The CTA itself lives
   in .client-dropdown-footer (always rendered) to keep the list pattern
   identical between empty + populated states. */
.client-dropdown-empty {
    padding: 10px 14px;
    color: var(--text-muted);
    font-size: 14px;
}
.client-selected {
    display: flex; align-items: center; gap: 8px;
    padding: 10px 12px; background: var(--status-success-bg);
    border: 1px solid var(--success); border-radius: 8px;
    font-weight: 600;
}
.client-add-btn { white-space: nowrap; flex-shrink: 0; }

/* Mobile (PR4.2): promote the client picker to a full-screen sheet on phones.
   The desktop floating dropdown is anchored under the field (~210px wide) — on
   a phone it truncates long company names and, worse, the on-screen keyboard
   covers it when the search input is focused. On phones we make the whole
   container a fixed full-screen flex column: search pinned at the top, the list
   fills the space above the keyboard and scrolls. Reuses the same input/list
   DOM + JS (toggleClientDropdown / filterClients / selectClient); a body class
   locks background scroll while open. Desktop is untouched. */
.client-sheet-head { display: none; }
@media (max-width: 640px) {
    body.client-picker-open { overflow: hidden; }
    #client-select-container.is-sheet {
        position: fixed; inset: 0; z-index: 1200;
        background: var(--bg-card);
        display: flex; flex-direction: column; gap: 10px;
        padding: calc(env(safe-area-inset-top, 0px) + 12px) 14px
                 calc(env(safe-area-inset-bottom, 0px) + 12px);
    }
    #client-select-container.is-sheet .client-sheet-head {
        display: flex; align-items: center; justify-content: space-between;
    }
    .client-sheet-title { font-weight: 700; font-size: 16px; color: var(--text); }
    .client-sheet-close {
        width: 40px; height: 40px; flex: 0 0 auto;
        border: none; background: transparent; cursor: pointer;
        font-size: 22px; line-height: 1; color: var(--text-muted);
    }
    #client-select-container.is-sheet .client-search-input-wrap { flex: 0 0 auto; }
    /* the list (display:block toggled by JS) becomes the scrollable body */
    #client-select-container.is-sheet .client-dropdown {
        position: static; inset: auto; margin-top: 0; width: auto;
        flex: 1 1 auto; max-height: none;
        border: none; box-shadow: none; border-radius: 0;
    }
    /* roomier tap targets inside the sheet */
    #client-select-container.is-sheet .client-dropdown-item { padding: 14px; min-height: 44px; }
}

/* ===== Quick add-client modal (modal-overlay/modal-box/modal-close already defined above) ===== */
.modal-header {
    display: flex; justify-content: space-between; align-items: center;
    padding: 20px 24px; border-bottom: 1px solid var(--border);
}
.modal-header h3 { font-size: 18px; font-weight: 700; margin: 0; }
.modal-body   { padding: 24px; }
.modal-footer {
    padding: 16px 24px; border-top: 1px solid var(--border);
    display: flex; gap: 12px; justify-content: flex-end;
}

/* ===== Onboarding progress bar ===== */
.onboarding-progress {
    background: var(--accent-light); border: 1px solid var(--accent-border);
    border-radius: 12px; padding: 16px 20px; margin-bottom: 24px;
}
.op-header { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.op-title  { font-weight: 700; font-size: 14px; }
.op-count  { color: var(--text-muted); font-size: 13px; }
.op-skip   { margin-left: auto; background: none; border: none;
             cursor: pointer; color: var(--text-muted); font-size: 13px; }
.op-bar    { height: 6px; background: var(--accent-border); border-radius: 3px; margin-bottom: 12px; }
.op-bar-fill { height: 100%; background: var(--primary); border-radius: 3px; transition: width 0.3s; }
.op-steps  { display: flex; gap: 32px; flex-wrap: wrap; row-gap: 12px; }
.op-step   { display: flex; align-items: center; gap: 8px;
             font-size: 13px; color: var(--text-muted); }
/* Step-number circular badge — reinforces the 'step 1 of 4' sequence, distinguishes done/active/pending */
.op-step-icon {
    width: 22px; height: 22px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 50%;
    font-size: 11.5px; font-weight: 600;
    background: var(--bg-card); border: 1px solid var(--border);
    color: var(--text-muted);
    flex-shrink: 0;
}
.op-step.done .op-step-icon {
    background: var(--status-success-bg); border-color: var(--success);
    color: var(--status-success-fg); font-size: 13px;
}
.op-step.active .op-step-icon {
    background: var(--primary); border-color: var(--primary);
    color: #fff;
}
/* Done steps are visually demoted — endowed-progress effect (Nunes & Drèze 2006) still applies
   so we keep them visible, but at lower opacity + smaller text so the active/pending steps
   carry the visual weight instead of competing equally with the checkmark. */
.op-step.done   { color: var(--status-success-fg); opacity: 0.6; font-size: 12px; }
.op-step.active { color: var(--primary); font-weight: 600; }
.op-step a      { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
/* Aspirational step ("Get paid") — a "what's coming" goal, not a numbered/blocking
   todo. Dimmed with a hollow dashed badge so it reads as the reward awaiting, not
   work the user must finish. */
.op-step.aspirational { opacity: 0.65; }
.op-step.aspirational .op-step-icon {
    background: transparent; border-style: dashed; color: var(--text-muted);
}

/* "Plan can be switched" hint at the bottom of the onboarding card for trial users — primary dashboard exposure */
.op-trial-hint {
    margin-top: 12px; padding-top: 10px;
    border-top: 1px solid var(--accent-border);
    font-size: 12.5px; color: var(--text-muted);
    display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
}
.op-trial-hint .icon-inline { color: var(--text-muted); flex-shrink: 0; }
.op-trial-hint strong { color: var(--text); font-weight: 600; }
.op-trial-hint a { color: var(--primary); font-weight: 500; }
.op-trial-hint a:hover { text-decoration: underline; }

/* ===== CSV import-result summary =====
   margin-top 20px so the result block visibly sits below the submit button
   instead of hugging it as if it were part of the form. */
.import-result-summary {
    margin-top: 20px; padding: 14px 16px; border-radius: 10px;
    border: 1px solid transparent; font-size: 14px;
}
.import-result-summary.is-success { background: var(--status-success-bg); border-color: #6EE7B7; }
.import-result-summary.has-errors { background: var(--status-danger-bg); border-color: #FCA5A5; }
.import-result-summary.is-warning { background: var(--status-warning-bg); border-color: #FCD34D; }
.import-result-summary .result-headline { font-size: 15px; }
.import-result-summary .result-headline strong { font-size: 18px; }
.import-result-summary .result-clients { margin-top: 4px; }
.import-result-summary .result-errors-count {
    margin: 10px 0 4px; font-size: 12px; color: var(--text-muted);
}
.import-result-summary .result-errors {
    margin: 4px 0 0; padding-left: 20px; font-size: 13px; color: var(--text-muted);
    max-height: 240px; overflow-y: auto;
}
.import-result-summary .result-errors li { margin-bottom: 4px; }
.import-result-summary .text-danger { color: var(--danger); }

/* ===== Invoice PDF import — upload zone, processing, results, success =====
   Moved out of inline <style> in tpl/invoice/pdf_import.tpl.php so the missing
   .result-card / .confidence-* / .result-fields / .input-group / .pdf-success
   classes the JS template referenced actually have rules. */
.pdf-upload-zone {
    position: relative;
    margin-top: 4px;
    border: 2px dashed var(--accent-border); border-radius: 12px;
    padding: 56px 24px; text-align: center; background: var(--bg);
    cursor: pointer;
    transition: border-color .15s, background .15s;
}
.pdf-upload-zone:hover,
.pdf-upload-zone.dragover { border-color: var(--primary); background: var(--accent-light); }
.pdf-upload-icon { color: var(--primary); margin-bottom: 8px; display: inline-flex; }
.pdf-upload-zone h3 { margin: 4px 0 6px; font-size: 20px; color: var(--text); }
.pdf-upload-click-hint { margin: 0; font-size: 14px; }
.pdf-upload-zone input[type=file] {
    position: absolute;
    inset: 0;
    z-index: 2;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
}
.pdf-upload-note { margin-top: 16px; font-size: 13px; }
.capture-intro { max-width: 680px; }
.capture-install-hint {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin: 2px 0 10px;
    padding: 7px 10px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: 13px;
    line-height: 1.35;
}
.capture-install-hint .icon-inline {
    flex-shrink: 0;
    color: var(--primary);
}
.capture-quota { margin-top: 0; }
.capture-actions {
    justify-content: center;
}
.capture-action-btn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
}
.capture-file-btn {
    background: var(--primary);
    border-color: var(--primary);
    color: #fff;
}
.capture-file-btn:hover {
    background: var(--primary-dark);
    color: #fff;
}
.capture-camera-btn {
    background: var(--bg-card);
    border-color: var(--border);
    color: var(--text);
}
.capture-camera-btn:hover {
    border-color: var(--primary);
    color: var(--primary);
}

@media (max-width: 768px), (display-mode: standalone) {
    .capture-camera-btn {
        order: 1;
        background: var(--primary);
        border-color: var(--primary);
        color: #fff;
    }
    .capture-camera-btn:hover {
        background: var(--primary-dark);
        color: #fff;
    }
    .capture-file-btn {
        order: 2;
        background: var(--bg-card);
        border-color: var(--border);
        color: var(--text);
    }
    .capture-file-btn:hover {
        border-color: var(--primary);
        color: var(--primary);
    }
}

.pdf-processing {
    display: flex; align-items: center; gap: 12px;
    margin-top: 24px; padding: 20px;
    border: 1px solid var(--border); border-radius: 8px;
    background: var(--bg-card); color: var(--text);
}
.pdf-processing-spinner {
    flex-shrink: 0; width: 24px; height: 24px;
    border: 3px solid var(--border); border-top-color: var(--primary);
    border-radius: 50%; animation: pdf-spin 1s linear infinite;
}
.pdf-processing-text { display: flex; flex-direction: column; gap: 2px; }
@keyframes pdf-spin { to { transform: rotate(360deg); } }

.results-header { margin: 24px 0 16px; }
.results-header h2 { margin: 0 0 6px; }
.results-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 12px; }
.results-list { display: flex; flex-direction: column; gap: 16px; }

.result-card {
    background: var(--bg-card);
    border: 1px solid var(--border); border-radius: 10px;
    padding: 16px 18px;
    box-shadow: var(--shadow);
}
.result-card.result-card-high   { border-left: 4px solid var(--success); }
.result-card.result-card-medium { border-left: 4px solid var(--warning); }
.result-card.result-card-low    { border-left: 4px solid var(--warning-strong); }
.result-card.result-card-duplicate { border-left: 4px solid var(--danger); }
.result-card-header {
    display: flex; justify-content: space-between; align-items: center;
    gap: 12px; margin-bottom: 12px; flex-wrap: wrap;
}
.result-filename { font-weight: 600; font-size: 14px; color: var(--text); }

.confidence-badge {
    display: inline-flex; align-items: center;
    padding: 3px 10px; border-radius: 999px;
    font-size: 11px; font-weight: 600;
    border: 1px solid;
}
.confidence-high   { background: var(--status-success-bg); color: var(--status-success-fg); border-color: transparent; }
.confidence-medium { background: var(--status-warning-bg); color: var(--status-warning-fg); border-color: transparent; }
.confidence-low    { background: var(--status-danger-bg);  color: var(--status-danger-fg);  border-color: transparent; }

/* Stage 4 (reaudit 4th pass): low-confidence cards require an explicit
   acknowledgement before they can be saved — the AI sometimes swaps
   vendor↔client or fabricates an amount. Visual cue is a warning banner
   tied to the same warning tokens; the checkbox label stays inline so
   the row stays compact. */
.confidence-warn-banner {
    background: var(--status-danger-bg);
    color: var(--status-danger-fg);
    border-radius: var(--radius);
    padding: 10px 12px; margin-bottom: 12px;
    font-size: 13px; line-height: 1.5;
}
.confidence-warn-banner strong { display: block; margin-bottom: 2px; }
.confidence-ack {
    display: inline-flex; align-items: center; gap: 6px;
    margin-top: 6px; font-weight: 600; cursor: pointer;
}
.confidence-ack-box { width: auto; margin: 0; cursor: pointer; }

.duplicate-warn-banner {
    background: var(--status-danger-bg);
    color: var(--status-danger-fg);
    border-radius: var(--radius);
    padding: 10px 12px; margin-bottom: 12px;
    font-size: 13px; line-height: 1.5;
}
.duplicate-warn-banner strong { display: block; margin-bottom: 2px; }
.duplicate-warn-banner a {
    color: inherit; font-weight: 700; text-decoration: underline;
    text-underline-offset: 2px;
}

/* 2-col grid on desktop, falls back to single col under 600px */
.result-fields {
    display: grid; grid-template-columns: 1fr 1fr;
    gap: 12px 16px;
}
.result-field { display: flex; flex-direction: column; min-width: 0; }
.result-field > label { font-size: 12px; font-weight: 600; color: var(--text-muted); margin-bottom: 4px; }
.result-field-half { /* explicit half-width even when grandparent grid varies */ }
.result-field-full { grid-column: 1 / -1; }   /* span both columns — for free-text like Notes */
.result-field-hint { font-size: 12px; margin-top: 4px; }
.result-field-hint-ok   { color: var(--success); }
.result-field-hint-warn { color: var(--warning-strong); }
.invoice-number-preview-input.is-duplicate {
    border-color: var(--danger);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 16%, transparent);
}

.input-group { display: flex; gap: 6px; }
.input-group > select { width: auto; min-width: 84px; }
.input-group > input  { flex: 1; min-width: 0; }

.result-card-footer { margin-top: 12px; text-align: right; }
.result-card.result-skipped { opacity: 0.4; pointer-events: none; }

@media (max-width: 600px) {
    .result-fields { grid-template-columns: 1fr; }
}

.import-errors {
    background: var(--status-warning-bg); color: var(--status-warning-fg);
    border-left: 4px solid var(--warning);
    padding: 10px 14px; border-radius: 0 8px 8px 0;
    margin: 0 0 16px; font-size: 13px;
}
.import-errors ul { margin: 6px 0 0; padding-left: 20px; }

.pdf-success {
    text-align: center; padding: 40px 24px;
    background: var(--status-success-bg); border-radius: 12px;
    color: var(--status-success-fg);
}
.pdf-success-icon { color: var(--success); display: inline-flex; margin-bottom: 8px; }
.pdf-success h2 { margin: 0 0 6px; color: inherit; }
.pdf-success-actions { display: flex; gap: 10px; justify-content: center; margin-top: 16px; flex-wrap: wrap; }

/* ===== First-activation celebration modal ===== */
.celebrate-modal { text-align: center; padding: 40px 32px; }
.celebrate-modal h2 { font-size: 28px; font-weight: 800; margin-bottom: 12px; }

/* ===== /invoice/replyQuickAction/ done page — public confirm after token-verified
   one-click reply action (pause / resolve) from the AI digest email. ===== */
.reply-action-done { max-width: 480px; margin: 0 auto; padding: 64px 32px; text-align: center; }
.reply-action-icon { display: inline-flex; margin-bottom: 8px; }
.reply-action-icon-ok   { color: var(--success); }
.reply-action-icon-warn { color: var(--warning); }
.reply-action-cta { margin-top: 16px; }

/* ===== /invoice/activated/ — full-page celebration shown on first activation only =====
   Previously lived as a 60-line inline <style> block in tpl/invoice/activated.tpl.php
   with hardcoded greens / greys; moved here so colors track theme tokens (dark mode). */
.activated-page { min-height: 80vh; display: flex; align-items: center; }
.activated-container { max-width: 600px; margin: 0 auto; padding: 40px 24px; }
.activated-hero { text-align: center; margin-bottom: 40px; }
.activated-check { color: var(--success); margin-bottom: 16px; display: inline-flex; }
.activated-hero h1 { font-size: 28px; font-weight: 800; margin-bottom: 12px; }

.activated-schedule { margin-bottom: 32px; }
.activated-schedule h2 { font-size: 18px; font-weight: 700; margin-bottom: 16px; }
.schedule-timeline { position: relative; }
.schedule-step {
    display: flex; align-items: center; gap: 16px;
    padding: 16px 0;   /* 12 → 16 — celebration page should breathe */
    border-bottom: 1px solid var(--border);
}
.schedule-step:last-child { border-bottom: none; }
.schedule-step-date {
    width: 60px; flex-shrink: 0;
    font-size: 13px; font-weight: 600;
    color: var(--text); text-align: right;
}
.schedule-sent { color: var(--success); }
.schedule-step-dot {
    width: 12px; height: 12px;
    border-radius: 50%; flex-shrink: 0;
}
.dot-done    { background: var(--success); }
.dot-pending { background: var(--bg); border: 2px solid var(--text-muted); }
.schedule-step-desc { font-size: 14px; color: var(--text-muted); }
.schedule-step-past .schedule-step-desc { color: var(--text-muted); }

.activated-notifications {
    background: var(--bg); border-radius: 12px;
    padding: 20px 24px; margin-bottom: 32px;
}
.activated-notifications h3 { font-size: 15px; font-weight: 700; margin-bottom: 12px; }
.notification-items { display: flex; flex-direction: column; gap: 10px; }
.notification-item { display: flex; align-items: center; gap: 10px; font-size: 14px; color: var(--text); }
.notif-icon { display: inline-flex; flex-shrink: 0; }

.activated-next { display: flex; gap: 12px; justify-content: center; margin-bottom: 24px; flex-wrap: wrap; }
.activated-stripe-hint {
    text-align: center;
    font-size: 14px; color: var(--text-muted);
    padding: 16px;
    background: var(--accent-light); border-radius: 8px;
}
.activated-stripe-hint .icon-inline { vertical-align: -2px; margin-right: 2px; }

/* ===== First-payment celebration banner (Onboarding v2 Step 5) ===== */
.first-payment-celebration {
    background: linear-gradient(135deg, #ECFDF5 0%, #D1FAE5 100%);
    border: 1px solid #6EE7B7; border-radius: 12px;
    padding: 16px 20px; margin-bottom: 24px;
}
.celebration-content   { display: flex; align-items: center; gap: 16px; }
.celebration-icon      { font-size: 32px; flex: 0 0 auto; }
.celebration-text      { flex: 1; line-height: 1.4; }
.celebration-text strong { display: block; font-size: 16px; color: var(--status-success-fg); }
.celebration-text span   { font-size: 13px; color: #047857; }
.celebration-close     { background: none; border: none; cursor: pointer;
                         color: #047857; font-size: 18px; }

/* Row 2 — referral upsell that piggybacks on the first-payment celebration. Same green
   surface as the rest of the card to read as one continuous moment, with a thin divider
   above to delineate "celebration" from "ask". */
.celebration-referral {
    display: flex; align-items: center; justify-content: space-between; gap: 16px;
    margin-top: 14px; padding-top: 12px;
    border-top: 1px dashed rgba(4, 120, 87, 0.3);
}
.celebration-referral-text  { font-size: 13px; color: #065f46; line-height: 1.45; }
.celebration-referral-text strong { color: var(--status-success-fg); }
.celebration-referral-cta { flex-shrink: 0; }
@media (max-width: 640px) {
    .celebration-referral { flex-direction: column; align-items: flex-start; }
}
/* Dark mode: the celebration card was hardcoded light-green and stayed a jarring
   bright block in dark mode. Map it onto the success tokens. */
[data-theme="dark"] .first-payment-celebration {
    background: var(--status-success-bg);
    border-color: color-mix(in srgb, var(--status-success-fg) 35%, transparent);
}
[data-theme="dark"] .celebration-text span,
[data-theme="dark"] .celebration-close { color: var(--status-success-fg); }
[data-theme="dark"] .celebration-referral-text { color: var(--status-success-fg); }
[data-theme="dark"] .celebration-referral {
    border-top-color: color-mix(in srgb, var(--status-success-fg) 30%, transparent);
}

/* Responsive */
@media (max-width: 768px) {
    .onboarding-paths { grid-template-columns: 1fr; }
    .onboarding-path-browse { grid-column: auto; }
    .op-steps { gap: 8px; }
    .op-step  { margin-right: 0; }
}

/* ============================================================
   Optimization Part 1 — recurring, credit, tags, bulk, partial
   payments, reconciliation, multi-currency
   ============================================================ */

/* --- shared utility helpers --- */
.text-green { color: var(--success); }
.btn-danger-outline {
    color: var(--status-danger-fg); border-color: #FCA5A5;
}
.btn-danger-outline:hover { background: var(--status-danger-bg); }
/* "Disconnect" is a separate, destructive action — set it apart from the
   "Send test" form above it with space and a hairline divider. */
.byo-disconnect { margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--border); }
.required { color: var(--danger); }
.checkbox-label {
    display: flex; align-items: center; gap: 8px;
    font-weight: 500; cursor: pointer;
}
.checkbox-label input[type="checkbox"] { width: auto; margin: 0; }

/* --- Task 1: recurring invoices --- */
.recurring-options-box {
    background: var(--accent-light); border: 1px solid var(--accent-border);
    border-radius: var(--radius); padding: 16px; margin-bottom: 16px;
}
.recurring-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 16px;
}
.recurring-grid .form-group { margin-bottom: 0; }
.recurring-grid input,
.recurring-grid select { min-height: 40px; }
.recurring-preview {
    margin-top: 8px; font-size: 13px; color: var(--primary);
    background: var(--bg-card); border-radius: 8px; padding: 8px 12px;
}
.recurring-badge { font-size: 13px; margin-left: 4px; cursor: default; }

/* Source badge in the Invoices list — small neutral pill next to the invoice number.
   Renders on every row except 'manual' (default, uninteresting). Clickable to filter the
   list by that source. Per-source tone hints at category (sync vs file vs sample). */

/* Invoice-number cells in the review / import-review / chase / client tables wrap
   a long unbreakable number (e.g. a garbage import) within the column instead of
   spilling into the Client cell. Hyphenated numbers still break at the hyphen first
   — `anywhere` only kicks in when there's no natural break point. (The main
   .invoice-table clips with an ellipsis instead, because it's fixed-layout.) */
td[data-col="invoice"] { overflow-wrap: anywhere; }

/* Client name in the invoice list — a quiet link to the client page. Reads as
   plain text at rest (so it doesn't compete with the invoice # link), reveals
   itself on hover. */
.client-link { color: inherit; text-decoration: none; }
.client-link:hover { color: var(--primary); text-decoration: underline; }

.source-badge {
    display: inline-block; margin-left: 6px;
    padding: 1px 6px; border-radius: 4px;
    font-size: 10px; font-weight: 600; line-height: 1.4;
    letter-spacing: 0;
    text-decoration: none; vertical-align: middle;
    background: var(--bg-tertiary, #F3F4F6);
    color: var(--text-muted, #6B7280);
    border: 1px solid var(--border, #E5E7EB);
}
.source-badge:hover { background: var(--bg-card); text-decoration: none; }
/* Sync sources (real-time integrations) — slight green tint */
.source-badge-quickbooks,
.source-badge-xero,
.source-badge-freshbooks,
.source-badge-zoho,
.source-badge-freeagent { color: var(--status-success-fg); background: var(--status-success-bg); border-color: color-mix(in srgb, var(--status-success-fg) 35%, var(--border)); }
/* Bulk imports (one-off file upload) — slight blue tint */
.source-badge-csv,
.source-badge-excel,
.source-badge-pdf { color: var(--status-info-fg); background: var(--status-info-bg); border-color: color-mix(in srgb, var(--status-info-fg) 35%, var(--border)); }

/* Intake captures (email / WhatsApp / phone) — same info family as the other
   "brought in by the user" sources, distinct from accounting-sync green. */
.source-badge-email,
.source-badge-whatsapp,
.source-badge-capture { color: var(--status-info-fg); background: var(--status-info-bg); border-color: color-mix(in srgb, var(--status-info-fg) 35%, var(--border)); }
/* Demo data — explicit warning tone so it never blends with real */
.source-badge-sample { color: var(--status-warning-fg); background: var(--status-warning-bg); border-color: color-mix(in srgb, var(--status-warning-fg) 35%, var(--border)); }
/* Historical migration */
.source-badge-migrate,
.source-badge-chaser,
.source-badge-invoicesherpa,
.source-badge-wave,
.source-badge-paidnice,
.source-badge-invoice2go { color: var(--primary); background: var(--accent-light); border-color: var(--accent-border); }

/* Reports "By source" breakdown panel — lives below the 4-stat grid on /reports/. */
.report-source-card { margin-top: 16px; }
/* PR8: keep the 5-column source table from forcing the whole page to scroll on
   phones — it scrolls inside its card instead. */
.report-source-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.report-source-scroll .report-source-table { min-width: 460px; }
.report-source-head { margin-bottom: 12px; }
.report-source-head h3 { margin: 0 0 4px; font-size: 16px; }
.report-source-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.report-source-table th,
.report-source-table td { padding: 8px 12px; border-bottom: 1px solid var(--border, #E5E7EB); }
.report-source-table th { text-align: left; font-weight: 600; color: var(--text-muted); }
.report-source-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.report-source-pct { font-weight: 600; }
/* Theme tokens, not fixed hexes — the old dark greens/reds vanished on the
   dark background. */
.report-source-pct-good { color: var(--success); }
.report-source-pct-warn { color: var(--warning-strong); }
.report-source-pct-bad  { color: var(--danger); }
.recurring-info-card {
    background: var(--accent-light); border: 1px solid var(--accent-border);
    border-radius: var(--radius); padding: 16px 20px; margin-bottom: 24px;
}
.recurring-info-card h4 { margin: 0 0 12px; font-size: 15px; }
.recurring-info-row {
    display: flex; justify-content: space-between;
    font-size: 14px; padding: 4px 0;
}
.recurring-info-row span { color: var(--text-muted); }

/* --- client/view 2-col top row (info + credit) --- */
.client-view-cols {
    display: grid;
    /* minmax(0, …) not 1fr: a bare 1fr track can't shrink below its content's
       min-content, so a long email / the credit-limit row pushed the card past
       the viewport on mobile. minmax(0,…) lets the track (and card) shrink. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 20px;
    align-items: start;
    margin-bottom: 20px;
}
.client-view-cols > .card { max-width: none; margin-bottom: 0; min-width: 0; }
@media (max-width: 768px) {
    .client-view-cols { grid-template-columns: minmax(0, 1fr); }
}

/* --- Task 2: credit control --- */
.credit-section h3 { margin: 0 0 16px; font-size: 16px; }
.credit-bar-wrap { margin-bottom: 20px; }
.credit-bar-label {
    display: flex; justify-content: space-between;
    font-size: 13px; color: var(--text-muted); margin-bottom: 6px;
}
.credit-bar {
    height: 10px; background: #E5E7EB;
    border-radius: 5px; overflow: hidden;
}
.credit-bar-fill {
    height: 100%; border-radius: 5px; transition: width .3s;
    width: var(--bar-width, 0%);
}
.credit-bar-ok      { background: var(--success); }
.credit-bar-warning { background: #D97706; }
.credit-bar-danger  { background: var(--danger); }
.credit-bar-pct {
    margin-top: 6px; font-size: 13px; color: var(--text-muted);
    display: flex; align-items: center; gap: 8px;
}
.credit-limit-form label {
    display: block; font-weight: 600; font-size: 13px; margin-bottom: 6px;
}
.credit-limit-form .input-row {
    display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
}
.credit-limit-form .input-row input { max-width: 200px; }

/* --- Task 6: blacklist --- */
.blacklist-warning {
    display: flex; gap: 14px; align-items: flex-start;
    background: var(--status-danger-bg); border: 1px solid #FCA5A5;
    border-radius: var(--radius); padding: 16px 20px; margin-bottom: 24px;
}
.blacklist-icon { font-size: 24px; line-height: 1; }
.blacklist-body { flex: 1; }
.blacklist-body strong { color: var(--status-danger-fg); }
.blacklist-body p { margin: 4px 0 0; font-size: 14px; }
.blacklist-warning .btn { flex-shrink: 0; }
/* Blacklist badge — labeled slate pill so it reads as a deliberate, manual block
   and is visually distinct from the red (auto, deliverability) email-suppressed pill. */
.blacklist-badge {
    display: inline-flex; align-items: center; gap: 3px;
    margin-left: 6px;
    padding: 1px 7px;
    border-radius: 4px;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    background: #F1F5F9;
    color: #475569;
    border: 1px solid #CBD5E1;
    cursor: help;
}
[data-theme="dark"] .blacklist-badge {
    background: var(--surface-2);
    color: var(--text-muted);
    border-color: var(--border);
}

/* On-autopay badge — positive state, so it uses the success palette. Mirrors
   the blacklist/suppression badges' shape. Token-based → dark-safe. */
.autopay-badge {
    display: inline-flex; align-items: center; gap: 3px;
    margin-left: 6px;
    padding: 1px 7px;
    border-radius: 4px;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    background: var(--status-success-bg);
    color: var(--status-success-fg);
    border: 1px solid color-mix(in srgb, var(--status-success-fg) 35%, var(--border));
    cursor: help;
}

/* Email-suppressed badge — shown when Resend told us the address bounces or
   the client complained. Helps operator spot bad addresses at a glance.
   help: account/suppression-list.md */
.suppression-badge {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 7px;
    border-radius: 4px;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    background: var(--status-danger-bg);
    color: var(--status-danger-fg);
    border: 1px solid color-mix(in srgb, var(--status-danger-fg) 35%, var(--border));
    cursor: help;
}

/* Saved-card chip on client detail — tells operator this client is 1-click
   ready, which is useful context when deciding whether to chase or let the
   reminder handle it. */
.saved-card-chip {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 4px;
    background: var(--status-success-bg);
    color: var(--status-success-fg);
    border: 1px solid color-mix(in srgb, var(--status-success-fg) 35%, var(--border));
    font-size: 12px;
    font-weight: 600;
    font-family: ui-monospace, Menlo, monospace;
    letter-spacing: 0.02em;
}

/* Latest client reply (with AI-classified intent + risk) — shown inline in
   the invoice list client column so users see "Disputed" / "Promised" /
   "Says paid" without opening each row. Color = risk level. */
.reply-badge {
    display: inline-flex; align-items: center; gap: 4px;
    margin-left: 6px;
    padding: 1px 8px; border-radius: 999px;
    font-size: 11px; font-weight: 500;
    text-decoration: none;
    border: 1px solid transparent;
    vertical-align: middle;
}
.reply-badge:hover { text-decoration: none; opacity: 0.85; }
.reply-badge-low {
    background: var(--accent-light); color: var(--primary); border-color: var(--accent-border);
}
.reply-badge-medium {
    background: var(--status-warning-bg); color: var(--status-warning-fg); border-color: color-mix(in srgb, var(--status-warning-fg) 35%, var(--border));
}
.reply-badge-high {
    background: var(--status-danger-bg); color: var(--status-danger-fg); border-color: color-mix(in srgb, var(--status-danger-fg) 35%, var(--border));
}
.reply-badge-unread { font-weight: 700; }

/* --- Task 4: bulk operations --- */
.invoice-list-controls {
    display: flex; justify-content: space-between;
    align-items: center; gap: 16px; flex-wrap: wrap;
}
.tag-filter select { min-width: 160px; }
.bulk-action-bar {
    display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
    background: var(--accent-light); border: 1px solid var(--accent-border);
    border-radius: var(--radius); padding: 10px 16px; margin-bottom: 16px;
    position: sticky; top: 0; z-index: 5;
}
/* On phones the bar's buttons wrap to several rows (~270px tall); pinned at
   top:0 that eats ~half the viewport while scrolling. Let it scroll away. */
@media (max-width: 480px) {
    .bulk-action-bar { position: static; }
}
.bulk-count { font-weight: 700; font-size: 14px; color: var(--primary); }
.bulk-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.bulk-dialog { max-width: 440px; }
.bulk-dialog-msg { margin: -4px 0 14px; color: var(--text-muted); font-size: 14px; line-height: 1.45; }
.bulk-dialog-field {
    margin: 0;
    min-width: 0;
}
.bulk-dialog > .bulk-dialog-field {
    margin-top: 10px;
}
.bulk-dialog-field > span {
    display: block;
    min-height: 16px;
    margin-bottom: 6px;
    font-weight: 600;
    font-size: 13px;
    line-height: 1.2;
}
.bulk-dialog-actions { justify-content: flex-end; }
.bulk-dialog input.form-control,
.bulk-dialog select.form-control:not([multiple]),
.bulk-dialog .tag-dropdown-trigger {
    box-sizing: border-box;
    height: 40px;
    min-height: 40px;
    font-size: 14px;
    line-height: 1.2;
}
.bulk-dialog .date-display-wrap {
    width: 100%;
}
.bulk-dialog select.form-control:not([multiple]) {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236B7280' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
    background-repeat: no-repeat;
    background-position: right 12px center;
    background-size: 12px;
    padding-right: 34px;
}
.bulk-dialog textarea.form-control { min-height: 96px; resize: vertical; }
.bulk-dialog select[multiple].form-control { min-height: 132px; padding: 8px; }
.bulk-tag-dropdown .tag-dropdown-trigger {
    border-radius: 8px;
    padding: 0 12px;
}
.bulk-tag-dropdown .tag-dropdown-label {
    color: var(--text);
}
.bulk-tag-current {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.bulk-tag-current-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.bulk-tag-menu {
    z-index: 1105;
    max-height: 240px;
}
.bulk-tag-menu .tag-dropdown-item {
    padding: 9px 10px;
    font-size: 15px;
}
.bulk-tag-menu .tag-dropdown-check-mark {
    font-size: 14px;
    font-weight: 800;
}
.bulk-money-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 104px;
    gap: 8px;
}
.bulk-payment-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
    margin-bottom: 14px;
}
.bulk-payment-note { min-height: 78px; }
.bulk-client-search {
    margin-bottom: 10px;
}
.bulk-client-results {
    display: grid;
    gap: 6px;
    max-height: 280px;
    overflow-y: auto;
    padding: 2px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-card);
}
.bulk-client-option {
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text);
    cursor: pointer;
    display: grid;
    gap: 2px;
    padding: 9px 10px;
    text-align: left;
}
.bulk-client-option:hover,
.bulk-client-option.is-selected {
    background: var(--accent-light);
}
.bulk-client-option strong {
    font-size: 14px;
    line-height: 1.25;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.bulk-client-option span {
    color: var(--text-muted);
    font-size: 12px;
    line-height: 1.25;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.bulk-client-empty {
    color: var(--text-muted);
    font-size: 13px;
    margin: 0;
    padding: 14px 10px;
    text-align: center;
}
.bulk-renumber-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 120px 96px;
    gap: 10px;
}
.bulk-renumber-preview {
    margin: 4px 0 14px;
    padding: 8px 10px;
    border-radius: var(--radius);
    background: var(--bg-tertiary);
    color: var(--text-muted);
    font-size: 13px;
}
.bulk-edit-modal { max-width: 760px; }
.bulk-edit-header {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(220px, 300px);
    gap: 18px;
    align-items: start;
    margin-bottom: 14px;
    padding-right: 28px;
}
.bulk-edit-header h3 {
    margin: 0;
    font-size: 20px;
}
.bulk-edit-header-text {
    min-width: 0;
}
.bulk-edit-subtitle {
    margin: 8px 0 0;
    color: var(--text-muted);
    font-size: 13px;
    line-height: 1.35;
    white-space: nowrap;
}
.bulk-result-modal { max-width: 720px; }
.bulk-result-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
}
.bulk-result-section {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-card);
    padding: 12px;
    min-height: 120px;
}
.bulk-result-section h4 {
    margin: 0 0 8px;
    font-size: 12px;
    font-weight: 700;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: .4px;
}
.bulk-result-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    gap: 6px;
    max-height: 260px;
    overflow: auto;
}
.bulk-result-list li {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 2px;
    padding: 7px 8px;
    border-radius: var(--radius-sm);
    background: var(--bg-secondary);
}
.bulk-result-label {
    font-weight: 700;
    font-size: 13px;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.bulk-result-reason,
.bulk-result-empty {
    font-size: 12px;
    color: var(--text-muted);
}
.bulk-result-empty { margin: 0; }
.bulk-action-search {
    margin-top: 0;
}
.bulk-action-search .form-control {
    height: 36px;
    max-width: 100%;
    font-size: 13px;
}
.bulk-action-picker {
    display: grid;
    grid-template-columns: 156px minmax(0, 1fr);
    gap: 14px;
    margin-top: 14px;
}
.bulk-action-nav {
    display: grid;
    align-content: start;
    gap: 6px;
    padding: 6px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-secondary);
}
.bulk-action-nav-item {
    width: 100%;
    border: 0;
    border-radius: var(--radius-sm);
    padding: 9px 10px;
    background: transparent;
    color: var(--text-muted);
    text-align: left;
    font-weight: 700;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}
.bulk-action-nav-item:hover { background: var(--bg-card); color: var(--text); }
.bulk-action-nav-item.is-active {
    background: var(--accent-light);
    color: var(--accent);
}
.bulk-action-panel {
    min-height: 300px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 12px;
    background: var(--bg-card);
}
.bulk-action-panel-head {
    margin-bottom: 10px;
}
.bulk-action-panel-head h4 {
    margin: 0;
    font-size: 14px;
    font-weight: 800;
    color: var(--text);
}
.bulk-action-panel-head p {
    margin: 2px 0 0;
    color: var(--text-muted);
    font-size: 12px;
}
.bulk-action-list {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--bg-card);
}
.bulk-action-chip-group {
    border: 0;
    border-top: 1px solid var(--border);
    border-radius: 0;
    background: var(--bg-card);
    padding: 10px 12px;
}
.bulk-action-list > .bulk-action-chip-group:first-child { border-top: 0; }
.bulk-action-chip-label {
    margin-bottom: 8px;
    color: var(--text-muted);
    font-size: 12px;
    font-weight: 800;
    letter-spacing: .2px;
}
.bulk-action-chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.bulk-action-chip {
    min-height: 32px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-secondary);
    color: var(--text);
    padding: 0 12px;
    cursor: pointer;
    font-size: 13px;
    font-weight: 800;
}
.bulk-action-chip:hover {
    border-color: var(--accent-border);
    background: var(--accent-light);
    color: var(--accent);
}
.bulk-action-card {
    min-height: 46px;
    border: 0;
    border-top: 1px solid var(--border);
    border-radius: 0;
    background: var(--bg-card);
    color: var(--text);
    padding: 10px 12px;
    text-align: left;
    cursor: pointer;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 12px;
    align-items: center;
    align-content: start;
}
.bulk-action-list > .bulk-action-card:first-child { border-top: 0; }
.bulk-action-card:hover {
    background: var(--accent-light);
}
.bulk-action-card:hover strong {
    color: var(--accent);
}
.bulk-action-card-body {
    min-width: 0;
    display: grid;
    gap: 2px;
}
.bulk-action-card strong {
    font-size: 14px;
    line-height: 1.25;
    overflow-wrap: anywhere;
}
.bulk-action-card-body span {
    font-size: 12px;
    line-height: 1.3;
    color: var(--text-muted);
}
.bulk-action-card-aside {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    justify-self: end;
}
.bulk-action-chevron {
    color: var(--text-muted);
    font-size: 22px;
    font-weight: 800;
    line-height: 1;
    transition: transform .12s ease, color .12s ease;
}
.bulk-action-card:hover .bulk-action-chevron {
    color: var(--accent);
    transform: translateX(2px);
}
.bulk-action-card-meta {
    border-radius: 999px;
    padding: 3px 8px;
    background: var(--bg-card);
    color: var(--text-muted);
    font-style: normal;
    font-size: 11px;
    font-weight: 800;
}
.bulk-action-empty {
    margin: 18px 0 0;
    padding: 18px;
    border: 1px dashed var(--border);
    border-radius: var(--radius);
    color: var(--text-muted);
    background: var(--bg-secondary);
    text-align: center;
}
.bulk-action-danger-title {
    margin: 14px 0 8px;
    padding-top: 0;
    border-top: 0;
    color: var(--status-danger-fg);
    font-size: 11px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .4px;
}
.bulk-action-list-danger {
    border-color: color-mix(in srgb, var(--status-danger-fg) 35%, var(--border));
}
.bulk-action-card.is-danger {
    background: color-mix(in srgb, var(--status-danger-bg) 55%, var(--bg-card));
}
.bulk-action-card.is-danger strong,
.bulk-action-card.is-danger .bulk-action-chevron { color: var(--status-danger-fg); }
.bulk-action-card.is-danger:hover {
    background: var(--status-danger-bg);
}
.bulk-action-card.is-danger:hover strong {
    color: var(--status-danger-fg);
}
@media (max-width: 700px) {
    .bulk-edit-header {
        grid-template-columns: 1fr;
        gap: 10px;
        padding-right: 24px;
    }
    .bulk-edit-subtitle { white-space: normal; }
    .bulk-action-picker { grid-template-columns: 1fr; }
    .bulk-action-nav { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .bulk-action-panel { min-height: 0; }
    .bulk-action-card { grid-template-columns: minmax(0, 1fr) auto; gap: 8px; }
    .bulk-action-card-meta { justify-self: start; }
    .bulk-result-grid { grid-template-columns: 1fr; }
    .bulk-payment-grid { grid-template-columns: 1fr; }
    .bulk-renumber-grid { grid-template-columns: 1fr; }
}
/* .invoice-checkbox-col is reused on both .invoice-table and .client-table.
   Selector intentionally NOT prefixed by either parent so the global
   `input,select,textarea{width:100%}` reset applies on both pages. Pre-fix the
   reset was scoped to .invoice-table only, leaving client checkboxes stretched
   + padded + bordered by the global rule → looked rendered but had a misaligned
   hit-area that made them look broken. */
.invoice-checkbox-col {
    width: 40px;
    min-width: 40px;
    max-width: 40px;
    text-align: center;
}
.invoice-checkbox-col input { width: auto; margin: 0; cursor: pointer; }
.invoice-row.selected { background: var(--accent-light); }

/* --- Text search box (consolidated into the invoice-filters panel, spans the whole row) --- */
.invoice-search-wrap {
    position: relative;
    width: 100%;
}
.invoice-search-icon {
    position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
    color: var(--text-muted, #9CA3AF);
    pointer-events: none;
}
.invoice-search-input {
    width: 100%;
    padding: 9px 36px 9px 38px;     /* leave 36-38px on left for icon, right for clear × */
    font-size: 14px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-card); color: var(--text);
    transition: border-color .12s, box-shadow .12s;
}
.invoice-search-input:focus {
    outline: none;
    border-color: var(--primary, var(--primary));
    box-shadow: 0 0 0 3px rgba(79,70,229,0.10);
}
.invoice-search-clear {
    position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
    width: 20px; height: 20px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 50%;
    background: var(--text-muted, #9CA3AF); color: #fff;
    font-size: 14px; line-height: 1;
    text-decoration: none;
    transition: background .12s;
}
.invoice-search-clear:hover { background: var(--ink, #111827); }

/* --- Header sort (global across invoice/client tables): clickable th inherits its color (no default purple <a>) --- */
.sort-link {
    color: inherit; text-decoration: none;
    display: inline-flex; align-items: center; gap: 4px;
    cursor: pointer; user-select: none;
}
.sort-link:hover { color: var(--primary); text-decoration: none; }
.sort-arrow { font-size: 11px; opacity: 0.4; transition: opacity .15s; }
.sort-arrow-active { opacity: 1; color: var(--primary); font-weight: 700; }
.sort-link:hover .sort-arrow-idle { opacity: 0.7; }

/* --- Combined collapsible filter panel (search + tag + amount + issued + due) --- */
.invoice-filters {
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: 8px; padding: 0; margin-bottom: 14px;
}
.invoice-filters > summary,
.invoice-filters-summary {
    cursor: pointer; padding: 10px 16px 10px 14px; font-size: 13px; font-weight: 600;
    color: var(--text-muted); list-style: none;
    display: flex; align-items: center; gap: 8px;
}
.invoice-filters > summary::-webkit-details-marker { display: none; }
.invoice-filters > summary::after {
    content: '▸'; display: inline-block; margin-left: auto;
    transition: transform .15s;
}
.invoice-filters[open] > summary::after { transform: rotate(90deg); }
.invoice-filters[open] > summary {
    color: var(--text); border-bottom: 1px solid var(--border);
}
.invoice-filter-active-count {
    display: inline-flex; align-items: center;
    padding: 2px 8px; border-radius: 999px;
    background: var(--accent-light); color: var(--primary);
    border: 1px solid var(--accent-border);
    font-size: 12px; font-weight: 600; margin-left: 2px;
}
.invoice-filters-form { padding: 16px; }
.invoice-filter-row {
    display: grid; grid-template-columns: repeat(4, 1fr);
    gap: 16px; margin-bottom: 14px;
}
.invoice-filter-row:last-of-type { margin-bottom: 0; }
.invoice-filter-search-field { grid-column: 1 / -1; }   /* Search row spans the full row */
.invoice-filter-main-row {
    grid-template-columns:
        minmax(150px, 0.9fr)
        minmax(250px, 1.35fr)
        minmax(250px, 1.35fr)
        minmax(108px, 0.5fr)
        minmax(108px, 0.5fr);
    gap: 14px;
}
.invoice-filter-main-row:not(:has(.invoice-filter-tag-cell)) {
    grid-template-columns:
        minmax(150px, 0.9fr)
        minmax(250px, 1.35fr)
        minmax(250px, 1.35fr)
        minmax(108px, 0.5fr);
}
/* Non-main filter rows that omit Tag should not reserve a dead 4th-column gap.
   :has() supported in all modern browsers Duefy targets. */
.invoice-filter-row:not(:has(.invoice-filter-tag-cell)):not(.invoice-filter-main-row) {
    grid-template-columns: repeat(3, 1fr);
}
@media (max-width: 980px) and (min-width: 769px) {
    .invoice-filter-main-row,
    .invoice-filter-main-row:not(:has(.invoice-filter-tag-cell)) {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}
@media (max-width: 768px) {
    .invoice-filter-row,
    .invoice-filter-row:not(:has(.invoice-filter-tag-cell)),
    .invoice-filter-main-row,
    .invoice-filter-main-row:not(:has(.invoice-filter-tag-cell)) {
        grid-template-columns: 1fr;
    }
}
.invoice-filter-field label {
    display: block; font-size: 11px; font-weight: 600;
    color: var(--text-muted); text-transform: uppercase;
    letter-spacing: .04em; margin-bottom: 4px;
}
.invoice-filter-pair {
    display: flex; align-items: center; gap: 6px;
}
.invoice-filter-pair .date-display-wrap {
    flex: 1;
    min-width: 0;
    --date-picker-hit-area: 34px;
}
.invoice-filter-pair input {
    flex: 1; min-width: 0;
    padding: 6px 10px; font-size: 13px;
    background: var(--bg-card); color: var(--text);
    border: 1px solid var(--border); border-radius: 6px;
}
.invoice-filter-pair span { color: var(--text-muted); font-size: 13px; }
.invoice-filter-select {
    width: 100%; padding: 6px 10px; font-size: 13px;
    background: var(--bg-card); color: var(--text);
    border: 1px solid var(--border); border-radius: 6px;
}
.invoice-filter-select:disabled { opacity: 0.6; cursor: not-allowed; }
.invoice-filter-actions { display: flex; gap: 8px; margin-top: 14px; margin-left: -2px; }

/* === Days column (derived: today - due_date) === */
.invoice-days {
    display: inline-block; padding: 2px 8px;
    font-size: 12px; font-weight: 600;
    border-radius: 999px; white-space: nowrap;
}
.invoice-days-overdue   { background: var(--status-danger-bg);  color: var(--status-danger-fg); }
.invoice-days-due-today { background: var(--status-warning-bg); color: var(--status-warning-fg); }
.invoice-days-future    { background: var(--bg-tertiary);       color: var(--text-muted); }
.invoice-days-muted     { color: var(--text-muted); }

/* === Custom tag-filter dropdown (multi-select) ===
   Replaces native <select> because Chrome ignores <option style="background">.
   Closed trigger = label + caret (no swatch — clean). Open menu = checkbox +
   swatch + name per row; multi-select. Compact, same height as adjacent inputs. */
.tag-dropdown {
    position: relative;
    width: 100%;
}
.tag-dropdown-trigger {
    /* Filter-row sibling inputs (.invoice-filter-pair input, padding 6px 10px,
       font 13px, border 1px) render at ~32px in Chrome. Set the same explicit
       height + line-height:1 + zero vertical padding so the button matches
       pixel-perfect instead of relying on Chrome's button-vs-input metrics. */
    appearance: none;
    -webkit-appearance: none;
    box-sizing: border-box;
    height: 32px;
    display: inline-flex; align-items: center; gap: 8px;
    width: 100%;
    padding: 0 10px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    cursor: pointer;
    font-size: 13px;
    font-family: inherit;
    color: var(--text);
    text-align: left;
    line-height: 1;
    margin: 0;
}
.tag-dropdown-trigger:hover { border-color: var(--text-muted); }
.tag-dropdown.is-open .tag-dropdown-trigger {
    border-color: var(--primary);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 18%, transparent);
}
.tag-dropdown-label {
    flex: 1; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    color: var(--text-muted);
}
.tag-dropdown.is-open .tag-dropdown-label,
.tag-dropdown-label:not(:empty):not([data-tag-label="All tags"]) {
    color: var(--text);
}
.tag-dropdown-caret {
    color: var(--text-muted); font-size: 11px; line-height: 1;
    transition: transform .15s;
}
.tag-dropdown.is-open .tag-dropdown-caret { transform: rotate(180deg); }

.tag-dropdown-swatch {
    --tag-color: var(--text-muted);
    /* Empty <span> has 0-width content; with flex-basis:auto the flex algorithm
       collapsed it to a thin sliver. Use explicit basis + min-width + inline-block
       so the swatch renders as a true 12×12 circle. */
    display: inline-block;
    flex: 0 0 12px;
    width: 12px; height: 12px;
    min-width: 12px;
    border-radius: 50%;
    background: var(--tag-color);
    border: 1px solid color-mix(in srgb, var(--tag-color) 70%, #000 30%);
}

.tag-dropdown-menu {
    position: absolute; left: 0; right: 0;
    top: calc(100% + 4px);
    min-width: 180px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.12);
    padding: 4px;
    z-index: 100;
    max-height: 280px;
    overflow-y: auto;
}
.tag-dropdown-item {
    /* Same appearance:none strip as trigger — UA button padding bumps height */
    appearance: none;
    -webkit-appearance: none;
    box-sizing: border-box;
    display: flex; align-items: center; gap: 8px;
    width: 100%;
    padding: 7px 10px;
    background: transparent;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 14px;
    font-family: inherit;
    color: var(--text);
    text-align: left;
    line-height: 1.4;
    margin: 0;
}
.tag-dropdown-item:hover { background: var(--bg-tertiary); }
.tag-dropdown-item.is-selected {
    background: color-mix(in srgb, var(--primary) 8%, transparent);
}
/* Check-mark on the RIGHT of every menu item — pushed right by margin-left:auto
   in the flex row. Only shown when .is-selected; doesn't reserve space when
   hidden so unselected rows look clean (swatch + name with no trailing gap). */
.tag-dropdown-check-mark {
    flex: 0 0 14px;
    width: 14px; height: 14px;
    margin-left: auto;       /* push to far right of the flex row */
    display: none;           /* fully removed when not selected */
    align-items: center; justify-content: center;
    color: var(--primary);
}
.tag-dropdown-item.is-selected .tag-dropdown-check-mark {
    display: inline-flex;
}
.tag-dropdown-name {
    flex: 1; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tag-dropdown-divider {
    height: 1px; background: var(--border);
    margin: 4px 0;
}
.tag-dropdown-clear {
    display: block; width: 100%;
    padding: 7px 10px;
    background: transparent; border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 13px;
    color: var(--text-muted);
    text-align: left;
}
.tag-dropdown-clear:hover { background: var(--bg-tertiary); color: var(--primary); }

/* Source reuses the tag dropdown shell, but is single-select and text-only.
   The menu keeps its left edge aligned with the trigger, while using a wider
   fixed menu so labels like "PDF / Photo" stay readable. */
.source-dropdown .tag-dropdown-menu {
    right: auto;
    width: 180px;
    max-height: min(72vh, 620px);
}
.source-dropdown-section-label {
    padding: 6px 10px 3px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.source-dropdown-name {
    flex: 1; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* === Inline "X unpaid" subtext inside the Amount cell (partial state) === */
.invoice-amount-unpaid {
    font-size: 11.5px; color: var(--danger); font-weight: 600;
    margin-top: 2px;
}

/* === Client list — search reuses invoice-search-wrap/input plus new CSS === */
.client-search-form { margin-bottom: 14px; max-width: 480px; }

.client-avatar-cell { width: 44px; padding-right: 4px; }
.client-avatar {
    display: inline-flex; align-items: center; justify-content: center;
    width: 32px; height: 32px;
    border-radius: 50%;
    background: var(--accent-light);
    color: var(--primary);
    font-weight: 700; font-size: 13px;
}

/* Force sort-link to nowrap — prevents multi-word headers like 'Invoices' / 'Outstanding' from wrapping */
.client-table thead th .sort-link,
.invoice-table thead th .sort-link { white-space: nowrap; }

/* Unified alignment: Outstanding right (amount alignment) / Overdue/Invoices/Score centered (short numbers / pills) /
   Last paid left (date); Company/Contact/Email default left (text). */
.client-table th[data-col="outstanding"],
.client-table .client-amount-cell {
    text-align: right;
    font-variant-numeric: tabular-nums;
}
.client-table th[data-col="overdue"],
.client-table th[data-col="invoices"],
.client-table th[data-col="score"],
.client-table td[data-col="overdue"],
.client-table td[data-col="invoices"],
.client-table td[data-col="score"] {
    text-align: center;
}
/* sort-link in centered columns also needs justify center, otherwise the ↕ arrow drifts from the title */
.client-table th[data-col="overdue"]  .sort-link,
.client-table th[data-col="invoices"] .sort-link,
.client-table th[data-col="score"]    .sort-link { justify-content: center; }
/* Outstanding right-aligned: sort-link justify-end */
.client-table th[data-col="outstanding"] .sort-link { justify-content: flex-end; }

.client-table .client-amount-cell { font-weight: 600; }

/* Quick-filter bar above the client table — instant toggle links (no Apply). */
.client-filter-bar {
    display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
    margin: 0 0 14px;
}
.client-filter-label {
    font-size: 12px; font-weight: 600; color: var(--text-muted);
    text-transform: uppercase; letter-spacing: .04em;
}
.client-filter-sep { width: 1px; height: 18px; background: var(--border); margin: 0 2px; }
.client-filter-chip {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 4px 12px; border-radius: 999px;
    background: var(--bg-tertiary); color: var(--text-muted);
    font-size: 13px; font-weight: 500; text-decoration: none;
    border: 1px solid transparent;
    transition: background .12s, color .12s, border-color .12s;
}
.client-filter-chip:hover { background: var(--surface-2); color: var(--ink); border-color: var(--border); }
.client-filter-chip.is-active { background: var(--accent-light); color: var(--primary); border-color: var(--primary); }
.client-filter-grade { min-width: 30px; justify-content: center; font-weight: 700; }
.client-filter-clear { font-size: 13px; color: var(--text-muted); text-decoration: underline; margin-left: 4px; }
.client-filter-clear:hover { color: var(--ink); }

/* Invoice list scoped to one client (deep-link from the Clients page). */
.invoice-client-scope {
    display: flex; align-items: center; gap: 8px;
    padding: 8px 14px; margin: 0 0 12px;
    background: var(--accent-light); border: 1px solid var(--primary);
    border-radius: 8px; font-size: 14px; color: var(--ink);
}
.invoice-client-scope-clear {
    margin-left: auto; display: inline-flex; align-items: center; gap: 3px;
    font-size: 13px; color: var(--primary); text-decoration: none; font-weight: 600;
}
.invoice-client-scope-clear:hover { text-decoration: underline; }

/* Overdue number = link to invoice list (red chip) */
.client-overdue-badge {
    display: inline-block;
    padding: 2px 8px;
    background: var(--status-danger-bg);
    color: var(--status-danger-fg);
    border-radius: 999px;
    font-size: 12px; font-weight: 700;
    text-decoration: none;
}
.client-overdue-badge:hover { filter: brightness(0.92); text-decoration: none; }

/* Invoice count = link to invoice list */
.client-invoice-count {
    color: var(--primary); text-decoration: none; font-weight: 600;
}
.client-invoice-count:hover { text-decoration: underline; }

/* Horizontal scroll wrap — fallback for narrow viewports. Padding tightened
   below so common desktop widths (≥1280) fit naturally without ever showing
   the scrollbar; scroll only kicks in on laptop-narrow / tablet. */
.client-table-wrap,
.invoice-table-wrap,
.reports-table-wrap,
.client-view-table-wrap { overflow-x: auto; margin: 0 -4px; padding: 0 4px; }

/* invoice/view empty-state for the "Reminder steps" section — when the invoice
   is pending or has no sequence steps yet, give the user the next action right
   in the empty slot instead of just a muted "nothing here" line. */
.iv-steps-empty { padding: 8px 0; }
.iv-steps-empty > p { margin: 0 0 12px; color: var(--text-muted); }

/* reports index empty state — retained for detail pages with no invoice history. */
.reports-empty { max-width: 640px; margin: 0 auto; text-align: left; padding: 28px; }
.reports-empty > h2 { margin: 0 0 10px; }
.reports-empty > p  { margin: 0 0 18px; line-height: 1.55; color: var(--text-muted); }
.reports-empty-actions { display: flex; gap: 12px; flex-wrap: wrap; }

/* Tighter padding than the global .table (11px 12px) so 11 columns fit on a
   standard 1280-wide desktop without horizontal scroll. */
.client-table th, .client-table td { padding: 10px 8px; }

/* Pin the row-actions (Edit) column to the right edge so it's never clipped
   when the table overflows its wrapper — happens on laptop-narrow windows or
   when the Pro "Score" column is shown. Opaque background lets the scrolled
   cells slide underneath; the soft left shadow only reads when content does. */
.client-table th[data-col="_actions"],
.client-table td[data-col="_actions"] {
    position: sticky;
    right: 0;
    z-index: 1;
    background: var(--bg-card);
    box-shadow: -8px 0 8px -8px rgba(17, 24, 39, .12);
}
.client-table tbody tr:hover td[data-col="_actions"] { background: var(--bg); }

/* Email cell — long emails get ellipsis */
.client-table .client-email-cell {
    max-width: 160px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.client-table .client-lastpaid-cell {
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
}

/* === Last-reminder relative time === */
.invoice-last-sent {
    font-size: 12px; color: var(--text-muted, #6B7280);
    cursor: help;
}

/* === Column configurator: toolbar + resize handle + modal === */
.invoice-table-toolbar {
    display: flex; justify-content: flex-end;
    padding: 8px 0;
}
/* position:relative anchors the absolute .col-resize-handle to each th so the
   drag-to-resize grip sits on the column's right edge. Every resizable table
   needs it (the client-view embed shipped without and its grips were dead). */
.invoice-table thead th, .client-table thead th,
#cv-invoices-table thead th { position: relative; }

/* The 6-column client-view embed sums to well under its card width —
   table-columns.js pins table width to the px sum (so drags are exact), which
   left a dead right half. min-width !important outranks the inline style;
   fixed layout distributes the surplus across columns, drags still work. */
#cv-invoices-table { min-width: 100% !important; }
.cv-invoices-head-actions { display: inline-flex; align-items: center; gap: 12px; }
/* Convention: numeric columns right-aligned (so amounts read magnitude at a glance) + tabular-nums (equal-width digits). Text columns left-aligned. */
.invoice-table th[data-col="amount"],
.invoice-table td[data-col="amount"] {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;        /* "USD 3,200.00" stays on one line; the unpaid sub-div breaks naturally */
}
.invoice-table th[data-col="amount"] .sort-link { justify-content: flex-end; }
/* Date columns stay left-aligned, but digits use tabular-nums (equal-width 2026-05-25 scans better) */
.invoice-table td[data-col="issued"],
.invoice-table td[data-col="due"] {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;        /* "2026-05-15" never breaks across YYYY-MM- / -DD */
}

/* === Row tidiness ===
   (A) Center every cell vertically so single-line cells (dates, amount, status)
       line up with taller rows that carry a sub-line or a stacked badge, instead
       of clinging to the top edge.
   (B) Keep the invoice number on one line so a long number never breaks
       mid-string ("INV-" / "0033…"); in auto table-layout the column widens to
       fit rather than wrapping.
   (C) Stack the source / recurring / transfer badges onto their own line below
       the number so every row has the same number-then-badges structure (rather
       than the badge sometimes sitting inline, sometimes wrapping). */
.invoice-table td { vertical-align: middle; }
/* Number on one line, clipped with an ellipsis when it can't fit the (fixed-layout)
   column — so it never breaks mid-string and never overflows into the Client cell.
   The full number is in the link's title attribute for hover. Real invoice numbers
   are short and never truncate; only pathologically long ones get the ellipsis. */
.invoice-table td[data-col="invoice_number"] > a:first-child {
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-variant-numeric: tabular-nums;
}
/* Source / transfer badges drop to their own line below the number (width:max-content
   keeps each pill hugging its label). The small recurring icon stays inline beside
   the number — it annotates the number itself. */
.invoice-table td[data-col="invoice_number"] .source-badge,
.invoice-table td[data-col="invoice_number"] .bt-pending-badge {
    display: block;
    width: max-content;
    margin-top: 4px;
}
/* Column-width resize handle — default shows a 1px light-grey vertical line as a hint;
   on hover/drag it grows to a 5px purple bar to make the affordance clear. */
.col-resize-handle {
    position: absolute; right: 0; top: 25%; bottom: 25%;
    width: 5px;
    cursor: col-resize;
    user-select: none;
}
/* Central 1px line — uses ::before, decoupled from the 5px hit zone, widens on hover */
.col-resize-handle::before {
    content: '';
    position: absolute;
    left: 2px; top: 0; bottom: 0;
    width: 1px;
    background: var(--border);
    transition: background .15s, width .15s, left .15s;
}
.col-resize-handle:hover::before,
body.col-resizing .col-resize-handle::before {
    background: var(--primary, var(--primary));
    width: 3px;
    left: 1px;
}
body.col-resizing { user-select: none; cursor: col-resize !important; }

/* === Columns config modal (dark-mode aware) ===
   layout: uses CSS grid (not flex) to force [drag | checkbox | label-flex] three columns,
   avoiding the visual bug where, in some UAs, flex pushes the label right and looks like it overflows the modal. */
.cols-modal {
    position: fixed; inset: 0; z-index: 9000;
    display: flex; align-items: center; justify-content: center;
}
.cols-modal[hidden] { display: none !important; }
.cols-modal-overlay {
    position: absolute; inset: 0;
    background: rgba(0,0,0,0.55);
    backdrop-filter: blur(2px);
}
.cols-modal-panel {
    position: relative;
    background: var(--bg-card); color: var(--text);
    border: 1px solid var(--border);
    border-radius: 12px;
    width: min(380px, calc(100% - 32px));
    max-height: 80vh; overflow: auto;
    padding: 20px 22px;
    box-shadow: 0 20px 50px rgba(0,0,0,0.35);
}
.cols-modal-head {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 4px;
}
.cols-modal-head h3 { margin: 0; font-size: 16px; font-weight: 700; color: var(--text); }
.cols-modal-close {
    background: none; border: none; cursor: pointer;
    font-size: 22px; line-height: 1; color: var(--text-muted); padding: 2px 6px;
    border-radius: 4px;
}
.cols-modal-close:hover { color: var(--text); background: var(--bg-tertiary); }
.cols-modal-hint { font-size: 12px; color: var(--text-muted); margin: 0 0 14px; }
.cols-modal-list { list-style: none; padding: 0; margin: 0; }
.cols-modal-item {
    display: grid;
    grid-template-columns: 16px 18px 1fr;   /* drag-handle | checkbox | label fills rest */
    align-items: center;
    gap: 10px;
    padding: 8px 12px; margin-bottom: 4px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    transition: background .12s, border-color .12s;
}
.cols-modal-item:hover { background: var(--bg-tertiary); }
.cols-modal-item.dragging {
    opacity: 0.5; border-color: var(--primary); border-style: dashed;
}
.cols-modal-drag {
    color: var(--text-muted); cursor: grab; user-select: none;
    display: inline-flex; align-items: center; justify-content: center;
    line-height: 1;
}
.cols-modal-drag:active { cursor: grabbing; }
/* Touch reorder: native HTML5 drag never fires on touch, so show up/down move
   buttons in the column modal (drag handle hidden there). Desktop keeps drag. */
.cols-modal-move { display: none; grid-column: 1; gap: 4px; }
.cols-modal-move button {
    display: inline-flex; align-items: center; justify-content: center;
    width: 24px; height: 28px; padding: 0;
    border: 1px solid var(--border); border-radius: 6px;
    background: var(--bg-card); color: var(--text);
    font-size: 14px; line-height: 1; cursor: pointer;
}
.cols-modal-move button:disabled { opacity: .4; cursor: default; }
@media (pointer: coarse) {
    .cols-modal-item { grid-template-columns: 56px 18px 1fr; }
    .cols-modal-item .cols-modal-drag { display: none; }
    .cols-modal-move { display: inline-flex; }
}
.cols-modal-row {
    display: contents;   /* label no longer acts as a flex container; input/span fall straight into the .cols-modal-item grid */
    cursor: pointer;
}
.cols-modal-item input[type="checkbox"] {
    cursor: pointer; margin: 0;
    grid-column: 2;
    accent-color: var(--primary);
}
.cols-modal-row > span {
    grid-column: 3;
    font-size: 14px; color: var(--text);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cols-modal-actions { margin-top: 14px; display: flex; justify-content: flex-end; }

/* Reset to defaults: 5-second Undo toast (Gmail-style) — applies immediately, can Undo within 5s */
.cols-undo-toast {
    position: fixed;
    bottom: 24px; left: 50%; transform: translateX(-50%);
    z-index: 10001;
    display: inline-flex; align-items: center; gap: 14px;
    background: var(--toast-bg); color: var(--toast-fg);
    border: 1px solid var(--toast-border);
    padding: 12px 18px;
    border-radius: 8px;
    font-size: 14px;
    box-shadow: 0 4px 14px rgba(0,0,0,0.25);
    animation: cols-undo-slide-in 0.2s ease-out;
}
@keyframes cols-undo-slide-in {
    from { opacity: 0; transform: translate(-50%, 10px); }
    to   { opacity: 1; transform: translate(-50%, 0); }
}
.cols-undo-btn {
    background: var(--toast-action-bg); color: var(--toast-action-fg);
    border: none; cursor: pointer;
    padding: 5px 12px; border-radius: 4px;
    font-weight: 600; font-size: 13px;
}
.cols-undo-btn:hover { background: var(--toast-action-hover); }
.cols-undo-countdown { opacity: 0.6; font-size: 12px; }

/* --- Tags column: compact chip inline within list rows ---
   --tag-color is set inline per-chip (the only inline style left, since tag colors
   come from user data). The rgba()/hex+alpha-suffix variants used to live inline. */
.invoice-tags-cell { max-width: 220px; }
.invoice-tag-chip {
    display: inline-flex; align-items: center;
    padding: 1px 8px; margin: 2px 4px 2px 0;
    font-size: 11px; font-weight: 600; line-height: 1.5;
    border: 1px solid; border-radius: 999px;
    text-decoration: none;
    transition: filter .12s;
    color: var(--tag-color, var(--text));
    background: color-mix(in srgb, var(--tag-color, var(--text)) 10%, transparent);
    border-color: color-mix(in srgb, var(--tag-color, var(--text)) 40%, transparent);
}
.invoice-tag-chip:hover { filter: brightness(0.92); }

/* --- Task 5: tags --- */
.tag-chip {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 3px 10px; border-radius: 999px;
    font-size: 12px; font-weight: 600; line-height: 1.6;
}
.tag-color-dot {
    width: 9px; height: 9px; border-radius: 50%;
    display: inline-block; flex-shrink: 0;
}
.tag-remove {
    background: none; border: none; cursor: pointer;
    font-size: 14px; line-height: 1; color: inherit; padding: 0;
    opacity: .7;
}
.tag-remove:hover { opacity: 1; }
.invoice-tags-section { position: relative; }
.invoice-tags-display {
    display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
}
.tag-add-btn {
    background: none; border: 1px dashed var(--border);
    border-radius: 999px; padding: 3px 12px;
    font-size: 12px; cursor: pointer; color: var(--text-muted);
}
.tag-add-btn:hover { border-color: var(--primary); color: var(--primary); }
.tag-picker {
    margin-top: 12px; border: 1px solid var(--border);
    border-radius: var(--radius); padding: 8px;
    max-width: 280px; box-shadow: var(--shadow);
}
.tag-picker-item {
    display: flex; align-items: center; gap: 8px;
    padding: 6px 8px; border-radius: 6px;
    font-size: 13px; cursor: pointer;
}
.tag-picker-item:hover { background: var(--bg); }
.tag-picker-empty { padding: 6px 8px; font-size: 13px; }
.tag-picker-create-toggle {
    background: none; border: none; padding: 0;
    font-size: 13px; color: var(--primary); cursor: pointer;
    font-weight: 500;
}
.tag-picker-create-toggle:hover { text-decoration: underline; }
.tag-picker-create-form {
    margin-top: 6px; padding: 8px;
    background: var(--bg); border-radius: 6px;
    display: flex; flex-direction: column; gap: 8px;
}
.tag-picker-create-form input[type="text"] {
    width: 100%; padding: 6px 8px;
    font-size: 13px; border: 1px solid var(--border);
    border-radius: 4px; background: var(--bg-card); color: var(--text);
    box-sizing: border-box;
}
.tag-picker-color-row {
    display: flex; gap: 6px; flex-wrap: wrap;
}
.tag-picker-color-swatch {
    width: 20px; height: 20px; border-radius: 50%;
    cursor: pointer; border: 2px solid transparent;
    box-shadow: 0 0 0 1px var(--border);
}
.tag-picker-color-swatch.selected {
    border-color: var(--bg-card);
    box-shadow: 0 0 0 2px var(--primary);
}
.tag-picker-footer {
    border-top: 1px solid var(--border);
    margin-top: 6px; padding-top: 8px; font-size: 13px;
    display: flex; justify-content: space-between; align-items: center;
    gap: 12px;
}
.tag-card-desc { margin: 6px 0 22px; }
.tag-create-form { max-width: 420px; margin-top: 4px; }
.tag-suggestions {
    margin-top: 22px;
    padding-top: 18px;
    border-top: 1px solid var(--border);
}
.tag-suggestions-label {
    font-size: 12px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.6px;
    margin-bottom: 10px;
}
.tag-suggestions-chips {
    display: flex; flex-wrap: wrap; gap: 8px;
}
.tag-suggestion-chip {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 4px 12px 4px 10px;
    border-radius: 999px;
    font-size: 13px; font-weight: 500;
    cursor: pointer; background: transparent;
    transition: filter 100ms ease;
}
.tag-suggestion-chip:hover:not(:disabled) { filter: brightness(0.95); }
.tag-suggestion-chip:disabled { opacity: 0.5; cursor: default; }
.tag-reorder-hint { margin: -4px 0 14px; font-size: 12px; }
.tag-drag-handle {
    color: var(--text-muted);
    cursor: grab;
    padding: 0 4px;
    display: inline-flex; align-items: center;
    line-height: 0;
}
.tag-drag-handle:active { cursor: grabbing; }
.tag-manage-row.tag-dragging {
    opacity: 0.4;
    background: var(--accent-light);
    border-radius: 6px;
}
.tag-color-choices { display: flex; gap: 10px; flex-wrap: wrap; }
.tag-color-swatch {
    width: 28px; height: 28px; border-radius: 50%;
    cursor: pointer; border: 2px solid transparent;
    box-shadow: 0 0 0 1px var(--border);
    /* rendered as a <button> for keyboard access — strip native chrome */
    padding: 0; appearance: none; -webkit-appearance: none;
}
.tag-color-swatch.selected {
    border-color: var(--bg-card);
    box-shadow: 0 0 0 2px var(--primary);
}
.tag-manage-list { display: flex; flex-direction: column; gap: 10px; }
.tag-manage-row {
    padding: 8px 0; border-bottom: 1px solid var(--border);
}
.tag-row-view {
    display: flex; align-items: center; gap: 14px;
    min-height: 36px;
}
.tag-manage-row[data-can-reorder="1"] .tag-row-view {
    cursor: grab;
}
.tag-manage-row[data-can-reorder="1"].tag-dragging .tag-row-view {
    cursor: grabbing;
}
.tag-usage { font-size: 13px; margin-left: auto; }
.tag-row-actions {
    display: flex; align-items: center; gap: 6px;
    margin-left: 4px;
    cursor: default;
}
.tag-row-action {
    min-width: 32px; height: 32px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-card);
    color: var(--text-muted);
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    padding: 0 9px;
    cursor: pointer;
    font-size: 13px; font-weight: 600;
}
.tag-row-action:hover {
    color: var(--text);
    background: var(--bg-tertiary);
}
.tag-row-delete-trigger {
    padding: 0;
    width: 32px;
}
.tag-row-delete-trigger:hover {
    color: var(--status-danger-fg);
    background: var(--status-danger-bg);
    border-color: color-mix(in srgb, var(--status-danger-fg) 35%, var(--border));
}
.tag-row-edit {
    margin-top: 8px;
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 10px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-tertiary);
}
.tag-row-edit[hidden] { display: none; }
.tag-edit-name-input {
    width: min(280px, 100%);
}
.tag-edit-colors {
    display: flex; gap: 7px; flex-wrap: wrap;
}
.tag-edit-color-swatch {
    width: 22px; height: 22px;
    border-radius: 999px;
    border: 2px solid transparent;
    box-shadow: 0 0 0 1px var(--border);
    cursor: pointer;
}
.tag-edit-color-swatch.selected {
    border-color: var(--bg-card);
    box-shadow: 0 0 0 2px var(--primary);
}
.tag-edit-actions {
    display: flex; align-items: center; gap: 8px;
}

/* --- Task 7: partial payments --- */
.payment-status-card { display: flex; flex-direction: column; gap: 14px; }
.payment-amounts { display: flex; flex-direction: column; gap: 6px; }
.payment-amount-row {
    display: flex; justify-content: space-between; font-size: 14px;
}
.payment-progress-bar {
    height: 10px; background: #E5E7EB;
    border-radius: 5px; overflow: hidden;
}
.payment-progress-fill {
    height: 100%; background: var(--success);
    border-radius: 5px; transition: width .3s;
}
.partial-payment-history h4 {
    margin: 0 0 8px; font-size: 14px;
}
.pp-row {
    display: flex; gap: 12px; flex-wrap: wrap; align-items: baseline;
    font-size: 13px; padding: 6px 0;
    border-bottom: 1px solid var(--border);
}
.pp-date   { color: var(--text-muted); min-width: 90px; }
.pp-method { font-weight: 600; }
.pp-amount { color: var(--success); font-weight: 700; margin-left: auto; }
.pp-note   { width: 100%; font-size: 12px; }

/* --- Task 8: bank reconciliation --- */
.recon-summary {
    display: flex; gap: 32px; flex-wrap: wrap;
}
.recon-summary-item { display: flex; flex-direction: column; gap: 2px; }
.recon-summary-label {
    font-size: 12px; color: var(--text-muted);
    text-transform: uppercase; letter-spacing: .04em;
}
.recon-table-head {
    display: grid; grid-template-columns: 2fr 1.2fr 2fr;
    gap: 16px; padding: 8px 12px;
    font-size: 12px; font-weight: 700; text-transform: uppercase;
    color: var(--text-muted); border-bottom: 2px solid var(--border);
}
.recon-row {
    display: grid; grid-template-columns: 2fr 1.2fr 2fr;
    gap: 16px; padding: 14px 12px; align-items: center;
    border-bottom: 1px solid var(--border);
}
.recon-row-confirmed { background: var(--status-success-bg); }
.recon-bank-date { font-size: 12px; color: var(--text-muted); }
.recon-bank-desc { font-weight: 600; font-size: 14px; }
.recon-bank-amount { font-weight: 700; color: var(--text); }
.recon-bank-ref { font-size: 12px; }
.recon-conf-bar {
    height: 8px; background: #E5E7EB;
    border-radius: 4px; overflow: hidden;
}
.recon-conf-fill { height: 100%; border-radius: 4px; }
.recon-conf-high { background: var(--success); }
.recon-conf-mid  { background: var(--warning); }
.recon-conf-low  { background: var(--danger); }
.recon-conf-pct  { font-size: 12px; margin-top: 4px; color: var(--text-muted); }
.recon-conf-none { font-size: 13px; }
.recon-confirmed-tag { font-size: 12px; margin-top: 4px; }
/* Sticky footer: a long statement otherwise scrolls the Confirm button out of
   sight and the matching session ends without posting. Mirrors .review-actionbar. */
.recon-footer-bar {
    position: sticky; bottom: 0; z-index: 5;
    display: flex; align-items: center; gap: 12px; margin-top: 16px;
    background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px;
    padding: 12px 16px; box-shadow: 0 -4px 16px rgba(17,24,39,.06);
}
.recon-footer-hint { flex: 1 1 auto; min-width: 0; font-size: 13px; }
.recon-footer-bar .btn { white-space: nowrap; }
.recon-draft-status { color: var(--success); }
/* Searchable invoice combobox (manual match) */
.recon-combo { position: relative; }
.recon-combo-input {
    width: 100%; min-height: 48px; padding-right: 34px;
    text-overflow: ellipsis; font-variant-numeric: tabular-nums;
}
.recon-combo-clear {
    position: absolute; right: 6px; top: 24px; transform: translateY(-50%);
    width: 24px; height: 24px; padding: 0; line-height: 1;
    border: 0; border-radius: 50%; cursor: pointer;
    background: var(--bg-tertiary); color: var(--text-muted); font-size: 15px;
}
.recon-combo-clear:hover { color: var(--text); }
.recon-combo-list {
    position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 30;
    max-height: 320px; overflow-y: auto;
    background: var(--bg-card); border: 1px solid var(--border); border-radius: 10px;
    box-shadow: 0 8px 24px rgba(17,24,39,.14);
}
.recon-combo-option {
    padding: 9px 12px; font-size: 13px; cursor: pointer;
    font-variant-numeric: tabular-nums;
}
.recon-combo-option.is-active,
.recon-combo-option:hover { background: var(--bg-tertiary); }
.recon-combo-option.is-disabled { color: var(--text-muted); opacity: .6; cursor: not-allowed; }
.recon-combo-empty, .recon-combo-more { padding: 9px 12px; font-size: 12px; color: var(--text-muted); }
/* Mobile bottom tab bar (≤720px) is fixed at bottom:0 — lift the sticky
   footer above it, same as .review-actionbar. */
@media (max-width: 720px) {
    .recon-footer-bar { bottom: calc(72px + env(safe-area-inset-bottom, 0px)); }
}

/* --- Task 9: multi-currency --- */
.dashboard-currency-setting {
    display: flex; align-items: center; gap: 8px;
    font-size: 13px; color: var(--text-muted); margin-bottom: 12px;
}
.dashboard-currency-setting select { width: auto; }
.currency-breakdown {
    margin-top: 12px; padding-top: 12px;
    border-top: 1px solid var(--border);
}
.currency-breakdown-row {
    display: flex; gap: 10px; align-items: baseline;
    font-size: 13px; padding: 3px 0;
}
.cb-currency { font-weight: 700; min-width: 42px; }
.cb-amount   { font-variant-numeric: tabular-nums; }
.cb-converted { margin-left: auto; font-size: 12px; }
.currency-breakdown-more { font-size: 12px; padding: 2px 0; }
.currency-rate-note { margin-top: 6px; font-size: 11px; }

/* stripe-nudge non-owner branch: replaces the legacy inline style="font-size:14px"
   and tightens spacing when paired with the email-owner button */
.stripe-nudge-owner-hint { font-size: 13px; color: var(--text-muted); }

/* --- credit note / reconciliation status badges --- */
.badge-cn-draft   { background: var(--bg-tertiary); color: var(--text-muted); }
.badge-cn-issued  { background: var(--status-info-bg); color: var(--status-info-fg); }
.badge-cn-applied { background: var(--status-success-bg); color: var(--status-success-fg); }
.badge-cn-void    { background: var(--status-danger-bg); color: var(--status-danger-fg); }
.badge-recon-processing { background: var(--status-warning-bg); color: var(--status-warning-fg); }
.badge-recon-done       { background: var(--status-success-bg); color: var(--status-success-fg); }
.badge-recon-failed     { background: var(--status-danger-bg); color: var(--status-danger-fg); }

@media (max-width: 768px) {
    .recon-table-head { display: none; }
    .recon-row {
        grid-template-columns: 1fr; gap: 8px;
        padding: 14px 8px;
    }
    /* nowrap: column + the base flex-wrap:wrap makes a multi-column flow whose
       column sizes to the widest child (the 600px tab row), re-inflating it.
       Single column → children stretch to the container width and scroll. */
    .invoice-list-controls { flex-direction: column; align-items: stretch; flex-wrap: nowrap; }
}

/* ======================================================
   Part 2 — optimization components
   ====================================================== */

/* ----- Trademark symbol ™ (Duefy™ in nav / footer / auth-page logo lockup) ----- */
.brand-tm {
    font-size: 0.55em;
    font-weight: 500;
    vertical-align: super;
    margin-left: 1px;
    opacity: 0.65;
    line-height: 1;
}

/* ----- user dropdown menu (darkMode.md) ----- */
.user-menu { position: relative; }
.user-menu-trigger {
    background: transparent;
    border: 1px solid transparent;
    border-radius: 8px;
    padding: 6px 10px;
    font-size: 14px;
    font-weight: 500;
    color: var(--text);
    cursor: pointer;
    display: inline-flex; align-items: center; gap: 6px;
}
.user-menu-trigger:hover { background: var(--bg-tertiary); border-color: var(--border); }
/* Long names ("Andersjboy 2") used to wrap onto two lines and stretch the navbar. */
.user-menu-name {
    max-width: 160px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Caret now an SVG (was Unicode ▾); transition rotates on open for a clear affordance. */
.user-menu-caret { color: var(--text-muted); transition: transform 0.15s ease; flex-shrink: 0; }
.user-menu.is-open .user-menu-caret { transform: rotate(180deg); }
.user-menu.is-open .user-menu-trigger { background: var(--bg-tertiary); border-color: var(--border); }

/* Discovery dot — small pulsing accent next to the caret while the user hasn't yet
   visited Refer & Earn. Cleared by cSettings::referrals on first visit. */
.user-menu-dot {
    position: absolute; top: 4px; right: 4px;
    width: 8px; height: 8px; border-radius: 50%;
    background: var(--accent, #6366F1);
    box-shadow: 0 0 0 0 rgba(99, 102, 241, 0.55);
    animation: user-menu-dot-pulse 2.2s ease-out infinite;
    pointer-events: none;
}
@keyframes user-menu-dot-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(99, 102, 241, 0.55); }
    70%  { box-shadow: 0 0 0 6px rgba(99, 102, 241, 0); }
    100% { box-shadow: 0 0 0 0 rgba(99, 102, 241, 0); }
}
.user-menu-trigger { position: relative; }
@media (prefers-reduced-motion: reduce) {
    .user-menu-dot { animation: none; }
}

.user-menu-dropdown {
    display: none;
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    min-width: 220px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.08);
    padding: 6px;
    z-index: 100;
}
.user-menu.is-open .user-menu-dropdown { display: block; }

.user-menu-item {
    display: flex; align-items: center; gap: 10px;
    width: 100%;
    padding: 8px 10px;
    border-radius: 6px;
    border: none;
    background: transparent;
    color: var(--text);
    font-size: 14px;
    text-decoration: none;
    cursor: pointer;
    text-align: left;
}
.user-menu-item:hover { background: var(--bg-tertiary); }
.user-menu-icon { color: var(--text-muted); flex-shrink: 0; }
.user-menu-label { flex: 1; }
.user-menu-divider { height: 1px; background: var(--border); margin: 6px 4px; }
.user-menu-item-logout { color: var(--text-muted); }
.user-menu-item-logout:hover { color: var(--text); }
.user-menu-badge {
    background: var(--danger); color: #fff;
    font-size: 10.5px; font-weight: 600;
    padding: 1px 6px; border-radius: 999px;
    margin-left: auto;
}
.user-menu-badge-info    { background: var(--primary); }   /* Info badge (Switch trial plan shows remaining days) */
.user-menu-badge-success { background: var(--success); }   /* Positive badge (Refer & Earn shows current credits) */

/* iOS-ish switch for the Dark Mode toggle row */
.user-menu-switch {
    width: 32px; height: 18px;
    background: var(--border);
    border-radius: 999px;
    position: relative;
    transition: background 0.15s ease;
    flex-shrink: 0;
}
.user-menu-switch-knob {
    position: absolute;
    top: 2px; left: 2px;
    width: 14px; height: 14px;
    background: white;
    border-radius: 50%;
    transition: transform 0.15s ease;
    box-shadow: 0 1px 2px rgba(0,0,0,0.2);
}
.user-menu-item-toggle.is-on .user-menu-switch { background: var(--primary); }
.user-menu-item-toggle.is-on .user-menu-switch-knob { transform: translateX(14px); }

/* ----- Settings → Profile → Appearance card ----- */
.appearance-options {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;
    margin-top: 12px;
}
.appearance-option {
    display: flex; flex-direction: column; align-items: center; gap: 8px;
    padding: 16px 12px;
    border: 1.5px solid var(--border);
    border-radius: 10px;
    cursor: pointer;
    transition: border-color 0.12s, background 0.12s;
    text-align: center;
}
.appearance-option:hover { border-color: var(--primary); }
.appearance-option input[type="radio"] {
    /* Visually hidden but reachable by `:has(input:checked)` selectors below.
       Must reset width/height — the global `input { width: 100% }` would otherwise
       stretch this absolute-positioned radio to its offsetParent (body) and create
       horizontal page overflow. */
    position: absolute;
    width: 0;
    height: 0;
    opacity: 0;
    pointer-events: none;
}
.appearance-option:has(input:checked) {
    border-color: var(--primary);
    background: rgba(79, 70, 229, 0.05);
}
.appearance-icon { color: var(--text-muted); display: inline-flex; }
.appearance-option:has(input:checked) .appearance-icon { color: var(--primary); }
.appearance-label { font-size: 14px; font-weight: 500; }
@media (max-width: 600px) {
    .appearance-options { grid-template-columns: 1fr; }
}

/* ----- nav search button ----- */
.nav-search-btn {
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 6px 12px;
    font-size: 13px;
    color: var(--text-muted);
    cursor: pointer;
    display: inline-flex; align-items: center; gap: 6px;
    /* Don't let a crowded nav (trial badge + long name + bell) squeeze the
       button and wrap "Search ⌘K" onto a second line, growing it taller. */
    flex: 0 0 auto;
    white-space: nowrap;
}
.nav-search-hint { white-space: nowrap; }
.nav-search-btn:hover { border-color: var(--primary); color: var(--text); }
.nav-search-hint kbd {
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: 4px; padding: 1px 5px; font-size: 11px;
}

/* ----- global search modal ----- */
.global-search-box {
    background: var(--bg-card); color: var(--text);
    border-radius: 14px; width: 100%; max-width: 600px;
    box-shadow: 0 24px 60px rgba(0,0,0,.3);
    overflow: hidden; position: relative; align-self: flex-start;
}
.global-search-input-wrap {
    display: flex; align-items: center; gap: 10px;
    padding: 14px 18px; border-bottom: 1px solid var(--border);
}
.global-search-icon { display: inline-flex; align-items: center; color: var(--text-muted); }
#global-search-input {
    flex: 1; border: none; padding: 4px 0; font-size: 16px;
    background: transparent; color: var(--text);
}
#global-search-input:focus { outline: none; box-shadow: none; }
/* Now a real <button>; reset the browser defaults that would otherwise show through */
.global-search-esc {
    background: var(--bg-tertiary); border: 1px solid var(--border);
    border-radius: 5px; padding: 2px 8px; font-size: 12px; cursor: pointer;
    color: var(--text-muted);
    font-family: inherit; line-height: 1.4;
}
.global-search-results { max-height: 60vh; overflow-y: auto; }
/* Command-palette footer — nav hints + keyboard-shortcuts entry (replaces the
   old floating bottom-center hint toast that overlapped page content). */
.global-search-footer {
    display: flex; align-items: center; gap: 14px;
    padding: 9px 16px; border-top: 1px solid var(--border);
    background: var(--bg);
}
.global-search-footer .gsf-hint {
    display: inline-flex; align-items: center; gap: 4px;
    font-size: 12px; color: var(--text-muted);
}
.global-search-footer .gsf-shortcuts {
    margin-left: auto;
    display: inline-flex; align-items: center; gap: 6px;
    background: none; border: none; cursor: pointer; font: inherit;
    font-size: 12px; color: var(--text-muted);
    padding: 3px 6px; border-radius: 6px;
}
.global-search-footer .gsf-shortcuts:hover { color: var(--text); background: var(--bg-tertiary); }
.global-search-footer kbd {
    background: var(--bg-tertiary); border: 1px solid var(--border); border-radius: 4px;
    padding: 1px 5px; font-size: 11px; font-family: monospace; color: var(--text);
}
/* Touch devices have no physical keyboard, so the ⌘K hint, the result-row
   shortcut badges (n / c / g·d) and the ↵/↑↓/? footer are noise — hide them. */
@media (pointer: coarse) {
    .global-search-footer { display: none; }
    #global-search-modal kbd,
    #global-search-modal .kbd-chord { display: none; }
}
.search-quick-actions { padding: 6px 10px 10px; }
/* Raycast-style group headers */
.search-group { margin-top: 8px; }
.search-group:first-child { margin-top: 0; }
.search-group-label {
    font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
    color: var(--text-muted); padding: 6px 14px 4px;
}
.search-quick-item, .search-result-item {
    display: flex; align-items: center; gap: 12px;
    padding: 11px 14px; border-radius: 8px;
    text-decoration: none; color: var(--text);
}
.search-quick-item:hover, .search-quick-item.search-result-selected,
.search-result-item:hover, .search-result-item.search-result-selected {
    background: var(--bg-tertiary); text-decoration: none;
}
.search-quick-icon, .search-result-icon {
    display: inline-flex; align-items: center; color: var(--text-muted); flex-shrink: 0;
}
.search-quick-label { flex: 1; min-width: 0; }
.search-quick-item kbd, .search-result-type, .kbd-chord kbd {
    font-size: 11px;
    background: var(--bg-tertiary); border: 1px solid var(--border);
    border-radius: 4px; padding: 1px 6px; color: var(--text-muted);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.search-quick-item > kbd, .search-result-type { margin-left: auto; }
/* Chord shortcut: g · d — two kbds separated by a soft dot to read as "then" */
.kbd-chord { display: inline-flex; align-items: center; gap: 4px; margin-left: auto; }
.kbd-then  { color: var(--text-muted); opacity: 0.6; font-size: 11px; }
.search-result-content { min-width: 0; flex: 1; }
.search-result-title { font-weight: 600; }
.search-result-title mark {
    background: var(--accent-light); color: var(--primary); border-radius: 2px;
}
.search-result-subtitle { font-size: 12px; }
.search-result-type { text-transform: capitalize; }
.search-no-results { padding: 28px 20px; text-align: center; color: var(--text-muted); }
.search-no-results a { color: var(--primary); }
/* nav search button icon — small Lucide replaces the prior 🔍 emoji */
.nav-search-icon { color: var(--text-muted); }

/* ----- keyboard-shortcut hint toast (passive discovery, once per session) ----- */
.shortcut-hint-toast {
    position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%);
    background: rgba(255,255,255,0.92);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    border: 1px solid var(--border);
    color: var(--text-muted);
    padding: 8px 16px; border-radius: 20px;
    font-size: 13px; display: flex; align-items: center; gap: 8px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.08); z-index: 200;
    transition: opacity 0.5s ease;
    animation: shortcut-hint-fade-in 0.3s ease;
}
[data-theme="dark"] .shortcut-hint-toast {
    background: rgba(31,41,55,0.92);
    box-shadow: 0 2px 8px rgba(0,0,0,0.4);
}
.shortcut-hint-toast kbd {
    background: var(--bg-tertiary); border: 1px solid var(--border); border-radius: 4px;
    padding: 1px 6px; font-size: 12px; font-family: monospace; color: var(--text);
}
.shortcut-hint-toast button {
    background: none; border: none; color: var(--text-muted); cursor: pointer;
    font-size: 14px; padding: 0; line-height: 1;
}
.shortcut-hint-toast button:hover { color: var(--text); }
@keyframes shortcut-hint-fade-in {
    from { opacity: 0; transform: translateX(-50%) translateY(8px); }
    to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}
.invoice-row.keyboard-selected {
    outline: 2px solid var(--primary); outline-offset: -2px;
}

/* ----- dashboard customizer ----- */
.page-head-actions { display: flex; align-items: center; gap: 10px; }
.dashboard-page-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
}
.dashboard-page-action .icon-inline {
    margin-right: 0;
    vertical-align: 0;
}
.dashboard-new-invoice-btn { min-width: 72px; }
/* Phones: "Customize" is a desktop layout tool and "New" duplicates the + action
   button, so drop both from the dashboard title row and give the space to content. */
@media (max-width: 640px) {
    .dashboard-page-action { display: none; }
}
.dashboard-customizer-overlay {
    position: fixed; inset: 0; background: rgba(17,24,39,.45); z-index: 900;
}
.dashboard-customizer {
    position: fixed; top: 0; right: 0; bottom: 0; width: 340px; max-width: 90vw;
    background: var(--bg-card); color: var(--text);
    box-shadow: -10px 0 40px rgba(0,0,0,.2); z-index: 901;
    display: flex; flex-direction: column;
}
.customizer-header {
    display: flex; justify-content: space-between; align-items: center;
    padding: 18px 20px; border-bottom: 1px solid var(--border);
}
.customizer-header h3 { margin: 0; font-size: 17px; }
.customizer-header button {
    background: none; border: none; font-size: 18px; cursor: pointer; color: var(--text-muted);
}
.customizer-body { padding: 18px 20px; flex: 1; overflow-y: auto; }
.customizer-section { margin-top: 18px; }
.customizer-section:first-of-type { margin-top: 14px; }
.customizer-section-title {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    margin-bottom: 8px;
    color: var(--text);
    font-size: 12px; font-weight: 700; letter-spacing: .04em;
    text-transform: uppercase;
}
.customizer-section-title small {
    color: var(--text-muted);
    font-size: 11px; font-weight: 600; letter-spacing: 0; text-transform: none;
}
.customizer-card-list { display: flex; flex-direction: column; gap: 8px; }
.customizer-card-item {
    display: flex; align-items: center; gap: 10px;
    background: var(--bg-tertiary); border: 1px solid var(--border);
    border-radius: 8px; padding: 10px 12px; cursor: grab;
}
.customizer-card-item.dragging { opacity: .5; }
.customizer-card-item .drag-handle { color: var(--text-muted); cursor: grab; }
.customizer-card-item .card-label { flex: 1; font-size: 14px; }
/* Move buttons: desktop reorders by dragging the handle, so hide these there.
   On touch devices (no native HTML5 drag) show them and hide the drag handle. */
.customizer-move-group { display: none; }
.customizer-move {
    display: inline-flex; align-items: center; justify-content: center;
    width: 34px; height: 34px; padding: 0;
    border: 1px solid var(--border); border-radius: 7px;
    background: var(--bg-card); color: var(--text); font-size: 16px; line-height: 1;
    cursor: pointer;
}
.customizer-move:disabled { opacity: .4; cursor: default; }
@media (pointer: coarse) {
    .customizer-card-item { cursor: default; }
    .customizer-card-item .drag-handle { display: none; }
    .customizer-move-group { display: inline-flex; gap: 6px; }
}
.customizer-footer {
    padding: 16px 20px; border-top: 1px solid var(--border);
    display: flex; gap: 10px;
}
.toggle-small { position: relative; display: inline-block; width: 38px; height: 22px; }
.toggle-small input { position: absolute; opacity: 0; width: 0; height: 0; }
.toggle-slider-small {
    position: absolute; inset: 0; background: var(--border);
    border-radius: 999px; transition: background .15s; cursor: pointer;
}
.toggle-slider-small::before {
    content: ""; position: absolute; width: 16px; height: 16px;
    left: 3px; top: 3px; background: var(--bg-card); border-radius: 50%;
    transition: transform .15s;
}
.toggle-small input:checked + .toggle-slider-small { background: var(--primary); }
.toggle-small input:checked + .toggle-slider-small::before { transform: translateX(16px); }

/* ----- mobile bottom nav ----- */
.mobile-bottom-nav {
    display: none;
    position: fixed; bottom: 0; left: 0; right: 0;
    background: var(--bg-card); border-top: 1px solid var(--border);
    padding: 8px 0 env(safe-area-inset-bottom, 8px);
    z-index: 100; flex-direction: row; justify-content: space-around;
}
.mobile-nav-item {
    display: flex; flex-direction: column; align-items: center;
    text-decoration: none; color: var(--text-muted);
    font-size: 11px; gap: 2px; padding: 4px 12px; transition: color .2s;
}
.mobile-nav-item.active { color: var(--primary); }
.mobile-nav-icon { display: inline-flex; line-height: 1; }
.mobile-nav-icon svg { width: 20px; height: 20px; }
.mobile-nav-add { position: relative; }
.mobile-nav-add-btn {
    width: 48px; height: 48px; background: var(--primary);
    color: #fff; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-size: 28px; margin-top: -16px;
    box-shadow: 0 4px 12px rgba(79,70,229,.4);
}
/* Smallest phones (≤360px): the per-item 12px side padding (120px total across
   5 items) pushed the last item (Settings) off the right edge. Tighten it so
   all five fit; roomier padding stays on larger screens. */
@media (max-width: 360px) {
    .mobile-nav-item { padding: 4px 6px; }
}

/* ----- mobile dashboard simplified view ----- */
.d-mobile-only { display: none; }
.mobile-stats-row { display: flex; gap: 10px; margin-bottom: 18px; }
.mobile-stat {
    flex: 1; background: var(--bg-card); border: 1px solid var(--border);
    border-radius: 10px; padding: 14px; text-align: center;
}
.mobile-stat-value { font-size: 20px; font-weight: 800; }
.mobile-stat-label { font-size: 11px; color: var(--text-muted); }
.mobile-invoice-card {
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: 10px; padding: 14px; margin-bottom: 10px;
}
.mic-client { font-weight: 700; }
.mic-amount { font-size: 18px; margin: 4px 0; }
.mic-status { font-size: 12px; color: var(--text-muted); }
.mic-status.overdue { color: var(--danger); font-weight: 600; }
.mic-actions { display: flex; gap: 8px; margin-top: 10px; }

/* 720, not 768 — the desktop top nav only collapses at <=720, so a 768 cutoff
   here meant BOTH navigations (top menu + bottom tab bar) showed at 721-768px. */
@media (max-width: 720px) {
    .mobile-bottom-nav { display: flex; }
    body { padding-bottom: 72px; }
    body:has(.mobile-bottom-nav) .container { padding-bottom: 122px; }
    /* Logged-in phones already have the bottom tab bar + More sheet, so the
       marketing footer (copyright + 6 legal/help links) is pure chrome eating
       the bottom of every page. Hide it here; legal links move into the More
       sheet so nothing becomes unreachable. Logged-out / marketing pages (no
       bottom nav) keep the footer. */
    body:has(.mobile-bottom-nav) .footer { display: none; }
    .d-mobile-only { display: block !important; }
    .d-desktop-only { display: none !important; }
    /* min-height bumps the tap target to 44px; inline-flex centering keeps the
       label vertically centered in that taller box (plain inline-block left the
       text stuck at the top). width:100% buttons (.btn-block etc.) keep their
       width since inline-flex honors an explicit width. */
    /* One consistent full-size button on phones: primary AND secondary share the
       same height + font so a primary+secondary pair (e.g. Ask AI / Export CSV,
       Customize / New) is always matched and aligned — and a touch more compact
       than the old 44px, which read as oversized. Prominence comes from the fill
       vs outline, not size. */
    .btn { min-height: 40px; font-size: 13px; display: inline-flex; align-items: center; justify-content: center; }
    /* Small buttons stay genuinely small — the rule above was inflating inline row
       buttons like the invoice "More actions" Add/Raise/Apply. */
    .btn.btn-sm { min-height: 34px; padding: 5px 11px; }
    /* font-size !important: anything <16px makes iOS Safari zoom the page on focus.
       Specific rules (filter inputs, date pickers, pay bank-claim, feedback) set
       13-14px and were overriding this — force 16px so focusing never zooms. */
    input, select, textarea { min-height: 44px; font-size: 16px !important; }
    .nav-search-hint { display: none; }
    .dashboard-customizer { width: 100%; }
}

/* ----- API docs page ----- */
.api-docs-page {
    display: grid; grid-template-columns: 220px 1fr; gap: 40px; padding: 24px 0;
}
.api-docs-sidebar { position: sticky; top: 24px; align-self: start; }
.api-docs-sidebar h2 { font-size: 15px; margin-bottom: 12px; }
.api-docs-sidebar nav { display: flex; flex-direction: column; gap: 4px; }
.api-docs-sidebar nav a {
    color: var(--text-muted); text-decoration: none; font-size: 14px;
    padding: 6px 10px; border-radius: 6px;
}
.api-docs-sidebar nav a:hover { background: var(--bg-tertiary); color: var(--text); }
.api-docs-content section { margin: 36px 0; }
.api-docs-content h1 { font-size: 28px; margin-bottom: 8px; }
.api-docs-content h2 {
    font-size: 20px; margin-bottom: 12px;
    padding-bottom: 8px; border-bottom: 1px solid var(--border);
}
.api-docs-content h4 { font-size: 13px; text-transform: uppercase;
    color: var(--text-muted); margin: 16px 0 8px; letter-spacing: .04em; }
.api-docs-content pre {
    background: var(--bg-tertiary); border: 1px solid var(--border);
    border-radius: 8px; padding: 14px 16px; overflow-x: auto; font-size: 13px;
}
.api-docs-content code { font-family: monospace; }
.api-endpoint {
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: 10px; padding: 18px 20px; margin-bottom: 16px;
}
.endpoint-header { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.method {
    font-size: 11px; font-weight: 700; padding: 3px 8px; border-radius: 4px;
    text-transform: uppercase;
}
.method.get  { background: var(--status-info-bg); color: var(--status-info-fg); }
.method.post { background: var(--status-success-bg); color: var(--status-success-fg); }
.api-params { width: 100%; border-collapse: collapse; font-size: 13px; }
.api-params th, .api-params td {
    text-align: left; padding: 7px 10px; border-bottom: 1px solid var(--border);
}
.api-params th { color: var(--text-muted); }

/* ----- invoice templates library ----- */
.templates-hero { text-align: center; padding: 36px 0 24px; }
.templates-hero h1 { font-size: 30px; margin-bottom: 10px; }
.templates-hero p { color: var(--text-muted); max-width: 620px; margin: 0 auto; }
.templates-filter {
    display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin-bottom: 28px;
}
.filter-btn {
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: 999px; padding: 6px 16px; font-size: 13px; cursor: pointer;
    color: var(--text);
}
.filter-btn.active { background: var(--primary); border-color: var(--primary); color: #fff; }
.templates-grid {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 20px; padding-bottom: 40px;
}
.template-card {
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: 12px; overflow: hidden; display: flex; flex-direction: column;
}
.template-preview { padding: 18px; }
.template-preview-mock { border-radius: 8px; padding: 16px; }
.mock-inv-header { font-weight: 800; font-size: 15px; margin-bottom: 12px; }
.mock-inv-lines { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.mock-line { height: 8px; background: rgba(0,0,0,.08); border-radius: 4px; }
.mock-line.short { width: 60%; }
.mock-inv-total {
    color: #fff; font-size: 11px; font-weight: 700;
    padding: 6px 10px; border-radius: 4px; display: inline-block;
}
.template-info { padding: 0 18px 12px; }
.template-info h3 { font-size: 16px; margin-bottom: 4px; }
.template-info p { font-size: 13px; }
.template-actions { display: flex; gap: 8px; padding: 0 18px 14px; }
.template-cta {
    margin-top: auto; padding: 14px 18px;
    border-top: 1px solid var(--border); background: var(--bg-tertiary);
}
.template-cta p { font-size: 12px; color: var(--text-muted); margin-bottom: 8px; }

/* ----- calculators index page ----- */
.calculators-hero { text-align: center; padding: 36px 0 24px; }
.calculators-hero h1 { font-size: 30px; margin-bottom: 10px; }
.calculators-hero p { color: var(--text-muted); max-width: 620px; margin: 0 auto; }
.calculators-grid {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 20px; margin-bottom: 36px;
}
.calculator-tool-card {
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: 12px; padding: 24px; text-decoration: none; color: var(--text);
    display: flex; flex-direction: column;
}
.calculator-tool-card:hover { border-color: var(--primary); text-decoration: none; }
.tool-card-icon { font-size: 32px; margin-bottom: 10px; }
.calculator-tool-card h3 { font-size: 17px; margin-bottom: 6px; }
.calculator-tool-card p { font-size: 13px; flex: 1; }
.tool-card-link { color: var(--primary); font-weight: 600; font-size: 14px; margin-top: 12px; }
.calculators-cta, .calculator-cta, .tool-cta {
    background: var(--accent-light); border-radius: 12px;
    padding: 28px; text-align: center; margin-top: 20px;
}
.calculators-cta h3, .tool-cta h3 { font-size: 18px; margin-bottom: 6px; }

/* ----- calculator pages ----- */
.calculator-page { max-width: 640px; margin: 0 auto; padding: 28px 0; }
.calculator-page h1 { font-size: 28px; margin-bottom: 8px; }
.calculator-page > p { color: var(--text-muted); margin-bottom: 20px; }
.calculator-box {
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: 12px; padding: 24px;
}
.input-currency { display: flex; align-items: center; }
.input-currency span {
    padding: 9px 12px; border: 1px solid var(--border); border-right: none;
    border-radius: 8px 0 0 8px; background: var(--bg-tertiary); color: var(--text-muted);
}
.input-currency input { border-radius: 0 8px 8px 0; }
.radio-group { display: flex; gap: 18px; flex-wrap: wrap; }
.radio-group label { display: flex; align-items: center; gap: 6px; font-size: 14px; }
.radio-group input { width: auto; min-height: auto; }
.calculator-result {
    background: var(--accent-light); border-radius: 10px;
    padding: 20px; margin: 18px 0; text-align: center;
}
.result-value { font-size: 36px; font-weight: 800; color: var(--primary); }
.result-label { color: var(--text-muted); font-size: 13px; }
.result-benchmark { margin-top: 10px; font-size: 14px; font-weight: 600; }
.result-row {
    display: flex; justify-content: space-between;
    padding: 6px 0; font-size: 14px; text-align: left;
}
.result-row.result-total {
    border-top: 1px solid var(--border); margin-top: 6px;
    padding-top: 12px; font-size: 16px;
}
.calculator-related { margin-top: 16px; text-align: center; font-size: 13px; }
.calculator-related a { color: var(--primary); }

/* ----- subject line generator tool ----- */
.tool-page { padding: 28px 0; }
.tool-container { max-width: 720px; margin: 0 auto; }
.tool-header { text-align: center; margin-bottom: 24px; }
.tool-header h1 { font-size: 28px; margin-bottom: 8px; }
.tool-header p { color: var(--text-muted); }
.tool-box {
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: 12px; padding: 24px;
}
.form-row { display: flex; gap: 16px; flex-wrap: wrap; }
.form-row .form-group { flex: 1; min-width: 200px; }
.tone-selector { display: flex; gap: 10px; flex-wrap: wrap; }
.tone-option {
    flex: 1; min-width: 130px; border: 1px solid var(--border);
    border-radius: 10px; padding: 12px; cursor: pointer; text-align: center;
}
.tone-option input { width: auto; min-height: auto; }
.tone-option span { display: block; font-weight: 600; margin: 4px 0 2px; }
.tone-option small { color: var(--text-muted); }
.tone-option:has(input:checked) {
    border-color: var(--primary); background: var(--accent-light);
}
.btn-lg { padding: 12px 22px; font-size: 16px; }
.subjects-result { margin-top: 22px; }
.subjects-list { display: flex; flex-direction: column; gap: 8px; margin: 12px 0; }
.subject-item {
    display: flex; align-items: center; gap: 12px;
    background: var(--bg-tertiary); border: 1px solid var(--border);
    border-radius: 8px; padding: 10px 14px;
}
.subject-text { flex: 1; font-size: 14px; }

/* ----- 2FA pages ----- */
/* Status pill + its Disable action, grouped on the left — keeps everything on
   this page left-aligned (space-between flung Disable to the far card edge). */
.tfa-enabled-status {
    margin: 16px 0 32px;
    display: flex; align-items: center; gap: 16px;
}
/* Bigger, greener "2FA is enabled" pill so the protected state reads at a glance. */
.tfa-enabled-status .badge {
    font-size: 13px; padding: 5px 12px; gap: 5px;
    display: inline-flex; align-items: center;
}
.tfa-disable-btn { flex-shrink: 0; }
/* Password field inside the disable / regenerate confirm modal. */
.tfa-modal-pw {
    display: block; width: 100%; margin: 0 0 14px;
    padding: 10px 12px; border: 1px solid var(--border); border-radius: 8px;
    background: var(--bg-card); color: var(--text);
}
.tfa-modal-err { color: var(--danger); font-size: 13px; margin: -6px 0 14px; }
.tfa-setup-steps { margin: 18px 0; }
.setup-step {
    display: flex; gap: 14px; padding: 14px 0;
    border-bottom: 1px solid var(--border);
}
.setup-step:last-child { border-bottom: none; }
.step-num {
    flex-shrink: 0; width: 28px; height: 28px; border-radius: 50%;
    background: var(--primary); color: #fff;
    display: flex; align-items: center; justify-content: center;
    font-weight: 700; font-size: 14px;
}
.input-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.input-row input { width: auto; flex: 1; min-width: 160px; }
.btn-danger-outline {
    background: var(--bg-card); border: 1px solid var(--danger); color: var(--danger);
}
.backup-codes-box {
    background: var(--accent-light); border-radius: 10px;
    padding: 20px; margin-top: 20px;
}
.backup-codes-grid {
    display: grid; grid-template-columns: repeat(2, 1fr);
    gap: 8px; margin: 14px 0;
}
.backup-code {
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: 6px; padding: 8px; text-align: center;
    font-family: monospace; font-size: 15px; letter-spacing: 2px;
}
.auth-icon { font-size: 48px; text-align: center; }
.btn-link {
    background: none; border: none; cursor: pointer;
    text-decoration: underline; font-size: 14px;
}

/* ======================================================
   Trial lifecycle — banners, extension page, billing plans
   ====================================================== */

/* ===== Trial-status banner ===== */
.trial-banner {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 10px 16px;
    padding: 10px 16px;
    font-size: 14px;
    line-height: 1.4;
    border-bottom: 1px solid var(--border);
}
.trial-banner > span {
    flex: 0 1 auto;
    min-width: 0;
}
.trial-banner strong { font-weight: 700; }
/* Phones: the trial banner sits on every page; the verbose "switch trial" link
   pushes it to ~3 lines. Drop that secondary link (still in Settings → Billing)
   and tighten so the banner costs ~2 lines, not 3. */
@media (max-width: 640px) {
    .trial-banner { padding: 8px 12px; font-size: 13px; gap: 6px 10px; }
    .trial-banner-secondary { display: none; }
    .trial-banner-btn { padding: 5px 12px; font-size: 12px; }
}

.trial-banner-warning {
    background: var(--status-warning-bg);
    color: var(--status-warning-fg);
}
[data-theme="dark"] .trial-banner-warning {
    background: #422006;
    color: #FCD34D;
}
.trial-banner-danger {
    background: var(--status-danger-bg);
    color: var(--status-danger-fg);
}
[data-theme="dark"] .trial-banner-danger {
    background: #450A0A;
    color: #FCA5A5;
}
.trial-banner-info {
    background: var(--accent-light);
    color: var(--primary-dark);
}
[data-theme="dark"] .trial-banner-info {
    color: #C7D2FE;
}
.trial-banner-sticky {
    position: sticky;
    top: 0;
    z-index: 50;
}

.trial-banner-btn {
    display: inline-block;
    padding: 6px 14px;
    border-radius: 8px;
    background: var(--primary);
    color: #fff;
    font-weight: 700;
    font-size: 13px;
    text-decoration: none;
    white-space: nowrap;
}
.trial-banner-btn:hover { background: var(--primary-dark); text-decoration: none; }

.trial-banner-link {
    font-size: 13px;
    font-weight: 600;
    color: inherit;
    text-decoration: underline;
    white-space: nowrap;
}
.trial-banner-link:hover { opacity: .8; }

.trial-banner-close {
    background: none;
    border: none;
    cursor: pointer;
    font-size: 14px;
    line-height: 1;
    color: inherit;
    opacity: .6;
    padding: 4px;
    display: inline-flex; align-items: center; justify-content: center;
}
.trial-banner-close:hover { opacity: 1; }

@media (max-width: 700px) {
    .trial-banner {
        justify-content: flex-start;
    }
    .trial-banner > span {
        flex-basis: 100%;
    }
}

/* ===== Trial-extension page ===== */
.trial-extend-page {
    padding: 40px 16px;
    display: flex;
    justify-content: center;
}
.trial-extend-container {
    width: 100%;
    max-width: 540px;
}
.extend-form,
.extend-used,
.extend-not-eligible,
.extend-success {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 16px;
    box-shadow: var(--shadow);
    padding: 36px 32px;
}
.trial-extend-container h1 {
    font-size: 24px;
    text-align: center;
    margin-bottom: 10px;
    color: var(--text);
}
.trial-extend-container > div > p {
    text-align: center;
    color: var(--text-muted);
    margin-bottom: 24px;
}

.extend-reasons {
    margin: 8px 0 24px;
}
.extend-reasons > p {
    text-align: left;
    color: var(--text);
    margin-bottom: 12px;
}
.extend-reason-item {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 14px 16px;
    margin-bottom: 10px;
    border: 1px solid var(--border);
    border-radius: 10px;
    cursor: pointer;
    transition: border-color .15s, background .15s;
}
.extend-reason-item:hover {
    border-color: var(--primary);
}
.extend-reason-item input[type="radio"] {
    margin-top: 3px;
    accent-color: var(--primary);
    flex-shrink: 0;
}
.extend-reason-item:has(input:checked) {
    border-color: var(--primary);
    background: var(--accent-light);
}
.extend-reason-item span {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.extend-reason-item strong {
    font-size: 14px;
    color: var(--text);
}
.extend-reason-item small {
    font-size: 13px;
    color: var(--text-muted);
}

.extend-response-card {
    margin-top: 20px;
    padding: 18px 20px;
    background: var(--accent-light);
    border-radius: 12px;
    text-align: center;
}
.extend-response-card strong {
    display: block;
    font-size: 15px;
    color: var(--primary-dark);
    margin-bottom: 6px;
}
[data-theme="dark"] .extend-response-card strong { color: #C7D2FE; }
.extend-response-card p {
    font-size: 14px;
    color: var(--text-muted);
    margin-bottom: 12px;
}

/* extend-page emoji container — smaller + tighter spacing to reduce 'childish' feel */
.extend-emoji {
    font-size: 36px; text-align: center;
    margin-bottom: 12px; line-height: 1;
    /* Mute the emoji a bit so it doesn't grab focus */
    opacity: .9;
}
.extend-emoji-big { font-size: 56px; opacity: 1; }
.extend-emoji-success { color: var(--success); display: flex; justify-content: center; }
.extend-emoji-success svg { width: 44px; height: 44px; }

/* Constrain the trial-extend h1 + p copy width to a readable range; don't stretch to the full 540px container */
.trial-extend-container h1 {
    font-size: 22px;
    max-width: 420px; margin-left: auto; margin-right: auto;
    line-height: 1.35;
}
.trial-extend-container > div > p {
    max-width: 440px; margin-left: auto; margin-right: auto;
    line-height: 1.55;
}

/* 'Need to talk to us?' info block — refined left-accent style (replaces the all-grey background) */
.extend-contact-box {
    margin-top: 28px; padding: 14px 16px;
    background: var(--bg-tertiary); border-left: 3px solid var(--primary);
    border-radius: 6px; font-size: 13.5px; line-height: 1.6;
    color: var(--text); text-align: left;
}
.extend-contact-box strong { display: block; margin-bottom: 4px; }
.extend-contact-box .icon-inline { color: var(--text-muted); }

/* 'This is a one-time offer.' fine print */
.extend-fine-print {
    text-align: center; margin-top: 16px;
    color: var(--text-muted); font-size: 12.5px;
}

/* extend page 'Back to Dashboard' button centered */
.extend-back-btn {
    margin-top: 20px;
    display: block; width: fit-content;
    margin-left: auto; margin-right: auto;
}
.extend-success .extend-back-btn { margin-top: 24px; width: 100%; }

/* ===== Expired notice (billing page) ===== */
.expired-notice {
    background: var(--accent-light);
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: 32px 28px;
    margin-bottom: 24px;
}
.expired-notice h2 {
    color: var(--text);
    margin-bottom: 8px;
}

/* ===== Plan selector ===== */
.billing-cycle-toggle {
    display: inline-flex;
    gap: 4px;
    padding: 4px;
    margin: 16px 0 24px;
    background: var(--bg-tertiary);
    border-radius: 10px;
}
.billing-cycle-btn {
    border: none;
    cursor: pointer;
    background: transparent;
    color: var(--text-muted);
    font-weight: 600;
    font-size: 14px;
    padding: 8px 18px;
    border-radius: 8px;
    transition: background .15s, color .15s;
}
.billing-cycle-btn.active {
    background: var(--bg-card);
    color: var(--text);
    box-shadow: var(--shadow);
}
.billing-cycle-save {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 7px;
    border-radius: 8px;
    background: var(--success);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
}

.billing-plan-selector {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
}
@media (max-width: 720px) {
    .billing-plan-selector { grid-template-columns: 1fr; }
}

.plan-card {
    position: relative;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: 24px 20px;
    display: flex;
    flex-direction: column;
}
.plan-card-highlight {
    border-color: var(--primary);
    box-shadow: 0 4px 16px rgba(79,70,229,0.18);
}
.plan-card-badge {
    position: absolute;
    top: -11px;
    left: 50%;
    transform: translateX(-50%);
    background: var(--primary);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    padding: 3px 12px;
    border-radius: 10px;
    white-space: nowrap;
}
.plan-card-name {
    font-size: 16px;
    font-weight: 700;
    color: var(--text);
    margin-bottom: 8px;
}
.plan-card-price {
    display: flex;
    align-items: baseline;
    gap: 4px;
}
.plan-card-amount {
    font-size: 32px;
    font-weight: 800;
    color: var(--text);
}
.plan-card-period {
    font-size: 14px;
    color: var(--text-muted);
}
.plan-card-cycle-note {
    font-size: 12px;
    margin-bottom: 16px;
}
.plan-card-features {
    list-style: none;
    margin: 0 0 20px;
    padding: 0;
    flex: 1;
}
.plan-card-features li {
    font-size: 13px;
    color: var(--text);
    padding: 5px 0;
    border-bottom: 1px solid var(--border);
}
.plan-card-features li:last-child { border-bottom: none; }
/* .plan-card-extra (Team Extra seats/orgs) was redefined as a muted style around line 427;
   the old rule 'color: var(--primary); font-weight: 600' over-emphasised it and has been removed. */

.plan-card-btn { margin-top: auto; }

/* ======================================================
   Feedback system
   ====================================================== */

/* ===== Pinned feedback button (bottom-right widget) ===== */
.feedback-widget {
    position: fixed;
    bottom: 24px;
    right: 24px;
    z-index: 500;
}
@media (max-width: 768px) {
    /* Mobile: sits above the bottom nav bar */
    .feedback-widget { bottom: 80px; }
}

.feedback-trigger {
    display: flex;
    align-items: center;
    gap: 0;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 50%;
    padding: 11px;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
    font-size: 14px;
    color: var(--text);
    transition: all 0.2s;
}
.feedback-trigger:hover {
    border-color: var(--primary);
    color: var(--primary);
    box-shadow: 0 4px 12px rgba(79,70,229,0.15);
}
/* UX audit P1: the always-expanded desktop pill sat over right-aligned content
   / form controls on shorter pages. Rest as a corner icon; expand to a labelled
   pill only on hover/focus, so it no longer covers anything at rest. */
.feedback-trigger-label {
    max-width: 0;
    opacity: 0;
    overflow: hidden;
    white-space: nowrap;
    transition: max-width 0.2s ease, opacity 0.15s ease, margin-left 0.2s ease;
}
.feedback-widget:hover .feedback-trigger,
.feedback-trigger:focus-visible {
    border-radius: 20px;
    padding: 8px 16px;
}
.feedback-widget:hover .feedback-trigger-label,
.feedback-trigger:focus-visible .feedback-trigger-label {
    max-width: 96px;
    opacity: 1;
    margin-left: 6px;
}
.feedback-trigger-icon { font-size: 16px; }

@media (max-width: 768px) {
    /* Mobile: show icon only */
    .feedback-trigger-label { display: none; }
    .feedback-trigger { padding: 10px; border-radius: 50%; }
}

.feedback-panel {
    position: absolute;
    bottom: 48px;
    right: 0;
    width: 380px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 12px 32px rgba(0,0,0,0.15);
    overflow: hidden;
}
@media (max-width: 768px) {
    .feedback-panel {
        position: fixed;
        bottom: 90px;
        right: 12px;
        left: 12px;
        width: auto;
    }
}

/* Chip-style soft categories: General highlighted by default, click to switch */
.feedback-chips {
    display: flex;
    gap: 6px;
    padding: 12px 12px 8px;
}
.feedback-chip {
    flex: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 6px 10px;
    cursor: pointer;
    font-size: 12.5px;
    color: var(--text-muted);
    transition: all 0.15s;
    white-space: nowrap;
}
.feedback-chip svg { flex-shrink: 0; }
.feedback-chip:hover { color: var(--text); border-color: var(--text-muted); }
.feedback-chip.is-active {
    background: var(--accent-light);
    border-color: var(--primary);
    color: var(--primary);
    font-weight: 600;
}

/* Attachment / screenshot upload area */
.feedback-attach { margin-top: 10px; }
.feedback-attach-btn {
    background: none;
    border: 1px dashed var(--border);
    border-radius: 8px;
    padding: 8px 12px;
    width: 100%;
    cursor: pointer;
    color: var(--text-muted);
    font-size: 13px;
    transition: all 0.15s;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
}
.feedback-attach-btn:hover {
    border-color: var(--primary);
    color: var(--primary);
    background: var(--accent-light);
}
.feedback-attach-hint {
    font-size: 11px;
    color: var(--text-muted);
    text-align: center;
    margin-top: 4px;
}

/* Inline error (too short / network failure) */
.feedback-inline-err {
    margin-top: 6px;
    padding: 6px 10px;
    background: rgba(220, 38, 38, 0.06);
    border: 1px solid rgba(220, 38, 38, 0.2);
    border-radius: 6px;
    font-size: 12px;
    color: var(--danger);
}
.feedback-attach-grid {
    margin-top: 8px;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
    gap: 6px;
}
.feedback-thumb {
    position: relative;
    border: 1px solid var(--border);
    border-radius: 6px;
    overflow: hidden;
    background: var(--bg-tertiary);
    aspect-ratio: 1 / 1;
}
.feedback-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.feedback-attach-remove {
    position: absolute;
    top: 4px;
    right: 4px;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: rgba(0,0,0,0.55);
    color: #fff;
    border: none;
    cursor: pointer;
    font-size: 12px;
    line-height: 1;
}
.feedback-attach-err {
    margin-top: 6px;
    font-size: 12px;
    color: var(--danger);
}

/* Drag onto any part of the panel → highlight hint */
.feedback-panel.is-dragover {
    outline: 2px dashed var(--primary);
    outline-offset: -2px;
}

.feedback-panel-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border);
    font-weight: 600;
    font-size: 14px;
    color: var(--text);
}
.feedback-panel-close {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--text-muted);
    font-size: 18px;
    line-height: 1;
}

.feedback-type-selector {
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.feedback-type-btn {
    display: flex;
    align-items: center;
    gap: 10px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 10px 14px;
    cursor: pointer;
    text-align: left;
    font-size: 14px;
    color: var(--text);
    transition: all 0.15s;
}
.feedback-type-btn:hover {
    background: var(--accent-light);
    border-color: var(--primary);
    color: var(--primary);
}

.feedback-content { padding: 12px; }
.feedback-back {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--text-muted);
    font-size: 13px;
    margin-bottom: 8px;
    padding: 0;
}
.feedback-type-label {
    font-size: 13px;
    font-weight: 600;
    color: var(--text);
    margin-bottom: 8px;
}
.feedback-content textarea {
    width: 100%;
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 10px;
    font-size: 13px;
    resize: none;
    font-family: inherit;
    background: var(--input-bg);
    color: var(--text);
    transition: border-color 0.15s;
}
.feedback-content textarea:focus {
    outline: none;
    border-color: var(--primary);
}
/* Category dropdown (only shown for the feature type) */
#feedback-category {
    font-size: 12px;
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 4px 8px;
    background: var(--input-bg);
    color: var(--text);
    width: 100%;
}
.feedback-success .feedback-success-inner {
    text-align: center;
    padding: 16px;
    color: var(--text);
}
.feedback-success-emoji { font-size: 32px; margin-bottom: 8px; }
.feedback-success p { margin: 4px 0; }

/* ===== Feature-request page /feedback/ ===== */
.feedback-page { padding: 8px 0 32px; }
.feedback-page-container {
    max-width: 720px;
    margin: 0 auto;
}
.feedback-page-header { margin-bottom: 20px; }
.feedback-page-header h1 { font-size: 26px; margin-bottom: 6px; }
.feedback-page-header p { color: var(--text-muted); font-size: 15px; }

.feedback-submit-inline {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 16px;
    margin-bottom: 24px;
    box-shadow: var(--shadow);
}
.feedback-submit-input-wrap {
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.feedback-submit-input-wrap textarea {
    width: 100%;
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 10px 12px;
    font-size: 14px;
    font-family: inherit;
    background: var(--input-bg);
    color: var(--text);
    resize: vertical;
    min-height: 76px;
    line-height: 1.5;
}
.feedback-submit-input-wrap textarea:focus {
    outline: none;
    border-color: var(--primary);
}
.feedback-submit-input-wrap .btn { flex-shrink: 0; align-self: flex-end; }
.feedback-inline-success {
    margin-top: 10px;
    color: var(--success);
    font-size: 14px;
    font-weight: 600;
}

.feedback-features-list { margin-bottom: 28px; }
.feedback-features-list h2,
.feedback-shipped h2 {
    font-size: 18px;
    margin-bottom: 12px;
}
.feedback-empty {
    padding: 28px;
    text-align: center;
    color: var(--text-muted);
    background: var(--bg-card);
    border: 1px dashed var(--border);
    border-radius: var(--radius);
}

.feedback-feature-item {
    display: flex;
    gap: 14px;
    align-items: flex-start;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 14px 16px;
    margin-bottom: 10px;
    box-shadow: var(--shadow);
}
.feedback-feature-item.feedback-feature-planned {
    border-color: var(--primary);
    background: var(--accent-light);
}
.feedback-feature-vote { flex-shrink: 0; }
.vote-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    width: 52px;
    padding: 8px 0;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 8px;
    cursor: pointer;
    color: var(--text-muted);
    transition: all 0.15s;
}
.vote-btn:hover {
    border-color: var(--primary);
    color: var(--primary);
}
.vote-btn.voted {
    background: var(--accent-light);
    border-color: var(--primary);
    color: var(--primary);
}
.vote-arrow { font-size: 11px; line-height: 1; }
.vote-count { font-size: 15px; font-weight: 700; line-height: 1; }

.feedback-feature-content { flex: 1; min-width: 0; }
.feedback-feature-text {
    font-size: 14px;
    color: var(--text);
    line-height: 1.45;
}
.feedback-feature-meta {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: 8px;
}
.feedback-category-tag {
    font-size: 11px;
    padding: 2px 8px;
    border-radius: 12px;
    background: var(--bg-tertiary);
    color: var(--text-muted);
    text-transform: capitalize;
}
.feedback-status-tag {
    font-size: 11px;
    padding: 2px 8px;
    border-radius: 12px;
    font-weight: 600;
}
.feedback-status-planned {
    background: var(--accent-light);
    color: var(--primary);
}
.feedback-status-reviewing {
    background: var(--bg-tertiary);
    color: var(--text-muted);
}

.feedback-shipped {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 16px;
    box-shadow: var(--shadow);
}
.feedback-shipped p { font-size: 13px; margin-bottom: 10px; }
.feedback-shipped-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 0;
    font-size: 14px;
    color: var(--text);
}
.shipped-check {
    color: var(--success);
    font-weight: 700;
    flex-shrink: 0;
}
.shipped-votes { font-size: 12px; flex-shrink: 0; }

/* ===================================================================
   API Keys (Settings → API Keys) + API Reference docs page
   =================================================================== */

/* ----- shared helpers ----- */
.text-link {
    color: var(--primary);
    font-size: 14px;
    font-weight: 500;
}
.text-link:hover { text-decoration: underline; }
.badge-muted { background: var(--bg-tertiary); color: var(--text-muted); }

/* ----- settings section header ----- */
.settings-section-header { margin-bottom: 18px; }
.settings-section-header h2 { margin: 0 0 6px; font-size: 18px; }
.settings-section-header p {
    color: var(--text-muted); font-size: 14px; margin: 0 0 8px; line-height: 1.5;
}
.api-keys-header {
    display: flex; justify-content: space-between; align-items: flex-start; gap: 18px;
}
.api-docs-link {
    display: inline-flex; align-items: center; gap: 6px;
    color: var(--text-muted);
    font-size: 13px; font-weight: 600;
    white-space: nowrap;
}
.api-docs-link:hover {
    color: var(--primary);
    text-decoration: none;
}
.api-keys-toolbar {
    display: flex; justify-content: space-between; align-items: center;
    padding: 12px 14px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 10px;
    margin-bottom: 12px;
}
.api-keys-toolbar-title {
    color: var(--text);
    font-size: 14px; font-weight: 700;
}
.api-keys-toolbar-meta {
    display: flex; align-items: center; gap: 8px;
    color: var(--text-muted);
    font-size: 13px;
}
.api-keys-toolbar-meta strong { color: var(--text); }

/* ----- API keys list ----- */
.api-keys-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 20px; }
.api-key-row {
    display: flex; align-items: center; justify-content: space-between; gap: 16px;
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: 10px; padding: 14px 16px;
}
.api-key-row.api-key-revoked { opacity: .6; }
.api-key-info { min-width: 0; flex: 1; }
.api-key-name {
    font-weight: 600; font-size: 15px; margin-bottom: 4px;
    overflow-wrap: anywhere;
}
.api-key-preview { margin-bottom: 4px; }
.api-key-preview code {
    display: inline-block;
    max-width: 100%;
    font-family: monospace; font-size: 13px;
    background: var(--bg-tertiary); border-radius: 4px; padding: 2px 7px;
    color: var(--text);
    white-space: normal;
    overflow-wrap: anywhere;
}
.api-key-meta { font-size: 12px; overflow-wrap: anywhere; }
.api-key-actions { flex-shrink: 0; }
.api-key-actions .btn,
.api-key-generate-row .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
}
.api-keys-empty {
    text-align: center; padding: 28px 18px; margin-bottom: 20px;
    background: rgba(0, 0, 0, .02);
    border-radius: 10px;
}
[data-theme="dark"] .api-keys-empty { background: rgba(255, 255, 255, .025); }
.api-keys-empty-icon {
    width: 44px; height: 44px;
    border-radius: 10px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--accent-light);
    color: var(--primary);
    margin-bottom: 12px;
}
.api-keys-empty-title {
    color: var(--text);
    font-size: 16px; font-weight: 700;
    margin-bottom: 4px;
}
.api-keys-empty p {
    margin: 0 auto;
    max-width: 520px;
    color: var(--text-muted);
    font-size: 14px; line-height: 1.5;
}
.api-key-generate {
    border-top: 1px solid var(--border); padding-top: 18px; margin-top: 4px;
}
.api-key-generate-head {
    display: flex; justify-content: space-between; align-items: flex-start; gap: 16px;
    margin-bottom: 14px;
}
.api-key-generate-head h3 {
    margin: 0 0 4px;
    font-size: 15px;
}
.api-key-generate-head p {
    margin: 0;
    color: var(--text-muted);
    font-size: 13px; line-height: 1.5;
}
.api-key-usage-pill {
    flex-shrink: 0;
    display: inline-flex; align-items: center; gap: 6px;
    padding: 6px 10px;
    border-radius: 999px;
    background: var(--bg-tertiary);
    color: var(--text-muted);
    font-size: 12px;
}
.api-key-usage-pill strong { color: var(--text); }
.api-key-generate-row {
    align-items: flex-start;
    gap: 12px;
}
.api-key-generate-row .btn {
    margin-top: 29px;
    flex-shrink: 0;
}
.api-key-limit-note {
    border-top: 1px solid var(--border);
    margin-top: 4px;
    padding-top: 16px;
    color: var(--text-muted);
    font-size: 13px;
}
@media (max-width: 720px) {
    .api-keys-header,
    .api-key-generate-head,
    .api-key-generate-row {
        flex-direction: column;
        align-items: stretch;
    }
    .api-docs-link { align-self: flex-start; }
    .api-key-generate-row .btn {
        margin-top: 0;
        width: 100%;
    }
    .api-key-row { align-items: stretch; }
    .api-key-actions { width: 100%; }
    .api-key-actions .btn { width: 100%; }
}

/* ----- new key modal extras ----- */
.new-key-warning {
    background: var(--status-warning-bg); color: var(--status-warning-fg); border-radius: 8px;
    padding: 10px 12px; font-size: 13px; line-height: 1.5; margin-bottom: 14px;
}
.new-key-display {
    display: flex; align-items: center; gap: 10px;
    background: var(--bg-tertiary); border: 1px solid var(--border);
    border-radius: 8px; padding: 10px 12px; margin-bottom: 16px;
}
.new-key-display code {
    flex: 1; min-width: 0; font-family: monospace; font-size: 13px;
    word-break: break-all; color: var(--text);
}
.new-key-tips { font-size: 13px; color: var(--text-muted); }
.new-key-tips p { margin: 0 0 6px; }
.new-key-tips ul { margin: 0; padding-left: 20px; }
.new-key-tips li { margin-bottom: 3px; }

/* ----- API docs page (task 6) ----- */
.api-docs-layout {
    display: grid; grid-template-columns: 240px 1fr; gap: 40px;
    max-width: 1100px; margin: 0 auto; padding: 24px 0 48px;
}
.api-docs-nav { position: sticky; top: 24px; align-self: start; }
.api-docs-nav-logo { margin-bottom: 18px; }
.api-docs-nav-logo a { font-size: 18px; font-weight: 700; color: var(--text); }
.api-docs-nav-logo span {
    display: block; font-size: 12px; color: var(--text-muted);
    text-transform: uppercase; letter-spacing: .05em; margin-top: 2px;
}
.api-docs-nav nav { display: flex; flex-direction: column; gap: 2px; }
.api-docs-nav nav a {
    color: var(--text-muted); text-decoration: none; font-size: 14px;
    padding: 6px 10px; border-radius: 6px;
}
.api-docs-nav nav a:hover { background: var(--bg-tertiary); color: var(--text); }
.api-nav-section {
    font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
    color: var(--text-muted); font-weight: 700;
    margin: 16px 0 4px; padding: 0 10px;
}
.api-nav-section:first-child { margin-top: 0; }

.api-docs-content { min-width: 0; }
.api-docs-content h1 { font-size: 28px; margin-bottom: 8px; }
.api-docs-content > p { color: var(--text-muted); line-height: 1.6; }
.api-docs-content section { margin: 36px 0; scroll-margin-top: 24px; }
.api-docs-content h2 {
    font-size: 20px; margin-bottom: 12px;
    padding-bottom: 8px; border-bottom: 1px solid var(--border);
}
.api-docs-content h4 {
    font-size: 13px; text-transform: uppercase; letter-spacing: .04em;
    color: var(--text-muted); margin: 16px 0 8px;
}
.api-docs-content ul, .api-docs-content ol {
    padding-left: 22px; line-height: 1.7; color: var(--text);
}
.api-docs-content section > p { line-height: 1.6; }

.api-info-box {
    background: var(--accent-light); border-radius: 8px;
    padding: 12px 14px; margin: 16px 0; font-size: 14px;
}
.api-info-box code {
    font-family: monospace; margin-left: 8px;
    background: var(--bg-card); border-radius: 4px; padding: 2px 7px;
}
.api-warning {
    background: var(--status-warning-bg); color: var(--status-warning-fg); border-radius: 8px;
    padding: 10px 14px; font-size: 13px; line-height: 1.5; margin: 14px 0;
}

/* code blocks inside docs (extends existing .code-block) */
.code-block-header {
    display: flex; align-items: center; justify-content: space-between;
    background: #111827; color: var(--text-muted);
    font-size: 12px; padding: 7px 12px;
    border-radius: 8px 8px 0 0; margin: 12px 0 0;
}
.code-block-header + pre,
.code-block-header ~ pre { margin-top: 0; border-radius: 0 0 8px 8px; }
.code-copy-btn {
    background: transparent; border: 1px solid #374151; color: #D1D5DB;
    font-size: 11px; padding: 2px 9px; border-radius: 4px; cursor: pointer;
}
.code-copy-btn:hover { background: #1F2937; color: #fff; }
.api-docs-content pre {
    background: #1F2937; color: #E5E7EB; border-radius: 8px;
    padding: 14px 16px; overflow-x: auto; font-size: 13px;
    margin: 12px 0 16px; line-height: 1.55;
}
.api-docs-content pre code { font-family: monospace; color: inherit; }

/* API reference tables */
.api-table {
    width: 100%; border-collapse: collapse; font-size: 13px; margin: 8px 0 16px;
}
.api-table th, .api-table td {
    text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--border);
    vertical-align: top;
}
.api-table th { color: var(--text-muted); font-weight: 600; }
.api-table code {
    font-family: monospace; background: var(--bg-tertiary);
    border-radius: 4px; padding: 1px 6px;
}

/* endpoint cards */
.api-endpoint {
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: 10px; padding: 18px 20px; margin-bottom: 16px;
}
.api-endpoint-header {
    display: flex; align-items: center; gap: 10px; margin-bottom: 8px;
}
.api-endpoint-header code {
    font-family: monospace; font-size: 14px; font-weight: 600; color: var(--text);
}
.api-method {
    font-size: 11px; font-weight: 700; padding: 3px 9px; border-radius: 4px;
    text-transform: uppercase; letter-spacing: .03em;
}
.api-method-get  { background: var(--status-info-bg); color: var(--status-info-fg); }
.api-method-post { background: var(--status-success-bg); color: var(--status-success-fg); }

@media (max-width: 860px) {
    .api-docs-layout { grid-template-columns: 1fr; gap: 20px; }
    .api-docs-nav { position: static; }
    .api-key-row { flex-direction: column; align-items: flex-start; }
}

/* ---- GDPR data request row (settings) + footer legal links ---- */
.settings-danger-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}
.settings-danger-item h4 {
    margin: 0 0 4px;
    font-size: 15px;
    font-weight: 600;
    color: var(--text);
}
.settings-danger-item p {
    margin: 0;
    color: var(--text-muted);
    font-size: 13px;
    line-height: 1.6;
}
.settings-danger-item .btn {
    flex-shrink: 0;
}

.footer-legal-links {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 16px;
}
.footer-legal-links a {
    color: var(--text-muted);
    text-decoration: none;
    font-size: 13px;
}
.footer-legal-links a:hover {
    color: var(--primary);
}
@media (max-width: 600px) {
    .settings-danger-item { flex-direction: column; align-items: flex-start; }
}

/* (.register-testimonial* CSS removed — the previous Sarah K. testimonial was fabricated,
   which FTC Section 5 treats as a deceptive practice that a disclaimer cannot cure. Restore the CSS
   when a real user gives written consent + a verification link.) */

/* ===== Stripe Connect nudge card (UX v2) ===== */
.stripe-nudge-card {
    display: flex;
    align-items: center;
    gap: 16px;
    background: linear-gradient(135deg, #EEF2FF, #F0FDF4);
    border: 1px solid var(--accent-border);
    border-radius: 12px;
    padding: 20px 24px;
    margin-bottom: 20px;
}
/* Dark mode: the hardcoded light gradient stayed bright on the dark page, washing
   out the (now-light) title to near-invisible. Use a subtle dark-indigo tint. */
[data-theme="dark"] .stripe-nudge-card {
    background: color-mix(in srgb, var(--primary) 12%, var(--bg-card));
    border-color: var(--accent-border, var(--border));
}
.stripe-nudge-icon { font-size: 32px; flex-shrink: 0; }
.stripe-nudge-content { flex: 1; }
.stripe-nudge-content h3 { font-size: 16px; font-weight: 700; margin-bottom: 4px; color: var(--text); }
.stripe-nudge-content p  { color: var(--text-muted); font-size: 14px; margin-bottom: 8px; }
.stripe-nudge-stat {
    font-size: 13px;
    color: var(--status-success-fg);
}
.stripe-nudge-actions {
    display: flex; flex-direction: column;
    gap: 8px; flex-shrink: 0; align-items: flex-end;
}
.stripe-nudge-card .btn-link {
    background: none; border: none; cursor: pointer;
    font-size: 13px; padding: 0; text-decoration: underline;
}
@media (max-width: 768px) {
    .stripe-nudge-card { flex-direction: column; align-items: flex-start; gap: 10px; padding: 14px 16px; }
    .stripe-nudge-actions { align-items: flex-start; }
    /* Compress (not remove) on phones: drop the benefits line + shrink the big icon.
       Title + description + CTA still carry the message. */
    .stripe-nudge-stat { display: none; }
    .stripe-nudge-icon { font-size: 22px; }
}

/* Referral nudge — sister card to .stripe-nudge-card, lighter accent (yellow/gold)
   to distinguish bonus/gift CTA from utility CTA. Shown on dashboard when the user
   has a pending referral credit gated on email verification. */
.referral-nudge-card {
    display: flex;
    align-items: center;
    gap: 16px;
    background: linear-gradient(135deg, #FEF3C7, #FFFBEB);
    border: 1px solid #FBBF24;
    border-radius: 12px;
    padding: 18px 22px;
    margin-bottom: 20px;
}
.referral-nudge-icon { flex-shrink: 0; display: flex; }
.referral-nudge-content { flex: 1; }
.referral-nudge-content h3 {
    font-size: 16px; font-weight: 700; margin-bottom: 4px; color: var(--text);
}
.referral-nudge-content p {
    color: var(--text-muted); font-size: 14px; margin: 0;
}
.referral-nudge-actions { flex-shrink: 0; }
/* Dismiss × (currently only the autopay nudge uses it). Warning-fg reads on the
   amber card in both themes — #92400E on light amber, #FCD34D on dark amber. */
.referral-nudge-close {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border: 0;
    border-radius: 7px;
    background: transparent;
    color: var(--status-warning-fg);
    opacity: 0.6;
    cursor: pointer;
    line-height: 1;
}
.referral-nudge-close:hover { opacity: 1; }
/* Dark mode: the card bg is a fixed light amber, but h3/p use --text/--text-muted
   (which flip light in dark mode) → light-on-light. Give it a dark amber-tinted
   surface so the existing text tokens regain contrast. */
[data-theme="dark"] .referral-nudge-card {
    background: rgba(251, 191, 36, 0.10);
    border-color: rgba(251, 191, 36, 0.32);
}
@media (max-width: 768px) {
    .referral-nudge-card { flex-direction: column; align-items: flex-start; }
}

/* ===== Sample data (UX v2) ===== */
.empty-sample-data {
    margin-top: 24px;
    text-align: center;
}
.empty-sample-data p {
    margin-bottom: 8px;
    font-size: 14px;
}
.sample-data-banner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    background: #FFF7ED;
    border: 1px solid #FED7AA;
    color: #9A3412;
    border-radius: 10px;
    padding: 12px 18px;
    margin-bottom: 20px;
    font-size: 14px;
}
.sample-data-banner strong { font-weight: 700; }
.sample-data-banner .btn { flex-shrink: 0; }

/* ===== Paid-subscription status banner ===== */
.sub-banner {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 20px;
    font-size: 14px;
    flex-wrap: wrap;
}
.sub-banner > span { flex: 1 1 280px; }
.sub-banner strong { font-weight: 700; }
.sub-banner-danger {
    background: var(--status-danger-bg);
    color: var(--status-danger-fg);
}
[data-theme="dark"] .sub-banner-danger {
    background: #3F1D1D;
    color: #FCA5A5;
}
.sub-banner-warning {
    background: var(--status-warning-bg);
    color: var(--status-warning-fg);
}
[data-theme="dark"] .sub-banner-warning {
    background: #3A2E12;
    color: #FCD34D;
}
.sub-banner-info {
    background: var(--accent-light);
    color: #3730A3;
}
[data-theme="dark"] .sub-banner-info {
    background: #1E2240;
    color: #A5B4FC;
}
.sub-banner-sticky {
    position: sticky;
    top: 0;
    z-index: 200;
}
.sub-banner-btn {
    background: var(--primary);
    color: #fff !important;
    padding: 6px 14px;
    border-radius: 6px;
    text-decoration: none;
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
}
.sub-banner-btn:hover {
    background: var(--primary-dark);
    text-decoration: none;
}
.sub-banner-btn-outline {
    background: transparent;
    color: var(--primary) !important;
    border: 1px solid var(--primary);
}
.sub-banner-btn-outline:hover {
    background: var(--primary);
    color: #fff !important;
}
.sub-banner-close {
    background: none;
    border: none;
    cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    opacity: 0.5;
    font-size: 16px;
    color: inherit;
    line-height: 1;
}
.sub-banner-close:hover { opacity: 1; }

/* ===== Billing current-plan details ===== */
.billing-current-plan {
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 20px;
    margin-bottom: 16px;
    background: var(--bg-card);
}
.billing-plan-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 16px;
}
.billing-plan-header h3 {
    margin: 0;
    font-size: 16px;
}
.plan-badge {
    display: inline-block;
    padding: 3px 12px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 700;
    background: var(--accent-light);
    color: var(--primary);
}
[data-theme="dark"] .plan-badge {
    background: #2A2F4A;
}
/* Large badge for the Settings → Billing fallback page */
.plan-badge-large {
    display: inline-block;
    padding: 6px 16px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 800;
    letter-spacing: 1.5px;
    background: var(--accent-light);
    color: var(--primary);
}
.plan-badge-solo { background: var(--bg-tertiary); color: #374151; }
.plan-badge-pro  { background: var(--accent-light); color: var(--primary); }
.plan-badge-team { background: var(--status-success-bg); color: var(--success); }

/* Feature-lock upgrade page (UX audit P1): value-selling gate for Team/Pro
   features instead of a bare "requires the X plan" error. */
.feature-lock { max-width: 620px; }
.feature-lock-card { text-align: center; padding: 36px 32px; }
.feature-lock-icon {
    width: 56px; height: 56px; margin: 0 auto 16px;
    border-radius: 16px; display: flex; align-items: center; justify-content: center;
    color: var(--primary); background: var(--accent-light);
}
.feature-lock-badge { display: inline-block; margin-bottom: 14px; }
.feature-lock-title { font-size: 26px; margin: 0 0 8px; }
.feature-lock-blurb { font-size: 15px; line-height: 1.55; margin: 0 auto 20px; max-width: 460px; }
.feature-lock-list {
    list-style: none; margin: 0 auto 26px; padding: 0;
    max-width: 380px; text-align: left;
    display: flex; flex-direction: column; gap: 10px;
}
.feature-lock-list li { display: flex; align-items: flex-start; gap: 9px; font-size: 14px; line-height: 1.45; }
.feature-lock-list li .icon-inline { color: var(--success); flex-shrink: 0; margin-top: 2px; }
.feature-lock-actions { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.feature-lock-note { margin: 2px 0 0; }
.feature-lock-back { margin: 22px 0 0; }

/* Customer-portal bulk-pay UI — moved off inline styles (UX audit P3). The
   portal is an intentionally light, standalone page, so colours stay fixed. */
.portal-bulk-bar {
    display: flex; justify-content: space-between; align-items: center;
    gap: 12px; padding: 10px 14px; margin-bottom: 10px; border-radius: 8px;
    background: #EEF2FF; color: #312E81; font-size: 14px; font-weight: 600;
}
.portal-bulk-select { display: flex; align-items: center; gap: 8px; cursor: pointer; }
.portal-bulk-checkout {
    display: none; margin-top: 18px; padding: 18px;
    border: 1px solid #E5E7EB; border-radius: 12px; background: #fff;
}
.portal-bulk-checkout.is-open { display: block; }
.portal-bulk-pe { margin: 14px 0; min-height: 120px; }
.portal-bulk-msg { margin-bottom: 10px; color: #DC2626; font-size: 13px; }

.billing-plan-details {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.billing-detail-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    padding: 9px 0;
    border-bottom: 1px solid var(--border);
    font-size: 14px;
}
.billing-detail-row:last-child { border-bottom: none; }
.billing-detail-row > span { color: var(--text-muted); }
.billing-detail-row strong {
    font-weight: 600;
    text-align: right;
}
.billing-plan-actions {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-top: 16px;
}
/* Pause-subscription panel (revealed under the plan actions). */
.billing-pause-panel { margin-top: 12px; padding: 12px 14px; background: var(--accent-light); border: 1px solid var(--border); border-radius: 8px; }
.billing-pause-panel p { margin: 0; }
.billing-pause-btns { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
/* Billing history tab: last-12-invoices table (lazy-loaded from Stripe). */
.billing-history-table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.billing-history-table th {
    text-align: left; padding: 8px 10px; font-size: 12px;
    color: var(--text-muted); border-bottom: 1px solid var(--border);
}
.billing-history-table td { padding: 9px 10px; border-bottom: 1px solid var(--bg-tertiary); }
.billing-history-table tbody tr:last-child td { border-bottom: 0; }
.billing-history-table .bh-amount { font-variant-numeric: tabular-nums; white-space: nowrap; }
.billing-history-table .bh-links { text-align: right; white-space: nowrap; }

/* Paused-state banner on the plan card: status + Resume now. */
.billing-paused-banner {
    display: flex; align-items: center; justify-content: space-between; gap: 14px;
    flex-wrap: wrap;
    padding: 12px 16px; margin-bottom: 16px;
    background: var(--status-warning-bg); color: var(--status-warning-fg);
    border: 1px solid color-mix(in srgb, var(--status-warning-fg) 30%, transparent);
    border-radius: 8px;
}
.billing-paused-text { flex: 1 1 240px; min-width: 0; line-height: 1.45; }
.billing-paused-banner .btn { flex: 0 0 auto; white-space: nowrap; }
.text-danger { color: var(--danger) !important; }

/* ===== Auth pages (login/signup redesign) ===== */
.auth-page {
    width: 100%;
    max-width: 460px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
}

/* Logo (replaces the "Back to Homepage" button) */
.auth-logo-wrap { width: 100%; text-align: center; }   /* Logo above the auth card: centered (axis matches the card below for visual balance) */
.auth-logo {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 20px;
    font-weight: 800;
    color: var(--primary);
    text-decoration: none;
}
.auth-logo span { color: var(--text); }
.auth-logo:hover { opacity: 0.85; }

.auth-subtitle {
    font-size: 14px;
    color: var(--text-muted);
    margin-bottom: 16px;
    text-align: center;
    /* If a subtitle does wrap, balance the lines instead of orphaning one word
       (graceful no-op on browsers without support). */
    text-wrap: balance;
}

/* Account-switch link (placed at the top) */
.auth-switch {
    font-size: 13px;
    color: var(--text-muted);
    margin-bottom: 16px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--border);
    text-align: center;
}
.auth-switch a {
    color: var(--primary);
    font-weight: 600;
    text-decoration: none;
}
.auth-switch a:hover { text-decoration: underline; }
/* Bottom-of-card variant: swap border-bottom (top version) for border-top, flip padding/margin */
.auth-switch-bottom {
    margin-top: 20px; margin-bottom: 0;
    padding-top: 16px; padding-bottom: 0;
    border-top: 1px solid var(--border); border-bottom: none;
}

/* Form elements */
.form-label-optional {
    font-size: 11px;
    color: var(--text-muted);
    font-weight: 400;
    margin-left: 4px;
}
.form-label-link {
    float: right;
    font-size: 13px;
    color: var(--primary);
    font-weight: 400;
    text-decoration: none;
}
.form-label-link:hover { text-decoration: underline; }

.required { color: var(--danger); }

.form-group-inline { margin-bottom: 14px; }
/* auth: Remember me (left) + Forgot password (right) on the same row */
.auth-row-split { display: flex; align-items: center; justify-content: space-between; gap: 12px; }

/* === Two-Factor Authentication input (verify_2fa) === */
.totp-wrap { margin: 20px 0; }
.totp-input {
    width: 100%; padding: 12px;
    font-size: 28px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    text-align: center; letter-spacing: 8px;
}
.backup-toggle-wrap { margin-top: 16px; text-align: center; font-size: 13px; }
.backup-toggle-btn {
    background: none; border: none; padding: 0;
    color: var(--text-muted); font-size: 13px; cursor: pointer;
}
.backup-toggle-btn:hover { color: var(--primary, var(--primary)); text-decoration: underline; }
.backup-section { margin-top: 14px; }
.backup-code-input {
    width: 100%; padding: 10px 12px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    text-transform: uppercase; letter-spacing: 3px;
    border: 1px solid var(--border); border-radius: 8px;
}
.backup-submit-btn { margin-top: 8px; }

/* === verify_email_result status card (success / already_verified / expired / invalid) === */
.auth-card-center { text-align: center; }
.auth-result-icon {
    display: inline-flex; align-items: center; justify-content: center;
    width: 80px; height: 80px;
    margin-bottom: 16px;
    border-radius: 50%;
}
.auth-result-icon-success { background: var(--status-success-bg); color: var(--status-success-fg); }
.auth-result-icon-warning { background: var(--status-warning-bg); color: var(--status-warning-fg); }
.auth-result-icon-error   { background: var(--status-danger-bg);  color: var(--status-danger-fg); }
.auth-result-cta { margin-top: 20px; }
.checkbox-label {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    color: var(--text-muted);
    cursor: pointer;
}

/* Password input */
.input-password-wrap {
    position: relative;
    display: flex;
    align-items: center;
}
.input-password-wrap input {
    flex: 1;
    padding-right: 44px;
}
.btn-toggle-password {
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    cursor: pointer;
    color: var(--text-muted);
    padding: 6px;
    line-height: 0;
    border-radius: 6px;
    transition: color .15s, background .15s;
}
.btn-toggle-password:hover { color: var(--primary); background: var(--bg-tertiary); }
.btn-toggle-password .icon-eye-off { display: none; }
.btn-toggle-password.is-revealed .icon-eye { display: none; }
.btn-toggle-password.is-revealed .icon-eye-off { display: inline-flex; }
.btn-toggle-password svg { display: inline-flex; }

/* Password-strength bar */
.password-strength {
    height: 4px;
    background: var(--bg-tertiary);
    border-radius: 2px;
    margin-top: 6px;
    overflow: hidden;
}
.password-strength-bar {
    height: 100%;
    width: 0;
    border-radius: 2px;
    transition: width 0.3s, background 0.3s;
}
.password-strength-label {
    font-size: 12px;
    margin-top: 3px;
    font-weight: 500;
}

/* Tiny inline confirm-password mismatch state — different visual weight than the
   global .form-error banner since it's a per-field hint, not a form-level rejection. */
.auth-confirm-mismatch { background: transparent; border: 0; padding: 6px 0 0; margin: 0; font-size: 12px; }

/* forgot-password "Check your inbox" success state — centered swap-in container */
.auth-fp-done { text-align: center; }
.auth-fp-tips {
    text-align: left;
    margin: 20px auto 0;
    max-width: 360px;
    line-height: 1.6;
}
.auth-fp-tip-list {
    list-style: none;
    padding: 8px 0 0;
    margin: 0;
}
.auth-fp-tip-list li {
    padding: 4px 0 4px 18px;
    position: relative;
}
.auth-fp-tip-list li::before {
    content: "•";
    position: absolute;
    left: 4px;
    color: var(--text-muted);
}

/* Form error */
.form-error {
    background: var(--status-danger-bg);
    color: var(--danger);
    border: 1px solid #FECACA;
    border-radius: 6px;
    padding: 10px 14px;
    font-size: 13px;
    margin-top: 12px;
}
/* Inline CTA inside .form-error (e.g. "Log in →" when email already exists). Same red
   tone as the surrounding text so it reads as part of the message, but bold + underlined
   so it's obviously actionable. */
.form-error-link {
    color: var(--danger);
    text-decoration: underline;
    font-weight: 600;
    white-space: nowrap;
}
.form-error-link:hover { text-decoration: none; }

/* Footer note */
.auth-footer-note {
    font-size: 12px;
    color: var(--text-muted);
    text-align: center;
    line-height: 1.5;
}
.auth-footer-note a { color: var(--text-muted); }

/* ===== Email-verification banner. Lives inside the .container column (moved out
   of inc.header on 2026-05-29), so it's styled as a rounded card — matching the
   sibling .sample-data-banner — with margin-bottom so it doesn't butt into the
   Dashboard page-head below. ===== */
.verify-banner {
    background: var(--status-warning-bg);
    border: 1px solid #FDE68A;
    border-radius: 10px;
    color: var(--status-warning-fg);
    font-size: 14px;
    margin-bottom: 20px;
}
.verify-banner-inner {
    padding: 12px 44px 12px 16px;  /* R:44 leaves room for the absolutely-positioned ✕ */
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 10px;
    flex-wrap: wrap;
    position: relative;
}
.verify-banner-icon { font-size: 16px; flex-shrink: 0; display: inline-flex; align-items: center; }
.verify-banner-link {
    background: none;
    border: 1px solid #92400E;
    border-radius: 5px;
    padding: 3px 10px;
    font-size: 13px;
    color: var(--status-warning-fg);
    cursor: pointer;
    font-weight: 600;
    white-space: nowrap;
}
.verify-banner-link:disabled { opacity: 0.5; cursor: not-allowed; }
.verify-banner-close {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--status-warning-fg);
    opacity: 0.6;
    font-size: 16px;
    display: inline-flex; align-items: center; justify-content: center;
    /* Pinned to the right of banner-inner, decoupled from the centered group (Linear / Stripe style) */
    position: absolute;
    right: 16px;
    top: 50%;
    transform: translateY(-50%);
    padding: 4px 8px;
    line-height: 1;
}
.verify-banner-close:hover { opacity: 1; }

/* Auth redesign: full-width Google button */
.btn-google { width: 100%; }

/* Import-review numeric columns (Amount / Line): right-align like money. The
   .num class was only styled under .report-source-table, so it was inert in the
   .ir-table import preview — amounts rendered left-aligned. */
.ir-table .num { text-align: right; font-variant-numeric: tabular-nums; }

/* ── Email-intake cards ────────────────────────────────────────────────
   Connection state reads as scannable icon facts (a "meta row") instead of
   a run-on sentence that orphan-wraps. Keeps the cards light on copy. */
.intake-page-lede {
    margin: 0 0 18px;
    font-size: 14px;
}
.invoice-intake-page .intake-page-lede {
    font-size: 15px;
}
.intake-card {
    max-width: 720px;
    padding: 20px 22px;
}
.invoice-intake-page .intake-card {
    max-width: 780px;
    padding: 22px;
}
/* === "Check intake" queue table (/invoice/intake/) ===
   Column order / visibility / width + click-to-sort reuse the shared
   table-columns engine (same as the invoice & client lists), which applies
   table-layout:fixed and explicit <col> widths — so column sizing is driven by
   the engine, not nth-child floors here. */
.intake-queue { padding: 20px 22px; }
.intake-queue-head-actions { display: flex; align-items: center; gap: 10px; }
.intake-queue-table { font-size: 13px; }
.intake-queue-table th,
.intake-queue-table td { vertical-align: top; }
/* position:relative anchors each th's absolute .col-resize-handle to its right edge. */
.intake-queue-table thead th { position: relative; }
.intake-queue-table thead th .sort-link { white-space: nowrap; }
.intake-queue-table .iq-when { white-space: nowrap; color: var(--text-muted); }
.intake-queue-table .iq-amount { font-variant-numeric: tabular-nums; }
.intake-queue-table td.iq-amount { white-space: nowrap; }
/* The amount VALUE stays on one line (nowrap above), but the meta lines under it
   — invoice #, due date — can carry a long no-space invoice number (e.g.
   #264120000018251…) that would otherwise spill across into the "Why" column.
   Let those wrap/break within the column instead. */
.intake-queue-table td.iq-amount .intake-queue-meta { white-space: normal; overflow-wrap: anywhere; }
/* Action column centred vertically so the buttons sit against the middle of a
   tall (multi-line) row rather than clinging to the top. */
.intake-queue-table .iq-action { text-align: right; white-space: nowrap; vertical-align: middle; }
.iq-action-btns { display: flex; gap: 6px; justify-content: flex-end; align-items: center; }
.intake-queue-table .iq-from-email { font-size: 11px; overflow-wrap: anywhere; }
/* Subject can be a long no-space filename (e.g. dzfp_2641…_2026….pdf); in the
   fixed-layout resizable table it would otherwise spill across the next columns.
   Clip to one line with an ellipsis — the full subject shows on hover (title). */
.intake-queue-table td[data-col="subject"] {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* Secondary line under the primary cell value (channel, sender name, due date,
   confidence) — muted + small, with a little breathing room above. */
.intake-queue-meta { color: var(--text-muted); font-size: 11.5px; margin-top: 3px; }
.intake-queue-table .intake-queue-reason { color: var(--text); }
/* Matched-client line in the From column — slightly emphasised so "we recognise
   this sender" reads at a glance. */
.intake-queue-table .intake-queue-match { color: var(--text); font-weight: 600; }
/* Primary forward card carries a subtle accent border so it reads as the
   main action; the rest are plain cards, uniform with the Tags page. */
.intake-card-primary {
    border-color: var(--accent-border);
}
/* Discovery tip that auto-forwarding is supported — a soft accent chip sitting
   just under the intake address it refers to. */
.intake-autoforward-hint {
    display: flex; align-items: center; gap: 8px;
    width: fit-content; max-width: 100%;   /* hug the text, don't span the full row */
    margin: 10px 0 2px; padding: 9px 12px;
    background: var(--accent-light); border-radius: 8px;
    font-size: 12.5px; line-height: 1.5; color: var(--text-muted);
}
.intake-autoforward-hint .icon-inline { color: var(--primary); flex-shrink: 0; }
.intake-autoforward-hint strong { color: var(--ink); font-weight: 600; }
/* Auto-forward confirmation banner (Gmail/Yahoo/iCloud forwarding code/link). */
.intake-fwd-confirm {
    margin: 14px 0 4px;
    padding: 14px 16px;
    border: 1px solid var(--accent-border);
    background: var(--accent-light);
    border-radius: 10px;
}
.intake-fwd-confirm-head {
    display: flex; align-items: center; gap: 8px;
    font-size: 14px; color: var(--ink);
}
.intake-fwd-confirm-head strong { flex: 1; }
.intake-fwd-dismiss {
    background: none; border: 0; cursor: pointer;
    font-size: 20px; line-height: 1; color: var(--text-muted); padding: 0 4px;
}
.intake-fwd-dismiss:hover { color: var(--ink); }
.intake-fwd-copy { margin: 6px 0 8px; }
.intake-fwd-code {
    margin: 8px 0; font-size: 14px;
}
.intake-fwd-code strong {
    font-family: ui-monospace, Menlo, monospace; font-size: 16px; letter-spacing: 1px;
    background: var(--bg-card); border-radius: 6px; padding: 3px 8px; border: 1px solid var(--border);
}
.intake-fwd-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.intake-card-log {
    background: var(--bg-card);
    border-color: var(--border);
}
/* Settings summary: a slim one-line card standing in for the full table.
   Plain block flow (not inline-flex like the empty-note) so the inline icon,
   count and link keep their natural word spacing. */
.intake-card-summary > h2 {
    margin-bottom: 10px;
}
.intake-summary-line {
    margin: 0;
    line-height: 1.6;
}
.intake-summary-line .icon-inline {
    vertical-align: -2px;
    margin-right: 2px;
}
.intake-card-log > h2 {
    margin-bottom: 16px;
    font-size: 17px;
}
.intake-card-head {
    justify-content: flex-start;
    align-items: center;
    gap: 16px;
}
.intake-title-control {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    min-width: 0;
}
.intake-title-control .intake-title {
    margin: 0;
}
.intake-title {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    flex-wrap: nowrap;
    min-width: 0;
}
.intake-title .badge { margin-left: 0; }
.intake-title .icon-inline {
    flex-shrink: 0;
    margin-top: 2px;
}
.intake-title > span {
    min-width: 0;
}
.intake-toggle-control {
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
}
.intake-provider-title {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    min-width: 0;
}
.intake-provider-title .badge { margin-left: 0; }
.intake-provider-title .icon-inline {
    color: var(--text-muted);
    flex-shrink: 0;
}
.intake-card > p.intake-card-copy {
    max-width: 660px;
    margin-bottom: 14px;
    line-height: 1.55;
}
.intake-card > p.intake-quota-line {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 6px 0 14px;
    line-height: 1.45;
}
.intake-quota-line .icon-inline {
    color: var(--text-muted);
    flex-shrink: 0;
}
.intake-address-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 14px 0 10px;
    flex-wrap: wrap;
}
.intake-address-control {
    display: flex;
    align-items: stretch;
    flex: 1 1 0;
    min-width: 0;
}
.intake-address-control .intake-addr {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
    border-right: 0;
}
.intake-copy-btn {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 80px;
}
.btn.intake-link-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    background: transparent;
    border-color: transparent;
    color: var(--text-muted);
    padding-left: 6px;
    padding-right: 6px;
}
.btn.intake-link-btn:hover {
    color: var(--primary);
    border-color: transparent;
    background: transparent;
}
.intake-details-summary {
    cursor: pointer;
    font-weight: 600;
    font-size: 13px;
    color: var(--text-muted);
    padding: 7px 0;
}
.intake-details-summary:hover { color: var(--primary); }
.intake-card > p.intake-empty-note {
    display: inline-flex;
    align-items: center;
    max-width: 100%;
    margin: 0;
    padding: 9px 12px;
    border: 1px dashed var(--border);
    border-radius: 8px;
    background: var(--bg);
    line-height: 1.55;
}
.intake-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 16px;
    margin: -2px 0 14px;
    font-size: 13px;
    color: var(--text-muted);
}
.intake-meta > span { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.intake-meta .icon-inline { color: var(--text-muted); flex-shrink: 0; }
.intake-meta code { font-size: 12px; color: var(--text); white-space: normal; }
.intake-meta strong { color: var(--text); font-weight: 600; }
/* Compact opt-in row (auto-create). Reset the global input width:100% so the
   checkbox doesn't stretch and push the label off the card. */
.intake-optin {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    margin-bottom: 14px;
    font-size: 13px;
    color: var(--text-muted);
    cursor: pointer;
}
.intake-optin > input { width: auto; flex: none; margin-top: 2px; }

/* Intake address chip: looks like the old readonly input, but renders the long
   random token muted and the @domain in brand color so the structure of
   add+<token>@in.duefy.ai reads at a glance instead of as one noisy string. */
.intake-addr {
    flex: 1;
    min-width: 0;
    display: inline-block;
    /* Wrap (not ellipsis) so the accented @domain is never hidden on a narrow
       column. Copy uses the full value in data-email regardless. */
    white-space: normal;
    overflow-wrap: anywhere;
    padding: 11px 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--input-bg);
    color: var(--text);
    font-family: ui-monospace, Menlo, monospace;
    font-size: 14px;
    line-height: 1.35;
    cursor: pointer;
    transition: border-color .12s ease;
}
.intake-addr:hover { border-color: var(--primary); }
.intake-addr .addr-token  { color: var(--text-muted); }
.intake-addr .addr-domain { color: var(--primary); font-weight: 500; }

@media (max-width: 640px) {
    .intake-address-control {
        flex-basis: 100%;
    }
    .intake-link-btn {
        width: auto;
    }
}

/* Email-intake method tabs — Forward email vs Watch your sent folder, shown
   one panel at a time (an either/or choice, not a stacked list of cards). */
/* Segmented control: a recessed grey track (--surface-2) with the active tab
   raised as a white card (--surface-3, below). Without the old shell card
   behind it the track needs real figure/ground — a primary-tinted near-white
   fill blended into the page background. */
.intake-method-tabs {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 5px;
    margin: 6px 0 20px;
    padding: 5px;
    max-width: 560px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 11px;
}
.invoice-intake-page .intake-method-tabs {
    width: 100%;
    max-width: 560px;
}
.intake-method-tab {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 7px;
    min-width: 0;
    border: 1px solid transparent;
    background: transparent;
    min-height: 40px;
    padding: 8px 12px;
    border-radius: 8px;
    font-size: 14px;
    font-weight: 600;
    color: var(--text-muted);
    cursor: pointer;
    transition: background .12s ease, color .12s ease;
}
.intake-method-tab:hover { color: var(--text); background: var(--bg-hover, rgba(127, 127, 127, .08)); }
.intake-method-tab.is-active {
    background: var(--surface-3, var(--bg-card));
    border-color: var(--border);
    color: var(--primary);
    box-shadow: 0 1px 3px rgba(0, 0, 0, .12);
}
.intake-method-tab.is-active:hover { background: var(--surface-3, var(--bg-card)); }
.intake-method-tab .icon-inline { flex-shrink: 0; }

.intake-log-scroll {
    max-width: 100%;
    overflow-x: auto;
}
.intake-log-table {
    table-layout: fixed;
    width: 100%;
    font-size: 13px;
    min-width: 0;
}
.intake-log-table th,
.intake-log-table td {
    padding: 12px 10px;
    vertical-align: middle;
}
.intake-log-table th:nth-child(1),
.intake-log-table td:nth-child(1) { width: 90px; }
.intake-log-table th:nth-child(2),
.intake-log-table td:nth-child(2) { width: 162px; }
.intake-log-table th:nth-child(3),
.intake-log-table td:nth-child(3) { width: 126px; }
.intake-log-table th:nth-child(4),
.intake-log-table td:nth-child(4) { width: 120px; }
.intake-log-table td:nth-child(2) code {
    white-space: normal;
    overflow-wrap: anywhere;
}
.intake-log-table td:nth-child(3),
.intake-log-table td:nth-child(5) {
    overflow-wrap: anywhere;
}
.intake-log-table .badge {
    white-space: nowrap;
}
.intake-log-table .badge-partial {
    background: transparent;
    border: 1px solid var(--status-warning-bg);
    color: var(--status-warning-fg);
    padding: 1px 7px;
}
.invoice-intake-page .intake-log-table th:nth-child(1),
.invoice-intake-page .intake-log-table td:nth-child(1) { width: 88px; }
.invoice-intake-page .intake-log-table th:nth-child(2),
.invoice-intake-page .intake-log-table td:nth-child(2) { width: 176px; }
.invoice-intake-page .intake-log-table th:nth-child(3),
.invoice-intake-page .intake-log-table td:nth-child(3) { width: 150px; }
.invoice-intake-page .intake-log-table th:nth-child(4),
.invoice-intake-page .intake-log-table td:nth-child(4) { width: 118px; }
.intake-result-match-label { display: block; font-size: 10px; font-weight: 600; letter-spacing: .3px; text-transform: uppercase; }
.intake-result-match {
    display: block;
    color: var(--text);
    font-weight: 600;
    line-height: 1.35;
}
/* Channel-provenance tag ("via Gmail/Outlook"). Neutral on purpose — it's
   passive metadata, so it must not compete with the actionable Review link. */
.intake-source-tag {
    background: var(--bg-tertiary);
    color: var(--text-muted);
    font-size: 10px;
}
.intake-complete-link {
    display: inline-flex;
    align-items: center;
    margin-top: 4px;
    padding: 2px 7px;
    border-radius: 6px;
    background: var(--accent-light);
    color: var(--primary);
    font-size: 12px;
    font-weight: 700;
    line-height: 1.35;
}
.intake-complete-link:hover {
    text-decoration: none;
    background: var(--bg-tertiary);
}

@media (max-width: 540px) {
    .intake-title-control {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        column-gap: 12px;
        width: 100%;
        align-items: start;
    }
    .intake-toggle-control {
        padding-top: 1px;
    }
    .intake-card > p.intake-empty-note {
        display: flex;
    }
}

@media (max-width: 640px) {
    .intake-log-table {
        min-width: 640px;
    }
}

/* Compact "scan on a computer" QR — kept secondary to the Open WhatsApp button
   so it never implies scanning is the only way to link. */
.intake-qr {
    display: inline-flex;
    align-items: center;
    gap: 14px;
    margin: 6px 0 16px;
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--bg-soft);
    max-width: 100%;
    flex-wrap: wrap;
}
.intake-qr img { width: 96px; height: 96px; flex: 0 0 auto; }
.intake-qr p { margin: 0; max-width: 230px; }

/* ============================================================
   Settings / Industry templates picker
   (was an inline <style> block in industry_templates.tpl.php)
   ============================================================ */
.industry-lede   { margin-bottom: 8px; }
.industry-status { margin-bottom: 18px; }
.industry-locked-note {
    background: var(--status-warning-bg); color: var(--status-warning-fg);
    padding: 10px 14px; border-radius: 8px; margin-bottom: 18px;
}
.industry-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 16px; margin-top: 8px;
}
.industry-card {
    border: 1px solid var(--border); border-radius: 12px;
    padding: 16px 18px; background: var(--bg-card);
    display: flex; flex-direction: column;
}
.industry-card-current { border-color: var(--primary); box-shadow: var(--focus-ring); }
.industry-card-head {
    display: flex; justify-content: space-between; align-items: flex-start;
    gap: 8px; margin-bottom: 6px;
}
.industry-card-title { font-weight: 700; font-size: 15px; color: var(--text); line-height: 1.3; }

/* Tone chip — coloured as an escalation spectrum so a glance tells you how
   hard the sequence pushes: friendly (blue) → formal (neutral) → firm (amber). */
.industry-card-chip {
    font-size: 11px; padding: 2px 8px; border-radius: 999px;
    font-weight: 600; text-transform: uppercase; letter-spacing: .04em;
    flex-shrink: 0;
}
.industry-card-chip--friendly { background: var(--status-info-bg);    color: var(--status-info-fg); }
.industry-card-chip--formal   { background: var(--bg-tertiary);       color: var(--text-muted); }
.industry-card-chip--firm     { background: var(--status-warning-bg); color: var(--status-warning-fg); }

.industry-card-pace {
    display: flex; align-items: center; gap: 5px;
    font-size: 12px; color: var(--text-muted); margin-bottom: 8px;
    font-family: ui-monospace, Menlo, monospace; cursor: help;
}
.industry-card-pace .icon-inline { color: var(--text-muted); flex-shrink: 0; }
.industry-card-blurb { font-size: 13px; color: var(--text); line-height: 1.5; margin-bottom: 12px; flex: 1; }

.industry-card-preview-btn {
    display: inline-flex; align-items: center; gap: 5px;
    background: none; border: none; padding: 0; margin-bottom: 14px;
    font: inherit; font-size: 13px; font-weight: 600; color: var(--primary);
    cursor: pointer; align-self: flex-start;
}
.industry-card-preview-btn:hover { text-decoration: underline; }

/* Apply — the only action on the page, so give it presence without 8 loud
   solid buttons: soft accent that fills to solid primary on hover. */
.industry-card-apply {
    margin-top: auto;
    background: var(--accent-light); color: var(--primary);
    border: 1px solid transparent; font-weight: 600;
}
.industry-card-apply:hover:not(:disabled) { background: var(--primary); color: #fff; opacity: 1; }
.industry-card-apply:disabled {
    background: var(--bg-tertiary); color: var(--text-muted);
    cursor: default; opacity: 1;
}

/* Step list — shared by the preview modal */
.industry-step-list {
    padding: 0; margin: 0; list-style: none;
    display: flex; flex-direction: column; gap: 12px;
}
.industry-step-list li {
    font-size: 12px; line-height: 1.5;
    padding-bottom: 12px; border-bottom: 1px solid var(--border);
}
.industry-step-list li:last-child { border-bottom: 0; padding-bottom: 0; }
.industry-step-meta { color: var(--text-muted); font-size: 11px; margin-bottom: 3px; }
.industry-step-subj { font-weight: 600; color: var(--text); margin-bottom: 3px; }
.industry-step-body { color: var(--text-muted); white-space: pre-wrap; }

/* ============================================================
   Settings / Reminder results  (/settings/deliverability/)
   ROI panel + exception-driven email-health corner.
   (was an inline <style> in deliverability.tpl.php; all colors
   pull from design tokens — see ADR 013.)
   ============================================================ */
.deliv-window-h3 { font-size: 0.95rem; margin: 0 0 0.75rem 0; color: var(--text-muted); }

/* ROI panel — "what your reminders collected".
   rr- prefix is scoped to this page (the dashboard already owns generic
   .roi-* classes — do not reuse them here). Two windows stacked vertically;
   each is one horizontal metrics strip with divider-separated columns (no
   nested boxes, no orphaned half-width card). "Collected" is the accent hero. */
.rr-empty { margin: 1.25rem 0 0.25rem; }
.rr-empty p:first-child { font-weight: 600; }
/* A *subtle* tint groups each window without the heavy block the solid
   --surface-2 fill produced on the white card. Light: a hair off white.
   Dark: a hair lighter than the card (--surface-2 == --bg-card in dark, so
   mix toward --surface-3 instead). */
.rr-windows { display: flex; flex-direction: column; gap: 0.85rem; margin: 1.25rem 0 0.25rem; }
.rr-window {
    padding: 1rem 1.25rem; border-radius: 10px;
    background: color-mix(in srgb, var(--surface-2) 45%, var(--bg-card));
}
[data-theme="dark"] .rr-window {
    background: color-mix(in srgb, var(--surface-3) 40%, var(--bg-card));
}
.rr-window-label {
    font-size: 0.72rem; font-weight: 700; letter-spacing: 0.06em;
    text-transform: uppercase; color: var(--text-muted); margin-bottom: 0.85rem;
}
.rr-row { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1.2fr; gap: 1.25rem; }
.rr-cell { padding-left: 1.25rem; border-left: 1px solid var(--border); min-width: 0; }
.rr-cell:first-child { padding-left: 0; border-left: 0; }
.rr-num { font-size: 1.4rem; font-weight: 700; line-height: 1.15; color: var(--text); white-space: nowrap; }
.rr-cell-hero .rr-num { font-size: 1.6rem; color: var(--primary); }
/* Extra-currency amounts under the main figure (multi-currency orgs). */
.rr-num-extra { font-size: 0.8rem; font-weight: 600; color: var(--text-muted); margin-top: 2px; }
.rr-unit { font-size: 0.85rem; font-weight: 600; color: var(--text-muted); margin-left: 1px; }
.rr-label { font-size: 0.78rem; font-weight: 600; margin-top: 0.3rem; color: var(--text-muted); }
/* Below ~900px the 4-up strip gets cramped (labels wrap hard); drop to a
   roomy 2×2 — 4 cells fill it evenly, so no orphaned half-width card. */
@media (max-width: 900px) {
    .rr-row { grid-template-columns: 1fr 1fr; gap: 1rem 1.25rem; }
    .rr-cell, .rr-cell:first-child { padding-left: 0; border-left: 0; }
}

/* Email-health corner */
.deliv-health-ok,
.deliv-health-warn { display: flex; align-items: center; gap: 8px; margin: 0.5rem 0 0; font-size: 0.9rem; }
.deliv-health-ok   { color: var(--text); }
.deliv-health-warn { color: var(--status-warning-fg); font-weight: 600; }
.deliv-health-ok .icon-inline,
.deliv-health-warn .icon-inline { flex-shrink: 0; }

/* Small delivery counts under the health status line. */
.rr-health-stats {
    display: flex; flex-wrap: wrap; align-items: baseline;
    gap: 0.4rem 1.1rem; margin-top: 0.75rem;
    font-size: 0.82rem; color: var(--text-muted);
}
.rr-health-stats strong { color: var(--text); font-weight: 700; font-size: 0.95rem; }
.rr-health-stat-bad strong { color: var(--status-warning-fg); }
.rr-health-stats-window { margin-left: auto; font-size: 0.75rem; }

.deliv-failures { margin: 1.25rem 0 0.5rem; }
.deliv-pagination { display: flex; gap: 10px; align-items: center; margin-top: 12px; }
.deliv-failures summary { font-weight: 600; cursor: pointer; }
.deliv-failures-table { margin-top: 0.75rem; }
.deliv-failures-table .ellipsis { max-width: 280px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.deliv-status { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 0.75rem; font-weight: 600; }
.deliv-status-failed  { background: var(--status-danger-bg);  color: var(--status-danger-fg); }
.deliv-status-bounced { background: var(--status-warning-bg); color: var(--status-warning-fg); }
.deliv-domain { margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid var(--border); }

/* ============================================================
   Settings / Pay-page branding — live preview (.bp-*)
   A faithful mini of the PUBLIC pay page (tpl/pay/index.tpl.php).
   That page is always light-themed regardless of the merchant's app
   theme, so this palette is intentionally fixed light (not theme tokens)
   — the preview must match what the customer actually sees.
   Brand colors on .bp-pay-btn are applied at runtime by the page JS.
   ============================================================ */
.bp-caption { margin-bottom: 14px; }
.bp-stage {
    border: 1px solid var(--border); border-radius: 12px;
    padding: 24px; background: #f3f4f6;
}
.bp-logo { text-align: center; margin-bottom: 14px; }
.bp-logo-img { max-height: 56px; max-width: 240px; object-fit: contain; }
.bp-logo-fallback { font-size: 20px; font-weight: 700; color: #6b7280; }
.bp-card {
    background: #fff; border: 1px solid #e5e7eb; border-radius: 16px;
    padding: 22px 20px; max-width: 380px; margin: 0 auto;
    color: #1f2937; text-align: center;
}
.bp-sender-sub { font-size: 13px; color: #6b7280; }
.bp-sender-name { font-size: 17px; font-weight: 700; margin-bottom: 14px; }
.bp-amount { font-size: 36px; font-weight: 800; letter-spacing: -1px; color: #111827; line-height: 1.1; }
.bp-invnum { font-size: 14px; color: #6b7280; margin-top: 2px; }
.bp-due {
    display: inline-block; margin-top: 10px; padding: 4px 12px;
    border-radius: 999px; font-size: 12px; font-weight: 600;
    background: #ecfdf5; color: #059669;
}
.bp-field-label { text-align: left; font-size: 12px; font-weight: 600; color: #6b7280; margin: 18px 0 6px; }
.bp-card-field {
    border: 1px solid #e5e7eb; border-radius: 8px; padding: 11px 12px;
    font-size: 14px; color: #9ca3af; text-align: left; background: #fff;
    font-family: ui-monospace, Menlo, monospace;
}
.bp-pay-btn {
    display: block; width: 100%; border: 0; border-radius: 10px;
    padding: 13px 16px; margin-top: 16px; color: #fff;
    font-weight: 700; font-size: 15px; cursor: default; background: #4F46E5;
}
.bp-secured { font-size: 11px; color: #9ca3af; margin-top: 12px; display: flex; align-items: center; justify-content: center; gap: 5px; }
.bp-secured .icon-inline { flex-shrink: 0; }
.bp-powered { text-align: center; color: #9ca3af; font-size: 12px; margin-top: 14px; }

/* Invoice detail — "bank transfer in progress" banner (ADR 028). */
.iv-bank-pending {
    display: flex; align-items: center; gap: 8px;
    margin: 14px 0 0; padding: 10px 14px; border-radius: 8px;
    font-size: 13px; line-height: 1.45;
    background: var(--status-info-bg); color: var(--status-info-fg);
}
.iv-bank-pending .icon-inline { flex-shrink: 0; }
.iv-bank-pending-text { flex: 1; min-width: 180px; }
.iv-bank-pending-actions { flex-shrink: 0; display: flex; gap: 6px; flex-wrap: wrap; }
@media (max-width: 560px) { .iv-bank-pending { flex-wrap: wrap; } }

/* Invoice list — "bank transfer in progress" pill (ADR 028). */
.bt-pending-badge {
    display: inline-flex; align-items: center; gap: 3px;
    margin-left: 6px; padding: 1px 7px; border-radius: 999px;
    font-size: 11px; font-weight: 600; vertical-align: middle;
    background: var(--status-info-bg); color: var(--status-info-fg);
}
.bt-pending-badge .icon-inline { flex-shrink: 0; }

/* ============================================================
   Mobile foundation (PR 1 of the mobile-optimization plan).
   Reusable building blocks for the mobile work — additive, not yet
   wired into templates (PR 3/4/5 consume them). All colors via design
   tokens so dark mode is covered.

   Breakpoint convention (new code): phone <=640px, tablet 641-960px,
   desktop >960px. Use 640 for the real table->card switch, 960 for
   two-col->one-col / sidebar drop. (Legacy 768px rules stay until touched.)
   ============================================================ */

/* Touch devices: give small secondary controls (icon buttons + short action
   links) a ~40px hit area so they're comfortable to tap. Icon glyphs stay
   centered; visual footprint barely changes. Primary actions are already >=44px. */
@media (pointer: coarse) {
    .iv-icon-btn, .needs-action-toggle, .saved-views-more, .duefy-impact-dismiss {
        min-width: 40px; min-height: 40px;
        display: inline-flex; align-items: center; justify-content: center;
    }
    .iv-side-link-btn, .iv-step-link {
        min-height: 38px; display: inline-flex; align-items: center;
    }
}

/* ---- visibility utilities (640 breakpoint) ---- */
.u-mobile  { display: none; }
@media (max-width: 640px) {
    .u-mobile  { display: block; }
    .u-desktop { display: none !important; }
}
/* Invoice detail: Cancel / Write off live in the hero on desktop (.u-desktop) and
   move into the "More actions" disclosure on phones. Block wrapper (children keep
   their flex layout) shown at the same 640px breakpoint the hero buttons hide at,
   so neither view ever shows them twice. */
.iv-more-mobile-only { display: none; }
@media (max-width: 640px) { .iv-more-mobile-only { display: block; } }

/* ---- list card (table -> card on phones) ----
   Pattern: desktop keeps its <table> (wrapped in .u-desktop), phones
   render a .mobile-card-list of .mobile-list-card built from the SAME
   server-side row data/helpers. */
.mobile-card-list { display: flex; flex-direction: column; gap: 10px; }
.mobile-list-card {
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: 12px; padding: 14px;
}
.mlc-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
.mlc-title { font-weight: 700; font-size: 15px; color: var(--text); line-height: 1.3; }
.mlc-sub   { font-size: 13px; color: var(--text-muted); margin-top: 2px; }
.mlc-amount { font-size: 18px; font-weight: 800; color: var(--text); margin: 8px 0 2px; }
.mlc-meta  { display: flex; flex-wrap: wrap; gap: 6px 12px; font-size: 12px; color: var(--text-muted); }
.mlc-badges { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
/* PR4.1: info area is a block link; the actions row sits below it as a sibling
   (not nested in the <a>) separated by a hairline divider. */
.mlc-link { display: block; text-decoration: none; color: inherit; }
/* Long unbroken client names / emails / invoice numbers must wrap, not blow the
   card wider than the viewport. The title column is a flex child → needs min-width:0
   to be allowed to shrink; the badge must not shrink. */
.mlc-top > div:first-child { min-width: 0; }
.mlc-top > .badge { flex-shrink: 0; }
.mlc-title, .mlc-sub, .mlc-amount { overflow-wrap: anywhere; }
/* Same for the invoice-detail hero facts (grid items default to min-width:auto). */
.iv-hero-fact > * { min-width: 0; overflow-wrap: anywhere; }
.mlc-actions { display: flex; gap: 8px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }
.mlc-actions .btn { flex: 1; min-height: 44px; }

/* ---- bottom sheet (mobile modal / filter / action sheet) ----
   Replaces cramped centered modals on phones. Toggle the .is-open class. */
.sheet-overlay {
    position: fixed; inset: 0; background: rgba(17,24,39,.55);
    z-index: 1000; display: none;
}
.sheet-overlay.is-open { display: block; }
.sheet {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 1001;
    background: var(--bg-card); color: var(--text);
    border-radius: 16px 16px 0 0; padding: 16px 16px calc(16px + env(safe-area-inset-bottom, 0px));
    max-height: 85vh; overflow-y: auto;
    transform: translateY(100%); transition: transform .22s ease;
    box-shadow: 0 -8px 30px rgba(0,0,0,.25);
}
.sheet-overlay.is-open .sheet { transform: translateY(0); }
.sheet-handle { width: 38px; height: 4px; border-radius: 999px; background: var(--border); margin: 2px auto 12px; }
.sheet-title { font-size: 16px; font-weight: 700; margin-bottom: 12px; }
.sheet-plan-badge { margin-left: auto; }
.sheet-item {
    display: flex; align-items: center; gap: 12px;
    width: 100%; padding: 13px 6px; min-height: 48px;
    background: none; border: 0; border-bottom: 1px solid var(--border);
    font: inherit; font-size: 15px; color: var(--text); text-align: left;
    text-decoration: none; cursor: pointer;
}
.sheet-item:last-child { border-bottom: 0; }
.sheet-item .icon-inline { flex-shrink: 0; color: var(--text-muted); }
/* Compact legal row at the bottom of the More sheet (the page footer is hidden
   on mobile, so legal lives here). */
.sheet-legal {
    padding: 12px 6px 2px;
    font-size: 12px;
    color: var(--text-muted);
    text-align: center;
}
.sheet-legal a { color: var(--text-muted); text-decoration: none; }
.sheet-legal a:hover { color: var(--text); text-decoration: underline; }

/* ---- sticky action bar (detail / form primary actions) ---- */
.mobile-sticky-actions {
    position: sticky; bottom: 0; z-index: 50;
    display: flex; gap: 8px;
    padding: 10px 14px calc(10px + env(safe-area-inset-bottom, 0px));
    background: var(--bg-card); border-top: 1px solid var(--border);
    margin: 0 -14px;   /* bleed to card edges; override per host as needed */
}
.mobile-sticky-actions .btn { flex: 1; min-height: 46px; }

/* ---- mobile top utility bar (PR 3: search / notifications / account) ---- */
.mobile-top-bar { display: none; }
@media (max-width: 640px) {
    .mobile-top-bar {
        display: flex; align-items: center; gap: 10px;
        padding: 8px 14px calc(8px + env(safe-area-inset-top, 0px));
    }
    .mobile-top-bar .mtb-title { font-weight: 700; font-size: 16px; flex: 1; }
    .mobile-top-bar .mtb-action {
        width: 40px; height: 40px; display: flex; align-items: center; justify-content: center;
        border-radius: 10px; background: var(--bg-tertiary); color: var(--text); position: relative;
    }
    .mtb-badge {
        position: absolute; top: 4px; right: 4px; min-width: 16px; height: 16px;
        background: var(--danger); color: #fff; border-radius: 999px;
        font-size: 10px; font-weight: 700; display: flex; align-items: center; justify-content: center; padding: 0 4px;
    }
}

/* ---- invoice list: table on desktop, cards on phone (PR4) ---- */
.invoice-mobile-list { display: none; }
a.mobile-list-card { text-decoration: none; color: inherit; }
.mlc-unpaid { font-size: 12px; font-weight: 600; color: var(--text-muted); }
@media (max-width: 640px) {
    .invoice-mobile-list { display: flex; flex-direction: column; gap: 10px; }
    /* hide the desktop table chrome on phones */
    #invoice-table, .invoice-table-wrap, .invoice-table-toolbar { display: none !important; }
    /* status filter tabs: scroll horizontally instead of wrapping into a tall block.
       min-width:0 lets the row shrink below its content width inside the column-flex
       .invoice-list-controls so overflow-x:auto actually engages (flex items default
       to min-width:auto = min-content, which would otherwise force the page wider). */
    .filter-tabs { display: flex; flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; min-width: 0; max-width: 100%; }
    .filter-tabs > a { flex: 0 0 auto; white-space: nowrap; }
    .filter-tabs::-webkit-scrollbar { display: none; }
}

/* ---- mobile shell (PR3): top actions in navbar + bottom-nav button items ---- */
.mobile-nav-actions { display: none; }
@media (max-width: 640px) {
    .mobile-nav-actions { display: flex; align-items: center; gap: 6px; margin-left: auto; }
    .mobile-nav-actions .mtb-action {
        width: 40px; height: 40px; display: flex; align-items: center; justify-content: center;
        border-radius: 10px; background: none; border: 0; color: var(--text); position: relative; cursor: pointer;
    }
    .mobile-nav-actions .mtb-badge {
        position: absolute; top: 3px; right: 3px; min-width: 16px; height: 16px;
        background: var(--danger); color: #fff; border-radius: 999px; font-size: 10px; font-weight: 700;
        display: flex; align-items: center; justify-content: center; padding: 0 4px;
    }
}
/* +/More in the bottom nav are <button> now — reset to match the <a> items */
button.mobile-nav-item { background: none; border: 0; font: inherit; cursor: pointer; }
.sheet-empty { padding: 8px 6px; }

/* ---- invoice detail mobile (PR5): sticky primary action + sidebar accordion ---- */
.iv-mobile-actions { display: none; }
@media (max-width: 640px) {
    .iv-mobile-actions {
        display: flex; gap: 8px; z-index: 90;
        position: fixed; left: 0; right: 0;
        bottom: calc(62px + env(safe-area-inset-bottom, 0px)); /* sit above the bottom nav */
        padding: 10px 14px;
        background: var(--bg-card); border-top: 1px solid var(--border);
        box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.06);
    }
    .iv-mobile-actions .btn { flex: 1; min-height: 46px; }
    /* leave room so the fixed bar never covers the last bit of content */
    body:has(.iv-mobile-actions) .container { padding-bottom: 190px; }
    /* lift the floating feedback launcher above the sticky action bar */
    body:has(.iv-mobile-actions) #feedback-widget { bottom: 138px; }

    /* sidebar cards become tap-to-expand accordions (JS adds .iv-acc / .is-open) */
    .iv-acc > .iv-side-title { cursor: pointer; position: relative; padding-right: 34px; }
    .iv-acc > .iv-side-title::after {
        content: ''; position: absolute; right: 14px; top: calc(50% - 5px);
        width: 7px; height: 7px;
        border-right: 2px solid var(--text-muted); border-bottom: 2px solid var(--text-muted);
        transform: rotate(45deg); transition: transform 0.18s ease;
    }
    .iv-acc.is-open > .iv-side-title::after { transform: rotate(-135deg); }
    .iv-acc:not(.is-open) > .iv-side-body { display: none; }
}

/* ---- invoice add/edit mobile (PR6): sticky save so the long form keeps its
        primary action; secondary "Save & add another" is desktop-only (.u-desktop) ---- */
@media (max-width: 640px) {
    .invoice-form-actions {
        position: sticky;
        bottom: calc(62px + env(safe-area-inset-bottom, 0px)); /* above the bottom nav */
        z-index: 40;
        margin: 18px -22px -22px;        /* bleed to the card edges */
        padding: 12px 22px;
        background: var(--bg-card);
        border-top: 1px solid var(--border);
        border-radius: 0 0 var(--radius) var(--radius);
        box-shadow: 0 -3px 10px rgba(0, 0, 0, 0.05);
    }
    .invoice-form-actions .btn { flex: 1; min-height: 46px; margin-top: 0; }
    /* lift the floating feedback launcher clear of the sticky save bar */
    body:has(.invoice-form-card) #feedback-widget { bottom: 146px; }
}

/* ---- dashboard + clients mobile (PR7): tables -> cards (reuses .mlc-* / .mobile-list-card) ---- */
.client-mobile-list,
.dash-recent-mobile,
.client-inv-mobile { display: none; }
@media (max-width: 640px) {
    .client-mobile-list,
    .dash-recent-mobile,
    .client-inv-mobile { display: flex; flex-direction: column; gap: 10px; }
    /* hide the desktop tables on phones (the shared .invoice-table-toolbar is
       already hidden by the PR4 rule) */
    #client-table, .client-table-wrap { display: none !important; }
    .dash-recent-table { display: none !important; }
    .client-view-table-wrap { display: none !important; }
    /* client filter chips: scroll horizontally instead of stacking into a tall block */
    .client-filter-bar {
        display: flex; flex-wrap: nowrap; overflow-x: auto;
        -webkit-overflow-scrolling: touch; gap: 6px;
    }
    .client-filter-bar > * { flex: 0 0 auto; }
    .client-filter-bar::-webkit-scrollbar { display: none; }

    /* page header (shared): stack title over actions and let the action buttons
       wrap instead of overflowing the viewport (e.g. client detail's 4 buttons) */
    .page-head { flex-direction: column; align-items: stretch; gap: 12px; }
    .head-actions { flex-wrap: wrap; }
}

/* Public status page (/status/) — was fully inline-styled with hardcoded hex,
   which broke under the dark app shell. Theme-token version. */
.status-page { max-width:560px; margin:64px auto; padding:0 24px; }
.status-hero { text-align:center; margin-bottom:32px; }
.status-emoji { font-size:56px; line-height:1; }
.status-hero h1 { font-size:26px; margin:12px 0 4px; }
.status-hero h1.status-degraded { color:var(--danger); }
.status-checked { color:var(--text-muted); margin:0; }
.status-list { border:1px solid var(--border); border-radius:12px; overflow:hidden; }
.status-row { display:flex; justify-content:space-between; align-items:center; padding:16px 20px; }
.status-row:not(:last-child) { border-bottom:1px solid var(--border); }
.status-component { font-weight:600; }
.status-up { color:var(--success); font-weight:600; font-size:14px; }
.status-down { color:var(--danger); font-weight:600; font-size:14px; }
.status-note { text-align:center; margin-top:16px; color:var(--text-muted); font-size:13px; }
.status-support { text-align:center; margin-top:24px; color:var(--text-muted); font-size:14px; }

/* ============================================================
   Reconcile pages (index / bankFeed / review) — consolidated from the
   templates' former inline <style> blocks. Layered AFTER the Task-8 base
   rules above (which provide base display:grid/flex that some of these
   partially override). One source of truth; templates carry no inline CSS.
   ============================================================ */
.recon-title-stack { display: flex; flex-direction: column; gap: 4px; }
.recon-title-line { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.recon-title-line h1 { margin: 0; }
.recon-title-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; color: var(--text-muted); font-size: 13px; font-weight: 600; }
.recon-mode-pill { display: inline-flex; align-items: center; gap: 5px; min-height: 24px; padding: 3px 9px; border: 1px solid var(--border); border-radius: 999px; background: var(--bg-card); color: var(--text-muted); font-size: 12px; font-weight: 700; text-decoration: none; }
.recon-page-tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.recon-page-tab { display: inline-flex; align-items: center; gap: 7px; min-height: 36px; padding: 7px 12px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-card); color: var(--text-muted); font-size: 14px; font-weight: 700; text-decoration: none; }
.recon-page-tab:hover { border-color: color-mix(in srgb, var(--primary) 30%, var(--border)); color: var(--primary); text-decoration: none; }
.recon-page-tab.active { border-color: color-mix(in srgb, var(--primary) 32%, var(--border)); background: color-mix(in srgb, var(--accent-light) 62%, var(--bg-card)); color: var(--primary); }
/* Phones: keep the two mode tabs on one row (equal halves) instead of wrapping
   to two stacked rows; tighten so both fit at 390px. */
@media (max-width: 640px) {
    .recon-page-tabs { flex-wrap: nowrap; }
    .recon-page-tab {
        flex: 0 1 auto; min-width: 0; white-space: nowrap;
        gap: 6px; padding: 9px 12px; font-size: 13px; min-height: 42px;
    }
}
.recon-plan-pill { border-color: color-mix(in srgb, var(--primary) 28%, var(--border)); background: color-mix(in srgb, var(--accent-light) 72%, var(--bg-card)); color: var(--primary); }
.recon-workspace { display: grid; grid-template-columns: minmax(0, 1.22fr) minmax(280px, .78fr); gap: 20px; align-items: stretch; margin-bottom: 20px; }
.recon-upload-card, .recon-scope-card { margin-bottom: 0; }
.recon-upload-card > p, .recon-history-intro { margin: 0 0 18px; max-width: 680px; }
.recon-bank-card { margin-bottom: 20px; }
.recon-bank-heading { min-width: 0; }
.recon-bank-kicker { display: inline-flex; align-items: center; gap: 6px; margin-bottom: 6px; color: var(--text-muted); font-size: 12px; font-weight: 800; text-transform: uppercase; }
.recon-bank-kicker .badge { text-transform: none; }
.recon-bank-card h2 { margin: 0; }
/* Connection status: a soft, borderless badge (not a clickable-looking pill). */
.recon-bank-status { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px; border-radius: 999px; font-size: 12px; font-weight: 700; line-height: 1.4; }
.recon-bank-status.is-good { background: var(--status-success-bg); color: var(--status-success-fg); }
.recon-bank-status.is-warning { background: var(--status-warning-bg); color: var(--status-warning-fg); }
/* The rest is passive metadata — plain muted text, dot-separated, no chrome. */
/* Connection facts stay on a single line; if the card is too narrow the tail
   truncates with an ellipsis (full text in the title tooltip) rather than
   wrapping into an orphaned phrase. flex-basis:100% keeps it on its own row
   under the status badge; min-width:0 lets the ellipsis kick in. */
.recon-bank-facts { flex: 1 1 100%; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--text-muted); font-size: 13px; }
.recon-bank-facts strong { color: var(--text); font-weight: 700; }
.recon-bank-actions { display: flex; flex-wrap: wrap; flex: 0 0 auto; justify-content: flex-end; gap: 10px; }
.recon-upload-form { display: flex; flex-direction: column; gap: 16px; }
.recon-file-hint { display: block; margin-top: 8px; line-height: 1.45; }
.recon-lock-banner { display: flex; align-items: flex-start; gap: 12px; padding: 12px 14px; margin: 0 0 18px; border: 1px solid color-mix(in srgb, var(--primary) 28%, var(--border)); border-radius: 8px; background: color-mix(in srgb, var(--accent-light) 68%, var(--bg-card)); }
.recon-lock-icon { flex: 0 0 auto; width: 28px; height: 28px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; color: var(--primary); background: var(--bg-card); }
.recon-lock-title { display: block; font-weight: 800; color: var(--text); }
.recon-lock-copy { display: block; color: var(--text-muted); font-size: 13px; line-height: 1.45; }
.recon-file-picker { position: relative; }
.recon-file-input { position: absolute; width: 1px; height: 1px; min-height: 0; opacity: 0; overflow: hidden; }
.recon-dropzone { display: flex; align-items: center; gap: 12px; min-height: 84px; padding: 14px 16px; border: 1.5px dashed var(--border); border-radius: 8px; background: var(--bg-card); color: var(--text); cursor: pointer; transition: border-color .15s, background .15s, box-shadow .15s; }
.recon-dropzone:hover, .recon-dropzone.is-dragover { border-color: var(--primary); background: color-mix(in srgb, var(--accent-light) 45%, var(--bg-card)); }
.recon-file-picker.is-disabled .recon-dropzone { cursor: not-allowed; opacity: .68; background: var(--bg-tertiary); }
.recon-dropzone-icon { flex: 0 0 auto; width: 38px; height: 38px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; color: var(--primary); background: var(--accent-light); }
.recon-dropzone-main { display: flex; flex-direction: column; min-width: 0; }
.recon-dropzone-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 800; }
.recon-dropzone-sub { color: var(--text-muted); font-size: 13px; }
.recon-locked-cta { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.recon-locked-cta .form-muted { margin: 0; }
.recon-flow { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0; margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--border); }
.recon-flow-step { position: relative; min-width: 0; padding: 0 16px; }
.recon-flow-step:first-child { padding-left: 0; }
.recon-flow-step + .recon-flow-step { border-left: 1px solid var(--border); }
.recon-flow-index { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; margin-bottom: 6px; border-radius: 999px; background: var(--primary); color: #fff; font-size: 11px; font-weight: 800; }
.recon-flow-title { display: block; color: var(--text); font-size: 13px; font-weight: 800; }
.recon-flow-copy { display: block; color: var(--text-muted); font-size: 12px; line-height: 1.4; }
.recon-scope-card { display: flex; flex-direction: column; }
.recon-scope-list { list-style: none; padding: 0; margin: 2px 0 16px; display: flex; flex-direction: column; gap: 13px; }
.recon-scope-list li { display: grid; grid-template-columns: 22px minmax(0, 1fr); gap: 10px; align-items: flex-start; }
.recon-scope-icon { width: 22px; height: 22px; border-radius: 7px; display: inline-flex; align-items: center; justify-content: center; color: var(--primary); background: var(--accent-light); }
.recon-scope-title { display: block; font-weight: 700; color: var(--text); }
.recon-scope-copy { display: block; font-size: 13px; color: var(--text-muted); line-height: 1.45; }
.recon-format-line { display: grid; grid-template-columns: 22px minmax(0, 1fr); gap: 10px; align-items: flex-start; margin-top: auto; padding-top: 14px; border-top: 1px solid var(--border); color: var(--text-muted); font-size: 13px; line-height: 1.5; }
.recon-format-icon { width: 22px; height: 22px; border-radius: 7px; display: inline-flex; align-items: center; justify-content: center; color: var(--primary); background: var(--accent-light); }
.recon-history-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 12px; }
.recon-history-head h2 { margin: 0; }
.recon-history-count { flex: 0 0 auto; color: var(--text-muted); font-size: 13px; font-weight: 700; padding: 4px 9px; border: 1px solid var(--border); border-radius: 999px; background: var(--bg-card); }
.recon-history-table { min-width: 760px; }
.recon-col-file { width: 28%; }
.recon-col-result { width: 46%; }
.recon-col-date { width: 14%; }
.recon-col-action { width: 12%; }
.recon-date-cell { white-space: nowrap; color: var(--text-muted); font-size: 13px; vertical-align: middle; }
.recon-history-file { display: flex; align-items: center; gap: 10px; min-width: 0; }
.recon-file-icon { flex: 0 0 auto; width: 30px; height: 30px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; color: var(--primary); background: var(--accent-light); }
.recon-file-name { display: block; max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 700; }
.recon-status-line { display: flex; align-items: center; gap: 8px; margin-top: 4px; }
.recon-result-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.recon-result-chip { display: inline-flex; align-items: center; gap: 4px; min-height: 28px; padding: 3px 9px; border-radius: 999px; background: var(--bg-tertiary); color: var(--text-muted); font-size: 13px; font-weight: 700; white-space: nowrap; }
.recon-result-chip strong { color: var(--text); }
.recon-result-chip.is-good { color: var(--status-success-fg); background: var(--status-success-bg); }
.recon-result-chip.is-attention { color: var(--status-warning-fg); background: var(--status-warning-bg); }
.recon-action-cell { text-align: right; white-space: nowrap; }
.recon-row-action { background: transparent; border-color: transparent; color: var(--text); }
.recon-row-action:hover { opacity: 1; background: var(--bg-tertiary); border-color: var(--border); color: var(--primary); }
.recon-empty-state { min-height: 174px; justify-content: center; padding: 26px 20px; }
.recon-bank-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(300px, .72fr); gap: 20px; align-items: stretch; margin-bottom: 20px; }
.recon-bank-grid > #bank-feed { display: flex; flex-direction: column; }
.recon-bank-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 18px; margin-bottom: 12px; }
.recon-bank-card h2, .recon-bank-help-card h2 { margin: 0; }
.recon-bank-copy { margin: 0; color: var(--text-muted); line-height: 1.45; }
.recon-bank-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin-top: auto; padding-top: 16px; border-top: 1px solid var(--border); }
/* "How it works" steps fill the left card so it reads as intentional at equal
   height with the taller help card. margin-top:auto pins them to the bottom. */
.recon-bank-steps { list-style: none; margin: 20px 0 0; padding: 16px 0 0; border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: 11px; margin-top: auto; }
.recon-bank-steps li { display: flex; align-items: flex-start; gap: 10px; color: var(--text-muted); font-size: 13px; line-height: 1.45; }
.recon-bank-step-num { flex: 0 0 auto; width: 20px; height: 20px; border-radius: 999px; display: inline-flex; align-items: center; justify-content: center; background: var(--accent-light); color: var(--primary); font-size: 11px; font-weight: 800; }
/* Disconnect is a low-emphasis action — quiet by default, danger only on hover. */
.recon-bank-disconnect { background: transparent; border-color: transparent; color: var(--text-muted); }
.recon-bank-disconnect:hover:not(:disabled) { background: var(--status-danger-bg); border-color: transparent; color: var(--status-danger-fg); }
.recon-bank-help-list { list-style: none; padding: 0; margin: 14px 0 0; display: flex; flex-direction: column; gap: 13px; }
.recon-bank-help-list li { display: grid; grid-template-columns: 22px minmax(0, 1fr); gap: 10px; align-items: flex-start; }
.recon-bank-help-icon { width: 22px; height: 22px; border-radius: 7px; display: inline-flex; align-items: center; justify-content: center; color: var(--primary); background: var(--accent-light); }
.recon-bank-help-title { display: block; font-weight: 800; color: var(--text); }
.recon-bank-help-copy { display: block; font-size: 13px; color: var(--text-muted); line-height: 1.45; }
.recon-history-intro { margin: 0 0 18px; max-width: 680px; }
.recon-review-head { align-items: flex-start; gap: 18px; }
.recon-review-title { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.recon-review-title h1 { margin: 0; }
.recon-review-subtitle { margin: 0; max-width: 760px; line-height: 1.45; }
.recon-back-btn { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
.recon-summary.recon-summary-card { display: grid; grid-template-columns: minmax(280px, 1.8fr) repeat(3, minmax(108px, .45fr)); gap: 18px; align-items: center; padding: 22px 28px; }
.recon-summary-file strong { display: block; min-width: 0; overflow-wrap: anywhere; line-height: 1.25; }
.recon-summary-item { min-width: 0; }
.recon-summary-item-num { align-items: flex-end; text-align: right; }
.recon-summary-value { font-size: 22px; line-height: 1.15; font-variant-numeric: tabular-nums; letter-spacing: 0; }
.recon-summary-value-success { color: var(--success); }
.recon-summary-value-warning { color: var(--warning-strong); }
.recon-review-card { padding: 28px; }
.recon-review-callout { display: grid; grid-template-columns: auto 1fr; gap: 12px; align-items: flex-start; padding: 14px 16px; margin-bottom: 20px; border: 1px solid color-mix(in srgb, var(--status-info-fg) 24%, var(--border)); border-radius: 8px; background: color-mix(in srgb, var(--status-info-bg) 38%, var(--bg-card)); color: var(--text); }
.recon-review-callout-icon { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; border-radius: 8px; background: var(--bg-card); color: var(--primary); }
.recon-review-callout strong { display: block; margin-bottom: 3px; }
.recon-review-callout span { display: block; color: var(--text-muted); line-height: 1.45; }
.recon-review-intro { margin: 0 0 14px; line-height: 1.45; }
.recon-table-head { grid-template-columns: minmax(250px, 1.15fr) minmax(150px, .65fr) minmax(430px, 1.75fr); padding: 10px 0 12px; }
.recon-row { grid-template-columns: minmax(250px, 1.15fr) minmax(150px, .65fr) minmax(430px, 1.75fr); gap: 22px; padding: 18px 0; }
.recon-row:last-child { border-bottom: 0; }
.recon-col { min-width: 0; }
.recon-bank-date { font-size: 13px; margin-bottom: 4px; }
.recon-bank-desc { font-size: 15px; line-height: 1.35; overflow-wrap: anywhere; }
.recon-bank-amount { margin-top: 4px; font-size: 17px; font-variant-numeric: tabular-nums; letter-spacing: 0; }
.recon-bank-ref { margin-top: 3px; font-size: 13px; overflow-wrap: anywhere; }
.recon-conf-none strong, .recon-conf-pct { display: block; }
.recon-conf-none strong { color: var(--text); font-size: 14px; }
.recon-conf-note { display: block; margin-top: 3px; color: var(--text-muted); line-height: 1.4; }
.recon-conf-bar { background: var(--bg-tertiary); }
.recon-confirmed-invoice { padding: 11px 12px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-tertiary); color: var(--text); line-height: 1.35; overflow-wrap: anywhere; }
.recon-match-warning { display: block; margin-top: 8px; color: var(--status-warning-fg); font-size: 13px; line-height: 1.4; }
.recon-confirmed-tag { display: inline-flex; align-items: center; gap: 5px; margin-top: 8px; font-weight: 700; }
.recon-selected-summary { display: none; margin-top: 8px; color: var(--text-muted); font-size: 13px; line-height: 1.4; overflow-wrap: anywhere; }
.recon-footer-bar { align-items: center; flex-wrap: wrap; }
#recon-confirm-btn { min-width: 190px; }
/* bank_feed locked-CTA sits under the intro copy (index's does not) */
.recon-bank-copy + .recon-locked-cta { margin-top: 16px; }
@media (max-width: 860px) {
    .recon-workspace { grid-template-columns: 1fr; }
    .recon-bank-header { flex-direction: column; }
    .recon-bank-actions { justify-content: flex-start; width: 100%; }
    .recon-bank-actions .btn { width: 100%; justify-content: center; }
    .recon-flow { grid-template-columns: 1fr; gap: 12px; }
    .recon-flow-step { padding: 0; }
    .recon-flow-step + .recon-flow-step { padding-top: 12px; border-left: 0; border-top: 1px solid var(--border); }
    .recon-history-head { flex-direction: column; align-items: stretch; }
    .recon-history-count { align-self: flex-start; }
    .recon-bank-grid { grid-template-columns: 1fr; }
}
@media (max-width: 1020px) {
    .recon-summary.recon-summary-card { grid-template-columns: 1fr 1fr; }
    .recon-summary-item-num { align-items: flex-start; text-align: left; }
}
@media (max-width: 1100px) {
    .recon-table-head { display: none; }
    .recon-row { grid-template-columns: 1fr; gap: 14px; }
    .recon-selected-summary:not(.is-empty) { display: block; }
}
@media (max-width: 768px) {
    .recon-review-head { align-items: stretch; }
    .recon-back-btn { justify-content: center; }
    .recon-summary.recon-summary-card { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px 14px; padding: 18px; }
    .recon-summary-file { grid-column: 1 / -1; }
    .recon-review-card { padding: 20px; }
    .recon-review-callout { grid-template-columns: 1fr; }
    .recon-row { grid-template-columns: 1fr; gap: 14px; padding: 18px 0; }
    .recon-table-head { display: none; }
    .recon-col-conf, .recon-col-inv { padding-top: 0; }
    .recon-footer-bar .btn { width: 100%; text-align: center; }
}

/* ---------- AR Inbox: per-client activity timeline (2.1) ---------- */
.cv-ar { margin-bottom: 20px; }
.ar-timeline { list-style: none; margin: 14px 0 0; padding: 0; }
.ar-item { display: flex; gap: 12px; padding: 11px 0; border-top: 1px solid var(--border); }
.ar-item:first-child { border-top: 0; }
.ar-dot { flex: 0 0 auto; width: 9px; height: 9px; border-radius: 50%; margin-top: 6px; background: var(--text-muted); }
.ar-reply .ar-dot   { background: var(--primary); }
.ar-promise .ar-dot { background: var(--status-success-fg); }
.ar-blocker .ar-dot { background: var(--status-warning-fg); }
.ar-note .ar-dot    { background: var(--primary); }
.ar-event .ar-dot, .ar-email .ar-dot { background: var(--text-muted); }
.ar-body { flex: 1; min-width: 0; }
.ar-line1 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ar-title { font-weight: 700; font-size: 14px; color: var(--text); }
.ar-tag { font-size: 11px; font-weight: 700; text-transform: capitalize; padding: 1px 7px; border-radius: 999px; background: var(--bg-tertiary); color: var(--text-muted); }
.ar-tag-warn { background: var(--status-warning-bg); color: var(--status-warning-fg); }
.ar-detail { font-size: 13px; color: var(--text-muted); margin-top: 2px; line-height: 1.45; overflow-wrap: anywhere; }
.ar-meta { font-size: 12px; color: var(--text-muted); margin-top: 3px; }

/* ---------- AR Inbox: global needs-attention queue (2.1 Phase 2) ---------- */
.inbox-count { display: inline-flex; align-items: center; justify-content: center; min-width: 22px; height: 22px; padding: 0 7px; border-radius: 999px; background: var(--accent-light); color: var(--primary); font-size: 12px; font-weight: 800; margin-left: 10px; }
.inbox-list { list-style: none; margin: 4px 0 0; padding: 0; }
.inbox-row { display: flex; align-items: flex-start; gap: 12px; padding: 13px 0; border-top: 1px solid var(--border); }
.inbox-row:first-child { border-top: 0; }
.inbox-reply .ar-dot   { background: var(--primary); }
.inbox-blocker .ar-dot { background: var(--status-warning-fg); }
.inbox-promise .ar-dot { background: var(--status-success-fg); }
.inbox-body { flex: 1; min-width: 0; }
.inbox-line1 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.inbox-type { font-weight: 800; font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); }
.inbox-client { font-weight: 700; font-size: 14px; }
.inbox-inv { font-size: 13px; color: var(--text-muted); }
.inbox-detail { font-size: 13px; color: var(--text-muted); margin-top: 3px; line-height: 1.45; overflow-wrap: anywhere; }
.inbox-actions { flex: 0 0 auto; display: flex; align-items: center; gap: 6px; }
@media (max-width: 600px) {
    .inbox-row { flex-wrap: wrap; }
    .inbox-actions { width: 100%; margin-top: 8px; }
}

/* SMS monthly-usage progress bar (Settings → Plan & Billing → Usage). Fill width comes
   from the --sms-pct custom property the template injects; colour shifts by state so the
   bar reads at a glance. All theme tokens → dark mode auto. */
.sms-meter {
    height: 8px;
    border-radius: 999px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    overflow: hidden;
    margin: 2px 0 10px;
}
.sms-meter-fill {
    width: var(--sms-pct, 0%);
    min-width: 8px;        /* keep a visible nub for tiny (sub-1%) usage; bar is hidden at 0 */
    height: 100%;
    border-radius: 999px;
    background: var(--primary);
    transition: width .3s ease;
}
.sms-meter.is-warn .sms-meter-fill { background: var(--warning); }
.sms-meter.is-over .sms-meter-fill { background: var(--danger); }

/* SMS credit packs (Settings → Notifications) — compact single-line rows. The card's
   focus is the SMS toggle, so these stay low-profile. Theme tokens → dark mode auto. */
.sms-buy-credits .sms-pack-list { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
/* Breathing room between the pack list and the "Turn SMS reminders on…" footer line. */
.sms-buy-credits .sms-buy-foot { margin-top: 14px; }
.sms-pack {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    width: 100%; text-align: left;
    padding: 8px 14px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-card);
    color: var(--text);
    font-size: 13.5px; line-height: 1.4;
    cursor: pointer;
    transition: border-color .15s ease, box-shadow .15s ease, background .15s ease;
}
.sms-pack:hover  { border-color: var(--accent); box-shadow: var(--shadow); }
.sms-pack:disabled { opacity: .55; cursor: default; box-shadow: none; }
.sms-pack.is-best { border-color: var(--accent); background: var(--accent-light); }
.sms-pack-main { font-weight: 600; }
.sms-pack-sub  { font-weight: 400; color: var(--text-muted); }
.sms-pack-save {
    flex-shrink: 0;
    font-size: 11.5px; font-weight: 600; white-space: nowrap;
    padding: 2px 9px; border-radius: 999px;
    background: var(--accent-light); color: var(--accent);
    border: 1px solid var(--accent-border);
}

/* SMS history — itemized log drilled down from the usage card. Status badges
   reuse the shared status tokens so they track light/dark like the rest. */
.badge-sms-sent,
.badge-sms-delivered { background: var(--status-success-bg); color: var(--status-success-fg); }
.badge-sms-queued    { background: var(--bg-tertiary);       color: var(--text-muted); }
.badge-sms-failed    { background: var(--status-danger-bg);  color: var(--status-danger-fg); }

/* "View SMS history" link in the usage-card header — kept quiet next to the H2. */
.sms-usage-history-link { font-size: 13px; font-weight: 500; }

.sms-history-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; }
.sms-history-head h2 { margin: 0 0 4px; }
.sms-history-head p  { margin: 0; }
.sms-history-back { white-space: nowrap; flex-shrink: 0; }
.sms-history-nav { display: flex; align-items: center; gap: 12px; margin: 18px 0; }
.sms-history-month { font-weight: 600; min-width: 9em; text-align: center; }
.sms-history-summary { margin: 0 0 10px; }
.sms-history-empty { margin: 18px 0 0; }
.sms-history-table .sms-history-date  { white-space: nowrap; color: var(--text-muted); }
.sms-history-table .sms-history-phone { white-space: nowrap; font-variant-numeric: tabular-nums; }
.sms-history-foot { margin-top: 12px; }
