/*
 * The landing page — five sections, one script.
 *
 * Standalone by design, the way `packages/app/public/legal.html` and the docs'
 * stylesheet are. The app's sheet is three thousand lines about tables and
 * popovers, and this page has neither; what the three share is the token block
 * below, copied from Nocturne and named the way `packages/app/src/styles.css`
 * names it. If a token moves in the app it moves here, and there is nothing else
 * to keep in step.
 *
 * The component classes — `.nav`, `.btn`, `.seg` — are Nocturne's, reproduced
 * rather than imported for the same reason: this page must render from two
 * requests, without a bundler.
 *
 * The page grew from one screen to five bands: the hero, then `01 Accounts`,
 * `02 Templates`, `03 Categories` and `04 Net worth`. Each band is a claim in
 * words beside an illustration of the screen that makes it good. The
 * illustrations are inert and their figures invented — see the note above
 * `.mock` — and every number in them obeys the app's own grouping rule, so a
 * visitor never sees a figure the app would not print.
 */

/* Inter, self-hosted. Latin and Latin Extended, because `zł` puts its ł in the
   extended range and the largest number on the page would otherwise change
   typeface halfway through. The files are placed at /fonts/ by the image
   (see Dockerfile) and by the dev server (see vite.config.ts); both take them
   from @fontsource/inter, so the page and the app cannot end up on different
   cuts of the face. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/inter-latin-400-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
    U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/inter-latin-ext-400-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
    U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
    U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/inter-latin-500-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
    U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/inter-latin-ext-500-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
    U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
    U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --font: "Inter", "Geist Sans", system-ui, -apple-system, sans-serif;
  --heading-weight: 500;

  --space-2: 5.6px;
  --space-3: 8.4px;
  --space-4: 11.2px;
  --radius-md: 8px;

  /* The page gutter, and the one value the mobile view changes. */
  --gutter: 56px;

  /* The content column every band centres on, gutters excluded. */
  --column: 1200px;

  /* Two derived colours whose formula is the same on both grounds, so they are
     written once and resolve per theme through `--bg` and `--text`. The bar
     lets the page show through itself; `--divider-soft` is the rule *inside* a
     card, quieter than the `--divider` that separates cards from the page. */
  --nav-bg: color-mix(in srgb, var(--bg) 92%, transparent);
  --divider-soft: color-mix(in srgb, var(--text) 8%, transparent);
}

:root,
[data-theme="dark"] {
  color-scheme: dark;
  /* Ink, the app's dark ground (`packages/app/src/styles/tokens.css`): a
     near-black neutral, not #000 and not the blue-cast navy this page used to
     sit on, and an off-white rather than #fff — both halves of halation. */
  --bg: #101114;
  --text: #e8e8eb;

  /* The accent, and the two steps this page needs either side of it: the base
     accent is link-safe now (9.5:1 on the ground) but the sub-headline still
     takes the 300 for the extra step; the 900 is the hero bloom and is never
     text. */
  --accent: #b8aeff;
  --accent-300: #d8d2ff;
  --accent-900: #2b2745;

  /* What sits on a filled accent button. Dark inverts here rather than using
     white: `#fff` on a `#b8aeff` fill is 1.8:1, and the page's own ground is
     9.5:1 on it. `--accent-300` doubles as the hover fill on both grounds —
     lighter here, darker on white — so one rule covers both. */
  --on-accent: var(--bg);

  /* Ink's three edges — loud, control, enclosure — under the names this page
     already used for them. */
  --neutral-600: #8a8e99;
  --neutral-700: #666973;
  --neutral-800: #35363d;
  /* The rule between cards and page, at Ink's hairline weight: 16% of the text
     sat under the Lc 15 floor on a neutral ground, a boundary you infer. The
     in-card rule is restated here for the same reason; `:root` keeps the
     light-and-dark default. */
  --divider: color-mix(in srgb, var(--text) 28%, transparent);
  --divider-soft: color-mix(in srgb, var(--text) 18%, transparent);

  /* The card ground and the strip that heads or foots it. Mixed from the
     neutral rather than stated, so a card stays a lift off *this* ground — the
     70% lands on Ink's control step and the 40% on its panel. */
  --surface: color-mix(in srgb, var(--neutral-800) 70%, transparent);
  --surface-alt: color-mix(in srgb, var(--neutral-800) 40%, transparent);

  /* Muted steps, spelled out — the same rule the light block below already
     follows. As alpha on the text colour they bottomed out near Lc 45 on this
     ground, which is under the Lc 60 any non-body text needs; Ink has exactly
     two legible steps under the body colour, so the six names land on those
     two rather than print below the floor. */
  --t-82: #cfd1d7;
  --t-70: #b8bbc4;
  --t-62: #b8bbc4;
  --t-60: #b8bbc4;
  --t-55: #b8bbc4;
  --t-50: #b8bbc4;

  --shadow-lg: 0 0 0 1px #8a8e99, 0 16px 40px rgba(0, 0, 0, 0.65);
  --shadow-md: 0 0 0 1px #8a8e99, 0 12px 32px rgba(0, 0, 0, 0.5);

  /* The mockup's ramp and its reserved gold — Ink's, five of the app's seven
     steps. Tokens rather than the literals they used to be in the markup, for
     the same reason the app moved its ramp into `tokens.css`: a chart colour is
     the one colour that has to flip with the ground and is drawn inline rather
     than by a rule. */
  --ramp-1: #d6d0ff;
  --ramp-2: #b9affa;
  --ramp-3: #9d91ec;
  --ramp-4: #8477d9;
  --ramp-5: #6053b0;
  --gold: #d8bb62;
  /* Gold as words — the never-match terms and the `0 hits` warning. On this
     ground the fill colour is already legible, so the two are the same. */
  --gold-text: #d8bb62;
}

/* The light ground, from the app's own light block. Two things do not simply
   invert: `--accent-300` is the *darker* step here, because on white the accent
   gets louder by deepening; and the `--t-*` steps stop being alpha. A share of a
   near-black text colour bottoms out around 3:1 on a light ground, which is the
   exact failure `styles/tokens.css` documents and bans — so they are spelled out
   as opaque steps, and the bottom two land on the same value rather than print
   below the floor. */
[data-theme="light"] {
  color-scheme: light;
  --bg: #f2f4f8;
  --text: #262a37;
  --divider-soft: color-mix(in srgb, var(--text) 8%, transparent);

  --accent: #5a4ac8;
  --accent-300: #4a3cb0;
  --accent-900: #cdc6f0;
  --on-accent: #ffffff;

  --neutral-600: #bec3d3;
  --neutral-700: #d6dae6;
  --neutral-800: #ffffff;
  --divider: color-mix(in srgb, var(--text) 14%, transparent);

  --surface: #ffffff;
  --surface-alt: #f7f8fb;

  --t-82: #343949;
  --t-70: #454b5e;
  --t-62: #5c6278;
  --t-60: #5c6278;
  --t-55: #6e7589;
  --t-50: #6e7589;

  --shadow-lg: 0 0 0 1px #bec3d3, 0 16px 40px rgba(19, 21, 34, 0.12);
  --shadow-md: 0 0 0 1px #bec3d3, 0 12px 32px rgba(19, 21, 34, 0.08);

  --ramp-1: #4536ad;
  --ramp-2: #5a4ac8;
  --ramp-3: #6f5fd4;
  --ramp-4: #9d93e6;
  --ramp-5: #cec8f5;
  --gold: #b98f22;
  /* The fill is 2.6:1 as body text on white, so words take a deeper step. */
  --gold-text: #8a6a15;
}

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

/* The bar links into the page, so the jump is animated — and is not, for a
   reader who has asked the system for stillness. */
html {
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.55;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
}

/* Nocturne's, unchanged, and the reason nothing below restyles a hover: the
   focus ring is the system's and must stay recognisable across the site. */
:focus {
  outline: none;
}
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
::selection {
  background: color-mix(in srgb, var(--accent) 30%, transparent);
}

.tnum {
  font-feature-settings: "tnum" 1;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ── top bar ──────────────────────────────────────────────────────────── */

/* It sticks because the page scrolls past four sections and `Start now` should
   not be something you have to scroll back up to find. */
.nav {
  position: sticky;
  top: 0;
  z-index: 20;
  padding: 0 var(--gutter);
  border-bottom: 1px solid var(--divider-soft);
  background: var(--nav-bg);
  backdrop-filter: blur(8px);
}

.nav-bar {
  display: flex;
  align-items: center;
  gap: var(--space-4) 24px;
  max-width: var(--column);
  margin: 0 auto;
  padding: 10px 0;
}

.nav-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: var(--heading-weight);
  font-size: 18px;
  letter-spacing: -0.01em;
  /* a two-word wordmark never breaks across lines */
  white-space: nowrap;
}

.nav-mark {
  display: block;
  flex: none;
}

/* Everything but the brand, in one box so the phone can fold it away as one
   thing — the reference links and the two switches do not fit beside a wordmark
   at 320px. On the desktop it is simply the rest of the bar. */
.nav-menu {
  display: flex;
  flex: 1;
  align-items: center;
  gap: 18px;
}

.nav-utils {
  display: flex;
  align-items: center;
  gap: 18px;
  /* pushes the reference links, the call to action and the two switches right */
  margin-left: auto;
}

.nav-switches {
  display: flex;
  align-items: center;
  gap: 6px;
  padding-left: 18px;
  border-left: 1px solid var(--divider);
}

/* Plain links, not buttons: `Docs`, `Legal` and `Demo` are reference, and giving
   them a box would make four calls to action out of one. */
.nav-link {
  color: var(--t-55);
  font-size: 14px;
  text-decoration: none;
}
.nav-link:hover {
  color: var(--accent);
}

/* The button that folds the menu away. Built by the script that makes it work
   — see the tail of `index.html` — so a page without JavaScript never shows a
   control that does nothing; there, the menu is simply always open. */
.nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--divider);
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--t-70);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}
.nav-toggle:hover {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}

/* The language switch. As a bare `Polski` link among the others it read as a
   fourth destination — a page about Polish — rather than as the control that
   swaps the page you are on. Showing both codes with the current one held down
   says which language you are in and which one the click gets you, and the
   smaller type keeps the box from being taken for a third button. */
.lang {
  display: inline-flex;
  flex: none;
  overflow: hidden;
  border: 1px solid var(--divider);
  border-radius: var(--radius-md);
}

.lang-opt {
  display: inline-flex;
  align-items: center;
  padding: 4px 9px;
  color: var(--t-60);
  font-size: 12px;
  line-height: 1.35;
  letter-spacing: 0.03em;
  text-decoration: none;
}
.lang-opt + .lang-opt {
  border-left: 1px solid var(--divider);
}
a.lang-opt:hover {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}
.lang-on {
  background: color-mix(in srgb, var(--text) 10%, transparent);
  color: var(--text);
}

/* The theme switch is the language switch's shape — same border, same segments,
   same 12px — because they are the same kind of control and sit side by side.
   It differs in being built by a script (see the tail of `index.html`): a
   language is two pages and works with scripts off, a theme is not. */
.themeSwitch {
  display: inline-flex;
  flex: none;
  overflow: hidden;
  border: 1px solid var(--divider);
  border-radius: var(--radius-md);
}

.themeSwitch button {
  padding: 4px 9px;
  border: 0;
  background: transparent;
  color: var(--t-60);
  font-family: var(--font);
  font-size: 12px;
  line-height: 1.35;
  letter-spacing: 0.03em;
  cursor: pointer;
}

.themeSwitch button + button {
  border-left: 1px solid var(--divider);
}

.themeSwitch button:hover[aria-pressed="false"] {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}

.themeSwitch button[aria-pressed="true"] {
  background: color-mix(in srgb, var(--text) 10%, transparent);
  color: var(--text);
}

/* ── buttons (Nocturne .btn) ──────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: var(--space-2) calc(var(--space-3) * 1.2);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text);
  font-family: var(--font);
  font-weight: var(--heading-weight);
  font-size: 14px;
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

/* `Start now` is filled rather than outlined. The page now has a bar, a hero
   and four sections competing for the eye, and an outline among that many
   outlined boxes stopped reading as the one thing to press. */
.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}
.btn-primary:hover {
  background: var(--accent-300);
  border-color: var(--accent-300);
}
.btn-primary:active {
  background: var(--accent);
  border-color: var(--accent);
}

.btn-secondary {
  border-color: var(--divider);
}
.btn-secondary:hover {
  background: color-mix(in srgb, var(--text) 7%, transparent);
}
.btn-secondary:active {
  background: color-mix(in srgb, var(--text) 14%, transparent);
}

/* ── hero ─────────────────────────────────────────────────────────────── */

/* The lit ground: an accent bloom from the top right, over the page's own
   colour. A bloom, never a flood — it stops well before the copy. */
.hero {
  padding: 0 var(--gutter);
  background: radial-gradient(
    900px 560px at 88% -80px,
    color-mix(in srgb, var(--accent-900) 80%, transparent),
    transparent 62%
  );
}

.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: 56px;
  align-items: center;
  max-width: var(--column);
  margin: 0 auto;
  padding: 80px 0 88px;
}

h1 {
  margin: 0 0 0 -0.06em; /* optical left margin: display type starts at the ink */
  font-weight: var(--heading-weight);
  font-size: 52px;
  line-height: 58px;
  letter-spacing: -0.015em;
  color: var(--text);
}

h1 span {
  display: block;
}

.h1-sub {
  margin-top: 10px;
  font-size: 34px;
  line-height: 42px;
  letter-spacing: -0.01em;
  color: var(--accent-300);
}

.lede {
  margin: 34px 0 0;
  font-size: 17px;
  line-height: 28px;
  color: var(--t-82);
  text-wrap: pretty;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: 28px;
}

/* Plain text with `·` separators, deliberately not chips: an outlined tag reads
   as something to press, and these are four statements of fact. */
.claims {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 26px 0 0;
  font-size: 13px;
  letter-spacing: 0.02em;
  color: var(--t-55);
}

/* The phone's answer where the two buttons would be. It is tinted with the
   accent rather than drawn as a warning: nothing is wrong, the machine is. */
.notice {
  display: flex;
  gap: 12px;
  margin-top: 28px;
  padding: 14px;
  border: 1px solid color-mix(in srgb, var(--accent) 28%, transparent);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--accent) 6%, transparent);
}

.notice-mark {
  flex: none;
  margin-top: 2px;
  color: var(--accent-300);
}

.notice-title {
  margin: 0;
  font-size: 15px;
  font-weight: var(--heading-weight);
  line-height: 22px;
}

.notice-body {
  margin: 6px 0 0;
  font-size: 14px;
  line-height: 21px;
  color: var(--t-70);
  text-wrap: pretty;
}

/* ── the four bands ───────────────────────────────────────────────────── */

/* Words on one side, an illustration of the screen on the other, and the sides
   swap every other band. The swap is done in the grid, not in the markup: the
   words come first in the source everywhere, which is the order a phone stacks
   them in and the order a screen reader reads them in. */
.band {
  padding: 0 var(--gutter);
  scroll-margin-top: 64px;
}

.band-grid {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: 56px;
  align-items: center;
  max-width: var(--column);
  margin: 0 auto;
  padding: 72px 0;
  border-top: 1px solid var(--divider);
}

.band-flip .band-grid {
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
}
.band-flip .band-text {
  grid-column: 2;
  grid-row: 1;
}
.band-flip .card {
  grid-column: 1;
  grid-row: 1;
}

/* The last band closes the page, so it carries the bottom air. */
.band:last-of-type .band-grid {
  padding-bottom: 96px;
}

.band-kicker {
  margin: 0;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent-300);
}

.band h2 {
  margin: 14px 0 0;
  font-weight: var(--heading-weight);
  font-size: 30px;
  line-height: 38px;
  letter-spacing: -0.015em;
}

.band-lede {
  margin: 16px 0 0;
  font-size: 16px;
  line-height: 27px;
  color: var(--t-82);
  text-wrap: pretty;
}

.band-note {
  margin: 14px 0 0;
  font-size: 14px;
  color: var(--t-55);
  text-wrap: pretty;
}

/* ── the illustrated screens ──────────────────────────────────────────── */

/* Illustrations, at illustration scale — the real screens are the app's, and
   these borrow their shape, not their measurements. Every one of them is
   `aria-hidden` behind a caption that says in words what it shows, because the
   money in them is invented and must never be read out as the visitor's.
   `.mock` is the hero's Overview card and carries the page's one big shadow;
   `.card` is the quieter form the four bands use. */
.mock,
.card {
  margin: 0;
  border: 1px solid var(--neutral-700);
  border-radius: var(--radius-md);
  background: var(--surface);
  overflow: hidden;
}

.mock {
  box-shadow: var(--shadow-lg);
}

.card {
  box-shadow: var(--shadow-md);
}

/* A tinted strip at the head or the foot of a card: the file it came from, the
   priority band it belongs to, the caveat the claim above needs. */
.card-strip {
  margin: 0;
  padding: 11px 16px;
  background: var(--surface-alt);
  font-size: 12px;
  line-height: 19px;
  color: var(--t-55);
}

.card-head {
  border-bottom: 1px solid var(--neutral-700);
}

.card-foot {
  border-top: 1px solid var(--neutral-700);
}

.card-caps {
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* The rounded tag on an account's kind and on the amount modes a template can
   read. Distinct from `.key` below, which is square, because one is a state
   the app assigned and the other is a word you typed. */
.pill {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border: 1px solid transparent;
  border-radius: 999px;
  font-size: 11.5px;
  white-space: nowrap;
}

.pill-accent {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent-300);
}

.pill-gold {
  background: color-mix(in srgb, var(--gold) 16%, transparent);
  color: var(--gold-text);
}

.pill-muted {
  background: color-mix(in srgb, var(--text) 8%, transparent);
  color: var(--t-62);
}

.pill-off {
  border-color: var(--divider);
  color: var(--t-55);
}

/* ── the Overview mockup (hero) ───────────────────────────────────────── */

.mock-filters {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--neutral-700);
  font-size: 12px;
  color: var(--t-60);
}

.seg {
  display: inline-flex;
  overflow: hidden;
  border: 1px solid var(--divider);
  border-radius: var(--radius-md);
  flex: none;
}

.seg-opt {
  display: inline-flex;
  align-items: center;
  padding: 5px 11px;
  font-size: 12px;
  line-height: 1.2;
}
.seg-opt + .seg-opt {
  border-left: 1px solid var(--divider);
}
.seg-on {
  color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}

/* 56px of bar plus its padding: the handoff is drawn without `border-box`, so
   its `height: 56px` is the bars alone. Taken literally here the ribbon loses
   half its height and the year stops being readable as a shape. */
.mock-ribbon {
  display: flex;
  align-items: flex-end;
  gap: 5px;
  height: 84px;
  padding: 16px 16px 12px;
}

.mock-ribbon i {
  flex: 1;
  border-radius: 2px;
  background: var(--neutral-600);
}
/* the month in focus, and the month still running */
.mock-ribbon i.on {
  background: var(--accent);
}
.mock-ribbon i.partial {
  background: var(--neutral-700);
}

.mock-summary {
  padding: 8px 16px 20px;
}

.mock-eyebrow {
  margin: 0;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--t-55);
}

.mock-figure {
  margin: 10px 0 0 -0.055em; /* optical margin, measured from the digit */
  font-weight: var(--heading-weight);
  font-size: 44px;
  line-height: 48px;
  color: var(--text);
}

.mock-delta {
  margin: 8px 0 0;
  font-size: 13px;
  color: var(--t-62);
}

/* The split bar and its legend. Shared with the net worth card, which splits
   holdings the same way and has no reason to say so differently. */
.mock-bar {
  display: flex;
  height: 14px;
  margin: 20px 0 0;
  border-radius: 3px;
  overflow: hidden;
}

.mock-legend {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px 28px;
  margin-top: 16px;
  font-size: 12.5px;
}

.mock-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.chip {
  width: 9px;
  height: 9px;
  border-radius: 2px;
  flex: none;
}

.mock-name {
  flex: 1;
}

.mock-share {
  color: var(--t-50);
}

.mock-tiles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-top: 20px;
}

.mock-tile {
  padding: 10px 12px;
  border: 1px solid var(--neutral-700);
  border-radius: 6px;
}

.mock-tile p:first-child {
  margin: 0;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--t-55);
}

.mock-tile p:last-child {
  margin: 6px 0 0;
  font-size: 16px;
  color: var(--text);
}

/* ── 01 · accounts ────────────────────────────────────────────────────── */

/* Three columns: which account, what you called it, and — the column that is
   the whole point — what that answer does to the totals. */
.acc-head,
.acc-row {
  display: grid;
  grid-template-columns: 1fr 96px 1fr;
  gap: 12px;
  align-items: center;
  padding: 13px 16px;
  border-bottom: 1px solid var(--divider-soft);
  font-size: 13px;
}

.acc-head {
  padding: 11px 16px;
  border-bottom-color: var(--neutral-700);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--t-55);
}

.acc-row:last-of-type {
  border-bottom: 0;
}

.acc-row .pill {
  justify-self: start;
}

.acc-effect {
  color: var(--t-62);
}

/* ── 02 · templates ───────────────────────────────────────────────────── */

.tpl-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 11px 16px;
  border-bottom: 1px solid var(--neutral-700);
  font-size: 12px;
  color: var(--t-62);
}

.tpl-head p {
  margin: 0;
}

.tpl-rows {
  padding: 6px 16px 14px;
}

/* Target field on the left, the column of the bank's the mapper found on the
   right, with a value off the sample after the dash. */
.tpl-row {
  display: grid;
  grid-template-columns: 108px 1fr;
  gap: 10px;
  align-items: baseline;
  padding: 11px 0;
  border-bottom: 1px solid var(--divider-soft);
}

.tpl-row:last-child {
  align-items: start;
  border-bottom: 0;
}

.tpl-field {
  font-size: 12.5px;
  color: var(--t-55);
}

.tpl-value {
  font-size: 13px;
}

.tpl-sample {
  color: var(--t-55);
}

.tpl-modes {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
}

.tpl-modes .pill {
  padding: 3px 9px;
}

/* ── 03 · categories with keywords ────────────────────────────────────── */

.cat-row {
  display: grid;
  grid-template-columns: 150px 1fr;
  gap: 12px;
  align-items: center;
  padding: 13px 16px;
  border-bottom: 1px solid var(--divider-soft);
}

.cat-row:last-of-type {
  border-bottom: 0;
}

.cat-name {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
}

.cat-keys {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* A keyword, and the number of rows it caught. Square, because it is a word
   you typed — see the note on `.pill`. */
.key {
  padding: 2px 8px;
  border-radius: 4px;
  background: color-mix(in srgb, var(--text) 7%, transparent);
  font-size: 11.5px;
  white-space: nowrap;
}

.key-hits {
  color: var(--t-55);
}

/* A keyword that has never matched. Gold rather than red: it is a typo to look
   at, not a failure. */
.key-cold {
  background: color-mix(in srgb, var(--gold) 16%, transparent);
  color: var(--gold-text);
}

.key-cold .key-hits {
  color: inherit;
}

.never {
  color: var(--gold-text);
}

/* ── 04 · net worth ───────────────────────────────────────────────────── */

.nw-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 16px 12px;
}

.nw-head > div:first-child {
  min-width: 0;
}

.nw-eyebrow {
  margin: 0;
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--t-55);
}

.nw-figure {
  margin: 8px 0 0;
  font-weight: var(--heading-weight);
  font-size: 32px;
  line-height: 36px;
  letter-spacing: -0.02em;
}

.nw-sides {
  display: grid;
  gap: 4px;
  text-align: right;
  font-size: 13px;
  color: var(--t-82);
}

.nw-amt {
  margin-left: 8px;
}

.nw-holdings {
  padding: 0 16px 16px;
}

.nw-holdings .mock-bar {
  margin-top: 0;
}

.nw-holdings .mock-legend {
  margin-top: 14px;
}

.nw-total {
  margin-left: 8px;
  letter-spacing: 0;
  text-transform: none;
  font-size: 12px;
}

/* One rule between the three, drawn by the gap rather than by borders, so the
   strip reads as a single foot to the card. */
.nw-tiles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  border-top: 1px solid var(--neutral-700);
  background: var(--neutral-700);
}

.nw-tile {
  padding: 12px 16px;
  background: var(--surface-alt);
}

.nw-tile p:first-child {
  margin: 0;
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--t-55);
}

.nw-tile p:last-child {
  margin: 6px 0 0;
  font-size: 15px;
}

.nw-return {
  color: var(--accent-300);
}

/* ── the two views ────────────────────────────────────────────────────── */

.mobile-only {
  display: none;
}

/* Between the design's canvas width and the breakpoint the columns stack: the
   pitch needs about 500px before the display line breaks in the wrong place,
   and 5fr of a narrower page does not give it. The illustrations are capped
   rather than run to the full width, because a 900px-wide card under a
   paragraph reads as a second page. */
@media (max-width: 1080px) {
  .hero-grid,
  .band-grid,
  .band-flip .band-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 44px;
  }

  .band-flip .band-text,
  .band-flip .card {
    grid-column: 1;
    grid-row: auto;
  }

  .mock,
  .card {
    max-width: 640px;
  }
}

/*
 * The phone. The page itself is the same page — the four bands and the hero
 * illustration are all here, at phone measurements — and the one content
 * change is the pair of buttons: below this width the app cannot do its job,
 * because the database file and the bank exports are on a computer. So the
 * actions are replaced by a notice saying so, rather than offered and then
 * refused. 720px is the design system's own collapse point.
 */
@media (max-width: 720px) {
  :root {
    --gutter: 20px;
  }

  .desktop-only {
    display: none;
  }

  .mobile-only {
    display: block;
  }

  /* The bar keeps the brand and a button; everything else folds behind it.
     `data-nav` is set before the first paint by the script in the head, so the
     menu is never seen opening itself. Without JavaScript the attribute is
     never written, the rule below never applies, and the menu stands open —
     which is the page working, not the page broken. */
  .nav-bar {
    flex-wrap: wrap;
    gap: 8px 12px;
    padding-bottom: 10px;
  }

  .nav-brand {
    font-size: 16px;
  }

  .nav-mark {
    width: 17px;
    height: 17px;
  }

  .nav-toggle-host {
    margin-left: auto;
  }

  .nav-menu {
    display: block;
    flex-basis: 100%;
    margin: 2px calc(var(--gutter) * -1) -10px;
    padding: 6px var(--gutter) 14px;
    border-top: 1px solid var(--divider-soft);
    background: var(--surface-alt);
  }

  [data-nav="closed"] .nav-menu {
    display: none;
  }

  .nav-utils {
    flex-wrap: wrap;
    gap: 0 16px;
    margin-left: 0;
    font-size: 15px;
  }

  /* `:not(.desktop-only)` because `Demo` is one of these and must stay gone:
     an equally specific rule would otherwise put it back. */
  .nav-utils > .nav-link:not(.desktop-only) {
    display: inline-flex;
    align-items: center;
    height: 44px;
    color: var(--t-62);
    font-size: 15px;
  }

  .nav-switches {
    margin-left: auto;
    padding-left: 0;
    border-left: 0;
  }

  .themeSwitch button,
  .lang-opt {
    padding: 8px 10px;
  }

  .hero {
    background: radial-gradient(
      520px 420px at 100% -100px,
      color-mix(in srgb, var(--accent-900) 80%, transparent),
      transparent 62%
    );
  }

  .hero-grid {
    gap: 28px;
    padding: 40px 0 48px;
  }

  h1 {
    margin-left: 0;
    font-size: 36px;
    line-height: 42px;
    letter-spacing: -0.02em;
  }

  .h1-sub {
    font-size: 24px;
    line-height: 30px;
  }

  .lede {
    margin-top: 22px;
    font-size: 16px;
    line-height: 26px;
  }

  .notice {
    margin-top: 24px;
  }

  .claims {
    margin-top: 20px;
    gap: 8px;
  }

  /* The folded bar is a 44px button in 20px of padding, so an anchored section
     needs more clearance here than it does on the desktop. */
  .band {
    scroll-margin-top: 76px;
  }

  .band-grid,
  .band-flip .band-grid {
    gap: 22px;
    padding: 40px 0;
  }

  .band:last-of-type .band-grid {
    padding-bottom: 64px;
  }

  .band-kicker {
    font-size: 11.5px;
  }

  .band h2 {
    margin-top: 12px;
    font-size: 25px;
    line-height: 32px;
    letter-spacing: -0.02em;
  }

  .band-lede {
    margin-top: 14px;
    font-size: 15.5px;
    line-height: 25px;
  }

  .band-note {
    margin-top: 12px;
    font-size: 13.5px;
    line-height: 22px;
  }

  .mock,
  .card {
    max-width: none;
  }

  /* The illustrations, at phone measurements. Nothing is dropped from them:
     the only cuts are to strings that would wrap to two lines in a strip one
     line tall — see `.wide-only` in the markup. */
  .mock-filters {
    padding: 10px 14px;
    font-size: 11.5px;
  }

  .seg-opt {
    padding: 4px 10px;
    font-size: 11.5px;
  }

  .mock-ribbon {
    gap: 4px;
    height: 68px;
    padding: 14px 14px 10px;
  }

  .mock-summary {
    padding: 6px 14px 18px;
  }

  .mock-eyebrow {
    font-size: 11px;
  }

  .mock-figure {
    font-size: 34px;
    line-height: 38px;
    letter-spacing: -0.02em;
  }

  .mock-delta {
    margin-top: 6px;
    font-size: 12.5px;
  }

  .mock-bar {
    height: 13px;
    margin-top: 16px;
  }

  .mock-legend {
    grid-template-columns: 1fr;
    gap: 9px;
    margin-top: 14px;
  }

  /* One column means the shares no longer line up on the grid, so they take a
     column of their own. */
  .mock-share {
    width: 30px;
    text-align: right;
  }

  .mock-tiles {
    gap: 8px;
    margin-top: 18px;
  }

  .mock-tile {
    padding: 9px 10px;
  }

  .mock-tile p:first-child {
    font-size: 10px;
    letter-spacing: 0.05em;
  }

  .mock-tile p:last-child {
    margin-top: 5px;
    font-size: 13.5px;
  }

  .card-strip {
    padding: 11px 14px;
  }

  /* The header row goes: three columns of 10px capitals do not survive a phone,
     and each row states its own effect on the line below it instead. */
  .acc-head,
  .wide-only {
    display: none;
  }

  .acc-row {
    grid-template-columns: 1fr auto;
    gap: 5px 10px;
    padding: 12px 14px;
  }

  .acc-effect {
    grid-column: 1 / -1;
    font-size: 12px;
    color: var(--t-55);
  }

  .tpl-head {
    display: block;
    padding: 10px 14px;
  }

  .tpl-head p + p {
    margin-top: 3px;
    color: var(--t-55);
  }

  .tpl-rows {
    padding: 4px 14px 12px;
  }

  .tpl-row {
    grid-template-columns: 88px 1fr;
    padding: 10px 0;
  }

  .tpl-field {
    font-size: 12px;
  }

  .tpl-value {
    font-size: 12.5px;
  }

  .cat-row {
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
    padding: 12px 14px;
  }

  .nw-head {
    display: block;
    padding: 14px 14px 12px;
  }

  .nw-figure {
    margin-top: 7px;
    font-size: 30px;
    line-height: 34px;
  }

  .nw-sides {
    display: flex;
    gap: 18px;
    margin-top: 8px;
    text-align: left;
    font-size: 12.5px;
  }

  .nw-amt {
    margin-left: 6px;
  }

  .nw-holdings {
    padding: 0 14px 16px;
  }

  .nw-holdings .mock-bar {
    height: 13px;
  }

  .nw-holdings .mock-legend {
    margin-top: 13px;
  }

  .nw-total {
    margin-left: 6px;
  }

  .nw-tile {
    padding: 11px 12px;
  }

  .nw-tile p:first-child {
    font-size: 10px;
    letter-spacing: 0.05em;
  }

  .nw-tile p:last-child {
    margin-top: 5px;
    font-size: 13.5px;
  }
}
