/* perawise-web — all styles for every page.
   Tokens mirror the app's Theme.swift. Light is the default whatever the OS says;
   dark applies only when /js/site.js sets data-theme="dark" on <html>. The iPhone is the
   default platform; Android content shows only when site.js sets data-platform="android".
   No web fonts: the system stack is SF Pro on Apple devices, which is the app's own face. */

:root {
  color-scheme: light;

  --surface-app: #F2F3F6;    /* repeated in site.js COLORS and every page's <meta name="theme-color"> */
  --surface-card: #FFFFFF;
  --surface-sunken: #F1F2F5;
  --brand: #1B6E4A;          /* text and icons */
  --brand-fill: #1B6E4A;     /* fills that carry white text */
  --brand-pressed: #124A33;
  --text-primary: #14171A;
  --text-secondary: #545B66; /* 5.9:1 on --surface-tint */
  --text-tertiary: #686F7B;  /* never on a tint: 4.4:1 */
  --text-quiet: #838994;     /* decorative numerals only, never words: 3.2:1 on --surface-app */
  --on-brand: #FFFFFF;       /* text on --brand-fill */
  --border: #E1E4E9;

  /* Web-only surfaces. The mint carries the brand; the three pale hues are the app's own
     Quick Links colours (Budgets amber, Bills purple, Goals teal), washed out. */
  --surface-tint: #E6F1EA;
  --tint-bills: #ECE9F6;
  --tint-budgets: #F5EEDD;
  --tint-goals: #E0F0EF;
  /* Rules drawn on --surface-tint: the brand, thinned. Both follow --brand into dark. */
  --tint-rule: color-mix(in srgb, var(--brand) 14%, transparent);
  --tint-rule-strong: color-mix(in srgb, var(--brand) 22%, transparent);

  --bezel: #0B0C0E;
  --rim: #25282D;
  --island: #000000;

  /* The iPhone/Android switch: a track, and the pill under the chosen side. The pill's own
     fill is barely off the track (1.3:1), so its edge is what marks the choice (WCAG 1.4.11). */
  --segment-track: var(--border);    /* --text-secondary on it: 5.4:1 */
  --segment-on: var(--surface-card);
  --segment-edge: #767C87;           /* 3.3:1 on --segment-track, 4.2:1 on --segment-on */
  --segment-shadow: 0 1px 2px rgb(20 23 26 / 0.1);

  --radius-card: 28px;
  --radius-compact: 16px;
  --shadow-phone: 0 1px 2px rgb(20 23 26 / 0.06), 0 18px 40px -12px rgb(20 23 26 / 0.28);
  --shadow-card: 0 1px 2px rgb(20 23 26 / 0.04);

  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, "Segoe UI", Roboto, sans-serif;
  --font-display: -apple-system, BlinkMacSystemFont, "SF Pro Display", system-ui, "Segoe UI", Roboto, sans-serif;

  /* Type scale. Text sizes come from here; only the display headings and the hero intro are fluid. */
  --text-sm: 0.9375rem;      /* 15px: eyebrows, fine print, status chip, footer, policy intro and footer */
  --text-body: 1.0625rem;    /* 17px: body, card and list text, the zero-ledger heading */
  --text-lead: 1.125rem;     /* 18px: section intros, policy section headings */
  --text-lg: 1.1875rem;      /* 19px: the wordmark, the policy lead */
  --text-title: 1.25rem;     /* 20px: step and card headings */
  --text-intro: clamp(1.125rem, 1rem + 0.5vw, 1.3125rem);      /* 18-21px: the hero's intro only */
  --text-section: clamp(2rem, 1.35rem + 2.4vw, 3rem);          /* 32-48px: major section titles */
  --text-section-minor: clamp(1.75rem, 1.35rem + 1.5vw, 2.25rem); /* 28-36px: minor section titles */

  --gutter: max(16px, 4vw);
  --max: 72rem;
  --space-section: clamp(4rem, 3rem + 5vw, 7.5rem);
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --surface-app: #0F1113;   /* repeated in site.js COLORS.dark */
  --surface-card: #1A1D21;
  --surface-sunken: #16191D;
  --brand: #3E9B70;          /* 4.7:1 on --surface-tint */
  --brand-fill: #358460;     /* 4.5:1 under white text */
  --brand-pressed: #2C7552;
  --text-primary: #F2F3F6;
  --text-secondary: #A8B0BC; /* 7.4:1 on --surface-tint */
  --text-tertiary: #7F8794;
  --text-quiet: #5E6570;     /* 3.2:1 on --surface-app */
  --border: #2A2F36;

  --surface-tint: #16241C;
  --tint-bills: #1D1B2A;
  --tint-budgets: #241E12;
  --tint-goals: #122321;

  --rim: #343941;

  --segment-track: var(--surface-card);
  --segment-on: var(--rim);          /* --text-primary on it: 10.5:1 */
  --segment-edge: #6A717D;           /* 3.4:1 on --segment-track */
  --segment-shadow: 0 1px 2px rgb(0 0 0 / 0.35);

  --shadow-phone: 0 18px 40px -12px rgb(0 0 0 / 0.7);
  --shadow-card: none;
}

/* ---------- Base ---------- */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--surface-app);
  color: var(--text-primary);
  font-family: var(--font);
  font-size: var(--text-body);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { display: block; max-width: 100%; height: auto; }

h1, h2, h3 {
  font-family: var(--font-display);
  margin: 0;
  text-wrap: balance;
}

p { margin: 0; text-wrap: pretty; }

a { color: var(--brand); text-underline-offset: 0.18em; text-decoration-thickness: 1px; }
a:hover { text-decoration-thickness: 2px; }

:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 3px;
  border-radius: 6px;
}

.skip-link {
  position: absolute;
  left: var(--gutter);
  top: 0.75rem;
  z-index: 10;
  padding: 0.6rem 1rem;
  border-radius: 999px;
  background: var(--brand-fill);
  color: var(--on-brand);
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-200%);
}
.skip-link:focus { transform: none; }

/* Read by screen readers, not drawn. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.wrap {
  width: 100%;
  max-width: calc(var(--max) + 2 * var(--gutter));
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* ---------- Header ---------- */

.site-header { container: header / inline-size; }
.site-header .wrap {
  display: flex;
  flex-wrap: wrap;           /* at large text sizes the actions drop below the wordmark */
  align-items: center;
  justify-content: space-between;
  gap: 0.25rem 0.75rem;
  padding-block: 1rem;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  color: var(--text-primary);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 750;
  letter-spacing: -0.02em;
  text-decoration: none;
  white-space: nowrap;
}
.wordmark img {
  width: 32px;
  height: 32px;
  border-radius: 22.5%;
  box-shadow: 0 0 0 1px var(--border);
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-left: auto;         /* stays right-aligned when it wraps to its own row */
}

/* The iPhone/Android switch. It sits between the wordmark and the actions in the markup, so
   Tab follows the one-row header left to right. On phones it takes a centred row of its own
   under the other two, so there Tab visits it before the actions on the row above: a known
   trade-off, since no single order matches both layouts. The landing page's is hidden in the
   markup until site.js wires it; the privacy pages' is two plain links. */
.header-switch {
  order: 3;                  /* flex only: the stacked header draws it last */
  flex: 1 0 100%;
  display: flex;
  justify-content: center;
}
.header-switch[hidden] { display: none; }

/* One row once the header is wide for its text: the query's em follows the text size, so at
   200% text the header keeps stacking instead of overlapping (36.5em is 620 px at normal
   size, so a 640 px window with a classic scrollbar still gets one row). Every item is pinned to row 1, so the flex-only order above can never push the
   switch onto a new grid row. */
@container header (min-width: 36.5em) {
  .site-header .wrap {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    gap: 0.75rem;
  }
  .site-header .wordmark { grid-area: 1 / 1; justify-self: start; }
  .header-switch { grid-area: 1 / 2; }
  .header-actions { grid-area: 1 / 3; justify-self: end; }
}

/* Each side is a full 44px target; the pill is drawn inside it, 4px in. */
.segmented {
  display: inline-flex;
  max-width: 100%;
  border-radius: 999px;
  background: var(--segment-track);
  box-shadow: inset 0 0 0 1px var(--border);
}
.segmented > a,
.segmented > button {
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  /* 4vw caps the sides at large text on a phone (at 200% on a 320 px screen, 1.125rem alone
     would push the pair past the gutter). */
  padding: 0.25rem min(1.125rem, 4vw);
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--text-secondary);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 600;          /* the same weight on both sides, so choosing never shifts the layout */
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}
.segmented > a::before,
.segmented > button::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 4px;
  border-radius: 999px;
}
.segmented > a:hover,
.segmented > button:hover { color: var(--text-primary); }
.segmented > [aria-pressed="true"],
.segmented > [aria-current="page"] { color: var(--text-primary); cursor: default; }
.segmented > [aria-pressed="true"]::before,
.segmented > [aria-current="page"]::before {
  background: var(--segment-on);
  box-shadow: 0 0 0 1px var(--segment-edge), var(--segment-shadow);
}
.segmented > :focus-visible { outline-offset: -2px; border-radius: 999px; }

/* Platform-specific content: data-only="ios" or "android" on any element. A display:none
   element is out of the accessibility tree, and with JS on a lazy image inside one is never
   fetched (Chrome ignores loading="lazy" when scripting is off, so a no-JS visit gets them all).
   !important so a component's own display rule (a shot-dark image, say) can never undo it. */
:root:not([data-platform="android"]) [data-only="android"],
:root[data-platform="android"] [data-only="ios"] { display: none !important; }

.site-nav a {
  display: inline-block;
  padding: 0.6rem 0.5rem;
  color: var(--text-secondary);
  font-weight: 550;
  text-decoration: none;
}
.site-nav a:hover { color: var(--text-primary); }
.site-nav a[aria-current="page"] { color: var(--text-primary); }

/* Hidden in the markup; site.js reveals it, so there is never a dead button. */
.theme-toggle {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  flex: none;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-sunken);
  color: var(--text-primary);
  cursor: pointer;
}
.theme-toggle[hidden] { display: none; }
.theme-toggle:hover { background: var(--surface-card); }
.theme-toggle:focus-visible { border-radius: 999px; }
.theme-toggle svg { grid-area: 1 / 1; }
.theme-toggle .icon-sun { display: none; }
[data-theme="dark"] .theme-toggle .icon-sun { display: block; }
[data-theme="dark"] .theme-toggle .icon-moon { display: none; }

/* ---------- Phone: a screenshot inside a CSS iPhone, or a Pixel ---------- */

/* The screenshots already carry the status bar, so the Dynamic Island sits over it
   the way it does on a real device. Sizes are shares of the phone's width (cqi). */
.phone {
  position: relative;
  container-type: inline-size;
  width: 100%;
  max-width: 300px;
}
.phone img {
  width: 100%;
  padding: 7px;                        /* fallback without container units */
  padding: 2.2cqi;
  border-radius: 46px;
  border-radius: 15cqi;                /* the screen's corner follows as 15 - 2.2 cqi */
  /* The screen area shows the page colour, not the bezel, while a lazy image loads. */
  background: linear-gradient(var(--surface-app), var(--surface-app)) content-box, var(--bezel);
  /* The inset white is the glass edge of the hardware, not a theme colour: it stays in both. */
  box-shadow: 0 0 0 1px var(--rim), inset 0 0 0 1px rgb(255 255 255 / 0.07), var(--shadow-phone);
}
.phone::before {
  content: "";
  position: absolute;
  z-index: 1;
  top: 4.6cqi;
  left: 50%;
  width: 27cqi;
  height: 7.9cqi;
  border-radius: 999px;
  background: var(--island);
  transform: translateX(-50%);
}

/* The Android screenshots in a Pixel-style frame: a slimmer, even bezel, a smaller corner,
   and a punch-hole camera centred in the status bar instead of the Dynamic Island. */
.phone--pixel img {
  padding: 5px;
  padding: 1.6cqi;
  border-radius: 30px;
  border-radius: 9.5cqi;                /* the screen's corner follows as 9.5 - 1.6 cqi */
}
.phone--pixel::before {
  top: 5.7cqi;                          /* centred on the status bar's clock line */
  width: 3.6cqi;
  height: 3.6cqi;
  border-radius: 50%;
}

/* Paired light and dark screenshots follow the toggle, not the OS. A display:none image
   is out of the accessibility tree, and with JS on a lazy one is never fetched until it is
   shown (without JS, Chrome ignores loading="lazy" and fetches every image). All four hero
   shots are lazy too: site.js preloads the one a visit will show from <head>, so it still
   arrives with the page, and a no-JS visit still gets the iPhone light one. */
.shot-dark { display: none; }
[data-theme="dark"] .shot-light { display: none; }
[data-theme="dark"] .shot-dark { display: block; }

/* ---------- Type ---------- */

.eyebrow {
  margin-bottom: 0.875rem;
  color: var(--brand);
  font-size: var(--text-sm);
  font-weight: 650;
}

.section-title {
  font-size: var(--text-section);
  font-weight: 750;
  line-height: 1.04;
  letter-spacing: -0.035em;
}
/* A second tier for the sections that list features, under the ones that make a case. */
.section-title--minor {
  font-size: var(--text-section-minor);
  line-height: 1.08;
  letter-spacing: -0.03em;
}

.section-text {
  max-width: 36ch;
  margin-top: 1rem;
  color: var(--text-secondary);
  font-size: var(--text-lead);
}
.section-text + .section-text { margin-top: 0.75rem; }

.fine {
  margin-top: 1.5rem;
  color: var(--text-secondary);
  font-size: var(--text-sm);
}

/* ---------- Hero ---------- */

.hero {
  overflow-x: clip;
  padding-block: clamp(1.5rem, 1rem + 3vw, 4rem) var(--space-section);
}

.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 3.5rem;
  align-items: center;
}

.hero h1 {
  max-width: 11ch;
  /* The floor gives way to 13vw on the narrowest screens, so at 200% text on a 320 px phone
     "month's" still fits on one line. At normal text 13vw only binds below 338 px. */
  font-size: clamp(min(2.75rem, 13vw), 1.6rem + 5vw, 5rem);
  font-weight: 800;
  line-height: 0.98;
  letter-spacing: -0.04em;
  overflow-wrap: break-word; /* only a word wider than a phone at large text sizes */
}

.hero .lede {
  max-width: 30ch;
  margin-top: 1.5rem;
  color: var(--text-secondary);
  font-size: var(--text-intro);
  line-height: 1.45;
}

.availability { margin-top: 2.25rem; }

/* A status, deliberately not a button: there is no listing to go to yet.
   Brand on the tint is 5.4:1 in light and 4.7:1 in dark. */
.coming-soon {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.375rem 0.875rem;
  border: 1px solid var(--tint-rule-strong);
  border-radius: 999px;
  background: var(--surface-tint);
  color: var(--brand);
  font-weight: 600;
  font-size: var(--text-sm);
}
.coming-soon::before {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.75;
}

.platform {
  margin-top: 0.875rem;
  color: var(--text-secondary);
  font-size: var(--text-sm);
}

/* The whole Home screen, on a soft mint wash. */
.hero-phone {
  position: relative;
  justify-self: center;
  width: min(290px, 76vw);
}
.hero-phone::after {
  content: "";
  position: absolute;
  z-index: -1;
  left: 50%;
  top: 50%;
  width: 190%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(closest-side, var(--surface-tint) 45%, transparent);
  transform: translate(-50%, -48%);
}
.hero-phone .phone { max-width: none; }
.hero { position: relative; isolation: isolate; }

@media (min-width: 52rem) {
  .hero-grid {
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
    gap: 3rem;
  }
  .hero-phone { width: 330px; justify-self: end; margin-right: clamp(0rem, 4vw, 3rem); }
}

/* ---------- How it works ---------- */

.steps { padding-bottom: var(--space-section); }

.steps-grid {
  container: steps / inline-size;
  display: grid;
  gap: 3rem;
  align-items: center;
}

.steps-phone { justify-self: center; width: min(270px, 70vw); order: 2; }
.steps-phone .phone { max-width: none; }

.step-list {
  display: grid;
  margin: 2.25rem 0 0;
  padding: 0;
  list-style: none;
}
.step-list li {
  display: grid;
  grid-template-columns: 4.25rem minmax(0, 1fr);
  gap: 1rem;
  align-items: center;   /* the numeral sits against the whole step, not just its title's baseline */
  padding-block: 1.5rem;
  border-top: 1px solid var(--border);
}
.step-list li:last-child { border-bottom: 1px solid var(--border); }

/* Decorative: the <ol> already carries the order. */
.step-num {
  color: var(--text-quiet);
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 1.8rem + 1.6vw, 3.25rem);
  font-weight: 800;
  line-height: 0.9;
  letter-spacing: -0.05em;
  font-variant-numeric: tabular-nums;
}
.step-list h3 {
  font-size: var(--text-title);
  font-weight: 700;
  letter-spacing: -0.02em;
}
.step-list p {
  margin-top: 0.35rem;
  color: var(--text-secondary);
}

@media (min-width: 52rem) {
  .steps-grid {
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    gap: 5rem;
  }
  .steps-phone { order: 0; width: 300px; }
  .step-list li { grid-template-columns: 5rem minmax(0, 1fr); gap: 1.25rem; }
}

/* Large text on a phone: the text is wide for the space it has (the query's em follows the
   text size). The numeral moves above its step so the words keep the full width. At normal
   text sizes this never matches, even at 320 px (16em is 272 px there). */
@container steps (max-width: 16em) {
  .step-list li { grid-template-columns: minmax(0, 1fr); gap: 0.25rem; align-items: start; }
  .step-num { font-size: 2rem; }
}

/* ---------- Assistant spotlight ---------- */

.spotlight {
  display: grid;
  gap: 2.75rem;
  overflow: hidden;
  padding: clamp(2rem, 1rem + 4.5vw, 4.5rem) clamp(1.5rem, 0.5rem + 4.5vw, 4.5rem) 0;
  border-radius: var(--radius-card);
  background: var(--surface-tint);
}
.spotlight .section-title { max-width: 12ch; }

/* The phone runs off the card's bottom edge. */
.spotlight-phone {
  justify-self: center;
  width: min(280px, 74%);
  height: clamp(20rem, 60vw, 25rem);
}
.spotlight-phone .phone { max-width: none; }

@media (min-width: 52rem) {
  .spotlight {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    gap: 3rem;
  }
  .spotlight-copy { align-self: center; padding-bottom: clamp(2rem, 4vw, 4.5rem); }
  .spotlight-phone { width: 320px; height: 32rem; margin-top: 0.5rem; }
}

/* ---------- Card grids ---------- */

.showcase { padding-top: var(--space-section); }

.showcase-head { max-width: 40rem; margin-bottom: clamp(2rem, 1.5rem + 2vw, 3rem); }

.card-grid {
  display: grid;
  gap: 2.5rem 1.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
@media (min-width: 40rem) { .card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* Below the two-column breakpoint each grid is a row that scrolls sideways, one card at a time,
   with the next one peeking in. The scroller runs to the screen's edges and is a focusable
   region in the markup, so arrow keys scroll it and screen readers name it. The cards' width
   is a share of the scroller (cqi), so the row never widens the page, at any text size. */
.card-scroller { container-type: inline-size; }
/* Range syntax on purpose: the exact complement of the grid's (min-width: 40rem) step, so no
   width gets both layouts or neither. */
@media (width < 40rem) {
  .card-scroller {
    margin-inline: calc(-1 * var(--gutter));
    padding-inline: var(--gutter);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--gutter);
  }
  .card-scroller:focus-visible { outline-offset: -2px; border-radius: 0; }
  .card-scroller .card-grid {
    grid-auto-flow: column;
    grid-auto-columns: 80cqi;
    gap: 1rem;
    width: max-content;
  }
  .card-scroller .card-item { scroll-snap-align: start; }
}
@media (min-width: 60rem) { .card-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* A tinted panel with the phone's lower half cut off by its bottom edge. */
.card-shot {
  display: flex;
  justify-content: center;
  aspect-ratio: 4 / 3.5;
  overflow: hidden;
  padding-top: 10%;
  border-radius: var(--radius-card);
  background: var(--surface-tint);
}
.card-shot .phone { width: 62%; max-width: none; flex: none; }

/* The essentials take the hue of their Quick Links icon in the app. */
.card-shot--bills { background: var(--tint-bills); }
.card-shot--budgets { background: var(--tint-budgets); }
.card-shot--goals { background: var(--tint-goals); }

.card-item h3 {
  margin-top: 1.25rem;
  font-size: var(--text-title);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.02em;
}
.card-item p {
  max-width: 34ch;
  margin-top: 0.375rem;
  color: var(--text-secondary);
}

/* ---------- Privacy summary ---------- */

.privacy-summary { padding-block: var(--space-section); }
.privacy-summary > .wrap { container: privacy / inline-size; }

.privacy-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2.5rem;
  padding: clamp(1.75rem, 0.75rem + 4.5vw, 4.5rem);
  border-radius: var(--radius-card);
  background: var(--surface-card);
  box-shadow: var(--shadow-card);
}
[data-theme="dark"] .privacy-card { box-shadow: 0 0 0 1px var(--border); }
@media (min-width: 52rem) {
  .privacy-card { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 4rem; align-items: center; }
}

.text-link {
  display: inline-block;
  margin-top: 1.75rem;
  font-weight: 650;
}

/* What Perawise does not have, kept like a ledger. */
.zero {
  padding: 0.5rem clamp(1.25rem, 0.75rem + 2vw, 1.75rem) 0.75rem;
  border-radius: var(--radius-compact);
  background: var(--surface-tint);
}
/* In dark the tint is barely off the card (1.05:1), so the table gets its own faint edge. */
[data-theme="dark"] .zero { box-shadow: 0 0 0 1px var(--tint-rule-strong); }
/* The row size, not an eyebrow: the zeros are the only green inside the tint. */
.zero-title {
  padding-block: 1.1rem 0.9rem;
  border-bottom: 1px solid var(--tint-rule-strong);
  color: var(--text-primary);
  font-family: var(--font);
  font-size: var(--text-body);
  font-weight: 650;
}
.zero-ledger { margin: 0; }
.zero-ledger div {
  display: flex;
  align-items: center;       /* the zero sits against its whole label, which can wrap */
  justify-content: space-between;
  gap: 1.5rem;
  padding-block: 1.1rem;
}
.zero-ledger div + div { border-top: 1px solid var(--tint-rule); }
.zero-ledger dt {
  min-width: 0;              /* a long label wraps instead of pushing its zero out */
  overflow-wrap: anywhere;
  color: var(--text-primary);
  font-weight: 500;
}
.zero-ledger dd {
  flex: none;
  margin: 0;
  font-family: var(--font-display);
  font-size: 2rem;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  color: var(--brand);
}

.yours {
  display: grid;
  gap: 0.75rem;
  margin: 1.5rem 0 0;
  padding: 0;
  list-style: none;
}
.yours li {
  position: relative;
  padding-left: 1.25rem;
  color: var(--text-secondary);
}
.yours li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 50%;
  background: var(--brand);
}
.yours strong { color: var(--text-primary); font-weight: 600; }

/* Large text on a phone (see the steps rule above): the rem paddings would take most of the
   width, so they tighten, and each label sits above its zero instead of beside it. */
@container privacy (max-width: 16em) {
  .privacy-card { padding: 1.5rem 0.75rem; }
  .zero { padding-inline: 0.625rem; }
  .zero-ledger div { flex-direction: column; align-items: flex-start; gap: 0.25rem; }
}

/* ---------- Footer ---------- */

.site-footer {
  border-top: 1px solid var(--border);
  background: var(--surface-sunken);
  color: var(--text-secondary);
  font-size: var(--text-sm);
}
.site-footer .wrap { padding-block: 3rem 2rem; }

/* Columns sit side by side while they fit, and wrap before the email address breaks. */
.footer-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 2.25rem 3rem;
}
.footer-brand { flex: 1 0 100%; }
.footer-brand p { margin-top: 0.75rem; max-width: 26ch; }

.footer-label {
  margin-bottom: 0.125rem;   /* the links' own padding makes up the rest of the gap */
  color: var(--text-primary);
  font-weight: 650;
}
.site-footer ul {
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
}
/* Each link is a 44px-tall target; the padding stands in for the list's gap. */
.site-footer ul a {
  display: inline-block;
  max-width: 100%;
  padding-block: 0.65rem;
  color: var(--text-secondary);
  text-decoration: none;
  overflow-wrap: anywhere;   /* phones and large text only; reset to break-word at 52rem below */
}
.site-footer ul a:hover { color: var(--text-primary); text-decoration: underline; }
.site-footer ul a[aria-current="page"] { color: var(--text-primary); }

.footer-legal {
  margin-top: 2rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
}

@media (min-width: 52rem) {
  .footer-grid { flex-wrap: nowrap; gap: 3rem; }
  .footer-brand { flex: 2 1 0; }
  .footer-col { flex: 1 1 0; }
  /* Side by side, the column must hold the whole address: break-word keeps its min width. */
  .site-footer ul a { overflow-wrap: break-word; }
}

/* ---------- Privacy page ---------- */

.policy { padding-block: 1rem var(--space-section); }

/* On phones the policy sits on the page itself, so the text gets the full width.
   From 40rem up it is a card. */
.policy-doc {
  max-width: 42rem;
  margin-inline: auto;
  padding-top: 0.5rem;
}
@media (min-width: 40rem) {
  .policy-doc {
    padding: clamp(1.5rem, 0.75rem + 4vw, 3.5rem);
    border-radius: var(--radius-card);
    background: var(--surface-card);
    box-shadow: var(--shadow-card);
  }
  [data-theme="dark"] .policy-doc { box-shadow: 0 0 0 1px var(--border); }
}

.policy h1 {
  font-size: clamp(2.25rem, 1.5rem + 3vw, 3.25rem);
  font-weight: 800;
  line-height: 1.02;
  letter-spacing: -0.04em;
}

.policy-intro {
  margin-top: 0.75rem;
  color: var(--text-secondary);
  font-size: var(--text-sm);
}

.policy-lead {
  margin-top: 2rem;
  padding-top: 2rem;
  border-top: 1px solid var(--border);
  color: var(--text-primary);
  font-size: var(--text-lg);
  line-height: 1.5;
}

.policy-sections { display: grid; gap: 2rem; margin-top: 2.5rem; }

.policy h2 {
  font-size: var(--text-lead);
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.015em;
}
.policy h2 + p {
  margin-top: 0.5rem;
  color: var(--text-secondary);
  line-height: 1.6;
}

.policy-footer {
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
  color: var(--text-tertiary);
  font-size: var(--text-sm);
}
.policy-footer p + p { margin-top: 0.2rem; }
.policy-footer a { color: inherit; overflow-wrap: anywhere; }
.policy-footer a:hover { color: var(--text-primary); }

/* ---------- Motion ---------- */

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
  .theme-toggle { transition: background-color 0.15s ease; }
  .segmented > a,
  .segmented > button { transition: color 0.15s ease; }
}
