/* Inter, the brand's typeface (the landing refresh; SIL Open Font License,
   fonts/OFL.txt), served from here: the CSP allows only our own fonts. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/inter-400.woff2?v=1") format("woff2");
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/inter-500.woff2?v=1") format("woff2");
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/inter-600.woff2?v=1") format("woff2");
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/inter-700.woff2?v=1") format("woff2");
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url("fonts/inter-800.woff2?v=1") format("woff2");
}

:root {
  /* Native controls -- the date picker's calendar icon and pop-up, dropdown
     lists, scrollbars -- are drawn by the browser; this tells it which theme. */
  color-scheme: light;
  --color-bg: #f5f7fa;
  --color-surface: #ffffff;
  --color-surface-alt: #f8fafc;
  --color-border: #e2e8f0;
  --color-border-strong: #cbd5e1;
  --color-text: #111827;
  --color-text-muted: #4a5568;
  /* The brand's navy (the logo's tile, the landing page's bands). */
  --color-brand-navy: #1e3a8a;
  /* The lowest point: a warm tint, as on the landing page's forecast. */
  --color-low: #b03a0a;
  --color-low-soft: #fff7ed;
  --color-low-border: #f3c9a8;
  --color-primary: #2563eb;
  --color-primary-hover: #1d4ed8;
  --color-primary-soft: #eaf1ff;
  --color-success: #15803d;
  --color-success-soft: #ecfdf3;
  --color-danger: #b91c1c;
  --color-danger-soft: #fef2f2;
  --color-warning: #9a5b00;
  --color-warning-soft: #fff6e5;
  --color-info: #0f6d8c;
  --color-info-soft: #e8f6fb;
  /* The brand's beacon amber: the register's "Today" marker. */
  --color-beacon: #f5a524;
  --color-beacon-soft: #fff7e8;
  --color-beacon-line: #f8d08a;
  --shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.06);
  --shadow-md: 0 6px 16px rgba(16, 24, 40, 0.08);
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 18px;
  --sidebar-width: 220px;
  /* Chart series (validated as a set against --color-surface, light and dark;
     see cashflow.js). Money in / money out / net. */
  --viz-in: #2a78d6;
  --viz-out: #eb6834;
  --viz-net: #1baf7a;
  --viz-baseline: #c3c7cf;
  /* Projected balance (upcoming.js) -- its own chart, so it only needs to
     clear 3:1 against the surface (5.1:1 light, 5.2:1 dark). */
  --viz-balance: #6b5bd6;
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --color-bg: #0f1115;
  --color-surface: #171a21;
  --color-surface-alt: #1d212a;
  --color-border: #2a2f3a;
  --color-text: #e5e7eb;
  --color-text-muted: #9aa1ae;
  --color-border-strong: #3a404c;
  --color-brand-navy: #93b4ff;
  --color-low: #fdba74;
  --color-low-soft: #2a1a10;
  --color-low-border: #6b3a1f;
  --color-primary: #5b8def;
  --color-primary-hover: #7ea6f5;
  --color-primary-soft: #16223c;
  --color-success: #34d399;
  --color-success-soft: #10261c;
  --color-danger: #f87171;
  --color-danger-soft: #2c1616;
  --color-warning: #fbbf24;
  --color-warning-soft: #2b2210;
  --color-info: #38bdf8;
  --color-info-soft: #102530;
  --color-beacon: #f5a524;
  --color-beacon-soft: #2a2110;
  --color-beacon-line: #6b4a12;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 8px 24px rgba(0, 0, 0, 0.5);
  --viz-in: #3987e5;
  --viz-out: #d95926;
  --viz-net: #199e70;
  --viz-baseline: #3a404c;
  --viz-balance: #8a7cf0;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--color-bg);
  color: var(--color-text);
}

h1, h2, h3 {
  font-weight: 700;
  letter-spacing: -0.01em;
}

/* Links: the landing page's blue, its navy on hover. */
a {
  color: var(--color-primary);
}

a:hover {
  color: var(--color-brand-navy);
}

/* Environment banner: shown whenever this instance isn't the production
   database, so dev/test data is never mistakable for real financial data. */

.env-banner {
  background: var(--color-warning);
  color: #1a1200;
  text-align: center;
  font-weight: 700;
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  padding: 0.5rem 1rem;
}

.env-banner.is-demo {
  background: var(--color-primary);
  color: #fff;
  font-weight: 600;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem 1rem;
}

/* View-only access to a partner's household (session.js showViewOnly): the
   banner says so, and everything marked data-edit, which would change the
   household's money, is hidden. Overrides any display rule it has. */
.env-banner.is-household {
  background: var(--color-primary);
  color: #fff;
  font-weight: 600;
}

body.view-only [data-edit] {
  display: none !important;
}

.demo-invite-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
}

.demo-invite-form label {
  color: #fff;
  font-weight: 600;
  margin: 0;
}

.demo-invite-form input {
  width: 16rem;
  max-width: 100%;
  padding: 0.3rem 0.6rem;
  font-size: 0.9rem;
}

.env-banner.is-demo button.secondary {
  background: transparent;
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.7);
}

.demo-invite-error {
  flex-basis: 100%;
  font-weight: 600;
}

.env-banner.is-demo button {
  background: #fff;
  color: var(--color-primary);
  padding: 0.3rem 0.85rem;
  font-size: 0.85rem;
}

/* Layout shell */

.app-shell {
  display: flex;
  min-height: 100vh;
}

.sidebar {
  width: var(--sidebar-width);
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border-right: 1px solid var(--color-border);
  padding: 1.25rem 1rem;
  position: sticky;
  top: 0;
  /* The environment banner (app.js sets its height) sits above the shell, so
     a full 100vh would push the bottom of the sidebar off-screen. */
  height: calc(100vh - var(--env-banner-height, 0px));
  overflow-y: auto;
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 700;
  font-size: 1.15rem;
  padding: 0 0.25rem;
  margin-bottom: 1.75rem;
}

/* The same mark as the browser tab's icon (favicon.svg). */
.brand-mark {
  width: 26px;
  height: 26px;
  flex: none;
  display: block;
}

.nav {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  flex: 1;
}

/* The sidebar's task groups (Today, Plan, ...), as the phone's tabs have them. */
.nav-group {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

/* Staff, for everyone else: no page in the group to show. */
.nav-group:not(:has(.nav-item:not([hidden]))) {
  display: none;
}

.nav-group-label {
  padding: 0 0.75rem 0.15rem;
  color: var(--color-text-muted);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  text-align: left;
  background: none;
  border: none;
  padding: 0.6rem 0.75rem;
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  font-size: 0.95rem;
  font-weight: 500;
  cursor: pointer;
}

.nav-item:hover {
  background: var(--color-surface-alt);
  color: var(--color-text);
}

.nav-item.active {
  background: var(--color-primary-soft);
  color: var(--color-primary);
}

/* Line icons, drawn like the phone's tab bar (and the landing page's). */
.nav-icon {
  flex: none;
  width: 1.15rem;
  height: 1.15rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* A bank needs something from them (banks.js): a dot, its title says how many. */
.nav-attention {
  flex: none;
  width: 0.55rem;
  height: 0.55rem;
  margin-left: auto;
  border-radius: 50%;
  background: var(--color-beacon);
}

/* In the sidebar it sits on the icon's corner, so the label keeps its width. */
#nav-banks {
  position: relative;
}

#nav-banks .nav-attention {
  position: absolute;
  top: 0.45rem;
  left: 1.55rem;
  box-shadow: 0 0 0 2px var(--color-surface);
}

.nav-attention[hidden] {
  display: none;
}

.theme-toggle {
  margin-top: 1rem;
  border: 1px solid var(--color-border);
  background: var(--color-surface-alt);
  color: var(--color-text);
  border-radius: var(--radius-sm);
  padding: 0.5rem 0.75rem;
  font-size: 0.82rem;
  cursor: pointer;
}

.theme-toggle:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

.main-col {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.topbar {
  padding: 1.75rem 2rem 1.15rem;
  border-bottom: 1px solid var(--color-border);
  background: var(--color-surface);
}

.topbar h1 {
  margin: 0 0 0.25rem;
  font-size: 1.6rem;
  font-weight: 800;
  letter-spacing: -0.02em;
}

.topbar .subtitle {
  margin: 0;
  color: var(--color-text-muted);
  font-size: 0.9rem;
}

main {
  padding: 1.75rem 2rem 3rem;
  flex: 1;
  min-width: 0;
}

.view + .view {
  margin-top: 0;
}

/* Shared components */

.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 1.5rem;
}

/* A hidden card doesn't count (one that only shows sometimes, heading a
   view), and one hidden thing between two cards (a notice) doesn't close
   the gap. */
.card:not([hidden]) + .card,
.card:not([hidden]) + [hidden] + .card,
.card + p,
#import-warnings:not(:empty) {
  margin-top: 1.25rem;
}

.section-title {
  margin: 0 0 1rem;
  font-size: 1.1rem;
}

.step-label {
  margin: 0 0 0.15rem;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-primary);
}

.empty-state {
  color: var(--color-text-muted);
  font-size: 0.9rem;
  margin: 0;
}

.stats-row {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-bottom: 1.25rem;
}

.stat-tile {
  flex: 1;
  min-width: 160px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: 1rem 1.25rem;
}

.stat-label {
  font-size: 0.78rem;
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.stat-value {
  font-size: 1.65rem;
  font-weight: 700;
  margin-top: 0.3rem;
}

.stat-value.negative {
  color: var(--color-danger);
}

/* Phones: a large net worth ($683,574.88) is wider than half the row. Each
   tile takes the room its number needs (wrapping to its own line when both
   don't fit), and the number shrinks a little on narrow screens, never
   breaking across lines. */
@media (max-width: 640px) {
  .stat-tile {
    flex: 1 1 auto;
  }

  .stat-value {
    white-space: nowrap;
    font-size: clamp(1.3rem, 6vw, 1.65rem);
  }
}

/* Accounts */

.accounts-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 1rem;
  margin-bottom: 1.5rem;
}

.account-card {
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 1rem 1.1rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.account-type-badge {
  display: inline-block;
  width: fit-content;
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  background: var(--color-primary-soft);
  color: var(--color-primary);
}

.account-name {
  font-weight: 600;
}

.account-balance {
  font-size: 1.25rem;
  font-weight: 700;
}

.account-balance.negative {
  color: var(--color-danger);
}

/* "Matches your statement through Sep 30" (app.js statementProof): on the
   account cards and first in the register's balance line. */
.statement-proof {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--color-success);
  cursor: help;
}

#register-balance .statement-proof {
  flex-basis: 100%;
}

.account-actions {
  display: flex;
  gap: 0.9rem;
  flex-wrap: wrap;
  margin-top: 0.2rem;
}

button.link-button.account-action {
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--color-text-muted);
}

button.link-button.account-action:hover,
button.link-button.account-action:focus-visible {
  color: var(--color-primary);
}

button.link-button.account-action.danger:hover,
button.link-button.account-action.danger:focus-visible {
  color: var(--color-danger);
}

.closed-accounts {
  margin: -0.5rem 0 1.25rem;
}

.closed-accounts[hidden] {
  display: none;
}

.closed-accounts summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--color-text-muted);
}

.closed-accounts-note {
  margin: 0.5rem 0;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

#closed-accounts-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.closed-account {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.9rem;
  padding: 0.6rem 0;
  border-top: 1px solid var(--color-border);
}

.closed-account-name {
  font-weight: 600;
  color: var(--color-text-muted);
}

.closed-account-balance {
  margin-left: auto;
  color: var(--color-text-muted);
}

.closed-account-balance.negative {
  color: var(--color-danger);
}

.closed-account .account-actions {
  margin-top: 0;
}

/* A modal <dialog> for a serious, can't-be-undone action. */
.confirm-dialog {
  width: min(460px, calc(100vw - 2rem));
  padding: 1.5rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  color: var(--color-text);
  box-shadow: var(--shadow-md);
}

.confirm-dialog::backdrop {
  background: rgba(15, 17, 21, 0.55);
}

.confirm-dialog form {
  display: block;
  margin: 0;
}

.confirm-dialog h2 {
  margin-top: 0;
}

.confirm-dialog p {
  margin: 0 0 0.6rem;
}

.confirm-dialog-list {
  margin: 0 0 0.8rem;
  padding-left: 1.2rem;
}

.confirm-dialog-list li {
  margin-bottom: 0.25rem;
}

.confirm-dialog-note {
  color: var(--color-text-muted);
  font-size: 0.9rem;
}

.confirm-dialog-irreversible {
  color: var(--color-danger);
  font-weight: 600;
}

.confirm-dialog label {
  margin-bottom: 0.8rem;
  font-size: 0.9rem;
  color: var(--color-text);
}

.confirm-dialog input {
  width: 100%;
  box-sizing: border-box;
}

.confirm-dialog label strong {
  font-weight: 700;
}

.confirm-dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.6rem;
}

.accounts-card {
  margin-bottom: 1.25rem;
}

/* The forecast in one sentence, first on the Overview (upcoming.js). */

.forecast-headline {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-primary);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: 1rem 1.25rem;
  margin-bottom: 1.25rem;
}

/* Reconciling (reconcile.js): the first time's steps, and what to do next. */
.reconcile-steps {
  margin: 0.4rem 0;
  padding-left: 1.4rem;
}

.reconcile-guide {
  margin: 0.25rem 0 0.75rem;
  padding: 0.5rem 0.75rem;
  border-left: 3px solid var(--color-primary);
  background: var(--color-primary-soft);
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
}

.reconcile-guide[hidden] {
  display: none;
}

/* Reports: how a chart is worked out, on request (UX principle 3). */
.rp-how {
  margin-top: 0.75rem;
}

.rp-how summary {
  cursor: pointer;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.rp-how p {
  margin: 0.4rem 0 0;
}

/* Overview: the totals past the two figures, in one line (upcoming.js). */
.upcoming-totals {
  margin: -0.5rem 0 1rem;
  font-size: 0.9rem;
  color: var(--color-text-muted);
}

.upcoming-totals strong {
  color: var(--color-text);
}

/* The forecast's switches, folded under Options. */
.cashflow-options {
  align-self: flex-end;
  font-size: 0.9rem;
}

.cashflow-options summary {
  cursor: pointer;
  padding: 0.6rem 0.25rem;
  color: var(--color-text-muted);
}

.cashflow-options-body {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: 0.25rem 0 0.5rem;
}

.cashflow-accounts {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  margin: 0.35rem 0 0;
  padding: 0;
  border: 0;
  min-width: 0;
}

.cashflow-accounts[hidden] {
  display: none;
}

.cashflow-accounts legend {
  padding: 0;
  margin-bottom: 0.25rem;
  font-size: 0.85rem;
  font-weight: 600;
}

.cashflow-account-boxes {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

#safe-accounts-edit {
  margin-left: 0.75rem;
}

/* How a figure or chart is worked out: on request (UX principle 3). */
.how-worked-out {
  margin-top: 0.75rem;
}

.how-worked-out summary {
  cursor: pointer;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.how-worked-out p {
  margin: 0.4rem 0 0;
}

#account-form[hidden] {
  display: none;
}

/* The demo's tour (session.js). */
.demo-tour {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1.25rem;
  margin-bottom: 1.25rem;
  border-left: 4px solid var(--color-beacon);
}

.demo-tour[hidden] {
  display: none;
}

.demo-tour-title {
  margin: 0;
  flex-basis: 100%;
}

.demo-tour-stops {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.5rem;
  margin: 0;
  padding-left: 1.2rem;
  flex: 1;
}

/* A stop on the tour, picked out for a moment. */
.tour-spot {
  outline: 3px solid var(--color-beacon);
  outline-offset: 4px;
  border-radius: var(--radius-md);
  transition: outline-color 0.3s ease;
}

/* Import: the two ways in, at the top. */
.import-ways {
  margin: 0 0 1rem;
  color: var(--color-text-muted);
}

.import-way {
  font-weight: 600;
}

.forecast-headline[hidden] {
  display: none;
}

/* Today's alerts past the first, until "N more things need you" (alerts.js). */
.overview-alerts .forecast-headline.is-folded {
  display: none;
}

.overview-alerts-more {
  display: block;
  margin: -0.5rem 0 1.25rem;
  font-weight: 600;
}

.overview-alerts-more[hidden] {
  display: none;
}

/* Bank connections (banks.js). */
.bank-intro {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  margin-bottom: 1rem;
}

.bank-intro button {
  flex: none;
}

.bank-connection {
  border-top: 1px solid var(--color-border);
  padding-top: 1rem;
  margin-top: 1rem;
}

.bank-connection-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
}

.bank-name {
  font-size: 1.05rem;
  margin: 0;
}

.bank-synced {
  margin: 0.25rem 0 0;
  font-size: 0.88rem;
}

.bank-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
}

.bank-status.is-good { color: var(--color-success); }
.bank-status.is-warning { color: var(--color-warning); }
.bank-status.is-danger { color: var(--color-danger); }

.bank-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin: 0;
}

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

/* Getting started (checklist.js): the steps to a first forecast. */
.checklist-card {
  margin-bottom: 1.25rem;
}

.checklist-card[hidden] {
  display: none;
}

.checklist-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  margin-bottom: 1rem;
}

.checklist-heading {
  font-size: 1.15rem;
  margin: 0;
}

.checklist-progress {
  margin: 0.15rem 0 0;
  color: var(--color-text-muted);
  font-size: 0.9rem;
}

.checklist-steps {
  list-style: none;
  margin: 0;
  padding: 0;
}

.checklist-step {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.65rem 0;
  border-top: 1px solid var(--color-border);
}

.checklist-mark {
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  border: 2px solid var(--color-border);
  display: grid;
  place-items: center;
  font-size: 0.85rem;
  font-weight: 700;
}

.checklist-step.is-done .checklist-mark {
  border-color: var(--color-success);
  background: var(--color-success);
  color: #fff;
}

.checklist-step.is-next .checklist-mark {
  border-color: var(--color-primary);
}

.checklist-text {
  flex: 1;
  min-width: 0;
}

.checklist-step.is-done .checklist-title {
  color: var(--color-text-muted);
}

.checklist-step.is-next .checklist-title {
  font-weight: 600;
}

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

.checklist-hint {
  color: var(--color-text-muted);
  font-size: 0.88rem;
  margin-top: 0.1rem;
}

.checklist-step button {
  flex: none;
}

@media (max-width: 640px) {
  .checklist-step {
    flex-wrap: wrap;
  }

  /* The text takes the row; the button goes under it. */
  .checklist-text {
    flex-basis: calc(100% - 2.25rem);
  }

  .checklist-step button {
    margin-left: 2.25rem;
  }
}

/* Safe to spend (safespend.js): the number, one line under it, and the cushion
   and how it's worked out as two quiet links below. */
.safe-card {
  display: grid;
  gap: 0.6rem;
  margin-bottom: 1.25rem;
}

.safe-card[hidden] {
  display: none;
}

.safe-amount {
  font-size: 2.4rem;
  font-weight: 700;
  line-height: 1.15;
  color: var(--color-success);
  font-variant-numeric: tabular-nums;
}

.safe-card.is-short .safe-amount {
  color: var(--color-danger);
}

.safe-card.is-thin .safe-amount {
  color: var(--color-text-muted);
}

/* Two sizes: the sentence and the cushion at 0.92rem; what's folded under
   "How it's worked out" smaller and muted. */
.safe-sub {
  margin: 0.35rem 0 0;
  font-size: 0.92rem;
}

.safe-side {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem 1.25rem;
  font-size: 0.85rem;
}

.safe-side .safe-cushion {
  order: 2;
}

.safe-side .safe-more {
  order: 1;
}

.safe-side .safe-more[open] {
  flex-basis: 100%;
}

.safe-more summary {
  cursor: pointer;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.safe-more p {
  margin: 0.4rem 0 0;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.safe-why {
  color: var(--color-text-muted);
}

.safe-cushion-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.5rem;
  margin: 0;
}

.safe-cushion-form input {
  width: 7rem;
}

.safe-cushion-form[hidden],
.safe-cushion-error[hidden] {
  display: none;
}

.safe-cushion-hint {
  color: var(--color-text-muted);
}


.forecast-headline.is-good {
  border-left-color: var(--color-success);
}

.forecast-headline.is-warning {
  border-left-color: var(--color-warning);
  background: var(--color-warning-soft);
}

.forecast-headline.is-danger {
  border-left-color: var(--color-danger);
  background: var(--color-danger-soft);
}

.forecast-headline-text {
  margin: 0;
  font-size: 1.15rem;
  font-weight: 600;
  line-height: 1.4;
}

.forecast-headline-more {
  margin: 0.35rem 0 0;
  font-size: 0.9rem;
  color: var(--color-text-muted);
}

.forecast-headline-more[hidden],
.forecast-headline-actions[hidden] {
  display: none;
}

.forecast-headline-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 0.85rem;
}

/* Free and Plus (plan.js): the plan page, the sidebar's plan line, and what
   a Free user sees where Plus would show more. */

.sidebar-plan {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--color-primary);
  margin-top: 0.2rem;
}

.sidebar-plan[hidden] {
  display: none;
}

.plan-status {
  border-left: 4px solid var(--color-primary);
}

.plan-name {
  margin: 0;
  font-size: 1.3rem;
  font-weight: 700;
}

.plan-why,
.plan-price {
  margin: 0.4rem 0 0;
  max-width: 44rem;
  line-height: 1.5;
}

.plan-price {
  color: var(--color-text-muted);
}

.plan-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin-top: 1rem;
}

.plan-actions button[hidden] {
  display: none;
}

.plan-notice {
  margin: 0 0 1rem;
}

.plan-error {
  margin: 0.75rem 0 0;
}

.plan-fine {
  margin: 0.75rem 0 0;
  font-size: 0.85rem;
  color: var(--color-text-muted);
  max-width: 44rem;
}

.plan-fine[hidden] {
  display: none;
}

.notice-preview summary {
  cursor: pointer;
  font-weight: 600;
  margin: 0.5rem 0;
}

.notice-subject {
  font-weight: 600;
  margin: 0.5rem 0;
}

.notice-body {
  white-space: pre-wrap;
  font-family: inherit;
  font-size: 0.9rem;
  line-height: 1.5;
  background: var(--color-surface-alt);
  border-radius: var(--radius-sm);
  padding: 0.85rem 1rem;
  margin: 0 0 1rem;
}

.plan-soon {
  font-size: 0.88rem;
  color: var(--color-text-muted);
}

/* Free next to Plus is read whole, not scrolled inside a box. */
.table-wrap.plan-table-wrap {
  max-height: none;
}

.plan-table td:first-child {
  font-weight: 500;
}

.plan-table th:not(:first-child),
.plan-table td:not(:first-child) {
  width: 28%;
}

.plus-lock {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem 1rem;
  margin: 0.75rem 0;
  padding: 0.75rem 1rem;
  border-radius: var(--radius-sm);
  background: var(--color-primary-soft);
}

.plus-lock[hidden] {
  display: none;
}

.plus-lock p {
  margin: 0;
  font-size: 0.9rem;
}

.up-locked {
  fill: var(--color-primary-soft);
  opacity: 0.85;
}

.up-locked-label {
  fill: var(--color-primary);
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.04em;
}

/* Card and loan payments (Overview, paydue.js) */

.paydue-card {
  margin-bottom: 1.25rem;
}

.paydue-card[hidden] {
  display: none;
}

.paydue-list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.paydue-row {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: 0.75rem 0.9rem;
}

.paydue-main {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  flex-wrap: wrap;
}

.paydue-text {
  flex: 1;
  min-width: 14rem;
}

.paydue-name {
  font-weight: 600;
}

.paydue-status {
  font-size: 0.9rem;
  color: var(--color-text-muted);
  margin-top: 0.15rem;
}

.paydue-status.is-overdue {
  color: var(--color-danger);
  font-weight: 600;
}

.paydue-status.is-done {
  color: var(--color-success);
}

.paydue-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

/* "New statement": there when one comes early, quieter than a button. */
.paydue-actions .paydue-new {
  font-size: 0.9rem;
  white-space: nowrap;
}

form.paydue-form {
  margin-top: 0.85rem;
  padding-top: 0.85rem;
  border-top: 1px solid var(--color-border);
}

.paydue-form input[type="number"] {
  width: 8rem;
}

.paydue-error,
.paydue-hint {
  flex-basis: 100%;
  margin: 0;
}

.paydue-error[hidden] {
  display: none;
}

/* Paycheck & bills (bills.js) */

form.bills-form {
  margin-top: 0;
}

#bills-bill-payee {
  width: 12rem;
}

#bills-pay-amount,
#bills-bill-amount {
  width: 8rem;
}

.bills-item-detail {
  display: block;
  font-weight: 400;
  font-size: 0.82rem;
  color: var(--color-text-muted);
}

#safe-alerts[hidden] {
  display: none;
}

#safe-alerts button.link-button {
  margin-left: 0.25rem;
  font-size: inherit;
}

.alert-preview-body {
  white-space: pre-wrap;
  font-family: inherit;
  font-size: 0.9rem;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: 0.85rem 1rem;
  margin: 0.5rem 0 0.75rem;
}

#alert-preview {
  margin-top: 1rem;
}

.upcoming-found {
  margin: 0.25rem 0 0.75rem;
  font-size: 0.88rem;
  color: var(--color-text-muted);
}

.upcoming-found[hidden] {
  display: none;
}

.upcoming-found button.link-button {
  margin-left: 0.35rem;
  color: var(--color-primary);
  text-decoration: none;
  font-size: inherit;
}

.bills-found-buttons {
  display: flex;
  gap: 0.5rem;
  flex-shrink: 0;
}

.bills-found-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 0.75rem;
}

.bills-found-actions[hidden] {
  display: none;
}

/* A found paycheck or bill (found.js), on Paycheck & bills and Recurring:
   on a phone, its buttons go on a line of their own. */
@media (max-width: 640px) {
  .found-row {
    flex-wrap: wrap;
  }

  .found-row .bills-found-buttons {
    width: 100%;
    justify-content: flex-end;
  }
}

.bills-done {
  display: flex;
  justify-content: flex-end;
  margin-top: 1.25rem;
}

.bills-done[hidden] {
  display: none;
}

/* Cash flow (Overview) */

.cashflow-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
  margin: 0.5rem 0 0.85rem;
}

.cashflow-title {
  margin: 0;
  font-size: 1.1rem;
}

.cashflow-sub {
  margin: 0.2rem 0 0;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.cashflow-card {
  position: relative; /* the tooltip is positioned inside it */
  margin-bottom: 1.25rem;
  transition: opacity 0.15s ease;
}

.cashflow-card.is-loading .cashflow-chart,
.cashflow-card.is-loading .cashflow-kpis {
  opacity: 0.5;
}

.cashflow-kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
  gap: 0.75rem;
  margin-bottom: 1.25rem;
}

.cashflow-kpis > .cashflow-kpi {
  padding: 0.75rem 0.9rem;
  border-radius: var(--radius-md);
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
}

.cashflow-kpi-value {
  margin-top: 0.3rem;
  font-size: 1.35rem;
  font-weight: 700;
}

.cashflow-kpi-value.positive {
  color: var(--color-success);
}

.cashflow-kpi-value.negative {
  color: var(--color-danger);
}

.chart-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.25rem;
  margin-bottom: 0.5rem;
  font-size: 0.82rem;
  color: var(--color-text-muted);
}

.chart-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.legend-swatch {
  width: 10px;
  height: 10px;
  border-radius: 2px;
}

.legend-line {
  width: 16px;
  height: 2px;
  border-radius: 1px;
}

.legend-swatch.cf-in, .chart-tooltip-key.cf-in { background: var(--viz-in); }
.legend-swatch.cf-out, .chart-tooltip-key.cf-out { background: var(--viz-out); }
.legend-line.cf-net, .chart-tooltip-key.cf-net { background: var(--viz-net); }

.cashflow-chart {
  min-height: 3rem;
}

.cashflow-svg {
  display: block;
  overflow: visible;
}

.cashflow-svg .cf-grid {
  stroke: var(--color-border);
  stroke-width: 1;
}

.cashflow-svg .cf-baseline {
  stroke: var(--viz-baseline);
  stroke-width: 1;
}

.cashflow-svg .cf-tick {
  fill: var(--color-text-muted);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}

.cashflow-svg .cf-direct-label {
  fill: var(--color-text-muted);
  font-size: 11px;
  font-weight: 600;
}

.cashflow-svg path.cf-in { fill: var(--viz-in); }
.cashflow-svg path.cf-out { fill: var(--viz-out); }

/* The current month isn't over yet: lighter, so it doesn't read as a drop. */
.cashflow-svg path.cf-partial { opacity: 0.5; }

.cashflow-svg .cf-net-line {
  fill: none;
  stroke: var(--viz-net);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.cashflow-svg .cf-net-dot {
  fill: var(--viz-net);
  stroke: var(--color-surface);
  stroke-width: 2;
}

.cashflow-svg .cf-hover-wash {
  fill: var(--color-surface-alt);
}

.cashflow-svg .cf-hit {
  fill: transparent;
  cursor: default;
}

.cashflow-svg .cf-hit:focus-visible {
  outline: none;
  stroke: var(--color-primary);
  stroke-width: 2;
}

.chart-tooltip {
  position: absolute;
  z-index: 10;
  min-width: 12rem;
  padding: 0.55rem 0.7rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
  font-size: 0.82rem;
  pointer-events: none;
}

.chart-tooltip[hidden] {
  display: none;
}

.chart-tooltip-title {
  margin-bottom: 0.35rem;
  font-weight: 600;
  color: var(--color-text);
}

.chart-tooltip-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.1rem 0;
  color: var(--color-text-muted);
}

.chart-tooltip-row strong {
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
}

.chart-tooltip-key {
  width: 12px;
  height: 2px;
  border-radius: 1px;
  flex-shrink: 0;
}

.cashflow-table {
  margin-top: 1rem;
}

.cashflow-table summary {
  cursor: pointer;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--color-primary);
}

.cashflow-table table {
  width: 100%;
  margin-top: 0.6rem;
}

.cashflow-table td.num,
.cashflow-table th.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Doubled up so it outranks .section-hint's negative top margin, defined later. */
.section-hint.cashflow-note {
  margin: 0.75rem 0 0;
}

/* Upcoming cash flow (Overview) */

.cashflow-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.75rem 1.25rem;
}

.cashflow-controls .checkbox-label {
  padding-bottom: 0.55rem; /* lines the text up with the select beside it */
}

/* Predicted payments: marked in words (badge, "(predicted)") and, on the
   chart, by a hollow dot -- never by color alone. */
.predicted-badge {
  display: inline-block;
  margin-left: 0.3rem;
  padding: 0.05rem 0.45rem;
  border-radius: 999px;
  border: 1px dashed var(--color-info);
  color: var(--color-info);
  font-size: 0.7rem;
  font-weight: 600;
  vertical-align: 1px;
}

#upcoming-table tr.is-predicted td {
  color: var(--color-text-muted);
}

/* The low point, tapped (upcoming.js showRowsThrough): its day picked out,
   what comes after faded. */
#upcoming-table tr.is-focus td {
  background: var(--color-primary-soft);
  font-weight: 600;
}

#upcoming-table tr.is-after-focus td {
  opacity: 0.45;
}

.upcoming-focus {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.75rem;
  margin: 0.75rem 0 0.25rem;
  font-size: 0.9rem;
}

.upcoming-focus[hidden] {
  display: none;
}

/* Under the chart: what the shaded days are (upcoming.js renderPayWindowNote). */
.upcoming-paywin {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 0.6rem;
  margin: 0.5rem 0 0;
  font-size: 0.9rem;
}

.upcoming-paywin[hidden] {
  display: none;
}

/* Lowest point: a tile that's also a button, in the warm tint the landing
   page gives the low point. */
.cashflow-kpis > .kpi-button {
  display: block;
  width: 100%;
  text-align: left;
  font: inherit;
  color: inherit;
  background: var(--color-low-soft);
  border-color: var(--color-low-border);
  cursor: pointer;
}

.kpi-button > span {
  display: block;
}

.kpi-button .cashflow-kpi-value {
  color: var(--color-low);
}

.cashflow-kpis > .kpi-button:not(:disabled):hover,
.cashflow-kpis > .kpi-button:focus-visible {
  border-color: var(--color-low);
  background: var(--color-low-soft);
}

.kpi-button:not(:disabled) .cashflow-kpi-note {
  text-decoration: underline dotted;
  text-underline-offset: 3px;
}

/* Not faded or lit like other disabled buttons: it's still the figure. */
.cashflow-kpis > .kpi-button:disabled,
.cashflow-kpis > .kpi-button:disabled:hover {
  cursor: default;
  opacity: 1;
  background: var(--color-low-soft);
}

.cashflow-svg .cf-direct-label.is-clickable,
.cashflow-svg .cf-hit.is-low {
  cursor: pointer;
}

.cashflow-svg .up-balance-dot.is-predicted {
  fill: var(--color-surface);
  stroke: var(--viz-balance);
  stroke-width: 2;
}

.legend-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--viz-balance);
  border: 2px solid var(--viz-balance);
}

.legend-dot.is-predicted {
  background: var(--color-surface);
}

.payplan-predicted {
  margin: -0.4rem 0 1rem;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.chart-legend[hidden] {
  display: none;
}

.cashflow-kpi-note {
  margin-top: 0.15rem;
  font-size: 0.8rem;
  color: var(--color-text-muted);
}

.cashflow-card.is-loading .upcoming-table {
  opacity: 0.5;
}

.cashflow-svg .up-balance-line {
  fill: none;
  stroke: var(--viz-balance);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.cashflow-svg .up-balance-dot {
  fill: var(--viz-balance);
  stroke: var(--color-surface);
  stroke-width: 2;
}

.cashflow-svg .up-balance-dot.is-active {
  r: 6;
}

.cashflow-svg .up-below-zero {
  fill: var(--color-danger-soft);
}

.cashflow-svg .up-crosshair {
  stroke: var(--color-text-muted);
  stroke-width: 1;
  stroke-dasharray: 3 3;
}

.chart-tooltip-key.up-balance { background: var(--viz-balance); }

.chart-tooltip-more {
  margin-top: 0.25rem;
  color: var(--color-text-muted);
}

#upcoming-table td.num,
#upcoming-table th.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.upcoming-table td.negative {
  color: var(--color-danger);
}

/* ↻ on anything a recurring series entered or will enter. */
.recurring-badge {
  margin-left: 0.25rem;
  color: var(--color-primary);
  font-weight: 700;
  cursor: help;
}

.upcoming-table .upcoming-date {
  white-space: nowrap;
  color: var(--color-text-muted);
}

.upcoming-table .upcoming-detail {
  font-size: 0.8rem;
  color: var(--color-text-muted);
}

.upcoming-pattern-actions button.link-button {
  margin-right: 0.75rem;
  color: var(--color-primary);
  text-decoration: none;
  font-size: 0.8rem;
}

.upcoming-table.single-account th:nth-child(3),
.upcoming-table.single-account td.upcoming-account {
  display: none;
}

/* Categories */

.category-list {
  display: flex;
  flex-direction: column;
}

.section-count {
  margin-left: 0.35rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--color-text-muted);
}

.category-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.6rem 0.25rem;
  border-bottom: 1px solid var(--color-border);
}

.category-row:last-child {
  border-bottom: none;
}

/* Renaming a category in place (app.js renameCategoryRow). */
.category-rename-input {
  width: 100%;
  max-width: 20rem;
}

.category-row-end .category-rename-btn {
  font-size: 0.85rem;
}

.category-row-child .category-name {
  padding-left: calc(var(--depth, 1) * 1.5rem);
  color: var(--color-text-muted);
}

.category-parent-path {
  color: var(--color-text-muted);
}

.category-row-end {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-shrink: 0;
}

.category-row-context .category-name {
  opacity: 0.55;
}

select.category-class {
  padding: 0.2rem 0.45rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--color-text-muted);
}

/* A category's tax line (the Taxes page counts it): quiet until it's set. */
select.category-tax {
  max-width: 13rem;
  padding: 0.2rem 0.45rem;
  font-size: 0.8rem;
  color: var(--color-text-muted);
}

select.category-tax.is-set {
  color: var(--color-text);
  font-weight: 600;
}

select.category-class.is-business {
  background: var(--color-info-soft);
  border-color: var(--color-info);
  color: var(--color-info);
}

.category-row.row-flash {
  background: var(--color-warning-soft);
  transition: background-color 0.3s ease;
}

.category-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.5rem 1.25rem;
  margin: 1.25rem 0;
}

.category-toolbar .section-hint {
  margin: 0 0 0.55rem;
}

.category-toolbar-notes .section-hint {
  margin: 0.15rem 0 0;
}

.category-toolbar-notes {
  padding-bottom: 0.4rem;
}

button.link-button.category-usage-show {
  color: var(--color-primary);
  font-size: inherit;
}

/* Usage: a count for categories in use; a "Not used" badge (words, not
   just color) and a quieter name for the rest. */
.usage-count {
  font-size: 0.78rem;
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.usage-count {
  cursor: help;
}

/* Hovering a count: its latest few transactions. Fixed to the viewport so
   the list's overflow never clips it. */
.recent-popover {
  position: fixed;
  z-index: 20;
  width: max-content;
  min-width: 16rem;
  max-width: min(26rem, calc(100vw - 16px));
  padding: 0.55rem 0.7rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
  font-size: 0.82rem;
  pointer-events: none;
}

.recent-popover[hidden] {
  display: none;
}

.recent-popover-title {
  margin-bottom: 0.35rem;
  font-weight: 600;
  color: var(--color-text);
}

.recent-popover-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0.2rem 0;
  color: var(--color-text-muted);
}

.recent-popover-date {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.recent-popover-payee {
  min-width: 0;
  color: var(--color-text);
  overflow-wrap: anywhere;
}

.recent-popover-where {
  display: block;
  font-size: 0.74rem;
  color: var(--color-text-muted);
}

.recent-popover-where:empty {
  display: none;
}

.recent-popover-row strong {
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.recent-popover-row strong.negative {
  color: var(--color-danger);
}

.recent-popover-note {
  margin-top: 0.35rem;
  color: var(--color-text-muted);
}

/* Over a year since its last transaction: the date says so, and the tooltip
   says it in words. */
.usage-count.is-stale .usage-last {
  color: var(--color-warning);
  font-weight: 600;
}

.usage-badge {
  font-size: 0.72rem;
  font-weight: 600;
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
  border: 1px dashed var(--color-warning);
  color: var(--color-warning);
  white-space: nowrap;
  cursor: help;
}

.category-row-unused .category-name {
  color: var(--color-text-muted);
  font-style: italic;
}

button.link-button.category-usage-delete {
  color: var(--color-danger);
  font-size: inherit;
}

/* Delete: quiet on each row until pointed at, then an inline panel. */
button.category-delete-btn {
  background: none;
  border: 1px solid transparent;
  color: var(--color-text-muted);
  padding: 0.2rem 0.5rem;
  font-size: 0.78rem;
  font-weight: 600;
}

button.category-delete-btn:hover,
button.category-delete-btn:focus-visible {
  background: var(--color-danger-soft);
  color: var(--color-danger);
}

.category-delete-panel {
  margin: 0.25rem 0 0.5rem calc(var(--depth, 0) * 1.5rem);
  padding: 0.75rem 0.9rem;
  border: 1px solid var(--color-danger);
  border-radius: var(--radius-sm);
  background: var(--color-danger-soft);
  font-size: 0.9rem;
}

.category-delete-panel p {
  margin: 0 0 0.5rem;
}

.category-delete-move {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9rem;
  color: var(--color-text);
}

.category-delete-move select {
  max-width: 22rem;
}

.category-delete-note {
  font-size: 0.82rem;
  color: var(--color-text-muted);
}

.category-delete-panel .category-delete-move + .category-delete-note {
  margin-top: 0.4rem;
}

.category-delete-actions {
  display: flex;
  gap: 0.6rem;
  margin-top: 0.6rem;
}

button.danger-btn {
  background: var(--color-danger);
  color: #fff;
}

button.danger-btn:hover {
  background: var(--color-danger);
  filter: brightness(0.92);
}

button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.category-notice {
  margin: -0.5rem 0 1.25rem;
}

/* Payees */

.payee-toolbar {
  margin-top: 0;
}

#payee-search {
  width: 16rem;
}

.payee-card[hidden] {
  display: none;
}

.payee-card .table-wrap {
  margin-top: 0.5rem;
}

/* Same column widths in every section, so Business and Personal line up. */
.payee-table {
  table-layout: fixed;
}

/* The Payees page's own tables: the short columns get what they need,
   Rename and Delete included, and Payee and Category share the rest. (The
   shared percentages further down left the actions 10%, too narrow once
   Rename joined Delete.) */
#view-payees .payee-table th:nth-child(1),
#view-payees .payee-table th:nth-child(2) { width: auto; }
#view-payees .payee-table th:nth-child(3) { width: 7.5rem; }
#view-payees .payee-table th:nth-child(4) { width: 7.5rem; }
#view-payees .payee-table th:nth-child(5) { width: 8.5rem; }

/* Recurring */

form.recurring-form {
  margin-top: 0;
}

/* Bills & paychecks: the list's heading with the ways to add one. */
.recurring-list-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1rem;
}

.recurring-list-head .section-title {
  margin: 0;
}

.recurring-add {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.recurring-form-card[hidden] {
  display: none;
}

/* Memo, end date and "still on time": folded until wanted. */
.recurring-more {
  flex-basis: 100%;
}

.recurring-how {
  margin-top: 0.75rem;
}

.recurring-how p {
  margin: 0.4rem 0 0;
}

.recurring-how summary,
.recurring-more summary {
  cursor: pointer;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.recurring-more-fields {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.85rem;
  margin-top: 0.6rem;
}

#recurring-payee,
#recurring-memo {
  width: 13rem;
}

#recurring-amount {
  width: 8rem;
}

.recurring-error {
  margin-top: 0.75rem;
}

.recurring-error[hidden] {
  display: none;
}

/* Twice a month: "On the [1st] and [15th]". */
.recurring-days {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

#recurring-days-label[hidden] {
  display: none;
}

.recurring-table th:nth-child(1) { width: 14%; }
.recurring-table th:nth-child(2) { width: 30%; }
.recurring-table th:nth-child(3) { width: 19%; }
.recurring-table th:nth-child(4) { width: 14%; }
.recurring-table th:nth-child(5) { width: 11%; }
.recurring-table th:nth-child(6) { width: 12%; }

.recurring-actions {
  text-align: right;
}

.recurring-actions button.link-button {
  margin-left: 0.6rem;
  color: var(--color-primary);
  text-decoration: none;
  font-size: 0.85rem;
}

.recurring-actions button.link-button.danger {
  color: var(--color-danger);
}

/* Export */

.export-list {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
}

.export-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 0.9rem 0;
  border-top: 1px solid var(--color-border);
}

.export-list .section-hint {
  margin: 0.25rem 0 0;
}

.export-list button {
  flex-shrink: 0;
  white-space: nowrap;
}

/* A download link that looks like the app's buttons. */
.button-link {
  flex-shrink: 0;
  display: inline-block;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  padding: 0.55rem 1.1rem;
  font-size: 0.88rem;
  font-weight: 600;
  background: var(--color-primary);
  color: #fff;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.button-link:hover {
  background: var(--color-primary-hover);
  color: #fff;
}

.button-link.secondary {
  background: var(--color-surface-alt);
  color: var(--color-text);
  border-color: var(--color-border);
}

.button-link.secondary:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

@media (max-width: 600px) {
  .export-list li {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.6rem;
  }
}

/* Reports (reports.js) */

.chart-legend-item[hidden] {
  display: none;
}

/* Download: CSV, Excel, PDF. */
.rp-download {
  position: relative;
}

.rp-download-toggle {
  list-style: none;
  cursor: pointer;
  padding: 0.5rem 0.9rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  font-weight: 600;
  font-size: 0.9rem;
}

.rp-download-toggle::-webkit-details-marker {
  display: none;
}

.rp-download-toggle::after {
  content: " ▾";
  color: var(--color-text-muted);
}

.rp-download-menu {
  position: absolute;
  right: 0;
  z-index: 5;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.35rem;
  min-width: 9rem;
  margin-top: 0.3rem;
  padding: 0.5rem 0.75rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
}

.rp-month-label {
  min-width: 9rem;
  text-align: center;
}

.rp-table-wrap {
  max-height: none;
}

.payee-table.rp-spend-table th:nth-child(1) { width: 24%; }
.payee-table.rp-spend-table th:nth-child(2) { width: 34%; }
.payee-table.rp-spend-table th:nth-child(3),
.payee-table.rp-spend-table th:nth-child(4),
.payee-table.rp-spend-table th:nth-child(5) { width: 14%; }

.rp-spend-table.is-past .rp-come-col {
  display: none;
}

/* Spent, then what's still to come (lighter, 2px apart), and a tick at a typical month. */
.rp-bar {
  position: relative;
  display: flex;
  gap: 2px;
  height: 12px;
  align-items: stretch;
}

.rp-bar-spent,
.rp-bar-come {
  background: var(--viz-out);
  border-radius: 0 4px 4px 0;
  min-width: 0;
}

.rp-bar-come,
.legend-swatch.rp-ahead,
.cashflow-svg path.rp-ahead {
  opacity: 0.45;
}

.rp-bar-typical {
  position: absolute;
  top: -3px;
  bottom: -3px;
  width: 2px;
  margin-left: -1px;
  background: var(--color-text);
}

.rp-bar-typical[hidden] {
  display: none;
}

.rp-legend-tick {
  display: inline-block;
  width: 2px;
  height: 12px;
  background: var(--color-text);
}

.legend-swatch.rp-ahead-key {
  background: var(--color-text-muted);
  opacity: 0.45;
}

.rp-spend-name {
  text-align: left;
  font-weight: 500;
}

/* A button centres its text, so a name that wraps on a phone would sit
   centred under the column's left-aligned heading. */
.rp-accounts-table .link-button {
  text-align: left;
}

.rp-detail-row td {
  background: var(--color-surface-alt);
}

.rp-detail-kids {
  margin: 0 0 0.5rem;
  font-size: 0.85rem;
}

.rp-detail-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
}

.rp-detail-table td {
  padding: 0.3rem 0.5rem;
  border-bottom: 1px solid var(--color-border);
}

.rp-detail-table .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.cashflow-svg .cf-hit.is-clickable {
  cursor: pointer;
}

.cashflow-svg .rp-net-line {
  fill: none;
  stroke: var(--viz-balance);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.cashflow-svg .rp-net-line.is-projected {
  stroke-dasharray: 5 5;
}

.cashflow-svg .rp-net-dot {
  fill: var(--viz-balance);
  stroke: var(--color-surface);
  stroke-width: 2;
}

.cashflow-svg .rp-net-dot.is-projected {
  fill: var(--color-surface);
  stroke: var(--viz-balance);
}

.cashflow-svg .rp-net-dot.is-picked {
  stroke: var(--color-text);
}

.cashflow-svg .rp-crosshair {
  stroke: var(--color-text-muted);
  stroke-width: 1;
  stroke-dasharray: 2 3;
}

.legend-line.rp-net-key,
.chart-tooltip-key.rp-net {
  background: var(--viz-balance);
}

.legend-line.rp-net-key.is-projected {
  background: repeating-linear-gradient(90deg, var(--viz-balance) 0 5px, transparent 5px 9px);
}

.rp-net-now {
  margin: 0.2rem 0 0;
  font-size: 1.8rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.rp-subtitle {
  margin: 1rem 0 0.25rem;
  font-size: 0.95rem;
}

.payee-table.rp-accounts-table th:nth-child(1) { width: 50%; }
.payee-table.rp-accounts-table th:nth-child(2) { width: 25%; }
.payee-table.rp-accounts-table th:nth-child(3) { width: 25%; }

/* Phones: each bar runs full width under its row, and the tables size to their contents. */
@media (max-width: 600px) {
  /* Spending rows: the name and amounts on one line, the bar on its own line under them. */
  .rp-spend-table,
  .rp-spend-table thead,
  .rp-spend-table tbody {
    display: block;
  }

  .rp-spend-table tr {
    display: grid;
    grid-template-columns: minmax(4.5rem, 1fr) repeat(3, auto);
    align-items: center;
    border-bottom: 1px solid var(--color-border);
  }

  .rp-spend-table.is-past tr {
    grid-template-columns: minmax(4.5rem, 1fr) repeat(2, auto);
  }

  .payee-table.rp-spend-table th,
  .payee-table.rp-spend-table td {
    min-width: 4.75rem;
    border-bottom: 0;
  }

  .payee-table.rp-spend-table th:first-child,
  .payee-table.rp-spend-table td:first-child {
    min-width: 0;
    /* A long one-word name ("Uncategorized") breaks rather than running into the amount. */
    overflow-wrap: anywhere;
    hyphens: auto;
  }

  .payee-table.rp-spend-table th:nth-child(2) {
    display: none;
  }

  .payee-table.rp-spend-table td.rp-bar-cell {
    grid-row: 2;
    grid-column: 1 / -1;
    padding-top: 0;
    padding-bottom: 0.6rem;
  }

  .payee-table.rp-spend-table td[colspan] {
    grid-column: 1 / -1;
  }

  .payee-table.rp-accounts-table {
    table-layout: auto;
  }

  .payee-table.rp-accounts-table th {
    width: auto !important;
  }

  .payee-table.rp-spend-table th,
  .payee-table.rp-spend-table td,
  .payee-table.rp-accounts-table th,
  .payee-table.rp-accounts-table td {
    padding-left: 0.45rem;
    padding-right: 0.45rem;
  }

  .rp-spend-table .num,
  .rp-accounts-table .num {
    white-space: nowrap;
  }

  /* The rows behind a category: date and amount on top, the rest wrapping. */
  .rp-detail-table,
  .rp-detail-table tbody,
  .rp-detail-table tr {
    display: block;
  }

  .rp-detail-table tr {
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: 0.1rem 0.5rem;
    padding: 0.35rem 0;
    border-bottom: 1px solid var(--color-border);
  }

  .rp-detail-table td {
    padding: 0;
    border: 0;
  }

  .rp-detail-table td:nth-child(4) {
    grid-column: 3;
    grid-row: 1;
  }

  .rp-detail-table td:nth-child(2) {
    grid-column: 2;
    grid-row: 1;
  }

  .rp-detail-table td:nth-child(3),
  .rp-detail-table td:nth-child(5) {
    grid-column: 2 / -1;
  }

  .rp-detail-table td:empty {
    display: none;
  }
}

/* Budgets */

.budget-month-nav {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.budget-month-nav .cashflow-title {
  min-width: 9rem;
  text-align: center;
}

button.budget-month-step {
  padding: 0.2rem 0.7rem;
  font-size: 1.1rem;
  line-height: 1.2;
}

.payee-table.budget-table th:nth-child(1) { width: 26%; }
.payee-table.budget-table th:nth-child(2) { width: 15%; }
.payee-table.budget-table th:nth-child(3),
.payee-table.budget-table th:nth-child(4),
.payee-table.budget-table th:nth-child(5),
.payee-table.budget-table th:nth-child(6) { width: 11%; }
.payee-table.budget-table th:nth-child(7) { width: 15%; }

/* A budget's numbers in a line, for phones (below). */
.budget-row-summary {
  display: none;
  margin-top: 0.35rem;
  font-size: 0.88rem;
}

/* Phones: each budget is a small card: its name, its bar, and what's left of
   it in one line; the column-by-column numbers are for wider screens. */
@media (max-width: 600px) {
  .budget-table,
  .budget-table tbody {
    display: block;
  }

  .budget-table thead {
    display: none;
  }

  .budget-table tbody tr {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.35rem 1rem;
    padding: 0.7rem 0.8rem;
    border-bottom: 1px solid var(--color-border);
  }

  .payee-table.budget-table td {
    padding: 0;
    border-bottom: none;
    text-align: left;
  }

  .budget-table td:first-child,
  .budget-table td.recurring-actions {
    grid-column: 1 / -1;
  }

  .budget-table td[data-label]::before {
    content: attr(data-label);
    display: block;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--color-text-muted);
  }

  .budget-table td:empty {
    display: none;
  }

  .budget-bar {
    max-width: none;
  }

  .budget-table td[data-label] {
    display: none;
  }

  .budget-row-summary {
    display: block;
  }
}

/* Every budget together (budgets.js): spent of budgeted, and one bar. */
.budget-total {
  margin-bottom: 0.25rem;
}

.budget-total[hidden] {
  display: none;
}

.budget-total-text {
  margin: 0;
  font-size: 1rem;
}

.budget-bar.budget-total-bar {
  max-width: none;
  height: 10px;
  margin-top: 0.5rem;
}

.budget-total-note {
  margin: 0.4rem 0 0;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.budget-total-note:empty {
  display: none;
}

.budget-total-note.negative,
.budget-row-summary.negative {
  color: var(--color-danger);
}

/* "Your month", folded to one line until opened. */
summary.budget-plan-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.75rem;
  cursor: pointer;
  list-style: none;
}

summary.budget-plan-summary::-webkit-details-marker {
  display: none;
}

.budget-plan-title {
  font-weight: 700;
  font-size: 1.05rem;
}

.budget-plan-title::before {
  content: "▸";
  display: inline-block;
  width: 1.1rem;
  color: var(--color-text-muted);
  font-size: 0.85rem;
}

details[open] > summary .budget-plan-title::before {
  content: "▾";
}

.budget-plan-line {
  color: var(--color-text-muted);
  font-size: 0.92rem;
}

.budget-plan-line.negative {
  color: var(--color-danger);
  font-weight: 600;
}

details.budget-plan[open] > summary.budget-plan-summary {
  margin-bottom: 1rem;
}

/* Spent (solid) then scheduled (lighter) out of the month's limit. Over the
   limit is also said in words, in the Left column. */
.budget-bar {
  display: flex;
  height: 6px;
  margin-top: 0.35rem;
  max-width: 16rem;
  border-radius: 999px;
  background: var(--color-surface-alt);
  box-shadow: inset 0 0 0 1px var(--color-border);
  overflow: hidden;
}

.budget-bar-spent {
  background: var(--color-primary);
}

.budget-bar-scheduled {
  background: var(--color-primary);
  opacity: 0.4;
}

.budget-bar.is-over .budget-bar-spent,
.budget-bar.is-over .budget-bar-scheduled {
  background: var(--color-danger);
}

.budget-status.is-over {
  color: var(--color-danger);
  font-weight: 600;
}

form.budget-form {
  margin-top: 0;
}

#budget-amount {
  width: 8rem;
}

/* Beats .section-hint's pull-up margin, which sits later in this file. */
.section-hint.budget-hint {
  margin: 0.75rem 0 0;
}

#budget-after.negative {
  color: var(--color-danger);
}

/* Savings goals (goals.js): each with its progress and one line of advice. */
.goal-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.goal-item {
  padding: 0.9rem 0;
  border-bottom: 1px solid var(--color-border);
}

.goal-item:first-child {
  padding-top: 0;
}

.goal-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  flex-wrap: wrap;
}

.goal-name {
  font-weight: 600;
}

.goal-amounts {
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

.goal-meter {
  height: 8px;
  margin: 0.5rem 0;
  border-radius: 4px;
  background: var(--color-primary-soft);
  overflow: hidden;
}

.goal-fill {
  height: 100%;
  border-radius: 4px;
  background: var(--color-primary);
}

.goal-fill.is-reached {
  background: var(--color-success);
}

.goal-sentence {
  margin: 0.25rem 0 0;
}

.goal-sentence.is-short {
  color: var(--color-warning);
}

.section-hint.goal-facts {
  margin: 0.25rem 0 0;
}

.goal-item.is-done .goal-fill {
  background: var(--color-text-muted);
}

.goal-done-head {
  padding: 1rem 0 0.25rem;
  font-size: 0.82rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}

/* "Spend from it": the money out it could be, one tap each. */
.goal-spending {
  margin-top: 0.75rem;
  padding: 0.75rem;
  border: 1px solid var(--color-border);
  border-radius: 8px;
}

.goal-spending .section-hint {
  margin: 0;
}

.goal-spending-list {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
  max-height: 22rem;
  overflow-y: auto;
}

.goal-spending-list li {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.4rem 0;
  border-top: 1px solid var(--color-border);
}

.goal-spending-list li.is-marked {
  font-weight: 600;
}

.goal-spending-what {
  flex: 1;
  min-width: 0;
}

.goal-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.6rem;
}

form.goal-form {
  margin-top: 0.5rem;
}

#goal-target,
#goal-starting,
#goal-amount {
  width: 8rem;
}

.goal-schedule-toggle {
  flex-basis: 100%;
}

fieldset.goal-schedule {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.85rem;
  margin: 0;
  padding: 0;
  border: 0;
}

fieldset.goal-schedule[hidden] {
  display: none;
}

.goal-days-inputs {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.goal-days-inputs input {
  width: 4.5rem;
}

#goal-days[hidden] {
  display: none;
}

.goal-paydays {
  flex-basis: 100%;
}

.section-hint.goal-kept-hint {
  flex-basis: 100%;
  margin: 0;
}

.goal-paydays[hidden] {
  display: none;
}

.section-hint.goal-payday {
  margin: 0;
}

.goal-form-buttons {
  display: flex;
  gap: 0.5rem;
  flex-basis: 100%;
}

.section-hint#goal-needed {
  margin: 0.75rem 0 0;
}

.payee-table.plan-bills-table th:nth-child(1) { width: 40%; }
.payee-table.plan-bills-table th:nth-child(2) { width: 40%; }
.payee-table.plan-bills-table th:nth-child(3) { width: 20%; }

.budget-suggestions {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
}

.budget-suggestions li {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.45rem 0;
  border-bottom: 1px solid var(--color-border);
}

.budget-suggestions li:last-child {
  border-bottom: none;
}

.budget-suggestion-name {
  flex: 1;
  min-width: 0;
}

.budget-suggestions .num {
  font-variant-numeric: tabular-nums;
  color: var(--color-text-muted);
}

.payee-table th:nth-child(1) { width: 34%; }
.payee-table th:nth-child(2) { width: 28%; }
.payee-table th:nth-child(3) { width: 15%; }
.payee-table th:nth-child(4) { width: 13%; }
.payee-table th:nth-child(5) { width: 10%; }

.payee-table td {
  padding-top: 0.4rem;
  padding-bottom: 0.4rem;
  vertical-align: middle;
}

.payee-table .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.payee-table .nowrap {
  white-space: nowrap;
}

.payee-table .muted {
  color: var(--color-text-muted);
}

.payee-name {
  font-weight: 500;
}

/* A payee's tick box, before its name (payees.js): beside it, in the
   name's own size and colour, not stacked like a form label. */
label.payee-name {
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  gap: 0.5rem;
  font-size: inherit;
  color: inherit;
}

/* Payees ticked to delete together (payees.js renderPayeeSelection). */
/* Floats at the bottom of the screen while payees are ticked, wherever
   the lists are scrolled to; above the tab bar on a phone (below). */
.payee-selection {
  position: sticky;
  bottom: 1rem;
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
  margin-top: 1rem;
  padding: 0.75rem 1rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: 0 6px 24px rgba(16, 24, 40, 0.16);
  font-weight: 600;
}

@media (max-width: 800px) {
  .payee-selection {
    bottom: calc(58px + env(safe-area-inset-bottom, 0px) + 0.75rem);
  }

  /* The count on its own line, the two buttons side by side under it. */
  #payee-selection-count {
    flex-basis: 100%;
  }
}

.payee-selection[hidden] {
  display: none;
}

.payee-also {
  margin-top: 0.1rem;
  font-size: 0.78rem;
  color: var(--color-text-muted);
  max-width: 28rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.payee-badge {
  display: inline-block;
  margin-left: 0.3rem;
  padding: 0.05rem 0.45rem;
  border-radius: 999px;
  background: var(--color-primary-soft);
  color: var(--color-primary);
  font-size: 0.7rem;
  font-weight: 600;
  vertical-align: 1px;
}

.payee-table tbody tr.payee-delete-row:hover {
  background: none;
}

.payee-delete-panel {
  margin: 0;
}

.category-notice[hidden] {
  display: none;
}

.category-form-hint {
  margin: 0.6rem 0 0;
}

#category-form-error {
  margin: 0.75rem 0 0;
}

#category-parent {
  max-width: 20rem;
}

#category-type:disabled {
  opacity: 0.6;
}

/* Transfers between accounts */

.transfer-label {
  display: inline-block;
  font-size: 0.8rem;
  font-weight: 600;
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
  background: var(--color-primary-soft);
  color: var(--color-primary);
  white-space: nowrap;
}

.transfer-label.muted {
  background: var(--color-surface-alt);
  color: var(--color-text-muted);
}

.section-hint {
  margin: -0.25rem 0 0.75rem;
  font-size: 0.85rem;
  color: var(--color-text-muted);
  max-width: 60rem;
}

.transfer-new-type {
  margin-left: 0.4rem;
}

.transfer-outcome {
  font-size: 0.82rem;
  color: var(--color-text-muted);
  min-width: 16rem;
}

#register-table tbody tr.row-flash,
#register-table tbody tr.row-flash:hover {
  background: var(--color-warning-soft);
  transition: background-color 0.3s ease;
}

.category-badge {
  font-size: 0.72rem;
  font-weight: 600;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  white-space: nowrap;
}

.category-badge.income {
  background: var(--color-success-soft);
  color: var(--color-success);
}

.category-badge.expense {
  background: var(--color-surface-alt);
  color: var(--color-text-muted);
}

/* Forms */

form {
  margin-top: 1rem;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.85rem;
}

label {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.82rem;
  font-weight: 500;
  color: var(--color-text-muted);
}

/* The display: flex above would otherwise beat the hidden attribute. */
label[hidden] {
  display: none;
}

input, select, button {
  font: inherit;
}

/* A select is as wide as its longest option (a long "Parent:Child" category),
   so it's kept inside whatever holds it. */
input, select, textarea {
  max-width: 100%;
}

input[type="text"],
input[type="search"],
input[type="email"],
input[type="password"],
input[type="date"],
input[type="number"],
input[type="file"],
select {
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: 0.9rem;
}

input:focus-visible, select:focus-visible, button:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 1px;
}

button {
  cursor: pointer;
  border: 1px solid transparent;
  border-radius: 10px;
  padding: 0.6rem 1.15rem;
  font-size: 0.88rem;
  font-weight: 600;
  background: var(--color-primary);
  color: #fff;
  height: fit-content;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

button:hover {
  background: var(--color-primary-hover);
}

/* The landing page's outline button: white, a 1.5px blue edge, blue words. */
button.secondary,
#register-clear-filters,
.row-cancel-btn {
  background: var(--color-surface);
  color: var(--color-primary);
  border: 1.5px solid var(--color-primary);
}

button.secondary:hover,
#register-clear-filters:hover,
.row-cancel-btn:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
  background: var(--color-primary-soft);
}

.row-save-btn,
#add-transaction-btn {
  background: var(--color-primary-soft);
  color: var(--color-primary);
}

.row-save-btn:hover,
#add-transaction-btn:hover {
  background: var(--color-primary);
  color: #fff;
}

.csv-mapping {
  margin-top: 1rem;
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.csv-mapping[hidden] {
  display: none;
}

.warning {
  color: var(--color-warning);
  background: var(--color-warning-soft);
  padding: 0.5rem 0.75rem;
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
  margin: 0 0 0.5rem;
}

/* Tables */

/* A table grows with the page, which does the scrolling: no box of its own to
   scroll inside, rows cut off at its bottom edge, or two scrollbars. A table
   wider than the screen still scrolls sideways. */
.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  margin-top: 1rem;
}

/* The Register and Reconcile keep a box of their own: the Register lands on
   today and pins its add row inside it (register.js). */
.table-wrap:has(> #register-table),
.table-wrap:has(> #reconcile-table) {
  max-height: 60vh;
  overflow: auto;
}

/* A fixed-layout table is never wider than its box, so on wider screens it
   needs no sideways scrolling: clipped instead, its column headings (sticky)
   stay in view as the page scrolls past them. */
@media (min-width: 801px) {
  .table-wrap:has(> table.payee-table) {
    overflow: clip;
  }
}

#import-preview-table, #import-categories-table, #import-memorized-table, #import-transfers-table, #import-file-accounts-table, #register-table, #upcoming-table, #reconcile-table, .payee-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.88rem;
  background: var(--color-surface);
}

#import-preview-table th, #import-preview-table td,
#import-categories-table th, #import-categories-table td,
#import-memorized-table th, #import-memorized-table td,
#import-transfers-table th, #import-transfers-table td,
#import-file-accounts-table th, #import-file-accounts-table td,
#register-table th, #register-table td,
#upcoming-table th, #upcoming-table td,
#reconcile-table th, #reconcile-table td,
.payee-table th, .payee-table td {
  text-align: left;
  padding: 0.55rem 0.7rem;
  border-bottom: 1px solid var(--color-border);
}

#import-preview-table thead th,
#import-categories-table thead th,
#import-memorized-table thead th,
#import-transfers-table thead th,
#import-file-accounts-table thead th,
#register-table thead th,
#upcoming-table thead th,
#reconcile-table thead th,
.payee-table thead th {
  position: sticky;
  top: 0;
  background: var(--color-surface-alt);
  color: var(--color-text-muted);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-weight: 600;
  z-index: 1;
}

#import-preview-table tbody tr:hover,
#import-categories-table tbody tr:hover,
#import-memorized-table tbody tr:hover,
#import-transfers-table tbody tr:hover,
#import-file-accounts-table tbody tr:hover,
#register-table tbody tr:hover,
#upcoming-table tbody tr:hover,
#reconcile-table tbody tr:hover,
.payee-table tbody tr:hover {
  background: var(--color-surface-alt);
}

#register-table input, #register-table select {
  font-size: 0.85rem;
  padding: 0.3rem 0.4rem;
  width: 100%;
}

.duplicate-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.85rem;
  margin: 1rem 0 0;
  padding: 0.6rem 0.85rem;
  background: var(--color-warning-soft);
  border: 1px solid var(--color-warning);
  border-radius: var(--radius-sm);
}

.duplicate-toolbar[hidden] {
  display: none;
}

.duplicate-count-badge {
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--color-warning);
}

/* A checkbox row shown only sometimes (Edit's "Remove the values you entered"). */
.checkbox-label[hidden] {
  display: none;
}

.checkbox-label {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.85rem;
  color: var(--color-text);
}

.checkbox-label input {
  margin: 0;
}

.duplicate-toolbar button {
  padding: 0.4rem 0.75rem;
  font-size: 0.82rem;
  margin-left: auto;
}

.duplicate-toolbar button + button {
  margin-left: 0;
}

#import-preview-table tbody tr.row-duplicate {
  background: var(--color-warning-soft);
  box-shadow: inset 3px 0 0 var(--color-warning);
}

#import-preview-table tbody tr.row-duplicate:hover {
  background: var(--color-warning-soft);
  filter: brightness(0.97);
}

.dup-badge {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 600;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  background: var(--color-warning);
  color: #fff;
  cursor: help;
  white-space: nowrap;
}

/* A row that is the bank's record of an entry already in the register. */
#import-preview-table tbody tr.row-matched {
  background: var(--color-success-soft);
  box-shadow: inset 3px 0 0 var(--color-success);
}

.match-cell {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 0.5rem;
}

.match-badge {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 600;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  background: var(--color-success-soft);
  color: var(--color-success);
  border: 1px solid var(--color-success);
}

.match-details,
.dup-details {
  font-size: 0.85rem;
  color: var(--color-text-muted);
  max-width: 18rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The import table's Notes column: a link/match choice sits on its own line
   under the badge, no wider than the column needs, so the table doesn't
   scroll sideways. A duplicate's details wrap rather than being cut off. */
#import-preview-table .match-cell .row-match {
  flex-basis: 100%;
  max-width: 16rem;
  font-size: 0.85rem;
  padding: 0.3rem 0.4rem;
}

.dup-details {
  white-space: normal;
  max-width: 20rem;
}

.repeat-badge {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 600;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  background: var(--color-info-soft);
  color: var(--color-info);
  cursor: help;
  white-space: nowrap;
}

.pending {
  color: var(--color-info);
  font-size: 0.78rem;
  margin-top: 0.2rem;
}

#import-commit-btn {
  margin-top: 1rem;
}

#import-result:not(:empty) {
  margin-top: 1rem;
  font-weight: 600;
}

/* Register */

.register-toolbar {
  margin-top: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.85rem;
}

/* Filters (register.js): a second row under the toolbar, when open. */
#register-search {
  width: 11rem;
}

.register-more-filters {
  flex-basis: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.85rem;
}

.register-more-filters[hidden] {
  display: none;
}

/* A <label> look-alike for controls that can't live inside a <label>
   (clicking anywhere in a label forwards the click to its first control). */
.field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.field-label {
  font-size: 0.82rem;
  font-weight: 500;
  color: var(--color-text-muted);
}

/* Multi-select dropdown (Register → Years) */

.multiselect {
  position: relative;
}

button.multiselect-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  min-width: 9rem;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: 0.9rem;
  font-weight: 400;
}

button.multiselect-toggle:hover,
button.multiselect-toggle[aria-expanded="true"] {
  background: var(--color-surface);
  border-color: var(--color-primary);
}

.multiselect-caret {
  color: var(--color-text-muted);
  font-size: 0.75rem;
}

.multiselect-panel {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 20;
  min-width: 100%;
  max-height: 18rem;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.35rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
}

.multiselect-panel[hidden] {
  display: none;
}

.multiselect-panel .checkbox-label {
  padding: 0.35rem 0.5rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.multiselect-panel .checkbox-label:hover {
  background: var(--color-surface-alt);
}

button.multiselect-all {
  background: none;
  color: var(--color-primary);
  text-align: left;
  padding: 0.35rem 0.5rem;
  font-size: 0.85rem;
}

button.multiselect-all:hover {
  background: var(--color-primary-soft);
}

.multiselect-empty {
  margin: 0;
  padding: 0.35rem 0.5rem;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

#register-balance.balance-line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 1.75rem;
  margin: 1rem 0 0;
}

.balance-figure {
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
  font-weight: 600;
  font-size: 1.05rem;
  cursor: help;
}

.balance-figure-label {
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}

.balance-note {
  font-size: 0.8rem;
  color: var(--color-text-muted);
}

/* Register rows: compact, one line each */

#register-table td {
  padding-top: 0.3rem;
  padding-bottom: 0.3rem;
}

#register-table .nowrap {
  white-space: nowrap;
}

#register-table .num {
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

#register-table .memo-cell {
  max-width: 18rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

#register-table tr.register-row {
  cursor: default;
}

#register-table tr.register-group-row td,
#register-table tbody tr.register-group-row:hover {
  background: var(--color-surface-alt);
}

#register-table tr.register-group-row td {
  padding-top: 0.4rem;
  padding-bottom: 0.4rem;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-text-muted);
}

.register-group-count {
  margin-left: 0.35rem;
  padding: 0.05rem 0.45rem;
  border-radius: 999px;
  background: var(--color-border);
  font-weight: 600;
}

.row-actions-cell {
  width: 1%;
  text-align: right;
}

button.row-menu-btn {
  background: none;
  color: var(--color-text-muted);
  padding: 0 0.45rem;
  font-size: 1.1rem;
  line-height: 1.4;
  font-weight: 700;
}

button.row-menu-btn:hover,
button.row-menu-btn[aria-expanded="true"] {
  background: var(--color-border);
  color: var(--color-text);
}

.row-menu {
  position: fixed;
  z-index: 50;
  min-width: 10rem;
  display: flex;
  flex-direction: column;
  padding: 0.3rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
}

.row-menu[hidden] {
  display: none;
}

button.row-menu-item {
  background: none;
  color: var(--color-text);
  text-align: left;
  font-weight: 500;
  padding: 0.45rem 0.65rem;
}

button.row-menu-item:hover,
button.row-menu-item:focus-visible {
  background: var(--color-surface-alt);
  outline: none;
}

button.row-menu-item.danger {
  color: var(--color-danger);
}

button.row-menu-item.danger:hover,
button.row-menu-item.danger:focus-visible {
  background: var(--color-danger-soft);
}

.register-edit-row button {
  padding: 0.3rem 0.7rem;
  font-size: 0.82rem;
}

/* Save and Cancel stack when the register is narrow, rather than widening
   the table past its box. */
.register-edit-row td.row-edit-actions button {
  margin: 0.1rem 0;
}

#register-add-row-body {
  background: var(--color-surface-alt);
}

/* Always in view: the add row sticks under the column headings, and an open
   split editor under it (register.js pinAddRow measures the offsets). Cells,
   not the row group, stick: that works in every browser. */
/* Each tucks 1px under what's above it: the headings' height shifts by a
   fraction of a pixel as the rows scroll, and a seam that thin still lets the
   rows' text show through. */
#register-add-row-body td {
  position: sticky;
  top: calc(var(--register-head-height, 2.25rem) - 1px);
  z-index: 1;
  background: var(--color-surface-alt);
}

#register-add-row-body tr.split-editor-row td {
  top: calc(var(--register-head-height, 2.25rem) + var(--register-add-height, 3rem) - 2px);
}

/* In a collapsed-border table the table draws the borders, and they don't
   move with sticky cells: rows scrolling underneath show through that line.
   The sticky cells draw their own lines instead. */
#register-table thead th,
#register-add-row-body td {
  border-bottom: 0;
  box-shadow: inset 0 -1px 0 var(--color-border);
}

#register-add-row-body tr:first-child td {
  box-shadow: inset 0 1px 0 var(--color-border), inset 0 -1px 0 var(--color-border);
}

.add-amount-cell {
  white-space: nowrap;
}

#register-table .add-amount-cell select {
  width: auto;
  margin-right: 0.25rem;
}

#register-table .add-amount-cell input {
  width: 6.5rem;
}

/* Wide screens: the Register fits its box, so Amount and Balance are always
   in view. Date, Amount, Balance, Cleared and the actions get what they need;
   Payee, Category and Memo share the rest, a long one wrapping (the memo
   trimmed) rather than widening the table. Below its minimum width (a narrow
   window) it scrolls sideways instead of squeezing them. Phones stack the
   rows instead. */
@media (min-width: 801px) {
  #register-table {
    table-layout: fixed;
    min-width: 52rem;
  }

  #register-table .register-col-date { width: 8.5rem; }
  #register-table .register-col-amount { width: 9rem; }
  #register-table .register-col-balance { width: 7rem; }
  #register-table .register-col-cleared { width: 6rem; }
  #register-table .register-col-actions { width: 5rem; }

  #register-table th,
  #register-table td {
    padding-inline: 0.5rem;
    overflow-wrap: break-word;
  }

  #register-table .category-search {
    min-width: 0;
  }

  /* The add and edit rows' boxes get the cells' room. */
  #register-table tr#register-add-row td,
  #register-table tr.register-edit-row td {
    padding-inline: 0.4rem;
  }

  #register-table .add-amount-cell select {
    width: 3.9rem;
  }

  #register-table .add-amount-cell input {
    width: calc(100% - 4.15rem);
  }

  #register-table tr#register-add-row button {
    padding-inline: 0.6rem;
    white-space: nowrap;
  }
}

.register-move-row .move-label {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.88rem;
  font-weight: 400;
  color: var(--color-text);
}

#register-table .register-move-row .move-target {
  width: auto;
  max-width: 100%;
}

.register-notice {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 0.75rem;
  margin: 0.75rem 0 0;
  padding: 0.5rem 0.75rem;
  border-radius: var(--radius-sm);
  background: var(--color-success-soft);
  color: var(--color-success);
  font-size: 0.88rem;
  font-weight: 500;
}

.register-notice[hidden] {
  display: none;
}

#bank-notice {
  margin: 0 0 0.75rem;
}

/* The register account's bank (banks.js renderRegisterBank). */
.register-bank {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin: 0.75rem 0 0;
}

.register-bank[hidden] {
  display: none;
}

.register-bank .forecast-headline {
  margin-bottom: 0;
}

.register-bank-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
}

.register-bank-text {
  margin: 0;
}

.register-bank-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

button.link-button {
  background: none;
  color: inherit;
  padding: 0;
  font-weight: 600;
  text-decoration: underline;
}

button.link-button:hover {
  background: none;
}

button.link-button.notice-close {
  margin-left: auto;
  text-decoration: none;
  opacity: 0.7;
}

/* Reconcile (Register) */

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

button.reconcile-open-btn,
button.register-import-btn {
  margin-left: auto;
}

button.register-import-btn + button.reconcile-open-btn {
  margin-left: 0;
}

button.reconcile-open-btn.is-resume {
  background: var(--color-warning-soft);
  color: var(--color-warning);
  border-color: var(--color-warning);
}

.reconcile-card {
  border-color: var(--color-primary);
}

.reconcile-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
}

.reconcile-title {
  margin-bottom: 0.2rem;
}

.reconcile-sub {
  margin: 0;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

/* Not the row layout every other form gets: intro, fields, then history. */
form.reconcile-start {
  display: block;
  margin-top: 1rem;
}

form.reconcile-start[hidden] {
  display: none;
}

.reconcile-intro {
  margin: 0 0 1rem;
  font-size: 0.9rem;
  max-width: 48rem;
}

.reconcile-fields {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.85rem;
}

#reconcile-start-error {
  margin-top: 0.75rem;
}

.reconcile-history {
  margin-top: 1.25rem;
  font-size: 0.85rem;
}

.reconcile-history-title {
  margin-bottom: 0.35rem;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}

.reconcile-history-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 1rem;
  padding: 0.3rem 0;
  border-top: 1px solid var(--color-border);
}

.reconcile-history-row .num {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

.reconcile-history-row .muted {
  color: var(--color-text-muted);
}

.reconcile-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 1rem 2rem;
  margin-top: 1.1rem;
}

.reconcile-figure-value {
  margin-top: 0.3rem;
  font-size: 1.35rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.reconcile-difference {
  padding: 0.45rem 0.8rem;
  border-radius: var(--radius-sm);
}

.reconcile-difference.is-balanced {
  background: var(--color-success-soft);
}

.reconcile-difference.is-balanced .reconcile-figure-value {
  color: var(--color-success);
}

.reconcile-difference.is-off {
  background: var(--color-warning-soft);
}

.reconcile-difference.is-off .reconcile-figure-value {
  color: var(--color-warning);
}

.reconcile-actions {
  display: flex;
  gap: 0.6rem;
  margin-left: auto;
}

.reconcile-checked {
  margin: 0.75rem 0 0;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.reconcile-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1.25rem;
  margin-top: 1rem;
  font-size: 0.85rem;
}

.reconcile-toolbar button.link-button {
  color: var(--color-primary);
  text-decoration: none;
  font-size: 0.85rem;
}

.reconcile-toolbar button.link-button:hover {
  text-decoration: underline;
}

.reconcile-toolbar-end {
  display: flex;
  gap: 1.25rem;
  margin-left: auto;
}

.reconcile-toolbar button.reconcile-cancel {
  color: var(--color-danger);
}

#reconcile-table td {
  padding-top: 0.3rem;
  padding-bottom: 0.3rem;
}

#reconcile-table .num {
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

#reconcile-table .nowrap {
  white-space: nowrap;
}

#reconcile-table .memo-cell {
  max-width: 14rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--color-text-muted);
}

#reconcile-table .reconcile-check-col {
  width: 2rem;
  text-align: center;
}

#reconcile-table input[type="checkbox"] {
  width: 1rem;
  height: 1rem;
  cursor: pointer;
  accent-color: var(--color-success);
}

#reconcile-table tr.reconcile-row {
  cursor: pointer;
}

#reconcile-table tbody tr.reconcile-row.is-checked,
#reconcile-table tbody tr.reconcile-row.is-checked:hover {
  background: var(--color-success-soft);
}

#reconcile-table tr.reconcile-row.is-after td:nth-child(2) {
  color: var(--color-warning);
}

#reconcile-add-body {
  background: var(--color-surface-alt);
}

#reconcile-table .reconcile-add-row input,
#reconcile-table .reconcile-add-row select {
  width: 100%;
  font-size: 0.85rem;
  padding: 0.3rem 0.4rem;
}

#reconcile-table .reconcile-add-row input[type="number"] {
  min-width: 6rem;
  text-align: right;
}

#reconcile-table .reconcile-add-row button {
  padding: 0.3rem 0.8rem;
  font-size: 0.82rem;
}

/* Pay this statement (Register, card and loan accounts) */

.payplan-card {
  position: relative; /* the chart tooltip is positioned inside it */
}

form.payplan-missing {
  display: block;
}

form.payplan-missing[hidden] {
  display: none;
}

.payplan-already {
  margin-top: 1.25rem;
}

.payplan-already-hint {
  margin: 0 0 0.35rem;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.payplan-already .reconcile-history-row .link-button {
  margin-left: auto;
}

.payplan-done {
  margin: 1rem 0 0;
  padding: 0.6rem 0.85rem;
  border-radius: var(--radius-sm);
  background: var(--color-success-soft);
  color: var(--color-success);
  font-weight: 500;
}

.payplan-figures {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2.25rem;
  margin-top: 1.1rem;
}

#payplan-due-note.is-overdue {
  color: var(--color-danger);
  font-weight: 600;
}

.payplan-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.85rem;
  margin-top: 1.25rem;
}

#payplan-cushion,
#payplan-other {
  width: 8rem;
}

.payplan-advice {
  margin: 1rem 0;
  padding: 0.7rem 0.9rem;
  border-radius: var(--radius-sm);
  font-size: 0.92rem;
  line-height: 1.45;
  background: var(--color-surface-alt);
}

.payplan-advice.is-good {
  background: var(--color-success-soft);
}

.payplan-advice.is-warning {
  background: var(--color-warning-soft);
}

.payplan-advice button.link-button {
  color: var(--color-primary);
}

.payplan-schedule {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.85rem;
  margin-top: 0.75rem;
}

.payplan-date-check {
  align-self: center;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.payplan-date-check.is-warning {
  color: var(--color-warning);
  font-weight: 500;
}

.legend-line.pp-with { background: var(--viz-balance); }
.legend-line.pp-without,
.chart-tooltip-key.pp-without {
  background: none;
  border-top: 2px dashed var(--color-text-muted);
  height: 0;
}
.legend-swatch.pp-window {
  background: var(--color-success-soft);
  border: 1px solid var(--color-success);
}

.cashflow-svg .pp-window {
  fill: var(--color-success-soft);
}

.cashflow-svg .pp-without-line {
  fill: none;
  stroke: var(--color-text-muted);
  stroke-width: 1.5;
  stroke-dasharray: 4 3;
}

.cashflow-svg .pp-cushion {
  stroke: var(--color-warning);
  stroke-width: 1;
  stroke-dasharray: 2 3;
}

.cashflow-svg .pp-due {
  stroke: var(--color-text-muted);
  stroke-width: 1;
}

.amount-negative {
  color: var(--color-danger);
}

.amount-positive {
  color: var(--color-success);
}

.status-badge {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 600;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  text-transform: capitalize;
  white-space: nowrap;
}

.status-badge.status-uncleared {
  background: var(--color-surface-alt);
  color: var(--color-text-muted);
}

.status-badge.status-cleared {
  background: var(--color-info-soft);
  color: var(--color-info);
}

.status-badge.status-reconciled {
  background: var(--color-success-soft);
  color: var(--color-success);
}

/* Working indicator: covers the page (so clicks can't land while the server
   is busy) with a small centered card saying what's happening. */

.busy-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background: rgba(15, 17, 21, 0.25);
  cursor: progress;
  animation: busy-fade-in 0.15s ease-out;
}

.busy-overlay[hidden] {
  display: none;
}

.busy-card {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  max-width: 100%;
  padding: 0.9rem 1.25rem;
  background: var(--color-surface);
  color: var(--color-text);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  font-weight: 500;
}

.busy-spinner {
  flex-shrink: 0;
  width: 1.25rem;
  height: 1.25rem;
  border: 2.5px solid var(--color-primary-soft);
  border-top-color: var(--color-primary);
  border-radius: 50%;
  animation: busy-spin 0.8s linear infinite;
}

@keyframes busy-spin {
  to { transform: rotate(360deg); }
}

@keyframes busy-fade-in {
  from { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .busy-overlay { animation: none; }
  .busy-spinner { animation-duration: 2.4s; }
}

/* Responsive */

@media (max-width: 800px) {
  .app-shell {
    flex-direction: column;
  }

  .sidebar {
    width: 100%;
    height: auto;
    position: relative;
    flex-direction: row;
    align-items: center;
    padding: 0.75rem 1rem;
    overflow-x: auto;
  }

  .brand {
    margin-bottom: 0;
    margin-right: 1rem;
  }

  .nav {
    flex-direction: row;
    flex: none;
  }

  .nav-item .nav-icon {
    display: none;
  }

  .theme-toggle {
    margin-top: 0;
    margin-left: auto;
    flex-shrink: 0;
  }

  .topbar, main {
    padding-left: 1.25rem;
    padding-right: 1.25rem;
  }

  form {
    flex-direction: column;
    align-items: stretch;
  }

  /* Stacked, each field spans the form, and none can widen it. */
  form > *,
  form label {
    min-width: 0;
  }

  form label > select {
    width: 100%;
  }

  /* Filters and toolbars outside a form: a label is no wider than its row,
     so the select in it (max-width: 100%) shrinks with it. */
  main label,
  main .field {
    max-width: 100%;
    min-width: 0;
  }

  /* A category's details and actions go on the line under its name. */
  .category-row {
    flex-wrap: wrap;
    row-gap: 0.35rem;
  }

  .category-row-end {
    flex-basis: 100%;
    flex-shrink: 1;
    flex-wrap: wrap;
    min-width: 0;
  }

  .category-row-child .category-row-end {
    padding-left: calc(var(--depth, 1) * 1.5rem);
  }
}

/* The signup wizard's steps: 1-3 on the signup screens (auth.html), 4-6 in the
   app's setup (app.js). */
.wizard-steps {
  list-style: none;
  display: flex;
  gap: 0.35rem;
  margin: 0 0 1.5rem;
  padding: 0;
  counter-reset: wizard;
}

.wizard-steps li {
  flex: 1;
  counter-increment: wizard;
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--color-text-muted);
  border-top: 3px solid var(--color-border);
  padding-top: 0.4rem;
  line-height: 1.25;
}

.wizard-steps li::before {
  content: counter(wizard) ". ";
}

.wizard-steps li.is-done {
  border-color: var(--color-success);
}

.wizard-steps li.is-done::before {
  content: "✓ ";
  color: var(--color-success);
}

.wizard-steps li.is-current {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

@media (max-width: 600px) {
  .wizard-steps li {
    font-size: 0;
  }
  .wizard-steps li::before {
    font-size: 0.72rem;
  }
  /* The step you're on says what it is. */
  .wizard-steps li.is-current {
    flex: 3;
    font-size: 0.72rem;
  }
}

/* Signed-in user, above the theme toggle. */
.sidebar-user {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.75rem 0.25rem 0;
  border-top: 1px solid var(--color-border);
  font-size: 0.85rem;
  min-width: 0;
}

.sidebar-user[hidden] {
  display: none;
}

.sidebar-user-name {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sidebar-user-email {
  color: var(--color-text-muted);
  font-size: 0.78rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sidebar-user .link-button {
  align-self: flex-start;
  margin-top: 0.35rem;
  color: var(--color-primary);
  text-decoration: none;
  font-size: 0.82rem;
}

/* Setup wizard (session.js): the steps bar above the page, and nothing to
   wander off to in the sidebar until it's done. */
.setup-bar {
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  padding: 1.1rem 2rem 1rem;
}

.setup-bar[hidden] {
  display: none;
}

.setup-bar .wizard-steps {
  margin-bottom: 0.9rem;
  max-width: 44rem;
}

.setup-bar-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.setup-bar-text {
  margin: 0;
  max-width: 48rem;
  font-size: 0.9rem;
  color: var(--color-text-muted);
}

.setup-bar-actions {
  display: flex;
  gap: 0.6rem;
}

body.is-setup .nav {
  visibility: hidden;
}

/* Phones: Back and Continue pinned to the bottom, in reach of a thumb and in
   sight after adding an account below. */
@media (max-width: 800px) {
  .setup-bar {
    padding: 0.9rem 1.25rem 0.8rem;
  }

  .setup-bar-actions {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 30;
    padding: 0.75rem 1.25rem calc(0.75rem + env(safe-area-inset-bottom, 0px));
    background: var(--color-surface);
    border-top: 1px solid var(--color-border);
    box-shadow: 0 -2px 10px rgba(16, 24, 40, 0.08);
  }

  .setup-bar-actions button {
    flex: 1;
    min-height: 48px;
  }

  .setup-bar-actions button[hidden] {
    display: none;
  }

  body.is-setup main {
    padding-bottom: 6rem;
  }
}

.setup-accounts {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.setup-account {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.65rem 0.85rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}

.setup-account-name {
  font-weight: 600;
  flex: 1;
}

.setup-account-balance {
  font-variant-numeric: tabular-nums;
  color: var(--color-text-muted);
}

/* ---- Support (staff, support.js) ---------------------------------------------- */

/* Ten people a page: the whole page shows, no scrolling box. */
.table-wrap.support-table-wrap {
  max-height: none;
}

.support-table th:nth-child(1) { width: 25%; }
.support-table th:nth-child(2),
.support-table th:nth-child(3) { width: 14%; }
.support-table th:nth-child(4) { width: 11%; }
.support-table th:nth-child(5) { width: 14%; }
.support-table th:nth-child(6) { width: 15%; }
.support-table th:nth-child(7) { width: 7%; }

.support-row-who strong {
  overflow-wrap: anywhere;
}

.support-table tr.support-row {
  cursor: pointer;
}

.support-table tr.support-row:hover,
.support-table tr.support-row:focus-visible {
  background: var(--color-surface-alt);
}

.support-row-name {
  display: block;
  color: var(--color-text-muted);
  font-size: 0.82rem;
}

.support-badge {
  display: inline-block;
  padding: 0 0.4rem;
  border-radius: var(--radius-sm);
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
  font-size: 0.75rem;
}

.support-badge.is-warning {
  color: var(--color-warning);
  background: var(--color-warning-soft);
  border-color: currentColor;
}

.support-badge.is-danger {
  color: var(--color-danger);
  background: var(--color-danger-soft);
  border-color: currentColor;
}

.support-flags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin-top: 0.2rem;
}

.support-notes-title {
  margin: 1.5rem 0 0.25rem;
  padding-top: 1rem;
  border-top: 1px solid var(--color-border);
  font-size: 1rem;
}

.support-note-form {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
  margin: 0.5rem 0 1rem;
}

.support-note-form textarea {
  width: 100%;
}

.support-notes {
  list-style: none;
  margin: 0;
  padding: 0;
}

.support-notes li {
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--color-border);
}

.support-notes li p {
  margin: 0 0 0.2rem;
  white-space: pre-wrap;
}

.support-pager {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.75rem;
  margin-top: 0.75rem;
  font-size: 0.88rem;
}

.support-pager[hidden] {
  display: none;
}

.support-facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.4rem 1.25rem;
  margin: 1rem 0;
  font-size: 0.9rem;
}

.support-facts dt {
  color: var(--color-text-muted);
}

.support-facts dd {
  margin: 0;
}

.support-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}

form.support-form {
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--color-border);
}

form.support-form[hidden] {
  display: none;
}

form.support-form .section-hint {
  flex-basis: 100%;
  margin: 0;
}

/* Phones: each person is a small card, the figures labeled two to a row. */
@media (max-width: 600px) {
  .support-table,
  .support-table tbody {
    display: block;
  }

  .support-table thead {
    display: none;
  }

  .support-table tbody tr {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.35rem 1rem;
    padding: 0.7rem 0.8rem;
    border-bottom: 1px solid var(--color-border);
  }

  .payee-table.support-table td {
    padding: 0;
    border-bottom: none;
    text-align: left;
  }

  .support-table td.support-row-who,
  .support-table td[colspan] {
    grid-column: 1 / -1;
  }

  .support-table td[data-label]::before {
    content: attr(data-label);
    display: block;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--color-text-muted);
  }
}

@media (max-width: 600px) {
  .support-facts {
    grid-template-columns: 1fr;
    gap: 0.1rem;
  }
  .support-facts dd {
    margin-bottom: 0.4rem;
  }
}

/* ---- Metrics and Team & audit (admins only, admin.js) ------------------------- */

#view-metrics .card {
  position: relative; /* the chart tooltips are positioned inside */
}

.scorecard {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 1rem;
  margin-top: 1rem;
}

.score-tile {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 1rem 1.1rem;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}

.score-tile .stat-label {
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.85rem;
  min-height: 2.4em;
}

.score-value {
  font-size: 1.7rem;
  font-weight: 700;
}

.score-target {
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--color-text-muted);
  margin-left: 0.4rem;
}

.score-meter {
  position: relative;
  height: 8px;
  border-radius: 4px;
  background: var(--color-primary-soft);
}

.score-fill {
  height: 100%;
  border-radius: 4px;
  background: var(--color-primary);
}

.score-fill.is-below {
  background: var(--color-warning);
}

.score-goal {
  position: absolute;
  top: -3px;
  width: 2px;
  height: 14px;
  margin-left: -1px;
  background: var(--color-text);
}

.score-status {
  font-size: 0.85rem;
  font-weight: 600;
}

.score-status.is-good span {
  color: var(--color-success);
}

.score-status.is-below span {
  color: var(--color-warning);
}

.score-status.is-waiting {
  color: var(--color-text-muted);
  font-weight: 500;
}

.score-cohort {
  font-size: 0.78rem;
  color: var(--color-text-muted);
}

.admin-usage {
  margin-top: 1rem;
}

.admin-chart-title {
  font-size: 0.95rem;
  margin: 0.5rem 0 0.25rem;
}

.cashflow-svg .dau-bar {
  fill: var(--color-primary);
}

.funnel {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}

.funnel-row {
  display: grid;
  grid-template-columns: minmax(10rem, 16rem) 1fr;
  align-items: center;
  gap: 0.85rem;
  padding: 0.2rem 0.3rem;
  border-radius: var(--radius-sm);
}

.funnel-row:hover,
.funnel-row:focus-visible {
  background: var(--color-surface-alt);
}

.funnel-label {
  font-size: 0.88rem;
}

.funnel-track {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.funnel-bar {
  height: 20px;
  border-radius: 0 4px 4px 0;
  background: var(--color-primary);
  flex: none; /* width: a share of the track, less room for the value beside it */
}

.funnel-value {
  font-size: 0.85rem;
  font-weight: 600;
  white-space: nowrap;
}

.audit-table td {
  vertical-align: top;
}

@media (max-width: 600px) {
  .funnel-row {
    grid-template-columns: 1fr;
    gap: 0.25rem;
  }
}

/* ---- Invites (admins only) ---------------------------------------------------- */

.nav-item[hidden] {
  display: none;
}

form.invite-form {
  margin-top: 0;
}

#invite-email,
#invite-note {
  width: 16rem;
}

.invite-error[hidden] {
  display: none;
}

/* Scrolls sideways in its .table-wrap on a phone rather than squeezing. */
.invite-table {
  min-width: 46rem;
}

.invite-table th:nth-child(1) { width: 28%; }
.invite-table th:nth-child(2) { width: 20%; }
.invite-table th:nth-child(3) { width: 13%; }
.invite-table th:nth-child(4) { width: 18%; }
.invite-table th:nth-child(5) { width: 21%; }

/* Split transactions (splits.js) */

.split-label {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 600;
  padding: 0.05rem 0.45rem;
  border-radius: 999px;
  background: var(--color-info-soft);
  color: var(--color-info);
}

.split-lines {
  margin-top: 0.15rem;
  font-size: 0.8rem;
}

.split-line {
  display: flex;
  justify-content: space-between;
  gap: 0.75rem;
}

.split-line-amount {
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.split-lines .muted {
  color: var(--color-text-muted);
}

#register-table tbody tr.split-editor-row:hover {
  background: none;
}

/* A narrow register scrolls sideways, and the editor, at the table's right
   edge, would sit out of view with the total's cents cut off. It sticks to
   the visible right edge and fits the visible width instead. */
.table-wrap:has(> #register-table) {
  container-type: inline-size;
}

.split-editor {
  max-width: min(44rem, 100cqw - 1.4rem);
  margin-left: auto;
  position: sticky;
  right: 0.7rem;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
}

.split-editor-head,
.split-editor-line {
  display: grid;
  grid-template-columns: minmax(10rem, 2fr) minmax(6rem, 2fr) 7rem 1.5rem;
  gap: 0.4rem;
  align-items: center;
}

.split-editor-head {
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--color-text-muted);
  padding-bottom: 0.25rem;
}

.split-editor-line {
  padding: 0.15rem 0;
}

/* The Payees page's Rename: a new name, or a payee to merge into (payees.js openPayeeRename). */
.payee-rename-label {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  max-width: 28rem;
}

.payee-rename-remember {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 400;
}

.payee-rename-remember[hidden] {
  display: none;
}

.payee-table .row-actions-cell {
  white-space: nowrap;
}

.payee-table .row-actions-cell .payee-rename-btn {
  margin-right: 0.5rem;
}

/* The import review's payee: Rename, and Make it a rule (import.js renderPayeeCell). */
.import-payee-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0 0.6rem;
  font-size: 0.8rem;
}

.import-payee-input {
  width: 100%;
  min-width: 10rem;
  box-sizing: border-box;
}

/* A line's category, and its business under it (splits.js splitBusinessHtml). */
.split-line-where {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-width: 0;
}

select.split-business[hidden] {
  display: none;
}

#register-table .split-editor-line .split-amount {
  text-align: right;
}

.split-editor button.link-button {
  background: none;
  border: none;
  padding: 0.2rem;
  color: var(--color-primary);
  font-size: 0.82rem;
  cursor: pointer;
}

.split-editor button.split-remove {
  color: var(--color-text-muted);
}

.split-editor button.split-remove:hover {
  color: var(--color-danger);
}

.split-editor-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
  padding-top: 0.35rem;
  font-size: 0.82rem;
}

.split-status {
  color: var(--color-warning);
}

.split-status.split-status-ok {
  color: var(--color-success);
}

@media (max-width: 600px) {
  .split-editor-head {
    display: none;
  }

  .split-editor-line {
    grid-template-columns: 1fr 6.5rem 1.5rem;
  }

  .split-editor-line .split-memo {
    grid-column: 1 / 3;
    grid-row: 2;
  }
}

.split-remember {
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  gap: 0.3rem;
  margin-right: auto;
  font-size: 0.8rem;
  font-weight: 400;
  color: var(--color-text-muted);
}

.split-remember[hidden] {
  display: none;
}

#register-table .split-remember input {
  width: auto;
}

.split-remember span {
  white-space: nowrap;
}

.split-leg-note {
  font-weight: 400;
  opacity: 0.8;
}

/* The Recurring form's split editor takes a row of its own. */
.recurring-split {
  flex-basis: 100%;
}

.recurring-split[hidden] {
  display: none;
}

.recurring-split .split-editor {
  max-width: 48rem;
  margin-left: 0;
}

.recurring-split .split-editor select,
.recurring-split .split-editor input[type="text"] {
  width: 100%;
  font-size: 0.85rem;
  padding: 0.3rem 0.4rem;
}

button.link-button.payee-forget-split {
  margin-left: 0.4rem;
  padding: 0;
  border: none;
  background: none;
  color: var(--color-primary);
  font-size: inherit;
  cursor: pointer;
}

/* Invite emails (invites.js) */

#invite-name {
  width: 11rem;
}

form.invite-form .invite-send {
  flex-direction: row;
  align-items: center;
  gap: 0.35rem;
  align-self: center;
  font-weight: 400;
}

form.invite-form .invite-send input {
  width: auto;
}

.invite-emailed {
  font-size: 0.78rem;
  margin-top: 0.15rem;
}

.invite-table button.link-button.invite-email-btn {
  margin-right: 0.6rem;
  padding: 0;
  border: none;
  background: none;
  color: var(--color-primary);
  font-size: 0.85rem;
  cursor: pointer;
}

.invite-preview {
  margin-top: 0.75rem;
  padding: 0.75rem 1rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface-alt);
  max-width: 44rem;
}

.invite-preview[hidden] {
  display: none;
}

.invite-preview-subject {
  margin: 0 0 0.5rem;
  font-weight: 600;
}

.invite-preview-body {
  margin: 0;
  white-space: pre-wrap;
  font-family: inherit;
  font-size: 0.88rem;
  line-height: 1.5;
}


/* Register: where today falls (register.js buildTodayRow). A band with the
   brand's beacon, not a ruled line; scheduled rows past it are softer. */

#register-table tbody tr.register-today-row td {
  background: var(--color-beacon-soft);
  border-top: 1px solid var(--color-beacon-line);
  border-bottom: 1px solid var(--color-beacon-line);
  padding-top: 0.4rem;
  padding-bottom: 0.4rem;
}

#register-table tbody tr.register-today-row:hover {
  background: none;
}

.today-marker {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.2rem 0.55rem;
  font-size: 0.85rem;
}

.today-beacon {
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  background: var(--color-beacon);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-beacon) 30%, transparent),
              0 0 10px 2px color-mix(in srgb, var(--color-beacon) 45%, transparent);
}

.today-note {
  color: var(--color-text-muted);
  font-size: 0.8rem;
}

/* Register: a value entered by hand sets the balance on its day (register.js buildValueRow). */
#register-table tbody tr.register-value-row td {
  background: var(--color-primary-soft);
  border-top: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
  padding-top: 0.4rem;
  padding-bottom: 0.4rem;
}

#register-table tbody tr.register-value-row td.num {
  font-weight: 700;
  white-space: nowrap;
}

.value-marker {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.2rem 0.55rem;
  font-size: 0.85rem;
}

.value-marker-note {
  color: var(--color-text-muted);
  font-size: 0.8rem;
}

#register-table td.today-balance {
  font-weight: 700;
  white-space: nowrap;
}

#register-table tbody tr.register-row.is-future > td:not(.row-actions-cell) {
  opacity: 0.72;
}

#register-table tbody tr.register-row.is-future > td:first-child {
  font-style: italic;
}

/* Phones: the tab bar along the bottom, the links under the page title, and
   the You page (tabbar.js). Wider screens use the sidebar instead. */

.tabbar,
.subnav {
  display: none;
}

.you-card {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}

.you-name {
  font-weight: 600;
  font-size: 1.05rem;
}

.you-name,
.you-email {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.you-email {
  color: var(--color-text-muted);
  font-size: 0.88rem;
}

.you-heading {
  margin: 1.25rem 0 0.5rem;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}

/* "TallyBeacon is not financial advice." at the foot of Help and You. */
.not-advice {
  margin-top: 1.5rem;
  text-align: center;
}

.card.you-list {
  padding: 0;
  overflow: hidden;
}

.you-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  min-height: 48px;
  padding: 0 1rem;
  background: none;
  border: 0;
  border-top: 1px solid var(--color-border);
  border-radius: 0;
  color: var(--color-text);
  font: inherit;
  font-size: 0.95rem;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

.you-list > .you-row:first-child,
.you-list > .you-row[hidden] + .you-row,
.you-list > .you-row:first-child[hidden] + .you-row {
  border-top: 0;
}

.you-row[hidden] {
  display: none;
}

.you-row::after {
  content: "›";
  color: var(--color-text-muted);
  font-size: 1.2rem;
}

.you-row:hover,
.you-row:focus-visible {
  background: var(--color-surface-alt);
}

.you-row[data-theme-toggle]::after,
.you-row-danger::after {
  content: none;
}

.you-row.you-row-danger {
  color: var(--color-danger);
  font-weight: 500;
}

#you-staff[hidden] {
  display: none;
}

@media (max-width: 800px) {
  /* The sidebar keeps only the logo, as a slim bar; the tab bar takes over. */
  .sidebar {
    padding: 0.6rem 1rem;
    overflow: visible;
    border-right: 0;
    border-bottom: 1px solid var(--color-border);
  }

  .sidebar .nav,
  .sidebar .sidebar-user,
  .sidebar .theme-toggle,
  .sidebar .sidebar-search {
    display: none; /* search: Insights → Search on a phone */
  }

  .tabbar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 30;
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    background: var(--color-surface);
    border-top: 1px solid var(--color-border);
    box-shadow: 0 -2px 10px rgba(16, 24, 40, 0.06);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }

  body.is-setup .tabbar {
    display: none;
  }

  .tab {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.2rem;
    min-height: 58px;
    padding: 0.4rem 0 0.35rem;
    background: none;
    border: 0;
    border-radius: 0;
    color: var(--color-text-muted);
    font: inherit;
    font-size: 0.72rem;
    font-weight: 500;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }

  .tab svg {
    width: 24px;
    height: 24px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  .tab:hover {
    background: none;
    color: var(--color-text);
  }

  .tab.active {
    color: var(--color-primary);
    font-weight: 600;
  }

  .tab:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: -4px;
  }

  /* Room under the page so the tab bar never covers its end. */
  .main-col {
    padding-bottom: calc(58px + env(safe-area-inset-bottom, 0px));
  }

  body.is-setup .main-col {
    padding-bottom: 0;
  }

  .subnav {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-top: 0.8rem;
  }

  .subnav[hidden] {
    display: none;
  }

  .subnav-item {
    min-height: 40px;
    padding: 0 1rem;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-surface);
    color: var(--color-text-muted);
    font: inherit;
    font-size: 0.88rem;
    font-weight: 500;
    cursor: pointer;
  }

  .subnav-item:hover {
    background: var(--color-surface-alt);
    color: var(--color-text);
  }

  .subnav-item.active {
    background: var(--color-primary-soft);
    border-color: var(--color-primary);
    color: var(--color-primary);
  }

  .subnav-back {
    min-height: 40px;
    padding: 0 0.25rem;
    margin-left: -0.25rem;
    background: none;
    border: 0;
    color: var(--color-primary);
    font: inherit;
    font-size: 0.92rem;
    font-weight: 500;
    cursor: pointer;
  }

  .subnav-back:hover {
    background: none;
    text-decoration: underline;
  }
}

/* The demo banner's shorter words, for phones (below). */
.demo-text-short {
  display: none;
}

/* Phones: the tab bar says where you are, so there's no logo bar, and the
   page's header is one compact bar pinned to the top: its title, and the
   other pages under the same tab in one row that scrolls sideways. Its
   description is for wider screens. */
@media (max-width: 800px) {
  html {
    scroll-padding-top: 5.5rem; /* what's scrolled to lands below the pinned header */
  }

  .sidebar {
    display: none;
  }

  .topbar {
    position: sticky;
    top: 0;
    z-index: 25;
    padding-top: 0.6rem;
    padding-bottom: 0.55rem;
  }

  .topbar h1 {
    margin: 0;
    font-size: 1.25rem;
  }

  .topbar .subtitle {
    display: none;
  }

  .subnav {
    flex-wrap: nowrap;
    overflow-x: auto;
    margin: 0.45rem -1.25rem 0;
    padding: 0 1.25rem;
    scrollbar-width: none;
  }

  .subnav::-webkit-scrollbar {
    display: none;
  }

  .subnav-item {
    flex: none;
    min-height: 34px;
    padding: 0 0.85rem;
    font-size: 0.85rem;
    white-space: nowrap;
  }

  /* The demo's banner: one line, its shorter words. */
  .env-banner.is-demo {
    flex-wrap: nowrap;
    justify-content: space-between;
    text-align: left;
    padding: 0.4rem 0.75rem;
    font-size: 0.8rem;
  }

  .env-banner.is-demo button {
    flex: none;
  }

  .demo-text-long {
    display: none;
  }

  .demo-text-short {
    display: inline;
  }
}

/* The phone Register's heading, chips, sheets and + button (register.js):
   wider screens use the toolbar and the add row instead. */
.register-phone-head,
.register-chips,
.register-fab,
.register-tools-done {
  display: none;
}

@media (max-width: 800px) {
  /* The page scrolls the register, not a box of its own. */
  .table-wrap:has(> #register-table) {
    max-height: none;
    overflow: visible;
  }

  .register-phone-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
  }

  .register-account-switch {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    min-width: 0;
    min-height: 44px;
    padding: 0;
    background: none;
    border: 0;
    color: var(--color-text);
    font: inherit;
    font-size: 1.15rem;
    font-weight: 700;
    text-align: left;
    cursor: pointer;
  }

  .register-account-switch:hover {
    background: none;
  }

  #register-account-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .register-account-caret {
    color: var(--color-text-muted);
    font-size: 0.8rem;
  }

  .register-tools-open {
    margin-left: auto;
    flex: none;
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    padding: 0;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    color: var(--color-text-muted);
  }

  .register-tools-open svg {
    width: 20px;
    height: 20px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
  }

  /* The balances on one line: today and projected first, cleared after. */
  #register-balance.balance-line {
    gap: 0.15rem 0.9rem;
    margin-top: 0.35rem;
  }

  #register-balance .balance-figure {
    font-size: 0.9rem;
  }

  #register-balance .balance-figure-label {
    font-size: 0.68rem;
  }

  #register-balance .balance-cleared {
    order: 1;
    color: var(--color-text-muted);
    font-weight: 500;
  }

  .register-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin-top: 0.5rem;
  }

  .register-chip {
    min-height: 30px;
    padding: 0 0.7rem;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-surface-alt);
    color: var(--color-text-muted);
    font: inherit;
    font-size: 0.8rem;
  }

  .register-chip.is-on {
    background: var(--color-primary-soft);
    border-color: transparent;
    color: var(--color-primary);
    font-weight: 600;
  }

  /* The toolbar is a sheet, opened from the search icon or a chip. */
  .register-card .register-toolbar,
  .register-account-field {
    display: none;
  }

  .register-card.is-tools-open .register-toolbar,
  .register-account-sheet {
    position: fixed;
    left: 0;
    right: 0;
    bottom: calc(58px + env(safe-area-inset-bottom, 0px));
    z-index: 41;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0.75rem;
    max-height: 75vh;
    overflow-y: auto;
    padding: 1rem 1.25rem 1.25rem;
    background: var(--color-surface);
    border-radius: 18px 18px 0 0;
    box-shadow: 0 -8px 28px rgba(16, 24, 40, 0.18);
  }

  .register-account-sheet[hidden] {
    display: none;
  }

  .register-card.is-tools-open .register-toolbar #register-search {
    width: 100%;
  }

  .register-tools-done {
    display: block;
  }

  .register-sheet-scrim {
    position: fixed;
    inset: 0;
    z-index: 40;
    background: rgba(15, 23, 42, 0.38);
  }

  .register-sheet-scrim[hidden] {
    display: none;
  }

  body.has-sheet {
    overflow: hidden;
  }

  .register-account-sheet {
    gap: 0;
  }

  #register-account-find {
    width: 100%;
    margin-bottom: 0.5rem;
  }

  .account-pick-group {
    padding: 0.7rem 0.1rem 0.3rem;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--color-text-muted);
  }

  .account-pick {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.75rem;
    width: 100%;
    min-height: 44px;
    padding: 0 0.1rem;
    background: none;
    border: 0;
    border-bottom: 1px solid var(--color-border);
    border-radius: 0;
    color: var(--color-text);
    font: inherit;
    text-align: left;
  }

  .account-pick:hover {
    background: var(--color-surface-alt);
  }

  .account-pick.is-current {
    color: var(--color-primary);
    font-weight: 700;
  }

  .account-pick-balance {
    flex: none;
    color: var(--color-text-muted);
    font-variant-numeric: tabular-nums;
  }

  .account-pick-none {
    color: var(--color-text-muted);
  }

  /* Adding: the + button, and Close only while the add row is open. */
  .register-fab {
    position: fixed;
    right: 1rem;
    bottom: calc(58px + 1rem + env(safe-area-inset-bottom, 0px));
    z-index: 26;
    display: grid;
    place-items: center;
    width: 56px;
    height: 56px;
    padding: 0;
    border-radius: 18px;
    font-size: 1.9rem;
    font-weight: 400;
    line-height: 1;
    box-shadow: 0 6px 16px rgba(37, 99, 235, 0.35);
  }

  .register-fab[hidden] {
    display: none;
  }

  button.register-add-toggle[aria-expanded="false"] {
    display: none;
  }

  /* Room for the rows: a slimmer card, and at its end room so the + button
     never covers the last row's menu. */
  #register-card {
    padding: 0.9rem 0.75rem 5rem;
  }

  .register-card.is-tools-open .register-toolbar > button {
    width: 100%;
    margin-left: 0;
  }

  /* The chips say what's narrowed; the note would repeat it. */
  #register-balance .balance-note {
    display: none;
  }

  /* A transfer's account wraps inside its pill rather than running on. */
  #register-table tr.register-row .transfer-label {
    display: inline;
    white-space: normal;
    -webkit-box-decoration-break: clone;
    box-decoration-break: clone;
  }

}

/* Phones: the Register without sideways scrolling (register.js). Each
   transaction takes two lines, payee and amount over date, category and
   balance, with its memo (and a reconciled mark) on a third when it has one.
   Tapping a row opens its actions. The add and edit rows stack their fields,
   and the add row stays closed until "+ Add a transaction" opens it. */

.register-add-toggle {
  display: none;
}

@media (max-width: 800px) {
  button.register-add-toggle {
    display: block;
    width: 100%;
    min-height: 44px;
    margin-top: 0.9rem;
    background: var(--color-primary-soft);
    color: var(--color-primary);
  }

  button.register-add-toggle:hover {
    background: var(--color-primary-soft);
  }

  button.register-add-toggle[aria-expanded="true"] {
    background: var(--color-surface-alt);
    color: var(--color-text);
    border-color: var(--color-border);
  }

  #register-table,
  #register-table tbody {
    display: block;
  }

  #register-table thead {
    display: none;
  }

  #register-table tbody tr {
    display: block;
  }

  #register-table tbody td {
    display: block;
    border-bottom: 0;
    padding: 0;
  }

  /* One transaction. */
  #register-table tbody tr.register-row {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto 2.75rem;
    grid-template-areas:
      "payee payee amount menu"
      "date  cat   balance menu"
      "memo  memo  status menu";
    column-gap: 0.6rem;
    align-items: baseline;
    padding: 0.6rem 0 0.6rem 0.75rem;
    border-bottom: 1px solid var(--color-border);
    cursor: pointer;
  }

  #register-table tr.register-row > td:nth-child(1) { grid-area: date; }
  #register-table tr.register-row > td:nth-child(2) { grid-area: payee; }
  #register-table tr.register-row > td:nth-child(3) { grid-area: cat; }
  #register-table tr.register-row > td:nth-child(4) { grid-area: memo; }
  #register-table tr.register-row > td:nth-child(5) { grid-area: amount; }
  #register-table tr.register-row > td:nth-child(6) { grid-area: balance; }
  #register-table tr.register-row > td:nth-child(7) { grid-area: status; }
  #register-table tr.register-row > td:nth-child(8) { grid-area: menu; align-self: center; width: auto; }

  #register-table tr.register-row > td:nth-child(2) {
    font-weight: 600;
    font-size: 0.95rem;
    overflow-wrap: anywhere;
  }

  #register-table tr.register-row > td:nth-child(5) {
    font-weight: 600;
    font-size: 0.95rem;
  }

  #register-table tr.register-row > td:nth-child(1),
  #register-table tr.register-row > td:nth-child(3),
  #register-table tr.register-row > td:nth-child(4),
  #register-table tr.register-row > td:nth-child(6) {
    margin-top: 0.15rem;
    font-size: 0.8rem;
    color: var(--color-text-muted);
  }

  /* A long category wraps rather than ending in "…". */
  #register-table tr.register-row > td:nth-child(3) {
    min-width: 0;
    overflow-wrap: break-word;
  }

  #register-table tr.register-row > td:nth-child(6)::before {
    content: "Bal. ";
  }

  #register-table tr.register-row > td.memo-cell {
    max-width: none;
  }

  /* The group headings already say uncleared or cleared: only a reconciled
     mark adds anything. */
  #register-table tr.register-row > td:nth-child(7):not(:has(.status-reconciled)),
  #register-table tr.register-row > td.memo-cell:empty {
    display: none;
  }

  #register-table tr.register-row > td:nth-child(7) {
    margin-top: 0.2rem;
    text-align: right;
  }

  #register-table button.row-menu-btn {
    width: 2.75rem;
    min-height: 44px;
  }

  #register-table tr.register-group-row td {
    padding: 0.4rem 0.75rem;
  }

  /* Today: the marker and today's balance. */
  #register-table tbody tr.register-today-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    background: var(--color-beacon-soft);
    border-top: 1px solid var(--color-beacon-line);
    border-bottom: 1px solid var(--color-beacon-line);
    padding: 0.45rem 0.75rem;
  }

  #register-table tbody tr.register-today-row td {
    border: 0;
    padding: 0;
  }

  #register-table tbody tr.register-today-row td:last-child {
    display: none;
  }

  #register-table tbody tr.register-value-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    background: var(--color-primary-soft);
    padding: 0.45rem 0.75rem;
  }

  #register-table tbody tr.register-value-row td {
    border: 0;
    padding: 0;
    background: none;
  }

  #register-table tbody tr.register-value-row td:last-child {
    display: none;
  }

  /* Adding or editing: the fields stacked, two to a line where they fit. */
  #register-table #register-add-row-body {
    display: none;
  }

  #register-table.is-adding #register-add-row-body {
    display: block;
  }

  #register-table #register-add-row-body tr td {
    position: static;
    box-shadow: none;
  }

  #register-table tbody tr#register-add-row,
  #register-table tbody tr.register-edit-row:not(.register-move-row) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas:
      "date   amount"
      "payee  payee"
      "cat    cat"
      "memo   memo"
      "status actions";
    gap: 0.5rem;
    padding: 0.75rem;
    border-bottom: 1px solid var(--color-border);
  }

  #register-table tbody tr.register-edit-row {
    background: var(--color-primary-soft);
  }

  #register-table tr#register-add-row > td:nth-child(1),
  #register-table tr.register-edit-row > td:nth-child(1) { grid-area: date; }
  #register-table tr#register-add-row > td:nth-child(2),
  #register-table tr.register-edit-row > td:nth-child(2) { grid-area: payee; }
  #register-table tr#register-add-row > td:nth-child(3),
  #register-table tr.register-edit-row > td:nth-child(3) { grid-area: cat; }
  #register-table tr#register-add-row > td:nth-child(4),
  #register-table tr.register-edit-row > td:nth-child(4) { grid-area: memo; }
  #register-table tr#register-add-row > td:nth-child(5),
  #register-table tr.register-edit-row > td:nth-child(5) { grid-area: amount; }
  #register-table tr#register-add-row > td:nth-child(7),
  #register-table tr.register-edit-row > td:nth-child(7) { grid-area: status; }
  #register-table tr#register-add-row > td:nth-child(8),
  #register-table tr.register-edit-row > td:nth-child(8) {
    grid-area: actions;
    display: flex;
    gap: 0.4rem;
    justify-content: flex-end;
    align-items: stretch;
  }

  #register-table tr#register-add-row > td:nth-child(6),
  #register-table tr.register-edit-row:not(.register-move-row) > td:nth-child(6) {
    display: none;
  }

  #register-table tr#register-add-row input,
  #register-table tr#register-add-row select,
  #register-table tr.register-edit-row input,
  #register-table tr.register-edit-row select {
    min-height: 44px;
    font-size: 1rem; /* under 16px, phones zoom in on the field */
    color: var(--color-text);
  }

  #register-table .add-amount-cell {
    display: flex;
    gap: 0.3rem;
  }

  #register-table .add-amount-cell input {
    width: auto;
    flex: 1;
    min-width: 0;
  }

  #register-table tr#register-add-row button,
  #register-table tr.register-edit-row button {
    min-height: 44px;
    flex: 1;
    font-size: 0.9rem;
  }

  #register-table tbody tr.register-move-row {
    padding: 0.75rem;
    background: var(--color-primary-soft);
  }

  #register-table tbody tr.register-move-row td + td {
    display: flex;
    gap: 0.4rem;
    margin-top: 0.6rem;
  }

  #register-table tbody tr.split-editor-row td {
    padding: 0 0.75rem 0.75rem;
  }

  #register-table .split-editor {
    margin-left: 0;
  }
}

/* Phones: tables with set column widths (.payee-table) size their columns
   to what's in them instead, so text never runs into the next column; one
   still too wide scrolls inside its box. Recurring takes a small card per
   series, like Budgets: payee and amount, then when, how often, the account
   and its actions. */
@media (max-width: 800px) {
  .payee-table {
    table-layout: auto;
  }

  .payee-table th {
    width: auto !important;
  }

  .recurring-table,
  .recurring-table tbody {
    display: block;
  }

  .recurring-table thead {
    display: none;
  }

  .recurring-table tbody tr {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas:
      "payee   payee   amount"
      "next    repeats repeats"
      "account account actions";
    gap: 0.2rem 0.6rem;
    align-items: baseline;
    padding: 0.7rem 0.8rem;
    border-bottom: 1px solid var(--color-border);
  }

  .payee-table.recurring-table td {
    padding: 0;
    border-bottom: none;
  }

  .recurring-table td:nth-child(1) { grid-area: next; }
  .recurring-table td:nth-child(2) { grid-area: payee; min-width: 0; }
  .recurring-table td:nth-child(3) { grid-area: account; }
  .recurring-table td:nth-child(4) { grid-area: repeats; }
  .recurring-table td:nth-child(5) { grid-area: amount; font-weight: 600; }
  .recurring-table td:nth-child(6) { grid-area: actions; }

  .recurring-table td:nth-child(1),
  .recurring-table td:nth-child(3),
  .recurring-table td:nth-child(4) {
    font-size: 0.8rem;
    color: var(--color-text-muted);
  }

  .recurring-table td:nth-child(1)::after {
    content: " ·";
  }

  .recurring-table tbody tr td.empty-state {
    grid-column: 1 / -1;
  }

  .recurring-table tbody tr:has(td.empty-state) {
    display: block;
  }

  .recurring-actions button.link-button {
    min-height: 36px;
    padding: 0 0.3rem;
  }
}

/* ---- Help & contact (help.js) ------------------------------------------------- */

.help-links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
  gap: 0.25rem 1rem;
}

.help-links a {
  display: block;
  padding: 0.35rem 0;
  color: var(--color-primary);
  text-decoration: none;
}

.help-links a:hover {
  text-decoration: underline;
}

/* A column, not the row every other form is (form, above). */
.contact-form {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.9rem;
  max-width: 36rem;
}

.contact-form label {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.contact-form select,
.contact-form button {
  align-self: flex-start;
}

.contact-form textarea {
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  font-size: 0.95rem;
  resize: vertical;
}

#contact-form[hidden],
#contact-error[hidden],
#contact-sent[hidden] {
  display: none;
}

.contact-sent {
  margin: 0;
  font-weight: 500;
}

/* ---- Connecting a bank: the consent and "confirm it's you" dialogs (banks.js) ---- */

.checkbox-label.bank-consent-check {
  align-items: flex-start;
  margin: 0.75rem 0 0;
  line-height: 1.45;
}

/* Not the full width every other dialog input gets (.confirm-dialog input). */
.confirm-dialog .bank-consent-check input {
  width: auto;
  margin-top: 0.2rem;
  flex: none;
}

.bank-consent-check span {
  flex: 1;
  font-weight: 400;
}

#bank-verify-form label {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  max-width: 12rem;
}

#bank-verify-error[hidden] {
  display: none;
}

/* Admin console: what banks said when a connection went wrong. */
.bank-sync-errors {
  margin: 0;
  padding-left: 1.1rem;
  font-size: 0.9rem;
}

.bank-sync-errors .num {
  font-weight: 600;
  margin-right: 0.35rem;
}

/* Admin console: the toolbar, what needs attention, section headings, and
   how a period's count compares with the one before (admin.js). */
.metrics-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.25rem;
  margin-bottom: 1rem;
}

.metrics-jump {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.metrics-jump a {
  padding: 0.3rem 0.8rem;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  background: var(--color-surface);
  color: var(--color-text);
  font-size: 0.88rem;
  text-decoration: none;
}

.metrics-jump a:hover,
.metrics-jump a:focus-visible {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

.metrics-period {
  display: flex;
  flex-direction: row; /* labels are columns elsewhere */
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9rem;
}

.metrics-updated {
  margin-left: auto;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.metrics-heading {
  font-size: 1.25rem;
  margin: 2rem 0 0.75rem;
  scroll-margin-top: 1rem;
}

.metrics-heading:focus {
  outline: none;
}

.attention-list {
  list-style: none;
  margin: 0.75rem 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.attention-list[hidden] {
  display: none;
}

.attention-item {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.25rem 0.6rem;
  padding: 0.55rem 0.8rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
  font-size: 0.92rem;
}

.attention-item.is-critical {
  background: var(--color-danger-soft);
  border-color: var(--color-danger);
}

.attention-item.is-warning {
  background: var(--color-warning-soft);
}

.attention-item.is-info {
  background: var(--color-surface-alt);
}

.attention-icon {
  font-size: 0.8rem;
}

/* The text stays beside its icon; "See it" goes under it when there's no room. */
.attention-item > span:not(.attention-icon) {
  flex: 1 1 12rem;
  min-width: 0;
}

@media (max-width: 600px) {
  .admin-usage .stat-tile {
    min-width: 8.5rem; /* two to a row on a phone */
  }
}

.attention-item.is-critical .attention-icon {
  color: var(--color-danger);
}

.attention-item.is-warning .attention-icon {
  color: var(--color-warning);
}

.attention-item.is-info .attention-icon {
  color: var(--color-info);
}

.attention-go {
  margin-left: auto;
  font-size: 0.85rem;
  white-space: nowrap;
}

.stat-delta {
  margin-top: 0.35rem;
  font-size: 0.78rem;
  color: var(--color-text-muted);
}

.stat-delta.is-good {
  color: var(--color-success);
}

.stat-delta.is-bad {
  color: var(--color-danger);
}

/* A target's last 8 weeks (admin.js scoreTrend). */
.score-trend {
  width: 100%;
  height: 36px;
  margin-top: 0.15rem;
}

.score-trend-line {
  fill: none;
  stroke: var(--color-primary);
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
}

.score-trend-target {
  stroke: var(--color-text-muted);
  stroke-dasharray: 3 3;
  vector-effect: non-scaling-stroke;
}

.score-trend-dot {
  fill: var(--color-primary);
}

.score-trend-empty {
  fill: var(--color-text-muted);
  font-size: 11px;
}

.cashflow-svg .bar-bad {
  fill: var(--color-danger);
}

/* payee-table sizes five columns; these have up to six: the first gets a third,
   the rest share what's left. */
.payee-table.ops-table th:nth-child(n) {
  width: auto;
}

.payee-table.ops-table th:first-child {
  width: 34%;
}

.ops-table code {
  font-size: 0.82rem;
  word-break: break-all;
}

.ops-table td.is-bad {
  color: var(--color-danger);
  font-weight: 600;
}

#ops-formats-wrap[hidden] {
  display: none;
}


/* ---- What if… (Overview forecast, whatif.js) ------------------------------------ */

.whatif {
  margin: 0.75rem 0 1rem;
  padding: 0.9rem 1rem;
  border: 1px dashed var(--viz-out);
  border-radius: var(--radius-sm);
}

.whatif[hidden],
.whatif [hidden] {
  display: none;
}

.whatif-top {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.5rem 1rem;
}

.whatif-result {
  flex: 1;
  min-width: 14rem;
  margin: 0;
  font-weight: 600;
}

.whatif-result.is-good { color: var(--color-success); }
.whatif-result.is-warning { color: var(--color-warning); }
.whatif-result.is-danger { color: var(--color-danger); }

.whatif-buttons {
  display: flex;
  gap: 0.5rem;
}

.whatif-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.6rem 0.75rem;
  margin-top: 0.8rem;
}

.whatif-form input[type="number"] {
  width: 7.5rem;
}

.whatif-changes {
  list-style: none;
  margin: 0.8rem 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.whatif-changes li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem 0.75rem;
  font-size: 0.9rem;
}

.whatif-changes li span {
  flex: 1;
  min-width: 12rem;
}

.whatif-hint {
  margin: 0.75rem 0 0;
}

.whatif-key {
  display: inline-block;
  width: 1.4rem;
  vertical-align: middle;
  border-top: 2px dashed var(--viz-out);
}

.whatif-badge {
  color: var(--viz-out);
  font-size: 0.7rem;
  font-weight: 600;
  vertical-align: 1px;
}

/* Struck through, all but the row's own Undo (a line-through can't be
   turned off inside the element that has it). */
#upcoming-table tr.is-whatif-skipped td {
  color: var(--color-text-muted);
}

#upcoming-table tr.is-whatif-skipped td:not(:nth-child(2)),
#upcoming-table tr.is-whatif-skipped td:nth-child(2) > div:not(.whatif-row-actions) {
  text-decoration: line-through;
}

.whatif-row-actions {
  display: flex;
  gap: 0.75rem;
  margin-top: 0.2rem;
}

.whatif-row-actions .link-button {
  font-size: 0.82rem;
}

.cashflow-svg .up-balance-line.is-behind {
  opacity: 0.45;
}

.cashflow-svg .up-whatif-line {
  fill: none;
  stroke: var(--viz-out);
  stroke-width: 2;
  stroke-dasharray: 6 4;
  stroke-linejoin: round;
}

.cashflow-svg .up-whatif-low {
  fill: var(--color-surface);
  stroke: var(--viz-out);
  stroke-width: 2;
}

@media (max-width: 640px) {
  .whatif-form {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: end;
  }

  .whatif-form label {
    min-width: 0;
  }

  .whatif-form input,
  .whatif-form select {
    width: 100%;
    min-width: 0;
  }

  .whatif-form button[type="submit"] {
    grid-column: 1 / -1;
  }
}

/* Making a what-if real: its payee and category, on its own line. */
.whatif-changes li.is-making input[type="text"] {
  width: 15rem;
  max-width: 100%;
}

.whatif-changes li.is-making select {
  max-width: 14rem;
}

/* Payee suggestions under a Payee box (payee-suggest.js): one list,
   floating under whichever box has focus. */
.payee-suggest {
  position: fixed;
  z-index: 60;
  max-width: calc(100vw - 1rem);
  margin: 0;
  padding: 0.25rem 0;
  list-style: none;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
  max-height: 16rem;
  overflow-y: auto;
}

.payee-suggest[hidden] {
  display: none;
}

.payee-suggest li {
  padding: 0.45rem 0.75rem;
  cursor: pointer;
  font-size: 0.95rem;
}

.payee-suggest li:hover,
.payee-suggest li.is-active {
  background: var(--color-primary-soft);
}

/* Type to find a category (category-search.js): the box in the dropdown's
   place, and the list's group names and its "nothing found". */
.category-search {
  width: 100%;
  min-width: 8rem;
  box-sizing: border-box;
}

select[data-searchable][hidden] {
  display: none;
}

.category-suggest {
  max-height: 20rem;
}

.payee-suggest li.category-suggest-group,
.payee-suggest li.category-suggest-none {
  cursor: default;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  background: none;
}

.payee-suggest li.category-suggest-none {
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.9rem;
}

.payee-suggest li[aria-selected="true"] {
  font-weight: 600;
}

/* ---- Rules (rules.js) ------------------------------------------------------------ */

.rules-card {
  margin-bottom: 1.25rem;
}

.rules-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.5rem 1rem;
}

.rules-head > div {
  flex: 1;
  min-width: 16rem;
}

.rule-offer {
  margin: 0.75rem 0;
}

.rule-dialog {
  width: min(640px, calc(100vw - 2rem));
}

.rule-fields {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0 0.75rem;
}

.rule-fields .rule-show-as-label,
.rule-fields .rule-category-label,
.rule-fields .rule-business-label {
  grid-column: 1 / -1;
}

#rule-business-row[hidden] {
  display: none;
}

.rule-fields select,
.rule-fields input {
  width: 100%;
  box-sizing: border-box;
}

.rule-preview {
  margin-top: 0.5rem;
}

.rule-preview[hidden] {
  display: none;
}

.rule-preview-table {
  max-height: 16rem;
  overflow-y: auto;
  margin-top: 0.5rem;
}

/* The dialog's "Also move…" box: a checkbox beside its words, not stretched
   like the dialog's text fields. */
.rule-preview .checkbox-label {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  margin-bottom: 0;
}

.rule-dialog input[type="checkbox"] {
  width: auto;
  margin-top: 0.2rem;
}

.rule-dialog .confirm-dialog-actions {
  margin-top: 1rem;
}

/* ---- Search (search.js) ------------------------------------------------------------ */

.sidebar-search {
  margin: -0.75rem 0 1.25rem;
  padding: 0 0.25rem;
}

.sidebar-search input {
  width: 100%;
  box-sizing: border-box;
}

.search-form {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.6rem 0.75rem;
  align-items: end;
}

.search-form .search-q {
  grid-column: 1 / -1;
}

.search-form input,
.search-form select {
  width: 100%;
  box-sizing: border-box;
  min-width: 0;
}

.search-form-buttons {
  grid-column: 1 / -1;
  display: flex;
  gap: 0.5rem;
}

.search-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.5rem 1rem;
}

.search-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.search-name {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.5rem;
  margin: 0.75rem 0;
}

.search-name[hidden] {
  display: none;
}

.search-months {
  display: flex;
  align-items: flex-end;
  gap: 0.35rem;
  height: 6.5rem;
  margin: 1.5rem 0 0.75rem;
}

.search-months[hidden] {
  display: none;
}

.search-month {
  flex: 1;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  min-width: 0;
}

/* The bar's share of the column above its label. */
.search-month-bar {
  flex: none;
}

.search-month-bar {
  width: 100%;
  max-width: 2.25rem;
  background: var(--viz-out);
  border-radius: 3px 3px 0 0;
}

.search-month-bar.is-in {
  background: var(--viz-in);
}

.search-month-label {
  margin-top: 0.25rem;
  font-size: 0.72rem;
  color: var(--color-text-muted);
  white-space: nowrap;
}

.search-row {
  cursor: pointer;
}

.search-row:hover td,
.search-row:focus td {
  background: var(--color-primary-soft);
}

.saved-searches {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.25rem;
}

#saved-searches-card {
  margin-bottom: 1.25rem;
}

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

/* ---- Taxes (tax.js) ---------------------------------------------------------------- */


.tax-form {
  margin: 1.25rem 0 0.5rem;
  font-size: 1rem;
}

.tax-table td {
  vertical-align: top;
}

/* Inside the cell: a cell that's itself a flex box loses its table layout. */
.tax-cats {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 0.75rem;
}

.tax-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.15rem;
}

/* A name long enough to wrap stays on the left: buttons centre their text by default. */
.tax-chip,
.tax-chip .link-button,
button.link-button.tax-need-name {
  text-align: left;
}

.tax-chip-remove {
  color: var(--color-text-muted);
  font-size: 0.8rem;
}

/* With more than one business: whose a business category is, wherever it shows (app.js categoryPathHtml). */
.business-badge {
  display: inline-block;
  margin-left: 0.35rem;
  padding: 0 0.4rem;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  color: var(--color-text-muted);
  font-size: 0.75rem;
  font-weight: 500;
  white-space: nowrap;
  vertical-align: 0.05em;
}

.business-badge.is-missing {
  border-color: var(--color-warning);
  color: var(--color-text);
}

/* The account's business, in its Edit (app.js openEditAccount). */
.edit-account-business {
  display: block;
  margin-top: 0.75rem;
}

.edit-account-business[hidden] {
  display: none;
}

.edit-account-business select {
  display: block;
  width: 100%;
  margin-top: 0.3rem;
}

#recurring-business-row[hidden] {
  display: none;
}

/* The register's business picker, under the category (register.js). */
select.row-business {
  display: block;
  width: 100%;
  margin-top: 0.3rem;
}

select.row-business[hidden] {
  display: none;
}

/* The Categories page has a picker for it; the badge is for view-only access, which hides the picker. */
body:not(.view-only) .category-business-badge {
  display: none;
}

/* Business mode (business.js): each Schedule C line's number, and the totals under the parts. */
.business-line-no {
  display: inline-block;
  min-width: 2.25rem;
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

.business-totals {
  margin-top: 1rem;
}

/* A line's note sits under its name, past the number. */
.business-totals td:first-child .upcoming-detail,
.business-table td:first-child .upcoming-detail {
  padding-left: 2.25rem;
}

.business-totals tr:last-child td {
  border-top: 2px solid var(--color-border);
}

#business-body > .section-hint {
  margin-top: 0.75rem;
}

/* Inventory and the home office for the year shown (business.js renderBusinessYear). */
.business-year {
  margin-top: 1rem;
}

/* The mileage log's totals: clear of its heading, not pulled up into it (.section-hint's negative margin). */
#business-miles > .section-hint {
  margin-top: 0.5rem;
}

/* The vehicles and trips tables have seven columns, not the payee table's five:
   their own widths, or the last two get none and the table scrolls sideways. */
#business-vehicles-wrap .payee-table th:nth-child(1) { width: 18%; }
#business-vehicles-wrap .payee-table th:nth-child(2) { width: 15%; }
#business-vehicles-wrap .payee-table th:nth-child(3),
#business-vehicles-wrap .payee-table th:nth-child(4) { width: 14%; }
#business-vehicles-wrap .payee-table th:nth-child(5) { width: 12%; }
#business-vehicles-wrap .payee-table th:nth-child(6) { width: 13%; }
#business-vehicles-wrap .payee-table th:nth-child(7) { width: 14%; }
#business-trips-wrap .payee-table th:nth-child(1) { width: 15%; }
#business-trips-wrap .payee-table th:nth-child(2) { width: 25%; }
#business-trips-wrap .payee-table th:nth-child(3) { width: 18%; }
#business-trips-wrap .payee-table th:nth-child(4) { width: 14%; }
#business-trips-wrap .payee-table th:nth-child(5) { width: 8%; }
#business-trips-wrap .payee-table th:nth-child(6) { width: 10%; }
#business-trips-wrap .payee-table th:nth-child(7) { width: 10%; }

.business-year summary {
  cursor: pointer;
  font-weight: 600;
}

.business-year-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.75rem 1.5rem;
  margin-top: 0.75rem;
}

.business-year-form fieldset {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  margin: 0;
  padding: 0;
  border: 0;
}

.business-year-form legend {
  flex-basis: 100%;
  margin-bottom: 0.25rem;
  font-weight: 600;
}

#business-office-sqft-row[hidden],
#business-office-amount-row[hidden],
#estax-share-row[hidden],
#estax-fixed-row[hidden],
#estax-off[hidden] {
  display: none;
}

#estax-card {
  margin-top: 1rem;
}

.estax-summary {
  margin: 0.5rem 0 0.75rem;
}

/* Clear of the form above, not pulled up into it (.section-hint's negative margin). */
#estax-card > .section-hint {
  margin-top: 1rem;
}

.business-unassigned {
  margin-top: 1.25rem;
}

.business-unassigned[hidden] {
  display: none;
}

.business-unassigned-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.75rem;
  margin: 0.5rem 0;
}

/* Fixed layout, as payee tables are: a narrow tick column, the rest shared. */
.payee-table.business-unassigned-table th:nth-child(1) { width: 2.25rem; }
.payee-table.business-unassigned-table th:nth-child(2) { width: 14%; }
.payee-table.business-unassigned-table th:nth-child(3) { width: 22%; }
.payee-table.business-unassigned-table th:nth-child(4) { width: 18%; }
.payee-table.business-unassigned-table th:nth-child(5) { width: auto; }
.payee-table.business-unassigned-table th:nth-child(6) { width: 16%; }

.business-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.business-list[hidden],
#business-which-field[hidden],
.tax-add#business-move[hidden] {
  display: none;
}

.business-list-name {
  font-weight: 600;
}

.business-list-actions {
  display: flex;
  gap: 0.75rem;
}

.tax-needs[hidden] {
  display: none;
}

.tax-need-why {
  display: block;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.tax-needs-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.tax-needs-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.35rem 0.75rem;
}

.tax-add {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.6rem 0.75rem;
  margin-top: 1.25rem;
  padding-top: 1rem;
  border-top: 1px solid var(--color-border);
}

.tax-add select {
  max-width: 100%;
}

@media (max-width: 640px) {
  .tax-add {
    flex-direction: column;
    align-items: stretch;
  }

  .tax-add select {
    width: 100%;
  }
}

/* A value entered by hand for an asset, investment or loan (app.js). */
.value-dialog {
  max-width: 28rem;
}

.value-fields {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 0 0.75rem;
}

/* The rate is a few digits; the category takes the rest, however long its name. */
.value-fields.loan-fields {
  grid-template-columns: 6.5rem minmax(0, 1fr);
}

.value-dialog select {
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
}

@media (max-width: 480px) {
  .value-fields,
  .value-fields.loan-fields {
    grid-template-columns: minmax(0, 1fr);
  }

  .value-fields.loan-fields input {
    max-width: 8rem;
  }
}

.value-history {
  margin-top: 1.1rem;
  border-top: 1px solid var(--color-border);
  padding-top: 0.8rem;
}

.value-history-title {
  font-size: 0.85rem;
  font-weight: 600;
  margin: 0 0 0.4rem;
}

.value-history ul {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 12rem;
  overflow-y: auto;
}

.value-history li {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 0 0.75rem;
  align-items: baseline;
  padding: 0.3rem 0;
  font-size: 0.9rem;
}

.value-history-amount {
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.value-history-note {
  grid-column: 1 / 3;
  font-size: 0.8rem;
}

.value-history-note:empty {
  display: none;
}

.value-history li button {
  grid-column: 3;
  grid-row: 1;
}

/* A checkbox in a dialog keeps its own size (.confirm-dialog input is full width). */
.confirm-dialog .checkbox-label {
  align-items: flex-start;
  gap: 0.5rem;
  font-weight: 400;
  font-size: 0.88rem;
}

.confirm-dialog .checkbox-label input {
  width: auto;
  flex: none;
  margin-top: 0.2rem;
}

/* Principal filed under a category, moved into a loan (app.js). */
.principal-dialog {
  width: min(560px, calc(100vw - 2rem));
}

.principal-list {
  list-style: none;
  margin: 0 0 0.9rem;
  padding: 0;
  max-height: 16rem;
  overflow-y: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}

.principal-list li {
  border-bottom: 1px solid var(--color-border);
  padding: 0.35rem 0.6rem;
}

.principal-list li:last-child {
  border-bottom: 0;
}

.principal-list .checkbox-label {
  display: grid;
  grid-template-columns: auto 7.5rem minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 0.6rem;
  margin: 0;
}

.principal-list .muted {
  color: var(--color-text-muted);
}

.principal-payee {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.principal-amount {
  font-variant-numeric: tabular-nums;
}

@media (max-width: 480px) {
  .principal-list .checkbox-label {
    grid-template-columns: auto minmax(0, 1fr) auto;
  }

  .principal-payee {
    grid-column: 2 / 4;
    grid-row: 2;
  }
}

/* An account card's ⋯ menu, in its top corner (app.js openAccountMenu). */
.account-card {
  position: relative;
}

button.account-menu-btn {
  position: absolute;
  top: 0.6rem;
  right: 0.6rem;
}

.account-card .account-name {
  padding-right: 1.8rem; /* clear of the menu button */
}

/* Loan details: the next payment and payoff (app.js loanNextText). */
.loan-next {
  font-size: 0.9rem;
}

/* Set up payments (app.js). */
.setup-pay-dialog {
  width: min(520px, calc(100vw - 2rem));
}

.setup-pay-escrow {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  margin: 0 0 0.8rem;
  padding: 0.6rem 0.8rem 0;
}

.setup-pay-escrow legend {
  font-size: 0.85rem;
  padding: 0 0.3rem;
  color: var(--color-text-muted);
}

.setup-pay-preview {
  background: var(--color-primary-soft);
  border-radius: var(--radius-sm);
  padding: 0.6rem 0.8rem;
  font-size: 0.9rem;
  margin-bottom: 0.8rem;
}

.setup-pay-preview.is-warning {
  background: var(--color-beacon-soft);
}

.setup-pay-why {
  display: block;
  margin-top: 0.25rem;
  color: var(--color-text-muted);
  font-size: 0.82rem;
}

/* A loan payment the app split: why (splits.js). */
.split-note {
  margin-top: 0.2rem;
  font-size: 0.75rem;
  color: var(--color-text-muted);
}

/* Set up payments: payments found in the register (app.js renderSetupFound). */
.setup-pay-found {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: 0.6rem 0.8rem;
  margin-bottom: 0.8rem;
}

.setup-pay-found-title {
  font-size: 0.85rem;
  font-weight: 600;
  margin-bottom: 0.4rem;
}

.setup-pay-found ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.setup-pay-found li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  font-size: 0.88rem;
  padding: 0.25rem 0;
}

.setup-pay-found li button {
  flex: none;
  padding: 0.35rem 0.75rem;
  font-size: 0.82rem;
}

.setup-pay-found .confirm-dialog-note {
  margin: 0.4rem 0 0;
}

/* A change that can be undone (app.js showUndoToast). */
.undo-toast {
  position: fixed;
  left: 50%;
  bottom: 1.25rem;
  transform: translateX(-50%);
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 0.9rem;
  width: max-content;
  max-width: min(560px, calc(100vw - 2rem));
  box-sizing: border-box;
  padding: 0.7rem 0.9rem 0.7rem 1rem;
  background: var(--color-text);
  color: var(--color-surface);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  font-size: 0.9rem;
}

.undo-toast[hidden] {
  display: none;
}

.undo-toast .link-button {
  color: inherit;
  font-weight: 700;
  text-decoration: underline;
  flex: none;
}

button.undo-toast-close {
  background: none;
  color: inherit;
  border: 0;
  padding: 0 0.2rem;
  font-size: 1.1rem;
  line-height: 1;
  opacity: 0.8;
  flex: none;
}

@media (max-width: 800px) {
  .undo-toast {
    left: 1rem;
    right: 1rem;
    transform: none;
    width: auto;
    max-width: none;
    bottom: calc(4.5rem + env(safe-area-inset-bottom, 0px)); /* above the tab bar */
  }

  .undo-toast > span {
    flex: 1;
  }
}

/* A one-time offer to add a passkey, on the Overview (webapp.js). */
.passkey-offer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1rem;
  border-left: 4px solid var(--color-beacon);
  margin-bottom: 1.25rem; /* as the Overview's other cards */
}

.passkey-offer p {
  margin: 0;
  flex: 1 1 18rem;
}

.passkey-offer-actions {
  display: flex;
  gap: 0.5rem;
}

.passkey-offer .warning {
  flex-basis: 100%;
}

/* Shown and hidden from webapp.js: the display rules above would otherwise
   win over [hidden], leaving the card up for everyone and Not now doing nothing. */
.passkey-offer[hidden],
.passkey-offer-actions[hidden] {
  display: none;
}

/* Moving everything over from another finance app (switch.js). */
.switch-card {
  margin-bottom: 1.25rem;
  border-left: 4px solid var(--color-primary);
}

.switch-how {
  margin: 0 0 0.9rem;
  font-size: 0.9rem;
}

.switch-how summary {
  cursor: pointer;
  color: var(--color-primary);
  font-weight: 600;
}

.switch-how ol {
  margin: 0.5rem 0 0;
  padding-left: 1.3rem;
}

.switch-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.75rem;
}

.switch-accounts {
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}

.switch-accounts > li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0.4rem 1rem;
  align-items: center;
  padding: 0.7rem 0.9rem;
  border-bottom: 1px solid var(--color-border);
}

.switch-accounts > li:last-child {
  border-bottom: 0;
}

.switch-accounts > li.is-left-out .switch-into,
.switch-accounts > li.is-left-out .switch-balance {
  opacity: 0.45;
}

.switch-include .muted {
  display: block;
  font-size: 0.82rem;
}

.switch-accounts .muted {
  color: var(--color-text-muted);
  font-weight: 400;
}

.switch-balance {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  text-align: right;
}

.switch-into {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: 0 0.75rem;
  padding-left: 1.6rem; /* under the name, past the checkbox */
}

.switch-into label {
  font-size: 0.85rem;
  margin: 0;
}

.switch-into label[hidden] {
  display: none;
}

.switch-into select,
.switch-into input {
  min-width: 0;
  max-width: 100%;
}

/* Under the export steps: whose names those are (app.html). */
.switch-trademarks {
  font-size: 0.78rem;
  color: var(--color-text-muted);
}

.switch-differs {
  grid-column: 1 / -1;
  font-size: 0.82rem;
  color: var(--color-text-muted);
}

/* Going into an account already here: what it has already (switch.js showAlreadyHere). */
.switch-already {
  grid-column: 1 / -1;
  padding-left: 1.6rem; /* under the name, past the checkbox */
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.switch-already[hidden] {
  display: none;
}

.switch-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
}

@media (max-width: 480px) {
  .switch-into {
    padding-left: 0;
  }

  .switch-into label {
    flex: 1 1 100%;
  }

  .switch-into select,
  .switch-into input {
    width: 100%;
    box-sizing: border-box;
  }
}

/* The switch wizard: a CSV file's categories, and a new account's balance today (switch.js). */
.switch-subhead {
  font-size: 1rem;
  margin: 0.4rem 0 0.2rem;
}

.switch-categories > li {
  grid-template-columns: minmax(0, 1fr) minmax(0, 18rem);
}

.switch-category-choice {
  margin: 0;
}

.switch-category-choice select {
  width: 100%;
  box-sizing: border-box;
}

.switch-categories .muted {
  font-size: 0.82rem;
}

@media (max-width: 480px) {
  .switch-categories > li {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ---- The sidebar's account row and its menu (settings.js) ------------------- */

.sidebar-user {
  position: relative;
  padding: 0.75rem 0 0;
}

.me-button {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  padding: 0.45rem 0.5rem;
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--color-text);
  text-align: left;
  cursor: pointer;
}

.me-button:hover,
.me-button[aria-expanded="true"] {
  background: var(--color-surface-alt);
}

.me-avatar {
  display: grid;
  place-items: center;
  flex: none;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: var(--color-primary-soft);
  color: var(--color-primary);
  font-size: 0.78rem;
  font-weight: 700;
}

.me-avatar {
  overflow: hidden;
}

.me-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Profile picture on Profile: the sidebar's avatar, bigger. */
.me-avatar.profile-photo {
  width: 3.5rem;
  height: 3.5rem;
  font-size: 1.1rem;
}

.settings-row.profile-photo-row {
  justify-content: flex-start;
  gap: 1rem;
}

.profile-photo-text {
  flex: 1;
  min-width: 0;
}

.profile-photo-actions {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

/* Side by side: not pushed apart like a row's lone button (.settings-row button). */
.settings-row .profile-photo-actions button {
  margin-left: 0;
}

/* Phones: the buttons on a line of their own, under the picture. */
@media (max-width: 600px) {
  .settings-row.profile-photo-row {
    flex-wrap: wrap;
  }

  .profile-photo-actions {
    flex-basis: 100%;
    justify-content: flex-start;
    padding-left: 4.5rem; /* under the words, past the picture */
  }
}

.me-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1;
}

.me-text .sidebar-plan {
  margin-top: 0;
}

.me-chevron {
  flex: none;
  width: 1rem;
  height: 1rem;
  fill: none;
  stroke: var(--color-text-muted);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.me-menu {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(100% + 0.35rem);
  z-index: 40;
  display: flex;
  flex-direction: column;
  padding: 0.35rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
}

.me-menu[hidden],
.me-menu button[hidden] {
  display: none;
}

.me-menu-email {
  padding: 0.35rem 0.6rem 0.5rem;
  margin-bottom: 0.25rem;
  border-bottom: 1px solid var(--color-border);
  color: var(--color-text-muted);
  font-size: 0.78rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.me-menu button {
  padding: 0.5rem 0.6rem;
  background: none;
  border: 0;
  border-radius: 6px;
  color: var(--color-text);
  font-size: 0.88rem;
  text-align: left;
  cursor: pointer;
}

.me-menu button:hover,
.me-menu button:focus-visible {
  background: var(--color-surface-alt);
}

.me-menu .me-menu-logout {
  margin-top: 0.25rem;
  border-top: 1px solid var(--color-border);
  border-radius: 0 0 6px 6px;
  color: var(--color-danger);
}

/* ---- Profile & settings (the You page) --------------------------------------- */

#view-you {
  max-width: 46rem;
}

.card.settings-card {
  padding: 0;
  overflow: hidden;
}

.settings-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin: 0;
  padding: 0.85rem 1rem;
  border-top: 1px solid var(--color-border);
}

.settings-card > :first-child {
  border-top: 0;
}

.settings-row[hidden] {
  display: none;
}

.settings-label {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--color-text-muted);
}

.settings-value {
  font-size: 0.95rem;
  overflow-wrap: anywhere;
}

.settings-text {
  font-size: 0.92rem;
  color: var(--color-text);
}

.settings-field {
  flex: 1;
  max-width: 22rem;
  font-weight: 600;
  font-size: 0.78rem;
}

/* Left-aligned, the button pushed right: "space-between" centres a lone item
   once a row wraps on a phone. */
form.settings-row {
  justify-content: flex-start;
}

.settings-row button,
.settings-row .button-link {
  flex: none;
  margin-left: auto;
}

.settings-row .button-link {
  margin-left: 0;
}

label.settings-check {
  flex-direction: row;
  font-weight: 400;
  cursor: pointer;
}

.settings-check input {
  flex: none;
  width: 1.1rem;
  height: 1.1rem;
}

.settings-note {
  margin: 0;
  padding: 0.6rem 1rem 0.85rem;
  border-top: 1px solid var(--color-border);
  font-size: 0.82rem;
  color: var(--color-text-muted);
}

.settings-error {
  margin: 0 1rem 0.75rem;
}

.settings-delete {
  margin-top: 1.5rem;
  text-align: center;
}

/* Phones get the sidebar's other pages here; wider screens have the sidebar. */
.you-phone-only {
  display: none;
}

@media (max-width: 800px) {
  .you-phone-only {
    display: block;
  }

  .settings-row {
    flex-wrap: wrap;
  }

  /* Phones stack forms in a centred column elsewhere; these stay a row. */
  #view-you form.settings-row {
    flex-direction: row;
    align-items: flex-end;
  }

  #view-you .settings-field {
    max-width: none;
  }
}

/* Changing your email or password: a short form under its row (settings.js). */
.settings-panel {
  padding: 0 1rem 1rem;
}

.settings-panel[hidden],
.settings-form[hidden] {
  display: none;
}

.settings-form {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.75rem;
  max-width: 22rem;
}

.settings-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.settings-hint {
  margin: 0;
  font-size: 0.82rem;
  color: var(--color-text-muted);
}

.settings-hint[hidden] {
  display: none;
}

.settings-panel .settings-error {
  margin: 0.75rem 0 0;
}

.settings-done {
  margin: 0;
  padding: 0.75rem 1rem;
  border-top: 1px solid var(--color-border);
  background: var(--color-primary-soft);
  font-size: 0.88rem;
}

.settings-done[hidden] {
  display: none;
}

/* ---- Investments (investments.js) ---------------------------------------------------- */

/* Free hides the period, as Taxes hides its year. */
.cashflow-controls[hidden] {
  display: none;
}

.inv-empty-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.inv-account-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.25rem 1rem;
  margin-bottom: 0.75rem;
}

.inv-account-head .section-title {
  margin: 0;
}

.inv-account-value {
  font-size: 1.25rem;
  font-weight: 700;
}

.inv-holdings-table,
.inv-perf-table {
  margin-top: 0.75rem;
}

.inv-holdings-table td,
.inv-perf-table td {
  vertical-align: top;
}

.payee-table.inv-holdings-table th:nth-child(1) { width: 52%; }
.payee-table.inv-holdings-table th:nth-child(2),
.payee-table.inv-holdings-table th:nth-child(3) { width: 24%; }
.payee-table.inv-perf-table th:nth-child(1) { width: 40%; }
.payee-table.inv-perf-table th:nth-child(n+2) { width: 20%; }

.inv-price-btn {
  display: block;
  text-align: left;
  margin-top: 0.2rem;
  font-size: 0.82rem;
}

.inv-positive {
  color: var(--color-success);
}

.inv-negative {
  color: var(--color-danger);
}

/* Phones: "Put in" goes under the account's name, so the numbers fit. */
.inv-put-phone {
  display: none;
}

@media (max-width: 640px) {
  .inv-perf-table th:nth-child(2),
  .inv-perf-table td:nth-child(2) {
    display: none;
  }

  .inv-put-phone {
    display: block;
  }

  .payee-table.inv-perf-table th:nth-child(1) { width: 44%; }
  .payee-table.inv-perf-table th:nth-child(n+3) { width: 28%; }
}

/* Trades (investments.js): each account's list, and the dialog. */
.inv-add-trade {
  margin-top: 0.75rem;
}

.inv-trades {
  margin-top: 0.75rem;
}

.inv-trades > summary {
  cursor: pointer;
  font-weight: 600;
}

.inv-trades-wrap {
  margin-top: 0.5rem;
}

.inv-trades-table td {
  vertical-align: top;
}

.payee-table.inv-trades-table th:nth-child(1) { width: 18%; }
.payee-table.inv-trades-table th:nth-child(2) { width: 44%; }
.payee-table.inv-trades-table th:nth-child(3) { width: 18%; }
.payee-table.inv-trades-table th:nth-child(4) { width: 20%; }

.inv-trade-actions {
  text-align: right;
  white-space: nowrap;
}

.inv-trade-actions .link-button + .link-button {
  margin-left: 0.6rem;
}

/* Fields the kind of trade doesn't take (investments.js TRADE_FIELDS). */
.trade-dialog [data-trade-field][hidden],
.trade-dialog .value-fields[hidden] {
  display: none;
}

@media (max-width: 640px) {
  .payee-table.inv-trades-table th:nth-child(1) { width: 22%; }
  .payee-table.inv-trades-table th:nth-child(2) { width: 38%; }
  .payee-table.inv-trades-table th:nth-child(3) { width: 24%; }
  .payee-table.inv-trades-table th:nth-child(4) { width: 16%; }

  .inv-trade-actions {
    white-space: normal;
  }

  .inv-trade-actions .link-button {
    display: block;
    margin: 0 0 0.3rem auto;
  }

  .inv-trade-actions .link-button + .link-button {
    margin-left: auto;
  }
}

/* Value over time (investments.js renderInvChart): the value as the net worth
   line, what was put in as a dashed muted line under it. */
.inv-perf-card {
  position: relative; /* the chart's tooltip is positioned inside it */
}

.inv-chart-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1rem;
}

.inv-chart-pick[hidden] {
  display: none;
}

.inv-chart-pick {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.legend-line.inv-value-key { background: var(--viz-balance); }
.legend-line.inv-put-key,
.chart-tooltip-key.inv-put {
  background: none;
  border-top: 2px dashed var(--color-text-muted);
  height: 0;
}

.cashflow-svg .inv-put-line {
  fill: none;
  stroke: var(--color-text-muted);
  stroke-width: 2;
  stroke-dasharray: 5 4;
  stroke-linejoin: round;
}

/* A holding's links: Update price, and its name and ticker. */
.inv-holding-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0 0.9rem;
}

.inv-holding-actions .inv-price-btn {
  display: inline;
}

.inv-label-btn {
  margin-top: 0.2rem;
  font-size: 0.82rem;
}

/* Taxes: sales of investments (tax.js renderTaxSales). */
/* The note under Each sale: clear of it, folded or open (.section-hint's
   negative top margin pulled it up against both). */
.tax-sales details + .section-hint {
  margin-top: 1rem;
}

.tax-sales[hidden] {
  display: none;
}

.tax-sales-table td {
  vertical-align: top;
}

/* Edit account: an investment account's tax-deferred and unvested settings. */
.edit-account-flags {
  display: grid;
  gap: 0.5rem;
  margin: 0.75rem 0;
}

.edit-account-flags[hidden] {
  display: none;
}

.edit-account-flags .muted {
  color: var(--color-text-muted);
}

/* Unvested shares (RSUs): marked, and left out of net worth. */
.account-type-badge.is-unvested {
  background: var(--color-warning-soft);
  color: var(--color-warning);
}

.inv-perf-unvested {
  margin: 0.75rem 0 0;
}

/* An investment account's tax-deferred / unvested badges, beside its name. */
.inv-account-head .account-type-badge {
  vertical-align: middle;
}

/* What follows it isn't pulled up into it (.section-hint's negative margin). */
.inv-account-head + .section-hint,
.inv-bank + .section-hint {
  margin-top: 0;
}

/* The account cards sit in their own box, so the gap between cards
   (.card + .card) doesn't reach the first one. */
#inv-accounts > .card:first-child {
  margin-top: 1.25rem;
}

/* A bank's fund that matches nothing here: in the review and on the card. */
.row-check,
.inv-bank-check {
  font-size: 0.85rem;
  color: var(--color-warning);
}

.inv-bank-check {
  flex-basis: 100%;
  margin: 0;
}

/* Synced from a bank: what's waiting there, with its review. */
.inv-bank {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
  margin: 0 0 0.75rem;
  font-size: 0.9rem;
}

/* Phones: a total's proceeds and cost go under its label, so the gain fits. */
.tax-sales-phone {
  display: none;
}

.payee-table.tax-each-sale th:nth-child(1) { width: 22%; }
.payee-table.tax-each-sale th:nth-child(2) { width: 34%; }
.payee-table.tax-each-sale th:nth-child(3) { width: 18%; }
.payee-table.tax-each-sale th:nth-child(4) { width: 26%; }

.tax-nowrap {
  white-space: nowrap;
}

@media (max-width: 640px) {
  .tax-sales-table th:nth-child(2), .tax-sales-table td:nth-child(2),
  .tax-sales-table th:nth-child(3), .tax-sales-table td:nth-child(3),
  .tax-each-sale th:nth-child(3), .tax-each-sale td:nth-child(3) {
    display: none;
  }

  .payee-table.tax-each-sale th:nth-child(1) { width: 30%; }
  .payee-table.tax-each-sale th:nth-child(2) { width: 36%; }
  .payee-table.tax-each-sale th:nth-child(4) { width: 34%; }

  .tax-nowrap {
    white-space: normal;
  }

  .tax-sales-phone {
    display: block;
  }
}

/* You → Household (household.js): the invite's email and access side by
   side, wrapping on a phone. */
form.settings-row.household-invite-form {
  flex-wrap: wrap;
  align-items: flex-end;
}

.household-invite-form select {
  width: 100%;
}

/* Plaid Link (banks.js) on a phone: Plaid's script lays its window over the
   page with a <style> it adds while Link is open, which the
   Content-Security-Policy (style-src 'self') refuses. Without it Link sat in
   the page at an iframe's default 300x150, too small to enter a code. The same
   rules here; Plaid sets this id on <html> only while Link is showing. */
html#plaid-link-temporary-id,
html#plaid-link-temporary-id > body {
  overflow: hidden !important;
}

html#plaid-link-temporary-id > body > .plaid-link-iframe {
  display: flex !important;
  position: fixed !important;
  top: 0 !important;
  left: 0 !important;
  right: 0 !important;
  bottom: 0 !important;
  border: 0 !important;
  overflow: auto !important;
  height: 100% !important;
  width: 100% !important;
  z-index: 2147483647 !important;
  background-color: rgba(17, 17, 18, 0.16) !important;
}

/* ---- The Overview's order (#4) and accounts by kind (#5) ----------------------- */

/* The forecast's sentence when it only repeats Safe to spend's lowest point. */
#view-overview:has(#safe-card:not([hidden])) #forecast-headline.is-plain {
  display: none;
}

/* Wide screens: the answer and what needs doing on the left, the accounts on
   the right; the forecast below, full width. */
@media (min-width: 1200px) {
  .overview-top {
    display: grid;
    grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
    gap: 0 1.5rem;
    align-items: start;
  }
}

/* Narrower: one column, in the order that matters -- the answer, what needs
   doing, the forecast, then the accounts (the Accounts tab lists them all). */
@media (max-width: 1199px) {
  .overview-top {
    display: flex;
    flex-direction: column;
  }

  .overview-col {
    display: contents;
  }

  .ov-answer { order: 1; }
  .overview-attention { order: 2; }
  .ov-forecast { order: 3; }
  .overview-top > .overview-col-b > .accounts-card { order: 4; }
}

/* "Needs attention": shown only over something there. */
.overview-attention-title {
  display: none;
  margin: 0.25rem 0 0.75rem;
  font-size: 1.05rem;
  font-weight: 700;
}

.overview-attention:has(.overview-alerts .forecast-headline:not([hidden]), #tax-season:not([hidden]),
    #paydue-card:not([hidden]), #billplan-card:not([hidden])) .overview-attention-title {
  display: block;
}

.accounts-card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}

.account-groups {
  display: grid;
  margin-top: 0.5rem;
}

.account-favorites {
  padding-bottom: 0.25rem;
}

.account-group {
  border-top: 1px solid var(--color-border);
}

.account-favorites + .account-group,
.account-group:first-child {
  border-top: 0;
}

.account-favorites + .account-group {
  border-top: 1px solid var(--color-border);
}

.account-group-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.7rem 2.6rem 0.7rem 0.25rem; /* its total over its accounts' balances, clear of their ⋯ */
  font-weight: 700;
}

summary.account-group-head {
  cursor: pointer;
  list-style: none;
}

summary.account-group-head::-webkit-details-marker {
  display: none;
}

summary.account-group-head .account-group-name::before {
  content: "▸";
  display: inline-block;
  width: 1.1rem;
  color: var(--color-text-muted);
  font-size: 0.8rem;
}

details[open] > summary.account-group-head .account-group-name::before {
  content: "▾";
}

.account-group-count {
  margin-left: 0.4rem;
  color: var(--color-text-muted);
  font-size: 0.82rem;
  font-weight: 500;
}

.account-group-total,
.account-row-balance {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.account-group-total.negative,
.account-row-balance.negative {
  color: var(--color-danger);
}

.account-row {
  display: flex;
  align-items: center;
  border-top: 1px solid var(--color-border);
}

/* In the row, not in a card's corner. */
.account-row button.account-menu-btn {
  position: static;
  flex: none;
}

.account-favorites .account-row:first-child {
  border-top: 0;
}

button.account-row-open {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  min-height: 44px;
  padding: 0.4rem 0.25rem 0.4rem 1.35rem;
  background: none;
  border: 0;
  border-radius: 0;
  color: var(--color-text);
  font: inherit;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
}

button.account-row-open:hover {
  background: var(--color-surface-alt);
  color: var(--color-text);
}

.account-favorites button.account-row-open {
  padding-left: 0.25rem;
}

.account-row-name {
  min-width: 0;
  overflow-wrap: anywhere;
}

.account-row-balance {
  font-weight: 600;
}

.account-star {
  margin-right: 0.35rem;
  color: #d99a06;
}

.accounts-net-worth {
  margin: 0.75rem 0 0;
  padding-top: 0.75rem;
  border-top: 1px solid var(--color-border);
  color: var(--color-text-muted);
  font-size: 0.92rem;
}

/* Add an account: clear of the net worth line above it. */
.accounts-card #account-add-open {
  margin-top: 1rem;
}

.accounts-net-worth:empty {
  display: none;
}

.accounts-net-worth strong {
  color: var(--color-text);
}

.net-worth-up {
  color: var(--color-success, #15803d);
  font-weight: 600;
}

.net-worth-down {
  color: var(--color-danger);
  font-weight: 600;
}

.accounts-page-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.accounts-page-actions button[hidden] {
  display: none;
}

/* ---- Phones: search in the header, the You page as a menu, attention badges ---- */

.topbar-search {
  display: none;
}

@media (max-width: 800px) {
  .topbar-search {
    position: absolute;
    top: 0.45rem;
    right: 1rem;
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    padding: 0;
    background: none;
    border: 0;
    color: var(--color-text-muted);
  }

  .topbar-search:hover {
    background: var(--color-surface-alt);
    color: var(--color-text);
  }

  .topbar-search svg {
    width: 22px;
    height: 22px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
  }

  .topbar h1 {
    padding-right: 2.75rem;
  }

  /* Each settings heading a row that opens its card. */
  #view-you h2.you-fold {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 52px;
    margin: 0 0 0.5rem;
    padding: 0 1rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    color: var(--color-text);
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: 0;
    text-transform: none;
    cursor: pointer;
  }

  #view-you h2.you-fold::after {
    content: "›";
    color: var(--color-text-muted);
    font-size: 1.3rem;
    transition: transform 0.15s;
  }

  #view-you h2.you-fold.is-open::after {
    transform: rotate(90deg);
  }

  #view-you h2.you-fold[hidden],
  #view-you h2.you-fold:not(.is-open) + .card {
    display: none;
  }

  #view-you h2.you-fold.is-open {
    margin-bottom: 0;
    border-radius: var(--radius-md) var(--radius-md) 0 0;
    border-bottom: 0;
  }

  #view-you h2.you-fold.is-open + .card {
    margin-bottom: 0.5rem;
    border-top-left-radius: 0;
    border-top-right-radius: 0;
  }
}

/* A folded account group with an account that needs you (app.js). */
.account-group-name {
  white-space: nowrap;
}

.account-group-attention {
  display: inline-grid;
  place-items: center;
  min-width: 1.25rem;
  height: 1.25rem;
  margin-left: 0.45rem;
  padding: 0 0.35rem;
  border-radius: 999px;
  background: var(--color-warning-soft);
  color: var(--color-warning);
  font-size: 0.72rem;
  font-weight: 700;
}

.account-group-attention[hidden] {
  display: none;
}

/* ---- Row actions (#8): a tap opens the row; ⋯ holds the rest (app.js) ----- */

tr.row-opens {
  cursor: pointer;
}

body.view-only tr.row-opens {
  cursor: default;
}

.recurring-actions .action-menu-btn {
  margin-left: auto;
}

td.recurring-actions {
  text-align: right;
}

/* A goal's ⋯ in its top corner, its heading line clear of it. */
.goal-item {
  position: relative;
}

.goal-head {
  padding-right: 2.75rem;
}

.goal-head .action-menu-btn {
  position: absolute;
  top: 0.55rem;
  right: 0;
}

.goal-item:first-child .goal-head .action-menu-btn {
  top: -0.35rem;
}

/* Phones: a budget's ⋯ in the card's top corner, not a line of its own. */
@media (max-width: 600px) {
  .budget-table tbody tr {
    position: relative;
  }

  .budget-table td.recurring-actions {
    position: absolute;
    top: 0.35rem;
    right: 0.35rem;
  }

  .budget-table td:first-child {
    padding-right: 2.75rem;
  }
}

/* ---- Reports: one report at a time (reports.js rpShowTab) ------------------- */

.rp-tabs-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1.25rem;
  margin-bottom: 1.25rem;
}

.rp-tabs {
  display: flex;
  gap: 0.35rem;
  overflow-x: auto;
  scrollbar-width: none;
}

.rp-tabs::-webkit-scrollbar {
  display: none;
}

button.rp-tab {
  flex: none;
  min-height: 38px;
  padding: 0 0.95rem;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  background: var(--color-surface);
  color: var(--color-text-muted);
  font: inherit;
  font-size: 0.9rem;
  font-weight: 500;
  white-space: nowrap;
}

button.rp-tab:hover {
  background: var(--color-surface-alt);
  color: var(--color-text);
}

button.rp-tab.is-active {
  background: var(--color-primary-soft);
  border-color: var(--color-primary);
  color: var(--color-primary);
  font-weight: 600;
}

label.rp-range {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9rem;
}

.rp-range[hidden],
.rp-own-range,
[data-rp-panel][hidden] {
  display: none;
}

@media (max-width: 800px) {
  .rp-tabs {
    margin: 0 -1.25rem;
    padding: 0 1.25rem;
  }
}

/* ---- Needs attention, compact (paydue.js): one line a row, one action ------- */

.overview-attention #paydue-card > h2 {
  display: none; /* "Needs attention" says it */
}

.paydue-list {
  gap: 0;
}

.paydue-list .paydue-row {
  padding: 0.6rem 0.4rem 0.6rem 0.8rem;
  border: 0;
  border-top: 1px solid var(--color-border);
  border-radius: 0;
}

.paydue-list .paydue-row:first-child {
  border-top: 0;
}

.paydue-list .paydue-row.is-urgent {
  box-shadow: inset 3px 0 0 var(--color-warning);
}

.paydue-list .paydue-main {
  flex-wrap: nowrap;
  gap: 0.6rem;
}

.paydue-list .paydue-text {
  min-width: 0;
}

.paydue-list .paydue-status {
  font-size: 0.85rem;
}

.paydue-list .paydue-actions {
  flex: none;
  flex-wrap: nowrap;
  gap: 0.25rem;
}

.paydue-list button.paydue-act:not(.link-button) {
  min-height: 32px;
  padding: 0.2rem 0.8rem;
  font-size: 0.85rem;
}

.paydue-list button.paydue-act.link-button {
  font-size: 0.88rem;
  font-weight: 600;
}

.paydue-row.paydue-group .paydue-name {
  font-weight: 600;
}

/* ---- The forecast card on a phone: one heading line, Try a purchase under the chart */

.upcoming-try,
.tl-short,
.paywin-short {
  display: none;
}

@media (max-width: 800px) {
  #upcoming-head {
    align-items: center;
    gap: 0.5rem 0.75rem;
  }

  #upcoming-sub,
  #whatif-open {
    display: none;
  }

  #upcoming-head .cashflow-controls {
    align-items: center;
    gap: 0.5rem 0.9rem;
  }

  /* "Look ahead" goes without saying beside the title: just the choice. */
  #upcoming-head label.upcoming-range-label {
    font-size: 0;
  }

  #upcoming-head label.upcoming-range-label select {
    font-size: 0.88rem;
    padding: 0.35rem 0.5rem;
  }

  #upcoming-head .cashflow-options summary {
    font-size: 0.85rem;
  }

  #upcoming-card .cashflow-kpis {
    grid-template-columns: 1fr 1fr;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
  }

  #upcoming-card .cashflow-kpis > .cashflow-kpi,
  #upcoming-card .cashflow-kpis > .kpi-button {
    padding: 0.55rem 0.65rem;
  }

  #upcoming-card .cashflow-kpi-value {
    font-size: 1.15rem;
  }

  #upcoming-card .upcoming-totals {
    font-size: 0.85rem;
  }

  #upcoming-in-note,
  #upcoming-out-note {
    display: none;
  }

  .upcoming-try {
    display: block;
    width: 100%;
    margin-top: 0.75rem;
  }

  #view-overview:has(#whatif-open[hidden]) .upcoming-try {
    display: none;
  }

  /* Words for a phone: In, Out, Scheduled; the safe window in a few words. */
  .tl-long {
    display: none;
  }

  .tl-short {
    display: inline;
  }

  /* The small print, folded: under How it's worked out. */
  #upcoming-legend,
  #upcoming-start-note {
    display: none;
  }

  /* The safe days to pay: a one-line chip in the shading's green. */
  #upcoming-paywin {
    display: flex;
    flex-wrap: nowrap;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.5rem;
    padding: 0.4rem 0.65rem;
    border-radius: var(--radius-sm);
    background: var(--color-success-soft, #ecfdf3);
    font-size: 0.85rem;
  }

  #upcoming-paywin[hidden],
  #upcoming-paywin .legend-swatch,
  #upcoming-paywin-text {
    display: none;
  }

  #upcoming-paywin .paywin-short {
    display: inline;
  }

  #upcoming-paywin button {
    flex: none;
    margin: 0;
  }

  /* Scheduled and How it's worked out on one line until one opens. */
  #upcoming-details,
  #upcoming-card details.how-worked-out {
    display: inline-block;
    width: auto;
    margin: 0.6rem 1.25rem 0 0;
    font-size: 0.88rem;
  }

  #upcoming-details[open],
  #upcoming-card details.how-worked-out[open] {
    display: block;
  }

  /* The Accounts tab adds accounts on a phone. */
  #account-add-open {
    display: none;
  }

  /* The budgets insight: a line of body text and a link, not a headline. */
  #overview-card-habit {
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
    padding: 0.7rem 0.9rem;
  }

  #overview-card-habit[hidden] {
    display: none;
  }

  #overview-card-habit .forecast-headline-text {
    margin: 0;
    font-size: 0.88rem;
    font-weight: 500;
  }

  #overview-card-habit .forecast-headline-actions {
    margin: 0;
  }

  #overview-card-habit .forecast-headline-actions button {
    min-height: 0;
    padding: 0;
    border: 0;
    background: none;
    color: var(--color-primary);
    font-weight: 600;
    white-space: nowrap;
  }
}
