@font-face { font-family: "Hubot Sans"; font-weight: 400; font-display: swap; src: url(../fonts/hubot-400.woff2) format("woff2"); }
@font-face { font-family: "Hubot Sans"; font-weight: 500; font-display: swap; src: url(../fonts/hubot-500.woff2) format("woff2"); }
@font-face { font-family: "Hubot Sans"; font-weight: 600; font-display: swap; src: url(../fonts/hubot-600.woff2) format("woff2"); }
@font-face { font-family: "Hubot Sans"; font-weight: 700; font-display: swap; src: url(../fonts/hubot-700.woff2) format("woff2"); }
/* Hubot Sans draws zero with a bar through it, which misreads in money amounts. Digits only come from Geist. */
@font-face { font-family: "Hubot Sans"; font-weight: 400; font-display: swap; src: url(../fonts/digits-400.woff2) format("woff2"); unicode-range: U+30-39; }
@font-face { font-family: "Hubot Sans"; font-weight: 500; font-display: swap; src: url(../fonts/digits-500.woff2) format("woff2"); unicode-range: U+30-39; }
@font-face { font-family: "Hubot Sans"; font-weight: 600; font-display: swap; src: url(../fonts/digits-600.woff2) format("woff2"); unicode-range: U+30-39; }
@font-face { font-family: "Hubot Sans"; font-weight: 700; font-display: swap; src: url(../fonts/digits-700.woff2) format("woff2"); unicode-range: U+30-39; }
@font-face { font-family: "Plex Serif"; font-weight: 400; font-display: swap; src: url(../fonts/ibm-plex-serif-latin-400-normal.woff2) format("woff2"); }
@font-face { font-family: "Plex Serif"; font-weight: 600; font-display: swap; src: url(../fonts/ibm-plex-serif-latin-600-normal.woff2) format("woff2"); }

/* Dastafe brand book: primary (Cloud White, Electric Blue, Midnight Navy), accents (Crimson Rose, Mango Orange,
   Lime Green), tints (Silver Mist, Steel Grey, Slate Blue). Surfaces are Cloud White laid over Midnight Navy at 5% and 9%. */
:root {
  --navy: #0A1729;
  --ground: #0A1729;
  --surface: #162234;
  --raised: #202B3C;
  --line: #3B4554;
  --ink: #FBFBFB;
  --soft: #CED1D4;
  --muted: #AEB3BA;   /* Silver Mist, one step lighter: the brand value is too faint for small text on navy */
  --steel: #6C747F;
  --indigo: #3D30ED;
  --red: #F4435B;
  --orange: #FFA726;
  --green: #8BC34A;
  --sans: "Hubot Sans", "Noto Sans Georgian", system-ui, sans-serif;
  --serif: "Plex Serif", Georgia, serif;
  --pad: clamp(18px, 3vw, 40px);
  --r: 16px;
  /* Type scale: four steps. meta = labels, captions, times; body = rows and inputs; lead = bar and buttons; display = titles and totals. */
  --t-meta: 15px;
  --t-body: 16px;
  --t-lead: 17px;
  --t-display: clamp(24px, 3vw, 34px);
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { height: 100%; margin: 0; }
body {
  background: var(--ground); color: var(--ink); font: 500 17px/1.5 var(--sans); letter-spacing: .012em; text-rendering: optimizeLegibility;   /* light text on dark reads thinner than it is, so body text is medium, not regular */
  font-variant-numeric: tabular-nums; -webkit-text-size-adjust: 100%;
  word-spacing: .06em; letter-spacing: .01em;   /* Hubot Sans sets a narrow word space, so small text runs together on a tablet; never add font-smoothing: antialiased, it thins the text */
  display: flex; flex-direction: column; overscroll-behavior: none;
}
button, input, select { font: inherit; color: inherit; letter-spacing: inherit; word-spacing: inherit; }   /* form controls do not inherit spacing on their own, and most of this app is buttons */
button { cursor: pointer; }
:focus-visible { outline: 3px solid var(--ink); outline-offset: 2px; }
main:focus { outline: none; }
h1, h2, h3, p { margin: 0; }
h1 { word-spacing: 0; }
[hidden] { display: none !important; }

.bar {
  flex: none; display: flex; align-items: center; gap: 18px;
  padding: calc(env(safe-area-inset-top) + 12px) var(--pad) 12px; min-height: 64px; border-bottom: 1px solid var(--line);
}
.bar-back { display: flex; align-items: center; gap: 10px; color: var(--ink); text-decoration: none; font-weight: 500; padding: 8px 16px 8px 12px; min-height: 44px; border-radius: 99px; background: var(--surface); border: 1px solid var(--line); }
.bar-back:active { background: var(--raised); }
.bar-title { flex: 1; font-weight: 500; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bar-brand { height: 32px; display: block; }

#view { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; -webkit-overflow-scrolling: touch; padding: var(--pad); padding-bottom: calc(var(--pad) + env(safe-area-inset-bottom)); }   /* the start screen's glow overhangs its container, and without this the first screen a prospect touches drags sideways into empty navy; the chip bar carries its own overflow-x */
#view.fill { padding: 0; overflow: hidden; display: flex; flex-direction: column; }
.wrap { max-width: 1240px; margin: 0 auto; }

/* Start */
.start { max-width: 860px; margin: 0 auto; min-height: 100%; display: flex; flex-direction: column; justify-content: center; gap: clamp(32px, 6vh, 56px); text-align: center; position: relative; }
.start::before { content: ""; position: absolute; inset: -10% -30% auto; height: 70%; background: radial-gradient(closest-side, rgba(61, 48, 237, .38), rgba(61, 48, 237, 0)); pointer-events: none; }
.start > * { position: relative; }
.start h1 { font-size: clamp(34px, 4.6vw, 54px); line-height: 1.06; font-weight: 700; letter-spacing: -.022em; max-width: 18ch; margin: 0 auto; }
.start-list { display: flex; flex-direction: column; gap: 12px; }
.start-item { display: block; text-decoration: none; color: inherit; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 26px 24px; }
.start-item:active { background: var(--raised); border-color: var(--c); }
.start-item i { display: block; width: 36px; height: 5px; border-radius: 3px; background: var(--c); margin: 0 auto 16px; }
.start-item h2 { font-size: clamp(21px, 2.3vw, 26px); font-weight: 600; letter-spacing: -.012em; line-height: 1.15; }
.start-item p { color: var(--soft); margin-top: 8px; font-size: 17px; line-height: 1.45; }
.start-note { color: var(--muted); font-size: 15px; }

/* Shared */
.btn {
  border: 0; border-radius: 14px; background: var(--indigo); color: #fff; font-weight: 600; font-size: 19px;
  padding: 18px 28px; min-height: 60px; letter-spacing: 0;
}
.btn:active { background: #3026C4; }
.btn.quiet { background: transparent; color: var(--ink); border: 1px solid var(--line); border-radius: 99px; font-size: 16px; font-weight: 500; padding: 10px 18px; min-height: 44px; }
.btn.quiet:active, .btn.quiet.on { background: var(--raised); }
.btn.quiet.on { border-color: var(--muted); }
.btn.plain { background: transparent; color: var(--muted); font-size: 15px; font-weight: 500; padding: 10px 4px; min-height: 44px; }
.tag { display: inline-flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 500; white-space: nowrap; color: var(--c); }
.tag::before { content: ""; width: 9px; height: 9px; border-radius: 2px; background: var(--c); }
.over { --c: var(--red); } .match { --c: var(--green); } .review { --c: var(--orange); } .under { --c: var(--muted); }
.num { text-align: right; white-space: nowrap; }
.muted { color: var(--muted); }

/* Invoices: ready */
.ready { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 4fr); gap: clamp(24px, 4vw, 64px); align-items: start; }
.ready h1 { font-size: clamp(32px, 4vw, 48px); line-height: 1.06; font-weight: 700; letter-spacing: -.012em; }
.ready-side { position: sticky; top: 0; display: flex; flex-direction: column; gap: 24px; }
.ready-side > p { color: var(--muted); }
.inputs { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.inputs div { background: var(--surface); padding: 16px 18px; display: flex; flex-direction: column-reverse; gap: 2px; }
.inputs span { color: var(--muted); font-size: 15px; }
.inputs b { font-weight: 600; font-size: 24px; letter-spacing: -.012em; }
.pile { display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; background: var(--surface); }
.pile-row { display: grid; grid-template-columns: 1fr auto; gap: 0 16px; padding: 13px 20px; border-bottom: 1px solid var(--line); }
.pile-row:last-child { border-bottom: 0; }
.pile-row small { color: var(--muted); font-size: 15px; grid-column: 1; }
.pile-row .num { grid-row: 1 / span 2; grid-column: 2; align-self: center; font-weight: 500; }

/* Reconcile: picking the two sources */
.picker { min-height: 100%; display: flex; flex-direction: column; justify-content: flex-start; padding-top: clamp(24px, 9vh, 90px);   /* sits high, so an open list of seven fits below it */ gap: clamp(22px, 4vh, 40px); max-width: 980px; }
.picker h1 { font-size: clamp(30px, 4vw, 46px); font-weight: 700; letter-spacing: -.022em; line-height: 1.06; text-align: center; }
.pick-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(16px, 3vw, 36px); align-items: start; position: relative; z-index: 5; }   /* above the button row, so an open list is never covered */
.dd { position: relative; display: flex; flex-direction: column; gap: 8px; }
.dd.open { z-index: 6; }
.dd-label { font-size: 15px; font-weight: 500; color: var(--muted); padding-left: 4px; }
.dd-btn { display: flex; align-items: center; justify-content: space-between; gap: 16px; width: 100%; min-height: 84px; padding: 14px 22px; text-align: left;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); transition: border-color .2s ease, background-color .2s ease, opacity .3s ease; }
.dd-btn:disabled { opacity: .4; }
.dd-btn svg { flex: none; color: var(--muted); transition: transform .2s ease; }
.dd.open .dd-btn svg { transform: rotate(180deg); }
.dd-value { display: flex; flex-direction: column; min-width: 0; }
.dd-value b { font-weight: 600; font-size: clamp(19px, 2.1vw, 24px); letter-spacing: -.012em; line-height: 1.2; }
.dd-value small, .dd-opt small { color: var(--muted); font-size: 15px; margin-top: 2px; }
.dd-opt small { line-height: 1.3; margin-top: 1px; }
.dd-value em { font-style: normal; color: var(--muted); font-size: 18px; }
.dd.left.chosen .dd-btn { border-color: var(--indigo); box-shadow: inset 4px 0 0 var(--indigo); background: rgba(61, 48, 237, .16); }
.dd.right.chosen .dd-btn { border-color: var(--orange); box-shadow: inset 4px 0 0 var(--orange); background: rgba(255, 167, 38, .1); }
.dd.open .dd-btn { border-color: var(--muted); }
.dd-list { position: absolute; z-index: 10; left: 0; right: 0; top: calc(100% + 8px); max-height: min(56vh, 470px); overflow-y: auto; -webkit-overflow-scrolling: touch;
  background: var(--raised); border: 1px solid var(--line); border-radius: var(--r); padding: 6px; box-shadow: 0 18px 40px -12px rgba(0, 0, 0, .6); animation: rise .18s ease both; }
.dd-opt { display: flex; flex-direction: column; width: 100%; text-align: left; min-height: 46px; justify-content: center; padding: 4px 16px; border: 0; border-radius: 10px; background: none; }   /* seven sources: set a little closer, so the whole list stands clear of the foot of the tablet and the newest pair is not under a standing thumb */
.dd-opt b { font-weight: 500; font-size: 17px; line-height: 1.3; }
.dd-opt:active, .dd-opt.on { background: rgba(251, 251, 251, .08); }
.pick-go { display: flex; justify-content: center; }
.pick-go .btn { min-width: 280px; }
.pick-go .btn:disabled { background: var(--raised); color: var(--muted); }

/* Reconcile: the two records and the rule their fields fly into */
.stage-wrap { position: relative; min-height: 100%; display: flex; flex-direction: column; justify-content: center; gap: 18px; }
.stage { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr) minmax(0, 1fr); gap: clamp(14px, 2.4vw, 32px); align-items: start; }
.stage h3 { font-size: 20px; font-weight: 600; letter-spacing: 0; }   /* the house rule: no negative letter-spacing under 22px, and these headings never reach it */
.stage h3 + p { color: var(--muted); font-size: 15px; margin: 2px 0 14px; }
.rec { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 20px 18px 14px; }
.rec.left { border-top: 4px solid var(--indigo); }
.rec.right { border-top: 4px solid var(--orange); }
.f { display: flex; flex-direction: column; justify-content: center; min-height: 50px;   /* grows when a long field name wraps, so its value is never cut through */ padding: 0 12px; margin: 0 -6px 4px; border-radius: 10px; border: 1px solid transparent; transition: opacity .5s ease, border-color .25s ease, background-color .25s ease; }
.f span { font-size: 15px; color: var(--muted); line-height: 1.25; }
.f b { font-weight: 500; font-size: 15px; line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.stage.dimmed .f.spare { opacity: .22; }
.rec.left .f.lift { border-color: var(--indigo); background: rgba(61, 48, 237, .3); }
.rec.right .f.lift { border-color: var(--orange); background: rgba(255, 167, 38, .2); }
.f.sent { opacity: .38; }
.rule { padding-top: 24px; text-align: center; }
.slot { display: flex; min-height: 78px; margin-bottom: 8px; border: 1px dashed var(--line); border-radius: 10px; transition: border-color .3s ease, background-color .3s ease; }   /* grows with its text, so a long value is never cut through */
.slot-in { flex: 1; min-width: 0; display: flex; flex-direction: column; justify-content: center; gap: 1px; padding: 6px 14px; opacity: 0; transition: opacity .3s ease; }
.slot .names { font-size: 15px; color: var(--muted); }
.slot .names i, .slot .val i { font-style: normal; color: var(--steel); margin: 0 3px; }
.slot .val { font-weight: 600; font-size: 15.5px; overflow-wrap: anywhere; }
.slot .verdict { font-size: 15px; color: var(--green); font-weight: 500; }
.slot .verdict em { font-style: normal; font-weight: 500; color: var(--muted); margin-right: 8px; }
.slot .verdict::after { content: " \2713"; }
.slot .verdict.bad::after { content: ""; }
.slot .verdict.bad { color: var(--orange); }
.slot.meet { border: 1px solid var(--green); background: rgba(139, 195, 74, .1); }
.slot.full .slot-in { opacity: 1; }
.ghost { position: absolute; z-index: 20; will-change: transform, opacity; margin: 0; pointer-events: none; display: flex; flex-direction: column; justify-content: center; padding: 0 12px; border-radius: 10px; overflow: hidden; }
.ghost span { font-size: 15px; line-height: 1.25; color: var(--soft); }
.ghost b { font-weight: 500; font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ghost.from-left { background: rgba(61, 48, 237, .55); border: 1px solid var(--indigo); text-align: left; }
.ghost.from-right { background: rgba(255, 167, 38, .38); border: 1px solid var(--orange); text-align: right; align-items: flex-end; }
.tally { margin-top: 18px; min-height: 52px; opacity: 0; transition: opacity .3s ease; font-size: 15px; color: var(--muted); }
.tally.on { opacity: 1; }
.tally .meter { height: 4px; border-radius: 2px; background: var(--line); overflow: hidden; margin-bottom: 10px; }
.tally .meter i { display: block; height: 100%; width: 100%; background: var(--green); transform: scaleX(0); transform-origin: left; }
.tally.done .meter i { transform: scaleX(1) !important; }
.tally b { font-weight: 700; font-size: 22px; color: var(--c); margin: 0 4px 0 12px; letter-spacing: -.012em; }
.tally b:first-child { margin-left: 0; }
.skip { text-align: center; color: var(--muted); font-size: 15px; }   /* steel is for lines only: as text it is too faint on navy */
.stage-next { min-height: 60px; display: flex; align-items: center; justify-content: center; }
.stage-next .btn { min-width: 280px; animation: rise .4s cubic-bezier(.2, .7, .2, 1) both; }
.pay-title { display: flex; align-items: center; justify-content: space-between; gap: 20px; margin-bottom: 24px; }
.pay-title h1 { font-size: var(--t-display); font-weight: 700; letter-spacing: -.03em; line-height: 1.1; text-wrap: balance; }
.pay-title h1 i { font-style: normal; font-weight: 500; color: var(--muted); }
.pay-title .btn { flex: none; }
.pay-title .btn.off { visibility: hidden; }   /* a closed day sends no test transaction; the button keeps its place, so nothing under it moves when the day changes */

/* Payments: the results page. Top to bottom: verdict, tie-out, one bar, what needs attention, what is worth knowing, the list. */
.mark { flex: none; display: inline-block; width: 13px; height: 13px; border-radius: 3px; background: var(--c); }
.pay > .verdict { margin-bottom: 16px; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0 24px; align-items: start; }   /* scoped: the matching animation has its own .verdict inside every slot */
/* The day switcher: one compact control beside the verdict it changes. The days of the run, oldest first, the one on screen lit */
.pay > .verdict .days { grid-area: 1 / 2; }
.pay > .verdict .v-sub, .pay > .verdict .v-sign { grid-column: 1 / -1; }
.seg.days button { padding: 0 14px; font-size: var(--t-meta); white-space: nowrap; }
.v-line { display: flex; align-items: baseline; gap: 14px; font-size: clamp(20px, 2.3vw, 27px); font-weight: 700; letter-spacing: -.02em; line-height: 1.22; word-spacing: 0; text-wrap: balance; }
.v-line b { display: inline-block; font-weight: 700; transform-origin: left center; }
.v-sub { color: var(--muted); font-size: var(--t-meta); margin: 8px 0 0 27px; text-wrap: balance; }
.tie { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); margin-bottom: 16px; }
.tie-sides { display: flex; flex-direction: column; gap: 12px; padding: 18px 24px 14px; border-right: 1px solid var(--line); }   /* set a little closer than the lines beside it: a side that starts with an opening line is one line taller, and the block must not push what needs attention off the first screen */
.tie-row, .tie-line { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0 16px; align-items: baseline; }
.tie .tl { font-size: var(--t-body); }
.tie .tl small { color: var(--muted); font-size: var(--t-meta); }
.tie-row small { grid-column: 1 / -1; color: var(--muted); font-size: var(--t-meta); }
.wf { display: flex; justify-content: space-between; gap: 16px; line-height: 1.2; }   /* a settlement: how the expected payouts are made up, figures under the total they add up to; set a little closer so the block is no taller than the list beside it */
.wf span:last-child { white-space: nowrap; }
.wf:first-child { margin-top: 2px; }
.tie-row .own { display: block; }
.wf-open { grid-column: 1 / -1; margin-top: 2px; }   /* how a side is made up: arithmetic a reader opens, not something they must read past */
.wf-open summary { display: inline-block; color: var(--muted); font-size: var(--t-meta); cursor: pointer; padding: 2px 0; list-style: none; }
.wf-open summary::-webkit-details-marker { display: none; }
.wf-open summary::after { content: " \203A"; display: inline-block; transition: transform .15s ease; }
.wf-open[open] summary::after { transform: rotate(90deg); }
.wf-open .wf-list { display: block; color: var(--muted); font-size: var(--t-meta); padding-top: 4px; }
.wf-plain { grid-column: 1 / -1; color: var(--muted); font-size: var(--t-meta); }
.tie .fig { text-align: right; white-space: nowrap; font-weight: 600; }
.tie-row .fig { font-size: clamp(19px, 2vw, 23px); font-weight: 700; letter-spacing: -.02em; word-spacing: 0; }
.tie-row.diff { margin-top: auto; padding-top: 12px; border-top: 1px solid var(--line); }   /* sits level with Unexplained, the figure it must agree with */
.tie-why { padding: 18px 20px 10px 24px; }
.tie-why h2 { font-size: var(--t-body); font-weight: 600; }
.tie-key { color: var(--muted); font-size: var(--t-meta); margin: 0 0 6px; }
@media (max-width: 1100px) { .v-line, .tie-row .fig, .start-item h2 { letter-spacing: 0; } }   /* the same rule: below this width these three fall under 22px, where tight tracking thins the text */
.tie-lines { display: flex; flex-direction: column; }
.tie-line { padding: 6px 0; border-top: 1px solid var(--line); }   /* the currency line carries a sentence, so the block is set a little closer: what needs attention must stay on the first screen */
.tie-line .tl > span { margin-right: 6px; }
.tie-line .tl small { display: inline-block; white-space: nowrap; }   /* "1 item, dealt with" moves to the next line whole, and leaves the title whole on the first: the gap belongs to the title, so a count on a line of its own starts at the edge */
.tie-line.said .tl small { white-space: normal; }   /* a line that names its stock says more than a count, and on a phone that phrase has to break rather than run off the card */
.tie-line[data-k=fx] .tl { display: contents; }   /* the FX note is a sentence, so it runs under the line at full width */
.tie-line[data-k=fx] .fig { grid-area: 1 / 2; }
.tie-line[data-k=fx] .tl small { grid-area: 2 / 1 / auto / -1; margin: 2px 0 0; white-space: normal; text-wrap: pretty; }
@media (max-width: 1100px) { .tie-line[data-k=fx] .tl small .wide { display: none; } }   /* the sentence has to stay on two lines here, or what needs attention drops off the first screen: what is already booked is on its own line under Worth knowing */
.tie-line.unexplained { order: 99; font-weight: 600; }
.tie-line.ok .fig { color: var(--green); }
.tie-line.bad .fig { color: var(--red); }
.split { margin-bottom: 14px; }
.split-head { display: flex; align-items: center; justify-content: space-between; gap: 10px 20px; flex-wrap: wrap; margin-bottom: 10px; }
.split-head p { flex: 1 1 320px; font-size: var(--t-body); }
.modes { display: flex; gap: 8px; }
.modes .chip, .filters .chip { min-height: 44px; padding: 8px 16px; font-size: var(--t-meta); color: var(--muted); }
.modes .chip.on, .filters .chip.on { background: var(--raised); color: var(--ink); border-color: var(--muted); }
.split-bar { position: relative; height: 14px; border-radius: 99px; overflow: hidden; background: var(--raised); }
.split-bar i { position: absolute; inset: 0; background: var(--c); transform-origin: left center; transition: transform .6s cubic-bezier(.2, .7, .2, 1); }   /* segments are placed with a transform, so switching count and value never re-lays-out the page */
.s-exact { --c: var(--green); } .s-within { --c: rgba(139, 195, 74, .45); } .s-attention { --c: var(--orange); } .s-transit { --c: var(--steel); }
.split-legend { list-style: none; display: flex; flex-wrap: wrap; gap: 6px 24px; margin: 12px 0 0; padding: 0; font-size: var(--t-meta); color: var(--soft); }
.split-legend i { display: inline-block; width: 9px; height: 9px; border-radius: 2px; background: var(--c); margin-right: 9px; }
.split-legend b { font-weight: 600; color: var(--ink); margin-left: 3px; }
.lists { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 430px), 1fr)); gap: 24px; align-items: start; margin-bottom: 20px; }
.glist h2 { display: flex; align-items: baseline; gap: 10px; font-size: var(--t-body); font-weight: 600; margin-bottom: 10px; }
.glist h2 small { margin-left: auto; color: var(--muted); font-size: var(--t-meta); font-weight: 500; }
.glines { display: flex; flex-direction: column; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.gline { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0 16px; align-items: start; width: 100%; min-height: 64px; padding: 13px 18px; border: 0; background: var(--surface); text-align: left; font-size: var(--t-body); }
.gline:active, .gline.on { background: var(--raised); }
.gline:disabled { cursor: default; }   /* a worth-knowing line with no row behind it reads the same, it just does not offer to filter the list */
.gline:disabled:active { background: var(--surface); }
.gline.on { box-shadow: inset 4px 0 0 var(--indigo); }
.gline small { display: block; color: var(--muted); font-size: var(--t-meta); margin-top: 2px; }
.gline .gv { text-align: right; white-space: nowrap; }
/* Ageing: how long an item has been open, once that is longer than today. Crimson Rose, because by then it is no longer a timing difference */
.age { font-style: normal; font-weight: 600; color: var(--red); }
.txr .age { white-space: nowrap; }
.ageing { display: flex; align-items: baseline; gap: 2px 14px; margin-top: 10px; padding: 0 2px; color: var(--soft); font-size: var(--t-meta); }   /* one line beside a second list. The label keeps its column, so buckets that wrap line up under the first bucket, and a bucket never breaks inside */
.ageing > span:first-child { flex: 0 0 auto; color: var(--muted); }
.ageing .ab { display: flex; flex-wrap: wrap; gap: 2px 14px; min-width: 0; }
.ageing .ab span { white-space: nowrap; }
.ageing b { font-weight: 600; color: var(--ink); }
.ageing .old b { color: var(--red); }
.gline .gv b { font-weight: 600; }
/* A group's line, the one action under it, and the document that action writes. Dealt with is Electric Blue wherever it shows: the bar, the rows, the marks */
.gitem { background: var(--surface); scroll-margin-top: 12px; }
.gitem.on { background: var(--raised); box-shadow: inset 4px 0 0 var(--indigo); }
.gitem .gline { background: none; }
.gitem .gline:active { background: var(--raised); }
.gitem.done .gt > span::before { content: ""; display: inline-block; width: 6px; height: 12px; margin: 0 11px 1px 3px; border: solid var(--green); border-width: 0 2.5px 2.5px 0; transform: rotate(45deg); }   /* a tick drawn, not typed: the glyph is hairline thin in this font */
.gdo { display: flex; flex-wrap: wrap; gap: 8px; padding: 0 18px 14px; }
.btn.act { font-size: var(--t-meta); min-height: 44px; padding: 8px 18px; border-radius: 99px; }
.gdo .btn.act + .btn.act, .gdo .btn.act.soft { background: none; border: 1px solid var(--line); color: var(--ink); }   /* where the person chooses between two, one solid button per group is enough; and a worth-knowing line is not where the solid button of the block above belongs */
.gdo .btn.act + .btn.act:active, .gdo .btn.act.soft:active { background: var(--raised); }
.gdo .btn.plain, .doc-acts .btn.plain, .v-sign .btn.plain { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.gdo .btn.plain { padding: 8px 0; margin-top: -8px; }
.gdoc { padding: 16px 18px; background: var(--ground); border-top: 1px solid var(--line); font-size: var(--t-meta); color: var(--soft); animation: rise .2s ease both; }
.gdoc h3 { font-size: var(--t-body); font-weight: 600; color: var(--ink); margin-bottom: 8px; }
.gdoc p, .gdoc li { overflow-wrap: anywhere; }
.gdoc p { margin-top: 8px; }
.gdoc .dh { margin-top: 2px; color: var(--ink); }
.gdoc .dh span { display: inline-block; min-width: 68px; color: var(--muted); }
.gdoc ol { margin: 8px 0 0; padding-left: 24px; }
.gdoc li + li { margin-top: 4px; }
.jr { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0 16px; padding: 8px 0; border-top: 1px solid var(--line); color: var(--ink); }
.jr b { font-weight: 600; white-space: nowrap; }
.jr small { grid-column: 1 / -1; font-size: var(--t-meta); color: var(--soft); }
.jr small i { font-style: normal; color: var(--muted); }
.jr small span { display: inline-block; margin-right: 14px; }   /* debit and credit wrap as two whole pieces, never in the middle of an account name */
.jr.sum { font-weight: 600; }
.doc-acts { display: flex; align-items: center; gap: 20px; margin-top: 14px; }
.glist > .btn.quiet { margin-top: 12px; }
.glist.done, .txr.done, .did { --c: var(--indigo); }
.s-resolved { --c: var(--indigo); }
.txd .did { grid-column: 1 / -1; display: flex; align-items: baseline; gap: 9px; margin-top: 4px; color: var(--ink); }
.txd .did .mark { width: 9px; height: 9px; border-radius: 2px; }
.v-sign { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin: 12px 0 0 27px; font-size: var(--t-meta); color: var(--soft); animation: rise .4s cubic-bezier(.2, .7, .2, 1) both; }
.v-sign input { width: 168px; height: 44px; padding: 0 12px; border-radius: 10px; border: 1px solid var(--line); background: var(--surface); font-size: var(--t-body); }
.v-sign input::placeholder { color: var(--muted); }
.v-sign input:focus { outline: none; border-color: var(--ink); }
.v-sign .btn.quiet { margin-left: 8px; }

.sim { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 22px; margin-bottom: 24px; }
.sim form { display: grid; grid-template-columns: 236px minmax(0, 1fr) 140px minmax(0, 1.6fr) 140px; gap: 12px; align-items: end; }
.sim form:where(.one-way) { grid-template-columns: minmax(0, 1fr) 140px minmax(0, 1.6fr) 140px; }   /* no direction to choose: the control is left out, not shown with one button */
.sim form:where(.no-method) { grid-template-columns: 140px minmax(0, 1.6fr) 140px; }                /* a balance has one method and one currency: only the amount and what happens to it */
.sim label { display: flex; flex-direction: column; gap: 5px; font-size: var(--t-meta); color: var(--muted); }
.sim select, .sim input { height: 48px; border-radius: 10px; border: 1px solid var(--line); background: var(--ground); color: var(--ink); padding: 0 12px; font-size: var(--t-body); width: 100%; -webkit-appearance: none; appearance: none; }
.sim select { background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%); background-position: calc(100% - 19px) 21px, calc(100% - 13px) 21px; background-size: 6px 6px; background-repeat: no-repeat; padding-right: 34px; }
.sim select option { font-weight: 500; background: var(--surface); color: var(--ink); }   /* Chrome draws the open list at regular weight otherwise */
.sim select:focus, .sim input:focus { outline: none; border-color: var(--ink); }
.sim .hint { grid-column: 1 / -1; color: var(--orange); font-size: var(--t-meta); }
.sim .btn { font-size: var(--t-lead); min-height: 48px; height: 48px; padding: 0 12px; border-radius: 10px; }
.sim .btn:disabled { background: var(--raised); color: var(--muted); }
.seg { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; background: var(--ground); border: 1px solid var(--line); border-radius: 10px; padding: 1px; }
.seg button { border: 0; background: none; border-radius: 8px; height: 44px; padding: 0; font-size: var(--t-body); color: var(--muted); }
.seg button.on { background: var(--raised); color: var(--ink); font-weight: 500; }
.steps { list-style: none; margin: 0; padding: 0; display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 18px; }
.steps:not(:empty) { margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--line); }
.steps li { position: relative; padding: 14px 0 0; font-size: var(--t-meta); line-height: 1.4; border-top: 3px solid var(--c, var(--indigo)); }
.steps li.result { grid-column: span 2; }
.steps b { display: block; font-weight: 600; }
.steps span { color: var(--soft); }
.steps small { display: block; color: var(--muted); font-size: var(--t-meta); margin-top: 2px; overflow-wrap: break-word; }
.steps .nw { white-space: nowrap; }
.steps .btn { display: block; margin-top: 10px; width: 100%; font-size: var(--t-meta); height: auto; min-height: 44px; padding: 8px 14px; border-radius: 99px; text-wrap: balance; }
.steps .btn.plain { width: auto; padding: 8px 0; color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.filters { display: flex; gap: 8px; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; position: sticky; top: calc(-1 * var(--pad)); z-index: 3; background: var(--ground); padding: 10px var(--pad); margin: 0 calc(-1 * var(--pad)) 2px; }   /* stays in sight while the list scrolls, so the active filter is never a guess; sticky offsets start at the view's padding, hence the negative top. One row that slides sideways, so the bar is never two rows tall */
.filters::-webkit-scrollbar { display: none; }
.filters .chip { flex: none; }
.filters .chip[data-f=group] { order: -1; }   /* the named filter leads the row, so it is never off screen */
.filters .chip b { font-weight: 600; margin-left: 4px; }
.filters .chip i { font-style: normal; margin-left: 10px; color: var(--muted); }
.tx { border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; background: var(--surface); }
.tx .pad { padding: 22px; }
.tx .more { height: 1px; overflow-anchor: none; }   /* or Chrome pins the view to the new bottom after a jump and the next page never loads */
.txr { content-visibility: auto; contain-intrinsic-size: auto 58px; }   /* rows far off screen cost nothing to draw */
.filters:empty { display: none; }
.txr { display: flex; gap: 16px; align-items: center; width: 100%; min-height: 58px; padding: 8px 46px 8px 18px; border: 0; border-bottom: 1px solid var(--line); background: none; text-align: left; font-size: var(--t-body); }
.txr::after { content: ""; position: absolute; right: 21px; top: 50%; width: 8px; height: 8px; margin-top: -7px; border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted); transform: rotate(45deg); transition: transform .2s ease; }
.txr.open::after { transform: translateY(4px) rotate(-135deg); }
.txr:active, .txr.open { background: var(--raised); }
.txr.sim-row { background: rgba(61, 48, 237, .16); }
.txr .t { color: var(--muted); font-size: var(--t-meta); flex: 0 0 50px; white-space: nowrap; }   /* "14 Sept" is a date, never "14" over "Sept" */
.txr .tm { display: none; }
.txr .who { flex: 1.1 1 0; min-width: 0; }
.txr .amt { flex: 1.2 1 0; min-width: 0; }
.txr .res { flex: 1.7 1 0; min-width: 0; }
.txr small { display: block; color: var(--muted); font-size: var(--t-meta); }
.txr .who { font-weight: 500; }
.txr .who small { font-weight: 500; }
.txr .amt { text-align: right; white-space: nowrap; }
.txr .res { display: flex; align-items: baseline; gap: 9px; color: var(--soft); font-size: var(--t-meta); }
.txr .res i { flex: none; width: 9px; height: 9px; border-radius: 2px; background: var(--c); transform: translateY(-1px); }
.txr.idle { --c: var(--line); }
.txr.idle .res { color: var(--muted); }
.txr.within { --c: rgba(139, 195, 74, .45); }
.txr.review .res { color: var(--orange); }
.txd { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 24px; padding: 16px 18px 18px 84px; border-bottom: 1px solid var(--line); background: var(--ground); font-size: var(--t-meta); }
.txd h4 { margin: 0 0 4px; font-size: var(--t-meta); font-weight: 500; color: var(--muted); }
.txd p { overflow-wrap: anywhere; }
.txd .differs { color: var(--orange); font-weight: 600; }
.txd .differs.calm { color: var(--green); }
.txd .differs.was { color: var(--ink); }   /* dealt with, and the two figures still differ: green is kept for what matched */
.txd .why { grid-column: 1 / -1; color: var(--orange); margin-top: 6px; max-width: 90ch; }
.txd .why.calm { color: var(--soft); }
/* An open payout: how it is made up, line by line, and its payments one tap away */
.txr.po .t, .txr.lb .t { flex-basis: 60px; }   /* "14 Sept" on one line needs 57px: any narrower and that row's name starts a pixel to the right of the others */
.txr.po + .txd, .txr.lb + .txd { padding-left: 94px; }
.txr.lb .who { flex: 1.5 1 0; }                /* a balance line is named, not numbered: the name earns the room the reference would have taken */
.txd .mk { display: flex; justify-content: space-between; gap: 16px; max-width: 440px; }
.txd .mk span:last-child { white-space: nowrap; }
.txd .mk.strong, .txd .mk.sum { font-weight: 600; }
.txd .mk.sum { margin: 4px 0 2px; padding-top: 5px; border-top: 1px solid var(--line); }
.pays { grid-column: 1 / -1; }
.pl { display: grid; grid-template-columns: 116px minmax(0, 1fr) 124px 136px 136px; gap: 0 16px; padding: 8px 0; border-top: 1px solid var(--line); }
.pl span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pl .pt, .pl .pf, .pl .pn { color: var(--muted); }
.pl .pa, .pl .pf, .pl .pn { text-align: right; }
.pl .pf.high, .pl.flag .pr, .pl small { color: var(--orange); font-weight: 600; }   /* the same two tones as the rest of an open row: orange where it needs attention, green where it matched. A fee above contract is money to claim back, so it stays orange in a matched payout too */
.pl.calm.flag .pr, .pl.calm small:not(.high) { color: var(--green); }
.pl.was.flag .pr, .pl.was small:not(.high) { color: var(--ink); }
.pl small { font-size: var(--t-meta); margin-left: 10px; }
.pays .btn.plain { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.pl { width: 100%; min-height: 44px; align-content: center; background: none; border-left: 0; border-right: 0; border-bottom: 0; font: inherit; color: inherit; text-align: left; cursor: pointer; }   /* every payment opens its own trace, so the line is a button: it must still read as a line of the list, and be worth a finger */
.pl:hover, .pl[aria-expanded=true] { background: var(--surface); }
.pl.still { cursor: default; }                                       /* a balance movement is a line of a day's total: there is nothing behind it to open */
.pl.still:hover { background: none; }
.pl.still small { color: var(--muted); font-weight: 500; }
.pl.still small.high, .pl.still .pf.high { color: var(--orange); font-weight: 600; }
.pl-hint { padding: 8px 0 2px; }

/* Follow the money: the stops one payment made, along a rail. Upright on a phone, across on a tablet. */
.trace { grid-column: 1 / -1; margin: 10px 0 2px; padding: 4px 0 2px; }
.tr { --n: 4; display: grid; grid-auto-flow: column; grid-template-columns: repeat(var(--n), minmax(0, 1fr)); grid-template-rows: auto auto auto auto; list-style: none; margin: 0; padding: 0; max-width: calc(var(--n) * 260px); }   /* --n is the number of stops: a two-stop chain keeps a stop's width instead of stretching half a row between two dots */
.tr-s { position: relative; min-width: 0; padding: 34px 16px 0 0; --dot: var(--steel); display: grid; grid-template-rows: subgrid; grid-row: span 4; }   /* one source name wraps and another does not: subgrid keeps every time, figure and note on the same line across the strip */
.tr-s > i { position: absolute; top: 20px; left: 0; width: 11px; height: 11px; border-radius: 50%; background: var(--dot); box-shadow: 0 0 0 4px var(--ground); }
.tr-s + .tr-s::before { content: ""; position: absolute; top: 24px; left: -100%; width: 100%; height: 3px; border-radius: 2px; background: var(--line); }
.tr-g { position: absolute; top: 0; left: 0; width: 100%; text-align: center; font-style: normal; font-size: var(--t-meta); color: var(--muted); }   /* centred over the stretch of line to the stop on its right */
.tr-s b { display: block; font-weight: 500; color: var(--muted); }
.tr-w { display: block; font-weight: 600; margin-top: 2px; }
.tr-w small { font-size: var(--t-meta); font-weight: 500; color: var(--muted); }   /* no text on these screens goes under 15px, and a small element would */
.tr-m { display: block; font-weight: 600; }
.tr-n { display: block; font-size: var(--t-meta); color: var(--muted); }
.tr-s.due, .tr-s.none { --dot: var(--line); }
.tr-s.due .tr-w, .tr-s.due .tr-m, .tr-s.none .tr-w, .tr-s.none .tr-m { color: var(--muted); }
.tr-s.brk::before, .tr-s.none::before { background: none; border-top: 3px dashed var(--line); height: 0; }   /* the money never went down this stretch */
.tr-s.brk { color: var(--orange); --dot: var(--orange); }
.tr-s.brk b, .tr-s.brk .tr-n, .tr-s.brk .tr-w, .tr-s.brk .tr-m { color: inherit; }
.trace.was .tr-s.brk { color: var(--ink); --dot: var(--ink); }
.tr-why { grid-column: 1 / -1; margin-top: 14px; color: var(--soft); max-width: 90ch; }
.trace:not(.calm):not(.was) .tr-why { color: var(--orange); }

/* Invoices: results */
.hero { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: clamp(20px, 3vw, 48px); align-items: end; margin-bottom: 28px; }
.hero .k { color: var(--muted); font-size: 17px; }
.hero .v { font-size: clamp(48px, 7vw, 84px); font-weight: 700; letter-spacing: -.012em; line-height: 1; color: var(--red); margin: 6px 0 12px; }
.hero .v small { font-size: .42em; font-weight: 600; letter-spacing: 0; margin-right: .25em; }
.hero .t { color: var(--muted); }
.hero .t b { color: var(--ink); font-weight: 600; }
.bars { display: flex; align-items: flex-end; gap: 6px; height: 132px; }
.bars button { flex: 1; min-width: 0; border: 0; padding: 0; background: var(--c); border-radius: 4px 4px 0 0; min-height: 10px; }
.legend { display: flex; flex-wrap: wrap; gap: 6px 22px; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); }
.legend .tag b { color: var(--ink); font-weight: 600; margin-left: 2px; }
.rows { display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; background: var(--surface); }
.row { display: grid; grid-template-columns: 6px minmax(0, 1.4fr) minmax(0, 2fr) 200px 20px; gap: 0 20px; align-items: center; padding: 0 20px 0 0; min-height: 68px; border: 0; border-bottom: 1px solid var(--line); background: none; text-align: left; width: 100%; }
.row:last-child { border-bottom: 0; }
.row:active { background: var(--raised); }
.row i { align-self: stretch; background: var(--c); }
.row .who { font-weight: 600; font-size: 18px; letter-spacing: 0; }
.row .who small { display: block; font-weight: 500; font-size: 15px; color: var(--muted); letter-spacing: 0; }
.row .what { color: var(--muted); font-size: 16px; justify-self: start; text-align: left; }
.row .who { justify-self: start; }
.row .amt { justify-self: end; }
.row .amt { font-weight: 600; font-size: 19px; color: var(--c); letter-spacing: 0; }
.row.match .amt { color: var(--muted); font-weight: 500; font-size: 16px; }
.row svg { color: var(--muted); }
.results-foot { display: flex; justify-content: space-between; align-items: center; margin-top: 10px; }

/* Invoice detail */
.detail-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; margin-bottom: 24px; flex-wrap: wrap; }
.detail-head h1 { font-size: clamp(30px, 3.8vw, 44px); font-weight: 700; letter-spacing: -.012em; line-height: 1.05; margin-top: 8px; }
.detail-head .sum { text-align: right; }
.detail-head .sum .v { font-size: clamp(30px, 3.8vw, 44px); font-weight: 700; letter-spacing: -.012em; line-height: 1.05; color: var(--c); }
.detail { display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 7fr); gap: clamp(20px, 2.6vw, 36px); align-items: start; }
.paper { background: var(--ink); color: var(--navy); border-radius: 4px; padding: 28px 26px 22px; font-family: var(--serif); font-size: 15px; line-height: 1.4; }
.paper .muted { color: var(--steel); }
.paper h3 { font-size: 21px; font-weight: 600; }
.paper .meta { display: grid; grid-template-columns: auto 1fr; gap: 2px 14px; margin: 14px 0 18px; font-size: 14px; }
.paper .meta dt { color: var(--steel); }
.paper .meta dd { margin: 0; }
.paper table { width: 100%; border-collapse: collapse; font-size: 14px; }
.paper th { text-align: left; font-weight: 600; border-bottom: 1.5px solid var(--navy); padding: 6px 0; }
.paper th.num { text-align: right; }
.paper td { padding: 6px 0; border-bottom: 1px solid rgba(10, 23, 41, .12); }
.paper .total td { border-top: 1.5px solid var(--navy); border-bottom: 0; font-weight: 600; font-size: 17px; padding-top: 10px; }
.paper .more { color: var(--steel); font-style: italic; }
.paper .flag td { background: rgba(255, 167, 38, .28); }
.check h2 { font-size: 15px; font-weight: 500; color: var(--muted); margin-bottom: 12px; }
.check section + section { margin-top: 30px; }
table.compare { width: 100%; border-collapse: separate; border-spacing: 0; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; font-size: 16px; }
.compare th { text-align: left; font-size: 15px; font-weight: 500; color: var(--muted); padding: 13px 16px; border-bottom: 1px solid var(--line); width: 27%; }
.compare th:first-child { width: 19%; }
.compare td { padding: 14px 16px; border-bottom: 1px solid var(--line); vertical-align: top; }
.compare tr:last-child td { border-bottom: 0; }
.compare td:first-child { color: var(--muted); }
.compare tr.bad td { background: rgba(244, 67, 91, .13); }
.compare tr.bad td:first-child { box-shadow: inset 4px 0 0 var(--red); color: var(--ink); font-weight: 500; }
.compare tr.bad td:nth-child(2) { color: var(--red); font-weight: 500; }
.findings { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.findings li { display: grid; grid-template-columns: 1fr auto; gap: 20px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 16px 18px; }
.findings b { display: block; font-weight: 600; margin-bottom: 4px; }
.findings span { color: var(--muted); }
.findings .amt { font-weight: 600; white-space: nowrap; color: var(--ink); font-size: 18px; }
.note { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 18px 20px; white-space: pre-wrap; font-size: 15.5px; line-height: 1.55; color: var(--soft); }
.note-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.note-head h2 { margin: 0; }
.ask-box { background: rgba(255, 167, 38, .1); border: 1px solid rgba(255, 167, 38, .55); border-radius: var(--r); padding: 24px 26px; display: flex; flex-direction: column; gap: 14px; }
.ask-box h2 { margin: 0; font-size: 26px; font-weight: 600; color: var(--ink); letter-spacing: -.012em; }
.ask-box p { color: var(--soft); }
.ask-box p b { color: var(--orange); font-weight: 600; }
.ask-box .acts { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 6px; }
.remembered { background: rgba(139, 195, 74, .12); border: 1px solid rgba(139, 195, 74, .5); border-radius: var(--r); padding: 16px 18px; color: var(--green); }

/* Chat */
.chat { flex: 1; min-height: 0; display: flex; flex-direction: column; max-width: 980px; width: 100%; margin: 0 auto; }
.thread { flex: 1; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; padding: var(--pad) var(--pad) 8px; display: flex; flex-direction: column; gap: 20px; }
.intro { margin: auto 0; }
.intro h1 { font-size: clamp(34px, 4.6vw, 54px); font-weight: 700; letter-spacing: -.022em; line-height: 1.05; max-width: 16ch; }
.intro p { color: var(--muted); margin-top: 16px; max-width: 58ch; }
.chips { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 28px; }
.chip { background: var(--surface); border: 1px solid var(--line); border-radius: 99px; padding: 12px 20px; min-height: 48px; font-size: 16px; }
.chip:active { background: var(--raised); }
.q { align-self: flex-end; background: var(--indigo); color: #fff; border-radius: 20px 20px 4px 20px; padding: 13px 20px; max-width: 80%; font-size: 18px; }
.a { align-self: flex-start; max-width: 92%; width: fit-content; }
.a-text { background: var(--surface); border: 1px solid var(--line); border-radius: 4px 20px 20px 20px; padding: 18px 22px; font-size: 19px; line-height: 1.5; white-space: pre-wrap; color: var(--soft); }
.a-text strong { font-weight: 600; color: var(--ink); }
.a-work { color: var(--muted); font-size: 15px; padding: 2px 4px; }
.proof { margin-top: 10px; font-size: 15px; color: var(--muted); padding: 0 4px; display: flex; flex-wrap: wrap; gap: 4px 16px; align-items: center; }
.proof .ok { color: var(--green); font-weight: 500; }
.proof .ok::before { content: "\2713\00a0"; }
.proof .warn { color: var(--orange); font-weight: 500; }
.proof button { background: none; border: 0; color: var(--ink); padding: 8px 0; font-size: 15px; font-weight: 500; text-decoration: underline; text-underline-offset: 3px; }
.output { margin-top: 8px; background: var(--surface); border: 1px solid var(--line); border-radius: 12px; overflow-x: auto; }
.output table { border-collapse: collapse; font-size: 15px; white-space: nowrap; }
.output caption { text-align: left; padding: 10px 14px; color: var(--muted); font-size: 15px; border-bottom: 1px solid var(--line); }
.output th, .output td { padding: 7px 14px; text-align: right; border-bottom: 1px solid var(--line); }
.output tr:last-child td { border-bottom: 0; }
.output th { font-weight: 500; color: var(--muted); }
.output th:first-child, .output td:first-child { text-align: left; }
.compose { flex: none; display: flex; gap: 10px; padding: 12px var(--pad) calc(16px + env(safe-area-inset-bottom)); }
.compose input { flex: 1; min-width: 0; border: 1px solid var(--line); border-radius: 14px; padding: 0 20px; height: 60px; font-size: 18px; background: var(--surface); }
.compose input::placeholder { color: var(--muted); }
.compose input:focus { outline: none; border-color: var(--ink); }
.compose .btn { padding: 0 30px; }
.compose .btn:disabled { background: var(--raised); color: var(--muted); }

/* Dashboard */
.frame { flex: 1; width: 100%; border: 0; background: #fff; }
.dash-fallback { max-width: 560px; margin: 12vh auto 0; padding: var(--pad); display: flex; flex-direction: column; align-items: center; gap: 14px; text-align: center; }
.dash-fallback .btn { min-width: 280px; }
.empty { max-width: 640px; margin: 8vh auto 0; padding: var(--pad); display: flex; flex-direction: column; gap: 14px; }
.empty h1 { font-size: 34px; font-weight: 700; letter-spacing: -.012em; }
.empty p { color: var(--soft); }
.empty code { background: var(--raised); padding: 2px 7px; border-radius: 6px; font-size: 15px; }

@media (max-width: 1100px) {   /* the five-column simulator form cuts its select text below this width */
  .sim form { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); }
  .sim form:where(.no-method) { grid-template-columns: 140px minmax(0, 1fr); }   /* only an amount and what happens to it: the choice keeps the room its longest line needs */
  .sim form .seg, .sim form .btn, .sim form label:nth-of-type(3) { grid-column: 1 / -1; }
  .steps { grid-auto-flow: row; }
  .steps li.result { grid-column: auto; }
  .txr .who { flex: 1 1 0; }
  .txr .amt { flex: 0 0 auto; min-width: 132px; }   /* as wide as the longest amount of the day, so amounts share a right edge; a larger test amount widens its own row instead of running into the status */
  .txr .amt .lbl { display: none; }   /* the open row says which side each figure is from */
  .txr .res { flex: 1.35 1 0; }
  .pl { grid-template-columns: 108px minmax(0, 1fr) 112px 124px; }   /* an upright tablet has no room for five columns: the net goes, and a note takes the line under its reference */
  .pl .pn { display: none; }
  .pl .pr { display: contents; }
  .pl .pr span { grid-area: 1 / 2; }
  .pl small { grid-area: 2 / 2 / auto / -1; margin-left: 0; }
}

@media (max-width: 800px) {   /* small tablets upright: the status needs the room, and the amount already names the currency the method repeats */
  .sim form:where(.no-method) { grid-template-columns: minmax(0, 1fr); }   /* upright on a phone there is no room beside the amount, so the choice takes its own line */
  .txr .who { flex: 0 0 140px; }
  .txr .who .m { display: none; }
}

@media (max-width: 860px) {
  .ready, .detail, .hero { grid-template-columns: minmax(0, 1fr); }
  .pick-grid { grid-template-columns: 1fr; }
  .f { min-height: 46px; padding: 0 8px; }
  .f b, .slot .val { font-size: 15px; }   /* nothing under 15px on these screens, and this is the screen a prospect watches for a quarter of his minute */
  .f b { white-space: normal; }   /* at 15px a full timestamp no longer holds one line here, and a value cut through by an ellipsis is worse than one on two lines */
  .stage h3 { font-size: 17px; }
  .pay > .verdict { grid-template-columns: minmax(0, 1fr); }   /* no room beside the verdict: the switcher takes the line above it, where nothing over it changes height from day to day, so it stays under the finger */
  .pay > .verdict .days { grid-area: auto; order: -1; justify-self: start; margin: 0 0 16px; }
  .tie { grid-template-columns: minmax(0, 1fr); }
  .tie-sides { border-right: 0; border-bottom: 1px solid var(--line); }
  .split-legend { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 330px), 1fr)); }   /* fixed cells, so By count and By value are the same height */
  .ready-side { position: static; order: -1; }
  .detail .paper { order: 2; }
  .row { grid-template-columns: 6px minmax(0, 1fr) auto 20px; padding-top: 12px; padding-bottom: 12px; }
  .row i { grid-row: 1 / span 2; margin: -12px 0; }
  .row .what { grid-column: 2 / span 2; grid-row: 2; font-size: 15px; }
  .row .amt { grid-column: 3; grid-row: 1; }
  .row svg { grid-column: 4; grid-row: 1 / span 2; }
}

@media (max-width: 740px) {   /* the row stacks: player and amount, then time, type and EUR value, then the status across the full width */
  .txr { flex-wrap: wrap; gap: 4px 16px; contain-intrinsic-size: auto 96px; }
  .txr::after { top: 29px; }
  .txr .t { display: none; }
  .txr .tm { display: inline; margin-right: 4px; }
  .txr .who { flex: 1 1 0; }
  .txr .amt { min-width: 0; }
  .txr .res { flex: 1 0 100%; }
  .txd, .txr.po + .txd, .txr.lb + .txd { padding-left: 18px; }   /* a payout's detail and a balance line's both lose the tablet's indent here, or a quarter of a phone's width is empty and the money breaks across three lines */
  .txr.po .who small { white-space: nowrap; }   /* "20 Oct, 568 payments" stays one line beside the amount */
  .pl { grid-template-columns: minmax(0, 1fr) auto; }   /* reference and amount, then time and fee, then the note if there is one */
  .pl .pr span { grid-area: 1 / 1; }
  .pl .pa { grid-area: 1 / 2; }
  .pl .pt { grid-area: 2 / 1; }
  .pl .pf { grid-area: 2 / 2; }
  .pl small { grid-area: 3 / 1 / auto / -1; white-space: normal; }   /* "Your test payment, may be the one left out" is wider than a phone */
  .tr { position: relative; grid-auto-flow: row; grid-template-columns: none; grid-template-rows: none; max-width: none; }   /* the strip stands upright: one rail down the left, the stops under each other */
  .tr::before { content: ""; position: absolute; top: 7px; bottom: 0; left: 4px; width: 3px; border-radius: 2px; background: var(--line); }
  .tr-s:last-child::after { content: ""; position: absolute; top: 16px; bottom: 0; left: 0; width: 11px; background: var(--ground); }   /* the rail ends at the last stop, whatever that stop has under it */
  .tr-s { display: block; grid-row: auto; padding: 0 0 4px 28px; }
  .tr-s > i { display: none; }
  .tr-s b::before { content: ""; position: absolute; left: 0; width: 11px; height: 11px; margin-top: 5px; border-radius: 50%; background: var(--dot); box-shadow: 0 0 0 4px var(--ground); }   /* the dot takes its height from the stop's own name, so it never drifts onto the wait above it */
  .tr-s + .tr-s::before, .tr-s.brk::before, .tr-s.none::before { display: none; }
  .tr-g { position: static; display: block; width: auto; text-align: left; padding: 10px 0 2px; }
  .tr-w, .tr-m { display: inline; }
  .tr-m { margin-left: 12px; }
}

@media (max-width: 600px) {
  .pay-title { flex-direction: column; align-items: flex-start; gap: 14px; }
  .pay-title .btn.off { visibility: visible; opacity: .4; }   /* here the button has a row of its own above the switcher: hidden it would leave a hole, so it stays and is greyed out */
  .v-line { gap: 11px; }
  .v-sub { margin-left: 24px; }
  .v-sign { margin-left: 24px; }
  .v-sign .btn.quiet { margin-left: 0; }
  .bar-title { visibility: hidden; }   /* no room beside the back button and the logo; the page heading says where you are */
  .tie-sides, .tie-why { padding-left: 18px; padding-right: 18px; }
  .tie-line .tl small { display: block; margin-left: 0; }
  .wf .wide { display: none; }
  .glist h2 { flex-wrap: wrap; gap: 2px 10px; }
  .glist h2 small { flex-basis: 100%; margin-left: 23px; }
  .ageing, .ageing .ab { flex-direction: column; }   /* a phone has no room for two buckets side by side: each takes a line of its own under the label */
  .gline .gt, .gline .gv { display: contents; }   /* the note runs the full width instead of being locked into the left column */
  .gline .gt span { grid-column: 1; grid-row: 1; }
  .gline .gv b { grid-column: 2; grid-row: 1; text-align: right; }
  .gline .gv small { grid-column: 1 / -1; grid-row: 2; text-align: right; }
  .gline .gt small { grid-column: 1 / -1; grid-row: 3; }
  .txd { grid-template-columns: 1fr; }
  .stage { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 12px; }   /* minmax(0, ...) or a long hash pushes the cards off the screen */
  .rec { padding: 16px 10px 8px; }
  .rule { grid-column: 1 / -1; grid-row: 2; padding-top: 4px; }
  .f.spare { display: none; }
  .slot { min-height: 66px; }
}

/* Motion, from the Claude Design patch (patch/animations.css).
   Transforms and opacity only, so the tablet never re-lays-out mid-animation. */
@keyframes rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes from-left { from { opacity: 0; transform: translateX(-28px); } to { opacity: 1; transform: none; } }
@keyframes from-right { from { opacity: 0; transform: translateX(28px); } to { opacity: 1; transform: none; } }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes ring { from { opacity: .7; transform: scale(1); } to { opacity: 0; transform: scale(1.045, 1.22); } }
@keyframes flash { from { opacity: 1; } to { opacity: 0; } }
@keyframes bump { 50% { transform: scale(1.06); } }

/* Start: headline, then the three tiles one after another */
.start > * { animation: rise .55s cubic-bezier(.2, .7, .2, 1) both; }
.start-list { animation: none; }
.start-item { animation: rise .55s cubic-bezier(.2, .7, .2, 1) both; transition: transform .15s ease; }
.start-item:nth-child(1) { animation-delay: .08s; }
.start-item:nth-child(2) { animation-delay: .16s; }
.start-item:nth-child(3) { animation-delay: .24s; }
.start-note { animation-delay: .36s; }
.start-item:active { transform: scale(.985); }

/* Picker: rows settle in; the right column unlocks smoothly; the button wakes up */
.picker > * { animation: rise .5s cubic-bezier(.2, .7, .2, 1) both; }
.pick-grid { animation-delay: .08s; }
.pick-go { animation-delay: .18s; }
.pick { transition: opacity .3s ease, background-color .2s ease, border-color .2s ease, box-shadow .2s ease, transform .12s ease; }
.pick:active:not(:disabled) { transform: scale(.985); }
.pick-go .btn { transition: background-color .3s ease, color .3s ease, transform .3s cubic-bezier(.2, .7, .2, 1); }
.pick-go .btn:disabled { transform: scale(.97); }
.picker.leaving { animation: fade .22s ease both reverse; }

/* Stage: the two records slide in from their sides, the rule column rises between them */
.rec.left { animation: from-left .6s cubic-bezier(.2, .7, .2, 1) both; }
.rec.right { animation: from-right .6s cubic-bezier(.2, .7, .2, 1) .08s both; }
.rule { animation: rise .6s cubic-bezier(.2, .7, .2, 1) .16s both; }
.slot-in { transform: translateY(4px); transition: opacity .3s ease, transform .3s ease; }
.slot.full .slot-in { transform: none; }
.slot { position: relative; }
.slot.full::after { content: ""; position: absolute; inset: -1px; border: 2px solid var(--green); border-radius: 10px; pointer-events: none; opacity: 0; animation: ring .7s ease-out; }

/* Results: the blocks rise one after another, the three totals count up (JS), rows stream in once, filters crossfade, detail unfolds */
.pay > * { animation: rise .5s cubic-bezier(.2, .7, .2, 1) both; }
.pay > .verdict { animation-delay: .05s; }
.pay > .tie { animation-delay: .1s; }
.pay > .split { animation-delay: .15s; }
.pay > .lists { animation-delay: .2s; }
.pay > .pay-list { animation-delay: .25s; }
.pay > .sim { animation-delay: 0s; }
#v-count.bump { animation: bump .4s ease; }
.tx.fresh .txr { animation: rise .4s ease both; animation-delay: calc(var(--i, 0) * 28ms); }
.tx.swap { animation: fade .18s ease both; }
.txd { animation: rise .2s ease both; }

/* Simulator: each step appears as it is reached; the new row flashes into the list */
.steps li { animation: rise .35s cubic-bezier(.2, .7, .2, 1) both; }
.txr { position: relative; }
.txr.sim-new::before { content: ""; position: absolute; inset: 0; background: rgba(61, 48, 237, .35); pointer-events: none; animation: flash 1.2s ease-out both; }
