/* Libney — tokens from the Claude Design mockup.
   Theme (light/dark) is a global Chase-controlled setting, applied via
   [data-theme] on <html>. Type scale/density is role-based via [data-role]. */

:root {
  --copper: #C0793D;
  --emerald: #10B981;
  --emerald-bright: #34D399;
  --amber: #F59E0B;
  --amber-bg: rgba(245, 158, 11, 0.14);
  --red: #F87171;

  --radius-lg: 22px;
  --radius-md: 14px;
  --radius-sm: 10px;
  --font: 'Segoe UI', system-ui, -apple-system, sans-serif;
}

/* Dark (default) */
:root,
:root[data-theme="dark"] {
  --bg: #0d1418;
  --bg-elevated: #141b1f;
  --bg-elevated-2: #1b2327;
  --text: #e8f1ee;
  --text-muted: rgba(232, 241, 238, 0.58);
  --border: rgba(255, 255, 255, 0.08);
  --shadow: 0 18px 50px rgba(0, 0, 0, 0.45);
}

:root[data-theme="light"] {
  --bg: #faf9f5;
  --bg-elevated: #ffffff;
  --bg-elevated-2: #f4f2ec;
  --text: #1a201d;
  --text-muted: #6b7280;
  --border: rgba(0, 0, 0, 0.08);
  --shadow: 0 10px 30px rgba(20, 20, 10, 0.08);
}

* { box-sizing: border-box; }

html, body {
  background: var(--bg);
  color: var(--text);
}

body {
  margin: 0;
  font-family: var(--font);
  /* Almost everything sizes in em, so scaling this one value scales the whole
     app rather than only the body text. */
  font-size: calc(15px * var(--text-scale, 1));
  -webkit-font-smoothing: antialiased;
}

body[data-role="viewer"] { font-size: 19px; }

button, input, select { font-family: inherit; }

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

/* --- Shell / navigation --------------------------------------------- */

#viewport {
  max-width: 480px;
  margin: 0 auto;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
}

.app-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 18px 18px 8px;
}
.app-header .brand-mark { font-size: 22px; }
.app-header .titles { flex: 1; min-width: 0; }
.app-header .titles h1 {
  margin: 0;
  font-size: 1.15em;
  font-weight: 800;
}
.app-header .titles .subtitle { font-size: 0.8em; color: var(--text-muted); }

.nav-btn {
  border: none;
  background: var(--bg-elevated-2);
  color: var(--text);
  border-radius: 999px;
  padding: 10px 16px;
  font-size: 0.85em;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
}
body[data-role="viewer"] .nav-btn { padding: 14px 20px; font-size: 0.9em; min-height: 48px; }
.nav-btn.back::before { content: "← "; }

.screen { padding: 4px 18px 100px; display: flex; flex-direction: column; gap: 16px; }
.screen[hidden] { display: none; }

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

.card {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px;
  box-shadow: var(--shadow);
}
.card h2 { margin: 0 0 12px; font-size: 1em; font-weight: 700; }

/* --- Home: balance hero ------------------------------------------------- */

.balance-hero .label { color: var(--text-muted); font-size: 0.8em; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.balance-hero .amount { font-size: 2.2em; font-weight: 800; margin-top: 4px; }
.balance-hero .amount .cents { font-size: 0.55em; color: var(--text-muted); font-weight: 700; }
.balance-hero .delta { margin-top: 6px; font-size: 0.85em; }
.balance-hero .delta.up { color: var(--emerald-bright); }
.balance-hero .delta.down { color: var(--red); }

/* --- Alerts -------------------------------------------------------------- */

.alerts-card {
  border: 1.5px solid var(--amber);
  background: var(--amber-bg);
}
.alerts-card h2 { display: flex; align-items: center; gap: 8px; }
.alerts-list { display: flex; flex-direction: column; gap: 10px; }
.alert-item { display: flex; justify-content: space-between; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--border); }
.alert-item:last-child { border-bottom: none; }
.alert-item .alert-title { font-weight: 700; font-size: 0.92em; }
.alert-item .alert-body { color: var(--text-muted); font-size: 0.85em; margin-top: 2px; }
.alert-item .alert-amount { font-weight: 800; white-space: nowrap; }
.alerts-actions { display: flex; gap: 10px; margin-top: 4px; }
.btn-primary, .btn-secondary, .btn-quiet {
  border: none; border-radius: 999px; padding: 10px 18px; font-weight: 700; font-size: 0.88em; cursor: pointer;
}
.btn-primary { background: var(--emerald); color: #05130c; }
.btn-secondary { background: var(--bg-elevated-2); color: var(--text); }
.btn-full { width: 100%; padding: 16px; border-radius: var(--radius-md); font-size: 1em; text-align: center; }

/* --- Accounts ------------------------------------------------------------ */

.institution-group { margin-bottom: 14px; }
.institution-group:last-child { margin-bottom: 0; }
.institution-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; color: var(--text-muted); font-size: 0.82em; font-weight: 700; }
.monogram {
  width: 30px; height: 30px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.72em; font-weight: 800; color: #fff;
  background: var(--copper); flex-shrink: 0;
}
.account-row { display: flex; justify-content: space-between; align-items: center; padding: 10px 0; gap: 10px; }
.account-row .name { font-weight: 700; font-size: 0.92em; }
.account-row .name .flag { color: var(--amber); font-weight: 700; font-size: 0.8em; margin-left: 6px; }
.account-row .meta { color: var(--text-muted); font-size: 0.78em; }
.account-row .right { text-align: right; }
.account-row .balance { font-weight: 800; }
.account-row .balance.negative { color: var(--text); }
.account-row .balance.positive { color: var(--emerald-bright); }
.sparkline { display: block; margin-top: 2px; }

/* --- Spend chart / movers -------------------------------------------------- */

.pill-row { display: flex; gap: 8px; flex-wrap: wrap; }
.pill {
  border: none; background: var(--bg-elevated-2); color: var(--text-muted);
  border-radius: 999px; padding: 8px 14px; font-size: 0.82em; font-weight: 700; cursor: pointer;
}
.pill.active { background: var(--emerald); color: #05130c; }
body[data-role="viewer"] .pill { padding: 12px 18px; font-size: 0.85em; }

.spend-total { font-size: 1.5em; font-weight: 800; margin: 10px 0 4px; }
.spend-caption { color: var(--text-muted); font-size: 0.8em; }
.chart-wrap { margin: 10px 0; }

.movers-row { display: flex; gap: 16px; align-items: center; margin-top: 8px; }
.movers-donut { flex-shrink: 0; }
.movers-list { flex: 1; display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.movers-list .row { display: flex; justify-content: space-between; font-size: 0.85em; }
.movers-list .row .cat { display: flex; align-items: center; gap: 6px; }
.movers-list .swatch { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }

/* --- Transactions --------------------------------------------------------- */

.txn-day-label { color: var(--text-muted); font-size: 0.78em; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; margin: 10px 0 4px; }
.txn-row { display: flex; align-items: center; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--border); }
.txn-row:last-child { border-bottom: none; }
.txn-row .txn-main { flex: 1; min-width: 0; }
.txn-row .txn-payee { font-weight: 700; font-size: 0.92em; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.txn-row .txn-meta { color: var(--text-muted); font-size: 0.78em; }
.txn-row .txn-amount { font-weight: 800; white-space: nowrap; }
.txn-row .txn-amount.positive { color: var(--emerald-bright); }
.badge { font-size: 0.68em; font-weight: 800; text-transform: uppercase; letter-spacing: .03em; padding: 2px 7px; border-radius: 999px; }
.badge.unusual { background: var(--amber-bg); color: var(--amber); }
.badge.wrong-account { background: rgba(248,113,113,0.15); color: var(--red); }

/* --- Settings -------------------------------------------------------------- */

.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 14px; }
.tabs button {
  border: none; background: none; color: var(--text-muted); font-weight: 700; font-size: 0.9em;
  padding: 10px 4px; margin-right: 18px; cursor: pointer; border-bottom: 2px solid transparent;
}
.tabs button.active { color: var(--text); border-bottom-color: var(--emerald); }
.tab-panel[hidden] { display: none; }

.settings-account-row, .user-row { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 12px 0; border-bottom: 1px solid var(--border); }
.settings-account-row:last-child, .user-row:last-child { border-bottom: none; }
.settings-account-row .name, .user-row .email { font-weight: 700; font-size: 0.9em; }
.settings-account-row .institution, .user-row .meta { color: var(--text-muted); font-size: 0.78em; }
.settings-account-row select {
  border: 1.5px solid var(--emerald); background: transparent; color: var(--text);
  border-radius: 999px; padding: 6px 10px; font-size: 0.8em; font-weight: 700;
}
.user-row .actions { display: flex; gap: 6px; flex-wrap: wrap; }
.user-row .actions button { font-size: 0.75em; padding: 6px 10px; }
.user-row .actions button.danger { background: rgba(248,113,113,0.15); color: var(--red); }
.user-row .toggle-row { display: flex; align-items: center; gap: 8px; font-size: 0.78em; color: var(--text-muted); margin-top: 4px; }

.add-user-form, .theme-form { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.add-user-form input, .add-user-form select, .theme-form input, .theme-form select {
  border: 1px solid var(--border); background: var(--bg-elevated-2); color: var(--text);
  border-radius: var(--radius-sm); padding: 10px 12px; font-size: 0.9em;
}
.theme-form label { font-size: 0.85em; font-weight: 700; display: flex; align-items: center; gap: 8px; }

.usage-bar { background: var(--bg-elevated-2); border-radius: 999px; height: 20px; overflow: hidden; margin: 8px 0; }
.usage-fill { height: 100%; background: var(--emerald); }
.usage-breakdown { display: flex; gap: 16px; margin-top: 10px; font-size: 0.82em; color: var(--text-muted); }
.usage-breakdown b { display: block; color: var(--text); font-size: 1.1em; }

/* --- Auth screens --------------------------------------------------------- */

.auth-screen { min-height: 100dvh; display: grid; grid-template-columns: 1fr; }
.auth-screen[hidden] { display: none; }
.auth-card { max-width: 360px; width: 100%; text-align: center; }
.auth-brand { font-size: 1.6em; font-weight: 800; margin-bottom: 30px; display: flex; align-items: center; justify-content: center; gap: 8px; }
.auth-brand .copper { color: var(--copper); }
.auth-brand .emerald { color: var(--emerald); }
.auth-step p { color: var(--text-muted); margin: 0 0 16px; }
.auth-step input {
  width: 100%; padding: 14px 16px; border-radius: var(--radius-md); border: 1px solid var(--border);
  background: var(--bg-elevated); color: var(--text); font-size: 1em; margin-bottom: 12px;
}
.auth-step button[type="submit"], .auth-step > button {
  width: 100%; padding: 14px; border: none; border-radius: var(--radius-md);
  background: var(--emerald); color: #05130c; font-weight: 800; font-size: 1em; cursor: pointer;
}
.auth-error { color: var(--red); font-size: 0.85em; margin-top: 10px; }
.checklist { text-align: left; background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 16px; margin: 16px 0; }
.checklist .item { display: flex; gap: 10px; align-items: flex-start; padding: 6px 0; font-size: 0.9em; }
.checklist .item::before { content: "✓"; color: var(--emerald-bright); font-weight: 800; }

/* --- Collapse / disclosure (Grandma's fixed layout) --------------------- */

.disclosure-toggle {
  width: 100%; text-align: center; background: var(--bg-elevated-2); border: none; color: var(--text);
  border-radius: var(--radius-sm); padding: 10px; font-weight: 700; font-size: 0.85em; cursor: pointer; margin-top: 6px;
}
.disclosure-scroll { max-height: 140px; overflow-y: auto; }
.no-page-scroll { height: 100dvh; overflow: hidden; }

.footer-signout { text-align: center; color: var(--text-muted); font-size: 0.8em; padding: 16px 0 4px; }
.footer-signout button { background: none; border: none; color: var(--emerald-bright); font-weight: 700; cursor: pointer; padding: 0; font-size: 1em; }

/* --- Assistant panel -------------------------------------------------------- */

.chat-fab {
  position: fixed; bottom: 20px; right: max(20px, calc((100vw - 480px) / 2 + 20px));
  width: 60px; height: 60px; border-radius: 50%; border: none;
  background: var(--emerald); color: #05130c; font-size: 1.6em; box-shadow: var(--shadow); cursor: pointer; z-index: 40;
}
.chat-panel {
  position: fixed; bottom: 0; right: 0; left: 0; margin: 0 auto; max-width: 480px;
  height: min(600px, 82dvh); background: var(--bg-elevated); border-radius: 22px 22px 0 0;
  box-shadow: var(--shadow); display: flex; flex-direction: column; overflow: hidden; z-index: 41;
  border: 1px solid var(--border); border-bottom: none;
}
.chat-panel[hidden] { display: none; }
.chat-header { display: flex; justify-content: space-between; align-items: center; padding: 14px 18px; border-bottom: 1px solid var(--border); }
.chat-header .title { font-weight: 800; }
.chat-header .caption { color: var(--text-muted); font-size: 0.78em; }
.chat-header button { background: none; border: none; color: var(--text-muted); font-size: 1.1em; cursor: pointer; }
.chat-messages { flex: 1; overflow-y: auto; padding: 14px 18px; display: flex; flex-direction: column; gap: 10px; }
.chat-msg { padding: 10px 14px; border-radius: 16px; max-width: 85%; font-size: 0.9em; line-height: 1.4; }
.chat-msg.user { align-self: flex-end; background: var(--emerald); color: #05130c; }
.chat-msg.assistant { align-self: flex-start; background: var(--bg-elevated-2); }

.rule-card { align-self: stretch; background: var(--bg-elevated-2); border: 1px solid var(--emerald); border-radius: 16px; padding: 14px; }
.rule-card .rule-kicker { color: var(--emerald-bright); font-size: 0.72em; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; margin-bottom: 6px; }
.rule-card .rule-text { font-weight: 700; margin-bottom: 8px; }
.rule-card .rule-actions { display: flex; gap: 8px; }

.chat-suggestions { display: flex; gap: 6px; flex-wrap: wrap; padding: 0 18px 10px; }
.chat-suggestion { border: 1px solid var(--border); background: none; color: var(--text-muted); border-radius: 999px; padding: 6px 12px; font-size: 0.78em; cursor: pointer; }
.chat-form { display: flex; border-top: 1px solid var(--border); }
.chat-form input { flex: 1; border: none; background: none; padding: 14px 18px; color: var(--text); font-size: 0.95em; }
.chat-form input:focus { outline: none; }
.chat-form button { border: none; background: var(--emerald); color: #05130c; font-weight: 800; padding: 0 20px; cursor: pointer; }

@media (max-width: 480px) {
  .chat-panel { border-radius: 18px 18px 0 0; }
  .chat-fab { right: 16px; bottom: 16px; }
}

/* --- Keys / access log / households ------------------------------------- */

.credentials-status { display: flex; flex-direction: column; gap: 8px; }
.cred-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 12px; border-radius: var(--radius-sm); background: var(--bg-elevated-2); font-size: 0.85em;
}
.cred-row button { font-size: 0.75em; padding: 5px 10px; }

.access-log-list { display: flex; flex-direction: column; gap: 8px; }
.access-row {
  display: flex; justify-content: space-between; gap: 10px; align-items: flex-start;
  padding: 10px 0; border-bottom: 1px solid var(--border);
}
.access-row:last-child { border-bottom: none; }
.access-row.external { background: var(--amber-bg); border-radius: var(--radius-sm); padding: 10px 12px; }
.access-actor { font-weight: 700; font-size: 0.88em; }
.access-detail { color: var(--text-muted); font-size: 0.8em; margin-top: 2px; }
.access-when { color: var(--text-muted); font-size: 0.75em; white-space: nowrap; }

.households-list { display: flex; flex-direction: column; }

.connections-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 6px; }
.connection-row {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border-radius: var(--radius-sm); background: var(--bg-elevated-2);
}
.connection-row.needs-reauth { background: var(--amber-bg); border: 1px solid var(--amber); }
.connection-row .name { font-weight: 700; font-size: 0.88em; }
.connection-row .meta { color: var(--text-muted); font-size: 0.78em; margin-top: 2px; }
.connection-row button { font-size: 0.78em; padding: 7px 12px; white-space: nowrap; }

.feature-toggles { display: flex; flex-direction: column; gap: 2px; margin-top: 6px; }
.feature-toggles .toggle-row { font-size: 0.76em; }

/* --- Rules settings tab -------------------------------------------------- */
.muted-note { color: var(--text-muted); font-size: 0.85em; margin: 0; }
.rules-list { display: flex; flex-direction: column; gap: 8px; }
.rule-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: var(--bg-elevated-2); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 10px 12px; flex-wrap: wrap;
}
/* A paused rule stays visible but reads as inactive, so it is obviously
   still there to turn back on rather than looking deleted. */
.rule-row.paused { opacity: 0.55; }
.rule-row-main { display: flex; align-items: center; gap: 8px; flex: 1 1 220px; min-width: 0; flex-wrap: wrap; }
.rule-tag {
  flex: none; font-size: 0.68em; font-weight: 800; text-transform: uppercase; letter-spacing: .04em;
  color: var(--emerald-bright); background: rgba(16, 185, 129, 0.14);
  border-radius: 999px; padding: 3px 8px;
}
.rule-row-text { font-size: 0.88em; overflow-wrap: anywhere; }
.rule-paused-tag { font-size: 0.7em; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); }
.rule-row-actions { display: flex; gap: 6px; flex: none; }
.rule-row-actions button {
  background: none; border: 1px solid var(--border); color: var(--text-muted);
  border-radius: var(--radius-sm); padding: 4px 10px; font-size: 0.78em; cursor: pointer; font-family: var(--font);
}
.rule-row-actions button:hover { color: var(--text); border-color: var(--text-muted); }

.rule-form { display: flex; flex-direction: column; gap: 6px; }
.rule-form label { font-size: 0.78em; color: var(--text-muted); margin-top: 6px; }
.rule-form input[type="text"], .rule-form select {
  width: 100%; box-sizing: border-box; background: var(--bg-elevated-2); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 10px 12px;
  font-family: var(--font); font-size: 0.9em;
}
.rule-form button { margin-top: 12px; }
.rule-error { color: var(--amber); background: var(--amber-bg); border-radius: var(--radius-sm); padding: 8px 10px; font-size: 0.82em; margin: 10px 0 0; }

/* --- Year over year ------------------------------------------------------ */
.yoy-headline { font-size: 1.5em; font-weight: 800; margin-bottom: 10px; }
/* Spending more than last year is the warning direction, not the good one -
   the opposite of the balance delta, where up is good. */
.yoy-headline.up { color: var(--amber); }
.yoy-headline.down { color: var(--emerald-bright); }
.yoy-sub { display: block; font-size: 0.46em; font-weight: 600; color: var(--text-muted); letter-spacing: 0; margin-top: 2px; }
.yoy-legend { display: flex; gap: 16px; flex-wrap: wrap; font-size: 0.82em; color: var(--text-muted); margin-top: 10px; }
.yoy-legend .swatch { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 6px; }
.yoy-note { color: var(--text-muted); font-size: 0.78em; margin: 10px 0 0; line-height: 1.45; }

/* --- Brand mark ---------------------------------------------------------- */
/* The icon carries its own dark plate, so it needs rounding to match and must
   never be stretched by the flex row it sits in. */
.brand-mark {
  flex: none;
  border-radius: 7px;
  vertical-align: middle;
  display: inline-block;
}
.auth-brand .brand-mark { border-radius: 9px; margin-right: 2px; }

/* --- Page navigation ----------------------------------------------------- */
.page-nav { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.page-tab {
  background: var(--bg-elevated-2); color: var(--text-muted); border: 1px solid var(--border);
  border-radius: 999px; padding: 7px 14px; font-size: 0.85em; cursor: pointer; font-family: var(--font);
}
.page-tab.active { background: var(--emerald); color: #05130c; border-color: transparent; font-weight: 700; }

/* A compact page is built to fit without scrolling, so its cards are tighter. */
#screen-page[data-layout="compact"] .card { padding: 14px 16px; }
#screen-page[data-layout="compact"] .card h2 { margin-bottom: 8px; }

/* --- Bills --------------------------------------------------------------- */
.bill-list { display: flex; flex-direction: column; gap: 2px; }
.bill-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--border); }
.bill-row:last-child { border-bottom: none; }
.bill-main { display: flex; align-items: center; gap: 10px; min-width: 0; }
.bill-name { display: block; font-weight: 600; font-size: 0.92em; overflow-wrap: anywhere; }
.bill-when { display: block; color: var(--text-muted); font-size: 0.78em; margin-top: 1px; }
.bill-amount { flex: none; font-weight: 700; font-variant-numeric: tabular-nums; }

/* --- Subscription watch --------------------------------------------------- */
.watch-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--border); flex-wrap: wrap; }
.watch-row:last-child { border-bottom: none; }
.watch-name { font-weight: 600; font-size: 0.92em; }
.watch-detail { font-size: 0.85em; color: var(--text-muted); font-variant-numeric: tabular-nums; }
/* A price rise is amber, the same colour used for anything AI-flagged. */
.watch-row.up .watch-detail b { color: var(--amber); }
.watch-row.ended .watch-name { text-decoration: line-through; opacity: 0.7; }

/* --- Budget -------------------------------------------------------------- */
.budget-row { margin-bottom: 14px; }
.budget-row:last-child { margin-bottom: 0; }
.budget-head { display: flex; justify-content: space-between; gap: 10px; font-size: 0.88em; margin-bottom: 6px; }
.budget-figures { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.budget-bar { position: relative; height: 9px; background: var(--bg-elevated-2); border-radius: 999px; overflow: hidden; }
.budget-fill { height: 100%; border-radius: 999px; background: var(--emerald); transition: width .3s; }
.budget-fill.close { background: var(--amber); }
.budget-fill.over { background: var(--red); }
/* A tick showing how far through the month we are: 60% spent means something
   different on the 3rd than on the 20th, and a bare bar cannot say which. */
.budget-pace { position: absolute; top: -2px; bottom: -2px; width: 2px; background: var(--text); opacity: 0.45; }
.budget-bar.unbudgeted { opacity: 0.35; }

.note-body { margin: 0; line-height: 1.5; color: var(--text-muted); font-size: 0.9em; white-space: pre-wrap; }

/* --- Suggestions --------------------------------------------------------- */
.suggestion { padding: 10px 0; border-bottom: 1px solid var(--border); }
.suggestion:last-of-type { border-bottom: none; }
.suggestion-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.suggestion-title { font-weight: 700; font-size: 0.93em; }
/* The figure is an estimate of money kept, so it reads as money, not a warning. */
.suggestion-saving { flex: none; color: var(--emerald-bright); font-weight: 700; font-variant-numeric: tabular-nums; }
.suggestion-detail { margin: 4px 0 0; font-size: 0.87em; line-height: 1.5; color: var(--text-muted); }

/* --- Accessibility settings ---------------------------------------------- */
/* Applied from each person's own settings, not the household's. */
:root { --text-scale: 1; }
[data-weight="bold"] body,
[data-weight="bold"] .card,
[data-weight="bold"] button { font-weight: 600; }
[data-weight="bold"] .txn-payee,
[data-weight="bold"] .bill-name,
[data-weight="bold"] .amount { font-weight: 800; }

/* High contrast pushes muted text back to full strength and firms up every
   edge, rather than only darkening the background. */
[data-contrast="high"] { --text-muted: var(--text); }
[data-contrast="high"] .card { border-width: 2px; }

/* Respect the setting AND the OS preference: either one is enough to mean it. */
[data-motion="reduced"] *,
[data-motion="reduced"] *::before,
[data-motion="reduced"] *::after {
  animation-duration: 0.001ms !important;
  transition-duration: 0.001ms !important;
  scroll-behavior: auto !important;
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

[data-underline="on"] button,
[data-underline="on"] a { text-decoration: underline; }

/* --- Page builder -------------------------------------------------------- */
.page-admin-list { display: flex; flex-direction: column; gap: 8px; }
.page-admin-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap;
  background: var(--bg-elevated-2); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 10px 12px;
}
.page-admin-name { font-weight: 700; font-size: 0.94em; }
.page-admin-who { font-size: 0.76em; color: var(--text-muted); margin-top: 3px; }
.page-admin-who .can-edit { color: var(--emerald-bright); margin-left: 8px; }
.tag-compact { font-size: 0.62em; text-transform: uppercase; letter-spacing: .04em; color: var(--copper); margin-left: 6px; }
.page-admin-actions, .builder-item-actions { display: flex; gap: 5px; flex: none; flex-wrap: wrap; }
.page-admin-actions button, .builder-item-actions button, .revision-row button, .feedback-head button {
  background: none; border: 1px solid var(--border); color: var(--text-muted);
  border-radius: var(--radius-sm); padding: 4px 9px; font-size: 0.76em; cursor: pointer; font-family: var(--font);
}
.page-admin-actions button:hover, .builder-item-actions button:hover { color: var(--text); border-color: var(--text-muted); }
.page-admin-actions button:disabled, .builder-item-actions button:disabled { opacity: 0.3; cursor: default; }

.builder-card { border: 1px solid var(--emerald); }
.builder-list { display: flex; flex-direction: column; gap: 8px; }
.builder-item { background: var(--bg-elevated-2); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 10px 12px; }
.builder-item.dragging { opacity: 0.4; }
.builder-item-head { display: flex; align-items: center; gap: 8px; justify-content: space-between; flex-wrap: wrap; }
.builder-item-name { font-weight: 600; font-size: 0.9em; flex: 1 1 auto; }
.drag-handle { cursor: grab; color: var(--text-muted); flex: none; }
.builder-item-settings { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: 8px; }
.cfg-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; font-size: 0.82em; flex-wrap: wrap; }
.cfg-row > span { color: var(--text-muted); display: flex; flex-direction: column; }
.cfg-hint { font-size: 0.85em; opacity: 0.75; margin-top: 1px; }
.cfg-row input[type="text"], .cfg-row input[type="number"], .cfg-row select {
  background: var(--bg); color: var(--text); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 6px 9px; font-family: var(--font); font-size: 1em; max-width: 55%;
}
.cfg-check { display: flex; flex-direction: row; align-items: center; gap: 8px; font-size: 0.82em; color: var(--text-muted); }
.builder-footer { display: flex; align-items: center; gap: 10px; margin-top: 14px; flex-wrap: wrap; }

.access-list { display: flex; flex-direction: column; gap: 6px; }
.access-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--border); flex-wrap: wrap; }
.access-row:last-child { border-bottom: none; }
.access-name { font-size: 0.88em; display: flex; flex-direction: column; }
.access-role { font-size: 0.75em; color: var(--text-muted); text-transform: capitalize; }

.revision-list { display: flex; flex-direction: column; gap: 6px; }
.revision-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--border); flex-wrap: wrap; }
.revision-row:last-child { border-bottom: none; }
.revision-summary { display: block; font-size: 0.87em; font-weight: 600; }
.revision-meta { display: block; font-size: 0.75em; color: var(--text-muted); margin-top: 1px; }

/* --- Feedback ------------------------------------------------------------ */
.feedback-fab {
  position: fixed; right: 20px; bottom: 88px; width: 46px; height: 46px; border-radius: 50%;
  background: var(--bg-elevated-2); color: var(--text); border: 1px solid var(--border);
  font-size: 1.1em; cursor: pointer; box-shadow: var(--shadow); z-index: 40;
}
.feedback-panel {
  position: fixed; right: 20px; bottom: 144px; width: min(340px, calc(100vw - 40px));
  background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius-md);
  padding: 16px; box-shadow: var(--shadow); z-index: 41;
}
.feedback-panel h2 { margin: 0 0 10px; font-size: 1em; }
.feedback-panel label { display: block; font-size: 0.78em; color: var(--text-muted); margin: 8px 0 4px; }
.feedback-panel select, .feedback-panel textarea {
  width: 100%; box-sizing: border-box; background: var(--bg-elevated-2); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 8px 10px;
  font-family: var(--font); font-size: 0.9em;
}
.feedback-panel button { margin-top: 12px; }

.feedback-row { background: var(--bg-elevated-2); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 10px 12px; margin-bottom: 8px; }
.feedback-row.done { opacity: 0.55; }
.feedback-head { display: flex; align-items: center; gap: 8px; justify-content: space-between; flex-wrap: wrap; }
.feedback-who { font-size: 0.75em; color: var(--text-muted); flex: 1 1 auto; }
.feedback-body { margin: 6px 0 0; font-size: 0.88em; line-height: 1.5; white-space: pre-wrap; }

/* --- Per-widget account picker ------------------------------------------- */
.cfg-accounts { align-items: flex-start; }
.cfg-account-list {
  display: flex; flex-direction: column; gap: 4px; max-height: 160px; overflow-y: auto;
  max-width: 55%; padding: 6px 8px; background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-sm);
}
/* Private accounts are still listed for the owner, but marked - putting one on
   a shared page shows nothing rather than leaking, and the tag says why. */
.cfg-private { color: var(--copper); font-size: 0.85em; margin-left: 6px; }
.user-row select[data-role] {
  background: var(--bg-elevated-2); color: var(--text); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 5px 8px; font-family: var(--font); font-size: 0.85em; margin-left: 6px;
}

/* --- Widget grid --------------------------------------------------------- */
/* One column by default. Two columns only where there is genuinely room -
   half-width on a phone is how a balance ends up wrapped over three lines. */
#screen-page { display: grid; grid-template-columns: 1fr; gap: 14px; align-content: start; }
#screen-page > .w-full, #screen-page > .footer-signout { grid-column: 1 / -1; }
@media (min-width: 760px) {
  #screen-page { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  #screen-page > .w-half { grid-column: span 1; }
}

/* Accents tint the card edge rather than its background, so contrast with the
   text is never affected by the choice. */
#screen-page > [data-accent] { border-left-width: 3px; border-left-style: solid; }
#screen-page > [data-accent="emerald"] { border-left-color: var(--emerald); }
#screen-page > [data-accent="copper"] { border-left-color: var(--copper); }
#screen-page > [data-accent="amber"] { border-left-color: var(--amber); }
#screen-page > [data-accent="slate"] { border-left-color: rgba(148, 163, 184, 0.8); }

/* --- Editing on the page ------------------------------------------------- */
#screen-page.editing { gap: 18px; }
.edit-wrap {
  position: relative; border: 1px dashed var(--border); border-radius: var(--radius-md);
  padding: 34px 8px 8px; background: rgba(127, 127, 127, 0.04);
}
.edit-wrap.dragging { opacity: 0.35; }
.edit-wrap.drop-target { border-color: var(--emerald); border-style: solid; }
.edit-wrap[data-accent] { border-left-width: 3px; border-left-style: solid; }
.edit-wrap[data-accent="emerald"] { border-left-color: var(--emerald); }
.edit-wrap[data-accent="copper"] { border-left-color: var(--copper); }
.edit-wrap[data-accent="amber"] { border-left-color: var(--amber); }
.edit-wrap[data-accent="slate"] { border-left-color: rgba(148, 163, 184, 0.8); }

.edit-bar {
  position: absolute; top: 6px; left: 8px; right: 8px;
  display: flex; align-items: center; gap: 8px;
}
.edit-name { flex: 1 1 auto; font-size: 0.75em; color: var(--text-muted); text-transform: uppercase; letter-spacing: .04em; }
.edit-actions { display: flex; gap: 4px; flex: none; }
.edit-actions button {
  background: var(--bg-elevated-2); border: 1px solid var(--border); color: var(--text-muted);
  border-radius: 6px; width: 26px; height: 24px; font-size: 0.8em; cursor: pointer; line-height: 1; padding: 0;
}
.edit-actions button:hover { color: var(--text); border-color: var(--text-muted); }
.edit-actions button:disabled { opacity: 0.3; cursor: default; }
/* The real widget still renders inside, because the point of editing here is
   seeing the actual numbers in the actual layout. */
.edit-body > .card { margin: 0; }
.edit-empty { color: var(--text-muted); font-size: 0.85em; font-style: italic; }
.edit-settings {
  margin-top: 8px; padding: 10px 12px; background: var(--bg-elevated-2);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  display: flex; flex-direction: column; gap: 8px;
}
.edit-palette, .edit-savebar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 12px 14px; background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius-md);
}
.edit-palette label { font-size: 0.8em; color: var(--text-muted); }
.edit-palette select {
  flex: 1 1 220px; background: var(--bg-elevated-2); color: var(--text); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 8px 10px; font-family: var(--font); font-size: 0.88em;
}
.edit-savebar { position: sticky; bottom: 12px; border-color: var(--emerald); }

/* --- Custom widgets ------------------------------------------------------ */
.custom-frame-wrap { width: 100%; }
/* The frame is sandboxed with an opaque origin, so it cannot style or measure
   the page around it - the height it reports is the only thing it influences. */
.custom-frame { width: 100%; border: 0; display: block; height: 120px; background: transparent; }

/* --- Widget catalogue ---------------------------------------------------- */
.cat-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--border); }
.cat-row:last-child { border-bottom: none; }
.cat-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cat-name { font-weight: 700; font-size: 0.9em; }
.cat-owner { font-size: 0.68em; text-transform: uppercase; letter-spacing: .04em; color: var(--copper); margin-left: 8px; }
.cat-desc { font-size: 0.82em; color: var(--text-muted); line-height: 1.45; }
.cat-usage { font-size: 0.75em; color: var(--emerald-bright); margin-top: 2px; }
#cw-html {
  width: 100%; box-sizing: border-box; background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 10px 12px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.82em; line-height: 1.5;
}

/* --- Widget prompt ------------------------------------------------------- */
#widget-prompt {
  width: 100%; box-sizing: border-box; background: var(--bg); color: var(--text-muted);
  border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 10px 12px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.78em; line-height: 1.5; resize: vertical;
}

/* --- Sign in ------------------------------------------------------------- */
/* Two halves on a desktop: what this is on the left, the way in on the right.
   One column on a phone, with the pitch trimmed so the form stays reachable
   without scrolling. */
@media (min-width: 900px) {
  .auth-screen { grid-template-columns: 1.05fr 1fr; }
}

.auth-pitch {
  display: flex; align-items: center; padding: 48px 40px;
  background:
    radial-gradient(900px 500px at 12% -10%, rgba(192, 121, 61, 0.20), transparent 60%),
    radial-gradient(700px 500px at 85% 110%, rgba(16, 185, 129, 0.18), transparent 60%),
    var(--bg-elevated);
  border-bottom: 1px solid var(--border);
}
@media (min-width: 900px) { .auth-pitch { border-bottom: 0; border-right: 1px solid var(--border); } }
.auth-pitch-inner { max-width: 520px; margin-inline: auto; }

.auth-pitch .auth-brand {
  display: flex; align-items: center; gap: 12px;
  font-size: 1.55em; font-weight: 800; letter-spacing: -0.01em; margin-bottom: 26px;
}
.auth-headline {
  margin: 0 0 16px; font-size: clamp(2.1rem, 5.2vw, 3.4rem); line-height: 1.06;
  font-weight: 800; letter-spacing: -0.03em;
}
.auth-sub { margin: 0 0 26px; font-size: 1.02em; line-height: 1.6; color: var(--text-muted); max-width: 46ch; }

.auth-points { list-style: none; margin: 0 0 24px; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.auth-points li { display: flex; gap: 12px; align-items: flex-start; font-size: 0.92em; line-height: 1.5; color: var(--text-muted); }
.auth-points b { color: var(--text); font-weight: 700; }
.auth-point-icon {
  flex: none; width: 30px; height: 30px; border-radius: 9px; display: grid; place-items: center;
  background: var(--bg-elevated-2); border: 1px solid var(--border); font-size: 0.85em;
}
/* The strongest claim on the page, so it is stated plainly and not dressed up. */
.auth-foot { margin: 0; font-size: 0.86em; color: var(--text-muted); border-left: 2px solid var(--emerald); padding-left: 12px; }

.auth-panel { display: flex; flex-direction: column; justify-content: center; align-items: center; padding: 40px 24px; gap: 16px; }
.auth-card {
  width: 100%; max-width: 400px; background: var(--bg-elevated); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 30px 28px; box-shadow: var(--shadow); text-align: left;
}
/* The mark repeats inside the card only where the pitch is not beside it. */
.auth-card-brand { display: flex; align-items: center; gap: 9px; font-weight: 800; font-size: 1.1em; margin-bottom: 18px; }
@media (min-width: 900px) { .auth-card-brand { display: none; } }
.auth-card-title { margin: 0 0 18px; font-size: 1.3em; font-weight: 800; letter-spacing: -0.01em; }
.auth-legal { margin: 0; font-size: 0.78em; color: var(--text-muted); text-align: center; max-width: 380px; }

.auth-spinner {
  width: 22px; height: 22px; border-radius: 50%; margin-bottom: 12px;
  border: 2px solid var(--border); border-top-color: var(--emerald); animation: auth-spin 0.8s linear infinite;
}
@keyframes auth-spin { to { transform: rotate(360deg); } }

/* On a short phone screen the pitch would push the form off-screen, so it
   yields rather than the thing people came to do. */
@media (max-width: 899px) {
  .auth-pitch { padding: 30px 22px 26px; }
  .auth-points, .auth-foot { display: none; }
  .auth-sub { margin-bottom: 0; font-size: 0.95em; }
  .auth-panel { padding-top: 26px; }
}

/* --- Sign in: escape the app's phone-width column ------------------------- */
/* #viewport caps the app at 480px, which is right for the dashboard and wrong
   for a full-bleed sign-in page. While signed out the shell stops constraining
   and the sign-in owns the whole window. */
body:has(#auth-screen:not([hidden])) #viewport { max-width: none; }

/* The assistant and feedback buttons belong to a signed-in session. Showing
   them on the sign-in page invites a click that cannot do anything. */
body:has(#auth-screen:not([hidden])) .chat-fab,
body:has(#auth-screen:not([hidden])) .feedback-fab,
body:has(#auth-screen:not([hidden])) .chat-panel { display: none !important; }
body.signed-out #viewport { max-width: none; }
body.signed-out .chat-fab,
body.signed-out .feedback-fab,
body.signed-out .chat-panel { display: none !important; }

/* --- Widget height ------------------------------------------------------- */
/* "Short" caps the card and scrolls what does not fit, so a long list can sit
   next to something small without dragging the page down. "Tall" gives a chart
   room to breathe. Neither clips a chart, because the canvas sizes to its
   wrapper rather than to the card. */
#screen-page > [data-height="short"] { max-height: 230px; overflow-y: auto; }
#screen-page > [data-height="tall"] { min-height: 420px; }
#screen-page > [data-height="tall"] .chart-wrap { min-height: 260px; }
#screen-page > [data-height="tall"] .chart-wrap canvas { height: 100% !important; }

.edit-wrap[data-height="short"] .edit-body { max-height: 200px; overflow-y: auto; }
.edit-wrap[data-height="tall"] .edit-body { min-height: 380px; }

/* --- Release notes ------------------------------------------------------- */
.release-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
.release-title { font-weight: 800; font-size: 1.02em; }
.release-meta { font-size: 0.76em; color: var(--text-muted); }
.release-list { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 8px; }
.release-list li { font-size: 0.88em; line-height: 1.55; color: var(--text-muted); }

/* --- Printing ------------------------------------------------------------ */
.print-status {
  flex: none; font-size: 0.7em; text-transform: uppercase; letter-spacing: .04em;
  padding: 3px 8px; border-radius: 999px; background: var(--bg-elevated-2); color: var(--text-muted);
}
.print-status.printed { color: var(--emerald-bright); }
.print-status.failed { color: var(--red); }
.print-status.queued, .print-status.claimed { color: var(--amber); }

/* The token appears exactly once, so it is given room rather than tucked away. */
.token-reveal {
  margin-top: 12px; padding: 14px; border: 1px solid var(--emerald);
  border-radius: var(--radius-sm); background: var(--bg-elevated-2);
}
.token-reveal p { margin: 0 0 8px; font-size: 0.85em; }
.token-reveal pre {
  margin: 0 0 10px; padding: 10px 12px; background: var(--bg); border: 1px solid var(--border);
  border-radius: var(--radius-sm); font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.76em; line-height: 1.5; overflow-x: auto; white-space: pre-wrap; word-break: break-all;
}
#printing-admin textarea, #printing-admin input[type="text"], #printing-admin select {
  width: 100%; box-sizing: border-box; background: var(--bg-elevated-2); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 9px 11px;
  font-family: var(--font); font-size: 0.9em;
}


/* --- hidden must actually mean hidden ------------------------------------
   The hidden attribute is display:none from the browser's own stylesheet,
   which any author rule with a display beats. #screen-page is a grid, so
   setting hidden on it did nothing and Settings rendered on top of the page
   underneath. This is the second time that has happened in this file - once
   for the chat panel, now for the grid - so the guard is written once, for
   everything, rather than per element. */
[hidden] { display: none !important; }

/* --- Settings is its own screen, not a column ----------------------------
   The app shell is 480px wide because a dashboard on a phone should be. A
   settings screen with twelve tabs is not that, and squeezing it there left
   the tabs needing 929px in a 444px row. */
body.on-settings #viewport { max-width: none; }
#screen-settings { width: 100%; max-width: 900px; margin-inline: auto; padding-inline: 4px; }
#settings-tabs { flex-wrap: wrap; row-gap: 6px; }
@media (min-width: 760px) {
  /* Two columns of cards once there is room, so a long settings page is not
     one endless ribbon. */
  .tab-panel { column-gap: 14px; }
  #tab-pages, #tab-widgets, #tab-printing { max-width: 760px; }
}

/* Disconnecting a bank is destructive, so it is coloured as such - but it sits
   next to Reconnect on every row, including healthy ones, so it stays quiet
   until pointed at rather than shouting from every connection. */
.btn-quiet {
  background: var(--bg-elevated-2); color: var(--text-muted);
  border: 1px solid var(--border);
}
.btn-quiet:hover { background: rgba(248, 113, 113, 0.15); color: var(--red); border-color: var(--red); }


/* --- Backups ------------------------------------------------------------- */
.backups-list { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.backup-row {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: var(--bg-elevated-2); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 10px 12px;
}
.backup-row .when { font-weight: 700; font-size: 0.86em; }
.backup-row .meta { color: var(--text-muted); font-size: 0.78em; margin-top: 2px; }
.backup-row button { font-size: 0.76em; padding: 6px 11px; }
/* The newest backup is the one anyone actually wants; the rest are history. */
.backup-row.latest { border-color: var(--emerald); }
.backup-row.latest .when::after {
  content: "latest"; margin-left: 8px; font-weight: 600; font-size: 0.8em; color: var(--emerald);
}

.restore-scope {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 12px; font-size: 0.8em; color: var(--text-muted);
}
.restore-scope select {
  background: var(--bg-elevated-2); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 6px 9px; font-size: 1em;
}
