/* Imports site/tokens.css, NOT ../design/tokens.css. This site is deployed
   as a standalone unit — the live rojsaathi.in is served from site/'s own
   contents only, with no design/ sibling directory alongside it (confirmed
   in production: ../design/tokens.css 503'd, every --rs-* custom property
   was undefined, and the whole site rendered unstyled). site/tokens.css is
   a byte-for-byte copy of design/tokens.css, kept in sync by hand — hex
   still lives in exactly one authored place (design/tokens.css is the
   source; this file gets copied, never independently edited) — and
   check.mjs's rule 11 fails the gate if the two ever drift apart. Never add
   a second reference reaching outside site/; anything site/ needs must
   live inside site/. */
@import url("tokens.css");

@font-face { font-family: "Manrope"; src: url("assets/fonts/manrope-latin-400-normal.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Manrope"; src: url("assets/fonts/manrope-latin-600-normal.woff2") format("woff2"); font-weight: 600; font-display: swap; }
@font-face { font-family: "Manrope"; src: url("assets/fonts/manrope-latin-800-normal.woff2") format("woff2"); font-weight: 800; font-display: swap; }
@font-face { font-family: "Noto Sans Devanagari"; src: url("assets/fonts/noto-sans-devanagari-devanagari-600-normal.woff2") format("woff2"); font-weight: 600; font-display: swap; }
@font-face { font-family: "Noto Sans Devanagari"; src: url("assets/fonts/noto-sans-devanagari-devanagari-700-normal.woff2") format("woff2"); font-weight: 700; font-display: swap; }

*, *::before, *::after { box-sizing: border-box; }
body {
  margin: 0;
  font-family: var(--rs-body);
  color: var(--rs-ink);
  background: var(--rs-paper);
  line-height: 1.55;
}
html[lang="hi"] body { font-family: var(--rs-deva); }

h1, h2, h3 { font-family: var(--rs-display); font-weight: 800; line-height: 1.15; margin: 0 0 var(--rs-s-3); }
h1 { font-size: clamp(2rem, 5vw, 3.25rem); }
h2 { font-size: clamp(1.5rem, 3vw, 2.25rem); }
p { margin: 0 0 var(--rs-s-3); }
a { color: inherit; }

.wrap { width: min(1080px, 100% - var(--rs-s-5)); margin-inline: auto; }
.section { padding-block: var(--rs-s-7); }
.section--ink { background: var(--rs-navy); color: var(--rs-paper); }
.section--tint { background: var(--rs-tint); }
.lede { font-size: 1.15rem; color: var(--rs-mute); max-width: 60ch; }
.section--ink .lede { color: var(--rs-paper); opacity: .82; }

/* Marigold appears ONCE per screen — as the single call to action. */
.cta {
  display: inline-block; padding: var(--rs-s-3) var(--rs-s-5);
  background: var(--rs-marigold); color: var(--rs-navy);
  font-weight: 800; text-decoration: none; border-radius: var(--rs-r-sm);
}
/* .cta is normally an <a> (no browser chrome to reset). Get early access
   (index.html#cta) and Invest in us' Get in touch (invest.html#reach) both
   submit it as a real <button>, which inherits UA border/font/cursor the
   <a> never had — reset those so a <button class="cta"> reads identically
   to an <a class="cta">. */
button.cta { border: 0; font: inherit; font-weight: 800; cursor: pointer; }
/* The second hero CTA (Task 13, matching the live site's dual-CTA hero) —
   navy outline, no fill, so marigold stays the only accent. */
.cta-secondary {
  display: inline-block; padding: calc(var(--rs-s-3) - 2px) calc(var(--rs-s-5) - 2px);
  background: transparent; color: var(--rs-navy);
  font-weight: 800; text-decoration: none; border-radius: var(--rs-r-sm);
  border: 2px solid var(--rs-navy);
}
.section--ink .cta-secondary { color: var(--rs-paper); border-color: var(--rs-paper); }
.hero-ctas { display: flex; flex-wrap: wrap; gap: var(--rs-s-4); align-items: center; margin-block: var(--rs-s-4); }
.hero-status { color: var(--rs-mute); font-size: .95rem; }

/* The site's two real, functional forms — Get early access (index.html#cta)
   and Invest in us' Get in touch (invest.html#reach) — are both mailto:
   forms (no backend; see each page's own .illustration-note disclaimer)
   and share this one component, so a visitor sees ONE form pattern across
   the site rather than a styled one and a bare, unstyled one. */
.form { display: grid; gap: var(--rs-s-4); max-width: 480px; margin-top: var(--rs-s-5); }
.form label { display: block; }
.form label > span { display: block; font-size: .9rem; font-weight: 600; color: var(--rs-mute); margin-bottom: var(--rs-s-1); }
.form input, .form textarea {
  display: block; width: 100%; padding: var(--rs-s-3);
  border: 1.5px solid var(--rs-mute); border-radius: var(--rs-r-sm);
  font: inherit; color: var(--rs-ink); background: var(--rs-paper);
}
.form input:focus, .form textarea:focus { outline: 2px solid var(--rs-navy); outline-offset: 1px; border-color: var(--rs-navy); }
.form .cta { justify-self: start; }
/* On a dark section (Get early access sits on section--ink), the
   mute-grey label/border pairing above reads too low-contrast against
   navy — switch to paper at reduced opacity, the same technique
   .section--ink .lede already uses. */
.section--ink .form label > span { color: var(--rs-paper); opacity: .82; }
.section--ink .form input, .section--ink .form textarea { border-color: rgba(255, 255, 255, .5); background: rgba(255, 255, 255, .06); color: var(--rs-paper); }
.section--ink .form input::placeholder, .section--ink .form textarea::placeholder { color: rgba(255, 255, 255, .6); }

/* The register motif: ruled rows, one cell, tabular numerals. */
.ledger { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.ledger th, .ledger td { text-align: left; padding: var(--rs-s-3); border-bottom: 1px solid var(--rs-tint); vertical-align: top; }
.ledger th { font-weight: 600; color: var(--rs-mute); font-size: .9rem; }
.ledger td:first-child { font-weight: 600; }
.scroll-x { overflow-x: auto; }

.badge { display: inline-block; padding: 2px 10px; border-radius: 999px; font-size: .8rem; font-weight: 600; background: var(--rs-tint); color: var(--rs-mute); }

.site-head { display: flex; align-items: center; justify-content: space-between; gap: var(--rs-s-4); padding-block: var(--rs-s-3); }
.site-head img { height: 34px; }
.nav { display: flex; gap: var(--rs-s-4); align-items: center; flex-wrap: wrap; }
.nav a { text-decoration: none; font-weight: 600; }
/* Task 16: the current page's own nav link, distinct by weight + an
   underline in the dominant navy — not marigold, which stays the single
   per-screen accent reserved for the one CTA. */
.nav a[aria-current="page"] { font-weight: 800; color: var(--rs-navy); border-bottom: 2px solid var(--rs-navy); }

.lang { display: inline-flex; border: 1px solid var(--rs-mute); border-radius: 999px; overflow: hidden; }
.lang button { border: 0; background: transparent; padding: 4px 12px; font: inherit; font-weight: 600; cursor: pointer; color: var(--rs-mute); }
.lang button[aria-pressed="true"] { background: var(--rs-navy); color: var(--rs-paper); }

/* .shot / .shot-phone (raw <img data-shot> captures, and the Task 13 fix for
   the vertical blowout they caused at width:100%) are removed as of Task 14
   — every screen that used them is now a recreated .device-phone /
   .device-browser component instead, sized correctly by construction. See
   site/assets/shots/README.md for why the PNGs themselves stay on disk. */
.grid-2 { display: grid; gap: var(--rs-s-5); grid-template-columns: 1fr; }
@media (min-width: 820px) { .grid-2 { grid-template-columns: 1fr 1fr; align-items: center; } }

/* Three-up persona columns (Task 13, home page). */
.grid-3 { display: grid; gap: var(--rs-s-5); grid-template-columns: 1fr; }
@media (min-width: 820px) { .grid-3 { grid-template-columns: repeat(3, 1fr); align-items: start; } }
.persona { background: var(--rs-tint); border-radius: var(--rs-r-md); padding: var(--rs-s-5); }
.persona h2 { margin-bottom: var(--rs-s-2); }
.persona .badge { margin-bottom: var(--rs-s-3); }
.persona ul { margin: 0 0 var(--rs-s-4); padding-left: 1.1em; }
.persona li { margin-bottom: var(--rs-s-2); }

/* The two-tier pricing table (Task 13). */
.price-grid { display: grid; gap: var(--rs-s-5); grid-template-columns: 1fr; }
@media (min-width: 640px) { .price-grid { grid-template-columns: 1fr 1fr; } }
.price-card { background: var(--rs-tint); border-radius: var(--rs-r-md); padding: var(--rs-s-5); }
.price-amount { font-family: var(--rs-num); font-weight: 800; font-size: 1.4rem; color: var(--rs-navy); margin: 0 0 var(--rs-s-4); }
.price-card ul { margin: 0 0 var(--rs-s-4); padding-left: 1.1em; }
.price-card li { margin-bottom: var(--rs-s-2); }

/* The payslip band directly under the hero (Task 15) — copy beside the
   card in a real two-column row (.grid-2, shared with /customer etc.), not
   a lone device centred in a full-width section. .payslip-card now wraps
   only the device itself, inside grid-2's second column, so the device
   keeps its default full size (280px, see the Device frames block below)
   instead of being stretched or starved of a partner. */
.payslip-card { text-align: center; }

/* A short note under a price figure — home page pricing card (Task 15). */
.price-note { color: var(--rs-mute); font-size: .9rem; margin: calc(-1 * var(--rs-s-3)) 0 var(--rs-s-4); }

.illustration-note { font-size: .85rem; color: var(--rs-mute); font-style: italic; }

/* The scroll walkthrough ("A day at Shreeji Heights"). Base state is fully
   visible and readable — no opacity: 0 — so it reads the same with
   JavaScript disabled, before walkthrough.js runs, or with
   prefers-reduced-motion set (which skips the observer entirely).
   .is-active only adds emphasis to the step in view; it never hides the rest.
   No marigold here by design: the home page already spends its one-accent
   allowance on two .cta elements elsewhere on the page. */
.walk-steps { list-style: none; margin: var(--rs-s-6) 0 0; padding: 0; display: grid; gap: var(--rs-s-5); }
.walk-step {
  display: grid; gap: var(--rs-s-4);
  padding: var(--rs-s-4);
  border: 1px solid var(--rs-mute);
  border-radius: var(--rs-r-md);
  transition: border-color .25s ease, transform .25s ease;
}
/* Task 15 fix: this was `.walk-step p`, which (0,1,1) beats `.app-note`'s
   and `.app-row-more`'s (0,1,0) — every note/caption INSIDE the device
   graphic (mute grey by its own component rule, on the device's white
   screen) was silently repainted paper-white by this rule, i.e. invisible
   white-on-white. Scoped to the direct-child caption only — the device's
   own nested text keeps its own component colours. */
.walk-step > p { margin: 0; color: var(--rs-paper); }
.walk-step.is-active { border-color: var(--rs-paper); transform: translateY(-2px); }
@media (min-width: 640px) {
  /* Task 15: the media column was 220px holding a device shrunk to 168px —
     legible width for a sentence, not for a screen with list rows and a
     hero figure. Widened so the device (see .walk-step .device below)
     renders at a size where its content actually reads, and the row no
     longer leaves a block of empty space beside one line of caption. */
  .walk-step { grid-template-columns: minmax(240px, 300px) 1fr; align-items: center; gap: var(--rs-s-5); }
  /* Unused as of Task 14: walk.s6 (the dues step) had no image while
     society-dues.png showed stale pre-canonical-cast figures, so its
     caption spanned both columns instead of leaving one blank. All six
     steps now carry a recreated device graphic (walkthrough.js), so every
     step uses the two-column layout above — kept, not deleted, in case a
     future step is ever text-only again. */
  .walk-step-full { grid-column: 1 / -1; }
}
@media (prefers-reduced-motion: reduce) {
  .walk-step { transition: none; }
}
.site-foot { padding-block: var(--rs-s-5); border-top: 1px solid var(--rs-tint); color: var(--rs-mute); font-size: .9rem; }

/* ============================================================
   Device frames (Task 14) — recreated app/console screens, not
   screenshots. Two reusable shells, used by every page: a phone
   frame (the vendor + resident app) and a browser frame (the
   society console). Real captures stay in assets/shots/ as the
   reference these are checked against — see that folder's README.
   Every string inside is data-i18n like everything else on the
   site, so the language toggle "comes free" instead of needing a
   second image folder per screen.
   ============================================================ */
.device { --device-w: 280px; font-size: .82rem; line-height: 1.4; }
.device-phone {
  width: var(--device-w);
  margin-inline: auto;
  border: 2px solid var(--rs-navy);
  border-radius: var(--rs-r-lg);
  padding: var(--rs-s-2);
  background: var(--rs-navy);
}
.device-phone__notch { width: 36px; height: 4px; margin: 0 auto var(--rs-s-2); background: var(--rs-paper); opacity: .5; border-radius: 999px; }
.device-screen { background: var(--rs-paper); border-radius: calc(var(--rs-r-lg) - 4px); padding: var(--rs-s-4); overflow: hidden; }

.device-browser { width: 100%; max-width: 640px; margin-inline: auto; border: 1px solid var(--rs-tint); border-radius: var(--rs-r-md); overflow: hidden; }
.device-browser__bar { display: flex; align-items: center; gap: var(--rs-s-2); padding: var(--rs-s-3) var(--rs-s-4); background: var(--rs-tint); }
.device-browser__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--rs-mute); opacity: .5; }
.device-browser__url { margin-left: var(--rs-s-3); font-size: .78em; color: var(--rs-mute); background: var(--rs-paper); padding: 2px 10px; border-radius: 999px; flex: 1; font-variant-numeric: tabular-nums; }
.device-browser .device-screen { border-radius: 0; padding: var(--rs-s-5); }

/* Compact variant for the walkthrough's media column (Task 14; widened and
   re-tuned Task 15). 168px/.58rem read as blank grey strips — list rows and
   the hero figure clipped or vanished at that scale, so the graphic carried
   no information. 224px/.7rem is still smaller than the default (280px/
   .82rem) so it sits beside its caption rather than towering over it, but
   stays legible. */
.walk-step .device { --device-w: 224px; font-size: .7rem; }
.walk-step .device-screen { padding: var(--rs-s-3); }
.walk-step .device-browser { max-width: 300px; }
.walk-step .device-browser__bar { padding: var(--rs-s-2) var(--rs-s-3); }

/* App chrome: topbar, hero figure, list rows, buttons — the vocabulary
   every phone screen composes from. */
.app-topbar { display: flex; align-items: baseline; gap: var(--rs-s-2); margin-bottom: var(--rs-s-3); font-weight: 700; color: var(--rs-navy); }
.app-topbar__back { color: var(--rs-mute); font-weight: 400; }
.app-topbar__sub { color: var(--rs-mute); font-weight: 400; font-size: .9em; }

.app-hero { margin-block: var(--rs-s-3); }
.app-hero__label { color: var(--rs-mute); font-size: .85em; }
.app-hero__amount { font-family: var(--rs-num); font-weight: 800; font-size: 1.55em; color: var(--rs-navy); font-variant-numeric: tabular-nums; display: block; }

.app-chip { display: inline-block; padding: 1px 8px; border-radius: 999px; background: var(--rs-tint); color: var(--rs-mute); font-size: .78em; }

.app-list { margin: var(--rs-s-3) 0 0; }
.app-list__row { display: flex; justify-content: space-between; gap: var(--rs-s-3); padding: var(--rs-s-2) 0; border-bottom: 1px solid var(--rs-tint); font-variant-numeric: tabular-nums; }
.app-list__row > :last-child { font-weight: 600; }
.app-list__row--total { border-top: 1px solid var(--rs-mute); border-bottom: 0; font-weight: 700; margin-top: var(--rs-s-1); padding-top: var(--rs-s-2); }
.app-list__row--total > * { font-weight: 700; }

.app-btn { display: block; width: 100%; text-align: center; padding: var(--rs-s-3); border-radius: var(--rs-r-sm); font-weight: 700; border: 0; font: inherit; margin-top: var(--rs-s-3); }
.app-btn--primary { background: var(--rs-marigold); color: var(--rs-navy); }
.app-btn--ghost { background: transparent; border: 1.5px solid var(--rs-navy); color: var(--rs-navy); padding: calc(var(--rs-s-3) - 1.5px); }

/* The attendance calendar. */
.app-cal { margin-top: var(--rs-s-2); }
.app-cal__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; text-align: center; }
.app-cal__dow { color: var(--rs-mute); font-size: .78em; padding-bottom: 4px; }
.app-cal__day { position: relative; padding: 3px 0; font-size: .82em; min-height: 1.8em; font-variant-numeric: tabular-nums; }
.app-cal__day--today { border-radius: 50%; outline: 1.5px solid var(--rs-navy); outline-offset: -2px; }
.app-cal__day--off { color: var(--rs-mute); }
.app-cal__day--off::after { content: ''; display: block; width: 4px; height: 4px; border-radius: 50%; background: var(--rs-mute); margin: 1px auto 0; }
.app-cal__day--flag { color: var(--rs-alert); font-weight: 700; outline: 1.5px solid var(--rs-alert); outline-offset: -2px; border-radius: 50%; }
.app-legend { display: flex; flex-wrap: wrap; gap: var(--rs-s-4); align-items: center; margin-top: var(--rs-s-3); font-size: .78em; color: var(--rs-mute); }
.app-legend__dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; margin-right: 4px; background: var(--rs-alert); }

/* The two-stroke tick — bilateral confirmation / verified payment, and
   nothing else (design/BRAND-GUIDE.md §1). Built once, used wherever the
   product itself uses it: a day the worker also confirmed, a collected
   figure the payer verified digitally. Never recoloured, never decorative. */
.tick-icon { width: 1em; height: 1em; display: inline-block; vertical-align: -0.15em; overflow: visible; }
.tick-icon .tick-arm-short { stroke: var(--rs-marigold); stroke-width: 2.6; stroke-linecap: round; fill: none; }
.tick-icon .tick-arm-long { stroke: var(--rs-navy); stroke-width: 2.6; stroke-linecap: round; fill: none; }

/* Route / customer-book list rows. */
.app-row { display: flex; justify-content: space-between; align-items: center; gap: var(--rs-s-3); padding: var(--rs-s-2) 0; border-bottom: 1px solid var(--rs-tint); }
.app-row__meta { color: var(--rs-mute); font-size: .85em; }
.app-row--flag { background: var(--rs-tint); margin-inline: calc(var(--rs-s-2) * -1); padding-inline: var(--rs-s-2); border-radius: var(--rs-r-sm); }
.app-row-more { color: var(--rs-mute); font-size: .82em; padding: var(--rs-s-2) 0; text-align: center; }
.app-stats { display: grid; gap: 2px; margin-bottom: var(--rs-s-3); font-size: .85em; }
.app-stats__row { display: flex; justify-content: space-between; padding: 2px 0; }
.app-stats__amount { font-family: var(--rs-num); font-variant-numeric: tabular-nums; font-weight: 700; }

/* The gate QR — an abstract glyph, deliberately not a scannable code. */
.app-qr { display: flex; justify-content: center; margin: var(--rs-s-4) 0; }
.app-qr .qr-cell { fill: var(--rs-navy); }
.app-qr .qr-bg { fill: var(--rs-paper); }

/* Quantity-change stepper. */
.app-qty { display: flex; align-items: center; justify-content: center; gap: var(--rs-s-4); margin: var(--rs-s-5) 0; font-family: var(--rs-num); font-variant-numeric: tabular-nums; }
.app-qty__value { font-size: 1.9em; font-weight: 800; color: var(--rs-mute); }
.app-qty__value--to { color: var(--rs-navy); }
.app-qty__arrow { color: var(--rs-mute); font-size: 1.3em; }
.app-qty__unit { font-size: .7em; color: var(--rs-mute); }

/* Console (browser-frame) chrome — Latin-only by design, see
   design/BRAND-GUIDE.md §3: the site never invents a Hindi console. */
.console-nav { display: flex; align-items: center; gap: var(--rs-s-4); padding-bottom: var(--rs-s-3); margin-bottom: var(--rs-s-4); border-bottom: 1px solid var(--rs-tint); font-size: .85em; flex-wrap: wrap; }
.console-nav__brand { font-weight: 800; color: var(--rs-navy); margin-right: auto; }
.console-nav a { color: var(--rs-mute); }
.console-nav__active { color: var(--rs-navy); font-weight: 600; }
.console-stat-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--rs-s-3); margin: var(--rs-s-4) 0; }
.console-stat { background: var(--rs-tint); border-radius: var(--rs-r-sm); padding: var(--rs-s-3); }
.console-stat__label { color: var(--rs-mute); font-size: .78em; }
.console-stat__amount { font-family: var(--rs-num); font-weight: 800; font-size: 1.15em; color: var(--rs-navy); font-variant-numeric: tabular-nums; }
.console-table { width: 100%; border-collapse: collapse; font-size: .85em; }
.console-table th, .console-table td { text-align: left; padding: var(--rs-s-2); border-bottom: 1px solid var(--rs-tint); font-variant-numeric: tabular-nums; }
.console-btn { display: inline-block; padding: 2px 10px; border-radius: var(--rs-r-sm); font-size: .78em; font-weight: 600; border: 1px solid var(--rs-navy); color: var(--rs-navy); background: transparent; }
.console-btn--primary { background: var(--rs-marigold); border-color: var(--rs-marigold); color: var(--rs-navy); }
.console-badge { display: inline-block; padding: 1px 8px; border-radius: 999px; font-size: .75em; background: var(--rs-tint); color: var(--rs-mute); }
.console-form input, .console-form textarea { display: block; width: 100%; margin-bottom: var(--rs-s-3); padding: var(--rs-s-2); border: 1px solid var(--rs-mute); border-radius: var(--rs-r-sm); font: inherit; color: var(--rs-mute); background: var(--rs-paper); }
.console-form label { display: block; font-size: .82em; color: var(--rs-mute); margin-bottom: 2px; }
.console-notice { background: var(--rs-tint); border-radius: var(--rs-r-sm); padding: var(--rs-s-3); margin-top: var(--rs-s-4); }
.console-notice h4 { margin: 0 0 4px; font-family: var(--rs-body); font-size: 1em; }
.console-notice__meta { color: var(--rs-mute); font-size: .78em; margin: var(--rs-s-2) 0; }
.console-vendor-card { background: var(--rs-tint); border-radius: var(--rs-r-sm); padding: var(--rs-s-3); margin-bottom: var(--rs-s-3); display: flex; justify-content: space-between; align-items: center; gap: var(--rs-s-3); flex-wrap: wrap; }
.console-vendor-card h5 { margin: 0; font-family: var(--rs-body); font-weight: 700; font-size: 1em; }
.console-vendor-card__role { color: var(--rs-mute); font-size: .82em; }
.console-section-h { font-size: .78em; text-transform: uppercase; letter-spacing: .04em; color: var(--rs-mute); margin: var(--rs-s-4) 0 var(--rs-s-2); }
.console-section-h:first-child { margin-top: 0; }
.console-page-title { font-family: var(--rs-display); font-weight: 800; font-size: 1.1em; color: var(--rs-navy); margin: 0 0 var(--rs-s-3); }
.console-period { display: flex; gap: var(--rs-s-3); align-items: center; flex-wrap: wrap; }

/* A short note inside a device screen — not the CTA, not a list row. */
.app-note { color: var(--rs-mute); font-size: .85em; margin: 0 0 var(--rs-s-3); }

/* Two lightweight text actions side by side (Task 15) — e.g. Dispute /
   Accept on a delivery-deviation card. Deliberately not .app-btn: mirrors
   the real in-app control (small inline taps, not a primary CTA), and
   keeps marigold reserved for the one .app-btn--primary per screen. */
.app-actions { display: flex; gap: var(--rs-s-4); align-items: center; margin: var(--rs-s-2) 0 var(--rs-s-3); }
.app-action { font-weight: 700; font-size: .95em; }
.app-action--alert { color: var(--rs-alert); }
.app-action--ink { color: var(--rs-navy); }

/* Plain single-stroke checkbox for a settings toggle (who to skip on
   vacation) — deliberately NOT the two-stroke tick, which means bilateral
   confirmation / verified payment only, never a UI selection state. */
.app-checkbox { display: inline-flex; align-items: center; justify-content: center; width: 1em; height: 1em; border: 1.5px solid var(--rs-navy); border-radius: 3px; margin-right: 4px; vertical-align: -0.15em; font-size: 1em; line-height: 1; color: var(--rs-navy); }

/* ============================================================
   Task 16 additions — the five missing product flows.
   ============================================================ */

/* B1 (/customer, discovery): one ranked result row. Rating is plain ink
   text, never the reserved verified-green — it's a 0-5 average, not a
   verified-payment figure (that's `verified_jobs`, in .app-vendor__meta
   below, also plain — see check.mjs rule 2 and the VendorCard.dart
   precedent it mirrors: neither field ever renders StatusKind.verified). */
.app-vendor { padding: var(--rs-s-2) 0; border-bottom: 1px solid var(--rs-tint); }
.app-vendor:last-child { border-bottom: 0; }
.app-vendor__top { display: flex; justify-content: space-between; align-items: baseline; gap: var(--rs-s-2); font-weight: 700; }
.app-vendor__rating { font-family: var(--rs-num); font-variant-numeric: tabular-nums; color: var(--rs-mute); font-weight: 700; white-space: nowrap; }
.app-vendor__meta { color: var(--rs-mute); font-size: .85em; margin: 2px 0 0; }

/* B2 (/customer, header search): the read-only tappable search field from
   mobile/lib/src/widgets/header_search_bar.dart, and a compact phone
   variant — sized down like .walk-step .device, but usable standalone for
   any small supporting graphic that doesn't need the full 280px frame. */
.app-search { display: flex; align-items: center; gap: var(--rs-s-2); background: var(--rs-tint); border-radius: var(--rs-r-md); padding: var(--rs-s-3); color: var(--rs-mute); }
.app-search__icon { flex: none; color: var(--rs-mute); }
.device-compact { --device-w: 200px; font-size: .72rem; }
.device-compact .device-screen { padding: var(--rs-s-3); }

/* B3 (/customer, add a vendor): a plain state-transition marker between two
   labelled rows in one phone frame (waiting for confirmation -> confirmed
   by both). Deliberately NOT the two-stroke tick — that stays reserved for
   the confirmed row itself, never the transition between states. */
.app-state-arrow { text-align: center; color: var(--rs-mute); margin: var(--rs-s-1) 0; font-size: 1.1em; }
