/* ==========================================================================
   Redesign layer (UI-POLISH-PLAN.md, built from the v6 mock-up).

   Loaded after style.css. Every token here is prefixed --m- so nothing in the
   older stylesheet can be shadowed by accident: style.css already owns
   --surface-raised, --text-main and friends, and those keep driving the screens
   that have not moved over yet.

   Dark is the app's default ground (:root), light comes from body.light-theme,
   the same switch style.css uses. tests/redesign-foundations.test.js checks
   every text colour below against both grounds at 4.5:1.
   ========================================================================== */
:root {
  --m-app-bg: #0e120e;
  --m-surface: #1a261b;
  --m-surface-2: #243425;
  --m-line: rgba(139, 168, 143, 0.18);
  --m-fg: #e6edd5;
  --m-muted: #c4d5c6;

  --m-brand: #a2d2a4;
  --m-brand-strong: #3b823c;
  --m-brand-soft: rgba(77, 156, 78, 0.2);
  --m-on-brand: #ffffff;

  /* One hue per kind of movement, so a colour always means the same thing:
     money in, money out, a transfer between your own wallets, a bill on a
     schedule, a budget. */
  --m-in: #8fd391;
  --m-out: #ef8f74;
  --m-move: #6cc4dc;
  --m-bill: #f2b544;
  --m-budget: #b9a2e8;

  /* Plus gold: small accents only (badge, scan control once Plus is active,
     the scan meter). Never a large fill. */
  --m-gold: #e8c36c;
  --m-gold-line: #b8913a;
  --m-gold-ink: #3a2a05;
  --m-gold-sheen: linear-gradient(135deg, #f5df94 0%, #cf9d33 48%, #f2d379 100%);

  /* Category hues, more saturated than the old sage set so a donut slice and
     its row read as the same thing at a glance. */
  --m-cat-food: #ef8f74;
  --m-cat-transport: #5bbfdc;
  --m-cat-shop: #df86c9;
  --m-cat-bills: #eab04a;
  --m-cat-fun: #a796f0;
  --m-cat-health: #63c39a;
  --m-cat-home: #c7ab80;

  --m-scrim: rgba(0, 0, 0, 0.6);
  --m-shadow: 0 18px 40px rgba(0, 0, 0, 0.55);
  --m-tile-shadow: 0 1px 0 rgba(255, 255, 255, 0.03);

  --m-font-display: 'Outfit', 'IBM Plex Sans Thai Looped', system-ui, sans-serif;
  --m-font-body: 'Inter', 'IBM Plex Sans Thai Looped', system-ui, sans-serif;
}

body.light-theme {
  --m-app-bg: #f2f5f1;
  --m-surface: #ffffff;
  --m-surface-2: #e5ebe4;
  --m-line: rgba(45, 90, 47, 0.15);
  --m-fg: #1c2a1b;
  --m-muted: #4f6851;

  --m-brand: #2f6f30;
  --m-brand-soft: rgba(77, 156, 78, 0.13);

  --m-in: #2f7a35;
  --m-out: #b4472c;
  --m-move: #1f6f8b;
  --m-bill: #8a5a00;
  --m-budget: #6b4fa0;

  --m-gold: #94680c;
  --m-gold-line: #c9a24a;

  --m-cat-food: #d0592f;
  --m-cat-transport: #2a8bab;
  --m-cat-shop: #b04f97;
  --m-cat-bills: #c08415;
  --m-cat-fun: #735fcf;
  --m-cat-health: #2f8f69;
  --m-cat-home: #8a7350;

  --m-scrim: rgba(8, 14, 8, 0.45);
  --m-shadow: 0 18px 40px rgba(30, 56, 27, 0.16);
  --m-tile-shadow: 0 1px 2px rgba(30, 56, 27, 0.06), 0 6px 18px rgba(30, 56, 27, 0.06);
}

/* The hidden attribute always wins. A component that sets display (grid, flex)
   would otherwise override the UA's [hidden] { display: none } and leave an
   empty layer over the screen: the bug that blocked every tap in the mock-up
   during the 2026-10-09 review. */
[hidden] { display: none !important; }

/* ---- Pretty wrap ---------------------------------------------------------
   No single word left alone on the last line. Chromium 117+ handles `pretty`;
   older WebViews fall back to applyPrettyWrapFallback() in ui-core.js, which
   joins the last two words of [data-pretty] texts with a no-break space. */
p, li, dd, .metric-desc, .m-sub { text-wrap: pretty; }
h1, h2, h3, h4 { text-wrap: balance; }

/* ---- Icons ---------------------------------------------------------------
   One inline <symbol> sprite in index.html (#m-sprite); the CSP forbids an
   external sprite file. Each icon-only button carries its own aria-label. */
.ic {
  width: 20px;
  height: 20px;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
}
.ic-sm { width: 14px; height: 14px; }
.ic-lg { width: 26px; height: 26px; }

.m-icon-btn {
  width: 40px;
  height: 40px;
  border-radius: 12px;
  border: 0;
  background: transparent;
  color: var(--m-fg);
  display: inline-grid;
  place-items: center;
  cursor: pointer;
  flex: none;
}
.m-icon-btn:hover { background: var(--m-surface-2); }
.m-icon-btn:disabled { opacity: 0.35; cursor: default; }
.m-icon-btn:focus-visible { outline: 2px solid var(--m-brand); outline-offset: 2px; }

/* ---- Chips ---------------------------------------------------------------
   One component for categories, groups, names and wallets. A chip is a toggle
   (aria-pressed) or a removable token (.m-chip-x). 36px tall: a 24px visual
   pill would miss the 24px minimum target once the gap is counted. */
.m-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.m-chips.scroll {
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: 2px;
}
.m-chips.scroll::-webkit-scrollbar { display: none; }

.m-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--m-line);
  background: var(--m-surface);
  color: var(--m-fg);
  font: 500 14px/1.2 var(--m-font-body);
  white-space: nowrap;
  cursor: pointer;
  flex: none;
}
.m-chip .dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--chip-c, var(--m-brand));
  flex: none;
}
.m-chip[aria-pressed="true"] {
  border-color: var(--chip-c, var(--m-brand));
  background: color-mix(in srgb, var(--chip-c, var(--m-brand)) 16%, var(--m-surface));
  font-weight: 600;
}
.m-chip:focus-visible { outline: 2px solid var(--m-brand); outline-offset: 2px; }
.m-chip .m-chip-x {
  border: 0;
  background: none;
  color: var(--m-muted);
  width: 24px;
  height: 24px;
  margin: -4px -6px -4px 0;
  border-radius: 50%;
  display: grid;
  place-items: center;
  cursor: pointer;
}
.m-chip .m-chip-x:hover { background: var(--m-surface-2); color: var(--m-fg); }

/* ---- Plus gold ----------------------------------------------------------- */
.m-plus-badge {
  font: 700 10px/1 var(--m-font-display);
  letter-spacing: 0.1em;
  padding: 5px 8px;
  border-radius: 999px;
  background: var(--m-gold-sheen);
  color: var(--m-gold-ink);
}

/* ==========================================================================
   The Add sheet: Chat, Form, Scan (js/add-sheet.js)
   ========================================================================== */
.modal-window.m-add {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 18px 18px 20px;
  background: var(--m-surface);
  color: var(--m-fg);
}
.m-add .m-add-head {
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.m-add .m-add-head h3 { font: 600 22px/1.1 var(--m-font-display); margin: 0; }

.m-mode-seg {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  background: var(--m-surface-2);
  border-radius: 12px;
  padding: 3px;
  gap: 2px;
  flex: none;
}
.m-mode-seg button {
  border: 0;
  background: transparent;
  color: var(--m-muted);
  font: 600 14px var(--m-font-body);
  min-height: 40px;
  border-radius: 9px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  position: relative;
}
.m-mode-seg button[aria-selected="true"] {
  background: var(--m-surface);
  color: var(--m-fg);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
}
.m-mode-seg .ic { width: 16px; height: 16px; }
.m-mode-seg button:focus-visible { outline: 2px solid var(--m-brand); outline-offset: 1px; }
/* The scan control is gold once Plus is active (small accent only). */
body.plus-active .m-mode-seg .m-scan-tab { color: var(--m-gold); }

/* ---- Form ------------------------------------------------------------- */
.m-form { display: flex; flex-direction: column; gap: 14px; }
.m-form .type-switch { gap: 8px; }
.m-form .type-opt { min-height: 44px; flex-direction: row; gap: 4px; border-radius: 14px; white-space: nowrap; padding: 6px 2px; font-size: 14px; }
.m-form .type-opt-move.is-checked {
  color: var(--m-move);
  border-color: var(--m-move);
  background: color-mix(in srgb, var(--m-move) 12%, transparent);
}

.m-amount-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 2px 0 6px;
  border-bottom: 2px solid var(--m-line);
}
.m-add[data-type="expense"] .m-amount-row:focus-within { border-bottom-color: var(--m-out); }
.m-add[data-type="income"] .m-amount-row:focus-within { border-bottom-color: var(--m-in); }
.m-add[data-type="transfer"] .m-amount-row:focus-within { border-bottom-color: var(--m-move); }
.m-cur {
  border: 1px solid var(--m-line);
  background: var(--m-app-bg);
  color: var(--m-fg);
  border-radius: 10px;
  padding: 8px 6px;
  font: 600 13px var(--m-font-body);
  flex: none;
  max-width: 96px;
}
.m-amount-in {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--m-fg);
  font: 600 40px/1.1 var(--m-font-display);
  text-align: right;
  font-variant-numeric: tabular-nums;
  outline: none;
  padding: 0;
  -moz-appearance: textfield;
}
.m-amount-wrap { position: relative; flex: 1; min-width: 0; display: flex; }
.m-amount-wrap .m-amount-ghost {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  font: 600 40px/1.1 var(--m-font-display);
  color: var(--m-line);
  pointer-events: none;
}
.m-amount-wrap.has-value .m-amount-ghost { display: none; }
.m-amount-in::-webkit-outer-spin-button,
.m-amount-in::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.m-lab {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--m-muted);
  margin: 0 0 8px;
  display: flex;
  justify-content: space-between;
  gap: 8px;
}
.m-lab em { font-style: normal; font-weight: 500; letter-spacing: 0; text-transform: none; text-align: right; }
.m-small {
  display: block;
  color: var(--m-muted);
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
}
.m-split-chip { --chip-c: var(--m-fg); }

.m-splitbox { margin-top: 10px; }
.m-splitbar { display: flex; gap: 2px; height: 10px; border-radius: 99px; overflow: hidden; background: var(--m-surface-2); }
.m-splitbar i { display: block; min-width: 4px; }
.m-parts { display: grid; margin-top: 8px; }
.m-part { display: flex; align-items: center; gap: 8px; font-size: 14px; min-height: 40px; }
.m-part .dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.m-part-name { flex: 1; font-weight: 500; }
.m-part-in, .m-part-rest {
  width: 104px;
  text-align: right;
  font: 600 15px var(--m-font-display);
  font-variant-numeric: tabular-nums;
}
.m-part-in {
  border: 0;
  border-bottom: 1.5px solid var(--m-line);
  background: transparent;
  color: var(--m-fg);
  padding: 6px 0;
  outline: none;
}
.m-part-in:focus { border-bottom-color: var(--m-brand); }
.m-part-rest { color: var(--m-muted); }
.m-split-note { font-size: 13px; color: var(--m-muted); margin: 8px 0 0; }
.m-split-warn { font-size: 13px; color: var(--m-out); margin: 8px 0 0; font-weight: 600; }

.m-pair { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 10px; }
.m-pair.one { grid-template-columns: minmax(0, 200px); }
.m-picktile, .m-rcard {
  border-radius: 16px;
  border: 1px solid var(--m-line);
  background: var(--m-app-bg);
  padding: 9px 12px;
  color: var(--m-fg);
  min-width: 0;
  display: grid;
  gap: 2px;
}
.m-tile-select, .m-tile-date {
  width: 100%;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--m-fg);
  font: 600 16px/1.3 var(--m-font-display);
  padding: 2px 0;
  outline: none;
}
.m-tile-date { font-size: 14px; }
.m-tile-select:focus-visible, .m-tile-date:focus-visible { outline: 2px solid var(--m-brand); outline-offset: 2px; border-radius: 4px; }
.m-tile-sub { font-size: 12px; color: var(--m-muted); font-variant-numeric: tabular-nums; }

.m-route { display: grid; gap: 0; }
.m-rcard {
  background: color-mix(in srgb, var(--m-move) 9%, var(--m-app-bg));
  border: 1.5px solid color-mix(in srgb, var(--m-move) 45%, transparent);
}
.m-rmid {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 46px;
  padding-left: 22px;
  border-left: 2px dashed color-mix(in srgb, var(--m-move) 55%, transparent);
  margin-left: 18px;
}
.m-ramt { flex: 1; font: 600 15px var(--m-font-display); color: var(--m-move); font-variant-numeric: tabular-nums; }
.m-routes { margin-top: 10px; align-items: center; }
.m-lead { font-size: 12px; color: var(--m-muted); }

.m-note-in {
  width: 100%;
  border: 0;
  border-bottom: 1px solid var(--m-line);
  background: transparent;
  color: var(--m-fg);
  font-size: 15px;
  padding: 8px 0;
  outline: none;
}
.m-note-in:focus { border-bottom-color: var(--m-brand); }
.m-saves-as { font-size: 12px; color: var(--m-muted); margin: 8px 0 0; min-height: 1em; }
.m-saves-as b { color: var(--m-fg); }

.m-form .m-save {
  flex: 1;
  width: 100%;
  min-height: 50px;
  border-radius: 16px;
  font: 600 17px var(--m-font-display);
  margin-top: 2px;
}

/* ---- Chat ------------------------------------------------------------- */
.m-chat { display: flex; flex-direction: column; min-height: 0; flex: 1; }
.m-thread {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 4px 0 8px;
  overflow-y: auto;
  min-height: 160px;
  max-height: 46vh;
}
.m-thread-empty { color: var(--m-muted); font-size: 14px; line-height: 1.5; margin: auto 0; text-align: center; }
.m-day-sep {
  align-self: center;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--m-muted);
  padding: 2px 10px;
  border-radius: 999px;
  background: var(--m-surface-2);
}
.m-bub { max-width: 86%; padding: 9px 12px; border-radius: 16px; font-size: 14px; line-height: 1.45; }
.m-bub.me { align-self: flex-end; background: var(--m-brand-strong); color: var(--m-on-brand); border-bottom-right-radius: 5px; }
.m-bub.mi { align-self: flex-start; background: var(--m-surface-2); color: var(--m-fg); border-bottom-left-radius: 5px; }
.m-bub .m-chips { margin-top: 8px; }
.m-acts { display: flex; gap: 16px; margin-top: 6px; }
.m-acts button {
  border: 0;
  background: none;
  color: var(--m-brand);
  font-weight: 600;
  font-size: 13px;
  padding: 6px 0;
  min-height: 32px;
  cursor: pointer;
}
.m-composer { border-top: 1px solid var(--m-line); padding-top: 10px; }
.m-preview { display: flex; flex-wrap: wrap; gap: 6px; min-height: 30px; margin-bottom: 8px; align-items: center; }
.m-pv {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  font-weight: 500;
  padding: 4px 9px;
  border-radius: 999px;
  background: var(--m-surface-2);
  color: var(--m-fg);
}
.m-pv .dot { width: 8px; height: 8px; border-radius: 50%; }
.m-pv-amt { font-weight: 700; color: var(--k); background: color-mix(in srgb, var(--k) 13%, transparent); }
.m-pv.none { color: var(--m-bill); background: transparent; border: 1px dashed var(--m-bill); }
.m-pv-ask { font-size: 12px; font-weight: 600; color: var(--m-bill); }
.m-preview .m-chip { min-height: 32px; padding: 4px 10px; font-size: 13px; }
.m-try {
  border: 1px dashed var(--m-line);
  background: transparent;
  color: var(--m-fg);
  border-radius: 999px;
  padding: 6px 10px;
  min-height: 32px;
  font-size: 13px;
  cursor: pointer;
}
.m-compose-row { display: flex; gap: 8px; align-items: center; }
.m-compose-in {
  flex: 1;
  min-width: 0;
  border: 1.5px solid var(--m-line);
  border-radius: 999px;
  padding: 11px 16px;
  background: var(--m-app-bg);
  color: var(--m-fg);
  font-size: 16px;
  outline: none;
}
.m-compose-in:focus { border-color: var(--m-brand); }
.m-send {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 0;
  background: var(--m-brand-strong);
  color: var(--m-on-brand);
  display: grid;
  place-items: center;
  cursor: pointer;
  flex: none;
}
.m-send:disabled { opacity: 0.4; cursor: default; }
/* Voice entry: the quieter twin of send, so send stays the one strong button. */
.m-mic {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 1.5px solid var(--m-line);
  background: var(--m-app-bg);
  color: var(--m-brand-strong);
  display: grid;
  place-items: center;
  cursor: pointer;
  flex: none;
}
.m-mic[hidden] { display: none; }

/* ---- Transactions search (js/ledger-search.js) ------------------------- */
.ledger-filter-selects { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 769px) {
  .ledger-filter-selects { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .ledger-search-hint { flex: 1 0 100%; }
}
.ledger-search-hint { margin: 0; font-size: 13px; color: var(--m-muted, var(--m-fg)); }
.ledger-search-hint[hidden] { display: none; }
.ledger-result-summary { margin: 4px 0 12px; font-size: 14px; font-weight: 600; font-variant-numeric: tabular-nums; }
.ledger-result-summary[hidden] { display: none; }

/* ---- Receipt photo on an entry (js/receipts.js) ------------------------ */
.receipt-field { display: flex; }
.receipt-pick, .receipt-has { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.receipt-pick-btn { cursor: pointer; }
.receipt-thumb {
  width: 64px;
  height: 64px;
  padding: 0;
  border: 1.5px solid var(--m-line);
  border-radius: 12px;
  overflow: hidden;
  background: var(--m-line);
  cursor: pointer;
}
.receipt-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.receipt-elsewhere { margin: 0; font-size: 14px; color: var(--m-muted, var(--m-fg)); }
.receipt-viewer-img { display: block; width: 100%; max-height: 70vh; object-fit: contain; border-radius: 12px; }
.tx-receipt-ic { margin-left: 6px; vertical-align: -2px; opacity: 0.7; }

/* ---- People: lent and borrowed (js/people.js) ------------------------- */
.people-section { margin-top: 28px; display: grid; gap: 12px; }
.people-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.people-head h3 { margin: 0; }
.people-summary span { display: block; white-space: nowrap; }
.people-head .btn-secondary { white-space: nowrap; flex-shrink: 0; }
.people-summary { margin: 4px 0 0; color: var(--m-muted, var(--m-fg)); font-size: 14px; font-variant-numeric: tabular-nums; }
.people-empty, .people-hint { margin: 0; color: var(--m-muted, var(--m-fg)); font-size: 14px; }
.people-list { display: grid; gap: 8px; }
.people-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 8px 12px;
  align-items: center;
  padding: 12px 14px;
  border: 1.5px solid var(--m-line);
  border-radius: 16px;
  background: var(--m-app-bg);
}
.people-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--m-brand-strong);
  color: var(--m-on-brand);
  font-weight: 600;
}
.people-main { display: grid; min-width: 0; }
.people-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.people-status { font-size: 14px; font-variant-numeric: tabular-nums; }
.people-row[data-status="owesYou"] .people-status { color: var(--m-in); }
.people-row[data-status="youOwe"] .people-status { color: var(--m-out); }
.people-actions { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 6px; }
.people-btn {
  min-height: 36px;
  padding: 0 14px;
  border-radius: 999px;
  border: 1.5px solid var(--m-line);
  background: transparent;
  color: var(--m-fg);
  cursor: pointer;
}
.people-btn-strong { background: var(--m-brand-strong); border-color: var(--m-brand-strong); color: var(--m-on-brand); }
.people-icon-btn {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 0;
  background: transparent;
  color: var(--m-fg);
  display: grid;
  place-items: center;
  cursor: pointer;
}
.people-tools { display: flex; gap: 2px; }
.people-btn:focus-visible, .people-icon-btn:focus-visible { outline: 2px solid var(--m-brand); outline-offset: 2px; }

/* ---- Savings goals (js/goals.js) --------------------------------------- */
.goals-list { display: grid; gap: 10px; }
.goals-empty { margin: 0; color: var(--m-muted, var(--m-fg)); font-size: 14px; max-width: 60ch; }
.goal-row {
  display: grid;
  gap: 8px;
  padding: 14px 16px;
  border: 1.5px solid var(--m-line);
  border-radius: 16px;
  background: var(--m-app-bg);
}
.goal-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.goal-name { font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.goal-tools { display: flex; gap: 2px; flex-shrink: 0; }
.goal-bar { height: 10px; border-radius: 999px; background: var(--m-line); overflow: hidden; }
.goal-bar span { display: block; height: 100%; border-radius: inherit; background: var(--m-brand-strong); }
.goal-row[data-state="reached"] .goal-bar span { background: var(--m-in); }
.goal-row[data-state="overdue"] .goal-status { color: var(--m-out); }
.goal-figures { display: flex; justify-content: space-between; gap: 8px; font-size: 14px; font-variant-numeric: tabular-nums; }
.goal-status { margin: 0; font-size: 14px; color: var(--m-muted, var(--m-fg)); }
.goal-card-bar { flex-shrink: 0; height: 4px; margin-top: 6px; border-radius: 999px; background: rgba(255, 255, 255, 0.25); overflow: hidden; }
.goal-card-bar span { display: block; height: 100%; background: #fff; border-radius: inherit; }
.m-mic:focus-visible { outline: 2px solid var(--m-brand); outline-offset: 2px; }

/* ---- Scan ------------------------------------------------------------- */
.m-scan-pane { display: grid; gap: 12px; }
.m-scan-target {
  display: grid;
  justify-items: center;
  gap: 6px;
  text-align: center;
  padding: 28px 18px;
  border-radius: 20px;
  border: 2px dashed color-mix(in srgb, var(--m-brand) 55%, transparent);
  background: var(--m-brand-soft);
  color: var(--m-fg);
  cursor: pointer;
}
.m-scan-target b { font: 600 19px var(--m-font-display); }
.m-scan-target span { font-size: 14px; color: var(--m-muted); line-height: 1.45; max-width: 32ch; }
body.plus-active .m-scan-target { border-color: var(--m-gold-line); }
.m-tip { display: flex; gap: 8px; align-items: flex-start; font-size: 13px; color: var(--m-muted); margin: 0; line-height: 1.45; }

/* ---- Save toast with Undo --------------------------------------------- */
.m-toast {
  position: fixed;
  left: 16px;
  right: 16px;
  bottom: calc(var(--bottom-nav-height, 64px) + env(safe-area-inset-bottom) + 18px);
  z-index: 1200;
  max-width: 480px;
  margin: 0 auto;
  background: var(--m-fg);
  color: var(--m-app-bg);
  border-radius: 14px;
  padding: 12px 14px;
  font-size: 14px;
  display: flex;
  align-items: center;
  gap: 10px;
  box-shadow: var(--m-shadow);
}
.m-toast span { flex: 1; }
.m-toast button {
  border: 0;
  background: none;
  color: inherit;
  font-weight: 700;
  text-decoration: underline;
  cursor: pointer;
  min-height: 32px;
  padding: 0 4px;
}

/* ---- Scan results (UI-POLISH-PLAN.md phase 4) -----------------------------
   Each slip is a card: the headline (title, amount, day, why), then the two
   things a slip cannot tell us (wallet, category), then the rest folded away. */
.slip-summary { display: grid; gap: 4px; }
.slip-summary p { margin: 0; color: var(--m-fg); font-size: 14px; }
.slip-summary p + p { color: var(--m-muted); font-size: 13px; }

.slip-wallet-all {
  position: sticky; top: 0; z-index: 2;
  display: grid; grid-template-columns: 1fr auto; gap: 6px 8px; align-items: center;
  padding: 8px 10px; border: 1px solid var(--m-line); border-radius: 12px;
  background: var(--m-surface-2); font-size: 13px; color: var(--m-muted);
}
.slip-wallet-all label { grid-column: 1 / -1; }
.slip-wallet-all .form-control { min-height: 40px; }
.slip-wallet-all button { min-height: 40px; }

.slip-review-row { background: var(--m-surface); border-color: var(--m-line); border-radius: 14px; }
.slip-row-text { display: grid; gap: 2px; min-width: 0; flex: 1; }
.slip-row-top { display: flex; justify-content: space-between; gap: 10px; color: var(--m-fg); font-size: 15px; }
.slip-row-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.slip-row-amount { flex: none; font-variant-numeric: tabular-nums; }
.slip-row-when { color: var(--m-muted); font-size: 12px; }
.slip-row-reason { color: var(--m-muted); font-size: 12px; line-height: 1.4; }
/* Logged twice? A fieldset grows to its widest child, so the choice is held to the row. */
.slip-review-row, .slip-review-row > *, .slip-row-text, .slip-row-top { min-width: 0; }
.slip-twin-choice select { width: 100%; max-width: 100%; min-width: 0; }

/* auto-fit: when the category is hidden (a transfer, or no direction yet) the
   wallet takes the whole row. */
/* align-items: end keeps the two boxes level when one label wraps (· check, · same as last time). */
.slip-row-pair { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 8px; align-items: end; }
.slip-row-pair .slip-review-field { min-width: 0; }
.slip-row-pair .slip-review-field[hidden] { display: none; }
/* The word comes from js/slip-scan.js (slip.checkFlag), so it follows the language. */
.slip-needs-check > span[data-flag]::after {
  content: " · " attr(data-flag); color: var(--m-bill); font-weight: 600;
}
.slip-needs-check .form-control { border-color: var(--m-bill); }
/* The category the payee's last entry went in (slip.sameAsLast). */
.slip-remembered > span[data-flag]::after {
  content: " · " attr(data-flag); color: var(--m-brand-strong); font-weight: 600;
}

.slip-row-details { display: grid; gap: 8px; }
.slip-row-details > summary {
  cursor: pointer; min-height: 36px; display: flex; align-items: center;
  color: var(--m-brand-strong); font-size: 13px; font-weight: 600;
}
.slip-row-details[open] { display: grid; gap: 10px; }
/* A pay-later list: one line per bill, the day and the amount, a note under. */
.slip-paylater-bill {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; column-gap: 10px; align-items: center;
  min-height: 40px; font-size: 14px; font-variant-numeric: tabular-nums;
}
.slip-paylater-bill small { grid-column: 2 / -1; color: var(--m-muted); font-size: 12px; }
.slip-paylater-bill small:empty { display: none; }
.slip-paylater-bill:has(input:disabled) { opacity: 0.6; }
/* Stacked, so "New: Pay later & instalments" reads in full at phone width. */
.slip-paylater-row .slip-row-pair { grid-template-columns: 1fr; }

/* Names as tags: chips with ×, then an input and Add. */
.m-tags { display: grid; gap: 8px; }
.m-tags > label { font-size: 12px; color: var(--m-muted); }
.m-tags .m-chips:empty { display: none; }
.m-tag-add { display: grid; grid-template-columns: 1fr auto; gap: 8px; }
.m-tag-add button { min-height: 44px; }

/* ---- Edit (js/edit-sheet.js): the Add Form, plus where it came from, a name,
   what will change, and Delete ---- */
.m-edit-head { display: grid; gap: 8px; margin-top: -4px; }
.m-edit-head[hidden] { display: none; }
.m-edit-src { margin: 0; font-size: 13px; color: var(--m-muted); line-height: 1.4; }
.m-group-chip .ic:last-child { width: 12px; height: 12px; color: var(--m-muted); }
.m-edit-diff { margin: 0; font-size: 12px; color: var(--m-muted); line-height: 1.5; display: flex; flex-wrap: wrap; gap: 2px 10px; }
.m-edit-diff b { color: var(--m-fg); font-weight: 600; }
.m-edit-diff span { color: var(--m-fg); font-variant-numeric: tabular-nums; }
.m-save-row { display: flex; gap: 10px; align-items: center; }
.m-del-btn { flex: none; min-height: 50px; padding: 0 18px; border-radius: 16px; border: 1.5px solid color-mix(in srgb, var(--m-out) 45%, transparent); background: transparent; color: var(--m-out); font: 600 15px var(--m-font-display); cursor: pointer; }
.m-del-btn:focus-visible { outline: 2px solid var(--m-out); outline-offset: 2px; }

/* ---- The scan coach tip: under the Scan tab, the first time only ---- */
.m-coach-anchor { position: relative; height: 0; margin-top: -12px; z-index: 5; }
.m-coach { position: absolute; top: 8px; right: 0; width: min(240px, 72%); margin: 0; background: var(--m-fg); color: var(--m-surface); padding: 12px 14px; border-radius: 14px; font-size: 13px; line-height: 1.4; box-shadow: var(--m-shadow); }
.m-coach[hidden] { display: none; }
.m-coach::before { content: ""; position: absolute; top: -6px; right: calc(16.6% - 6px); width: 12px; height: 12px; background: var(--m-fg); transform: rotate(45deg); }
.m-coach b { display: block; margin-bottom: 2px; }

/* ---- Onboarding: three ways to add ---- */
.onboarding-ways { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.onboarding-ways li { display: flex; align-items: flex-start; gap: 12px; padding: 12px; border: 1px solid var(--m-line); border-radius: 14px; background: var(--m-surface); color: var(--m-fg); }
.onboarding-ways .ow-ic { flex: none; width: 36px; height: 36px; border-radius: 12px; display: grid; place-items: center; background: var(--m-brand-soft); color: var(--m-brand); }
.onboarding-ways .ow-ic .ic { width: 18px; height: 18px; }
.onboarding-ways .ow-txt { flex: 1; min-width: 0; display: grid; gap: 3px; }
.onboarding-ways .ow-txt b { font: 600 15px var(--m-font-display); }
.onboarding-ways .ow-txt small { font-size: 13px; color: var(--m-muted); line-height: 1.4; }
.onboarding-ways .ow-bubble { justify-self: start; margin-top: 4px; padding: 6px 12px; border-radius: 14px 14px 14px 4px; background: var(--m-brand-strong); color: var(--m-on-brand); font-size: 14px; font-weight: 600; }
.ow-slip { flex: none; width: 48px; height: 63px; align-self: center; }
.ow-slip .ow-paper { fill: var(--m-app-bg); stroke: var(--m-line); stroke-width: 1.5; }
.ow-slip .ow-bank { fill: var(--m-move); }
.ow-slip .ow-line { fill: var(--m-line); }
.ow-slip .ow-amt { fill: var(--m-fg); font: 700 13px var(--m-font-display); }
.ow-slip .ow-ok { fill: var(--m-brand-strong); }
.ow-slip .ow-tick { fill: none; stroke: var(--m-on-brand); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

/* ---- Settings: Scan Slips ---- */
.scan-allowance { font-weight: 600; margin: 0 0 10px; }
.scan-share-hint { font-size: 13px; color: var(--m-muted); margin: 10px 0 0; }
.slip-shared-count { font-weight: 600; font-size: 16px; margin: 0 0 8px; }
.settings-subhead { font-size: 15px; margin: 20px 0 6px; }
.scan-how { margin-top: 16px; font-size: 13px; }
.scan-how summary { cursor: pointer; font-weight: 600; min-height: 32px; display: flex; align-items: center; }
.scan-how ul { margin: 6px 0 0; padding-left: 18px; display: grid; gap: 6px; line-height: 1.45; }

/* Find new slips (js/slip-watch.js): the Overview card and its Settings block. */
/* margin-top clears .mo-head-tools, which sits absolutely at the pane's top right. */
.slip-watch-card { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 10px 12px; margin: 44px 0 16px; padding: 14px 16px; border-radius: 16px; background: var(--m-brand-soft); color: var(--m-fg); }
.slip-watch-card[hidden] { display: none; }
.slip-watch-card .ic { width: 22px; height: 22px; color: var(--m-brand-strong); }
.slip-watch-card p { margin: 0; font-weight: 600; font-size: 15px; line-height: 1.35; text-wrap: pretty; }
.slip-watch-card-actions { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 8px; }
.slip-watch-card-actions button { min-height: 44px; }
.slip-watch-toggle { display: flex; align-items: center; gap: 8px; cursor: pointer; font-weight: 500; font-size: 13px; min-height: 44px; }
.slip-watch-toggle input { width: 16px; height: 16px; accent-color: var(--green-matcha); cursor: pointer; }
.slip-watch-status { font-size: 12px; opacity: 0.75; margin: 4px 0 10px; }
.slip-watch-status:empty { display: none; }
.slip-watch-range { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; margin: 0 0 10px; }
.slip-watch-range label { display: grid; gap: 4px; font-size: 13px; font-weight: 500; }

/* Import from CSV (js/csv-import-ui.js) and from a bank statement (js/statement-import-ui.js). */
.csv-import-checked { font-size: 14px; color: var(--m-in); font-weight: 600; }
.statement-error { color: var(--m-out); font-size: 14px; }
.csv-import .btn-secondary { width: 100%; }
.csv-import { display: grid; gap: 12px; }
.csv-import p { margin: 0; }
.csv-import h4 { margin: 8px 0 0; font-size: 14px; }
.csv-import-file, .csv-import-note { font-size: 13px; color: var(--m-muted); overflow-wrap: anywhere; }
.csv-import-summary { font-size: 15px; }
.csv-import-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); gap: 8px; align-items: center; font-size: 14px; }
.csv-import-row > span { overflow-wrap: anywhere; }
.csv-import-row small { display: block; color: var(--m-muted); font-size: 12px; }
.csv-import-row .form-control { min-width: 0; width: 100%; }
.csv-import details { border-top: 1px solid var(--m-line); padding-top: 8px; }
.csv-import details[open] { display: grid; gap: 8px; }
.csv-import summary { cursor: pointer; font-weight: 600; min-height: 36px; display: flex; align-items: center; }
.csv-import-skipped ul { margin: 0; padding-left: 18px; display: grid; gap: 4px; font-size: 13px; line-height: 1.45; }
.csv-import [data-csv-run][disabled] { opacity: 0.5; cursor: not-allowed; }
@media (max-width: 420px) { .csv-import-row { grid-template-columns: 1fr; gap: 4px; } }
