/* AIAM.
   The month is a banknote: a panel in the colour of how the month is going,
   a guilloché rosette, the figure in Archivo set extra-wide and heavy like a
   denomination. Everything else is quiet: lists, one stacked bar, hairlines.
   One family (Archivo, OFL, self-hosted), contrast by width and weight. */

@font-face {
  font-family: "Archivo";
  src: url("/static/archivo.woff2") format("woff2");
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
}

:root {
  --paper: #f3f4f6;
  --surface: #ffffff;
  --ink: #181b21;
  --muted: #5e6572;
  --rule: #dfe2e7;
  --accent: #1f6a4b;
  --accent-soft: #e2efe8;
  --gain: #1c7a47;
  --loss: #b42318;
  --warn-soft: #fbf0dc;

  /* Note states. Text on them is white: all clear 4.5:1. */
  --note-ok: #1f6a4b;
  --note-tight: #9a4e14;
  --note-over: #a42a22;
  --note-plain: #2a3140;

  /* Categorical series: dataviz reference palette, light steps. */
  --s1: #2a78d6; --s2: #eb6834; --s3: #1baf7a; --s4: #eda100;
  --s5: #e87ba4; --s6: #008300; --s7: #4a3aa7; --s0: #a9aeb7;

  --font: "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;
  --tabbar: 60px;
  color-scheme: light dark;
}
@media (prefers-color-scheme: dark) {
  :root {
    --paper: #121418; --surface: #1b1e24; --ink: #eceef1; --muted: #a1a7b1; --rule: #2c3039;
    --accent: #5cc49a; --accent-soft: #1b3329; --gain: #6fd39c; --loss: #f0877a; --warn-soft: #3a2f1a;
    --note-ok: #1a5a40; --note-tight: #85440f; --note-over: #8f241d; --note-plain: #262c38;
    --s1: #3987e5; --s2: #d95926; --s3: #199e70; --s4: #c98500;
    --s5: #d55181; --s6: #008300; --s7: #9085e9; --s0: #6b717c;
  }
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--paper); color: var(--ink);
  font: 400 16px/1.5 var(--font); font-stretch: 100%;
  font-variant-numeric: tabular-nums lining-nums;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--accent); text-underline-offset: .18em; text-decoration-thickness: 1px; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

/* ---------- shell ---------- */
/* The app is a frame of the real viewport height: header, a scrolling stage,
   and on phones the dock at the end. Nothing is fixed to the bottom edge: in
   an installed PWA that edge is not where the browser says it is (napnap). */
body.app { position: fixed; inset: 0; display: flex; flex-direction: column; overflow: hidden; }
.stage { position: relative; flex: 1; min-height: 0; }
.scroll { position: absolute; inset: 0; overflow-y: auto; overscroll-behavior: contain;
          -webkit-overflow-scrolling: touch; }
.top {
  position: relative; z-index: 30; flex: none;
  display: flex; align-items: center; gap: 2.5rem;
  padding: max(.7rem, env(safe-area-inset-top)) max(1rem, calc((100% - 1120px) / 2 + 1rem)) .7rem;
  /* Solid, not blurred: backdrop-filter would make the header the containing
     block of the fixed tab bar inside it, pinning the bar to the top. */
  background: var(--paper);
  box-shadow: 0 1px 0 var(--rule);
}
.tools { margin-left: auto; display: flex; gap: .25rem; }
.tool { position: relative; display: grid; place-items: center; width: 2.6rem; height: 2.6rem;
        border-radius: 50%; color: var(--ink); }
.tool:hover, .tool.on { background: var(--surface); box-shadow: 0 0 0 1px var(--rule); }
.tool .badge { position: absolute; top: 3px; right: 1px; }
.brand {
  display: flex; align-items: center; gap: .6rem; color: var(--ink); text-decoration: none;
  font-weight: 800; font-stretch: 125%; font-size: 1.1rem; letter-spacing: .02em;
}
.brand img { border-radius: 8px; }
.tabs { display: flex; gap: .15rem; }
.tabs a {
  position: relative; display: flex; align-items: center; gap: .45rem;
  padding: .5rem .8rem; border-radius: 999px; color: var(--muted); text-decoration: none;
  font-size: .95rem; font-weight: 500;
}
.tabs a:hover { color: var(--ink); }
.tabs a[aria-current="page"] { color: var(--ink); background: var(--surface); box-shadow: 0 0 0 1px var(--rule); }
.icon { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.7;
        stroke-linecap: round; stroke-linejoin: round; flex: none; }
.badge {
  min-width: 1.15rem; height: 1.15rem; padding: 0 .3rem; border-radius: 1rem;
  background: var(--loss); color: #fff; font-size: .7rem; font-weight: 700; line-height: 1.15rem; text-align: center;
}
main { max-width: 1120px; margin: 0 auto; padding: .5rem 1rem 4rem; }
body.bare main { max-width: 30rem; }

.dock { display: none; }
@media (max-width: 760px) {
  .top .tabs { display: none; }
  .dock {
    flex: none; display: grid; grid-template-columns: repeat(4, 1fr);
    height: calc(var(--tabbar) + env(safe-area-inset-bottom));
    padding: 0 .25rem env(safe-area-inset-bottom);
    background: var(--surface); border-top: 1px solid var(--rule);
  }
  .dock a { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .2rem;
            font-size: .68rem; font-weight: 500; color: var(--muted); text-decoration: none; }
  .dock a[aria-current="page"] { color: var(--accent); }
  body.app main { padding-bottom: 6rem; }
}

/* ---------- type ---------- */
h1 { font-weight: 800; font-stretch: 115%; font-size: 1.9rem; line-height: 1.15; margin: .5rem 0 1.25rem;
     letter-spacing: -.01em; }
h2 { font-weight: 700; font-stretch: 110%; font-size: 1.12rem; line-height: 1.3; margin: 0 0 .8rem; }
h3 { font-weight: 650; font-size: 1rem; margin: 0 0 .5rem; }
.caption { color: var(--muted); font-size: .92rem; margin: -.4rem 0 1rem; max-width: 62ch; }
small { font-size: .82rem; color: var(--muted); }

/* ---------- the note ---------- */
.hero-grid { display: grid; gap: 2rem 3rem; align-items: start; margin-bottom: 2.5rem; }
@media (min-width: 900px) { .hero-grid { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); } }

.note {
  --c: var(--note-plain);
  position: relative; overflow: hidden; isolation: isolate;
  color: #fff; background: var(--c); border-radius: 22px;
  padding: 1.1rem 1.3rem 1.2rem;
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / .08);
}
.note.ok { --c: var(--note-ok); }
.note.tight { --c: var(--note-tight); }
.note.over { --c: var(--note-over); }
.note::before {
  content: ""; position: absolute; z-index: -1; width: 420px; height: 420px;
  right: -150px; top: -130px; background: url("/static/guilloche.svg") center / contain no-repeat;
}
.note header { display: flex; justify-content: space-between; gap: 1rem; font-size: .85rem;
               font-weight: 600; opacity: .85; }
.note .lead { margin: 1.4rem 0 0; font-size: 1rem; opacity: .9; }
.note .figure { margin: .1rem 0 0; line-height: .95; display: flex; align-items: baseline; flex-wrap: wrap; }
.note .whole { font-weight: 850; font-stretch: 125%; font-size: clamp(3.6rem, 17vw, 6.4rem);
               letter-spacing: -.035em; }
.note .cents { font-weight: 700; font-stretch: 125%; font-size: clamp(1.3rem, 5vw, 2rem); opacity: .75; }
.note .cur { font-weight: 700; font-stretch: 125%; font-size: clamp(1.3rem, 5vw, 2rem); margin-left: .35rem; }
.note .sub { margin: .55rem 0 1.1rem; font-size: 1rem; font-weight: 500; }
.note .strip { display: block; width: 100%; height: auto; overflow: visible; }
.strip .bar { fill: rgb(255 255 255 / .55); }
.strip .bar.today { fill: #fff; }
.strip .stub { fill: rgb(255 255 255 / .22); }
.strip .notch { fill: var(--c); }
.strip .hit { fill: transparent; }
.strip .allowance { stroke: rgb(255 255 255 / .8); stroke-width: 1; stroke-dasharray: 2 3; }
.strip text { font: 600 7.5px var(--font); fill: rgb(255 255 255 / .8); }
.strip .clip { fill: #fff; }
.note .budget { margin-top: 1rem; padding-top: .9rem; border-top: 1px solid rgb(255 255 255 / .18); }
.note .budget p { margin: 0 0 .45rem; font-size: .92rem; font-weight: 500; }
.note .budget small { color: rgb(255 255 255 / .7); display: block; margin-top: .35rem; }
.note .meter .track { fill: rgb(255 255 255 / .2); }
.note .meter .fill { fill: #fff; }
.note .meter .today { stroke: var(--c); stroke-width: 3; vector-effect: non-scaling-stroke; }
.note .meter { overflow: visible; display: block; width: 100%; height: 10px; }
.note .setgoal { margin: 1rem 0 0; }
.note .setgoal a { color: #fff; font-weight: 600; }

.facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem; margin: 1.1rem .2rem 0; }
.facts dt { font-size: .8rem; color: var(--muted); }
.facts dd { margin: .1rem 0 0; font-weight: 700; font-stretch: 112%; font-size: 1.05rem; }

/* ---------- where the money goes ---------- */
.catstack { display: block; width: 100%; height: 22px; margin: .2rem 0 1rem; }
.seg.s0, .key.s0 { fill: var(--s0); background: var(--s0); }
.seg.s1, .key.s1 { fill: var(--s1); background: var(--s1); }
.seg.s2, .key.s2 { fill: var(--s2); background: var(--s2); }
.seg.s3, .key.s3 { fill: var(--s3); background: var(--s3); }
.seg.s4, .key.s4 { fill: var(--s4); background: var(--s4); }
.seg.s5, .key.s5 { fill: var(--s5); background: var(--s5); }
.seg.s6, .key.s6 { fill: var(--s6); background: var(--s6); }
.seg.s7, .key.s7 { fill: var(--s7); background: var(--s7); }
.key { display: block; width: 10px; height: 10px; border-radius: 3px; flex: none; }
.legend { list-style: none; margin: 0; padding: 0; }
.legend a {
  display: grid; grid-template-columns: 10px 1fr auto auto; align-items: baseline; gap: .75rem;
  padding: .6rem 0; border-top: 1px solid var(--rule); color: var(--ink); text-decoration: none;
}
.legend li:last-child a { border-bottom: 1px solid var(--rule); }
.legend a:hover .name { color: var(--accent); }
.legend .key { transform: translateY(1px); }
.legend .name small { display: block; }
.legend small.up { color: var(--loss); }
.legend small.down { color: var(--gain); }
.share { color: var(--muted); font-size: .85rem; min-width: 2.6rem; text-align: right; }
.pending { display: flex; align-items: center; justify-content: space-between; gap: 1rem;
           margin-top: 1rem; padding: .7rem .9rem; border-radius: 12px; background: var(--surface);
           box-shadow: 0 0 0 1px var(--rule); }
.pending p { margin: 0; font-size: .92rem; }

/* ---------- layout ---------- */
.columns { display: grid; gap: 0 3rem; }
@media (min-width: 900px) { .columns { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); } }
.block { margin: 0 0 2.25rem; }
.headrow { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; }
.headrow a { font-size: .92rem; }

/* ---------- lists ---------- */
.plain, .moves, .feed, .points { list-style: none; margin: 0; padding: 0; }
.plain li {
  display: grid; grid-template-columns: 1fr auto; align-items: baseline; gap: .1rem 1rem;
  padding: .65rem 0; border-top: 1px solid var(--rule);
}
.plain li:last-child { border-bottom: 1px solid var(--rule); }
.moves li {
  display: grid; grid-template-columns: 10px 1fr auto; align-items: baseline; gap: .1rem .75rem;
  padding: .65rem 0; border-top: 1px solid var(--rule);
}
.moves li:last-child { border-bottom: 1px solid var(--rule); }
.moves .key { transform: translateY(1px); }
.name { min-width: 0; color: var(--ink); text-decoration: none; overflow-wrap: anywhere; }
a.name:hover { color: var(--accent); }
.name small { display: block; }
.detail { opacity: .8; }
.amount { white-space: nowrap; text-align: right; font-weight: 600; }
.amount.pos, .pos { color: var(--gain); }
.amount.neg, .neg { color: var(--loss); }

/* movements page */
.pagehead { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.pagehead h1 { margin-bottom: .5rem; }
.pager { display: flex; gap: .4rem; }
.pager a { display: grid; place-items: center; width: 2.6rem; height: 2.6rem; border-radius: 50%;
           font-size: 1.4rem; text-decoration: none; color: var(--ink); background: var(--surface);
           box-shadow: 0 0 0 1px var(--rule); }
.pager a:hover { color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.filter { margin: 0 0 1rem; display: flex; gap: 1rem; align-items: baseline; font-weight: 600; }
.day { font-weight: 700; font-size: .85rem; color: var(--muted); margin: 1.6rem 0 .3rem; }
.moves.edit .name small { display: none; }
.recat { grid-column: 2 / -1; display: flex; gap: .4rem; margin-top: .1rem; }
.recat select { padding: .15rem .35rem; font-size: .82rem; color: var(--muted); background: transparent;
                border-color: transparent; margin-left: -.35rem; }
.recat select:hover, .recat select:focus { border-color: var(--rule); color: var(--ink); }
.js .recat button { display: none; }

/* notifications */
.feed { max-width: 46rem; }
.feed li { border-top: 1px solid var(--rule); }
.feed li:last-child { border-bottom: 1px solid var(--rule); }
.feed a { display: grid; gap: .1rem; padding: .75rem 0 .75rem 1rem; color: var(--ink); text-decoration: none;
          border-left: 3px solid transparent; }
.feed li.unread a { border-left-color: var(--accent); }
.feed li:not(.unread) strong { font-weight: 500; }
.feed span { color: var(--muted); }
.empty { color: var(--muted); padding: 1rem 0 2rem; }
#push { padding: 1.1rem; background: var(--surface); border-radius: 16px; box-shadow: 0 0 0 1px var(--rule); max-width: 46rem; }
#push-status { margin: 0 0 .8rem; }

/* advisor */
.verdict { padding: 0 0 1.75rem; margin-bottom: 2rem; border-bottom: 1px solid var(--rule); }
.verdict .summary { font-size: 1.35rem; line-height: 1.45; font-weight: 500; font-stretch: 105%;
                    margin: 0 0 1.25rem; max-width: 42ch; }
.verdict .facts { margin: 0; }
.verdict small { display: block; margin-top: 1rem; }
.points li { position: relative; padding: .5rem 0 .5rem 1.2rem; max-width: 65ch; }
.points li::before { content: ""; position: absolute; left: 0; top: 1.05rem; width: .5rem; height: 2px;
                     border-radius: 1px; background: var(--muted); }
.points.warn li::before { background: var(--note-tight); }

/* bank */
.status { margin: 0 0 1rem; padding: .9rem 1rem; border-radius: 14px; background: var(--surface);
          box-shadow: 0 0 0 1px var(--rule); font-weight: 600; }
.status.ok { box-shadow: inset 4px 0 0 var(--accent), 0 0 0 1px var(--rule); }
.status small { display: block; margin-top: .25rem; font-weight: 400; }

/* sign-in */
.signin { padding-top: 10vh; }
.signin h1 { font-size: 2.6rem; font-stretch: 125%; font-weight: 850; letter-spacing: -.02em; }
.signin .or { color: var(--muted); font-size: .9rem; margin: 1.75rem 0 .5rem; }
.code { font-weight: 800; font-stretch: 125%; font-size: 1.7rem; letter-spacing: .35em; text-align: center; }
.legal { display: flex; gap: 1.25rem; margin-top: 3rem; font-size: .85rem; }
.legal a { color: var(--muted); }
.prose { max-width: 62ch; padding-top: 1.5rem; }
.prose p { line-height: 1.65; }

/* ---------- activity (background jobs) ---------- */
#activity { max-width: 1120px; margin: 0 auto; padding: .9rem 1rem 0; }
#activity:has(.activity:empty) { padding-top: 0; }
.activity:empty { display: none; }
.job {
  margin: .25rem 0 1rem; padding: .9rem 1rem; border-radius: 16px;
  background: var(--surface); box-shadow: 0 0 0 1px var(--rule);
}
.job.running { box-shadow: inset 4px 0 0 var(--accent), 0 0 0 1px var(--rule); }
.job.failed { box-shadow: inset 4px 0 0 var(--loss), 0 0 0 1px var(--rule); }
.job.done { box-shadow: inset 4px 0 0 var(--gain), 0 0 0 1px var(--rule); }
.job .title { margin: 0; font-weight: 650; }
.job .line { margin: .15rem 0 0; color: var(--ink); font-size: .92rem; }
.job .meta { margin: .45rem 0 0; color: var(--muted); font-size: .85rem; }
.job .meter { display: block; width: 100%; height: 6px; margin-top: .7rem; }
.job .meter .track { fill: var(--rule); }
.job .meter .fill { fill: var(--accent); }
.meter.indeterminate { position: relative; height: 6px; margin-top: .7rem; border-radius: 3px;
                       background: var(--rule); overflow: hidden; }
.meter.indeterminate b { position: absolute; inset: 0 auto 0 0; width: 30%; border-radius: 3px;
                         background: var(--accent); animation: slide 1.4s ease-in-out infinite; }
@keyframes slide { from { transform: translateX(-100%); } to { transform: translateX(340%); } }

/* ---------- controls ---------- */
form.stack { display: grid; gap: .9rem; max-width: 24rem; }
.row { display: flex; flex-wrap: wrap; gap: .6rem; align-items: end; margin-bottom: 1rem; }
.actions { display: flex; flex-wrap: wrap; gap: .6rem; }
.actions form { margin: 0; }
label { display: grid; gap: .3rem; font-size: .9rem; color: var(--muted); }
label.check { display: flex; align-items: center; gap: .65rem; color: var(--ink); font-size: 1rem; padding: .2rem 0; }
label.check input { width: 1.15rem; height: 1.15rem; accent-color: var(--accent); }
input, select {
  font: inherit; color: var(--ink); background: var(--surface);
  padding: .65rem .75rem; border: 1px solid var(--rule); border-radius: 10px; min-width: 0;
}
input:focus, select:focus { border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px var(--accent-soft); }
button, .button {
  display: inline-block; font: 600 1rem/1.2 var(--font); padding: .75rem 1.2rem; border-radius: 999px;
  border: 1px solid var(--ink); background: var(--ink); color: var(--paper);
  cursor: pointer; text-decoration: none; text-align: center;
}
button:hover, .button:hover { opacity: .88; }
button.secondary, .button.secondary { background: transparent; color: var(--ink); border-color: var(--rule); }
button.secondary:hover, .button.secondary:hover { border-color: var(--ink); opacity: 1; }
button.small { padding: .35rem .8rem; font-size: .85rem; }
button.link { background: none; border: 0; padding: 0; color: var(--muted); text-decoration: underline;
              text-underline-offset: .18em; font-weight: 400; font-size: .95rem; border-radius: 0; }
button[disabled] { opacity: .45; cursor: default; }

.notice { margin: 0 0 1rem; padding: .75rem 1rem; border-radius: 14px; background: var(--accent-soft); }
.notice.warn { background: var(--warn-soft); color: var(--ink); }
[hidden] { display: none !important; }

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* ---------- kinds ---------- */
.tag { display: inline-block; margin-right: .4rem; padding: 0 .4rem; border-radius: 6px;
       font-size: .72rem; font-weight: 650; line-height: 1.35rem; vertical-align: 1px;
       background: var(--rule); color: var(--ink); }
.tag.refund, .tag.income { background: color-mix(in srgb, var(--gain) 16%, transparent); color: var(--gain); }
.amount.mute, .mute { color: var(--muted); }
.moves li.internal .name, .moves li.savings .name { color: var(--muted); }
.chips-row { display: flex; gap: .4rem; overflow-x: auto; margin: 0 -1rem 1rem; padding: .1rem 1rem;
             scrollbar-width: none; }
.chips-row::-webkit-scrollbar { display: none; }
.chips-row a { flex: none; padding: .45rem .85rem; border-radius: 999px; font-size: .88rem; font-weight: 550;
               color: var(--ink); text-decoration: none; background: var(--surface); box-shadow: 0 0 0 1px var(--rule); }
.chips-row a[aria-current] { background: var(--ink); color: var(--paper); box-shadow: none; }
.pager .off { display: grid; place-items: center; width: 2.6rem; height: 2.6rem; color: var(--rule); font-size: 1.4rem; }

/* ---------- month viewer ---------- */
.chart-block { margin-bottom: 1.5rem; }
.chart-legend { display: flex; flex-wrap: wrap; gap: .4rem 1.2rem; margin: 0 0 .6rem; font-size: .85rem; color: var(--muted); }
.chart-legend span { display: inline-flex; align-items: center; gap: .45rem; }
.months { display: block; width: 100%; height: clamp(140px, 32vw, 220px); overflow: visible; }
.month-labels { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; margin-top: .35rem; }
.month-labels a { text-align: center; font-size: .78rem; font-weight: 650; color: var(--muted); text-decoration: none;
                  padding: .2rem 0; border-radius: 6px; }
.month-labels a[aria-current] { color: var(--paper); background: var(--ink); }
.months .base { stroke: var(--rule); }
.months .s1 { fill: var(--s1); }
.months .s2 { fill: var(--s2); }
.months .grp { opacity: .38; }
.months .grp.sel, .months .grp:hover { opacity: 1; }
.months .hit { fill: transparent; }
.ledger { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .75rem;
          margin: 0 0 2rem; padding: 1rem; border-radius: 18px; background: var(--surface);
          box-shadow: 0 0 0 1px var(--rule); }
.ledger span { display: block; font-size: .8rem; color: var(--muted); }
.ledger strong { display: block; font-weight: 800; font-stretch: 115%; font-size: 1.2rem; line-height: 1.3; }
.ledger small { display: block; margin-top: .2rem; font-size: .75rem; line-height: 1.3; }
@media (max-width: 420px) {
  .ledger { grid-template-columns: 1fr 1fr; }
  .ledger .net { grid-column: 1 / -1; padding-top: .7rem; border-top: 1px solid var(--rule); }
  .ledger .net strong { font-size: 1.6rem; }
}
.cats-net small.refund { color: var(--gain); }

/* ---------- chat ---------- */
.bubble {
  position: absolute; z-index: 40; right: 1rem; bottom: 1rem;
  display: grid; place-items: center; width: 3.4rem; height: 3.4rem; border-radius: 50%;
  background: var(--ink); color: var(--paper);
  box-shadow: 0 6px 20px rgb(0 0 0 / .22), 0 0 0 1px rgb(255 255 255 / .06);
}
.bubble .icon { width: 24px; height: 24px; }
@media (min-width: 761px) { .bubble { bottom: 1.5rem; right: 1.5rem; } }
#chat-sheet { position: fixed; z-index: 50; inset: 0; background: rgb(0 0 0 / .35); }
#chat-sheet[hidden] { display: none; }
.chat { display: flex; flex-direction: column; min-height: 0; }
.chat.sheet {
  position: absolute; inset: 0; background: var(--paper);
  padding-top: env(safe-area-inset-top);
  display: flex; flex-direction: column;
  animation: rise .22s ease-out;
}
@media (min-width: 761px) {
  .chat.sheet { inset: 0 0 0 auto; width: min(440px, 100%); box-shadow: -10px 0 40px rgb(0 0 0 / .18);
                animation-name: slidein; }
}
@keyframes rise { from { transform: translateY(24px); opacity: 0; } }
@keyframes slidein { from { transform: translateX(24px); opacity: 0; } }
/* The chat page: the stage does not scroll, the chat log does. */
body.chatpage .scroll { overflow: hidden; display: flex; flex-direction: column; }
body.chatpage main { flex: 1; min-height: 0; width: 100%; padding-bottom: 0; }
body.chatpage main > .chat { height: 100%; }
.chat-head { display: flex; justify-content: space-between; align-items: center; gap: 1rem;
             padding: .9rem 1rem .7rem; border-bottom: 1px solid var(--rule); }
main > .chat .chat-head { padding-inline: 0; }
.chat-head h2 { margin: 0; }
.chat-actions { display: flex; align-items: center; gap: .6rem; }
.chat-actions form { margin: 0; }
.icon-btn { display: grid; place-items: center; width: 2.4rem; height: 2.4rem; flex: none; aspect-ratio: 1; padding: 0; border-radius: 50%;
            background: var(--surface); color: var(--ink); border: 0; box-shadow: 0 0 0 1px var(--rule); }
.chat-log { flex: 1; overflow-y: auto; padding: 1rem; display: flex; flex-direction: column; gap: .8rem;
            overscroll-behavior: contain; }
main > .chat .chat-log { padding-inline: 0; }
.msg { max-width: 88%; padding: .7rem .9rem; border-radius: 18px; line-height: 1.45; overflow-wrap: anywhere; }
.msg p { margin: 0 0 .5rem; } .msg p:last-child { margin-bottom: 0; }
.msg ul { margin: .3rem 0 .5rem; padding-left: 1.1rem; }
.msg li { margin: .15rem 0; }
.msg code { font-size: .9em; padding: 0 .25rem; border-radius: 4px; background: var(--paper); }
.msg.me { align-self: flex-end; background: var(--ink); color: var(--paper); border-bottom-right-radius: 6px; }
.msg.ai { align-self: flex-start; background: var(--surface); box-shadow: 0 0 0 1px var(--rule);
          border-bottom-left-radius: 6px; }
.msg.err { align-self: flex-start; background: var(--warn-soft); }
.msg.typing { display: flex; align-items: center; gap: .6rem; color: var(--muted); font-size: .92rem; }
.dots { display: inline-flex; gap: 3px; }
.dots i { width: 6px; height: 6px; border-radius: 50%; background: var(--muted); animation: blink 1.2s infinite; }
.dots i:nth-child(2) { animation-delay: .2s; } .dots i:nth-child(3) { animation-delay: .4s; }
@keyframes blink { 0%, 80%, 100% { opacity: .25; } 40% { opacity: 1; } }
.steps { margin-top: .5rem; font-size: .82rem; color: var(--muted); }
.steps summary { cursor: pointer; }
.steps ul { margin: .3rem 0 0; }
.chat-empty { margin: auto 0 0; }
.chat-empty p { color: var(--muted); margin: 0 0 .7rem; }
.chips { display: flex; flex-direction: column; align-items: flex-start; gap: .45rem; }
.chip { font: 500 .95rem/1.3 var(--font); text-align: left; padding: .6rem .9rem; border-radius: 14px;
        background: var(--surface); color: var(--ink); border: 0; box-shadow: 0 0 0 1px var(--rule); }
.chip:hover { box-shadow: 0 0 0 1px var(--ink); opacity: 1; }
.chat-input { display: flex; align-items: flex-end; gap: .5rem;
              padding: .7rem 1rem max(.7rem, env(safe-area-inset-bottom)); border-top: 1px solid var(--rule);
              background: var(--paper); }
main > .chat .chat-input { padding-inline: 0; padding-bottom: .7rem; }
.chat-input textarea { flex: 1; resize: none; font: inherit; color: var(--ink); max-height: 9rem;
                       padding: .7rem .9rem; border-radius: 20px; border: 1px solid var(--rule); background: var(--surface); }
.chat-input textarea:focus { outline: none; border-color: var(--ink); }
.chat-input button { width: 2.9rem; height: 2.9rem; padding: 0; display: grid; place-items: center; border-radius: 50%; flex: none; }
button.link.small { font-size: .85rem; }

.chat-actions .link { white-space: nowrap; }
main { padding-top: 1rem; }
.block form + form, .block .row + form { margin-top: .9rem; }
.row { margin-bottom: 0; }
.row label { flex: 1 1 12rem; }

/* ---------- rows are links ---------- */
.moves li { display: block; padding: 0; }
.moves a.row { display: grid; grid-template-columns: 10px 1fr auto; align-items: baseline; gap: .1rem .75rem;
               padding: .7rem 0; color: var(--ink); text-decoration: none; }
.moves a.row:active { background: color-mix(in srgb, var(--ink) 5%, transparent); }
.moves .recat { margin: -.35rem 0 .55rem calc(10px + .75rem); }
.back { margin: 0 0 .5rem; }
.back a { text-decoration: none; font-weight: 600; }
.txhead { margin-bottom: 1.25rem; }
.txhead h1 { margin: .5rem 0 .25rem; overflow-wrap: anywhere; }
.big { font-weight: 800; font-stretch: 118%; font-size: 1.9rem; margin: 0; }
.recat.solo { display: flex; align-items: end; gap: .6rem; margin: 0 0 1.25rem; }
.recat.solo label { flex: 1; }
.recat.solo select { font-size: 1rem; color: var(--ink); background: var(--surface); border-color: var(--rule); margin: 0; }
.kv { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .9rem 1rem; margin: 0 0 1.5rem;
      padding: 1rem; border-radius: 16px; background: var(--surface); box-shadow: 0 0 0 1px var(--rule); }
.kv .wide { grid-column: 1 / -1; }
.kv dt { font-size: .8rem; color: var(--muted); }
.kv dd { margin: .1rem 0 0; font-weight: 600; overflow-wrap: anywhere; }
.kv dd.big { font-size: 1.4rem; }

/* ---------- loans ---------- */
.loan { margin: 0 0 2rem; }
.loan header { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: .25rem 1rem; }
.loan header h2 { margin: 0; }
.loanbar { margin: .5rem 0 1rem; }
.loanbar .meter { display: block; width: 100%; height: 10px; }
.loanbar .track { fill: var(--rule); }
.loanbar .fill { fill: var(--accent); }
.loanbar p { margin: .4rem 0 0; font-weight: 600; }
.terms summary { cursor: pointer; font-weight: 600; color: var(--accent); margin-bottom: .75rem; }
.block form + .caption { margin-top: 1rem; }
.loan header + .caption, .loan header + .tag { margin-top: .5rem; }
.loan header small { display: block; width: 100%; }
