:root {
  --bg: #0f1419;
  --panel: #1a1f29;
  --panel-2: #232a36;
  --border: #2d3543;
  --text: #e6edf3;
  --muted: #8b95a5;
  --accent: #7aa2f7;
  --accent-2: #bb9af7;
  --good: #9ece6a;
  --bad: #f7768e;
  --warn: #e0af68;
  --joint: #73daca;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, sans-serif;
  font-size: 14px;
  line-height: 1.45;
}

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 28px;
  border-bottom: 1px solid var(--border);
  background: linear-gradient(180deg, #161b22, var(--bg));
}

.brand h1 {
  margin: 0;
  font-size: 20px;
  letter-spacing: 0.2px;
}

.brand .tag {
  margin: 2px 0 0;
  color: var(--muted);
  font-size: 12px;
}

.topbar-actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

#refresh-btn {
  font-size: 18px;
  padding: 6px 12px;
  line-height: 1;
  min-width: 40px;
}

.tabs {
  display: flex;
  gap: 4px;
  padding: 10px 24px 0;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
}

.tab {
  background: transparent;
  border: 1px solid transparent;
  border-bottom: none;
  color: var(--muted);
  padding: 8px 16px;
  cursor: pointer;
  font-size: 13px;
  border-radius: 6px 6px 0 0;
}

.tab:hover { color: var(--text); }

.tab.active {
  color: var(--text);
  background: var(--panel);
  border-color: var(--border);
}

main {
  padding: 24px 28px;
  max-width: 1200px;
  margin: 0 auto;
}

.tab-panel { display: none; }
.tab-panel.active { display: block; }

.grid {
  display: grid;
  gap: 16px;
  margin-bottom: 16px;
}

.summary-grid {
  grid-template-columns: repeat(3, 1fr);
}

.two-col {
  grid-template-columns: 1fr 1fr;
}

@media (max-width: 880px) {
  .summary-grid, .two-col { grid-template-columns: 1fr; }
}

.card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 18px 20px;
}

.card h3 {
  margin: 0 0 14px;
  font-size: 14px;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--muted);
}

.joint-card h3 { color: var(--joint); }

.row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 0;
  border-bottom: 1px dashed rgba(255,255,255,0.04);
  font-variant-numeric: tabular-nums;
}

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

.row.total {
  margin-top: 6px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  border-bottom: none;
  font-weight: 600;
}

.row span { color: var(--muted); }
.row strong { color: var(--text); }

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

label {
  display: block;
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 12px;
}

input, select, button {
  font-family: inherit;
  font-size: 13px;
}

input[type="text"], input[type="number"], select {
  width: 100%;
  padding: 8px 10px;
  margin-top: 4px;
  background: var(--panel-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  outline: none;
}

input:focus, select:focus {
  border-color: var(--accent);
}

button {
  cursor: pointer;
  padding: 9px 14px;
  border-radius: 6px;
  border: 1px solid var(--accent);
  background: var(--accent);
  color: #0b1020;
  font-weight: 600;
}

button:hover { filter: brightness(1.07); }

button.ghost {
  background: transparent;
  color: var(--text);
  border-color: var(--border);
}

button.ghost.danger:hover {
  border-color: var(--bad);
  color: var(--bad);
}

button.icon {
  background: transparent;
  border: none;
  color: var(--muted);
  padding: 4px 8px;
  font-size: 16px;
}
button.icon:hover { color: var(--bad); }

.form-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
  align-items: end;
}

.form-row input, .form-row select { margin-top: 0; }
.form-row button { align-self: end; }

@media (max-width: 720px) {
  .form-row { grid-template-columns: 1fr 1fr; }
  .form-row button { grid-column: 1 / -1; }
}

.data-table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}

.data-table th, .data-table td {
  text-align: left;
  padding: 10px 8px;
  border-bottom: 1px solid var(--border);
}

.data-table th {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--muted);
  font-weight: 500;
}

.data-table .num, .data-table .num-label { text-align: right; }
.data-table tfoot td { border-bottom: none; padding-top: 14px; }

.pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
  background: var(--panel-2);
  border: 1px solid var(--border);
}

.pill.personalA { color: var(--accent); border-color: rgba(122,162,247,0.35); }
.pill.personalB { color: var(--accent-2); border-color: rgba(187,154,247,0.35); }
.pill.joint { color: var(--joint); border-color: rgba(115,218,202,0.35); }

.pill.investment { color: var(--warn); border-color: rgba(224,175,104,0.35); }
.pill.savings { color: var(--good); border-color: rgba(158,206,106,0.35); }
.pill.insurance { color: var(--insurance); border-color: rgba(91,125,177,0.35); }

.positive { color: var(--good); }
.negative { color: var(--bad); }

.bar-stack {
  display: flex;
  width: 100%;
  height: 22px;
  border-radius: 6px;
  overflow: hidden;
  background: var(--panel-2);
  margin-bottom: 10px;
}

.bar-stack > div { height: 100%; }
.bar-stack .seg-exp { background: var(--bad); }
.bar-stack .seg-sav { background: var(--good); }
/* Surplus uses --warn (mustard) so it never collides with the
   terracotta family (--accent / --bad) used by expense segments. */
.bar-stack .seg-surplus { background: var(--warn); }

.legend {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  color: var(--muted);
  font-size: 12px;
}

.legend i.sw {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 2px;
  margin-right: 4px;
  vertical-align: middle;
}
.legend i.exp { background: var(--bad); }
.legend i.sav { background: var(--good); }
.legend i.surplus { background: var(--accent); }

.howto {
  margin: 0;
  padding-left: 20px;
  color: var(--muted);
}
.howto li { margin-bottom: 6px; }

.foot {
  padding: 18px 28px;
  border-top: 1px solid var(--border);
  text-align: center;
  color: var(--muted);
  font-size: 12px;
}

/* Statements & history */
.upload-area {
  margin: 8px 0 12px;
}

.more-options {
  margin-top: 14px;
  border-top: 1px solid var(--border);
  padding-top: 10px;
}

.more-options summary {
  cursor: pointer;
  color: var(--muted);
  font-size: 13px;
  padding: 6px 0;
  list-style: none;
  user-select: none;
}
.more-options summary::-webkit-details-marker { display: none; }
.more-options summary::before {
  content: "›";
  display: inline-block;
  margin-right: 8px;
  transition: transform 0.15s ease;
}
.more-options[open] summary::before { transform: rotate(90deg); }
.more-options summary:hover { color: var(--text); }

.more-options-body {
  padding: 12px 0 4px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.more-options-body .ghost { align-self: flex-start; }

.sub-heading {
  margin: 6px 0 -4px;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--muted);
}

/* Settings card on the Plan tab */
.settings-card {
  padding: 12px 16px;
}

.settings-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

.settings-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0;
  min-width: 160px;
}

.settings-field > span {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--muted);
}

textarea {
  width: 100%;
  padding: 10px;
  background: var(--panel-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  resize: vertical;
  outline: none;
}
textarea:focus { border-color: var(--accent); }

input[type="file"] {
  width: 100%;
  padding: 10px;
  background: var(--panel-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
}

input[type="date"], input[type="month"] {
  width: 100%;
  padding: 8px 10px;
  margin-top: 4px;
  background: var(--panel-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  outline: none;
  color-scheme: dark;
}

.card-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 14px;
}
.card-head h3 { margin: 0; }
.card-head > div { display: flex; gap: 8px; }

.data-table select.cat-select {
  padding: 4px 6px;
  font-size: 12px;
  background: var(--panel-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 4px;
  margin: 0;
}

.bar-col { width: 30%; }

.bar-inline {
  height: 8px;
  border-radius: 4px;
  background: var(--panel-2);
  overflow: hidden;
}

.bar-inline > div {
  height: 100%;
  background: var(--accent);
}

.big {
  font-size: 24px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.big.positive { color: var(--good); }
.big.negative { color: var(--bad); }

.storage-status {
  font-size: 11px;
  color: var(--muted);
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--panel-2);
}
.storage-status[data-kind="ok"] { color: var(--good); border-color: rgba(158,206,106,0.35); }
.storage-status[data-kind="warn"] { color: var(--warn); border-color: rgba(224,175,104,0.35); }
.storage-status[data-kind="pending"] { color: var(--accent); border-color: rgba(122,162,247,0.35); }

/* ============================================================
   Mobile / iPhone — keep small-screen tweaks together at the
   end of the file so they cleanly override desktop rules.
   ============================================================ */

html { -webkit-text-size-adjust: 100%; }
body {
  /* prevents iOS rubber-band overscroll from showing white edges */
  overscroll-behavior: contain;
  /* respects the iPhone home-indicator safe area */
  padding-bottom: env(safe-area-inset-bottom);
}

/* Inputs MUST be >=16px on iOS or Safari zooms in on focus */
input[type="text"],
input[type="number"],
input[type="date"],
input[type="month"],
select,
textarea {
  font-size: 16px;
}

/* Bigger touch targets — 44px is Apple's HIG minimum */
button,
.sub-tab,
.tab {
  min-height: 44px;
  -webkit-tap-highlight-color: rgba(122, 162, 247, 0.2);
}
.data-table button.icon { min-height: 32px; min-width: 32px; }

/* Tablet and narrower */
@media (max-width: 880px) {
  main { padding: 16px; }
  .topbar { padding: 12px 16px; }
  .tabs { padding: 8px 12px 0; overflow-x: auto; flex-wrap: nowrap; }
  .tab { white-space: nowrap; flex-shrink: 0; }
}

/* Phone */
@media (max-width: 640px) {
  /* Topbar: stack vertically, smaller fonts */
  .topbar {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    padding: 12px 14px env(safe-area-inset-bottom);
    padding-top: max(12px, env(safe-area-inset-top));
  }
  .brand h1 { font-size: 17px; }
  .brand .tag { display: none; }
  .topbar-actions {
    width: 100%;
    flex-wrap: wrap;
    gap: 8px;
  }
  .currency { margin-right: auto; }
  .storage-status { order: -1; width: 100%; text-align: center; padding: 6px 10px; }

  /* Tab strip: horizontal scroll instead of wrapping */
  .tabs {
    padding: 6px 12px 0;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .tabs::-webkit-scrollbar { display: none; }
  .tab { padding: 10px 14px; font-size: 13px; }

  main { padding: 12px; }
  .card { padding: 14px; border-radius: 8px; }
  .card h3 { font-size: 12px; margin-bottom: 10px; }

  .grid { gap: 12px; }

  /* Form rows: always stack on phones, even when content is short */
  .form-row {
    grid-template-columns: 1fr;
    gap: 10px;
  }
  .form-row button { width: 100%; }

  /* Wide tables: let them scroll horizontally inside the card */
  .data-table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    white-space: nowrap;
  }
  .data-table th, .data-table td { padding: 10px 8px; }
  .data-table .pill {
    /* keep pills compact on phones so columns aren't massive */
    font-size: 10px;
    padding: 2px 6px;
  }

  /* Preview table: description column wraps, others stay tight */
  #stmt-preview-table td:nth-child(2) {
    white-space: normal;
    min-width: 180px;
  }

  /* Category dropdowns shrink to fit */
  .data-table select.cat-select {
    font-size: 13px;
    padding: 6px 8px;
  }

  /* Card head: title + actions wrap nicely */
  .card-head {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
  }
  .card-head > div {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
  }
  .card-head > div > button { width: 100%; }
  /* When the AI button is visible, give Save the full width on its own row */
  .card-head > div > button#stmt-save { grid-column: 1 / -1; }

  /* Big-number cards in History tab */
  .big { font-size: 20px; }
  .summary-grid { grid-template-columns: 1fr; }

  /* Sub-tabs: scroll instead of wrap */
  .sub-tabs {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    flex-wrap: nowrap;
  }
  .sub-tabs::-webkit-scrollbar { display: none; }
  .sub-tab { white-space: nowrap; flex-shrink: 0; }

  /* Allocation bar legend wraps cleanly */
  .legend { row-gap: 6px; }
}

/* Very small phones (iPhone SE, mini) */
@media (max-width: 380px) {
  .brand h1 { font-size: 15px; }
  .topbar-actions button { padding: 8px 10px; font-size: 12px; }
  main { padding: 10px; }
  .card { padding: 12px; }
}

.cat-pill {
  display: inline-block;
  font-size: 11px;
  padding: 1px 6px;
  border-radius: 4px;
  background: var(--panel-2);
  color: var(--muted);
  margin-right: 4px;
}

/* Expandable saved-statement rows: click ▸ to reveal individual transactions
   for in-place category edits or deletion. */
button.stmt-toggle {
  background: transparent;
  border: none;
  color: var(--muted);
  padding: 2px 6px;
  min-height: 28px;
  min-width: 28px;
  font-size: 14px;
  border-radius: 4px;
}
button.stmt-toggle:hover { color: var(--text); background: var(--panel-2); }

tr.statement-expanded > td {
  background: var(--bg);
  padding: 10px 14px 14px;
  border-top: none;
}

.stmt-txns .stmt-txn-table {
  margin-top: 4px;
  font-size: 12px;
}
.stmt-txns .stmt-txn-table th,
.stmt-txns .stmt-txn-table td {
  padding: 6px 6px;
}
.stmt-txns .stmt-txn-table select.cat-select {
  padding: 4px 6px;
  font-size: 12px;
}

/* Live planning summary on the Plan tab */
.plan-summary { display: flex; flex-direction: column; gap: 16px; }

.plan-summary-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
}

.plan-summary-grid > div {
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
}

.summary-label {
  font-size: 10px;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--muted);
}

.summary-value {
  font-size: 18px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  margin-top: 4px;
}

.summary-sub {
  font-size: 11px;
  color: var(--muted);
  margin-top: 4px;
  font-variant-numeric: tabular-nums;
  min-height: 14px;
}

/* Per-account breakdown row — three small cards inside the summary */
.account-breakdown {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}

.account-card {
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

.account-card.personalA { border-color: rgba(122,162,247,0.4); }
.account-card.personalB { border-color: rgba(187,154,247,0.4); }
.account-card.joint     { border-color: rgba(115,218,202,0.4); }
.account-card-click { cursor: pointer; transition: background 0.12s ease, border-color 0.12s ease; }
.account-card-click:hover { background: rgba(255,255,255,0.04); border-color: rgba(255,255,255,0.18); }
.account-card-click:focus-visible { outline: 2px solid var(--accent, #6cf); outline-offset: 2px; }

.account-card h4 {
  margin: 0 0 6px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--muted);
}

.account-card .acc-row {
  display: flex;
  justify-content: space-between;
  padding: 2px 0;
  color: var(--muted);
}

.account-card .acc-row strong { color: var(--text); font-weight: 500; }

.account-card .acc-surplus {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
  font-weight: 600;
}


.plan-warnings {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px 12px;
  border-radius: 8px;
  border: 1px solid rgba(247,118,142,0.45);
  background: rgba(247,118,142,0.1);
  color: var(--bad);
  font-size: 13px;
}

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

.plan-warnings .warn-head {
  font-weight: 600;
  letter-spacing: 0.3px;
}

/* Inputs flagged as over-budget — red border + subtle red background */
input.input-invalid,
input.input-invalid:focus {
  border-color: var(--bad) !important;
  background: rgba(247,118,142,0.08);
}

.joint-balance, .contrib-suggest {
  padding: 10px 12px;
  border-radius: 8px;
  font-size: 13px;
  border: 1px solid var(--border);
  background: var(--panel-2);
}

.joint-balance.shortfall {
  border-color: rgba(247,118,142,0.4);
  background: rgba(247,118,142,0.08);
  color: var(--bad);
}

.joint-balance.surplus {
  border-color: rgba(158,206,106,0.35);
  background: rgba(158,206,106,0.06);
}

.joint-balance.balanced { color: var(--muted); }

.contrib-suggest {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  align-items: baseline;
  color: var(--text);
}

/* Native [hidden] attribute is display:none, but our class rules above
   set display:flex and override it. Restore the attribute behaviour. */
.joint-balance[hidden],
.contrib-suggest[hidden] { display: none; }
.contrib-suggest .contrib-label {
  color: var(--muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
}
.contrib-suggest .contrib-amount { font-weight: 600; font-variant-numeric: tabular-nums; }

.pies-row {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  justify-content: center;
  align-items: flex-start;
}

.pie-block {
  flex: 1 1 calc(50% - 8px);
  min-width: 280px;
  max-width: 560px;
}

.pie-title {
  margin: 0 0 8px;
  font-size: 11px;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--muted);
}

.pie-wrap {
  display: grid;
  grid-template-columns: 180px 1fr;
  gap: 14px;
  /* Anchor the pie SVG to the top of each block so two side-by-side
     pies keep the same horizontal baseline regardless of how tall the
     legends below them get. */
  align-items: start;
}

#plan-pie, #joint-mini-pie { width: 180px; height: 180px; display: block; }

.pie-legend {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  color: var(--text);
}

/* Each legend row is a clickable button-header plus an optional sub-list
   of the individual items in that category. The button is styled to look
   like a row, not a button. */
.pie-legend .leg-row {
  display: flex;
  flex-direction: column;
}

.pie-legend .leg {
  display: flex;
  align-items: center;
  gap: 8px;
  font-variant-numeric: tabular-nums;
  background: transparent;
  border: none;
  color: var(--text);
  padding: 4px 6px;
  border-radius: 4px;
  text-align: left;
  font-size: 12px;
  cursor: pointer;
  width: 100%;
}
.pie-legend .leg.leg-static { cursor: default; }
.pie-legend .leg:not(.leg-static):hover { background: var(--panel-2); }
.pie-legend .leg-row.is-open > .leg { background: var(--panel-2); }

.pie-legend .leg i {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 2px;
  flex-shrink: 0;
}

.pie-legend .leg .leg-label { flex: 0 1 auto; }
.pie-legend .leg .leg-pct {
  margin-left: auto;
  color: var(--muted);
}
.pie-legend .leg .leg-chevron {
  color: var(--muted);
  width: 12px;
  text-align: right;
  flex-shrink: 0;
}

/* Inline sub-list under an expanded category — one row per individual
   expense/saving, with monthly equivalent + account + (if non-monthly) a
   per-occurrence subtitle. */
.pie-legend .leg-items {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 2px 0 6px 24px;
  padding: 6px 8px;
  border-left: 2px solid var(--border);
  background: rgba(255,255,255,0.015);
  border-radius: 0 4px 4px 0;
}

.pie-legend .leg-item {
  display: grid;
  grid-template-columns: 1fr auto;
  column-gap: 8px;
  font-size: 11px;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.pie-legend .leg-item-name { font-weight: 500; }
.pie-legend .leg-item-amt { text-align: right; }
.pie-legend .leg-item-acc {
  grid-column: 1 / -1;
  color: var(--muted);
  font-size: 10px;
}
.pie-legend .leg-item-sub {
  grid-column: 1 / -1;
  color: var(--muted);
  font-size: 10px;
  font-style: italic;
}
.pie-legend .leg-item-empty {
  font-size: 11px;
  color: var(--muted);
  font-style: italic;
  padding: 4px 0;
}

.pie-empty {
  color: var(--muted);
  font-size: 12px;
  padding: 18px 0;
  text-align: center;
}

@media (max-width: 720px) {
  .plan-summary-grid { grid-template-columns: 1fr 1fr; }
  .pies-row { grid-template-columns: 1fr; }
  .pie-wrap { grid-template-columns: 1fr; gap: 10px; }
  #plan-pie, #joint-mini-pie { margin: 0 auto; }
}

/* Editable in-place tables on the Plan tab */
.editable-table td { padding: 4px 6px; }
.editable-table th { padding: 8px 6px; }

.editable-table input[type="text"],
.editable-table input[type="number"],
.editable-table select {
  margin: 0;
  padding: 6px 8px;
  font-size: 14px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
}
.editable-table input:focus,
.editable-table select:focus {
  background: var(--panel-2);
  border-color: var(--accent);
}

.editable-table tr.ghost-row input,
.editable-table tr.ghost-row select {
  color: var(--text);
  border-style: dashed;
  border-color: var(--border);
  background: rgba(255,255,255,0.015);
}

/* Category combobox: input + caret + absolute-positioned dropdown. Tapping
   the input shows the full category list; typing filters; clicking an
   option fills the value. */
.cat-combobox {
  position: relative;
  display: block;
  width: 100%;
}
.cat-combobox > input {
  width: 100%;
  padding-right: 22px;  /* leave room for the caret */
}
.cat-combobox > .cat-caret {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--muted);
  pointer-events: none;
  font-size: 11px;
}
.cat-combobox > .cat-dropdown {
  position: absolute;
  top: calc(100% + 2px);
  left: 0;
  right: 0;
  z-index: 20;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: 0 8px 16px rgba(0,0,0,0.3);
  max-height: 220px;
  overflow-y: auto;
  padding: 4px;
}
.cat-combobox > .cat-dropdown[hidden] { display: none; }

/* While a category dropdown is open inside this card, hoist the whole
   card so its absolute-positioned dropdown isn't covered by the next
   sibling card (which would otherwise win on stacking). */
.card.has-open-dropdown { z-index: 50; position: relative; }
.cat-option {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-radius: 4px;
  font-size: 13px;
  cursor: pointer;
}
.cat-option:hover { background: var(--panel); }
.cat-option > i {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 2px;
  flex-shrink: 0;
}
.cat-empty {
  padding: 8px;
  font-size: 12px;
  color: var(--muted);
  text-align: center;
}
/* On phones, the dropdown is wide enough to be useful without overflowing
   the parent row. */
@media (max-width: 640px) {
  .cat-combobox > .cat-dropdown { font-size: 14px; }
  .cat-option { padding: 8px 10px; min-height: 36px; }
}

/* Category section headers inside the editable expenses table. Light bar
   above each group of expenses, with the category name on the left and a
   running monthly subtotal on the right. */
.editable-table tr.category-header > td {
  background: var(--panel-2);
  padding: 8px 12px;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--muted);
}
.editable-table tr.category-header .cat-header-name {
  color: var(--text);
  font-weight: 600;
  margin-right: 12px;
}
.editable-table tr.category-header .cat-header-total {
  font-variant-numeric: tabular-nums;
  float: right;
}

.editable-table tr.ghost-row input::placeholder { color: var(--muted); }

.editable-table input.num { text-align: right; }

/* iOS would zoom on focus if font-size < 16px */
@media (max-width: 640px) {
  .editable-table input,
  .editable-table select { font-size: 16px; }
  .editable-table td, .editable-table th { padding: 6px 4px; }
}

/* On phones, the editable tables become stacked cards so 5–6 columns
   don't squash into 60px slivers. Each row is a card; the field label
   comes from the matching <th> via the data-col attribute. */
@media (max-width: 640px) {
  .editable-table { display: block; min-width: 0; white-space: normal; }
  .editable-table thead { display: none; }
  .editable-table tbody, .editable-table tfoot { display: block; }
  .editable-table tr {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 8px;
    row-gap: 6px;
    padding: 10px 10px 8px;
    margin-bottom: 8px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--panel-2);
    /* Establish a positioning context so the absolutely-positioned delete
       cell (top: 4px / right: 4px) anchors to this card rather than
       escaping to the viewport. */
    position: relative;
  }
  .editable-table tr.ghost-row {
    background: rgba(255,255,255,0.02);
    border-style: dashed;
  }
  .editable-table td {
    display: block;
    padding: 0;
    border: none;
    position: relative;
  }
  /* Stack on mobile: Name full-width, then 2-col rows for the middle
     columns, Amount full-width, Delete in the corner. The expense table
     has nine columns (Name, Category, Remark, Account, Cadence, Anchor
     month, Deadline, Amount, Delete), so the full-width Amount sits at
     nth-child(8) and the absolutely-positioned Delete at nth-child(9).
     The recurring expenses table mirrors the same column set. */
  #expenses-table tr td:nth-child(1),
  #expenses-table-recurring tr td:nth-child(1) { grid-column: 1 / -1; }   /* Name */
  #expenses-table tr td:nth-child(8),
  #expenses-table-recurring tr td:nth-child(8) { grid-column: 1 / -1; }   /* Amount */
  #expenses-table tr td:nth-child(9),
  #expenses-table-recurring tr td:nth-child(9) {                          /* Delete */
    position: absolute;
    top: 4px;
    right: 4px;
  }
  /* On phones, the × sits in the corner — small and subtle. Tap-target
     is still 28px (just enough), but the visual chrome is minimal so
     each entry card feels uncluttered. */
  .editable-table button.icon {
    background: transparent;
    border: none;
    color: var(--muted);
    border-radius: 50%;
    font-size: 15px;
    line-height: 1;
    padding: 0;
    min-height: 28px;
    min-width: 28px;
    opacity: 0.55;
  }
  .editable-table button.icon:active {
    background: rgba(179, 90, 69, 0.15);
    color: var(--bad);
    opacity: 1;
  }
  /* Savings: Name full-width, 2-col grid for Type|Account, Cadence|Anchor,
     Deadline (paired with empty space — falls into the natural grid),
     Amount full-width, Delete absolute. Eight columns total:
     Name, Type, Account, Cadence, Anchor month, Deadline, Amount, Delete. */
  #savings-table tr td:nth-child(1) { grid-column: 1 / -1; }    /* Name */
  #savings-table tr td:nth-child(7) { grid-column: 1 / -1; }    /* Amount */
  #savings-table tr td:nth-child(8) {                            /* Delete */
    position: absolute;
    top: 6px;
    right: 6px;
  }
  /* Footer total: single full-width row */
  .editable-table tfoot tr {
    background: transparent;
    border: none;
    padding: 6px 4px;
    grid-template-columns: 1fr auto;
  }
  .editable-table tfoot td {
    grid-column: auto !important;
  }
  /* Category section headers on phones: flat banner, not a card-style row. */
  .editable-table tr.category-header {
    display: block;
    padding: 0;
    margin: 6px 0 4px;
    background: transparent;
    border: none;
  }
  .editable-table tr.category-header > td {
    display: block;
    padding: 8px 12px;
    border-radius: 6px;
  }
  .editable-table tr.category-header td::before { content: none; }
  .editable-table input,
  .editable-table select {
    width: 100%;
    background: var(--bg);
    border: 1px solid var(--border);
    padding: 8px 10px;
  }
  .editable-table input.num { text-align: right; }
  /* Tiny field label above each cell — pulled from the header text */
  .editable-table td::before {
    content: attr(data-col);
    display: block;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--muted);
    margin-bottom: 2px;
  }
  /* Delete cell has no label — points at the last (delete) column of each
     editable table. After the cadence/anchor/deadline columns were added,
     these are nth-child(9) for both expense tables and nth-child(8) for
     savings. Without this, the data-col attribute pseudo-element label
     would push the × button down and clip it against the card padding. */
  #expenses-table tr td:nth-child(9)::before,
  #expenses-table-recurring tr td:nth-child(9)::before,
  #savings-table tr td:nth-child(8)::before { content: none; }
}

/* Per-account breakdown wraps to a single column on phone */
@media (max-width: 640px) {
  .account-breakdown { grid-template-columns: 1fr; }
}

/* ============================================================
   Futuristic redesign layer — lives at the end so its rules
   override the matching defaults above. Refreshed tokens, ambient
   page lighting, hero-scale typography, gradient-bordered cards
   via mask trick, pill tabs. CSS-only — no layout changes.
   ============================================================ */

:root {
  /* Cooler, deeper page palette. Panels carry a subtle blue undertone
     so the eye reads them as a layered surface rather than flat gray. */
  --bg:           #0a0e16;
  --panel:        #131a26;
  --panel-2:      #1a2231;
  --border:       #283246;
  --border-strong:#3a4660;
  --text:         #ecf0f6;
  --muted:        #98a2b3;

  /* Slightly brighter accents — read as more saturated against the
     deeper background without crossing into neon territory. */
  --accent:   #82b1ff;   /* primary blue   */
  --accent-2: #c4a3ff;   /* purple accent  */
  --good:     #a5e07a;
  --bad:      #ff8a9b;
  --warn:     #f0b773;
  --joint:    #7be3d3;

  /* Shared elevation + ring tokens. */
  --shadow-card:
    0 1px 0 rgba(255, 255, 255, 0.05) inset,
    0 8px 24px -10px rgba(0, 0, 0, 0.55),
    0 2px 6px rgba(0, 0, 0, 0.25);
  --shadow-pop:
    0 1px 0 rgba(255, 255, 255, 0.07) inset,
    0 18px 36px -10px rgba(0, 0, 0, 0.6),
    0 4px 10px rgba(0, 0, 0, 0.3);
  --ring:     0 0 0 3px rgba(130, 177, 255, 0.28);
  --ring-bad: 0 0 0 3px rgba(255, 138, 155, 0.28);
}

/* Ambient page lighting: two soft radial highlights in opposite corners
   give the dark canvas depth without distracting from content. The
   gradients are fixed so they don't scroll out of view on long pages. */
body {
  background:
    radial-gradient(1200px 800px at 85% -10%, rgba(130, 177, 255, 0.10), transparent 60%),
    radial-gradient(900px 700px at -15% 110%, rgba(196, 163, 255, 0.08), transparent 55%),
    var(--bg);
  background-attachment: fixed;
  font-feature-settings: "ss01", "cv11";
  letter-spacing: -0.005em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Subtle gradient-edge highlight on every card via a 1px masked overlay.
   This is what gives modern dashboards their "lit from above" feel. */
.card {
  position: relative;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.025), rgba(255,255,255,0.005) 50%, transparent),
    var(--panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: var(--shadow-card);
}
.card::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(180deg,
    rgba(255, 255, 255, 0.10),
    rgba(255, 255, 255, 0) 35%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  pointer-events: none;
}

/* Card titles in uppercase eyebrow style — cleaner separation between
   the section header and content body. */
.card h3 {
  font-size: 12px;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 500;
  margin: 0 0 16px;
}

/* Topbar refinements: bigger brand, glassy status pill, soft underline.
   Horizontal padding follows the page gutter so the brand title and the
   top-right actions line up with main + tabs + subtabs. */
.topbar {
  background: linear-gradient(180deg, rgba(255,255,255,0.02), transparent);
  border-bottom: 1px solid var(--border);
  padding: 20px var(--page-gutter, 28px);
}
.brand h1 {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.015em;
  background: linear-gradient(180deg, #fff, rgba(255,255,255,0.7));
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
}
.storage-status {
  font-weight: 500;
  letter-spacing: 0.2px;
  background: rgba(26, 34, 49, 0.65);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(255,255,255,0.06);
}

/* Pill-style tab strip. Visually distinct active tab without an underline
   bar; uses a recessed panel-2 background so the active tab reads as
   selected. */
.tabs {
  display: inline-flex;
  gap: 2px;
  margin: 16px 24px 0;
  padding: 5px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 1px 0 rgba(255,255,255,0.04) inset;
  overflow: visible;
}
.tab {
  background: transparent;
  border: 1px solid transparent;
  color: var(--muted);
  padding: 9px 18px;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 500;
}
.tab:hover { color: var(--text); }
.tab.active {
  background: var(--panel-2);
  color: var(--text);
  border-color: rgba(255,255,255,0.06);
  box-shadow:
    0 1px 0 rgba(255,255,255,0.04) inset,
    0 2px 6px rgba(0,0,0,0.25);
}
.tab.active::after { display: none; }  /* drop the old underline */

/* Smoother transitions everywhere interactive. */
.card, .tab, button, input, select, textarea, .leg, .cat-option,
.account-card, .data-table tbody tr {
  transition: background-color 160ms ease, border-color 160ms ease,
              color 140ms ease, box-shadow 180ms ease,
              transform 120ms cubic-bezier(0.4, 0, 0.2, 1),
              filter 140ms ease;
}

/* Inputs: refined background, accent focus ring. */
input[type="text"],
input[type="number"],
input[type="date"],
input[type="month"],
select,
textarea {
  background: rgba(255,255,255,0.025);
  border-color: var(--border);
}
input[type="text"]:hover,
input[type="number"]:hover,
input[type="date"]:hover,
input[type="month"]:hover,
select:hover {
  border-color: var(--border-strong);
}
input[type="text"]:focus,
input[type="number"]:focus,
input[type="date"]:focus,
input[type="month"]:focus,
select:focus,
textarea:focus {
  border-color: var(--accent);
  box-shadow: var(--ring);
  background: rgba(255,255,255,0.035);
}
input.input-invalid:focus { box-shadow: var(--ring-bad); }

/* Primary buttons get a gradient + a subtle glow. Secondary ("ghost")
   stays clean and bordered. */
button {
  background: linear-gradient(180deg, #95bdff, #6c98ed);
  border: none;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: #0a1224;
  box-shadow:
    0 1px 0 rgba(255,255,255,0.25) inset,
    0 4px 12px -3px rgba(130, 177, 255, 0.45);
  border-radius: 8px;
  padding: 10px 16px;
}
button:hover { filter: brightness(1.06); transform: translateY(-1px); }
button:active { transform: translateY(0) scale(0.98); filter: brightness(0.98); }
button.ghost {
  background: rgba(255,255,255,0.02);
  border: 1px solid var(--border);
  color: var(--text);
  box-shadow: none;
}
button.ghost:hover {
  background: rgba(255,255,255,0.05);
  border-color: var(--border-strong);
  transform: translateY(-1px);
}
button.ghost.danger:hover {
  border-color: rgba(255,138,155,0.45);
  color: var(--bad);
}
button.icon {
  background: transparent;
  border: none;
  color: var(--muted);
  box-shadow: none;
  padding: 4px 8px;
}
button.icon:hover {
  background: rgba(255,138,155,0.10);
  color: var(--bad);
}

/* Refresh icon button keeps the topbar tidy. */
#refresh-btn {
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--border);
  color: var(--text);
  box-shadow: none;
}
#refresh-btn:hover {
  background: rgba(255,255,255,0.08);
  border-color: var(--border-strong);
}

/* Hero-scale summary tiles. Bigger values + tighter, brighter labels. */
.plan-summary-grid > div {
  background:
    linear-gradient(180deg, rgba(255,255,255,0.035), transparent 70%),
    var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px 16px;
  box-shadow: 0 1px 0 rgba(255,255,255,0.04) inset;
}
.summary-label {
  font-size: 10px;
  letter-spacing: 1px;
  font-weight: 600;
  color: var(--muted);
}
.summary-value {
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -0.025em;
  margin-top: 6px;
  line-height: 1.05;
}
.summary-sub { font-size: 11px; margin-top: 6px; }

/* Per-account cards get a gradient top accent (not a hard line) in the
   account color — feels more refined, less ruled-table-y. */
.account-card {
  position: relative;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.025), transparent 60%),
    var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
}
.account-card::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: transparent;
  opacity: 0.95;
}
.account-card.personalA::before {
  background: linear-gradient(90deg, var(--accent), rgba(130,177,255,0) 75%);
}
.account-card.personalB::before {
  background: linear-gradient(90deg, var(--accent-2), rgba(196,163,255,0) 75%);
}
.account-card.joint::before {
  background: linear-gradient(90deg, var(--joint), rgba(123,227,211,0) 75%);
}
.account-card h4 { font-size: 11px; letter-spacing: 0.7px; font-weight: 600; }

/* Pie chart surfaces — slight drop shadow gives them dimension. */
#plan-pie, #joint-mini-pie {
  filter: drop-shadow(0 6px 18px rgba(0, 0, 0, 0.45));
}
.pie-title {
  font-size: 11px;
  letter-spacing: 0.7px;
  font-weight: 600;
  color: var(--muted);
}

/* Pie legend rows. Slightly larger touch targets + a sharper hover state. */
.pie-legend .leg {
  padding: 6px 8px;
  border-radius: 6px;
  font-size: 12px;
}
.pie-legend .leg:not(.leg-static):hover {
  background: rgba(255,255,255,0.04);
  box-shadow: 0 0 0 1px var(--border) inset;
}
.pie-legend .leg-row.is-open > .leg {
  background: rgba(255,255,255,0.04);
  box-shadow: 0 0 0 1px var(--accent) inset;
}
.pie-legend .leg-items {
  background: rgba(255,255,255,0.02);
  border-left-color: var(--accent);
}

/* Category combobox dropdown: drop shadow, rounded, refined. */
.cat-combobox > .cat-dropdown {
  background: var(--panel);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-pop);
  border-radius: 10px;
}
.cat-option { border-radius: 6px; }
.cat-option:hover {
  background: rgba(130,177,255,0.10);
  color: var(--text);
}

/* Joint balance + contribution suggestion: refined contrast. */
.joint-balance, .contrib-suggest {
  background: rgba(255,255,255,0.025);
  border-color: var(--border);
}
.joint-balance.shortfall {
  background:
    linear-gradient(180deg, rgba(255,138,155,0.10), transparent 80%),
    rgba(255,138,155,0.04);
  border-color: rgba(255,138,155,0.40);
}
.joint-balance.surplus {
  background:
    linear-gradient(180deg, rgba(165,224,122,0.08), transparent 80%),
    rgba(165,224,122,0.04);
  border-color: rgba(165,224,122,0.32);
}

/* Editable table category headers: sleeker pill-style banners.
   Click anywhere on the header to collapse/expand its rows. */
.editable-table tr.category-header { cursor: pointer; }
.editable-table tr.category-header > td {
  background: rgba(255,255,255,0.03);
  border-color: var(--border);
  border-radius: 0;
  font-size: 11px;
  letter-spacing: 0.7px;
  text-transform: uppercase;
  color: var(--muted);
}
.editable-table tr.category-header:hover > td {
  background: rgba(255,255,255,0.05);
}
.editable-table tr.category-header .cat-chevron {
  display: inline-block;
  width: 12px;
  margin-right: 6px;
  color: var(--muted);
  font-size: 11px;
  line-height: 1;
  text-align: center;
  transition: transform 160ms ease;
}
.editable-table tr.category-header.is-collapsed > td {
  background: rgba(255,255,255,0.015);
}

/* Pills (account badges) — softer fill, refined text. */
.pill {
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  font-weight: 500;
}

/* "+ Add expense" / "+ Add savings" panels below their respective tables.
   Distinct visual treatment (dashed border + slightly recessed bg) tells
   the user "this is where you create new entries", not a row in the list. */
.add-card {
  border-style: dashed !important;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.015), transparent 70%),
    rgba(255,255,255,0.012) !important;
}
.add-card h3 {
  color: var(--accent);
  text-transform: none;
  letter-spacing: -0.005em;
  font-size: 14px;
  font-weight: 600;
}
.add-form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 8px;
  align-items: end;
}
.add-form label {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 9px;
  letter-spacing: 1.2px;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
  font-style: normal; /* override the global .muted italic */
}
.add-form input, .add-form select {
  margin-top: 0;
  font-size: 12px;
  padding: 5px 8px;
  border-radius: 8px;
}
.add-form button[type="submit"] {
  height: 30px;
  align-self: end;
  font-size: 12px;
  padding: 0 16px;
}
.add-form .cat-combobox { position: relative; }
.add-card { padding: 14px 16px; }
@media (max-width: 640px) {
  .add-form { grid-template-columns: 1fr 1fr; gap: 8px; }
  .add-form button[type="submit"] {
    grid-column: 1 / -1;
    height: 34px;
    font-size: 13px;
  }
  /* iOS still needs 16px font-size on inputs to avoid focus-zoom,
     but we keep them shallow (6px padding) so the rows don't dominate. */
  .add-form input, .add-form select { font-size: 16px; padding: 6px 10px; }
  .add-card { padding: 14px; }
}

/* Partner profile cards on the Plan tab: minimalist single-line rows.
   Label on the left, value on the right with a hairline underline that
   highlights on focus. Way less visual weight than full-width inputs. */
#tab-setup .grid.two-col .card label {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 12px;
  margin-bottom: 10px;
  font-size: 12px;
  letter-spacing: 0.5px;
  color: var(--muted);
  text-transform: uppercase;
}
#tab-setup .grid.two-col .card label:last-child { margin-bottom: 0; }
#tab-setup .grid.two-col .card label input {
  margin-top: 0;
  padding: 4px 0;
  text-align: right;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  width: auto;
  min-width: 110px;
  max-width: 170px;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  text-transform: none;        /* the input's value isn't a label */
  letter-spacing: -0.005em;
}
#tab-setup .grid.two-col .card label input:hover {
  border-bottom-color: var(--border-strong);
  background: transparent;
}
#tab-setup .grid.two-col .card label input:focus {
  border: none;
  border-bottom: 1px solid var(--accent);
  background: transparent;
  box-shadow: none;
}
/* Card heading sits a touch tighter to the rows below. */
#tab-setup .grid.two-col .card h3 { margin-bottom: 12px; }

/* Restore-backup modal: full-page dim + centered glass card. Used on the
   Plan tab settings card "Restore backup" button. */
.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: rgba(8, 11, 18, 0.65);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.modal-backdrop[hidden] { display: none; }
.modal-card {
  width: min(560px, 100%);
  max-height: calc(100vh - 40px);
  display: flex;
  flex-direction: column;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.04), transparent 60%),
    var(--panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: var(--shadow-pop);
  padding: 18px 20px 20px;
}
.modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}
.modal-head h3 {
  margin: 0;
  font-size: 14px;
  letter-spacing: 0.3px;
  text-transform: none;
  color: var(--text);
}

/* List of recent backups inside the restore modal. */
.restore-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  overflow-y: auto;
  margin-top: 6px;
  padding-right: 4px;
}
.restore-item {
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 12px;
}
.restore-item-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
}
.restore-item-when {
  font-weight: 500;
  font-size: 13px;
  color: var(--text);
}
.restore-item-go {
  padding: 6px 14px;
  font-size: 12px;
}
.restore-item-sub {
  margin-top: 4px;
  font-size: 11px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.restore-empty {
  padding: 14px;
  text-align: center;
  color: var(--muted);
  font-size: 13px;
}

/* Settings-row actions cluster — multiple buttons sit on the right side
   of the settings card. */
.settings-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

/* Save button flash when the user explicitly confirms a save. */
#save-btn.save-flashed {
  background: rgba(165, 224, 122, 0.15);
  border-color: rgba(165, 224, 122, 0.45);
  color: var(--good);
}

/* Editable-table delete button on desktop: a small subtle × icon — no
   label, no pill, just a muted glyph that turns terracotta on hover.
   Less aggressive than the previous labeled pill. */
@media (min-width: 641px) {
  .editable-table button.icon {
    padding: 2px 6px;
    border-radius: 4px;
    background: transparent;
    border: none;
    color: var(--muted);
    font-size: 16px;
    line-height: 1;
    opacity: 0.6;
  }
  .editable-table button.icon:hover {
    background: rgba(179, 90, 69, 0.10);
    color: var(--bad);
    opacity: 1;
  }
}

/* Refined scrollbars on dark theme. */
* {
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.12) transparent;
}
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.10);
  border-radius: 4px;
}
*::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.18); }

/* Tabular numerics everywhere a number sits in a row. */
.summary-value, .acc-row, .acc-surplus, #exp-total, #sav-total,
.leg, .leg-item-amt, #plan-income, #plan-expenses, #plan-savings,
#plan-surplus, .big, .pill {
  font-variant-numeric: tabular-nums;
}

/* Subtle entrance for tab panel content — a soft fade-up on first paint.
   Doesn't animate during normal use (only when the panel becomes visible). */
.tab-panel.active > * {
  animation: cfm-rise 240ms cubic-bezier(0.4, 0, 0.2, 1) both;
}
@keyframes cfm-rise {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Phone-only overrides */
@media (max-width: 640px) {
  .topbar { padding: 14px 16px; }
  .brand h1 { font-size: 18px; }
  .card { padding: 16px; border-radius: 12px; }
  .summary-value { font-size: 22px; }
  /* Soften iOS tap-highlight color to match the accent. */
  * { -webkit-tap-highlight-color: rgba(130, 177, 255, 0.18); }

  /* Convert the top pill tab strip into a fixed bottom navigation bar.
     IMPORTANT: explicitly override the desktop `width: max-content` and
     `max-width: calc(...)` that would otherwise shrink this bar to fit
     just the three icons and shove it into the corner. */
  .tabs {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 100;
    margin: 0;
    width: 100% !important;
    max-width: none !important;
    padding: 6px 0;
    padding-bottom: calc(6px + env(safe-area-inset-bottom));
    background: rgba(19, 26, 38, 0.85);
    -webkit-backdrop-filter: blur(16px) saturate(140%);
    backdrop-filter: blur(16px) saturate(140%);
    -webkit-backdrop-filter: blur(16px) saturate(140%);
    border: none;
    border-top: 1px solid var(--border);
    border-radius: 0;
    box-shadow: 0 -6px 20px rgba(0, 0, 0, 0.45);
    display: flex;
    justify-content: space-around;
    overflow: visible;
  }
  /* Icon-and-label bottom nav. Earlier this used `font-size: 0` to hide
     the text and relied solely on mask-image SVG icons. That worked when
     the mask icons rendered, but the icons can disappear silently if the
     browser blocks the inline data: URI (older iOS Safari CSP behaviour),
     leaving the user with two unlabelled dark stripes and no way to tell
     "Plan" from "Spending". Showing the label as well makes the nav
     self-explanatory even if the icon ever fails. */
  .tab {
    flex: 1;
    background: transparent;
    border: none;
    padding: 4px 0 2px;
    min-height: 52px;
    color: var(--muted);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.2px;
    border-radius: 0;
  }
  .tab::before {
    content: "";
    display: block;
    /* Instagram bottom-nav icons sit around 22-24px. Thinner stroke
       (1.5px) gives the same airy outline look. */
    width: 22px;
    height: 22px;
    background: currentColor;
    -webkit-mask-position: center;
            mask-position: center;
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
    -webkit-mask-size: contain;
            mask-size: contain;
  }
  .tab[data-tab="dashboard"]::before {
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><line x1='6' y1='20' x2='6' y2='14'/><line x1='12' y1='20' x2='12' y2='10'/><line x1='18' y1='20' x2='18' y2='4'/></svg>");
            -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><line x1='6' y1='20' x2='6' y2='14'/><line x1='12' y1='20' x2='12' y2='10'/><line x1='18' y1='20' x2='18' y2='4'/></svg>");
            mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><line x1='6' y1='20' x2='6' y2='14'/><line x1='12' y1='20' x2='12' y2='10'/><line x1='18' y1='20' x2='18' y2='4'/></svg>");
  }
  .tab[data-tab="plan"]::before {
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5'><circle cx='12' cy='12' r='10'/><circle cx='12' cy='12' r='6'/><circle cx='12' cy='12' r='2' fill='black' stroke='none'/></svg>");
            -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5'><circle cx='12' cy='12' r='10'/><circle cx='12' cy='12' r='6'/><circle cx='12' cy='12' r='2' fill='black' stroke='none'/></svg>");
            mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5'><circle cx='12' cy='12' r='10'/><circle cx='12' cy='12' r='6'/><circle cx='12' cy='12' r='2' fill='black' stroke='none'/></svg>");
  }
  .tab[data-tab="monthly"]::before {
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='4' width='18' height='18' rx='2'/><line x1='3' y1='10' x2='21' y2='10'/><line x1='8' y1='2' x2='8' y2='6'/><line x1='16' y1='2' x2='16' y2='6'/></svg>");
            -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='4' width='18' height='18' rx='2'/><line x1='3' y1='10' x2='21' y2='10'/><line x1='8' y1='2' x2='8' y2='6'/><line x1='16' y1='2' x2='16' y2='6'/></svg>");
            mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='4' width='18' height='18' rx='2'/><line x1='3' y1='10' x2='21' y2='10'/><line x1='8' y1='2' x2='8' y2='6'/><line x1='16' y1='2' x2='16' y2='6'/></svg>");
  }
  .tab[data-tab="spending"]::before {
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><rect x='2' y='5' width='20' height='14' rx='2'/><line x1='2' y1='10' x2='22' y2='10'/></svg>");
            -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><rect x='2' y='5' width='20' height='14' rx='2'/><line x1='2' y1='10' x2='22' y2='10'/></svg>");
            mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><rect x='2' y='5' width='20' height='14' rx='2'/><line x1='2' y1='10' x2='22' y2='10'/></svg>");
  }
  /* Instagram active state is just a filled / full-color version of the
     same icon — no dot, no pill, no underline. We approximate by going
     from muted gray to the brighter text color. */
  .tab.active {
    background: transparent;
    color: var(--text);
    border: none;
    box-shadow: none;
  }
  .tab.active::after { display: none; }
  /* Slightly shorter bar height — closer to Instagram's 49pt nav. */
  .tabs { padding: 5px 8px 5px; padding-bottom: calc(5px + env(safe-area-inset-bottom)); }
  .tab { min-height: 44px; }

  /* Reserve room at the bottom of every page so content scrolls clear of
     the fixed nav bar. 86px = 52px min-height + safe-area room. */
  main { padding-bottom: calc(86px + env(safe-area-inset-bottom)); }
  .foot { padding-bottom: calc(86px + env(safe-area-inset-bottom)); }
}

body {
  font-feature-settings: "ss01", "cv11";
  letter-spacing: -0.005em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Smoother transitions across interactive elements without animating
   layout (so phones don't jank). */
.card, .tab, button, input, select, textarea, .leg, .cat-option,
.account-card, .data-table tbody tr {
  transition: background-color 140ms ease, border-color 140ms ease,
              color 140ms ease, box-shadow 160ms ease,
              transform 100ms cubic-bezier(0.4, 0, 0.2, 1),
              filter 140ms ease;
}

/* Cards get a soft inner highlight (1px lighter top) and a low spread
   shadow. Reads as gentle elevation against the dark page bg. */
.card {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.025), transparent 60%),
    var(--panel);
  border-color: var(--border);
  box-shadow: var(--shadow-card);
}

/* Inputs / selects: pronounced focus ring + smoother border transition. */
input[type="text"]:focus,
input[type="number"]:focus,
input[type="date"]:focus,
input[type="month"]:focus,
select:focus,
textarea:focus {
  border-color: var(--accent);
  box-shadow: var(--ring);
}

input.input-invalid:focus { box-shadow: var(--ring-bad); }

/* Buttons: tactile press, smoother hover lift. */
button { will-change: transform; }
button:hover { filter: brightness(1.08); }
button:active { transform: translateY(1px) scale(0.98); }
button.ghost:hover {
  background: var(--panel-2);
  border-color: var(--border-strong, #3a455a);
}
button.icon:hover { background: rgba(247, 118, 142, 0.12); }

/* Active tab pill — colored underline that smoothly tracks state. */
.tab.active {
  background: var(--panel);
  border-color: var(--border);
  position: relative;
}
.tab.active::after {
  content: "";
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: -1px;
  height: 2px;
  background: var(--accent);
  border-radius: 2px 2px 0 0;
}

/* Brand title weight up; mono-numeric across the app. */
.brand h1 {
  font-weight: 600;
  letter-spacing: -0.01em;
}

/* Summary tiles: bigger numbers + tighter label rhythm. */
.plan-summary-grid > div {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.025), transparent 70%),
    var(--panel-2);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.03) inset;
}
.summary-label { letter-spacing: 0.7px; font-weight: 500; }
.summary-value { font-size: 22px; letter-spacing: -0.01em; }

/* Per-account breakdown cards: 2px top accent in account color so the
   household, joint, and personal pots are visually distinct at a glance. */
.account-card {
  position: relative;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.02), transparent 70%),
    var(--panel-2);
  overflow: hidden;
}
.account-card::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
}
.account-card.personalA::before { background: var(--accent); }
.account-card.personalB::before { background: var(--accent-2); }
.account-card.joint::before     { background: var(--joint); }

/* Tables: subtle row hover so the eye tracks. Doesn't apply to the
   editable in-place tables (those have their own card layout on mobile). */
.data-table tbody tr { background: transparent; }
.data-table:not(.editable-table) tbody tr:hover {
  background: rgba(255, 255, 255, 0.018);
}

/* Pie center labels: slightly heavier, more present. Done in SVG attrs
   from JS but we can polish the legend rows here. */
.pie-legend .leg { padding: 5px 6px; }
.pie-legend .leg:not(.leg-static):hover {
  background: var(--panel-2);
  box-shadow: 0 0 0 1px var(--border) inset;
}
.pie-legend .leg-row.is-open > .leg {
  box-shadow: 0 0 0 1px var(--border) inset;
}

/* Category combobox: deeper shadow on the floating dropdown and a soft
   entry fade. */
.cat-combobox > .cat-dropdown {
  box-shadow: 0 12px 32px -8px rgba(0, 0, 0, 0.55),
              0 4px 8px rgba(0, 0, 0, 0.25);
  border-color: var(--border);
}

/* Storage status pill: a hair more contrast. */
.storage-status {
  font-weight: 500;
  letter-spacing: 0.2px;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  background: var(--panel-2);
}

/* Refined scrollbars on dark theme — thin, unobtrusive. */
* {
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.12) transparent;
}
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.1);
  border-radius: 4px;
}
*::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.18); }

/* Saved statement chevron + expanded transactions: gentler entrance. */
button.stmt-toggle {
  transition: transform 160ms cubic-bezier(0.4, 0, 0.2, 1),
              background 140ms ease, color 140ms ease;
}

/* Spending tab tightening — Upload form + History tables read smaller
   so each card feels journal-like rather than form-heavy. */
#tab-statements label { font-size: 11px; letter-spacing: 0.4px; color: var(--muted); }
#tab-statements input[type="text"],
#tab-statements input[type="file"],
#tab-statements input[type="month"],
#tab-statements select,
#tab-statements textarea {
  font-size: 13px;
  padding: 6px 10px;
}
#tab-statements .more-options summary { font-size: 12px; }
#tab-statements .upload-area .muted { font-size: 11px; }

/* History sub-tab: smaller summary numbers, slimmer table rows. */
#tab-history .big { font-size: 18px; line-height: 1.1; }
#tab-history .summary-grid .card { padding: 12px 14px; }
#tab-history .summary-grid .card h3 { font-size: 11px; margin-bottom: 6px; }
#tab-history .data-table th { font-size: 10px; }
#tab-history .data-table td { font-size: 12px; padding: 7px 6px; }
#tab-history .cat-pill { font-size: 10px; }
#tab-history label { font-size: 11px; color: var(--muted); }

/* Saved statements expanded view */
.stmt-txns .stmt-txn-table { font-size: 11px; }
.stmt-txns .stmt-txn-table th,
.stmt-txns .stmt-txn-table td { padding: 4px 6px; }

@media (max-width: 640px) {
  #tab-history .big { font-size: 16px; }
}

/* ════════════════════════════════════════════════════════════════════
   SOFT / ORGANIC WARM aesthetic — final aesthetic layer, overrides
   every prior token. Cream canvas, terracotta + sage accents, soft
   warm shadows, deep rounding, Fraunces display serif paired with
   Manrope body sans. Reads like a kitchen journal.
   ════════════════════════════════════════════════════════════════════ */

:root {
  /* Canvas + surfaces */
  --bg:           #F4ECDC;   /* warm cream                */
  --bg-2:         #EFE5D0;   /* slightly darker cream     */
  --panel:        #FBF6E9;   /* paper white               */
  --panel-2:      #F1E7D1;   /* recessed paper            */
  --border:       #DBCDB1;   /* warm beige hairline       */
  --border-strong:#C5B59A;
  /* Type */
  --text:         #2F2620;   /* warm dark coffee          */
  --muted:        #6F6055;   /* muted clay                */
  /* Accents */
  --accent:       #C25A41;   /* terracotta primary        */
  --accent-2:     #8E5572;   /* plum                      */
  --good:         #7C9A6B;   /* sage success              */
  --warn:         #C99B2D;   /* mustard                   */
  --bad:          #B35A45;   /* darker terracotta = danger*/
  --joint:        #6B958A;   /* dusty teal                */
  --insurance:    #5B7DB1;   /* steel blue (savings type) */
  /* Elevation */
  --shadow-card:
    0 1px 0 rgba(255,255,255,0.55) inset,
    0 12px 24px -16px rgba(80, 45, 20, 0.18),
    0 2px 6px rgba(80, 45, 20, 0.06);
  --shadow-pop:
    0 1px 0 rgba(255,255,255,0.6) inset,
    0 24px 40px -16px rgba(80, 45, 20, 0.22),
    0 6px 12px rgba(80, 45, 20, 0.10);
  --ring:     0 0 0 3px rgba(194, 90, 65, 0.18);
  --ring-bad: 0 0 0 3px rgba(179, 90, 69, 0.22);
}

/* Page canvas: cream with two soft organic blooms in opposite corners
   PLUS a very faint SVG-noise grain so the surface reads like real paper
   rather than flat color. The noise is a 100x100 turbulence pattern
   tiled at 4% opacity — invisible at a glance, makes the page feel
   handmade up close. */
body {
  background:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.18  0 0 0 0 0.12  0 0 0 0 0.08  0 0 0 0.06 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>"),
    radial-gradient(1200px 800px at 90% -10%, rgba(194,90,65,0.10), transparent 60%),
    radial-gradient(900px 700px at -10% 110%, rgba(142,85,114,0.07), transparent 55%),
    var(--bg);
  background-attachment: fixed, fixed, fixed, fixed;
  background-size: 200px 200px, auto, auto, auto;
  color: var(--text);
  font-family: "Manrope", "Helvetica Neue", system-ui, sans-serif;
  font-weight: 400;
  font-size: 13px;
  letter-spacing: -0.003em;
  line-height: 1.55;
  font-feature-settings: "ss01", "cv11";
}

/* Display typography: Fraunces with a warm SOFT axis = 70 so the curves
   feel friendly and journal-like. Numbers use mono-spaced glyphs. */
h1, h2, h3, h4,
.brand h1,
.summary-value,
.big,
.modal-head h3 {
  font-family: "Fraunces", "Iowan Old Style", "Georgia", serif;
  font-variation-settings: "opsz" 60, "SOFT" 70, "wght" 600;
  letter-spacing: -0.015em;
  color: var(--text);
}

/* Numbers everywhere: tabular + slight contrast. */
.summary-value, .acc-row strong, .acc-surplus, #exp-total, #sav-total,
.leg, .leg-item-amt, #plan-income, #plan-expenses, #plan-savings,
#plan-surplus, .big, .pill, input[type="number"] {
  font-variant-numeric: tabular-nums;
}

/* Topbar: warm cream with hairline divider. Brand uses Fraunces. */
.topbar {
  background: linear-gradient(180deg, rgba(255,250,238,0.7), transparent);
  border-bottom: 1px solid var(--border);
}
.brand h1 {
  font-variation-settings: "opsz" 144, "SOFT" 100, "wght" 500;
  letter-spacing: -0.02em;
  font-size: 20px;
  background: none;
  -webkit-text-fill-color: currentColor;
  color: var(--text);
}

/* Storage status pill: warm paper with sage when synced. */
.storage-status {
  background: rgba(251, 246, 233, 0.7);
  border: 1px solid var(--border);
  color: var(--muted);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.storage-status[data-kind="ok"] {
  color: var(--good);
  border-color: rgba(124, 154, 107, 0.35);
  background: rgba(124, 154, 107, 0.07);
}
.storage-status[data-kind="warn"] {
  color: var(--warn);
  border-color: rgba(201, 155, 45, 0.35);
  background: rgba(201, 155, 45, 0.08);
}

/* Cards: paper-white, deep rounding, no harsh border — just a soft
   warm shadow. The ::before light overlay from the previous layer is
   neutralized; warm theme reads cleanest without it. */
.card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 18px;
  box-shadow: var(--shadow-card);
}
.card::before { display: none; }

.card h3 {
  font-family: "Fraunces", "Iowan Old Style", "Georgia", serif;
  font-variation-settings: "opsz" 24, "SOFT" 100, "wght" 500;
  font-size: 13px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 14px;
}

/* Tabs — desktop pill bar */
.tabs {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 5px;
  box-shadow: 0 1px 0 rgba(255,255,255,0.6) inset;
  /* `main` is `max-width: 1200px; margin: 0 auto` so its CONTENT area's
     left edge is at `max(28px, (100vw - 1200px) / 2 + 28px)` from page
     left. Mirror that here so the pill bar lines up with the cards in
     `main` on wider screens, not body's hard left edge. */
  margin: 16px var(--page-gutter, 28px) 0;
  width: max-content;
  max-width: calc(100% - 2 * var(--page-gutter, 28px));
}

:root {
  /* Legacy `--page-gutter` was a dynamic calc that auto-grew to center
     content against an old 1200px `main`. Under the new sidebar layout
     the layout container handles its own centering (via max-width +
     margin: auto), and the gutter only needs to be a small breathing-
     room pad against the viewport edges. */
  --page-gutter: 28px;
}
.tab {
  background: transparent;
  border: 1px solid transparent;
  color: var(--muted);
  border-radius: 999px;
  font-family: "Manrope", system-ui, sans-serif;
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0.2px;
  cursor: pointer;
  -webkit-user-select: none;
          user-select: none;
}
.tab:hover { color: var(--text); background: rgba(0,0,0,0.025); }
.tab.active {
  background: var(--accent);
  color: #FFFCF4;
  border-color: var(--accent);
  box-shadow: 0 4px 10px -4px rgba(194, 90, 65, 0.45);
}
.tab.active::after { display: none; }

/* Sub-tabs: italic Fraunces secondary nav. Only the strip for the
   currently-active main tab is visible (toggled by initTabs). */
.subtabs {
  display: none;
  gap: 6px;
  /* Use the same content-aligned gutter as .tabs so the sub-tab strip
     sits flush with main's content edge on wide screens. */
  margin: 14px var(--page-gutter, 28px) 0;
  padding: 0;
  flex-wrap: wrap;
}
.subtabs.active { display: flex; }
.subtab {
  background: transparent;
  border: none;
  color: var(--muted);
  /* Match the fixed-expense category header type style — Manrope, small
     uppercase eyebrow with extra letter-spacing. Consistent with every
     other small label/eyebrow in the app. */
  font-family: "Manrope", system-ui, sans-serif;
  font-style: normal;
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.7px;
  text-transform: uppercase;
  padding: 8px 4px 10px;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  cursor: pointer;
  -webkit-user-select: none;
          user-select: none;
  box-shadow: none;
}
.subtab:hover { color: var(--text); background: transparent; }
.subtab.active {
  color: var(--accent);
  border-bottom-color: var(--accent);
  background: transparent;
}
@media (max-width: 640px) {
  .subtabs {
    /* On phone the topbar uses 16px horizontal padding; sub-tabs follow. */
    margin: 8px 16px 0;
    padding: 0;
    overflow-x: auto;
    flex-wrap: nowrap;
    scrollbar-width: none;
  }
  .subtabs::-webkit-scrollbar { display: none; }
  .subtab { font-size: 13px; padding: 6px 6px 8px; flex-shrink: 0; }
}

/* Inputs / selects: warm paper, hairline bottom border that turns
   terracotta on focus. */
input[type="text"],
input[type="number"],
input[type="date"],
input[type="month"],
select,
textarea {
  background: rgba(255,252,244,0.6);
  border: 1px solid var(--border);
  border-radius: 10px;
  color: var(--text);
  font-family: "Manrope", system-ui, sans-serif;
}
input[type="text"]:hover,
input[type="number"]:hover,
input[type="date"]:hover,
input[type="month"]:hover,
select:hover {
  border-color: var(--border-strong);
}
input[type="text"]:focus,
input[type="number"]:focus,
input[type="date"]:focus,
input[type="month"]:focus,
select:focus,
textarea:focus {
  background: #FFFDF6;
  border-color: var(--accent);
  box-shadow: var(--ring);
}

/* Buttons */
button {
  background: var(--accent);
  color: #FFFCF4;
  border: 1px solid var(--accent);
  border-radius: 10px;
  font-family: "Manrope", system-ui, sans-serif;
  font-weight: 600;
  letter-spacing: -0.003em;
  box-shadow: 0 4px 10px -4px rgba(194, 90, 65, 0.5),
              0 1px 0 rgba(255,255,255,0.25) inset;
}
button:hover {
  filter: brightness(1.04);
}
button:active { transform: translateY(1px) scale(0.985); filter: brightness(0.96); }
button.ghost {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--border);
  box-shadow: none;
}
button.ghost:hover {
  background: rgba(0,0,0,0.025);
  border-color: var(--border-strong);
}
button.ghost.danger:hover {
  border-color: rgba(179,90,69,0.5);
  color: var(--bad);
  background: rgba(179,90,69,0.06);
}
button.icon {
  background: transparent;
  border: none;
  color: var(--muted);
  box-shadow: none;
}
button.icon:hover { background: rgba(179,90,69,0.08); color: var(--bad); }

#refresh-btn, #save-btn {
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--text);
  box-shadow: 0 1px 0 rgba(255,255,255,0.6) inset;
}
#refresh-btn:hover, #save-btn:hover {
  background: var(--panel-2);
  border-color: var(--border-strong);
}
#save-btn.save-flashed {
  background: rgba(124, 154, 107, 0.18);
  border-color: rgba(124, 154, 107, 0.55);
  color: var(--good);
}

/* Summary tiles: hero numbers in Fraunces, label small sans, paper bg */
.plan-summary-grid > div {
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 16px 18px;
  box-shadow: 0 1px 0 rgba(255,255,255,0.5) inset;
}
.summary-label {
  font-family: "Manrope", sans-serif;
  font-weight: 500;
  font-size: 9px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--muted);
}
.summary-value {
  font-family: "Fraunces", serif;
  font-variation-settings: "opsz" 144, "SOFT" 40, "wght" 450;
  font-size: 24px;
  letter-spacing: -0.025em;
  margin-top: 5px;
  line-height: 1.05;
  color: var(--text);
}
.summary-value.negative { color: var(--bad); }
.summary-value.positive { color: var(--good); }
.summary-sub { color: var(--muted); }

/* Per-account cards: paper bg, gradient top accent in account color. */
.account-card {
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 14px;
}
.account-card h4 {
  font-family: "Fraunces", serif;
  font-variation-settings: "opsz" 24, "SOFT" 100, "wght" 500;
  font-style: italic;
  font-size: 13px;
  letter-spacing: -0.005em;
  text-transform: none;
  color: var(--text);
  margin-bottom: 10px;
}
.account-card .acc-row { font-size: 12px; padding: 3px 0; }
.account-card .acc-surplus { font-size: 13px; padding-top: 8px; }
.account-card .acc-row { color: var(--muted); }
.account-card .acc-row strong { color: var(--text); }
.account-card.personalA::before { background: linear-gradient(90deg, var(--accent), transparent 75%); }
.account-card.personalB::before { background: linear-gradient(90deg, var(--accent-2), transparent 75%); }
.account-card.joint::before     { background: linear-gradient(90deg, var(--joint), transparent 75%); }

/* Pie surfaces — softer drop shadow on cream */
#plan-pie, #joint-mini-pie {
  filter: drop-shadow(0 8px 16px rgba(80, 45, 20, 0.10));
}
.pie-title {
  font-family: "Fraunces", serif;
  font-variation-settings: "opsz" 24, "SOFT" 100, "wght" 500;
  font-style: italic;
  font-size: 12px;
  letter-spacing: 0.3px;
  text-transform: none;
  color: var(--muted);
}

/* Legend rows in pie */
.pie-legend .leg {
  font-family: "Manrope", sans-serif;
  color: var(--text);
}
.pie-legend .leg:not(.leg-static):hover {
  background: rgba(0,0,0,0.025);
  box-shadow: 0 0 0 1px var(--border) inset;
}
.pie-legend .leg-pct, .pie-legend .leg-item-acc, .pie-legend .leg-item-sub {
  color: var(--muted);
}

/* Category combobox dropdown floats on cream */
.cat-combobox > .cat-dropdown {
  background: var(--panel);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-pop);
}
.cat-option:hover {
  background: rgba(194, 90, 65, 0.08);
  color: var(--text);
}
.cat-empty { color: var(--muted); }

/* Editable table: paper rows, hairline bottoms, sage hover */
.data-table th { color: var(--muted); font-family: "Manrope", sans-serif; font-weight: 600; }
.data-table th, .data-table td { border-bottom: 1px solid var(--border); }
.data-table:not(.editable-table) tbody tr:hover {
  background: rgba(0,0,0,0.018);
}

.editable-table tr.category-header > td {
  background: var(--panel-2);
  color: var(--muted);
  border-color: var(--border);
  font-family: "Manrope", sans-serif;
  font-weight: 600;
  letter-spacing: 0.6px;
  text-transform: uppercase;
}
.editable-table tr.category-header:hover > td {
  background: var(--bg-2);
}

/* Pills */
.pill {
  background: rgba(0,0,0,0.04);
  border: 1px solid var(--border);
  color: var(--muted);
}
.pill.personalA { color: var(--accent);   border-color: rgba(194,90,65,0.35); }
.pill.personalB { color: var(--accent-2); border-color: rgba(142,85,114,0.35); }
.pill.joint     { color: var(--joint);    border-color: rgba(107,149,138,0.35); }
.pill.savings   { color: var(--good);      border-color: rgba(124,154,107,0.35); }
.pill.investment{ color: var(--warn);      border-color: rgba(201,155,45,0.35); }
.pill.insurance { color: var(--insurance); border-color: rgba(91,125,177,0.35); }

/* "+ Add" panels: dashed border, recessed cream */
.add-card {
  background: rgba(251, 246, 233, 0.6) !important;
  border-style: dashed !important;
  border-color: var(--border-strong) !important;
}
.add-card h3 {
  color: var(--accent);
  font-style: italic;
  text-transform: none;
  letter-spacing: -0.005em;
  font-size: 12px;
  font-variation-settings: "opsz" 24, "SOFT" 100, "wght" 500;
  margin-bottom: 10px;
}

/* Joint balance + contribution suggest cards */
.joint-balance, .contrib-suggest {
  background: var(--panel-2);
  border-color: var(--border);
  color: var(--text);
}
.joint-balance.shortfall {
  background: rgba(179,90,69,0.08);
  border-color: rgba(179,90,69,0.4);
  color: var(--bad);
}
.joint-balance.surplus {
  background: rgba(124,154,107,0.10);
  border-color: rgba(124,154,107,0.35);
  color: var(--text);
}

/* Plan warnings */
.plan-warnings {
  background: rgba(179,90,69,0.08);
  border-color: rgba(179,90,69,0.45);
  color: var(--bad);
}
input.input-invalid,
input.input-invalid:focus {
  border-color: var(--bad) !important;
  background: rgba(179,90,69,0.06);
}

/* Restore modal: warm glass over cream */
.modal-backdrop {
  background: rgba(60, 35, 20, 0.30);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}
.modal-card {
  background: var(--panel);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-pop);
}
.restore-item {
  background: var(--panel-2);
  border: 1px solid var(--border);
}

/* Statement-toggle chevron */
button.stmt-toggle { color: var(--muted); }
button.stmt-toggle:hover { color: var(--text); background: var(--panel-2); }

/* Row hover indicator */
.row { border-bottom-color: rgba(0,0,0,0.06); }
.row.total { border-top-color: var(--border); }

/* Dashboard allocation-of-income bar background only.
   Segment colors live in the canonical rule above (.bar-stack .seg-exp /
   .seg-sav / .seg-surplus) so all four allocation bars stay visually
   distinct from each other AND from the inline "→ Joint" segment color. */
.bar-stack { background: var(--panel-2); }

/* Editable inline inputs (table cells) */
.editable-table input[type="text"],
.editable-table input[type="number"],
.editable-table select {
  background: transparent;
  border: 1px solid transparent;
}
.editable-table input:focus,
.editable-table select:focus {
  background: rgba(255,252,244,0.7);
  border-color: var(--accent);
}
.editable-table tr {
  background: var(--panel-2) !important;
  border-color: var(--border);
}

/* Italic muted captions across the app — gives the journal-like warmth. */
.muted { font-style: italic; }
.card-head .muted { font-style: italic; }
.summary-sub { font-style: italic; font-size: 10px; }

/* Hairline row separators in dashboard cards — fade ends so the line
   reads less like a ruled spreadsheet and more like a margin note. */
.row {
  border-bottom: 1px solid transparent;
  border-image: linear-gradient(90deg, transparent, var(--border) 20%, var(--border) 80%, transparent) 1;
  padding: 5px 0;
}
.row span { color: var(--muted); }

/* Phone overrides */
@media (max-width: 640px) {
  .brand h1 { font-size: 18px; }
  .summary-value { font-size: 22px; }
  /* Bottom nav: clean paper-white, very Instagram. Crisp 1px top
     divider, no soft shadow — just a flat solid bar against the page. */
  .tabs {
    background: var(--panel);
    border-top: 1px solid var(--border);
    border-radius: 0;
    box-shadow: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  /* Bottom nav: icon-only, Instagram-style minimalism. Re-apply the
     mobile-only font-size:0 here so the new aesthetic's pill-tab font
     declaration above doesn't bleed in and reveal the labels. */
  .tab {
    font-size: 0;
    color: var(--muted);
    background: transparent;
    border: none;
    border-radius: 0;
    padding: 0;
    min-height: 52px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .tab.active {
    background: transparent;
    color: var(--accent);
    border: none;
    box-shadow: none;
  }
  .tab.active::after {
    /* no dot indicator — Instagram-style minimalism keeps just the
       color difference. */
    display: none;
  }
  /* Soft warm tap-highlight on iOS. */
  * { -webkit-tap-highlight-color: rgba(194, 90, 65, 0.15); }
}

/* Scrollbar thumb tinted warm */
* {
  scrollbar-color: rgba(80, 45, 20, 0.20) transparent;
}
*::-webkit-scrollbar-thumb {
  background: rgba(80, 45, 20, 0.18);
}
*::-webkit-scrollbar-thumb:hover { background: rgba(80, 45, 20, 0.28); }

/* =========================================================================
   FINAL TYPOGRAPHY NORMALIZATION (overrides every earlier layer)

   The user's reference is the fixed-expense category header row — Manrope
   11px UPPERCASE, 0.7px letter-spacing, weight 600, muted color. That's the
   "perfect size" they pointed at, so it becomes the canonical small-label
   font for every eyebrow / pill / nav-label / column-header across the app.

   Body text + tappable inputs stay at 13px Manrope (large enough to read,
   small enough not to feel chunky). Hero numeric values stay on Fraunces
   but at a single restrained size — no more competing scales.

   Italics are removed everywhere except the journal-style mini-captions
   that genuinely benefit from them (none right now — user asked to remove
   them from sub-tabs and we strip them globally for consistency).
   ========================================================================= */

/* Eyebrows / labels / small caps everywhere -------------------------------- */
.subtab,
.summary-label,
.card h3,
.card-head h3,
.account-card h3,
.account-card h4,
.pie-title,
.pie-legend .leg,
.data-table th,
.editable-table th,
.editable-table tr.category-header > td,
#tab-statements label,
#tab-history label,
.add-form label,
.add-card h3,
.muted,
.summary-sub,
.acc-row .lbl,
.acc-row .acc-label,
.row span,
.stmt-row .stmt-date,
.stmt-row .stmt-acc,
.cat-pill {
  font-family: "Manrope", system-ui, sans-serif !important;
  font-style: normal !important;
  font-weight: 600 !important;
  font-size: 11px !important;
  letter-spacing: 0.7px !important;
  text-transform: uppercase !important;
  color: var(--muted);
}

/* Inline body captions that shouldn't be ALL-CAPS — keep them small + muted
   but readable (sentence case). */
.card-head .muted,
.muted-note,
#restore-help,
.plan-warnings,
.summary-sub {
  text-transform: none !important;
  letter-spacing: 0.2px !important;
  font-weight: 500 !important;
}

/* Body text — inputs, table cells, regular paragraphs ---------------------- */
body,
input,
select,
textarea,
button,
.row,
.editable-table td,
.data-table td,
.stmt-row,
p {
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 13px;
}

/* Reserve Fraunces (serif) for ONLY the hero numeric values. One scale. */
.summary-value,
.big,
#exp-total,
.account-card .acc-amount,
.account-card .acc-surplus {
  font-family: "Fraunces", "Iowan Old Style", "Georgia", serif !important;
  font-style: normal !important;
  font-variation-settings: "opsz" 144, "SOFT" 40, "wght" 450;
  font-size: 22px !important;
  letter-spacing: -0.01em !important;
  text-transform: none !important;
  color: var(--text) !important;
}

/* Brand wordmark sits a hair larger than hero numbers. */
.brand h1 {
  font-family: "Fraunces", "Iowan Old Style", "Georgia", serif;
  font-style: normal;
  font-size: 18px;
  letter-spacing: -0.005em;
}

/* Sub-tab active state — small caps stay, color shifts to accent + 1px
   underline. */
.subtab.active {
  color: var(--accent) !important;
  border-bottom-color: var(--accent);
}

/* Strip italics globally (user explicitly asked for no italics in sub-tabs;
   we strip everywhere for one coherent voice). */
.muted, .card-head .muted, .summary-sub,
.account-card h4, .stmt-row .stmt-date,
.editable-table input[type="text"]::placeholder,
.add-form input::placeholder {
  font-style: normal !important;
}

/* =========================================================================
   BOTTOM NAV — proper alignment
   ========================================================================= */
@media (max-width: 640px) {
  .tabs {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100% !important;
    max-width: none !important;
    padding: 0 !important;
    padding-bottom: env(safe-area-inset-bottom) !important;
    margin: 0 !important;
    background: var(--panel);
    border-top: 1px solid var(--border);
    border-radius: 0;
    box-shadow: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    display: flex;
    justify-content: space-around;
    align-items: stretch;
    overflow: visible;
  }
  /* Every tab is a flex column: icon centered above tiny label.
     Equal width, fixed height, no padding inside that could nudge icons. */
  .tab {
    flex: 1 1 0;
    min-width: 0;
    background: transparent;
    border: none;
    border-radius: 0;
    margin: 0;
    padding: 8px 0 6px;
    min-height: 52px;
    color: var(--muted);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    /* Re-enable the label text but at the fixed-expense font size. */
    font-family: "Manrope", system-ui, sans-serif !important;
    font-size: 9px !important;
    font-weight: 600 !important;
    letter-spacing: 0.6px !important;
    text-transform: uppercase !important;
    line-height: 1;
  }
  .tab::before {
    content: "";
    display: block;
    width: 22px;
    height: 22px;
    background: currentColor;
    -webkit-mask-position: center;
            mask-position: center;
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
    -webkit-mask-size: contain;
            mask-size: contain;
  }
  .tab.active {
    background: transparent;
    color: var(--accent);
    border: none;
    box-shadow: none;
  }
  .tab.active::after { display: none; }
}

/* =========================================================================
   Subtle Restore / Erase controls in Overview footer
   ========================================================================= */
.overview-utility {
  margin-top: 18px;
  display: flex;
  justify-content: center;
  gap: 18px;
  padding: 14px 0 2px;
  border-top: 1px dashed var(--border);
}
.overview-utility button {
  background: transparent;
  border: none;
  padding: 4px 6px;
  color: var(--muted);
  font-family: "Manrope", system-ui, sans-serif !important;
  font-size: 10px !important;
  font-weight: 600 !important;
  letter-spacing: 0.7px !important;
  text-transform: uppercase !important;
  cursor: pointer;
  box-shadow: none;
  border-radius: 0;
  opacity: 0.7;
}
.overview-utility button:hover {
  opacity: 1;
  color: var(--text);
}
.overview-utility button.danger:hover {
  color: var(--bad);
}

/* =========================================================================
   TOPBAR ICON BUTTONS — Save + Refresh
   Tiny, glyph-only, low-contrast pair pinned to the top-right corner.
   User asked for "really small ... just icons not text that too small".
   ========================================================================= */
.topbar-actions {
  gap: 4px !important;
}
.topbar-actions .icon-btn {
  background: transparent !important;
  border: 1px solid transparent !important;
  padding: 0 !important;
  width: 22px !important;
  height: 22px !important;
  min-width: 22px !important;
  min-height: 22px !important;
  line-height: 1 !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  color: var(--muted) !important;
  font-family: "Manrope", system-ui, sans-serif !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  letter-spacing: 0 !important;
  text-transform: none !important;
  border-radius: 4px !important;
  cursor: pointer;
  box-shadow: none !important;
  opacity: 0.65;
}
.topbar-actions .icon-btn:hover {
  opacity: 1;
  color: var(--text) !important;
  border-color: var(--border) !important;
}
.topbar-actions #storage-status {
  font-size: 10px !important;
  opacity: 0.6;
}

/* Single-pie row variant for Expenses + Savings sub-tabs. */
.pies-row.pies-row-single {
  grid-template-columns: 1fr !important;
  max-width: 460px;
  margin: 0 auto;
}

/* Sync status as a tiny colored dot riding alongside the app title.
   Green = synced, red = warning/offline, amber = saving/pending. */
.brand h1 .sync-dot,
#storage-status.sync-dot {
  display: inline-block !important;
  width: 8px !important;
  height: 8px !important;
  min-width: 0 !important;
  min-height: 0 !important;
  padding: 0 !important;
  margin: 0 0 3px 8px !important;
  border: none !important;
  border-radius: 50% !important;
  background: var(--muted) !important;
  vertical-align: middle !important;
  font-size: 0 !important;
  text-indent: -9999px !important;
  overflow: hidden !important;
  opacity: 0.85;
  transition: background-color 180ms ease, box-shadow 180ms ease;
  cursor: help;
}
#storage-status.sync-dot[data-kind="ok"] {
  background: var(--good, #6F8F5F) !important;
  box-shadow: 0 0 0 3px rgba(111, 143, 95, 0.18);
}
#storage-status.sync-dot[data-kind="warn"] {
  background: var(--bad, #C25A41) !important;
  box-shadow: 0 0 0 3px rgba(194, 90, 65, 0.18);
}
#storage-status.sync-dot[data-kind="pending"] {
  background: var(--warn, #C99B2D) !important;
  box-shadow: 0 0 0 3px rgba(201, 155, 45, 0.18);
  animation: sync-pulse 1.4s ease-in-out infinite;
}
@keyframes sync-pulse {
  0%, 100% { opacity: 0.55; }
  50%      { opacity: 1; }
}
/* Older mobile layout rule made #storage-status full-width — neutralize. */
@media (max-width: 640px) {
  #storage-status.sync-dot {
    order: 0 !important;
    width: 8px !important;
    text-align: left !important;
    padding: 0 !important;
  }
}

/* Topbar layout: title left, icon buttons pinned top-right on EVERY
   viewport. Overrides the older mobile rule that stacked the topbar
   vertically (which pushed the icons below the heading). */
.topbar {
  flex-direction: row !important;
  align-items: center !important;
  justify-content: space-between !important;
  flex-wrap: nowrap !important;
}
.topbar-actions {
  width: auto !important;
  margin-left: auto !important;
  flex-wrap: nowrap !important;
  align-self: center !important;
}
@media (max-width: 640px) {
  .topbar {
    padding: 10px 14px !important;
    padding-top: max(10px, env(safe-area-inset-top)) !important;
    gap: 8px !important;
  }
  .topbar-actions {
    gap: 4px !important;
  }
}

/* 3-up pies row for Expenses / Savings sub-tabs (Joint + per-partner).
   On wide viewports all three pies render side by side and the picker
   dropdown is hidden. Below ~860px the dropdown takes over and only the
   selected pie renders, so the layout never collapses to a tall stack. */
.pies-row.pies-row-tri {
  grid-template-columns: repeat(3, 1fr) !important;
  gap: 18px;
}
.pies-row.pies-row-tri .pie-wrap {
  grid-template-columns: 1fr !important;
  gap: 10px;
  justify-items: center;
}
.pies-row.pies-row-tri svg {
  width: 100%;
  max-width: 200px;
  height: auto;
}

.pie-selector {
  display: none;
  margin: 0 0 14px;
}
.pie-selector label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: "Manrope", system-ui, sans-serif !important;
  font-size: 11px !important;
  font-weight: 600 !important;
  letter-spacing: 0.7px !important;
  text-transform: uppercase !important;
  color: var(--muted);
}
.pie-selector select {
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 13px;
  padding: 6px 28px 6px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--panel);
  color: var(--text);
  text-transform: none;
  letter-spacing: 0;
  font-weight: 500;
}

@media (max-width: 860px) {
  .pie-selector { display: block; }
  .pies-row.pies-row-tri {
    grid-template-columns: 1fr !important;
    gap: 0;
  }
  .pies-row.pies-row-tri .pie-block { display: none !important; }
  .pies-row.pies-row-tri[data-active="joint"] .pie-block[data-pie-key="joint"],
  .pies-row.pies-row-tri[data-active="a"]     .pie-block[data-pie-key="a"],
  .pies-row.pies-row-tri[data-active="b"]     .pie-block[data-pie-key="b"] {
    display: block !important;
  }
  .pies-row.pies-row-tri .pie-block .pie-title { display: none; }
  .pies-row.pies-row-tri svg { max-width: 220px; }
}

/* Allocation rows — four stacked bars on the Dashboard. */
.alloc-rows {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.alloc-row { display: flex; flex-direction: column; gap: 4px; }
.alloc-row .bar-stack { margin-bottom: 0 !important; }
.alloc-label {
  font-family: "Manrope", system-ui, sans-serif !important;
  font-size: 11px !important;
  font-weight: 600 !important;
  letter-spacing: 0.7px !important;
  text-transform: uppercase !important;
  color: var(--muted) !important;
}
.alloc-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 14px;
  color: var(--muted);
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 11px;
  margin-top: 2px;
}
.alloc-legend .sw {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 2px;
  margin-right: 5px;
  vertical-align: middle;
}
.alloc-legend .sw.exp     { background: var(--bad); }
.alloc-legend .sw.sav     { background: var(--good); }
.alloc-legend .sw.surplus { background: var(--warn); }
.alloc-empty { font-size: 11px; color: var(--muted); opacity: 0.7; }

/* Compact upload control — small button + chosen-filename + muted hint,
   instead of the native input that fills an entire row. */
.upload-area {
  display: flex !important;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  margin: 6px 0 10px !important;
}
.upload-area #stmt-file {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.upload-area .upload-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--panel);
  color: var(--text);
  font-family: "Manrope", system-ui, sans-serif !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  letter-spacing: 0.3px !important;
  cursor: pointer;
  transition: background-color 120ms ease, border-color 120ms ease;
}
.upload-area .upload-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}
.upload-area .upload-filename {
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 12px;
  color: var(--text);
  opacity: 0.85;
  max-width: 240px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.upload-area .upload-help {
  font-size: 11px !important;
  color: var(--muted) !important;
  margin: 0 !important;
  flex: 1 1 200px;
}

/* =========================================================================
   PLANNED EXPENSES — sub-tab list, summary, dashboard upcoming card,
   plus the "→ Planned" segment color on the allocation bars.
   ========================================================================= */

/* Bar segment color — plum (--accent-2). Distinct from the other 4
   segment hues (brick exp, sage sav, mustard surplus, teal → joint). */
.bar-stack .seg-planned { background: var(--accent-2); }
.alloc-legend .sw.planned { background: var(--accent-2); }

/* "Planned reserve" rows on the dashboard cards sit below the surplus
   total. Muted, with a subtle dashed top to separate accumulating
   savings goals from the recurring math. */
.row.reserve {
  border-top: 1px dashed var(--border);
  margin-top: 4px;
  padding-top: 6px;
  color: var(--muted);
}
.row.reserve strong {
  font-weight: 600;
  color: var(--accent-2);
}

/* Planned sub-tab summary card — three bucket cards side by side.
   Each shows: pre-planning surplus → planned draw → remaining surplus,
   with a bar showing what share of surplus is going to planned. */
.planned-summary-card { padding-bottom: 14px; }
.planned-summary-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}
@media (max-width: 860px) {
  .planned-summary-grid { grid-template-columns: 1fr; }
}
.planned-bucket {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 16px;
  background: var(--panel);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.planned-bucket-title {
  font-family: "Manrope", system-ui, sans-serif !important;
  font-size: 11px !important;
  font-weight: 600 !important;
  letter-spacing: 0.7px !important;
  text-transform: uppercase !important;
  color: var(--muted);
}
.planned-bar-track {
  position: relative;
  height: 8px;
  background: var(--panel-2);
  border-radius: 999px;
  overflow: hidden;
}
.planned-bar-fill {
  height: 100%;
  background: var(--accent-2);
  border-radius: 999px;
  transition: width 240ms ease;
}
.planned-bar-fill.over   { background: var(--bad); }
.planned-bar-fill.idle   { background: transparent; }
.planned-bucket-stats {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.planned-stat {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 12px;
}
.planned-stat-label {
  color: var(--muted);
  font-weight: 500;
}
.planned-stat-val {
  color: var(--text);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.planned-stat-val.positive { color: var(--good); }
.planned-stat-val.negative { color: var(--bad); }
.planned-bucket-warn {
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 11px;
  padding: 4px 0 0;
  color: var(--muted);
  border-top: 1px dashed var(--border);
  margin-top: 2px;
  padding-top: 6px;
}
.planned-bucket-warn.shortfall { color: var(--bad); font-weight: 600; }
.planned-bucket-warn.ok { color: var(--muted); }

/* Overview account-card "→ Planned" inline row + reserve footer line. */
.acc-row.planned strong { color: var(--accent-2); }
.acc-row.acc-reserve {
  margin-top: 2px;
  padding-top: 6px;
  border-top: 1px dashed var(--border);
  color: var(--muted);
}
.acc-row.acc-reserve strong { color: var(--accent-2); }

/* =========================================================================
   Overview summary expanded to 6 cells (added "Planned this month" and
   "Bank balance"). Auto-fit grid keeps each cell at ~150px so on phones
   the grid wraps to 2 columns instead of forcing a horizontal scroll.
   ========================================================================= */
.plan-summary-grid {
  display: grid !important;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)) !important;
  gap: 12px !important;
}

/* =========================================================================
   MONTHLY TAB
   ========================================================================= */
.monthly-summary { padding-bottom: 14px; }
.monthly-totals {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin-top: 10px;
}
@media (max-width: 720px) {
  .monthly-totals { grid-template-columns: 1fr; }
}
.mt-cell {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
  background: var(--panel);
}
.mt-cell .summary-label {
  font-family: "Manrope", system-ui, sans-serif !important;
  font-size: 11px !important;
  font-weight: 600 !important;
  letter-spacing: 0.7px !important;
  text-transform: uppercase !important;
  color: var(--muted);
}
.mt-cell .summary-value {
  font-family: "Fraunces", "Manrope", serif;
  font-size: 22px;
  font-weight: 450;
  color: var(--text);
  margin-top: 2px;
}
.mt-cell .summary-value.positive { color: var(--good); }
.mt-cell .summary-value.negative { color: var(--bad); }

/* Balances card */
.monthly-balances-card { padding-bottom: 14px; }
.monthly-balances {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  margin-bottom: 10px;
}
@media (max-width: 720px) {
  .monthly-balances { grid-template-columns: 1fr; }
}
.bal-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0;
  font-family: "Manrope", system-ui, sans-serif !important;
  font-size: 11px !important;
  font-weight: 600 !important;
  letter-spacing: 0.7px !important;
  text-transform: uppercase !important;
  color: var(--muted) !important;
  font-style: normal !important;
}
.bal-row input[type="number"] {
  font-family: "Fraunces", "Manrope", serif !important;
  font-size: 18px !important;
  font-weight: 500 !important;
  letter-spacing: 0 !important;
  text-transform: none !important;
  padding: 8px 12px !important;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--panel);
  color: var(--text) !important;
  width: 100%;
  box-sizing: border-box;
}
.bal-projection .row {
  display: flex;
  justify-content: space-between;
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
}
.bal-projection .row:last-of-type { border-bottom: none; }
.bal-projection .muted { font-size: 11px; margin: 6px 0 0 !important; }

/* Incoming + Outgoing lists */
.monthly-list {
  display: flex;
  flex-direction: column;
  gap: 0;
}
.monthly-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 13px;
}
.monthly-row-label {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.monthly-row-amount {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--text);
  font-weight: 600;
}
.monthly-acct {
  font-size: 10px;
  font-weight: 500;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.4px;
}
.monthly-group {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 4px 12px;
  margin-bottom: 12px;
  background: var(--panel);
}
.monthly-group:last-child { margin-bottom: 0; }
.monthly-group > summary { list-style: none; cursor: pointer; user-select: none; }
.monthly-group > summary::-webkit-details-marker { display: none; }
.monthly-group-chevron {
  display: inline-block;
  width: 1em;
  margin-right: 6px;
  font-size: 10px;
  color: var(--muted);
  transition: transform 0.15s ease;
}
.monthly-group[open] > summary .monthly-group-chevron { transform: rotate(90deg); }
.monthly-group-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
  font-family: "Manrope", system-ui, sans-serif !important;
  font-size: 11px !important;
  font-weight: 600 !important;
  letter-spacing: 0.7px !important;
  text-transform: uppercase !important;
  color: var(--muted) !important;
}
.monthly-group:not([open]) > summary.monthly-group-head { border-bottom: none; }
.monthly-group-head strong {
  color: var(--text);
  font-family: "Fraunces", "Manrope", serif;
  font-size: 14px;
  font-weight: 500;
}
.monthly-group-exp     .monthly-group-head strong { color: var(--bad); }
.monthly-group-sav     .monthly-group-head strong { color: var(--good); }
.monthly-group-planned .monthly-group-head strong { color: var(--accent-2); }
.monthly-item:last-child { border-bottom: none; }
.monthly-item-planned { color: var(--accent-2); }
.monthly-subtotal {
  border-bottom: none;
  border-top: 2px solid var(--border);
  margin-top: 4px;
  padding-top: 10px;
  font-weight: 700;
}
.monthly-grand-total .monthly-row-amount {
  font-family: "Fraunces", "Manrope", serif;
  font-size: 18px;
  font-weight: 500;
}
.monthly-empty { padding: 12px 0; font-size: 12px; }

/* Overview summary cells — clickable variants match the resting style
   of the non-clickable cells (Surplus, Bank balance) exactly. No
   padding/border/margin shifts, no chevron, no glyph. Interactivity is
   communicated by cursor + a barely-there hover tint, plus a clear
   focus ring for keyboard users. */
.summary-cell.clickable {
  cursor: pointer;
  outline: none;
  border-radius: 4px;
  transition: background-color 140ms ease, box-shadow 140ms ease;
}
.summary-cell.clickable:hover {
  background: rgba(194, 90, 65, 0.05);
}
.summary-cell.clickable:focus-visible {
  box-shadow: 0 0 0 2px rgba(194, 90, 65, 0.35);
}

/* =========================================================================
   VIEW PICKER — segmented control sitting above a sub-tab's pie + list.
   Replaces the old dropdown selectors on Expenses / Savings / Planned and
   adds a new one on Overview. 4 options: All/Combined, Joint, Chintu, Shanu.
   ========================================================================= */
/* View picker — minimal "bookmark tab" pattern.
   The picker row carries a hairline baseline that the content card
   below visually hangs from (the card loses its top border-radius and
   tucks underneath via -1px margin). Active tab's terracotta underline
   sits on that baseline like a tab sticking out of a document — bookmark
   into the page below. No container, no shadows, no labels — just
   typography and one line. */
.view-picker-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  margin: 4px 0 0;
  padding: 0;
  border-bottom: 1px solid var(--border);
}
.overview-picker-row { margin-top: 0; }
.view-picker {
  display: flex;
  gap: 28px;
  align-items: baseline;
  width: auto;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 0;
  box-shadow: none;
}
.view-pick-btn {
  flex: 0 0 auto;
  background: transparent;
  border: none;
  border-radius: 0;
  box-shadow: none;
  padding: 10px 2px 11px;
  font-family: "Manrope", system-ui, sans-serif !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  letter-spacing: 1px !important;
  text-transform: uppercase !important;
  color: var(--muted);
  cursor: pointer;
  position: relative;
  white-space: nowrap;
  min-height: 0;
  transition: color 200ms ease;
}
/* Override global button :hover filter which would otherwise brighten
   the (transparent) background and reveal the inherited terracotta. */
.view-pick-btn:hover { filter: none; }
.view-pick-btn:active { transform: none; }
.view-pick-btn::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;            /* overlap the row's baseline */
  height: 2px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 240ms cubic-bezier(0.4, 0, 0.2, 1);
}
.view-pick-btn:hover { color: var(--text); }
.view-pick-btn.active { color: var(--accent); }
.view-pick-btn.active::after { transform: scaleX(1); }

/* The card immediately after a view-picker-row tucks under the row's
   baseline so the picker reads as the card's header. Square the top
   corners on that side and reuse the existing border as the seam. */
.view-picker-row + .card {
  border-top-left-radius: 0;
  border-top-right-radius: 0;
  margin-top: 0;
}

@media (max-width: 540px) {
  .view-picker {
    gap: 18px;
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .view-picker::-webkit-scrollbar { display: none; }
  .view-pick-btn {
    font-size: 11px !important;
    letter-spacing: 0.6px !important;
    padding: 8px 2px 10px;
  }
}

/* ============================================================
   Mode toggle — Option W: iOS-style binary switch.
   A literal knob that slides between two labels. Used for the
   Current ⇄ Recommended swap on Plan→Overview and Projection.
   Reads unambiguously as a setting (vs. underline tabs which
   navigate). The label on the active side picks up terracotta
   so users can read the state without parsing the knob.
   ============================================================ */
.mode-toggle {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  user-select: none;
}
.mode-toggle-label {
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.9px;
  text-transform: uppercase;
  color: var(--muted);
  cursor: pointer;
  padding: 4px 2px;
  transition: color 220ms ease;
  white-space: nowrap;
}
.mode-toggle-label:hover { color: var(--text); }
.mode-toggle-label.active { color: var(--accent); }
.mode-toggle-switch {
  width: 44px;
  height: 24px;
  min-height: 24px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  position: relative;
  cursor: pointer;
  padding: 0;
  flex: 0 0 auto;
  transition: background 260ms ease;
  box-shadow: inset 0 1px 2px rgba(80, 45, 20, 0.06);
}
.mode-toggle-switch::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 18px;
  height: 18px;
  border-radius: 999px;
  background: var(--accent);
  transition: transform 280ms cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: 0 1px 3px rgba(80, 45, 20, 0.25);
}
.mode-toggle-switch[data-state="right"]::after {
  transform: translateX(20px);
}
.mode-toggle-switch:focus-visible {
  outline: none;
  box-shadow:
    inset 0 1px 2px rgba(80, 45, 20, 0.06),
    var(--ring);
}

/* Compare — moved out of the segmented control onto its own quiet text
   link, since the binary toggle can't host a third state. Sits to the
   right of the toggle on the Projection tab. */
.mode-compare-btn {
  background: transparent;
  border: 1px solid var(--border);
  padding: 5px 12px;
  border-radius: 999px;
  box-shadow: none;
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--muted);
  cursor: pointer;
  min-height: 26px;
  transition: color 200ms ease, border-color 200ms ease, background 200ms ease;
}
.mode-compare-btn:hover {
  color: var(--text);
  border-color: var(--border-strong);
  filter: none;
}
.mode-compare-btn:active { transform: none; }
.mode-compare-btn.active {
  color: var(--accent);
  border-color: var(--accent);
  background: rgba(194, 90, 65, 0.08);
}
.mode-toggle-switch:hover { filter: none; }
.mode-toggle-switch:active { transform: none; }

/* Single-pie wrap for the new picker-driven layout (replaces pies-row-tri). */
.single-pie-wrap {
  display: grid;
  /* Pie column fixed at 220px; legend column flexes but is capped so the
     pie + legend pair stays balanced within each pie-block. Both columns
     are centered within their pie-block via `justify-content: center` so
     the two pie pairs read as mirror images rather than left-anchored.
     `align-items: start` anchors the SVG to the top of each block so
     two pies sitting side-by-side stay on the same horizontal baseline
     regardless of how tall their respective legends are. */
  grid-template-columns: 220px minmax(180px, 280px);
  gap: 20px;
  align-items: start;
  justify-content: center;
}
.single-pie-wrap .pie-wrap {
  display: contents;
}
.single-pie-wrap svg {
  width: 100%;
  max-width: 220px;
  height: auto;
}
.single-pie-wrap .pie-title {
  grid-column: 1 / -1;
  margin: 0 0 4px;
}
@media (max-width: 640px) {
  .single-pie-wrap {
    grid-template-columns: 1fr;
    justify-items: center;
  }
}
.leg-jump { cursor: pointer; }
.leg-jump:hover { color: var(--text); }

/* =========================================================================
   AUTO-TRACKING SUB-TAB — Gmail connection cards + bank-account mapping
   ========================================================================= */
.gmail-conn-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 14px;
}
@media (max-width: 600px) {
  .gmail-conn-grid { grid-template-columns: 1fr; }
}
.gmail-conn {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
  background: var(--panel);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.gmail-conn-name {
  font-family: "Manrope", system-ui, sans-serif !important;
  font-size: 11px !important;
  font-weight: 600 !important;
  letter-spacing: 0.7px !important;
  text-transform: uppercase !important;
  color: var(--muted);
}
.gmail-conn-status {
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 12px;
  color: var(--text);
}
.gmail-conn-actions {
  display: flex;
  gap: 8px;
  margin-top: 4px;
}
.gmail-conn-actions button {
  font-size: 12px;
  padding: 6px 12px;
}
.poll-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 4px;
}
.poll-row button {
  font-size: 12px;
  padding: 6px 14px;
}
.poll-row .muted {
  margin: 0;
  font-size: 11px;
}

#bank-accounts-table {
  width: 100%;
  margin-top: 4px;
}
#bank-accounts-table input[type="text"],
#bank-accounts-table select {
  width: 100%;
  box-sizing: border-box;
  font-size: 13px;
  padding: 4px 6px;
}
.unmapped-warn {
  margin-top: 10px;
  padding: 8px 12px;
  border: 1px dashed var(--warn);
  border-radius: 6px;
  background: rgba(201, 155, 45, 0.06);
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 12px;
  color: var(--text);
}
.unmapped-warn .link-btn {
  margin-left: 8px;
}

/* =========================================================================
   Sortable table headers — click cycles asc → desc → off. Small chevron
   glyph shows direction; whole header is the click target. Applies to
   Expenses + Savings (anything with `.sortable` + `th[data-sort-key]`).
   ========================================================================= */
.sortable thead th[data-sort-key] {
  position: relative;
  cursor: pointer;
  user-select: none;
  padding-right: 18px;
  transition: color 120ms ease;
}
.sortable thead th[data-sort-key]:hover {
  color: var(--text);
}
.sortable thead th[data-sort-key]::after {
  content: "";
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  opacity: 0.25;
}
.sortable thead th.sorted-asc::after {
  border-bottom: 5px solid currentColor;
  opacity: 1;
}
.sortable thead th.sorted-desc::after {
  border-top: 5px solid currentColor;
  opacity: 1;
}

/* =========================================================================
   Paused savings/investment row — dimmed name + amount so the row stays
   visible in the list but reads as "not currently contributing". The
   pause/resume icon takes care of its own visual via textContent.
   ========================================================================= */
.row-paused {
  opacity: 0.55;
}
.row-paused [data-field="name"],
.row-paused [data-field="amount"] {
  text-decoration: line-through;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--muted);
}
.row-actions {
  white-space: nowrap;
}
.row-actions .icon {
  padding: 0 4px;
  font-size: 14px;
}
.row-actions .row-pause:hover {
  color: var(--accent);
}
.row-actions .row-del:hover {
  color: var(--bad);
}

/* Overview Bank-balance cell — projection line sits above the
   "Edit balances" link, colored green/red by surplus sign. */
#plan-bank-projection {
  display: block;
  margin-bottom: 2px;
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}
#plan-bank-projection.positive { color: var(--good); }
#plan-bank-projection.negative { color: var(--bad); }

/* =========================================================================
   PROJECTION SUB-TAB — line chart of projected balance per bucket + table
   ========================================================================= */
.projection-wrap {
  width: 100%;
  margin: 8px 0 14px;
  position: relative;
}
.projection-tooltip {
  position: absolute;
  pointer-events: none;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 10px;
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 11px;
  color: var(--text);
  box-shadow: 0 4px 12px rgba(0,0,0,0.08);
  z-index: 5;
  min-width: 170px;
  max-width: 220px;
}
.projection-tooltip[hidden] { display: none; }
.ptip-month {
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  font-size: 10px;
  color: var(--muted);
  margin-bottom: 4px;
}
.ptip-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 2px 0;
}
.ptip-sw {
  display: inline-block;
  width: 10px;
  height: 3px;
  border-radius: 2px;
  flex: 0 0 auto;
}
.ptip-label { flex: 1; }
.ptip-val {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
.ptip-val.neg { color: var(--bad); }
#projection-chart { touch-action: pan-y; }

/* =========================================================================
   Smart planned-expense schedule UI — priority badge + monthly draw
   sparkline + at-risk flag + variable contribution suggestion block.
   ========================================================================= */
.priority-badge {
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.4px;
  color: var(--muted);
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 1px 7px;
}
.priority-badge.priority-p1 {
  color: var(--bad, #f88);
  border-color: rgba(255, 140, 140, 0.5);
  background: rgba(255, 140, 140, 0.10);
}
.priority-badge.priority-p2 {
  color: var(--warn, #e0af68);
  border-color: rgba(224, 175, 104, 0.45);
  background: rgba(224, 175, 104, 0.10);
}
.priority-badge.priority-p3 {
  color: var(--muted);
}
.planned-risk-badge {
  margin-left: 6px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.3px;
  color: var(--bad);
  text-transform: uppercase;
}
.planned-row.at-risk {
  border-left: 3px solid var(--bad);
}
.planned-schedule {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  margin-top: 6px;
  height: 30px;
  padding: 0 2px;
}
.psched-cell {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  flex: 1 1 0;
  min-width: 6px;
  height: 100%;
  position: relative;
}
.psched-bar {
  display: block;
  width: 100%;
  max-width: 14px;
  background: var(--accent-2);
  border-radius: 2px 2px 0 0;
  opacity: 0.55;
  transition: opacity 140ms ease;
}
.psched-cell:hover .psched-bar { opacity: 1; }
.psched-cell.current .psched-bar {
  opacity: 1;
  background: var(--accent);
}

/* Variable contribution suggestion block — stacks two rows: "this
   month" (smart) vs "steady-state baseline" (income-proportional). */
.contrib-block {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 14px;
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
}
.contrib-block:last-child { border-bottom: none; }
.contrib-block:first-child .contrib-label { color: var(--accent); }

/* Per-month text breakdown beneath each planned row's sparkline.
   "Jun ₹0 · Jul ₹0 · Aug ₹15,000 · Sep ₹15,000" — explicit numbers so
   the schedule is readable, not just visually inferred. */
.planned-schedule-text {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  margin-top: 6px;
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 11px;
  color: var(--muted);
}
.psched-month strong {
  font-weight: 600;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  margin-left: 2px;
}
.psched-month.zero strong { color: var(--muted); font-weight: 500; }
.psched-month.current { color: var(--accent); font-weight: 600; }
.psched-month.current strong { color: var(--accent); }

/* Projection sub-tab — contribution table + per-goal draw table.
   Wide tables on a phone need horizontal scroll. */
.projection-goals-wrap { overflow-x: auto; }
#planned-schedule-table th,
#planned-schedule-table td {
  white-space: nowrap;
  padding: 6px 10px;
}
#planned-schedule-table .num { font-variant-numeric: tabular-nums; }
#planned-schedule-table tbody td.muted-cell { color: var(--muted); }
#contrib-table .num { font-variant-numeric: tabular-nums; }
#contrib-table tbody tr:nth-child(odd) { background: rgba(0,0,0,0.02); }

/* Projection's merged table — 7 columns (month + 2 contribs + 4 net-worth).
   Phones get horizontal scroll; visual separator between contrib group
   and net-worth group so the eye can parse the row halves. */
.projection-table-wrap {
  overflow-x: auto;
  max-width: 100%;
  -webkit-overflow-scrolling: touch;
}
.projection-merged { min-width: 640px; }
.projection-merged .proj-group-row th {
  font-family: "Manrope", system-ui, sans-serif !important;
  font-size: 10px !important;
  font-weight: 600 !important;
  letter-spacing: 0.5px !important;
  text-transform: uppercase !important;
  color: var(--muted) !important;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border);
}
.projection-merged .group-contrib { color: var(--accent) !important; }
.projection-merged .group-nw      { color: var(--text) !important; }
.projection-merged th.group-sep,
.projection-merged td.group-sep {
  border-left: 1px solid var(--border);
}
.projection-merged tbody tr:nth-child(odd) { background: rgba(0,0,0,0.02); }

/* Salary tab — auto-suggest panel */
.auto-suggest-card { margin-top: 14px; }
.auto-suggest-table .num { font-variant-numeric: tabular-nums; }
.auto-suggest-table tbody tr:nth-child(odd) { background: rgba(0,0,0,0.02); }
.auto-suggest-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
}
.auto-suggest-actions button {
  font-size: 12px;
  padding: 6px 14px;
}
.auto-suggest-actions .primary {
  background: var(--accent);
  color: var(--panel);
  border-color: var(--accent);
}
.auto-suggest-actions .primary:hover {
  filter: brightness(1.05);
}
.auto-suggest-actions #auto-apply-hint {
  font-size: 11px;
  flex: 1 1 200px;
}

/* Projection — Current / Recommended / Compare segmented control. */
.projection-mode-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin: 4px 0 10px;
  max-width: 100%;
  min-width: 0;
}
.projection-mode-seg {
  display: inline-flex;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--panel-2);
  gap: 2px;
}
.plan-pie-mode-seg {
  display: inline-flex;
}
.plan-pie-mode-seg[hidden] { display: none; }
.pie-block { display: flex; flex-direction: column; align-items: stretch; }
.pie-block .pie-wrap { justify-content: center; }
.pie-block .pie-title { text-align: center; }
.overview-mode-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  flex-wrap: wrap;
  margin: 0 0 12px;
  text-align: center;
}
.overview-mode-hint {
  font-size: 11px;
  flex: 0 1 auto;
  min-width: 0;
}
@media (max-width: 720px) {
  /* On phones the toggle pill consumes most of the row width; the hint
     would otherwise wrap mid-sentence beside it and look broken. Hide
     it — the Current / Recommended labels speak for themselves. */
  .overview-mode-hint { display: none; }
}
.planned-edit-card {
  width: min(520px, 100%);
  max-height: calc(100vh - 40px);
  overflow-y: auto;
}
/* Override the .add-form grid — the edit form is a vertical form
   inside a narrow modal, so labels stack and inputs span the full
   width. Two-column grid lets compact fields (amount, due, priority)
   sit alongside their siblings. */
.planned-edit-form.add-form {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px 14px;
  align-items: stretch;
  margin-top: 8px;
}
.planned-edit-form.add-form label {
  display: flex;
  flex-direction: column;
  gap: 5px;
  font-size: 10px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
  text-align: left;
}
.planned-edit-form.add-form label > input,
.planned-edit-form.add-form label > select,
.planned-edit-form.add-form label > .cat-combobox > input {
  font-size: 14px;
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--panel-2);
  color: var(--text);
  font-family: inherit;
  width: 100%;
  box-sizing: border-box;
  margin-top: 0;
}
.planned-edit-form.add-form label > input:focus,
.planned-edit-form.add-form label > select:focus,
.planned-edit-form.add-form label > .cat-combobox > input:focus {
  outline: none;
  border-color: var(--accent, #6cf);
}
/* Name + Note span the full row for breathing room. */
.planned-edit-form.add-form label:nth-of-type(1),
.planned-edit-form.add-form .planned-edit-note-row {
  grid-column: 1 / -1;
}
.planned-edit-actions {
  grid-column: 1 / -1;
  display: flex;
  justify-content: space-between;
  gap: 8px;
  margin-top: 6px;
}
.planned-edit-actions .ghost.danger { color: var(--bad, #f88); }
.planned-edit-actions button {
  padding: 10px 20px;
  font-size: 13px;
  border-radius: 999px;
  height: auto;
}
@media (max-width: 540px) {
  .planned-edit-form.add-form { grid-template-columns: 1fr; }
}
.planned-schedule-target th { color: var(--muted); font-weight: 500; }
.planned-schedule-short th { color: var(--text); }
.planned-schedule-short th.negative { color: var(--bad, #f88); font-weight: 600; }
.planned-atrisk {
  background: rgba(255, 140, 140, 0.06);
  border: 1px solid rgba(255, 140, 140, 0.4);
  border-radius: 12px;
  padding: 12px 14px;
  margin-bottom: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.planned-atrisk[hidden] { display: none; }
.planned-atrisk-head-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.planned-atrisk-head-bar strong { color: var(--bad, #f88); }
.planned-atrisk-icon {
  font-size: 16px;
  color: var(--bad, #f88);
}
.planned-atrisk-row {
  background: var(--panel-2);
  border-radius: 10px;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.planned-atrisk-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}
.planned-atrisk-name {
  font-weight: 600;
  font-size: 14px;
}
.planned-atrisk-kind {
  font-size: 9px;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  padding: 2px 6px;
  border-radius: 999px;
  background: rgba(115, 218, 202, 0.16);
  color: var(--joint, #6B958A);
}
.planned-atrisk-due {
  margin-left: auto;
  font-size: 11px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.3px;
}
.planned-atrisk-stats {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 8px 16px;
  font-variant-numeric: tabular-nums;
}
.planned-atrisk-stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.planned-atrisk-stat .muted {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
}
.planned-atrisk-stat strong { font-size: 14px; font-weight: 600; }
@media (max-width: 540px) {
  .planned-atrisk-stats { grid-template-columns: 1fr 1fr; }
}
.overview-compare-badge {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  font-weight: 600;
  color: var(--warn, #e0af68);
  background: rgba(224, 175, 104, 0.12);
  border: 1px solid rgba(224, 175, 104, 0.35);
  border-radius: 999px;
  padding: 3px 10px;
}
.overview-compare-badge[hidden] { display: none; }
.mode-btn {
  background: transparent;
  border: none;
  padding: 6px 14px;
  border-radius: 999px;
  font-family: "Manrope", system-ui, sans-serif !important;
  font-size: 11px !important;
  font-weight: 600 !important;
  letter-spacing: 0.5px !important;
  text-transform: uppercase !important;
  color: var(--muted);
  cursor: pointer;
  min-height: 26px;
  transition: background-color 140ms ease, color 140ms ease;
}
.mode-btn:hover { color: var(--text); }
.mode-btn.active {
  background: var(--panel);
  color: var(--accent);
  box-shadow: 0 1px 2px rgba(0,0,0,0.06);
}
.projection-mode-hint {
  font-size: 11px;
  flex: 1 1 200px;
}

/* Compare mode shows two tables stacked — title each one for clarity. */
.projection-table-title {
  margin: 14px 0 6px;
  font-family: "Manrope", system-ui, sans-serif !important;
  font-size: 11px !important;
  font-weight: 600 !important;
  letter-spacing: 0.7px !important;
  text-transform: uppercase !important;
  color: var(--muted) !important;
}

/* =========================================================================
   MOBILE OVERFLOW SAFETY NET
   `overflow-x: clip` (NOT `hidden`) — `hidden` on html+body together with
   body's `overscroll-behavior: contain` kills touch-scrolling on iOS
   Safari. `clip` clips children the same way but doesn't establish a
   scroll container, so vertical touch-scroll stays alive.
   ========================================================================= */
html, body {
  max-width: 100%;
  overflow-x: clip;
}
@media (max-width: 720px) {
  main { padding-left: 12px; padding-right: 12px; }
  .card { max-width: 100%; box-sizing: border-box; }
  .card-head { flex-wrap: wrap; }
  .data-table { max-width: 100%; }
  .auto-suggest-actions { flex-direction: column; align-items: stretch; }
  .auto-suggest-actions button { width: 100%; }
  .auto-suggest-actions #auto-apply-hint { text-align: center; flex: 1 1 100%; }
  /* Schedule strip on planned rows can have many cells — let it scroll
     horizontally rather than wrap awkwardly. */
  .planned-schedule { overflow-x: auto; }
  /* Chips row stays readable on phone by wrapping rather than scrolling. */
  .projection-compare-chips { flex-wrap: wrap; min-width: 0; }
}
.projection-leg-note {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 10px !important;
  text-transform: none !important;
  letter-spacing: 0.3px !important;
  color: var(--muted);
}
.projection-leg-note .leg-solid,
.projection-leg-note .leg-dashed {
  width: 18px;
  height: 0;
  display: inline-block;
  border-top: 2px solid var(--text);
  margin: 0 2px;
}
.projection-leg-note .leg-dashed {
  border-top-style: dashed;
  opacity: 0.55;
}
#projection-chart {
  width: 100%;
  max-width: 1440px;
  height: auto;
  display: block;
  margin: 0 auto;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--panel);
}
.projection-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  justify-content: center;
  margin-top: 10px;
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 11px;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--muted);
}
.projection-leg-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.projection-leg-item i {
  width: 12px;
  height: 3px;
  border-radius: 2px;
  display: inline-block;
}
.projection-table {
  margin-top: 10px;
  font-size: 12px;
}
.projection-table th { font-weight: 600; }
.projection-table td.num,
.projection-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.projection-table .negative { color: var(--bad); }
#projection-subtitle { font-size: 11px; }

/* Pending + done lists */
.planned-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 4px;
}
.planned-month-header {
  font-family: "Manrope", system-ui, sans-serif !important;
  font-size: 11px !important;
  font-weight: 600 !important;
  letter-spacing: 0.7px !important;
  text-transform: uppercase !important;
  color: var(--muted) !important;
  margin: 12px 0 2px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--border);
}
.planned-month-header:first-child { margin-top: 0; }

.planned-row {
  position: relative;
  display: grid;
  grid-template-columns: 1fr auto auto;
  grid-template-areas:
    "main amount actions"
    "progress progress progress"
    "progtext progtext progtext";
  gap: 6px 12px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--panel);
}
.planned-row.past-due {
  border-left: 3px solid var(--warn);
}
.planned-row.fully-funded {
  border-left: 3px solid var(--good);
}
.planned-row-main { grid-area: main; min-width: 0; }
.planned-row-name {
  font-weight: 600;
  color: var(--text);
}
.planned-row-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  margin-top: 4px;
}
.planned-row-meta .cat-pill,
.planned-row-meta .pill {
  font-size: 10px;
  padding: 1px 7px;
  border-radius: 999px;
  border: 1px solid;
  font-weight: 600;
  letter-spacing: 0.4px;
}
.planned-row-meta .planned-due {
  font-size: 11px;
  color: var(--muted);
  font-family: "Manrope", system-ui, sans-serif;
}
.planned-row-note {
  font-size: 11px !important;
  margin-top: 4px !important;
}
.planned-row-amount {
  grid-area: amount;
  font-family: "Fraunces", "Manrope", serif;
  font-size: 16px;
  font-weight: 500;
  color: var(--text);
  align-self: start;
}
.planned-row-actions {
  grid-area: actions;
  display: flex;
  gap: 2px;
  align-self: start;
}
.planned-row-actions .icon {
  width: 26px; height: 26px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 4px;
  background: transparent;
  color: var(--muted);
  font-size: 13px;
  cursor: pointer;
}
.planned-row-actions .icon:hover {
  border-color: var(--border);
  color: var(--text);
}
.planned-row-actions .planned-done-btn:hover { color: var(--good); }
.planned-row-actions .planned-del-btn:hover  { color: var(--bad); }

.planned-progress {
  grid-area: progress;
  height: 6px;
  background: var(--panel-2);
  border-radius: 999px;
  overflow: hidden;
}
.planned-progress-fill {
  height: 100%;
  background: var(--accent-2);
  border-radius: 999px;
  transition: width 220ms ease;
}
.planned-progress-text {
  grid-area: progtext;
  font-size: 11px;
  color: var(--muted);
  font-family: "Manrope", system-ui, sans-serif;
}

/* Past-due fully-funded done rows in the collapsed details card */
.planned-done-card summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: baseline;
  gap: 6px;
}
.planned-done-card summary::-webkit-details-marker { display: none; }
.planned-done-card .inline-h3 {
  display: inline;
  margin: 0;
  font-family: "Manrope", system-ui, sans-serif !important;
  font-size: 11px !important;
  font-weight: 600 !important;
  letter-spacing: 0.7px !important;
  text-transform: uppercase !important;
  color: var(--muted) !important;
}
.planned-done-list .planned-row {
  opacity: 0.7;
}

/* Dashboard "Upcoming Planned" card */
.upcoming-card .card-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}
.upcoming-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 8px;
}
.upcoming-row { display: flex; flex-direction: column; gap: 4px; }
.upcoming-row.past-due .upcoming-name { color: var(--warn); }
.upcoming-row-head {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-size: 12px;
}
.upcoming-name { font-weight: 600; color: var(--text); }
.upcoming-due { font-size: 11px; }
.upcoming-row-foot {
  font-size: 11px;
  font-family: "Manrope", system-ui, sans-serif;
}
.upcoming-empty { font-size: 12px; padding: 4px 0; }

.link-btn {
  background: transparent;
  border: none;
  padding: 0;
  color: var(--accent);
  font-family: "Manrope", system-ui, sans-serif !important;
  font-size: 11px !important;
  font-weight: 600 !important;
  letter-spacing: 0.4px !important;
  text-transform: uppercase !important;
  cursor: pointer;
}
.link-btn:hover { color: var(--text); }

/* =========================================================================
   Month / date input overflow fix
   Native <input type="month"> renders an internal stepper + a calendar
   picker icon that together make the control wider AND taller than a
   plain text/number input. In a tight auto-fit grid (.add-form,
   .form-row) the input pushes its cell past the minmax minimum and
   overlaps neighbors. Two fixes:
   1. Force min-width: 0 on the label (grid item) so the cell can shrink.
   2. Strip every internal sub-widget — spinner, picker icon, etc. — and
      size the input identically to text/number inputs. The whole input
      remains clickable to pop the native picker (label is still bound
      via for/id), so removing the icon doesn't hide functionality.
   ========================================================================= */
.add-form label,
.form-row label {
  min-width: 0 !important;
}
.add-form input[type="month"],
.add-form input[type="date"],
.form-row input[type="month"],
.form-row input[type="date"] {
  width: 100% !important;
  max-width: 100% !important;
  min-width: 0 !important;
  box-sizing: border-box !important;
  /* Match the size/typography of sibling number/text inputs exactly. */
  font-size: inherit;
  line-height: 1.4;
  appearance: none;
  -webkit-appearance: none;
}
.add-form input[type="month"],
.add-form input[type="date"] {
  font-size: 12px;
  padding: 5px 8px;
  border-radius: 8px;
  height: auto;
}
@media (max-width: 640px) {
  .add-form input[type="month"],
  .add-form input[type="date"] {
    font-size: 16px;       /* iOS focus-zoom safeguard */
    padding: 6px 10px;
  }
}
/* Hide every WebKit-internal sub-widget so the visible glyph is just
   the YYYY-MM text. Without this the picker icon and reset button
   eat ~25px and push content out of the cell on Safari/Chrome. */
.add-form input[type="month"]::-webkit-inner-spin-button,
.form-row input[type="month"]::-webkit-inner-spin-button,
.add-form input[type="date"]::-webkit-inner-spin-button,
.form-row input[type="date"]::-webkit-inner-spin-button,
.add-form input[type="month"]::-webkit-clear-button,
.form-row input[type="month"]::-webkit-clear-button,
.add-form input[type="date"]::-webkit-clear-button,
.form-row input[type="date"]::-webkit-clear-button,
.add-form input[type="month"]::-webkit-calendar-picker-indicator,
.form-row input[type="month"]::-webkit-calendar-picker-indicator,
.add-form input[type="date"]::-webkit-calendar-picker-indicator,
.form-row input[type="date"]::-webkit-calendar-picker-indicator {
  display: none !important;
  -webkit-appearance: none !important;
  appearance: none !important;
  width: 0;
  margin: 0;
  padding: 0;
}
/* The whole input stays clickable — pop the native picker from any tap. */
.add-form input[type="month"],
.form-row input[type="month"],
.add-form input[type="date"],
.form-row input[type="date"] {
  cursor: pointer;
}

/* =========================================================================
   PROJECTION ROW HOVER + MONTH-BREAKDOWN MODAL
   ========================================================================= */
.projection-row-click { cursor: pointer; transition: background 0.12s ease; }
.projection-row-click:hover { background: rgba(255,255,255,0.04); }
.projection-row-click:hover td:first-child { color: var(--accent, #6cf); }
.proj-h-ledger { font-size: 11.5px; }
.ledger-owed-a strong { color: var(--good, #4a8c3a); font-weight: 600; font-size: 11.5px; }
.ledger-owed-b strong { color: var(--accent, #c25a41); font-weight: 600; font-size: 11.5px; }

.month-breakdown-card {
  width: min(1080px, 100%);
  max-height: calc(100vh - 40px);
  overflow-y: auto;
}

/* --- Month-breakdown flow tree (Chintu → Joint ← Shanu) --- */
.mb-flow {
  display: grid;
  grid-template-columns: 1fr 1.15fr 1fr;
  gap: 14px;
  align-items: stretch;
}
.flow-col {
  display: flex;
  flex-direction: column;
  padding: 14px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  font-variant-numeric: tabular-nums;
}
.flow-col-center {
  background: rgba(194, 90, 65, 0.04);
  border-color: rgba(194, 90, 65, 0.20);
}
.flow-col-head {
  margin-bottom: 8px;
  padding-bottom: 8px;
  border-bottom: 1px dashed var(--border);
}
.flow-col-head h4 {
  margin: 0 0 4px;
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.flow-opening {
  font-size: 11.5px;
  color: var(--muted);
}
.flow-opening strong {
  color: var(--text);
  font-weight: 600;
  margin-left: 6px;
}
.flow-line {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  padding: 5px 0;
  font-size: 12.5px;
  border-bottom: 1px dotted rgba(80,45,20,0.08);
}
.flow-line:last-of-type { border-bottom: none; }

/* Expandable line: <details>/<summary>. The summary mirrors the
   non-expandable .flow-line layout so a closed <details> looks
   identical. The chevron rotates when open. */
.flow-line-expandable {
  display: block;
  padding: 0;
  border-bottom: 1px dotted rgba(80,45,20,0.08);
}
.flow-line-expandable > summary {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  padding: 5px 0;
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.flow-line-expandable > summary::-webkit-details-marker { display: none; }
.flow-line-expandable .flow-chev {
  display: inline-block;
  margin-left: 4px;
  font-size: 10px;
  color: var(--muted);
  transition: transform 160ms ease;
}
.flow-line-expandable[open] .flow-chev { transform: rotate(90deg); }
.flow-items-list {
  list-style: none;
  margin: 0 0 6px;
  padding: 4px 8px 6px 14px;
  background: rgba(80,45,20,0.03);
  border-left: 2px solid rgba(194,90,65,0.25);
  border-radius: 0 6px 6px 0;
}
.flow-item {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  padding: 3px 0;
  font-size: 11.5px;
  color: var(--muted);
}
.flow-item-label {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
  flex: 1 1 auto;
  color: var(--text);
}
.flow-item-sub {
  font-size: 10.5px;
  color: var(--muted);
  letter-spacing: 0.2px;
}
.flow-item-amount {
  font-variant-numeric: tabular-nums;
  color: var(--text);
  font-weight: 500;
}
.flow-label {
  color: var(--text);
  flex: 1 1 auto;
  min-width: 0;
}
.flow-amount {
  color: var(--text);
  font-weight: 600;
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
}
.flow-line.flow-in .flow-amount { color: var(--good, #4a8c3a); }
.flow-line.flow-out .flow-amount,
.flow-line.flow-contrib-out .flow-amount { color: var(--accent, #c25a41); }
.flow-line.flow-stay .flow-amount { color: var(--good, #4a8c3a); }
.flow-line.flow-drain .flow-amount { color: var(--bad, #c25a41); }
.flow-line.flow-contrib-out,
.flow-line.flow-contrib-in {
  margin-top: 4px;
  padding: 6px 8px;
  background: rgba(194, 90, 65, 0.06);
  border: 1px solid rgba(194, 90, 65, 0.18);
  border-radius: 8px;
  font-weight: 500;
}
.flow-line.flow-stay,
.flow-line.flow-drain {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
}
.flow-arrow {
  display: inline-block;
  color: var(--accent, #c25a41);
  font-weight: 700;
  margin-right: 4px;
}
.flow-col-foot {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 13px;
}
.flow-col-foot span {
  text-transform: uppercase;
  letter-spacing: 0.6px;
  font-size: 11px;
  color: var(--muted);
  font-weight: 600;
}
.flow-col-foot strong {
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 16px;
  font-weight: 700;
  color: var(--text);
}
.flow-col-foot strong.negative { color: var(--bad, #c25a41); }
@media (max-width: 800px) {
  .mb-flow {
    grid-template-columns: 1fr;
  }
  .flow-col-center { order: -1; }   /* Joint on top on mobile */
}
.mb-summary {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 16px;
  padding: 10px 12px;
  margin: 6px 0 14px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  font-variant-numeric: tabular-nums;
}
.mb-summary-row {
  display: contents;
  font-size: 12px;
  color: var(--muted);
}
.mb-summary-row strong { color: var(--text); font-weight: 600; }
.mb-summary-row.mb-summary-delta { font-size: 13px; padding-top: 4px; }
.mb-summary-row.mb-summary-delta span { color: var(--text); font-weight: 500; }

.mb-bucket {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 12px;
  margin-bottom: 12px;
  background: var(--panel-2);
}
.mb-bucket-head {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px 12px;
  padding-bottom: 8px;
  border-bottom: 1px dashed var(--border);
  margin-bottom: 8px;
}
.mb-bucket-head h4 {
  margin: 0;
  font-size: 13px;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--text);
}
.mb-balance-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-variant-numeric: tabular-nums;
  flex-wrap: wrap;
}
.mb-balance-pair {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
}
.mb-balance-label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--muted);
}
.mb-balance-pair strong { font-size: 14px; font-weight: 600; }
.mb-arrow { color: var(--muted); }
.mb-delta {
  font-size: 11px;
  padding: 2px 6px;
  border-radius: 6px;
  background: rgba(255,255,255,0.04);
  font-weight: 600;
}
.mb-delta.positive { color: var(--good, #6c9); background: rgba(108,200,150,0.10); }
.mb-delta.negative { color: var(--bad, #f88); background: rgba(255,140,140,0.10); }

.mb-section { margin-top: 6px; }
.mb-section > summary { list-style: none; cursor: pointer; }
.mb-section > summary::-webkit-details-marker { display: none; }
.mb-section-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--muted);
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
  user-select: none;
}
.mb-section-head:hover { color: var(--text); }
.mb-section-head .positive { color: var(--good, #6c9); }
.mb-section-head .negative { color: var(--bad, #f88); }
.mb-section-title {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.mb-chevron {
  display: inline-block;
  font-size: 9px;
  line-height: 1;
  transition: transform 0.15s ease;
  color: var(--muted);
  transform: rotate(0deg);
}
.mb-section[open] > summary .mb-chevron { transform: rotate(90deg); }
.mb-section-count {
  font-size: 10px;
  padding: 1px 6px;
  border-radius: 999px;
  background: rgba(255,255,255,0.05);
  font-weight: 500;
  letter-spacing: 0;
}

.mb-lines { list-style: none; padding: 0; margin: 0; }
.mb-line {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 2px 12px;
  padding: 4px 0;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  border-bottom: 1px solid rgba(255,255,255,0.03);
}
.mb-line:last-child { border-bottom: none; }
.mb-line-name { color: var(--text); }
.mb-line-sub {
  grid-column: 1;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  color: var(--muted);
}
.mb-line-amt {
  grid-row: 1 / span 2;
  grid-column: 2;
  align-self: center;
  font-weight: 500;
}
.mb-line-amt.positive { color: var(--good, #6c9); }
.mb-line-amt.negative { color: var(--bad, #f88); }

.mb-empty { padding: 6px 0; font-size: 12px; }

@media (max-width: 540px) {
  .month-breakdown-card { padding: 14px 14px 16px; }
  .mb-bucket-head h4 { font-size: 12px; }
  .mb-balance-pair strong { font-size: 13px; }
}

/* ---- Plan → Mode sub-tab: recommendation-mode chooser cards ---- */
.mode-tab-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
  margin: 4px 0 12px;
}
.mode-card {
  text-align: left;
  background: rgba(255,255,255,0.03);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 10px;
  padding: 14px 14px 12px;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.08s ease;
  display: flex;
  flex-direction: column;
  gap: 8px;
  color: inherit;
  font: inherit;
}
.mode-card:hover {
  background: rgba(255,255,255,0.05);
  border-color: rgba(255,255,255,0.18);
}
.mode-card:active { transform: scale(0.995); }
.mode-card.active {
  border-color: var(--accent, #6cf);
  background: rgba(108,207,255,0.08);
  box-shadow: inset 0 0 0 1px var(--accent, #6cf);
}
.mode-card-label {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.2px;
}
.mode-card-desc {
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted);
}
.mode-card-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: auto;
}
.mode-card-tag {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(255,255,255,0.05);
  color: var(--muted);
}
.mode-card.active .mode-card-tag {
  background: rgba(108,207,255,0.15);
  color: var(--accent, #6cf);
}
.mode-tab-foot {
  font-size: 12px;
  line-height: 1.6;
  padding-top: 6px;
  border-top: 1px solid rgba(255,255,255,0.05);
}

/* ====================================================================
   v3 dashboard layout
   Two-column shell: sticky sidebar (section nav) + flexing main.
   Replaces the old four-row stacked tab pattern with a single primary
   tab strip (Plan/Spending), a sidebar for sections, and a per-section
   page-header that hosts viewing + scenario controls.
   ==================================================================== */
.app-layout {
  display: flex;
  align-items: stretch;
  gap: 28px;
  padding: 0 var(--page-gutter, 28px);
  margin: 14px 0 0;
  min-height: 0;
  /* Full-bleed: no max-width. Layout fills the viewport, with only the
     `--page-gutter` padding for breathing room against the edges. */
  max-width: none;
  width: 100%;
}
.app-sidebar {
  flex: 0 0 220px;
  position: sticky;
  top: 16px;
  align-self: flex-start;
  padding: 6px 0;
  z-index: 5;
  transition: flex-basis 260ms cubic-bezier(0.4, 0, 0.2, 1);
}
/* Collapse toggle — small floating chevron pinned to the sidebar's
   trailing edge. Visible in both states; flips direction when the
   sidebar collapses. Hidden on mobile (sidebar is a horizontal strip
   there, no point collapsing). */
/* Collapse handle — refined "bookmark tab" shape attached to the
   sidebar's outer edge. Position:fixed so it escapes the sidebar's
   overflow clipping (overflow-y:auto forces overflow-x clipping too
   in every browser).

   Two instances exist: one anchored near the top, one vertically
   centered, both controlled by `.sidebar-toggle--top` / `--mid`. The
   handle tracks the sidebar's right edge across all states by
   animating `left` only. */
.sidebar-toggle {
  position: fixed;
  /* Expanded sidebar geometry: page-gutter (28) + sidebar (220) = 248
     right edge; tab sits flush against it. */
  left: 248px;
  width: 18px;
  height: 56px;
  min-height: 0;
  /* Flat on the left (attaches to whatever is to its left), rounded
     on the right — a literal pull-tab silhouette. */
  border-radius: 0 10px 10px 0;
  background: var(--panel);
  border: 1px solid var(--border-strong, var(--border));
  border-left: none;
  padding: 0;
  line-height: 1;
  font-size: 0;
  cursor: pointer;
  box-shadow: 4px 4px 16px -6px rgba(80, 45, 20, 0.28),
              1px 0 2px rgba(80, 45, 20, 0.10);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  z-index: 60;
  color: var(--muted);
  transition: left 260ms cubic-bezier(0.4, 0, 0.2, 1),
              background 200ms ease,
              border-color 200ms ease,
              color 200ms ease,
              width 200ms cubic-bezier(0.4, 0, 0.2, 1),
              box-shadow 200ms ease;
}
.sidebar-toggle--top { top: 22px; }
.sidebar-toggle--mid { top: 50vh; transform: translateY(-50%); }
/* Decorative inner rail — a 2px vertical accent line that hints at
   the affordance even without hovering. Subtle in resting state,
   brightens on hover. */
.sidebar-toggle-rail {
  position: absolute;
  left: 4px;
  top: 14px;
  bottom: 14px;
  width: 2px;
  border-radius: 2px;
  background: currentColor;
  opacity: 0.35;
  transition: opacity 200ms ease, background 200ms ease;
  pointer-events: none;
}
.sidebar-toggle-icon {
  display: block;
  margin-left: 4px;
  color: currentColor;
  transition: transform 280ms cubic-bezier(0.4, 0, 0.2, 1);
}
.sidebar-toggle:hover {
  width: 24px;
  background: var(--accent, var(--panel-2));
  border-color: var(--accent, var(--border-strong));
  color: var(--panel);
  box-shadow: 6px 6px 22px -6px rgba(80, 45, 20, 0.36),
              1px 0 2px rgba(80, 45, 20, 0.12);
}
.sidebar-toggle:hover .sidebar-toggle-rail { opacity: 0.7; }
.sidebar-toggle:active { width: 22px; }
.sidebar-toggle:focus-visible {
  outline: 2px solid var(--accent, var(--border-strong));
  outline-offset: 2px;
}

/* ──────────────────────────────────────────────────────────────────
   Collapsed sidebar: hover-reveal overlay pattern.

   When collapsed, the sidebar leaves the flex flow entirely and becomes
   a `position: fixed` overlay anchored to the viewport's left edge,
   hidden by `transform: translateX(-100%)`. A thin invisible
   `.sidebar-edge-zone` strip at the viewport's left edge catches
   mouse-enter and slides the sidebar into view. Mouse-leave slides it
   back out. The chevron toggle stays visible at the far-left so the
   user can also click to make the expanded state persistent again.

   This is the modern app pattern (VS Code / Linear / Notion-style):
   collapse reclaims the layout space, hover gives quick access without
   making the choice permanent.
   ────────────────────────────────────────────────────────────────── */
.sidebar-edge-zone {
  display: none;
}
.app-layout.sidebar-collapsed .sidebar-edge-zone {
  display: block;
  position: fixed;
  top: 0;
  left: 0;
  width: 18px;
  height: 100vh;
  z-index: 4;
}

.app-layout.sidebar-collapsed .app-sidebar {
  /* Out of flow → main reclaims the freed slot via flex 0 0 0.
     Full-height overlay: top:0, height:100vh so the slide-in panel
     spans edge-to-edge vertically. Hide animation uses `left` rather
     than `transform` — a transformed ancestor creates a new containing
     block for child `position: fixed` elements, which would otherwise
     drag the toggle chevron off-screen with the sidebar. */
  position: fixed;
  top: 0;
  left: -240px;
  width: 240px;
  max-width: 240px;
  height: 100vh;
  max-height: 100vh;
  flex: 0 0 0;
  padding: 22px 14px 22px;
  background: var(--bg-2);
  border: none;
  border-right: 1px solid var(--border);
  border-radius: 0;
  box-shadow:
    16px 0 32px -10px rgba(80, 45, 20, 0.22),
    4px 0 10px -4px rgba(80, 45, 20, 0.12);
  z-index: 50;
  transform: none;
  overflow-y: auto;
  overflow-x: visible;
  transition: left 260ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* Re-enable nav content when in collapsed-overlay mode — the slide does
   the hiding visually, no need for display:none. */
.app-layout.sidebar-collapsed .app-sidebar .tabs {
  display: inline-flex;
}
.app-layout.sidebar-collapsed .app-sidebar .subtabs.active {
  display: flex;
}
.app-layout.sidebar-collapsed .app-sidebar .subtabs:not(.active) {
  display: none;
}

/* Hover triggers — sliding in from the edge zone OR while the sidebar
   itself is hovered (so the panel stays open as you move into it).
   Also opens when the collapse handle is hovered, via :has(). */
.app-layout.sidebar-collapsed .sidebar-edge-zone:hover ~ .app-sidebar,
.app-layout.sidebar-collapsed .app-sidebar:hover,
.app-layout.sidebar-collapsed:has(.sidebar-toggle:hover) .app-sidebar {
  left: 0;
}

/* Chevron position + rotation when collapsed. -34px places it just
   outside the sidebar's right edge — in collapsed-hidden state the
   chevron lives at viewport x≈ -34 + 240 - 240 = -34 (off-screen) BUT
   since the sidebar is also out via translateX(-100%), the chevron's
   absolute position relative to the viewport is approximately at the
   sidebar's translated location. To always keep the chevron clickable
   at the viewport-left edge, we override its positioning specifically
   for the collapsed state below. */
/* Collapsed state — bookmark tab pinned at viewport's left edge
   (left: 0). The chevron flips to point right (= "open"). */
.app-layout.sidebar-collapsed .sidebar-toggle {
  left: 0;
}
.app-layout.sidebar-collapsed .sidebar-toggle-icon {
  transform: rotate(180deg);
}
/* Sidebar overlay open (edge-zone hovered, sidebar hovered, OR any
   collapse handle hovered via :has()). Slide BOTH handles alongside
   sidebar's right edge and flip chevron back to "close". */
.app-layout.sidebar-collapsed .sidebar-edge-zone:hover ~ .sidebar-toggle,
.app-layout.sidebar-collapsed .app-sidebar:hover ~ .sidebar-toggle,
.app-layout.sidebar-collapsed:has(.sidebar-toggle:hover) .sidebar-toggle {
  left: 240px;
}
.app-layout.sidebar-collapsed .sidebar-edge-zone:hover ~ .sidebar-toggle .sidebar-toggle-icon,
.app-layout.sidebar-collapsed .app-sidebar:hover ~ .sidebar-toggle .sidebar-toggle-icon,
.app-layout.sidebar-collapsed:has(.sidebar-toggle:hover) .sidebar-toggle .sidebar-toggle-icon {
  transform: rotate(0deg);
}

@media (max-width: 880px) {
  .sidebar-toggle, .sidebar-edge-zone { display: none; }
}

/* --- Page breadcrumb (shown only when sidebar is collapsed so the user
       knows where they are without the nav labels visible). ---------- */
.page-header-title-group {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.page-breadcrumb {
  display: none;
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--muted);
}
.page-breadcrumb-sep {
  margin: 0 6px;
  color: var(--border-strong);
}
/* Topbar breadcrumb under the "Couple Fund Manager" title is always
   visible — it's the only on-screen breadcrumb now. The legacy
   .page-breadcrumb inside each section's header stays hidden via the
   default `display: none` rule above. */
.brand-breadcrumb {
  display: block;
  margin-top: 4px;
}
.brand-breadcrumb:empty {
  display: none;
}
.app-layout > main {
  flex: 1 1 auto;
  min-width: 0;
  /* Override the legacy `main { max-width: 1200px; margin: 0 auto }`
     so the content area takes the full flex remainder beside the
     sidebar instead of staying boxed. */
  max-width: none;
  padding: 0;
  margin: 0;
}
/* Inside the sidebar, the .subtabs strip becomes a vertical list. Only
   the active group is visible (preserved from existing initTabs logic).
   Old horizontal margin/gutter is reset because the sidebar already
   provides its own positioning. */
.app-sidebar .subtabs {
  display: none;
  flex-direction: column;
  gap: 2px;
  margin: 0;
  padding: 0;
  border: none;
  flex-wrap: nowrap;
}
.app-sidebar .subtabs.active { display: flex; }
.app-sidebar .subtab {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  text-align: left;
  padding: 10px 14px;
  border: none;
  border-left: 2px solid transparent;
  border-bottom: none;
  border-radius: 0 8px 8px 0;
  background: transparent;
  color: var(--muted);
  font-family: "Manrope", system-ui, sans-serif;
  font-weight: 500;
  font-size: 13px;
  letter-spacing: 0;
  text-transform: none;
  cursor: pointer;
  box-shadow: none;
  transition: background 180ms ease, color 180ms ease, border-color 180ms ease;
}
.app-sidebar .subtab:hover {
  color: var(--text);
  background: rgba(80, 45, 20, 0.04);
  filter: none;
}
.app-sidebar .subtab:active { transform: none; }
.app-sidebar .subtab.active {
  color: var(--accent);
  background: rgba(194, 90, 65, 0.08);
  border-left-color: var(--accent);
  border-bottom-color: transparent;
  font-weight: 600;
}
/* On phone/tablet, sidebar collapses into a horizontal scrollable strip
   that reuses the same .subtabs / .subtab DOM. */
@media (max-width: 880px) {
  .app-layout {
    flex-direction: column;
    gap: 12px;
    padding: 0 16px;
    margin-top: 10px;
  }
  .app-sidebar {
    flex: 0 0 auto;
    position: static;
    padding: 0;
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .app-sidebar::-webkit-scrollbar { display: none; }
  .app-sidebar .subtabs {
    flex-direction: row;
    gap: 4px;
    width: max-content;
    padding: 4px 0 6px;
  }
  .app-sidebar .subtab {
    border-left: none;
    border-bottom: 2px solid transparent;
    border-radius: 8px;
    padding: 8px 12px;
    flex-shrink: 0;
    width: auto;
  }
  .app-sidebar .subtab.active {
    border-left-color: transparent;
    border-bottom-color: var(--accent);
    border-radius: 8px;
  }
}

/* --- Page header (per-section title strip) --- */
.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin: 4px 0 18px;
  padding: 0;
  border: none;
  background: none;
  /* Stacking-context: needed so the viewing dropdown menu (absolutely
     positioned inside) paints above the cards that follow in the DOM. */
  position: relative;
  z-index: 20;
}
.page-title {
  font-family: "Fraunces", "Times New Roman", serif;
  font-weight: 500;
  font-size: 22px;
  letter-spacing: -0.3px;
  margin: 0;
  color: var(--text);
}
.page-header-tools {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

/* --- Viewing dropdown --- */
.viewing-dropdown { position: relative; }
.viewing-trigger {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 3px 12px;
  height: 28px;
  min-height: 0;
  line-height: 1;
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 11px;
  font-weight: 500;
  color: var(--text);
  cursor: pointer;
  box-shadow: none;
  letter-spacing: 0;
  text-transform: none;
  transition: border-color 180ms ease, background 180ms ease;
}
.viewing-trigger:hover {
  border-color: var(--border-strong);
  filter: none;
}
.viewing-trigger:active { transform: none; }
.viewing-label {
  color: var(--muted);
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: 0.7px;
  font-weight: 600;
}
.viewing-value {
  color: var(--accent);
  font-weight: 600;
  letter-spacing: 0.1px;
}
.viewing-chevron {
  font-size: 9px;
  color: var(--muted);
  margin-left: 2px;
  transition: transform 180ms ease;
  line-height: 1;
}
.viewing-dropdown.open .viewing-chevron { transform: rotate(180deg); }
.viewing-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 200px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 4px;
  box-shadow:
    0 1px 0 rgba(255,255,255,0.6) inset,
    0 12px 30px -10px rgba(80, 45, 20, 0.30),
    0 4px 10px -4px rgba(80, 45, 20, 0.12);
  z-index: 1000;
}
.viewing-option {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: none;
  border-radius: 8px;
  padding: 9px 12px;
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text);
  cursor: pointer;
  box-shadow: none;
  transition: background 140ms ease, color 140ms ease;
}
.viewing-option:hover {
  background: rgba(80, 45, 20, 0.05);
  filter: none;
}
.viewing-option:active { transform: none; }
.viewing-option.active {
  background: rgba(194, 90, 65, 0.10);
  color: var(--accent);
  font-weight: 600;
}

/* --- Scenario toggle (Current / Recommended segmented control) --- */
.scenario-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0;
  height: 28px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px;
  box-shadow: inset 0 1px 2px rgba(80, 45, 20, 0.04);
}
.scenario-btn {
  background: transparent;
  border: none;
  padding: 0 12px;
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.4px;
  color: var(--muted);
  cursor: pointer;
  border-radius: 999px;
  box-shadow: none;
  min-height: 0;
  height: 22px;
  white-space: nowrap;
  transition: color 180ms ease, background 200ms ease, box-shadow 200ms ease;
}
.scenario-btn:hover { color: var(--text); filter: none; }
.scenario-btn:active { transform: none; }
.scenario-btn.active {
  background: var(--accent);
  color: #FFFCF4;
  box-shadow:
    0 1px 0 rgba(255,255,255,0.25) inset,
    0 2px 6px -2px rgba(194, 90, 65, 0.4);
}

/* --- Plan / Spending top tabs — now lives inside the sidebar, sitting
       above the section nav. Spans the sidebar's full width so it reads
       as a single left-column block with the sub-tabs below. ----------- */
.app-sidebar .tabs {
  display: inline-flex;
  margin: 0 0 14px;
  padding: 4px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 999px;
  box-shadow: 0 1px 0 rgba(255,255,255,0.4) inset;
  gap: 2px;
  width: 100%;
  box-sizing: border-box;
}
.app-sidebar .tab {
  flex: 1 1 0;
  padding: 7px 14px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0;
  border: 1px solid transparent;
  text-align: center;
}
.app-sidebar .tab.active {
  background: var(--accent);
  color: #FFFCF4;
  border-color: var(--accent);
  box-shadow:
    0 1px 0 rgba(255,255,255,0.25) inset,
    0 4px 10px -4px rgba(194, 90, 65, 0.45);
}

/* --- Deprecated legacy controls — hide entirely now that they're moved
       into the page-header. Selectors kept for backward-compat in any
       JS sync paths. --- */
.view-picker-row,
.view-picker,
.overview-mode-row {
  display: none !important;
}

/* --- Joint buffer target card --- */
#joint-buffer-card { margin-top: 16px; }
.joint-buffer-row {
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: flex-start;
  padding-top: 6px;
}
.joint-buffer-label {
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
}
.joint-buffer-input {
  width: 80px;
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--panel);
  color: var(--text);
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 14px;
  font-weight: 600;
}
.joint-buffer-foot {
  font-size: 12.5px;
  line-height: 1.5;
}

/* --- Fairness policy card (Settings → strict / over-time per mode) --- */
#fairness-policy-card { margin-top: 16px; }
.fairness-row {
  padding: 14px 0;
  border-top: 1px solid var(--border);
}
.fairness-row:first-of-type { border-top: none; padding-top: 4px; }
.fairness-row-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 4px;
}
.fairness-row-head h4 {
  margin: 0;
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
}
.fairness-seg {
  display: inline-flex;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px;
  height: 28px;
  box-shadow: inset 0 1px 2px rgba(80, 45, 20, 0.04);
}
.fairness-btn {
  background: transparent;
  border: none;
  padding: 0 12px;
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.4px;
  color: var(--muted);
  cursor: pointer;
  border-radius: 999px;
  box-shadow: none;
  min-height: 0;
  height: 22px;
  white-space: nowrap;
  transition: color 180ms ease, background 200ms ease, box-shadow 200ms ease;
}
.fairness-btn:hover { color: var(--text); }
.fairness-btn.active {
  background: var(--accent);
  color: #FFFCF4;
  box-shadow: 0 1px 0 rgba(255,255,255,0.25) inset, 0 2px 6px -2px rgba(194, 90, 65, 0.4);
}
.fairness-desc {
  margin: 4px 0 8px;
  font-size: 12.5px;
  line-height: 1.5;
}
.ledger-card {
  margin-top: 8px;
  padding: 10px 14px;
  background: rgba(194, 90, 65, 0.06);
  border: 1px solid rgba(194, 90, 65, 0.18);
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.ledger-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.ledger-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--muted);
  font-weight: 600;
}
.ledger-value {
  font-family: "Manrope", system-ui, sans-serif;
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
}
.ledger-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: 12px;
  color: var(--muted);
}

/* =========================================================================
   MOBILE — definitive overrides for phone widths.

   The cascade above is layered: there are at least four separate `.tabs`
   blocks (desktop pill, desktop-collapsed, mobile bottom nav at one
   breakpoint, mobile bottom nav at another), plus a high-specificity
   `.app-sidebar .tabs` desktop block. On phones, the desktop block was
   winning on specificity for things like `display: inline-flex` and
   `border-radius: 999px`, leaving the bottom nav off-screen-shaped or
   invisible. Rather than untangle 6,000 lines of CSS, we put one final
   high-specificity, !important-marked block at the end of the cascade so
   it wins on every property that matters for mobile.
   ========================================================================= */
@media (max-width: 640px) {

  /* --- Bottom navigation bar (Plan / Spending) ---------------------------
     Minimal: flat panel, hairline top divider, no shadow, no pill on the
     active tab. Active state is JUST a color change to the accent —
     standard iOS bottom-nav language. Smaller icons + smaller label so
     the bar reads as a single thin strip, not a chunky bar. */
  .app-sidebar .tabs {
    position: fixed !important;
    left: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    z-index: 100 !important;
    width: 100% !important;
    max-width: none !important;
    margin: 0 !important;
    padding: 4px 0 !important;
    padding-bottom: calc(4px + env(safe-area-inset-bottom)) !important;
    background: var(--panel) !important;
    border: none !important;
    border-top: 1px solid rgba(80, 45, 20, 0.10) !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    display: flex !important;
    flex-direction: row !important;
    justify-content: space-around !important;
    align-items: stretch !important;
    gap: 0 !important;
    overflow: visible !important;
  }
  .app-sidebar .tabs .tab {
    flex: 1 1 0 !important;
    min-width: 0 !important;
    min-height: 44px !important;
    padding: 4px 0 2px !important;
    margin: 0 !important;
    background: transparent !important;
    border: none !important;
    border-radius: 0 !important;
    color: var(--muted) !important;
    opacity: 0.7 !important;
    display: flex !important;
    flex-direction: column !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 3px !important;
    font-family: "Manrope", system-ui, sans-serif !important;
    font-size: 10px !important;
    font-weight: 500 !important;
    letter-spacing: 0.4px !important;
    text-transform: none !important;
    text-align: center !important;
    line-height: 1 !important;
    box-shadow: none !important;
  }
  .app-sidebar .tabs .tab::before {
    width: 19px !important;
    height: 19px !important;
  }
  .app-sidebar .tabs .tab.active {
    background: transparent !important;
    color: var(--accent) !important;
    opacity: 1 !important;
    font-weight: 600 !important;
  }
  /* Subtabs row should sit BELOW the topbar in normal flow (not the
     bottom-fixed nav). The wider 880px rule already does most of this;
     we just make sure they don't get squished by the higher-specificity
     desktop tab block. */
  .app-sidebar .subtabs {
    margin: 0 !important;
    width: 100% !important;
  }
  /* Reserve scroll room at the bottom of every page so content scrolls
     clear of the fixed nav bar. */
  main, .foot { padding-bottom: calc(80px + env(safe-area-inset-bottom)) !important; }

  /* --- Compact expanded edit card -----------------------------------------
     Every wasted pixel on the form turns into a swipe. Pack labels +
     inputs as tight as possible without breaking iOS focus-zoom safety
     (input font-size must stay >= 16px or Safari will auto-zoom on tap). */
  .editable-table tr {
    padding: 8px 10px 6px !important;
    row-gap: 4px !important;
    column-gap: 8px !important;
    border-color: rgba(80, 45, 20, 0.12) !important;
  }
  .editable-table td::before {
    font-size: 9px !important;
    letter-spacing: 0.5px !important;
    margin-bottom: 1px !important;
    color: var(--muted) !important;
    opacity: 0.65 !important;
    line-height: 1 !important;
  }
  .editable-table input,
  .editable-table select {
    padding: 2px 0 3px !important;
    background: transparent !important;
    border: none !important;
    border-bottom: 1px solid rgba(80, 45, 20, 0.15) !important;
    border-radius: 0 !important;
    /* Smaller than the category section header (11px uppercase). The
       viewport meta sets `maximum-scale=1` so this can safely go below
       the iOS 16px focus-zoom threshold without triggering a zoom. */
    font-size: 13px !important;
    line-height: 1.2 !important;
    min-height: 0 !important;
    margin: 0 !important;
  }
  /* Make category section headers stand out as the strongest type in the
     editable-table — they're the only navigational landmark when the rest
     of the form is intentionally quiet. */
  .editable-table tr.category-header > td {
    font-weight: 800 !important;
    color: var(--text) !important;
    opacity: 1 !important;
  }

  /* --- Apply the same compact-input treatment to EVERY form across the
         app (Add expense / Add savings / Add planned / Settings / etc.),
         not just the editable-table. -------------------------------------- */
  .add-form input,
  .add-form select,
  .add-form textarea,
  .add-card input,
  .add-card select,
  .add-card textarea,
  .card input[type="text"],
  .card input[type="number"],
  .card input[type="date"],
  .card input[type="month"],
  .card select,
  .card textarea,
  #joint-buffer-card input,
  #fairness-policy-card input,
  #fairness-policy-card select,
  #partners-form input,
  #partners-form select {
    font-size: 13px !important;
    line-height: 1.2 !important;
    min-height: 0 !important;
  }
  /* Optional polish: lighter input chrome for the add-* forms to match the
     editable-table card styling. Borderless with a thin baseline so the
     forms feel consistent everywhere. */
  .add-form input,
  .add-form select,
  .add-form textarea,
  .add-card input,
  .add-card select,
  .add-card textarea {
    padding: 4px 0 4px !important;
    background: transparent !important;
    border: none !important;
    border-bottom: 1px solid rgba(80, 45, 20, 0.15) !important;
    border-radius: 0 !important;
    margin: 0 !important;
  }
  .add-form input:focus,
  .add-form select:focus,
  .add-form textarea:focus,
  .add-card input:focus,
  .add-card select:focus,
  .add-card textarea:focus {
    outline: none !important;
    border-bottom-color: var(--accent) !important;
  }
  /* Custom select chevron for the add-* forms — same SVG we use in
     editable-table. */
  .add-form select,
  .add-card select {
    appearance: none !important;
    -webkit-appearance: none !important;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path d='M1 1l4 4 4-4' fill='none' stroke='rgba(80,45,20,0.5)' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/></svg>") !important;
    background-repeat: no-repeat !important;
    background-position: right 4px center !important;
    background-size: 10px 6px !important;
    padding-right: 20px !important;
  }
  /* Field labels above add-form inputs (matches the editable-table label
     scale so the two form styles look identical). */
  .add-form label,
  .add-card label {
    font-size: 9px !important;
    letter-spacing: 0.5px !important;
    opacity: 0.65 !important;
    color: var(--muted) !important;
    margin-bottom: 1px !important;
    line-height: 1 !important;
  }

  /* --- Section / card headers go BOLD across the project so they read as
         the dominant landmarks, matching what we just did for the
         editable-table category headers. ----------------------------------- */
  .card-head h3,
  .card h3,
  .add-card h3,
  .account-card h3,
  .pie-title,
  .projection-table-title {
    font-weight: 800 !important;
    color: var(--text) !important;
    opacity: 1 !important;
  }
  /* Sub-section h4 stays one step lighter so the hierarchy is preserved. */
  .card h4,
  .account-card h4,
  .fairness-row-head h4 {
    font-weight: 700 !important;
  }

  /* --- Planned row: stop the grid-template-areas layout from collapsing on
         narrow widths (it was producing visual overlap of name + amount).
         Replace with a simple stacked block — name + amount on the top row
         via inline flex, meta pills below, progress + schedule below that,
         actions absolutely positioned in the top-right corner. ------------ */
  .planned-row {
    display: block !important;
    grid-template-columns: none !important;
    grid-template-areas: none !important;
    position: relative !important;
    padding: 12px 88px 12px 14px !important;  /* right padding reserves room for the absolute actions */
  }
  .planned-row-main {
    display: block !important;
    grid-area: auto !important;
    min-width: 0 !important;
  }
  .planned-row-amount {
    grid-area: auto !important;
    display: block !important;
    margin-top: 6px !important;
    font-size: 18px !important;
    font-weight: 600 !important;
  }
  .planned-row-actions {
    grid-area: auto !important;
    position: absolute !important;
    top: 8px !important;
    right: 8px !important;
    display: flex !important;
    gap: 2px !important;
  }
  .planned-progress {
    grid-area: auto !important;
    margin-top: 8px !important;
  }
  .planned-progress-text,
  .planned-schedule,
  .planned-schedule-text {
    grid-area: auto !important;
  }
  .editable-table input:focus,
  .editable-table select:focus {
    outline: none !important;
    border-bottom-color: var(--accent) !important;
  }
  /* Amount cell sits on its own row by spec but doesn't need a separate
     bottom section visually — collapse the gap and align the value with
     the rest of the fields. */
  #expenses-table tr td:nth-child(8),
  #expenses-table-recurring tr td:nth-child(8),
  #savings-table tr td:nth-child(7) {
    margin-top: 2px !important;
    padding-top: 2px !important;
    border-top: none !important;
  }
  /* Hide the empty "Anchor" / "Deadline" cell labels when the value is
     literally "N/A" — saves another row of dead pixels. (Pure CSS — we
     can't read input values, but the empty deadline date input is the
     common case for monthly cadences.) */
  .editable-table input[type="date"]:placeholder-shown,
  .editable-table input[type="month"]:placeholder-shown {
    padding: 1px 0 !important;
  }
  /* Custom select arrow — the native iOS chevron (◊) is ugly and sits
     right at the card edge. Replace with a subtle ▾ on the right via
     a CSS background-image so it tracks the input bounds. */
  .editable-table select {
    appearance: none !important;
    -webkit-appearance: none !important;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path d='M1 1l4 4 4-4' fill='none' stroke='rgba(80,45,20,0.5)' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/></svg>") !important;
    background-repeat: no-repeat !important;
    background-position: right 4px center !important;
    background-size: 10px 6px !important;
    padding-right: 20px !important;
  }
  /* Date inputs render with their own native chrome on iOS — flat-line the
     visual to match other fields. */
  .editable-table input[type="date"],
  .editable-table input[type="month"] {
    background: transparent !important;
  }

  /* --- Wide tables: scroll affordance on the right edge -------------------
     iOS Safari hides scrollbars by default, so a horizontally-scrollable
     table looks like a clipped table to the user — they don't know there's
     more content to the right. Add a soft fade on the right edge so the
     "there's more" hint is always visible. The fade disappears (visually)
     once the user has scrolled to the end, courtesy of `scroll-snap-type`
     keeping each column flush with the viewport edge.

     The wrap also gets snap behaviour so swipes feel deliberate (column
     by column) rather than freely sliding past important cells. */
  .projection-table-wrap,
  .projection-goals-wrap {
    position: relative !important;
    -webkit-overflow-scrolling: touch !important;
    scroll-snap-type: x proximity !important;
    /* Mask-based fade — only fades the right edge, leaves the rest opaque.
       Pure CSS, no extra DOM. Falls back to no fade on browsers without
       mask-image, which still renders the table normally. */
    -webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 32px), transparent 100%);
            mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 32px), transparent 100%);
  }
  /* Re-enable a full mask once the wrap is scrolled to the very end —
     done via a CSS @container or :scope animation isn't possible without
     JS, so we keep the gradient permanent. A 32px fade is gentle enough
     that the final column is still legible behind the mask. */
  .projection-table th,
  .projection-table td {
    scroll-snap-align: start !important;
  }
  /* Tighter column padding on phones — the projection table has 7-9
     columns of numbers, every saved pixel means one less swipe to see
     all of them. */
  .projection-table th,
  .projection-table td {
    padding: 6px 8px !important;
    font-size: 12px !important;
  }
  .projection-merged .proj-group-row th {
    padding: 4px 8px 6px !important;
  }
  /* Lower the forced min-width on phones — the desktop comment specified
     640px to keep all 7 columns at desktop widths but on a 390px screen
     it just amplifies how far you have to scroll. With tighter padding
     above, a 520px min-width still keeps every column legible. */
  .projection-merged { min-width: 520px !important; }
}


