/* iPhone redesign — the shared chrome vocabulary.
   Spec: design_handoff_greenmagpie_iphone/README.md. Every value here comes from a `--gm-*` token
   in tokens.css (DESIGN_STANDARD.md: "no hardcoded hex colors outside tokens.css"); the bare
   pixel numbers are the handoff's own type/size scale, which is deliberately literal.

   Kept in its own file rather than appended to styles.css: styles.css is already 1800 lines, and
   these are a coherent, separable layer (CLAUDE.md's "many small files"). */

/* ==================== Screen header (iOS-style large title) ====================
   Replaces the removed desktop top bar. One per screen. */

.gm-screen-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-3);
  margin: 4px 0 18px;
}

.gm-screen-head .gm-head-text { min-width: 0; }

.gm-eyebrow {
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gm-muted);
  margin-bottom: 6px;
  overflow-wrap: break-word;
}

.gm-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 36px;
  line-height: 1.08;
  letter-spacing: -0.015em;
  color: var(--gm-ink);
  margin: 0;
  overflow-wrap: break-word;
}

.gm-title.sm { font-size: 28px; }
.gm-subtitle { font-size: 13.5px; color: var(--gm-muted); margin-top: 6px; }
.gm-subtitle strong { color: var(--gm-ink); font-weight: 700; }

/* Trailing actions in a screen header — always a real control, never a bare text link. */
.gm-head-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }

.gm-round-btn {
  width: var(--gm-tap-min);
  height: var(--gm-tap-min);
  border-radius: 50%;
  border: 1px solid var(--gm-border-strong);
  background: var(--gm-card);
  color: var(--gm-ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
  transition: background var(--duration-fast) var(--ease-standard);
}
.gm-round-btn:active { background: var(--gm-track); }
.gm-round-btn:focus-visible { outline: 3px solid var(--gm-green); outline-offset: 2px; }
.gm-round-btn svg { stroke: currentColor; fill: none; }
.gm-round-btn.ink { background: var(--gm-ink-surface); color: var(--gm-ink-surface-text); border-color: transparent; }
.gm-round-btn.plain { background: none; border-color: transparent; }

/* A back affordance that is a button, not a centred link. */
.gm-back {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: var(--gm-tap-min);
  padding: 0 10px 0 4px;
  margin-left: -4px;
  background: none;
  border: none;
  color: var(--gm-green);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  max-width: 100%;
  overflow-wrap: anywhere;
  text-align: left;
}
.gm-back svg { stroke: currentColor; fill: none; flex-shrink: 0; }

/* ==================== Buttons ==================== */

.gm-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-height: var(--gm-btn-h);
  padding: 0 18px;
  border-radius: var(--gm-radius-control);
  border: 1px solid transparent;
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  text-align: center;
  transition: background var(--duration-fast) var(--ease-standard),
              transform var(--duration-fast) var(--ease-standard);
}
.gm-btn:active { transform: scale(0.985); }
.gm-btn:focus-visible { outline: 3px solid var(--gm-green); outline-offset: 2px; }
.gm-btn svg { stroke: currentColor; fill: none; flex-shrink: 0; }

.gm-btn.primary { background: var(--gm-green); color: var(--gm-on-green); }
.gm-btn.primary:active { background: var(--gm-green-deep); }

.gm-btn.secondary {
  background: var(--gm-card);
  color: var(--gm-ink);
  border-color: var(--gm-border-strong);
}
.gm-btn.secondary:active { background: var(--gm-track); }

.gm-btn.ink { background: var(--gm-ink-surface); color: var(--gm-ink-surface-text); }

.gm-btn.lg { min-height: var(--gm-btn-h-lg); font-size: 16px; }

/* Two of these sit side by side inside a row (approve / deny a join request). Still 44px tall —
   the handoff's floor for anything a thumb has to hit — just narrower and lighter than a
   full-width action button. */
.gm-btn.sm {
  min-height: 44px;
  padding: 0 14px;
  font-size: 13.5px;
  border-radius: 12px;
}

.gm-btn[disabled] {
  background: var(--gm-disabled);
  color: var(--gm-card);
  border-color: transparent;
  cursor: not-allowed;
}
.gm-btn[disabled]:active { transform: none; }

.gm-btn.danger { background: var(--gm-rust-tint); color: var(--gm-rust); }

/* The handoff's recurring "action pair": two equal items side by side (two buttons, or the Day
   view's two stat tiles). */
.gm-action-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--gm-grid-gap);
  margin: 14px 0;
}
/* The stacking margin below is for cards in a column. Inside the pair they are grid cells, and it
   would push the right-hand one down by 12px — visible as two tiles that don't line up. Needs to
   out-specify `.gm-card + .gm-card`, hence naming both classes. */
.gm-action-pair > .gm-card + .gm-card,
.gm-action-pair > .gm-rows + .gm-card,
.gm-action-pair > .gm-card + .gm-rows { margin-top: 0; }

/* ==================== Cards, rows, sections ==================== */

.gm-card {
  background: var(--gm-card);
  border: 1px solid var(--gm-border);
  border-radius: var(--gm-radius-feature);
  padding: var(--gm-card-pad);
}

.gm-card.flush { padding: 0; overflow: hidden; border-radius: var(--gm-radius-card); }

.gm-card + .gm-card,
.gm-card + .gm-rows,
.gm-rows + .gm-card { margin-top: 12px; }

/* A grouped list: rows separated by hairlines, the whole thing one rounded card. */
.gm-rows {
  background: var(--gm-card);
  border: 1px solid var(--gm-border);
  border-radius: var(--gm-radius-card);
  overflow: hidden;
}

.gm-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: var(--gm-tap-min);
  padding: var(--gm-row-pad-y) var(--gm-row-pad-x);
  background: none;
  border: none;
  border-bottom: 1px solid var(--gm-separator);
  font-family: var(--font-body);
  text-align: left;
  color: var(--gm-ink);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-standard);
}
.gm-row:last-child { border-bottom: none; }
.gm-row:active { background: var(--gm-gold-tint); }
.gm-row:focus-visible { outline: 3px solid var(--gm-green); outline-offset: -3px; }
.gm-row.static { cursor: default; }
.gm-row.static:active { background: none; }

.gm-row-tile {
  width: 40px;
  height: 40px;
  border-radius: var(--gm-radius-tile);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  background: var(--gm-track);
  color: var(--gm-ink-2);
}
.gm-row-tile.sm { width: 30px; height: 30px; border-radius: 9px; }
.gm-row-tile svg { stroke: currentColor; fill: none; }
.gm-row-tile.green { background: var(--gm-green-tint); color: var(--gm-green-deep); }
.gm-row-tile.gold { background: var(--gm-gold-tint); color: var(--gm-gold-deep); }
.gm-row-tile.rust { background: var(--gm-rust-tint); color: var(--gm-rust); }
.gm-row-tile.neutral { background: var(--gm-track); color: var(--gm-ink-2); }

/* These are <span>s (a <div> inside a <button> is invalid), so they need to be told to stack. */
.gm-row-body { flex: 1; min-width: 0; display: block; }
.gm-row-title, .gm-row-sub { display: block; }
.gm-row-title {
  font-size: 15.5px;
  font-weight: 700;
  color: var(--gm-ink);
  overflow-wrap: break-word;
}
.gm-row.sm .gm-row-title { font-size: 14.5px; font-weight: 600; }
.gm-row-sub {
  font-size: 12.5px;
  color: var(--gm-muted);
  margin-top: 2px;
  overflow-wrap: break-word;
}
.gm-row-value {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--gm-muted);
  flex-shrink: 0;
  white-space: nowrap;
}
.gm-row-value.plain { font-weight: 400; }
.gm-row-chevron { color: var(--gm-placeholder); display: flex; flex-shrink: 0; }
.gm-row-chevron svg { stroke: currentColor; fill: none; }

.gm-row.danger .gm-row-title { color: var(--gm-rust); }

/* Group eyebrow above a .gm-rows card. */
.gm-group-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gm-muted);
  margin: 22px 0 8px;
}
.gm-group-label:first-child { margin-top: 0; }
.gm-group-label.danger { color: var(--gm-rust); }
.gm-rows.danger { border-color: rgba(168, 83, 43, 0.25); }

.gm-section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin: 24px 0 10px;
}
.gm-section-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 19px;
  color: var(--gm-ink);
}
.gm-section-meta { font-size: 13px; color: var(--gm-muted); white-space: nowrap; }

/* ==================== Segmented control ==================== */

.gm-segment {
  display: flex;
  gap: 3px;
  padding: 3px;
  background: var(--gm-track);
  border-radius: var(--gm-radius-segment);
}

.gm-segment button {
  flex: 1;
  min-height: 38px;
  padding: 0 10px;
  border: none;
  border-radius: 8px;
  background: none;
  color: var(--gm-ink-2);
  font-family: var(--font-body);
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
  transition: background var(--duration-base) var(--ease-standard),
              color var(--duration-base) var(--ease-standard);
}
.gm-segment button[aria-selected="true"] {
  background: var(--gm-card);
  color: var(--gm-ink);
  box-shadow: 0 1px 3px rgba(31, 51, 32, 0.15);
}
.gm-segment button:focus-visible { outline: 3px solid var(--gm-green); outline-offset: 2px; }

/* The tab-level segmented control (Balance · Groups · Friends) needs a real 44px target. */
.gm-segment.tabs button { min-height: var(--gm-tap-min); font-size: 13.5px; }

/* Dark pill variant — the handoff's chips and currency/split segments. */
.gm-segment.dark button[aria-selected="true"] {
  background: var(--gm-ink-surface);
  color: var(--gm-ink-surface-text);
  box-shadow: none;
}

/* ==================== Toggle ==================== */

.gm-toggle {
  position: relative;
  width: 50px;
  height: 30px;
  flex-shrink: 0;
  border: none;
  border-radius: 999px;
  background: var(--gm-warm-grey);
  cursor: pointer;
  transition: background var(--duration-base) var(--ease-standard);
}
.gm-toggle[aria-checked="true"] { background: var(--gm-green); }
.gm-toggle:focus-visible { outline: 3px solid var(--gm-green); outline-offset: 2px; }
.gm-toggle::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 2px rgba(31, 51, 32, 0.25);
  transition: transform var(--duration-base) var(--ease-standard);
}
.gm-toggle[aria-checked="true"]::after { transform: translateX(20px); }

/* ==================== Pills, chips ==================== */

.gm-pill {
  display: inline-flex;
  align-items: center;
  border-radius: 999px;
  padding: 3px 9px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  background: var(--gm-track);
  color: var(--gm-ink-2);
  white-space: nowrap;
}
.gm-pill.green { background: var(--gm-green-tint); color: var(--gm-green-deep); }
.gm-pill.gold { background: var(--gm-gold-tint); color: var(--gm-gold-deep); }
.gm-pill.rust { background: var(--gm-rust-tint); color: var(--gm-rust); }
.gm-pill.ink { background: var(--gm-ink-surface); color: var(--gm-ink-surface-text); }

/* Horizontally scrolling chip row (categories, filters, day strip). Scrolls inside itself so the
   page body never scrolls sideways. */
.gm-chip-row {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 2px;
}
.gm-chip-row::-webkit-scrollbar { display: none; }

.gm-chip {
  flex-shrink: 0;
  min-height: var(--gm-tap-min);
  padding: 0 16px;
  border-radius: 999px;
  border: 1px solid var(--gm-border-strong);
  background: var(--gm-card);
  color: var(--gm-ink);
  font-family: var(--font-body);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--duration-fast) var(--ease-standard);
}
.gm-chip[aria-pressed="true"], .gm-chip[aria-selected="true"], .gm-chip[aria-checked="true"] {
  background: var(--gm-ink-surface);
  color: var(--gm-ink-surface-text);
  border-color: transparent;
}
.gm-chip:focus-visible { outline: 3px solid var(--gm-green); outline-offset: 2px; }

/* Interest Profile capture — one .interest-chip per taxonomy item, a .gm-chip for the star cycle
   plus a small always-visible Avoid control, so Avoid never depends on a long-press alone (see
   frontend/js/interests-sheet.js). */
.interest-group { margin-top: 14px; }
.interest-chip-row {
  display: flex; flex-wrap: wrap; gap: 8px;
}
.interest-chip { display: inline-flex; align-items: stretch; border-radius: 999px; }
.interest-chip .gm-chip { display: inline-flex; align-items: center; gap: 5px; }
.interest-chip-stars { font-size: 11px; letter-spacing: 1px; }
.interest-chip-avoid {
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--gm-tap-min); min-width: 32px;
  border: 1px solid var(--gm-border-strong); border-left: none;
  border-radius: 0 999px 999px 0;
  background: var(--gm-card); color: var(--gm-ink-2);
  margin-left: -1px;
}
.interest-chip-avoid[aria-pressed="true"] {
  background: var(--gm-rust-tint); color: var(--gm-rust); border-color: var(--gm-rust);
}
.interest-chip.avoided .gm-chip { opacity: 0.5; text-decoration: line-through; }

/* ==================== Avatar stack ==================== */

.gm-avatar-stack { display: flex; align-items: center; flex-shrink: 0; }
.gm-avatar-stack > * {
  margin-left: -10px;
  border: 2px solid var(--gm-card);
  border-radius: 50%;
  background: var(--gm-track);
  flex-shrink: 0;
}
.gm-avatar-stack > *:first-child { margin-left: 0; }
.gm-avatar-stack.on-cover > * { border-color: var(--gm-paper); }

.gm-avatar-add {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  color: var(--gm-ink);
  background: var(--gm-card);
  cursor: pointer;
}
.gm-avatar-add svg { stroke: currentColor; fill: none; }

/* ==================== Progress / stacked bars ==================== */

.gm-bar {
  display: flex;
  height: 8px;
  border-radius: 4px;
  overflow: hidden;
  background: var(--gm-track);
}
.gm-bar > span { display: block; height: 100%; }
.gm-bar.on-dark { background: rgba(246, 244, 236, 0.18); }

.gm-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  font-size: 12.5px;
  color: var(--gm-muted);
}
.gm-legend span { display: inline-flex; align-items: center; gap: 5px; }
.gm-legend i {
  width: 8px;
  height: 8px;
  border-radius: 2px;
  display: inline-block;
  flex-shrink: 0;
}

/* ==================== Tab bar (5 slots, raised centre +) ==================== */

.tabbar {
  --tab-bar-h: 76px;
  background: var(--gm-card);
  border-top: 1px solid var(--gm-border);
  box-shadow: none;
  padding: 8px 8px calc(8px + env(safe-area-inset-bottom, 0px));
  height: auto;
  min-height: calc(var(--tab-bar-h) + env(safe-area-inset-bottom, 0px));
  align-items: flex-start;
}

.tabbar button[data-tab] {
  gap: 5px;
  min-height: var(--gm-tap-min);
  color: var(--gm-inactive);
  font-size: 10.5px;
  font-weight: 600;
  padding-top: 6px;
}
.tabbar button[data-tab].active { color: var(--gm-ink); }
.tabbar button[data-tab] svg { width: 22px; height: 22px; }

/* The centre slot. It is inside the bar (not a floating corner button) because the handoff makes
   it the app's single, always-present "add an expense" action — see the deleted .fab-float. */
.tabbar .tabbar-add {
  flex: 1;
  position: relative;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  background: none;
  border: none;
  cursor: pointer;
  padding-top: 6px;
  /* The visible circle is absolutely positioned above the bar, so without this the button's own
     box collapses to a few pixels tall and the real tap target is nothing like the 54px disc you
     can see — caught by scripts/test_accessibility.py, invisible on screen. */
  min-height: var(--gm-tap-min);
}

.tabbar .tabbar-add-circle {
  position: absolute;
  top: -22px;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  background: var(--gm-green);
  color: var(--gm-on-green);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 6px 16px rgba(46, 94, 34, 0.35);
  transition: transform var(--duration-fast) var(--ease-standard);
}
.tabbar .tabbar-add:active .tabbar-add-circle { transform: scale(0.92); }
.tabbar .tabbar-add-circle svg { stroke: var(--gm-on-green); width: 30px; height: 30px; }
.tabbar .tabbar-add:focus-visible .tabbar-add-circle { outline: 3px solid var(--gm-green); outline-offset: 3px; }

/* Unread dot on the You tab. */
.tabbar .tab-dot {
  position: absolute;
  top: 4px;
  right: 50%;
  margin-right: -16px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--gm-rust);
}
.tabbar button[data-tab] { position: relative; }

/* The screen no longer sits under a sticky top bar, so it needs its own top safe-area padding. */
main#screen {
  padding-top: calc(var(--space-4) + env(safe-area-inset-top, 0px));
  padding-left: var(--gm-gutter);
  padding-right: var(--gm-gutter);
}

/* ==================== Cover header (trip hub, trip cards) ====================
   Bleeds to the screen edges past main#screen's own gutter. */

.gm-cover {
  position: relative;
  height: 250px;
  margin: calc(-1 * (var(--space-4) + env(safe-area-inset-top, 0px))) calc(-1 * var(--gm-gutter)) 18px;
  overflow: hidden;
  background: var(--gm-track);
}
.gm-cover-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.gm-cover-scrim { position: absolute; inset: 0; background: var(--gm-cover-scrim); }
.gm-cover-top {
  position: absolute;
  left: var(--gm-gutter);
  right: var(--gm-gutter);
  top: calc(14px + env(safe-area-inset-top, 0px));
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.gm-cover-btn {
  width: var(--gm-tap-min);
  height: var(--gm-tap-min);
  border-radius: 50%;
  border: none;
  background: rgba(246, 244, 236, 0.9);
  color: var(--gm-ink-surface);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  backdrop-filter: blur(6px);
}
.gm-cover-btn svg { stroke: currentColor; fill: none; }
.gm-cover-btn:focus-visible { outline: 3px solid #fff; outline-offset: 2px; }

.gm-cover-bottom {
  position: absolute;
  left: var(--gm-gutter);
  right: var(--gm-gutter);
  bottom: 16px;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
}
.gm-cover-eyebrow {
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gm-paper);
  opacity: 0.85;
  margin-bottom: 4px;
}
.gm-cover-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 44px;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--gm-paper);
  overflow-wrap: break-word;
}

/* ==================== Empty / loading helpers ==================== */

.gm-empty {
  text-align: center;
  padding: 32px 16px;
}
.gm-empty .gm-empty-title {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 700;
  color: var(--gm-ink);
  margin-bottom: 6px;
}
.gm-empty .gm-empty-sub { font-size: 13.5px; color: var(--gm-muted); line-height: 1.5; }
.gm-empty .gm-btn { margin-top: 18px; }

/* Dashed "add" affordance — a real button, sized like one. */
.gm-add-dashed {
  width: 100%;
  min-height: var(--gm-tap-min);
  padding: 12px;
  border: 2px dashed var(--gm-border-strong);
  border-radius: var(--gm-radius-card);
  background: none;
  color: var(--gm-green);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}
.gm-add-dashed:active { background: var(--gm-track); }
.gm-add-dashed:focus-visible { outline: 3px solid var(--gm-green); outline-offset: 2px; }

/* Anything wide enough to overflow scrolls inside its own box, never the page. */
.gm-scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }

@media print {
  .gm-cover, .gm-head-actions, .gm-back { display: none !important; }
}

/* ==================== Agenda — Day view (handoff 1f) ==================== */

/* The horizontal day strip. Pills are 52px wide and scroll inside the strip, never the page. */
.agenda-day-strip { margin-top: 14px; gap: 8px; }

.agenda-day-pill {
  flex-shrink: 0;
  width: 52px;
  min-height: var(--gm-tap-min);
  padding: 8px 0;
  border-radius: var(--gm-radius-control);
  border: 1px solid var(--gm-border-strong);
  background: var(--gm-card);
  color: var(--gm-ink);
  font-family: var(--font-body);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  transition: background var(--duration-fast) var(--ease-standard);
}
.agenda-day-pill[aria-selected="true"] {
  background: var(--gm-ink-surface);
  color: var(--gm-ink-surface-text);
  border-color: transparent;
}
.agenda-day-pill:focus-visible { outline: 3px solid var(--gm-green); outline-offset: 2px; }
.agenda-day-pill-wd { font-size: 11px; font-weight: 700; opacity: 0.7; }
.agenda-day-pill-n { font-family: var(--font-display); font-size: 20px; font-weight: 700; line-height: 1; }

/* Time rail + card. The rail is a fixed 44px so every card's left edge lines up whether or not
   its item has a time. */
.agenda-day-row { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 10px; }

.agenda-day-time {
  width: 44px;
  flex-shrink: 0;
  padding-top: 15px;
  text-align: right;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--gm-muted);
}

.agenda-day-row .agenda-card {
  flex: 1;
  min-width: 0;
  background: var(--gm-card);
  border: 1px solid var(--gm-border);
  border-radius: var(--gm-radius-card);
  padding: 14px 16px;
  cursor: pointer;
  /* The card is its own drag handle here (long press), so the browser must not claim the gesture
     as a text selection or a callout. */
  -webkit-touch-callout: none;
  user-select: none;
}
.agenda-day-row .agenda-card:focus-visible { outline: 3px solid var(--gm-green); outline-offset: 2px; }
.agenda-day-row .agenda-card.continuation { background: var(--gm-paper); }

.agenda-day-card-top { display: flex; align-items: baseline; gap: 8px; }
.agenda-day-icon { color: var(--gm-muted); flex-shrink: 0; align-self: center; display: flex; }
.agenda-day-icon svg { stroke: currentColor; fill: none; }
.agenda-day-title {
  flex: 1;
  min-width: 0;
  font-size: 15.5px;
  font-weight: 700;
  color: var(--gm-ink);
  overflow-wrap: break-word;
}
.agenda-day-cost { font-size: 14px; font-weight: 700; color: var(--gm-ink); white-space: nowrap; flex-shrink: 0; }
.agenda-day-sub { font-size: 12.5px; color: var(--gm-muted); margin-top: 3px; overflow-wrap: break-word; }
.agenda-day-pills { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }

/* The Ideas row doubles as a drop target, so it needs the same highlight a day gets. */
.gm-rows.agenda-day.drop-target,
.agenda-day-row .agenda-card.agenda-dragging { opacity: 0.4; }
.gm-rows.agenda-day.drop-target { outline: 2px dashed var(--gm-green); outline-offset: 2px; }

/* ==================== Add expense — amount-first capture (handoff 1h) ==================== */

.flow-capture { display: flex; flex-direction: column; gap: 12px; }

/* Sits directly under the sheet's own "Add expense" header, as its second line. */
.flow-capture-sub { font-size: 12.5px; color: var(--gm-muted); margin-top: -6px; overflow-wrap: break-word; }

.flow-amount-display {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 54px;
  line-height: 1.05;
  color: var(--gm-ink);
  letter-spacing: -0.02em;
  overflow-wrap: anywhere;
  margin-top: 4px;
}
.flow-amount-display.empty { color: var(--gm-placeholder); }

.flow-conversion { font-size: 13.5px; color: var(--gm-muted); margin-top: -6px; overflow-wrap: break-word; }

/* Note field with a trailing Photo control, sharing one card-shaped box. */
.flow-note-row {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 50px;
  padding: 0 14px;
  background: var(--gm-card);
  border: 1px solid var(--gm-border-strong);
  border-radius: var(--gm-radius-control);
}
.flow-note {
  flex: 1;
  min-width: 0;
  border: none;
  background: none;
  padding: 0;
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--gm-ink);
}
.flow-note:focus { outline: none; }
.flow-note::placeholder { color: var(--gm-placeholder); }
.flow-photo-btn {
  flex-shrink: 0;
  min-height: var(--gm-tap-min);
  padding: 0 4px;
  background: none;
  border: none;
  color: var(--gm-green);
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}
.flow-photo-btn:focus-visible { outline: 3px solid var(--gm-green); outline-offset: 2px; }

.flow-photo-panel {
  padding: 12px;
  background: var(--gm-track);
  border-radius: var(--gm-radius-control);
}

.flow-chips { margin-top: 2px; }

.flow-split-bar {
  background: var(--gm-green-tint);
  border-radius: var(--gm-radius-control);
  padding: 10px;
}
.flow-split-bar .gm-segment { background: rgba(255, 253, 248, 0.6); }
.flow-split-preview {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--gm-green-deep);
  margin-top: 8px;
  text-align: center;
  overflow-wrap: break-word;
  min-height: 16px;
}

/* Capture screen's "Paid by · <name> · Change" row. Deliberately quieter than the split bar
   above it: for most expenses the trip's default payer is already right, so this is a statement
   with a way out, not a control competing with the keypad. */
.flow-payer-row {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  min-height: 44px;
  padding: 10px 14px;
  border: 1px solid var(--gm-border);
  border-radius: var(--gm-radius-control);
  background: var(--gm-card);
  text-align: left;
}
.flow-payer-name {
  flex: 1;
  min-width: 0;
  font-size: 14px;
  font-weight: 700;
  color: var(--gm-ink);
  overflow-wrap: break-word;
}
.flow-payer-change {
  flex-shrink: 0;
  font-size: 13px;
  font-weight: 700;
  color: var(--gm-green);
}

/* One payer's box on the who-paid step, once "Several people paid" is on. Indented under the
   person it belongs to, so a column of names and a column of amounts read as pairs rather than
   as two lists that happen to be adjacent. */
.flow-payer-amount {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: -2px 0 6px 38px;
}
.flow-payer-amount .detail {
  flex: 1;
  min-width: 0;
}
/* The :not() chain is deliberate, not cargo-culted: styles.css's base input rule carries four of
   them and therefore outranks a plain `.flow-payer-amount input`, so the box rendered full-width
   and sat on top of its own label. Matching that specificity is what lets width apply at all. */
.flow-payer-amount input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]) {
  flex: 0 0 120px;
  width: 120px;
  padding: 8px 12px;
  min-height: 40px;
  text-align: right;
}

.flow-keypad {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}
.flow-key {
  min-height: 50px;
  border-radius: var(--gm-radius-control);
  border: 1px solid var(--gm-border-strong);
  background: var(--gm-card);
  color: var(--gm-ink);
  font-family: var(--font-body);
  font-size: 22px;
  font-weight: 600;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background var(--duration-fast) var(--ease-standard);
  /* A keypad gets held down and dragged across; none of that should select text or pop a callout. */
  user-select: none;
  -webkit-touch-callout: none;
}
.flow-key:active { background: var(--gm-track); }
.flow-key:focus-visible { outline: 3px solid var(--gm-green); outline-offset: 2px; }
.flow-key svg { stroke: currentColor; fill: none; }

/* ==================== Trips list — cover cards (handoff 1d) ==================== */

.trip-cover-card {
  display: block;
  width: 100%;
  padding: 0;
  margin-bottom: 16px;
  background: var(--gm-card);
  border: 1px solid var(--gm-border);
  border-radius: var(--gm-radius-feature);
  overflow: hidden;
  text-align: left;
  font-family: var(--font-body);
  cursor: pointer;
  /* The handoff's cards carry no shadow; these elements also keep the older .trip-card class
     (25 browser suites open a trip through it), whose rules include one. */
  box-shadow: none;
  gap: 0;
  transition: transform var(--duration-fast) var(--ease-standard);
}
.trip-cover-card:active { transform: scale(0.99); }
.trip-cover-card:focus-visible { outline: 3px solid var(--gm-green); outline-offset: 2px; }

.trip-cover {
  position: relative;
  display: block;
  height: 150px;
  background: var(--gm-track);
}
.trip-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.trip-cover-scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(31, 51, 32, 0) 45%, rgba(31, 51, 32, 0.55) 100%);
}
.trip-cover-pill {
  position: absolute;
  left: 12px;
  bottom: 12px;
  padding: 5px 10px;
  border-radius: 999px;
  background: rgba(31, 51, 32, 0.85);
  color: var(--gm-paper);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.trip-cover-flags { position: absolute; right: 12px; top: 12px; font-size: 18px; letter-spacing: 2px; }

.trip-cover-body { display: block; padding: 14px 16px 16px; }
.trip-cover-name {
  display: block;
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 700;
  color: var(--gm-ink);
  overflow-wrap: break-word;
}
.trip-cover-dates { display: block; font-size: 13px; color: var(--gm-muted); margin-top: 2px; }

.trip-card-people { display: flex; align-items: center; gap: 8px; margin-top: 12px; min-height: 24px; }
.trip-card-people-names { font-size: 13px; color: var(--gm-muted); overflow-wrap: anywhere; }
.trip-card-money-slot { display: block; margin-top: 12px; }
.trip-card-money {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 13px;
  color: var(--gm-muted);
  flex-wrap: wrap;
}
.trip-card-money strong { font-weight: 700; color: var(--gm-ink); }

.trip-past-row {
  border-radius: var(--gm-radius-card);
  border: 1px solid var(--gm-border);
  margin-bottom: 10px;
  background: var(--gm-card);
  box-shadow: none;
}

/* ==================== Home — trip-first (handoff 1a) ==================== */

.home-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 18px;
}
.home-wordmark {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 700;
  color: var(--gm-ink);
}
.home-unread-dot {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--gm-rust);
}

.home-eyebrow {
  font-size: 13px;
  font-weight: 600;
  color: var(--gm-muted);
  margin-bottom: 2px;
  overflow-wrap: break-word;
}
.home-trip-title {
  display: block;
  width: 100%;
  padding: 0;
  margin: 0 0 14px;
  background: none;
  border: none;
  text-align: left;
  font-family: var(--font-display);
  font-size: 40px;
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--gm-ink);
  cursor: pointer;
  overflow-wrap: break-word;
}
.home-trip-title:focus-visible { outline: 3px solid var(--gm-green); outline-offset: 2px; }

/* Deliberately dark in both themes: it is the headline of the screen. */
.home-budget-card {
  background: var(--gm-ink-surface);
  color: var(--gm-ink-surface-text);
  border-radius: var(--gm-radius-feature);
  padding: var(--gm-card-pad);
}
.home-budget-eyebrow {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.7;
  margin-bottom: 6px;
}
.home-budget-figures { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.home-budget-amount { font-family: var(--font-display); font-size: 36px; font-weight: 700; line-height: 1.05; }
.home-budget-of { font-size: 14px; opacity: 0.7; }
.home-budget-footer {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 10px;
  font-size: 12.5px;
  font-weight: 700;
}
.home-budget-footer > span:last-child { opacity: 0.7; font-weight: 500; }

.home-today-time {
  width: 44px;
  flex-shrink: 0;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--gm-muted);
}
.home-agenda-link {
  background: none;
  border: none;
  padding: 0 2px;
  min-height: var(--gm-tap-min);
  color: var(--gm-green);
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}

/* The balance strip. A row, not a centred hero — "you are owed X" and "settle up" belong on the
   same line, which is what makes the second one obviously the action. */
.balance-hero.home-balance-strip {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: var(--gm-tap-min);
  margin: 20px 0 4px;
  padding: 14px 16px;
  background: var(--gm-green-tint);
  border: none;
  border-radius: var(--gm-radius-card);
  text-align: left;
  cursor: pointer;
}
.balance-hero.home-balance-strip:focus-visible { outline: 3px solid var(--gm-green); outline-offset: 2px; }
.home-balance-donut, .home-balance-magpie { flex-shrink: 0; display: flex; align-items: center; }
.home-balance-text { flex: 1; min-width: 0; display: block; }
.balance-hero.home-balance-strip .label {
  display: block;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gm-ink-2);
}
.balance-hero.home-balance-strip .figure {
  display: block;
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 700;
  color: var(--gm-green-deep);
  margin-top: 2px;
}
.balance-hero.home-balance-strip .figure.debt { color: var(--gm-rust); }
.home-balance-cta {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-size: 13px;
  font-weight: 700;
  color: var(--gm-green-deep);
  white-space: nowrap;
}
.home-balance-cta svg { stroke: currentColor; fill: none; }

/* ==================== You tab (handoff 2, screen 4a) ====================
   The screen that replaced the profile bottom sheet. Values are the handoff's own literal
   type/size scale; every colour comes from a --gm-* token (DESIGN_STANDARD.md). */

.you-identity { padding: 18px; }

.you-identity-top { display: flex; align-items: center; gap: 14px; }

.you-avatar-wrap { position: relative; flex-shrink: 0; display: block; }

.you-avatar {
  width: 64px;
  height: 64px;
  border-radius: var(--gm-radius-feature);
  object-fit: cover;
  background: var(--gm-track);
  display: block;
}

/* The pencil badge. Visually 24px per the handoff, but its tap target is padded out to the 44px
   floor — a 24px circle is a real control, not decoration, and has to be hittable. */
.you-avatar-badge {
  position: absolute;
  right: -10px;
  bottom: -10px;
  width: var(--gm-tap-min);
  height: var(--gm-tap-min);
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
}
.you-avatar-badge::before {
  content: "";
  position: absolute;
  right: 10px;
  bottom: 10px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--gm-ink-surface);
  border: 2px solid var(--gm-card);
}
.you-avatar-badge svg {
  position: relative;
  margin: 0 15px 15px 0;
  stroke: var(--gm-ink-surface-text);
  fill: none;
}
.you-avatar-badge:focus-visible { outline: 3px solid var(--gm-green); outline-offset: -8px; border-radius: 50%; }

.you-identity-text { min-width: 0; display: block; }
.you-name {
  display: block;
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 700;
  color: var(--gm-ink);
  overflow-wrap: break-word;
}
.you-email {
  display: block;
  font-size: 13px;
  color: var(--gm-muted);
  margin-top: 2px;
  overflow-wrap: anywhere;
}

#you-avatar-controls { margin-top: 16px; }
#you-avatar-controls .gm-segment { background: var(--gm-track); }
/* The handoff draws these pills 12px/700; the 44px floor is not negotiable, so they are the
   handoff's type at the app's minimum height rather than the handoff's height. */
#you-avatar-controls .gm-segment button { min-height: var(--gm-tap-min); font-size: 12px; }

.you-palette-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 12px;
  flex-wrap: wrap;
}

.you-palette { display: flex; gap: 4px; flex-wrap: wrap; }
/* Same trick as the pencil badge: the circle reads 30px, the hit area is a full 44x44. Eight
   palettes at 44px wrap to two rows on a 390px screen, which is the right trade — a 30px-wide
   target is one scripts/test_accessibility.py rejects, and it is right to. */
.you-palette button {
  width: var(--gm-tap-min);
  height: var(--gm-tap-min);
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.you-palette button::before {
  content: "";
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--swatch);
  box-shadow: inset 0 0 0 1px var(--gm-border);
  transition: box-shadow var(--duration-base) var(--ease-standard);
}
.you-palette button[aria-checked="true"]::before {
  box-shadow: 0 0 0 3px var(--gm-ink);
}
.you-palette button:focus-visible { outline: 3px solid var(--gm-green); outline-offset: -4px; border-radius: 999px; }

/* A text action inside a card (the handoff's "Use a photo ›", "Sign out"). Still a real 44px
   target — the "never a centred text link as the primary action" rule is about primary actions;
   these are secondary escapes from a control that already works. */
.you-link {
  min-height: var(--gm-tap-min);
  padding: 0 2px;
  background: none;
  border: none;
  color: var(--gm-green);
  font-family: var(--font-body);
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
}
.you-link:focus-visible { outline: 3px solid var(--gm-green); outline-offset: 2px; }

.you-photo-note {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  font-size: 12.5px;
  color: var(--gm-muted);
}

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

.you-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin-top: 12px;
}

.you-stat {
  min-height: var(--gm-tap-min);
  padding: 12px;
  border-radius: 14px;
  border: 1px solid var(--gm-border);
  background: var(--gm-card);
  font-family: var(--font-body);
  text-align: left;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 4px;
  transition: background var(--duration-fast) var(--ease-standard);
}
.you-stat:active { background: var(--gm-track); }
.you-stat:focus-visible { outline: 3px solid var(--gm-green); outline-offset: 2px; }
.you-stat.green { background: var(--gm-green-tint); border-color: transparent; }

.you-stat-eyebrow {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gm-muted);
  overflow-wrap: break-word;
}
.you-stat.green .you-stat-eyebrow { color: var(--gm-green-deep); }
.you-stat-value {
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 700;
  color: var(--gm-ink);
  overflow-wrap: anywhere;
}
.you-stat.green .you-stat-value { color: var(--gm-green-deep); }

/* The behavioural-telemetry disclosure. Card-shaped like the row groups either side of it so it
   reads as part of the screen rather than fine print, but not a button: there is nothing to tap,
   and giving it a chevron would promise a screen that doesn't exist. Body-text size and
   --gm-ink-2 (not --gm-placeholder) so it is genuinely readable in both themes — a disclosure set
   in whisper-grey is a disclosure in name only. */
.you-privacy-note {
  margin: 0;
  padding: 14px 16px;
  background: var(--gm-card);
  border: 1px solid var(--gm-border);
  border-radius: var(--gm-radius-card);
  font-size: var(--text-sm);
  line-height: 1.5;
  color: var(--gm-ink-2);
  overflow-wrap: break-word;
}

.you-footer {
  margin: 26px 0 10px;
  text-align: center;
  font-size: 12px;
  color: var(--gm-placeholder);
}
.you-footer .you-link { font-size: 12px; }

/* ==================== Balances (handoff 2, screen 4b) ==================== */

/* The dark net card. Deliberately dark in both themes, same as the Home budget card: it is the
   headline of the screen. */
.bal-net {
  background: var(--gm-ink-surface);
  color: var(--gm-ink-surface-text);
  border-radius: var(--gm-radius-feature);
  padding: 18px 20px 16px;
}

.bal-net-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; }
.bal-net-left { min-width: 0; }

.bal-net-eyebrow {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.75;
  margin-bottom: 6px;
  overflow-wrap: break-word;
}
.bal-net-amount {
  font-family: var(--font-display);
  font-size: 36px;
  font-weight: 700;
  line-height: 1.05;
  color: var(--gm-green-on-dark);
  overflow-wrap: anywhere;
}
.bal-net-amount.debt { color: var(--gm-rust-text); }

.bal-net-right {
  flex-shrink: 0;
  text-align: right;
  font-size: 12.5px;
  line-height: 1.6;
  opacity: 0.9;
}
.bal-net-right .debt { color: var(--gm-rust-text); opacity: 1; }
.bal-net-note { margin-top: 10px; font-size: 12px; opacity: 0.8; overflow-wrap: break-word; }

.bal-net-actions { display: flex; gap: 8px; margin-top: 14px; }
.bal-net-btn {
  flex: 1;
  min-height: var(--gm-tap-min);
  padding: 0 12px;
  border: none;
  border-radius: var(--gm-radius-tile);
  font-family: var(--font-body);
  font-size: 13.5px;
  font-weight: 700;
  cursor: pointer;
  color: var(--gm-ink-surface-text);
  overflow-wrap: anywhere;
  transition: background var(--duration-fast) var(--ease-standard);
}
.bal-net-btn.primary { background: var(--gm-green); color: var(--gm-on-green); }
.bal-net-btn.ghost { background: rgba(246, 244, 236, 0.14); }
.bal-net-btn:active { filter: brightness(0.92); }
.bal-net-btn:focus-visible { outline: 3px solid var(--gm-paper); outline-offset: 2px; }
.bal-net-btn[disabled] { opacity: 0.4; cursor: not-allowed; }

/* ---- Panel head: helper text left, action pill right ---- */
.bal-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}
/* .gm-pill is a label elsewhere; as a button it still has to clear the 44px floor. */
.bal-pill {
  min-height: var(--gm-tap-min);
  padding: 0 14px;
  border: none;
  font-family: var(--font-body);
  font-size: 12.5px;
  cursor: pointer;
  flex-shrink: 0;
}
.bal-pill:focus-visible { outline: 3px solid var(--gm-green); outline-offset: 2px; }

/* ---- People rows ----
   Two controls on one row (open the person / act on the balance), so the row is a container
   rather than one big button — a button inside a button is invalid HTML and the inline action
   would be unreachable by keyboard. */
.gm-rows.bal-people.faded { opacity: 0.75; }

.bal-person {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px var(--gm-row-pad-x) 10px 10px;
  border-bottom: 1px solid var(--gm-separator);
}
.bal-person:last-child { border-bottom: none; }

.bal-person-main {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: var(--gm-tap-min);
  padding: 0 6px;
  background: none;
  border: none;
  font-family: var(--font-body);
  text-align: left;
  cursor: pointer;
  border-radius: var(--gm-radius-tile);
}
.bal-person-main:active { background: var(--gm-gold-tint); }
.bal-person-main:focus-visible { outline: 3px solid var(--gm-green); outline-offset: -2px; }
.bal-person-main img { border-radius: 50%; flex-shrink: 0; background: var(--gm-track); }

.bal-person-text { min-width: 0; display: block; }
.bal-person-name {
  display: block;
  font-size: 15px;
  font-weight: 700;
  color: var(--gm-ink);
  overflow-wrap: break-word;
}
.bal-person-sub {
  display: block;
  font-size: 12.5px;
  color: var(--gm-muted);
  margin-top: 2px;
  overflow-wrap: break-word;
}

.bal-person-right {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
}
/* One person, one row — but a person you share an AUD flat and a JPY trip with has two net
   figures, and they are never blended into one. They stack, biggest exposure first, and the
   smaller ones step down a size so the row still has exactly one leading number. */
.bal-person-amounts {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 1px;
}
.bal-person-amount { display: block; font-size: 15px; font-weight: 700; white-space: nowrap; }
.bal-person-amount.sm { font-size: 12.5px; }
.bal-person-amount.credit { color: var(--gm-green-deep); }
.bal-person-amount.debt { color: var(--gm-rust); }
.bal-person-amount.settled { color: var(--gm-muted); }

/* The handoff draws this as a small 11.5px link under the amount. It is still a control a thumb
   has to hit, so the box is a full 44px tall and the negative margin pulls the *visual* back to
   the tight stack the design asks for — caught by scripts/test_accessibility.py at 50x30. */
.bal-person-action {
  min-height: var(--gm-tap-min);
  margin: -7px 0;
  padding: 0 4px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  background: none;
  border: none;
  color: var(--gm-green);
  font-family: var(--font-body);
  font-size: 11.5px;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
}
.bal-person-action:focus-visible { outline: 3px solid var(--gm-green); outline-offset: 2px; }

/* The person sheet's header. */
.bal-person-head { display: flex; align-items: center; gap: 14px; margin-bottom: 6px; }
.bal-person-head img { border-radius: 50%; flex-shrink: 0; background: var(--gm-track); }

/* ---- Group rows ---- */
.bal-group-thumb {
  width: 44px;
  height: 44px;
  border-radius: var(--gm-radius-tile);
  flex-shrink: 0;
  background: var(--gm-track);
  object-fit: cover;
}
.bal-group-net {
  flex-shrink: 0;
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
  text-align: right;
}
.bal-group-net.credit { color: var(--gm-green-deep); }
.bal-group-net.debt { color: var(--gm-rust); }
.bal-group-net.settled { color: var(--gm-muted); }

/* Row values that carry a direction, inside a sheet's grouped list. */
.gm-row-value.credit { color: var(--gm-green-deep); }
.gm-row-value.debt { color: var(--gm-rust); }

/* The person sheet's headline: the net with this person across everything you share. It leads
   the sheet, so it is a size up from the per-group figures that explain it. */
.gm-row-value.bal-net-figure { font-size: 17px; }

/* These group rows also carry the older .list-item class, because 24 browser suites open a group
   through `.list-item[data-open]` — the same compatibility affordance .trip-cover-card makes for
   .trip-card. That class brings its own card chrome, which has to be undone here so the row still
   reads as one row of a grouped list. */
.gm-row.bal-group.list-item {
  border: none;
  border-bottom: 1px solid var(--gm-separator);
  border-radius: 0;
  margin-bottom: 0;
  background: none;
  padding: var(--gm-row-pad-y) var(--gm-row-pad-x);
  gap: 12px;
}
.gm-row.bal-group.list-item:last-child { border-bottom: none; }
.gm-row.bal-group.list-item:active { transform: none; background: var(--gm-gold-tint); }

/* ==================== Owner console (handoff 2, screen 4c) ==================== */

.admin-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 6px;
}

.gm-pill.admin-owner-pill {
  background: var(--gm-rust-tint);
  color: var(--gm-rust);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 5px 10px;
}

/* Title and range segment share a line; the segment shrinks rather than the title wrapping. */
.admin-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 4px 0 16px;
  flex-wrap: wrap;
}
.gm-segment.admin-range { flex-shrink: 0; width: auto; }
.gm-segment.admin-range button { min-height: var(--gm-tap-min); padding: 6px 12px; font-size: 12px; flex: 0 0 auto; }

.admin-tiles {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
.admin-tile {
  background: var(--gm-card);
  border: 1px solid var(--gm-border);
  border-radius: var(--gm-radius-card);
  padding: 14px;
}
.admin-tile-eyebrow {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gm-muted);
  overflow-wrap: break-word;
}
.admin-tile-figures { display: flex; align-items: baseline; gap: 8px; margin-top: 4px; flex-wrap: wrap; }
.admin-tile-value {
  font-family: var(--font-display);
  font-size: 26px;
  font-weight: 700;
  line-height: 1.05;
  color: var(--gm-ink);
  overflow-wrap: anywhere;
}
.admin-tile-delta { font-size: 11.5px; font-weight: 700; white-space: nowrap; }
.admin-tile-delta.up { color: var(--gm-green-deep); }
.admin-tile-delta.down { color: var(--gm-rust); }

.gm-card.admin-chart-card { margin-top: 12px; padding: 14px 16px 12px; }
.admin-chart-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}
.admin-chart-title { font-size: 14.5px; font-weight: 700; color: var(--gm-ink); }
.admin-chart-meta { font-size: 12px; color: var(--gm-muted); white-space: nowrap; }

/* Status dot. Sized like a row's icon tile slot so HEALTH rows line up with the rows above and
   below them, rather than sitting 20px further left. */
.admin-dot {
  width: 30px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.admin-dot::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--gm-warm-grey);
}
.admin-dot.ok::before { background: var(--gm-green); }
.admin-dot.warn::before { background: var(--gm-gold); }
.admin-dot.error::before { background: var(--gm-rust); }

/* The console is a full-screen overlay, so it needs the same 560px column main#screen has —
   without it a desktop browser stretches six stat tiles across 1500px. */
#gm-admin-overlay > * { max-width: 560px; margin-left: auto; margin-right: auto; }

/* ---- Keyboard-activatable rows ----
   Rows that are real controls without being <button> elements — the group list, expense rows,
   pending-approval rows, member rows, notifications. They carry role="button" tabindex="0"
   data-kbd-click (see frontend/js/app.js), which makes them Tab stops, so two things follow that
   the accessibility gate already requires of every other control:

     * a visible focus ring — a Tab stop the eye can't follow is worse than no Tab stop at all;
     * the same 44px minimum target height every other control is held to, since these are now
       controls by every definition the gate uses. */
[data-kbd-click] { min-height: 44px; }
[data-kbd-click]:focus-visible { outline: 3px solid var(--gm-green); outline-offset: -3px; }

/* ==================== Agenda — view segment, travel hops, map view ==================== */

/* Three ways to read one plan: the full timeline, the day rail, the map. A segment rather than
   the round cycling button this replaced — see the comment at its markup in itinerary.js. */
.agenda-view-segment { margin-bottom: 14px; }
.agenda-view-segment button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: var(--gm-tap-min);
}
.agenda-view-segment svg { stroke: currentColor; fill: none; flex-shrink: 0; }

/* The connector between two consecutive stops in the Day view: a dotted rail continuing the line
   the time column already implies, with the walk and the directions link riding on it. Indented to
   54px so it starts exactly where the cards do (44px time rail + the row's own 10px gap) — the
   hop belongs to the space between two cards, not to the time column beside them. */
.agenda-hop {
  display: flex;
  align-items: stretch;
  gap: 12px;
  margin: -4px 0 6px 54px;
}
.agenda-hop-rail {
  flex: 0 0 auto;
  width: 0;
  margin-left: 13px;
  border-left: 2px dotted var(--gm-border-strong);
}
.agenda-hop-body {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  min-height: var(--gm-tap-min);
  min-width: 0;
}

/* The estimate. Rendered hidden and unhidden only once a real number arrives, so a day with no
   estimates has no empty pills sitting in it. */
.agenda-hop-eta {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border-radius: 999px;
  padding: 4px 10px;
  background: var(--gm-track);
  color: var(--gm-ink-2);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
}
/* The reset's own [hidden] rule is `display:none !important`, but this element only exists inside
   redesign.css's cascade — and a class-level `display:inline-flex` beats a bare attribute
   selector. Spelled out here so the slot really is gone until a number arrives. */
.agenda-hop-eta[hidden] { display: none; }
.agenda-hop-eta svg { stroke: currentColor; fill: none; }
.agenda-hop-dist { color: var(--gm-muted); font-weight: 600; }

/* Always present, estimate or no estimate — a deep link into the visitor's own maps app needs no
   API key and no server, so it is the half of this row that can never be missing. */
.agenda-hop-dir {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: var(--gm-tap-min);
  padding: 0 10px;
  border-radius: 10px;
  color: var(--gm-green-deep);
  font-size: 12px;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}
.agenda-hop-dir svg { stroke: currentColor; fill: none; }
.agenda-hop-dir:hover { background: var(--gm-green-tint); }
.agenda-hop-dir:focus-visible { outline: 3px solid var(--gm-green); outline-offset: 2px; }

/* Google's required notice for walking routes (still beta upstream): shown once under the day,
   and only when a walking estimate actually rendered. */
.agenda-hop-note {
  margin: 4px 0 0 54px;
  overflow-wrap: break-word;
}

/* ---------------------------------------------------------------------------
   Transit: the hop badge, and the sheet behind it.

   One rule governs every colour below: --gm-line-color is *data*, not palette. It arrives from
   the transit operator's own feed (or the server's reference table as a fallback) on a per-line
   `style` attribute, exactly the way the avatar palette's --swatch does, and it is the only kind
   of hardcoded colour tokens.css doesn't own. It is therefore never used as text on the page's
   own background — only as a rail, a dot, or a chip's fill with the operator's own paired text
   colour on top — because an arbitrary feed colour cannot be assumed to clear WCAG AA against
   either theme's surface, and a rail has no contrast requirement to fail.
   --------------------------------------------------------------------------- */

/* The badge in the hop row. Same pill as the walking ETA — it is the same slot, saying a
   different thing — plus a rail of the line's colour on its leading edge and a real button's
   affordances, because unlike the walk pill this one opens something. */
.agenda-hop-eta.agenda-hop-transit {
  border: 0;
  cursor: pointer;
  font-family: inherit;
  text-align: left;
  padding-left: 8px;
  border-left: 3px solid var(--gm-line-color, var(--gm-green));
  border-radius: 4px 999px 999px 4px;
  max-width: 100%;
  /* It opens a sheet, so unlike the walking pill beside it this one is a real tap target. */
  min-height: var(--gm-tap-min);
}
.agenda-hop-eta.agenda-hop-transit:hover { background: var(--gm-green-tint); }
.agenda-hop-eta.agenda-hop-transit:focus-visible {
  outline: 3px solid var(--gm-green);
  outline-offset: 2px;
}
.agenda-hop-line { overflow-wrap: break-word; min-width: 0; }
.agenda-hop-transfers { color: var(--gm-muted); font-weight: 600; }

/* --- The sheet --------------------------------------------------------------------------- */

.transit-summary {
  margin: 0 0 14px;
  font-size: 15px;
  font-weight: 700;
  color: var(--gm-ink-2);
}

.transit-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* One vehicle you board. The line's colour is the card's leading rail — the "boarding pass"
   treatment the flight card uses, at the scale a list of two or three of these can carry. */
.transit-step {
  border: 1px solid var(--gm-border);
  border-left: 4px solid var(--gm-line-color, var(--gm-border-strong));
  border-radius: var(--gm-radius-card);
  background: var(--gm-card);
  padding: 12px 14px;
}
.transit-step-head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.transit-step-icon { display: inline-flex; color: var(--gm-ink-2); }
.transit-step-icon svg { stroke: currentColor; fill: none; }

/* The station-numbering letter, on the operator's own colour with the operator's own paired text
   colour. This is the one place the feed colour carries text, and it is the one place it is safe
   to: the two values ship together precisely so they read against each other. */
.transit-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  height: 24px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--gm-line-color, var(--gm-ink-surface));
  color: var(--gm-line-ink, var(--gm-on-green));
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.02em;
}

.transit-step-names { display: flex; flex-direction: column; min-width: 0; }
.transit-line-name { font-size: 15px; font-weight: 700; overflow-wrap: break-word; }
.transit-line-alt { font-size: 13px; color: var(--gm-ink-2); overflow-wrap: break-word; }
.transit-operator { font-size: 11.5px; color: var(--gm-muted); overflow-wrap: break-word; }

.transit-stop { display: flex; align-items: flex-start; gap: 10px; margin-top: 10px; }
.transit-stop-dot {
  flex: 0 0 auto;
  width: 10px;
  height: 10px;
  margin-top: 5px;
  border-radius: 50%;
  border: 2px solid var(--gm-line-color, var(--gm-border-strong));
}
/* Board is hollow, get-off is filled — the same visual grammar a route map uses, so the two are
   distinguishable without reading either label. */
.transit-stop-dot.alight { background: var(--gm-line-color, var(--gm-border-strong)); }
.transit-stop-text { display: flex; flex-direction: column; min-width: 0; }
.transit-stop-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--gm-muted);
}
.transit-stop-name { font-size: 14.5px; font-weight: 600; overflow-wrap: break-word; }

.transit-facts { margin: 10px 0 0; padding-left: 18px; }
.transit-facts li { overflow-wrap: break-word; }

/* "Look for: 銀座線 — orange signs marked G". The sentence this whole sheet exists to deliver. */
.transit-hint {
  margin: 10px 0 0;
  padding: 8px 10px;
  border-radius: 10px;
  background: var(--gm-track);
  color: var(--gm-ink-2);
  font-size: 13px;
  overflow-wrap: break-word;
}

/* Between two rides: the transfer. */
.transit-connector {
  list-style: none;
  margin-left: 14px;
  padding-left: 14px;
  border-left: 2px dotted var(--gm-border-strong);
  color: var(--gm-muted);
  font-size: 12px;
  font-weight: 700;
}

#transit-directions { margin-top: 16px; text-decoration: none; }
.transit-note { margin: 10px 0 0; overflow-wrap: break-word; }

/* The map view's day filter. A plain chip row, scrolling inside itself like the day strip. */
.agenda-map-days { margin-bottom: 12px; }

/* The inline map wants more of the screen than the sheet's does — it is the view, not a panel
   inside one — but never so much that the legend below it stops being discoverable. */
#agenda-body .leaflet-map.tall { height: min(52vh, 420px); }

/* ==================== Public, read-only Agenda (/agenda/<token>) ====================
   frontend/agenda.html reuses the .agenda-day-* chrome above so a shared plan looks like the
   plan. What it must not inherit is the *affordances*: in the app a card is a drag handle and a
   drawer trigger, so it carries cursor:pointer and user-select:none. On a page where nothing can
   be opened or moved, a pointer cursor is a promise the page can't keep — and blocking text
   selection on a read-only itinerary stops a viewer copying an address into their maps app. */
.agenda-public {
  max-width: 560px;
  margin: 0 auto;
  padding: var(--space-5) var(--space-4) var(--space-8);
}
.agenda-public .agenda-card {
  cursor: default;
  user-select: text;
  -webkit-touch-callout: default;
}
.agenda-public-head { margin-bottom: var(--space-5); }
/* .gm-pill is inline by default, which butts the icon straight against the label. */
.agenda-public-head .gm-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.agenda-public-head .gm-pill svg { stroke: currentColor; fill: none; }
.agenda-public-head h1 {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 700;
  color: var(--gm-ink);
  margin: var(--space-2) 0 0;
  overflow-wrap: break-word;
}
.agenda-public-meta {
  font-size: var(--text-sm);
  color: var(--gm-muted);
  margin-top: var(--space-1);
  overflow-wrap: break-word;
}
.agenda-public-footer {
  margin-top: var(--space-7);
  padding-top: var(--space-4);
  border-top: 1px solid var(--gm-border);
  text-align: center;
  font-size: var(--text-xs);
  color: var(--gm-muted);
}
.agenda-public-footer a {
  display: inline-block;
  margin-top: var(--space-2);
  min-height: 44px;
  line-height: 44px;
  color: var(--gm-green-deep);
}

/* Explanatory copy at the top of a sheet — what this thing does, before the button that does it.
   Several sheets had been inlining these two declarations; named here so the next one doesn't. */
.gm-sheet-intro {
  font-size: 12.5px;
  color: var(--gm-muted);
  margin: 0 0 8px;
  overflow-wrap: break-word;
}

/* The Agenda share link's five-minute window, stated beside the button rather than under it.
   Doubles as the live countdown once a link exists (frontend/js/agenda-share-link.js). */
.gm-share-countdown {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin: 14px 0 10px;
  font-size: 13px;
  font-weight: 700;
  color: var(--gm-gold-deep);
}
.gm-share-countdown svg { stroke: currentColor; fill: none; flex-shrink: 0; }
