/* Chhupa Tax — every style in the app, in one file, in one system.

   Ink for tax, grey for what you kept, ONE accent (a deep teal) and only ever on
   something you can act on: a primary button, the selected segment or chip, a
   link, a focus ring, a rate badge (ADR 0013). Never on an amount, never as a
   large ground, never as category identity.

   Structure is carried by tone, not by outlines: the page is grey, the things
   that sit on it are white (card), the wells inside them are grey again (panel),
   and pressing a thing moves it one step down that ladder. Dark mode is the same
   ladder built upward from near-black — it is a designed theme, not an inversion.

   Everything measurable is a token: a 4pt spacing scale, five radii, ten type
   steps, two rule weights (1px hairline, 2px emphasis). Public Sans for words,
   IBM Plex Mono — tabular — for every figure. */

/* ---------- 1. tokens ----------------------------------------------------
   Literal hex on every colour: `npm run check` reads these values straight out
   of this file to prove AA in both themes, and it cannot resolve a var(). */
:root{--desk:#F2F4F7;--paper:#F2F4F7;--card:#FFFFFF;--panel:#E4E8EE;--pressed:#D8DEE6;--fill:#FFFFFF;--thumb:#FFFFFF;--rule:#E3E7ED;--ink:#14181E;--ink2:#485160;--ink3:#5A6575;--acc:#0B6A6F;--accInk:#FFFFFF;--accFill:#0B6A6F;--accFillInk:#FFFFFF;--accSoft:#E1EFEF;--danger:#A8331F;--ct-fuel:#D9EAFC;--ch-fuel:#0070C2;--ct-food:#FBE0E2;--ch-food:#AE284A;--ct-subs:#D2EDF4;--ch-subs:#00869D;--ct-dine:#F6E4D3;--ch-dine:#8B5200;--ct-alc:#F7E0EC;--ch-alc:#C9549D;--ct-other:#EBE4F9;--ch-other:#9867D9;--ct-big:#E4E6FC;--ch-big:#554DBD;--ct-invest:#DBEEDD;--ch-invest:#049438;--ct-ptax:#EAE9D3;--ch-ptax:#777000;--ct-tds:#D4EFE7;--ch-tds:#00836E;--ct-inc:#F8E0EB;--ch-inc:#D2008A;--ct-gains:#D6EFE3;--ch-gains:#007D5A;--ct-direct:#F9E3D6;--ch-direct:#CE6000;--inv:#20262E;--invInk:#F2F4F7;--toastAcc:#7EDCD0;--scrim:rgba(15,20,27,.4);--sh-thumb:0 1px 3px rgba(20,24,30,.14),0 1px 1px rgba(20,24,30,.04);--sh-sheet:0 -8px 24px rgba(20,24,30,.16);--sh-toast:0 8px 24px rgba(20,24,30,.24);--sh-nav:0 -1px 0 var(--rule),0 -8px 24px rgba(20,24,30,.06);--s1:4px;--s2:8px;--s3:12px;--s4:16px;--s5:20px;--s6:24px;--s8:32px;--s10:40px;--s12:48px;--r1:4px;--r2:8px;--r3:12px;--r4:16px;--r5:24px;--rf:999px;--div:linear-gradient(var(--rule),var(--rule));--ease:cubic-bezier(.2,0,0,1);--sans:"Public Sans","Segoe UI",Roboto,Helvetica,Arial,sans-serif;--mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;color-scheme:light}
/* Dark is the same ladder built upward from near-black: page, card, panel,
   pressed. One accent, brighter here so it clears AA on the dark page (9.95). */
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){--desk:#0F1319;--paper:#0F1319;--card:#171C24;--panel:#222934;--pressed:#2C3441;--fill:#222934;--thumb:#333C4A;--rule:#2A3240;--ink:#E9EDF2;--ink2:#B1BBC8;--ink3:#909CAC;--acc:#4FD1C1;--accInk:#062522;--accFill:#4FD1C1;--accFillInk:#062522;--accSoft:#15302F;--danger:#F0765F;--ct-fuel:#1A2A3B;--ch-fuel:#B5D9FF;--ct-food:#392124;--ch-food:#FF9BA8;--ct-subs:#0F2D34;--ch-subs:#00AFCB;--ct-dine:#362514;--ch-dine:#FFCB9A;--ct-alc:#36212D;--ch-alc:#CE6AA7;--ct-other:#2C2438;--ch-other:#C8A4FF;--ct-big:#25263B;--ch-big:#7E7FE1;--ct-invest:#1C2E1E;--ch-invest:#58B768;--ct-ptax:#2B2A13;--ch-ptax:#D5CE51;--ct-tds:#112F28;--ch-tds:#009C84;--ct-inc:#37212B;--ch-inc:#FFD8E9;--ct-gains:#152F24;--ch-gains:#8DFFD1;--ct-direct:#382317;--ch-direct:#D06E2E;--inv:#E9EDF2;--invInk:#14181E;--toastAcc:#0B6A6F;--scrim:rgba(0,0,0,.6);--sh-thumb:0 1px 2px rgba(0,0,0,.4);--sh-sheet:0 -8px 32px rgba(0,0,0,.5);--sh-toast:0 8px 24px rgba(0,0,0,.4);--sh-nav:0 -1px 0 var(--rule);color-scheme:dark}}
:root[data-theme="dark"]{--desk:#0F1319;--paper:#0F1319;--card:#171C24;--panel:#222934;--pressed:#2C3441;--fill:#222934;--thumb:#333C4A;--rule:#2A3240;--ink:#E9EDF2;--ink2:#B1BBC8;--ink3:#909CAC;--acc:#4FD1C1;--accInk:#062522;--accFill:#4FD1C1;--accFillInk:#062522;--accSoft:#15302F;--danger:#F0765F;--ct-fuel:#1A2A3B;--ch-fuel:#B5D9FF;--ct-food:#392124;--ch-food:#FF9BA8;--ct-subs:#0F2D34;--ch-subs:#00AFCB;--ct-dine:#362514;--ch-dine:#FFCB9A;--ct-alc:#36212D;--ch-alc:#CE6AA7;--ct-other:#2C2438;--ch-other:#C8A4FF;--ct-big:#25263B;--ch-big:#7E7FE1;--ct-invest:#1C2E1E;--ch-invest:#58B768;--ct-ptax:#2B2A13;--ch-ptax:#D5CE51;--ct-tds:#112F28;--ch-tds:#009C84;--ct-inc:#37212B;--ch-inc:#FFD8E9;--ct-gains:#152F24;--ch-gains:#8DFFD1;--ct-direct:#382317;--ch-direct:#D06E2E;--inv:#E9EDF2;--invInk:#14181E;--toastAcc:#0B6A6F;--scrim:rgba(0,0,0,.6);--sh-thumb:0 1px 2px rgba(0,0,0,.4);--sh-sheet:0 -8px 32px rgba(0,0,0,.5);--sh-toast:0 8px 24px rgba(0,0,0,.4);--sh-nav:0 -1px 0 var(--rule);color-scheme:dark}

/* ---------- 2. base and type --------------------------------------------- */
*{box-sizing:border-box;margin:0;padding:0}
html{background:var(--desk)}
/* The screen transitions translate 14px sideways. Without a clipping box the
   page can be dragged horizontally for the length of the animation — measured,
   window.scrollX reached 10. It cannot be fixed on <html> or <body>: overflow on
   body propagates to the viewport, and the viewport still scrolls. So the
   screens get their own box. `clip`, not `hidden`, so no scroll container is
   created and vertical scrolling is untouched. */
#screens{overflow-x:clip}
body{background:var(--desk);color:var(--ink);font-family:var(--sans);font-size:15px;line-height:23px;
 font-synthesis:none;-webkit-font-smoothing:antialiased;min-height:100dvh;max-width:520px;margin:0 auto;
 padding-bottom:104px}
/* Every figure is monospace and tabular, so columns line up and a number that
   changes does not reflow the line it sits in. */
/* .rt is out of this family: it carries prose as often as a figure — 'you
   choose', 'list', '750 ml' — and monospace made those read as code. */
.mono,.big,.amt,.ln span:last-child{font-family:var(--mono);font-variant-numeric:tabular-nums}
/* A comma in a monospace face takes a full digit's advance, which puts a hole in
   every grouped figure. The separator is pulled tight; the digits either side of
   it keep their column. */
.sep{font-style:normal;margin:0 -.13em}
.dash{color:var(--ink3)}

button{font:inherit;color:inherit;background:none;border:0;cursor:pointer;-webkit-tap-highlight-color:transparent}
input,select{font:inherit;color:inherit}
/* One focus indicator for the whole app. Inputs own their own (a 2px border),
   so the outline would only double it. */
button:focus-visible,a:focus-visible,summary:focus-visible{outline:2px solid var(--acc);outline-offset:2px}
input:focus-visible,select:focus-visible{outline:0}
.pill:has(select:focus-visible){outline:2px solid var(--acc);outline-offset:2px}

h2{font-size:21px;line-height:25px;font-weight:700;letter-spacing:-.02em}
h3{font-size:16px;line-height:21px;font-weight:600;letter-spacing:-.005em}
p{color:var(--ink2);font-size:15px;line-height:23px}
.small{font-size:13px;line-height:19px}
/* A word marked inside a paragraph takes the page's own emphasis, not the
   browser's 700 — which is heavier than any heading at this size, in the
   middle of a sentence (spec 058). */
.small b,.hint b,.muted b,p b{font-weight:600}
.muted,.hint{font-size:13px;line-height:18px;color:var(--ink3)}
.big{font-size:38px;line-height:42px;font-weight:600;letter-spacing:-.03em}
/* The answer, not the input, is the largest figure on an add screen. The
   scale had preserved an inversion rather than correcting it (spec 060). */
.big.mid{font-size:28px;line-height:35px;letter-spacing:-.02em}
/* The overline: one size, one tracking, one colour, everywhere it appears. */
.sec,.taxpanel .lbl,.sacard .lbl,.cell .m,.tl small,.list>.muted,#sr-recent>.muted,
#settings .stack>div>.muted:first-child,#sh-tag{
/* 13px, not the 12px floor: RECENT, HIDDEN IN PRICES and TAX INSIDE THIS
   FILL-UP are the structure of their screens, and nothing structural should
   sit where there is no headroom left (spec 060). */
 font-size:13px;line-height:17px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--ink3)}
.sec{margin:0}

/* ---------- 3. icons -----------------------------------------------------
   One set (spec 046), drawn once in app.js and dropped in here. Every slot is
   the same box: 20px, currentColor, stroke 1.75, nothing painted. */
[data-g],.chev,.list .ic,.lastrow .ic,.mag,.tab .tg{display:inline-flex;align-items:center;justify-content:center;flex:none}
[data-g] svg,.chev svg,.list .ic svg,.lastrow .ic svg,.mag svg,.tab .tg svg,.ib svg,.back>svg{
 width:20px;height:20px;display:block;flex:none;fill:none;stroke:currentColor}
.chev{color:var(--ink3)}

/* ---------- 4. layout ---------------------------------------------------- */
.screen{display:none;padding:12px 20px 32px;background:var(--paper)}
.screen.on{display:block}
.stack>*+*{margin-top:var(--s4)}
.stack.add>*+*{margin-top:var(--s5)}
.stack.add>h2+*{margin-top:var(--s4)}
.row{display:flex;align-items:center;gap:var(--s2)}
.between{justify-content:space-between}
.grow{flex:1;min-width:0}
.row.wrap{flex-wrap:wrap}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:var(--s3)}
/* Two fields side by side: their inputs sit on one line even when one label
   wraps to two. */
.grid2 .field{display:flex;flex-direction:column;justify-content:flex-end}
/* A screen title and the line that explains it are one block. */
h2+p.muted,h2+p.small{margin:var(--s1) 0 var(--s4)}

/* ---------- 5. header ----------------------------------------------------
   One component: a leading Back (chevron + word), a trailing action. */
.hd{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);min-height:56px;margin-bottom:var(--s2)}
.back{display:inline-flex;align-items:center;gap:2px;min-height:44px;padding:0 12px 0 4px;margin-left:-8px;
 font-size:15px;line-height:23px;font-weight:500;color:var(--ink);border-radius:var(--r2)}
.back [data-g]{color:var(--ink2)}
.back:active{background:var(--panel)}
.wordmark{font-size:18px;line-height:23px;font-weight:700;letter-spacing:-.02em}
/* An icon button is a thumb-sized target with no ground until it is pressed. */
.ib{position:relative;width:44px;height:44px;display:inline-flex;align-items:center;justify-content:center;
 border-radius:50%;background:none;color:var(--ink);flex:none}
.ib svg{width:22px;height:22px}
.ib:active{background:var(--panel)}
/* The trailing seg sizes to its words rather than to a hard-coded width. */
.hd .seg{flex:none;width:auto}
.hd .seg button{flex:0 0 auto;padding:0 var(--s4)}
.hd .tag,.hd .muted{flex:none}
/* The state selector: a 44px pill with the shared chevron over a full-size
   native select. */
.pill{position:relative;display:inline-flex;align-items:center;gap:var(--s1);min-height:44px;padding:0 10px 0 14px;
 border-radius:var(--rf);background:var(--panel);font-size:13px;line-height:19px;font-weight:500;color:var(--ink)}
.pill .chev{color:var(--ink2);transform:rotate(90deg)}
.pill select{position:absolute;inset:0;width:100%;height:100%;opacity:0;cursor:pointer}
.pill:active{background:var(--pressed)}

/* ---------- 6. home ------------------------------------------------------ */
.home .hero{padding:var(--s6) 0 var(--s2)}
.home .hero .lbl{font-size:13px;line-height:19px;color:var(--ink2)}
.home .hero .big{margin:var(--s1) 0 var(--s3)}
/* The split is two plain lines of meta, not a blockquote. */
/* Held one rung above the reduction. At 13 it landed on the same size as a
   Recent row's caption, so Home's second level and its fourth were
   typographically identical — 38 / 20 / 14 / 13 reads as four rungs where
   38 / 20 / 13 / 13 reads as three (spec 060). */
.split{margin:0 0 var(--s4);font-size:14px;line-height:21px;color:var(--ink2)}
.split span{display:block}
.split b{font-family:var(--mono);font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums}
/* One object, two figures, each labelled above its own number — a month and a
   financial year are not a comparison, so they are not put in one row. */
.projcard{display:grid;grid-template-columns:1fr 1fr;background:var(--card);border-radius:var(--r4);overflow:hidden}
.projcard .proj{display:block;padding:var(--s4)}
.projcard .proj+.proj{box-shadow:inset 1px 0 0 var(--rule)}
.projcard .proj .lbl{display:block;font-size:13px;line-height:18px;color:var(--ink3);margin-bottom:var(--s1)}
.projcard .proj .v{display:block;font-family:var(--mono);font-weight:600;font-size:19px;line-height:24px;
 letter-spacing:-.01em;font-variant-numeric:tabular-nums}
#home .row.between{margin:var(--s8) 0 var(--s2);min-height:44px}
#home .hd .ib{margin-right:-11px}
/* Nothing logged is not ₹0 — it is three ways in. */
#h-empty{margin-top:var(--s2)}
#h-empty>p{font-size:13px;line-height:19px;color:var(--ink2);margin-bottom:var(--s3)}
#h-empty b{color:var(--ink);font-weight:600}

/* ---------- 7. section heads -------------------------------------------- */
.sechd{display:flex;justify-content:space-between;align-items:center;gap:var(--s3);min-height:20px;margin:0 0 var(--s2)}
*+.sechd{margin-top:var(--s8)}
.sechd .v{font-family:var(--mono);font-weight:500;font-size:13px;line-height:18px;color:var(--ink2);
 font-variant-numeric:tabular-nums}
.sechd .v small,.tl .v .d{font-family:var(--sans);font-size:13px;font-weight:400;color:var(--ink3)}
.chipgrp+.chipgrp{margin-top:var(--s6)}
.chipgrp .sec{margin-bottom:var(--s2)}

/* ---------- 8. the list card --------------------------------------------
   A group of rows is one raised card with inset dividers. No row carries a
   remove: removing is done in the sheet the row opens, and undone from the
   toast. */
.list{background:var(--card);border-radius:var(--r4);overflow:hidden}
.list:empty{display:none}
.list .it{display:flex;align-items:center;gap:var(--s3);min-height:64px;padding:var(--s3) var(--s4);cursor:pointer;
 background-color:var(--card);background-image:var(--div);background-repeat:no-repeat;background-position:right bottom;
 background-size:calc(100% - 68px) 1px}
.list .it:last-child,.list .it:has(+.muted){background-image:none}
.list .it:active{background-color:var(--panel)}
.list .it>div:not([class]){flex:1;min-width:0}
.list .ic{width:40px;height:40px;border-radius:var(--r3);background:var(--panel);color:var(--ink2)}
.list .t1{font-size:16px;line-height:21px;font-weight:500;letter-spacing:-.005em;color:var(--ink);
 white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.list .t2{font-size:13px;line-height:18px;color:var(--ink3);margin-top:1px;
 white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.list .amt{margin-left:auto;flex:none;text-align:right;font-size:15px;line-height:21px;font-weight:600;
 white-space:nowrap;color:var(--ink)}
.list .amt small{display:block;font-family:var(--sans);font-size:12px;line-height:16px;font-weight:400;
 color:var(--ink3);margin-top:1px}
/* Rows with no tile — search results, the bottle list — take the divider from
   the text edge instead. */
#sr-list .it,#al-groups .it{background-size:calc(100% - var(--s4)) 1px}
/* A label inside the card is an overline, not a heading floating above it. */
.list>.muted{padding:var(--s5) var(--s4) 6px}
.list>.muted:first-child{padding-top:var(--s4)}
.list>p.muted{padding:var(--s3) var(--s4) var(--s4);font-size:13px;line-height:19px;font-weight:400;
 letter-spacing:0;text-transform:none}
/* The rate a row carries is a badge, one colour, never a meaning scale in grey. */
.rt{font-family:var(--sans);font-variant-numeric:tabular-nums;margin-left:auto;flex:none;padding:var(--s1) var(--s2);border-radius:var(--r1);background:var(--panel);
 color:var(--ink2);font-size:13px;line-height:17px;font-weight:500;white-space:nowrap}
/* A badge's weight is its magnitude: nothing hidden, through to the top slab.
   Ink, never a second hue — the danger colour said 'wrong', not 'more'. */
.rt.r0{color:var(--ink3)}
.rt.r5{color:var(--ink2)}
.rt.r18{color:var(--ink)}
.rt.r40{color:var(--ink);background:var(--pressed);font-weight:600}
#al-groups .sec{margin:var(--s6) 0 var(--s2)}
#al-groups .sec:first-child{margin-top:0}

/* ---------- 9. proportion rows and action rows --------------------------
   A proportion row: label and figure on one line, a 4px track beneath scaled to
   the largest row in its list. Sorted largest first by whoever renders it. The
   group is a card, like every other group of rows. */
.prow{min-height:52px;padding:var(--s3) var(--s4);background-color:var(--card);background-image:var(--div);
 background-repeat:no-repeat;background-position:right bottom;background-size:calc(100% - var(--s4)) 1px}
.prow:first-child,:not(.prow)+.prow{border-top-left-radius:var(--r4);border-top-right-radius:var(--r4)}
.prow:last-child,.prow:has(+:not(.prow)),.prow:not(:has(+*)){border-bottom-left-radius:var(--r4);border-bottom-right-radius:var(--r4)}
.prow:last-child,.prow:has(+:not(.prow)),.prow:has(+.prow.tot){background-image:none}
.prow .ln{display:flex;justify-content:space-between;align-items:baseline;gap:var(--s3)}
.prow .k{font-size:16px;line-height:21px;font-weight:500}
.prow .v{font-family:var(--mono);font-weight:600;font-size:15px;line-height:21px;text-align:right;white-space:nowrap;
 font-variant-numeric:tabular-nums}
/* "so far ₹31,187" is a caption, so it is set as one, under its figure. */
.prow .v .tag{display:block;margin:2px 0 0;padding:0;background:none;font-family:var(--sans);font-size:12px;
 line-height:16px;font-weight:500;letter-spacing:0;text-transform:none;color:var(--ink3)}
.prow .track{height:4px;background:var(--panel);border-radius:var(--r1);margin-top:var(--s2);overflow:hidden}
.prow .track i{display:block;height:100%;background:var(--ink);border-radius:var(--r1)}
/* An expected month is lighter, not labelled: the figure grey, the fill grey. */
.prow.exp .v,.prow.exp .k{color:var(--ink3)}
.prow.exp .track i{background:var(--ink3)}
/* The month you are in is filled, not underlined; the total carries the one 2px
   rule in the app. */
.prow.cur{background-color:var(--panel)}
.prow.cur .k,.prow.tot .k{font-weight:600}
.prow.tot{background-image:linear-gradient(var(--ink),var(--ink));background-position:left top;background-size:100% 2px}
.prow[data-go],.prow[data-edit]{cursor:pointer}
.prow[data-go]:active,.prow[data-edit]:active{background-color:var(--panel)}
.prow.cur[data-go]:active{background-color:var(--pressed)}
/* An action row: a choice as a row with a chevron, never a grid of buttons. */
.acts{background:var(--card);border-radius:var(--r4);overflow:hidden}
.arow{display:flex;align-items:center;gap:var(--s3);width:100%;min-height:56px;padding:var(--s2) var(--s4);
 border-radius:var(--r4);text-align:left;font-size:16px;line-height:21px;font-weight:500;color:var(--ink);
 text-decoration:none;background-color:var(--card);background-image:var(--div);background-repeat:no-repeat;
 background-position:right bottom;background-size:calc(100% - var(--s4)) 1px}
.arow:last-child{background-image:none}
.arow .sub{display:block;font-size:13px;line-height:18px;font-weight:400;color:var(--ink3)}
.arow>[data-g]:first-child{color:var(--ink3)}
.arow .chev{margin-left:auto}
.arow:active{background-color:var(--panel)}
.prow+.arow{margin-top:var(--s2)}
/* A proportion row that folds open in place (spec 051). Same row, same track,
   same figure; the caption says what is inside and the caret says it opens. The
   entries appear in a well beneath it — one step down the surface ladder, so
   "inside this row" is read rather than guessed — and opening one pushes no
   screen, which is why Back from This year is always Home.

   The corner and divider rules above key off a .prow's siblings, and a summary
   is an only child of its <details>; these three selectors put the card's
   corners back on the group and the hairlines back between the rows. */
.folds{background:var(--card);border-radius:var(--r4);overflow:hidden}
.folds+.folds,.folds+.arow{margin-top:var(--s6)}
.folds>details:not(:last-child),.folds>details[open]>summary.prow{
 background-image:var(--div);background-repeat:no-repeat;background-position:right bottom;
 background-size:calc(100% - var(--s4)) 1px}
.folds summary.prow{display:block;border-radius:0;background-image:none;list-style:none;cursor:pointer}
.folds summary.prow::-webkit-details-marker{display:none}
.prow .k{display:flex;align-items:baseline;gap:var(--s2);min-width:0}
/* The label names the row, so it is the last thing that gives way: at 360 an
   income figure plus a caption plus a caret had been ellipsing 'On salary,
   TDS' down to 'On salary, T…', losing the word that distinguishes it. */
.prow .lb{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1 1 auto}
.prow .n{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis}
/* The caption is words, not a figure: the mono face .ln's last child would give
   it says "amount" in a place where nothing is an amount. */
.prow .k .n{flex:none;font-family:var(--sans);font-size:12px;line-height:16px;font-weight:400;letter-spacing:0;
 color:var(--ink3);white-space:nowrap;font-variant-numeric:normal}
.prow .k .n::after{content:"";display:inline-block;width:6px;height:6px;margin:0 0 3px 7px;
 border:solid var(--ink3);border-width:0 1.5px 1.5px 0;transform:rotate(45deg)}
details[open]>summary .k .n::after{transform:rotate(225deg);margin-bottom:-1px}
/* The open fold's body: the same list rows every screen uses, in the well. */
.dis>.list{border-radius:0;background:var(--panel);padding:var(--s1) 0}
.dis>.list .it{background-color:transparent}
.dis>.list .it:active{background-color:var(--pressed)}
/* Inside a fold the body is --panel, so the tile inverts to --card to keep its
   step. The category rule is more specific, so it has to say so too. */
.dis>.list .ic,.dis>.list .it[data-cat] .ic{background:var(--card)}
.dis>.list .it[data-cat] .ic{color:var(--ch,var(--ink2))}
.dis>.list .it:last-child{background-image:none}
.dis>.list>p.muted{padding:var(--s3) var(--s4)}
/* Inside a fold a caption may take a second line: "₹1,80,000 TDS · ₹1,200
   professional tax" is two figures a person is here to read, and an ellipsis
   would eat the second one (spec 037). */
.dis>.list .t2{white-space:normal;overflow:visible}
/* A search result's caption is the rate rule — "5% up to ₹2,500 a pair, 18%
   above" — so truncating it destroys the thing the row exists to say. It
   wraps instead (spec 057). Every other list keeps its one-line caption. */
#sr-list .t2{white-space:normal;overflow:visible}
/* A month not yet paid is lighter, not labelled — the caption already says it. */
.dis>.list .it.exp,.dis>.list .it.exp .amt{color:var(--ink3)}
/* The x that asks the two questions a repeating charge raises in a month. A
   20px mark with a 44px hit box: drawn any larger it pushes that row's figure
   out of the column the rest of the fold reads down. */
.list .it>.x{position:relative;flex:none;width:20px;height:20px;margin-right:-4px;display:inline-flex;
 align-items:center;justify-content:center;border-radius:50%;background:none;color:var(--ink3);
 font-size:18px;line-height:1}
.list .it>.x::after{content:"";position:absolute;inset:-12px}
.list .it>.x:active{background:var(--pressed)}
.list .it>.grid2.twotap{width:100%;gap:var(--s2)}
.list .it>.grid2.twotap .btn{min-height:44px;padding:0 var(--s3);font-size:14px}
/* Nothing logged is one sentence and a drawing, not twelve rows of zero. */
.nothing{display:flex;flex-direction:column;align-items:center;gap:var(--s3);
 padding:var(--s10) var(--s4);text-align:center}
.nothing p{max-width:34ch}
.nothing .art{width:76px;height:76px}

/* A timeline: every version of a monthly line, newest first, the month it began. */
.tl{position:relative;margin:var(--s2) 0 0 var(--s2);padding-left:var(--s5);border-left:1px solid var(--rule)}
.tl>div{position:relative;padding:2px 0 var(--s4)}
.tl>div::before{content:"";position:absolute;left:-25px;top:8px;width:9px;height:9px;border-radius:50%;
 background:var(--ink);box-shadow:0 0 0 3px var(--paper)}
.tl>div.past::before{background:var(--rule)}
.tl small{display:block;margin-bottom:2px}
.tl .v{font-family:var(--mono);font-weight:600;font-size:15px;line-height:21px;font-variant-numeric:tabular-nums}
.tl .d{font-size:13px;line-height:19px;color:var(--ink2)}

/* ---------- 9b. a colour per category (ADR 0017, spec 055) ---------------
   Colour says which thing it is. Length says how much. So a hue lands in
   exactly two places — the 40px icon tile, as a tinted ground with the glyph
   drawn in the hue, and a 10px dot before a category's own label in This year
   — and nowhere else. Bars stay ink and figures stay ink, which is the half of
   ADR 0013 that survives. No hue ever appears without the word it stands for
   beside it: that is what makes the measured colour-blindness collisions cost
   recognition speed rather than meaning. `npm run check` measures every glyph
   on its own tile and every dot on every ground it can sit on, in both themes,
   and keeps all thirteen clear of the accent and of the danger colour. */
.list .it[data-cat] .ic{background:var(--ct,var(--panel));color:var(--ch,var(--ink2))}
/* The dot is identity at a glance, so it is sized to be seen and not to
   crowd the label — 10px plus 7px of gap took 17px out of a column that was
   already ellipsing "On salary, TDS" at 360 (spec 051). */
details[data-cat]>.prow .lb::before{content:"";display:inline-block;width:8px;height:8px;margin-right:6px;border-radius:50%;background:var(--ch,var(--ink3));vertical-align:1px;flex:none}
[data-cat="fuel"]{--ct:var(--ct-fuel);--ch:var(--ch-fuel)}
[data-cat="food"]{--ct:var(--ct-food);--ch:var(--ch-food)}
[data-cat="subs"]{--ct:var(--ct-subs);--ch:var(--ch-subs)}
[data-cat="dine"]{--ct:var(--ct-dine);--ch:var(--ch-dine)}
[data-cat="alc"]{--ct:var(--ct-alc);--ch:var(--ch-alc)}
[data-cat="other"]{--ct:var(--ct-other);--ch:var(--ch-other)}
[data-cat="big"]{--ct:var(--ct-big);--ch:var(--ch-big)}
[data-cat="invest"]{--ct:var(--ct-invest);--ch:var(--ch-invest)}
[data-cat="ptax"]{--ct:var(--ct-ptax);--ch:var(--ch-ptax)}
[data-cat="tds"]{--ct:var(--ct-tds);--ch:var(--ch-tds)}
[data-cat="inc"]{--ct:var(--ct-inc);--ch:var(--ch-inc)}
[data-cat="gains"]{--ct:var(--ct-gains);--ch:var(--ch-gains)}
[data-cat="direct"]{--ct:var(--ct-direct);--ch:var(--ch-direct)}

/* ---------- 10. buttons: filled, tonal, text ---------------------------- */
.btn{display:flex;align-items:center;justify-content:center;width:100%;min-height:52px;padding:0 var(--s5);
 border-radius:var(--r3);font-size:15px;line-height:23px;font-weight:600;text-align:center;
 background:var(--accFill);color:var(--accFillInk);text-decoration:none}
/* Pressing dims the fill rather than moving the button: a control that shifts
   under the thumb reads as a slip, not as a press. */
.btn:active{box-shadow:inset 0 0 0 999px rgba(0,0,0,.08)}
/* A tonal button has to stay visible on whatever ground it sits on. Inside an
   open fold the body is --panel too, so the reversible half of the two-tap
   choice disappeared next to its solid partner. The edge is what carries it. */
.btn.ghost,.btn.line{background:var(--panel);color:var(--ink);box-shadow:inset 0 0 0 1px var(--rule)}
.dis>.list .btn.ghost{background:var(--card)}
.btn.ghost:active,.btn.line:active{box-shadow:none;background:var(--pressed)}
/* Disabled is a grey waiting state, not the accent at low opacity (spec 049). */
.btn[disabled]{background:var(--panel);color:var(--ink3);opacity:1}
/* A quiet, centred text action at a full-size target — for the thing done rarely. */
.quiet{display:block;width:100%;min-height:44px;padding:0 var(--s3);border-radius:var(--r3);text-align:center;
 font-size:15px;line-height:23px;font-weight:500;color:var(--acc)}
.quiet.danger{color:var(--danger)}
.quiet:active{background:var(--panel)}
/* Padding for the thumb, negative margin so the line box is unchanged. */
.link{display:inline-flex;align-items:center;min-height:44px;padding:0 var(--s2);margin:0 -8px;
 border-radius:var(--r2);font-size:13px;line-height:19px;font-weight:500;color:var(--acc);text-decoration:none}
.link:active{background:var(--panel)}
/* A 40px icon button: the sheet's close, the salary editor's close. */
.iconbtn{position:relative;width:40px;height:40px;display:inline-flex;align-items:center;justify-content:center;
 border-radius:50%;background:var(--panel);color:var(--ink);flex:none}
.iconbtn::after{content:"";position:absolute;inset:-2px}
.iconbtn:active{background:var(--pressed)}

/* ---------- 11. chips, tags, toggles, segments -------------------------- */
/* Search's routes and its recent picks are one chip. */
.chiplink,.recent button{position:relative;display:inline-flex;align-items:center;gap:var(--s2);min-height:36px;
 padding:0 14px;border-radius:var(--rf);background:var(--fill);color:var(--ink);
 font-size:13px;line-height:19px;font-weight:500}
.chiplink::after,.recent button::after{content:"";position:absolute;inset:-4px 0}
.chiplink:active,.recent button:active{background:var(--panel)}
.chiplink svg{width:16px;height:16px}
.recent{display:flex;flex-wrap:wrap;gap:var(--s2)}
#sr-recent>.muted{margin-bottom:var(--s2)}
.tag{display:inline-block;padding:3px var(--s2);border-radius:var(--r1);background:var(--panel);color:var(--ink2);
 font-size:12px;line-height:16px;font-weight:600}
.tag.ok{background:var(--panel);color:var(--ink2)}
/* An answer chip: a card you can pick, marked by the accent when picked. */
.chips{display:grid;grid-template-columns:1fr 1fr;gap:var(--s2)}
.chip{position:relative;padding:14px var(--s4);border-radius:var(--r3);background-color:var(--card);text-align:left;
 font-size:14px;line-height:19px;font-weight:500;color:var(--ink)}
.chip small{display:block;margin-top:2px;font-size:13px;line-height:18px;font-weight:400;color:var(--ink2)}
.chip.sel{box-shadow:inset 0 0 0 2px var(--acc)}
/* The chosen chip is the one thing on a question the accent may mark: it is the
   active state of a control, which is what the accent is for (ADR 0013). */
.chip.sel>small::after{content:"";position:absolute;top:14px;right:14px;width:6px;height:11px;
 border:solid var(--acc);border-width:0 2px 2px 0;transform:rotate(45deg)}
.chip:active{background-color:var(--panel)}
/* One column of choices is a list, not a grid of cards: rows in one card, the
   chosen one filled and marked at its edge. */
.chips.one{display:block;background:var(--card);border-radius:var(--r4);overflow:hidden}
.chips.one .chip{display:flex;justify-content:space-between;align-items:center;gap:var(--s3);width:100%;
 min-height:56px;padding:var(--s3) var(--s4);border-radius:0;box-shadow:none;background-color:var(--card);
 background-image:var(--div);background-repeat:no-repeat;background-position:right bottom;
 background-size:calc(100% - var(--s4)) 1px}
.chips.one .chip:last-child{background-image:none}
.chips.one .chip>span:first-of-type{flex:1;text-align:left;font-size:16px;line-height:21px;font-weight:500}
.chips.one .chip small{font-size:13px;line-height:18px;color:var(--ink3)}
.chips.one .chip .r{flex:none;padding:var(--s1) var(--s2);border-radius:var(--r1);background-color:var(--panel);
 font-family:var(--mono);font-size:13px;line-height:17px;font-weight:500;color:var(--ink2);white-space:nowrap}
.chips.one .chip.sel{background-color:var(--panel);box-shadow:inset 3px 0 0 var(--acc)}
.chips.one .chip.sel>span:first-of-type{font-weight:600}
.chips.one .chip.sel .r{background-color:var(--card);color:var(--ink)}
.chips.one .chip:active{background-color:var(--pressed)}
/* A tile: a figure in a small card, two across. */
.tile{padding:14px var(--s3);border-radius:var(--r3);background:var(--card);border:1px solid transparent;
 text-align:center;font-size:13px;line-height:19px;font-weight:500;color:var(--ink)}
/* A switch the width of the row it sits in. */
.tog{display:flex;align-items:center;gap:var(--s3);min-height:52px;padding:0 var(--s4);border-radius:var(--r3);
 background:var(--panel);font-size:14px;line-height:19px;font-weight:500;cursor:pointer}
.tog input{width:20px;height:20px;margin:0;flex:none;accent-color:var(--acc)}
/* The segmented control: a pill whose thumb carries the state. The accent stays
   off it — the thumb is the mark. */
.seg{display:flex;min-height:44px;padding:2px;border-radius:var(--rf);background:var(--panel)}
.seg button{position:relative;flex:1 1 0;min-width:0;min-height:40px;padding:0 var(--s2);border-radius:var(--rf);
 font-size:13px;line-height:19px;font-weight:500;color:var(--ink2);white-space:nowrap;overflow:hidden;
 text-overflow:ellipsis}
.seg button::after{content:"";position:absolute;inset:-2px}
.seg button.sel{background:var(--thumb);color:var(--acc);font-weight:600;box-shadow:var(--sh-thumb)}
.seg.fit{display:inline-flex;max-width:100%}
.seg.fit button{flex:0 1 auto;padding:0 var(--s3)}

/* ---------- 12. inputs --------------------------------------------------- */
.field{position:relative}
.field label{display:block;margin-bottom:6px;font-size:13px;line-height:18px;font-weight:500;color:var(--ink2)}
.field input,.field select{width:100%;min-height:52px;padding:0 14px;border-radius:var(--r2);
 border:1px solid var(--rule);background:var(--fill);font-size:16px;line-height:23px;font-weight:400;
 color:var(--ink);appearance:none;outline:none}
.field input::placeholder{color:var(--ink3);font-weight:400}
/* Focus is one 2px accent edge, drawn as border + inset so nothing reflows. */
.field input:focus,.field select:focus{border-color:var(--acc);box-shadow:inset 0 0 0 1px var(--acc)}
/* The browser's own spinner and search-clear button are chrome the design did
   not ask for. */
input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}
input[type=number]{-moz-appearance:textfield;appearance:textfield}
input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}
.err{display:none;margin-top:6px;color:var(--danger);font-size:13px;line-height:18px}
.err.on{display:block}
/* The amount: not a box, an object. The ₹ and the digits share one baseline and
   one underline, and the container is plain text — it is `.field.amount` now, so
   it can never inherit the figure styling the way `.field.big` did. */
.field.amount{position:relative;scroll-margin-top:12px;font-family:var(--sans);font-size:16px;line-height:23px;
 font-weight:400;letter-spacing:0;font-variant-numeric:normal}
.field.amount label{margin-bottom:2px}
.field.amount .lblrow{display:flex;justify-content:space-between;align-items:center;gap:var(--s3);margin-bottom:2px}
.field.amount .lblrow label{margin:0}
.prefix{display:flex;align-items:baseline;gap:6px;padding:var(--s1) 0 var(--s2);border-bottom:1px solid var(--rule)}
.prefix:focus-within{border-bottom-color:var(--acc);box-shadow:0 1px 0 var(--acc)}
.prefix span{font-family:var(--mono);font-size:21px;line-height:1;font-weight:500;color:var(--ink2);letter-spacing:0}
/* 44px by declaration. This took its height from a 40px figure on a 48px
   line, so shrinking the figure by any amount dropped the target under the
   rule — which is how a tap target should never have been defined. */
.field.amount input{width:100%;min-height:44px;padding:0;border:0;border-radius:0;background:none;box-shadow:none;
 font-family:var(--mono);font-size:32px;line-height:40px;font-weight:600;letter-spacing:-.02em;
 font-variant-numeric:tabular-nums}
.field.amount input:focus{border:0;box-shadow:none}
/* spec 030: the figure stays in view while typing — a mirror of it on the input
   line for the long screens where the panel cannot fit beside the keyboard. */
.lblfig{display:none;position:absolute;right:0;bottom:12px;font-family:var(--mono);font-weight:600;font-size:13px;
 line-height:18px;color:var(--ink);white-space:nowrap;font-variant-numeric:tabular-nums}
.lblfig small{display:block;text-align:right;font-family:var(--sans);font-weight:400;font-size:12px;line-height:16px;
 color:var(--ink3)}
.field.amount.mir .lblfig{display:block}
.field.amount.mir input{width:calc(100% - 130px)}
/* The search box carries its magnifier. */
#sr-qwrap .mag{position:absolute;left:14px;top:16px;color:var(--ink3);pointer-events:none}
#sr-q{min-height:52px;padding-left:44px;border-radius:var(--r3);font-size:16px}
#sr-hint{margin-top:var(--s2)}

/* ---------- 13. add screens --------------------------------------------- */
/* The result stands alone (spec 015): a small-caps label, the figure, a grey
   detail line. Whitespace does the framing. */
.taxpanel{padding:0}
.taxpanel .big{margin-top:var(--s1);color:var(--ink)}
.taxpanel .hint{margin-top:var(--s2)}
/* Repeat-last on fuel (product rule), as a quiet card rather than a second
   filled button. A screen with two filled buttons has no primary action. */
/* One row anatomy. This was 56px with a 32px circular tile while every list row
   is 64px with a 40px rounded-square one, so the same idea was drawn two ways
   on two screens. */
.lastrow{display:flex;align-items:center;gap:var(--s3);width:100%;min-height:64px;padding:var(--s3) var(--s4);
 border-radius:var(--r3);background:var(--card);color:var(--ink);text-align:left}
.lastrow .ic{width:40px;height:40px;border-radius:var(--r3);background:var(--panel);color:var(--ink2);flex:none;display:grid;place-items:center}
.lastrow .ic svg{width:18px;height:18px}
.lastrow .t1{display:block;font-size:15px;line-height:21px;font-weight:600}
.lastrow .t2{display:block;font-size:13px;line-height:18px;color:var(--ink3)}
.lastrow .chev{margin-left:auto}
.lastrow:active{background:var(--panel)}
/* Food's split, folded (spec 015). Closed on entry; the same fields inside. */
.fold{background:var(--card);border-radius:var(--r4);padding:0 var(--s4)}
.fold summary{display:flex;align-items:center;gap:var(--s3);min-height:56px;cursor:pointer;list-style:none;
 font-size:14px;line-height:19px;font-weight:600;color:var(--ink)}
.fold summary::-webkit-details-marker{display:none}
.fold summary .muted{font-weight:400}
.fold summary .chev{margin-left:auto;transform:rotate(90deg)}
.fold[open] summary .chev{transform:rotate(-90deg)}
.fold>.stack{padding:var(--s1) 0 var(--s4)}
.bar{display:flex;height:8px;border-radius:var(--r1);overflow:hidden;background:var(--panel)}
.bar i{display:block;height:100%}
.bar .k{background:var(--pressed)}
.bar .t{background:var(--ink)}
.bar .f{background:var(--ink3)}
.legend{display:flex;flex-wrap:wrap;gap:var(--s2) var(--s4);margin-top:var(--s2);font-size:13px;line-height:18px;
 color:var(--ink2)}
.legend b{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:6px;vertical-align:middle}
.legend .k b{background:var(--pressed)}
.legend .t b{background:var(--ink)}
.legend .f b{background:var(--ink3)}
/* How a figure was arrived at: one line per term, the total in ink. */
.lines{background:var(--card);border-radius:var(--r3);padding:0 var(--s4)}
.fold .lines,.panel .lines,.sheet-in .lines{padding:0;background:none}
.lines .ln{display:flex;justify-content:space-between;align-items:baseline;gap:var(--s3);padding:var(--s3) 0;
 border-bottom:1px solid var(--rule)}
.lines .ln:last-child{border-bottom:0}
.lines .ln span:first-child{color:var(--ink2);font-size:14px;line-height:19px}
.lines .ln span:last-child{font-variant-numeric:tabular-nums}
.lines .ln.tot{font-weight:600}
.lines .ln.tot span:first-child{color:var(--ink)}
.lines .ln.tax span:last-child{font-weight:600}
.panel{background:var(--card);border-radius:var(--r4);padding:var(--s4)}
#rg-say{margin-top:var(--s2);color:var(--ink2)}
#rg-gross-note{margin-top:var(--s1)}

/* ---------- 14. salary --------------------------------------------------- */
/* A button, not a panel: it opens the current month, the one most likely to
   need correcting (spec 047). display is set here, so renderSalary's
   style.display='' restores a flex row rather than an inline-block. */
.sacard{display:flex;align-items:center;gap:var(--s3);width:100%;margin-bottom:var(--s4);padding:var(--s4);
 border-radius:var(--r4);background:var(--card);color:var(--ink);text-align:left;font:inherit}
.sacard .body{flex:1;min-width:0}
.sacard .lbl,.sacard .v,.sacard .c{display:block}
.sacard .v{margin-top:var(--s1);font-family:var(--mono);font-size:20px;line-height:25px;font-weight:600;
 font-variant-numeric:tabular-nums;color:var(--ink)}
.sacard .v small{font-family:var(--sans);font-size:13px;font-weight:400;color:var(--ink2);margin:0 2px 0 5px}
.sacard .c{margin-top:2px;font-size:13px;line-height:18px;color:var(--ink3)}
.sacard .chev{flex:none}
.sacard:active{background:var(--panel)}
#sa-edit{margin-bottom:var(--s4)}
#sa-edit .row.between{min-height:40px}
#sa-edit h3{font-size:18px;line-height:23px;font-weight:600;letter-spacing:-.01em}
/* The financial year as it is: twelve months, three across, a quarter a row.
   minmax(0,…) so a wide figure cannot push a column past the viewport. */
.sagrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s2)}
.cell{display:flex;flex-direction:column;align-items:flex-start;gap:var(--s1);min-height:64px;min-width:0;
 padding:var(--s3);border:1px solid transparent;border-radius:var(--r3);background:var(--card);text-align:left;
 color:var(--ink)}
.cell .m{display:flex;align-items:center;gap:6px}
.cell .a{font-family:var(--mono);font-size:15px;line-height:19px;font-weight:600;font-variant-numeric:tabular-nums;
 letter-spacing:-.01em;max-width:100%}
.cell .a.long{font-size:13px}
.cell.set .m::after,.legdot{content:"";display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--ink)}
.legdot{vertical-align:middle;margin-right:2px}
/* An expected month is drawn, not filled; a set one is a card. */
.cell.fut,.cell.blank{background:none;border:1px dashed var(--rule)}
.cell.fut .a,.cell.blank .a,.cell.zero .a{color:var(--ink3);font-weight:500}
.cell:active{background:var(--panel)}
/* The one active state on the screen: the month being edited (ADR 0013). */
.cell.on{background:var(--card);border-color:transparent;box-shadow:0 0 0 2px var(--acc)}
.sagrid+p.muted{margin-top:var(--s3)}
#sa-regime{margin-top:var(--s6)}
#st-del{margin-top:var(--s3)}

/* ---------- 15. settings ------------------------------------------------- */
#settings .stack>div>.muted:first-child{margin-bottom:6px}
details.info{background:var(--card);border-radius:var(--r4);padding:0 var(--s4)}
details.info+details.info{margin-top:var(--s2)}
details.info summary{display:flex;align-items:center;gap:var(--s3);min-height:56px;cursor:pointer;list-style:none;
 font-size:16px;line-height:21px;font-weight:500;color:var(--ink)}
details.info summary::-webkit-details-marker{display:none}
details.info summary .chev{margin-left:auto;transform:rotate(90deg)}
details.info[open] summary .chev{transform:rotate(-90deg)}
details.info .small,details.info .stack{padding-bottom:var(--s4)}

/* ---------- 16. share ----------------------------------------------------
   The share card is a canvas at its natural 1080x1350; the page only scales it. */
.cardimg{display:block;width:100%;height:auto;aspect-ratio:1080/1350;border-radius:var(--r4);border:1px solid var(--rule);background:var(--card)}

/* ---------- 17. the bottom bar ------------------------------------------
   Four equal, quiet items. No pills, no discs, no accent: the bar is Home-only,
   so there is no active tab for the accent to mark. */
#nav{position:fixed;left:0;right:0;bottom:0;z-index:10;max-width:520px;margin:0 auto;display:none;
 padding:var(--s2) var(--s2) calc(var(--s3) + env(safe-area-inset-bottom));background:var(--card);box-shadow:var(--sh-nav)}
#nav.on{display:block}
#nav .row{gap:0}
.tab{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--s1);
 min-height:56px;padding:var(--s1) 0;font-size:12px;line-height:16px;font-weight:500;color:var(--ink2)}
.tab .tg svg{width:24px;height:24px}
/* An add is an action, so it carries the accent; Salary is a place, so it
   does not. The rule CLAUDE.md states, drawn (ADR 0013). */
/* The three adds carry the accent so they read as actions and Salary reads as
   a place — the rule CLAUDE.md states. On the glyph and the word only: a
   filled disc behind three of four items is the accent as a ground, which the
   same rule forbids, and it made the fourth look disabled (ADR 0013). */
.tab.add,.tab.add .tg{color:var(--acc)}
.tab:active{color:var(--ink)}
.tab:active .tg{transform:scale(.96)}

/* ---------- 18. overlays: the sheet and the toast ----------------------- */
.sheet{position:fixed;inset:0;z-index:30;display:none;align-items:flex-end;background:var(--scrim)}
.sheet.on{display:flex}
.sheet-in{width:100%;max-width:520px;margin:0 auto;padding:var(--s2) var(--s5) calc(var(--s6) + env(safe-area-inset-bottom));
 border-radius:var(--r5) var(--r5) 0 0;background:var(--card);box-shadow:var(--sh-sheet)}
.sheet-in::before{content:"";display:block;width:36px;height:4px;margin:0 auto var(--s3);border-radius:2px;
 background:var(--rule)}
.sheet-in.stack>*+*{margin-top:var(--s4)}
.sheet-in>.row.between{min-height:40px}
#sh-tag{background:none;padding:0}
/* The entry's name is the sheet's title, and still editable. */
.sheet-in .field:has(#sh-name){margin-top:var(--s1)}
.sheet-in .field:has(#sh-name) label{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);
 white-space:nowrap}
#sh-name{min-height:44px;padding:0 0 var(--s2);border:0;border-radius:0;background:none;font-size:18px;line-height:23px;
 font-weight:600;letter-spacing:-.01em;box-shadow:inset 0 -1px 0 var(--rule)}
#sh-name:focus{border:0;box-shadow:inset 0 -2px 0 var(--acc)}
/* One line, full width, one action. */
.toast{position:fixed;left:0;right:0;bottom:calc(92px + env(safe-area-inset-bottom));z-index:40;
 width:calc(100% - 40px);max-width:480px;margin:0 auto;display:none;align-items:center;gap:var(--s1);
 min-height:48px;padding:var(--s1) var(--s1) var(--s1) var(--s4);border-radius:var(--r3);
 background:var(--inv);color:var(--invInk);font-size:13px;line-height:19px;box-shadow:var(--sh-toast)}
.toast.on{display:flex}
#toast-msg{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.toast button{flex:none;min-height:44px;padding:0 var(--s3);border-radius:var(--r2);color:var(--toastAcc);
 font-size:13px;font-weight:600;white-space:nowrap}
.toast button:empty{display:none}
/* Above the bar on Home; near the bottom edge elsewhere, clear of the primary
   button that sits where the bar would be (spec 035). */
body:not(:has(#nav.on)) .toast{bottom:calc(20px + env(safe-area-inset-bottom))}

/* ---------- 19. onboarding and the drawings (specs 021, 049) ------------
   One box, ink strokes, a panel-grey body and an ink fill for the tax share.
   Everything is currentColor, so dark mode needs no second rule (ADR 0013). */
/* Onboarding and the reveal run one step below the rest of the app: nine
   screens of a sentence and four chips do not need the size a screen of
   figures does (spec 056). */
#onb,#reveal{font-size:14px;line-height:21px}
#onb .wordmark{font-size:16px;line-height:23px}
#onb .chip{min-height:56px;padding:11px 14px;font-size:13px;line-height:18px}
#onb .chip small{margin-top:1px;font-size:12px;line-height:16px}
/* 16px is the floor on an input: below it iOS Safari zooms the page. */
#onb .field input,#onb .field select{min-height:48px;font-size:16px;line-height:21px}
#onb .btn,#reveal .btn{min-height:48px;font-size:14px;line-height:19px}
#onb .quiet{min-height:44px;font-size:13px;line-height:19px}
#reveal .big{font-size:29px;line-height:34px;letter-spacing:-.025em}
#reveal .muted,#reveal .hint{font-size:13px;line-height:18px}
.q{margin:0 0 6px;font-size:18px;line-height:23px;font-weight:700;letter-spacing:-.02em}
.qs{margin:2px 0 0;font-size:13px;line-height:18px;color:var(--ink3)}
/* The head is a fixed box the answer block sits under, so the first chip's
   top is a constant rather than the sum of a picture, a title, a subtitle
   and a fact. A short head settles downward against the chips instead of
   dragging them up; a long one is given the room from its own slack. */
.qhead{display:flex;flex-direction:column;justify-content:flex-end;height:120px;
 padding-bottom:var(--s4);overflow:hidden}
/* Children keep their natural height: a head too short for its question should
   overflow, where the audit sees it, rather than squash the question to fit. */
.qhead>*{flex:none}
/* 120px is the tallest question head measured over all nine, at 360 and 390,
   with the longest state name in the fuel sentence: 113px, for "Mobile,
   broadband and OTT in a month?" over a two-line fact. The welcome is not a
   question and has no chips to anchor, so it takes the height it needs. */
.qhead.intro{height:auto;min-height:120px}
.qdock:has(.chips){min-height:186px}
.qdock .chips+.field{margin-top:10px}
/* Hidden from the eye, kept for the accessible name: the label became the
   placeholder, and a control still has to be labelled. */
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
 clip-path:inset(50%);white-space:nowrap;border:0}
.dots3{display:flex;gap:5px}
.dots3 i{width:6px;height:6px;border-radius:50%;background:var(--rule)}
.dots3 i.on{background:var(--ink)}
.lbl-or{margin:var(--s4) 0 var(--s2)}
#onb-body .chips+.field{margin-top:var(--s4)}
#onb-next{margin-top:var(--s6)}
#onb-skip{margin-top:var(--s1)}
.art{display:block;width:88px;height:88px;flex:none;color:var(--ink);fill:none;stroke:currentColor;stroke-width:2;
 stroke-linecap:round;stroke-linejoin:round}
.art .k{fill:var(--panel);stroke:none}
.art .t{fill:currentColor;stroke:none}
.art .d{stroke:var(--ink3)}
.art.sm{width:56px;height:56px;color:var(--ink2)}
/* The welcome: three things on a shelf, each showing how much of it is tax. */
.hero3{display:flex;justify-content:space-around;align-items:flex-end;margin-top:0;padding:var(--s1) var(--s1) 0;
 border-bottom:2px solid var(--ink)}
/* The negative margin seats the drawing on the shelf rule, so it scales
   with the drawing: -12px under 104px is -6px under 56px, and leaving it
   at -12px drops the drawing through its own shelf (spec 056). */
.hero3 .art{width:56px;height:56px;margin-bottom:-6px}
.caps{display:grid;grid-template-columns:1fr 1fr 1fr;margin:6px 0 0;text-align:center;font-size:12px;
 line-height:17px;color:var(--ink2)}
.caps b{font-family:var(--mono);font-size:13px;line-height:17px;font-weight:600;color:var(--ink)}
/* The one true line under a question. It carries the share as well now, so
   there is no picture and no second figure saying the same thing. */
.qshare{margin:0;font-size:13px;line-height:19px;color:var(--ink2)}
.qshare b{font-family:var(--mono);font-weight:600;color:var(--ink)}
/* Sized and seated against the figure it qualifies, not against the line box. */
.approx{display:inline-block;width:.62em;height:.62em;margin-right:.16em;vertical-align:.02em;stroke:currentColor;
 fill:none;opacity:.75}
/* The running figure: a bar on a fixed rule, one segment per answer, so the
   number and the picture grow together instead of the number jumping alone. */
/* The slot is always there; only its rule and its contents come and go, so
   the button below it is as still as the chips above it. */
.onb-run{display:block;min-height:46px;margin:0;padding-top:var(--s3);border-top:0}
.onb-run.on{border-top:1px solid var(--rule)}
.onb-run:not(.on) .ln{visibility:hidden}
.onb-run .ln{display:flex;justify-content:space-between;align-items:baseline;gap:var(--s3)}
.onb-run .ln .sec{font-size:13px;line-height:18px;font-weight:400;letter-spacing:0;text-transform:none;color:var(--ink3)}
.onb-run .v{font-family:var(--mono);font-size:16px;line-height:21px;font-weight:600;color:var(--ink);
 font-variant-numeric:tabular-nums}
.reveal{margin-top:var(--s2)}

/* ---------- 20. motion ---------------------------------------------------
   Four jobs only: say which direction you moved, answer a press, show that a
   number changed because of something you did, and let a proportion grow rather
   than jump. Nothing here decorates. All of it is off under
   prefers-reduced-motion, which is the default state of this block — motion is
   opt-in, not opt-out. */
@keyframes navf{from{opacity:0;transform:translate3d(14px,0,0)}to{opacity:1;transform:none}}
@keyframes navb{from{opacity:0;transform:translate3d(-14px,0,0)}to{opacity:1;transform:none}}
@keyframes rowin{from{opacity:0;transform:translate3d(0,-7px,0)}to{opacity:1;transform:none}}
@keyframes toastin{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@keyframes up{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@keyframes fillup{from{transform:translateY(100%)}}
@keyframes grow{from{transform:scaleX(0)}}
@media (prefers-reduced-motion:no-preference){
 /* forward pushes in from the right, back from the left — the nav stack, made
    visible. 190ms: long enough to read direction, short enough to feel instant. */
 .screen.on[data-nav="f"]{animation:navf .19s var(--ease) both}
 .screen.on[data-nav="b"]{animation:navb .19s var(--ease) both}
 /* a press lands instantly and releases in 150ms */
 .btn,.chip,.tile,.list .it,.arow,.prow,.cell,.chiplink,.recent button,.ib,.pill,.seg button,.quiet,.link,.back,
 .lastrow,.sacard,.iconbtn,.tab,.tab .tg,.chev{
  transition:background-color .15s var(--ease),box-shadow .15s var(--ease),color .15s var(--ease),transform .15s var(--ease)}
 .btn:active,.chip:active,.list .it:active,.arow:active,.prow:active,.cell:active,.chiplink:active,
 .recent button:active,.ib:active,.pill:active,.quiet:active,.link:active,.back:active,.lastrow:active,
 .sacard:active,.iconbtn:active,.tab:active .tg{transition-duration:0s}
 /* the proportion grows into place instead of teleporting */
 .bar i,.prow .track i{transition:width .4s var(--ease)}
 .toast.on{animation:toastin .2s var(--ease) both}
 /* only the row you just created, and only once */
 .list .it.new{animation:rowin .3s var(--ease) both}
 /* the reveal arrives as one thing, quickly */
 .reveal>*{animation:up .3s var(--ease) both}
 .reveal>*:nth-child(2){animation-delay:.04s}
 .reveal>*:nth-child(3){animation-delay:.08s}
 .reveal>*:nth-child(4){animation-delay:.12s}
 /* the tax rises into each object once, left to right */
 .hero3 .t{animation:fillup .7s var(--ease) both}
 .hero3 .art:nth-child(2) .t{animation-delay:.12s}
 .hero3 .art:nth-child(3) .t{animation-delay:.24s}
}
/* A select must look like a control: the appearance is stripped, so the
   chevron is put back. Painted as a mask in currentColor rather than baked
   into the data URI, so one rule serves both themes and no hex hides from
   the colour audit inside a URL (spec 050). */
.field select{padding-right:44px}
.field{position:relative}
.field:has(select)::after{content:"";position:absolute;right:14px;bottom:16px;width:20px;height:20px;pointer-events:none;background:var(--ink3);-webkit-mask:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="none" stroke="black" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M5.5 8L10 12.5 14.5 8"/></svg>') center/20px no-repeat;mask:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="none" stroke="black" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M5.5 8L10 12.5 14.5 8"/></svg>') center/20px no-repeat}

/* The bottle row: the whole row is the picker, the word only says so (spec 052). */
.arow.pick{position:relative;cursor:pointer}
.arow.pick select{position:absolute;inset:0;opacity:0;width:100%;height:100%;cursor:pointer}
.arow.pick .lb{min-width:0;flex:1 1 auto}
.arow.pick .t1{display:block;font-weight:500}
.arow.pick .link{margin-left:auto;flex:none;padding:0}
/* "same as last time" is prose, and .amount is in the mono figure family. */
.field.amount .lblrow .hint{font-family:var(--sans);letter-spacing:0;font-variant-numeric:normal}
/* The empty headline is a dash, not a bar: set at the figure's size it painted
   a 48x6 rectangle floating in a 90px line box, which reads as a skeleton. */
.home .hero .big .dash{font-family:var(--sans);font-size:27px;line-height:1;color:var(--ink3);vertical-align:.1em}

/* The toast says the whole sentence: it was ellipsising "Added Mobile recharge
   — ₹61 a month f…" mid-word, and its two actions ran together in one accent
   with nothing between them. */
.toast{align-items:flex-start}
.toast #toast-msg{white-space:normal;overflow:visible;text-overflow:clip;flex:1 1 auto}
.toast button+button{margin-left:var(--s1);position:relative}
.toast button+button::before{content:"";position:absolute;left:calc(var(--s1) * -1);top:50%;width:1px;height:16px;margin-top:-8px;background:currentColor;opacity:.35}
/* A native date picker paints the browser's own filled glyph beside 43 drawn
   stroke icons. Hidden, and the field keeps its own chevron affordance. */
input[type=date]::-webkit-calendar-picker-indicator{opacity:0}
input[type=date]{position:relative}

/* ---- the reveal (spec 053) --------------------------------------------
   One bar for the year — length is what you spend, ink is the tax inside it —
   read by the legend directly under it, and then a ranked table. Every row used
   to draw its own track at the width of that category's spend, so eight rows
   ended at eight different places; the tax is the one figure now, in one
   right-aligned column (spec 056). */
.rvsent{margin:0;font-size:13px;line-height:20px;color:var(--ink2)}
.rvsent b{font-family:var(--mono);font-weight:600;color:var(--ink)}
.rvbar{margin:12px 0 4px}
.rvbar .bar{height:10px}
.rrow{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);
 min-height:48px;padding:var(--s2) 0;border-bottom:1px solid var(--rule);cursor:pointer}
.rrow .lb{min-width:0;font-size:14px;line-height:19px;font-weight:500;
 overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rrow .lb small{display:block;margin-top:1px;font-size:12px;line-height:16px;font-weight:400;
 color:var(--ink3);font-variant-numeric:tabular-nums}
.rrow .v{flex:none;font-family:var(--mono);font-weight:600;font-size:14px;white-space:nowrap;
 font-variant-numeric:tabular-nums}
.rrow.tot{min-height:44px;border-bottom:2px solid var(--ink);cursor:default}
.rrow.tot .lb{font-weight:700}
#reveal #rv-axis{margin:10px 0 2px}
/* The button is reachable while the rows scroll under it. */
#reveal .btn{position:sticky;bottom:var(--s3);z-index:2}
@media (prefers-reduced-motion:no-preference){
 .rrow{animation:up .5s ease both;animation-delay:calc(.45s + var(--i) * .06s)}
}

/* A count, beside the bottle it counts (spec 054). Two 44px targets and the
   figure between them — small enough not to be a sixth decision, present
   enough that nobody types a whole evening's bill as one bottle. */
.qty{display:flex;align-items:center;gap:var(--s2);margin-top:calc(var(--s3) * -1)}
.qty .lb{flex:1;font-size:13px;color:var(--ink2)}
.qty .qb{width:44px;height:44px;border-radius:var(--rf);background:var(--panel);color:var(--ink);font-size:18px;line-height:1;display:grid;place-items:center}
.qty .qb:active{background:var(--pressed)}
.qty .qb[disabled]{color:var(--ink3);opacity:1}
.qty .n{min-width:32px;text-align:center;font-family:var(--mono);font-weight:600;font-size:16px;font-variant-numeric:tabular-nums}

/* A label inside a list card sits at the card's own edge, where a 16px corner
   clips its first letter — COMMON rendered as :OMMON. It takes the same inset
   the rows beside it take (spec 054). */
.list>.sec,.list>.muted{padding:var(--s3) var(--s4) var(--s2)}
/* The scope switch is one of the editor's controls, so it is the width of the
   others; .seg.fit sized it to its own text and left it 7px short of Save. */
#sa-edit .seg.fit{display:flex;width:100%}
#sa-edit .seg.fit button{flex:1 1 0}
