:root{
  --leaf:#0B5A3C; --leaf-deep:#063D28; --leaf-tint:#E3F0E7;
  --turmeric:#F0A81C; --turmeric-tint:#FCF1D8;
  --chilli:#D4381C; --chilli-tint:#FBE7E2;

  /* ---- STATUS BADGE PALETTE, one place for the whole app ---------------
     Here rather than in `yard.css` because badges are not the yard's alone:
     the finance registers carry Unpaid, Overdue and Cancelled, and a second
     red defined over there is how two screens come to disagree about what
     "needs attention" looks like. `yard.css` reads these.

     SOLID, AND THE REASON IS THE YARD. It is worked outdoors, and a tinted
     badge measured against the white card it sits on came out at 1.02-1.20:1
     - in sun that is not a badge, it is a slightly warm word. The TEXT was
     never the problem: dark ink on a pale tint reads at 5.0-8.6:1 and always
     passed. What failed is the badge announcing itself.

     Each clears 4.5:1 BOTH ways - the white label against the fill, and the
     fill against the white card - because a badge has to be findable before
     it can be read:

         --st-red     #C2261A   5.86:1
         --st-amber   #96590A   5.63:1
         --st-green   #0F7A46   5.39:1
         --st-blue    #1B5FAF   6.36:1
         --st-purple  #6B2E92   8.64:1
         --st-grey    #5C665F   5.96:1

     #B06A00 was the first amber and is deliberately NOT here: 4.28:1, under
     AA. These labels are ~11px bold, which is normal text by WCAG's measure
     and not large text, so 3:1 does not apply to them.

     There is no dark mode in this application - `base.html` declares no
     `prefers-color-scheme` block and no `data-theme`, and the page is
     `--canvas` #FAF6EE throughout - so one set of figures covers it. If one
     is ever added these need re-measuring against the dark ground.

     COLOUR IS NEVER THE ONLY CARRIER: every badge keeps its word, so glare,
     a monochrome print and a colourblind reader all still get the state. */
  --st-red:#C2261A; --st-amber:#96590A; --st-green:#0F7A46;
  --st-blue:#1B5FAF; --st-purple:#6B2E92; --st-grey:#5C665F;
  --canvas:#FAF6EE; --card:#FFFFFF; --ink:#1E2420; --ink-soft:#5C665F;
  --line:#E6E0D2; --radius:14px;
}
*{margin:0;padding:0;box-sizing:border-box}
html{font-size:18px}
body{font-family:'Public Sans','Noto Sans Kannada','Noto Sans Devanagari','Noto Sans Tamil','Noto Sans Telugu','Noto Sans Malayalam',system-ui,sans-serif;background:var(--canvas);color:var(--ink);line-height:1.5}
a{color:inherit}
.topbar{background:linear-gradient(120deg,var(--leaf-deep),var(--leaf) 70%);color:#fff;padding:0 24px}
/* Gap 28 -> 18 -> 14. The bar carries ten children, so the gaps alone were
   252px of a 1180px row - it was already at its limit before the organisation
   name asked for a share, and 18 bought 90px back for every one of them.
   The Insights chip put it over again: on an FPO Manager's header - the
   busiest in the application - the row came out 1241px against a 1180px
   viewport, so the PAGE scrolled sideways on every screen. 14 buys a further
   36px across the nine gaps, and `.user-chip`'s padding below buys the rest.
   Measured rather than chosen, and the figures are in that comment. */
.topbar-inner{max-width:1180px;margin:0 auto;height:64px;display:flex;align-items:center;gap:14px;position:relative}
.brand{font-family:'Bricolage Grotesque','Noto Sans Kannada','Noto Sans Devanagari','Noto Sans Tamil','Noto Sans Telugu','Noto Sans Malayalam',sans-serif;font-weight:800;font-size:1.35rem;letter-spacing:-.02em;display:flex;align-items:center;gap:10px;text-decoration:none;color:#fff}
.brand-mark{width:30px;height:30px;border-radius:8px;background:var(--turmeric);display:grid;place-items:center;color:var(--leaf-deep);font-size:1rem}
.topbar .spacer{flex:1}
/* ---- instance branding: whose AgriBid this is -------------------------
   Two identities in one bar. `.brand` is the PRODUCT - 1.35rem, weight 800,
   the display face, full white. This is the ORGANISATION the installation is
   registered to, and every value here is deliberately a step down from that:
   smaller, lighter, the body face, slightly translucent. Subordinate by
   construction, so the two can never read as one combined name.

   CENTRED BY BEING THE MIDDLE, rather than placed in the middle. This element
   takes all the space between the brand and the controls - it replaces the
   `.spacer` that used to do that - and centres its own text inside it. Two
   earlier attempts were measured and thrown away, and the numbers are why
   this one is written the way it is:

     absolute centring on the bar   the six chips of an authenticated header
                                    begin at 49% of a 1180px bar, so the bar's
                                    own centre is inside them: overlap of 246px
     a flex spacer either side      the same bar is exactly FULL at 1180px, so
                                    both spacers computed to width 0 and the
                                    name sat 28px from the logo

   Growing into the gap works in both cases because it does not need free
   space to exist first: with room it centres in the room, and with none it
   still occupies the whole middle and its text stays centred in that.

   `min-width:0` is load-bearing. A flex item's automatic minimum size is its
   content, so without it a long name refuses to shrink and pushes the log-out
   control off the end instead of truncating. */
.instance-name{
  flex:1 1 auto;min-width:0;text-align:center;
  font-size:.95rem;font-weight:600;letter-spacing:.01em;
  color:rgba(255,255,255,.9);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* The footer strip, mirroring the topbar: product left, organisation centred.
   Same technique for the same reason - the centre of the footer, not the
   centre of whatever space the brand leaves behind it. */
.footer-brand{
  max-width:1180px;margin:0 auto;padding:34px 24px 0;
  display:flex;align-items:center;position:relative;min-height:34px}
/* The footer CAN take the bar's true centre, and does, because nothing sits
   to its right to collide with - the constraint that pushed the header's name
   into the free space simply is not present here. Same arrangement to the
   eye, arrived at the way each bar allows. */
.footer-brand .instance-name{
  position:absolute;left:50%;transform:translateX(-50%);
  max-width:min(34ch,46%);color:rgba(255,255,255,.82)}

/* Below this the name steps out of the topbar rather than shrinking into
   nonsense. The breakpoint is measured, not chosen: on the busiest header in
   the application - an FPO Manager, six chips - the space left for the name is

       1280px+ : 237px      1200px : 209px      1100px : 109px
       1024px :  33px       960px and under : 0

   so by 1024 it renders "M..." and by 960 it is a sliver. 1100 is the last
   width where it still says something. Nothing is lost below it: the footer
   carries the name at every width, and the footer has room because nothing
   sits to its right. */
@media (max-width:1100px){
  .topbar .instance-name{display:none}
}
@media (max-width:520px){
  .footer-brand{flex-direction:column;align-items:flex-start;gap:8px}
  .footer-brand .instance-name{position:static;transform:none;max-width:100%}
}

/* `flex:none` and `nowrap` decide WHO absorbs a squeeze, and it must not be
   these. A flex item shrinks by default, so once the organisation name joined
   the bar the chips gave up width first and their labels broke onto two lines
   - "FPO identity" and "Log out" over two lines each, measured. The controls
   are the working part of the header; the name is the decoration. It carries
   `min-width:0` and truncates, and they keep their size. */
/* Horizontal padding 14 -> 11, and the inner gap 10 -> 8. `flex:none` (below)
   means a chip never gives width back under pressure, so the only way to fit
   one more of them is to make each one narrower - six chips at 6px each is
   36px, which with the row gap above is the 61px the bar was over by.
   Vertical padding is untouched: these are finger targets on a yard tablet
   and their height is the part that must not move. */
.user-chip{display:flex;align-items:center;gap:8px;flex:none;white-space:nowrap;font-size:.88rem;font-weight:600;background:rgba(255,255,255,.12);padding:7px 11px;border-radius:99px;color:#fff;text-decoration:none}
.user-chip .dot{width:8px;height:8px;border-radius:50%;background:var(--turmeric)}
.wrap{max-width:1180px;margin:0 auto;padding:24px}
h1.page{font-family:'Bricolage Grotesque','Noto Sans Kannada','Noto Sans Devanagari','Noto Sans Tamil','Noto Sans Telugu','Noto Sans Malayalam',sans-serif;font-weight:800;font-size:1.8rem;letter-spacing:-.02em;margin-bottom:18px}
.live-flag{display:inline-flex;align-items:center;gap:7px;background:var(--chilli);color:#fff;font-weight:700;font-size:.72rem;letter-spacing:.06em;padding:4px 10px;border-radius:99px}
.pub-flag{display:inline-flex;background:var(--leaf-tint);color:var(--leaf-deep);font-weight:700;font-size:.72rem;letter-spacing:.06em;padding:4px 10px;border-radius:99px}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:18px}
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:18px 20px}
.card h3{font-family:'Bricolage Grotesque','Noto Sans Kannada','Noto Sans Devanagari','Noto Sans Tamil','Noto Sans Telugu','Noto Sans Malayalam',sans-serif;font-weight:600;font-size:1.08rem;margin:8px 0 4px}
.card .sub{color:var(--ink-soft);font-size:.86rem}
.lot-row{display:flex;justify-content:space-between;align-items:center;padding:10px 0;border-top:1px dashed var(--line);margin-top:10px;text-decoration:none}
.lot-row .p{font-family:'IBM Plex Mono',monospace;font-weight:600}
.btn{display:inline-block;background:var(--chilli);color:#fff;border:none;font-weight:700;font-size:.95rem;padding:10px 18px;border-radius:10px;cursor:pointer;text-decoration:none}
.btn:hover{background:#B92E14}
.btn:focus-visible,.chip:focus-visible{outline:3px solid var(--turmeric);outline-offset:2px}
/* live room */
.room{display:grid;grid-template-columns:1fr 420px;gap:22px;align-items:start}
.lot-title{font-family:'Bricolage Grotesque','Noto Sans Kannada','Noto Sans Devanagari','Noto Sans Tamil','Noto Sans Telugu','Noto Sans Malayalam',sans-serif;font-weight:800;font-size:1.6rem;letter-spacing:-.02em}
.attr{display:inline-block;font-size:.8rem;font-weight:600;padding:5px 11px;border-radius:9px;margin:4px 6px 0 0}
.attr.green{background:var(--leaf-tint);color:var(--leaf-deep)}
.attr.gold{background:var(--turmeric-tint);color:#8A5B06}
.board{background:var(--leaf-deep);color:#fff;border-radius:var(--radius);padding:22px 22px 18px;position:sticky;top:20px}
.board-eyebrow{display:flex;justify-content:space-between;font-size:.75rem;letter-spacing:.08em;text-transform:uppercase;color:rgba(255,255,255,.65);font-weight:600}
.price{font-family:'IBM Plex Mono',monospace;font-weight:700;font-size:2.8rem;margin-top:8px;line-height:1;font-variant-numeric:tabular-nums}
.price .unit{font-size:.95rem;color:rgba(255,255,255,.6);margin-left:6px}
.flash{color:var(--turmeric)}
.board-meta{display:flex;justify-content:space-between;margin-top:12px;padding-top:12px;border-top:1px solid rgba(240,168,28,.35);font-size:.85rem;color:rgba(255,255,255,.85)}
.countdown{margin-top:14px;display:flex;justify-content:space-between;align-items:center;background:rgba(255,255,255,.06);border-radius:12px;padding:11px 15px}
.countdown .time{font-family:'IBM Plex Mono',monospace;font-size:1.4rem;font-weight:700;font-variant-numeric:tabular-nums}
.countdown.warn .time{color:var(--turmeric)}
.delta-dots span{display:inline-block;width:9px;height:9px;border-radius:50%;background:rgba(255,255,255,.22);border:1px solid rgba(255,255,255,.35);margin-left:5px}
.delta-dots span.used{background:var(--turmeric);border-color:var(--turmeric)}
.chips{display:grid;grid-template-columns:repeat(5,1fr);gap:8px;margin-top:10px}
.chip{font-family:'IBM Plex Mono',monospace;font-weight:600;background:rgba(255,255,255,.08);color:#fff;border:1px solid rgba(255,255,255,.18);border-radius:10px;padding:8px 0;cursor:pointer;text-align:center}
.chip.sel{background:var(--turmeric);color:var(--leaf-deep);border-color:var(--turmeric)}
.your-bid{margin-top:12px;display:flex;justify-content:space-between;align-items:baseline;font-size:.9rem;color:rgba(255,255,255,.8)}
.your-bid b{font-family:'IBM Plex Mono',monospace;font-size:1.2rem;color:#fff}
.place-btn{width:100%;margin-top:12px;background:var(--chilli);color:#fff;border:none;font-weight:700;font-size:1rem;padding:14px;border-radius:12px;cursor:pointer}
.place-btn:disabled{opacity:.5;cursor:not-allowed}
.msg{margin-top:10px;font-size:.85rem;text-align:center;min-height:1.2em}
.msg.err{color:#FFB4A4}.msg.ok{color:var(--turmeric)}
.panel{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:18px 20px;margin-top:22px}
.panel h2{font-family:'Bricolage Grotesque','Noto Sans Kannada','Noto Sans Devanagari','Noto Sans Tamil','Noto Sans Telugu','Noto Sans Malayalam',sans-serif;font-weight:600;font-size:1.05rem;margin-bottom:10px}
.history{list-style:none}
.history li{display:flex;gap:14px;padding:9px 2px;border-bottom:1px dashed var(--line);font-size:.9rem}
.history li:last-child{border-bottom:none}
.history .nick{font-weight:700;color:var(--leaf-deep);width:130px}
.history li.you .nick{color:var(--chilli)}
.history .amt{font-family:'IBM Plex Mono',monospace;font-weight:600;margin-left:auto}
.rank-tag{font-size:.7rem;font-weight:700;background:var(--turmeric-tint);color:#8A5B06;padding:1px 7px;border-radius:6px;align-self:center}
.login-card{max-width:400px;margin:60px auto;background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:28px}
.login-card h1{font-family:'Bricolage Grotesque','Noto Sans Kannada','Noto Sans Devanagari','Noto Sans Tamil','Noto Sans Telugu','Noto Sans Malayalam',sans-serif;font-size:1.4rem;margin-bottom:14px}
.login-card p{margin:8px 0}
.login-card input{width:100%;padding:10px 12px;border:1px solid var(--line);border-radius:8px;font:inherit}
.login-card .btn{width:100%;margin-top:14px}
@media(max-width:960px){.room{grid-template-columns:1fr}.board{position:static}}
/* sell wizard */
.stepper{display:flex;gap:8px;margin:6px 0 20px;flex-wrap:wrap}
.step{display:flex;align-items:center;gap:8px;font-size:.85rem;font-weight:600;color:var(--ink-soft);
  background:var(--card);border:1px solid var(--line);border-radius:99px;padding:7px 14px}
.step .n{width:20px;height:20px;border-radius:50%;background:var(--line);display:grid;place-items:center;font-size:.72rem}
.step.on{color:var(--leaf-deep);border-color:var(--leaf)}
.step.on .n{background:var(--turmeric);color:var(--leaf-deep)}
.step.done{color:var(--leaf-deep)}
.step.done .n{background:var(--leaf);color:#fff}
.field{margin-bottom:14px}
.field label{display:block;font-size:.82rem;font-weight:600;margin-bottom:5px}
.field input[type=text],.field input[type=number],.field input[type=datetime-local],
.field select,.field textarea{width:100%;padding:10px 12px;border:1px solid var(--line);
  border-radius:9px;font:inherit;background:#fff}
.field textarea{min-height:70px}
.field .help{font-size:.78rem;color:var(--ink-soft);margin-top:4px}
.errbox{background:var(--chilli-tint);color:var(--chilli);border:1px solid var(--chilli);
  border-radius:10px;padding:10px 14px;margin-bottom:14px;font-weight:600;font-size:.9rem}
.okbox{background:var(--leaf-tint);color:var(--leaf-deep);border:1px solid var(--leaf);
  border-radius:10px;padding:10px 14px;margin-bottom:14px;font-weight:600;font-size:.9rem}
.radio-card{display:flex;gap:12px;align-items:center;background:var(--card);border:1px solid var(--line);
  border-radius:12px;padding:14px 16px;margin-bottom:10px;cursor:pointer}
.radio-card:has(input:checked){border-color:var(--leaf);background:var(--leaf-tint)}
.product-card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  padding:18px 20px;margin-bottom:14px;position:relative}
.product-card h4{font-family:'Bricolage Grotesque','Noto Sans Kannada','Noto Sans Devanagari','Noto Sans Tamil','Noto Sans Telugu','Noto Sans Malayalam',sans-serif;font-size:.98rem;margin-bottom:10px}
.row2{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.row3{display:grid;grid-template-columns:2fr 1fr 1fr;gap:12px}
.row4{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
.ghost-btn{background:none;border:2px dashed var(--line);border-radius:12px;width:100%;
  padding:12px;font:inherit;font-weight:600;color:var(--ink-soft);cursor:pointer}
.ghost-btn:hover{border-color:var(--leaf);color:var(--leaf-deep)}
.rm-btn{position:absolute;top:12px;right:12px;background:var(--chilli-tint);color:var(--chilli);
  border:none;border-radius:8px;padding:4px 10px;font-weight:700;cursor:pointer;font-size:.8rem}
.wiz-actions{display:flex;justify-content:space-between;margin-top:18px}
.btn.secondary{background:var(--card);color:var(--ink);border:1px solid var(--line)}
/* Secondary needs its own hover, or it inherits `.btn:hover`'s dark fill and
   keeps its dark ink — measured at 1.3:1, i.e. unreadable at the moment
   somebody is actually pressing it. Both stylesheets darken `.btn` on hover
   (red here, leaf-deep in yard.css), so the fix belongs beside the rule that
   makes the button light in the first place. */
.btn.secondary:hover{background:var(--leaf-tint);color:var(--ink)}
.table{width:100%;border-collapse:collapse;font-size:.9rem}
.table th{text-align:left;font-size:.75rem;text-transform:uppercase;letter-spacing:.05em;
  color:var(--ink-soft);padding:8px 10px;border-bottom:1px solid var(--line)}
.table td{padding:9px 10px;border-bottom:1px dashed var(--line)}
.thumb-strip{display:flex;gap:8px;margin-top:8px;flex-wrap:wrap}
.thumb-strip img{width:64px;height:64px;object-fit:cover;border-radius:8px;border:1px solid var(--line)}
@media(max-width:760px){.row2,.row3,.row4{grid-template-columns:1fr}}

/* ===== v0.8.2 homepage ===== */
.hero{background:linear-gradient(135deg,var(--leaf-deep) 0%,var(--leaf) 62%,#0E6B47 100%);color:#fff;position:relative;overflow:hidden}
.hero::before{content:"";position:absolute;inset:0;opacity:.07;background:
  repeating-linear-gradient(45deg,#fff 0 1px,transparent 1px 14px),
  repeating-linear-gradient(-45deg,#fff 0 1px,transparent 1px 14px)}
.hero-inner{max-width:1180px;margin:0 auto;padding:52px 24px 46px;display:grid;grid-template-columns:1.25fr .9fr;gap:36px;align-items:center;position:relative}
.hero-eyebrow{display:inline-flex;align-items:center;gap:9px;font-size:.78rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;background:rgba(255,255,255,.12);padding:6px 14px;border-radius:99px;color:var(--turmeric)}
.hero-eyebrow .pulse{width:9px;height:9px;border-radius:50%;background:var(--turmeric);animation:pulse 1.6s ease-out infinite}
@keyframes pulse{0%{box-shadow:0 0 0 0 rgba(240,168,28,.7)}100%{box-shadow:0 0 0 10px rgba(240,168,28,0)}}
.hero h1{font-family:'Bricolage Grotesque','Noto Sans Kannada','Noto Sans Devanagari','Noto Sans Tamil','Noto Sans Telugu','Noto Sans Malayalam',sans-serif;font-weight:800;font-size:clamp(1.9rem,4vw,3.1rem);letter-spacing:-.025em;line-height:1.12;margin:16px 0 12px}
.hero h1 em{font-style:normal;color:var(--turmeric)}
.hero p.lede{font-size:1.06rem;color:rgba(255,255,255,.85);max-width:52ch}
.hero-ctas{display:flex;gap:12px;margin-top:24px;flex-wrap:wrap}
.btn.gold{background:var(--turmeric);color:var(--leaf-deep)}
.btn.gold:hover{background:#DE9A12}
.btn.ghost{background:transparent;border:1.5px solid rgba(255,255,255,.45);color:#fff}
.btn.ghost:hover{background:rgba(255,255,255,.1)}
.hero-board{background:rgba(6,61,40,.75);border:1px solid rgba(255,255,255,.14);backdrop-filter:blur(2px);border-radius:16px;padding:20px 22px;box-shadow:0 18px 44px rgba(0,0,0,.28)}
.hero-board .price{font-size:2.4rem}
.hero-board .lot-name{font-family:'Bricolage Grotesque','Noto Sans Kannada','Noto Sans Devanagari','Noto Sans Tamil','Noto Sans Telugu','Noto Sans Malayalam',sans-serif;font-weight:600;font-size:1.12rem;margin:6px 0 2px}
.hero-board .go{display:block;text-align:center;margin-top:16px;background:var(--chilli);color:#fff;font-weight:700;padding:10px;border-radius:10px;text-decoration:none}
.hero-board .go:hover{background:#B92E14}

/* ticker */
.ticker-wrap{background:var(--leaf-deep);border-top:1px solid rgba(255,255,255,.12);color:#fff;overflow:hidden;position:relative}
.ticker-inner{max-width:1180px;margin:0 auto;padding:0 24px;position:relative;overflow:hidden}
.ticker-label{position:absolute;left:0;top:0;bottom:0;display:flex;align-items:center;gap:8px;background:var(--turmeric);color:var(--leaf-deep);font-weight:800;font-size:.72rem;letter-spacing:.08em;text-transform:uppercase;padding:0 16px;z-index:2}
.ticker{display:flex;gap:0;white-space:nowrap;animation:tick 38s linear infinite;padding:11px 0;will-change:transform}
.ticker:hover{animation-play-state:paused}
.ticker .t{display:inline-flex;align-items:baseline;gap:8px;padding:0 26px;border-right:1px solid rgba(255,255,255,.14);font-size:.9rem}
.ticker .t .amt{font-family:'IBM Plex Mono',monospace;font-weight:700;color:var(--turmeric)}
@keyframes tick{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@media (prefers-reduced-motion: reduce){.ticker{animation:none;overflow-x:auto}.hero-eyebrow .pulse{animation:none}}

/* stats strip */
.stats{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin:26px 0 8px}
.stat{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:16px 18px;display:flex;flex-direction:column;gap:2px}
.stat b{font-family:'IBM Plex Mono',monospace;font-size:1.5rem;font-weight:700;color:var(--leaf-deep)}
.stat span{font-size:.8rem;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-soft)}

/* richer auction cards */
.card .commodity-row{display:flex;align-items:center;gap:12px;margin-top:10px}
.tile{width:44px;height:44px;border-radius:12px;background:var(--leaf-tint);color:var(--leaf-deep);display:grid;place-items:center;font-family:'Bricolage Grotesque','Noto Sans Kannada','Noto Sans Devanagari','Noto Sans Tamil','Noto Sans Telugu','Noto Sans Malayalam',sans-serif;font-weight:800;font-size:1.15rem;flex:none;overflow:hidden}
.tile img{width:100%;height:100%;object-fit:cover}
.card .meta-line{font-size:.82rem;color:var(--ink-soft);margin-top:8px;display:flex;gap:14px;flex-wrap:wrap}
.card .meta-line b{color:var(--ink)}

/* how it works + trust */
.section-title{font-family:'Bricolage Grotesque','Noto Sans Kannada','Noto Sans Devanagari','Noto Sans Tamil','Noto Sans Telugu','Noto Sans Malayalam',sans-serif;font-weight:800;font-size:1.45rem;letter-spacing:-.02em;margin:40px 0 16px}
.how{display:grid;grid-template-columns:1fr 1fr;gap:18px}
.how .col{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:20px 22px}
.how .col h3{font-family:'Bricolage Grotesque','Noto Sans Kannada','Noto Sans Devanagari','Noto Sans Tamil','Noto Sans Telugu','Noto Sans Malayalam',sans-serif;font-size:1.05rem;margin-bottom:12px;display:flex;align-items:center;gap:10px}
.how .col h3 .chip-ic{width:30px;height:30px;border-radius:9px;display:grid;place-items:center;font-size:.95rem}
.how .col.buyers h3 .chip-ic{background:var(--turmeric-tint)}
.how .col.sellers h3 .chip-ic{background:var(--leaf-tint)}
.how ol{list-style:none;display:flex;flex-direction:column;gap:10px}
.how li{display:flex;gap:12px;align-items:flex-start;font-size:.93rem}
.how li .n{flex:none;width:22px;height:22px;border-radius:50%;background:var(--leaf-deep);color:#fff;font-size:.72rem;font-weight:700;display:grid;place-items:center;margin-top:2px}
.trust{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-top:18px}
.trust .t{background:var(--leaf-deep);color:#fff;border-radius:var(--radius);padding:18px 20px}
.trust .t h4{font-family:'Bricolage Grotesque','Noto Sans Kannada','Noto Sans Devanagari','Noto Sans Tamil','Noto Sans Telugu','Noto Sans Malayalam',sans-serif;font-size:.98rem;margin-bottom:5px;color:var(--turmeric)}
.trust .t p{font-size:.85rem;color:rgba(255,255,255,.82)}

/* footer */
.footer{background:var(--leaf-deep);color:rgba(255,255,255,.85);margin-top:56px}
/* Top padding is now the `.footer-brand` strip's job - the brand moved up
   there so it could sit opposite a centred organisation name. */
.footer-inner{max-width:1180px;margin:0 auto;padding:16px 24px 26px;display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:28px}
.footer .brand{font-size:1.15rem}
.footer p{font-size:.88rem;max-width:38ch}
.footer h5{font-size:.75rem;letter-spacing:.09em;text-transform:uppercase;color:var(--turmeric);margin-bottom:10px}
.footer ul{list-style:none;display:flex;flex-direction:column;gap:7px;font-size:.9rem}
.footer a{text-decoration:none;color:rgba(255,255,255,.85)}
.footer a:hover{color:#fff;text-decoration:underline}
.footer .fine{border-top:1px solid rgba(255,255,255,.14);margin-top:6px}
.footer .fine div{max-width:1180px;margin:0 auto;padding:14px 24px;font-size:.78rem;color:rgba(255,255,255,.55);display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap}

/* empty state */
.empty{background:var(--card);border:1.5px dashed var(--line);border-radius:var(--radius);padding:44px 24px;text-align:center;max-width:560px;margin:26px auto}
.empty .ic{width:58px;height:58px;border-radius:16px;background:var(--turmeric-tint);display:grid;place-items:center;font-size:1.5rem;margin:0 auto 14px}
.empty h3{font-family:'Bricolage Grotesque','Noto Sans Kannada','Noto Sans Devanagari','Noto Sans Tamil','Noto Sans Telugu','Noto Sans Malayalam',sans-serif;font-size:1.15rem;margin-bottom:6px}
.empty p{color:var(--ink-soft);font-size:.92rem;margin-bottom:18px}

@media (max-width:880px){
  .hero-inner{grid-template-columns:1fr;padding:38px 20px}
  .stats,.how,.trust{grid-template-columns:1fr}
  .footer-inner{grid-template-columns:1fr}
}

/* v0.8.4 back links */
.back-link{display:inline-flex;align-items:center;gap:6px;font-size:.88rem;font-weight:600;color:var(--leaf-deep);text-decoration:none;margin-bottom:14px;padding:6px 12px;border:1px solid var(--line);border-radius:99px;background:var(--card)}
.back-link:hover{background:var(--leaf-tint)}
.board .back-link,.hero .back-link{background:rgba(255,255,255,.1);border-color:rgba(255,255,255,.25);color:#fff}

/* staff breadcrumb - mirrors yard.css's .crumbs, for pages outside the
   yard visual language (finance, review/membership, the registers) that
   still need in-app back navigation without pointing at the marketplace */
.crumbs{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:.82rem;margin-bottom:14px;color:var(--ink-soft)}
.crumbs a{color:var(--ink-soft);text-decoration:none;font-weight:500}
.crumbs a:hover{color:var(--leaf-deep);text-decoration:underline}
.crumbs .sep{opacity:.45}
.crumbs .here{color:var(--ink);font-weight:700}
.crumbs .plain{color:var(--ink-soft);font-weight:500}

/* v0.9.1 profile */
.profile-head{background:linear-gradient(135deg,var(--leaf-deep),var(--leaf));color:#fff;border-radius:var(--radius);padding:24px 26px;display:flex;align-items:center;gap:18px;flex-wrap:wrap}
.avatar{width:62px;height:62px;border-radius:18px;background:var(--turmeric);color:var(--leaf-deep);display:grid;place-items:center;font-family:'Bricolage Grotesque',sans-serif;font-weight:800;font-size:1.7rem;flex:none}
.profile-head h1{font-family:'Bricolage Grotesque','Noto Sans Kannada','Noto Sans Devanagari','Noto Sans Tamil','Noto Sans Telugu','Noto Sans Malayalam',sans-serif;font-size:1.5rem;font-weight:800;letter-spacing:-.02em}
.profile-head .ph{font-family:'IBM Plex Mono',monospace;font-size:.9rem;color:rgba(255,255,255,.75);margin-top:2px}
.role-chips{display:flex;gap:7px;flex-wrap:wrap;margin-top:9px}
.role-chip{background:rgba(255,255,255,.15);border:1px solid rgba(255,255,255,.25);color:#fff;font-size:.72rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;padding:4px 11px;border-radius:99px}
.role-chip.gold{background:var(--turmeric);color:var(--leaf-deep);border-color:transparent}
.profile-grid{display:grid;grid-template-columns:1.35fr .95fr;gap:18px;margin-top:18px}
.pcard{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:20px 22px}
.pcard h3{font-family:'Bricolage Grotesque','Noto Sans Kannada','Noto Sans Devanagari','Noto Sans Tamil','Noto Sans Telugu','Noto Sans Malayalam',sans-serif;font-size:1.05rem;margin-bottom:4px}
.pcard .hint{font-size:.83rem;color:var(--ink-soft);margin-bottom:14px}
.kv{display:flex;justify-content:space-between;gap:12px;padding:9px 0;border-bottom:1px dashed var(--line);font-size:.92rem}
.kv:last-child{border-bottom:none}
.kv span:first-child{color:var(--ink-soft)}
.kv b{font-weight:600}
.mini-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:4px}
.mini-stat{background:var(--leaf-tint);border-radius:12px;padding:12px;text-align:center}
.mini-stat b{display:block;font-family:'IBM Plex Mono',monospace;font-size:1.35rem;color:var(--leaf-deep)}
.mini-stat span{font-size:.72rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--ink-soft)}
.kyc{display:inline-flex;align-items:center;gap:6px;font-size:.75rem;font-weight:700;padding:3px 10px;border-radius:99px}
.kyc.yes{background:var(--leaf-tint);color:var(--leaf-deep)}
.kyc.no{background:var(--turmeric-tint);color:#8A5B06}
.org-row{display:flex;justify-content:space-between;align-items:center;gap:10px;padding:11px 0;border-bottom:1px dashed var(--line)}
.org-row:last-child{border-bottom:none}
@media (max-width:880px){.profile-grid{grid-template-columns:1fr}}

/* ===== v1.0 finance & MIS ===== */
.fin-nav{display:flex;gap:6px;flex-wrap:wrap;margin:14px 0 18px;padding-bottom:12px;border-bottom:1px solid var(--line)}
.fin-nav a{font-size:.86rem;font-weight:600;color:var(--ink-soft);text-decoration:none;padding:7px 13px;border-radius:99px;border:1px solid transparent}
.fin-nav a:hover{background:var(--leaf-tint);color:var(--leaf-deep)}
.fin-nav a.on{background:var(--leaf-deep);color:#fff}
.kpi-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:12px}
.kpi{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:15px 17px}
.kpi .lbl{font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-soft)}
.kpi .val{font-family:'IBM Plex Mono',monospace;font-size:1.5rem;font-weight:700;color:var(--leaf-deep);margin-top:5px;line-height:1.1}
.kpi .sub2{font-size:.78rem;color:var(--ink-soft);margin-top:3px}
.kpi.gold{background:linear-gradient(135deg,#FFF8E7,#FFF1CC);border-color:#F3DFA8}
.kpi.gold .val{color:#8A5B06}
.kpi.chilli .val{color:var(--chilli)}
.kpi.deep{background:var(--leaf-deep);border-color:transparent}
.kpi.deep .lbl{color:rgba(255,255,255,.6)}
.kpi.deep .val{color:var(--turmeric)}
.kpi.deep .sub2{color:rgba(255,255,255,.7)}
.filters{display:flex;gap:10px;align-items:flex-end;flex-wrap:wrap;background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:14px 16px;margin-bottom:16px}
.filters .f{display:flex;flex-direction:column;gap:4px}
.filters label{font-size:.74rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-soft)}
.filters input,.filters select{padding:8px 10px;border:1px solid var(--line);border-radius:8px;font:inherit;font-size:.9rem}
.rep-table{width:100%;border-collapse:collapse;background:var(--card);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;font-size:.9rem}
.rep-table th{background:var(--leaf-tint);color:var(--leaf-deep);text-align:left;font-size:.74rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;padding:11px 12px;white-space:nowrap}
.rep-table td{padding:11px 12px;border-top:1px solid var(--line);vertical-align:top}
.rep-table tr:hover td{background:#FCFAF5}
.rep-table .num{text-align:right;font-family:'IBM Plex Mono',monospace;white-space:nowrap}
.rep-table tfoot td{background:var(--leaf-deep);color:#fff;font-weight:700;border-top:2px solid var(--leaf)}
.rep-table tfoot .num{color:var(--turmeric)}
.rep-table .muted{color:var(--ink-soft);font-size:.84rem}
.rep-table-narrow{width:auto;max-width:760px}
.rep-table thead{display:table-header-group}
/* full-width grouping row introducing one transaction/record within an
   otherwise flat table - e.g. one journal entry's account/party/debit/
   credit lines. Kept in the existing palette: canvas tint + a top rule,
   not a new colour. page-break-inside:avoid keeps the heading from being
   orphaned at the bottom of a printed page, separate from its lines. */
.rep-table .entry-row td{background:var(--canvas);border-top:2px solid var(--line);padding:9px 12px;page-break-inside:avoid}
.rep-table .entry-row:first-child td{border-top:none}
.entry-kind{font-weight:700;color:var(--leaf-deep);font-size:.88rem}
.entry-when{font-size:.78rem;color:var(--ink-soft);margin-left:10px}
.entry-ref{font-family:'IBM Plex Mono',monospace;font-size:.78rem;color:var(--ink-soft);margin-left:10px}
.entry-narration{font-size:.84rem;color:var(--ink-soft);margin-top:2px}
.pill{display:inline-block;font-size:.7rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;padding:3px 9px;border-radius:99px}
.pill.paid{background:var(--leaf-tint);color:var(--leaf-deep)}
/* Was #D4381C on #FBE7E2 - 4.02:1, UNDER AA, and nothing to do with
   sunlight: it was simply too pale a red on too pale a pink. Solid now, which
   fixes the ratio and puts it in the same family the yard uses for a state
   somebody has to act on. */
.pill.unpaid{background:var(--st-red);color:#fff}
.pill.part{background:var(--turmeric-tint);color:#8A5B06}
.pill.due{background:var(--turmeric-tint);color:#8A5B06}
.pill.hold{background:#EEE;color:#666}
/* Already solid and already passing at 4.79:1; moved onto the shared red so
   Overdue and Unpaid cannot drift apart, which lifts it to 5.86:1. */
.pill.od{background:var(--st-red);color:#fff}
.ageing{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-bottom:16px}
.ageing .b{background:var(--card);border:1px solid var(--line);border-left:4px solid var(--leaf);border-radius:10px;padding:12px 14px}
.ageing .b:nth-child(2){border-left-color:var(--turmeric)}
.ageing .b:nth-child(3){border-left-color:#E07A1F}
.ageing .b:nth-child(4){border-left-color:var(--chilli)}
.ageing .b .lbl{font-size:.72rem;font-weight:700;text-transform:uppercase;color:var(--ink-soft)}
.ageing .b .val{font-family:'IBM Plex Mono',monospace;font-size:1.2rem;font-weight:700;margin-top:3px}
.doc{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:26px 28px;max-width:820px}
.doc-head{display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap;border-bottom:2px solid var(--leaf-deep);padding-bottom:16px;margin-bottom:18px}
.doc-head h1{font-family:'Bricolage Grotesque',sans-serif;font-size:1.5rem;font-weight:800}
.doc-meta{font-size:.86rem;color:var(--ink-soft);line-height:1.7}
.doc-meta b{color:var(--ink)}
.doc-total{background:var(--leaf-tint);border-radius:10px;padding:14px 16px;margin-top:16px}
.doc-total .row{display:flex;justify-content:space-between;padding:5px 0;font-size:.92rem}
.doc-total .row.big{border-top:1px solid var(--leaf);margin-top:6px;padding-top:10px;font-size:1.1rem;font-weight:700;color:var(--leaf-deep)}
.trend{display:flex;align-items:flex-end;gap:6px;height:120px;padding:12px 0}
.trend .bar{flex:1;background:linear-gradient(180deg,var(--leaf),var(--leaf-deep));border-radius:5px 5px 0 0;min-height:3px;position:relative}
.trend .bar span{position:absolute;bottom:-20px;left:0;right:0;text-align:center;font-size:.66rem;color:var(--ink-soft);white-space:nowrap}
.balanced{display:inline-flex;align-items:center;gap:6px;font-size:.8rem;font-weight:700;padding:5px 12px;border-radius:99px}
.balanced.ok{background:var(--leaf-tint);color:var(--leaf-deep)}
.balanced.bad{background:var(--chilli);color:#fff}
@media print{.topbar,.footer,.fin-nav,.filters,.back-link,.crumbs,.no-print{display:none!important}
  .doc{border:none;padding:0;max-width:100%}body{background:#fff}}
@media (max-width:880px){.ageing{grid-template-columns:repeat(2,1fr)}
  .rep-table{font-size:.82rem}.rep-table th,.rep-table td{padding:8px 7px}}
/* Ticker: keep the track from starting mid-item */
.ticker-wrap{align-items:center}
.ticker{
  padding-left:0;
  animation:tick 60s linear infinite;
}
.ticker .t:first-child{padding-left:26px}
/* ---------------------------------------------------------------- toasts --
   Transient confirmation for any screen, raised by AgriBid.toast() or by an
   HX-Trigger header on a fragment response. Deliberately site-wide rather
   than a yard component: a toast is a toast whether it confirms a farmer
   registered, a payout released or a document printed.

   Upper right, above everything, and never in the way of the pointer - the
   stack itself does not take clicks, only the toasts inside it do, so a
   control underneath an expired toast is never dead. */
.toast-stack{
  position:fixed;top:16px;right:16px;z-index:1000;
  display:flex;flex-direction:column;gap:8px;
  max-width:min(380px,calc(100vw - 32px));pointer-events:none
}
/* Empty for almost the whole life of every page, and an empty box should not
   be in the layout at all. Found by the tablet harness, which measures every
   element against the viewport and correctly reported a zero-width container
   sitting on the right edge - the toast itself was fine (measured x=667..784
   inside an 800px viewport), but a guard that catches real overflow is worth
   more than an exception carved out of it. */
.toast-stack:empty{display:none}
.toast{
  pointer-events:auto;display:flex;align-items:flex-start;gap:9px;
  padding:11px 13px;border-radius:10px;font-size:.9rem;font-weight:500;
  background:#fff;border:1px solid var(--line);
  box-shadow:0 6px 20px rgba(28,24,16,.14);
  opacity:1;transform:translateY(0);transition:opacity .25s,transform .25s
}
.toast.leaving{opacity:0;transform:translateY(-6px)}
.toast-i{font-weight:700;line-height:1.35}
.toast-x{
  margin-left:auto;background:none;border:none;cursor:pointer;
  font:inherit;font-size:1.05rem;line-height:1;color:inherit;opacity:.55;
  padding:0 2px
}
.toast-x:hover{opacity:1}
.toast.success{background:#e8f3ec;border-color:#c3e0ce;color:#0B5A3C}
.toast.warning{background:#fdf3dd;border-color:#f2ddab;color:#8a5d00}
.toast.error{background:#fbe6e1;border-color:#f3c6bb;color:#9c2a12}

@media (prefers-reduced-motion:reduce){
  .toast{transition:none}
}

/* ------------------------------------------------- data-entry forms (.dform)
   The forms an FPO Manager fills in - Variety today, the Farmer and Buyer
   registers next - share one shape: a single column of fields, most of them
   carrying a line of explanation. Written as bare `<p><label>…</label><input>`
   the label, the control and the explanation all render at the same weight,
   the browser lays them out inline, and the form reads as prose rather than as
   something to fill in.

   This is the `.field` block above with the three things it did not have: a
   rhythm the whole form keeps, a way to separate groups of fields without
   drawing a box round each of them, and a tidy set for a run of checkboxes.
   It is scoped under `.dform` rather than folded into `.field` itself so that
   the sell wizard and the profile screens, which use `.field` on their own,
   do not move.

   To adopt it on another form: put `class="dform"` on the <form>, wrap each
   field in `<div class="field">` with its <label> first and its explanation
   last as `<span class="hint">`, group the fields in `<div class="fgroup">`,
   put a run of checkboxes in `<div class="optset">`, and put the buttons in
   `<div class="dform-actions">`. No other markup changes are needed.

   NOTE ON ORDER: `.dform .hint` and `.pcard .hint` have the same specificity,
   so this block must stay AFTER `.pcard` in this file. A hint under a control
   needs a top margin, not the bottom margin a `.pcard` intro paragraph wants. */

.dform .field{margin-bottom:18px}
.dform .field:last-child{margin-bottom:0}
.dform .field>label{
  display:block;font-size:.82rem;font-weight:600;color:var(--ink);
  letter-spacing:.01em;margin-bottom:6px}
.dform input[type=text],.dform input[type=tel],.dform input[type=email],
.dform input[type=number],.dform input[type=date],.dform select,
.dform textarea{
  width:100%;padding:10px 12px;border:1px solid var(--line);border-radius:9px;
  font:inherit;font-size:.95rem;background:#fff;color:var(--ink)}
/* One height for every control on the row, whatever kind it is. Measured
   before fixing: a text input came out 48px (line-height 1.5 of a 17.1px
   font), a `<select>` 44px because it inherits `line-height:normal`, and a
   date input 50px because of the calendar button it draws inside itself. Three
   heights in one row of four fields is the difference between a form that
   looks built and one that looks typed. */
.dform input[type=text],.dform input[type=tel],.dform input[type=email],
.dform input[type=number],.dform input[type=date],.dform select{
  height:48px;line-height:1.5}
.dform textarea{min-height:70px}
.dform input:focus,.dform select:focus,.dform textarea:focus{
  outline:2px solid var(--leaf);outline-offset:-1px}
.dform input:disabled,.dform select:disabled{
  background:#F4F1E8;color:var(--ink-soft);cursor:not-allowed}

/* Help text: kept in full, and kept out of the way. Subordinate to its field
   by size, colour and weight, and measured so a long explanation does not run
   the width of a wide screen. */
.dform .hint{
  display:block;font-size:.79rem;font-weight:400;line-height:1.45;
  color:var(--ink-soft);margin:6px 0 0;max-width:62ch}
.dform .field>.hint:not(:last-child){margin:2px 0 8px}

/* Groups: whitespace and one hairline, never a box - a box round a pair of
   fields reads as a second card inside the card. */
.dform .fgroup+.fgroup{
  margin-top:26px;padding-top:24px;border-top:1px solid var(--line)}
.dform-actions{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin-top:24px;padding-top:20px;border-top:1px solid var(--line)}

/* A run of checkboxes as an aligned set rather than a wrapping line of them.
   Each one stays a real <label> wrapping its own <input>, so the whole target
   is clickable and nothing about what posts changes. */
.dform .optset{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(112px,1fr));
  gap:8px;margin-top:4px}
.dform .optset label,.dform .field>label.checkfield{
  display:flex;align-items:center;gap:9px;margin:0;
  font-size:.88rem;font-weight:500;line-height:1.35;color:var(--ink);
  background:#fff;border:1px solid var(--line);border-radius:9px;
  padding:9px 12px;min-height:42px;cursor:pointer}
.dform .field>label.checkfield{letter-spacing:0}
.dform .optset label:hover,.dform .field>label.checkfield:hover{
  border-color:var(--leaf)}
.dform .optset label:has(input:checked),
.dform .field>label.checkfield:has(input:checked){
  border-color:var(--leaf);background:var(--leaf-tint);color:var(--leaf-deep);
  font-weight:600}
.dform .optset label:focus-within,
.dform .field>label.checkfield:focus-within{
  outline:3px solid var(--turmeric);outline-offset:2px}
.dform .optset input[type=checkbox],.dform .checkfield input[type=checkbox],
.dform .optset input[type=radio]{
  flex:none;width:16px;height:16px;accent-color:var(--leaf);cursor:pointer}

/* A single-choice set - the buyer application's "nature of candidature".
   Deliberately `.optset` with radios in it rather than a second component:
   the card, the hover, the checked state and the focus ring above are already
   written and already correct, and `:has(input:checked)` does not care which
   control type is inside. Only two things differ, and both are about the
   labels being longer than a unit code.

   `.wide` gives them a column that fits, so "Organisation / institution" does
   not wrap to two lines beside "Company". Below 380px it drops to one column
   rather than squeezing two - a card an inch wide is not a target. */
.dform .optset.wide{
  grid-template-columns:repeat(auto-fit,minmax(184px,1fr));
  /* Every card the same height, including across rows. Without this a grid
     row is only as tall as its own contents, so a label that wraps to two
     lines makes ITS row 63px and leaves the row above at 42 - measured in the
     browser at 1280 and at 480, where the ragged row was a different one each
     time. `1fr` on the implicit rows makes the tallest decide for all of
     them, which is what "a clean grid" has to mean when the labels are
     sentences rather than unit codes. */
  grid-auto-rows:1fr}
@media (max-width:380px){
  .dform .optset.wide{grid-template-columns:1fr}
}

/* A fact the form states rather than asks for - today the FPO a location is
   filed under. Deliberately NOT a disabled input: a disabled control still
   looks like a control, and this is not one the operator is being denied, it
   is something that was never theirs to choose. So it reads as text, sitting
   on the same baseline grid as the fields around it. */
.dform .readonly-value{
  padding:10px 0;font-size:.95rem;font-weight:600;color:var(--ink)}
.dform .readonly-value .none{font-weight:400;color:var(--ink-soft)}

/* Short fields side by side, using the `.row2`/`.row3`/`.row4` helpers already
   in this file - which already collapse to one column below 760px, so this
   costs no new responsive behaviour. The rhythm has to be handed up to the
   row, or the fields inside it keep their own 18px and the row adds its gap
   on top. */
.dform .row2 .field,.dform .row3 .field,.dform .row4 .field{margin-bottom:0}
.dform .row2,.dform .row3,.dform .row4{margin-bottom:18px}
.dform .row2:last-child,.dform .row3:last-child,
.dform .row4:last-child{margin-bottom:0}

/* The tablet step the shared helpers never had: they went straight from four
   columns to one at 760px, so a 1024px tablet got four fields squeezed to
   ~190px each. Two columns in between.

   BOUNDED at the low end, and that is not decoration. Written as a plain
   `max-width:1000px` it also matched every width below 760, and being more
   specific (0,2,0 against the shared helper's 0,1,0) it BEAT the one-column
   rule there - so a phone got two columns and 271px of horizontal scroll.
   Measured, not theorised.

   Scoped under `.dform` deliberately. `.row2`/`.row3`/`.row4` are also used by
   the profile screen and the phase-2 sell wizard, and this is a data-entry
   refinement rather than a change to every grid in the application. */
@media (min-width:761px) and (max-width:1000px){
  .dform .row3,.dform .row4{grid-template-columns:repeat(2,1fr)}
}

/* Section headings inside a form. The `.fgroup` note above says groups carry
   whitespace and a hairline and NOT a heading, and that stands for a form of
   six fields where a heading is decoration. An application form is the case
   it does not cover: it is long, it is filled in once by somebody who has
   never seen it, and knowing that the next eight fields are all optional
   registration details is the difference between finishing and abandoning.
   Sized well below the card's own title so it groups rather than competes. */
.dform .fgroup-title{
  font-size:.76rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--ink-soft);margin:0 0 14px}
.dform .fgroup-title .n{color:var(--leaf);margin-right:7px}

/* The one marker on the form, and it is on two fields. Coloured and given a
   label of its own so it is not a decorative asterisk somebody has to guess
   the meaning of. */
.dform .req{color:var(--chilli);font-weight:700;margin-left:2px}

/* ===== a disabled .btn has to look disabled =====================
   `.btn` is the only button class on every screen off base.html, and until
   now nothing here said anything about `:disabled` - so a control the server
   had deliberately turned off was painted in full chilli, kept
   `cursor:pointer`, and DARKENED ON HOVER via `.btn:hover`. A manager met a
   button that looked live, pressed it, and the browser silently swallowed the
   click (a disabled control fires no event and submits no form): "nothing
   happens", with the refusal invisible. Reported off the password-reset queue;
   the master-data list's Deactivate control had it too.

   Placed at the end of the file on purpose. `.btn.secondary:hover` and
   `.btn.gold:hover` are (0,3,0) selectors, so `.btn:disabled` at (0,2,0)
   would lose to them on a disabled secondary button; the `:disabled:hover`
   pair matches their weight and wins on source order from here. Moving this
   block above them puts the hover fill back on a dead control. */
.btn:disabled,.btn:disabled:hover,
.btn[aria-disabled=true],.btn[aria-disabled=true]:hover{
  background:var(--line);color:var(--ink-soft);border-color:var(--line);
  cursor:not-allowed;box-shadow:none}

/* -------------------------------------------------- financial year ------- */
/* The period a finance screen is reporting on, under its heading. Quiet by
   design: it is a statement of scope, not a control - the control is the
   selector in the filter row above it. */
.fy-span {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  margin: -6px 0 14px; font-size: .9rem; color: var(--ink-soft);
}
.fy-span b { font-size: .95rem; color: var(--leaf-deep); font-weight: 700; }
.fy-span .fy-narrowed {
  font-size: .74rem; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: #8a5d00;
  background: #fdf3dd; border-radius: 99px; padding: 2px 9px;
}

/* ------------------------------------------------ master-data filters ---- */
/* Compact by intention: this is a control strip above a table, not a panel.
   The brief's own note - "avoid making the filter area excessively large" -
   is the requirement, and a card with one field per row is what breaks it. */
.md-filter {
  background: #fff; border: 1px solid var(--line); border-radius: 12px;
  padding: 13px 15px 15px; margin-bottom: 14px;
}
.md-filter h2 {
  font-size: .72rem; font-weight: 800; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-soft); margin: 0 0 10px;
}
.md-filter-row {
  display: flex; gap: 14px; align-items: flex-end; flex-wrap: wrap;
}
.md-f { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.md-f label {
  font-size: .76rem; font-weight: 700; color: var(--ink);
}
.md-f select, .md-f input {
  height: 38px; padding: 0 10px; font: inherit; font-size: .88rem;
  border: 1px solid var(--line); border-radius: 9px; background: #fff;
  color: var(--ink); min-width: 210px;
}
.md-f select:focus, .md-f input:focus {
  outline: 2px solid var(--leaf); outline-offset: -1px;
}
.md-f-actions { flex-direction: row; align-items: center; gap: 8px; }

.md-count { font-size: .86rem; color: var(--ink-soft); margin: 0 0 9px; }
.md-count-in { color: var(--leaf-deep); font-weight: 600; }

/* Navigation, not an action - so it is a link and never a button. The
   commodity screen summarises varieties and does not maintain them. */
.md-nav {
  font-size: .84rem; font-weight: 600; color: var(--leaf-deep);
  text-decoration: none; white-space: nowrap;
}
.md-nav:hover { text-decoration: underline; }

@media (max-width: 700px) {
  .md-filter-row { flex-direction: column; align-items: stretch; }
  .md-f select, .md-f input { min-width: 0; width: 100%; }
}

/* ==================================== the seller settlement register ======
   A financial register rather than an HTML table. Written as reusable
   components because Buyer Dues, Commission and the Ledger are the same
   shape and will want them next - nothing below names this one screen.

   REUSE, deliberately, rather than a second design system beside the first:

     the filter card   `.md-filter` + `.md-f`, already built for the
                       master-data screens and already responsive. It gained
                       a head row here and nothing else.
     the summary       `.kpi` in a compact modifier. A settlement summary sits
                       above a table and must not read as a dashboard tile.
     the empty state   `.empty`, untouched.
     the numbers       `.num`'s mono face and right alignment, the convention
                       `.rep-table` set.

   What is genuinely new is `.reg`: a table too wide for a laptop that has to
   stay readable rather than be shrunk to fit. It scrolls inside its own box,
   its head stays put, and the seller column stays put with it - so the name
   a row is about is never scrolled away from the money explaining it. */

/* --------------------------------------------------------- page header --- */
/* The title leads and the period is subordinate to it - a step down in size,
   weight and colour, and onto its own line at narrow widths rather than
   competing for the first one. */
.page-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 18px 24px; flex-wrap: wrap; margin-bottom: 16px;
}
.page-head h1 { margin-bottom: 2px; }
.page-head .page-sub {
  font-size: .92rem; color: var(--ink-soft); max-width: 52ch;
}
.period-badge {
  background: var(--leaf-tint); border: 1px solid #CFE3D6;
  border-radius: 12px; padding: 9px 14px; min-width: 210px;
}
/* The badge holds `finance/_fy_heading.html` rather than restating it. That
   partial is the one place the period is worded, and the "narrowed within
   the year" caveat with it - copying its markup here to get a different
   shape would have put the same sentence in two templates, which is how one
   screen comes to caveat a narrowed range and its neighbour does not. Only
   the arrangement is overridden: stacked here, inline everywhere else. */
.period-badge .fy-span {
  display: block; margin: 0; font-size: .8rem; line-height: 1.35;
}
.period-badge .fy-span b { display: block; font-size: .95rem; }
.period-badge .fy-span span { display: block; }
.period-badge .fy-span .fy-narrowed { display: inline-block; margin-top: 6px; }

/* ------------------------------------------------------- filter card ----- */
/* `.md-filter` supplies the box, the title and the field row. All this adds
   is a head that can carry an action on the right - an export is a different
   kind of thing from a filter and must not sit in the same row as Apply, or
   it competes with the control the operator actually came to press. */
.md-filter-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-bottom: 10px;
}
.md-filter-head h2 { margin: 0; }
.md-f-hint {
  font-size: .74rem; color: var(--ink-soft); font-weight: 500; margin-top: 3px;
}
/* Lets a shared partial that nests its control inside its own `<label>` -
   `finance/_fy_filter.html` does - sit in this row without being rewritten
   to match. The label text stacks above the control exactly as a sibling
   pair would. */
.md-f > label { display: flex; flex-direction: column; gap: 5px; }
/* The search narrows the list under it, so the two are one control in two
   parts and are boxed as one. Apart, they read as unrelated fields that
   happen to sit together - which is what the raw select/input pair did. */
.md-f-pair {
  display: flex; flex-direction: column; gap: 6px;
  border: 1px dashed var(--line); border-radius: 10px; padding: 9px 10px;
  background: #FCFAF5;
}
.md-f-pair > label { font-size: .76rem; font-weight: 700; color: var(--ink); }
/* `.md-filter-row` bottom-aligns, which is right when every field is one
   control tall. A composite is three, so bottom-alignment pushed the plain
   fields down and left a band of empty card above them. Opt-in, so the
   master-data screens - which have no composite - keep the alignment they
   were designed with. The actions drop by a label's height so they line up
   with the controls rather than with the labels. */
.md-filter-row.has-group { align-items: flex-start; }
.md-filter-row.has-group .md-f-actions { margin-top: 22px; }

/* A green primary, matching the yard's own convention where `.btn` is
   already leaf rather than chilli. `:not(:disabled)` on the hover is not
   decoration: `.btn:disabled:hover` sits at the end of this file at (0,3,0),
   and a bare `.btn.leaf:hover` would tie it and, being later, win - which is
   the ordering trap this stylesheet has already been bitten by twice. */
.btn.leaf { background: var(--leaf-deep); color: #fff; }
.btn.leaf:not(:disabled):hover { background: var(--leaf); }

/* --------------------------------------------------- applied filters ----- */
/* What the figures below actually represent, in words. The filter card says
   what WILL be applied; this says what WAS. */
.applied {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 0 0 16px; font-size: .84rem;
}
.applied .ap-lbl {
  font-size: .72rem; font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-soft);
}
.applied .ap {
  background: var(--card); border: 1px solid var(--line); border-radius: 99px;
  padding: 4px 12px; color: var(--ink);
}
.applied .ap b { font-weight: 700; color: var(--leaf-deep); }

/* -------------------------------------------------------- summary row ---- */
/* `.kpi` at about two thirds scale. A summary strip above a register is
   orientation, not the headline of the screen - the register is. */
/* 132px was enough while these screens ran the full width of the window.
   Inside the shared 1180px container it is not: a figure like
   `Rs 28,760.00` at 1.08rem mono needs about 130px of its own, so the
   track clipped it. Measured - three figures on the settlement strip
   came back `clipped: true`. The cards wrap to a second row instead,
   which is what a responsive grid is for. */
.kpi-grid.compact {
  grid-template-columns: repeat(auto-fit, minmax(152px, 1fr)); gap: 10px;
}
.kpi-grid.compact .kpi { padding: 11px 13px; }
.kpi-grid.compact .kpi .lbl { font-size: .66rem; letter-spacing: .05em; }
.kpi-grid.compact .kpi .val { font-size: 1.08rem; margin-top: 3px; }
.kpi-grid.compact .kpi .val .cur { font-size: .8em; opacity: .65; margin-right: 1px; }

/* ------------------------------------------------------ the register ----- */
.reg-note {
  font-size: .78rem; color: var(--ink-soft); margin: 18px 0 7px;
  display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap;
}
/* The scroll box. `max-height` is what makes a sticky head worth having; both
   axes are handled by this one container, so there is no second scrolling
   element to get out of step with it. */
.reg-scroll {
  overflow: auto; max-height: 70vh;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius);
}
/* `separate` rather than `collapse`: a collapsed border is painted by the
   table and not by the cell, so it does not travel with a sticky header and
   the head comes away from its own underline as soon as the body scrolls. */
.reg { width: 100%; border-collapse: separate; border-spacing: 0; font-size: .88rem; }
.reg th, .reg td { padding: 10px 14px; text-align: left; white-space: nowrap; }
/* `th` as well as `td`: the seller cell is a row header, so the row's rule
   has to be drawn on both or it stops short of the sticky column. */
.reg tbody td, .reg tbody th { border-top: 1px solid var(--line); vertical-align: middle; }

/* Two header rows. The group row is given a fixed height so the second row's
   offset is a number rather than a guess - sticky needs one, and a header
   that overlaps itself by three pixels is worse than no sticky header. */
.reg thead th { position: sticky; z-index: 2; background: var(--leaf-tint); }
.reg .reg-groups th {
  top: 0; height: 30px; padding: 5px 14px;
  font-size: .67rem; font-weight: 800; letter-spacing: .09em;
  text-transform: uppercase; color: var(--leaf);
  background: #D6E8DC; border-bottom: 1px solid #C3DBCB;
}
.reg .reg-groups th + th { border-left: 1px solid #C3DBCB; }
.reg .reg-cols th {
  top: 30px;
  font-size: .71rem; font-weight: 800; letter-spacing: .04em;
  text-transform: uppercase; color: var(--leaf-deep);
  border-bottom: 1px solid #C3DBCB;
}

/* The seller column stays while the money scrolls. It is the only column
   that says what a row is about, so scrolling away from it turns the
   register into a grid of unattributed numbers. */
.reg .reg-seller {
  position: sticky; left: 0; z-index: 1;
  background: var(--card); border-right: 1px solid var(--line);
  white-space: normal; min-width: 190px;
}
.reg thead .reg-seller { z-index: 3; }
.reg .reg-groups .reg-seller { background: #D6E8DC; }
.reg .reg-cols .reg-seller { background: var(--leaf-tint); }
.reg tbody tr:hover td { background: #FCFAF5; }
.reg tbody tr:hover .reg-seller { background: #F7F3EA; }

/* The name is the row; the phone is how you confirm it is the right one. */
.reg .s-name { font-weight: 700; color: var(--ink); line-height: 1.25; }
/* `font-weight` is not decoration here. The seller cell is a `<th>`, so
   everything in it inherits the UA's bold and the phone came out at 700 -
   the same weight as the name it is meant to sit under. Caught in the
   browser; nothing server-side could see it. */
.reg .s-phone {
  font-family: 'IBM Plex Mono', monospace; font-size: .78rem;
  font-weight: 500; color: var(--ink-soft); margin-top: 1px;
}
/* Room for the seller ledger this will grow into. Text today, because no
   per-seller staff view exists yet - see the template. */
.reg .s-name a { color: var(--leaf-deep); text-decoration: none; }
.reg .s-name a:hover { text-decoration: underline; }

.reg .num {
  text-align: right; font-family: 'IBM Plex Mono', monospace;
  font-variant-numeric: tabular-nums;
}
/* A count is not money and should not be read as an amount. */
.reg .cnt {
  text-align: right; font-family: 'IBM Plex Mono', monospace;
  color: var(--ink-soft);
}
/* Colour is never the only carrier here: every column is named, and a
   negative prints its own minus sign. These only let a zero recede and a
   figure that is owed stand out. */
.reg .zero { color: #A8AFA9; }
.reg .neg { color: var(--chilli); }
.reg .money-key { font-weight: 700; color: var(--leaf-deep); }
.reg .money-due { color: var(--chilli); font-weight: 700; }
.reg .money-hold { color: #8a5d00; font-weight: 700; }

/* The total is a different kind of row and is built to look like one. */
.reg tfoot th, .reg tfoot td {
  background: var(--leaf-deep); color: #fff; font-weight: 700;
  border-top: 2px solid var(--leaf);
}
.reg tfoot .reg-seller { background: var(--leaf-deep); border-right-color: var(--leaf); }
.reg tfoot .t-lbl { font-size: .72rem; letter-spacing: .07em; text-transform: uppercase; }
.reg tfoot .t-sub { font-size: .74rem; font-weight: 500; color: rgba(255,255,255,.7); }
.reg tfoot .num { color: var(--turmeric); }
.reg tfoot .zero, .reg tfoot .neg,
.reg tfoot .money-key, .reg tfoot .money-due, .reg tfoot .money-hold { color: var(--turmeric); }

@media (max-width: 760px) {
  .page-head { flex-direction: column; }
  .period-badge { min-width: 0; width: 100%; }
  .reg-scroll { max-height: none; }
  .reg .reg-seller { position: static; }
  .reg .reg-cols th { top: 0; }
}
@media print {
  .reg-scroll { max-height: none; overflow: visible; border: none; }
  .reg thead th, .reg .reg-seller { position: static; }
  .applied, .md-filter { display: none !important; }
}

/* ------------------------------- the rest of the finance module ----------
   Buyer Dues, Commission, Invoices and Payouts adopt the register the Farmer
   Settlement screen introduced. Almost nothing new was needed, which is the
   point of having built it as components: `.page-head`, `.period-badge`,
   `.md-filter`, `.kpi-grid.compact`, `.reg`, `.applied` and `.empty` are
   reused unchanged. What follows is only what those four screens do that
   Farmer Settlement does not - carry links, status pills and row actions
   inside the register. */

/* `.btn.small` was used by `payout_list.html` and DEFINED NOWHERE - so every
   "Pay" and "Print voucher" control rendered at full size in a table cell.
   Defined here rather than on the page that revealed it, because the yard
   stylesheet has its own and the two should agree. */
.btn.small { font-size: .82rem; padding: 6px 12px; border-radius: 8px; }

/* A record the row is about, reached from the register. Not a `.btn`: it is
   navigation to the document, not an action on it. */
.reg .lnk {
  color: var(--leaf-deep); font-weight: 700; text-decoration: none;
  font-family: 'IBM Plex Mono', monospace; font-size: .84rem;
}
.reg .lnk:hover { text-decoration: underline; }

/* A cell of controls. The hold/release pair is a POST form and the pay link
   is not, so without this they sit on different baselines with the form's
   own line box between them. */
.reg .row-actions {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
}
.reg .row-actions form { display: contents; }

/* Status pills already exist (`.pill.paid/.unpaid/.part/.due/.hold/.od`) and
   are reused as they are. Only the cancelled state had no rule - it is not a
   warning and not a success, so it recedes rather than colouring. */
/* Was #6B7269 on #ECEAE3 - 4.12:1, under AA. Darkened to the shared grey,
   which reads 4.95:1 on the same ground. NOT made solid: cancelled is an
   inert state rather than one to act on, and a register of cancelled
   invoices in solid grey would shout louder than the live rows above it. */
.pill.cancelled { background: #ECEAE3; color: var(--st-grey); }
.reg td .pill { vertical-align: middle; }

/* The ageing strip on Buyer Dues. `.kpi` would overstate it - these are one
   figure each with no heading hierarchy, and they sit UNDER the summary as a
   breakdown of a single card on it. */
.age-strip {
  display: flex; gap: 0; flex-wrap: wrap; margin: 0 0 4px;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--card); overflow: hidden;
}
.age-cell {
  flex: 1 1 120px; padding: 9px 14px; min-width: 0;
  border-right: 1px solid var(--line);
}
.age-cell:last-child { border-right: none; }
.age-cell .age-lbl {
  display: block; font-size: .66rem; font-weight: 800; letter-spacing: .05em;
  text-transform: uppercase; color: var(--ink-soft);
}
.age-cell .age-val {
  display: block; font-family: 'IBM Plex Mono', monospace;
  font-size: .95rem; font-weight: 700; color: var(--ink); margin-top: 2px;
}
/* Anything actually overdue is the one thing on this strip worth colouring. */
.age-cell.od .age-val { color: var(--chilli); }

/* Pagination under a register, matching the register rather than the browser
   defaults it had. */
.reg-pager {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-top: 14px; font-size: .86rem;
  color: var(--ink-soft);
}
.reg-pager a {
  color: var(--leaf-deep); font-weight: 600; text-decoration: none;
  border: 1px solid var(--line); border-radius: 8px; padding: 6px 12px;
  background: var(--card);
}
.reg-pager a:hover { background: var(--leaf-tint); }
.reg-pager .pg-where { font-weight: 600; color: var(--ink); }

/* A serial column is an index, not a figure - it must not read as money. */
.reg .sl {
  text-align: right; font-family: 'IBM Plex Mono', monospace;
  color: var(--ink-soft); font-size: .82rem;
}
/* A date is neither. Left, plain, and quieter than the money beside it. */
.reg .dt { font-size: .84rem; color: var(--ink); white-space: nowrap; }
.reg .dt .dt-sub { display: block; font-size: .76rem; color: var(--ink-soft); }

/* A checkbox is not a text control and must not be given a control's box.
   It sits on the same baseline grid as the fields beside it, so the row does
   not develop a step where one filter happens to be a toggle. */
/* `.md-f > label` above sets `flex-direction: column` so a partial that
   nests its control inside its own label stacks correctly. That rule is
   (0,2,0) and this one is (0,1,0), so without matching its weight the
   checkbox stacked ABOVE its own text with the box centred between them -
   which is exactly what the first render of Buyer Dues did. */
.md-f > label.md-f-check,
.md-f-check {
  display: flex; flex-direction: row; align-items: center; gap: 8px;
  height: 38px; font-size: .88rem; font-weight: 500; color: var(--ink);
  white-space: nowrap;
}
/* `min-width: 0` is the load-bearing one. `.md-f input` sets a 210px floor -
   right for a name or a date, and it applies to a CHECKBOX too. `min-width`
   beats `width`, so the box rendered 210px wide with the glyph centred in it
   and its label stranded a hundred pixels away. Setting `width` alone does
   not fix it; the floor has to be lifted. Height likewise: 38px on a
   checkbox makes it a tall empty column. */
.md-f-check input {
  width: 17px; height: 17px; min-width: 0; padding: 0;
  accent-color: var(--leaf-deep);
}

.md-f-date input, .md-f-date select { min-width: 158px; }

/* ============================================ payments & collections ======
   Two counters: money in from a buyer, money out to a farmer. Built from the
   finance register's own components - `.md-filter` for the search, `.reg` for
   the invoice and lot tables, `.empty` for a miss - so these read as part of
   the module rather than as a new corner of it. What follows is only what a
   counter does that a report does not: identify a person, and stop before
   writing. */

/* The party result card. Deliberately NOT a table: a search result is one
   person to recognise, not a row to compare against its neighbours. */
.party-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 18px; }
.party {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 13px 16px;
}
.party-who { flex: 1 1 220px; min-width: 0; }
.party .s-name { font-weight: 700; color: var(--ink); }
.party .s-phone {
  font-family: 'IBM Plex Mono', monospace; font-size: .82rem;
  font-weight: 500; color: var(--ink-soft);
}
.party-meta { font-size: .8rem; color: var(--ink-soft); margin-top: 2px; }
.party-amt { display: flex; flex-direction: column; gap: 3px; align-items: flex-end; }
.party-amt .lbl {
  font-size: .66rem; font-weight: 800; letter-spacing: .05em;
  text-transform: uppercase; color: var(--ink-soft);
}
.party-amt .num { font-family: 'IBM Plex Mono', monospace; font-weight: 700; }
/* The party already chosen. A tinted band rather than another white card, so
   "who this payment is for" cannot be mistaken for one more search result. */
.party.selected { background: var(--leaf-tint); border-color: #CFE3D6; }
.party.selected .lbl {
  font-size: .66rem; font-weight: 800; letter-spacing: .05em;
  text-transform: uppercase; color: var(--leaf);
}

.pay-switch { display: flex; gap: 8px; flex-wrap: wrap; }
.pay-search input { min-width: 340px; }
.pay-wide input { min-width: 320px; }
.pay-form .md-filter-head h2 { margin: 0; }
.pay-out { font-size: .82rem; color: var(--ink-soft); }
.pay-out b { font-family: 'IBM Plex Mono', monospace; color: var(--leaf-deep); }
.pay-amt {
  height: 38px; padding: 0 10px; font: inherit; font-size: .88rem;
  font-family: 'IBM Plex Mono', monospace; text-align: right;
  border: 1px solid var(--line); border-radius: 9px; background: #fff;
  width: 130px; min-width: 0;
}
.pay-amt:focus { outline: 2px solid var(--leaf); outline-offset: -1px; }
.reg tr.is-selected td, .reg tr.is-selected .reg-seller { background: var(--leaf-tint); }

/* ------------------------------------------------------- the confirmation */
/* The last screen before money is recorded, and the ONLY thing on it. A
   confirmation shown beside the form it came from invites confirming the
   wrong one, so the template renders this instead of the form rather than
   under it. */
.confirm-card {
  background: var(--card); border: 1.5px solid var(--leaf);
  border-radius: var(--radius); padding: 22px 24px;
  max-width: 620px; margin: 0 0 20px;
}
.confirm-card h2 {
  font-family: 'Bricolage Grotesque', sans-serif; font-size: 1.1rem;
  color: var(--leaf-deep); margin: 0 0 16px;
}
.confirm-kv { display: grid; grid-template-columns: auto 1fr; gap: 9px 20px; margin: 0 0 20px; }
.confirm-kv dt {
  font-size: .72rem; font-weight: 800; letter-spacing: .05em;
  text-transform: uppercase; color: var(--ink-soft); padding-top: 2px;
}
.confirm-kv dd { margin: 0; font-size: .95rem; color: var(--ink); }
.confirm-kv dd.num { font-family: 'IBM Plex Mono', monospace; }
/* The figure the whole screen exists to have read. */
.confirm-kv dd.strong {
  font-size: 1.25rem; font-weight: 700; color: var(--leaf-deep);
}
.confirm-kv .ck-sub {
  display: block; font-family: 'IBM Plex Mono', monospace;
  font-size: .8rem; color: var(--ink-soft);
}
.confirm-actions { display: flex; gap: 10px; align-items: center; }

@media (max-width: 700px) {
  .pay-search input, .pay-wide input { min-width: 0; width: 100%; }
  .party { align-items: flex-start; }
  .confirm-kv { grid-template-columns: 1fr; gap: 3px 0; }
  .confirm-kv dd { margin-bottom: 9px; }
}

/* `hidden` must actually hide. `.md-f` sets `display: flex`, and an author
   rule beats the UA stylesheet's `[hidden] { display: none }` - so the
   mode-specific fields stayed on screen and Cash asked for a cheque number.
   Caught in the browser; the attribute was being set correctly all along.
   (0,2,0) here against `.md-f`'s (0,1,0), so it wins wherever it sits. */
.md-f[hidden] { display: none; }

/* ---------------------------------------------- a panel that flows -------
   `.reg-scroll` caps itself at 70vh so a long REGISTER scrolls under its own
   sticky head. That is right for a report you read and wrong for a counter
   you act on: every row on the payment screens carries a control, and a
   panel that scrolls internally puts buttons where an operator has no reason
   to look. Measured before it was changed - twelve invoices in a 900px
   window left the last row 233px below the bottom of its own box.

   Only the cap is lifted. `overflow-x` stays, because a wide table must
   still scroll sideways rather than squeeze; `overflow-y` computes to `auto`
   with it - the two axes cannot be set apart once one leaves `visible` - but
   with no cap the box is exactly as tall as its rows, so there is nothing to
   scroll and no scrollbar is drawn. The page scrolls instead.

   A modifier rather than a change to `.reg-scroll`, so the finance registers
   keep the behaviour they were designed with. */
.reg-scroll.reg-flow { max-height: none; }

/* THE ACTUAL COVERING ELEMENT, and it was not the height cap.
   `.reg thead th` is `position: sticky` with `top: 30px` - written so the
   settlement register's column row sits below its 30px group row while the
   body scrolls under it. On a counter there is no group row, and once
   `.reg-flow` removed the height cap the panel stopped having scrollable
   overflow of its own - so the header began sticking against the PAGE
   instead, and covered row one at z-index 2/3 as soon as the page scrolled.
   Measured across four widths and every scroll position: 56 hits, all of
   them `th` at `position: sticky`.

   Sticky is not needed here at all now, so the vertical half goes. The
   HORIZONTAL half stays on the first column: a wide table still scrolls
   sideways, and the head has to travel with the body column or the two come
   apart. `top: auto` is what switches sticky off in one axis only. */
.reg-scroll.reg-flow .reg thead th,
.reg-scroll.reg-flow .reg .reg-groups th,
.reg-scroll.reg-flow .reg .reg-cols th { position: static; top: auto; }
.reg-scroll.reg-flow .reg thead th.reg-seller {
  position: sticky; left: 0; top: auto; z-index: 2;
}

/* ------------------------------------------------------- error pages -----
   The friendly refusal, the miss and the failure. Built from `.empty`'s
   shape - a centred card on the page ground - because an error page is an
   empty state with a reason, and inventing a second look for it would make
   the one screen somebody meets on a bad day the one that feels foreign. */
.errcard {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 44px 32px; text-align: center;
  max-width: 560px; margin: 56px auto;
}
.errcard .err-ic {
  width: 58px; height: 58px; border-radius: 16px; background: var(--leaf-tint);
  display: grid; place-items: center; font-size: 1.5rem; margin: 0 auto 16px;
}
.errcard h1 {
  font-family: 'Bricolage Grotesque', 'Noto Sans Kannada', 'Noto Sans Tamil',
               sans-serif;
  font-size: 1.35rem; font-weight: 800; letter-spacing: -.01em;
  color: var(--leaf-deep); margin: 0 0 10px;
}
.errcard p {
  color: var(--ink-soft); font-size: .95rem; line-height: 1.6;
  margin: 0 auto 22px; max-width: 44ch;
}
.err-actions {
  display: flex; gap: 10px; justify-content: center; flex-wrap: wrap;
}

/* ------------------------------------------------------ day summary ------
   Today's yard, session by session. Cards rather than a table: an operator
   is reading one session at a time to see where it has got to, not comparing
   a column down a list. */
.period-badge .pb-day {
  display: block; font-size: 1rem; font-weight: 800; color: var(--leaf-deep);
}
.period-badge .pb-when {
  display: block; font-size: .78rem; color: var(--ink-soft); margin-top: 2px;
}
.period-badge .pb-refresh { margin-top: 8px; }

.sess-grid {
  display: grid; gap: 14px; margin-top: 4px;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}
.sess-card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 16px 18px;
  display: flex; flex-direction: column; gap: 12px;
}
.sess-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 12px;
}
.sess-head h2 {
  font-family: 'Bricolage Grotesque', sans-serif; font-size: 1.05rem;
  font-weight: 800; color: var(--leaf-deep); margin: 0;
}
.sess-sub { font-size: .84rem; color: var(--ink-soft); margin-top: 2px; }
.sess-mkt {
  font-family: 'IBM Plex Mono', monospace; font-size: .76rem;
  margin-left: 6px; color: #8A8578;
}
.sess-figs {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px 14px; margin: 0;
}
.sess-figs div { display: flex; justify-content: space-between; gap: 8px; }
.sess-figs .wide { grid-column: 1 / -1; border-top: 1px dashed var(--line);
                   padding-top: 8px; }
.sess-figs dt {
  font-size: .72rem; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--ink-soft);
}
.sess-figs dd {
  margin: 0; font-family: 'IBM Plex Mono', monospace; font-weight: 700;
  color: var(--ink);
}
.sess-figs dd.money { color: var(--leaf-deep); }

/* The operational stages. Colour is never the only carrier - each stage is
   named, and the colour repeats what the worksheet already shows. */
.sess-stages { display: flex; gap: 6px; flex-wrap: wrap; }
.sess-stages .stg {
  font-size: .7rem; font-weight: 700; padding: 4px 9px; border-radius: 99px;
  background: #F2EFE7; color: #6B7269;
}
.sess-stages .stg.green { background: var(--leaf-tint); color: var(--leaf-deep); }
.sess-stages .stg.yellow { background: var(--turmeric-tint); color: #8A5B06; }
.sess-stages .stg.red { background: var(--chilli-tint); color: var(--chilli); }
.sess-stages .stg.grey { background: #F2EFE7; color: #8A8578; }

.sess-open { align-self: flex-start; margin-top: 2px; }
.kpi-grid.compact .kpi .val .mixed {
  font-size: .8rem; font-weight: 700; color: var(--ink-soft);
}

/* -------------------------------------------------- market settings ------
   A read-only statement of terms with an edit mode, built from `.pcard` and
   the `.kv` row shape the profile screens already use. */
.ms-wrap { max-width: 720px; }
.ms-form section.pcard { margin-bottom: 14px; }
.ms-form section.pcard h3 { margin-bottom: 10px; }
.ms-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; padding: 9px 0; border-bottom: 1px dashed var(--line);
  min-height: 40px;
}
.ms-row:last-child { border-bottom: none; }
.ms-lbl { font-size: .9rem; color: var(--ink-soft); }
.ms-val { font-family: 'IBM Plex Mono', monospace; font-weight: 700;
          color: var(--ink); }
.ms-in { display: flex; align-items: center; gap: 6px; position: relative; }
.ms-in input {
  height: 36px; width: 120px; padding: 0 10px; text-align: right;
  font: inherit; font-family: 'IBM Plex Mono', monospace; font-size: .9rem;
  border: 1px solid var(--line); border-radius: 9px; background: #fff;
}
.ms-in input:focus { outline: 2px solid var(--leaf); outline-offset: -1px; }
.ms-unit { font-size: .85rem; color: var(--ink-soft); font-weight: 700; }
/* Beside the field it belongs to, which is where somebody looks for it. */
.ms-err {
  position: absolute; top: 100%; right: 0; margin-top: 3px;
  font-size: .76rem; color: var(--chilli); white-space: nowrap;
}
.ms-in:has(.ms-err) { margin-bottom: 16px; }
.ms-note { font-size: .82rem; color: var(--ink-soft); margin-top: 8px; }
.ms-warn {
  background: #FDF3DD; border: 1px solid #F2DDAB; border-radius: var(--radius);
  padding: 13px 16px; margin-bottom: 14px; font-size: .88rem;
  color: #6b5320; line-height: 1.55;
}
.ms-warn b { display: block; color: #8a5d00; margin-bottom: 3px; }
.ms-actions { display: flex; gap: 10px; margin-top: 4px; }

/* ============================================== data visualisation ========
   Built from the finance register's own components - `.kpi` for totals,
   `.md-filter` for the period, `.empty` for a quiet period - so the page is
   part of the module rather than a second dashboard style. What is new is
   the horizontal bar list, which is deliberately CSS rather than a charting
   library: this project renders its charts as markup and carries no
   frontend framework. */
.vz-panel {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 18px 20px; margin-bottom: 16px;
}
.vz-title {
  font-family: 'Bricolage Grotesque', sans-serif; font-size: 1.05rem;
  font-weight: 800; color: var(--leaf-deep); margin: 0 0 14px;
}
.vz-sub {
  font-size: .74rem; font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-soft); margin: 18px 0 10px;
}
.vz-panel .kpi-grid { margin-bottom: 6px; }

/* The bar list. A row per category, the label reading at full size. */
.vz-bars { display: flex; flex-direction: column; gap: 7px; }
.vz-row { display: flex; align-items: center; gap: 12px; }
.vz-label {
  flex: 0 0 150px; font-size: .84rem; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  text-align: right;
}
.vz-label a { color: var(--leaf-deep); text-decoration: none; font-weight: 600; }
.vz-label a:hover { text-decoration: underline; }
.vz-track {
  flex: 1 1 auto; display: flex; align-items: center; gap: 8px; min-width: 0;
}
.vz-bar {
  height: 16px; border-radius: 0 3px 3px 0; background: var(--leaf);
  min-width: 2px; flex: 0 0 auto;
}
.vz-bar.sales { background: var(--leaf); }
.vz-bar.coll { background: var(--turmeric); }
/* Two bars stacked in one row, for a paired comparison per period. */
.vz-pair { flex-wrap: wrap; }
.vz-pair .vz-bar { flex-basis: 100%; }
.vz-val {
  font-family: 'IBM Plex Mono', monospace; font-size: .78rem;
  color: var(--ink); white-space: nowrap;
}
.vz-legend {
  display: flex; gap: 18px; font-size: .8rem; color: var(--ink-soft);
  margin-bottom: 10px;
}
.vz-legend i {
  width: 11px; height: 11px; border-radius: 3px; display: inline-block;
  margin-right: 6px;
}
.vz-legend .i-sales { background: var(--leaf); }
.vz-legend .i-coll { background: var(--turmeric); }

.vz-qty { display: flex; gap: 26px; flex-wrap: wrap; margin: 10px 0 4px; }
.vz-qty .lbl {
  display: block; font-size: .68rem; font-weight: 800; letter-spacing: .05em;
  text-transform: uppercase; color: var(--ink-soft);
}
.vz-qty b { font-family: 'IBM Plex Mono', monospace; font-size: 1rem; }
.vz-split { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
.vz-none { font-size: .85rem; color: var(--ink-soft); }
.vz-total { margin-top: 12px; font-size: .88rem; color: var(--ink-soft); }
.vz-total b { font-family: 'IBM Plex Mono', monospace; color: var(--leaf-deep); }

@media (max-width: 760px) {
  .vz-split { grid-template-columns: 1fr; }
  .vz-label { flex-basis: 96px; font-size: .78rem; }
  .vz-val { font-size: .72rem; }
}

/* ---- workflow navigation: `_pagenav.html` + `_leaveguard.html` ---------
   ONE VISUAL TREATMENT FOR THE WHOLE APPLICATION, which is most of the point
   of having a component at all. Back sits left and Forward right in every
   section, so the control an operator reaches for is in the same place on a
   finance register as on a yard screen.

   `justify-content:space-between` over two always-present halves rather than
   over the links themselves: with only one control the flex box would centre
   it, and a lone "Continue" drifting to the middle of the bar on some screens
   and sitting right on others is exactly the inconsistency this replaces. The
   empty half holds its side of the row.

   Sized as finger targets (44px) because these are the primary navigation on
   a yard tablet, and `flex-wrap` plus `min-width:0` is what keeps them on the
   screen at 360px instead of pushing the page sideways. */
.pagenav{
  display:flex;justify-content:space-between;align-items:center;gap:12px;
  flex-wrap:wrap;margin:26px 0 4px;padding-top:18px;
  border-top:1px solid var(--line)}
.pagenav-back,.pagenav-next{display:flex;min-width:0}
.pagenav-next{justify-content:flex-end}
.pnav{
  display:inline-flex;align-items:center;gap:9px;min-height:44px;
  padding:9px 16px;border-radius:10px;text-decoration:none;
  background:var(--card);border:1px solid var(--line);
  color:var(--ink);font-weight:600;font-size:.93rem}
.pnav:hover{border-color:var(--leaf);color:var(--leaf-deep)}
.pnav:focus-visible{outline:3px solid var(--turmeric);outline-offset:2px}
/* Forward is the leading action where it exists, so it is the filled one -
   the same weight `.btn.leaf` carries elsewhere. Back is always secondary:
   returning is available everywhere and should never compete with the step
   the operator is being invited to take. */
.pnav.fwd{background:var(--leaf-deep);border-color:var(--leaf-deep);color:#fff}
.pnav.fwd:hover{background:var(--leaf);border-color:var(--leaf);color:#fff}
.pnav-ar{font-size:1.05rem;line-height:1;opacity:.8}
.pnav-lb{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
@media (max-width:520px){
  /* Each control takes its own row rather than shrinking its label to an
     ellipsis - "Continue to..." is not a destination anybody can read. */
  .pagenav{flex-direction:column;align-items:stretch}
  .pagenav-next{justify-content:stretch}
  .pnav{justify-content:center}
}
@media print{.pagenav,.leaveguard{display:none!important}}

/* The unsaved-work question. A dialog rather than a banner because it is
   asked in response to an action and needs an answer before that action
   happens - a banner would let the navigation through underneath it. */
.leaveguard{
  position:fixed;inset:0;z-index:60;display:grid;place-items:center;
  background:rgba(30,36,32,.45);padding:20px}
.leaveguard[hidden]{display:none}
.lg-card{
  background:var(--card);border:1px solid var(--line);border-radius:14px;
  padding:26px 26px 20px;max-width:430px;width:100%;
  box-shadow:0 18px 50px rgba(0,0,0,.22)}
.lg-card h2{
  font-family:'Bricolage Grotesque',sans-serif;font-weight:800;
  font-size:1.15rem;color:var(--leaf-deep);margin:0 0 8px}
.lg-card p{color:var(--ink-soft);font-size:.94rem;line-height:1.6;margin:0 0 20px}
.lg-acts{display:flex;gap:10px;justify-content:flex-end;flex-wrap:wrap}

/* ---- "what happens now", after an action ------------------------------
   A panel rather than a toast. A toast is right for "that worked" and wrong
   for "here are the three things you might do about it" - it disappears on a
   timer, and the operator is left holding a receipt number with nowhere to
   take it. Anything that names destinations has to stay on the page. */
.donecard{
  display:flex;align-items:center;gap:16px;flex-wrap:wrap;
  background:var(--leaf-tint);border:1px solid var(--leaf);
  border-radius:14px;padding:16px 20px;margin:0 0 20px}
.done-ic{
  width:38px;height:38px;border-radius:50%;flex:none;
  background:var(--leaf-deep);color:#fff;display:grid;place-items:center;
  font-size:1.1rem;font-weight:700}
.done-txt{flex:1 1 220px;min-width:0}
.done-txt h2{
  font-family:'Bricolage Grotesque',sans-serif;font-weight:800;
  font-size:1.05rem;color:var(--leaf-deep);margin:0 0 2px}
.done-txt p{margin:0;color:var(--ink-soft);font-size:.9rem}
.done-acts{display:flex;gap:8px;flex-wrap:wrap}
.done-acts .btn{font-size:.88rem;padding:9px 14px}
@media print{.donecard{display:none!important}}

/* ---- Journal / Ledger: category tabs and the journal register ----------
   THE TABS ARE A SECOND LEVEL BELOW `.fin-nav`, and are drawn to read that
   way. `.fin-nav` is the module's own navigation - pills, and the active one
   a solid dark-green lozenge. Repeating that treatment here would put two
   rows of identical pills on the page and leave the operator working out
   which of the two "current" markers they were looking at. So these are
   underlined tabs: the same dark green, spent on a 3px rule and the label's
   weight rather than on a filled background. */
.ltabs { margin: 0 0 14px; }
/* The strip scrolls sideways rather than wrapping or cramping. Eight
   categories do not fit a phone, and a wrapped second row would sit directly
   under the chips row below it and read as one confused block. */
.ltabs-strip {
  display: flex; gap: 2px; overflow-x: auto; scrollbar-width: thin;
  border-bottom: 2px solid var(--line);
}
.ltab {
  display: inline-flex; align-items: center; gap: 8px; flex: none;
  padding: 11px 15px 10px; text-decoration: none;
  font-size: .87rem; font-weight: 600; color: var(--ink-soft);
  border-bottom: 3px solid transparent; margin-bottom: -2px;
  white-space: nowrap;
}
.ltab:hover { color: var(--leaf-deep); background: var(--leaf-tint); }
.ltab.on { color: var(--leaf-deep); font-weight: 800;
           border-bottom-color: var(--leaf-deep); }
.ltab:focus-visible { outline: 3px solid var(--turmeric); outline-offset: -3px; }
/* The count is information, not emphasis - it must not compete with the name
   it belongs to, so it is smaller, lighter and set in the mono face that
   every other figure in this module uses. */
.lt-n {
  font-family: 'IBM Plex Mono', monospace; font-size: .74rem; font-weight: 600;
  color: var(--ink-soft); background: var(--line); border-radius: 99px;
  padding: 1px 7px; min-width: 20px; text-align: center;
}
.ltab.on .lt-n { background: var(--leaf-deep); color: #fff; }

/* Second level, for the two categories that have one. Quieter than the tabs
   above by construction: no underline, smaller, and the active one a tint
   rather than a rule - it is a filter inside a category, not a category. */
.lchips { display: flex; gap: 7px; flex-wrap: wrap; margin: 0 0 16px; }
.lchip {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: .8rem; font-weight: 600; color: var(--ink-soft);
  text-decoration: none; padding: 6px 12px; border-radius: 99px;
  border: 1px solid var(--line); background: var(--card);
}
.lchip:hover { border-color: var(--leaf); color: var(--leaf-deep); }
.lchip.on { background: var(--leaf-tint); border-color: var(--leaf);
            color: var(--leaf-deep); font-weight: 700; }
.lchip:focus-visible { outline: 3px solid var(--turmeric); outline-offset: 2px; }
.lc-n { font-family: 'IBM Plex Mono', monospace; font-size: .72rem;
        color: var(--ink-soft); }
.lchip.on .lc-n { color: var(--leaf-deep); }

/* ---- the journal register itself --------------------------------------
   ONE header row, not the two the settlement register has. `.reg .reg-cols
   th` is offset `top:30px` to clear the group row above it; with no group row
   that offset would strand the sticky header 30px down the scroll box. */
.ledger-reg .reg-cols th { top: 0; }

/* The transaction block: what happened, when, and what it was worth. A row
   spanning the table so the narration reads as a sentence - squeezed into a
   column it would be the truncated cell this redesign exists to remove. */
.ledger-reg .jentry > th {
  background: var(--leaf-tint); border-top: 1px solid #C3DBCB;
  border-bottom: 1px solid #C3DBCB; padding: 9px 14px 8px;
  white-space: normal; font-weight: 400;
}
.je-top { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.je-kind {
  font-size: .72rem; font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; color: var(--leaf-deep);
}
.je-when { font-size: .78rem; color: var(--ink-soft); font-weight: 600; }
.je-time { font-family: 'IBM Plex Mono', monospace; font-weight: 500; }
.je-ref {
  font-family: 'IBM Plex Mono', monospace; font-size: .74rem;
  color: var(--leaf); background: var(--card); border: 1px solid #C3DBCB;
  border-radius: 5px; padding: 1px 6px;
}
/* The entry's own total, pushed to the right so it lands over the money
   columns it is the sum of. `JournalEntry.total` - an existing property, not
   a figure this screen works out. */
.je-amt {
  margin-left: auto; font-family: 'IBM Plex Mono', monospace;
  font-size: .92rem; font-weight: 700; color: var(--leaf-deep);
}
.je-narr {
  font-size: .84rem; color: var(--ink); line-height: 1.45; margin-top: 3px;
  white-space: normal; max-width: 78ch;
}

.ledger-reg .jline .jl-acct { font-weight: 600; color: var(--ink); }
.ledger-reg .jline td, .ledger-reg .jline th { border-top: none; }
/* Debit and credit told apart by WEIGHT and by an em dash in the empty cell,
   not by colour. Two colours down a ledger is harder to read rather than
   easier, and the distinction has to survive a monochrome print - which this
   page is going to be printed on. */
.ledger-reg .jl-dr { font-weight: 700; color: var(--ink); }
.ledger-reg .jl-cr { font-weight: 500; color: var(--leaf-deep); }
.ledger-reg .jl-none { color: #B9B4A6; font-weight: 400; }
/* A negative figure is unusual in a journal and must not be missed. */
.ledger-reg .jl-dr.neg, .ledger-reg .jl-cr.neg { color: var(--chilli); font-weight: 700; }

@media (max-width: 640px) {
  .je-amt { margin-left: 0; }
  .ltab { padding: 10px 12px 9px; font-size: .84rem; }
}
@media print {
  .ltabs, .lchips { display: none !important; }
  .ledger-reg .jentry > th { background: none; }
}

/* ---- receipts and payments: the two sides of one account --------------
   Side by side because that is what makes it an ACCOUNT rather than two
   lists; stacked on a narrow screen, where a two-column money table would
   be unreadable rather than merely tight. */
.rp-book { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
@media (max-width: 900px) { .rp-book { grid-template-columns: 1fr; } }
.rp-book .muted { color: #6b6558; }

/* ---- the bulk sale-confirmation picker -------------------------------
   A CHECKBOX IS THE CONTROL HERE, not a link, and a browser's default one
   in a default table cell measured 36px tall - below the 44px this project
   holds itself to wherever something is tapped rather than clicked. Manager
   and Supervisor use this standing at a counter, so the box is sized and
   its cell padded until the row IS the target.

   SCOPED TO THIS TABLE and deliberately not to `.ytable`. That class is
   defined in `yard.css`, which finance screens DO NOT LOAD - three of them
   (`buyer_confirmations`, `receipts_payments`, `trial_balance`) already
   carry it and render browser-default because of it. Styling `.ytable`
   here would restyle those two other screens as a side effect of adding a
   picker, which is a wider change than the one being made and is worth
   deciding on its own. Named rather than quietly fixed. */
#bulkConf tbody td { padding: 11px 12px; vertical-align: middle; }
#bulkConf .bc-pick, #bulkConf #bcAll {
  width: 18px; height: 18px; accent-color: var(--leaf); cursor: pointer;
}
/* The whole name is the label, so the tap target is the name and not just
   the box beside it. */
#bulkConf tbody label { cursor: pointer; display: block; }
