/* Tokens — extracted from the approved mockup. Exact values; see
   docs/superpowers/specs/2026-09-22-ui-design-system.md §1.
   No shadows exist in this design system. Elevation is borders. */

:root {
  --bg-ground: #faf7f2;
  --bg-surface: #ffffff;
  --bg-faint: #fdfbf8;

  --ink: #1c1a17;
  --ink-muted: #6b6255;
  --ink-faint: #8a7f70;

  --line: #e6dfd4;
  --line-strong: #cfc4b4;
  --fill-subtle: #f2ece2;

  --accent: #b4532a;
  --accent-hover: #8e3f1f;
  --accent-subtle: #fbf3ec;
  --accent-subtle-line: #e8d3c2;

  --positive: #1f6f63;
  --positive-subtle: #f0f6f4;
  --positive-subtle-line: #cfe0db;
  --negative: #9e3a2f;

  /* Not from the mockup — the artboards have no drawer, because they have
     no wide layout to draw a rail behind (shell spec §1 is the one place
     invention is permitted). --ink (#1C1A17) at reduced opacity, for the
     phone-width drawer's scrim. */
  --scrim: rgba(28, 26, 23, 0.32);
  /* A sheet's travel: quick off the mark, a long soft landing. */
  --ease-sheet: cubic-bezier(0.32, 0.72, 0, 1);

  --radius-pill: 999px;
  --radius-lg: 16px;
  --radius-md: 14px;
  --radius-sm: 12px;
  --radius-xs: 11px;
  --radius-2xs: 10px;

  --display: "Fraunces", Georgia, serif;
  --body: "IBM Plex Sans", system-ui, sans-serif;
}

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  background: var(--bg-ground);
  color: var(--ink);
  font-family: var(--body);
  font-size: 14px;
  /* The artboards set no body line-height (the browser's "normal"), and
     give prose its own (1.45–1.7) where they want it — every such block
     carries its own class below. A global 1.45 made every label, figure
     and row taller than drawn (task-fidelity Part A). */
  line-height: normal;
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--accent);
}
a:hover {
  color: var(--accent-hover);
}

/* The frame. Every screen is the same three regions: a fixed header, a
   scrolling middle, and a fixed footer where an input affordance exists.
   390px is the mockup's artboard width; on a wider viewport the column
   simply centres rather than stretching, because no responsive variant
   was ever designed. */

#root {
  height: 100%;
}

/* Shell — spec `docs/superpowers/specs/2026-09-22-app-shell-and-responsive.md`
   §1. Two panes at desktop width, one pane at phone width. Every VISUAL
   consequence of the 768px breakpoint (rail position, pane width, drawer
   transform) is still pure CSS, in the single media query below.
   `.app-frame` (below) is unchanged: the screen inside the pane never
   rescales, at any width.
   The one thing CSS cannot do — keep the drawer's menu button OUT of the
   DOM entirely at desktop width, not merely visually hidden — is decided
   by `viewport.ts`'s `useIsDesktop()`, read through shell context by
   `ScreenHeader`'s "top" variant (`ScreenHeader.tsx`). See that file and
   task-15-report.md for the bug this replaced: a menu button rendered
   unconditionally with the native `hidden` attribute is still a real DOM
   node with a 0×0 rect at desktop width, not "not rendered". */

.shell {
  height: 100%;
  display: flex;
  overflow: hidden;
  background: var(--bg-ground);
}

.shell-rail {
  width: 264px;
  flex-shrink: 0;
  background: var(--bg-surface);
  border-right: 1px solid var(--line);
  overflow-y: auto;
  display: flex;
  flex-direction: column;

  /* Phone width (default): an off-canvas drawer, closed until the menu
     button opens it. */
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  z-index: 40;
  transform: translateX(-100%);
  transition: transform 200ms ease;
}

.shell-rail[data-open="true"] {
  transform: translateX(0);
}

.shell-scrim {
  position: fixed;
  inset: 0;
  z-index: 35;
  border: 0;
  padding: 0;
  background: var(--scrim);
  cursor: pointer;
}

.shell-pane {
  flex: 1;
  min-width: 0;
  height: 100%;
  display: flex;
  justify-content: center;
  overflow: hidden;
}

@media (min-width: 768px) {
  .shell-rail {
    position: static;
    transform: none;
    transition: none;
    z-index: auto;
  }

  .shell-scrim {
    display: none;
  }

  /* The screen fills the pane (task-fidelity B1, shell spec §1 "Pane").
     Its header bar and footer bar run edge to edge — background and
     border across the whole pane — so the page never reads as a phone
     card on a beige wall. Only their inner content, and every scrolling
     region's content, is inset to a centred column of `--col`. `--inset`
     is the gap either side of that column; `100%` resolves against each
     region's own containing block (the full-width frame). Each region
     keeps its artboard gutter (20px headers, 16px bodies/footers) inside
     the column, so nothing inside a card rescales. */
  .shell-pane {
    --col: 560px;
  }

  .shell-pane .app-frame {
    max-width: none;
    --inset: max(0px, calc((100% - var(--col)) / 2));
  }

  .shell-pane .app-header,
  .shell-pane .expense-header {
    padding-left: calc(var(--inset) + 20px);
    padding-right: calc(var(--inset) + 20px);
  }

  .shell-pane .app-stream,
  .shell-pane .app-footer,
  .shell-pane .home-list,
  .shell-pane .home-footer,
  .shell-pane .expense-body,
  .shell-pane .expense-footer,
  .shell-pane .correction-body,
  .shell-pane .pot-body {
    padding-left: calc(var(--inset) + 16px);
    padding-right: calc(var(--inset) + 16px);
  }

  /* The signed-out front door and the Auth screen have no bars: the hero
     itself is the column. */
  .shell-pane .auth-frame {
    max-width: var(--col);
  }
}

/* A wider pane gets a wider column (task-fidelity B1): 640px from 1100px.
   Not a layout state — the shell is still rail + pane — only the column's
   measure. */
@media (min-width: 1100px) {
  .shell-pane {
    --col: 640px;
  }
}

/* Rail content (shell spec §1): the trip list, each trip's own sections
   underneath it, then the viewer's identity and sign-out. Not from any
   artboard — the shell is the one place invention is permitted. */
.rail-nav {
  padding: 20px 16px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-height: 100%;
}

.rail-link {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 0 8px;
  border-radius: var(--radius-xs);
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
}

.rail-link[aria-current="page"] {
  background: var(--fill-subtle);
  color: var(--ink);
  font-weight: 600;
}

.rail-home-link {
  margin-bottom: 4px;
}

/* task-ai R2: the global Trippy, at the top of the rail. */
.rail-trippy-link {
  gap: 10px;
  margin-bottom: 2px;
}

.rail-trip-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-bottom: 6px;
}

.rail-trip-link {
  font-family: var(--display);
  font-size: 15px;
}

.rail-sections {
  display: flex;
  flex-direction: column;
  margin: 0 0 6px 14px;
  padding-left: 10px;
  border-left: 1px solid var(--line);
}

.rail-section-link {
  font-size: 13.5px;
  font-weight: 500;
  min-height: 38px;
}

.rail-empty,
.rail-loading {
  margin: 4px 8px;
}

/* Viewer identity + sign-out (shell spec §5; task-15's own sign-out
   requirement — the API existed since task 14 with no UI trigger). */
.rail-viewer {
  margin-top: auto;
  padding-top: 12px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.rail-viewer-block + .rail-viewer-block {
  margin-top: 4px;
  padding-top: 8px;
  border-top: 1px solid var(--fill-subtle);
}

.rail-viewer-name {
  font-size: 14px;
  font-weight: 600;
  margin-top: 2px;
}

.rail-viewer-email {
  font-size: 11.5px;
  color: var(--ink-muted);
  margin-top: 1px;
}

.rail-signout,
.rail-signin {
  width: 100%;
  font-size: 13px;
  padding: 9px 0;
  border-radius: var(--radius-xs);
  min-height: 36px;
  box-sizing: border-box;
}

.app-frame {
  width: 100%;
  max-width: 390px;
  margin: 0 auto;
  height: 100%;
  background: var(--bg-ground);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.app-header {
  flex-shrink: 0;
  background: var(--bg-surface);
  border-bottom: 1px solid var(--line);
  padding: 16px 20px 13px;
}

.app-stream {
  flex-grow: 1;
  overflow-y: auto;
  padding: 12px 16px 6px;
  display: flex;
  flex-direction: column;
  gap: 9px;
}

/* A scrolling column's children keep their own height: a card with
   overflow:hidden loses its automatic min-height as a flex item and was
   being squashed to fit (Drafts' action rows were cut off —
   task-fidelity Part A). The column scrolls instead. */
.app-stream > *,
.home-list > *,
.expense-body > *,
.correction-body > * {
  flex-shrink: 0;
}

.app-footer {
  flex-shrink: 0;
  background: var(--bg-surface);
  border-top: 1px solid var(--line);
  padding: 9px 16px calc(16px + env(safe-area-inset-bottom, 0px));
}

/* Shared micro-label: the single most repeated style in the system. The
   artboards draw it at the default weight (400); ui-design-system §1.2
   amended (task-fidelity Part A). */
.micro-label {
  font-size: 10px;
  font-weight: 400;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.money {
  font-variant-numeric: tabular-nums;
}

.loading {
  padding: 48px 0;
  text-align: center;
  color: var(--ink-muted);
}

/* Home — the trip list. Ported from project/Home.dc.html verbatim; see
   docs/superpowers/specs/2026-09-22-app-shell-and-responsive.md §3.
   Values below are the artboard's own inline styles, unchanged — only
   their colours are expressed as tokens.
   Home's header is now the shared `.screen-head` (below, via
   `ScreenHeader`'s "top" variant) — `.home-head` only overrides the one
   value the artboard genuinely gives Home that Room doesn't share: a
   26px title instead of Room's 23px. */

.home-head .screen-head-title h1 {
  font-size: 26px;
}

/* Home.dc.html's header: 20px 20px 14px, and the viewer's name sits at
   the row's far end on the title's baseline — not stacked under it
   (task-fidelity B3 / Part A). */
.home-head {
  padding-top: 20px;
  padding-bottom: 14px;
}

.home-head .screen-head-top {
  align-items: baseline;
}

.home-head-name {
  font-size: 12px;
  color: var(--ink-muted);
}

.home-list {
  flex-grow: 1;
  overflow-y: auto;
  padding: 16px 16px 6px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: var(--radius-pill);
  flex-shrink: 0;
}
.dot-positive {
  background: var(--positive);
}
.dot-accent {
  background: var(--accent);
}

.home-section-label-row {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 0 0 8px 2px;
}

.home-section-label {
  font-size: 10px;
  font-weight: 600;
  color: var(--positive);
  text-transform: uppercase;
  letter-spacing: 0.09em;
}

.home-section-label-muted {
  font-size: 10px;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.09em;
  margin: 0 0 8px 2px;
}

/* task-ai R2: the global Trippy entry on Home. */
.home-trippy-card {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  margin-bottom: 16px;
  padding: 12px 14px;
  border-radius: var(--radius-md);
  background: var(--accent-subtle);
  border: 1px solid var(--accent-subtle-line);
  color: var(--ink);
  text-decoration: none;
}
.home-trippy-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.home-trippy-title {
  font-weight: 600;
}
.home-trippy-sub {
  font-size: 13px;
  color: var(--ink-muted);
}

.home-active-card {
  display: block;
  background: var(--bg-surface);
  border: 1.5px solid var(--ink);
  border-radius: var(--radius-lg);
  padding: 16px;
  text-decoration: none;
  color: inherit;
}

.home-active-card-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.home-active-name {
  font-family: var(--display);
  font-size: 21px;
  font-weight: 600;
}

.home-active-day {
  font-size: 11.5px;
  color: var(--ink-muted);
}

.home-active-meta {
  font-size: 12.5px;
  color: var(--ink-muted);
  margin-top: 5px;
}

.home-active-stats {
  display: flex;
  gap: 20px;
  margin-top: 14px;
  padding-top: 13px;
  border-top: 1px solid var(--fill-subtle);
}

.home-stat-label {
  display: block;
  font-size: 10px;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.home-stat-value {
  display: block;
  font-size: 17px;
  font-weight: 600;
  margin-top: 2px;
}

.home-stat-negative {
  color: var(--negative);
}

.home-stat-positive {
  color: var(--positive);
}

.home-active-last-message {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 13px;
  padding-top: 12px;
  border-top: 1px solid var(--fill-subtle);
}

.home-active-last-message-text {
  flex-grow: 1;
  min-width: 0;
  font-size: 12.5px;
  color: var(--ink-muted);
}

.home-active-last-message-text strong {
  color: var(--ink);
  font-weight: 600;
}

/* Home.dc.html's unread pill (task-fidelity B6): 11px/600 white on the
   accent, 2px 8px, fully rounded. */
.home-unread-pill {
  flex-shrink: 0;
  font-size: 11px;
  font-weight: 600;
  color: #ffffff;
  background: var(--accent);
  border-radius: var(--radius-pill);
  padding: 2px 8px;
}

.home-earlier-list {
  background: var(--bg-surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.home-earlier-row {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  padding: 13px 15px;
  border-bottom: 1px solid var(--fill-subtle);
  text-decoration: none;
  color: inherit;
}

.home-earlier-main {
  flex-grow: 1;
  min-width: 0;
}

.home-earlier-name-row {
  display: flex;
  align-items: center;
  gap: 7px;
}

.home-earlier-name {
  font-family: var(--display);
  font-size: 15px;
  font-weight: 600;
}

.home-earlier-status {
  display: block;
  font-size: 11.5px;
  color: var(--ink-muted);
  margin-top: 3px;
}

.home-earlier-status-accent {
  color: var(--accent);
}

.home-earlier-meta {
  font-size: 11.5px;
  color: var(--ink-faint);
  flex-shrink: 0;
  text-align: right;
}

.home-footer {
  flex-shrink: 0;
  background: var(--bg-surface);
  border-top: 1px solid var(--line);
  padding: 11px 16px calc(18px + env(safe-area-inset-bottom, 0px));
}

.home-footer .primary {
  width: 100%;
  font-size: 15px;
  padding: 14px 0;
  border-radius: var(--radius-sm);
  min-height: 44px;
}

/* "top" screen header (Home, Room) — ported from project/Room.dc.html
   per app-shell spec §3 and ui-design-system spec §4.1, now shared by
   both top-level screens through `ScreenHeader.tsx`.
   `.screen-head-title` carries `flex: 1` deliberately (task-15's D1 fix):
   it is always the row's only growing item, so its left edge sits at the
   header's own padding box (20px) whether or not a trailing menu button
   renders — nothing to its LEFT ever reserves width for a control that
   may or may not be there at a given breakpoint. */

.screen-head-top {
  display: flex;
  align-items: center;
  gap: 10px;
}

.screen-head-title {
  flex: 1;
  min-width: 0;
}

.screen-head-title h1 {
  margin: 0;
  font-family: var(--display);
  font-size: 23px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.screen-head-meta {
  font-size: 11px;
  color: var(--ink-faint);
  margin-top: 1px;
}

.screen-head-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  /* The controls here are 44px touch targets (spec §4.1); the artboards
     draw them at 32px. The 6px either side overlaps the header's own
     padding, so the header keeps the artboard's height while each target
     keeps its full 44px (task-fidelity Part A). */
  margin-block: -6px;
}

/* The drawer's menu button, when `ScreenHeader` renders it at all (only
   the "top" variant, only below 768px — see viewport.ts). It is a plain
   flex child of `.screen-head-actions`, in normal document flow, in
   source order (no CSS `order` — reading order and visual order stay the
   same): no `position: fixed`, no offset math to keep in sync with the
   header's own padding. That fixed-position overlay was task-15's
   D1/D3 root cause. */

/* Filter pill (spec §4.9): the artboard pads it to well under 44px tall
   (padding 6px top/bottom on a 12.5px label). `min-height` reaches the
   44px touch target while keeping the artboard's own horizontal padding
   and font size — the visible pill looks the same, the tappable box just
   isn't undersized. */
.filter-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 44px;
  padding: 6px 10px 6px 11px;
  font-family: var(--body);
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink);
  border-radius: var(--radius-pill);
  border: 1px solid var(--line-strong);
  background: var(--bg-ground);
}

/* Popover menu (task-deadcontrols D1/D2) — the Room's filter pill and
   trip-actions kebab, `Menu.tsx`. No shadow (spec §1.6: elevation is a
   border). Anchored under its button's trailing edge — both buttons sit
   top-right of the header, so it opens leftwards and stays on a 390px
   screen; `max-width` guarantees that whatever the labels. */
.menu {
  position: relative;
  display: inline-flex;
}
.menu-pop {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 30;
  min-width: 212px;
  max-width: calc(100vw - 32px);
  padding: 4px;
  background: var(--bg-surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  display: flex;
  flex-direction: column;
}
.menu-item {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 12px;
  border: none;
  border-radius: var(--radius-2xs);
  background: transparent;
  color: var(--ink);
  font-family: var(--body);
  font-size: 14px;
  font-weight: 500;
  text-align: left;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}
.menu-item:hover,
.menu-item:focus-visible {
  background: var(--fill-subtle);
  color: var(--ink);
  outline: none;
}
.menu-item-checked {
  font-weight: 600;
}
.menu-item-check {
  flex-shrink: 0;
  color: var(--accent);
}
.menu-item-label {
  flex-grow: 1;
}
.menu-item-meta {
  color: var(--ink-muted);
  font-weight: 400;
}

.room-stats {
  display: flex;
  gap: 22px;
  margin-top: 11px;
}

.room-stat-value {
  display: block;
  font-size: 17px;
  font-weight: 600;
  margin-top: 2px;
}

.room-stat-negative {
  color: var(--negative);
}

.room-stat-positive {
  color: var(--positive);
}

/* Stream content sits inside .app-stream (the frame's scrolling region);
   .stream itself no longer carries layout — .app-stream owns it. */

.card {
  background: var(--bg-surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 12px 14px;
}

/* A member's expense waiting in the organiser's queue (task-access R5):
   visibly not booked yet. */
.card-pending {
  border-style: dashed;
}
.card-pending .card-head-main {
  display: flex;
  justify-content: space-between;
  gap: 8px;
}

/* Expanded (spec §4.5): the border steps up a shade, the same toggle
   button underneath — nothing about the card's identity changes. */
.card-expanded {
  border-color: var(--line-strong);
}

.card-head {
  display: flex;
  width: 100%;
  min-height: 44px;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 0;
  background: none;
  border: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

.card-head-main {
  display: flex;
  flex: 1;
  min-width: 0;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.card-title {
  font-family: var(--display);
  font-size: 16px;
  font-weight: 600;
}

.card-amount {
  font-size: 18px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ExpenseCard, as Room.dc.html draws it: the whole head (title row +
   sub-line) is one toggle padded 13px 15px, chevron centred beside both;
   the expanded panel is a full-bleed band under it (12px 15px 14px). */
.expense-card {
  padding: 0;
  overflow: hidden;
  /* overflow:hidden drops a flex item's automatic min-height; without
     this the stream's column would squash the card to nothing. */
  flex-shrink: 0;
}

.expense-card .card-head {
  padding: 13px 15px;
  gap: 12px;
}

.card-head-body {
  flex-grow: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.card-head-body .card-sub {
  display: block;
}

.expense-card .card-people {
  margin: 0;
  padding: 12px 15px 14px;
  border-radius: 0;
}

.expense-card .card-label {
  margin: 0 0 8px;
  font-size: 10px;
  font-weight: 400;
}

.card-pending {
  padding: 13px 15px;
}

/* The toggle chevron. Same icon in both states — it just flips. */
.chevron {
  flex-shrink: 0;
  color: var(--ink-faint);
  transition: transform 120ms ease;
}

.chevron-up {
  transform: rotate(180deg);
}

.card-sub {
  margin-top: 4px;
  color: var(--ink-muted);
  font-size: 12px;
}

.card-label {
  margin: 10px 0 6px;
  color: var(--ink-muted);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* The expanded panel (spec §4.5): a faint background under the head,
   bled to the card's own edges and rounded bottom corners. */
.card-people {
  margin: 8px -14px -12px;
  padding: 10px 14px 12px;
  background: var(--bg-faint);
  border-top: 1px solid var(--fill-subtle);
  border-radius: 0 0 var(--radius-md) var(--radius-md);
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.chip {
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
}

/* Recorded-expense chip (spec §4.6 #1): a muted, low-emphasis historical
   record — the canonical exclusion signal (dashed border, muted ink). */
.chip-on {
  background: var(--fill-subtle);
}

.chip-off {
  border: 1px dashed var(--line-strong);
  color: var(--ink-faint);
}

/* The exclusion sentence (spec §4.5): plain text, no box, sits directly
   under the chips. */
.exclusion-note {
  margin: 8px 0 0;
  color: var(--ink-muted);
  font-size: 11.5px;
  line-height: 1.4;
}

/* The expanded card's footer row (spec §4.5): "N replies" (→ the thread
   below) and "Correct this", both 12px/500. Colour comes from the page's
   own `a` rule (var(--accent)) — nothing here overrides it. */
.card-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 12px;
  padding-top: 11px;
  border-top: 1px solid var(--fill-subtle);
}

.card-footer-link {
  font-size: 12px;
  font-weight: 500;
  text-decoration: none;
}

/* A superseded expense (task 11): nothing is ever silently edited (product
   spec §7), so this card keeps showing exactly what it originally
   recorded — struck through, to read at a glance as no longer current —
   plus who corrected it and why. */
.card-amount-corrected {
  color: var(--ink-faint);
  text-decoration: line-through;
}

/* task-fidelity B11: the struck figure and the one that stands now, side
   by side — Correction.dc.html's "~~₹60~~ ₹45" pairing at the card's own
   sizes. The struck total drops to the sub-line's weight so the current
   one reads first. */
.card-amount-pair {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
}

.card-amount-pair .card-amount-corrected {
  font-size: 13px;
  font-weight: 500;
}

.card-was {
  color: var(--ink-faint);
  text-decoration: line-through;
  margin-right: 4px;
}

.card-corrected-tag {
  display: inline-block;
  margin-right: 6px;
  font-size: 10px;
  font-weight: 600;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.07em;
}

.card-corrected-note strong {
  color: var(--ink);
  font-weight: 600;
}

/* The inline reply thread (spec §4.5): rendered OUTSIDE the card, indented
   under it. `.app-stream`'s own 9px gap (see above) supplies the space
   between the card and this element, same as between any two stream
   siblings. */
.thread {
  margin-left: 14px;
  padding-left: 12px;
  border-left: 2px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.thread-line {
  font-size: 13px;
  line-height: 1.45;
}

.thread-line strong {
  font-weight: 600;
}

.thread-body {
  color: var(--ink-muted);
}

/* Chat bubbles — spec §4.2. */
.bubble-wrap {
  max-width: 78%;
  display: flex;
  flex-direction: column;
}
.bubble-in {
  align-self: flex-start;
}
.bubble-out {
  align-self: flex-end;
}

.bubble-sender {
  font-size: 11px;
  color: var(--ink-muted);
  margin: 0 0 3px 13px;
}

.bubble {
  font-size: 14px;
  line-height: 1.45;
  padding: 9px 13px;
}
.bubble-in .bubble {
  background: var(--bg-surface);
  border: 1px solid var(--line);
  border-radius: 16px 16px 16px 4px;
}
.bubble-out .bubble {
  background: var(--ink);
  color: var(--bg-ground);
  border-radius: 16px 16px 4px 16px;
}

/* Presence / system line — spec §4.4. Not a bubble, not a card: a plain
   flex row that sits directly in the stream like a caption. Shared by
   PresenceLine and PlanLine (task 16) — same visual weight, different
   icon, since neither carries money or needs a decision. */
.stream-caption {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 2px 4px;
  color: var(--ink-muted);
}
.stream-caption-text {
  font-size: 12.5px;
  color: var(--ink-muted);
}
.stream-caption-text strong {
  color: var(--ink);
  font-weight: 600;
}

/* Day divider — spec §4.3. */
.day-divider {
  display: flex;
  align-items: center;
  gap: 10px;
}
.day-divider-line {
  flex-grow: 1;
  height: 1px;
  background: var(--line);
}
.day-divider-label {
  font-size: 11px;
  color: var(--ink-muted);
  letter-spacing: 0.04em;
}

/* Composer, draft, form ---------------------------------------------- */

/* The composer's own outer box is superseded by .app-footer, which now
   supplies the fixed-footer background/border/padding. .composer-row is
   still needed for the input/button row's own layout — spec §4.8. */

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.composer-row {
  display: flex;
  align-items: center;
  gap: 9px;
}

.composer-row .composer-input {
  flex-grow: 1;
  min-width: 0;
  width: auto;
  font-family: var(--body);
  font-size: 14px;
  color: var(--ink);
  padding: 11px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--bg-ground);
}

.icon-btn {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border-radius: var(--radius-pill);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
}

.icon-btn-outline {
  border: 1px solid var(--line-strong);
  background: var(--bg-surface);
  color: var(--ink);
}

.icon-btn-primary {
  border: none;
  background: var(--accent);
  color: #ffffff;
}

/* Ghost: transparent fill, the plain --line border (not --line-strong) —
   the Room header's kebab (spec §4.1), rebuilt at 44px from the
   artboard's 32px per the recorded touch-target ruling. */
.icon-btn-ghost {
  border: 1px solid var(--line);
  background: transparent;
  color: var(--ink);
}

/* Listening (task-deadcontrols D3): the mic is pressed, clay-accented,
   with a pulsing ring — existing tokens only. The ring holds still for
   anyone who asked for reduced motion; the pressed fill still shows. */
.icon-btn-listening {
  position: relative;
  border-color: var(--accent);
  background: var(--accent-subtle);
  color: var(--accent);
}
.icon-btn-listening::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: var(--radius-pill);
  border: 2px solid var(--accent);
  pointer-events: none;
  animation: mic-pulse 1.2s ease-out infinite;
}
@keyframes mic-pulse {
  0% {
    opacity: 0.9;
    transform: scale(0.92);
  }
  100% {
    opacity: 0;
    transform: scale(1.18);
  }
}
@media (prefers-reduced-motion: reduce) {
  .icon-btn-listening::after {
    animation: none;
    opacity: 0.6;
  }
}

.icon-btn:disabled {
  opacity: 0.4;
  cursor: default;
}

/* Voice status (task-voice): the line under the composer while the mic
   records (a live timer) or the server transcribes. Existing tokens. */
.composer-voice-status {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  font-size: 13px;
  color: var(--ink-muted);
}
.composer-voice-dot {
  width: 8px;
  height: 8px;
  border-radius: var(--radius-pill);
  background: var(--accent);
}
.composer-voice-clock {
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.composer-voice-hint {
  color: var(--ink-faint);
}
.icon-btn[aria-busy="true"] {
  cursor: progress;
}

/* Zero specificity (`:where`), so any component's own class — the big
   underlined amount fields, the UPI field — wins over this base box
   (task-fidelity Part A: `input[type="text"]` used to outrank them). */
:where(input[type="text"], select) {
  width: 100%;
  padding: 10px 12px;
  background: var(--bg-surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  font: inherit;
  color: inherit;
}

input[type="text"]:focus,
select:focus,
button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

button {
  padding: 10px 14px;
  background: var(--bg-surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  font: inherit;
  color: var(--ink);
  cursor: pointer;
}

button:hover:not(:disabled) {
  border-color: var(--accent);
}

button:disabled {
  opacity: 0.5;
  cursor: default;
}

button.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  font-weight: 600;
}

/* The draft card — ported from project/Draft.dc.html (task-fidelity
   Part A): a status label above; the card itself (1.5px accent border,
   the speech-bubble corner at bottom-right because it is your message);
   its actions and the "nothing is saved" note below it. */
.draft-wrap {
  display: flex;
  flex-direction: column;
  gap: 11px;
  margin-bottom: 12px;
}

.draft-status {
  align-self: flex-end;
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.draft {
  background: var(--bg-surface);
  border: 1.5px solid var(--accent);
  border-radius: var(--radius-lg) var(--radius-lg) 4px var(--radius-lg);
  overflow: hidden;
}

.draft-label {
  font-size: 10px;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.draft-label-faint {
  color: var(--ink-faint);
}

.draft-source {
  padding: 11px 15px;
  background: var(--accent-subtle);
  border-bottom: 1px solid var(--accent-subtle-line);
}

.draft-quote {
  margin-top: 3px;
  font-size: 14px;
  font-style: italic;
}

.draft-amount-block {
  padding: 14px 15px 12px;
}

.draft-amount-row {
  display: flex;
  align-items: baseline;
  gap: 4px;
  margin-top: 3px;
}

.draft-amount-glyph {
  font-size: 24px;
  font-weight: 500;
  color: var(--ink-muted);
}

.draft-amount-figure {
  font-size: 28px;
  font-weight: 600;
}

.draft-facts {
  display: flex;
  gap: 10px;
  padding: 0 15px 12px;
}

.draft-fact {
  flex: 1;
  min-width: 0;
}

.draft-fact-value {
  margin-top: 4px;
  font-size: 14px;
  font-weight: 500;
}

.draft-split {
  padding: 12px 15px;
  border-top: 1px solid var(--fill-subtle);
}

.draft-chips {
  margin-top: 8px;
}

.chip-draft-on,
.chip-draft {
  font-size: 11.5px;
  padding: 4px 10px;
}

.chip-draft-on {
  background: var(--ink);
  color: var(--bg-surface);
}

.draft-foot {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 11px 15px;
  border-top: 1px solid var(--fill-subtle);
}

.draft-foot-count {
  font-size: 12.5px;
  color: var(--ink-muted);
}

.draft-foot-each {
  font-size: 16px;
  font-weight: 600;
}

.draft-actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.draft-confirm {
  width: 100%;
  font-size: 15px;
  border-radius: var(--radius-sm);
}

.draft-actions-row {
  display: flex;
  gap: 8px;
}

.draft-actions-row .btn-secondary {
  flex: 1;
  font-size: 14px;
  border-radius: var(--radius-sm);
  text-decoration: none;
}

.draft-reject {
  color: var(--ink-muted);
}

.draft-note {
  margin: 2px 0 0;
  font-size: 12px;
  line-height: 1.55;
  color: var(--ink-muted);
  text-align: center;
}

.error {
  margin: 8px 0;
  padding: 10px 12px;
  background: var(--accent-subtle);
  border: 1px solid var(--accent-subtle-line);
  border-radius: 10px;
  color: var(--negative);
  font-size: 14px;
}

/* Add expense / Edit expense — ported from project/AddExpense.dc.html and
   project/Edit.dc.html per app-shell spec §3 and ui-design-system spec
   §4.6 item 3 / §4.9 / §4.10. Both screens' headers share these exact
   values (both artboards: padding 15px 20px 12px). */

.expense-header {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--bg-surface);
  border-bottom: 1px solid var(--line);
  padding: 15px 20px 12px;
}

/* The artboards' back button is 34×34 — below the 44×44 touch-target
   floor spec §4.1 records as a known inconsistency to fix, not
   reproduce. Rebuilt on the shared 44×44 `.icon-btn`, with the
   artboard's own `--line` border (not `--line-strong`) preserved. */
.icon-btn-back {
  border: 1px solid var(--line);
  background: var(--bg-surface);
  color: var(--ink);
}

.expense-header-title {
  min-width: 0;
}

.expense-header-title h1 {
  margin: 0;
  font-family: var(--display);
  font-size: 20px;
  font-weight: 600;
}

.expense-header-sub {
  font-size: 12px;
  color: var(--ink-muted);
  margin-top: 1px;
}

/* The <form> itself is the flex column filling the rest of the frame,
   below the header — its own scrolling body plus its own fixed footer,
   the same shape every other screen's .app-frame uses. */
.expense-form-shell {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.expense-body {
  flex-grow: 1;
  overflow-y: auto;
  padding: 13px 16px 4px;
  display: flex;
  flex-direction: column;
  gap: 11px;
}

.expense-footer {
  flex-shrink: 0;
  background: var(--bg-surface);
  border-top: 1px solid var(--line);
  padding: 11px 16px calc(17px + env(safe-area-inset-bottom, 0px));
  display: flex;
  gap: 9px;
}

/* The underline-only text field (spec §4.10) — used here for AddExpense's
   "What was it" description. */
.expense-body .field-underline {
  display: block;
  width: 100%;
  margin-top: 4px;
  font-family: var(--body);
  font-size: 15px;
  color: var(--ink);
  padding: 9px 0;
  border: none;
  border-radius: 0;
  border-bottom: 1px solid var(--line);
  background: transparent;
}

.amount-payer-row {
  display: flex;
  gap: 12px;
  align-items: flex-end;
}

/* AddExpense's amount/toggle row sits below the description field;
   Edit's is the card's first and only row. */
.amount-payer-row.spaced-top {
  margin-top: 13px;
}

.amount-field {
  flex-grow: 1;
  min-width: 0;
}

.amount-field-row {
  display: flex;
  align-items: baseline;
  gap: 3px;
  margin-top: 2px;
}

.amount-currency {
  font-size: 20px;
  font-weight: 500;
  color: var(--ink-muted);
}

/* The "big number" underline field (spec §4.10) — the one input every
   money screen singles out with the 1.5px accent underline. */
.amount-field-row .amount-input {
  width: 100%;
  min-width: 0;
  border: none;
  border-bottom: 1.5px solid var(--accent);
  background: transparent;
  font-family: var(--body);
  font-size: 24px;
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  padding: 0 0 2px;
  border-radius: 0;
}

.amount-mode {
  flex-shrink: 0;
}

/* Segmented Total/Each toggle (spec §4.9). */
.amount-mode-toggle {
  display: flex;
  margin-top: 4px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  overflow: hidden;
}

.amount-mode-toggle button {
  font-family: var(--body);
  font-size: 12px;
  padding: 6px 12px;
  border: none;
  background: transparent;
  color: var(--ink-muted);
  cursor: pointer;
}

.amount-mode-toggle button[aria-pressed="true"] {
  background: var(--ink);
  color: #fff;
  font-weight: 600;
}

/* task-rw2: Equal / Exact / Shares — full-size targets. */
.split-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}

.split-head .section-label {
  margin: 0 0 0 2px;
}

.split-mode-toggle {
  margin-top: 0;
}

.split-mode-toggle button {
  min-height: 44px;
  min-width: 44px;
  padding: 6px 14px;
  font-size: 13px;
}

.exact-amount {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  flex-shrink: 0;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-2xs);
  padding: 0 8px;
  background: var(--bg-surface);
}

.exact-amount-glyph {
  color: var(--ink-muted);
  font-size: 14px;
}

.exact-amount-input {
  width: 72px;
  min-height: 44px;
  border: none;
  background: transparent;
  font: inherit;
  font-size: 15px;
  color: var(--ink);
  text-align: right;
}

.exact-amount-input:focus {
  outline: none;
}

.exact-amount:focus-within {
  border-color: var(--accent);
}

.split-balance {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-muted);
}

.split-balance-off {
  color: var(--negative);
}

.split-balance-ok {
  color: var(--positive);
}

.draft-exact-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 10px;
}

.draft-exact-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.share-pill {
  flex-shrink: 0;
  min-height: 44px;
  min-width: 44px;
  padding: 6px 12px;
  border: 1px solid var(--accent-subtle-line);
  border-radius: var(--radius-pill);
  background: var(--accent-subtle);
  color: var(--accent-hover);
  font-family: var(--body);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}

.share-pill:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.share-pill-figure {
  font-weight: 400;
}

.draft-shares-hint {
  margin-top: 8px;
}

/* task-rw2 B1: several bills from one message, one sheet. */
.draft-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.draft-list-title {
  font-family: var(--display);
  font-size: 18px;
  font-weight: 600;
  color: var(--ink);
}

.draft-list-head .draft-quote {
  margin-top: 4px;
}

.draft-list-item {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 10px 12px 12px;
  background: var(--bg-faint);
}

.draft-list-count {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-faint);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 6px;
}

.draft-list-done {
  margin: 0;
  padding: 12px;
  border-radius: var(--radius-sm);
  background: var(--positive-subtle);
  border: 1px solid var(--positive-subtle-line);
  color: var(--positive);
  font-weight: 600;
}

.draft-list-skipped {
  background: var(--fill-subtle);
  border-color: var(--line);
  color: var(--ink-muted);
  font-weight: 400;
}

.draft-actions-compact {
  flex-direction: row;
  gap: 8px;
}

.draft-actions-compact > * {
  flex: 1 1 0;
  min-width: 0;
}

/* task-rw2 A14: "Looks like … — add anyway?" A warning, never a block. */
.duplicate-warning {
  margin: 8px 0 0;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  background: var(--accent-subtle);
  border: 1px solid var(--accent-subtle-line);
  color: var(--ink);
  font-size: 14px;
  line-height: 1.4;
}

.duplicate-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-weight: 600;
  color: var(--accent);
}

.draft-exact-name {
  font-size: 14px;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* AddExpense's payer field, set off below the amount row by a divider. */
.card-divider-section {
  margin-top: 13px;
  padding-top: 12px;
  border-top: 1px solid var(--fill-subtle);
}

.expense-body .select-field {
  display: inline-block;
  margin-top: 4px;
  font-family: var(--body);
  font-size: 14px;
  color: var(--ink);
  padding: 7px 9px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--bg-ground);
}

/* AddExpense's payer select spans the card's full width; Edit's sits
   inline beside the amount field at its own content width. */
.expense-body .select-field-wide {
  display: block;
  width: 100%;
  box-sizing: border-box;
  padding: 8px 9px;
}

.section-label {
  margin: 0 0 6px 2px;
}

.checkbox-list {
  background: var(--bg-surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  overflow: hidden;
}

/* The editable checkbox row (spec §4.6 item 3) — NOT a chip: a full-width
   label, a 21px accent checkbox, the name, and a presence sub-line. The
   transparent 3px left stripe is a reserved, inert placeholder so Edit's
   "just added" highlight (below) never shifts the row's content. */
.checkbox-row {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 14px;
  background: var(--bg-surface);
  border-left: 3px solid transparent;
  border-bottom: 1px solid var(--fill-subtle);
  cursor: pointer;
}

.checkbox-row input[type="checkbox"] {
  width: 21px;
  height: 21px;
  accent-color: var(--accent);
  margin: 0;
  flex-shrink: 0;
}

/* Edit only: a row whose inclusion just changed from off to on. */
.checkbox-row-added {
  background: var(--accent-subtle);
  border-left: 3px solid var(--accent);
}

.checkbox-row-main {
  flex-grow: 1;
  min-width: 0;
}

.checkbox-row-name {
  display: block;
  font-size: 14px;
  font-weight: 500;
}

.checkbox-row-sub {
  display: block;
  font-size: 11px;
  color: var(--ink-muted);
  margin-top: 1px;
}

.checkbox-row-tag {
  font-size: 10px;
  font-weight: 600;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.07em;
}

/* Edit's exclusion-reason field — the boxed text input (spec §4.10). */
.expense-body .field-boxed {
  width: 100%;
  box-sizing: border-box;
  margin-top: 5px;
  font-family: var(--body);
  font-size: 13.5px;
  color: var(--ink);
  padding: 10px 13px;
  border: 1px solid var(--line);
  border-radius: var(--radius-xs);
  background: var(--bg-surface);
}

.field-hint {
  margin: 6px 2px 0;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--ink-muted);
}

.summary-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

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

.summary-value {
  font-size: 20px;
  font-weight: 600;
}

.summary-value-group {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.summary-value-before {
  font-size: 15px;
  color: var(--ink-faint);
  text-decoration: line-through;
}

/* Correction — ported from project/Correction.dc.html, route
   /t/:tripId/e/:eventId/correct (app-shell spec §3, ui-design-system
   spec §4.6 item 4 / §4.10). Header reuses `.expense-header`/
   `.icon-btn-back`/`.expense-header-title` verbatim (same detail-screen
   shape as Edit/AddExpense); the body's own values differ from
   `.expense-body` (14px/6px/12px here vs 13px/4px/11px there) because the
   two artboards genuinely specify different numbers — the porting rule
   changes values only where real data replaces an invented one, never to
   make two screens match each other. */
.correction-body {
  flex-grow: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 14px 16px 6px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.correction-summary-card {
  background: var(--bg-surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 15px;
}

.correction-sentence {
  margin: 0;
  font-size: 13px;
  color: var(--ink-muted);
  line-height: 1.5;
}

.correction-sentence strong {
  color: var(--ink);
  font-weight: 600;
}

/* The struck-through old per-head figure beside the new one — spec
   §4.10's own worked example, 23px vs 27px, both tabular-nums. */
.correction-perhead-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-top: 11px;
}

.correction-perhead-before {
  font-size: 23px;
  font-weight: 600;
  color: var(--ink-faint);
  text-decoration: line-through;
}

.correction-perhead-arrow {
  flex-shrink: 0;
  color: var(--ink-muted);
}

.correction-perhead-after {
  font-size: 27px;
  font-weight: 600;
}

.correction-perhead-each {
  font-size: 12px;
  color: var(--ink-muted);
}

.correction-people-line {
  margin-top: 3px;
  font-size: 12px;
  color: var(--ink-muted);
}

.correction-changes-card {
  background: var(--bg-surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 2px 15px 4px;
}

.correction-changes-label {
  padding: 12px 0 2px;
}

/* The correction delta row (spec §4.6 item 4) — neither a chip nor a
   checkbox: a plain two-column row, name at 14px, signed amount at
   15px/600 tabular-nums, --negative for a decrease and --positive for an
   increase. */
.correction-delta-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 11px 0;
  border-bottom: 1px solid var(--fill-subtle);
}

.correction-delta-name {
  font-size: 14px;
}

.correction-delta-amount {
  font-size: 15px;
  font-weight: 600;
}

.correction-delta-amount-negative {
  color: var(--negative);
}

.correction-delta-amount-positive {
  color: var(--positive);
}

/* The "Net change ₹0" summary row the delta list ends on. */
.correction-net-row {
  display: flex;
  justify-content: space-between;
  padding: 11px 0 12px;
}

.correction-net-label {
  font-size: 13px;
  color: var(--ink-muted);
}

.correction-net-value {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-muted);
}

/* The Reason field — boxed (spec §4.10), not underline-only: this
   screen's amount figures are plain display text, not an editable
   field, so §4.10's underline treatment has nothing to attach to here
   (it stays on Edit/AddExpense's own "big number" amount inputs). */
.correction-reason-input {
  display: block;
  width: 100%;
  box-sizing: border-box;
  margin-top: 6px;
  font-family: var(--body);
  font-size: 14px;
  color: var(--ink);
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--bg-surface);
}

.correction-footnote {
  margin: 0;
  font-size: 12px;
  line-height: 1.55;
  color: var(--ink-muted);
  padding: 0 2px;
}

/* Footer buttons (spec §4.9) — Cancel is always a real `<a>`/`<Link>`;
   the primary action is always a real `<button type="submit">`, never a
   link, per the porting rule's flagged deviation from the static mock. */
.btn-secondary {
  flex-grow: 1;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  text-align: center;
  font-family: var(--body);
  font-size: 15px;
  font-weight: 500;
  padding: 13px 0;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--ink);
  text-decoration: none;
  cursor: pointer;
}

.btn-primary {
  flex-grow: 2;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  text-align: center;
  font-family: var(--body);
  font-size: 15px;
  font-weight: 600;
  padding: 13px 0;
  border-radius: var(--radius-sm);
  border: none;
  background: var(--accent);
  color: #fff;
  cursor: pointer;
  text-decoration: none;
}

.btn-primary:hover:not(:disabled) {
  background: var(--accent-hover);
}

.btn-primary:disabled {
  opacity: 0.5;
  cursor: default;
}


/* Advisory / callout (ui-design-system spec §4.7): ONE component, reused
   for Invite's identity warning and Member's no-pot upsell (and, in later
   tasks, Settle/Pot's own advisories) — accent-subtle fill, never
   redrawn per screen. */
.advisory {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 13px 15px;
  background: var(--accent-subtle);
  border: 1px solid var(--accent-subtle-line);
  border-radius: var(--radius-md);
  color: var(--ink);
}

.advisory svg {
  flex-shrink: 0;
  color: var(--accent);
  margin-top: 1px;
}

.advisory-text {
  font-size: 12.5px;
  line-height: 1.55;
}

/* The upsell variant is a whole-card `<a>`, not just a text block —
   align-items steps down to center and a trailing chevron sits at the
   far edge. */
.advisory-link {
  align-items: center;
  text-decoration: none;
}

.advisory-link .advisory-text {
  flex-grow: 1;
  font-size: 13px;
  line-height: 1.45;
}

/* Members — ported from project/Members.dc.html per app-shell spec §3
   and ui-design-system spec §4.11 (list row / avatar). Header reuses
   .expense-header/.icon-btn-back/.expense-header-title — same detail-
   header shape as Edit/AddExpense (spec §4.1's "Detail" header). */

.members-body {
  gap: 12px;
}

.roster-card {
  background: var(--bg-surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.roster-row {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 12px 15px;
  border-bottom: 1px solid var(--fill-subtle);
}

.roster-avatar {
  width: 34px;
  height: 34px;
  flex-shrink: 0;
  border-radius: var(--radius-pill);
  background: var(--fill-subtle);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-muted);
}

.roster-main {
  flex-grow: 1;
  min-width: 0;
}

.roster-name-row {
  display: flex;
  align-items: center;
  gap: 6px;
}

.roster-name {
  font-size: 14.5px;
  font-weight: 500;
}

.badge-custodian {
  font-size: 9.5px;
  font-weight: 600;
  color: var(--accent);
  background: var(--accent-subtle);
  border: 1px solid var(--accent-subtle-line);
  border-radius: var(--radius-pill);
  padding: 1px 7px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.roster-status {
  display: block;
  font-size: 11.5px;
  color: var(--ink-muted);
  margin-top: 2px;
}

.roster-status-positive {
  color: var(--positive);
}

.roster-status-faint {
  color: var(--ink-faint);
}

.roster-status-accent {
  color: var(--accent);
}

.roster-trailing {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 3px;
}

.roster-amount {
  font-size: 12.5px;
  font-weight: 600;
}

.roster-amount-positive {
  color: var(--positive);
}

.roster-amount-negative {
  color: var(--ink);
}

.roster-link {
  font-size: 12px;
  font-weight: 500;
  text-decoration: none;
}

.roster-add-row {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 13px 15px;
  min-height: 44px;
  border: none;
  border-radius: 0;
  background: transparent;
  font: inherit;
  color: inherit;
  cursor: pointer;
}

.roster-add-row:hover:not(:disabled) {
  border-color: transparent;
}

.roster-add-icon {
  width: 34px;
  height: 34px;
  flex-shrink: 0;
  border-radius: var(--radius-pill);
  border: 1px dashed var(--line-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--accent);
}

.roster-add-label {
  font-size: 14.5px;
  font-weight: 500;
  color: var(--accent);
}

.add-member-card {
  padding: 13px 15px;
}

/* The accent-underline text field (spec §4.10 groups this with the
   "big number" amount fields) — Members' own "Their name" input. */
.add-member-card .field-underline {
  border-bottom: 1.5px solid var(--accent);
  margin-top: 5px;
  padding: 10px 0;
  font-size: 15px;
}

.add-member-actions {
  display: flex;
  gap: 8px;
  margin-top: 11px;
}

.add-member-submit {
  font-size: 14.5px;
  border-radius: var(--radius-xs);
}

.add-member-actions .btn-secondary {
  font-size: 14.5px;
  border-radius: var(--radius-xs);
}

/* Task-ux2 U3: the whole roster row opens the member's page. The name
   link's ::after stretches over the row (the row is its containing
   block); the trailing Invite link sits on its own layer above it, so
   the two are sibling links rather than one nested in the other. */
.roster-row {
  position: relative;
  min-height: 44px;
}

.roster-row-link {
  color: var(--ink);
  text-decoration: none;
}

.roster-row-link::after {
  content: "";
  position: absolute;
  inset: 0;
}

.roster-row-link:focus-visible {
  outline: none;
}

.roster-row-link:focus-visible::after {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.roster-link {
  position: relative;
  z-index: 1;
  min-height: 44px;
  min-width: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  margin-bottom: -10px;
}

/* Member (one member's own view) — ported from project/Member.dc.html.
   The mock's own header had no back button, on the theory that this is
   the screen a member lands on through their OWN link. Task 15 (D3)
   overturns that: a member can reach this screen by navigating INTO it
   (Pot's back button already pointed here), and did so with no way back
   except a link at the very bottom of the page. It now renders through
   the shared `.expense-header`/`ScreenHeader`, same as every other
   detail screen. */

.member-hero {
  padding: 16px 16px 14px;
}

.member-hero-label {
  font-size: 12px;
  color: var(--ink-muted);
}

.member-hero-row {
  display: flex;
  align-items: baseline;
  gap: 9px;
  margin-top: 3px;
}

/* IBM Plex Sans, not Fraunces — see MemberScreen.tsx's own note: the
   type-scale table's 34px/Fraunces entry for this exact figure conflicts
   with this task's "Fraunces for screen titles only" constraint (and
   with ui-design-system spec §2's own "never used for ... numerals").
   The constraint wins. */
.member-hero-figure {
  font-size: 34px;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.member-hero-positive {
  color: var(--positive);
}

.member-hero-to {
  font-size: 13px;
  color: var(--ink-muted);
}

.member-pay-row {
  display: flex;
  gap: 13px;
  margin-top: 14px;
  align-items: center;
}

.member-qr-slot {
  flex-shrink: 0;
}

.member-pay-actions {
  flex-grow: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.member-breakdown {
  padding: 4px 16px 12px;
}

.member-breakdown-label {
  padding: 12px 0 4px;
}

.member-breakdown-row {
  display: flex;
  justify-content: space-between;
  padding: 8px 0;
  border-bottom: 1px solid var(--fill-subtle);
  font-size: 13px;
}

.member-breakdown-total {
  padding: 10px 0 0;
  border-bottom: none;
  font-size: 14px;
  font-weight: 600;
}

/* Member.dc.html: "Your share" / "You already paid" are 13px muted
   labels beside 14px/600 figures, the second 6px under the first; the
   final line is ruled off above (task-fidelity Part A). */
.member-breakdown-total > span:first-child {
  font-size: 13px;
  font-weight: 400;
  color: var(--ink-muted);
}

.member-breakdown-total + .member-breakdown-total {
  padding-top: 6px;
}

/* The artboard frames the QR: 1px line, 10px radius, 6px padding. */
.member-qr-frame {
  border: 1px solid var(--line);
  border-radius: var(--radius-2xs);
  padding: 6px;
  background: var(--bg-surface);
}

.member-qr-frame svg {
  display: block;
}

.member-breakdown-positive {
  color: var(--positive);
}

.member-breakdown-final {
  margin-top: 8px;
  padding: 9px 0 0;
  border-top: 1px solid var(--line);
  border-bottom: none;
  font-size: 15px;
  font-weight: 600;
}

.member-breakdown-final > span:first-child {
  font-size: 13px;
}

.member-breakdown-final .money {
  font-size: 15px;
}

.member-open-room {
  display: block;
  text-align: center;
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  padding: 4px 0;
}

/* "Your UPI id" — an ADDITION beyond the Member artboard (G1: task-15b),
   which has no such section at all. Styled like the other "one field on
   this screen that takes input" cards (Pot's contribute card, Edit's
   amount field): the 1.5px accent border marks it as the writable one. */
.member-vpa-card {
  padding: 14px 16px;
}

.member-vpa-label {
  padding: 0 0 6px;
}

.member-vpa-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.member-vpa-value {
  font-size: 14px;
  font-weight: 500;
}

.member-vpa-form {
  display: flex;
  gap: 8px;
  align-items: center;
}

.member-vpa-input {
  flex-grow: 1;
  min-width: 0;
  border: none;
  border-bottom: 1.5px solid var(--accent);
  background: transparent;
  font-family: var(--body);
  font-size: 14px;
  color: var(--ink);
  padding: 8px 2px;
}

.member-vpa-save,
.member-vpa-change {
  flex-shrink: 0;
  flex-grow: 0;
  padding: 0 16px;
  font-size: 14px;
  border-radius: var(--radius-xs);
}

/* Presence window — an ADDITION beyond the Member artboard (task-presence:
   `presence_set` predates this build entirely). Styled like the VPA card
   just above: the one other place on this screen that takes input. */
.member-presence-card {
  padding: 14px 16px;
}

.member-presence-label {
  padding: 0 0 6px;
}

.member-presence-current {
  margin: 0 0 10px;
  font-size: 13px;
  color: var(--ink-muted);
}

.member-presence-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.member-presence-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.member-presence-input {
  min-height: 44px;
  box-sizing: border-box;
  font-family: var(--body);
  font-size: 14px;
  color: var(--ink);
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-xs);
  background: var(--bg-surface);
}

.member-presence-actions {
  display: flex;
}

/* Invite — ported from project/Invite.dc.html. The QR here is an
   ADDITION beyond the artboard (which has none — only Member.dc.html
   does) per this task's own brief: "Invite shows the link, a QR ..."
   See InviteScreen.tsx's own note. */

.invite-link-card {
  padding: 15px;
}

.invite-link-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 7px;
}

/* Real code, sized to scan from another phone's camera: at the artboard's
   56px a ~60-character link packs its modules under 2px each. */
.invite-qr {
  flex-shrink: 0;
  padding: 4px;
  background: #ffffff;
  border: 1px solid var(--line);
  border-radius: var(--radius-2xs);
  line-height: 0;
}

.invite-link-box {
  flex-grow: 1;
  min-width: 0;
  font-family: ui-monospace, Menlo, monospace;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink);
  background: var(--bg-ground);
  border: 1px solid var(--line);
  border-radius: var(--radius-2xs);
  padding: 10px 12px;
  word-break: break-all;
}

.invite-actions {
  display: flex;
  gap: 8px;
  margin-top: 11px;
}

.btn-whatsapp {
  flex-grow: 1;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  text-align: center;
  font-size: 13.5px;
  font-weight: 600;
  padding: 11px 0;
  border-radius: var(--radius-2xs);
  border: none;
  background: var(--positive);
  color: #fff;
  text-decoration: none;
  cursor: pointer;
}

.btn-whatsapp[aria-disabled="true"] {
  opacity: 0.5;
  pointer-events: none;
}

.invite-copy {
  flex-grow: 0;
  padding: 11px 15px;
  font-size: 13.5px;
  border-radius: var(--radius-2xs);
}

.invite-capabilities {
  padding: 4px 15px 12px;
}

.invite-capabilities-label {
  padding: 12px 0 8px;
}

.invite-capabilities-list {
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--ink);
}

.invite-capabilities-cannot {
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--ink-faint);
  margin-top: 7px;
}

.invite-rotate {
  width: 100%;
  font-size: 13.5px;
  border-radius: var(--radius-xs);
  color: var(--ink-muted);
}

/* Ask — ported from project/Ask.dc.html per app-shell spec §3 and
   ui-design-system spec §4.8/§5. The header, stream and footer reuse
   .expense-header/.app-stream/.app-footer, same as every other detail
   screen; only the answer card itself is new. */

.ask-empty {
  margin: 4px 2px 0;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--ink-muted);
}

/* The Room's filtered-to-nothing state (task-deadcontrols D1). */
.room-filter-empty {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
}
.room-filter-empty .btn-secondary {
  flex-grow: 0;
  padding: 0 18px;
  font-size: 14px;
}

.ask-exchange {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.ask-exchange-answer {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* The "Read only · nothing changed" badge (spec: Ask's per-screen note).
   Teal, matching the --positive token used everywhere else a state is
   reassuring rather than owed. */
.ask-badge {
  display: flex;
  align-items: center;
  gap: 7px;
  padding-left: 2px;
  color: var(--positive);
}

.ask-badge-text {
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* The breakdown card. Its own radius/padding (16px / 15px 16px) differ
   from the shared `.card` (14px / 12px 14px) — the artboard's own values,
   kept rather than folded into the Room card since Ask's card is a
   summary of several expenses, not one expense. */
.ask-card {
  background: var(--bg-surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 15px 16px;
}

.ask-card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.ask-card-amount {
  font-size: 22px;
  font-weight: 600;
  white-space: nowrap;
}

.ask-line-list {
  margin-top: 10px;
}

.ask-line {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 0;
  border-bottom: 1px solid var(--fill-subtle);
}

.ask-line:last-child {
  border-bottom: none;
}

.ask-line-main {
  flex-grow: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.ask-line-label {
  font-size: 13.5px;
}

.ask-line-sub {
  font-size: 11px;
  color: var(--ink-muted);
  margin-top: 1px;
}

.ask-line-amount {
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
}

/* No top border, per the artboard — unlike `.card-footer`, which the
   Room expense card uses and does have one. */
.ask-card-footer {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding-top: 11px;
}

/* The personalised "your share" note — same visual weight as `.card`,
   the artboard's own smaller padding kept as its own class. */
.ask-share-card {
  padding: 12px 15px;
}

.ask-share-text {
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--ink);
}

.ask-not-built {
  padding: 13px 15px;
}

/* The real link an intent with its own screen gets (G4: nearby, settle)
   — never a promise with nothing behind it. Absent for an intent with
   no screen at all (chat) or one Ask deliberately doesn't act on
   (expense), so this rule only ever shows up alongside a genuine <a>. */
.ask-not-built-action {
  display: inline-block;
  margin-top: 9px;
  color: var(--accent);
}

.ask-disclaimer {
  margin: 2px 2px 0;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--ink-muted);
}

/* Drafts — ported from project/Drafts.dc.html, ui-design-system spec
   §4.2 ("Drafts uses 14px→14px 14px 4px 14px radius, 13px text, 8px 12px
   padding — treat as the same [bubble] component at a smaller density")
   and §4.9's confirm/reject pair. Header reuses `.expense-header` (the
   detail-screen shape, spec §4.1) — nothing new needed there. */

.bubble-compact .bubble {
  font-size: 13px;
  padding: 8px 12px;
  border-radius: 14px 14px 4px 14px;
}

.submission-card {
  background: var(--bg-surface);
  border: 1.5px solid var(--accent);
  border-radius: 14px 14px 4px 14px;
  overflow: hidden;
}

/* Settlement (spec §5: "teal accent, since money flows TO the viewer"). */
.submission-card-positive {
  border-color: var(--positive);
}

.submission-badge {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 9px 13px;
  background: var(--accent-subtle);
  border-bottom: 1px solid var(--accent-subtle-line);
  color: var(--accent);
}

.submission-badge-positive {
  color: var(--positive);
}

.submission-badge-text {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.submission-body {
  padding: 12px 13px;
}

.submission-body-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.submission-label {
  font-size: 13.5px;
  font-weight: 500;
}

.submission-amount {
  font-size: 21px;
  font-weight: 600;
}

.submission-amount-positive {
  color: var(--positive);
}

.submission-sub {
  margin-top: 3px;
  font-size: 11.5px;
  color: var(--ink-muted);
}

.submission-note {
  margin-top: 7px;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--ink-muted);
}

.submission-actions {
  display: flex;
  gap: 7px;
  padding: 9px 13px;
  border-top: 1px solid var(--fill-subtle);
}

.submission-action {
  flex: 1;
  font-family: var(--body);
  font-size: 12.5px;
  font-weight: 500;
  padding: 8px 0;
  border-radius: 9px;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--ink-muted);
  cursor: pointer;
}

/* Confirm — the primary half of the pair, `flex-grow: 2` per spec §4.9.
   Its fill matches the card's own accent: clay for expense/contribution,
   teal for settlement (`.submission-action-confirm-positive`). */
.submission-action-confirm {
  flex-grow: 2;
  font-weight: 600;
  border: none;
  background: var(--accent);
  color: #ffffff;
}

.submission-action-confirm-positive {
  background: var(--positive);
}

/* A real, visibly disabled control (contribution/settlement Confirm) —
   never a live-looking button that silently does nothing. The `title`
   naming the screen that will enable it lives on the element in JSX. */
.submission-action-confirm:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Pot — ported from project/Pot.dc.html per app-shell spec §3 and
   ui-design-system spec §4.9/§4.10. Header reuses
   .expense-header/.icon-btn-back/.expense-header-title, same detail-
   header shape as every other detail screen (spec §4.1). See
   PotScreen.tsx's own docstring for the artboard deviations (no invented
   rupee "target", waiting members carry no figure, a real select for who
   is contributing). */

.pot-body {
  gap: 12px;
  padding: 14px 16px 6px;
}

.pot-balance-card {
  background: var(--bg-surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 16px;
}

/* The artboard's "In the pot" is a 12px sentence-case caption, not the
   uppercase micro-label (task-fidelity Part A, Pot). */
.pot-balance-label {
  font-size: 12px;
  color: var(--ink-muted);
}

.pot-balance-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-top: 3px;
}

.pot-balance-row .pot-balance-figure {
  margin-top: 0;
}

/* "of ₹5,000" — shown only once the organiser has set a target
   (task-fidelity B4); the artboard's 13px muted value. */
.pot-balance-target {
  font-size: 13px;
  color: var(--ink-muted);
}

/* The organiser's "Set a target" / "Change target": a text link in the
   accent, 44px tall for the touch target, not a boxed button. */
.pot-target-toggle {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin: 2px 0 -10px;
  padding: 0;
  border: 0;
  background: none;
  font-family: var(--body);
  font-size: 12.5px;
  font-weight: 500;
  color: var(--accent);
  cursor: pointer;
}

/* task-final F1: "Held by X · Change" — the organiser's custodian menu. */
.pot-custodian {
  display: inline-flex;
  align-items: center;
  gap: 0;
}
.pot-custodian-change {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  min-width: 44px;
  justify-content: center;
  padding: 0 4px;
  border: 0;
  background: none;
  font-family: var(--body);
  font-size: 11.5px;
  font-weight: 500;
  color: var(--accent);
  cursor: pointer;
}
.pot-custodian-change:hover {
  color: var(--accent-hover);
}
.pot-target-toggle:hover {
  color: var(--accent-hover);
}

.pot-target-form {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--fill-subtle);
}

.pot-target-row {
  display: flex;
  align-items: baseline;
  gap: 4px;
  margin-top: 3px;
}

.pot-target-currency {
  font-size: 18px;
  font-weight: 500;
  color: var(--ink-muted);
}

.pot-target-input {
  width: 100%;
  min-width: 0;
  border: none;
  border-bottom: 1.5px solid var(--accent);
  border-radius: 0;
  background: transparent;
  font-family: var(--body);
  font-size: 20px;
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  padding: 0 0 2px;
}

.pot-target-actions {
  display: flex;
  gap: 8px;
  margin-top: 12px;
}

.pot-target-actions .btn-secondary,
.pot-target-actions .btn-primary {
  font-size: 14px;
  border-radius: var(--radius-xs);
}

/* IBM Plex Sans, not Fraunces — the type-scale table's own "Fraunces for
   screen titles only" constraint applies here exactly as MemberScreen's
   own hero figure notes: this is a numeral, never a title. */
.pot-balance-figure {
  margin-top: 3px;
  font-size: 32px;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.pot-balance-negative {
  color: var(--negative);
}

.pot-progress-track {
  height: 7px;
  border-radius: var(--radius-pill);
  background: var(--fill-subtle);
  margin-top: 12px;
  overflow: hidden;
}

.pot-progress-fill {
  height: 100%;
  background: var(--accent);
}

.pot-progress-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 8px;
  font-size: 11.5px;
  color: var(--ink-muted);
}

/* The 1.5px accent border (spec §1.4) marking the one field on this
   screen that takes input, same device Edit/AddExpense/Members use for
   their own "big number"/name fields. */
/* task-upi R1: the holder has no UPI id yet — the one thing to do here. */
.pot-upi-required {
  background: var(--accent-subtle);
  border: 1.5px solid var(--accent);
  border-radius: var(--radius-lg);
  padding: 14px 16px;
}

.pot-upi-required-title {
  display: block;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
}

.pot-upi-required-row {
  display: flex;
  gap: 8px;
  margin-top: 10px;
}

.pot-upi-required-input {
  flex: 1;
  min-width: 0;
  min-height: 44px;
  box-sizing: border-box;
  font-family: var(--body);
  font-size: 15px;
  color: var(--ink);
  padding: 10px 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-xs);
  background: var(--bg-surface);
}

.pot-upi-missing {
  margin: 0;
  padding: 14px 16px;
  background: var(--accent-subtle);
  border: 1px solid var(--accent-subtle-line);
  border-radius: var(--radius-lg);
  font-size: 14px;
  color: var(--ink);
}

.pot-holder-hint {
  margin: 6px 0 0;
}

.pot-contribute-card {
  background: var(--bg-surface);
  border: 1.5px solid var(--accent);
  border-radius: var(--radius-lg);
  padding: 14px 16px;
}

/* The "who's paying in" select — an addition over the artboard (see
   PotScreen.tsx's docstring): a member id is never typed, so this
   roster-backed field is what the amount below is actually validated
   against server-side. */
.pot-contributor-select {
  display: block;
  width: 100%;
  box-sizing: border-box;
  margin-top: 4px;
  font-family: var(--body);
  font-size: 14px;
  color: var(--ink);
  padding: 8px 9px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--bg-ground);
}

.pot-amount-label {
  margin-top: 12px;
  display: block;
}

.pot-amount-row {
  display: flex;
  align-items: baseline;
  gap: 4px;
  margin-top: 3px;
}

/* 22px/500 — the artboard's own currency glyph beside the "big number"
   input (matches Draft/Edit/AddExpense's own glyph size, ui-design-system
   spec §1.2), not the 20px the spec's colour-table row separately (and,
   on inspection of the artboard itself, wrongly) names for this screen. */
.pot-amount-currency {
  font-size: 22px;
  font-weight: 500;
  color: var(--ink-muted);
}

/* 27px — the artboard's own value for the Pot contribution input,
   distinct from Edit/AddExpense's 24px (ui-design-system spec §1.2). */
.pot-amount-input {
  width: 100%;
  min-width: 0;
  border-radius: 0;
  border: none;
  border-bottom: 1.5px solid var(--accent);
  background: transparent;
  font-family: var(--body);
  font-size: 27px;
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  padding: 0 0 2px;
}

.pot-pay-btn {
  width: 100%;
  flex-grow: 0;
  margin-top: 12px;
  border-radius: var(--radius-xs);
}

.pot-list-card {
  background: var(--bg-surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.pot-list-label {
  padding: 12px 15px 6px;
}

.pot-list-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 15px;
  border-bottom: 1px solid var(--fill-subtle);
}

.pot-list-name {
  flex-grow: 1;
  font-size: 14px;
}

.pot-list-amount {
  font-size: 14px;
}

.pot-list-amount-positive {
  color: var(--positive);
}

.pot-list-trailing {
  width: 46px;
  flex-shrink: 0;
  display: flex;
  justify-content: flex-end;
  color: var(--positive);
}

.pot-list-waiting {
  font-size: 11px;
  color: var(--ink-faint);
}

/* A waiting member's share of the target — the artboard's muted figure
   beside "waiting" (task-fidelity B4). */
.pot-list-ask {
  color: var(--ink-faint);
}

.pot-list-footer {
  padding: 11px 15px;
}

.pot-send-link {
  width: auto;
  font-size: 12px;
  font-weight: 600;
  color: var(--accent);
  text-decoration: none;
  min-height: 44px;
  /* The 44px touch box overlaps the row's own 11px padding, so the row
     stays the artboard's height instead of growing to 66px. */
  margin-block: -11px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

.pot-send-link:hover {
  text-decoration: underline;
}

.pot-footnote {
  margin: 0 2px;
}

/* Settle — ported from project/Settle.dc.html per app-shell spec §3 and
   ui-design-system spec §4.7 (advisory)/§4.9 (buttons, incl. the QR
   icon-button's 36×36 size)/§1 (tokens). Header reuses
   .expense-header/.icon-btn-back/.expense-header-title, same shape as
   Pot/Drafts. See SettleScreen.tsx's own docstring for every deviation
   from the artboard's single fictional example. */

.settle-card {
  background: var(--bg-surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  flex-shrink: 0;
}

/* The artboard's 36px QR toggle keeps a 44px touch target (spec §4.1). */
.settle-qr-toggle::after {
  content: "";
  position: absolute;
  inset: -4px;
}

.settle-row-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 16px 13px;
}

.settle-row-compact {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 16px;
}

/* Compact rows share one card (Settle.dc.html), each after the first
   divided by the faint rule. */
.settle-list {
  border-radius: var(--radius-lg);
}

.settle-list .settle-row-compact + .settle-row-compact {
  border-top: 1px solid var(--fill-subtle);
}

.settle-row-name {
  font-size: 14px;
  font-weight: 500;
}

.settle-row-sub {
  font-size: 12px;
  color: var(--ink-muted);
  margin-top: 1px;
}

.settle-amount {
  font-size: 16px;
  font-weight: 600;
}

.settle-row-trailing {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* The per-row "show QR" icon button — §4.9's own 36×36 size note. */
.settle-qr-toggle {
  position: relative;
  width: 36px;
  height: 36px;
  padding: 0;
  flex-shrink: 0;
  border-radius: var(--radius-2xs);
  border: 1px solid var(--line);
  background: var(--bg-surface);
  color: var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.settle-expanded-body {
  display: flex;
  gap: 14px;
  align-items: center;
  padding: 0 16px 15px;
}

.settle-qr-frame {
  flex-shrink: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-2xs);
  padding: 6px;
  background: var(--bg-surface);
}

.settle-actions {
  flex-grow: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.settle-no-upi {
  margin: 0;
  font-size: 12px;
  color: var(--ink-faint);
}

.settle-no-upi-compact {
  text-align: right;
}

/* Task-ux2 U10: to the receiver, the missing UPI id is theirs to add —
   a real link, in the accent, with a full touch target. */
.settle-row-compact > :first-child {
  flex-shrink: 0;
}

.settle-add-upi.settle-no-upi-compact {
  max-width: 140px;
  line-height: 1.35;
}

.settle-add-upi {
  color: var(--accent);
  font-weight: 500;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

.settle-total-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 2px 4px;
}

.settle-total-label {
  font-size: 13px;
  color: var(--ink-muted);
}

.settle-total-value {
  font-size: 20px;
  font-weight: 600;
}

.settle-see-link {
  display: block;
  text-align: center;
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  padding: 2px 0;
}

.settle-footnote {
  margin: 0 2px;
  text-align: center;
}

/* Nearby — ported from project/Nearby.dc.html per app-shell spec §3/§4
   and ui-design-system spec §4.2 (compact bubble density; unused here —
   Nearby carries no chat bubble of its own, see NearbyScreen.tsx's own
   docstring), §4.7 (the boxed advisory — reused verbatim via `.advisory`
   for the "left out" note, deliberately NOT the artboard's own literal
   `#FDFBF8` box; spec §4.7 is explicit this is the SAME accent-subtle
   component every other screen's callout uses) and the positive-subtle
   tag treatment for "open till …". Header/badge/footer/disclaimer all
   reuse .expense-header/.ask-badge/.submission-actions/.ask-disclaimer
   verbatim — only the card's own body is new. */

.nearby-card {
  background: var(--bg-surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.nearby-card-head {
  padding: 12px 14px 9px;
}

.nearby-card-sub {
  margin-top: 3px;
  font-size: 11.5px;
  color: var(--ink-muted);
}

/* One checklist row per suggestion — including a CLOSED one. Constraint:
   closedness is information, not a filter, so a closed place is never
   dropped from this list; its checkbox is simply disabled (you cannot
   add a place to today's plan that you cannot reach). */
.nearby-row {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 11px 14px;
  border-bottom: 1px solid var(--fill-subtle);
  cursor: pointer;
}

.nearby-row-closed {
  cursor: default;
}

.nearby-row input[type="checkbox"] {
  width: 20px;
  height: 20px;
  accent-color: var(--accent);
  margin: 2px 0 0;
  flex-shrink: 0;
}

.nearby-row-main {
  display: block;
  flex-grow: 1;
  min-width: 0;
}

.nearby-row-name {
  display: block;
  font-size: 14px;
  font-weight: 500;
}

.nearby-row-closed .nearby-row-name {
  color: var(--ink-muted);
}

.nearby-row-meta {
  display: block;
  margin-top: 2px;
  font-size: 11.5px;
  color: var(--ink-muted);
}

.nearby-row-tags {
  display: flex;
  gap: 8px;
  margin-top: 5px;
  flex-wrap: wrap;
}

.nearby-tag {
  font-size: 10.5px;
  border-radius: var(--radius-pill);
  padding: 2px 7px;
}

/* Positive-subtle tag treatment (ui-design-system spec §1/§4): the "open
   till …" pill — teal ink on a teal-tinted fill, its own subtle border,
   distinct from --accent-subtle. */
.nearby-tag-open {
  color: var(--positive);
  background: var(--positive-subtle);
  border: 1px solid var(--positive-subtle-line);
}

.nearby-tag-closed {
  color: var(--ink-faint);
  border: 1px solid var(--line-strong);
}

/* Distinct from "closed" on purpose (task-osm): not knowing whether a
   place is open is information in its own right, never the same claim
   as knowing it's shut. A dashed border reads as "uncertain", not
   "negative", the way the solid `nearby-tag-closed` border does. */
.nearby-row-unknown .nearby-row-name {
  color: var(--ink-muted);
}

.nearby-tag-unknown {
  color: var(--ink-muted);
  border: 1px dashed var(--line);
}

.nearby-tag-price {
  color: var(--ink-muted);
  border: 1px solid var(--line);
}

/* The "left out" note — `.advisory`/`.advisory-text` (spec §4.7) reused
   verbatim, just inset to sit flush inside this card's own edges. One
   per closed place that has an explanation, never a whole-list filter. */
.nearby-advisory {
  margin: 0 14px 11px;
}

.nearby-summary {
  padding: 0 14px 11px;
}

.nearby-confirmed {
  margin: 0;
  padding: 11px 14px;
  color: var(--positive);
  font-size: 12.5px;
  line-height: 1.5;
}

/* Auth — ported from project/Auth.dc.html, route /signin (app-shell spec
   §2/§3). Outside the Shell entirely (no rail — src/client/main.tsx),
   so `.app-frame` here is the whole page, not a pane's content. */

.auth-frame {
  justify-content: space-between;
}

.auth-hero {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 0 28px;
}

.auth-mark {
  width: 54px;
  height: 54px;
  border-radius: var(--radius-md);
  background: var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 26px;
}

/* 34px/600 Fraunces, -0.02em — ui-design-system spec §1.2's own "Auth
   headline" row. Fraunces is used for this headline only on this screen. */
.auth-headline {
  margin: 0;
  font-family: var(--display);
  font-size: 34px;
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.02em;
}

.auth-subhead {
  margin: 14px 0 0;
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--ink-muted);
}

/* The Google button: a primary-styled control (task brief; design-system
   spec §4.9) in SHAPE — full width, 44px+ touch target, the same
   geometry every other primary CTA in this app uses — but the artboard
   keeps its own white/outlined colouring rather than the generic accent
   fill (porting rule, app-shell spec §3.2: values don't change). 15.5px/
   500 per the type scale's own "Auth 'Continue with Google' label" row. */
.auth-google-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 11px;
  margin-top: 34px;
  min-height: 44px;
  box-sizing: border-box;
  font-family: var(--body);
  font-size: 15.5px;
  font-weight: 500;
  padding: 15px 0;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line-strong);
  background: var(--bg-surface);
  color: var(--ink);
  text-decoration: none;
}

.auth-google-btn:hover {
  color: var(--ink);
  border-color: var(--ink-faint);
}

.auth-google-mark {
  flex-shrink: 0;
}

.auth-divider {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 22px 0;
}

.auth-divider-line {
  flex-grow: 1;
  height: 1px;
  background: var(--line);
}

.auth-divider-label {
  font-size: 11.5px;
  color: var(--ink-faint);
}

.auth-invite-note {
  background: var(--bg-surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 15px;
}

.auth-invite-note-head {
  display: flex;
  align-items: center;
  gap: 9px;
}

.auth-invite-note-title {
  font-size: 13.5px;
  font-weight: 600;
}

.auth-invite-note-body {
  margin: 8px 0 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-muted);
}

.auth-legal {
  flex-shrink: 0;
  padding: 0 28px 26px;
}

.auth-legal p {
  margin: 0;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--ink-faint);
  text-align: center;
}

/* The invite link's join screen (task-id) — the Auth screen's hero,
   with the account it will join as, and one clear action. */
.join-headline {
  font-size: 28px;
}

.join-eyebrow {
  margin-bottom: 10px;
}

.join-account {
  margin-top: 28px;
  padding: 13px 15px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
  font-size: 14px;
  line-height: 1.45;
  overflow-wrap: anywhere;
}

.join-cta {
  margin-top: 14px;
  width: 100%;
  flex-grow: 0;
  text-decoration: none;
}

.join-switch {
  margin-top: 10px;
  width: 100%;
  flex-grow: 0;
}

.join-footnote {
  margin: 22px 0 0;
  font-size: 13.5px;
  color: var(--ink-muted);
}

/* "Sign in to keep this trip" (task-id): a member still on an old link. */
/* The banner sits above the screen, in the same column as it. */
.keep-wrap {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  min-width: 0;
}

.keep-wrap > .app-frame {
  flex: 1;
  min-height: 0;
  height: auto;
}

.keep-banner {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  flex-shrink: 0;
  box-sizing: border-box;
  width: calc(100% - 32px);
  max-width: calc(var(--col, 390px) - 32px);
  margin: 12px auto 0;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
  font-size: 13.5px;
  line-height: 1.45;
}

.keep-banner-text {
  flex: 1 1 200px;
}

.keep-banner .btn-primary {
  flex: 0 0 auto;
  padding: 11px 16px;
  text-decoration: none;
}

/* Joined state on Members and a person's page (task-id) — organisers only. */
.join-line {
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--ink-muted);
  overflow-wrap: anywhere;
}

.join-line-positive {
  color: var(--positive);
}

.member-access-actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 10px;
}

.member-access-actions .btn-secondary {
  flex-grow: 0;
  text-decoration: none;
}

.invite-status {
  margin: 6px 0 0;
}

.roster-join {
  display: block;
  margin-top: 2px;
}

.badge-coorganiser {
  font-size: 9.5px;
  font-weight: 600;
  color: var(--ink-muted);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  padding: 1px 7px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* New-trip dialog (task-ux defect 2) — no artboard has one, so this
   matches the system's existing shapes rather than inventing a new
   visual language: the scrim token Shell's own drawer already uses
   (--scrim), the card's own tokens (--bg-surface / --line / --radius-lg),
   Fraunces for the title (spec §1.2's 20px/600/Fraunces `<h1>` size,
   used here for the dialog's own heading), the boxed field from spec
   §4.10, and the primary/secondary button pair from spec §4.9. */
.dialog-scrim {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.dialog-scrim-close {
  position: absolute;
  inset: 0;
  z-index: 0;
  border: 0;
  padding: 0;
  margin: 0;
  background: var(--scrim);
  cursor: pointer;
}

.dialog-card {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 360px;
  box-sizing: border-box;
  background: var(--bg-surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 20px;
}

.dialog-title {
  margin: 0 0 16px;
  font-family: var(--display);
  font-size: 20px;
  font-weight: 600;
  color: var(--ink);
}

.dialog-field {
  display: block;
  width: 100%;
  box-sizing: border-box;
  margin-top: 5px;
  font-family: var(--body);
  font-size: 15px;
  color: var(--ink);
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-xs);
  background: var(--bg-ground);
}

.dialog-date-row {
  display: flex;
  gap: 12px;
  margin-top: 14px;
}

.dialog-date-field {
  flex: 1;
  min-width: 0;
}

/* task-upi R1: the organiser's UPI id, under the dates. */
.dialog-upi-label {
  display: block;
  margin-top: 14px;
}

.dialog-field-hint {
  margin: 6px 0 0;
}

.dialog-actions {
  display: flex;
  gap: 9px;
  margin-top: 18px;
}

/* Check in (task-fidelity B7) — the detail-screen shape, existing tokens. */
.checkin-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 15px;
}

.checkin-locate {
  flex-grow: 0;
  font-size: 14px;
  border-radius: var(--radius-xs);
}

.member-checkin-link {
  margin-top: 10px;
  flex-grow: 0;
  font-size: 14px;
  border-radius: var(--radius-xs);
  text-decoration: none;
}

/* While a draft replaces the composer, the footer takes the stream's
   ground colour — Draft.dc.html draws the card on the ground, not on a
   white bar (task-fidelity Part A). */
.app-footer:has(.draft-wrap) {
  background: var(--bg-ground);
}

/* The base buttons grow (flex-grow 1/2) for the paired footer rows; one
   sitting straight in a scrolling column must keep its own height —
   Invite's "Make a new link" had grown to fill the screen
   (task-fidelity Part A). */
.app-stream > .btn-primary,
.app-stream > .btn-secondary {
  flex-grow: 0;
}

/* Nearby's Places / Food toggle (task-fidelity B5): the Room's filter
   pill, at the end of the suggestion badge row. */
.nearby-kind {
  margin-left: auto;
  text-transform: none;
  letter-spacing: normal;
}

/* task-final F5: where Nearby searches, and the organiser's Change. */
.nearby-near {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 2px 2px 0;
  font-size: 12.5px;
  color: var(--ink-muted);
}
.nearby-near-change {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  min-width: 44px;
  padding: 0 4px;
  border: 0;
  background: none;
  font-family: var(--body);
  font-size: 12.5px;
  font-weight: 500;
  color: var(--accent);
  cursor: pointer;
}
.nearby-near-change:hover {
  color: var(--accent-hover);
}
.nearby-near-form {
  margin: 4px 2px 8px;
}
.nearby-wide-hint {
  margin: 0 2px 8px;
}
.nearby-finding {
  margin-top: 12px;
}

.ask-badge:has(.nearby-kind) {
  display: flex;
  align-items: center;
}

/* "Added by mistake?" — the organiser's fix-name / remove card on a
   person's page. Reuses the add-member form's field and action row. */
.manage-member-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.manage-member-question {
  margin: 0;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--ink);
}

.manage-member-remove {
  color: var(--negative);
}

.manage-member-confirm {
  background: var(--negative);
}

.manage-member-blockers {
  margin: 0;
  padding-left: 18px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink);
}

/* --- task-upi: pay by UPI, then the receiver confirms ------------------ */

.upi-pay-head {
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
}

.upi-pay-body {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 12px;
  align-items: flex-start;
}

.upi-pay-qr {
  flex-shrink: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-2xs);
  padding: 6px;
  background: var(--bg-surface);
  text-align: center;
}

.upi-pay-qr svg {
  display: block;
}

.upi-pay-qr-caption {
  margin-top: 4px;
  font-size: 11.5px;
  color: var(--ink-muted);
}

.upi-pay-actions {
  flex: 1 1 180px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.upi-pay-actions .btn-primary,
.upi-pay-actions .btn-secondary {
  flex-grow: 0;
  width: 100%;
  text-decoration: none;
}

.upi-pay-vpa {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  min-height: 44px;
  font-size: 13px;
  color: var(--ink-muted);
}

.upi-pay-vpa-value {
  font-weight: 600;
  color: var(--ink);
  overflow-wrap: anywhere;
}

.upi-pay-copy,
.upi-pay-cancel,
.claim-try-again {
  min-height: 44px;
  min-width: 44px;
}

.upi-pay-cancel {
  align-self: flex-start;
}

.upi-pay-note {
  margin: 10px 0 0;
}

.claim-status {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  background: var(--positive-subtle);
  border: 1px solid var(--positive-subtle-line);
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
}

.claim-status + .upi-pay,
.claim-status + form {
  margin-top: 12px;
}

.claim-status-sub {
  font-size: 12px;
  font-weight: 400;
  color: var(--ink-muted);
}

.claim-status-refused {
  background: var(--accent-subtle);
  border-color: var(--accent-subtle-line);
  font-weight: 500;
  gap: 8px;
}

.claim-status-refused .claim-try-again {
  flex-grow: 0;
  align-self: flex-start;
  padding: 0 16px;
}

.claim-confirm {
  background: var(--bg-surface);
  border: 1.5px solid var(--accent);
  border-radius: var(--radius-lg);
  padding: 14px 16px;
}

.claim-confirm + .claim-confirm {
  margin-top: 10px;
}

.claim-confirm-text {
  font-size: 14px;
  color: var(--ink);
}

.claim-confirm-ref {
  margin-top: 4px;
  font-size: 12px;
  color: var(--ink-muted);
}

.claim-confirm-actions {
  display: flex;
  gap: 9px;
  margin-top: 12px;
}

.pot-claims-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.pot-record-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 8px;
}

.pot-record-card {
  border: 1px solid var(--line);
}

.stream-caption-pending svg {
  color: var(--accent);
}

.upi-pay-copy,
.upi-pay-cancel {
  background: none;
  border: none;
  padding: 0 4px;
  font-family: var(--body);
  font-size: 13px;
  font-weight: 600;
  color: var(--accent);
  cursor: pointer;
}

.upi-pay-copy:hover,
.upi-pay-cancel:hover {
  color: var(--accent-hover);
}

/* task-upi R3: a Settle row stacks its status, pay block and actions. */
.settle-expanded-stack {
  flex-direction: column;
  align-items: stretch;
  gap: 10px;
}

.settle-expanded-stack > .btn-secondary,
.settle-expanded-stack > .btn-primary {
  flex-grow: 0;
}

.settle-expanded-stack > .field-hint {
  margin: 0;
}

/* A problem with one field, said directly under that field. */
.field-error {
  margin-top: 6px;
  font-size: 13px;
  line-height: 1.4;
  color: var(--negative);
}

.dialog-field[aria-invalid="true"] {
  border-color: var(--negative);
}

.member-claim-status,
.member-claims {
  margin-top: 14px;
}

.member-claims .claim-confirm + .claim-confirm {
  margin-top: 10px;
}

.pot-upi-required-label {
  display: block;
  margin-top: 10px;
}

.pot-upi-required-input[aria-invalid="true"],
.member-vpa-input[aria-invalid="true"] {
  border-color: var(--negative);
}

/* Archive / delete a trip. */
.room-archived {
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.room-archived .btn-secondary {
  flex-grow: 0;
  padding: 0 16px;
}

.home-archived {
  margin-top: 18px;
}

.home-archived-summary {
  cursor: pointer;
  min-height: 44px;
  display: flex;
  align-items: center;
  gap: 6px;
  list-style: none;
}

.home-archived-summary::-webkit-details-marker {
  display: none;
}

.home-archived-summary::after {
  content: "▾";
  margin-left: 2px;
}

.home-archived[open] .home-archived-summary::after {
  content: "▴";
}

.delete-trip-warning {
  color: var(--negative);
}

.delete-trip-confirm {
  background: var(--negative);
}

.link-button {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: var(--accent);
  text-decoration: underline;
  cursor: pointer;
}

/* The draft card, edited in place: fields look like the card's own text
   (same size and weight as the read-only figures they replace), with an
   underline to say "you can change this". */
.draft-amount-row {
  align-items: center;
}

.draft-amount-input {
  flex: 1 1 auto;
  min-width: 0;
  width: 100%;
  font-family: var(--body);
  font-size: 28px;
  font-weight: 600;
  color: var(--ink);
  background: transparent;
  border: none;
  border-bottom: 1px dashed var(--line-strong);
  padding: 2px 0;
  min-height: 44px;
}

.draft-mode-toggle {
  flex-shrink: 0;
  margin-top: 0;
}

.draft-mode-toggle button {
  min-height: 44px;
}

.draft-total-line {
  margin-top: 4px;
  font-size: 13px;
  color: var(--ink-muted);
}

.draft-fact-input,
.draft-fact-select {
  display: block;
  width: 100%;
  box-sizing: border-box;
  margin-top: 4px;
  font-family: var(--body);
  font-size: 14px;
  font-weight: 500;
  color: var(--ink);
  background: transparent;
  border: none;
  border-bottom: 1px dashed var(--line-strong);
  padding: 6px 0;
  min-height: 44px;
}

.draft-fact-select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-muted) 50%),
    linear-gradient(135deg, var(--ink-muted) 50%, transparent 50%);
  background-position: calc(100% - 10px) 55%, calc(100% - 5px) 55%;
  background-size: 5px 5px;
  background-repeat: no-repeat;
  padding-right: 20px;
}

.draft-fact-input:focus,
.draft-fact-select:focus,
.draft-amount-input:focus {
  outline: none;
  border-bottom: 1.5px solid var(--accent);
}

.draft-fact {
  min-width: 0;
}

.chip-toggle {
  font-family: var(--body);
  cursor: pointer;
  border: 1px solid transparent;
  min-height: 44px;
  padding: 6px 14px;
  font-size: 13px;
}

.chip-toggle.chip-off {
  border: 1px dashed var(--line-strong);
  background: transparent;
}

.chip-toggle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.draft-chips {
  gap: 6px;
}

.draft-problem {
  padding: 0 15px 12px;
}

/* A generated draft is reviewed in a sheet over the chat: a bottom sheet
   on a phone, a centred dialog from 768px. */
.draft-sheet-scrim {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.draft-sheet {
  position: relative;
  z-index: 1;
  width: 100%;
  max-height: 92vh;
  overflow-y: auto;
  box-sizing: border-box;
  background: var(--bg-ground);
  border-top: 1px solid var(--line);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: 0 16px calc(16px + env(safe-area-inset-bottom));
  animation: sheet-up 340ms var(--ease-sheet) both;
}

/* The scrim fades while the sheet slides; leaving runs both backwards,
   a little faster (SHEET_EXIT_MS in DraftSheet.tsx). */
.draft-sheet-scrim > .dialog-scrim-close {
  animation: sheet-scrim-in 240ms ease-out both;
}

.draft-sheet-scrim[data-state="closing"] {
  pointer-events: none;
}

.draft-sheet-scrim[data-state="closing"] > .dialog-scrim-close {
  animation: sheet-scrim-out 220ms ease-in both;
}

.draft-sheet-scrim[data-state="closing"] .draft-sheet {
  animation: sheet-down 220ms cubic-bezier(0.4, 0, 1, 1) both;
}

.draft-sheet-head {
  position: sticky;
  top: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  background: var(--bg-ground);
  z-index: 1;
}

.draft-sheet-grip {
  position: absolute;
  top: 8px;
  left: calc(50% - 18px);
  width: 36px;
  height: 4px;
  border-radius: 999px;
  background: var(--line-strong);
}

.draft-sheet-close {
  position: absolute;
  right: -6px;
  top: 6px;
}

.draft-sheet-title {
  position: absolute;
  left: 0;
  top: 22px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}

.draft-sheet-head {
  min-height: 64px;
}

/* The sheet's header carries the title; the card's own status line would
   repeat it. */
.draft-sheet-body .draft-status {
  display: none;
}

.draft-sheet-body .draft-wrap {
  margin: 0;
}

@keyframes sheet-up {
  from {
    transform: translateY(100%);
  }
  to {
    transform: none;
  }
}

@keyframes sheet-down {
  from {
    transform: none;
  }
  to {
    transform: translateY(100%);
  }
}

@keyframes sheet-scrim-in {
  from {
    opacity: 0;
  }
}

@keyframes sheet-scrim-out {
  to {
    opacity: 0;
  }
}

/* On a wide screen the dialog rises a little and settles, rather than
   travelling the whole viewport. */
@keyframes sheet-pop {
  from {
    transform: translateY(16px) scale(0.98);
    opacity: 0;
  }
}

@keyframes sheet-unpop {
  to {
    transform: translateY(8px) scale(0.98);
    opacity: 0;
  }
}

/* The expense form, hosted in the sheet instead of taking over the
   footer: the sheet scrolls, the Cancel / Add row stays in reach. */
.draft-sheet-body .expense-form-shell {
  flex: none;
  overflow: visible;
}

.draft-sheet-body .expense-body {
  overflow: visible;
  padding: 0 0 12px;
}

.draft-sheet-body .expense-footer {
  position: sticky;
  bottom: 0;
  margin: 0 -16px calc(-16px - env(safe-area-inset-bottom));
  background: var(--bg-ground);
}

/* The + sheet: what can be added to the trip from the chat. */
.add-menu {
  list-style: none;
  margin: 0 -8px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.add-menu-item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 56px;
  padding: 8px;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--ink);
  font-family: var(--body);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 120ms ease;
}

.add-menu-item:hover,
.add-menu-item:focus-visible {
  background: var(--fill-subtle);
  outline: none;
}

.add-menu-item:active {
  background: var(--accent-subtle);
}

.add-menu-icon {
  flex-shrink: 0;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-pill);
  background: var(--accent-subtle);
  border: 1px solid var(--accent-subtle-line);
  color: var(--accent);
}

.add-menu-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.add-menu-label {
  font-size: 15px;
  font-weight: 500;
}

.add-menu-hint {
  font-size: 13px;
  color: var(--ink-muted);
}

/* The composer's + turns into a × while its sheet is open. */
.composer-add svg {
  transition: transform 200ms var(--ease-sheet);
}

.composer-add[aria-expanded="true"] svg {
  transform: rotate(45deg);
}

@media (min-width: 768px) {
  .draft-sheet-scrim {
    align-items: center;
    padding: 24px;
  }

  .draft-sheet {
    max-width: 520px;
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: 0 20px 20px;
    animation-name: sheet-pop;
    animation-duration: 220ms;
  }

  .draft-sheet-scrim[data-state="closing"] .draft-sheet {
    animation: sheet-unpop 180ms ease-in both;
  }

  .draft-sheet-body .expense-footer {
    margin: 0 -20px -20px;
    padding-bottom: 17px;
  }

  .draft-sheet-grip {
    display: none;
  }

  .draft-sheet-title {
    top: 24px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .draft-sheet,
  .draft-sheet-scrim > .dialog-scrim-close,
  .draft-sheet-scrim[data-state="closing"] .draft-sheet,
  .draft-sheet-scrim[data-state="closing"] > .dialog-scrim-close {
    animation: none;
  }

  .composer-add svg {
    transition: none;
  }
}

/* task-rw1 A1: the drafter couldn't read a money line. Nothing was
   posted; the person retries or adds it by hand. Existing tokens. */
.composer-unreadable {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin-bottom: 8px;
  padding: 10px 12px;
  background: var(--accent-subtle);
  border: 1px solid var(--accent-subtle-line);
  border-radius: var(--radius-sm);
}
.composer-unreadable-text {
  flex: 1 1 180px;
  font-size: 13px;
  color: var(--ink);
}
.composer-unreadable-actions {
  display: flex;
  gap: 8px;
}
.composer-unreadable-actions button {
  min-height: 44px;
  padding: 0 14px;
}

/* task-rw1 E6: a pot handover waiting for the cash to change hands. */
.pot-handover {
  margin-top: 12px;
  padding: 12px 14px;
  background: var(--accent-subtle);
  border: 1px solid var(--accent-subtle-line);
  border-radius: var(--radius-sm);
}
.pot-handover-title {
  font-weight: 600;
  color: var(--ink);
}
.pot-handover-text {
  margin: 6px 0;
  color: var(--ink);
}
.pot-handover-actions {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}

/* task-rw1 F3/F5: the amount on a pay block — part, or a little more. */
.pay-amount {
  margin-bottom: 10px;
}
.pay-amount-row {
  display: flex;
  align-items: baseline;
  gap: 6px;
  border-bottom: 1px solid var(--line-strong);
}
.pay-amount-currency {
  font-size: 20px;
  color: var(--ink-muted);
}
.pay-amount-input {
  flex: 1;
  min-height: 44px;
  border: none;
  background: transparent;
  font-size: 22px;
  font-weight: 600;
  color: var(--ink);
  padding: 4px 0;
}
.pay-amount-input:focus {
  outline: none;
}
.pay-amount-note {
  margin-top: 6px;
}
.claim-confirm-unmatched {
  margin: 6px 0;
}

/* task-rw1 A10: what a refund does to the expense it was for. */
.refund-preview {
  margin: 0;
  padding: 0 15px 12px;
  font-size: 13px;
  color: var(--ink);
}
.refund-before {
  text-decoration: line-through;
  color: var(--ink-faint);
}
.refund-expense-select {
  margin-top: 6px;
  min-height: 44px;
}
/* Hints inside a draft card sit on the card's own inset. */
.draft .pot-shortfall,
.draft .contribution-note {
  margin: 0;
  padding: 0 15px 12px;
}

/* task-rw1 H6: when an expense happened. */
.when-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.when-input {
  min-height: 44px;
  max-width: 220px;
}
.draft-when .when-input {
  max-width: none;
}
.when-hint {
  margin: 2px 0 0;
}

/* ---------------------------------------------------------------------
   task-rt R3: notifications — the bell with its unread badge, its list
   (a popover under the bell from 768px, a bottom sheet on a phone) and
   the toast stack. Existing tokens only; no shadows (spec §1.6):
   elevation is a border. Every target is 44px.
   --------------------------------------------------------------------- */

.notif {
  flex-shrink: 0;
}
.expense-header .notif {
  margin-left: auto;
  margin-block: -6px;
}
.notif-bell {
  position: relative;
}
.notif-badge {
  position: absolute;
  top: 5px;
  right: 4px;
  min-width: 17px;
  height: 17px;
  padding: 0 4px;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: #ffffff;
  border: 1.5px solid var(--bg-surface);
  font-size: 10px;
  font-weight: 600;
  line-height: 14px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  box-sizing: border-box;
}

.notif-pop {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 40;
  width: 360px;
  max-width: calc(100vw - 32px);
  max-height: min(70vh, 560px);
  overflow-y: auto;
  padding: 4px;
  background: var(--bg-surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  display: flex;
  flex-direction: column;
  text-align: left;
}
.notif-sheet {
  position: fixed;
  top: auto;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 61;
  width: auto;
  max-width: none;
  max-height: 80vh;
  padding: 8px 8px calc(12px + env(safe-area-inset-bottom));
  border: none;
  border-top: 1px solid var(--line);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  animation: sheet-up 340ms var(--ease-sheet) both;
}
.notif-scrim {
  position: fixed;
  inset: 0;
  z-index: 60;
  border: none;
  padding: 0;
  background: var(--scrim);
  cursor: default;
}

.notif-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 44px;
  padding: 0 4px 0 12px;
}
.notif-head-title {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}
.notif-mark-all {
  min-height: 44px;
  padding: 0 10px;
  border: none;
  border-radius: var(--radius-2xs);
  background: transparent;
  color: var(--accent);
  font-family: var(--body);
  font-size: 12.5px;
  font-weight: 500;
  cursor: pointer;
}
.notif-mark-all:hover,
.notif-mark-all:focus-visible {
  background: var(--accent-subtle);
  color: var(--accent-hover);
  outline: none;
}
.notif-empty {
  margin: 0;
  padding: 8px 12px 16px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-muted);
}
.notif-group {
  display: flex;
  flex-direction: column;
}
.notif-group + .notif-group {
  border-top: 1px solid var(--fill-subtle);
  margin-top: 4px;
  padding-top: 4px;
}
.notif-group-label {
  padding: 6px 12px 4px;
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.notif-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-height: 44px;
  padding: 10px 12px;
  border: none;
  border-radius: var(--radius-2xs);
  background: transparent;
  color: var(--ink);
  font-family: var(--body);
  text-align: left;
  cursor: pointer;
}
.notif-item:hover,
.notif-item:focus-visible {
  background: var(--fill-subtle);
  outline: none;
}
.notif-dot {
  flex-shrink: 0;
  width: 8px;
  height: 8px;
  margin-top: 5px;
  border-radius: var(--radius-pill);
  background: transparent;
}
.notif-item-unread .notif-dot {
  background: var(--accent);
}
.notif-item-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.notif-item-title {
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.35;
  color: var(--ink-muted);
}
.notif-item-unread .notif-item-title {
  font-weight: 600;
  color: var(--ink);
}
.notif-item-body {
  font-size: 12.5px;
  color: var(--ink-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.notif-item-meta {
  font-size: 11px;
  color: var(--ink-faint);
}

/* The toast stack: top right; across the top at phone width. */
.toast-stack {
  position: fixed;
  /* Under the header's controls row (the bell is at 16–60px), so a toast
     never sits on top of the bell it belongs to. */
  top: 70px;
  right: 16px;
  z-index: 70;
  width: 360px;
  max-width: calc(100vw - 32px);
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
}
.toast-stack > * {
  pointer-events: auto;
}
@media (max-width: 767.98px) {
  .toast-stack {
    top: calc(8px + env(safe-area-inset-top));
    left: 16px;
    right: 16px;
    width: auto;
    max-width: none;
  }
}
.toast {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 4px;
  padding: 4px 4px 4px 0;
  background: var(--bg-surface);
  border: 1px solid var(--line-strong);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-md);
  animation: toast-in 200ms ease-out;
}
@keyframes toast-in {
  from {
    transform: translateY(-12px);
    opacity: 0;
  }
  to {
    transform: none;
    opacity: 1;
  }
}
.toast-main {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  min-height: 44px;
  justify-content: center;
  padding: 6px 4px 6px 12px;
  border: none;
  background: transparent;
  color: var(--ink);
  font-family: var(--body);
  text-align: left;
  cursor: pointer;
}
.toast-title {
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.35;
}
.toast-body {
  font-size: 12.5px;
  color: var(--ink-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.toast-action {
  min-height: 44px;
  padding: 0 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-2xs);
  background: var(--bg-surface);
  color: var(--accent);
  font-family: var(--body);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.toast-action:hover {
  border-color: var(--accent);
}
.toast-close {
  border: none;
  background: transparent;
  color: var(--ink-faint);
}
.toast-close:hover {
  color: var(--ink);
}
.toast-main:focus-visible,
.toast-action:focus-visible,
.toast-close:focus-visible,
.toast-more:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.toast-more {
  align-self: flex-end;
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  background: var(--bg-surface);
  color: var(--ink-muted);
  font-family: var(--body);
  font-size: 12.5px;
  font-weight: 500;
  cursor: pointer;
}

@media (prefers-reduced-motion: reduce) {
  .toast,
  .notif-sheet {
    animation: none;
  }
}

.settle-remind-btn {
  margin-top: 8px;
}

/* A corrected expense's earlier versions, inside its one card. */
.card-history {
  margin: 8px 0 0;
  padding-left: 18px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* Check in / check out from chat (task-checkin) — existing tokens only. */
.presence-where {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 15px;
  border-top: 1px solid var(--fill-subtle);
}

.presence-located {
  margin: 0;
  padding: 8px 10px;
  font-size: 13px;
  font-weight: 500;
  color: var(--ink);
  background: var(--accent-subtle);
  border: 1px solid var(--accent-subtle-line);
  border-radius: var(--radius-xs);
}

.presence-locate {
  min-height: 44px;
  width: 100%;
}

.checkin-body .presence-draft {
  width: 100%;
}

/* task-potcash: a pot-payout draft card. "Pot now ₹3,000 → ₹2,700" is the
   server's preview; the refusal is a plain sentence, not an error. */
.payout-pot-line {
  margin: 0 15px 12px;
  padding: 10px 12px;
  border-radius: var(--radius-2xs);
  background: var(--fill-subtle);
  color: var(--ink);
  font-size: 14px;
}
.payout-refusal {
  margin: 12px 15px;
  padding: 12px;
  border-radius: var(--radius-2xs);
  background: var(--accent-subtle);
  border: 1px solid var(--accent-subtle-line);
  color: var(--ink);
  font-size: 15px;
  line-height: 1.45;
}

/* task-potcash: the Pot screen's cash. "Tushar should have ₹1,200 in hand"
   under the figure; the payout form; the pot's movements. */
.pot-in-hand {
  margin-top: 6px;
  font-size: 13.5px;
  color: var(--ink-muted);
}
.pot-payout-card {
  background: var(--bg-surface);
  border: 1.5px solid var(--line-strong);
  border-radius: var(--radius-lg);
  padding: 14px 16px;
}
.pot-payout-closed {
  display: flex;
}
.pot-payout-closed .pot-payout-open {
  width: 100%;
}
.pot-payout-method {
  margin-top: 12px;
}
.pot-payout-method button,
.settle-record-method button {
  min-height: 44px;
}
.pot-movement-time {
  color: var(--ink-faint);
  font-size: 12.5px;
}
.pot-movement-out {
  color: var(--ink);
}
.pot-list-back {
  color: var(--ink-muted);
  font-size: 12.5px;
}

/* task-ai R1: @trippy. The answer is its own bubble — Trippy's avatar and
   name over an accent-tinted surface. A private question or answer is
   visibly private: a dashed border, a lock, "Only you can see this". */
.trippy-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: #fff;
}
.trippy-head {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0 0 4px 2px;
  font-size: 12px;
}
.trippy-name {
  font-weight: 600;
  color: var(--accent-hover);
}
.trippy-quick {
  font-size: 11px;
  color: var(--ink-muted);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  padding: 1px 8px;
}
.trippy-answer {
  max-width: 88%;
}
.bubble-in .bubble.trippy-bubble {
  background: var(--accent-subtle);
  border: 1px solid var(--accent-subtle-line);
  white-space: pre-line;
}
.trippy-thinking {
  color: var(--ink-muted);
  font-style: italic;
}
.trippy-private .bubble,
.bubble-in.trippy-private .bubble.trippy-bubble {
  border: 1.5px dashed var(--line-strong);
}
.bubble-out.trippy-private .bubble {
  background: var(--fill-subtle);
  color: var(--ink);
  border-color: var(--ink-faint);
}
.trippy-foot {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 12px;
  margin-top: 2px;
}
.trippy-private-note {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  color: var(--ink-muted);
  margin: 3px 4px 0;
}
.bubble-out .trippy-private-note {
  align-self: flex-end;
}
.btn-link {
  min-height: 44px;
  padding: 0 4px;
  border: none;
  background: transparent;
  color: var(--accent);
  font-family: var(--body);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.btn-link:disabled {
  opacity: 0.5;
  cursor: default;
}
.trippy-visibility {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0 0 8px;
  font-size: 12px;
  color: var(--ink-muted);
}
.trippy-visibility button {
  min-height: 44px;
  padding: 0 14px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line-strong);
  background: var(--bg-surface);
  color: var(--ink);
  font-family: var(--body);
  font-size: 13px;
  cursor: pointer;
}
.trippy-visibility button[aria-pressed="true"] {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--bg-ground);
}
/* task-ai R1b: a tagged member, as a chip in the bubble. */
.mention-chip {
  display: inline;
  padding: 0 5px;
  border-radius: 6px;
  background: var(--accent-subtle);
  color: var(--accent-hover);
  font-weight: 600;
  text-decoration: none;
}
.bubble-out .mention-chip {
  background: rgba(255, 255, 255, 0.16);
  color: var(--bg-ground);
}
.bubble-out.trippy-private .mention-chip {
  background: var(--accent-subtle);
  color: var(--accent-hover);
}
.trippy-intro {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--accent-subtle-line);
  border-radius: var(--radius-md);
  background: var(--accent-subtle);
  color: var(--ink-muted);
  font-size: 13px;
  line-height: 1.45;
}
.trippy-intro p {
  margin: 0;
}
/* task-ai R1b: the @ list, anchored above the input. */
.mention-field {
  position: relative;
  flex-grow: 1;
  min-width: 0;
  display: flex;
}
.mention-field .composer-input {
  flex-grow: 1;
  min-width: 0;
}
.mention-list {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(100% + 6px);
  z-index: 20;
  margin: 0;
  padding: 4px;
  list-style: none;
  max-height: 264px;
  overflow-y: auto;
  background: var(--bg-surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
}
.mention-option {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 6px 10px;
  border-radius: var(--radius-xs);
  cursor: pointer;
}
.mention-option-active {
  background: var(--fill-subtle);
}
.mention-initial {
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-pill);
  background: var(--fill-subtle);
  border: 1px solid var(--line);
  color: var(--ink);
  font-weight: 600;
  font-size: 13px;
}
.mention-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.mention-name {
  font-size: 14px;
  font-weight: 500;
}
.mention-sub {
  font-size: 12px;
  color: var(--ink-muted);
}

/* task-ai R5: a draft the offline reader made says so, quietly. */
.draft-sheet-note {
  margin: 0 0 8px;
  font-size: 13px;
  color: var(--ink-muted);
}
.draft-sheet-reasons {
  margin: 0 0 10px;
  padding: 8px 12px;
  list-style: none;
  border-radius: var(--radius-sm);
  background: var(--accent-subtle);
  border: 1px solid var(--accent-subtle-line);
  color: var(--ink);
  font-size: 13px;
  line-height: 1.4;
}
.draft-sheet-reasons li + li {
  margin-top: 4px;
}

/* "New messages" — shown when something arrives while you are reading
   further up; tapping it scrolls to the latest. */
.app-frame {
  position: relative;
}

.jump-latest {
  position: absolute;
  left: 50%;
  bottom: 88px;
  transform: translateX(-50%);
  z-index: 5;
  min-height: 44px;
  padding: 0 18px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--bg-surface);
  color: var(--accent);
  font-family: var(--body);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
}

/* ==== task-threads: Slack-like threads (R1/R3) ==========================
   Tokens only. A card with a thread gets a foot: the reply count with
   the repliers' initials, or "Reply in thread" — a hover action on a
   pointer device, a small visible button on a phone. The panel is a
   column beside the Room from 1100px (the Room keeps its column), an
   overlay panel at 768–1099, a full-height sheet below 768. */
.threaded {
  display: flex;
  flex-direction: column;
  gap: 4px;
  border-radius: var(--radius-sm);
}

.threaded-active {
  outline: 2px solid var(--accent-subtle-line);
  outline-offset: 3px;
}

.threaded-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
}

.bubble-out + .threaded-foot,
.threaded > .bubble-out ~ .threaded-foot {
  justify-content: flex-end;
}

.thread-summary,
.thread-reply-btn,
.thread-why {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 0 10px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--accent);
  font-family: var(--body);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}

.thread-summary:hover,
.thread-reply-btn:hover,
.thread-why:hover {
  background: var(--accent-subtle);
  border-color: var(--accent-subtle-line);
}

.thread-summary:focus-visible,
.thread-reply-btn:focus-visible,
.thread-why:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.thread-summary-last {
  color: var(--ink-muted);
  font-weight: 400;
}

.thread-avatars {
  display: inline-flex;
}

.thread-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  border: 1.5px solid var(--bg-ground);
  background: var(--fill-subtle);
  color: var(--ink);
  font-size: 10px;
  font-weight: 600;
}

.thread-avatar + .thread-avatar {
  margin-left: -6px;
}

.thread-avatar-trippy {
  background: var(--accent-subtle);
  color: var(--accent);
}

.thread-unread-dot {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: var(--accent);
}

.thread-reply-btn {
  color: var(--ink-muted);
  font-weight: 500;
}

.thread-reply-long {
  display: none;
}

.thread-why {
  color: var(--ink-muted);
  font-weight: 500;
}

/* Desktop with a pointer: "Reply in thread" shows on hover or focus. */
@media (min-width: 768px) and (hover: hover) {
  .thread-reply-long {
    display: inline;
  }
  .thread-reply-short {
    display: none;
  }
  .threaded .thread-reply-btn {
    opacity: 0;
  }
  .threaded:hover .thread-reply-btn,
  .threaded:focus-within .thread-reply-btn {
    opacity: 1;
  }
}

/* --- The panel ---------------------------------------------------------- */
.room-split {
  display: flex;
  width: 100%;
  height: 100%;
  min-width: 0;
}

.room-split > .app-frame {
  flex: 1 1 auto;
  min-width: 0;
}

.thread-panel {
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--bg-ground);
}

.thread-panel-room {
  position: fixed;
  inset: 0;
  z-index: 60;
  animation: thread-in 180ms ease-out;
}

.thread-scrim {
  display: none;
}

.thread-head {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 60px;
  padding: 8px 8px 8px 20px;
  background: var(--bg-surface);
  border-bottom: 1px solid var(--line);
}

.thread-head-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.thread-title {
  margin: 0;
  font-family: var(--display);
  font-size: 18px;
  font-weight: 600;
  color: var(--ink);
}

.thread-meta {
  font-size: 12.5px;
  color: var(--ink-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.thread-follow {
  min-height: 44px;
  padding: 0 12px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line);
  background: var(--bg-surface);
  color: var(--ink);
  font-family: var(--body);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}

.thread-follow[aria-pressed="true"] {
  border-color: var(--accent-subtle-line);
  background: var(--accent-subtle);
  color: var(--accent);
}

.thread-close {
  min-width: 44px;
  min-height: 44px;
}

.thread-stream {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 14px 16px 8px;
  display: flex;
  flex-direction: column;
  gap: 9px;
}

.thread-stream > * {
  flex-shrink: 0;
}

.thread-divider {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--ink-muted);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.thread-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}

.thread-also,
.thread-private-note {
  font-size: 11.5px;
  color: var(--ink-muted);
}

.thread-private-note {
  margin: 0 0 6px;
}

.thread-foot {
  flex-shrink: 0;
  background: var(--bg-surface);
  border-top: 1px solid var(--line);
  padding: 9px 16px calc(12px + env(safe-area-inset-bottom, 0px));
}

.thread-also-send {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  font-size: 13px;
  color: var(--ink-muted);
  cursor: pointer;
}

.thread-also-send input {
  width: 18px;
  height: 18px;
  accent-color: var(--accent);
}

/* 768–1099: an overlay panel on the right, over a scrim. */
@media (min-width: 768px) {
  .thread-panel-room {
    left: auto;
    width: min(420px, 100%);
    border-left: 1px solid var(--line);
  }
  .thread-scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 59;
    border: 0;
    padding: 0;
    background: var(--scrim);
    cursor: pointer;
  }
}

/* From 1100: a column beside the Room. The Room keeps its content column
   (its frame never goes below the column plus gutters); the thread takes
   what is left, 320–420px. */
@media (min-width: 1100px) {
  .room-split > .app-frame {
    flex: 1 0 calc(var(--col, 640px) + 32px);
  }
  .thread-panel-room {
    position: static;
    inset: auto;
    z-index: auto;
    flex: 0 1 420px;
    min-width: 320px;
    width: auto;
    animation: none;
  }
  .thread-scrim {
    display: none;
  }
}

@keyframes thread-in {
  from {
    transform: translateX(24px);
    opacity: 0;
  }
  to {
    transform: none;
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .thread-panel-room {
    animation: none;
  }
}

/* The Ask screen and global Trippy: the thread list beside (or above)
   the open thread. */
.trippy-threads {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.trippy-thread-link {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  width: 100%;
  min-height: 44px;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--bg-surface);
  color: var(--ink);
  font-family: var(--body);
  text-align: left;
  cursor: pointer;
}

.trippy-thread-link[aria-current="true"] {
  border-color: var(--accent-subtle-line);
  background: var(--accent-subtle);
}

.trippy-thread-title {
  font-size: 14px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

.trippy-thread-sub {
  font-size: 12px;
  color: var(--ink-muted);
}

.trippy-threads-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.ask-layout {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.ask-layout > .thread-panel-page {
  flex: 1;
  min-height: 0;
}

.ask-list {
  padding: 12px 16px;
  overflow-y: auto;
}

@media (min-width: 1100px) {
  .ask-layout {
    flex-direction: row;
  }
  .ask-list {
    width: 300px;
    flex-shrink: 0;
    border-right: 1px solid var(--line);
  }
}
/* ==== end task-threads ================================================= */
/* task-threads: the Ask screen below 1100 shows the list or the open
   thread, not both; "All questions" goes back to the list. */
.thread-back {
  min-height: 44px;
  white-space: nowrap;
}
@media (max-width: 1099.98px) {
  .ask-layout[data-open="false"] > .thread-panel-page {
    display: none;
  }
  .ask-layout[data-open="true"] > .ask-list {
    display: none;
  }
}
@media (min-width: 1100px) {
  .thread-back {
    display: none;
  }
}
/* task-threads (after the live look): the list sits below the intro, its
   button its own size; on a pointer device the hover "Reply in thread"
   floats over the card's corner instead of holding open a 44px row. */
.ask-list > .trippy-threads {
  margin-top: 12px;
}
.trippy-threads-head .btn-secondary {
  flex-grow: 0;
  padding: 0 16px;
}
@media (min-width: 768px) and (hover: hover) {
  .threaded {
    position: relative;
  }
  .threaded .thread-reply-btn {
    position: absolute;
    top: -18px;
    right: 10px;
    z-index: 2;
    background: var(--bg-surface);
    border-color: var(--line);
  }
  .threaded-foot:not(:has(.thread-summary, .thread-why)) {
    display: contents;
  }
}
