/* Empaisa components. Tokens only (tokens.css): no colour literals here.
   The shell is one grid on 100dvh: the screen (its own header, then content
   that scrolls) and the bottom nav. A wider screen is a wider phone. */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: var(--text-m);
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
}
html[lang="ta"] body { font-family: var(--font-ta); }
html[lang="ar"] body { font-family: var(--font-ar); }
html[lang="te"] body { font-family: var(--font-te); }
html[lang="ml"] body { font-family: var(--font-ml); }
html[lang="kn"] body { font-family: var(--font-kn); }
html[lang="hi"] body { font-family: var(--font-hi); }
html[lang="si"] body { font-family: var(--font-si); }
/* Right to left (Arabic): arrows that mean back or forward point the other way. */
[dir="rtl"] .icon.flip { transform: scaleX(-1); }
h1, h2, h3, p { margin: 0; }
a { color: var(--accent); }
a:hover { color: var(--accent-hover); }
button, input, select, textarea { font: inherit; color: inherit; }
input, select, textarea, select.chip { font-size: var(--text-field); }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
/* A dialog's close button sits at its edge, which cut the ring outside it: draw it inside. */
dialog .icon-btn:focus-visible { outline-offset: -3px; }
.sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}
svg.icon { width: 22px; height: 22px; flex: 0 0 auto; }
svg.icon-s { width: 16px; height: 16px; }
svg.icon-l { width: 46px; height: 46px; }

/* --- shell ---------------------------------------------------------------- */
.shell {
  display: grid;
  grid-template-rows: 1fr auto;
  height: 100dvh;
  /* the smaller of the two: --app-h is the window's own height (app.js), for the phones whose
     100dvh reaches under the system bar and hid the tab bar */
  height: min(100dvh, var(--app-h, 100dvh));
  max-width: 480px;
  margin-inline: auto;
  padding: env(safe-area-inset-top) env(safe-area-inset-right) 0 env(safe-area-inset-left);
  background: var(--bg);
}
.shell > main {
  display: grid;
  grid-template-rows: auto 1fr;
  min-height: 0;
  overflow: hidden;
}
/* Pinned to the top, not centred: titles take one line or two (Shop's
   shop name and date), and centring moved the mark and the avatar from tab
   to tab. Detail headers (back, title, action) stay centred on each other. */
.bar {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: start;
  gap: var(--space-2);
  padding: var(--space-5) var(--space-5) var(--space-3);
}
.bar h1 { font-size: var(--text-xl); font-weight: 700; }
.bar.detail { align-items: center; }
.bar .chips { align-items: center; }
.bar.detail h1 { font-size: var(--text-l); text-align: center; }
.bar .kicker {
  display: block;
  font-size: var(--text-xs); font-weight: 600; color: var(--muted);
  letter-spacing: 0.04em; text-transform: uppercase;
}
.bar .aside { font-size: var(--text-s); color: var(--muted); font-weight: 600; }
.screen {
  display: grid;
  align-content: start;
  gap: var(--space-4);
  padding: 0 var(--space-5) var(--space-6);
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* Bottom nav: Shop · Items · mic · Money · Dues, mic raised. */
.tabs {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  align-items: center;
  min-height: 72px;
  padding: 0 var(--space-2) env(safe-area-inset-bottom);
  border-top: 1px solid var(--border);
  background: var(--bg);
  /* The raised mic reaches up over the page: the nav sits above it, or a
     card with its own layer (a stretched link) covers the mic. */
  position: relative; z-index: 3;
}
.tabs a {
  display: grid; justify-items: center; gap: var(--space-1);
  min-height: var(--touch); padding-block: var(--space-2);
  color: var(--muted); font-size: var(--text-xs); font-weight: 600; text-decoration: none;
}
.tabs a[aria-current="page"] { color: var(--ink); font-weight: 700; }
.tabs .mic-tab { display: grid; justify-items: center; }
/* A live part of a screen (refetched as a whole) lays out like the screen itself. */
.screen-part { display: grid; gap: var(--space-3); min-width: 0; }
/* More (canvas artboard 40): an icon, then the name and what is inside. */
.row.more-row { grid-template-columns: auto minmax(0, 1fr); justify-items: start; min-height: 60px; }
.row.more-row .main { text-align: start; }

/* --- the top-right menu (MedicDay's who-menu, canvas artboard 17) ---------- */
.who-bar { display: flex; align-items: center; gap: var(--space-2); }
/* the language picker before it: a globe and the code ("EN"), the select over it, unseen, so a
   tap opens the phone's own list of the languages by name; it fits beside any header's controls */
.app-lang { position: relative; flex: none; }
.app-lang-face { display: inline-flex; align-items: center; gap: 4px; min-height: var(--touch); padding-inline: var(--space-2); border: 1px solid var(--border); border-radius: var(--radius-m); background: var(--surface); color: var(--ink); font-size: var(--text-s); font-weight: 700; }
.app-lang-face .icon { width: 18px; height: 18px; }
.app-lang-face .code { text-transform: uppercase; }
.app-lang select { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; font-size: 16px; }
.app-lang:focus-within .app-lang-face { outline: 3px solid var(--focus); outline-offset: 2px; }
.who-menu { position: relative; }
.who-menu > summary { list-style: none; cursor: pointer; border-radius: 50%; }
.who-menu > summary::-webkit-details-marker { display: none; }
.who-menu > summary:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.avatar { width: var(--touch); height: var(--touch); border-radius: 50%; display: grid; place-items: center;
  background: var(--accent-bg); color: var(--accent); font-size: var(--text-s); font-weight: 700; }
.who-menu[open] .avatar { box-shadow: 0 0 0 2px var(--accent); }
.who-menu .menu { position: absolute; inset-inline-end: 0; top: calc(100% + 8px); z-index: 20; min-width: 15rem;
  display: flex; flex-direction: column; padding: var(--space-1); background: var(--bg);
  border: 1px solid var(--border); border-radius: var(--radius-m); box-shadow: var(--shadow); }
.who-menu .menu a, .who-menu .menu button { display: flex; align-items: center; min-height: var(--touch); width: 100%;
  padding: 0 var(--space-3); border: 0; border-radius: var(--radius-s); background: none; color: var(--ink);
  font: inherit; text-align: start; text-decoration: none; cursor: pointer; }
.who-menu .menu a:hover, .who-menu .menu button:hover { background: var(--surface); }
.who-menu .menu-who { display: flex; flex-direction: column; gap: 2px; padding: var(--space-2) var(--space-3);
  margin-bottom: var(--space-1); border-bottom: 1px solid var(--border); overflow-wrap: anywhere; }
.who-menu .menu-who small { font-size: var(--text-s); color: var(--muted); }
.who-menu .menu form { border-top: 1px solid var(--border); margin-top: var(--space-1); padding-top: var(--space-1); }
.who-menu .menu form button { color: var(--warn-ink); font-weight: 600; }

/* --- the settings shell (MedicDay's, canvas artboard 18): pills on a phone - */
/* One column no wider than the screen: sized to its content, the pill strip
   would widen to fit every pill and be cut off instead of scrolling. */
.settings-shell { display: grid; grid-template-rows: auto minmax(0, 1fr); grid-template-columns: minmax(0, 1fr); min-height: 0; }
.settings-nav { border-bottom: 1px solid var(--border); min-width: 0; }
.settings-nav-group { display: none; }
.settings-nav-scroll { display: flex; gap: var(--space-1); overflow-x: auto; scrollbar-width: none; padding: var(--space-1) var(--space-4) var(--space-3); }
.settings-nav-scroll::-webkit-scrollbar { display: none; }
/* A row of filter chips (Money): one line that scrolls sideways, edge to edge of the screen. */
.chips.chip-strip {
  flex-wrap: nowrap; align-items: center; overflow-x: auto; overflow-y: hidden; scrollbar-width: none;
  overscroll-behavior-x: contain; margin-inline: calc(-1 * var(--space-5)); padding-inline: var(--space-5);
  /* Safari gives a scrolling grid item no height of its own: the row would vanish */
  min-height: calc(var(--touch) + var(--space-1)); flex-shrink: 0;
}
.chip-strip::-webkit-scrollbar { display: none; }
.chip-strip > * { flex: none; }
.settings-nav a { flex: 0 0 auto; display: flex; align-items: center; min-height: var(--touch); padding: 0 var(--space-3);
  border-radius: 999px; color: var(--muted); font-weight: 600; text-decoration: none; white-space: nowrap; }
.settings-nav a[aria-current="page"] { background: var(--accent-bg); color: var(--accent); font-weight: 700; }
.settings-main { padding-top: var(--space-4); }
/* A page's own sub-pages (CSupport -> Messaging: WhatsApp settings, Message templates) */
.sub-tabs { display: flex; gap: var(--space-1); overflow-x: auto; scrollbar-width: none; margin-block-end: var(--space-3); }
.sub-tabs a { flex: 0 0 auto; display: flex; align-items: center; min-height: var(--touch); padding: 0 var(--space-3);
  border-radius: 999px; color: var(--muted); font-weight: 600; text-decoration: none; white-space: nowrap; }
.sub-tabs a[aria-current="page"] { background: var(--accent-bg); color: var(--accent); font-weight: 700; }

/* --- loading (canvas artboard 20) -------------------------------------------
   Pressed at once: anything tappable dips to 98% and dims under the finger,
   before any answer. While its request runs, the tapped link or button stays
   dim and cannot be tapped twice; Save, Cash, UPI and Credit show a spinner
   in place of the label, same size. A screen loading shows its skeleton (app.js): a screen's
   shape in grey over <main>, a wave of light running down it, block after block. */
.shell > main { position: relative; }
.skeleton {
  /* over the screen's own layers (1), under the tab bar (3), so the raised mic stays on top */
  position: absolute; inset: 0; z-index: 2; display: grid; align-content: start; gap: var(--space-3);
  padding: var(--space-4); background: var(--bg); pointer-events: none;
  animation: sk-in 140ms ease-out both;
}
.sk-head { display: flex; justify-content: space-between; align-items: center; min-height: var(--touch); }
.sk { display: block; border-radius: var(--radius-s); background: var(--surface); animation: sk-wave 1.2s ease-in-out infinite both; }
.sk-title { width: 42%; height: 22px; }
.sk-dot { width: 36px; height: 36px; border-radius: 50%; }
.sk-line { width: 64%; height: 14px; }
.sk-card { height: 96px; border-radius: var(--radius-m); }
.sk-row { height: 52px; }
.skeleton > .sk:nth-child(2) { animation-delay: 80ms; }
.skeleton > .sk:nth-child(3) { animation-delay: 160ms; }
.skeleton > .sk:nth-child(4) { animation-delay: 240ms; }
.skeleton > .sk:nth-child(5) { animation-delay: 320ms; }
.skeleton > .sk:nth-child(6) { animation-delay: 400ms; }
.skeleton > .sk:nth-child(7) { animation-delay: 480ms; }
.skeleton > .sk:nth-child(8) { animation-delay: 560ms; }
/* A part of a screen loading (a target with data-skeleton, a Money chip): what
   it held hides but its chip strip, and the rows' skeleton sits in its place,
   in the flow. */
.skeleton.part { position: static; inset: auto; z-index: auto; padding: 0; background: none; }
[data-skeleton].sk-loading > :not(.chip-strip):not(.skeleton) { display: none; }
@keyframes sk-in { from { opacity: 0; } }
@keyframes sk-wave { 0%, 100% { background: var(--surface); } 50% { background: var(--surface-2); } }
@media (prefers-reduced-motion: reduce) { .sk, .skeleton { animation: none; } }
:is(button, .btn, .chip, .row, .icon-btn, .tabs a, a.main, .line .name, .qty-tap):not(.mic) {
  -webkit-tap-highlight-color: transparent;
  transition: transform 80ms ease-out, opacity 80ms ease-out;
}
:is(button, .btn, .chip, .row, .icon-btn, .tabs a, a.main):not(.mic):not(:disabled):active {
  transform: scale(0.98); opacity: 0.7;
}
:is(a, button).htmx-request:not(.mic), form.htmx-request button[type="submit"] {
  opacity: 0.6; pointer-events: none; cursor: progress;
}
:is(form.htmx-request button[type="submit"], button.htmx-request, a.htmx-request):is(.primary, .strong, .warn, .danger) {
  position: relative; color: transparent; opacity: 0.85;
}
:is(form.htmx-request button[type="submit"], button.htmx-request, a.htmx-request):is(.primary, .strong, .warn, .danger)::after {
  content: ""; position: absolute; inset: 0; margin: auto; width: 18px; height: 18px;
  border: 2px solid var(--spin, currentColor); border-top-color: transparent; border-radius: 50%;
  animation: spin 0.9s linear infinite;
}
.btn.primary { --spin: var(--accent-ink); }
.btn.strong { --spin: var(--strong-ink); }
.btn.warn { --spin: var(--warn-ink); }
.btn.danger { --spin: var(--on-warn); }
@media (prefers-reduced-motion: reduce) {
  :is(button, .btn, .chip, .row, .icon-btn, .tabs a, a.main):not(.mic):active { transform: none; }
}

/* --- the mic ---------------------------------------------------------------- */
.mic {
  display: grid; place-items: center;
  width: 64px; height: 64px;
  margin-top: -36px;
  border: 0; border-radius: 50%;
  background: var(--accent); color: var(--accent-ink);
  box-shadow: 0 0 0 6px var(--bg);
  cursor: pointer;
  touch-action: none;
  user-select: none; -webkit-user-select: none;
  -webkit-touch-callout: none; /* iOS: no long-press menu over a held mic */
}
.mic.big { width: 112px; height: 112px; margin: 0; box-shadow: none; }
.mic svg { width: 28px; height: 28px; }
.mic.big svg { width: 46px; height: 46px; }
.mic.is-listening { background: var(--warn); color: var(--on-warn); animation: pulse 1.2s ease-in-out infinite; }
@keyframes pulse { 50% { transform: scale(1.06); } }
@media (prefers-reduced-motion: reduce) { .mic.is-listening { animation: none; } }
.mic .spinner { display: none; width: 26px; height: 26px; border-width: 3px; }
.mic.is-busy { cursor: progress; }
.mic.is-busy svg { display: none; }
.mic.is-busy .spinner { display: block; }

/* What the mic is doing, just above the nav: listening (with a clock), or
   "hold the mic" after a tap. After letting go, the progress dialog. */
[x-cloak] { display: none !important; }

/* A screen change cross-fades (app.js); the tab bar is captured on its own,
   so it does not fade. */
.tabs { view-transition-name: tabs; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: 0.12s; }
.voice-status {
  position: fixed; z-index: 5;
  inset-inline: max(var(--space-4), calc(50% - 224px));
  bottom: calc(96px + env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-l);
  background: var(--strong); color: var(--strong-ink);
  font-weight: 600;
}
.voice-status .voice-aside { margin-inline-start: auto; font-size: var(--text-s); font-weight: 500; opacity: 0.75; }
.voice-status .voice-cancel {
  min-height: var(--touch); padding: 0 var(--space-3); margin-block: calc(-1 * var(--space-2));
  border: 0; border-radius: var(--radius-pill); background: transparent; color: inherit;
  font: inherit; font-weight: 700; text-decoration: underline; cursor: pointer;
}
.voice-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--warn); flex: 0 0 auto; }
.spinner {
  width: 16px; height: 16px; flex: 0 0 auto;
  border: 2px solid currentColor; border-top-color: transparent; border-radius: 50%;
  animation: spin 0.9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation-duration: 3s; } }
.snap-pick { position: relative; display: grid; grid-auto-flow: column; justify-content: center; gap: var(--space-2); cursor: pointer; }
.snap-pick input[type="file"] { position: absolute; inset: 0; opacity: 0; cursor: pointer; }
.snap-pick:has(input:focus-visible) { outline: 3px solid var(--focus); }
.snap-reading { justify-items: center; text-align: center; padding-block: var(--space-6); }
.snap-reading .spinner { width: 32px; height: 32px; border-width: 3px; color: var(--accent); }
.snap-lines { display: grid; gap: var(--space-3); }
.snap-line { display: grid; gap: var(--space-2); padding: var(--space-3); border: 1px solid var(--border); border-radius: var(--radius-m); }
.snap-line.unsure { border: 2px solid var(--warn); background: var(--warn-bg); }
.snap-line .printed { overflow-wrap: anywhere; }
.snap-line .snap-n { color: var(--muted); font-variant-numeric: tabular-nums; }
.snap-line.bad { border: 2px solid var(--warn-ink); scroll-margin-top: var(--space-4); }
.warn-text { color: var(--warn-ink); font-weight: 700; }
.sent-note { display: inline-flex; align-items: center; gap: var(--space-1); min-height: var(--touch); color: var(--accent); font-size: var(--text-s); font-weight: 700; }
.sent-note svg { width: 18px; height: 18px; }
dialog.alert .replay { display: flex; align-items: center; justify-content: center; gap: var(--space-2); }
dialog.alert .replay .icon { width: 20px; height: 20px; }
dialog.alert .replay-icon { display: inline-flex; }
dialog.alert .replay-box { display: grid; gap: var(--space-2); }
/* How far the replay has played (canvas artboard 11). */
.replay-track { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--space-3); align-items: center; }
.replay-track progress {
  appearance: none; -webkit-appearance: none; width: 100%; height: 6px;
  border: 0; border-radius: var(--radius-pill); background: var(--border); overflow: hidden;
}
.replay-track progress::-webkit-progress-bar { background: var(--border); border-radius: var(--radius-pill); }
.replay-track progress::-webkit-progress-value { background: var(--accent); border-radius: var(--radius-pill); }
.replay-track progress::-moz-progress-bar { background: var(--accent); border-radius: var(--radius-pill); }
.replay-time { font-size: var(--text-s); font-weight: 600; color: var(--muted); font-variant-numeric: tabular-nums; }
dialog.alert .replay-note { margin: 0; font-size: var(--text-s); color: var(--muted); text-align: center; }
dialog.alert .alert-title { font-size: var(--text-l); font-weight: 700; }
/* The mic's status is a sheet from the top (canvas artboard 28), shown without a backdrop: the
   bill behind stays in view and fills in, then the sheet says what went on it and slides away. */
dialog.voice-progress[open] {
  position: fixed; inset: 0 0 auto 0; z-index: 20;
  display: grid; gap: var(--space-3);
  width: 100%; max-width: 480px; margin: 0 auto;
  padding: calc(env(safe-area-inset-top) + var(--space-4)) var(--space-5) var(--space-4);
  border-radius: 0 0 var(--radius-l) var(--radius-l); box-shadow: var(--shadow);
  animation: slide-down 0.2s ease-out;
}
@keyframes slide-down { from { transform: translateY(-40px); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { dialog.voice-progress[open] { animation: none; } }
dialog.voice-progress .alert-title { font-size: var(--text-l); font-weight: 700; }
.voice-added { display: flex; align-items: center; gap: var(--space-2); margin: 0; color: var(--accent); font-weight: 600; }
.voice-added .icon { width: 18px; height: 18px; flex: none; }
/* A line the mic just added or grew flashes once. */
.line.fresh { animation: fresh-line 2.4s ease-out; }
@keyframes fresh-line { from { background: var(--accent-bg); } to { background: transparent; } }
@media (prefers-reduced-motion: reduce) { .line.fresh { animation: none; background: var(--accent-bg); } }

/* The mic's progress after letting go (canvas artboard 19): done steps get
   a tick on the accent, the running one a spinner, the rest a ring. */
/* What is it? (canvas artboard 36): four big answers, two by two; the chosen one dark. */
.voice-kind { display: grid; gap: var(--space-2); margin: 0; padding: 0; border: 0; min-width: 0; }
.voice-kind legend { padding: 0; margin-bottom: var(--space-2); font-size: var(--text-m); font-weight: 700; }
.voice-kind-buttons { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-2); }
.voice-kind-buttons .btn[aria-pressed="true"] { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.voice-kind-buttons .btn.wide { grid-column: 1 / -1; }
/* Tasks (canvas artboard 44): a circle to mark done, then the task. */
.task-row { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: var(--space-2); }
.task-row form { display: contents; }
.task-tick { display: grid; place-items: center; width: var(--touch); height: var(--touch); border: 0; background: none; color: transparent; cursor: pointer; }
.task-tick .icon { width: 26px; height: 26px; padding: 3px; border: 2px solid var(--muted); border-radius: 50%; box-sizing: border-box; }
.task-row.done .task-tick { color: var(--accent-ink); }
.task-row.done .task-tick .icon { background: var(--accent); border-color: var(--accent); }
.task-row.done .title { text-decoration: line-through; color: var(--muted); }
.task-due .buttons { display: grid; gap: var(--space-2); }
.steps { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-3); }
.steps li { display: grid; grid-template-columns: 22px minmax(0, 1fr); gap: var(--space-3); align-items: start; }
.steps .step-icon { display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; }
.steps .step-icon .icon { display: none; width: 14px; height: 14px; stroke-width: 3; }
.steps .step-icon .spinner { display: none; color: var(--accent); }
.steps .done .step-icon { background: var(--accent); color: var(--accent-ink); }
.steps .done .step-icon .icon { display: block; }
.steps .active .step-icon .spinner { display: block; }
.steps .waiting .step-icon { width: 14px; height: 14px; margin: 4px; border: 2px solid var(--border-strong); }
.steps .waiting { color: var(--muted); }
.steps .step-text { display: grid; gap: var(--space-1); min-width: 0; }
.steps .step-name { font-weight: 600; line-height: 22px; }
.steps .active .step-name { font-weight: 700; }
.steps .step-pct { color: var(--muted); font-weight: 600; font-variant-numeric: tabular-nums; }
.steps .step-note, .step-slow { font-size: var(--text-s); color: var(--muted); margin: 0; }
.steps .step-words { display: block; margin-top: var(--space-1); padding: var(--space-2) var(--space-3); border-radius: var(--radius-s);
  background: var(--surface); font-size: var(--text-s); line-height: 1.4; overflow-wrap: anywhere; }

/* Shop: what to say, and typing it (the mic is the nav's). */
.speak {
  display: grid; gap: var(--space-3);
  padding: var(--space-4);
  border-radius: var(--radius-l); background: var(--surface);
}
.speak .hint { margin: 0; font-size: var(--text-s); color: var(--muted); line-height: 1.4; }
.speak .chips { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.speak .search { background: var(--bg); }
.speak .chip { background: var(--bg); }
.say-form { display: grid; grid-template-columns: 1fr auto; gap: var(--space-2); width: 100%; }

/* --- building blocks --------------------------------------------------------- */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: var(--space-3); }
.stat {
  display: grid; gap: var(--space-1);
  padding: var(--space-4) var(--space-3);
  border-radius: var(--radius-m); background: var(--surface);
}
.stat .label { font-size: var(--text-xs); font-weight: 600; color: var(--muted); }
.stat .value { font-size: 20px; font-weight: 700; }
.stat .sub { font-size: var(--text-xs); color: var(--muted); }
.in { color: var(--accent); }
.out { color: var(--warn); }

.section { display: grid; gap: var(--space-2); }
.section-head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-2); }
.badge.muted { background: var(--surface); color: var(--muted); }
.meter { height: 8px; border-radius: 4px; background: var(--surface); overflow: hidden; }
.meter span { display: block; height: 100%; background: var(--accent); }
.meter.over span { background: var(--warn); }
.cat-list { display: grid; gap: var(--space-3); }
.cat { display: grid; gap: var(--space-2); padding: var(--space-3) 0; border-bottom: 1px solid var(--border); }
.cat-head { display: flex; align-items: center; gap: var(--space-2); }
.cat-actions { margin-inline-start: auto; display: flex; gap: var(--space-1); }
.hidden-cat strong { color: var(--muted); }
.chip.off { opacity: 0.55; text-decoration: line-through; }
.inline-form { display: flex; gap: var(--space-2); align-items: center; }
.inline-form input { min-width: 0; flex: 1 1 auto; height: var(--touch); padding: 0 var(--space-3); border: 1px solid var(--border); border-radius: var(--radius-m); background: var(--bg); color: var(--ink); }
.add-sub { flex: 1 1 100%; }
.link-row { text-decoration: none; color: inherit; }
.section-head h2 { font-size: var(--text-m); font-weight: 700; }
.label-head {
  font-size: var(--text-s); font-weight: 700; color: var(--muted);
  letter-spacing: 0.04em; text-transform: uppercase;
}
.label-head.warn { color: var(--warn-ink); }

.list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.list.ruled { gap: 0; }
.row {
  display: grid; grid-template-columns: 1fr auto; align-items: center; gap: var(--space-3);
  min-height: var(--touch); padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-s); background: var(--surface);
  color: inherit; text-decoration: none;
}
a.row:hover { background: var(--surface-2); color: inherit; }
.ruled > li > .row { background: none; border-radius: 0; border-bottom: 1px solid var(--border); padding-inline: 0; }
.row.outlined { background: none; border: 1px solid var(--border); }
.row.alert { background: var(--warn-bg); border: 1px solid var(--warn-border); }
.row .main { display: grid; gap: 2px; min-width: 0; }
.row .title { font-weight: 600; overflow-wrap: anywhere; }
.row .meta { font-size: var(--text-s); color: var(--muted); }
.row .amount { font-weight: 700; text-align: end; white-space: nowrap; }
.row .end { display: grid; justify-items: end; gap: 2px; }
.row .end .meta { font-size: var(--text-xs); }
.badge {
  display: inline-block; padding: 2px var(--space-2); border-radius: var(--radius-s);
  font-size: var(--text-xs); font-weight: 700;
  background: var(--warn-bg); color: var(--warn-ink);
}
.empty { padding: var(--space-5); text-align: center; color: var(--muted); font-size: var(--text-s); }
/* Money -> Purchases (canvas artboard 22): by supplier, by item; a supplier's
   bills with their lines in a drawer. */
.purchases, .purchase-cols, .purchase-cols > section { display: grid; gap: var(--space-3); min-width: 0; }
/* Payment links (canvas artboards 26-27) */
.pay-link-box, .pay-link-sent { display: grid; gap: var(--space-2); }
.pay-link-box form { margin: 0; }
.pay-link-sent .meta span[dir="ltr"] { overflow-wrap: anywhere; }
.pay-page { gap: var(--space-4); padding-block: var(--space-5); }
.pay-head { display: grid; gap: var(--space-1); }
.pay-head p { margin: 0; }
.pay-amount { font-size: 40px; font-weight: 700; }
.pay-apps { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: var(--space-2); }
.pay-qr summary { font-weight: 600; cursor: pointer; }
.pay-qr .qr { display: grid; justify-items: center; padding-top: var(--space-3); }
.pay-done { background: var(--surface); }
/* Money -> Sales (canvas artboard 33) */
.sales { display: grid; gap: var(--space-4); min-width: 0; }
.mode-split { display: grid; gap: var(--space-2); }
/* All bills over a date range (canvas artboard 47) */
.range-form { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto; gap: var(--space-2); align-items: end; }
.bill-day { display: grid; gap: var(--space-2); }
.day-head { display: flex; justify-content: space-between; gap: var(--space-2); padding-top: var(--space-2); border-top: 1px solid var(--border); }
.mode-bar { display: flex; height: 12px; border-radius: 6px; overflow: hidden; background: var(--surface); }
.mode-bar span { min-width: 4px; }
.mode-cash { background: var(--accent); }
.mode-upi { background: var(--strong); }
.mode-credit { background: var(--warn); }
.mode-legend { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-4); margin: 0; padding: 0; list-style: none; font-size: var(--text-s); color: var(--muted); }
.mode-legend li { display: flex; align-items: center; gap: var(--space-1); }
.mode-legend .dot { width: 10px; height: 10px; border-radius: 50%; }
.day-bars { gap: var(--space-1); }
.day-bar { display: grid; grid-template-columns: 6.5rem minmax(0, 1fr) auto; gap: var(--space-3); align-items: center; min-height: var(--touch); color: inherit; text-decoration: none; }
.day-bar .day { font-size: var(--text-s); color: var(--muted); }
.day-bar .track { height: 10px; border-radius: 5px; background: var(--surface); overflow: hidden; }
.day-bar .fill { display: block; height: 100%; border-radius: 5px; background: var(--accent); }
.day-bar .amount { font-weight: 700; }
/* Money -> Accounts (canvas artboard 23) */
.accounts { display: grid; gap: var(--space-3); min-width: 0; }
.stat.wide .value { font-size: var(--text-xxl); }
.accounts .row.outlined { background: var(--bg); border: 1px solid var(--border); }
.card.payout { background: var(--warn-bg); border: 1px solid var(--warn-border); }
.card.payout p { margin: 0; }
.card.payout input[type="date"] { max-width: 11rem; }
.card.fee-card { display: grid; gap: var(--space-2); }
.card.fee-card p { margin: 0; }
.row.off { opacity: 0.6; }
/* A Service's bill: who it is for, first (canvas artboard 39). */
.bill-for { margin: 0 var(--space-4) var(--space-2); }
.bill-for .aside { font-weight: 700; color: var(--accent); }
/* An entry said by voice (canvas artboard 37): its (i) sits at the row's end, beside the row,
   never inside its link. */
.list li.with-said { position: relative; }
.list li.with-said > .row { padding-inline-end: calc(var(--touch) + var(--space-1)); }
.said-btn { color: var(--muted); }
.list li.with-said > .said-btn { position: absolute; inset-inline-end: var(--space-1); top: 50%; transform: translateY(-50%); }
.said { display: grid; gap: var(--space-4); }
.said-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-3); }
.said-list li { display: grid; gap: 2px; }
.said-list q { font-size: var(--text-l); line-height: 1.45; overflow-wrap: anywhere; }
.said-list .meta { font-size: var(--text-s); color: var(--muted); }
/* an expense's History and Settings -> Activity (docs/AUDIT.md): who, when, each change before -> after */
.expense-after { display: grid; gap: var(--space-4); padding-top: 0; }
.audit-list > li { display: grid; gap: 2px; padding-block: var(--space-2); }
.audit-changes { list-style: none; margin: var(--space-1) 0 0; padding: 0; display: grid; gap: 2px; }
.audit-changes li { display: grid; grid-template-columns: minmax(0, 7rem) minmax(0, 1fr); gap: var(--space-2); overflow-wrap: anywhere; }
/* the bill's photo in the dialog: the whole of it, a tap opens it full size */
.said-photo { display: block; }
.said-photo img { display: block; width: 100%; max-height: 60dvh; object-fit: contain; border-radius: var(--radius-m); background: var(--surface); }
.said-amended { display: grid; gap: 2px; margin: 0; padding-top: var(--space-3); border-top: 1px solid var(--border); }
.said-amended q { font-size: var(--text-l); line-height: 1.45; overflow-wrap: anywhere; font-weight: 600; }
.said-amended .meta { font-size: var(--text-s); color: var(--muted); }
.purchases .row.outlined { background: var(--bg); border: 1px solid var(--border); }
.purchase-bills { display: grid; gap: var(--space-3); }
.purchase-bill-head { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--space-3); align-items: start; }
.purchase-bill-head .main { display: grid; gap: 2px; min-width: 0; }
.purchase-bill-head .amount { font-weight: 700; white-space: nowrap; }
.purchase-lines { list-style: none; margin: var(--space-2) 0 0; padding: var(--space-2) 0 0; border-top: 1px solid var(--border); display: grid; gap: var(--space-1); }
.purchase-lines li { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--space-3); font-size: var(--text-s); color: var(--muted); }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  min-height: var(--touch); padding: 0 var(--space-4);
  border: 0; border-radius: var(--radius-m);
  background: var(--surface); color: var(--ink);
  font-weight: 700; text-decoration: none; cursor: pointer;
}
.btn:hover { background: var(--surface-2); color: var(--ink); }
.btn.primary { background: var(--accent); color: var(--accent-ink); }
.btn.primary:hover { background: var(--accent-hover); color: var(--accent-ink); }
.btn.strong { background: var(--strong); color: var(--strong-ink); }
.btn.warn { background: var(--warn-bg); color: var(--warn-ink); border: 2px solid var(--warn); }
.btn.danger { background: var(--warn); color: var(--on-warn); }
.btn.ghost { background: none; color: var(--muted); }
.btn.dashed { background: none; border: 1px dashed var(--border-strong); }
.btn.tall { min-height: 56px; font-size: var(--text-l); }
.btn.small { min-height: 36px; padding: 0 var(--space-3); font-size: var(--text-s); border-radius: var(--radius-s); }
.btn.block { width: 100%; }
.icon-btn {
  display: grid; place-items: center; width: var(--touch); height: var(--touch);
  border: 0; border-radius: 50%; background: none; color: var(--ink); text-decoration: none; position: relative;
}
.icon-btn.filled { background: var(--surface); }
.icon-btn .count {
  position: absolute; top: 4px; inset-inline-end: 4px; min-width: 18px; height: 18px; padding: 0 4px;
  border-radius: 9px; background: var(--warn); color: var(--on-warn);
  font-size: var(--text-xs); font-weight: 700; display: grid; place-items: center;
}
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 36px; padding: 0 var(--space-4); border: 0; border-radius: var(--radius-pill);
  background: var(--surface); color: var(--ink); font-size: var(--text-s); font-weight: 600;
  text-decoration: none; cursor: pointer;
}
.chip[aria-current="true"], .chip[aria-pressed="true"] { background: var(--strong); color: var(--strong-ink); }
.chips { display: flex; flex-wrap: wrap; gap: var(--space-2); }

.notice {
  display: grid; grid-template-columns: 1fr auto; align-items: center; gap: var(--space-3);
  padding: var(--space-3) var(--space-4); border-radius: var(--radius-m);
  background: var(--warn-bg); border: 1px solid var(--warn-border); color: var(--warn-ink);
}
.notice.plain { grid-template-columns: auto 1fr; background: var(--surface); border: 0; color: var(--muted); }
.notice .dot { width: 10px; height: 10px; border-radius: 50%; background: var(--accent); }
.notice strong { color: var(--ink); }
.error { color: var(--warn-ink); font-weight: 600; font-size: var(--text-s); }

/* --- forms ----------------------------------------------------------------- */
.form { display: grid; gap: var(--space-4); }
.field { display: grid; gap: var(--space-1); }
.field > span, .field > label { font-size: var(--text-s); font-weight: 600; color: var(--muted); }
.field input, .field select, .field textarea, .search input {
  min-height: 48px; width: 100%; padding: 0 var(--space-4);
  border: 1px solid var(--border); border-radius: var(--radius-m); background: var(--bg);
}
.field textarea { padding-block: var(--space-3); min-height: 80px; }
/* a voice draft's What for: bigger words, two lines at least, growing with them; without field-sizing, three lines */
.field textarea.grow { font-size: var(--text-xl); line-height: 1.3; min-height: calc(2lh + 2 * var(--space-3)); resize: none; field-sizing: content; }
@supports not (field-sizing: content) { .field textarea.grow { height: calc(3lh + 2 * var(--space-3)); } }
/* Every select is a customisable one (appearance: base-select), as MedicDay's:
   its own button styled like the fields, and a picker that matches the app —
   rounded, shadowed, the chosen option in the accent colour. Browsers without
   base-select keep the native select. The chosen text stays on one line with
   an ellipsis, so a long option never makes the control taller. */
select, select::picker(select) { appearance: base-select; }
select { display: flex; align-items: center; gap: var(--space-2); color: var(--ink); cursor: pointer; }
select > button { min-width: 0; }
select selectedcontent { display: block; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
select::picker-icon { color: var(--muted); }
select::picker(select) { margin: 6px 0 0; min-width: anchor-size(width); max-height: 18rem; overflow-y: auto; padding: var(--space-1);
  background: var(--bg); color: var(--ink); border: 1px solid var(--border); border-radius: var(--radius-m); box-shadow: var(--shadow); }
select option { display: flex; align-items: center; gap: var(--space-2); min-height: var(--touch); padding: 0 var(--space-3); border-radius: var(--radius-s); }
select option:hover, select option:focus-visible { background: var(--surface); }
select option:checked { background: var(--accent-bg); color: var(--accent); font-weight: 700; }
select option::checkmark { color: var(--accent); }
select optgroup { font-weight: 700; color: var(--muted); }
.field .help { font-size: var(--text-xs); color: var(--muted); }
.field-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-3); }
/* iOS gives date and time fields a minimum width wider than half a drawer: in a two-column row
   they pushed the drawer sideways, which then wobbled under the finger. They fit their column. */
input[type="date"], input[type="time"], input[type="datetime-local"] { min-width: 0; width: 100%; -webkit-appearance: none; appearance: none; }
.search {
  display: grid; grid-template-columns: auto 1fr; align-items: center; gap: var(--space-2);
  padding-inline: var(--space-4); border-radius: var(--radius-m); background: var(--surface);
}
.search input { border: 0; background: none; padding: 0; }
.segmented { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: var(--space-2); }
.segmented label {
  position: relative;
  display: grid; place-items: center; min-height: var(--touch); padding: 0 var(--space-2);
  border-radius: var(--radius-s); background: var(--surface); font-weight: 600; cursor: pointer; text-align: center;
}
/* The radio stays inside its own button: unpinned, it measured the whole
   page and pushed the drawer wider than the phone. */
.segmented input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; pointer-events: none; }
.segmented input:checked + span { color: var(--strong-ink); }
.segmented label:has(input:checked) { background: var(--strong); color: var(--strong-ink); }
.segmented label:has(input:focus-visible) { outline: 3px solid var(--focus); }
/* Many choices (the accounts): they wrap onto more rows, each as wide as its name. */
.segmented.wrap { display: flex; flex-wrap: wrap; }
.segmented.wrap label { flex: 1 1 auto; padding: 0 var(--space-3); }
.toggle {
  display: grid; grid-template-columns: 1fr auto; align-items: center; gap: var(--space-3);
  min-height: var(--touch); padding: var(--space-3) 0; border-bottom: 1px solid var(--border);
}
.toggle input { width: 44px; height: 26px; accent-color: var(--accent); }

/* --- bill ------------------------------------------------------------------- */
/* The lines keep at least one whole row (a line is 60px) however tall the foot grows with the QR:
   the foot scrolls for the rest. */
.bill { display: grid; grid-template-rows: minmax(min(4.5rem, 35%), 1fr) minmax(0, auto); min-height: 0; overflow: hidden; }
/* The bill's screen can carry rows between its header and the bill (a Service's "For", the daily
   prices reminder): those keep their height and the bill takes the rest, not the first of them. */
.shell > main:has(> #bill-body) { display: flex; flex-direction: column; }
.shell > main:has(> #bill-body) > * { flex: none; }
.shell > main:has(> #bill-body) > #bill-body { flex: 1 1 auto; }
/* The bill (canvas artboard 29): one row per item — name and price, − qty +, amount — ruled,
   not boxed, so the lines read as a bill. */
.bill-lines { gap: 0; }
.line {
  display: grid; grid-template-columns: minmax(0, 1fr) auto 64px; align-items: center; gap: var(--space-3);
  min-height: 60px; padding: var(--space-2) 0; border-bottom: 1px solid var(--border);
}
.line .what { display: grid; min-width: 0; }
.line.unsure { margin-inline: calc(-1 * var(--space-3)); padding-inline: var(--space-3); border: 2px solid var(--warn); border-radius: var(--radius-m); background: var(--warn-bg); }
/* The whole line opens its drawer (the name's link is stretched over it);
   the stepper sits above and keeps its own taps. */
.line { position: relative; cursor: pointer; }
.line .name::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.line .stepper { position: relative; z-index: 1; }
/* The quantity opens the how-much drawer: dotted underline says tap me. */
.qty-tap { display: grid; place-items: center; min-height: var(--touch); padding-inline: var(--space-1); color: inherit; text-decoration: underline dotted var(--muted); text-underline-offset: 4px; }
.qty-entry { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--space-3); align-items: stretch; }
.qty-entry input[name="qty"], .qty-entry #qty-typed { min-width: 0; height: 64px; padding-inline: var(--space-4); border: 2px solid var(--accent); border-radius: var(--radius-m); background: var(--bg); color: var(--ink); font: inherit; font-size: var(--text-xxl); font-weight: 700; }
.qty-entry .segmented label { min-width: 56px; }
.qty-entry #qty-typed:focus { outline: none; box-shadow: 0 0 0 3px var(--accent-bg); }
/* The amount as it was is selected: the first key replaces it (app.js qtyEdit). */
.qty-entry #qty-typed::selection { background: var(--accent-bg); color: var(--ink); }
.qty-unit { display: grid; place-items: center; padding-inline: var(--space-3); font-weight: 700; }
/* An unpriced line: name and why on top, stepper and Set price below. */
.line.unpriced { grid-template-columns: auto minmax(0, 1fr); }
.line.unpriced .what { grid-column: 1 / -1; }
.line.unpriced .what .name { white-space: normal; }
.line.unpriced .set-price { justify-self: end; }
.line .set-price {
  display: inline-grid; place-items: center; min-height: var(--touch); padding: 0 var(--space-3);
  border-radius: var(--radius-s); background: var(--warn); color: var(--on-warn);
  font-size: var(--text-s); font-weight: 700; white-space: nowrap;
}
.line .name { font-weight: 700; color: inherit; text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.line .each { font-size: var(--text-s); color: var(--muted); }
.line.unsure .each { color: var(--warn-ink); font-weight: 600; }
.line .total { text-align: end; font-weight: 700; }
.stepper { display: flex; align-items: center; border-radius: 999px; background: var(--surface); }
.line.unsure .stepper { background: var(--bg); }
.stepper button {
  width: var(--touch); height: var(--touch); border: 0; background: none; font-size: 20px; cursor: pointer;
}
.stepper output { min-width: 28px; text-align: center; font-weight: 700; }
.add-items { min-height: 52px; border: 2px dashed var(--border-strong); background: var(--bg); font-weight: 700; }
.clear-bill { justify-self: end; }
/* Add items (canvas artboard 30): one plain search box (its own border is its focus ring), best
   sellers as chips, results with their + */
.sheet-search {
  width: 100%; height: 52px; padding: 0 var(--space-4);
  border: 2px solid var(--border-strong); border-radius: var(--radius-m);
  background: var(--surface); color: var(--ink); font-size: var(--text-field);
}
.sheet-search:focus { outline: none; border-color: var(--accent); }
.quick-items { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-3); }
.quick-items form { display: contents; }
.pick-list { gap: 0; }
.pick-row { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: var(--space-3); min-height: 60px; border-bottom: 1px solid var(--border); }
.pick-row .what { display: grid; min-width: 0; }
.pick-row .title { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pick-row .meta { font-size: var(--text-s); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pick-row .meta.in { color: var(--accent); font-weight: 600; }
.pick-row .price { font-weight: 700; }
.pick-row .add { display: inline-flex; align-items: center; justify-content: center; gap: 2px; min-width: var(--touch); height: var(--touch); padding-inline: var(--space-2); border: 0; border-radius: var(--radius-s); background: var(--surface); color: var(--ink); font-weight: 700; cursor: pointer; }
.pick-row .add.on { background: var(--accent); color: var(--accent-ink); }
.pick-row .add .icon { width: 20px; height: 20px; }
/* Add items' Done: a green tick in a circle. */
.done-tick { display: grid; place-items: center; width: var(--touch); height: var(--touch); border: 0; border-radius: 50%; background: var(--accent); color: var(--accent-ink); cursor: pointer; }
.done-tick .icon { width: 24px; height: 24px; stroke-width: 3; }
.qty-editor, .sheet-root { display: contents; }
/* A line taken to nothing: faded until the server takes it off. */
.line.going { opacity: 0.4; }
/* Today's prices (canvas artboard 31): one row per item, the price box on the right. */
.prices { display: grid; grid-template-rows: 1fr auto; min-height: 0; overflow: hidden; }
.price-list { gap: 0; }
.price-row { display: grid; grid-template-columns: minmax(0, 1fr) 7.5rem; gap: var(--space-3); align-items: center; min-height: 68px; border-bottom: 1px solid var(--border); }
.price-row .what { display: grid; min-width: 0; }
.price-row .title { font-weight: 700; }
.price-input { width: 100%; height: 52px; padding: 0 var(--space-3); border: 2px solid var(--border-strong); border-radius: var(--radius-m); background: var(--surface); color: var(--ink); font-weight: 700; text-align: end; }
.price-input:focus { outline: none; border-color: var(--accent); }
.price-line { display: grid; grid-template-columns: minmax(0, 1fr) 7.5rem; gap: var(--space-3); align-items: center; padding-top: var(--space-3); border-top: 1px solid var(--border); }
.price-line .what { display: grid; }
/* The bill's banner: daily prices not yet set today. */
/* The bill just settled, to send (canvas artboard 46). */
.last-bill { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin: 0 var(--space-5); padding: var(--space-2) var(--space-3); border-radius: var(--radius-m); background: var(--accent-bg); font-size: var(--text-s); }
.last-bill a { font-weight: 700; color: var(--accent); white-space: nowrap; min-height: var(--touch); display: inline-flex; align-items: center; }
.bill-copy { max-width: 560px; margin-inline: auto; }
.price-nudge { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin: 0 var(--space-5); padding: var(--space-2) var(--space-3); border: 1px solid var(--warn-border); border-radius: var(--radius-m); background: var(--warn-bg); font-size: var(--text-s); }
.price-nudge a { color: var(--warn-ink); font-weight: 700; white-space: nowrap; }
.price-nudge button { border: 0; background: none; color: var(--muted); min-width: var(--touch); min-height: var(--touch); cursor: pointer; }
/* Add to home screen (canvas artboard 48) */
.install-prompt { display: grid; grid-template-columns: 40px minmax(0, 1fr) auto auto; align-items: center; gap: var(--space-2); margin: 0 var(--space-5); padding: var(--space-2) var(--space-3); border-radius: var(--radius-m); background: var(--accent-bg); font-size: var(--text-s); }
.screen .install-prompt { margin: 0; }
.install-prompt img { border-radius: var(--radius-s); }
.install-prompt > span { display: grid; }
.install-prompt button { border: 0; background: none; min-width: var(--touch); min-height: var(--touch); cursor: pointer; font: inherit; }
.install-prompt .install-go { color: var(--accent); font-weight: 700; }
.install-prompt .install-later { color: var(--muted); }
.install-steps { margin: 0; padding-inline-start: var(--space-5); display: grid; gap: var(--space-3); line-height: 1.4; }
.install-steps .icon { vertical-align: middle; color: var(--accent); }
.new-item summary { min-height: var(--touch); display: flex; align-items: center; color: var(--muted); font-weight: 600; cursor: pointer; }
.bill-foot {
  display: grid; gap: var(--space-3);
  padding: var(--space-4) var(--space-5) calc(var(--space-5) + env(safe-area-inset-bottom));
  border-top: 1px solid var(--border); background: var(--bg);
  /* the QR is taller than a short screen's room under the strips: the foot takes what it needs, up
     to all but the first line, and scrolls, so Cash instead and Credit are always reachable */
  overflow-y: auto; overscroll-behavior: contain;
}
.bill-total { display: flex; justify-content: space-between; align-items: baseline; }
.bill-total .count { font-weight: 600; color: var(--muted); }
.bill-total .sum { font-size: var(--text-xxl); font-weight: 700; }
.bill-total .tax { font-size: var(--text-s); color: var(--muted); }
.pay { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-3); }
.pay > *, .pay .btn { min-width: 0; }
.pay form { display: grid; }
.foot-hint { font-size: var(--text-xs); color: var(--muted); text-align: center; }
.qr { display: grid; justify-items: center; gap: var(--space-3); text-align: center; }
.qr svg { width: min(72vw, 260px, 34dvh); height: auto; color: var(--qr-ink); background: var(--qr-bg); border-radius: var(--radius-m); }
.paid { display: grid; justify-items: center; gap: var(--space-2); padding: var(--space-4); color: var(--accent); font-weight: 700; font-size: var(--text-l); }

/* --- loan ------------------------------------------------------------------ */
.card { display: grid; gap: var(--space-3); padding: var(--space-4); border-radius: var(--radius-l); background: var(--surface); }
.card .big { font-size: var(--text-xxl); font-weight: 700; }
.facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-2); }
.facts div { display: grid; gap: 2px; }
.facts dt { font-size: var(--text-xs); color: var(--muted); font-weight: 600; }
.facts dd { margin: 0; font-weight: 700; }
.split { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-2); flex-wrap: wrap; }
.actions { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); padding: var(--space-4) var(--space-5) calc(var(--space-4) + env(safe-area-inset-bottom)); border-top: 1px solid var(--border); }

/* --- drawers and alerts: always <dialog> ------------------------------------- */
dialog { color: var(--ink); background: var(--bg); border: 0; padding: 0; }
dialog::backdrop { background: var(--backdrop); }
dialog.drawer {
  width: 100%; max-width: 480px; max-height: 88svh;
  margin: auto auto 0; border-radius: var(--radius-l) var(--radius-l) 0 0;
  overflow: hidden;
}
dialog.drawer[open] { display: grid; grid-template-rows: auto 1fr; animation: slide-up 0.2s ease-out; }
/* With the keyboard up (app.js fitDrawer): the drawer sits on the keyboard and fits what is left. */
dialog.drawer.over-keyboard[open] {
  margin-bottom: var(--kb, 0); max-height: calc(var(--vvh, 100dvh) - var(--space-2));
  /* the strip down to the keyboard (its bar, the browser's) stays the drawer's, not the page's */
  box-shadow: 0 160px 0 var(--bg);
}
/* Add items is tall from the start, its search held at the top while the results scroll under it. */
dialog.drawer:has(.add-sheet)[open] { height: 88svh; }
dialog.drawer.over-keyboard:has(.add-sheet)[open] { height: calc(var(--vvh, 100dvh) - var(--space-2)); }
.add-sheet .sheet-search { position: sticky; top: 0; z-index: 1; box-shadow: 0 var(--space-2) 0 var(--bg); }
@keyframes slide-up { from { transform: translateY(40px); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { dialog.drawer[open] { animation: none; } }
.drawer-handle { justify-self: center; width: 40px; height: 4px; margin: var(--space-2) 0; border-radius: 2px; background: var(--border-strong); }
.drawer-body { display: grid; grid-template-rows: auto 1fr auto; min-height: 0; overflow: hidden; }
.drawer-head { display: grid; grid-template-columns: 1fr auto; align-items: center; padding: 0 var(--space-5) var(--space-3); }
.drawer-head h2 { font-size: var(--text-l); font-weight: 700; }
.drawer-content {
  display: grid; align-content: start; gap: var(--space-4); padding: 0 var(--space-5) var(--space-4);
  /* scrolls up and down only, and its scroll never moves the page behind */
  overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain;
}
.drawer-foot { position: sticky; bottom: 0; padding: var(--space-3) var(--space-5) calc(var(--space-4) + env(safe-area-inset-bottom)); background: var(--bg); border-top: 1px solid var(--border); }
.standalone .drawer-body { display: grid; }
/* A form that ends with its sticky Save: no padding under it, so nothing
   scrolls into view below the button. */
.drawer-content:has(> .drawer-foot) { padding-bottom: 0; }
dialog.alert { width: min(92vw, 360px); border-radius: var(--radius-l); padding: var(--space-5); }
dialog.alert[open] { display: grid; gap: var(--space-4); }
dialog.alert .buttons { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }

/* --- sign-in ---------------------------------------------------------------- */
.welcome { display: grid; align-content: center; gap: var(--space-5); padding: var(--space-6) var(--space-5); min-height: 100%; }
.welcome .brand { font-size: var(--text-xxl); font-weight: 700; color: var(--accent); }
/* The brand logo (brand_logo.dtl), coloured from tokens: the green tile and
   dark wordmark on light, the brighter tile and white wordmark on dark. */
.brand-logo { display: block; height: 32px; width: auto; }
.brand-logo .brand-tile { fill: var(--brand-tile); }
.brand-logo .brand-bar { fill: var(--brand-bar); }
.brand-logo .brand-word { fill: var(--brand-word); }
.welcome .brand .brand-logo { height: 44px; margin-bottom: var(--space-2); }
/* Signed in: the mark beside each tab's title, a way home; on a computer
   the full logo leads the sidebar instead (the desktop block). */
.bar-title { display: flex; align-items: flex-start; gap: var(--space-3); min-width: 0; }
.home-mark { display: flex; flex: 0 0 auto; border-radius: var(--radius-s); }
.brand-mark { height: 36px; }
.tabs a.tabs-logo { display: none; }
h1.brand { margin: 0; }
.welcome .lede { color: var(--muted); }
.shape-pick {
  display: grid; gap: var(--space-2); min-width: 0; margin: 0;
  padding: var(--space-3) var(--space-3) var(--space-3);
  border: 1px solid var(--border); border-radius: var(--radius-l);
}
.shape-pick legend { padding: 0 var(--space-2); font-size: var(--text-s); font-weight: 600; color: var(--muted); }
.shape-pick input { accent-color: var(--accent); width: 20px; height: 20px; }
.shape-pick label { display: grid; grid-template-columns: auto 1fr; gap: var(--space-3); align-items: center; padding: var(--space-3) var(--space-4); border-radius: var(--radius-m); background: var(--surface); cursor: pointer; }
.shape-pick label:has(input:checked) { outline: 2px solid var(--accent); }
.shape-pick small { display: block; color: var(--muted); font-size: var(--text-s); }
fieldset.plain { border: 0; padding: 0; margin: 0; }
button.row { width: 100%; border: 0; font: inherit; text-align: start; cursor: pointer; }
button.row.outlined { border: 1px solid var(--border); }

/* Grid children may shrink below their content: nothing pushes the phone
   wider than its screen. */
.shell, .shell > main, .screen, .bill, .drawer-body, .drawer-content { grid-template-columns: minmax(0, 1fr); min-width: 0; }
.row, .line, .notice { min-width: 0; }
.line .name { color: var(--ink); text-decoration: none; }
.line .name:hover { color: var(--accent); }
.tabs[hidden] { display: none; }
a.main { color: inherit; text-decoration: none; }
a.main:hover .title { color: var(--accent); }

.field-row .span-all { grid-column: 1 / -1; }
.toggle.save-item { border-bottom: 0; }

/* --- desktop (1024 px and wider) --------------------------------------------
   Everything for desktop is inside this one query: below 1024 px nothing here
   applies, so phones and small tablets are exactly as before. The bottom tabs
   become a left sidebar led by the mic, content widens, Shop and Dues use
   columns, and drawers slide in from the right. Design: canvas artboard 8. */
.mic-label { display: none; }
.share-link { display: grid; gap: var(--space-2); justify-items: center; text-align: center; }
.share-link-buttons { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-2); }
.share-link-form { display: grid; gap: var(--space-2); }

/* Tax (docs/TAX.md, canvas artboards 49-53) */
.turnover-nudge { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin: 0 var(--space-5); padding: var(--space-2) var(--space-3); border-radius: var(--radius-m); background: var(--accent-bg); font-size: var(--text-s); }
.screen .turnover-nudge { margin: 0; }
.turnover-nudge.over { border: 1px solid var(--warn-border); background: var(--warn-bg); }
.turnover-nudge a { color: var(--accent); font-weight: 700; white-space: nowrap; }
.turnover-nudge.over a { color: var(--warn-ink); }
.turnover-nudge button { border: 0; background: none; color: var(--muted); min-width: var(--touch); min-height: var(--touch); cursor: pointer; }
.turnover { display: grid; gap: var(--space-2); }
.turnover-sold { margin: 0; font-size: var(--text-l); font-weight: 700; }
.turnover .track { display: block; height: 10px; border-radius: 5px; background: var(--surface); overflow: hidden; }
.turnover .fill { display: block; height: 100%; border-radius: 5px; background: var(--accent); }
.turnover.near .fill, .turnover.over .fill { background: var(--warn); }
.add-row { align-items: end; }
/* A choice as radio rows, each with a line saying what it does (a linked tax's drawer, artboard 57) */
.choice-list { display: grid; }
.choice { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: start; gap: var(--space-3); min-height: var(--touch); padding: var(--space-3) 0; border-bottom: 1px solid var(--border); cursor: pointer; }
.choice:last-child { border-bottom: 0; }
.choice input { width: 20px; height: 20px; margin: 2px 0 0; accent-color: var(--accent); }
.choice > span { display: grid; gap: 2px; }
.choice .meta { font-size: var(--text-s); color: var(--muted); }
/* Taxes: a linked tax's row says whether the shop charges it */
.row .state { font-size: var(--text-s); font-weight: 600; color: var(--muted); white-space: nowrap; }
.row .state.in { color: var(--accent); }
/* Online orders (docs/ORDERS.md, canvas artboards 60-61): the shop's page, its cart, the order's page,
   and the shop's Orders */
.shop-head { display: grid; gap: var(--space-1); }
.shop-head h1 { margin: 0; }
.shop-wa { display: grid; gap: var(--space-2); text-align: center; }
.shop-wa .meta { margin: 0; }
/* Delivery (canvas artboard 67): Pick up / Delivery side by side, the distance and fee found */
.choice-list.two { grid-template-columns: 1fr 1fr; gap: var(--space-2); }
.choice-list.two .choice { border: 1px solid var(--border); border-radius: var(--radius-m); padding: var(--space-3); }
.choice-list.two .choice:last-child { border-bottom: 1px solid var(--border); }
p.ok { margin: 0; font-weight: 600; color: var(--accent); }
.delivery-pin { display: grid; gap: var(--space-2); }
.delivery-pin .meta { margin: 0; }
.order-where { display: grid; gap: var(--space-1); padding: var(--space-3); border: 1px solid var(--border); border-radius: var(--radius-m); background: var(--surface); }
.order-where p { margin: 0; }
.shop-who { display: flex; justify-content: space-between; align-items: center; gap: var(--space-3); }
/* Your orders on the shop's page (canvas artboard 64): a ready one stands out. */
.your-orders { display: grid; gap: var(--space-2); }
.your-orders .label-head { margin: 0; }
.your-orders a.row { color: inherit; text-decoration: none; }
.your-orders a.row.ready { border-radius: var(--radius-m); background: var(--accent-bg); }
.shop-body { display: grid; gap: var(--space-3); padding-bottom: var(--space-6); }
.shop-item { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--space-3); min-height: 60px; border-bottom: 1px solid var(--border); }
.shop-item .main { display: grid; min-width: 0; }
/* An item with sizes on the shop's page: its name once, each size a row under it */
.shop-group { display: grid; gap: var(--space-1); padding-top: var(--space-3); border-bottom: 1px solid var(--border); }
.shop-group > .list { gap: 0; padding-inline-start: var(--space-3); }
.shop-group .shop-item:last-child { border-bottom: 0; }
.shop-qty { display: flex; align-items: center; gap: var(--space-2); }
.shop-cart { position: sticky; bottom: var(--space-3); display: flex; justify-content: space-between; gap: var(--space-3); }
.order-state { display: grid; gap: var(--space-1); }
.order-state.off strong { color: var(--muted); }
.pickup-code { font-size: 2.25rem; letter-spacing: 0.4em; font-variant-numeric: tabular-nums; }
.drawer-foot.two { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); }
.order-row.warn .title { color: var(--warn-ink); }
.chip[aria-current="page"] { background: var(--strong); color: var(--strong-ink); }
.shop-link .qr svg { width: min(60vw, 220px); }

/* Empaisa's tax invoice for its fee (canvas artboard 62): the parties side by side, the amounts as the
   bill's tax summary; printed without the app around it */
.invoice { display: grid; gap: var(--space-3); }
.invoice-head h1 { margin: 0; }
.invoice-parties { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.invoice-parties p { margin: 0; }
@media print {
  .no-print, .bar, .tabs, .settings-nav, .support-head { display: none !important; }
  .invoice { border: 0; box-shadow: none; }
}

/* A public page's top: Empaisa, and the language switch on the right */
.public-head { display: flex; justify-content: space-between; align-items: center; gap: var(--space-3); }
.public-head .label-head { margin: 0; }
.lang-switch { display: flex; align-items: center; gap: var(--space-2); }
.lang-switch select { min-height: var(--touch); padding-inline: var(--space-3); border: 1px solid var(--border); border-radius: var(--radius-m); background: var(--surface); color: var(--accent); font: inherit; font-weight: 700; }
/* Sign in (canvas artboard 59): no header; the form high, clear of the keyboard; the language
   switch at the foot. The code and the number are one field under one border and focus ring:
   "+91" shows, the select over it (invisible, the phone's own picker) names the countries. */
.shell > main:has(> .screen.login) { grid-template-rows: minmax(0, 1fr); }
.screen.login { grid-template-rows: 1fr auto; padding-top: max(var(--space-6), env(safe-area-inset-top)); }
.login .welcome { align-content: start; gap: var(--space-5); padding: var(--space-6) 0 0; min-height: 0; }
.login .welcome .brand .brand-logo { height: 40px; margin: 0; }
.login-head { display: grid; gap: var(--space-2); }
.login-head h2 { margin: 0; font-size: var(--text-xl); line-height: 1.2; }
.login-head .lede { margin: 0; font-size: var(--text-m); line-height: 1.45; }
.login-head .lede a { color: var(--accent); font-weight: 700; white-space: nowrap; }
.phone-field { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; min-height: 56px;
  border: 1px solid var(--border); border-radius: var(--radius-m); background: var(--bg); }
.phone-field:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-bg); }
.phone-cc { position: relative; display: flex; align-items: center; gap: var(--space-1); align-self: stretch;
  padding-block: 0; padding-inline: var(--space-4) var(--space-3); border-inline-end: 1px solid var(--border);
  font-size: var(--text-l); font-weight: 600; cursor: pointer; }
.phone-cc::after { content: ""; width: 7px; height: 7px; margin: -3px 0 0 var(--space-1); border: solid var(--muted);
  border-width: 0 2px 2px 0; transform: rotate(45deg); }
.phone-cc select { position: absolute; inset: 0; width: 100%; opacity: 0; cursor: pointer; }
.field .phone-field input { min-height: 54px; border: 0; background: none; font-size: var(--text-l); letter-spacing: 0.04em; }
.field .phone-field input:focus-visible { outline: none; }
.field .code-input { min-height: 56px; text-align: center; font-size: var(--text-xl); font-weight: 600; letter-spacing: 0.4em; }
.login-foot { display: grid; justify-items: center; gap: var(--space-1); padding: var(--space-5) 0 max(var(--space-4), env(safe-area-inset-bottom)); text-align: center; }
.login-foot p { margin: 0; font-size: var(--text-s); color: var(--muted); }
/* Taxes: how it shows on a bill — a row that opens the drawer; in it the receipt's summary on a slip,
   then what the customer pays */
.card.preview-link { color: inherit; text-decoration: none; }
.tax-preview-result { display: grid; gap: var(--space-2); padding: var(--space-3); border-radius: var(--radius-m); background: var(--surface); }
.tax-pays { display: flex; justify-content: space-between; gap: var(--space-3); margin: 0; padding-top: var(--space-2); border-top: 1px solid var(--border); font-weight: 700; }
.untaxed { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); color: inherit; text-decoration: none; }
.tax-item { display: grid; grid-template-columns: var(--touch) minmax(0, 1fr) auto; align-items: center; gap: var(--space-2); }
.tax-item .pick { display: grid; place-items: center; min-height: var(--touch); }
.tax-apply { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; gap: var(--space-2); }
.tax-summary { display: grid; gap: var(--space-1); margin: 0; font-size: var(--text-s); }
.tax-summary > div { display: flex; justify-content: space-between; gap: var(--space-3); }
.tax-summary dt { color: var(--muted); }
.tax-summary dd { margin: 0; font-variant-numeric: tabular-nums; }
.tax-summary .tax-sum { padding-top: var(--space-1); border-top: 1px solid var(--border); font-weight: 700; }
.tax-summary .tax-sum dt { color: var(--ink); }
.tax-report table { width: 100%; border-collapse: collapse; font-size: var(--text-s); font-variant-numeric: tabular-nums; }
.tax-report th, .tax-report td { padding: var(--space-2) var(--space-1); border-bottom: 1px solid var(--border); text-align: end; }
.tax-report th:first-child, .tax-report td:first-child { text-align: start; }
.tax-report th { color: var(--muted); font-weight: 600; }
.tax-report .table-scroll { overflow-x: auto; }

/* Item sizes (canvas artboard 69): a group's row opens to its sizes; codes in a fixed-width face */
.item-group > summary { list-style: none; cursor: pointer; }
.item-group > summary::-webkit-details-marker { display: none; }
.item-group > summary .title::after { content: " ▸"; color: var(--muted); }
.item-group[open] > summary .title::after { content: " ▾"; }
.item-group > summary:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.ruled > li > .item-group > summary.row { background: none; border-radius: 0; border-bottom: 1px solid var(--border); padding-inline: 0; }
.item-group .sizes > li > .row { padding-inline-start: var(--space-4); background: var(--surface); }
.code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.92em; }
input.code { text-transform: uppercase; }
.sizes-box { display: grid; gap: var(--space-2); padding: var(--space-3); border-radius: var(--radius-m); background: var(--surface); }
/* Import, checked: the counts, then each row left out or changed */
.import-counts { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-2); text-align: center; }
.import-counts .stat { display: grid; padding: var(--space-3) var(--space-2); border-radius: var(--radius-m); background: var(--surface); font-size: var(--text-s); }
.import-counts .stat strong { font-size: var(--text-l); }
.import-counts .stat.new { background: var(--accent-bg); }
.import-counts .stat.out { background: var(--warn-bg); }
.import-rows { margin: 0; padding-inline-start: var(--space-4); display: grid; gap: var(--space-1); font-size: var(--text-s); }
.import-preview { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius-m); }
.import-preview table { border-collapse: collapse; font-size: var(--text-s); }
.import-preview th, .import-preview td { padding: var(--space-1) var(--space-2); text-align: start; white-space: nowrap; border-bottom: 1px solid var(--border); }
.import-preview th { color: var(--muted); font-weight: 600; background: var(--surface); }
.import-preview tbody tr:last-child td { border-bottom: 0; }
.import-more { text-align: end; }
.import-preview .num { text-align: end; font-variant-numeric: tabular-nums; }
.import-tag { display: inline-block; padding: 0 var(--space-2); border-radius: var(--radius-s); background: var(--surface); font-size: var(--text-xs); }
.import-tag.new { background: var(--accent-bg); color: var(--ink); }
.import-list { list-style: none; margin: 0; padding: 0; display: grid; }
.import-list > li { display: grid; gap: var(--space-1); padding-block: var(--space-2); border-bottom: 1px solid var(--border); }
.import-list .import-head { display: flex; justify-content: space-between; gap: var(--space-2); }
.import-map { list-style: none; margin: 0; padding: 0; display: grid; }
.import-map li { display: grid; grid-template-columns: minmax(0, 1fr) minmax(9rem, 13rem); gap: var(--space-2); align-items: center; padding-block: var(--space-2); border-bottom: 1px solid var(--border); }
.import-map label { display: grid; min-width: 0; }
.import-map label small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.import-map select { min-height: 44px; }
.import-map select:has(option[value=""]:checked) { color: var(--muted); }
.import-used { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-1); font-size: var(--text-s); }
.import-foot { display: grid; grid-template-columns: auto 1fr; gap: var(--space-2); }
.import-foot > :last-child { order: -1; }

/* The camera reading barcodes on the bill */
.scan-cam video { width: 100%; max-height: 50dvh; border-radius: var(--radius-m); background: var(--ink); object-fit: cover; }

/* Labels (docs/CATALOG.md): how many of each, then the printable sheet or roll. A label is
   black on white whatever the theme, so a scanner reads it. */
.label-picks .row { cursor: pointer; }
.qty-box { width: 4.5rem; min-height: var(--touch); padding: 0 var(--space-2); border: 1px solid var(--border); border-radius: var(--radius-s); background: var(--bg); color: var(--ink); font: inherit; text-align: center; }
.labels.sheet { display: grid; grid-template-columns: repeat(3, 63.5mm); grid-auto-rows: 38.1mm; gap: 0 2.5mm; }
.labels.roll { display: grid; gap: var(--space-3); justify-content: start; }
.labels .label { box-sizing: border-box; display: grid; align-content: center; justify-items: center; gap: 0.5mm; padding: 2mm; overflow: hidden; background: var(--label-bg); color: var(--label-ink); border: 1px dashed var(--border); text-align: center; line-height: 1.1; }
.labels.roll .label { width: 50mm; height: 25mm; padding: 1mm 2mm; }
.label-shop { font-size: 6pt; }
.label-name { font-size: 8pt; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.label-price { font-size: 9pt; font-weight: 700; }
.labels .barcode { width: 34mm; height: auto; }
.labels.roll .barcode { width: 30mm; }
.label-code { font-size: 6pt; }
@page roll { size: 50mm 25mm; margin: 0; }
@media print {
  .shell > .tabs, .voice-status, .no-print { display: none !important; }
  .labels .label { border: 0; }
  .labels.roll .label { page: roll; break-after: page; }
  .labels.sheet { margin: 13mm 7mm 0; }
}

/* The avatar menu's accounts (who_menu.dtl): a circle, then the name with its kind under it; the
   one in use has a green circle with a tick, the others an empty circle and switch on a tap. Not
   the menu's last form (Sign out): no rule above it, plain ink. */
.who-menu .menu form.menu-account { border-top: 0; margin-top: 0; padding-top: 0; }
.who-menu .menu .menu-account button, .who-menu .menu-account.current { display: flex; align-items: center; gap: var(--space-3); min-height: var(--touch); padding: var(--space-1) var(--space-3); color: var(--ink); font-weight: 400; text-align: start; }
.menu-account .what { display: grid; gap: 1px; min-width: 0; }
.menu-account small { color: var(--muted); font-size: var(--text-xs); font-weight: 500; }
.menu-account .tick { flex: none; display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--border); }
.menu-account.current .tick { background: var(--accent); border-color: var(--accent); color: var(--bg); }
.menu-account.current .tick .icon { width: 14px; height: 14px; stroke-width: 3; }
.menu-account.current .what > span { font-weight: 700; }
.menu-add { display: flex; align-items: center; gap: var(--space-2); color: var(--accent); border-bottom: 1px solid var(--border); }
.menu-add .icon { width: 18px; height: 18px; }

/* The product tour (docs/TOUR.md), MedicDay's: a ring around the control a step is about, the rest dimmed,
   a card beside it with Back / Next / Skip and a dot per step */
.tour-shade { position: fixed; inset: 0; z-index: 60; }
.tour-ring { position: fixed; z-index: 61; border-radius: var(--radius-m); pointer-events: none; box-shadow: 0 0 0 3px var(--accent), 0 0 0 200vmax var(--backdrop); transition: top .2s ease, left .2s ease, width .2s ease, height .2s ease; }
.tour-ring.centre { box-shadow: 0 0 0 200vmax var(--backdrop); }
.tour-card { position: fixed; z-index: 62; width: min(22rem, calc(100vw - 32px)); box-sizing: border-box; background: var(--bg); color: var(--ink); border-radius: var(--radius-l); box-shadow: var(--shadow); padding: var(--space-4) var(--space-4) var(--space-3); }
.tour-card h2 { font-size: var(--text-l); margin: 0 0 var(--space-1); }
.tour-card p { margin: 0 0 var(--space-2); color: var(--muted); }
.tour-dots { display: flex; gap: 5px; margin: var(--space-2) 0 var(--space-3); }
.tour-dots span { width: 6px; height: 6px; border-radius: 3px; background: var(--border); transition: width .2s ease; }
.tour-dots span.on { width: 16px; background: var(--accent); }
/* Tamil runs long: Skip takes its own line when Back and Next need the width, never pushing Next off the card */
.tour-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2); }
.tour-actions > * { min-width: 0; }
.tour-nav { display: flex; gap: var(--space-2); margin-inline-start: auto; }
.tour-back[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) { .tour-ring, .tour-dots span { transition: none; } }

/* Share Empaisa (docs/SHARING.md): the strip now and then, the menu row, the profile card */
.share-prompt { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-3); border-radius: var(--radius-m); background: var(--accent-bg); font-size: var(--text-s); }
.share-prompt > span { display: grid; }
.share-prompt .btn .icon, .share-card .btn .icon, .menu-share .icon { width: 18px; height: 18px; }
.share-later { border: 0; background: none; min-width: var(--touch); min-height: var(--touch); cursor: pointer; font: inherit; color: var(--muted); }
.who-menu .menu .menu-share { justify-content: space-between; gap: var(--space-2); margin-top: var(--space-1); border-top: 1px solid var(--border); border-radius: 0; color: var(--accent); font-weight: 600; }
.who-menu .menu .menu-share .icon { flex: none; }
.share-card { display: grid; gap: var(--space-2); }

/* Money's and Expense's month, at the top of the screen (no longer in the header) */
.month-row { display: flex; align-items: center; gap: var(--space-2); }
.month-row select.chip { font-weight: 700; }

/* Personal's day: the account's name as the title, one line; the date on its own card, centred */
.bar-title > div:has(> h1.account-title) { min-width: 0; }
.bar h1.account-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.today-card { display: grid; justify-items: center; gap: 2px; padding: var(--space-4); border-radius: var(--radius-l); background: var(--accent-bg); text-align: center; }
.today-date { font-size: var(--text-xl); font-weight: 700; color: var(--ink); }
.today-word { font-size: var(--text-s); font-weight: 600; color: var(--accent); text-transform: uppercase; letter-spacing: 0.06em; }
/* Personal's day: what was spent today on top (home.dtl), the total large, then the rows */
.spent-today { display: grid; gap: var(--space-2); padding: var(--space-4); border-radius: var(--radius-l); background: var(--surface); }
.spent-head { display: flex; justify-content: space-between; align-items: start; gap: var(--space-3); }
.spent-total { display: grid; gap: 2px; min-width: 0; }
.spent-total .label { font-size: var(--text-s); color: var(--muted); font-weight: 600; }
.spent-total .value { font-size: var(--text-xxl); font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums; }
.spent-total .meta { font-size: var(--text-s); color: var(--muted); }
.spent-today .empty { margin: 0; color: var(--muted); }
.more-link { justify-self: start; font-weight: 600; color: var(--accent); text-decoration: none; }

/* The launch flash (opened from the home-screen icon, app.js): the mark on the page's ground,
   two rings radiating from it, the whole fading into the app; it never takes a tap. */
.launch { display: none; }
html.launching .launch {
  position: fixed; inset: 0; z-index: 1000; display: grid; place-items: center;
  background: var(--bg); pointer-events: none;
  animation: launch-out 320ms ease-out 760ms forwards;
}
.launch-mark { position: relative; display: grid; place-items: center; width: 64px; height: 64px; }
.launch-mark .brand-mark { width: 64px; height: 64px; animation: launch-in 360ms ease-out both; }
.launch-ring {
  position: absolute; inset: 0; border: 2px solid var(--accent); border-radius: 18px; opacity: 0;
  animation: launch-ring 900ms ease-out 120ms both;
}
.launch-ring + .launch-ring { animation-delay: 380ms; }
@keyframes launch-in { from { transform: scale(0.82); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes launch-ring { from { transform: scale(1); opacity: 0.55; } to { transform: scale(2.6); opacity: 0; } }
@keyframes launch-out { to { opacity: 0; visibility: hidden; } }
@media (prefers-reduced-motion: reduce) {
  .launch-ring { display: none; }
  .launch-mark .brand-mark { animation: none; }
  html.launching .launch { animation-delay: 400ms; }
}

/* Money -> Charts (canvas artboard 79, docs/CHARTS.md). The switch beside the month. */
.view-switch { display: flex; margin-inline-start: auto; border: 1px solid var(--border-strong); border-radius: var(--radius-pill); overflow: hidden; }
.view-switch a { display: grid; place-items: center; min-height: var(--touch); padding: 0 var(--space-4); color: var(--ink); font-size: var(--text-s); font-weight: 600; text-decoration: none; }
.view-switch a[aria-current="page"] { background: var(--strong); color: var(--strong-ink); }
.charts { display: grid; gap: var(--space-3); min-width: 0; }
.card.chart { gap: var(--space-2); min-width: 0; }
/* A name, its bar (its share of the largest), the amount; thin bars, rounded at the end. */
.hbars { display: grid; gap: var(--space-2); margin: 0; padding: 0; list-style: none; }
.hbars li { display: grid; grid-template-columns: minmax(5rem, 34%) minmax(0, 1fr) auto; align-items: center; gap: var(--space-2); min-height: 32px; }
.hbars .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hbars .bar { height: 12px; width: var(--share); min-width: 2px; border-start-end-radius: 4px; border-end-end-radius: 4px; }
.hbars .bar.out { background: var(--chart-out); }
.hbars .bar.in { background: var(--chart-in); }
.hbars .amount { display: grid; justify-items: end; font-weight: 700; font-variant-numeric: tabular-nums; }
.hbars .amount .meta { font-weight: 400; font-size: var(--text-xs); color: var(--muted); }
.chart-box { position: relative; height: 180px; min-width: 0; }
.chart-legend { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: 0; font-size: var(--text-s); color: var(--muted); }
.chart-legend .key { display: inline-block; width: 10px; height: 10px; border-radius: 2px; }
.chart-legend .key.in { background: var(--chart-in); }
.chart-legend .key.out { background: var(--chart-out); margin-inline-start: var(--space-3); }

/* Money: the part a chip swaps; its sections stay rows of the screen's grid. */
.money-body { display: contents; }

@media (min-width: 1024px) {
  /* Money -> Charts: two columns of cards */
  .charts { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; }
  .shell {
    max-width: none;
    grid-template-columns: 248px minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr);
    grid-template-areas: "nav main";
  }
  .shell > main { grid-area: main; }
  .voice-status { inset-inline: calc(248px + var(--space-6)) var(--space-6); bottom: var(--space-6); max-width: 560px; }
  .tabs {
    grid-area: nav;
    display: flex; flex-direction: column; align-items: stretch; gap: 6px;
    min-height: 0; padding: 28px 16px;
    border-top: 0; border-inline-end: 1px solid var(--border);
  }
  .tabs a {
    display: flex; flex-direction: row; justify-content: flex-start; align-items: center; gap: 12px;
    min-height: var(--touch); padding: 0 14px; border-radius: var(--radius-s);
    font-size: var(--text-m);
  }
  .tabs a:hover { background: var(--surface); color: var(--ink); }
  .tabs a[aria-current="page"] { background: var(--surface); }
  .tabs .mic-tab { order: -1; display: block; margin-bottom: 18px; }
  .tabs a.tabs-logo { order: -2; display: flex; min-height: 0; padding: 0 8px 22px; border-radius: 0; }
  .tabs a.tabs-logo:hover { background: none; }
  .tabs-logo .brand-logo { height: 30px; }
  .home-mark { display: none; }
  .tabs .mic {
    display: flex; align-items: center; justify-content: flex-start; gap: 12px;
    width: 100%; height: auto; min-height: 56px; margin: 0; padding: 0 16px;
    border-radius: var(--radius-m); box-shadow: none;
  }
  .tabs .mic svg { width: 24px; height: 24px; }
  .mic-label { display: inline; font-size: var(--text-m); font-weight: 700; text-align: start; line-height: 1.25; }

  /* Content: from the sidebar's edge (not centred: the owner's choice), at
     most 1100 px wide, more air. The strips under a header line up with it. */
  .bar, .screen { padding-inline: 40px max(40px, calc(100% - 1140px)); }
  .bill-for, .last-bill, .price-nudge, .install-prompt, .turnover-nudge { margin-inline: 40px; max-width: 1100px; }
  .screen .install-prompt, .screen .turnover-nudge { margin-inline: 0; }
  .bar { padding-top: 32px; padding-bottom: 16px; }
  .bar h1 { font-size: 28px; }
  .screen { padding-bottom: 40px; gap: var(--space-5); }
  .stats { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--space-4); }
  .stat { padding: 18px 20px; }
  .stat .value { font-size: 28px; }

  /* Shop: the mic and recent bills side by side under the day's figures. */
  .screen.home { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; }
  .screen.home > .stats { grid-column: 1 / -1; }
  .screen.home > .speak { padding: 20px 24px; }
  /* Dues: Overdue, This week, Coming up as columns. */
  .screen.dues { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); align-items: start; }
  .screen.dues > .stats { grid-column: 1 / -1; }
  /* Purchases: by supplier and by item side by side. */
  .purchase-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; gap: var(--space-5); }

  /* The voice bill keeps its full-screen takeover, centred. */
  .shell:has(> .tabs[hidden]) { grid-template-columns: minmax(0, 1fr); grid-template-areas: "main"; }
  .shell:has(> .tabs[hidden]) > main { width: 100%; max-width: 760px; justify-self: center; }
  .shell:has(> .tabs[hidden]) .bar, .shell:has(> .tabs[hidden]) .screen { padding-inline: 24px; }

  /* Drawers come in from the right (the left in Arabic), full height. */
  dialog.drawer {
    width: 460px; max-width: 460px; height: 100dvh; max-height: 100dvh;
    margin: 0; margin-inline-start: auto; border-radius: 0;
    border-start-start-radius: var(--radius-l); border-end-start-radius: var(--radius-l);
  }
  dialog.drawer[open] { animation: slide-left 0.2s ease-out; }
  [dir="rtl"] dialog.drawer[open] { animation-name: slide-right; }
  .drawer-handle { visibility: hidden; }
  /* the side drawer is already full height; no keyboard to sit on */
  dialog.drawer:has(.add-sheet)[open], dialog.drawer.over-keyboard[open] { height: 100dvh; max-height: 100dvh; margin-bottom: 0; }
  /* Settings: the section menu becomes a grouped sidebar beside the page. */
  /* The whole area scrolls (the sidebar stays put, sticky): with no rows to
     hold it, the page would grow past the window and be cut off. */
  .settings-shell { grid-template-rows: none; grid-template-columns: 15rem minmax(0, 1fr); gap: var(--space-5); align-items: start;
    padding-inline: var(--space-5); min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
  .settings-nav { border-bottom: 0; position: sticky; top: var(--space-4); }
  .settings-nav-group { display: block; margin: var(--space-4) var(--space-3) var(--space-1); font-size: var(--text-xs);
    font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
  .settings-nav-group:first-child { margin-top: 0; }
  .settings-nav-scroll { flex-direction: column; gap: 2px; overflow: visible; padding: 0; }
  .settings-nav a { border-radius: var(--radius-s); white-space: normal; }
  .settings-nav a:hover { background: var(--surface); }
  .settings-main { padding-top: 0; max-width: 44rem; overflow: visible; }
}
@keyframes slide-left { from { transform: translateX(40px); opacity: 0; } }
@keyframes slide-right { from { transform: translateX(-40px); opacity: 0; } }
@media (min-width: 1024px) and (prefers-reduced-motion: reduce) { dialog.drawer[open] { animation: none; } }
