/* ==========================================================================
   তিরিশ — components. Colour comes only from tokens.css.
   ========================================================================== */

*,*::before,*::after{box-sizing:border-box;}
html,body{height:100%;overflow:hidden;}
body{
  margin:0;background:var(--poly);color:var(--ink);
  font-family:var(--body);font-size:15px;line-height:1.55;
  /* Keep the layout the same size before and after the Bangla webfont lands.
     Without this the whole list reflows when Hind Siliguri arrives, which on
     a slow shop connection is the first thing the dealer sees happen. */
  font-size-adjust:from-font;
  -webkit-font-smoothing:antialiased;-webkit-tap-highlight-color:transparent;
  overscroll-behavior-y:none;
}
button{font:inherit;color:inherit;background:none;border:none;padding:0;cursor:pointer;}
a{color:inherit;text-decoration:none;}
input,select,textarea{font:inherit;color:inherit;}
ul{list-style:none;margin:0;padding:0;}
h1,h2,h3{margin:0;font-weight:inherit;}
:where(a,button,input,select,textarea,[tabindex]):focus-visible{
  outline:3px solid var(--sack);outline-offset:2px;border-radius:7px;
}
.num{font-variant-numeric:tabular-nums;font-feature-settings:'tnum' 1;}

/* Hidden to the eye, present to a screen reader. The :focus-within exception
   is what lets the skip link appear when a keyboard reaches it. */
.visually-hidden:where(:not(:focus-within,:active)){
  position:absolute !important;clip-path:inset(50%) !important;overflow:hidden !important;
  width:1px !important;height:1px !important;margin:-1px !important;padding:0 !important;
  border:0 !important;white-space:nowrap !important;
}
.skip{position:absolute;z-index:60;top:10px;left:10px;background:var(--sheet);
  color:var(--sack-ink);padding:0 16px;min-height:48px;display:inline-flex;align-items:center;
  border-radius:var(--r-s);box-shadow:var(--sh-m);font-weight:600;}

/* ---------- type scale: fractional sizes, negative tracking ---------- */
.display{font-family:var(--display);font-size:31.5px;line-height:1.08;letter-spacing:-.022em;font-weight:700;text-wrap:balance;}
.h1{font-family:var(--display);font-size:22.5px;line-height:1.18;letter-spacing:-.016em;font-weight:600;text-wrap:balance;}
.h2{font-family:var(--display);font-size:17.5px;line-height:1.25;letter-spacing:-.011em;font-weight:600;}
.lede{font-size:15.5px;line-height:1.5;color:var(--ink-2);margin:0;text-wrap:pretty;}
.meta{font-size:12.75px;line-height:1.4;color:var(--ink-3);margin:0;letter-spacing:.004em;}
.eyebrow{font-size:11.25px;font-weight:600;letter-spacing:.075em;text-transform:uppercase;
  color:var(--ink-3);margin:0;font-family:var(--body);padding:0 4px 8px;display:block;}
.money{font-family:var(--display);letter-spacing:-.018em;font-weight:700;}

/* ---------- shell: a phone on the desk, not a broken website ---------- */
.frame{min-height:100%;display:flex;justify-content:center;align-items:stretch;background:var(--poly);}
/* Fixed height, never min-height: .body scrolls inside, so the tab bar and the
   sheet sit on the viewport instead of at the bottom of the whole list. */
.app{position:relative;width:100%;max-width:428px;display:flex;flex-direction:column;
     height:100dvh;background:var(--poly);overflow:hidden;}
#mount{display:contents;}
@media (min-width:660px) and (min-height:720px){
  .frame{background:var(--sunk);padding:28px 16px;align-items:center;
         background-image:radial-gradient(circle at 1px 1px,var(--rule-2) 1px,transparent 0);
         background-size:22px 22px;}
  .app{height:min(896px,calc(100dvh - 56px));border-radius:36px;
       box-shadow:var(--sh-l),0 0 0 9px var(--ink),0 0 0 10.5px var(--rule-2);}
}

/* ---------- sign in ---------- */
.top.loginband{padding-bottom:18px;}
.login{flex:1 1 auto;overflow-y:auto;padding:0 22px calc(var(--safe-b) + 28px);
  display:flex;flex-direction:column;justify-content:center;}
.formerr{min-height:20px;margin:2px 0 10px;font-size:13.25px;color:var(--stencil-ink);font-weight:600;}

/* ---------- header ---------- */
.top{padding:calc(var(--safe-t) + 18px) 18px 0;background:var(--sack);color:var(--on-sack);flex:0 0 auto;}
.top .brand{display:flex;align-items:baseline;gap:9px;}
.top .mark{margin:0;font-family:var(--display);font-size:25px;font-weight:800;letter-spacing:-.02em;line-height:1;}
.top .sub{font-size:12.25px;opacity:.72;}
.top .shop{margin-top:2px;font-size:12.75px;opacity:.66;}
.top .ledger{margin-top:15px;display:flex;align-items:flex-end;justify-content:space-between;gap:12px;}
.top .out{display:block;font-family:var(--display);font-size:33px;font-weight:800;
  letter-spacing:-.025em;line-height:1;}
.top .outlab{display:block;font-size:11.25px;font-weight:600;letter-spacing:.075em;
  text-transform:uppercase;opacity:.62;margin-bottom:5px;}
.top .birds{text-align:right;font-size:12.5px;opacity:.72;line-height:1.35;}

/* The dealer must be able to tell "on this phone" from "the shop's books know".
   Text, not only a colour: a colour alone is unreadable to a third of the
   people who will ever hold this phone in daylight. */
.sync{margin:14px -18px 0;padding:9px 18px;display:flex;align-items:center;gap:8px;
  font-size:12.5px;background:var(--band);color:var(--on-band);}
.sync svg{flex:0 0 auto;opacity:.9;}
/* Opaque, and from a token. An earlier version was a 78% colour-mix over a
   translucent strip, which measured at a contrast nobody should have to
   squint through — and status text saying whether the dealer's money is
   recorded anywhere is not decoration. */
.sync.ok{color:var(--on-band);}
.sync.wait,.sync.busy{background:var(--brood);color:#1B1304;font-weight:600;}
.sync.off{background:var(--stencil);color:#FFF1EF;font-weight:600;}
.sync .again{margin-left:auto;min-height:32px;padding:0 10px;border-radius:99px;
  background:rgba(255,255,255,.22);font-size:12px;font-weight:700;}

/* ---------- scroll body ---------- */
.body{flex:1 1 auto;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;
  padding:16px 14px calc(var(--safe-b) + 24px);}
.sec{margin:0 0 20px;}

/* ---------- the strip ---------- */
.strip{display:flex;gap:9px;padding:0 4px 14px;}
.chip{flex:1;background:var(--sheet);border:1px solid var(--rule);border-radius:var(--r-m);
  padding:10px 11px;box-shadow:var(--sh-s);}
.chip b{display:block;font-family:var(--display);font-size:19.5px;font-weight:700;
  letter-spacing:-.018em;line-height:1.15;}
.chip span{display:block;font-size:11.5px;color:var(--ink-3);margin-top:1px;line-height:1.3;}
.chip.hot{background:var(--stencil-wash);border-color:color-mix(in srgb,var(--stencil) 28%,transparent);}
.chip.hot b{color:var(--stencil-ink);}
/* --ink-3 measured 4.44:1 on the stencil wash — under AA by a hair, and this
   is the one chip a dealer reads in a hurry. The label joins the red family,
   which is also what it is saying. */
.chip.hot span{color:var(--stencil-ink);}

/* ---------- cards ---------- */
.cards{display:block;}
.card{width:100%;text-align:left;display:block;background:var(--sheet);
  border:1px solid var(--rule);border-radius:var(--r-l);padding:14px 15px 13px;
  box-shadow:var(--sh-m);margin-bottom:11px;position:relative;overflow:hidden;
  transition:transform .16s cubic-bezier(.2,.7,.3,1),box-shadow .16s;}
button.card:active{transform:scale(.988);box-shadow:var(--sh-s);}
.card::before{content:'';position:absolute;inset:0 auto 0 0;width:3.5px;background:var(--rule-2);}
.card.flat::before{display:none;}
.card.flat{padding:12px 14px;}
.card.s-overdue::before{background:var(--stencil);}
.card.s-unpaid::before{background:var(--brood);}
.card.s-lifting::before{background:var(--sack);}
.card.s-settled{opacity:.62;box-shadow:none;}
.card.s-settled::before{background:var(--grit);}

/* The card is a <button>, whose content model is phrasing content, so every
   box inside it is a <span> that has been told to behave. */
.card .who{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;}
.card .who > span,.card .who > div{min-width:0;}
.card .name{display:block;font-family:var(--display);font-size:17.5px;font-weight:600;
  letter-spacing:-.012em;line-height:1.2;}
.card .vil{display:block;font-size:12.25px;color:var(--ink-3);margin-top:1px;}
.card .amt{display:block;text-align:right;flex:0 0 auto;}
.card .amt .money{display:block;font-size:19px;}
.card .amt .meta{display:block;margin-top:0;}
.lineitem{display:flex;justify-content:space-between;align-items:baseline;}
.lineitem.ruled{margin-top:9px;padding-top:9px;border-top:1px dashed var(--rule);}
.lineitem + .lineitem:not(.ruled){margin-top:8px;}

/* the day dial — a real <progress>, so it carries its own role and value */
.run{display:flex;align-items:center;gap:11px;margin-top:12px;}
.dial{flex:0 0 auto;position:relative;width:42px;height:42px;display:grid;place-items:center;}
@property --value{syntax:'<number>';inherits:true;initial-value:0;}
progress.ring{
  --size:42px;--thickness:3.4px;
  --track:var(--sunk);--fill:var(--sack);
  appearance:none;-webkit-appearance:none;border:none;
  width:var(--size);height:var(--size);border-radius:50%;
  background:conic-gradient(var(--fill) calc(var(--value) * 1%), var(--track) 0);
  transition:--value 0s;
}
@media (prefers-reduced-motion:no-preference){progress.ring{transition-duration:.45s;}}
/* Hollow the middle. border-area is not in Firefox, so this is the fallback
   that actually runs nearly everywhere. */
progress.ring{mask-image:radial-gradient(transparent calc(50% - var(--thickness)),
  #000 calc(50% - var(--thickness) + .5px));}
progress.ring::-webkit-progress-bar,progress.ring::-webkit-progress-value{
  background:none;display:none;}
progress.ring::-moz-progress-bar{background:none;}
.s-overdue progress.ring{--fill:var(--stencil);}
.s-unpaid progress.ring{--fill:var(--brood);}
.s-settled progress.ring{--fill:var(--grit);}
.dial .t{position:absolute;inset:0;display:grid;place-items:center;
  font-family:var(--display);font-size:14px;font-weight:700;letter-spacing:-.02em;color:var(--sack);}
.s-overdue .dial .t{color:var(--stencil);}
.s-unpaid .dial .t{color:var(--brood);}
.s-settled .dial .t{color:var(--grit);}

.runtext{display:block;min-width:0;}
.runtext .st{display:block;font-size:13.75px;font-weight:600;line-height:1.3;}
.s-overdue .runtext .st{color:var(--stencil-ink);}
.s-unpaid  .runtext .st{color:var(--brood-ink);}
.s-lifting .runtext .st{color:var(--sack-ink);}
.runtext .sub{display:block;font-size:12.25px;color:var(--ink-3);}

/* the feed line — the thing no khata app can draw */
.feed{margin-top:11px;padding-top:10px;border-top:1px dashed var(--rule);
  display:flex;align-items:center;gap:9px;}
.bar{flex:1 1 auto;height:7px;border-radius:99px;background:var(--sunk);position:relative;overflow:hidden;}
.bar i{position:absolute;inset:0 auto 0 0;background:var(--sack);border-radius:99px;
  transition:width .5s cubic-bezier(.2,.7,.3,1);}
.bar u{position:absolute;top:-3px;bottom:-3px;width:2px;background:var(--ink-2);opacity:.75;}
.feed .fig{flex:0 0 auto;font-size:12.25px;color:var(--ink-3);}
.feed.over .bar i{background:var(--stencil);}
.feed.over .fig{color:var(--stencil-ink);font-weight:600;}

.flag{margin-top:9px;background:var(--stencil-wash);border-radius:var(--r-s);
  padding:8px 10px;display:flex;gap:8px;align-items:flex-start;}
.flag svg{flex:0 0 auto;color:var(--stencil);margin-top:1px;}
.flag p,.flag > span{margin:0;font-size:12.5px;line-height:1.38;color:var(--stencil-ink);}
.flag.note{background:var(--wash-2);}
.flag.note svg{color:var(--sack);}
.flag.note p{color:var(--sack-ink);}

/* ---------- empty ---------- */
.empty{text-align:left;padding:28px 18px;background:var(--sheet);
  border:1px dashed var(--rule-2);border-radius:var(--r-l);}
.empty svg{color:var(--rule-2);margin-bottom:10px;}

/* ---------- entrance ---------- */
.stag > *{opacity:0;transform:translateY(9px);animation:rise .42s cubic-bezier(.2,.75,.3,1) forwards;}
.stag > *:nth-child(1){animation-delay:.02s}
.stag > *:nth-child(2){animation-delay:.06s}
.stag > *:nth-child(3){animation-delay:.10s}
.stag > *:nth-child(4){animation-delay:.14s}
.stag > *:nth-child(5){animation-delay:.18s}
.stag > *:nth-child(6){animation-delay:.22s}
.stag > *:nth-child(n+7){animation-delay:.26s}
@keyframes rise{to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){
  .stag > *{animation:none;opacity:1;transform:none}
  *{transition-duration:.01ms !important}
}

/* ---------- tab bar ---------- */
.tabs{flex:0 0 auto;background:var(--sheet);box-shadow:var(--sh-bar);
  padding:7px 6px calc(var(--safe-b) + 7px);z-index:20;}
.tabs ul{display:flex;}
.tabs li{flex:1;display:flex;}
.tab{flex:1;min-height:48px;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:2px;color:var(--ink-3);border-radius:var(--r-s);}
.tab span{font-size:11px;font-weight:600;}
.tab[aria-current="page"]{color:var(--sack-ink);background:var(--wash-2);}
.tab:active{background:var(--sunk);}

/* ---------- the sheet: a real <dialog> ---------- */
dialog.sheet{
  position:fixed;margin:0;padding:0;border:0;max-width:428px;width:100%;
  left:50%;translate:-50% 0;top:auto;bottom:0;max-height:92dvh;
  background:var(--sheet);color:var(--ink);
  border-radius:var(--r-xl) var(--r-xl) 0 0;box-shadow:var(--sh-sheet);
  display:none;flex-direction:column;overflow:hidden;
}
dialog.sheet[open]{display:flex;}
dialog.sheet::backdrop{background:rgba(15,22,33,.46);backdrop-filter:blur(2px);}
@media (prefers-reduced-motion:no-preference){
  dialog.sheet[open]{animation:up .3s cubic-bezier(.2,.8,.25,1);}
  dialog.sheet[open]::backdrop{animation:fade .2s ease;}
}
@keyframes up{from{transform:translateY(100%)}to{transform:none}}
@keyframes fade{from{opacity:0}to{opacity:1}}
.sheet .grab{width:38px;height:4px;border-radius:99px;background:var(--rule-2);margin:9px auto 2px;flex:0 0 auto;}
.sheet .sh{padding:8px 18px 12px;border-bottom:1px solid var(--rule);flex:0 0 auto;
  display:flex;align-items:flex-start;justify-content:space-between;gap:12px;}
.sheet .sb{overflow-y:auto;padding:14px 18px calc(var(--safe-b) + 16px);}
.x{width:38px;height:38px;border-radius:99px;display:grid;place-items:center;
  background:var(--sunk);color:var(--ink-2);flex:0 0 auto;}

/* ---------- ledger rows ---------- */
.rows{display:block;}
.row{display:flex;gap:11px;padding:10px 0;border-bottom:1px solid var(--rule);align-items:flex-start;}
.row:last-child{border-bottom:0;}
.row .ic{flex:0 0 auto;width:32px;height:32px;border-radius:var(--r-xs);display:grid;
  place-items:center;background:var(--wash-2);color:var(--sack-ink);}
.row .ic.cash{background:var(--grit-wash);color:var(--grit);}
.row .t{flex:1 1 auto;min-width:0;}
.row .t b{display:block;font-size:14.25px;font-weight:600;line-height:1.3;}
.row .t span{display:block;font-size:12.25px;color:var(--ink-3);}
.row .v{flex:0 0 auto;text-align:right;font-size:14.25px;font-weight:600;}
.row .v.cash{color:var(--grit);}

/* ---------- controls ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:48px;
  padding:0 18px;border-radius:var(--r-m);background:var(--sack);color:var(--on-sack);
  font-weight:600;font-size:15.25px;width:100%;box-shadow:var(--sh-s);
  transition:transform .14s,background .14s;}
.btn:active{transform:scale(.985);background:var(--sack-press);}
.btn[disabled]{background:var(--sunk);color:var(--ink-3);box-shadow:none;cursor:default;}
.btn.ghost{background:var(--sheet);color:var(--sack-ink);border:1.5px solid var(--rule-2);box-shadow:none;}
.btn.ghost:active{background:var(--wash-2);}
.why{margin:7px 2px 0;font-size:12.5px;color:var(--ink-3);text-align:center;}

.fld{margin-bottom:13px;}
.fld label{display:block;font-size:12.75px;font-weight:600;color:var(--ink-2);margin-bottom:5px;}
/* The hint goes ABOVE the input, where an autofill popover cannot cover it. */
.fld .hint{display:block;font-size:12px;color:var(--ink-3);margin:-2px 0 5px;}
.fld input,.fld select{width:100%;min-height:48px;padding:0 13px;border-radius:var(--r-s);
  background:var(--sheet-2);border:1.5px solid var(--rule);font-size:16px;}
.fld input:focus,.fld select:focus{border-color:var(--sack);background:var(--sheet);outline:none;}
/* Errors appear only once the field has been left or a submit attempted —
   :invalid alone shouts at a number the dealer is still halfway through
   typing. Never colour alone: the border moves and the message appears. */
.fld .err{display:none;margin:5px 0 0;font-size:12.25px;color:var(--stencil-ink);font-weight:600;}
.fld input:user-invalid{border-color:var(--stencil);background:var(--stencil-wash);}
.fld input:user-invalid ~ .err{display:block;}
.fld input:user-valid{border-color:color-mix(in srgb,var(--grit) 55%,var(--rule));}
.two{display:flex;gap:10px;}.two > *{flex:1;min-width:0;}

.seg{display:flex;gap:6px;background:var(--sunk);padding:4px;border-radius:var(--r-m);margin-bottom:14px;}
.seg button{flex:1;min-height:44px;border-radius:var(--r-s);font-size:13.5px;font-weight:600;color:var(--ink-2);}
.seg button[aria-pressed="true"]{background:var(--sheet);color:var(--sack-ink);box-shadow:var(--sh-s);}

/* ---------- SMS composer ---------- */
.sms textarea{width:100%;min-height:96px;padding:12px 13px;border-radius:var(--r-s);
  background:var(--sheet-2);border:1.5px solid var(--rule);font-size:15.5px;line-height:1.5;resize:vertical;}
.sms textarea:focus{border-color:var(--sack);background:var(--sheet);outline:none;}
.gauge{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:8px;
  padding:9px 11px;border-radius:var(--r-s);background:var(--sheet-2);border:1px solid var(--rule);}
.gauge.two-parts{background:var(--brood-wash);border-color:color-mix(in srgb,var(--brood) 32%,transparent);}
.gauge .c{font-size:12.75px;color:var(--ink-2);}
.gauge.two-parts .c{color:var(--brood-ink);font-weight:600;}
.gauge .k{font-size:12.75px;font-weight:600;}
.tmpl{display:flex;flex-wrap:wrap;gap:7px;margin:11px 0 3px;}
.tmpl button{padding:8px 12px;min-height:44px;border-radius:99px;background:var(--wash-2);
  color:var(--sack-ink);font-size:12.75px;font-weight:600;border:1px solid transparent;}
.tmpl button:active{border-color:var(--sack);}

/* ---------- pill ---------- */
.pill{display:inline-flex;align-items:center;gap:5px;padding:4px 9px;border-radius:99px;
  font-size:11.75px;font-weight:600;background:var(--sunk);color:var(--ink-2);margin-top:8px;}
.pill.overdue{background:var(--stencil-wash);color:var(--stencil-ink);}
.pill.unpaid{background:var(--brood-wash);color:var(--brood-ink);}
.pill.lifting{background:var(--wash);color:var(--sack-ink);}
.pill.settled{background:var(--grit-wash);color:var(--grit);}

/* ---------- toast: its own top layer, no z-index to lose ---------- */
.toast{margin:0;border:0;padding:12px 15px;background:var(--ink);color:var(--poly);
  border-radius:var(--r-m);font-size:13.75px;box-shadow:var(--sh-l);
  position:fixed;left:50%;translate:-50% 0;bottom:calc(var(--safe-b) + 90px);
  width:min(400px,calc(100vw - 28px));inset-inline-end:auto;inset-block-start:auto;
  transition:opacity .22s,translate .22s,overlay .22s allow-discrete,display .22s allow-discrete;
  opacity:0;}
.toast:is(:popover-open,.\:popover-open,.open){opacity:1;display:block;}
@starting-style{.toast:is(:popover-open,.\:popover-open,.open){opacity:0;translate:-50% 8px;}}
/* Without the Popover API the element is display:none until .open is set. */
.toast:not(:popover-open):not(.open){display:none;}
