/* askit customer app — design tokens + components.
 *
 * The token set is lifted from the marketing site (website/index.html) so the app and the
 * site read as one product: teal primary, coral accent, Mulish, three radii, brand-tinted
 * shadows, one easing curve. Tokens are bare HSL triplets consumed as hsl(var(--x) / a),
 * which makes every transparency variant free.
 *
 * Note the brand mark is NOT teal — the askit logo is black with a yellow "it". Teal is the
 * product's colour, the logo is the identity, and they sit side by side exactly as they do
 * on the website. The yellow appears only in the wordmark, never as a UI colour.
 *
 * Light and dark are both defined at token level. No component may hard-code a colour: a
 * value that exists only inside a media query renders one theme's text on the other's ground.
 */

:root {
  --background: 150 30% 98%;
  --foreground: 175 35% 12%;
  --card: 0 0% 100%;
  --primary: 168 76% 28%;
  --primary-foreground: 150 30% 98%;
  --primary-glow: 158 70% 55%;
  --secondary: 158 45% 92%;
  --muted: 150 25% 95%;
  --muted-foreground: 175 15% 40%;
  --accent: 14 90% 64%;
  --destructive: 0 72% 46%;
  --border: 158 25% 88%;
  --ring: 168 76% 38%;

  /* The logo's own colours — used for the wordmark only. */
  --brand-ink: 0 0% 5%;
  --brand-pop: 55 100% 55%;

  --gradient-primary: linear-gradient(135deg, hsl(168 76% 28%), hsl(158 70% 42%));
  --gradient-hero:
    radial-gradient(1100px 520px at 12% -8%, hsl(158 70% 88% / .75), transparent 62%),
    radial-gradient(820px 460px at 92% 4%, hsl(14 90% 88% / .5), transparent 60%);

  --shadow-soft: 0 8px 30px -8px hsl(168 60% 25% / .12);
  --shadow-card: 0 16px 50px -18px hsl(168 60% 22% / .18);
  --shadow-glow: 0 18px 46px -18px hsl(168 76% 38% / .38);

  --ease: cubic-bezier(.22, 1, .36, 1);
  --r-pill: 9999px;
  --r-md: 1rem;
  --r-lg: 1.5rem;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --background: 174 30% 7%;
    --foreground: 150 25% 93%;
    --card: 174 26% 11%;
    --primary: 158 60% 46%;
    --primary-foreground: 174 30% 7%;
    --primary-glow: 158 70% 55%;
    --secondary: 168 25% 17%;
    --muted: 172 22% 15%;
    --muted-foreground: 158 12% 70%;
    --accent: 14 85% 66%;
    --destructive: 0 70% 62%;
    --border: 170 20% 22%;
    --ring: 158 60% 50%;
    --gradient-primary: linear-gradient(135deg, hsl(168 55% 32%), hsl(158 60% 46%));
    --gradient-hero:
      radial-gradient(1100px 520px at 12% -8%, hsl(168 55% 16% / .85), transparent 62%),
      radial-gradient(820px 460px at 92% 4%, hsl(14 60% 18% / .5), transparent 60%);
    --shadow-soft: 0 8px 30px -8px hsl(0 0% 0% / .45);
    --shadow-card: 0 16px 50px -18px hsl(0 0% 0% / .55);
    --shadow-glow: 0 18px 46px -18px hsl(158 70% 45% / .2);
  }
}

:root[data-theme="dark"] {
  --background: 174 30% 7%;
  --foreground: 150 25% 93%;
  --card: 174 26% 11%;
  --primary: 158 60% 46%;
  --primary-foreground: 174 30% 7%;
  --primary-glow: 158 70% 55%;
  --secondary: 168 25% 17%;
  --muted: 172 22% 15%;
  --muted-foreground: 158 12% 70%;
  --accent: 14 85% 66%;
  --destructive: 0 70% 62%;
  --border: 170 20% 22%;
  --ring: 158 60% 50%;
  --gradient-primary: linear-gradient(135deg, hsl(168 55% 32%), hsl(158 60% 46%));
  --gradient-hero:
    radial-gradient(1100px 520px at 12% -8%, hsl(168 55% 16% / .85), transparent 62%),
    radial-gradient(820px 460px at 92% 4%, hsl(14 60% 18% / .5), transparent 60%);
  --shadow-soft: 0 8px 30px -8px hsl(0 0% 0% / .45);
  --shadow-card: 0 16px 50px -18px hsl(0 0% 0% / .55);
  --shadow-glow: 0 18px 46px -18px hsl(158 70% 45% / .2);
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
/* A phone screen must never scroll sideways. A backstop only — anything that actually
   overflows is a bug to find, not to hide, and the layout is verified clean at 320px. */
html, body { max-width: 100%; overflow-x: hidden; }

body {
  margin: 0;
  min-height: 100dvh;
  background: hsl(var(--background));
  color: hsl(var(--foreground));
  font-family: 'Mulish', system-ui, -apple-system, sans-serif;
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { margin: 0; line-height: 1.18; font-weight: 800; text-wrap: balance; }
h1 { font-size: 1.6rem; letter-spacing: -.015em; }
p  { margin: 0; }

:focus-visible {
  outline: 2px solid hsl(var(--ring));
  outline-offset: 2px;
  border-radius: var(--r-md);
}

[hidden] { display: none !important; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── Shell ─────────────────────────────────────────────────────────────────── */
.app {
  max-width: 30rem;
  margin: 0 auto;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);
}

.appbar {
  display: flex; align-items: center; gap: .7rem;
  padding: .8rem 1.25rem;
  background: hsl(var(--card));
  border-bottom: 1px solid hsl(var(--border));
  position: sticky; top: 0; z-index: 10;
}
.appbar-logo { width: 2.1rem; height: 2.1rem; border-radius: .65rem; flex: none; }
.appbar-title { font-size: .95rem; font-weight: 900; letter-spacing: -.01em; }
.appbar-sub { font-size: .72rem; color: hsl(var(--muted-foreground)); }

.screen { flex: 1; padding: 1.75rem 1.25rem 2rem; display: none; }
.screen.active { display: block; animation: rise .45s var(--ease) both; }
/* The gate centres its content vertically, so it needs flex rather than block. */
/* The home screen manages its own gutters so the hero can run full-bleed, rather than
   pulling it out with negative margins — which widens the box beyond its parent and invites
   a sideways scroll on the one screen size nobody tests. */
.screen.home { padding: 0; }

@keyframes rise { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  .screen.active { animation: none; }
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* ── Home hero ─────────────────────────────────────────────────────────────── */
.hero {
  position: relative;
  padding: 2.75rem 1.25rem 2.5rem;
  background-image: var(--gradient-hero);
  text-align: center;
  overflow: hidden;
}
/* Film grain — the same trick the marketing site uses to stop a flat gradient
   looking like a flat gradient. Cheap, and it survives any theme. */
.hero::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  opacity: .04; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='n'><feTurbulence baseFrequency='0.9'/></filter><rect width='120' height='120' filter='url(%23n)'/></svg>");
}

.brand-logo {
  width: 4.5rem; height: 4.5rem;
  border-radius: 1.35rem;
  box-shadow: var(--shadow-glow);
  display: block; margin: 0 auto 1.1rem;
}

.brand-greeting {
  font-size: .95rem; font-weight: 700;
  color: hsl(var(--muted-foreground));
  margin-bottom: .3rem;
}

.hero h1 { font-size: clamp(1.7rem, 7vw, 2.1rem); }

/* Set as plain type, deliberately. Repeating the logo's yellow "it" as a filled badge here
   put a loud swatch directly under the actual logo, competing with it and breaking the
   headline across two lines — and yellow on a light ground fails contrast besides. The mark
   above already carries the identity; the headline only has to be readable. */
.wordmark { font-weight: 900; letter-spacing: -.02em; white-space: nowrap; }

.brand-line {
  margin: .7rem auto 0;
  max-width: 22rem;
  color: hsl(var(--muted-foreground));
  font-size: .98rem;
}

.trust {
  list-style: none; margin: 1.5rem 0 0; padding: 0;
  display: flex; justify-content: center; flex-wrap: wrap; gap: .45rem;
}
.trust li {
  display: inline-flex; align-items: center; gap: .4rem;
  font-size: .75rem; font-weight: 700;
  color: hsl(var(--primary));
  background: hsl(var(--card) / .75);
  border: 1px solid hsl(var(--border));
  border-radius: var(--r-pill);
  padding: .38rem .7rem;
  backdrop-filter: blur(8px);
}
.trust .t-ic { font-weight: 800; opacity: .85; }

/* ── Cards ─────────────────────────────────────────────────────────────────── */
.card {
  background: hsl(var(--card));
  border: 1px solid hsl(var(--border));
  border-radius: var(--r-lg);
  padding: 1.35rem 1.25rem;
  box-shadow: var(--shadow-card);
}
/* Lifted over the hero's lower edge so the two read as one composition. */
.locator { margin: -1.5rem 1.25rem 0; position: relative; z-index: 1; }
.card-title { font-size: 1.05rem; font-weight: 800; }
.card-help { font-size: .87rem; color: hsl(var(--muted-foreground)); margin: .3rem 0 1.1rem; }
.card-foot { font-size: .76rem; color: hsl(var(--muted-foreground)); text-align: center; margin-top: .9rem; }

.divider {
  display: flex; align-items: center; gap: .75rem;
  margin: 1rem 0;
  color: hsl(var(--muted-foreground));
  font-size: .78rem;
}
.divider::before, .divider::after {
  content: ""; flex: 1; height: 1px; background: hsl(var(--border));
}

/* minmax(0, 1fr), not 1fr: a bare `1fr` is `minmax(auto, 1fr)` and refuses to shrink below
   the track's min-content width. An <input> reports one from its size attribute, so the
   field plus the button would refuse to fit a 320px phone (verified — at 320 without this
   the row is wider than the card). `size="6"` in the markup narrows it further, since the
   field only ever holds six digits. */
.pin-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: .6rem; }
.pin-row .field { min-width: 0; }
/* Looser tracking than the OTP box: this one shows a word as its placeholder, and at .18em
   "Pincode" is clipped on a 320px screen. */
#pincode { letter-spacing: .08em; }

/* ── Controls ──────────────────────────────────────────────────────────────── */
a.btn { text-decoration: none; }
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  width: 100%; min-height: 3.25rem; padding: 0 1.4rem;
  border: 0; border-radius: var(--r-pill);
  font: inherit; font-size: .95rem; font-weight: 800;
  cursor: pointer;
  transition: transform .25s var(--ease), box-shadow .25s var(--ease), filter .25s var(--ease);
}
.btn:disabled { opacity: .6; cursor: progress; transform: none; }

.btn-primary {
  background: var(--gradient-primary);
  color: hsl(var(--primary-foreground));
  box-shadow: 0 10px 26px -10px hsl(var(--primary) / .6);
}
.btn-primary:hover:not(:disabled) { transform: translateY(-2px); filter: brightness(1.05); }

.btn-solid {
  width: auto; padding: 0 1.5rem;
  background: hsl(var(--foreground));
  color: hsl(var(--background));
}
.btn-solid:hover:not(:disabled) { transform: translateY(-2px); }

.btn-ghost {
  background: transparent;
  color: hsl(var(--primary));
  border: 2px solid hsl(var(--primary) / .22);
}
.btn-ghost:hover:not(:disabled) { background: hsl(var(--secondary)); }

.field {
  width: 100%; min-height: 3.25rem;
  padding: .75rem 1.1rem;
  border: 1.5px solid hsl(var(--border));
  border-radius: var(--r-md);
  background: hsl(var(--background));
  color: hsl(var(--foreground));
  font: inherit; font-size: 1rem;
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.field::placeholder { color: hsl(var(--muted-foreground) / .65); }
.field:focus {
  outline: none;
  border-color: hsl(var(--ring));
  box-shadow: 0 0 0 4px hsl(var(--ring) / .14);
}

/* Digits line up and don't reflow as they're typed. */
.field-code {
  font-variant-numeric: tabular-nums;
  letter-spacing: .18em;
  text-align: center;
  font-size: 1.15rem;
  font-weight: 800;
}
#otp.field-code { letter-spacing: .4em; font-size: 1.45rem; }

.stack { display: grid; gap: .75rem; margin-top: 1.5rem; }

/* ── Messages & states ─────────────────────────────────────────────────────── */
.eyebrow {
  display: inline-block;
  font-size: .7rem; font-weight: 800; text-transform: uppercase; letter-spacing: .08em;
  color: hsl(var(--primary));
  background: hsl(var(--secondary));
  padding: .35rem .9rem;
  border-radius: var(--r-pill);
  margin-bottom: .9rem;
}
.lede { margin-top: .6rem; color: hsl(var(--muted-foreground)); }

.note {
  border-radius: var(--r-md);
  padding: .8rem 1rem;
  font-size: .87rem; font-weight: 600;
  margin-top: 1rem;
}
.note-bad { background: hsl(var(--destructive) / .1); color: hsl(var(--destructive)); }
.note-good { background: hsl(var(--secondary)); color: hsl(var(--primary)); }

.state-icon {
  width: 3.75rem; height: 3.75rem;
  border-radius: var(--r-md);
  background: hsl(var(--secondary));
  color: hsl(var(--primary));
  display: grid; place-items: center;
  font-size: 1.7rem; font-weight: 800;
  margin-bottom: 1.1rem;
}
.state-icon.ok { background: var(--gradient-primary); color: hsl(var(--primary-foreground)); }

.spinner {
  width: 1.15rem; height: 1.15rem;
  border: 2px solid currentColor; border-top-color: transparent;
  border-radius: 50%;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ── Footer ────────────────────────────────────────────────────────────────── */
.app-foot {
  margin-top: auto;
  padding: 1.4rem 1.25rem calc(1.4rem + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; align-items: center; gap: .55rem;
  font-size: .76rem;
  color: hsl(var(--muted-foreground));
  text-align: center;
  /* A hairline anchors the footer to the page, so the empty stretch above it reads as
     deliberate breathing room instead of a layout that ran out of content. */
  border-top: 1px solid hsl(var(--border) / .6);
}
/* The legal entity, not the brand — the name that belongs on a receipt. */
.app-foot strong { font-weight: 800; }
.app-foot a { color: hsl(var(--primary)); font-weight: 700; text-decoration: none; }
.app-foot a:hover { text-decoration: underline; }

/* ── Language switch ───────────────────────────────────────────────────────── */
/* A visible switch, not a launch modal. The plan puts language at S1, but a blocking
   popup before anyone has seen the product is friction on the one screen that has to
   feel effortless — and it is unanswerable later. This is always reachable and always
   reversible. */
.lang-switch {
  display: inline-flex;
  gap: .2rem;
  padding: .2rem;
  background: hsl(var(--muted));
  border: 1px solid hsl(var(--border));
  border-radius: var(--r-pill);
}
.lang-switch button {
  border: 0;
  background: transparent;
  color: hsl(var(--muted-foreground));
  font: inherit;
  font-size: .78rem;
  font-weight: 800;
  padding: .3rem .85rem;
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: background .25s var(--ease), color .25s var(--ease);
}
.lang-switch button.on {
  background: hsl(var(--card));
  color: hsl(var(--primary));
  box-shadow: var(--shadow-soft);
}
/* In the app bar it sits at the far right, away from the wordmark. */
.appbar .lang-switch { margin-left: auto; }

/* On the home hero it sits centered above the logo — the founder's call: the one
   control a Hindi-only customer must find gets discoverability over minimalism. */
.hero-lang {
  display: inline-flex;
  margin: 0 auto 1.6rem;
  background: hsl(var(--card) / .7);
  backdrop-filter: blur(8px);
}
.hero { display: flex; flex-direction: column; align-items: center; }
.hero .brand, .hero .trust { width: 100%; }

/* ── First-run language gate ───────────────────────────────────────────────── */
.langgate {
  padding: 0;
  display: none;
  background-image: var(--gradient-hero);
}
.langgate.active { display: flex; }
.langgate-inner {
  margin: auto;
  padding: 2rem 1.5rem;
  text-align: center;
  max-width: 22rem;
  width: 100%;
}
.langgate h1 { margin-top: .5rem; font-size: 1.5rem; }
/* The Hindi prompt sits beside the English one at equal weight — a customer who reads
   only Hindi has to recognise this screen without reading the line above it. */
.lang-sub { font-size: 1.15rem; font-weight: 700; color: hsl(var(--foreground) / .75); }
.lang-pick { font-size: 1.05rem; }
.lang-pick[data-lang="hi"] {
  background: hsl(var(--card));
  color: hsl(var(--primary));
  box-shadow: var(--shadow-soft);
  border: 2px solid hsl(var(--primary) / .22);
}

/* ── Compose: the editable medicine list ───────────────────────────────────── */
/* The widget this whole app exists for. On WhatsApp, changing a quantity costs a
   two-tap picker capped at ten rows, or learning a reply grammar ("2=10"). Here it
   is a stepper next to the name. */
.field-area { min-height: 5.5rem; resize: vertical; line-height: 1.5; }

.upload { cursor: pointer; }

/* One vertical beat for the whole compose flow (founder screenshot: the blocks sat
 * at accidental distances — some touching, some 20px apart). Every block below the
 * lede now sits exactly 1rem after the previous one; the first card gets a touch
 * more as a section break. rx-card and .note already carry the same 1rem. */
.addmed { margin-top: 1.1rem; }
.upload-row { margin-top: 1rem; }
.medlist { margin-top: 1rem; }
.medrow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: .6rem;
  align-items: center;
  padding: .7rem 0;
  border-top: 1px solid hsl(var(--border));
}
.medrow:first-child { border-top: 0; }
.medrow .mn { font-weight: 700; font-size: .95rem; overflow-wrap: anywhere; }
/* A low-confidence OCR line is marked, never silently presented as fact — the customer
   becomes a second reader before a pharmacist ever sees it. */
.medrow .mn.unsure { text-decoration: underline dashed hsl(var(--accent)); text-underline-offset: 3px; }
.medrow .md { font-size: .74rem; color: hsl(var(--muted-foreground)); font-style: italic; }

.stepper {
  display: inline-flex; align-items: center; gap: .1rem;
  background: hsl(var(--muted));
  border-radius: var(--r-pill);
  padding: .15rem;
}
.stepper button {
  width: 2rem; height: 2rem;
  border: 0; border-radius: 50%;
  background: hsl(var(--card));
  color: hsl(var(--primary));
  font: inherit; font-size: 1.1rem; font-weight: 800; line-height: 1;
  cursor: pointer;
}
.stepper button:disabled { opacity: .4; cursor: not-allowed; }
.stepper .qty {
  min-width: 2rem; text-align: center;
  font-variant-numeric: tabular-nums; font-weight: 800; font-size: .95rem;
}
.medrow .drop {
  border: 0; background: transparent; cursor: pointer;
  color: hsl(var(--muted-foreground)); font-size: 1.1rem; padding: .2rem .3rem;
}
.medrow .drop:hover { color: hsl(var(--destructive)); }

/* ── Review ────────────────────────────────────────────────────────────────── */
.rev-row {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: .72rem; font-weight: 800; text-transform: uppercase; letter-spacing: .07em;
  color: hsl(var(--muted-foreground));
  margin-top: 1.1rem;
}
.rev-row:first-child { margin-top: 0; }
.rev-value { font-size: .95rem; margin-top: .3rem; }
.rev-meds { margin: .3rem 0 0; padding-left: 1.1rem; font-size: .95rem; }
.rev-meds li { margin: .15rem 0; }
/* PRIORITY-1 urgent/normal segmented choice */
.pri-seg { display: flex; gap: .5rem; margin-top: .45rem; }
.pri-opt {
  flex: 1; padding: .55rem .6rem; border-radius: .6rem; cursor: pointer;
  border: 1.5px solid hsl(var(--border)); background: hsl(var(--card));
  color: hsl(var(--foreground)); font: inherit; font-size: .9rem; font-weight: 600;
}
.pri-opt.on { border-color: hsl(var(--primary)); background: hsl(var(--primary) / .08); }
#pri-urgent.on { border-color: hsl(0 72% 45%); background: hsl(0 72% 45% / .1);
                 color: hsl(0 72% 42%); }
.linkish {
  border: 0; background: transparent; cursor: pointer;
  color: hsl(var(--primary)); font: inherit; font-size: .72rem; font-weight: 800;
  text-transform: uppercase; letter-spacing: .07em;
}

/* ── Sourcing: the radar ───────────────────────────────────────────────────── */
/* Concentric rings ripple outward from the askit pin while a sweep rotates and the
   pharmacy markers light up in turn — searching-the-neighbourhood, drawn rather than
   claimed. Pure CSS; reduced-motion gets the still composition. */
.radar {
  position: relative;
  width: 13rem; height: 13rem;
  margin: .5rem auto 1.5rem;
  border-radius: 50%;
  background:
    radial-gradient(circle, hsl(var(--primary) / .10) 1px, transparent 1.5px) 0 0 / 14px 14px,
    radial-gradient(circle at center, hsl(var(--secondary) / .8), hsl(var(--secondary) / .15) 70%);
  border: 1px solid hsl(var(--border));
}
.radar .ring {
  position: absolute; inset: 0;
  border-radius: 50%;
  border: 1.5px solid hsl(var(--primary) / .5);
  opacity: 0;
  transform: scale(.25);
}
.radar .sweep {
  position: absolute; inset: 0;
  border-radius: 50%;
  background: conic-gradient(from 0deg, hsl(var(--primary) / .28), transparent 70deg);
  -webkit-mask: radial-gradient(circle, transparent 26%, black 27%);
          mask: radial-gradient(circle, transparent 26%, black 27%);
}
.radar .pin {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 3.2rem; height: 3.2rem;
  border-radius: 1rem;
  background: hsl(var(--card));
  box-shadow: var(--shadow-glow);
  display: grid; place-items: center;
}
.radar .pin img { border-radius: .7rem; display: block; }
.radar .dot {
  position: absolute;
  width: 1.7rem; height: 1.7rem;
  border-radius: 50%;
  background: hsl(var(--card));
  border: 1.5px solid hsl(var(--border));
  color: hsl(var(--primary));
  display: grid; place-items: center;
  font-size: .8rem; font-weight: 800;
  opacity: .55;
}
.radar .d1 { top: 16%;  left: 62%; }
.radar .d2 { top: 58%;  left: 12%; }
.radar .d3 { top: 68%;  left: 72%; }
@media (prefers-reduced-motion: no-preference) {
  .radar .ring { animation: ripple 3.2s cubic-bezier(.2, .6, .4, 1) infinite; }
  .radar .r2 { animation-delay: 1.05s; }
  .radar .r3 { animation-delay: 2.1s; }
  @keyframes ripple {
    0%   { opacity: 0;  transform: scale(.25); }
    12%  { opacity: .7; }
    100% { opacity: 0;  transform: scale(1); }
  }
  .radar .sweep { animation: sweep 4s linear infinite; }
  @keyframes sweep { to { transform: rotate(360deg); } }
  /* Each pharmacy lights as the sweep passes — offsets matched to its angle. */
  .radar .dot { animation: found 4s ease-in-out infinite; }
  .radar .d1 { animation-delay: .6s; }
  .radar .d2 { animation-delay: 2.3s; }
  .radar .d3 { animation-delay: 3.2s; }
  @keyframes found {
    0%, 100% { opacity: .55; transform: scale(1); box-shadow: none; }
    8%       { opacity: 1;   transform: scale(1.18); box-shadow: 0 0 0 6px hsl(var(--primary) / .18); }
    20%      { opacity: .55; transform: scale(1); box-shadow: none; }
  }
}

.src-title { text-align: center; }
/* One line at a time, softly swapped. min-height stops the layout breathing as
   messages of different lengths rotate through. */
.src-msg {
  text-align: center;
  min-height: 3.2em;
  margin-bottom: 1.25rem;
  transition: opacity .4s var(--ease);
}
.src-msg.swap { opacity: 0; }

.opt {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  gap: .7rem; align-items: center;
  width: 100%; text-align: left;
  border: 1.5px solid hsl(var(--border));
  border-radius: var(--r-md);
  background: hsl(var(--background));
  /* Buttons do NOT inherit text colour — the UA default is near-black, which made
     "Option A" and the price camouflage into the dark card (founder screenshot). */
  color: hsl(var(--foreground));
  padding: .8rem .85rem; margin-bottom: .55rem;
  font: inherit; cursor: pointer;
}
.opt.sel { border-color: hsl(var(--primary)); box-shadow: 0 0 0 3px hsl(var(--ring) / .16); }
.opt .radio {
  width: 1.05rem; height: 1.05rem; border-radius: 50%;
  border: 2px solid hsl(var(--border-strong, var(--border)));
}
.opt.sel .radio {
  border-color: hsl(var(--primary));
  background: radial-gradient(circle at center, hsl(var(--primary)) 45%, transparent 50%);
}
.opt .on { font-weight: 800; font-size: .92rem; }
.opt .os { font-size: .74rem; color: hsl(var(--muted-foreground)); }
.opt .op { font-weight: 800; font-variant-numeric: tabular-nums; text-align: right; }
.opt .tag {
  display: block; font-size: .58rem; font-weight: 800;
  text-transform: uppercase; letter-spacing: .05em; color: hsl(var(--accent));
}

/* ── Quote ─────────────────────────────────────────────────────────────────── */
.quote-line, .quote-total {
  display: flex; justify-content: space-between; gap: 1rem;
  font-variant-numeric: tabular-nums;
}
.quote-line { font-size: .9rem; padding: .45rem 0; border-top: 1px solid hsl(var(--border)); }
.quote-total {
  font-size: 1.1rem; font-weight: 800; padding-top: .7rem; margin-top: .3rem;
  border-top: 2px solid hsl(var(--border));
}
.quote-item { display: flex; justify-content: space-between; gap: 1rem; font-size: .9rem; padding: .35rem 0; }
.quote-item .sub { color: hsl(var(--muted-foreground)); font-size: .78rem; }

/* ── Track ─────────────────────────────────────────────────────────────────── */
.otp-card { text-align: center; margin-bottom: 1.25rem; }
.otp-digits { display: flex; justify-content: center; gap: .5rem; margin-top: .6rem; }
.otp-digits span {
  width: 2.6rem; height: 3rem; border-radius: var(--r-md);
  background: var(--gradient-primary); color: hsl(var(--primary-foreground));
  display: grid; place-items: center;
  font-size: 1.35rem; font-weight: 800; font-variant-numeric: tabular-nums;
}

.timeline { list-style: none; margin: 1.25rem 0 0; padding: 0; }
.timeline li {
  position: relative; padding: 0 0 1.25rem 1.85rem;
  font-size: .93rem; color: hsl(var(--muted-foreground));
}
.timeline li::before {
  content: ""; position: absolute; left: .3rem; top: .45rem;
  width: .65rem; height: .65rem; border-radius: 50%;
  background: hsl(var(--border));
}
/* The connecting line stops at the last step rather than trailing into nothing. */
.timeline li:not(:last-child)::after {
  content: ""; position: absolute; left: .58rem; top: 1.1rem; bottom: 0;
  width: 2px; background: hsl(var(--border));
}
.timeline li.done { color: hsl(var(--foreground)); font-weight: 700; }
.timeline li.done::before { background: hsl(var(--primary)); }
.timeline li.done:not(:last-child)::after { background: hsl(var(--primary) / .45); }
.timeline li.now { color: hsl(var(--primary)); font-weight: 800; }
.timeline li.now::before { background: hsl(var(--primary)); box-shadow: 0 0 0 4px hsl(var(--primary) / .18); }

/* ── Modular medicine entry ────────────────────────────────────────────────── */
.addmed { padding: 1rem; }
.addmed-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: .6rem;
  align-items: center;
}
.addmed .stepper { align-self: stretch; }
.btn.slim { min-height: 2.6rem; margin-top: .7rem; font-size: .88rem; }

/* ── Paired address fields ─────────────────────────────────────────────────── */
.field-pair {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: .75rem;
}

/* ── Prescription pages strip ──────────────────────────────────────────────── */
.rx-card { margin-top: 1rem; padding: 1rem 1.1rem; }
.rx-card .card-title { display: flex; align-items: baseline; gap: .5rem; }
.rx-count-badge {
  font-size: .7rem; font-weight: 800;
  color: hsl(var(--primary));
  background: hsl(var(--secondary));
  border-radius: var(--r-pill);
  padding: .15rem .6rem;
}
.rx-strip { display: flex; gap: .7rem; margin-top: .8rem; flex-wrap: wrap; }
.rx-page { position: relative; }
.rx-page img, .rx-page .rx-pdf {
  width: 4.2rem; height: 5.4rem;
  object-fit: cover;
  border-radius: .6rem;
  border: 1.5px solid hsl(var(--border));
  display: grid; place-items: center;
  background: hsl(var(--muted));
  font-size: 1.4rem;
}
.rx-page .rx-x {
  position: absolute; top: -.45rem; right: -.45rem;
  width: 1.4rem; height: 1.4rem;
  border-radius: 50%;
  border: 0;
  background: hsl(var(--foreground));
  color: hsl(var(--background));
  font-size: .85rem; font-weight: 800; line-height: 1;
  cursor: pointer;
}
.rx-page .rx-label {
  display: block; text-align: center;
  font-size: .62rem; color: hsl(var(--muted-foreground));
  margin-top: .25rem;
}
.upload.disabled { opacity: .5; pointer-events: none; }

/* Camera + gallery, side by side. The disabled class lands on the ROW now (the id
 * moved with it), so at the page cap both doors close together. */
.upload-row { display: grid; grid-template-columns: 1fr 1fr; gap: .6rem; }
.upload-row.disabled { opacity: .5; pointer-events: none; }
.upload-row .upload { padding: 0 .5rem; font-size: .88rem; white-space: nowrap; }


/* ── Timeline ticks: a completed stage says so ──────────────────────────────── */
.timeline li.done::before {
  content: "✓";
  width: 1.1rem; height: 1.1rem;
  left: .08rem; top: .28rem;
  background: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
  display: grid; place-items: center;
  font-size: .68rem; font-weight: 800;
}
.timeline li.done:not(:last-child)::after { left: .58rem; top: 1.3rem; }

/* ── Feedback ──────────────────────────────────────────────────────────────── */
.stars { display: flex; gap: .4rem; margin: .4rem 0 1rem; }
.stars button {
  border: 0; background: transparent; cursor: pointer;
  font-size: 2.1rem; line-height: 1;
  color: hsl(var(--border));
  transition: color .15s var(--ease), transform .15s var(--ease);
}
.stars button.on { color: #FFC53D; transform: scale(1.08); }
.fb-help {
  display: flex; gap: .6rem; align-items: flex-start;
  font-size: .85rem; color: hsl(var(--muted-foreground));
  margin-top: .9rem; cursor: pointer;
}
.fb-help input { margin-top: .2rem; accent-color: hsl(var(--primary)); }

/* ── DPDP consent block (verify screen) ────────────────────────────────────── */
.consent { text-align: left; }
.consent-list {
  margin: .6rem 0 0; padding-left: 1.1rem;
  font-size: .85rem; color: hsl(var(--muted-foreground));
  display: grid; gap: .35rem;
}
.consent .card-foot a { color: hsl(var(--primary)); font-weight: 600; }

/* The erasure button: quiet like every ghost, but its color says what it is. */
.btn.danger { color: hsl(var(--destructive)); }


/* ── Rx strip: pending + add-page tiles ────────────────────────────────────── */
.rx-pending img, .rx-pending .rx-pdf { opacity: .45; }
.rx-pending::after {
  content: "";
  position: absolute; top: 2.2rem; left: 50%; margin-left: -.55rem;
  width: 1.1rem; height: 1.1rem;
  border: 2px solid hsl(var(--primary)); border-top-color: transparent;
  border-radius: 50%;
  animation: spin .7s linear infinite;
}
.rx-add {
  cursor: pointer;
  /* It became a <button> when adding a page grew two sources (camera/gallery), so
   * the UA's button chrome has to go — the dashed .rx-plus box IS the visual. */
  border: 0; background: transparent; padding: 0;
  font: inherit; color: inherit; text-align: center;
}
.rx-add .rx-plus {
  width: 4.2rem; height: 5.4rem;
  border: 1.5px dashed hsl(var(--primary) / .5);
  border-radius: .6rem;
  display: grid; place-items: center;
  font-size: 1.6rem; font-weight: 700;
  color: hsl(var(--primary));
  background: hsl(var(--secondary) / .3);
}

/* ══ Dynamics pass (founder ask, 2026-08-22) ══════════════════════════════════
   Welcome/location split, the shared overlay, and motion. Every animation here is
   killed wholesale by the prefers-reduced-motion block above — additive only. */

/* ── Welcome screen ─────────────────────────────────────────────────────────── */
/* The welcome hero owns the whole viewport: brand breathes, CTA sits low where a
   thumb already is. min-height (not height) so tiny screens still just scroll. */
.hero-tall {
  min-height: calc(100dvh - 6.5rem);   /* the footer stays visible below */
  display: flex; flex-direction: column; justify-content: center;
  padding-top: 3.25rem; padding-bottom: 3rem;
}
.welcome-cta { margin: 2rem auto 0; width: 100%; max-width: 19rem; }

/* Staggered entrance: each hero element arrives a beat after the last. Runs once
   per display change, which is exactly when the screen appears. */
.screen.active .hero-tall .brand-logo   { animation: rise .5s var(--ease) both; }
.screen.active .hero-tall .brand-greeting { animation: rise .5s var(--ease) .08s both; }
.screen.active .hero-tall h1            { animation: rise .5s var(--ease) .16s both; }
.screen.active .hero-tall .brand-line   { animation: rise .5s var(--ease) .24s both; }
.screen.active .hero-tall .trust        { animation: rise .5s var(--ease) .34s both; }
.screen.active .hero-tall .welcome-cta  { animation: rise .5s var(--ease) .44s both; }

/* ── Slim hero (location screen) ────────────────────────────────────────────── */
.hero-slim { padding: 1.7rem 1.25rem 2.7rem; text-align: left; }
.hero-slim h1 { font-size: 1.35rem; line-height: 1.25; }
.loc-back { padding: 0 1.25rem; margin-top: 1rem; }

/* The options card needs air below the sourcing title once the radar retires. */
#options-card { margin-top: 1.1rem; }

/* ── Card stagger on every screen ───────────────────────────────────────────── */
/* Direct children only: rows re-rendered by polling live deeper and must not
   replay an entrance on every 5s tick. */
.screen.active > .card        { animation: rise .5s var(--ease) .08s both; }
.screen.active > .card + .card { animation-delay: .16s; }
.screen.active > .stack       { animation: rise .5s var(--ease) .16s both; }

/* ── Touch feedback ─────────────────────────────────────────────────────────── */
.btn { transition: transform .12s var(--ease), box-shadow .2s var(--ease), opacity .2s; }
.btn:active:not(:disabled) { transform: scale(.965); }
.opt { transition: transform .12s var(--ease), border-color .2s, background .2s; }
.opt:active { transform: scale(.98); }

/* ── The overlay ────────────────────────────────────────────────────────────── */
.overlay {
  position: fixed; inset: 0; z-index: 60;
  display: grid; place-items: center;
  padding: 1.25rem;
}
.overlay[hidden] { display: none; }
.overlay-backdrop {
  position: absolute; inset: 0;
  background: hsl(var(--foreground) / .45);
  backdrop-filter: blur(3px);
  animation: ov-fade .25s both;
}
.overlay-card {
  position: relative; z-index: 1;
  width: 100%; max-width: 21rem;
  background: hsl(var(--card));
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  padding: 1.9rem 1.4rem 1.6rem;
  text-align: center;
  animation: ov-pop .38s var(--ease) both;
}
.overlay-icon {
  min-height: 3.1rem; font-size: 2.5rem;
  display: flex; align-items: center; justify-content: center;
  margin-bottom: .55rem;
}
.overlay-title { font-size: 1.12rem; font-weight: 800; }
.overlay-sub { font-size: .89rem; color: hsl(var(--muted-foreground)); margin-top: .45rem; }
.overlay-sub:empty { display: none; }
.overlay-actions { margin-top: 1.35rem; }
.overlay-x {
  position: absolute; top: .45rem; right: .65rem;
  width: 2.1rem; height: 2.1rem;
  border: 0; border-radius: 50%; background: transparent;
  font-size: 1.35rem; line-height: 1; color: hsl(var(--muted-foreground));
  cursor: pointer;
}
.overlay-x:active { background: hsl(var(--muted)); }
@keyframes ov-fade { from { opacity: 0; } }
@keyframes ov-pop {
  from { opacity: 0; transform: scale(.92) translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* The overlay's own spinner — bigger than the button one, same vocabulary. */
.spinner-lg {
  width: 2.5rem; height: 2.5rem;
  border: 3px solid hsl(var(--secondary));
  border-top-color: hsl(var(--primary));
  border-radius: 50%;
  animation: spin .9s linear infinite;
}
/* The success tick pops with a little overshoot — the one place a bounce earns it. */
.ov-tick { animation: tick-pop .5s cubic-bezier(.34, 1.56, .64, 1) both; }
@keyframes tick-pop { from { opacity: 0; transform: scale(.4); } to { opacity: 1; transform: none; } }

/* ── Delivery handover code ──────────────────────────────────────────────────
   Deliberately the loudest thing on the tracking screen. It is read aloud, once, to
   someone standing at the door — often outdoors, often in a hurry — so it is sized and
   spaced to be legible at arm's length rather than styled to match the copy around it. */
.otp-card {
  margin-top: 1.4rem;
  padding: 1.1rem 1rem 1.2rem;
  border-radius: var(--r-lg);
  background: hsl(var(--secondary));
  border: 1px solid hsl(var(--primary) / .25);
  text-align: center;
}
.otp-label {
  font-size: .78rem; font-weight: 800;
  letter-spacing: .09em; text-transform: uppercase;
  color: hsl(var(--primary));
}
.otp-code {
  margin-top: .45rem;
  font-size: 2.6rem; font-weight: 800; line-height: 1.1;
  /* Tabular figures so the digits sit on an even rhythm, and generous tracking so 1 and
     7, or 0 and 8, are not misheard when read out. */
  font-variant-numeric: tabular-nums;
  letter-spacing: .22em; text-indent: .22em;
  color: hsl(var(--foreground));
}
.otp-hint {
  margin-top: .5rem;
  font-size: .8rem; font-weight: 600;
  color: hsl(var(--muted-foreground));
}

/* ── My orders ─────────────────────────────────────────────────────────────── */
.ordrow {
  display: block; width: 100%;
  margin-top: .75rem; padding: .95rem 1rem;
  border: 1px solid hsl(var(--border));
  border-radius: var(--r-md);
  background: hsl(var(--card));
  text-align: left; font: inherit; color: inherit;
  cursor: pointer;
  transition: border-color .15s, box-shadow .15s;
}
.ordrow:hover, .ordrow:focus-visible { border-color: hsl(var(--ring)); box-shadow: var(--shadow-soft); }
/* A live order is why most people open this list, so it is marked, not just sorted. */
.ordrow.live { border-color: hsl(var(--primary) / .45); background: hsl(var(--secondary) / .5); }
.ordrow-top { display: flex; align-items: center; gap: .55rem; }
.ordrow-ref { font-weight: 800; font-size: .93rem; font-variant-numeric: tabular-nums; }
.ordrow-pill {
  font-size: .68rem; font-weight: 800;
  letter-spacing: .05em; text-transform: uppercase;
  padding: .16rem .5rem; border-radius: 999px;
  background: hsl(var(--primary)); color: hsl(var(--primary-foreground));
}
.ordrow-meds {
  margin-top: .3rem;
  font-size: .88rem; color: hsl(var(--foreground));
  /* One line: a long medicine list must not turn every row into a paragraph. */
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ordrow-foot {
  display: flex; justify-content: space-between; gap: .75rem;
  margin-top: .45rem;
  font-size: .79rem; font-weight: 600;
  color: hsl(var(--muted-foreground));
}
