/* ==========================================================================
   Black Cambry 2026 — Expenses View (Slice C)
   --------------------------------------------------------------------------
   Per-view stylesheet for the Expenses route (`#expenses`). Loaded AFTER
   components.css so view-scoped rules can layer on top of the canonical
   primitives (`.cambry-card`, `.cambry-input`, `.cambry-fab`,
   `.cambry-loading`, `.cambry-error`, `.cambry-empty`) without
   redeclaring any selector-and-property pair already defined there
   (Req 15.5).

   Sections:
     - Money_Workflow_Header strip — shared header used by both
       `#expenses` and `#payments`; rules are intentionally inline here
       (and will be duplicated into payments.css when Slice G ships)
       until both views are deployed and we can decide whether to
       migrate to components.css per Req 15.5.
     - View shell (.expenses-view)
     - Trip_Dashboard summary tiles (Total_Spend / Your_Share / Your_Balance)
     - Spend_By_Category bars
     - Filter strip (My / All / Outstanding)
     - Expense_Card list — `.cambry-card` variant; only layout glue here
     - Member_Chip row — chip primitives prefilled here so Slice D / E
       have nothing CSS-side to add
     - Activity_Feed — prefilled here so Slice F has nothing CSS-side
       to add

   Tokens consumed (defined in styles.css :root):
     --color-bg          #1f2c38   slate background
     --color-surface     #2a3a4a   card chrome, one step lighter than bg
     --color-primary     #3a526a   chip/button base
     --color-accent      #f896ff   soft pink accent
     --color-accent-hover #ffb1ff  lighter pink for :hover
     --color-on-accent   #1f2c38   dark text for accent fills
     --color-text        #e8edf0   body copy on slate
     --color-text-muted  #a6b7bf   secondary text
     --color-error       #ff8aa1   warning / "you owe" tone
     --color-success     #7fd197   inline-success tone

   Typography: Yantramanav (loaded in index.html).
   Requirements covered: 1.1, 1.4, 1.5, 1.7, 1.8, 6.1, 6.2, 7.1, 7.4,
                         7.5, 7.6, 7.7, 15.1, 15.2, 15.3, 15.5, 16.1,
                         16.3, 16.5
   ========================================================================== */

/* --------------------------------------------------------------------------
   Money_Workflow_Header strip (Req 15.3)
   --------------------------------------------------------------------------
   Shared header rendered at the top of both `#expenses` and `#payments`.
   The rules live in expenses.css for Slice C; payments.css will
   duplicate them in Slice G. Once both views ship we can decide whether
   to migrate the rules into components.css per the two-view threshold
   in Req 15.5.

   The status-pill slot (`.money-workflow-header__status`) reuses the
   existing `.status-badge` rule from trip_detail.css — JS emits the
   element with both classes so the visual treatment carries over
   without redeclaring its visual properties here.
   -------------------------------------------------------------------------- */
.money-workflow-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 1rem 0 0.75rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  margin-bottom: 1.25rem;
}

.money-workflow-header__title {
  font-family: 'Yantramanav', sans-serif;
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--color-text);
  letter-spacing: 0.01em;
  margin: 0;
  /* Allow long trip names to truncate so the nav pill stays visible. */
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Status-pill slot — layout glue only. Visual treatment (background,
   border-radius, uppercase, padding) comes from `.status-badge` in
   trip_detail.css; the JS emits the element with
   `class="money-workflow-header__status status-badge"` so the existing
   rule applies without re-declaring its properties here (Req 15.5). */
.money-workflow-header__status {
  flex-shrink: 0;
}

/* Test-trip pill — sits next to the status pill so admins operating
   in a test trip never confuse it with the real one. Soft-pink Cambry
   accent so it reads as a semantic flag rather than a status mutation.
   Layout-only here; the visual idiom (radius, padding, font sizing)
   matches the .status-badge from trip_detail.css for a consistent
   pill row. */
.money-workflow-header__test-pill {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
  background-color: var(--color-accent);
  color: var(--color-on-accent);
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: help;
}

/* The two-button nav pill container — pill-shaped wrapper holding two
   nav buttons side by side. The 8 px row-gap meets Req 16.3 when the
   row wraps. */
.money-workflow-header__nav {
  display: inline-flex;
  align-items: center;
  gap: 0; /* segments share an edge; the buttons themselves carry their
             own borders / fills so the pair reads as one segmented control */
  padding: 0.25rem;
  background-color: var(--color-surface);
  border-radius: 999px;
  flex-shrink: 0;
}

.money-workflow-header__nav-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Bounding rect ≥ 1936 px² with no dimension below 32 px (Req 16.1):
     min-height 44 px × default label width (~80 px) easily clears the
     area threshold. */
  min-width: 88px;
  min-height: 44px;
  padding: 0.55rem 1.1rem;
  border: none;
  border-radius: 999px;
  background-color: transparent;
  color: var(--color-text-muted);
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  text-decoration: none;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.money-workflow-header__nav-button:hover:not(:disabled) {
  color: var(--color-text);
}

.money-workflow-header__nav-button:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.money-workflow-header__nav-button--active {
  background-color: var(--color-accent);
  color: var(--color-on-accent);
}

.money-workflow-header__nav-button--active:hover:not(:disabled) {
  background-color: var(--color-accent-hover);
  color: var(--color-on-accent);
}

/* --------------------------------------------------------------------------
   View shell
   --------------------------------------------------------------------------
   Vertical stack of dashboard sections; bottom padding clears the
   Floating_Action_Pill that mounts to <body> from
   `renderFloatingActionPill` (the pill itself is styled by .cambry-fab
   in components.css — we do not redeclare it here).
   -------------------------------------------------------------------------- */
.expenses-view {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  padding: 1.25rem 1rem 6rem;
  max-width: 1200px;
  margin: 0 auto;
  width: 100%;
}

/* --------------------------------------------------------------------------
   Trip_Dashboard summary tiles (Req 1.1, 16.5)
   --------------------------------------------------------------------------
   Three-tile row: Total_Spend, Your_Share, Your_Balance.
     - viewport ≥ 600 px: single horizontal row (3 columns)
     - viewport <  600 px: three stacked rows
   Mobile-first default uses `flex-direction: column`; the @media block
   flips to `row` at the breakpoint.
   -------------------------------------------------------------------------- */
.expenses-summary {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

@media (min-width: 600px) {
  .expenses-summary {
    flex-direction: row;
  }

  .expenses-summary__tile {
    /* Each tile takes an equal share of the row; min-width: 0 prevents
       long values from blowing out the grid on narrow tablets. */
    flex: 1 1 0;
    min-width: 0;
  }
}

.expenses-summary__tile {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 1rem 1.1rem;
  background-color: var(--color-surface);
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
}

.expenses-summary__label {
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.7rem;
  font-weight: 500;
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin: 0;
}

.expenses-summary__value {
  font-family: 'Yantramanav', sans-serif;
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--color-text);
  line-height: 1.15;
  margin: 0;
  /* Long base-currency totals (e.g. JPY without decimal places) can
     overflow; let them truncate gracefully. */
  overflow-wrap: anywhere;
}

/* "You're owed" treatment — Req 1.4. Soft pink accent. */
.expenses-summary__balance--owed {
  color: var(--color-accent);
}

/* "You owe" treatment — Req 1.5. Warning hue (`--color-error` is the
   only warning-tone token in styles.css; it's a desaturated pink-red
   that is visually distinct from the soft pink accent). */
.expenses-summary__balance--owe {
  color: var(--color-error);
}

/* --------------------------------------------------------------------------
   Spend_By_Category bars (Req 1.7)
   --------------------------------------------------------------------------
   One row per category, sorted by descending base-currency total.
   Each row reads `Label  ━━━━━━━  Amount` with the bar between the
   label and amount scaled to that category's share of total spend.
   The bar's width is set inline (`style="width: NN%"`) by the JS so
   we only need the chassis here.
   -------------------------------------------------------------------------- */
.expenses-spend-by-category {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 1rem;
  background-color: var(--color-surface);
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
}

.expenses-spend-by-category__row {
  display: grid;
  grid-template-columns: minmax(6rem, 8rem) 1fr minmax(4rem, auto);
  align-items: center;
  gap: 0.75rem;
}

.expenses-spend-by-category__label {
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--color-text);
  /* Truncate long category names rather than break the row layout. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.expenses-spend-by-category__bar {
  /* Track + filled bar in one element. The accent fill is painted via
     a linear-gradient capped at the inline width, so JS only sets the
     `width` style — no per-category color logic needed. */
  height: 8px;
  border-radius: 999px;
  background-color: var(--color-primary);
  position: relative;
  overflow: hidden;
}

.expenses-spend-by-category__bar::before {
  content: '';
  position: absolute;
  inset: 0;
  background-color: var(--color-accent);
  border-radius: inherit;
  /* The JS sets `--bar-fill: NN%` via inline style on the row's bar
     element; default to 0 so an unset bar reads as empty rather than
     full. */
  width: var(--bar-fill, 0%);
}

.expenses-spend-by-category__amount {
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--color-text);
  text-align: right;
  /* Tabular-nums keeps the right edge of the column aligned across
     rows even when amounts have different glyph widths. */
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   Filter strip — My expenses / All / Outstanding (Req 7.7)
   --------------------------------------------------------------------------
   Three pills in a horizontal row. The active pill rides the soft pink
   `--color-accent` fill so the user can see which filter is applied at
   a glance. Bounding rect ≥ 1936 px² (44 × 44 minimum) and 8 px gap
   between adjacent pills (Req 16.1 / 16.3).
   -------------------------------------------------------------------------- */
.expenses-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem; /* 8 px — adjacent-control separation per Req 16.3 */
}

.expenses-filter__pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 88px;
  min-height: 44px;
  padding: 0.55rem 1.1rem;
  border: 1px solid var(--color-primary);
  border-radius: 999px;
  background-color: transparent;
  color: var(--color-text-muted);
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease,
              border-color 0.15s ease;
}

.expenses-filter__pill:hover:not(:disabled) {
  color: var(--color-text);
  border-color: var(--color-accent);
  background-color: rgba(248, 150, 255, 0.08);
}

.expenses-filter__pill:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}

.expenses-filter__pill--active {
  background-color: var(--color-accent);
  color: var(--color-on-accent);
  border-color: var(--color-accent);
}

.expenses-filter__pill--active:hover:not(:disabled) {
  background-color: var(--color-accent-hover);
  border-color: var(--color-accent-hover);
  color: var(--color-on-accent);
}

/* --------------------------------------------------------------------------
   Expense_Card list (Req 7.1, 7.4–7.6)
   --------------------------------------------------------------------------
   The list container and a `.cambry-card` variant — `.expenses-card` —
   that adds expense-row layout (leading thumb slot, body, trailing
   split-status pill) without redeclaring `.cambry-card`'s base
   properties (background, border-radius, padding, box-shadow). The
   card markup is `class="cambry-card expenses-card"`.

   Per Req 15.5, ANY selector-and-property pair that already lives in
   components.css (`.cambry-card { background, border-radius, padding,
   box-shadow }`) is NOT repeated here.
   -------------------------------------------------------------------------- */
.expenses-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.6rem; /* 8 px+ between adjacent cards (Req 16.3) */
}

/* Layout glue ON TOP of `.cambry-card` — does NOT redeclare base
   properties. The cambry-card sets `flex-direction: column` already;
   we override to row here so the card reads `[thumb] [body] [status]`
   horizontally on every viewport, with the body column flexing. */
.expenses-card {
  flex-direction: row;
  align-items: center;
  gap: 0.85rem;
  cursor: pointer;
}

.expenses-card__thumb {
  /* 64 × 64 leading slot. Used for the receipt thumbnail (Slice I) and
     the category-glyph fallback (this slice). The slot is fixed-width
     so the body column has predictable width regardless of whether the
     thumbnail loaded. */
  flex-shrink: 0;
  width: 64px;
  height: 64px;
  border-radius: 8px;
  background-color: var(--color-surface);
  /* Center children (img or glyph span) inside the slot. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

/* Modifier when the slot is a category-glyph (no thumbnail). The
   glyph span sits centered; size/styling of the span itself is up to
   the JS. */
.expenses-card__thumb--icon {
  background-color: var(--color-primary);
  color: var(--color-text-muted);
  font-size: 1.5rem;
  line-height: 1;
}

/* Slice I — Req 7.2 / 7.3. Style the <img> mounted inside the 64×64
   leading slot. ``object-fit: cover`` lets non-square thumbnails
   crop-fill the box without distortion; the parent's
   ``border-radius`` + ``overflow: hidden`` round the visual corners.
   The full-receipt fallback (Req 7.3) reuses this rule — same 64 px
   container, same crop. */
.expenses-card__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.expenses-card__base-amount {
  /* Slice H — Req 10.9. Secondary base-currency annotation rendered
     adjacent to the original-currency primary value on the card's
     meta line when the expense's currency differs from the trip's
     base_currency. Smaller font + muted color so the original
     amount remains the dominant figure; the parenthesised base
     equivalent reads as supplementary context. */
  font-size: 0.85em;
  color: var(--color-text-muted);
  white-space: nowrap;
}

.expenses-card__split-status {
  /* Trailing inline indicator — "Split: 4 people" / "you owe X" /
     "owed X". A pill chassis matches the filter strip but at smaller
     scale. Bounding rect intentionally below the 44 px tap target —
     the parent .expenses-card carries the full hit area; this pill
     is a non-interactive visual glyph. */
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  padding: 0.25rem 0.6rem;
  border-radius: 999px;
  background-color: var(--color-primary);
  color: var(--color-text);
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

/* Modifier applied when the user taps a card to expand it inline
   (Req 7.6). Inline-expanded variant: switch to column layout so the
   per-row split breakdown can stack below the header. The accent ring
   is painted via box-shadow so the card geometry doesn't shift when
   the modifier is added (mirrors `.cambry-card--active`'s pattern in
   components.css). */
.expenses-card--expanded {
  flex-direction: column;
  align-items: stretch;
  cursor: default;
  box-shadow:
    inset 0 0 0 2px var(--color-accent),
    0 2px 8px rgba(0, 0, 0, 0.25);
}

/* Slice I — Req 7.6. The 240 CSS-pixel receipt thumbnail rendered
   inside the inline expansion. ``object-fit: contain`` (vs the
   leading slot's ``cover``) preserves the entire receipt's aspect
   ratio so users can read the full image without cropping. The
   ``max-width / max-height`` pair enforces the 240 px ceiling on
   the longer edge while letting portrait or landscape receipts
   shrink to fit the shorter edge naturally. */
.expenses-card__expansion-thumb {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  max-width: 240px;
  max-height: 240px;
  border-radius: 8px;
  background-color: var(--color-surface);
  overflow: hidden;
}

.expenses-card__expansion-thumb img {
  max-width: 240px;
  max-height: 240px;
  object-fit: contain;
  display: block;
}

/* Glyph variant — used when both ``receipt_thumbnail_s3_key`` and
   ``receipt_s3_key`` are null. The visual is a 240×240 box carrying
   the upscaled category emoji so the expansion still has a
   leading visual anchor. */
.expenses-card__expansion-thumb--icon {
  width: 240px;
  height: 240px;
  background-color: var(--color-primary);
  color: var(--color-text-muted);
  font-size: 6rem;
  line-height: 1;
}

/* Per-participant split breakdown rendered inside the Expense_Card
   expansion (Req 7.6). Lists each split participant on its own row
   with their share formatted in the trip's base currency. The payer
   row carries an inline ``(payer)`` suffix so the user reads the
   responsibility chain at a glance. The list is wrapped in a small
   surface block so it reads as a discrete section under the receipt
   thumbnail. */
.expenses-card__expansion-breakdown {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.85rem 1rem;
  background-color: var(--color-surface);
  border-radius: 8px;
}

.expenses-card__expansion-heading {
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin: 0;
}

.expenses-card__expansion-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.expenses-card__expansion-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.9rem;
  font-weight: 400;
  line-height: 1.3;
  color: var(--color-text);
}

/* Small inline avatar to the left of the participant's name in the
   breakdown row. Reuses the shared ``.cambry-avatar`` chassis (so the
   typography for the placeholder letter is inherited) and downsizes
   the bounding rect to ~28 px so the breakdown reads as denser than
   the Settle_Up_View's row-level avatars. We do NOT redeclare
   ``.cambry-avatar`` properties here per Req 15.5 — the chassis lives
   in components.css; this rule is layout glue only. */
.expenses-card__expansion-row-avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  flex-shrink: 0;
  /* Center the placeholder letter / spinner inside the smaller
     bounding rect (the chassis sets inline-flex centering at the
     larger sizes elsewhere; doing it here means the chassis at
     this size still reads consistent). */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background-color: var(--color-primary);
  color: var(--color-text);
  font-size: 0.8rem;
  font-weight: 700;
  text-transform: uppercase;
  user-select: none;
  /* Subtle border so the avatar circle reads cleanly against the
     surrounding card surface. */
  border: 1px solid rgba(255, 255, 255, 0.08);
  overflow: hidden;
}

.expenses-card__expansion-row-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
  display: block;
}

.expenses-card__expansion-name {
  /* Truncate long roster names rather than break the row layout. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.expenses-card__expansion-amount {
  flex-shrink: 0;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--color-text);
}

/* --------------------------------------------------------------------------
   Member_Chip row (Req 4.6, 4.7, 16.1, 16.3)
   --------------------------------------------------------------------------
   Horizontal scrolling row of avatar+name chips used in the
   Add_Expense_Sheet's split row and in the Settle_Up_View's
   debtor/creditor avatars. Pre-filled here so Slice D / E / G have
   nothing CSS-side to add.

   Tap-target: every chip's bounding rectangle is at least 1936 px²
   with no dimension below 32 px (Req 16.1). Adjacent chips are
   separated by at least 8 px (Req 16.3).
   -------------------------------------------------------------------------- */
.member-chip-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem; /* 8 px — Req 16.3 */
  padding: 0.25rem 0;
  /* Allow horizontal scrolling on overflow without truncating chips. */
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.member-chip {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  /* Bounding rect ≥ 1936 px² with no dimension below 32 px (Req 16.1).
     44 × 44 satisfies both bounds with margin to spare. */
  min-width: 44px;
  min-height: 44px;
  padding: 0.4rem 0.6rem;
  border: 1px solid transparent;
  border-radius: 12px;
  background-color: var(--color-surface);
  color: var(--color-text);
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.8rem;
  font-weight: 500;
  cursor: pointer;
  user-select: none;
  transition: background-color 0.15s ease, box-shadow 0.15s ease,
              border-color 0.15s ease;
}

.member-chip:hover:not(:disabled) {
  background-color: rgba(248, 150, 255, 0.08);
  border-color: var(--color-accent);
}

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

/* Selected treatment — pink ring, painted via box-shadow so the chip
   geometry is unchanged when the modifier toggles on/off. */
.member-chip--selected {
  box-shadow: 0 0 0 2px var(--color-accent);
}

/* Layout glue ONLY for the avatar slot inside a chip. The avatar's
   own size, border-radius, and image-fit rules live in components.css
   under `.cambry-avatar` (or will, when the shared primitive is
   added); we do not redeclare them here per Req 15.5. The markup is
   `class="cambry-avatar member-chip__avatar"`. */
.member-chip__avatar {
  margin-bottom: 0.3rem;
}

/* --------------------------------------------------------------------------
   Activity_Feed (Req 6.1, 6.2)
   --------------------------------------------------------------------------
   Pre-filled here so Slice F has nothing CSS-side to add. Renders a
   chronological list of expense_added / payment_recorded items below
   the expense list.
   -------------------------------------------------------------------------- */
.activity-feed {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.activity-item {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.65rem 0.85rem;
  background-color: var(--color-surface);
  border-radius: 8px;
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.9rem;
  font-weight: 400;
  line-height: 1.4;
  color: var(--color-text);
  /* Left border tinted per item kind, painted via the modifier rules
     below so the base item reads neutral when no modifier is applied. */
  border-left: 3px solid var(--color-primary);
}

/* Expense-added items use the soft pink accent on the left border so
   "money was committed" reads with a matching visual weight to the
   accent treatment elsewhere in the dashboard. */
.activity-item--expense {
  border-left-color: var(--color-accent);
}

/* Payment-recorded items use the success tone since a recorded
   payment is "settling done" — visually distinct from new spend. */
.activity-item--payment {
  border-left-color: var(--color-success);
}

.activity-item__timestamp {
  flex-shrink: 0;
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--color-text-muted);
  letter-spacing: 0.01em;
  white-space: nowrap;
}

/* "Show all" affordance rendered below the truncated list when more
   than 25 items exist (Slice F — Q6 / Req 8.3). Pill-shaped ghost
   button using the soft pink accent token to match the filter strip
   and the receipt retake button. The bounding rectangle satisfies
   Req 16.1 (≥ 1936 px², ≥ 32 px on every dimension) — 44 × 88 here
   matches the filter pill geometry. */
.activity-feed__show-all {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 88px;
  min-height: 44px;
  margin-top: 0.5rem;
  padding: 0.55rem 1.1rem;
  background-color: transparent;
  color: var(--color-accent);
  border: 1px solid var(--color-accent);
  border-radius: 999px;
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.9rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.activity-feed__show-all:hover:not(:disabled) {
  background-color: rgba(248, 150, 255, 0.08);
  color: var(--color-accent-hover);
  border-color: var(--color-accent-hover);
}

.activity-feed__show-all:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}

/* --------------------------------------------------------------------------
   Add_Expense_Sheet (Slice D — Req 2.2, 2.4, 2.5, 3.7, 4.1, 16.4)
   --------------------------------------------------------------------------
   Native ``<dialog>``-based sheet rendered by ``openAddExpenseSheet`` in
   ``expenses.js``. The JS applies BOTH ``.add-expense-sheet--mobile`` AND
   ``.add-expense-sheet--modal`` modifiers at all times; the media queries
   below decide which set of rules wins per viewport (Req 16.4 / Q9):

     - ``@media (max-width: 899px)`` — full-screen sheet, safe-area padded
     - ``@media (min-width: 900px)`` — centered 600 px modal

   Sheet structure (selectors below match exactly the markup emitted by
   ``buildSheetMarkup`` / ``buildStep1`` / ``buildStep2`` / ``buildStep3``
   / ``buildActionsFooter`` / ``mountReceiptCapture`` in ``expenses.js``):

     .add-expense-sheet                — root <dialog>
     .add-expense-sheet__header        — sticky-style title bar
     .add-expense-sheet__title         — title text
     .add-expense-sheet__close         — × close button
     .add-expense-sheet__body          — scrollable content area
     .add-expense-sheet__step          — one of the three vertical steps
     .add-expense-sheet__step-label    — small label above each step
     .add-expense-sheet__field         — generic field row
     .add-expense-sheet__field-label   — label above each input
     .add-expense-sheet__field-error   — inline validation error text
     .add-expense-sheet__field--invalid — input-error modifier
     .add-expense-sheet__field--auto-filled — OCR-prefilled hint (Req 3.5)
     .add-expense-sheet__actions       — sticky footer
     .add-expense-sheet__submit        — primary submit pill
     .add-expense-sheet__cancel        — secondary cancel button
     .add-expense-sheet__payer-name    — payer indicator name span
     .add-expense-sheet__payer-change  — Change-payer ghost button

   Receipt capture region (Req 2.2 / 2.4 / 2.5):
     .add-expense-sheet__receipt           — wrapper
     .add-expense-sheet__capture           — primary capture tile
     .add-expense-sheet__capture-icon      — icon at center of tile
     .add-expense-sheet__capture-label     — label below the icon
     .add-expense-sheet__capture--has-preview — compact post-capture mode
     .add-expense-sheet__no-receipt        — secondary "no receipt" pill
     .add-expense-sheet__preview           — captured-image container
     .add-expense-sheet__preview-image     — the <img> itself
     .add-expense-sheet__retake            — Retake control
     .add-expense-sheet__upload-status     — inline upload-and-OCR status

   OCR_Confidence_Indicator (Req 3.7 — escalating attention as confidence
   drops):
     .ocr-pill          — base
     .ocr-pill--high    — green-ish (low-key)
     .ocr-pill--medium  — amber-ish (warning)
     .ocr-pill--low     — pink/red-ish (attention)

   Constraints:
     - All interactive controls satisfy Req 16.1 (bounding rect ≥ 1936 px²
       with no dimension below 32 px).
     - 8 px minimum gap between adjacent controls (Req 16.3).
     - Inputs use ``.cambry-input`` from components.css; we DO NOT redeclare
       any of its base properties (Req 15.5). The
       ``.add-expense-sheet__field--invalid .cambry-input`` rule below only
       overrides ``border-color``.
     - Honors iOS safe-area insets via ``env(safe-area-inset-*)`` in the
       mobile variant.
     - Dialog body is a flex column so header / body / footer stack and the
       body region scrolls independently (Req 16.4 — mobile sheet is
       scrollable).
   -------------------------------------------------------------------------- */

/* Root dialog. ``padding: 0`` because each inner section
   (__header / __body / __actions) carries its own padding. The flex
   column gives us the header-on-top, body-scrolls, footer-pinned layout
   below. */
.add-expense-sheet {
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
  color: var(--color-text);
  padding: 0;
}

/* Backdrop dim — used by the native <dialog> when shown via
   ``dialog.showModal()``. */
.add-expense-sheet::backdrop {
  background: rgba(0, 0, 0, 0.55);
}

/* Mobile variant: full-screen sheet at viewport widths below 900 CSS
   pixels (Req 16.4 / Q9). The native <dialog>'s default centered
   ``inset`` is overridden so the sheet fills the viewport. iOS safe-
   area insets keep the controls clear of the home-indicator and the
   notch. */
@media (max-width: 899px) {
  .add-expense-sheet--mobile {
    inset: 0;
    width: 100%;
    height: 100%;
    max-width: 100%;
    max-height: 100%;
    margin: 0;
    border: 0;
    border-radius: 0;
    padding:
      env(safe-area-inset-top)
      env(safe-area-inset-right)
      env(safe-area-inset-bottom)
      env(safe-area-inset-left);
  }
}

/* Modal variant: centered 600 px modal at viewport widths at or above
   900 CSS pixels (Req 16.4 / Q9). ``margin: auto`` keeps the dialog
   centered inside its viewport-anchored containing block; the max-*
   bounds let the modal stay reachable on shorter desktops. */
@media (min-width: 900px) {
  .add-expense-sheet--modal {
    width: 600px;
    max-width: 90vw;
    max-height: 90vh;
    margin: auto;
    border-radius: 16px;
  }
}

/* ── Sheet structure ──────────────────────────────────────────────── */

/* Top bar — title on the left, close (×) on the right. The subtle
   bottom border matches the money_workflow header treatment so the
   visual chassis reads consistent across the rebuild. */
.add-expense-sheet__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.add-expense-sheet__title {
  font-family: 'Yantramanav', sans-serif;
  font-size: 1.15rem;
  font-weight: 700;
  margin: 0;
}

/* Close button — ≥ 1936 px² hit area, ≥ 32 px each dim per Req 16.1.
   The 44 × 44 minimum exceeds both bounds with margin to spare. */
.add-expense-sheet__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  background: transparent;
  border: none;
  border-radius: 8px;
  color: var(--color-text-muted);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  transition: color 0.15s ease, background-color 0.15s ease;
}

.add-expense-sheet__close:hover:not(:disabled) {
  color: var(--color-text);
  background: var(--color-surface);
}

.add-expense-sheet__close:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* Scrollable body — flex: 1 1 auto consumes the remaining space
   between the header and the actions footer; ``overflow-y: auto``
   lets the body scroll independently so the actions footer stays
   pinned at the bottom of the dialog (Req 16.4 — mobile sheet
   should be scrollable). */
.add-expense-sheet__body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 1rem 1.25rem;
}

/* One of the three vertical steps. The ``margin-bottom`` separates
   adjacent steps so the user reads them as discrete blocks. */
.add-expense-sheet__step {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-bottom: 1.5rem;
}

/* "Step 1 — What was it?" / etc. */
.add-expense-sheet__step-label {
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin: 0;
}

/* Generic field row — label on top, control underneath. */
.add-expense-sheet__field {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.add-expense-sheet__field-label {
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--color-text);
}

/* Inline validation error rendered below an input. */
.add-expense-sheet__field-error {
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.85rem;
  color: var(--color-error);
  margin: 0;
  padding: 0.35rem 0;
}

/* Modifier on a field whose input has a validation error. We override
   ONLY the ``.cambry-input`` border-color — the rest of the input's
   base properties continue to come from components.css per Req 15.5. */
.add-expense-sheet__field--invalid .cambry-input {
  border-color: var(--color-error);
}

/* Modifier on a field whose value was set by OCR (Req 3.5). The
   subtle pink left edge cues the user that the value came from the
   automated pre-fill; the modifier is removed when the user commits
   an edit on the field (Req 3.6). */
.add-expense-sheet__field--auto-filled {
  border-left: 3px solid var(--color-accent);
  padding-left: 0.6rem;
}

/* Sticky footer with the cancel + submit buttons. The top border
   echoes the header bottom border so the body region reads as a
   bounded scroll area. */
.add-expense-sheet__actions {
  display: flex;
  gap: 0.75rem;
  padding: 1rem 1.25rem;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  background: var(--color-bg);
  justify-content: flex-end;
}

/* Primary submit pill. Pink accent. ≥ 1936 px² / ≥ 32 px each dim
   per Req 16.1 — 140 × 44 satisfies the bounding-rect constraint
   without ambiguity. */
.add-expense-sheet__submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 140px;
  min-height: 44px;
  padding: 0.6rem 1.5rem;
  background: var(--color-accent);
  color: var(--color-on-accent);
  border: none;
  border-radius: 999px;
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.15s ease;
}

.add-expense-sheet__submit:hover:not(:disabled) {
  background: var(--color-accent-hover);
}

.add-expense-sheet__submit:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}

.add-expense-sheet__submit:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Secondary cancel pill — outline ghost button. */
.add-expense-sheet__cancel {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 100px;
  min-height: 44px;
  padding: 0.6rem 1.25rem;
  background: transparent;
  color: var(--color-text-muted);
  border: 1px solid var(--color-primary);
  border-radius: 999px;
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.add-expense-sheet__cancel:hover:not(:disabled) {
  color: var(--color-text);
  border-color: var(--color-accent);
}

.add-expense-sheet__cancel:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}

/* Inline payer-name span next to the "Paid by" label. */
.add-expense-sheet__payer-name {
  color: var(--color-text);
  font-weight: 500;
}

/* "Change" payer button — small ghost pill. ≥ 1936 px² / ≥ 32 px
   each dim per Req 16.1 (44 × ~88 once the label renders). */
.add-expense-sheet__payer-change {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0.4rem 0.85rem;
  background: transparent;
  color: var(--color-accent);
  border: none;
  border-radius: 8px;
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.15s ease;
}

.add-expense-sheet__payer-change:hover:not(:disabled) {
  background: var(--color-surface);
}

.add-expense-sheet__payer-change:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* ── Receipt capture region (Req 2.2 / 2.4 / 2.5) ─────────────────── */

/* Wrapper around the capture / preview / retake / no-receipt /
   upload-status children. */
.add-expense-sheet__receipt {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-bottom: 1rem;
}

/* Primary capture affordance at the top of the sheet (Req 2.2). The
   pink dashed ring + large icon + label reads as "tap me first". On
   hover the dashed ring tightens its color to the hover variant so
   the affordance feels live without shifting geometry. */
.add-expense-sheet__capture {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 140px;
  padding: 1.5rem;
  background: var(--color-surface);
  border: 2px dashed var(--color-accent);
  border-radius: 16px;
  color: var(--color-text);
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}

.add-expense-sheet__capture:hover:not(:disabled) {
  background: rgba(248, 150, 255, 0.08);
  border-color: var(--color-accent-hover);
}

.add-expense-sheet__capture:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}

.add-expense-sheet__capture-icon {
  font-size: 2rem;
  line-height: 1;
}

.add-expense-sheet__capture-label {
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.95rem;
  font-weight: 600;
}

/* Compact mode applied by ``mountReceiptCapture`` once an image is
   captured: the tile collapses to a row so the preview can sit
   alongside it. */
.add-expense-sheet__capture--has-preview {
  flex-direction: row;
  gap: 0.5rem;
  min-height: 60px;
  padding: 0.75rem;
}

.add-expense-sheet__capture--has-preview .add-expense-sheet__capture-icon {
  font-size: 1.25rem;
}

/* Secondary "I don't have a receipt" affordance — smaller ghost pill
   that sits alongside the capture tile. ``align-self: flex-start``
   keeps it from stretching to the wrapper width. */
.add-expense-sheet__no-receipt {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  align-self: flex-start;
  min-height: 44px;
  padding: 0.5rem 1rem;
  background: transparent;
  color: var(--color-text-muted);
  border: 1px solid var(--color-primary);
  border-radius: 999px;
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.85rem;
  font-weight: 500;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.add-expense-sheet__no-receipt:hover:not(:disabled) {
  color: var(--color-text);
  border-color: var(--color-text-muted);
}

.add-expense-sheet__no-receipt:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}

/* Captured-image preview container (Req 2.4) — preview image on the
   left, retake button on the right. */
.add-expense-sheet__preview {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  max-width: 100%;
}

/* The <img> itself. The longest-edge cap of 240 CSS pixels matches
   Req 2.4. ``object-fit: contain`` preserves the aspect ratio inside
   the box so portrait receipts don't stretch. */
.add-expense-sheet__preview-image {
  max-width: 240px;
  max-height: 240px;
  object-fit: contain;
  border-radius: 8px;
}

/* Retake control adjacent to the preview (Req 2.5). 44 × 88 satisfies
   Req 16.1's ≥ 1936 px² / ≥ 32 px each-dim bounds with margin. */
.add-expense-sheet__retake {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  min-width: 88px;
  padding: 0.5rem 1rem;
  background: transparent;
  color: var(--color-accent);
  border: 1px solid var(--color-accent);
  border-radius: 999px;
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.15s ease;
}

.add-expense-sheet__retake:hover:not(:disabled) {
  background: rgba(248, 150, 255, 0.08);
}

.add-expense-sheet__retake:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}

/* Inline status row shown during the upload-and-OCR fetch
   ("Uploading and reading receipt…"). */
.add-expense-sheet__upload-status {
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.85rem;
  color: var(--color-text-muted);
  padding: 0.4rem 0;
}

/* ── OCR_Confidence_Indicator (Req 3.7) ───────────────────────────── */

/* Inline pill rendered next to a prefilled field carrying
   ``OCR: high|medium|low``. The three modifiers escalate visual
   attention as confidence drops, per Req 3.7. The amber ``--medium``
   color uses the literal hex ``#f0b657`` because styles.css does not
   define a ``--color-warning`` token; revisit when the token lands. */
.ocr-pill {
  display: inline-flex;
  align-items: center;
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.ocr-pill--high {
  background: rgba(127, 209, 151, 0.18);
  color: var(--color-success);
}

.ocr-pill--medium {
  background: rgba(240, 182, 87, 0.18);
  color: #f0b657;
}

.ocr-pill--low {
  background: rgba(255, 138, 161, 0.18);
  color: var(--color-error);
}

/* --------------------------------------------------------------------------
   Slice E — Split_Mode picker, per-row inputs, Category picker
   --------------------------------------------------------------------------
   Selectors emitted by the Slice E sub-tasks 5.2 / 5.3 / 5.4 / 5.5:

     Split_Mode picker (Step 3 of the Add_Expense_Sheet):
       .split-mode-picker                    — flex container holding 4 pills
       .split-mode-picker__option            — one pill per mode
                                               (Equally / Exact / Percent / Shares)
       .split-mode-picker__option--active    — currently-selected mode

     Per-row split-amounts table (rendered for Exact / Percent / Shares):
       .split-rows-table                     — grid container (label + input)
       .split-rows-table__row                — single row inside the grid
       .split-rows-table__label              — member-name column
       .split-rows-table__input-cell         — input column wrapper
       .split-rows-table__suffix             — non-input glyph next to the input
                                               (currency code, "%", computed
                                                amount for Shares mode)
       .split-rows-table__remainder          — live remainder indicator row
       .split-rows-table__remainder--valid   — sum matches the target
       .split-rows-table__remainder--invalid — sum is under or over the target

     Category picker (Step 1 of the Add_Expense_Sheet):
       .category-picker                      — wrap-flex container of 5 chips
       .category-picker__option              — one chip per category
       .category-picker__option--active      — currently-selected category
       .category-picker__option-glyph        — leading category glyph
       .category-picker__option-label        — chip text label

   All numeric / text inputs inside the per-row table reuse
   ``.cambry-input`` from components.css — Req 15.5. The
   ``.split-rows-table__input-cell`` selector below carries layout glue
   only (column wrapper, width); the input itself is rendered as
   ``<input class="cambry-input split-rows-table__input" />`` and we
   override only ``text-align`` and a width hint on the input — both
   are properties NOT declared on ``.cambry-input`` in components.css,
   so no redeclaration occurs.

   Tap-target invariants (Req 16.1 / 16.3):
     - Every Split_Mode pill: bounding rect ≥ 1936 px² with no
       dimension below 32 px.
     - Every category chip: same bounds plus ≥ 8 px gap between
       adjacent chips.
     - Per-row inputs inherit ``.cambry-input``'s 44 px min-height so
       each input row already clears the area threshold; the
       per-row container preserves that height with ``align-items:
       center``.

   Requirements covered:
     5.1 (default-selected Equally + accent treatment),
     5.3 / 5.4 / 5.5 (per-mode row layout + remainder indicator),
     6.1 (5 category chips), 15.5 (no redeclaration of components.css
     primitives), 16.1 (≥ 1936 px² hit area), 16.3 (≥ 8 px adjacent gap).
   -------------------------------------------------------------------------- */

/* ── Split_Mode picker ──────────────────────────────────────────────── */

.split-mode-picker {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  /* 8 px gap between adjacent pills (Req 16.3). */
  gap: 0.5rem;
  /* The picker reads as one segmented control. Bottom margin separates
     it from the per-row table that renders directly below in the
     non-`equal` modes. */
  margin-bottom: 0.75rem;
}

.split-mode-picker__option {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Bounding rect ≥ 1936 px² with no dimension below 32 px (Req 16.1).
     88 × 44 satisfies both bounds. The four labels (Equally, Exact,
     Percent, Shares) all fit comfortably inside 88 px. */
  min-width: 88px;
  min-height: 44px;
  padding: 0.55rem 1.1rem;
  border: 1px solid var(--color-primary);
  border-radius: 999px;
  background-color: transparent;
  color: var(--color-text-muted);
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease,
              border-color 0.15s ease;
}

.split-mode-picker__option:hover:not(:disabled) {
  color: var(--color-text);
  border-color: var(--color-accent);
  background-color: rgba(248, 150, 255, 0.08);
}

.split-mode-picker__option:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}

/* Active pill — soft pink #f896ff fill (Req 5.1). The dark
   --color-on-accent text keeps AA contrast against the pink fill. */
.split-mode-picker__option--active {
  background-color: var(--color-accent);
  color: var(--color-on-accent);
  border-color: var(--color-accent);
}

.split-mode-picker__option--active:hover:not(:disabled) {
  background-color: var(--color-accent-hover);
  border-color: var(--color-accent-hover);
  color: var(--color-on-accent);
}

/* ── Per-row split-amounts table (Exact / Percent / Shares) ─────────── */

/* Grid container: one row per (payer + each split-with member), plus a
   final remainder-indicator row. The grid lays out:
     col 1 (1fr)     — member name label
     col 2 (auto)    — numeric input cell (input + optional suffix)
   The remainder row spans both columns. */
.split-rows-table {
  display: grid;
  grid-template-columns: 1fr auto;
  /* 8 px between adjacent rows so each row's 44 px input still clears
     Req 16.3 in the vertical axis. The horizontal column gap separates
     the label from the input. */
  row-gap: 0.5rem;
  column-gap: 0.75rem;
  align-items: center;
  margin-bottom: 0.5rem;
}

.split-rows-table__row {
  /* Row is a contents-only wrapper so the label and input cell sit
     directly on the parent grid; we only need it as a hook for
     keyboard navigation / per-row aria attributes. */
  display: contents;
}

.split-rows-table__label {
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--color-text);
  /* Long member names truncate rather than blow out the grid. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

/* Wrapper around the input + optional suffix glyph (currency code in
   Exact mode, "%" in Percent mode, computed amount in Shares mode).
   Layout glue only — the input itself uses .cambry-input. */
.split-rows-table__input-cell {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  /* Cap the input column so the labels keep their share of the row
     even with long currency suffixes. The 8rem floor keeps the
     numeric input usable on the narrowest 320 CSS-px viewport. */
  min-width: 8rem;
  max-width: 12rem;
}

/* Layout-only override on the input: right-aligned numeric content
   reads more naturally in money-row tables. ``width: 100%`` lets the
   input fill the cell so the suffix glyph sits flush against its
   trailing edge. Both properties are NOT declared on .cambry-input
   in components.css, so this is additive layout glue (Req 15.5).
   ``.cambry-input`` already declares ``width: 100%`` for its base
   chassis but this rule is harmless when the parent is a flex item
   with no width constraint of its own. */
.split-rows-table__input {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.split-rows-table__suffix {
  flex-shrink: 0;
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Live remainder indicator row — renders ``Remaining: $X.XX`` (Exact),
   ``Remaining: NN.N%`` (Percent), or hidden in Shares mode where the
   per-row computed amounts already telegraph the split. The row
   spans both grid columns. */
.split-rows-table__remainder {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  margin-top: 0.25rem;
  border-radius: 8px;
  background-color: var(--color-surface);
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.85rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* Sum matches the target — soft green so the user reads "ready to
   submit" at a glance. */
.split-rows-table__remainder--valid {
  color: var(--color-success);
  background-color: rgba(127, 209, 151, 0.12);
}

/* Sum is under- or over-allocated — pink-red warning tone matching
   the rest of the Add_Expense_Sheet's inline validation idiom. */
.split-rows-table__remainder--invalid {
  color: var(--color-error);
  background-color: rgba(255, 138, 161, 0.14);
}

/* ── Category picker (Step 1) ───────────────────────────────────────── */

/* Wrap-flex of 5 chips — Accommodation / Food & Drink / Transport /
   Activity / Other. The 8 px gap meets Req 16.3 in both axes when
   the row wraps to a second line on narrow viewports. */
.category-picker {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem; /* 8 px — Req 16.3 */
}

.category-picker__option {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  /* Bounding rect ≥ 1936 px² with no dimension below 32 px (Req 16.1).
     The min-width 88 px × min-height 44 px envelope clears 3872 px²
     before label content stretches the chip further. */
  min-width: 88px;
  min-height: 44px;
  padding: 0.5rem 0.95rem;
  border: 1px solid var(--color-primary);
  border-radius: 999px;
  background-color: transparent;
  color: var(--color-text-muted);
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease,
              border-color 0.15s ease;
}

.category-picker__option:hover:not(:disabled) {
  color: var(--color-text);
  border-color: var(--color-accent);
  background-color: rgba(248, 150, 255, 0.08);
}

.category-picker__option:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}

/* Active treatment — pink fill matching the Split_Mode picker so the
   two pickers read as a cohesive system. */
.category-picker__option--active {
  background-color: var(--color-accent);
  color: var(--color-on-accent);
  border-color: var(--color-accent);
}

.category-picker__option--active:hover:not(:disabled) {
  background-color: var(--color-accent-hover);
  border-color: var(--color-accent-hover);
  color: var(--color-on-accent);
}

/* Leading category glyph (emoji or icon char). Sits before the text
   label inside the chip; matched font-size keeps the glyph aligned on
   the chip's baseline. */
.category-picker__option-glyph {
  font-size: 1rem;
  line-height: 1;
}

.category-picker__option-label {
  white-space: nowrap;
}


/* ---------------------------------------------------------------
 * TODO #14 — Edit + Delete action row in the Expense_Card
 * expansion. Two side-by-side buttons mounted under the breakdown.
 *
 * Tap-target Req 16.1: each button is ≥ 44 × 44 (1936 px²) via
 * ``min-height: 44px`` plus ``flex: 1`` so the button stretches
 * horizontally on every viewport.
 *
 * Token notes (per the ticket spec):
 * - ``--color-border-subtle``, ``--spacing-md/sm``, ``--radius-md``,
 *   and ``--color-danger`` are not defined in components.css; the
 *   ``var(... , <fallback>)`` form gracefully resolves to the
 *   hard-coded fallback so the rule renders correctly today.
 * - ``--color-accent`` is defined in components.css and is reused
 *   here for the Edit button + focus ring.
 * --------------------------------------------------------------- */

.expenses-card__expansion-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--spacing-sm, 8px);
  padding: var(--spacing-md, 12px);
  border-top: 1px solid var(--color-border-subtle, rgba(255, 255, 255, 0.08));
}

.expenses-card__expansion-action {
  flex: 1;
  min-height: 44px;
  padding: 0 var(--spacing-md, 16px);
  border-radius: var(--radius-md, 8px);
  font: inherit;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 120ms ease, border-color 120ms ease;
}

.expenses-card__expansion-action--edit {
  background: transparent;
  border: 1px solid var(--color-accent, #f896ff);
  color: var(--color-accent, #f896ff);
}

.expenses-card__expansion-action--edit:hover {
  background: rgba(248, 150, 255, 0.08);
}

/* No --color-danger token exists in components.css today; the
   ``#ff6b6b`` fallback ships the visual treatment with no missing
   token. When a danger token gets added centrally the var() will
   pick it up automatically. */
.expenses-card__expansion-action--delete {
  background: transparent;
  border: 1px solid var(--color-danger, #ff6b6b);
  color: var(--color-danger, #ff6b6b);
}

.expenses-card__expansion-action--delete:hover {
  background: rgba(255, 107, 107, 0.08);
}

.expenses-card__expansion-action:focus-visible {
  outline: 2px solid var(--color-accent, #f896ff);
  outline-offset: 2px;
}

.expenses-card__expansion-action:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Inline feedback slot for delete failures — surfaces the backend's
   detail without re-rendering the list. Spans the full row width
   so the message is readable on narrow viewports. */
.expenses-card__expansion-feedback {
  flex-basis: 100%;
  margin: 0;
  font-size: 0.875rem;
  color: var(--color-text-muted, rgba(255, 255, 255, 0.6));
}

.expenses-card__expansion-feedback--error {
  color: var(--color-danger, #ff6b6b);
}
