/* app.css — shared shell for the auth / account / privacy pages.
 *
 * Design tokens are copied verbatim from dashboard_template.html (.viz-root:
 * the Rocket Money measured system in research/rocketmoney_dashboard_design.md
 * §4.4) so these pages look like the same product. Dark mode uses the same
 * selector shape as the dashboard: prefers-color-scheme (guarded so an
 * explicit data-theme="light" wins) plus :root[data-theme="dark"].
 *
 * --danger-bg / --danger-ink are the two additions auth.md §7.1 marks as new
 * (the measured alert wash; the darkened red for >=4.5:1 on the wash).
 *
 * Contrast pass (measured with WCAG 2.x relative-luminance ratios):
 *   --link      light --red #de3341 on --page is 4.21:1 (fails); #c62d3c —
 *               the documented CTA hover red — is 5.10:1 there, 5.47:1 on
 *               --card. Dark keeps #ff5c6a (6.47:1 on the dark page).
 *   --green-ink light --green #2c8440 on --green-tint #eaf3ec is 4.13:1
 *               (fails for banner text; the .check glyph only needs 3:1 and
 *               keeps --green). #277639 is 4.96:1 there.
 *   --btn-*     the CTA trio. Dark --red #ff5c6a carries white at 3.00:1
 *               (fails), so dark starts at #c62d3c (5.47:1) and hovers/actives
 *               LIGHTER (#d23042 4.95:1, #de3341 4.51:1) — light mode keeps
 *               its darker downward hover. No new colour values: only existing
 *               system reds, re-assigned per theme.
 * --hero-overlap is the shared geometry of the auth hero band and the card
 * that overlaps its bottom edge (theme-independent).
 */

:root {
  color-scheme: light;
  --page: #f7f7f7;
  --card: #ffffff;
  --ink: #1c1b1a;
  --ink2: #545453;
  --hairline: #ececec;
  --chip: #f3f3f3;
  --grad-a: #ab285f;
  --grad-b: #d23042;
  --blue: #7594fc;
  --blue-fill: #edf1ff;
  --green: #2c8440;
  --green-tint: #eaf3ec;
  --green-ink: #277639;
  --red: #de3341;
  --link: #c62d3c;
  --btn-bg: #de3341;
  --btn-hover: #c62d3c;
  --btn-active: #b32836;
  --tab-inactive: #4c6870;
  --track: #f0f0f0;
  --danger-bg: #fee7e7;
  --danger-ink: #96192b;
  --hero-overlap: 48px;
}

@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) {
    color-scheme: dark;
    --page: #0d0d0e;
    --card: #17171a;
    --ink: #f0efec;
    --ink2: #c3c2b7;
    --hairline: #2c2c2c;
    --chip: #26262a;
    --grad-a: #7c1d44;
    --grad-b: #9c2230;
    --blue: #6b8bf7;
    --blue-fill: rgba(107,139,247,0.16);
    --green: #4cc38a;
    --green-tint: rgba(76,195,138,0.14);
    --green-ink: #4cc38a;
    --red: #ff5c6a;
    --link: #ff5c6a;
    --btn-bg: #c62d3c;
    --btn-hover: #d23042;
    --btn-active: #de3341;
    --tab-inactive: #8b949c;
    --track: #26262a;
    --danger-bg: rgba(222,51,65,0.16);
    --danger-ink: #ff8a94;
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --page: #0d0d0e;
  --card: #17171a;
  --ink: #f0efec;
  --ink2: #c3c2b7;
  --hairline: #2c2c2c;
  --chip: #26262a;
  --grad-a: #7c1d44;
  --grad-b: #9c2230;
  --blue: #6b8bf7;
  --blue-fill: rgba(107,139,247,0.16);
  --green: #4cc38a;
  --green-tint: rgba(76,195,138,0.14);
  --green-ink: #4cc38a;
  --red: #ff5c6a;
  --link: #ff5c6a;
  --btn-bg: #c62d3c;
  --btn-hover: #d23042;
  --btn-active: #de3341;
  --tab-inactive: #8b949c;
  --track: #26262a;
  --danger-bg: rgba(222,51,65,0.16);
  --danger-ink: #ff8a94;
}

/* ---- base ---- */
* { box-sizing: border-box; }
body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--page);
  color: var(--ink);
  font-family: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 14px;
  line-height: 1.45;
  -webkit-text-size-adjust: 100%;
}
a { color: var(--link); text-decoration: underline; text-underline-offset: 2px; }
a:hover { color: var(--ink); }
img, svg { max-width: 100%; }
.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;
}

/* ---- brand bar ---- */
.topbar {
  position: sticky; top: 0; z-index: 20;
  min-height: 52px;
  background: linear-gradient(135deg, var(--grad-a), var(--grad-b));
  color: #ffffff;
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  /* the notch/status-bar inset belongs on the TOP edge of the sticky bar */
  padding: calc(10px + env(safe-area-inset-top)) 16px 10px;
}
.topbar .wordmark {
  font-weight: 800; font-size: 17px; letter-spacing: -0.01em;
  color: #ffffff; text-decoration: none;
}
.topnav { display: flex; align-items: center; gap: 14px; }
.topnav a, .topnav .linklike {
  color: rgba(255, 255, 255, 0.92);
  font-size: 13px; font-weight: 600;
  text-decoration: none;
}
.topnav a:hover, .topnav .linklike:hover { color: #ffffff; text-decoration: underline; }
.inline-form { display: inline; margin: 0; }
.linklike {
  background: none; border: 0; padding: 0; font-family: inherit; cursor: pointer;
}

/* ---- shell / columns ---- */
.shell {
  flex: 1;
  width: 100%;
  max-width: 600px;
  margin: 0 auto;
  padding: 20px 16px 32px;
  display: flex;
  flex-direction: column;
}
.auth-wrap {
  width: 100%;
  max-width: 400px;
  margin: auto auto;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
/* "New here? ..." / "Already have an account? ..." sit on the page, not in
   the card (auth.md §7.2 layout), so the wrap's gap owns the spacing. */
.auth-wrap > .alt { margin: 0; }

/* ---- auth hero band (login / sign-up) -------------------------------
   The dashboard's brand bar promoted to a taller gradient band; the auth
   card overlaps its bottom edge. .shell--auth zeroes the shell's top
   padding so the overlap is exactly --hero-overlap at every width. */
.auth-hero {
  background: linear-gradient(135deg, var(--grad-a), var(--grad-b));
  color: #ffffff;
  padding: calc(24px + env(safe-area-inset-top)) 16px calc(var(--hero-overlap) + 44px);
  text-align: center;
}
.auth-hero .wordmark {
  font-weight: 800; font-size: 22px; letter-spacing: -0.01em;
  color: #ffffff;
}
/* .shell.shell--auth (not just .shell--auth): must also beat the
   min-width:720px .shell padding rule that comes later in this file. */
.shell.shell--auth {
  padding-top: 0;
  padding-bottom: calc(32px + env(safe-area-inset-bottom));
}
/* Fallback when something sits above the card (a flash banner — e.g. the
   post-delete redirect lands on /login): no overlap, just breathing room. */
.auth-wrap--hero { margin-top: 14px; }
/* Nothing above the card: it overlaps the hero band's bottom edge. */
.auth-wrap--hero:first-child { margin-top: calc(-1 * var(--hero-overlap)); }
.shell--auth > .flash-stack { margin-top: 14px; }

.page-wrap { display: flex; flex-direction: column; gap: 14px; }
.page-title { font-size: 24px; font-weight: 800; margin: 0; letter-spacing: -0.01em; }

/* ---- cards ---- */
.card {
  background: var(--card);
  border-radius: 16px;
  padding: 24px;
  /* flat by design: grouping is white-on-#f7f7f7 plus radius, no shadows */
}
.card h2 { margin: 0 0 6px; font-size: 20px; font-weight: 800; letter-spacing: -0.01em; }
.auth-card h1 { margin: 0 0 4px; font-size: 24px; font-weight: 800; letter-spacing: -0.01em; }
.sub { margin: 0 0 18px; font-size: 14px; color: var(--ink2); }
.hint { margin: 6px 0 14px; font-size: 13px; color: var(--ink2); }
.sentence { margin: 8px 0; font-size: 14px; line-height: 1.5; }
.card-danger h2 { color: var(--danger-ink); }

/* ---- forms ---- */
.field { margin-bottom: 14px; }
label { display: block; font-size: 13px; font-weight: 600; color: var(--ink2); margin-bottom: 6px; }
input[type="text"], input[type="email"], input[type="password"] {
  width: 100%; height: 48px; padding: 0 14px;
  border: 1px solid var(--hairline); border-radius: 10px;
  background: var(--card); color: var(--ink);
  font: inherit; font-size: 16px; /* 16px prevents iOS zoom on focus */
}
input::placeholder { color: var(--ink2); opacity: 0.7; }
input:focus {
  outline: none;
  border-color: var(--red);
  box-shadow: 0 0 0 3px rgba(222, 51, 65, 0.22);
}
input[aria-invalid="true"] { border-color: var(--red); }
.field-error {
  display: flex; align-items: flex-start; gap: 6px;
  margin: 6px 0 0; font-size: 13px; font-weight: 600; color: var(--danger-ink);
}
.field-error::before {
  content: "!";
  flex: none; width: 15px; height: 15px; margin-top: 1px;
  border-radius: 50%; background: var(--danger-ink); color: var(--page);
  font-size: 11px; font-weight: 800; line-height: 15px; text-align: center;
}
.pw-wrap { position: relative; }
.pw-wrap input { padding-right: 54px; }
.pw-toggle {
  position: absolute; right: 2px; top: 2px;
  width: 44px; height: 44px;
  display: grid; place-items: center;
  border: 0; border-radius: 10px; background: none;
  color: var(--ink2); cursor: pointer;
}
.pw-toggle:hover { background: var(--chip); color: var(--ink); }

/* ---- forgot password (login) ----------------------------------------
   A native <details> so the honest "coming soon" note works with zero
   JavaScript (no mailer exists yet; the deployment operator resets
   passwords — see webapp/templates/privacy.html "Not built yet"). */
.forgot { margin: 10px 0 0; }
.forgot summary {
  display: inline-block; cursor: pointer;
  font-size: 13px; font-weight: 600; color: var(--link);
  text-decoration: underline; text-underline-offset: 2px;
  list-style: none;  /* hide the native marker; we draw the chevron */
}
.forgot summary::-webkit-details-marker { display: none; }
.forgot summary:hover { color: var(--ink); }
.forgot summary::after {
  content: ""; display: inline-block;
  width: 6px; height: 6px; margin-left: 7px; vertical-align: 1px;
  border-right: 1.8px solid currentColor; border-bottom: 1.8px solid currentColor;
  transform: rotate(45deg);
  transition: transform 0.18s ease;
}
.forgot[open] summary::after { transform: rotate(225deg); }
.forgot-note {
  margin: 8px 0 0; padding: 10px 12px;
  border-radius: 10px; background: var(--chip); color: var(--ink);
  font-size: 13px; line-height: 1.45;
}

.btn-primary {
  width: 100%; height: 48px; margin-top: 6px;
  border: 0; border-radius: 12px;
  background: var(--btn-bg); color: #ffffff;
  font-family: inherit; font-size: 16px; font-weight: 700;
  cursor: pointer;
}
.btn-primary:hover { background: var(--btn-hover); }
.btn-primary:active { background: var(--btn-active); }
.btn-primary:disabled { opacity: 0.55; cursor: default; }
/* submit/loading state (app.js): label swapped via data-busy, spinner here.
   prefers-reduced-motion stops the spin globally (the ring stays). */
.btn-primary.is-busy::after {
  content: ""; display: inline-block;
  width: 14px; height: 14px; margin-left: 8px;
  border: 2px solid rgba(255, 255, 255, 0.45);
  border-top-color: #ffffff; border-radius: 50%;
  vertical-align: -2px;
  animation: btn-spin 0.7s linear infinite;
}
@keyframes btn-spin { to { transform: rotate(360deg); } }
.btn-danger {
  width: 100%; height: 48px; margin-top: 6px;
  border: 0; border-radius: 12px;
  background: var(--danger-bg); color: var(--danger-ink);
  font-family: inherit; font-size: 16px; font-weight: 700;
  cursor: pointer;
}
.btn-danger:hover { filter: brightness(0.97); }
.alt { margin: 16px 0 0; font-size: 14px; color: var(--ink2); text-align: center; }
.smallprint {
  margin: 18px 0 0; padding-top: 14px; border-top: 1px solid var(--hairline);
  font-size: 13px; color: var(--ink2);
}

/* ---- banners (flash + form errors) ---- */
.flash-stack { display: flex; flex-direction: column; gap: 10px; margin-bottom: 14px; }
.banner {
  border-radius: 12px; padding: 12px 14px;
  font-size: 13px; font-weight: 600;
}
.banner-error { background: var(--danger-bg); color: var(--danger-ink); }
.banner-success { background: var(--green-tint); color: var(--green-ink); }
.auth-card .banner { margin-bottom: 16px; }

/* ---- profile rows / plain lists ---- */
.row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  padding: 10px 0; border-bottom: 1px solid var(--hairline); font-size: 14px;
}
.row:last-child { border-bottom: 0; }
.row-label { color: var(--ink2); }
.row-value { font-weight: 600; text-align: right; word-break: break-word; }
.plain-list { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 8px; font-size: 14px; line-height: 1.5; }
.link-row { margin: 4px 0 0; font-size: 14px; }
.link-dot { color: var(--ink2); margin: 0 4px; }

/* ---- "See where your data goes" expander ---- */
.trust { display: flex; flex-direction: column; }
.trust-toggle {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; padding: 10px 12px;
  border: 0; border-radius: 10px; background: none;
  color: var(--ink2); font-family: inherit; font-size: 13px; font-weight: 600;
  text-decoration: underline; text-underline-offset: 3px;
  cursor: pointer;
}
.trust-toggle:hover { background: var(--chip); color: var(--ink); }
.trust-toggle .chev { transition: transform 0.18s ease; }
.trust-toggle[aria-expanded="true"] .chev { transform: rotate(180deg); }
.trust-panel {
  margin-top: 10px; padding: 20px;
  background: var(--card); border-radius: 16px;
  text-align: left;
}
.trust-title { margin: 0 0 14px; font-size: 16px; font-weight: 800; }
.flow-steps { list-style: none; margin: 0; padding: 0; }
.flow-steps li { position: relative; padding: 0 0 16px 38px; }
.flow-steps li:last-child { padding-bottom: 0; }
.flow-steps li:not(:last-child)::before {
  content: ""; position: absolute; left: 12px; top: 30px; bottom: 2px;
  width: 2px; background: var(--hairline);
}
.flow-steps p { margin: 0; font-size: 14px; line-height: 1.5; }
.step-n {
  position: absolute; left: 0; top: 0;
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--chip); color: var(--ink);
  font-size: 13px; font-weight: 700;
  display: grid; place-items: center;
}
.promises {
  list-style: none; margin: 18px 0 0; padding: 16px 0 0;
  border-top: 1px solid var(--hairline);
  display: flex; flex-direction: column; gap: 10px;
}
.promises li { display: flex; align-items: flex-start; gap: 10px; font-size: 14px; line-height: 1.45; }
.check {
  flex: none; width: 18px; height: 18px; margin-top: 1px;
  border-radius: 50%; background: var(--green-tint); color: var(--green);
  display: grid; place-items: center;
}
.powered {
  display: flex; align-items: center; gap: 8px;
  margin-top: 18px; padding-top: 14px;
  border-top: 1px solid var(--hairline);
  font-size: 13px; color: var(--ink2);
}
.powered a { color: var(--ink2); }
.powered a:hover { color: var(--ink); }
.plaid-mark { color: var(--ink2); }

/* ---- login card trust strip -----------------------------------------
   The two verbatim promise lines + the small Plaid mark, surfaced from
   the collapsed expander onto the card itself (_plaid_trust.html
   card_trust_strip). Reuses .promises/.powered with the --flush modifiers
   so the card and the panel render the same components. */
.card-trust {
  margin-top: 18px; padding-top: 16px;
  border-top: 1px solid var(--hairline);
}
.promises--flush { margin: 0; padding: 0; border-top: 0; }
.powered--flush { margin: 12px 0 0; padding: 0; border-top: 0; }

/* ---- trust footer ---- */
.trust-footer {
  margin-top: auto; padding: 28px 4px 8px;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  font-size: 12px; color: var(--ink2); text-align: center;
}
.trust-footermark {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  opacity: 0.75;
}
.plaid-lockup { color: var(--ink2); }
.plaid-links { display: inline-flex; flex-wrap: wrap; justify-content: center; gap: 2px 2px; line-height: 1.9; }
.plaid-links a { color: var(--ink2); }
.plaid-links a:hover { color: var(--ink); }

/* ---- focus + motion ---- */
a:focus-visible, button:focus-visible, input:focus-visible,
summary:focus-visible, .trust-toggle:focus-visible {
  outline: 2px solid var(--red); outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* ---- wider screens ---- */
@media (min-width: 720px) {
  .shell { padding-top: 32px; padding-bottom: 40px; }
}
