:root {
  font-family: system-ui, sans-serif;
  color-scheme: light dark;
  /* Ember Ledger (design system artifact): warm cream ground, deep brown
     ink, one terracotta action colour. */
  --surface: #fbf6ef;      /* surface */
  --card: #ffffff;         /* surface-raised */
  --sunken: #f3eadd;       /* surface-sunken: inputs, tracks */
  --line: #e6d9c8;         /* border */
  --text: #2b2118;         /* ink */
  --text-2: #6e5e50;       /* ink-muted */
  --text-3: #8c7b6b;       /* hints and axes, a step below ink-muted (not in the system) */
  --series-plan: #4e8a87;  /* categorical slot 1: cat-bills, the one cool hue */
  --series-whatif: #b54a24; /* categorical slot 2: primary terracotta */
  --status-good: #3f6b2e;  /* income */
  --status-critical: #b3261e; /* over-budget, reserved */
  --warning: #8a5a0c;      /* warning */
  --accent: #b54a24;       /* primary */
  --on-accent: #ffffff;    /* on-primary */
  --gap: .75rem;
}
@media (prefers-color-scheme: dark) {
  :root {
    --surface: #1c1814;
    --card: #28221d;
    --sunken: #14110e;
    --line: #3b332b;
    --text: #f3ece3;
    --text-2: #b8a99a;
    --text-3: #8c7b6b;
    --series-plan: #7db8b4;
    --series-whatif: #e8875f;
    --status-good: #9cc47f;
    --status-critical: #ff8a80;
    --warning: #f2c46b;
    --accent: #e8875f;
    --on-accent: #2b1408;
  }
}

/* ---- app shell: the page itself never scrolls; panes scroll inside ---- */
html, body { height: 100%; }
body { margin: 0; display: flex; flex-direction: column; overflow: hidden; background: var(--surface); color: var(--text); accent-color: var(--accent); }
header { flex: none; display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding: .6rem 1rem; border-bottom: 1px solid var(--line); background: var(--card); }
header a { color: inherit; text-decoration: none; }
nav { display: flex; gap: 1rem; }
nav a { color: var(--text-2); padding: .25rem 0; }
nav a.active { color: var(--text); font-weight: 600; }
main { flex: 1; min-height: 0; display: flex; flex-direction: column; width: 100%; max-width: 96rem; margin: 0 auto; padding: var(--gap) 1rem 1rem; box-sizing: border-box; }
.app { flex: 1; min-height: 0; display: grid; gap: var(--gap); }
/* a pane is a column that gives its spare height to .scroll */
.pane { min-height: 0; display: flex; flex-direction: column; }
.pane > .scroll { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.pane > h2, .pane > .hint, .pane > form, .pane > .fields, .pane > h3, .pane > .card-head { flex: none; }
/* list header: title + "+ Add", which opens that list's add dialog */
.card-head { display: flex; align-items: center; justify-content: space-between; gap: .5rem; margin: 0 0 .5rem; }
.card-head h2 { margin: 0; }
.add-btn { border: 1px solid var(--accent); background: none; color: var(--accent); border-radius: .4rem; padding: .3rem .8rem; font-weight: 600; }
.add-btn:hover { background: var(--accent); color: var(--on-accent); }
dialog select { width: 100%; }

h1 { font-size: 1.5rem; margin: 0; }
h2 { font-size: 1.1rem; margin: 0 0 .5rem; }
h3 { font-size: .95rem; margin: .75rem 0 .4rem; color: var(--text-2); }
/* 1rem text in fields keeps iOS from zooming into them on focus */
input, select, button { font: inherit; font-size: 1rem; }
button { cursor: pointer; padding: .4rem .8rem; background: var(--sunken); color: var(--text); border: 1px solid var(--text-3); border-radius: .4rem; }
button:disabled { cursor: default; opacity: .5; }
button.icon { padding: 0 .4rem; border: 0; background: none; color: var(--text-3); font-size: 1.1rem; }
button.icon:hover { color: var(--status-critical); }
input, select { padding: .4rem; min-width: 0; max-width: 100%; box-sizing: border-box; }
input:not([type=range], [type=checkbox], [type=file], [type=hidden]), select, textarea { background: var(--sunken); color: var(--text); border: 1px solid var(--text-3); border-radius: .4rem; }
form { display: flex; gap: .5rem; flex-wrap: wrap; margin: .6rem 0 0; }
form > input { flex: 1; }
label { display: flex; flex-direction: column; gap: .25rem; font-size: .85rem; color: var(--text-2); }
label input { color: var(--text); }
.card { background: var(--card); border: 1px solid var(--line); border-radius: .5rem; padding: .85rem; box-sizing: border-box; }
.fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr)); gap: .6rem; }
.hint { color: var(--text-3); font-size: .85rem; margin: 0 0 .5rem; }
.when { color: var(--text-3); font-size: .85rem; }
.status { font-size: .9rem; margin: .4rem 0 0; }
.status.good { color: var(--status-good); }
.status.critical { color: var(--status-critical); }

/* ---- plan page: chart + afford | needs ---- */
#plan { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); }
#plan .pane-plan { display: flex; flex-direction: column; min-height: 0; gap: var(--gap); }
#plan .pane-plan .afford { flex: none; }
/* segmented switch: Chart | Needs on phones, Spent | Received always */
.seg { display: none; gap: .25rem; padding: .2rem; border-radius: .5rem; background: var(--line); }
.seg a, .seg button { flex: 1; border: 0; background: none; padding: .35rem .9rem; border-radius: .35rem; color: var(--text-2); text-decoration: none; text-align: center; font-size: .9rem; }
.seg .active { background: var(--card); color: var(--text); font-weight: 600; }
.seg.sub { display: flex; margin-left: auto; }
.month-nav .seg a { font-size: .9rem; color: var(--text-2); }
.month-nav .seg a.active { color: var(--text); }

/* ---- accounts and budget: a summary over two list cards ---- */
#accounts, #budget { grid-template-rows: minmax(0, 1fr); }
.board { min-height: 0; display: grid; gap: var(--gap); grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
.board > .summary { grid-column: 1 / -1; padding: 0 .25rem; }
.board > .summary .hint { flex-basis: 100%; margin: 0; }
.list form.add { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; }
.list form.add .wide { grid-column: 1 / -1; }
.list form.add > * { width: 100%; min-width: 0; }
#accounts .list form.add button { grid-column: auto; }
#budget .list form.add button { grid-column: 1 / -1; }
/* settings: plan knobs | expense input choice with a live preview */
#settings { grid-template-columns: minmax(0, 26rem) minmax(0, 34rem); align-content: start; overflow-y: auto; }
#settings > .pane { min-height: auto; } /* each card as tall as its content: the picker preview must not spill into the next */
.pickers { display: grid; gap: .4rem; margin-bottom: .75rem; }
.choice { flex-direction: row; align-items: flex-start; gap: .6rem; padding: .5rem .6rem; border: 1px solid var(--line); border-radius: .5rem; cursor: pointer; color: var(--text); font-size: .95rem; }
.choice:has(input:checked) { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.choice input { margin-top: .2rem; }
.choice span { display: flex; flex-direction: column; gap: .1rem; }
.choice small { color: var(--text-3); font-size: .8rem; }

/* accounts: edits wait for Save; a changed row and the save bar say so */
.budget .was { display: none; font-size: .75rem; color: var(--text-3); }
.budget .term { display: block; font-size: .75rem; color: var(--text-2); }
.budget.changed .was { display: block; }
.budget.changed input { border-color: var(--series-whatif); box-shadow: 0 0 0 1px var(--series-whatif); }
.budget.changed .name::before { content: "● "; color: var(--series-whatif); }
.accounts .budget .name { display: block; }
.choice input { flex: none; }
[hidden] { display: none !important; }
.budget .name.link { border: 0; background: none; padding: 0; text-align: left; color: var(--text); font-size: 1rem; cursor: pointer; }
.budget .name.link:hover { color: var(--accent); text-decoration: underline; }

/* ---- drag pickers for an expense amount (picker.js) ---- */
.picker { margin: .25rem 0; outline: none; user-select: none; -webkit-user-select: none; }
.picker-readout { font-size: 1.6rem; font-weight: 700; text-align: center; font-variant-numeric: tabular-nums; }
.pk-hint { font-size: .8rem; color: var(--text-3); text-align: center; margin: .35rem 0 0; }
.pk-track { position: relative; height: 2.75rem; border-radius: 1.4rem; background: var(--line); touch-action: none; cursor: pointer; margin: .6rem 0 .3rem; }
.pk-fill { position: absolute; inset: 0 auto 0 0; border-radius: 1.4rem; background: var(--accent); opacity: .35; }
.pk-thumb { position: absolute; top: 50%; width: 2.3rem; height: 2.3rem; transform: translate(-50%, -50%); border-radius: 50%; background: var(--card); border: 3px solid var(--accent); box-sizing: border-box; }
.pk-ticks { position: relative; height: 1rem; font-size: .7rem; color: var(--text-3); }
.pk-ticks span { position: absolute; transform: translateX(-50%); white-space: nowrap; }
.pk-ticks span:first-child { transform: none; }
.pk-ticks span:last-child { transform: translateX(-100%); }
.pk-dial-wrap { position: relative; width: min(14rem, 100%); margin: 0 auto; }
.pk-dial { width: 100%; display: block; touch-action: none; cursor: grab; }
.pk-arc-bg { fill: none; stroke: var(--line); stroke-width: 16; stroke-linecap: round; }
.pk-arc { fill: none; stroke: var(--accent); stroke-width: 16; stroke-linecap: round; }
.pk-knob { fill: var(--card); stroke: var(--accent); stroke-width: 4; }
.pk-dial-wrap .picker-readout { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 1.3rem; pointer-events: none; }
.pk-pad { touch-action: none; border: 1px dashed var(--text-3); border-radius: .6rem; padding: .8rem .5rem; text-align: center; cursor: ns-resize; }
.pk-scrub { position: relative; height: 15rem; padding: 0; border-radius: 0; display: grid; place-items: center; cursor: move; overflow: hidden; user-select: none; }
.picker-scrub .picker-readout { margin-bottom: .5rem; }
.pk-scrub-dot { position: absolute; display: none; pointer-events: none; width: 1.6rem; height: 1.6rem; border-radius: 50%; border: 2px solid var(--accent); background: color-mix(in srgb, var(--accent) 25%, transparent); transform: translate(-50%, -50%); }
.pk-scrub.held .pk-scrub-dot { display: block; }
.pk-scale { position: absolute; inset: 0; pointer-events: none; }
.pk-scale .cross { position: absolute; background: var(--text-3); opacity: .35; }
.pk-scale .cross.h { width: 100%; height: 1px; }
.pk-scale .cross.v { height: 100%; width: 1px; }
.pk-scale .line { position: absolute; background: var(--text-3); opacity: .5; }
.pk-scale .line.from-left, .pk-scale .line.from-right { width: 1px; height: 100%; }
.pk-scale .line.from-top, .pk-scale .line.from-bottom { height: 1px; width: 100%; }
.pk-scale b { position: absolute; font-weight: 400; font-size: .75rem; color: var(--text-2); white-space: nowrap; font-variant-numeric: tabular-nums; }
.pk-scale b.now { color: var(--accent); font-weight: 600; font-size: .85rem; }
.pk-scale b.from-left { transform: translate(6px, -50%); }
.pk-scale b.from-right { transform: translate(calc(-100% - 6px), -50%); }
.pk-scale b.from-top { transform: translate(-50%, 4px); }
.pk-scale b.from-bottom { transform: translate(-50%, calc(-100% - 4px)); }
.pk-scale b::after { content: ""; position: absolute; background: currentColor; }
.pk-scale b.from-left::after { left: -6px; top: 50%; width: 5px; height: 1px; }
.pk-scale b.from-right::after { right: -6px; top: 50%; width: 5px; height: 1px; }
.pk-scale b.from-top::after { top: -4px; left: 50%; height: 4px; width: 1px; }
.pk-scale b.from-bottom::after { bottom: -4px; left: 50%; height: 4px; width: 1px; }
.pk-pattern { position: relative; width: 17rem; max-width: 100%; aspect-ratio: 1; margin: .5rem auto 0; touch-action: none; user-select: none; -webkit-user-select: none; cursor: pointer; }
.picker-readout.want { animation: want .6s; color: var(--status-critical); }
@keyframes want { 25% { transform: translateX(-6px); } 75% { transform: translateX(6px); } }
.pk-ring { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.pk-seg path { fill: transparent; stroke: var(--text-3); stroke-width: .5; transition: fill .1s, stroke .1s; }
.pk-seg text { fill: var(--text); font-size: 7px; text-anchor: middle; dominant-baseline: central; font-variant-numeric: tabular-nums; }
.pk-seg.wide text { font-size: 5.2px; }
.pk-seg.over path { stroke: var(--accent); }
.pk-seg.on path { stroke: var(--accent); fill: color-mix(in srgb, var(--accent) 22%, transparent); }
.pk-seg.on text { fill: var(--accent); }
.pk-mid { fill: color-mix(in srgb, var(--text-3) 10%, transparent); stroke: var(--text-3); stroke-width: .5; }
.pk-pattern.menu .pk-mid { stroke: var(--accent); fill: color-mix(in srgb, var(--accent) 12%, transparent); }
.pk-pattern.menu .pk-ringset.digits { display: none; }
.pk-pattern .picker-readout { position: absolute; left: 50%; top: 50%; translate: -50% -70%; font-size: 1.35rem; white-space: nowrap; pointer-events: none; }
.pk-acct { position: absolute; left: 50%; top: 50%; translate: -50% 45%; max-width: 50%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: .8rem; color: var(--text-2); pointer-events: none; }
.pk-seg.blank path { stroke-dasharray: 1 1.5; }
.pk-seg.add path { stroke: var(--accent); }
.pk-seg.add text { fill: var(--accent); font-weight: 600; }
.pk-seg.cur path { stroke: var(--accent); stroke-width: 1; }
.pk-seg.over.add path, .pk-seg.over.cancel path, .pk-ringset.menu .pk-seg.over path { fill: color-mix(in srgb, var(--accent) 22%, transparent); stroke: var(--accent); }
.pk-ringset.menu .pk-seg text { font-size: 5px; }
/* The ring's middle and bottom do the dialog's Cancel / Add while it is on screen. */
form.ring-actions:has(.picker-pattern:not([style*="none"])) .actions { display: none; }
.pk-trail { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
.pk-trail polyline { fill: none; stroke: var(--accent); stroke-width: 4; stroke-linecap: round; stroke-linejoin: round; opacity: .5; }
.pk-near { color: var(--text-3); font-size: .95rem; min-height: 1.4em; font-variant-numeric: tabular-nums; }
.pk-grid { position: relative; display: grid; grid-template-columns: repeat(5, 1fr); grid-template-rows: repeat(9, 1fr); gap: 2px; height: 15rem; touch-action: none; cursor: crosshair; margin-top: .4rem; }
.pk-grid span { display: flex; align-items: center; justify-content: center; font-size: .68rem; background: var(--line); border-radius: .2rem; color: var(--text-3); }
.pk-grid-h, .pk-grid-v { position: absolute; pointer-events: none; background: var(--accent); opacity: .55; }
.pk-grid-h { left: 0; right: 0; height: 1px; }
.pk-grid-v { top: 0; bottom: 0; width: 1px; }
.pk-grid-dot { position: absolute; width: 1.4rem; height: 1.4rem; margin: -.7rem 0 0 -.7rem; border-radius: 50%; background: var(--accent); border: 3px solid var(--card); box-sizing: border-box; pointer-events: none; box-shadow: 0 1px 6px #0006; }
.pk-ruler { position: relative; height: 4.2rem; overflow: hidden; touch-action: none; cursor: ew-resize; border-radius: .5rem; background: var(--line); margin-top: .4rem; }
.pk-ruler-strip { position: absolute; inset: 0 auto 0 0; will-change: transform; }
.pk-ruler-strip i { position: absolute; bottom: 0; width: 1px; height: .6rem; background: var(--text-3); }
.pk-ruler-strip i.major { height: 1.4rem; background: var(--text-2); }
.pk-ruler-strip b { position: absolute; top: .35rem; transform: translateX(-50%); font-size: .7rem; font-weight: 400; color: var(--text-2); white-space: nowrap; }
.pk-ruler-mark { position: absolute; left: 50%; top: 0; bottom: 0; width: 2px; margin-left: -1px; background: var(--accent); }
/* quick add: the + on a category row, tap or drag up */
.categories .category .quick { touch-action: none; flex: none; width: 2.2rem; height: 2.2rem; min-height: 0; padding: 0; border: 1px solid var(--accent); border-radius: 50%; background: none; color: var(--accent); font-size: 1.2rem; line-height: 1; }
.categories .category .quick:active, .categories .category .quick.dragging { background: var(--accent); color: var(--on-accent); }
.categories .category.idle .name, .categories .category.idle .amount { color: var(--text-3); }
/* the expense page's categories as a grid of cards */
.categories.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr)); gap: .5rem; }
.categories.cards li { position: relative; display: flex; flex-direction: column; align-items: stretch; gap: .1rem; padding: .5rem .6rem .55rem; border: 1px solid var(--line); border-radius: .6rem; background: var(--card); cursor: pointer; min-width: 0; }
.categories.cards li:active { border-color: var(--accent); }
.categories.cards li.hint { grid-column: 1 / -1; cursor: default; border-style: dashed; background: none; }
.categories.cards .category .name { flex: none; font-weight: 600; padding-right: 1.9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.categories.cards .category .quick { position: absolute; top: .35rem; right: .35rem; width: 1.75rem; height: 1.75rem; min-height: 0; font-size: 1rem; }
.categories.cards .category .amount { margin-left: 0; font-size: 1.05rem; margin-top: .1rem; }
.categories.cards .category small { font-size: .78rem; }
.categories.cards .category .bar { flex-basis: auto; margin-top: .3rem; }
.quick-bubble { position: fixed; z-index: 50; pointer-events: none; transform: translate(-50%, -140%); background: var(--card); color: var(--text); border: 1px solid var(--accent); border-radius: .5rem; padding: .35rem .65rem; font-weight: 600; white-space: nowrap; box-shadow: 0 4px 16px #0005; font-variant-numeric: tabular-nums; }
.quick-bubble small { display: block; font-weight: 400; color: var(--text-3); }
#settings .round { margin-bottom: .5rem; }
.pk-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr)); gap: .4rem; margin-top: .4rem; }
.pk-tile { touch-action: none; min-height: 3.2rem; border: 1px solid var(--line); background: var(--card); border-radius: .5rem; color: var(--text); font-size: .9rem; }
.pk-tile.on { border-color: var(--accent); background: var(--accent); color: var(--on-accent); }
.pk-bubble { font-size: 1.1rem; min-height: 1.6em; }
#settings label .hint { margin: 0; font-size: .8rem; }

/* chart: fills the height its pane leaves (plan.js sizes the viewBox to match) */
.chart-wrap { position: relative; flex: 1; min-height: 12rem; display: flex; flex-direction: column; align-items: center; background: var(--card); border: 1px solid var(--line); border-radius: .5rem; padding: .5rem; box-sizing: border-box; }
.chart-wrap svg { flex: 0 1 auto; min-height: 0; width: 100%; height: auto; max-height: 100%; display: block; touch-action: pan-y; }
.chart-wrap svg text { font-size: 11px; fill: var(--text-2); }
.grid line { stroke: var(--line); stroke-width: 1; }
.zero { stroke: var(--text-3); stroke-width: 1; }
.buffer { stroke: var(--text-3); stroke-width: 1; stroke-dasharray: 2 4; }
.buffer-label { font-size: 10px; }
.crosshair { stroke: var(--text-3); stroke-width: 1; pointer-events: none; }
path.plan { fill: none; stroke: var(--series-plan); stroke-width: 2; stroke-linejoin: round; }
path.whatif { fill: none; stroke: var(--series-whatif); stroke-width: 2; stroke-dasharray: 6 4; stroke-linejoin: round; }
.shortfall line { stroke: var(--status-critical); stroke-width: 1; stroke-dasharray: 3 3; }
.shortfall text { fill: var(--status-critical); font-size: 10px; }
.marker { cursor: grab; touch-action: none; }
.marker line { stroke: var(--series-plan); stroke-width: 1; stroke-dasharray: 2 2; }
.marker circle { fill: var(--series-plan); stroke: var(--card); stroke-width: 2; }
.marker .hit { fill: transparent; stroke: none; } /* finger-sized target around the dot */
.marker text { fill: var(--text); font-size: 10px; pointer-events: none; }
.marker.earning line { stroke: var(--status-good); }
.marker.earning circle { fill: var(--status-good); }
.marker.off line { stroke: var(--text-3); }
.marker.off circle { fill: var(--card); stroke: var(--text-3); }
.marker.off .hit { fill: transparent; stroke: none; }
.marker.off text { fill: var(--text-3); }
.chart-tip { position: absolute; pointer-events: none; background: var(--card); border: 1px solid var(--line); border-radius: .3rem; padding: .3rem .5rem; font-size: .8rem; box-shadow: 0 2px 8px #0002; }
.legend { flex: none; align-self: stretch; display: flex; flex-wrap: wrap; gap: .25rem 1rem; font-size: .8rem; color: var(--text-2); padding: .4rem .25rem 0; }
.swatch { display: inline-block; width: 1.2rem; height: 0; border-top: 2px solid; vertical-align: middle; margin-right: .3rem; }
.swatch.plan { border-color: var(--series-plan); }
.swatch.whatif { border-color: var(--series-whatif); border-top-style: dashed; }
.swatch.buffer { border-color: var(--text-3); border-top-style: dotted; }

/* summary strip under the chart */
.summary { flex: none; display: flex; flex-wrap: wrap; gap: .5rem 1.5rem; padding: .25rem .25rem 0; align-items: baseline; }
.summary .status { flex-basis: 100%; margin: 0; }
.stat { display: flex; flex-direction: column; }
.stat .label { font-size: .8rem; color: var(--text-3); }
.stat strong { font-size: 1.1rem; }

/* ---- lists ---- */
ul { list-style: none; margin: 0; padding: 0; }
.goals li, .incomes li, .budgets li, .expenses li, .categories li, .months li { display: flex; align-items: center; gap: .75rem; padding: .4rem 0; border-bottom: 1px solid var(--line); }
.accounts .budget input { width: 9rem; }
.liabilities .budget input { color: var(--status-critical); }
.incomes .name { min-width: 0; }
.incomes .name small { display: block; color: var(--text-3); }
.goals .goal { padding: 0; }
.goal input[type=checkbox] { margin: 0; }
.goal .edit { flex: 1; display: flex; align-items: center; gap: .75rem; min-width: 0; padding: .5rem 0; border: 0; background: none; color: inherit; text-align: left; border-radius: .3rem; }
.goal .edit:hover { color: var(--accent); }
.goal .name { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.goal .amount { margin-left: 0; }
.goal.earning .amount { color: var(--status-good); }
.goal .when { white-space: nowrap; min-width: 4.5rem; text-align: right; }
.goal.off .name, .goal.off .amount { color: var(--text-3); text-decoration: line-through; }
.amount { font-variant-numeric: tabular-nums; margin-left: auto; white-space: nowrap; }
.cashflow.income .amount { color: var(--status-good); }
.cashflows .total { color: var(--text-2); font-size: .9rem; border-bottom: 0; }
.expense .date { color: var(--text-3); font-size: .85rem; min-width: 6rem; }
.expense .name { min-width: 0; overflow-wrap: anywhere; }
.expense .name small { display: block; color: var(--text-3); }
.categories, .months { font-size: .9rem; }
/* budget: a field per category */
.budgets .budget { padding: .25rem 0; }
.budget .name { flex: 1; font-size: 1rem; color: var(--text); }
.budget input { width: 9rem; text-align: right; }
.budgets .total { color: var(--text-2); font-size: .9rem; border-bottom: 0; }
/* expenses summary: spent vs budget per category, with a bar */
.categories .category { flex-wrap: wrap; gap: .25rem .75rem; }
.categories .category .name { flex: 1; }
.categories .category small { color: var(--text-3); }
.categories .category.over .amount { color: var(--status-critical); }
.bar { flex-basis: 100%; height: 4px; border-radius: 2px; background: var(--line); overflow: hidden; }
.bar i { display: block; height: 100%; background: var(--series-plan); }
.category.over .bar i { background: var(--status-critical); }

/* ---- edit dialog ---- */
dialog { box-sizing: border-box; width: min(26rem, calc(100vw - 2rem)); padding: 1.25rem; border: 1px solid var(--line); border-radius: .5rem; background: var(--card); color: var(--text); box-shadow: 0 8px 32px #0004; }
dialog::backdrop { background: #0008; }
dialog form { display: flex; flex-direction: column; gap: .75rem; margin: 0; }
/* flex, not grid: Chrome sizes a grid row holding a type=month input far too tall */
dialog .fields { display: flex; gap: .75rem; }
dialog .fields label { flex: 1 1 0; min-width: 0; }
dialog input:not([type=checkbox]) { width: 100%; box-sizing: border-box; }
dialog .check { flex-direction: row; align-items: center; gap: .5rem; font-size: 1rem; color: var(--text); }
dialog .actions { display: flex; gap: .5rem; justify-content: flex-end; margin-top: .25rem; }
dialog .actions .danger { margin-right: auto; color: var(--status-critical); }
button.primary { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }

/* ---- expenses page: form + totals | list ---- */
#expenses, #received { grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); grid-template-rows: auto minmax(0, 1fr); }
#expenses .month-nav, #received .month-nav { grid-column: 1 / -1; }
/* one pane: the cards; the list is in the History dialog */
#expenses { grid-template-columns: minmax(0, 1fr); }
/* Import and History, on the totals' line */
.summary .tools { margin-left: auto; display: flex; gap: .4rem; align-self: center; }
.summary .tools button { border: 1px solid var(--line); background: none; color: var(--text); border-radius: .4rem; padding: .3rem .75rem; font-weight: 600; }
.summary .tools button:hover { border-color: var(--accent); color: var(--accent); }
.sort-bar[hidden] { display: none; }
.sort-bar { flex: none; margin: 0 0 .5rem; display: flex; justify-content: space-between; align-items: center; gap: .5rem; padding: .55rem .75rem; border: 1px solid var(--accent); border-radius: .5rem; background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--text); text-align: left; }
.sort-bar span { color: var(--accent); font-weight: 600; white-space: nowrap; }
dialog.import textarea { width: 100%; box-sizing: border-box; font: .85rem/1.4 ui-monospace, monospace; resize: vertical; }
dialog.import .hint { margin: 0; }
dialog.import .import-file { display: flex; align-items: center; justify-content: space-between; gap: .5rem; margin: 0; padding: .5rem .6rem; border: 1px solid var(--line); border-radius: .4rem; overflow-wrap: anywhere; }
dialog.sorter-dialog .sort-note { margin: -.4rem 0 0; }
dialog.import .import-row { display: flex; gap: .5rem; }
dialog.import .import-row select { flex: 1; min-width: 0; width: auto; }
dialog.import form { gap: .55rem; }
dialog.import .file-btn { flex: none; display: inline-flex; flex-direction: row; align-items: center; padding: 0 .8rem; border: 1px solid var(--line); border-radius: .4rem; color: var(--text); font-size: .9rem; cursor: pointer; }
dialog.import .file-btn:hover { border-color: var(--accent); color: var(--accent); }
/* the sorter: a ring of categories round the expense waiting */
dialog.sorter-dialog h2 small { font-size: .85rem; font-weight: 400; color: var(--text-3); margin-left: .4rem; }
.so-pad { position: relative; width: 19rem; max-width: 100%; aspect-ratio: 1; margin: 0 auto; touch-action: none; user-select: none; -webkit-user-select: none; }
.so-seg.skip text, .so-seg.delete text { font-weight: 600; }
.so-seg.delete path { stroke: var(--status-critical); }
.so-seg.delete text { fill: var(--status-critical); }
.pk-seg.so-seg.over path, .pk-seg.so-seg.on path { stroke: var(--accent); fill: color-mix(in srgb, var(--accent) 22%, transparent); }
.pk-seg.so-seg.delete.over path, .pk-seg.so-seg.delete.on path { stroke: var(--status-critical); fill: color-mix(in srgb, var(--status-critical) 22%, transparent); }
.so-card { position: absolute; left: 50%; top: 50%; translate: -50% -50%; width: 50%; display: flex; flex-direction: column; align-items: center; gap: .15rem; text-align: center; pointer-events: none; cursor: grab; }
.so-card.enter { animation: so-in .18s ease-out; }
@keyframes so-in { from { opacity: 0; scale: .85; } }
.so-amt { font-size: 1.15rem; white-space: nowrap; }
.so-dir { font-size: .7rem; color: var(--accent); text-transform: uppercase; letter-spacing: .04em; }
.so-pad.in .so-amt { color: var(--status-good); }
.so-seg.transfer text, .so-seg.back text { fill: var(--accent); font-weight: 600; }
.so-pad.transfer .pk-mid { stroke: var(--accent); stroke-dasharray: 1.5 1; }
.so-note { font-size: .85rem; max-width: 100%; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow-wrap: anywhere; }
.so-meta { font-size: .72rem; color: var(--text-3); }
.so-pad.held .so-card { scale: .8; padding: .35rem .5rem; border-radius: .5rem; background: var(--card); box-shadow: 0 4px 16px #0006; }
.so-pad.held .pk-mid { stroke: var(--accent); }
.so-pad.empty .so-seg { opacity: .35; }
.so-pad.empty .so-amt { color: var(--status-good); }
.import-error { margin: 0; max-height: 8rem; overflow: auto; white-space: pre-wrap; font: .82rem/1.4 ui-monospace, monospace; color: var(--status-critical); }
dialog.history[open] { display: flex; flex-direction: column; gap: .5rem; width: min(36rem, calc(100vw - 2rem)); max-height: 85dvh; }
dialog.history h2 { margin: 0; flex: none; }
dialog.history .scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
dialog.history .actions { flex: none; }
.month-nav { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
.month-nav a, .month-nav .disabled { font-size: 1.5rem; text-decoration: none; color: var(--text-2); }
.month-nav .disabled { color: var(--text-3); }
#expense-summary { padding: .5rem .25rem 0; }
#expense-summary .categories, #expense-summary .months, #received-summary .categories, #received-summary .months { flex-basis: 100%; }

/* ---- bottom tab bar (phones only) ---- */
.tabs { display: none; }

/* ---- phones: one pane at a time, tab bar at the bottom ---- */
@media (max-width: 48rem) {
  header nav { display: none; }
  header { padding: .5rem .75rem; }
  main { padding: var(--gap) .75rem; }
  .app { display: flex; flex-direction: column; }
  .pane { flex: 1; }
  #plan .pane-plan { gap: .5rem; overflow-y: auto; } /* short phones: the chart keeps 12rem and the pane scrolls */
  #plan .seg { display: flex; flex: none; }
  .board { display: block; overflow-y: auto; overscroll-behavior: contain; }
  .board > * { margin-bottom: var(--gap); }
  #settings { display: block; overflow-y: auto; }
  #settings > .pane { margin-bottom: var(--gap); }
  .board .pane > .scroll { overflow: visible; }
  .month-nav h1 { font-size: 1.25rem; }
  .tabs { flex: none; display: flex; border-top: 1px solid var(--line); background: var(--card); padding: .25rem .25rem calc(.25rem + env(safe-area-inset-bottom)); }
  .tabs a, .tabs button { flex: 1; border: 0; background: none; padding: .55rem .1rem; color: var(--text-3); text-decoration: none; text-align: center; font-size: .82rem; border-radius: .4rem; }
  .tabs .active { color: var(--accent); font-weight: 600; }
  .card { padding: .75rem; }
  .chart-wrap { padding: .35rem .15rem; }
  form.add { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; }
  form.add .wide, form.add button { grid-column: 1 / -1; }
  form.add input, form.add select { width: 100%; }
  .goal .edit { flex-wrap: wrap; gap: 0 .75rem; }
  .goal .name { flex: 1 1 100%; }
  .goal .amount { margin-left: 0; }
  .goal .when { margin-left: auto; }
  .expense .date { min-width: 4.5rem; font-size: .8rem; }
  .summary { gap: .35rem 1.25rem; }
  #expenses, #received { display: flex; flex-direction: column; }
  /* A sheet at the bottom of the screen, within reach of the thumb. */
  dialog { width: 100vw; max-width: 100vw; margin: auto 0 0; border-width: 1px 0 0; border-radius: .9rem .9rem 0 0; padding-bottom: calc(1.25rem + env(safe-area-inset-bottom, 0px)); max-height: 92dvh; }
  dialog .actions { flex-wrap: wrap; }
  dialog .actions button { flex: 1; }
  dialog .actions .danger { flex-basis: 100%; margin-right: 0; }
  dialog.history[open] { width: 100vw; max-height: 92dvh; }
}
/* wider than a phone: every pane is visible, whatever the tab signal says */
@media (min-width: 48.01rem) {
  .pane { display: flex !important; }
}

/* touch: finger-sized fields and buttons */
@media (pointer: coarse) {
  input:not([type=checkbox]):not([type=range]), select, button:not(.icon) { min-height: 2.75rem; }
  input[type=range] { height: 2.75rem; }
  input[type=checkbox] { width: 1.3rem; height: 1.3rem; margin: 0; }
  button.icon { min-width: 2.75rem; }
  .marker { cursor: default; }
}

/* Sign-in and registration */
.auth { display: flex; flex-direction: column; gap: .8rem; width: 100%; max-width: 24rem; margin: 3rem auto; }
.auth h1 { margin: 0; }
.auth .status:empty, .account .status:empty { display: none; }
.account .account-actions { margin-top: .5rem; padding-top: 0; border-top: 0; }
.auth button { padding: .55rem .8rem; }
.account-actions { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .8rem; padding-top: .8rem; border-top: 1px solid var(--line); }
.banner { margin-right: auto; padding: .1rem .5rem; border-radius: .3rem; background: var(--warning); color: var(--surface); font-size: .8rem; font-weight: 600; }

/* Expense dialog: Details switch */
label.switch { flex-direction: row; align-items: center; gap: .55rem; font-size: .9rem; color: var(--text); cursor: pointer; }
label.switch small { color: var(--text-3); font-size: .8rem; }
label.switch input { appearance: none; flex: none; width: 2.4rem; height: 1.4rem; margin: 0; border-radius: 1rem; background: var(--line); position: relative; cursor: pointer; transition: background .15s; }
label.switch input::after { content: ""; position: absolute; top: .15rem; left: .15rem; width: 1.1rem; height: 1.1rem; border-radius: 50%; background: #fff; transition: transform .15s; }
label.switch input:checked { background: var(--accent); }
label.switch input:checked::after { transform: translateX(1rem); }
label.switch input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.for-category { margin: 0; font-size: .9rem; color: var(--text-2); }

/* Fan picker: the grid in polar coordinates, pivot at the bottom-right */
.pk-fan { width: 100%; max-width: 20rem; margin: .4rem 0 0 auto; aspect-ratio: 1; touch-action: none; cursor: crosshair; }
.pk-fan svg { display: block; width: 100%; height: 100%; overflow: visible; }
.pk-fan .band { fill: var(--line); }
.pk-fan .band.odd { fill: color-mix(in srgb, var(--line) 60%, var(--card)); }
.pk-fan .ray { stroke: var(--card); stroke-width: .5; }
.pk-fan text { fill: var(--text-3); font-size: 3.6px; text-anchor: middle; pointer-events: none; user-select: none; }
.pk-fan .cell { font-size: 3.1px; dominant-baseline: central; fill: var(--text-2); paint-order: stroke; stroke: var(--line); stroke-width: 1.2px; stroke-linejoin: round; }
.pk-fan .cell.odd { stroke: color-mix(in srgb, var(--line) 60%, var(--card)); }
.pk-fan .guide { fill: none; stroke: var(--accent); stroke-width: .45; opacity: .6; pointer-events: none; }
.pk-fan .dot { fill: var(--accent); stroke: var(--card); stroke-width: 1; pointer-events: none; filter: drop-shadow(0 .4px 1.5px #0006); }
dialog h2[tabindex="-1"] { outline: none; }

/* settings: registrations waiting for the admin */
.pending-users { list-style: none; margin: 0; padding: 0; }
.pending-users li { display: flex; align-items: center; gap: .5rem; padding: .4rem 0; border-bottom: 1px solid var(--line); }
.pending-users .name { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.pending-users small { display: block; font-size: .75rem; color: var(--text-2); }

/* header: which book the pages show (personal or a household) */
.book-switch { font-size: .9rem; padding: .2rem .4rem; max-width: 12rem; }
@media (max-width: 48rem) { .book-switch { margin-left: auto; max-width: 55vw; } }

/* plan: which books the plan adds together */
.plan-scope { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem .75rem; margin-bottom: .5rem; font-size: .9rem; }
.plan-scope .label { color: var(--text-2); }
.plan-scope .chip { display: inline-flex; align-items: center; gap: .3rem; padding: .15rem .6rem; border: 1px solid var(--line); border-radius: 999px; background: var(--card); cursor: pointer; }
.plan-scope .chip input { margin: 0; }
.goal .name .book, .entry .by { display: block; font-size: .75rem; color: var(--text-2); }

/* accounts: contributions in or out of this book */
.contributions strong.in { color: var(--status-good); }
.summary .account-actions { margin-top: .5rem; }

/* settings: households */
.households .household { border-top: 1px solid var(--line); padding: .75rem 0; }
.households h3 { margin: 0 0 .25rem; font-size: 1rem; }
.households .members { list-style: none; margin: .25rem 0; padding: 0; }
.households .members li { display: flex; align-items: center; gap: .5rem; padding: .3rem 0; }
.households .members .name { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.households .members small { color: var(--text-2); font-size: .75rem; margin-left: .25rem; }
.households .household-head { display: flex; align-items: baseline; gap: .5rem; }
.head-actions { display: flex; gap: .5rem; align-items: center; }
button.link { border: 0; background: none; padding: 0; color: var(--accent); font-size: .85rem; cursor: pointer; }
button.link:hover { text-decoration: underline; }
dialog .status:empty { display: none; }
.households .invite { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem .75rem; }
.households .code { font-family: ui-monospace, monospace; letter-spacing: .08em; }

/* header: the notification bell and its list */
.bell { position: relative; display: inline-flex; align-items: center; justify-content: center; padding: .3rem; border: 0; background: none; color: var(--text-2); cursor: pointer; align-self: center; }
.bell:hover { color: var(--text); }
.bell .badge { position: absolute; top: -.1rem; right: -.25rem; min-width: 1.1rem; padding: 0 .25rem; border-radius: 999px; background: var(--accent); color: var(--on-accent, #fff); font-size: .7rem; font-weight: 600; line-height: 1.1rem; text-align: center; }
.notice-list { list-style: none; margin: 0; padding: 0; max-height: 60vh; overflow-y: auto; }
.notice-list li { display: flex; flex-direction: column; gap: .1rem; padding: .5rem .25rem; border-bottom: 1px solid var(--line); }
.notice-list li.unread { font-weight: 600; }
.notice-list li.unread::before { content: "●"; color: var(--accent); font-size: .6rem; margin-bottom: -.2rem; }
.notice-list a { color: inherit; }
.notice-list small { font-weight: 400; font-size: .75rem; color: var(--text-2); }

/* tap rows (budget categories, accounts): what it is and its amount; a tap opens its dialog */
.budgets .tap-row { padding: 0; }
.tap-row > button { display: flex; flex-wrap: wrap; align-items: baseline; gap: .2rem .75rem; width: 100%; padding: .55rem .25rem; border: 0; border-radius: .35rem; background: none; color: var(--text); font: inherit; text-align: left; cursor: pointer; }
.tap-row > button:hover { background: color-mix(in srgb, var(--accent) 7%, transparent); }
.tap-row .name { flex: 1; font-size: 1rem; }
.tap-row .amount small, .tap-row .sub { color: var(--text-3); font-size: .8rem; }
.tap-row .sub { flex-basis: 100%; }
.tap-row.over .bar i { background: var(--status-critical); }
.tap-row.over .sub { color: var(--status-critical); }
.liabilities .tap-row .amount { color: var(--status-critical); }
.amount-dialog .name-field { font-size: 1.1rem; font-weight: 600; }
.amount-dialog .readout { font-size: 1.6rem; font-weight: 700; text-align: center; }
.amount-dialog .readout + .hint { margin: -.5rem 0 0; text-align: center; }
.amount-dialog .picker-readout { display: none; } /* the readout above shows the amount, and "No budget" */
.amount-dialog .term { display: flex; flex-direction: column; gap: .75rem; }
.amount-dialog .term .hint { margin: 0; }
.suggest { display: flex; flex-wrap: wrap; gap: .4rem; }
.suggest .chip { padding: .3rem .6rem; border: 1px solid var(--line); border-radius: 999px; background: none; color: var(--text-2); font-size: .85rem; cursor: pointer; }
.suggest .chip strong { color: var(--text); font-weight: 600; }
.suggest .chip:hover { border-color: var(--accent); }
.fill-list { list-style: none; margin: 0; padding: 0; max-height: 50vh; overflow-y: auto; }
.fill-list li { border-bottom: 1px solid var(--line); }
.fill-list .check { display: flex; flex-direction: row; align-items: center; gap: .6rem; padding: .45rem 0; font-size: .95rem; color: var(--text); }
.fill-list .name { flex: 1; }
.fill-list small { color: var(--text-2); white-space: nowrap; }
.card-head { flex-wrap: wrap; }
.head-actions button { white-space: nowrap; }

/* settings: AI assistants (MCP) and the OAuth consent page */
.ai-assistants h3 { margin: 1rem 0 .3rem; font-size: .95rem; }
.copy-field { display: flex; gap: .5rem; }
.copy-field input { flex: 1; min-width: 0; font-family: ui-monospace, monospace; font-size: .85rem; }
.connect-howto { margin-top: .6rem; }
.connect-howto ol { margin: .5rem 0 0; padding-left: 1.2rem; display: flex; flex-direction: column; gap: .4rem; }
.connect-howto code { overflow-wrap: anywhere; }
.consent-list { margin: 0; padding-left: 1.2rem; display: flex; flex-direction: column; gap: .3rem; }
.consent-actions { display: flex; justify-content: flex-end; gap: .5rem; }
