/* ── Snowball — private, in-browser debt payoff planner ─────────────── */
:root {
  --brand: #0e7490;
  --brand-dark: #155e75;
  --brand-light: #67e8f9;
  --brand-soft: #ecfeff;
  --brand-border: #a5f3fc;
  --ink: #1a1a2e;
  --muted: #6b7280;
  --line: #e7e8ee;
  --bg: #f7f7fb;
  --card: #ffffff;
  --ok: #0f766e;
  --danger: #b91c1c;
  --warn: #b45309;
  --shadow: 0 1px 3px rgba(20,20,40,.06), 0 8px 24px rgba(20,20,40,.05);
  /* Elevation v1 — soft, layered, low-opacity shadow ladder. Cards use sm/md,
     raised modals/popovers use lg. (--shadow kept above for anything still
     referencing it directly.) */
  --shadow-sm: 0 1px 2px rgba(16,24,40,.04), 0 1px 3px rgba(16,24,40,.06);
  --shadow-md: 0 2px 4px rgba(16,24,40,.05), 0 6px 16px rgba(16,24,40,.08);
  --shadow-lg: 0 8px 24px rgba(16,24,40,.10), 0 24px 60px rgba(16,24,40,.14);

  /* Surfaces referenced directly (not through a token) in light mode — named
     here so the dark override has a single place to retint them. */
  --topbar-bg: rgba(255,255,255,.85);
  --input-bg: #fbfbfd;
  --input-bg-focus: #ffffff;
  --track-bg: #e7e8ee;
  --pill-bg: #f0fdf9;
  --pill-border: #99f6e4;
  --rm-hover-bg: #fee2e2;
  --warn-bg: #fffbeb;
  --warn-border: #fde68a;
  --status-err-bg: #fef2f2;
  --status-ok-bg: #ecfdf5;
  --footer-ink: #9ca3bf;
  --sep: #c3c8dd;
  --backdrop: rgba(20,20,40,.45);
  /* Chart ink — read by drawChart() so the canvas retints with the theme. */
  --chart-grid: #e7e8ee;
  --chart-label: #6b7280;
  --chart-snowball: #0e7490;
  --chart-avalanche: #c2410c;
}

/* ── Dark theme ─────────────────────────────────────────────────────────
   Opt-in overlay applied to <html data-theme="dark">. Only overrides the
   token values above — every rule downstream reads the tokens, so light
   mode is untouched. Warm near-black chrome, light-not-white ink, a
   brightened brand that stays vivid on dark. */
[data-theme="dark"] {
  --brand: #22c3e6;
  --brand-dark: #7fe3f6;
  --brand-light: #67e8f9;
  --brand-soft: #12303a;
  --brand-border: #1d5566;
  --ink: #e8e8ed;
  --muted: #9aa2b1;
  --line: #2c2e37;
  --bg: #15161a;
  --card: #1c1d22;
  --ok: #4ade9e;
  --danger: #f87171;
  --warn: #fbbf24;
  --shadow: 0 1px 3px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.35);
  /* Elevation v1 dark ladder — cooler, higher-opacity so raised surfaces still
     read against the near-black chrome. */
  --shadow-sm: 0 1px 2px rgba(0,0,0,.45), 0 1px 3px rgba(0,0,0,.5);
  --shadow-md: 0 2px 4px rgba(0,0,0,.5), 0 6px 16px rgba(0,0,0,.55);
  --shadow-lg: 0 8px 24px rgba(0,0,0,.55), 0 24px 60px rgba(0,0,0,.65);

  --topbar-bg: rgba(21,22,26,.85);
  --input-bg: #24262e;
  --input-bg-focus: #2a2c35;
  --track-bg: #2c2e37;
  --pill-bg: #123029;
  --pill-border: #1f5648;
  --rm-hover-bg: #402022;
  --warn-bg: #2c2410;
  --warn-border: #5a4a1a;
  --status-err-bg: #3a1e1e;
  --status-ok-bg: #123028;
  --footer-ink: #7c8496;
  /* Dark-mode contrast fix: the footer "·" separator was near-invisible at
     #3a3d49 (~1.7:1 on --bg). Bumped so the divider actually reads while
     staying subtler than the muted links it sits between (~3.7:1). */
  --sep: #6b7280;
  --backdrop: rgba(0,0,0,.6);
  --chart-grid: #2c2e37;
  --chart-label: #9aa2b1;
  --chart-snowball: #38d0ef;
  --chart-avalanche: #fb7a45;
}

/* Subtle color transition when the theme flips (root chrome only). */
html { transition: background-color .25s ease, color .25s ease; }
body { transition: background-color .25s ease, color .25s ease; }
@media (prefers-reduced-motion: reduce) {
  html, body { transition: none; }
}

/* ── Theme toggle button (topbar) ─────────────────────────────────────── */
.theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  /* Visual box stays compact, but the hit area is at least 40px so the
     icon-only control clears the minimum comfortable touch target. The 18px
     icon is unchanged. */
  width: 40px; height: 40px; min-width: 40px; min-height: 40px; border-radius: 10px;
  background: transparent; border: 1px solid var(--line); color: var(--muted);
  transition: background-color .12s ease, color .12s ease, border-color .12s ease;
}
.theme-toggle:hover { background: var(--brand-soft); color: var(--brand); border-color: var(--brand-border); }
.theme-toggle svg { width: 18px; height: 18px; }
/* Icon reflects the CURRENT mode: sun in light mode, moon in dark mode. */
.theme-toggle .icon-moon { display: none; }
.theme-toggle .icon-sun { display: block; }
[data-theme="dark"] .theme-toggle .icon-moon { display: block; }
[data-theme="dark"] .theme-toggle .icon-sun { display: none; }
.topbar-right { display: flex; align-items: center; gap: 12px; }

/* Visually-hidden but present for assistive tech (screen-reader live regions). */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── Tabular numerals (Elevation v1) ──────────────────────────────────
   Lines up columns of digits in stats, totals, prices, dates, the payoff
   list, code, and numeric inputs so figures don't jitter as they change.
   A .tnum utility is available for any inline number that needs it too. */
.tnum,
.stat-card .stat-value,
.whatif-amt,
.whatif-stat-value,
.pro-price-amt,
.progress-therm .pt-top,
.payoff-row .po-top,
.goal-msg,
.whatif-save,
.whatif-msg,
.restore-code-value,
.field input,
.restore-code-input {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { height: 100%; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  color: var(--ink);
  background: var(--bg);
  font-size: 15px;
  line-height: 1.5;
}
a { color: var(--brand); text-decoration: none; }
button { font-family: inherit; cursor: pointer; }
input, select { font-family: inherit; font-size: 14px; }

/* ── Top bar ───────────────────────────────────────────────────────── */
.topbar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px max(28px, env(safe-area-inset-right)) 14px max(28px, env(safe-area-inset-left));
  padding-top: max(14px, env(safe-area-inset-top));
  background: var(--topbar-bg);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line);
}
.logo { display: flex; align-items: center; gap: 10px; cursor: pointer; }
.logo svg { width: 30px; height: 30px; }
.logo b { font-size: 17px; font-weight: 800; letter-spacing: -.3px; }
/* Two-tone wordmark: "Snow" stays ink, "ball" takes the brand accent. */
.logo b.wordmark span { color: var(--brand); }
.privacy-pill {
  display: flex; align-items: center; gap: 7px;
  font-size: 12.5px; font-weight: 600; color: var(--ok);
  background: var(--pill-bg); border: 1px solid var(--pill-border);
  padding: 5px 12px; border-radius: 999px;
  margin-right: -10px;
}
.privacy-pill svg { width: 14px; height: 14px; }
@media (max-width: 480px) {
  .privacy-pill { font-size: 10.5px; padding: 4px 9px; gap: 5px; margin-right: 0; max-width: 148px; }
  .privacy-pill svg { width: 12px; height: 12px; }
}

/* ── Hero ──────────────────────────────────────────────────────────── */
.hero { text-align: center; padding: 40px 24px 20px; }
.hero h1 { font-size: 34px; font-weight: 800; letter-spacing: -1px; line-height: 1.2; max-width: 680px; margin: 0 auto 10px; }
.hero .accent { color: var(--brand); }
.hero p { color: var(--muted); font-size: 15.5px; max-width: 520px; margin: 0 auto; }

.btn {
  border: none; border-radius: 12px; padding: 11px 20px; font-weight: 700; font-size: 14.5px;
  background: var(--brand); color: #fff; box-shadow: 0 6px 18px rgba(14,116,144,.22);
  transition: transform .1s ease, box-shadow .1s ease;
}
.btn:hover { transform: translateY(-1px); box-shadow: 0 10px 24px rgba(14,116,144,.28); }
.btn:active { transform: translateY(0); }
.btn.ghost { background: transparent; color: var(--brand); border: 1.5px solid var(--brand-border); box-shadow: none; }
.btn.ghost:hover { background: var(--brand-soft); }
.btn.sm { padding: 8px 14px; font-size: 13px; }
.btn[disabled] { opacity: .5; cursor: not-allowed; transform: none; box-shadow: none; }

footer { text-align: center; color: var(--footer-ink); font-size: 12.5px; padding: 30px 24px max(40px, env(safe-area-inset-bottom)); border-top: 1px solid var(--line); margin-top: 30px; }
footer a { color: var(--muted); }

/* ── App layout ────────────────────────────────────────────────────── */
.app { max-width: 1120px; margin: 0 auto; padding: 10px 24px 24px; }
.app-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); gap: 24px; align-items: flex-start; }
@media (max-width: 900px) { .app-grid { grid-template-columns: 1fr; } }

.panel { background: var(--card); border: 1px solid var(--line); border-radius: 16px; padding: 20px; box-shadow: var(--shadow-sm); margin-bottom: 16px; transition: box-shadow .15s ease; }
.panel h3 { font-size: 14.5px; font-weight: 800; margin-bottom: 14px; display: flex; align-items: center; justify-content: space-between; }
.field-label { font-size: 12px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .4px; margin-bottom: 6px; display: block; }
.field { margin-bottom: 14px; }
.field input, .field select {
  width: 100%; border: 1.5px solid var(--line); border-radius: 9px; padding: 9px 11px;
  background: var(--input-bg); color: var(--ink); transition: border-color .12s ease;
}
.field input:focus, .field select:focus { outline: none; border-color: var(--brand-light); background: var(--input-bg-focus); }
.field-row { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; }
@media (max-width: 560px) { .field-row { grid-template-columns: 1fr; } }
.hint { font-size: 12px; color: var(--muted); margin-top: 10px; }

/* ── Strategy toggle ───────────────────────────────────────────────── */
.strategy-picker { display: flex; gap: 10px; margin-bottom: 6px; }
.strategy-opt {
  flex: 1; border: 2px solid var(--line); border-radius: 12px; padding: 12px; text-align: left;
  background: var(--card);
  transition: border-color .15s ease, background-color .15s ease;
}
.strategy-opt .st-name { font-weight: 800; font-size: 13.5px; color: var(--ink); display: block; }
.strategy-opt .st-desc { font-size: 11.5px; color: var(--muted); display: block; margin-top: 2px; }
.strategy-opt.active { border-color: var(--brand); background: var(--brand-soft); }
.strategy-opt.active .st-name { color: var(--brand-dark); }

/* ── Debt entries ──────────────────────────────────────────────────── */
.debt-row { border: 1.5px solid var(--line); border-radius: 12px; padding: 14px 16px; margin-bottom: 10px; }
.debt-row .debt-top { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }
.debt-row .debt-label { font-size: 12px; font-weight: 700; color: var(--brand-dark); text-transform: uppercase; letter-spacing: .3px; }
/* Hit area padded up to a comfortable minimum (>=40px) without enlarging the
   12px label / 14px icon — the extra is padding, so the control stays visually
   the same size. Negative right margin keeps it flush to the row's edge. */
.debt-row .rm-debt { background: none; border: none; color: var(--muted); display: flex; align-items: center; justify-content: center; gap: 4px; font-size: 12px; padding: 10px 10px; min-height: 40px; margin: -6px -6px -6px 0; border-radius: 6px; transition: background-color .15s ease, color .15s ease; }
.debt-row .rm-debt:hover { background: var(--rm-hover-bg); color: var(--danger); }
.debt-row .rm-debt svg { width: 14px; height: 14px; }
.debt-warn { display: flex; align-items: flex-start; gap: 8px; font-size: 12.5px; color: var(--warn); background: var(--warn-bg); border: 1px solid var(--warn-border); border-radius: 9px; padding: 8px 10px; margin-top: 8px; }
.debt-warn svg { width: 15px; height: 15px; flex: none; margin-top: 1px; }

/* ── Results ───────────────────────────────────────────────────────── */
.stat-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-bottom: 16px; }
@media (max-width: 560px) { .stat-grid { grid-template-columns: 1fr; } }
.stat-card { background: var(--brand-soft); border: 1px solid var(--brand-border); border-radius: 12px; padding: 14px 16px; }
.stat-card .stat-value { font-size: 21px; font-weight: 800; color: var(--brand-dark); letter-spacing: -.4px; }
.stat-card .stat-label { font-size: 11.5px; color: var(--muted); font-weight: 600; text-transform: uppercase; letter-spacing: .3px; margin-top: 3px; }

.progress-therm { margin-bottom: 12px; }
.progress-therm .pt-top { display: flex; justify-content: space-between; font-size: 12.5px; margin-bottom: 5px; }
.progress-therm .pt-name { font-weight: 700; }
.progress-therm .pt-pct { color: var(--muted); }
.progress-track { height: 10px; border-radius: 6px; background: var(--track-bg); overflow: hidden; }
.progress-fill { height: 100%; background: linear-gradient(90deg, var(--brand-light), var(--brand)); border-radius: 6px; }

/* Payoff-order list — visually similar to the thermometer rows but its own
   classes, since these show dates (not percentages) and shouldn't drift
   out of sync if .pt-pct ever grows percentage-specific styling. */
.payoff-row { margin-bottom: 10px; }
.payoff-row .po-top { display: flex; justify-content: space-between; font-size: 12.5px; }
.payoff-row .po-name { font-weight: 700; }
.payoff-row .po-date { color: var(--muted); }

.chart-wrap { margin-top: 4px; }
.chart-wrap canvas { width: 100%; height: 220px; display: block; }
.chart-legend { display: flex; flex-wrap: wrap; gap: 10px 16px; margin-top: 10px; font-size: 11.5px; color: var(--muted); }
.chart-legend .lg-item { display: flex; align-items: center; gap: 5px; }
.chart-legend .lg-swatch { width: 10px; height: 10px; border-radius: 3px; }

.autosave-note { font-size: 12px; color: var(--muted); margin-top: 10px; }

/* ── Goal-seek ("reach a debt-free date") ──────────────────────────── */
.goal-seek .field input[type="month"] { width: 100%; border: 1.5px solid var(--line); border-radius: 9px; padding: 9px 11px; background: var(--input-bg); color: var(--ink); }
.goal-seek .field input[type="month"]:focus { outline: none; border-color: var(--brand-light); background: var(--input-bg-focus); }
.goal-result { margin-top: 12px; }
.goal-result:empty { margin-top: 0; }
.goal-msg { font-size: 13.5px; font-weight: 600; color: var(--ink); margin-bottom: 10px; }
.goal-msg.ok { color: var(--ok); }
.goal-apply { margin-top: 2px; }

/* ── Export payoff plan (Pro) + Share milestone (free) ─────────────── */
.export-row { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); display: flex; flex-wrap: wrap; gap: 10px; }
.export-row .status-msg { margin-top: 10px; flex-basis: 100%; }

/* ── "What if I paid extra?" live slider (free) ────────────────────── */
.whatif { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--line); }
.whatif-title { font-size: 13.5px; font-weight: 800; color: var(--ink); }
.whatif .hint { margin-top: 6px; margin-bottom: 12px; }
.whatif-row { display: flex; align-items: center; gap: 14px; }
.whatif-amt {
  flex: none; min-width: 92px; text-align: right;
  font-size: 15px; font-weight: 800; color: var(--brand-dark); letter-spacing: -.3px;
  font-variant-numeric: tabular-nums;
}
/* Range input themed with tokens so it reads correctly in dark mode. */
.whatif-slider {
  flex: 1; min-width: 0; height: 22px;
  -webkit-appearance: none; appearance: none; background: transparent; cursor: pointer;
}
.whatif-slider:focus { outline: none; }
.whatif-slider::-webkit-slider-runnable-track {
  height: 6px; border-radius: 6px; background: var(--track-bg);
}
.whatif-slider::-moz-range-track {
  height: 6px; border-radius: 6px; background: var(--track-bg);
}
.whatif-slider::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 20px; height: 20px; margin-top: -7px; border-radius: 50%;
  background: var(--brand); border: 2px solid var(--card);
  box-shadow: 0 1px 4px rgba(14,116,144,.35);
  transition: transform .1s ease;
}
.whatif-slider::-moz-range-thumb {
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--brand); border: 2px solid var(--card);
  box-shadow: 0 1px 4px rgba(14,116,144,.35);
}
.whatif-slider:active::-webkit-slider-thumb { transform: scale(1.1); }
.whatif-slider:focus-visible::-webkit-slider-thumb { outline: 2px solid var(--brand); outline-offset: 2px; }
.whatif-slider:focus-visible::-moz-range-thumb { outline: 2px solid var(--brand); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
  .whatif-slider::-webkit-slider-thumb { transition: none; }
  .whatif-slider:active::-webkit-slider-thumb { transform: none; }
}
.whatif-readout { margin-top: 14px; }
.whatif-readout:empty { margin-top: 0; }
.whatif-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 10px; }
.whatif-stat { background: var(--brand-soft); border: 1px solid var(--brand-border); border-radius: 10px; padding: 10px 12px; }
.whatif-stat-value { font-size: 16px; font-weight: 800; color: var(--brand-dark); letter-spacing: -.3px; }
.whatif-stat-label { font-size: 10.5px; color: var(--muted); font-weight: 600; text-transform: uppercase; letter-spacing: .3px; margin-top: 2px; }
.whatif-save { font-size: 13px; font-weight: 600; color: var(--ink); }
.whatif-save.muted { color: var(--muted); font-weight: 500; }
.whatif-msg { font-size: 13px; color: var(--warn); }
.whatif-apply { margin-top: 12px; }

.preview-wrap { position: sticky; top: 90px; }

/* ── Pro paywall modal ────────────────────────────────────────────── */
.modal-backdrop {
  position: fixed; inset: 0; background: var(--backdrop); backdrop-filter: blur(2px);
  display: flex; align-items: center; justify-content: center; z-index: 100; padding: 20px;
}
.modal {
  background: var(--card); border-radius: 18px; padding: 28px; max-width: 380px; width: 100%;
  box-shadow: var(--shadow-lg);
}
.pro-modal h3 { font-size: 20px; font-weight: 800; margin-bottom: 8px; }
/* Optional personalized lead-in line above the price (context-driven). */
.pro-lead { font-size: 14px; font-weight: 600; color: var(--brand-dark); margin-bottom: 12px; }
.pro-price { margin-bottom: 16px; }
.pro-price-amt { font-size: 28px; font-weight: 800; color: var(--brand-dark); }
.pro-price-note { font-size: 13.5px; color: var(--muted); }
.pro-features { padding-left: 20px; margin-bottom: 20px; color: var(--ink); font-size: 14px; }
.pro-features li { margin-bottom: 6px; }
.pro-actions { display: flex; gap: 10px; }
.pro-actions .btn { flex: 1; }
.pro-msg:empty { margin: 0; }
.status-msg { margin-top: 12px; padding: 10px 14px; border-radius: 10px; font-size: 13.5px; }
.status-msg.err { background: var(--status-err-bg); color: var(--danger); }
.status-msg.ok { background: var(--status-ok-bg); color: var(--ok); }

.restore-code-box {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: var(--brand-soft); border: 1.5px dashed var(--brand-border); border-radius: 10px;
  padding: 12px 14px; margin-bottom: 18px;
}
.restore-code-value { font-size: 15px; font-weight: 700; letter-spacing: .3px; color: var(--brand-dark); word-break: break-all; }
.restore-code-input {
  width: 100%; border: 1.5px solid var(--line); border-radius: 9px; padding: 10px 12px;
  font-size: 15px; letter-spacing: .5px; margin-bottom: 14px; text-transform: uppercase;
  background: var(--input-bg); color: var(--ink);
}
.restore-code-input:focus { outline: none; border-color: var(--brand-light); }
.restore-link {
  display: block; width: 100%; text-align: center; background: none; border: none;
  color: var(--muted); font-size: 12.5px; margin-top: 12px; padding: 4px; text-decoration: underline;
  transition: color .15s ease;
}
.restore-link:hover { color: var(--brand-dark); }
/* .restore-link's display:block (author) would beat the UA's [hidden]
   rule — restate it so the footer license link can hide via `hidden`. */
.restore-link[hidden] { display: none; }

/* ── Pro license card ─────────────────────────────────────────────── */
.license-modal { max-width: 560px; }
.license-card-canvas {
  width: 100%; max-width: 100%; height: auto; display: block;
  border: 1px solid var(--line); border-radius: 12px; margin: 4px 0 16px;
  box-shadow: var(--shadow-sm);
}
.license-actions { flex-wrap: wrap; }
.license-actions .btn { flex: 1 1 auto; }

/* Save-your-license-card nag banner (dismiss = this page load only) */
.save-nag {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  background: var(--brand-soft); border-bottom: 1px solid var(--brand-border);
  color: var(--brand-dark); font-size: 13px; font-weight: 600;
  padding: 8px max(16px, env(safe-area-inset-right)) 8px max(16px, env(safe-area-inset-left));
}
.save-nag .save-nag-view { padding: 5px 12px; font-size: 12.5px; box-shadow: none; }
.save-nag .save-nag-close {
  background: none; border: none; color: var(--brand-dark);
  font-size: 18px; line-height: 1; padding: 2px 8px; border-radius: 6px;
}
.save-nag .save-nag-close:hover { background: rgba(14, 116, 144, .12); }
@media (max-width: 560px) { .save-nag { flex-wrap: wrap; text-align: center; } }
/* Access-ended notice (Pro revoked/refunded): same slim slot, calm — never red. */
.save-nag.access-ended { font-weight: 500; }

/* ── Refund request (request-only; opens a pre-filled email) ──────────── */
.refund-block {
  margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line);
  text-align: center;
}
.refund-link {
  display: inline-block; color: var(--muted); font-size: 13px; font-weight: 600;
  text-decoration: underline; text-underline-offset: 2px;
}
.refund-link:hover { color: var(--brand-dark); }
.refund-note {
  margin: 8px 0 0; font-size: 12px; color: var(--muted); line-height: 1.5;
}

/* ── Footer back-up & restore row ─────────────────────────────────── */
.footer-tools { margin-top: 4px; display: flex; align-items: center; justify-content: center; gap: 6px; }
.footer-tools .restore-link { display: inline-block; width: auto; margin-top: 0; }
.footer-tools-sep { color: var(--sep); }


/* ── Paywall: durable one-time reassurance + neutral (info) status ────── */
.pro-reassure-durable {
  font-size: 12px; color: var(--muted); margin: -6px 0 14px;
  padding: 8px 12px; background: var(--pill-bg); border: 1px solid var(--pill-border);
  border-radius: 9px; line-height: 1.45;
}
/* Neutral/info status tone — grey, calm, NOT the red error tone. Used for a
   deliberately-cancelled checkout and the offline case, so closing checkout on
   purpose never reads as an error. */
.status-msg.info { background: var(--input-bg); color: var(--muted); border: 1px solid var(--line); }

/* ── Ownership celebration modal ──────────────────────────────────────── */
.celebrate-modal { max-width: 460px; text-align: left; }
.celebrate-headline {
  font-size: 24px !important; font-weight: 800; letter-spacing: -.5px;
  color: var(--brand-dark); margin-bottom: 8px !important;
}
.celebrate-thanks { font-size: 14.5px; color: var(--ink); line-height: 1.5; margin-bottom: 16px; }
.celebrate-unlocked {
  background: var(--brand-soft); border: 1px solid var(--brand-border);
  border-radius: 12px; padding: 14px 16px; margin-bottom: 16px;
}
.celebrate-unlocked-title {
  font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px;
  color: var(--brand-dark); margin-bottom: 8px;
}
.celebrate-list { padding-left: 20px; margin: 0; font-size: 13.5px; color: var(--ink); }
.celebrate-list li { margin-bottom: 5px; }
.celebrate-code-lead { font-size: 13px; color: var(--muted); margin-bottom: 12px; line-height: 1.45; }

/* Amber "couldn't mint the code" self-heal section (inside celebration / anywhere). */
.mint-code-section { margin-top: 4px; }
.mint-code-note {
  font-size: 13px; color: var(--warn); line-height: 1.45; margin-bottom: 14px;
  padding: 10px 12px; background: var(--warn-bg); border: 1px solid var(--warn-border); border-radius: 10px;
}

/* ── Restore-success toast ────────────────────────────────────────────── */
.snow-toast {
  position: fixed; left: 50%; bottom: max(24px, env(safe-area-inset-bottom));
  transform: translate(-50%, 20px); z-index: 200;
  background: var(--brand-dark); color: #fff; font-size: 13.5px; font-weight: 600;
  padding: 11px 18px; border-radius: 12px; box-shadow: var(--shadow-lg);
  max-width: min(92vw, 420px); text-align: center;
  opacity: 0; pointer-events: none; transition: opacity .2s ease, transform .2s ease;
}
.snow-toast.show { opacity: 1; transform: translate(-50%, 0); }
@media (prefers-reduced-motion: reduce) {
  .snow-toast { transition: opacity .2s ease; transform: translate(-50%, 0); }
}

/* ── Confetti: gentle snowfall (celebration) ──────────────────────────── */
/* Pure CSS/DOM; each .snowflake gets its own duration/delay inline. Sits above
   everything, ignores pointer events, and self-removes after the fall. Snowball's
   buyer is often stressed, so this is a soft, slow drift — not a loud burst. */
.snowfall-layer { position: fixed; inset: 0; z-index: 150; pointer-events: none; overflow: hidden; }
.snowfall-layer .snowflake {
  position: absolute; top: -16px; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #ffffff, var(--brand-light));
  box-shadow: 0 0 6px rgba(103,232,249,.55);
  animation-name: snow-fall; animation-timing-function: linear; animation-fill-mode: forwards;
}
@keyframes snow-fall {
  0%   { transform: translateY(-16px) translateX(0); opacity: 0; }
  10%  { opacity: 1; }
  90%  { opacity: 1; }
  100% { transform: translateY(102vh) translateX(24px); opacity: 0; }
}
/* Reduced motion: draw nothing (JS also skips creating flakes) — the warm copy
   carries the moment on its own. */
@media (prefers-reduced-motion: reduce) {
  .snowfall-layer { display: none; }
  .snowfall-layer .snowflake { animation: none; }
}

/* ── Keyboard focus visibility (WCAG 2.4.7) — added from experience audit ── */
:focus-visible { outline: 2px solid var(--brand, currentColor); outline-offset: 2px; border-radius: 3px; }
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible, .restore-code-input:focus-visible { outline: 2px solid var(--brand, currentColor); outline-offset: 1px; }
