:root {
  color-scheme: light;

  /* ---- surfaces & ink (2026 redesign — design canvas
     claude.ai/artifact/8rxrWe5fnksCMYrnXTPawt) ---------------------------- */
  --bg: #f3f5f8;
  --surface: #ffffff;
  --surface-2: #f1f3f6;
  --ink: #111827;
  --muted: #4b5563;
  --muted-2: #9ca3af;
  --border: #e5e7eb;
  --border-strong: #d1d5db;

  /* ---- accent (primary brand: blue) ------------------------------------ */
  --accent: #1d4ed8;
  --accent-dark: #1e40af;
  --accent-light: #e0e9ff;
  --accent-ink: #ffffff;

  /* ---- semantic: warning / near-match attention ----------------------- */
  --warning-bg: #fff7e6;
  --warning-border: #fcd9a0;
  --warning-strong: #8a5a00;
  --warning-ink: #7a4b00;

  /* ---- semantic: error -------------------------------------------------- */
  --error: #b42318;
  --error-bg: #fee4e2;
  --error-border: #f4a9a0;

  /* ---- semantic: success (its own color, not accent) -------------------- */
  --success: #15803d;
  --success-bg: #dcfce7;

  /* ---- semantic: replacement (its own tint — a swap is neither a sale
     nor a return, so it doesn't borrow either of those hues) ------------ */
  --replacement-bg: #f3e8ff;

  /* ---- categorical (expense-category pie chart): reuses the existing
     semantic hues first, then adds just enough new ones to round out a
     distinct 8-color set — never the palette a chart needing 20 colors
     would want, but this app's category lists stay short by design. --- */
  --chart-cat-1: var(--accent);
  --chart-cat-2: var(--success);
  --chart-cat-3: var(--warning-strong);
  --chart-cat-4: var(--error);
  --chart-cat-5: #6b21a8;
  --chart-cat-6: #0e7490;
  --chart-cat-7: #be185d;
  --chart-cat-8: #a16207;

  /* ---- spacing scale (4px base) ---------------------------------------- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-7: 32px;
  --space-8: 40px;

  /* ---- type scale -------------------------------------------------------- */
  --text-xs: 0.75rem;
  --text-sm: 0.8125rem;
  --text-base: 1rem;
  --text-md: 1.0625rem;
  --text-lg: 1.25rem;
  --text-xl: 1.75rem;

  /* ---- radius scale: generous rounding, per the redesign — cards and
     sheets read as an approachable consumer tool rather than the sharp,
     near-zero radius the previous B2B-styled look deliberately used.
     --radius-pill for fully circular/capsule elements (avatar, chips,
     nav pills), --radius-sheet for the bottom-sheet modal's top corners
     only. ------------------------------------------------------------ */
  --radius-sm: 10px;
  --radius-md: 12px;
  --radius-lg: 18px;
  --radius-xl: 20px;
  --radius-pill: 999px;
  --radius-sheet: 24px;

  /* ---- elevation ---------------------------------------------------------- */
  --shadow-xs: 0 1px 2px rgba(17, 24, 39, 0.06);
  --shadow-sm: 0 2px 8px rgba(17, 24, 39, 0.08);
  --shadow-md: 0 10px 24px rgba(17, 24, 39, 0.12);
  --shadow-warning: 0 8px 20px rgba(138, 90, 0, 0.22);

  padding-top: env(safe-area-inset-top, 0px);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: 'Noto Sans', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 16px;
  line-height: 1.45;
  -webkit-tap-highlight-color: transparent;
  -webkit-font-smoothing: antialiased;
}

#app {
  max-width: 480px;
  margin: 0 auto;
  padding: var(--space-5) var(--space-4) var(--space-6);
  min-height: 100vh;
}

.screen { display: flex; flex-direction: column; gap: var(--space-5); }

h1 { font-size: var(--text-xl); font-weight: 800; margin: 0; letter-spacing: -0.01em; }
h2 { font-size: var(--text-lg); font-weight: 700; margin: 0; letter-spacing: -0.01em; }
.subtitle { color: var(--muted); margin: 0; font-size: var(--text-base); }

:focus-visible {
  outline: 2.5px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* ==================================================== buttons: hierarchy */

button { font: inherit; }
/* Universal fallback so any unstyled button still reacts to press and to
   being disabled. Class rules win on specificity — .ds-btn:disabled resets
   this opacity, because the boards draw a disabled action as a solid grey
   rather than a faded one. */
button:active:not(:disabled) { transform: translateY(1px); }
button:disabled { opacity: 0.5; cursor: not-allowed; }

/* Its own class rather than a plain text link: a bare underlined arrow was a
   ~12px tap target, small enough on a phone to read as "there is no back
   button at all". 44px is the usual minimum for a thumb. */
.back-button {
  background: none;
  border: none;
  color: var(--accent);
  font-size: var(--text-base);
  font-weight: 600;
  padding: var(--space-2) var(--space-3) var(--space-2) var(--space-1);
  margin-left: calc(var(--space-1) * -1);
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  border-radius: var(--radius-sm);
  text-align: left;
}
.back-button .icon-back { width: 20px; height: 20px; flex: 0 0 auto; }

/* ==================================================================== spinner */

.spinner {
  display: inline-block;
  width: 1.1em;
  height: 1.1em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: spin 0.6s linear infinite;
  flex: 0 0 auto;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .spinner { animation-duration: 1.4s; }
}

.btn-busy { display: inline-flex; align-items: center; gap: var(--space-2); }

.boot-loading {
  display: flex;
  justify-content: center;
  padding-top: 40vh;
  color: var(--muted-2);
}
.boot-loading .spinner { width: 2em; height: 2em; }

/* ==================================================================== forms */

/* .screen's gap only spaces its own direct children (<header>, <form>) —
   nothing previously gave a form's OWN children (each field, the line
   items container, notes, the error banner, submit) any gap at all, so
   they stacked with near-zero space between them regardless of how much
   padding each individual field/card had internally. Targeting `form`
   itself, not a specific [data-role], so this can't reappear for a form
   added later the way it did for pin-form here the first time. */
form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* Same gap-less-container bug for multiple line items stacking directly
   on top of each other once a second one is added. */
[data-role="line-items"] {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

input, textarea, select {
  font: inherit;
  width: 100%;
  padding: var(--space-3) var(--space-3);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--ink);
  min-height: 48px;
}
textarea { min-height: 72px; }
input:disabled { background: var(--surface-2); color: var(--muted); cursor: not-allowed; }

input:focus-visible, textarea:focus-visible, select:focus-visible {
  border-color: var(--accent);
  outline: 2.5px solid var(--accent);
  outline-offset: 0;
}

label {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--muted);
}

.error {
  background: var(--error-bg);
  color: var(--error);
  border: 1px solid var(--error-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-sm);
  font-weight: 600;
  margin: 0;
}

.home-header, .form-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}
.form-header h2 { flex: 1; }

/* ===================================================================== home */

/* Spacing principle for the whole screen: .screen's own flex `gap`
   (--space-5) is the ONLY thing that spaces top-level sections apart —
   Today's-so-far card, the Record group, the Manage group. No element
   below adds its own margin to also push away from a sibling; that's
   what caused the inconsistent, compounding padding review flagged
   earlier (a margin AND the flex gap both applying between the same two
   elements). Each section internally uses its own small, single gap
   (--space-3) between its own label and its own content. */

.home-top-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.home-date { font-size: var(--text-sm); color: var(--muted); font-weight: 500; }

/* align-items is reset explicitly: the shared .home-header/.form-header
   rule above sets `center`, which in a column would shrink-wrap the name
   and defeat `min-width: 0` below. The name is centred by text-align
   instead, and the user row stays against the gutter. */
.home-header { display: flex; flex-direction: column; align-items: stretch; gap: var(--space-1); }
/* One line, always. A long trading name ("Siddhi Vinayak Marketing,
   Jaipur") would otherwise wrap to two and shove the whole screen down,
   so the size flexes with the viewport instead of the text wrapping.
   Not ellipsised — a truncated business name reads as a bug.

   `min-width: 0` matters: as a flex item with nowrap its automatic
   minimum is the full text width, so without this it grew past its
   parent and spilled into the header's own padding — which is what made
   the name look like it was touching the screen edges. */
.entity-name {
  margin: 0;
  min-width: 0;
  /* 5.4vw fitted the shop's own name to the pixel in Chromium and
     overflowed it by 4px in WebKit, which is what the phones run. */
  font-size: clamp(16px, 5.2vw, 26px);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: clip;
  /* A name too long to fit still starts at the gutter: CSS start-aligns
     an overflowing line rather than clipping both ends. */
  text-align: center;
}
.home-user-row { display: flex; align-items: center; gap: var(--space-2); }
.home-avatar {
  width: 28px; height: 28px; border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--accent-ink);
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: var(--text-xs);
  flex: 0 0 auto;
  text-transform: uppercase;
}
.home-username { font-size: var(--text-sm); font-weight: 600; color: var(--muted); flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Generic icon-only tap target — logout here, reusable anywhere a bare
   icon button is needed without outbox-icon-button's count badge. */
.icon-button {
  flex: 0 0 auto;
  width: 36px; height: 36px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-pill);
  background: none;
  border: 0;
  color: var(--muted);
  cursor: pointer;
}
.icon-button svg { width: 20px; height: 20px; }
.icon-button:active { background: var(--surface-2); }

/* ---- "Today so far" summary card: the one place on Home that talks to
   the server (businessSummary + expenseSummary for today), so it starts
   hidden and is only revealed for an admin once that fetch resolves. --- */
.home-summary-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  border-radius: var(--radius-xl);
  background: var(--accent);
  color: var(--accent-ink);
  text-decoration: none;
  cursor: pointer;
}
.home-summary-top { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.home-summary-label { font-size: var(--text-sm); color: rgba(255,255,255,0.82); }
.home-summary-link { font-size: var(--text-sm); font-weight: 700; }

/* Icon + count only, muted until something's actually queued — this is
   staff/debugging surface, not a control a layman user needs to notice. */
.outbox-icon-button {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  background: none;
  border: none;
  padding: var(--space-2);
  margin: calc(var(--space-2) * -1); /* keeps the tap target ~36px without widening the visual footprint */
  color: var(--muted-2);
  min-height: 36px;
}
.outbox-icon-button svg { width: 20px; height: 20px; flex: 0 0 auto; }
.outbox-icon-button[data-has-items="true"] { color: var(--ink); }

/* =================================================================== outbox */

.outbox-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.outbox-item {
  border: 1.5px solid var(--border);
  border-left: 4px solid var(--border-strong);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
}
.outbox-item-summary { font-weight: 700; font-size: var(--text-base); }
.outbox-item-status {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--muted);
  margin-top: var(--space-1);
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.outbox-item-status::before {
  content: "";
  width: 8px; height: 8px;
  border-radius: var(--radius-pill);
  background: var(--muted-2);
  flex: 0 0 auto;
}
.outbox-item-status.status-stale { color: var(--warning-strong); }
.outbox-item-status.status-stale::before { background: var(--warning-border); }
.outbox-item.status-stale { border-left-color: var(--warning-border); }
.outbox-item-status.status-failed { color: var(--error); }
.outbox-item-status.status-failed::before { background: var(--error); }
.outbox-item.status-failed { border-left-color: var(--error); }

.outbox-item-actions { display: flex; gap: var(--space-3); margin-top: var(--space-3); }
.outbox-item-actions button {
  font: inherit;
  border-radius: var(--radius-sm);
  border: 1.5px solid var(--border-strong);
  background: var(--surface);
  color: var(--ink);
  padding: var(--space-2) var(--space-3);
  font-weight: 600;
  font-size: var(--text-sm);
  min-height: 40px;
  cursor: pointer;
}
.outbox-item-actions button:first-child { border-color: var(--accent); color: var(--accent); }

.empty-state { color: var(--muted); text-align: center; margin-top: var(--space-8); font-size: var(--text-base); }

/* ====================================================================== toast */

#toast {
  position: fixed;
  bottom: calc(var(--space-4) + env(safe-area-inset-bottom, 0px));
  left: var(--space-4);
  right: var(--space-4);
  max-width: 448px;
  margin: 0 auto;
  background: var(--ink);
  color: #fff;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  text-align: center;
  font-weight: 600;
  font-size: var(--text-sm);
  box-shadow: var(--shadow-md);
  /* Above .ds-sheet-backdrop (20). A toast is transient and must be the
     topmost thing on screen: at 10 it painted UNDER any open bottom
     sheet, so every "could not save" raised from inside a sheet was
     invisible and the tap read as if nothing had happened at all. */
  z-index: 30;
}
[hidden] { display: none !important; }

/* No dark-mode block: every design board is light-only and :root pins color-scheme: light. */

/* ========================================================================
   DESIGN-CANVAS LAYER (ds-*)
   claude.ai/artifact/8rxrWe5fnksCMYrnXTPawt

   Values here are transcribed from the .dc.html boards verbatim rather
   than mapped onto the older token set above, so a reviewer can diff a
   rule against its board by grepping the hex. The boards define a
   light-only UI and carry no dark variants, which is why this stylesheet
   has no prefers-color-scheme block at all. Screens on
   this layer use .ds-screen and never .screen; the two coexist until the
   last legacy screen is migrated.
   ===================================================================== */

:root {
  --ds-bg: #f3f5f8;
  --ds-surface: #ffffff;
  --ds-surface-2: #f1f3f6;
  --ds-surface-3: #f9fafb;
  --ds-ink: #111827;
  --ds-ink-2: #1f2937;
  --ds-ink-3: #374151;
  --ds-muted: #4b5563;
  --ds-muted-2: #9ca3af;
  --ds-border: #e5e7eb;
  --ds-border-strong: #d1d5db;
  --ds-divider: #eef0f3;

  --ds-accent: #1d4ed8;
  --ds-accent-dark: #1e40af;
  --ds-accent-deep: #1e3a8a;
  --ds-accent-light: #e0e9ff;
  --ds-on-accent: #ffffff;
  --ds-on-accent-soft: #dbe4ff;

  --ds-success: #15803d;
  --ds-success-bg: #dcfce7;
  --ds-money-in: #bbf7d0;
  --ds-error: #b42318;
  --ds-error-deep: #912018;
  --ds-error-bg: #fee4e2;
  --ds-money-out: #fecaca;
  --ds-warn-bg: #fff7e6;
  --ds-warn-border: #fcd9a0;
  --ds-warn-ink: #7a4b00;
  --ds-purple-bg: #f3e8ff;
  --ds-purple-ink: #6b21a8;
  --ds-cyan-bg: #cffafe;
  --ds-cyan-ink: #0e7490;

  --ds-shadow-tab: 0 1px 2px rgba(17, 24, 39, 0.12);
  --ds-shadow-key: 0 1px 2px rgba(17, 24, 39, 0.06);
}

/* #app's padding is the legacy screens' — ds screens bleed to the frame
   edge and set their own, exactly as the boards do. */
.screen { padding: var(--space-5) var(--space-4) var(--space-6); }
#app:has(.ds-screen) { padding: 0; }

.ds-screen {
  display: flex;
  flex-direction: column;
  gap: 0;
  min-height: 100vh;
  padding-bottom: 32px;
  background: var(--ds-bg);
  color: var(--ds-ink);
}

.ds-screen--fill { padding-bottom: 0; }

/* ---- app bar ---------------------------------------------------------- */

.ds-appbar {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 8px 8px 0 4px;
  flex-shrink: 0;
}

.ds-appbar--action { padding-right: 12px; }

.ds-appbar-icon {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 12px;
  background: none;
  color: var(--ds-ink);
  cursor: pointer;
}

.ds-appbar-icon svg { width: 24px; height: 24px; }
.ds-appbar-icon--close svg { width: 22px; height: 22px; }

/* The Stock/Parties boards set no tracking here; the Reports boards do,
   hence the modifier rather than a blanket letter-spacing. */
.ds-appbar-title {
  margin: 0;
  flex-grow: 1;
  min-width: 0;
  font-size: 26px;
  font-weight: 700;
  color: var(--ds-ink);
}

.ds-appbar-title--tight { letter-spacing: -0.01em; }

.ds-appbar-title--sm { font-size: 22px; }

.ds-appbar-btn {
  height: 40px;
  padding: 0 14px;
  flex-shrink: 0;
  border: 0;
  border-radius: 12px;
  background: var(--ds-accent);
  color: var(--ds-on-accent);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}

/* ---- segmented control ------------------------------------------------ */

.ds-segmented {
  margin: 8px 16px 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 4px;
  padding: 4px;
  background: var(--ds-border);
  border-radius: 14px;
  flex-shrink: 0;
}

.ds-segmented-item {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 40px;
  border: 0;
  border-radius: 10px;
  background: none;
  color: var(--ds-ink-3);
  font-size: 14px;
  font-weight: 500;
  text-align: center;
  cursor: pointer;
}

.ds-segmented-item[aria-current='page'] {
  background: var(--ds-surface);
  color: var(--ds-ink);
  font-weight: 600;
  box-shadow: var(--ds-shadow-tab);
}

/* ---- hero (the blue figure card) -------------------------------------- */

.ds-hero {
  margin: 0 16px;
  padding: 20px;
  border-radius: 20px;
  background: var(--ds-accent);
  color: var(--ds-on-accent);
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.ds-hero-label {
  font-size: 14px;
  color: var(--ds-on-accent-soft);
  letter-spacing: 0.02em;
}

.ds-hero-value {
  font-size: 40px;
  font-weight: 600;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
}

.ds-hero-value--sm { font-size: 36px; }

.ds-hero-split {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  padding-top: 14px;
  border-top: 1px solid rgba(255, 255, 255, 0.22);
}

.ds-hero-cell { display: flex; flex-direction: column; gap: 2px; }
.ds-hero-cell-label { font-size: 13px; color: var(--ds-on-accent-soft); }

.ds-hero-cell-value {
  font-size: 17px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.ds-hero-cell-value--in { color: var(--ds-money-in); }
.ds-hero-cell-value--out { color: var(--ds-money-out); }

.ds-hero-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 12px;
  border-top: 1px solid rgba(255, 255, 255, 0.22);
  font-size: 14px;
}

.ds-hero-foot-label { color: var(--ds-on-accent-soft); }
.ds-hero-foot-value { font-weight: 600; font-variant-numeric: tabular-nums; }

/* ---- section headings ------------------------------------------------- */

.ds-section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 24px 20px 10px;
}

.ds-section-label {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--ds-ink-3);
}

.ds-section-hint { font-size: 13px; color: var(--ds-muted); }

/* A group heading standing on its own, without the hint SectionHead pairs
   it with — Home's "Record" and "Manage". */
.ds-group-head { margin: 0; padding: 24px 20px 10px; font-size: 14px; font-weight: 600; color: var(--ds-ink-3); }

/* ---- cards, rows, lists ----------------------------------------------- */

.ds-card {
  background: var(--ds-surface);
  border: 1px solid var(--ds-border);
  border-radius: 16px;
  overflow: hidden;
}

.ds-listcard {
  list-style: none;
  margin: 0 16px 24px;
  padding: 0;
  background: var(--ds-surface);
  border: 1px solid var(--ds-border);
  border-radius: 16px;
  overflow: hidden;
}

.ds-listcard > li { border-bottom: 1px solid var(--ds-divider); }
.ds-listcard > li:last-child { border-bottom: 0; }

/* Home's Manage card sits under 18px-cornered tiles and ends the screen,
   so it matches their radius and drops the list's trailing margin. */
.ds-listcard--grouped { margin-bottom: 0; border-radius: 18px; }

.ds-row {
  width: 100%;
  min-height: 64px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  background: none;
  border: 0;
  text-align: left;
  text-decoration: none;
  color: var(--ds-ink);
  cursor: pointer;
  box-sizing: border-box;
}

.ds-row-text {
  flex-grow: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.ds-row-title { font-size: 16px; font-weight: 600; }
.ds-row-sub { font-size: 13px; color: var(--ds-muted); }

/* icons.mjs emits no width/height by design, so every slot that hosts a
   glyph must size it — an unsized inline <svg> falls back to 300×150. */
.ds-row-chevron { width: 18px; height: 18px; flex-shrink: 0; color: var(--ds-muted); }
.ds-row-chevron svg { width: 18px; height: 18px; display: block; }

/* ---- icon chip -------------------------------------------------------- */

.ds-chip-icon {
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 12px;
  background: var(--ds-surface-2);
  color: var(--ds-ink-2);
}

.ds-chip-icon svg { width: 22px; height: 22px; }
.ds-chip-icon--sm svg { width: 20px; height: 20px; }

.ds-chip-icon--sale { background: var(--ds-success-bg); color: var(--ds-success); }
.ds-chip-icon--purchase { background: var(--ds-accent-light); color: var(--ds-accent); }
.ds-chip-icon--return { background: var(--ds-error-bg); color: var(--ds-error-deep); }
.ds-chip-icon--replacement { background: var(--ds-purple-bg); color: var(--ds-purple-ink); }
.ds-chip-icon--payment { background: var(--ds-cyan-bg); color: var(--ds-cyan-ink); }
.ds-chip-icon--expense { background: var(--ds-warn-bg); color: #8a5a00; }
.ds-chip-icon--report { background: var(--ds-surface-2); color: var(--ds-accent); }
.ds-chip-icon--date { background: var(--ds-accent-light); color: var(--ds-accent); }

/* ---- avatar ----------------------------------------------------------- */

.ds-avatar {
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: var(--ds-surface-2);
  color: var(--ds-ink-2);
  font-size: 14px;
  font-weight: 700;
}

.ds-avatar--accent { background: var(--ds-accent); color: var(--ds-on-accent); }

/* ---- tiles ------------------------------------------------------------ */

.ds-tile-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  padding: 0 16px;
}

.ds-tile {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 16px;
  min-height: 116px;
  box-sizing: border-box;
  background: var(--ds-surface);
  border: 1px solid var(--ds-border);
  border-radius: 18px;
  text-align: left;
  text-decoration: none;
  color: var(--ds-ink);
  cursor: pointer;
}

.ds-tile-text { display: flex; flex-direction: column; gap: 2px; }
.ds-tile-title { font-size: 16px; font-weight: 600; }
.ds-tile-sub { font-size: 13px; color: var(--ds-muted); }

.ds-widerow {
  margin: 10px 16px 0;
  width: auto;
  background: var(--ds-surface);
  border: 1px solid var(--ds-border);
  border-radius: 18px;
}

/* ---- stat tiles ------------------------------------------------------- */

.ds-statgrid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  padding: 12px 16px 0;
  flex-shrink: 0;
}

.ds-stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px;
  border-radius: 14px;
  background: var(--ds-surface);
  border: 1px solid var(--ds-border);
}

.ds-stat-label { font-size: 13px; color: var(--ds-muted); }

.ds-stat-value {
  font-size: 22px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.ds-stat--accent {
  background: var(--ds-accent);
  border-color: var(--ds-accent);
  color: var(--ds-on-accent);
}

.ds-stat--accent .ds-stat-label { color: var(--ds-on-accent-soft); }

.ds-stat--warn {
  background: var(--ds-warn-bg);
  border-color: var(--ds-warn-border);
  color: var(--ds-warn-ink);
}

.ds-stat--warn .ds-stat-label { color: inherit; }

/* Party statement's six small tiles: 2 columns of figures, not 3 of KPIs. */
.ds-statgrid--sm { margin: 12px 16px 0; padding: 0; gap: 8px; }
.ds-statgrid--sm .ds-stat { padding: 10px 12px; }
.ds-statgrid--sm .ds-stat-value { font-size: 15px; }

/* ---- pills / chips ---------------------------------------------------- */

.ds-chiprow {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding: 12px 16px 16px;
}

.ds-pill {
  display: flex;
  align-items: center;
  height: 36px;
  padding: 0 14px;
  flex-shrink: 0;
  border-radius: 999px;
  border: 1px solid var(--ds-border-strong);
  background: var(--ds-surface);
  color: var(--ds-ink-2);
  font-size: 14px;
  /* The Period board's quick ranges are the only pills drawn at 500; the
     statement filters, picker presets and date chips are all 600. */
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}


.ds-pill[aria-pressed='true'] {
  background: var(--ds-accent);
  border-color: var(--ds-accent);
  color: var(--ds-on-accent);
  font-weight: 600;
}

.ds-pill--lg { height: 40px; font-size: 15px; font-weight: 600; }

.ds-tag {
  font-size: 12px;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--ds-surface-2);
  color: var(--ds-ink-3);
  white-space: nowrap;
}

.ds-tag--mode { font-weight: 600; padding: 3px 8px; }

/* ---- accordion sections (Today / Period reports) ---------------------- */

.ds-acc-list { display: flex; flex-direction: column; gap: 10px; padding: 0 16px; }

.ds-acc-head {
  width: 100%;
  min-height: 72px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  background: none;
  border: 0;
  text-align: left;
  cursor: pointer;
  color: var(--ds-ink);
}

.ds-acc-text { flex-grow: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ds-acc-label { font-size: 15px; font-weight: 600; }
.ds-acc-count { font-size: 14px; color: var(--ds-muted); }

.ds-acc-total {
  font-size: 20px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.ds-acc-chevron {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  color: var(--ds-muted);
  transition: transform 0.2s;
}

.ds-acc-chevron svg { width: 20px; height: 20px; display: block; }
.ds-acc-head[aria-expanded='true'] .ds-acc-chevron { transform: rotate(180deg); }

.ds-acc-body { border-top: 1px solid var(--ds-border); }
.ds-acc-entries { list-style: none; margin: 0; padding: 4px 0; }

.ds-acc-entry {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
}

.ds-acc-entry-text { flex-grow: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }

.ds-acc-entry-name {
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ds-acc-entry-meta { font-size: 13px; color: var(--ds-muted); }

.ds-acc-entry-amt {
  min-width: 76px;
  text-align: right;
  font-size: 14px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.ds-acc-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px 12px;
  background: var(--ds-surface-3);
  border-top: 1px solid var(--ds-divider);
  font-size: 14px;
  color: var(--ds-muted);
}

/* ---- checkbox card ---------------------------------------------------- */

.ds-checkcard {
  margin: 0 16px 10px;
  display: flex;
  /* Explicit, because these cards are <label>s and the legacy `label`
     rule stacks its children in a column — which put every checkbox
     above its own text instead of beside it. */
  flex-direction: row;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  min-height: 48px;
  box-sizing: border-box;
  background: var(--ds-surface);
  border: 1px solid var(--ds-border);
  border-radius: 14px;
  cursor: pointer;
}

.ds-checkcard input[type='checkbox'] {
  width: 22px;
  height: 22px;
  min-height: 0;
  margin: 0;
  padding: 0;
  accent-color: var(--ds-accent);
  flex-shrink: 0;
}

.ds-checkcard-text { display: flex; flex-direction: column; gap: 1px; }
.ds-checkcard-title { font-size: 15px; font-weight: 600; }
.ds-checkcard-sub { font-size: 13px; color: var(--ds-muted); }

/* ---- form fields ------------------------------------------------------ */

.ds-field { display: flex; flex-direction: column; gap: 8px; }

.ds-field-label {
  font-size: 14px;
  font-weight: 600;
  color: var(--ds-ink-3);
}

.ds-field-optional { font-weight: 400; color: var(--ds-muted); }

.ds-field-shell {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 14px;
  height: 52px;
  background: var(--ds-surface);
  border: 1px solid var(--ds-border-strong);
  border-radius: 14px;
}

.ds-field-shell:focus-within { border-color: var(--ds-accent); }
.ds-field-shell--invalid { border-color: var(--ds-error); }
/* A leading field icon is a hint, not a control — the boards draw it in
   muted ink. Slots that want it accented (the date fields) override. */
.ds-field-shell svg { width: 20px; height: 20px; flex-shrink: 0; color: var(--ds-muted); }

.ds-field-input {
  flex-grow: 1;
  min-width: 0;
  width: 100%;
  height: 48px;
  min-height: 0;
  padding: 0;
  border: 0;
  background: none;
  border-radius: 0;
  font-size: 16px;
  color: var(--ds-ink);
}

.ds-field-input:focus-visible { outline: none; }

.ds-search-shell { height: 48px; }
.ds-search-shell .ds-field-input { height: 44px; }

.ds-textarea {
  box-sizing: border-box;
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--ds-border-strong);
  border-radius: 14px;
  background: var(--ds-surface);
  /* 15px is the boards' notes size. Note this is below the 16px at which
     iOS Safari stops zooming a focused field — the Expense board's own
     16px note avoids that, hence the modifier. */
  font-size: 15px;
  line-height: 1.4;
  color: var(--ds-ink);
  resize: none;
}

.ds-textarea--lg { font-size: 16px; }

.ds-amount-shell { height: 64px; gap: 6px; }
.ds-amount-symbol { font-size: 28px; font-weight: 600; color: var(--ds-muted); }

.ds-amount-shell .ds-field-input {
  height: 60px;
  font-size: 30px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.ds-field-error { font-size: 13px; font-weight: 600; color: var(--ds-error); }

.ds-daterow { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ds-daterow-long { font-size: 14px; color: var(--ds-muted); }

/* ---- step header ------------------------------------------------------ */

.ds-steps { padding: 6px 20px 0; flex-shrink: 0; }
.ds-steps-row { display: flex; align-items: center; gap: 10px; }

.ds-step-badge {
  font-size: 14px;
  font-weight: 700;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--ds-accent-light);
  color: var(--ds-accent-deep);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.ds-step-name { font-size: 17px; font-weight: 600; }

.ds-step-segs {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 6px;
  margin-top: 12px;
}

.ds-step-seg { height: 4px; border-radius: 2px; background: var(--ds-border-strong); }
.ds-step-seg--done { background: var(--ds-accent); }

/* ---- scrolling body + sticky footer ----------------------------------- */

.ds-body {
  flex-grow: 1;
  overflow-y: auto;
  padding: 20px 16px 24px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* A flex item shrinks by default, so on a short viewport the browser
   squashes these cards instead of overflowing the body — and .ds-card
   clips the remainder, leaving content that cannot be scrolled to
   because nothing overflows. Holding their natural height is what gives
   a scrolling column something to scroll. Every height-constrained
   column in the kit needs this, not just the wizard body. */
.ds-body > *,
.ds-sheet > *,
.cw-done-main > * { flex-shrink: 0; }

.ds-footbar {
  flex-shrink: 0;
  padding: 12px 16px 28px;
  background: var(--ds-surface);
  border-top: 1px solid var(--ds-border);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.ds-foothint { font-size: 13px; color: var(--ds-muted); text-align: center; }

/* ---- buttons ---------------------------------------------------------- */

.ds-btn {
  width: 100%;
  height: 52px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  border: 0;
  border-radius: 14px;
  background: var(--ds-accent);
  color: var(--ds-on-accent);
  font-size: 16px;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}

.ds-btn svg { width: 22px; height: 22px; flex-shrink: 0; }

/* The boards draw a disabled action as a solid, still-legible grey — not
   a faded one, so the global button:disabled opacity is reset here. */
.ds-btn:disabled {
  background: var(--ds-border-strong);
  color: var(--ds-muted);
  opacity: 1;
  cursor: not-allowed;
}

.ds-btn--ghost {
  background: var(--ds-surface);
  border: 1px solid var(--ds-border-strong);
  color: var(--ds-ink);
  font-size: 15px;
}

.ds-btn--danger { background: var(--ds-error); font-size: 17px; font-weight: 700; height: 56px; }
.ds-btn--tall { height: 54px; font-size: 17px; }

.ds-btn-pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  padding: 12px 16px 28px;
}

.ds-link {
  align-self: flex-start;
  min-height: 44px;
  padding: 0 4px;
  background: none;
  border: 0;
  color: var(--ds-accent);
  font-size: 15px;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}

/* ---- info note -------------------------------------------------------- */

.ds-note {
  display: flex;
  gap: 10px;
  padding: 12px;
  border-radius: 12px;
  background: var(--ds-surface-2);
  font-size: 14px;
  line-height: 1.4;
  color: var(--ds-ink-2);
}

.ds-note svg { width: 18px; height: 18px; flex-shrink: 0; margin-top: 1px; }

/* The update wall draws the same note one step larger than the sheets do. */
.ds-note--lg { gap: 12px; padding: 14px; border-radius: 14px; font-size: 15px; line-height: 1.45; }
.ds-note--lg svg { width: 22px; height: 22px; color: var(--ds-ink-3); }

/* ---- bottom sheet ----------------------------------------------------- */

.ds-sheet-backdrop {
  position: fixed;
  inset: 0;
  z-index: 20;
  background: rgba(17, 24, 39, 0.5);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}

.ds-sheet {
  background: var(--ds-surface);
  border-radius: 24px 24px 0 0;
  padding: 10px 16px calc(28px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-height: 90dvh;
  overflow-y: auto;
}

.ds-sheet-handle {
  width: 40px;
  height: 4px;
  border-radius: 2px;
  background: var(--ds-border-strong);
  margin: 0 auto;
  flex-shrink: 0;
}

.ds-sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.ds-sheet-title { margin: 0; font-size: 22px; font-weight: 600; }

.ds-sheet-input {
  box-sizing: border-box;
  width: 100%;
  height: 50px;
  min-height: 0;
  padding: 0 14px;
  border: 1px solid var(--ds-border-strong);
  border-radius: 12px;
  background: var(--ds-surface-3);
  font-size: 16px;
  color: var(--ds-ink);
}

textarea.ds-sheet-input { height: auto; padding: 12px 14px; resize: none; }

.ds-sheet-readout {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 12px 14px;
  border-radius: 12px;
  background: var(--ds-surface-3);
  border: 1px solid var(--ds-divider);
}

.ds-sheet-readout-label { font-size: 13px; color: var(--ds-muted); }

.ds-sheet-readout-value {
  font-size: 17px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ---- review / summary card ------------------------------------------- */

.ds-review-head {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 18px 16px;
  background: var(--ds-accent);
  color: var(--ds-on-accent);
}

.ds-review-eyebrow { display: flex; align-items: center; gap: 8px; }
.ds-review-eyebrow-label { font-size: 14px; color: var(--ds-on-accent-soft); }

.ds-review-amount {
  font-size: 34px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.ds-review-dl { margin: 0; padding: 4px 16px; }

.ds-review-row {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid var(--ds-divider);
}

.ds-review-row:last-child { border-bottom: 0; }

/* 72px on the wizard boards, 84px on the Expense summary board. */
.ds-review-dl--wide .ds-review-dt { width: 84px; }

.ds-review-dt {
  width: 72px;
  flex-shrink: 0;
  margin: 0;
  font-size: 14px;
  color: var(--ds-muted);
}

.ds-review-dd {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.45;
  overflow-wrap: anywhere;
}

/* The boards set no weight on a summary's notes row, unlike its other
   rows; an absent value is greyed on top of that. #6b7280 is the board's
   own ink for it, a step lighter than --ds-muted. */
.ds-review-dd--light { font-weight: 400; }
.ds-review-dd--muted { font-weight: 400; color: #6b7280; }

/* ---- done screen ------------------------------------------------------ */

.ds-done {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 32px 24px;
  text-align: center;
}

.ds-done-check {
  width: 72px;
  height: 72px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: var(--ds-accent);
  color: var(--ds-on-accent);
}

.ds-done-check svg { width: 36px; height: 36px; }
.ds-done-title { margin: 0; font-size: 28px; font-weight: 700; }

.ds-done-amount {
  margin: 0;
  font-size: 26px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.ds-done-meta { margin: 0; font-size: 15px; line-height: 1.45; color: var(--ds-ink-3); }

/* ---- PIN keypad ------------------------------------------------------- */

.ds-pin {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 40px 24px 16px;
}

.ds-pin-title {
  margin: 0;
  font-size: 32px;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.2;
}

.ds-pin-title-hi {
  font-family: 'Noto Sans Devanagari', 'Noto Sans', sans-serif;
  color: #d2461f;
}

.ds-pin-prompt { margin: 16px 0 0; font-size: 18px; font-weight: 600; text-align: center; }

.ds-pin-dots { display: flex; gap: 20px; padding: 14px 0 4px; }

.ds-pin-dot {
  width: 20px;
  height: 20px;
  border-radius: 999px;
  box-sizing: border-box;
  background: transparent;
  border: 2px solid var(--ds-muted-2);
}

.ds-pin-dot--filled { background: var(--ds-accent); border-color: var(--ds-accent); }
.ds-pin-dot--error { background: var(--ds-error); border-color: var(--ds-error); }

/* Same height as the error line it replaces, so the keypad does not jump
   between "checking" and whatever the answer turns out to be. */
.ds-pin-checking {
  margin: 0;
  min-height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-size: 15px;
  font-weight: 600;
  color: var(--ds-muted);
}

.ds-pin-error {
  margin: 0;
  min-height: 24px;
  font-size: 15px;
  font-weight: 600;
  color: var(--ds-error);
  text-align: center;
}

.ds-keypad {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  padding: 0 24px;
}

.ds-key {
  height: 68px;
  border-radius: 16px;
  background: var(--ds-surface);
  border: 1px solid var(--ds-border);
  font-size: 28px;
  font-weight: 600;
  color: var(--ds-ink);
  cursor: pointer;
  box-shadow: var(--ds-shadow-key);
}

.ds-key--icon {
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 0;
  box-shadow: none;
  color: var(--ds-ink-3);
}

.ds-key--icon svg { width: 30px; height: 30px; }
.ds-key:disabled { opacity: 0.5; cursor: not-allowed; }

.ds-pin-foot {
  margin: 0;
  padding: 20px 32px 32px;
  font-size: 14px;
  line-height: 1.45;
  color: var(--ds-muted);
  text-align: center;
}

/* ---- full-screen states (fetch error, update required) ---------------- */

.ds-state-wrap {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 24px 16px 48px;
}

.ds-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 28px 20px 24px;
  background: var(--ds-surface);
  border: 1px solid var(--ds-border);
  border-radius: 20px;
  text-align: center;
}

.ds-state-icon {
  width: 64px;
  height: 64px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: var(--ds-surface-2);
  color: var(--ds-ink-3);
}

.ds-state-icon svg { width: 32px; height: 32px; }
.ds-state-icon--error { background: var(--ds-error-bg); color: var(--ds-error); }

.ds-state-title { margin: 0; font-size: 21px; font-weight: 700; line-height: 1.3; }
.ds-state-body { margin: 0; font-size: 16px; line-height: 1.5; color: var(--ds-ink-3); }

.ds-state-safe {
  margin: 0;
  padding: 10px 12px;
  border-radius: 12px;
  background: var(--ds-surface-2);
  font-size: 14px;
  line-height: 1.45;
  color: var(--ds-ink-2);
}

.ds-state-code { margin: 0; font-size: 13px; line-height: 1.45; color: var(--ds-muted); }

/* The update wall's help line sits a step above its code line (14 → 13). */
.ds-alert-help { margin: 0; font-size: 14px; line-height: 1.45; color: var(--ds-muted); text-align: center; }
.ds-alert-help span { font-size: 13px; }
.ds-state .ds-btn { margin-top: 6px; }

/* ---- update required -------------------------------------------------- */

.ds-screen--alert { background: var(--ds-surface); padding-bottom: 0; }

.ds-alert-hero {
  background: var(--ds-error);
  color: var(--ds-on-accent);
  padding: 72px 24px 32px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.ds-alert-icon {
  width: 64px;
  height: 64px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.16);
}

.ds-alert-icon svg { width: 36px; height: 36px; }
.ds-alert-title { margin: 0; font-size: 30px; font-weight: 700; line-height: 1.2; }
.ds-alert-body { margin: 0; font-size: 17px; line-height: 1.45; color: #ffe4e0; }

.ds-alert-main {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 24px 20px 0;
}

.ds-versions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  border: 1px solid var(--ds-border);
  border-radius: 14px;
  overflow: hidden;
}

.ds-version { display: flex; flex-direction: column; gap: 2px; padding: 14px 16px; }
.ds-version + .ds-version { border-left: 1px solid var(--ds-border); }
.ds-version--old { background: #fef3f2; }
.ds-version-label { font-size: 13px; color: var(--ds-muted); }
.ds-version--old .ds-version-label { color: #7a1a12; }

.ds-version-value {
  font-size: 22px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.ds-version--old .ds-version-value { color: var(--ds-error); }

.ds-alert-h2 { margin: 0; font-size: 16px; font-weight: 700; }
.ds-alert-p { margin: 0; font-size: 15px; line-height: 1.5; color: var(--ds-ink-3); }

.ds-alert-foot {
  padding: 16px 20px 32px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* ---- statement ledger ------------------------------------------------- */

.ds-ledger-band {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 14px;
  background: var(--ds-surface-3);
  font-size: 14px;
  color: var(--ds-ink-3);
}

.ds-ledger-band--top { border-bottom: 1px solid var(--ds-divider); }
.ds-ledger-band--bottom { color: var(--ds-ink); font-weight: 600; }
.ds-ledger-band-value { font-weight: 600; font-variant-numeric: tabular-nums; }
.ds-ledger-band--bottom .ds-ledger-band-value { font-weight: 700; }

.ds-ledger { list-style: none; margin: 0; padding: 0; }

.ds-ledger-row {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--ds-divider);
}

.ds-ledger-date {
  width: 36px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 2px;
}

.ds-ledger-dd { font-size: 20px; font-weight: 600; line-height: 1; }
.ds-ledger-mon { font-size: 12px; color: var(--ds-muted); }

.ds-ledger-text { flex-grow: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.ds-ledger-tagrow { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.ds-ledger-note { font-size: 14px; color: var(--ds-ink-2); line-height: 1.35; }

.ds-ledger-amounts {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  flex-shrink: 0;
}

.ds-ledger-amt { font-size: 15px; font-weight: 600; font-variant-numeric: tabular-nums; }
.ds-ledger-bal { font-size: 12px; color: var(--ds-muted); font-variant-numeric: tabular-nums; }

/* ---- misc ------------------------------------------------------------- */

.ds-empty {
  padding: 32px 20px;
  text-align: center;
  font-size: 15px;
  color: var(--ds-muted);
}

/* ---- screen-specific: capture wizard ---------------------------------- */
/* (wizard boards only; shared parts belong in the kit above) */

/* The boards are a fixed 844px frame: body scrolls, foot bar stays put.
   .ds-screen's min-height would let the body grow instead of scrolling. */
.cw-screen { height: 100dvh; min-height: 0; overflow: hidden; }
.cw-body { padding-bottom: 24px; }

/* ---- date --------------------------------------------------------- */

.cw-date-shell svg { color: var(--ds-accent); }
.cw-date-input { font-weight: 600; }

/* ---- party + item suggestions -------------------------------------- */

.cw-sug-heading {
  padding: 4px 4px 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--ds-muted);
}

.cw-sug {
  list-style: none;
  margin: 0;
  padding: 4px 0;
  background: var(--ds-surface);
  border: 1px solid var(--ds-border);
  border-radius: 14px;
}

.cw-sug--drop { border-radius: 12px; box-shadow: 0 6px 16px rgba(17, 24, 39, 0.08); }

.cw-sug-row {
  width: 100%;
  min-height: 56px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 14px;
  background: none;
  border: 0;
  text-align: left;
  color: var(--ds-ink);
  cursor: pointer;
}

.cw-sug-row--item { min-height: 48px; justify-content: space-between; padding: 6px 14px; }
/* A party row names someone, an item row names a thing in a list of them. */
.cw-sug-row--item .cw-sug-name { font-weight: 500; }
.cw-sug-row .ds-avatar { width: 36px; height: 36px; }

.cw-sug-text { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cw-sug-name { font-size: 15px; font-weight: 600; }
.cw-sug-meta { font-size: 13px; font-weight: 400; color: var(--ds-muted); }

.cw-sug-stock { font-size: 13px; font-weight: 600; color: var(--ds-muted); white-space: nowrap; }
.cw-sug-stock--out { color: var(--ds-error); }

.cw-sug-empty { padding: 4px 14px 10px; font-size: 14px; color: var(--ds-muted); }

.cw-create-row { border-top: 1px solid var(--ds-divider); color: var(--ds-accent); }
.cw-create-row .cw-sug-name { color: var(--ds-accent); }

.cw-create-icon {
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: var(--ds-accent-light);
}

.cw-create-icon svg { width: 18px; height: 18px; }

/* ---- the chosen party ---------------------------------------------- */

.cw-party {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 12px 12px 14px;
  background: var(--ds-surface);
  border: 2px solid var(--ds-accent);
  border-radius: 14px;
}

.cw-party--plain { border: 1px solid var(--ds-border); padding: 12px 14px; }

.cw-party-text { flex-grow: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cw-party-name { font-size: 16px; font-weight: 600; }
.cw-party-meta { font-size: 13px; color: var(--ds-muted); }

.cw-party-change {
  height: 44px;
  padding: 0 12px;
  flex-shrink: 0;
  background: none;
  border: 0;
  border-radius: 10px;
  font-size: 14px;
  font-weight: 600;
  color: var(--ds-accent);
  cursor: pointer;
}

/* ---- lines already added ------------------------------------------- */

.cw-lines {
  list-style: none;
  margin: 0;
  padding: 0;
  background: var(--ds-surface);
  border: 1px solid var(--ds-border);
  border-radius: 14px;
  overflow: hidden;
}

.cw-line {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 6px 8px 14px;
  border-bottom: 1px solid var(--ds-divider);
}

.cw-line:last-child { border-bottom: 0; }

.cw-line-text { flex-grow: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cw-line-name { font-size: 15px; font-weight: 600; }
.cw-line-meta { font-size: 14px; color: var(--ds-muted); }

.cw-line-amount { font-size: 15px; font-weight: 600; font-variant-numeric: tabular-nums; }

.cw-line-remove {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 0;
  border-radius: 10px;
  color: var(--ds-muted);
  cursor: pointer;
}

.cw-line-remove svg { width: 18px; height: 18px; }

/* Lines copied from an earlier step: the same rows, headed by a band that
   says where they came from, and with no remove column to promise an edit
   that belongs on the step they were copied from. */
.cw-mirror {
  display: flex;
  flex-direction: column;
  background: var(--ds-surface);
  border: 1px solid var(--ds-border);
  border-radius: 14px;
  overflow: hidden;
}

.cw-mirror-head {
  padding: 12px 14px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ds-muted);
  background: var(--ds-surface-3);
  border-bottom: 1px solid var(--ds-divider);
}

.cw-mirror-row { display: flex; align-items: center; gap: 12px; padding: 12px 14px; }

/* ---- the line editor card ------------------------------------------ */

.cw-editor {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 16px;
  background: var(--ds-surface);
  border: 1px solid var(--ds-border);
  border-radius: 16px;
}

.cw-editor-title { font-size: 15px; font-weight: 600; }
.cw-editor .ds-field { gap: 6px; }

.cw-editor .ds-field-shell {
  height: 50px;
  border-radius: 12px;
  background: var(--ds-surface-3);
}

.cw-editor .ds-field-input { height: 46px; }

.cw-grid2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }

.cw-stepper {
  display: flex;
  align-items: center;
  height: 50px;
  background: var(--ds-surface-3);
  border: 1px solid var(--ds-border-strong);
  border-radius: 12px;
  overflow: hidden;
}

.cw-stepper:focus-within { border-color: var(--ds-accent); }

.cw-stepper-btn {
  width: 44px;
  height: 48px;
  flex-shrink: 0;
  background: none;
  border: 0;
  font-size: 20px;
  color: var(--ds-ink);
  cursor: pointer;
}

.cw-stepper-input {
  flex-grow: 1;
  min-width: 0;
  width: 40px;
  height: 46px;
  min-height: 0;
  padding: 0;
  border: 0;
  background: none;
  border-radius: 0;
  text-align: center;
  font-size: 17px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ds-ink);
}

.cw-stepper-input:focus-visible { outline: none; }

.cw-rate-shell { gap: 4px; padding: 0 12px; }
.cw-rupee { font-size: 17px; font-weight: 600; color: var(--ds-muted); }

.cw-rate-input {
  font-size: 17px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.cw-rate-spinner { width: 16px; height: 16px; color: var(--ds-muted); }

.cw-hint { font-size: 13px; color: var(--ds-muted); }
.cw-hint--block { font-size: 14px; color: var(--ds-ink-3); }

/* Advisory, never a gate (ADR-0020) — the colour warns, the button stays live. */
.cw-alert {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 14px;
  border-radius: 12px;
  background: #fee4e2;
  border: 1px solid #f4a9a0;
  color: #7a1a12;
  font-size: 14px;
  line-height: 1.45;
}

.cw-alert strong { display: flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 700; }
.cw-alert strong svg { width: 20px; height: 20px; flex-shrink: 0; }

.cw-add {
  height: 46px;
  border-radius: 12px;
  background: var(--ds-surface);
  border: 1.5px solid var(--ds-accent);
  color: var(--ds-accent);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
}

/* #6b7280 is this one label's own grey — readable while clearly disabled,
   and a step darker than the --ds-muted-2 the kit's dimmed text uses. */
.cw-add:disabled { border-color: var(--ds-border-strong); color: #6b7280; cursor: not-allowed; }

/* Where a prefilled rate came from. Blue when it was actually filled in
   from a past sale, plain grey when there was nothing to fill it from. */
.cw-ratehint {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-radius: 10px;
  background: var(--ds-surface-2);
  color: var(--ds-ink-2);
  font-size: 14px;
  line-height: 1.35;
}

.cw-ratehint--filled { background: var(--ds-accent-light); color: var(--ds-accent-deep); }
.cw-ratehint svg { width: 18px; height: 18px; flex-shrink: 0; }

/* ---- notes ---------------------------------------------------------- */

.cw-textarea--over { border: 2px solid var(--ds-error); }

.cw-count { display: flex; justify-content: space-between; gap: 12px; font-size: 13px; }
.cw-count-error { color: var(--ds-error); font-weight: 600; }
.cw-count-total { color: var(--ds-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.cw-count-total--over { color: var(--ds-error); font-weight: 700; }

/* ---- review card ---------------------------------------------------- */

.cw-review-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  background: var(--ds-accent);
  color: var(--ds-on-accent);
}

.cw-review-head-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cw-review-eyebrow { display: flex; align-items: center; gap: 8px; }
.cw-review-doctype { font-size: 13px; color: var(--ds-on-accent-soft); }

.cw-review-amount {
  font-size: 24px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.cw-review-date { font-size: 14px; color: var(--ds-on-accent-soft); white-space: nowrap; }

.cw-review .ds-review-dd { flex-grow: 1; }

.cw-fact { display: flex; flex-direction: column; gap: 2px; }
.cw-fact-sub { font-size: 13px; font-weight: 400; color: var(--ds-muted); }

.cw-edit {
  height: 28px;
  flex-shrink: 0;
  padding: 0 4px;
  background: none;
  border: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--ds-accent);
  cursor: pointer;
}

.cw-group { border-top: 1px solid var(--ds-border); }

.cw-group-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px 4px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ds-muted);
}

.cw-table { margin: 0 16px; font-size: 14px; font-variant-numeric: tabular-nums; }

.cw-tr {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 0.9fr) minmax(0, 0.8fr) minmax(0, 1fr);
  gap: 8px;
  padding: 9px 0;
  border-top: 1px solid var(--ds-divider);
  align-items: baseline;
  text-align: right;
}

.cw-tr > :first-child { text-align: left; }
.cw-tr--head { padding: 6px 0; border-top: 0; font-size: 13px; color: var(--ds-muted); }
.cw-td-name { font-weight: 600; overflow-wrap: anywhere; }
.cw-td-amt { font-weight: 600; }

/* The last thing in the review card, so its lower padding is what sets
   the gap to the card's bottom edge — 14px read as cramped against a
   16px gutter on every other side. */
.cw-group-total {
  display: flex;
  justify-content: space-between;
  margin: 4px 16px 0;
  padding: 10px 0 20px;
  border-top: 1.5px solid var(--ds-ink);
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.cw-review-foot {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  background: var(--ds-surface-3);
  border-top: 1px solid var(--ds-border);
  font-size: 14px;
  color: var(--ds-ink-3);
}

.cw-review-foot > :last-child { font-weight: 700; color: var(--ds-ink); }

/* ---- amber asides (the Return escape hatch) ------------------------- */

.cw-caution {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 8px 10px 14px;
  background: var(--ds-warn-bg);
  border: 1px solid var(--ds-warn-border);
  border-radius: 12px;
  color: var(--ds-warn-ink);
}

.cw-caution-text { flex-grow: 1; font-size: 14px; line-height: 1.35; }

.cw-caution-btn {
  height: 44px;
  flex-shrink: 0;
  padding: 0 12px;
  background: none;
  border: 0;
  font-size: 14px;
  font-weight: 700;
  color: var(--ds-warn-ink);
  text-decoration: underline;
  cursor: pointer;
}

.cw-warnbtn {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  padding: 8px 12px;
  background: var(--ds-warn-bg);
  border: 1px solid var(--ds-warn-border);
  border-radius: 12px;
  text-align: left;
  color: var(--ds-warn-ink);
  cursor: pointer;
}

.cw-warnbtn > span { flex-grow: 1; font-size: 14px; line-height: 1.35; }
.cw-warnbtn svg { width: 20px; height: 20px; flex-shrink: 0; }
.cw-warnbtn svg:last-child { width: 18px; height: 18px; }

/* ---- checkbox cards -------------------------------------------------- */

.ds-checkcard.cw-checkcard {
  margin: 0;
  align-items: flex-start;
  padding: 14px;
  border-color: var(--ds-border-strong);
}

.ds-checkcard.cw-checkcard--expense { padding: 12px 14px; }
.cw-checkcard .ds-checkcard-sub { font-size: 14px; line-height: 1.4; }

.cw-checkcard--personal { background: var(--ds-warn-bg); border-color: var(--ds-warn-border); }

/* ---- sheets ---------------------------------------------------------- */

.cw-sheet-intro { display: flex; flex-direction: column; gap: 4px; }
.cw-sheet-intro .ds-sheet-title { font-size: 21px; line-height: 1.25; }
.cw-sheet-sub { margin: 0; font-size: 14px; color: var(--ds-muted); }
.cw-sheet-body { margin: 0; font-size: 15px; line-height: 1.5; color: var(--ds-ink-2); }

.cw-sheet-readout { flex-direction: column; align-items: stretch; gap: 4px; }
.cw-sheet-readout-value { font-size: 14px; font-weight: 600; }

.cw-sheet-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  padding-top: 4px;
}

.cw-sheet-stack { display: flex; flex-direction: column; gap: 10px; padding-top: 4px; }
.cw-sheet-actions .ds-btn { height: 50px; font-size: 15px; }
/* The stacked pair carries a decision rather than a save, and the boards
   give it the primary button's own 52px. */
.cw-sheet-stack .ds-btn { height: 52px; font-size: 15px; }

.cw-near { display: flex; flex-direction: column; gap: 8px; }
.cw-near-label { margin: 0; font-size: 14px; color: var(--ds-muted); }
.cw-near-row { display: flex; flex-wrap: wrap; gap: 8px; }

/* ---- payment direction ----------------------------------------------- */

.cw-dirgrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }

.cw-dir {
  min-height: 92px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  padding: 12px 14px;
  background: var(--ds-surface);
  border: 1px solid var(--ds-border-strong);
  border-radius: 16px;
  text-align: left;
  color: var(--ds-ink);
  cursor: pointer;
}

.cw-dir--in { background: #f0fdf4; border: 2px solid var(--ds-success); }
.cw-dir--out { background: #fef3f2; border: 2px solid var(--ds-error); }

.cw-dir-icon {
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 10px;
}

.cw-dir-icon svg { width: 20px; height: 20px; }
.cw-dir-icon--in { background: var(--ds-success-bg); color: var(--ds-success); }
.cw-dir-icon--out { background: var(--ds-error-bg); color: var(--ds-error); }

.cw-dir-text { display: flex; flex-direction: column; gap: 1px; }
.cw-dir-label { font-size: 16px; font-weight: 700; }
.cw-dir-sub { font-size: 13px; color: var(--ds-muted); }

/* ---- pill rows (payment modes, expense categories) ------------------- */

.cw-pillrow { display: flex; flex-wrap: wrap; gap: 8px; }

.cw-subgroup-label { font-size: 14px; font-weight: 600; color: var(--ds-warn-ink); padding-top: 4px; }

/* ---- done screen ----------------------------------------------------- */

.cw-done-main {
  flex-grow: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-bottom: 8px;
}

/* Centred, but safely: justify-content would push the overflow above
   scrollTop 0 where no gesture reaches, whereas auto margins simply
   collapse once there is no longer room to spare. */
.cw-done-main > :first-child { margin-top: auto; }
.cw-done-main > :last-child { margin-bottom: auto; }

.cw-done-main .ds-done { flex-grow: 0; }

.cw-moves {
  margin: 0 16px;
  background: var(--ds-surface);
  border: 1px solid var(--ds-border);
  border-radius: 16px;
  overflow: hidden;
}

.cw-moves-head {
  padding: 12px 16px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ds-muted);
  background: var(--ds-surface-3);
  border-bottom: 1px solid var(--ds-divider);
}

.cw-moves-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 16px;
  font-size: 14px;
}

.cw-moves-delta { font-weight: 700; font-variant-numeric: tabular-nums; }
.cw-moves-delta--in { color: var(--ds-success); }


/* The party's standing, on the second line of the payment's party card. */
.cw-party-balance { font-size: 14px; font-weight: 600; }
.cw-party-balance--up { color: var(--ds-success); }
.cw-party-balance--down { color: var(--ds-error); }
.cw-party-balance--level { color: var(--ds-muted); }

/* Settle the whole balance in one tap, beside the amount it fills. */
.cw-fullchip {
  align-self: flex-start;
  height: 36px;
  padding: 0 14px;
  border: 0;
  border-radius: 999px;
  background: var(--ds-accent-light);
  color: var(--ds-accent-deep);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}

/* Where this payment leaves the balance: a reading, not a decision, so it
   is the boards' plain grey strip rather than a tinted card. */
.cw-after {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 12px 14px;
  border-radius: 12px;
  background: var(--ds-surface-2);
  font-size: 14px;
}

.cw-after-label { color: var(--ds-ink-3); }
.cw-after-value { font-weight: 700; text-align: right; }
.cw-after-value--up { color: var(--ds-success); }
.cw-after-value--down { color: var(--ds-error); }
.cw-after-value--level { color: var(--ds-ink); }

/* A payment's done figure carries its direction in the sign and the ink. */
.cw-done-amount--in { color: var(--ds-success); }
.cw-done-amount--out { color: var(--ds-error); }

/* A step this run skips keeps its segment, greyed apart from both the
   done and the still-to-come states. */
.cw-step-seg--skipped { background: var(--ds-border); }

/* An invalid field on the capture boards is drawn at 2px, not just recoloured. */
.cw-screen .ds-field-shell--invalid { border-width: 2px; }

/* A swap's net money effect, as its own card under the review summary.
   Signed and coloured on purpose: one figure whose direction IS the
   message, unlike the statement's table where both are noise. */
.cw-net {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 16px;
  border-radius: 16px;
  border: 1px solid;
}

.cw-net-label { font-size: 15px; font-weight: 600; }
.cw-net-value { font-size: 24px; font-weight: 700; font-variant-numeric: tabular-nums; }

.cw-net--collect {
  background: var(--ds-success-bg);
  border-color: #a7e3bd;
  color: #14532d;
}

.cw-net--pay {
  background: var(--ds-error-bg);
  border-color: #f4a9a0;
  color: #7a1a12;
}

.cw-net--even {
  background: var(--ds-surface-2);
  border-color: var(--ds-border);
  color: var(--ds-ink-3);
}

/* ---- screen-specific: stock + parties --------------------------------- */

/* Stock: the search field and its filter pills are one block above the list. */
/* flex-shrink:0 throughout: the list below is the only part that may
   give way on a short viewport. */
.stock-toolbar {
  padding: 12px 16px 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex-shrink: 0;
}

.stock-filters { display: flex; gap: 8px; }
.stock-filters .ds-pill { font-weight: 600; }

.stock-listhead {
  display: flex;
  justify-content: space-between;
  padding: 14px 20px 6px;
  font-size: 13px;
  color: var(--ds-muted);
  flex-shrink: 0;
}

/* Stock rows are tighter than a standard .ds-row: one line of text, a figure. */
.stock-row { min-height: 60px; padding: 10px 14px; }

.stock-row-main {
  flex-grow: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
}

.stock-row-name { font-size: 15px; font-weight: 600; }

.stock-row-qty {
  flex-shrink: 0;
  display: flex;
  align-items: baseline;
  gap: 4px;
}

.stock-qty {
  font-size: 20px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.stock-qty--out { color: var(--ds-error); }
.stock-units { font-size: 13px; color: var(--ds-muted); }

.parties-toolbar { padding: 12px 16px 0; flex-shrink: 0; }

.parties-count {
  padding: 12px 4px 8px;
  font-size: 13px;
  color: var(--ds-muted);
}

.parties-row { padding: 10px 12px 10px 14px; }
.parties-row .ds-row-title { font-size: 15px; }

.parties-meta {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* A party nobody can be called or visited at is a gap to fill, not a
   detail to grey out, so the line carries the warning ink instead. */
.parties-meta--missing { color: #8a5a00; }

.parties-statement-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ds-accent);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}

.parties-statement-link:disabled { cursor: default; opacity: 0.55; }

/* Both edit sheets: a label sitting directly on its control, no field
   shell — .ds-field's 8px gap is for the bordered shells. */
.admin-field { display: flex; flex-direction: column; gap: 6px; }

/* The name is the row's key on both screens, shown but never typed into. */
.admin-field input[readonly] { color: var(--ds-muted); }

.admin-confirm-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

/* A failure that leaves the sheet open is stated on this line, beside the
   control that failed, rather than as a toast at the foot of the screen —
   the user is looking at the sheet, and the retry button is right here. */
.admin-sheet-error {
  margin: 0;
  padding: 10px 12px;
  border-radius: 12px;
  background: var(--ds-error-bg);
  color: var(--ds-error-deep);
  font-size: 14px;
  font-weight: 600;
}

.admin-empty { margin: 0; padding: 24px 16px; }

/* ---- screen-specific: home -------------------------------------------- */

/* The top strip is carried over from the previous design at the owner's
   request, so it keeps its own classes — it just needs the horizontal
   padding it used to inherit from #app. */
.ds-screen .home-top-row { padding: 20px 24px 0; }
/* 24px rather than the board's 20: asked for in review, and the
   name and the date line share the gutter so they move together. */
.ds-screen .home-header { padding: 0 24px; }

.ds-screen .home-summary-card {
  margin: 16px 16px 0;
  padding: 18px 20px;
  border-radius: 20px;
  background: var(--ds-accent);
  color: var(--ds-on-accent);
  border: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
  text-align: left;
  cursor: pointer;
}

.ds-screen .home-summary-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
}

.ds-screen .home-summary-label { font-size: 14px; color: var(--ds-on-accent-soft); }

.ds-screen .home-summary-link {
  font-size: 14px;
  font-weight: 600;
  color: var(--ds-on-accent);
}

/* Four figures, so 2×2 — four across leaves no room for "Payment
   collected" or a lakh-sized number at 390px. */
.home-summary-figures {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px 10px;
}

.home-summary-figure { display: flex; flex-direction: column; gap: 2px; }
.home-summary-figure-label { font-size: 13px; color: var(--ds-on-accent-soft); }

.home-summary-figure-value {
  font-size: 20px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* Skeleton while the first-ever fetch is in flight — the board is static
   and so cannot draw this state, but it is the honest one to show. */
.home-summary-figure-value.is-loading {
  color: transparent;
  background: rgba(255, 255, 255, 0.28);
  border-radius: var(--radius-sm);
}

/* ---- screen-specific: reports ----------------------------------------- */

/* ---- freshness --------------------------------------------------------- */

/* Every screen computing from the snapshot states the instant it was
   taken — the condition on which reports are cached at all (ADR-0021). */
.asof {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px 20px 0;
}

.asof-stamp {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ds-muted);
}

/* A control, drawn as the text it wraps: the stamp is the affordance, and
   a button chrome here would compete with the card above it. */
.asof-button {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
  align-self: flex-start;
}

.asof-button:disabled { cursor: default; }

.asof-mark {
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
}

/* Sized against the stamp rather than the 1.1em the spinner defaults to,
   which next to 13px text reads as a page-level loading state. */
.asof-mark.spinner { border-width: 2px; }

.asof-mark--fresh { color: var(--ds-success); }

/* Not a failure — entries are waiting their turn, and the note beside it
   says so in words. Warn ink rather than error red. */
.asof-mark--pending {
  border-radius: 50%;
  background: var(--ds-warn-ink);
  width: 9px;
  height: 9px;
}
.asof-mark--fresh svg { width: 14px; height: 14px; display: block; }

/* Queued entries are deliberately in none of the figures beside this, so
   it reads as something to know rather than as more quiet metadata. */
.asof-unsent { font-size: 13px; color: var(--ds-warn-ink); }

/* On Home the stamp trails the summary card, so it takes the card's own
   gutter instead of the screen's. */
.home-summary-asof { padding: 8px 4px 0; }

/* Today's board heads the summary with the day it reports on. */
.reports-dayline { padding: 8px 20px 12px; }
.reports-dayline-date { font-size: 15px; font-weight: 600; }

/* ---- period bar ------------------------------------------------------- */

.reports-rangecard {
  margin: 16px 16px 0;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 10px 10px 14px;
  background: var(--ds-surface);
  border: 1px solid var(--ds-border);
  border-radius: 16px;
}

.reports-rangecard-text { flex-grow: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.reports-rangecard-title { font-size: 16px; font-weight: 600; }
.reports-rangecard-sub { font-size: 13px; color: var(--ds-muted); }

.reports-rangecard-btn {
  height: 44px;
  padding: 0 14px;
  flex-shrink: 0;
  border: 0;
  border-radius: 12px;
  background: var(--ds-surface-2);
  color: var(--ds-ink);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}

/* The Period board draws its quick ranges lighter than every other pill
   row, and only the pressed one at the pills' usual weight — so the quiet
   weight is scoped to the rest rather than set on the whole row. */
.reports-quickranges .ds-pill[aria-pressed='false'] { font-weight: 500; }

/* The two money-out sections are the only ones the boards draw in red. */
.reports-acc--out .ds-chip-icon--report { color: var(--ds-error); }

/* ---- custom range picker ---------------------------------------------- */

/* The picker's own rows carry the board's 16px gutter, so the sheet gives
   up its horizontal padding and its uniform gap for this one use. */
.ds-sheet:has(.reports-grid) {
  padding-left: 0;
  padding-right: 0;
  gap: 0;
}

.ds-sheet:has(.reports-grid) .ds-sheet-head { padding: 6px 8px 0 20px; }

.reports-endcards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  padding: 12px 16px 0;
}

.reports-endcard {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px;
  border: 1px solid var(--ds-border-strong);
  border-radius: 12px;
}

.reports-endcard--active { border: 2px solid var(--ds-accent); padding: 9px 11px; }
.reports-endcard--active .reports-endcard-value { color: var(--ds-accent); }
.reports-endcard-label { font-size: 13px; color: var(--ds-muted); }
.reports-endcard-value { font-size: 15px; font-weight: 600; }

.reports-presets { padding: 12px 16px 4px; }

.reports-monthnav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 8px 0 20px;
}

.reports-monthnav-label { font-size: 16px; font-weight: 600; }
.reports-monthnav-buttons { display: flex; gap: 4px; }
.reports-monthnav-buttons .ds-appbar-icon svg { width: 20px; height: 20px; }
.reports-monthnav-buttons .ds-appbar-icon:disabled { opacity: 0.3; cursor: not-allowed; }

.reports-weekdays {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  padding: 4px 16px 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--ds-muted);
  text-align: center;
}

.reports-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  row-gap: 4px;
  padding: 6px 16px 0;
}

/* The band is the cell's background, not the button's, so it runs edge to
   edge between days rather than leaving a gap at every column boundary. */
.reports-cell { height: 44px; display: flex; align-items: center; justify-content: center; }
.reports-cell--band-start { background: var(--ds-accent-light); border-radius: 12px 0 0 12px; }
.reports-cell--band-mid { background: var(--ds-accent-light); }
.reports-cell--band-end { background: var(--ds-accent-light); border-radius: 0 12px 12px 0; }

.reports-day {
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: var(--ds-ink);
  font-size: 15px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}

.reports-day:disabled { color: var(--ds-muted-2); cursor: not-allowed; }
.reports-day--today { border: 1.5px solid var(--ds-ink); font-weight: 700; }

.reports-day--edge {
  background: var(--ds-accent);
  color: var(--ds-on-accent);
  border: 0;
  font-weight: 700;
}

.reports-pickerhint {
  margin: 0;
  padding: 10px 20px;
  font-size: 14px;
  line-height: 1.4;
  color: var(--ds-ink-3);
}

.reports-pickerfoot {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px 0;
  border-top: 1px solid var(--ds-divider);
}

.reports-pickerfoot-text { flex-grow: 1; display: flex; flex-direction: column; gap: 2px; }
.reports-pickerfoot-days { font-size: 20px; font-weight: 600; }
.reports-pickerfoot-note { font-size: 13px; color: var(--ds-muted); }

.reports-pickerfoot .ds-btn { width: auto; height: 48px; padding: 0 28px; font-size: 15px; }

/* ---- party statement --------------------------------------------------- */

.stmt-head { margin: 16px 16px 0; }

.stmt-party {
  width: 100%;
  min-height: 64px;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 12px 12px 14px;
  background: none;
  border: 0;
  text-align: left;
  color: var(--ds-ink);
  cursor: pointer;
}

.stmt-change { font-size: 14px; font-weight: 600; color: var(--ds-accent); }

.stmt-daterow {
  width: 100%;
  min-height: 48px;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  background: none;
  border: 0;
  border-top: 1px solid var(--ds-divider);
  text-align: left;
  color: var(--ds-ink);
  cursor: pointer;
}

.stmt-daterow-icon { display: flex; flex-shrink: 0; color: var(--ds-accent); }
.stmt-daterow-icon svg { width: 18px; height: 18px; }
.stmt-daterow-label { flex-grow: 1; min-width: 0; font-size: 14px; font-weight: 600; }
.stmt-daterow-days { font-size: 13px; color: var(--ds-muted); }

.stmt-herowrap .ds-hero { margin: 12px 16px 0; padding: 18px 20px; gap: 14px; }

/* The statement's money figures are all one ink; the only row drawn
   differently moved the balance by nothing, and shows a dash, not a figure. */
.ds-ledger-amt--zero { color: var(--ds-muted); }

.stmt-herohint {
  margin: 6px 16px 0;
  font-size: 12px;
  color: var(--ds-muted);
}

.stmt-filters { padding: 12px 16px; }
.stmt-ledgercard { margin: 0 16px 24px; }
.stmt-partylist { margin: 0; max-height: 46dvh; overflow-y: auto; }

/* The net-sales line: an equation, not a card, so it reads as the
   subtraction of the three sections drawn above it rather than as a
   seventh figure of its own. */
.reports-netline {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 0 12px;
  margin: 2px 4px 6px;
  padding: 10px 14px;
  border-radius: 12px;
  background: var(--ds-surface-3);
}

.reports-netline-label { font-size: 14px; font-weight: 700; color: var(--ds-ink); }
.reports-netline-sub { grid-column: 1; font-size: 12px; color: var(--ds-muted); }
.reports-netline-value {
  grid-row: 1 / span 2;
  grid-column: 2;
  align-self: center;
  font-size: 16px;
  font-weight: 700;
  color: var(--ds-ink);
  font-variant-numeric: tabular-nums;
}

/* ---- failure card ------------------------------------------------------ */

/* A retry already in flight stays a solid working grey with white text:
   the pale .ds-btn:disabled reads as "not available" rather than "busy". */
.ds-state--retrying .ds-btn:disabled {
  background: #6b7280;
  color: var(--ds-on-accent);
}
