/* Balance: money, spend by category, the ledger, the heatmap, credits.
   Loaded by index.html. Styles for other pages are in their own
   file, so a session working on one page never opens the others. */

/* ===== money: the sticky control block ===== */
/* position:sticky dies inside an overflow:hidden ancestor, so this one card
   opts out of the shared clip. */
section.money-card{overflow:visible}
.stick{position:sticky;top:var(--tabh);z-index:5;background:var(--card);
  border-radius:13px 13px 0 0;border-bottom:1px solid var(--line-2);
  box-shadow:var(--sticky-shadow)}

/* month navigator: one bar the width of the card, arrows at both ends. The
   middle is a button too - it jumps back to the newest month. */
.monthnav{display:flex;align-items:stretch;margin:15px 18px 0;overflow:hidden;
  border:1px solid var(--line);border-radius:10px;background:var(--sunk)}
.mnav{flex:none;width:46px;padding:9px 0;font:inherit;font-size:18px;
  line-height:1.2;cursor:pointer;background:none;border:none;color:var(--ink-2)}
.mnav:hover:not(:disabled){background:var(--card);color:var(--ink)}
.mnav:disabled{opacity:.28;cursor:default}
.mnav-mid{flex:1;min-width:0;padding:9px 4px;border:none;background:none;
  cursor:pointer;color:var(--ink);
  font-family:var(--display);
  font-size:15px;font-weight:700;letter-spacing:-.01em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mnav-mid:hover{background:var(--card)}
.figs{display:flex;gap:10px;padding:12px 18px 0}
.fig{flex:1;min-width:0;border-radius:10px;padding:10px;background:var(--sunk)}
.fig.in{background:var(--in-soft)}
.fig.out{background:var(--out-soft)}
.fig-label{font-family:var(--body);font-size:10px;
  text-transform:uppercase;letter-spacing:.08em;color:var(--ink-3)}
/* Sized to fit three figures across a phone without wrapping. A wrapped
   currency value reads as two numbers, which is worse than a small one. */
.fig-val{font-family:var(--body);
  font-size:clamp(12px,3.9vw,19px);
  font-weight:700;margin-top:3px;font-variant-numeric:tabular-nums;
  letter-spacing:-.03em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.fig.in .fig-val{color:var(--in)}
.fig.out .fig-val{color:var(--out)}
.fig.net .fig-val{color:var(--ink)}

/* tab strip: scrolls sideways on a phone rather than wrapping to two rows */
.tabs{display:flex;gap:7px;overflow-x:auto;padding:12px 18px 13px;
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.tabs::-webkit-scrollbar{display:none}
.tab{flex:none;font:inherit;font-size:13px;font-weight:600;cursor:pointer;
  padding:5px 12px;border-radius:999px;border:1px solid var(--line);
  background:var(--card);color:var(--ink-2);white-space:nowrap}
.tab:hover{border-color:var(--ink-3)}
.tab[aria-pressed="true"]{background:var(--tan);border-color:transparent;
  color:var(--ink);font-weight:700}

/* ===== spend by category: name, proportional rule, amount ===== */
.cats{display:flex;flex-direction:column;gap:2px;margin:0 0 4px}
.cat{display:grid;grid-template-columns:66px 1fr auto;align-items:center;gap:10px;
  width:100%;font:inherit;text-align:left;cursor:pointer;background:none;
  border:none;padding:5px 0;border-radius:6px}
.cat-name{font-size:13px;font-weight:600;color:var(--ink-2)}
.cat-bar{height:6px;border-radius:3px;background:var(--sunk);overflow:hidden}
.cat-bar i{display:block;height:100%;background:var(--out);border-radius:3px}
.cat-amt{font-family:var(--body);font-size:13px;
  font-weight:600;font-variant-numeric:tabular-nums;color:var(--ink-2);
  white-space:nowrap}
.money-card.picked .cat{opacity:.4}
.money-card.picked .cat.on{opacity:1}
.cat.on .cat-name{color:var(--ink);font-weight:700}
/* the Wedding bar: on top, ruled off from the everyday bars, which the
   without-wedding total heads */
.cat.wed{padding-bottom:9px;border-bottom:1px dashed var(--line);border-radius:0}
.cat.wed + .cat-every{margin:6px 0 4px}
/* income: always last, green, the money in against the bars above */
.cat.inc{margin-top:6px;padding-top:9px;border-top:1px dashed var(--line);
  border-radius:0}
.cat.inc .cat-bar i{background:var(--in)}
.cat.inc .cat-amt{color:var(--in)}
.cat-every{margin:6px 0 0;font-size:12px;color:var(--ink-3);text-align:right;
  font-family:var(--body);font-variant-numeric:tabular-nums}
.cats-head{font-family:var(--body);font-size:11px;
  text-transform:uppercase;letter-spacing:.08em;color:var(--ink-3);margin:0 0 8px}

/* ===== the transactions, grouped by the day they posted ===== */
/* Collapsed by default: the figures and the bars are the daily read, the
   individual rows are the follow-up question. */
.disclose{display:flex;align-items:center;justify-content:space-between;gap:10px;
  width:100%;margin-top:16px;padding:11px 13px;border-radius:10px;
  border:1px solid var(--line);background:var(--sunk);color:var(--ink-2);
  font:inherit;font-size:13px;font-weight:600;cursor:pointer}
.disclose:hover{border-color:var(--ink-3);color:var(--ink)}
.chev{flex:none;width:7px;height:7px;margin-top:-3px;
  border-right:2px solid currentColor;border-bottom:2px solid currentColor;
  transform:rotate(45deg);transition:transform .2s ease}
.disclose[aria-expanded="true"] .chev{transform:rotate(-135deg);margin-top:2px}
@media (prefers-reduced-motion: reduce){.chev{transition:none}}
.ledger{margin-top:18px;padding-top:14px;border-top:1px solid var(--line-2)}
.day{margin-top:16px;padding-top:13px;border-top:1px solid var(--line-2)}
/* filtering can hide the first group, so the leading rule is set in JS
   rather than with :first-child */
.day.lead{margin-top:0;padding-top:0;border-top:none}
.day-label{font-family:var(--body);font-size:11px;
  text-transform:uppercase;letter-spacing:.08em;color:var(--ink-3);margin:0 0 9px}
.txns{display:flex;flex-direction:column;gap:10px}
.txn{display:flex;justify-content:space-between;gap:12px;align-items:baseline}
.txn-main{min-width:0}
.txn-name{font-size:14px;font-weight:600;color:var(--ink);overflow-wrap:anywhere}
.txn-name.raw{color:var(--ink-2);font-weight:500}
.txn-meta{font-family:var(--body);font-size:11px;
  color:var(--ink-3);margin-top:2px}
.txn-amt{font-family:var(--body);font-size:14px;
  font-weight:600;color:var(--out);white-space:nowrap;
  font-variant-numeric:tabular-nums}
.txn-amt.pos{color:var(--in)}
.caveat{margin:16px 0 0;color:var(--ink-3);font-size:13px;line-height:1.45}
.caveat+.caveat{margin-top:6px}

/* ===== spending: four calendar weeks of days, shaded by spend ===== */
/* Sunday to Saturday, newest week at the bottom. A square is a day's spend in
   dining, grocery and shopping and shows the day of the month; the column on
   the right is that week's total. Days still to come in this week are faint
   outlines, so the grid keeps its shape. */
.heat{display:grid;grid-template-columns:44px repeat(7,minmax(0,1fr)) 50px;
  gap:5px;align-items:center}
.heat-h{font-family:var(--body);font-size:10px;
  letter-spacing:.06em;color:var(--ink-3);text-align:center}
.heat-wk{font-family:var(--body);font-size:10px;
  color:var(--ink-3);white-space:nowrap}
.heat-wk.now{color:var(--ink);font-weight:700}
/* the week rows scroll inside the card, newest at the bottom; the header row stays.
   Four rows tall: a square is a seventh of what the 44px label, 50px total
   and eight 5px gaps leave of the width, and four of them plus three gaps.
   The 2px padding keeps the picked day's ring from being clipped. */
.bud-heat{display:flex;flex-direction:column;gap:5px;container-type:inline-size}
.heat-scroll{display:flex;flex-direction:column-reverse;overflow-y:auto;padding:2px;margin:-2px;box-sizing:content-box;
  max-height:calc((100cqw - 134px) * 4 / 7 + 15px);scrollbar-width:none}
.heat-scroll::-webkit-scrollbar{display:none}
.heat-tot{font-family:var(--body);font-size:11px;
  font-weight:600;text-align:right;color:var(--ink-2);white-space:nowrap;
  font-variant-numeric:tabular-nums}
/* red as soon as a week passes the caps' total, this week included; green only
   once a week has ended at or under it, because a week still running can
   always go over */
.heat-tot.over{color:var(--out)}
.heat-tot.under{color:var(--in)}
.heat-d{display:flex;align-items:center;justify-content:center;width:100%;
  aspect-ratio:1;border-radius:6px;padding:0;border:none;cursor:pointer;
  background:var(--sunk);font-family:var(--body);
  font-size:10px;color:var(--ink-3);font-variant-numeric:tabular-nums}
/* The squares are coloured inline from these stops (balance.js): green at $0
   to grey at the day budget, then yellow once past it, through orange and
   red, to deep red at the top number. A recent day with nothing on it yet is
   left plain rather than green — its charges may simply not have posted. */
:root{--heat-g:#5a8a57;--heat-g2:#c3cba9;--heat-n:#d5cabd;
  --heat-y:#e0b23a;--heat-o:#d9772a;--heat-r:#c0412a;--heat-r3:#5e150c}
.heat-d{transition:background .25s}
/* every day's number is white, centred, whatever the square's colour (Adrien, 2026-10-19,
   after the colours changed; it was black from 2026-09-28) */
.heat-d,.heat-d.lite,.heat-d.hot{color:#fff;font-weight:600}
@media (prefers-reduced-motion: reduce){.heat-d{transition:none}}
.heat-d.future{background:none;box-shadow:inset 0 0 0 1px var(--line-2);
  color:var(--line);cursor:default}
.heat-d.today{box-shadow:inset 0 0 0 1.5px var(--ink-3)}
.heat-d[aria-pressed="true"]{box-shadow:0 0 0 2px var(--accent)}
/* the two numbers under the squares */
.heat-legend{display:flex;justify-content:space-between;gap:10px;margin-top:14px}
.hs-num{display:flex;align-items:center;gap:6px;min-width:0;cursor:text}
.hs-lab{white-space:nowrap}
.hs-lab{font-family:var(--body);font-size:11px;color:var(--ink-3)}
.hs-field{display:flex;align-items:center;gap:2px;padding:4px 8px;border-radius:8px;
  border:1px solid var(--line);background:var(--sunk);
  font-family:var(--body);font-size:13px;color:var(--ink-3)}
.hs-field:focus-within{border-color:var(--accent)}
.hs-in{width:2.6em;padding:0;border:none;background:none;color:var(--ink);
  font:inherit;font-size:16px;font-weight:700;font-variant-numeric:tabular-nums;
  -moz-appearance:textfield}
.hs-in:focus{outline:none}
.hs-in::-webkit-outer-spin-button,.hs-in::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.heat-detail{margin:14px 0 0;padding:11px 13px;border-radius:10px;
  background:var(--sunk);font-size:14px;line-height:1.45;color:var(--ink-2)}
.heat-detail b{color:var(--ink)}
.day-head{display:flex;justify-content:space-between;align-items:baseline;gap:12px}
.day-total{flex:none;font-family:var(--body);
  font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums}
.heat-detail .late{display:block;margin-top:4px;font-size:12px;color:var(--warn)}
/* the charges behind the day, under its total */
.day-txns{list-style:none;margin:10px 0 0;padding:8px 0 0;
  border-top:1px solid var(--line-2);display:flex;flex-direction:column;gap:7px}
.day-txn{display:flex;justify-content:space-between;align-items:baseline;gap:12px}
.day-txn-name{min-width:0;font-size:13px;color:var(--ink);overflow-wrap:anywhere}
.day-txn-meta{display:block;font-family:var(--body);
  font-size:11px;color:var(--ink-3)}
.day-txn-amt{flex:none;font-family:var(--body);
  font-size:13px;font-weight:600;color:var(--ink-2);font-variant-numeric:tabular-nums}
.day-txn.out .day-txn-name,.day-txn.out .day-txn-amt{color:var(--ink-3)}
.day-txn.out .day-txn-amt{text-decoration:line-through}
.day-txn-was{color:var(--ink-3);font-weight:400}
.day-txn-back{color:var(--ink-3)}

/* ===== renaming and categorizing a row, from the page ===== */
/* A tapped row opens under itself. The edit is stored against the merchant,
   not the charge, so tomorrow's charge from the same place lands named. */
.txn-row{display:flex;flex-direction:column}
.txn{width:100%;font:inherit;text-align:left;background:none;border:none;
  padding:0;color:inherit}
.ledger.editable button.txn{cursor:pointer}
.ledger.editable button.txn:hover .txn-name{color:var(--accent)}
.txn.open .txn-name{color:var(--accent)}
/* A charge the bank has not settled. It counts in every total — the money is
   spent — so the marker goes on the row rather than into `category`, which the
   spend bars read, or into the name, which the merchant alias map matches on. */
.ed-hint{margin:0 0 14px;color:var(--ink-3);font-size:12px}
.txn-edit{margin:11px 0 3px;padding:13px;border:1px solid var(--line);
  border-radius:10px;background:var(--sunk)}
.ed-lab{display:block;font-family:var(--body);
  font-size:10px;text-transform:uppercase;letter-spacing:.08em;
  color:var(--ink-3);margin:0 0 6px}
.ed-block{margin-top:12px}
.ed-name{width:100%;font:inherit;font-size:16px;font-weight:600;
  color:var(--ink);background:var(--card);border:1px solid var(--line);
  border-radius:8px;padding:9px 10px}
.ed-chips{display:flex;flex-wrap:wrap;gap:6px}
.ed-chip{font:inherit;font-size:12px;font-weight:600;cursor:pointer;
  padding:5px 11px;border-radius:999px;border:1px solid var(--line);
  background:var(--card);color:var(--ink-2)}
.ed-chip:hover{border-color:var(--ink-3)}
.ed-chip[aria-pressed="true"]{background:var(--tan);border-color:transparent;
  color:var(--ink);font-weight:700}
.ed-acts{display:flex;align-items:center;gap:8px;margin-top:14px}
.ed-btn{font:inherit;font-size:13px;font-weight:600;cursor:pointer;
  padding:8px 15px;border-radius:9px;border:1px solid var(--line);
  background:var(--card);color:var(--ink-2)}
.ed-btn:hover{border-color:var(--ink-3);color:var(--ink)}
.ed-btn.go{background:var(--ink);border-color:var(--ink);color:var(--on-ink)}
.ed-note{margin:11px 0 0;color:var(--ink-3);font-size:12px;line-height:1.45}

/* ===== card credits ===== */
/* Struck through rather than removed: these refresh on their own cycle,
   so a used credit is a state, not a deletion. */
/* The whole list, at full height. It used to sit in a 392px window that
   cut the last row to say there was more below; with the same credit split
   across two cards, the thing worth seeing was the split, not the cut. */

/* A flat list, soonest deadline first. Credits that sit on two cards were
   once folded under one expandable row; the fold hid the deadline,
   which is the only thing that makes one of them urgent. Each card's credit
   is its own line now, and the sub-line carries the card and the days left. */
.creds>*+*{border-top:1px solid var(--line-2)}
.cred-meta .soon{color:var(--warn);font-weight:700}
.creds{display:flex;flex-direction:column}
.cred{display:block;width:100%;padding:13px 0}
.cred+.cred{border-top:1px solid var(--line-2)}
.cred-top{display:flex;justify-content:space-between;gap:12px;align-items:center}
.cred-title{display:flex;align-items:center;gap:9px;min-width:0}
/* The merchant's own icon, served from page/icons beside this file rather than
   from a favicon service, which would hand the credit list to a third party on
   every load. It is decoration: a missing one hides itself and the row reads
   the same. */
.cred-icon{flex:none;width:22px;height:22px;border-radius:6px;object-fit:contain;
  background:var(--sunk)}
.cred-name{font-size:14px;font-weight:600;color:var(--ink);overflow-wrap:anywhere}
.cred-meta{display:block;font-family:var(--body);
  font-size:11px;color:var(--ink-3);margin-top:2px;white-space:normal}
.cred-amt{font-family:var(--body);font-size:14px;
  font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums;
  white-space:nowrap}
/* the bar is the state: it fills as the credit is claimed, and a full bar
   strikes the row through. Nothing leaves the list — these come back. */
.cred-track{display:block;height:7px;border-radius:4px;background:var(--sunk);
  overflow:hidden;margin-top:10px}
.cred-track i{display:block;height:100%;width:0;background:var(--in);
  border-radius:4px;transition:width .25s ease}
.cred-legend{display:flex;justify-content:space-between;gap:10px;margin-top:6px;
  font-family:var(--body);font-size:11px;
  color:var(--ink-3);font-variant-numeric:tabular-nums}
.cl-r.soon{color:var(--warn);font-weight:700}
.cred.used .cred-name,
.cred.used .cred-amt{text-decoration:line-through;
  text-decoration-thickness:1.5px;color:var(--ink-3)}
.cred.used .cred-icon{opacity:.45}
.cred.used .cl-r{color:var(--in);font-weight:700}
@media (prefers-reduced-motion: reduce){.cred-track i{transition:none}}


/* ===== the money pieces: month figures, spend by category, transactions ===== */
.money-part .card-body:has(>.gap-note[hidden]:only-child){display:none}
.money-part .figs{padding-bottom:15px}
.money-part .figs+.card-body{padding-top:0}
.money-part .card-head+.monthnav{margin-top:14px}
.money-part .card-body>.gap-note{margin:0 0 12px}
.money-part .ledger{margin-top:0;padding-top:0;border-top:0}
.money-part>.tabs{padding-bottom:0}
