/* The brand faces, served from this domain.

   Until 5 September 2026 this file used device stacks and shipped no font at all, for a reason
   that still holds: loading Google Fonts from Google sends the visitor IP to Google, which EU
   courts have found unlawful without consent. Self-hosting keeps that property. Nothing here
   reaches a third party, so the cookie banner and the privacy policy are unaffected.

   What the stacks could not give was a stable identity: Apple resolved Iowan Old Style, Windows
   Constantia, elsewhere Georgia, so the letterforms, the perceived weight and the line breaks all
   changed between a laptop and a phone. Headings also asked for 600, which several of those faces
   do not have, leaving the browser to synthesise it.

   Both files are variable across 400 to 700, so every weight already in this sheet renders as a
   real cut rather than a synthetic bold, and one file covers the range instead of four.
   Fraunces and DM Sans are both SIL Open Font License, which permits this.

   font-display: swap, so text is readable in the fallback from the first paint and never hidden.
   The old device stacks stay as the fallback: on a slow connection the page is legible in the
   same serif it used to ship in, not in Times. */
@font-face {
  font-family: "Fraunces";
  src: url("/fonts/fraunces.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Fraunces";
  src: url("/fonts/fraunces-italic.woff2") format("woff2");
  font-weight: 400 700;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "DM Sans";
  src: url("/fonts/dm-sans.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

:root {
  color-scheme: light;
  --ink-950: oklch(23% 0.018 160);
  --ink-850: oklch(31% 0.020 160);
  --ink-700: oklch(44% 0.018 162);
  --ink-500: oklch(53% 0.015 163);
  --ink-300: oklch(79% 0.012 165);
  --ink-150: oklch(90% 0.008 165);
  --ink-075: oklch(95.5% 0.006 165);

  --paper: oklch(97.6% 0.006 165);
  --paper-raised: oklch(99.5% 0.002 165);
  --paper-deep: oklch(94.5% 0.010 165);
  /* Hue 152, matching --moss. These were 167 and 152: fifteen degrees apart at nearly identical
     lightness and chroma, which reads as a printing error rather than as two colours. --primary is
     the action colour and --moss the large soft field, so they keep different lightness on purpose;
     it is only the hue that had to agree. */
  --primary: oklch(50% 0.085 152);
  --primary-hover: oklch(42% 0.075 152);
  --terracotta: oklch(67% 0.115 47);
  --terracotta-deep: oklch(51% 0.13 41);
  --terracotta-soft: oklch(93% 0.038 47);
  --moss: oklch(52% 0.095 152);
  --moss-soft: oklch(93% 0.030 152);
  --amber: oklch(66% 0.110 84);
  --amber-soft: oklch(93% 0.035 84);
  --danger: oklch(52% 0.150 25);
  --danger-soft: oklch(94% 0.025 25);

  /* Declared above as @font-face. The old device stacks remain as fallbacks: they are what the
     visitor sees for the moment before the file arrives, and what they keep if it never does. */
  --font-display: "Fraunces", "Iowan Old Style", "Palatino Linotype", Palatino, Constantia, Cambria, Georgia, serif;
  --font-body: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-lg: 1.25rem;
  --text-xl: 1.563rem;
  /* Responsive, so h2 stays below h1 at every width. h1 floors at 2.45rem; a fixed 2.441rem here
     put them 0.14px apart on a phone. The ratio now runs from 1.31 at 1280 to 1.97 at 1920. */
  --text-2xl: clamp(1.75rem, 5.2vw, 2.441rem);
  --text-3xl: 3.052rem;

  --space-2xs: 0.25rem;
  --space-xs: 0.5rem;
  --space-sm: 0.75rem;
  --space-md: 1rem;
  --space-lg: 1.5rem;
  --space-xl: 2rem;
  --space-2xl: 3rem;
  --space-3xl: 4rem;
  --space-4xl: 6rem;

  --radius-sm: 0.5rem;
  --radius-md: 0.875rem;
  --radius-lg: 1.4rem;
  --radius-pill: 999px;

  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-toggle: cubic-bezier(0.65, 0, 0.35, 1);
  --header-height: 4.5rem;
  --page-max: 78rem;
}

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

html {
  background: var(--paper);
  color: var(--ink-950);
  font-family: var(--font-body);
  font-size: 100%;
  font-kerning: normal;
  scroll-behavior: smooth;
  /* Swallow the ~scrollbar-width overflow introduced by the full-bleed hero's
     100vw (vw includes the vertical scrollbar). clip avoids creating a scroll
     container, so sticky/anchored elements keep working. */
  overflow-x: clip;
}

body {
  min-block-size: 100vh;
  margin: 0;
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
  background:
    radial-gradient(circle at 88% 6%, oklch(94% 0.022 168) 0, transparent 22rem),
    var(--paper);
  color: var(--ink-950);
  font-size: var(--text-base);
  line-height: 1.5;
  text-rendering: optimizeLegibility;
}

button,
input,
select {
  font: inherit;
}

button,
summary,
a,
input,
select {
  -webkit-tap-highlight-color: transparent;
}

button,
summary {
  cursor: pointer;
}

button:focus-visible,
a:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible {
  outline: 3px solid var(--terracotta-deep);
  outline-offset: 3px;
}

/* Non-interactive headings receive temporary programmatic focus after navigation or
   after unlocking premium, so screen readers announce the new context. Suppress the
   visible ring; they are not interactive controls. */
:is(h1, h2, h3)[tabindex]:focus,
:is(h1, h2, h3)[tabindex]:focus-visible {
  outline: none;
}

button:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

a {
  color: inherit;
}

svg {
  display: block;
  inline-size: 1.25rem;
  block-size: 1.25rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

h1,
h2,
h3,
h4,
h5,
p,
ul,
ol,
dl,
dd,
fieldset {
  margin: 0;
}

h1,
h2,
h3,
h4,
h5 {
  text-wrap: balance;
}

h1,
h2 {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.035em;
}

h1 {
  /* Was 4.8rem (76.8px). Two reasons for the cut. Fraunces carries a larger x-height than the
     Palatino-class faces this replaced, so the same pixel size reads noticeably bigger. And 4.8rem
     met the desktop rule below, which caps at 3.6rem, producing a 33 per cent drop at a single
     pixel of viewport. That drop is now 57.6 to 51.2, which the eye reads as the layout changing
     rather than as a fault. It cannot be removed entirely: the desktop size is set by the
     illustration beside the headline, not by taste. See the note on the desktop rule. */
  font-size: clamp(2.45rem, 10vw, 3.6rem);
  /* 0.98 set the leading tighter than the type size itself, which a display serif cannot carry
     over two lines: the descenders of "paperwork" ran into the capitals below them. 1.05 stays
     tight enough to read as display type and gives the descenders somewhere to go. It costs the
     hero roughly 7px of height, against the 105px of clearance the illustration was tuned to. */
  line-height: 1.05;
}

h2 {
  font-size: var(--text-2xl);
  line-height: 1.05;
}

h3 {
  font-size: var(--text-lg);
  line-height: 1.2;
}

p {
  max-inline-size: 70ch;
}

.hidden {
  display: none !important;
}

.skip-link {
  position: fixed;
  inset-block-start: var(--space-sm);
  inset-inline-start: var(--space-sm);
  z-index: 600;
  translate: 0 -200%;
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-sm);
  background: var(--ink-950);
  color: var(--paper-raised);
  font-weight: 700;
  transition: translate 180ms var(--ease-out);
}

.skip-link:focus {
  translate: 0 0;
}

.site-header {
  position: relative;
  z-index: 20;
  display: flex;
  min-block-size: var(--header-height);
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  inline-size: min(100% - 2rem, var(--page-max));
  margin-inline: auto;
  border-block-end: 1px solid var(--ink-150);
}

.wordmark {
  display: inline-flex;
  min-block-size: 2.75rem;
  align-items: center;
  gap: var(--space-sm);
  color: var(--ink-950);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
  letter-spacing: -0.025em;
  text-decoration: none;
}

.wordmark-tld {
  color: var(--primary);
}

.header-meta {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: var(--space-md);
}

.jurisdiction {
  display: none;
  align-items: center;
  gap: var(--space-2xs);
  color: var(--ink-700);
  font-size: var(--text-sm);
}

.flag-ie {
  flex: 0 0 auto;
  border-radius: 2px;
}

/* An <a> styled as a header control: match the quiet-button box, keep link semantics. */
.header-guides-link {
  display: inline-flex;
  align-items: center;
  min-block-size: 2.75rem;
  border-radius: var(--radius-pill, 999px);
  color: var(--ink-950);
  font-weight: 600;
  text-decoration: none;
}

@media (hover: hover) {
  .header-guides-link:hover {
    border-color: var(--primary);
    color: var(--primary);
  }
}

.header-pricing-button[aria-current="page"] {
  border-color: var(--primary);
  background: var(--ink-075);
  color: var(--primary);
}

#app {
  inline-size: min(100% - 2rem, var(--page-max));
  margin-inline: auto;
}

/* Reserve the first viewport for as long as #app is still empty.
 *
 * app.js renders the entire page into #app, so between first paint and that render the footer
 * sits directly under the header. Measured on the intro screen, it then jumps down about 2,300px.
 * That is a large shift of an element that is visible in the viewport, and Cloudflare's field data
 * for 10 to 24 August named footer.site-footer as the site's worst CLS contributor at 0.4194,
 * with 14% of loads in the "poor" bucket.
 *
 * It never reproduced locally, and the reason is worth keeping: the dev server is fast enough that
 * app.js finishes before first paint, so nothing ever moves. Only a real connection is slow enough
 * to paint the empty state first. Absence of a local repro was not evidence of absence.
 *
 * :empty stops matching the instant app.js writes anything, so this costs nothing after render and
 * cannot leave a gap on a page that has content. 100vh rather than svh deliberately: vh is the
 * larger mobile viewport, so the footer starts below the fold whether or not the toolbar is showing.
 */
#app:empty {
  min-block-size: 100vh;
}

/* ...unless the planner is never coming, which compat-guard.js signals by adding this class before
   it reveals the notice below. Without it the reserved viewport pushes the explanation off the
   bottom of the screen and the visitor sees a blank page and scrolls away. Equal specificity to the
   rule above, so it has to stay after it. A plain class, not :has(), because the browsers this
   matters to predate :has() by years. */
#app.planner-blocked {
  min-block-size: 0;
}

/* Who's behind it. Sits between the planner and the footer, on the same measure as the footer so
   the page keeps one spine. Quiet by design: this section earns trust by being specific, not by
   being loud, and it must never compete with the planner for a first-time visitor's attention. */
/* The three newest guides, between the planner and the founder section. Same construction as
   .founder below: the section holds the page width so its rule lines up with the footer's, and the
   content is held to a narrower measure and centred. The measure is wider here because three cards
   need the room that prose does not. */
.home-guides {
  inline-size: min(100% - 2rem, var(--page-max));
  margin-inline: auto;
  margin-block-start: var(--space-3xl);
  padding-block-start: var(--space-2xl);
  /* No rule here on purpose. This section follows the green band, so the surface has already
     changed and a hairline would be a second boundary drawn over one that is already working. */
}
.home-guides-eyebrow,
.home-guides h2,
.home-guides-list,
.home-guides-more {
  inline-size: min(100%, 64rem);
  margin-inline: auto;
}
.home-guides-eyebrow {
  margin-block: 0 var(--space-xs);
  color: var(--primary);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-align: center;
  max-inline-size: none;   /* see the note on .founder-eyebrow: the global p cap is wrong here */
}
.home-guides h2 {
  margin-block: 0 var(--space-xl);
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 600;
  line-height: 1.1;
  color: var(--ink-950);
  text-align: center;
}
/* Two columns by default and four when the row can hold them. Four cards across 64rem leaves
   about 232px each, which a square thumbnail with a kicker, a title and a date still carries;
   below that they pair up rather than stacking, since one card per row on a phone made each one
   taller than the viewport. */
.home-guides-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-lg);
}

@media (min-width: 64rem) {
  .home-guides-list {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}
.home-guide-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  padding: var(--space-md);
  border: 1px solid var(--ink-150);
  border-radius: var(--radius-md, 0.875rem);
  background: var(--paper-raised);
  color: inherit;
  text-decoration: none;
  transition: border-color 120ms ease, transform 120ms ease;
}
.home-guide-card:hover,
.home-guide-card:focus-visible {
  border-color: var(--primary);
  transform: translateY(-2px);
}
.home-guide-card img {
  inline-size: 100%;
  block-size: auto;
  aspect-ratio: 1 / 1;
  border-radius: var(--radius-sm, 0.5rem);
  margin-block-end: var(--space-xs);
}
/* Below about 30rem two columns cannot hold a 17px title without breaking it into ribbons, so the
   card turns on its side: a small square thumbnail beside the text instead of above it. One column
   at full width would have worked too, but four square pictures stacked make the section enormously
   tall and push the founder note and the sign-up off the end of the page. */
@media (max-width: 30rem) {
  .home-guides-list {
    grid-template-columns: 1fr;
    gap: var(--space-md);
  }
  .home-guide-card {
    display: grid;
    grid-template-columns: 4.5rem 1fr;
    align-items: center;
    column-gap: var(--space-sm);
    row-gap: 0;
  }
  .home-guide-card img {
    grid-row: 1 / span 3;
    margin-block-end: 0;
  }
}

.home-guide-kicker {
  color: var(--primary);
  /* Same treatment as .eyebrow, and for the same reason. Uppercase is kept because this is a
     taxonomy label and the shape helps it read as one, but 700 and 0.08em on top of that made it
     compete with the title it is supposed to introduce. On the card the title earns the tap. */
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.home-guide-card h3 {
  margin: 0;
  font-family: var(--font-display);
  /* This used to fall to 0.875rem (14px) so that two columns could survive on a phone. That is the
     wrong thing to protect: the title is what earns the tap, and the grid was being kept intact by
     shrinking the only part of the card that does any work. The floor is now 17px and the layout
     gives way instead, one column with the picture as a thumbnail beside the text. */
  font-size: clamp(1.0625rem, 2.2vw + 0.25rem, var(--text-lg));
  font-weight: 600;
  line-height: 1.25;
  color: var(--ink-950);
}
.home-guide-date { color: var(--ink-500); font-size: var(--text-xs); }
.home-guides-more {
  margin-block: var(--space-xl) 0;
  text-align: center;
  max-inline-size: none;
}
.home-guides-button {
  display: inline-block;
  padding: 0.65rem 1.4rem;
  border: 1px solid var(--ink-300);
  border-radius: var(--radius-pill, 999px);
  color: var(--ink-950);
  font-weight: 600;
  text-decoration: none;
}
.home-guides-button:hover,
.home-guides-button:focus-visible {
  border-color: var(--primary);
  color: var(--primary);
}

@media (max-width: 46rem) {
  .home-guides h2 { font-size: var(--text-xl); }
}

/* Two different widths on purpose. The section keeps the page width so its top rule lines up with
   the footer's, and the content inside is held to a prose measure and centred within it.
   The first attempt let the content inherit the full 78rem: the text still wrapped at its own
   40rem, leaving roughly 490px of dead space to its right, and the whole block read as shoved
   against the left edge. Narrowing the section itself fixed that but then gave two stacked
   horizontal rules of different lengths, which looked like a mistake. This does both. */
.founder {
  inline-size: min(100% - 2rem, var(--page-max));
  margin-inline: auto;
  margin-block-start: var(--space-3xl);
  padding-block-start: var(--space-2xl);
  /* Matching padding at the end: without it the contact line sat directly on the footer's rule,
     with no air between the last thing the reader reads and the legal small print. */
  padding-block-end: var(--space-2xl);
  border-block-start: 1px solid var(--ink-150);
}
.founder-eyebrow,
.founder h2,
.founder-body {
  inline-size: min(100%, 50rem);
  margin-inline: auto;
}
/* Eyebrow and heading centred, body left-aligned. Centred prose is harder to read, so only the two
   lines short enough to scan at a glance get it. */
.founder-eyebrow {
  /* margin-block, not the shorthand: `margin: 0 0 x` also sets margin-inline to 0, which killed the
     `auto` above and left the heading pinned to the left edge while the body sat centred. */
  margin-block: 0 var(--space-xs);
  color: var(--primary);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-align: center;
  /* The global `p { max-inline-size: 70ch }` caps this to about 503px, which is a sensible measure
     for a paragraph and wrong for a centred one-line label: it left the eyebrow centred on its own
     box rather than on the block below it, off by a few pixels. The cap still applies to the real
     paragraphs in .founder-text, which is where it belongs. */
  max-inline-size: none;
}
.founder h2 {
  margin-block: 0 var(--space-xl);
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 600;
  line-height: 1.1;
  color: var(--ink-950);
  text-align: center;
}
/* Photo beside the text on a wide screen, above it on a narrow one. Grid rather than float so the
   image cannot overlap the paragraphs when the text is short. */
.founder-body {
  display: grid;
  grid-template-columns: 7.5rem minmax(0, 1fr);
  gap: var(--space-xl);
  align-items: start;
}
.founder-photo {
  inline-size: 7.5rem;
  block-size: 7.5rem;
  border-radius: 50%;
  object-fit: cover;
  /* Explicit background: a portrait cut out on white would otherwise sit on the page tint and
     read as a floating head. */
  background: var(--paper-raised);
}
/* No max-inline-size here any more: the section itself is now the constraint, so a cap here would
   only reintroduce the gap it was meant to prevent. */
.founder-text {
  min-inline-size: 0;   /* let the grid track shrink instead of overflowing on narrow screens */
}
.founder-text p {
  margin: 0 0 var(--space-md);
  color: var(--ink-850);
  font-size: var(--text-base);
  line-height: 1.65;
}
.founder-text p:last-child { margin-block-end: 0; }
.founder-text strong { color: var(--ink-950); font-weight: 600; }
.founder-contact { color: var(--ink-700); }
.founder-contact a { color: var(--primary); }

@media (max-width: 46rem) {
  .founder-body {
    grid-template-columns: 1fr;
    gap: var(--space-lg);
  }
  .founder h2 { font-size: var(--text-xl); }

  /* One column now, so the photo is a grid item in a full-width track and its fixed 7.5rem sat
     against the left edge while the heading above it was centred. */
  .founder-photo { justify-self: center; }

  /* One gutter for the whole page. These held 100% - 2rem, which is 16px a side on a phone, while
     the full-bleed bands padded 24px, so the text shifted towards the edge and back again as the
     reader scrolled. 3rem takes the wider of the two. */
  .founder,
  .home-guides {
    inline-size: min(100% - 3rem, var(--page-max));
  }
}

/* Email sign-up. A tinted band so it reads as a moment rather than another content block, and the
   band is free: a block-level child of body is already full width, so a background on the section
   plus a constrained inner wrapper does it with no 100vw anywhere. */
.subscribe {
  margin-block-start: var(--space-2xl);
  padding-block: var(--space-3xl);
  background: var(--paper-deep);
}
.subscribe-inner {
  inline-size: min(100% - 2rem, 34rem);
  margin-inline: auto;
  text-align: center;
}

/* Same gutter as the rest of the page on a phone. Kept here rather than with the other two
   because this one caps at a 34rem form measure instead of the page measure, and because a rule
   placed before .subscribe-inner above would lose to it on source order. */
@media (max-width: 46rem) {
  .subscribe-inner {
    inline-size: min(100% - 3rem, 34rem);
  }
}
.subscribe-eyebrow {
  margin-block: 0 var(--space-xs);
  color: var(--primary);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  max-inline-size: none;
}
.subscribe h2 {
  margin-block: 0 var(--space-md);
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 600;
  line-height: 1.1;
  color: var(--ink-950);
}
.subscribe-lead {
  margin-block: 0 var(--space-xl);
  margin-inline: auto;
  color: var(--ink-700);
  line-height: 1.6;
}
/* The label is left-aligned against the field even though the block is centred: a centred label
   floating above a full-width input reads as a caption rather than as the name of the box. */
.subscribe-label {
  display: block;
  margin-block-end: var(--space-2xs);
  text-align: start;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink-850);
}
.subscribe-row {
  display: flex;
  gap: var(--space-sm);
  align-items: stretch;
}
.subscribe-row input {
  flex: 1 1 auto;
  min-inline-size: 0;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--ink-300);
  border-radius: var(--radius-md, 0.875rem);
  background: var(--paper-raised);
  color: var(--ink-950);
  font: inherit;
}
.subscribe-row input:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}
.subscribe-button {
  flex: 0 0 auto;
  padding: 0.7rem 1.4rem;
  border: 1px solid transparent;
  border-radius: var(--radius-pill, 999px);
  background: var(--primary);
  color: #fff;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.subscribe-button:hover:not(:disabled) { background: var(--primary-hover); }
.subscribe-button:disabled { opacity: 0.6; cursor: default; }
/* Off-screen rather than display:none: a bot reading the DOM fills what it can see in the markup,
   and some skip anything explicitly hidden. */
.subscribe-hp {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
/* The global `p { max-inline-size: 70ch }` caps this at about 453px inside a 544px block, so the
   consent wrapped short of the button and read as a caption on the input rather than as the terms
   of the whole form. 70ch is a reading measure for body prose; this is a four line legal note that
   should share the form's own width. */
.subscribe-consent {
  max-inline-size: none;
  margin-block: var(--space-md) 0;
  text-align: start;
  /* ink-500 clears AA on --paper, and this note sits on --paper-deep, where the same pair measures
     4.46 against the 4.5 that 12px text needs. One step darker. Consent text is the last place to
     accept a near miss, because it is the part a reader is entitled to be able to read. */
  color: var(--ink-700);
  font-size: var(--text-xs);
  line-height: 1.5;
}
.subscribe-status {
  margin-block: var(--space-md) 0;
  color: var(--primary);
  font-weight: 600;
}
.subscribe-status-warn { color: var(--terracotta-deep); }

@media (max-width: 30rem) {
  .subscribe-row { flex-direction: column; }
  .subscribe h2 { font-size: var(--text-xl); }
}

.site-footer {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
  inline-size: min(100% - 2rem, var(--page-max));
  margin-inline: auto;
  padding-block: var(--space-2xl) max(var(--space-xl), env(safe-area-inset-bottom));
  border-block-start: 1px solid var(--ink-150);
  color: var(--ink-700);
  font-size: var(--text-xs);
}

.footer-top {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

.footer-brand {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.footer-wordmark {
  color: var(--ink-950);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
  letter-spacing: -0.02em;
}

.footer-tld {
  color: var(--primary);
}


.footer-disclaimer {
  max-inline-size: 46ch;
  margin: 0;
  color: var(--ink-700);
  font-size: var(--text-xs);
  line-height: 1.5;
}

/* Same rule as in guides.css, deliberately duplicated rather than shared: the two stylesheets are
   independent by design and each defines its own --primary, so a shared file would have to pick one
   green for both. The markup is identical in every footer, which is what keeps them in step. */
.footer-social {
  display: flex;
  gap: var(--space-sm);
  margin-block-start: var(--space-sm);
  padding: 0;
  list-style: none;
}
.footer-social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 2.75rem;
  block-size: 2.75rem;
  border-radius: 50%;
  background-color: var(--primary);
  color: var(--paper);
  transition: background-color 120ms ease;
}
.footer-social a:hover,
.footer-social a:focus-visible {
  background-color: var(--primary-hover);
}
.footer-social svg {
  inline-size: 1.15rem;
  block-size: 1.15rem;
  fill: currentColor;
}

.footer-legal {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.footer-link {
  /* Used on both <button> (dialogs) and <a> (real pages), so it has to sit correctly either way. */
  display: inline-flex;
  align-items: center;
  min-block-size: 2.75rem;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--primary);
  font-size: var(--text-sm);
  font-weight: 600;
  text-align: start;
  text-decoration: none;
}

.footer-bottom {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  padding-block-start: var(--space-md);
  border-block-start: 1px solid var(--ink-150);
}

@media (hover: hover) {
  .footer-link:hover {
    color: var(--primary-hover);
    text-decoration: underline;
    text-underline-offset: 0.2em;
  }
}

.calendar-dialog-note {
  margin: 0;
  color: var(--ink-700);
  font-size: var(--text-xs);
  line-height: 1.45;
}

.eyebrow {
  color: var(--primary);
  /* Was 12px, weight 700, uppercase, tracked out to 0.12em. Every one of those is a way of adding
     emphasis, and four at once on the smallest text on the page is why it read as loud rather than
     as a label. Sentence case at 13 and weight 500 keeps it a caption, which is its job. */
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  line-height: 1.3;
}

.primary-button,
.secondary-button,
.quiet-button,
.complete-button,
.danger-button,
.text-button {
  display: inline-flex;
  min-block-size: 2.75rem;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  border: 0;
  border-radius: var(--radius-pill);
  font-weight: 700;
  text-decoration: none;
  transition: background-color 150ms var(--ease-toggle), color 150ms var(--ease-toggle), transform 150ms var(--ease-out);
}

.primary-button {
  padding: 0.8rem 1.25rem;
  background: var(--primary);
  color: var(--paper-raised);
}

.primary-button svg {
  transition: transform 180ms var(--ease-out);
}

.secondary-button,
.quiet-button {
  padding: 0.7rem 1rem;
  border: 1px solid var(--ink-300);
  background: transparent;
  color: var(--ink-950);
}

.complete-button {
  padding: 0.8rem 1.1rem;
  background: var(--moss);
  color: var(--paper-raised);
}

.danger-button {
  padding: 0.7rem 1rem;
  background: var(--danger);
  color: var(--paper-raised);
}

.text-button {
  justify-content: flex-start;
  min-block-size: 2.75rem;
  padding-inline: 0;
  background: transparent;
  color: var(--primary);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
}

.text-button-danger {
  color: var(--danger);
}

@media (hover: hover) {
  .primary-button:hover {
    background: var(--primary-hover);
  }

  .primary-button:hover svg {
    transform: translateX(0.2rem);
  }

  .secondary-button:hover,
  .quiet-button:hover {
    border-color: var(--primary);
    background: var(--ink-075);
  }

  .complete-button:hover {
    background: oklch(40% 0.08 151);
  }

  .text-button:hover {
    color: var(--primary-hover);
  }
}

.primary-button:active,
.secondary-button:active,
.quiet-button:active,
.complete-button:active,
.danger-button:active {
  transform: translateY(1px);
}

/* Welcome */
/* The hero grounds differ by device, because the illustration only ever worked with room around it.
   Phones and tablets get pure colour: a raised-paper wash, a eucalyptus bloom from the top-left, an
   amber one warming the corner by the primary action. The illustration appears at 1280px and above,
   where there is room to set it beside the copy rather than behind it. Declaring it inside that
   media query rather than here is what keeps it off phones and tablets entirely: a background
   image in an unmatched media query is never fetched. */
.welcome-shell {
  position: relative;
  isolation: isolate;
  display: grid;
  overflow: hidden;
  inline-size: 100vw;
  min-block-size: clamp(26rem, 62svh, 40rem);
  margin-inline: calc(50% - 50vw);
  padding: clamp(var(--space-2xl), 8vw, var(--space-4xl)) var(--space-lg);
  background:
    radial-gradient(ellipse 90% 80% at 12% -12%, var(--moss-soft) 0%, transparent 58%),
    radial-gradient(ellipse 80% 70% at 96% 108%, var(--amber-soft) 0%, transparent 55%),
    linear-gradient(to bottom, var(--paper-raised), var(--paper));
  place-items: center;
}

/* Tablet keeps the phone's ground: colour only, no illustration. Between 641px and 1023px there is
   not enough width to set a text column beside the couple, so the picture could only go behind
   centred copy, and the veil needed to keep that copy readable dimmed the picture to the point of
   being barely worth loading. Colour on its own is the more confident answer, and it means the
   image now downloads on desktop alone. Only the taller shell carries over. */
@media (min-width: 40.0625rem) {
  .welcome-shell {
    min-block-size: clamp(32rem, 74svh, 46rem);
  }
}

.welcome-copy {
  position: relative;
  z-index: 2;
  display: flex;
  inline-size: min(100%, 44rem);
  flex-direction: column;
  align-items: center;
  gap: var(--space-lg);
  text-align: center;
}

.welcome-copy .eyebrow {
  color: var(--ink-850);
}

/* The one accent on the page, and the reason it is here rather than anywhere else: the ordering
   is what separates this from a pile of correct information, which anyone can already find. The
   headline said it and gave it no more weight than the rest of the sentence.

   Italic Fraunces and terracotta, nothing else. No second weight, no underline, no highlight:
   emphasis stops working the moment there is more than one kind of it on a page. em rather than a
   span because this really is stress emphasis, and a screen reader is right to convey it.

   terracotta-deep measures 6.09:1 on paper, so it clears AA for body text, let alone at this size.
   The green stays the dominant colour and keeps the button. */
.welcome-copy h1 em {
  color: var(--terracotta-deep);
  font-style: italic;
  /* Its own line, always. Left inline, the accent starts wherever the wrap happens to land: on a
     375px screen that was the word "in" alone in terracotta at the end of the second line, with the
     rest of the phrase below it, which reads as a mistake rather than as emphasis. On desktop the
     headline already broke at the comma, so this changes nothing there and only fixes the phone. */
  display: block;
}

.welcome-copy h1 {
  /* 11ch was tuned for a four word headline and turned anything longer into a five line column.
     20ch lets the current headline break once, at its comma, and still keeps a display measure. */
  max-inline-size: 20ch;
  color: var(--ink-950);
}

.welcome-lead {
  max-inline-size: 37rem;
  color: var(--ink-850);
  font-size: var(--text-lg);
  line-height: 1.45;
}

.welcome-benefits {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-sm) var(--space-lg);
  margin: 0;
  padding: 0;
  list-style: none;
}

.welcome-benefits li {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  color: var(--ink-950);
  /* Was 14px at weight 700. Small and insistent at the same time is the combination that flattens
     a hierarchy: three lines shouting at the size of a footnote compete with the headline instead
     of supporting it. Sixteen at 500 is quieter and easier to read, and it lets the reading order
     land where it should, headline, then lead, then these, then the button. */
  font-size: var(--text-base);
  font-weight: 400;
}

/* The lead names the benefit, the rest explains it. One weight step is enough to let the eye take
   the three benefits in a glance and stop, or read on: two would put the bullets back in
   competition with the headline, which is what 700 on the whole line was doing before. */
.welcome-benefits li strong {
  font-weight: 600;
}

.welcome-benefits li svg {
  flex: 0 0 auto;
  color: var(--primary);
}

.welcome-actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-md);
}

.welcome-actions > span {
  color: var(--ink-850);
  font-size: var(--text-sm);
}

/* Desktop, and desktop only. The illustration is drawn with its left half deliberately empty and
   the scene pushed into the right, so from 1280px up the copy moves into that empty half and the
   picture is left uncovered. The veil changes character with it: a horizontal wash that holds under
   the text column and has cleared before the figures, instead of a radial one that had to dim the
   whole picture in order to keep centred text readable.

   The right anchor is deliberate. `cover` crops from the sides once the shell is proportionally
   taller than the picture, and the empty left is the only part that can be lost without cost.

   1280 and not 1024, which was the first attempt. The text column is a fixed width while the
   picture scales with the viewport, so as the window narrows the drawn scene marches left to meet
   the text: measured at 1024 the headline ran 71px into the plant, with only a quarter of the veil
   left to cover it. 1280 is where the two stop colliding. Below it the hero takes the phone and
   tablet ground instead, which is a treatment that already works rather than a compromise.

   This block sits after the .welcome-* rules it overrides, not next to the tablet media query where
   it reads better. A media query adds no specificity, so up there `.welcome-copy { text-align:
   center }` further down the file would simply win. */
@media (min-width: 80rem) {
  .welcome-shell {
    justify-items: start;
    /* 8vw of block padding was sized for a centred hero that had nothing beside the text. A
       horizontal layout needs less, and the saving is what keeps the primary action above the fold
       on a 680px laptop. */
    padding-block: clamp(var(--space-2xl), 6vw, var(--space-3xl));
    padding-inline: max(var(--space-xl), calc(50vw - var(--page-max) / 2));
    /* Strong at the left edge and gone by 58%. The strength at the left is not about the empty
       cream there, which needs no help: it is the dark green shape in the bottom-left corner, which
       the primary button sits directly on top of and which would otherwise rob a solid green button
       of its edge. It clears by 58% so the plant, the table and the window keep their own colour
       instead of sitting under a wash.

       The illustration is an SVG, so there is one file and no 1x/2x pair to choose between: it is
       sharp at every width and on every display, and at 54KB it is lighter than either of the two
       rasters it replaced. The .webp beside it is no longer used here and survives only as the
       og:image, because social previews do not render SVG. */
    background:
      linear-gradient(
        to right,
        oklch(97.6% 0.006 165 / 0.92) 0%,
        oklch(97.6% 0.006 165 / 0.88) 26%,
        oklch(97.6% 0.006 165 / 0.42) 44%,
        oklch(97.6% 0.006 165 / 0) 58%
      ),
      url("/assets/hero-couple.svg") 100% 50% / cover no-repeat var(--paper);
  }

  .welcome-copy {
    inline-size: min(100%, 33rem);
    align-items: start;
    text-align: start;
  }

  /* The headline comes down from 76.8px. That size was set when the illustration sat under a 92%
     veil and was effectively invisible, so the type had to carry the whole hero on its own. Now the
     picture carries half of it, and a headline this size would only compete with it: at 76.8px the
     sentence needs a 44rem measure to stay on two lines, which is wider than the empty half of the
     picture allows. Below 58px it breaks in two at its own comma, in a 33rem column.

     The 20ch cap goes with it. It was a measure for a centred headline and, being in ch, it scales
     with the font, so it re-imposed a third line at every size it was tested against. */
  .welcome-copy h1 {
    max-inline-size: none;
    /* The top of the range is set by the picture, not by taste. `text-wrap: balance` already gives
       the shortest possible longest-line for two lines, so the size is what decides whether the last
       word reaches the scene. 3.6rem is the largest that still breaks in two: 3.9rem goes to three
       lines and takes the hero with it. Measured at 1920 it leaves 105px to the plant.

       It was briefly 3.4rem, when the previous raster put the plant at 43% of the frame instead of
       50% and 3.6rem overlapped it by 29px. That constraint went with that picture. */
    font-size: clamp(2.9rem, 4vw, 3.6rem);
  }

  .welcome-lead {
    max-inline-size: none;
  }

  .welcome-benefits {
    justify-content: start;
  }

  .welcome-actions {
    align-items: start;
  }
}

/* Home page: "how it works" + FAQ, below the hero */
/* The home is full-bleed bands: the hero (colour wash on phones, the illustration on wider screens),
   then the steps and the questions on paper, and a eucalyptus-green band for the call to action, so
   the page settles on paper and lifts to colour at the decision. Each band centres its own content.
   This used to say the steps and questions sat together on paper-deep. They never did: the steps were
   on paper throughout and only the questions stepped down. See the surface note further below. */
.home-how,
.home-faq,
.home-start {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-xl);
  inline-size: 100vw;
  margin-inline: calc(50% - 50vw);
  padding-block: clamp(var(--space-2xl), 6vw, var(--space-4xl));
  padding-inline: var(--space-lg);
}

/* Three surfaces, and each one means exactly one thing. A change of background should mean the
   reader's job has changed, so a surface that marks two different jobs marks neither.

   That is what happened here. The questions used to sit on paper-deep because they were "a
   different act" from the steps, which was true of the page as it stood then. The subscribe form
   was added later on the same paper-deep, and from that point the step down meant both "answer your
   objections" and "give us your email". The reader gets a seam and no information from it.

   So the questions come back onto paper with everything else that is there to be read, and the two
   remaining surfaces each keep one job:
     paper       the page talks to you
     paper-deep  the page asks you for something (the subscribe form, and nothing else)
     moss        the page asks you to start (the green band, and nothing else)

   The closing call to action sits on paper rather than on moss, which is the one place this is not
   literally true. That is deliberate: it is the same ask at a much lower volume, after the reader
   has finished, and a second green band there would read as the page starting over. */
.home-how,
.home-faq {
  background: var(--paper);
}

/* The two sections share a surface now, so the boundary has to be drawn rather than implied. The
   rule across this page: a hairline where consecutive sections sit on the same background, and
   nothing where the background itself changes.

   The line spans its own section's content, which is why this one is narrower than the one above
   the founder section. Those sections run to the page measure and this one runs to a 46rem reading
   measure, so a line matching the founder's width would float clear of the questions it introduces.
   The first attempt here set the width on .faq-shell and overrode that 46rem, widening the content
   to 1200px as a side effect of trying to draw a rule. */
.home-faq {
  padding-block-start: 0;
}

.home-faq .faq-shell {
  padding-block-start: clamp(var(--space-2xl), 6vw, var(--space-4xl));
  border-block-start: 1px solid var(--ink-150);
}

.home-start {
  /* The palette's eucalyptus green. moss-soft alone read as washed grey-green, so it is pulled a
     step towards moss to make the green actually present while staying light enough for dark ink. */
  background: color-mix(in oklch, var(--moss-soft) 80%, var(--moss));
  /* Breathing room before the footer. This band used to end exactly where the footer began, and two
     coloured blocks with no gap between them read as one block: since the lower one is obviously a
     footer, the upper one was being absorbed into it and skipped. It is the second and last chance
     to convert on this page, so it has to announce itself as a section rather than as chrome. */
  margin-block-end: clamp(var(--space-lg), 4vw, var(--space-2xl));
}

/* The closing route into the planner, after the founder section. Paper background on purpose: the
   green band above is the pitch, and a second coloured band this far down would read as the page
   starting over rather than finishing. This one is a closing line, so it sits on the same surface
   as the prose it follows and is separated by space alone. */
.home-closing {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-lg);
  padding-block: clamp(var(--space-2xl), 5vw, var(--space-3xl));
  padding-inline: var(--space-lg);
  text-align: center;
}

.home-closing-line {
  /* Sized between the body and the section headings: it is the last sentence on the page and has to
     carry weight, but a third heading here would compete with the two real ones above it. */
  max-inline-size: 34rem;
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-lg);
  line-height: 1.4;
  color: var(--ink-950);
}

.home-section-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-xs);
  max-inline-size: 44rem;
  text-align: center;
}

.home-section-head h2 {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 600;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.home-section-head p {
  color: var(--ink-700);
  font-size: var(--text-lg);
  line-height: 1.45;
}

/* Steps: an open numbered sequence, deliberately not a card grid. */
.how-steps {
  display: grid;
  inline-size: min(100%, 64rem);
  gap: var(--space-lg);
  margin: 0;
  padding: 0;
  list-style: none;
}

.how-step {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2xs);
  padding-block-start: var(--space-md);
  text-align: center;
}

/* Editorial marker: a short clay tick on the top rule, per step (a top accent, not a
   side-stripe), and repeated across the row it reads as an ordered sequence. */
.how-step::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  /* Centred with the step it marks. It was pinned left, which was correct while the content was. */
  inset-inline-start: 50%;
  transform: translateX(-50%);
  inline-size: 2.5rem;
  block-size: 2px;
  background: var(--terracotta-deep);
}

.how-step-num {
  margin-block-end: var(--space-2xs);
  /* Deeper clay than --terracotta so the meaningful ordinals clear WCAG AA (≥4.5:1). */
  color: var(--terracotta-deep);
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.how-step h3 {
  font-size: var(--text-lg);
  font-weight: 700;
}

.how-step p {
  max-inline-size: 36ch;
  color: var(--ink-700);
  line-height: 1.5;
}

/* Trust-badge row: a distinct assurance strip below the steps. */
.home-badges {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-sm) var(--space-lg);
  margin: 0;
  /* No rule above these. Space separates them from the steps, and the section boundary below was
     close enough that the reader crossed two lines inside about 80px. */
  padding-block-start: var(--space-xl);
  padding-inline: 0;
  list-style: none;
}

.home-badges li {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  color: var(--ink-850);
  font-size: var(--text-sm);
  font-weight: 700;
}

.home-badges li svg {
  flex: 0 0 auto;
  inline-size: 1.15rem;
  block-size: 1.15rem;
  color: var(--primary);
}

/* FAQ accordion */
/* Mobile: heading → questions → CTA in source order. */
.faq-shell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-xl);
  inline-size: min(100%, 46rem);
}

.faq-list {
  inline-size: 100%;
}

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

.faq-item {
  border-block-end: 1px solid var(--ink-150);
}

.faq-item:first-child {
  border-block-start: 1px solid var(--ink-150);
}

.faq-item > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  min-block-size: 3.75rem;
  margin-inline: calc(var(--space-sm) * -1);
  padding-block: var(--space-md);
  padding-inline: var(--space-sm);
  border-radius: var(--radius-sm);
  color: var(--ink-950);
  font-size: var(--text-lg);
  font-weight: 700;
  list-style: none;
  transition: background-color 150ms var(--ease-out);
}

.faq-item > summary::-webkit-details-marker {
  display: none;
}

@media (hover: hover) {
  .faq-item > summary:hover {
    background: var(--ink-075);
  }

  .faq-item > summary:hover svg {
    color: var(--terracotta-deep);
  }
}

.faq-item > summary svg {
  flex: 0 0 auto;
  inline-size: 1.35rem;
  block-size: 1.35rem;
  color: var(--ink-500);
  transition: transform 200ms var(--ease-out), color 150ms var(--ease-out);
}

.faq-item[open] > summary svg {
  transform: rotate(180deg);
}

.faq-answer {
  padding-block: 0 var(--space-lg);
}

/* Gentle reveal of the answer on open (snaps instantly under reduced motion). */
.faq-item[open] .faq-answer {
  animation: fade-in 240ms var(--ease-out) both;
}

.faq-answer p {
  max-inline-size: 68ch;
  color: var(--ink-700);
  line-height: 1.6;
}

/* Closing call to action */
.home-cta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-sm);
  text-align: center;
}

.home-cta-title {
  max-inline-size: 22ch;
  color: var(--ink-950);
  font-family: var(--font-display);
  /* Was a flat --text-xl, which left the closing section the smallest of the three headings on the
     page while the other two sit at --text-2xl. It now reaches the same size on a wide screen and
     stays at the old size on a narrow one, where the band is shorter and a 39px serif line would
     wrap three times inside it. */
  font-size: clamp(var(--text-xl), 3.5vw, var(--text-2xl));
  line-height: 1.15;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.home-cta-sub {
  margin-block-end: var(--space-xs);
  color: var(--ink-700);
  font-size: 0.95rem;
}

/* Tighter than the reading bands above: this is a short prompt, not a section to dwell in. */
.home-start {
  padding-block: clamp(var(--space-xl), 4vw, var(--space-2xl));
}

@media (min-width: 52rem) {
  .how-steps {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-2xl);
  }

  .how-step-num {
    font-size: var(--text-3xl);
  }
}









/* Loading and error */
.loading-shell,
.error-shell {
  display: flex;
  min-block-size: 65vh;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: var(--space-lg);
  max-inline-size: 42rem;
}

.loading-shell p,
/* The compatibility notice ships hidden and is revealed by compat-guard.js. Without this rule the
   display: flex above wins over the browser default for [hidden], which is only display: none at
   user-agent specificity, and the notice shows on every visit. Caught in the browser on 4 September
   2026, having passed as hidden in the DOM. Same shape as .share-status[hidden] elsewhere. */
.error-shell[hidden] {
  display: none;
}

.error-shell > p:not(.eyebrow) {
  color: var(--ink-700);
  font-size: var(--text-lg);
}

.skeleton {
  overflow: hidden;
  border-radius: var(--radius-sm);
  background: var(--paper-deep);
}

.skeleton-title { inline-size: 75%; block-size: 4rem; }
.skeleton-copy { inline-size: 92%; block-size: 1.5rem; }
.skeleton-panel { inline-size: 100%; block-size: 10rem; }

/* Onboarding */
.onboarding-shell {
  display: grid;
  gap: var(--space-2xl);
  /* Balance the whitespace around the Back/Continue row: the gap above it comes from the
     form's own rhythm, so keep the gap below it on the same scale instead of a page-sized drop. */
  padding-block: var(--space-xl) var(--space-2xl);
}

.onboarding-progress {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  color: var(--ink-700);
  font-size: var(--text-sm);
}

.onboarding-progress > span {
  font-weight: 700;
}

.onboarding-progress .progress-track {
  overflow: hidden;
  inline-size: 100%;
  block-size: 0.35rem;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--ink-150);
}

.onboarding-progress .progress-track::-webkit-progress-bar {
  border-radius: inherit;
  background: var(--ink-150);
}

.onboarding-progress .progress-track::-webkit-progress-value {
  border-radius: inherit;
  background: var(--terracotta);
}

.onboarding-progress .progress-track::-moz-progress-bar {
  border-radius: inherit;
  background: var(--terracotta);
}

.onboarding-progress ol {
  display: none;
  padding: 0;
  list-style: none;
}

.onboarding-progress li {
  min-block-size: 2.5rem;
}

.onboarding-progress .step-item {
  display: grid;
  grid-template-columns: 1.75rem 1fr;
  align-items: center;
  gap: var(--space-sm);
  inline-size: 100%;
  min-block-size: 2.75rem;
  margin-inline: calc(var(--space-xs) * -1);
  padding: 0.2rem var(--space-xs);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: start;
}

button.step-item {
  cursor: pointer;
  transition: background-color 150ms var(--ease-out);
}

@media (hover: hover) {
  button.step-item:hover {
    background: var(--ink-075);
  }

  button.step-item:hover .step-marker {
    border-color: var(--primary);
    color: var(--primary);
  }
}

.step-marker {
  display: grid;
  inline-size: 1.6rem;
  block-size: 1.6rem;
  place-items: center;
  border: 1px solid var(--ink-300);
  border-radius: 50%;
  font-size: var(--text-xs);
  font-weight: 700;
}

.onboarding-progress li svg {
  inline-size: 0.9rem;
  block-size: 0.9rem;
}

.onboarding-progress li.current {
  color: var(--ink-950);
  font-weight: 700;
}

.onboarding-progress li.current .step-marker {
  border-color: var(--primary);
  background: var(--primary);
  color: var(--paper-raised);
}

.onboarding-progress li.complete .step-marker {
  border-color: var(--moss);
  color: var(--moss);
}



.question-panel {
  max-inline-size: 46rem;
}

.question-panel form {
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
}

.question-panel h1 {
  max-inline-size: 14ch;
  font-size: clamp(2.2rem, 9vw, 4rem);
}

.question-intro {
  max-inline-size: 38rem;
  color: var(--ink-700);
  font-size: var(--text-lg);
}

fieldset {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  padding: 0;
  border: 0;
}

legend,
.date-field label,
.select-field label {
  margin-block-end: var(--space-sm);
  color: var(--ink-850);
  font-size: var(--text-sm);
  font-weight: 700;
}

.date-field > label:first-child span {
  color: var(--ink-700);
  font-weight: 600;
}

.choice-grid {
  display: grid;
  gap: var(--space-sm);
}

.choice-card {
  position: relative;
  display: block;
  cursor: pointer;
}

.choice-card input {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  opacity: 0;
}

.choice-card-content {
  display: grid;
  min-block-size: 5.75rem;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--space-md);
  padding: var(--space-md);
  border: 1px solid var(--ink-150);
  border-radius: var(--radius-md);
  background: var(--paper-raised);
  transition: border-color 180ms var(--ease-toggle), background-color 180ms var(--ease-toggle), transform 180ms var(--ease-out);
}

.choice-icon {
  display: grid;
  inline-size: 2.8rem;
  block-size: 2.8rem;
  place-items: center;
  border-radius: 50%;
  background: var(--paper-deep);
  color: var(--primary);
}

.choice-icon svg {
  inline-size: 1.3rem;
  block-size: 1.3rem;
}

.choice-card-content > span:nth-child(2) {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.choice-card-content strong {
  line-height: 1.25;
}

.choice-card-content small {
  color: var(--ink-700);
  line-height: 1.35;
}

.choice-indicator {
  inline-size: 1.25rem;
  block-size: 1.25rem;
  border: 1.5px solid var(--ink-300);
  border-radius: 50%;
  background: var(--paper-raised);
  box-shadow: inset 0 0 0 0.25rem var(--paper-raised);
  transition: background-color 150ms var(--ease-toggle), border-color 150ms var(--ease-toggle);
}

.choice-card input:checked + .choice-card-content {
  border-color: var(--primary);
  background: var(--ink-075);
}

.choice-card input:checked + .choice-card-content .choice-indicator {
  border-color: var(--primary);
  background: var(--primary);
}

.choice-card input:focus-visible + .choice-card-content {
  outline: 3px solid var(--terracotta-deep);
  outline-offset: 3px;
}

@media (hover: hover) {
  .choice-card:hover .choice-card-content {
    border-color: var(--ink-500);
    transform: translateY(-1px);
  }
}

.segmented-field {
  display: flex;
  inline-size: fit-content;
  min-block-size: 2.9rem;
  padding: 0.2rem;
  border: 1px solid var(--ink-150);
  border-radius: var(--radius-pill);
  background: var(--paper-deep);
}

.segmented-field label {
  position: relative;
  cursor: pointer;
}

.segmented-field input {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  opacity: 0;
}

.segmented-field span {
  display: grid;
  min-block-size: 2.4rem;
  place-items: center;
  padding-inline: var(--space-md);
  border-radius: var(--radius-pill);
  color: var(--ink-700);
  font-size: var(--text-sm);
  font-weight: 700;
}

.segmented-field input:checked + span {
  background: var(--paper-raised);
  color: var(--ink-950);
  box-shadow: 0 1px 3px oklch(25% 0.03 327 / 0.1);
}

.segmented-field input:focus-visible + span {
  outline: 3px solid var(--terracotta-deep);
  outline-offset: 2px;
}

.date-field,
.select-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

input[type="date"],
input[type="number"],
input[type="email"],
textarea,
select {
  inline-size: 100%;
  min-block-size: 3.4rem;
  padding: 0.8rem 1rem;
  border: 1.5px solid var(--ink-300);
  border-radius: var(--radius-md);
  background-color: var(--paper-raised);
  color: var(--ink-950);
  font-weight: 600;
  box-shadow: inset 0 1px 2px oklch(23% 0.018 160 / 0.04);
  transition: border-color 160ms var(--ease-out), box-shadow 160ms var(--ease-out), background-color 160ms var(--ease-out);
}

@media (hover: hover) {
  input[type="date"]:hover,
  input[type="number"]:hover,
  input[type="email"]:hover,
  textarea:hover,
  select:hover {
    border-color: var(--primary);
  }
}

/* Border tints on focus (mouse or keyboard); the terracotta focus-visible ring from
   the global rule still shows for keyboard users. */
input[type="date"]:focus,
input[type="number"]:focus,
input[type="email"]:focus,
textarea:focus,
select:focus {
  border-color: var(--primary);
  box-shadow: inset 0 0 0 1px var(--primary);
}

/* Custom dropdown chevron so selects match the rest of the form. */
select {
  appearance: none;
  -webkit-appearance: none;
  padding-inline-end: 2.6rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23566' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.95rem center;
  background-size: 1.05rem;
}

input[type="date"] {
  max-inline-size: 22rem;
  font-variant-numeric: tabular-nums;
}

input[type="number"] {
  max-inline-size: 10rem;
  font-variant-numeric: tabular-nums;
}

/* Nudge the native date picker button so it reads as interactive. */
input[type="date"]::-webkit-calendar-picker-indicator {
  cursor: pointer;
  opacity: 0.55;
  transition: opacity 160ms var(--ease-out);
}

input[type="date"]:hover::-webkit-calendar-picker-indicator,
input[type="date"]:focus::-webkit-calendar-picker-indicator {
  opacity: 1;
}

input[type="date"]:disabled,
select:disabled {
  border-color: var(--ink-150);
  background-color: var(--paper-deep);
  color: var(--ink-500);
  box-shadow: none;
  cursor: not-allowed;
}

.date-alternative {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  max-inline-size: 28rem;
  padding-block-start: var(--space-sm);
}

.date-alternative > label {
  margin: 0;
}

.date-alternative-word {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  color: var(--ink-700);
  font-size: var(--text-sm);
  font-weight: 700;
}

.date-alternative-word::before,
.date-alternative-word::after {
  block-size: 1px;
  flex: 1;
  background: var(--ink-150);
  content: "";
}

.select-field + .select-field,
.account-field + .account-field {
  padding-block-start: var(--space-sm);
}

.account-field .segmented-field {
  inline-size: 100%;
  flex-wrap: wrap;
  border-radius: var(--radius-md);
}

.account-field .segmented-field label {
  flex: 1 1 50%;
}

.account-field .segmented-field span {
  min-block-size: 2.75rem;
}

.account-status-note {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: var(--space-sm);
  min-block-size: 3.8rem;
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--ink-150);
  border-radius: var(--radius-sm);
  background: color-mix(in oklch, var(--paper-raised) 70%, var(--ink-075));
  color: var(--ink-700);
}

.account-status-marker {
  display: grid;
  inline-size: 1.35rem;
  block-size: 1.35rem;
  place-items: center;
  margin-block-start: 0.1rem;
  border: 1px solid var(--primary);
  border-radius: 50%;
  color: var(--primary);
  font-family: var(--font-display);
  font-size: var(--text-xs);
  font-weight: 700;
  line-height: 1;
}

.account-status-note p {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  font-size: var(--text-sm);
  line-height: 1.4;
}

.account-status-note strong {
  color: var(--ink-950);
}

.account-status-note span:last-child {
  max-inline-size: 64ch;
}

.account-guide {
  border-block: 1px solid var(--ink-150);
}

.account-guide > summary {
  display: flex;
  min-block-size: 3.75rem;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  padding-block: var(--space-md);
  color: var(--ink-950);
  list-style: none;
}

.account-guide > summary::-webkit-details-marker {
  display: none;
}

.account-guide > summary > span {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.account-guide > summary > span svg {
  color: var(--primary);
}

.account-guide > summary > svg {
  flex: 0 0 auto;
  color: var(--ink-500);
  transition: transform 180ms var(--ease-out);
}

.account-guide[open] > summary > svg {
  transform: rotate(180deg);
}

.account-guide-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
  padding-block: var(--space-sm) var(--space-xl);
  color: var(--ink-700);
}

.account-guide-body > p {
  font-size: var(--text-sm);
}

.account-guide-steps {
  display: grid;
  gap: var(--space-lg);
  padding: 0;
  list-style: none;
}

.account-guide-steps li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-md);
  align-items: start;
}

.account-guide-steps li + li {
  position: relative;
}

.account-step-number {
  display: grid;
  inline-size: 2.3rem;
  block-size: 2.3rem;
  place-items: center;
  border: 1px solid var(--ink-300);
  border-radius: 50%;
  color: var(--primary);
  font-size: var(--text-xs);
  font-weight: 850;
  font-variant-numeric: tabular-nums;
}

.account-guide-steps div {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.account-guide-steps strong {
  color: var(--ink-950);
}

.account-guide-steps p {
  max-inline-size: 54ch;
  font-size: var(--text-sm);
}

.official-help-link {
  display: inline-flex;
  inline-size: fit-content;
  min-block-size: 2.75rem;
  align-items: center;
  gap: var(--space-xs);
  color: var(--primary);
  font-size: var(--text-sm);
  font-weight: 700;
  text-underline-offset: 0.2em;
}

.official-help-link svg {
  inline-size: 1rem;
  block-size: 1rem;
}

.account-guide-body > small {
  margin-block-start: calc(var(--space-sm) * -1);
  color: var(--ink-500);
}

.sr-only {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.field-footnote {
  color: var(--ink-700);
  font-size: var(--text-sm);
}

/* Quiet, always-visible early entry to the support-first path on the first onboarding step. */
.loss-route-entry {
  margin-block-start: var(--space-lg);
  padding-block-start: var(--space-lg);
  border-block-start: 1px solid var(--ink-150);
}
.loss-route-entry p {
  margin: 0 0 var(--space-xs);
  color: var(--ink-700);
  font-size: var(--text-sm);
}
.loss-route-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  color: var(--primary);
  font-weight: 600;
}
.loss-route-link svg {
  inline-size: 1rem;
  block-size: 1rem;
}
@media (hover: hover) {
  .loss-route-link:hover {
    color: var(--primary-hover);
    text-decoration: underline;
    text-underline-offset: 0.2em;
  }
}

/* Out-of-scope off-ramp (birth outside the Republic of Ireland). */
.out-of-scope {
  max-inline-size: 42rem;
  margin-inline: auto;
  padding-block: var(--space-2xl);
}
.out-of-scope h1 {
  margin: 0 0 var(--space-lg);
}
.oos-links {
  list-style: none;
  margin: var(--space-xl) 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}
.oos-links li {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  padding-block-end: var(--space-lg);
  border-block-end: 1px solid var(--ink-150);
}
.oos-links li:last-child {
  border-block-end: 0;
  padding-block-end: 0;
}
.oos-links a {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  color: var(--primary);
  font-weight: 600;
}
.oos-links a svg {
  inline-size: 1rem;
  block-size: 1rem;
}
.oos-links span {
  color: var(--ink-700);
  font-size: var(--text-sm);
}
.oos-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  /* The buttons used to sit directly under the closing line, which read as part of the sentence
     rather than as the way out of the screen. The list above it already separates its items by
     space-lg, so anything less here would make the actions look like another list item. */
  margin-block-start: var(--space-xl);
}

.stacked-fields {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

/* Grouped onboarding step: labelled sections with air between them. */
.onboard-group + .onboard-group {
  margin-block-start: var(--space-xl);
}
.onboard-group-title {
  margin-block: 0 var(--space-md);
  font-size: 1.05rem;
  font-weight: 700;
}
.onboard-group > .stacked-fields + .registration-route-question {
  margin-block-start: var(--space-lg);
}

.inline-question {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-sm);
  padding-block-end: var(--space-md);
  border-block-end: 1px solid var(--ink-150);
}

.inline-question legend {
  margin: 0;
  padding: 0;
}

/* From tablet up, put the label and the Yes/No control on one row; on phones they stack so a long
   question is not squeezed beside the pills. */
@media (min-width: 40rem) {
  .inline-question {
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: var(--space-md);
  }
}

.registration-route-question {
  border-block: none;
}

.registration-route-question > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  min-block-size: 3.5rem;
  padding-block: var(--space-md);
  /* One hairline under the summary, like every other row, instead of a full box border that used to
     double up against the questions' own hairlines. */
  border-block-end: 1px solid var(--ink-150);
  font-weight: 700;
  list-style: none;
}

.registration-route-question > summary svg {
  flex: 0 0 auto;
  color: var(--ink-500);
  transition: transform 180ms var(--ease-out);
}

.registration-route-question[open] > summary svg {
  transform: rotate(180deg);
}

.registration-route-question > summary::-webkit-details-marker,
.journey-action > details > summary::-webkit-details-marker,
.detail-collapse > summary::-webkit-details-marker {
  display: none;
}

.details-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
  padding-block: var(--space-md) var(--space-lg);
}

.sensitive-disclosure > summary {
  font-weight: 700;
  color: var(--ink-700);
}

.sensitive-checkbox {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  padding: var(--space-md);
  border: 1px solid var(--ink-150);
  border-radius: var(--radius-md);
  background: var(--paper-raised);
  cursor: pointer;
  font-weight: 600;
}

.sensitive-checkbox input {
  flex: 0 0 auto;
  margin-block-start: 0.15rem;
  inline-size: 1.1rem;
  block-size: 1.1rem;
  accent-color: var(--primary);
}

.form-error {
  min-block-size: 1.5rem;
  color: var(--danger);
  font-size: var(--text-sm);
  font-weight: 700;
}

/* The error text takes programmatic focus so it's announced, but it's coloured,
   bold and role="alert" already; the focus ring is redundant noise. */
.form-error:focus,
.form-error:focus-visible {
  outline: none;
}

.form-navigation {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  padding-block-start: var(--space-sm);
}

/* Planning overview */
.planning-overview {
  display: flex;
  flex-direction: column;
  gap: clamp(3rem, 7vw, 6rem);
  padding-block: var(--space-2xl) var(--space-4xl);
}

.planning-hero {
  display: grid;
  gap: var(--space-xl);
  padding-block-end: var(--space-2xl);
  border-block-end: 1px solid var(--ink-150);
}

.planning-hero > div,
.planning-section-heading,
.planning-next-step > div {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.planning-hero h1 {
  max-inline-size: 14ch;
  font-size: clamp(2.5rem, 10vw, 4.3rem);
}

.planning-hero > p {
  max-inline-size: 42rem;
  align-self: end;
  color: var(--ink-700);
  font-size: var(--text-lg);
}

.planning-now,
.planning-map {
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
}

.planning-section-heading h2,
.planning-hse-signpost h2,
.planning-next-step h2 {
  max-inline-size: 22ch;
  font-size: clamp(1.75rem, 6vw, 2.441rem);
}

.planning-now-list {
  display: grid;
  margin: 0;
  padding: 0;
  border-block-start: 1px solid var(--ink-300);
  list-style: none;
}

.planning-now-list > li {
  display: grid;
  grid-template-columns: 2.75rem minmax(0, 1fr);
  gap: var(--space-md);
  padding-block: var(--space-lg);
  border-block-end: 1px solid var(--ink-300);
}

.planning-now-number {
  display: grid;
  inline-size: 2.5rem;
  block-size: 2.5rem;
  place-items: center;
  border-radius: 50%;
  background: var(--moss-soft);
  color: var(--primary);
  font-size: var(--text-xs);
  font-weight: 850;
}

.planning-now-list > li > div {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.planning-now-list h3,
.planning-timeline h4 {
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.35;
}

.planning-now-list p,
.planning-timeline p {
  max-inline-size: 64ch;
  color: var(--ink-700);
  font-size: var(--text-sm);
}

.planning-now-list a,
.planning-timeline a {
  display: inline-flex;
  min-block-size: 2.75rem;
  inline-size: fit-content;
  align-items: center;
  gap: var(--space-xs);
  color: var(--primary);
  font-size: var(--text-sm);
  font-weight: 700;
  text-underline-offset: 0.2em;
}

.planning-now-list a svg,
.planning-timeline a svg {
  inline-size: 1rem;
  block-size: 1rem;
}

.planning-map-heading > p {
  max-inline-size: 30rem;
  color: var(--ink-700);
}

.planning-timeline {
  display: grid;
  gap: var(--space-md);
  margin: 0;
  padding: 0;
  list-style: none;
}

.planning-phase {
  padding: var(--space-lg);
  border: 1px solid var(--ink-150);
  border-radius: var(--radius-md);
  background: var(--paper-raised);
}

.planning-phase > header {
  display: flex;
  align-items: baseline;
  gap: var(--space-sm);
  padding-block-end: var(--space-sm);
}

.planning-phase > header span {
  color: var(--terracotta);
  font-size: var(--text-xs);
  font-weight: 850;
  letter-spacing: 0.08em;
}

.planning-phase > header h3 {
  max-inline-size: 14ch;
  font-size: var(--text-lg);
}

.planning-phase > ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.planning-phase > ul > li {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  padding-block: var(--space-md);
  border-block-start: 1px solid var(--ink-150);
}

.planning-hse-signpost {
  display: grid;
  gap: var(--space-xl);
  padding: clamp(1.5rem, 5vw, 3rem);
  border-radius: var(--radius-lg);
  background: var(--primary);
  color: var(--paper-raised);
}

.planning-hse-signpost > div {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.planning-hse-signpost .eyebrow,
.planning-hse-signpost p {
  color: color-mix(in oklch, var(--paper-raised) 82%, var(--primary));
}

.planning-hse-signpost .secondary-button {
  align-self: end;
  border-color: var(--paper-raised);
  background: var(--paper-raised);
  color: var(--primary);
}

.planning-next-step {
  display: grid;
  gap: var(--space-xl);
  align-items: end;
  padding-block: var(--space-2xl);
  border-block-start: 1px solid var(--ink-300);
}

.planning-next-step p:not(.eyebrow) {
  max-inline-size: 38rem;
  color: var(--ink-700);
}

.planning-next-step .primary-button {
  justify-self: start;
}

.planning-hse-actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-sm);
}

.planning-hse-actions .secondary-button {
  align-self: flex-start;
}

.planning-hse-link {
  display: inline-flex;
  min-block-size: 2.75rem;
  align-items: center;
  gap: var(--space-2xs);
  color: var(--paper-raised);
  font-size: var(--text-sm);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.planning-hse-link svg {
  inline-size: 1rem;
  block-size: 1rem;
}

/* "Our baby has arrived" hand-off at the bottom of the expecting dashboard. */
.stage-transition {
  display: grid;
  gap: var(--space-lg);
  align-items: center;
  margin-block: var(--space-2xl);
  padding: clamp(1.5rem, 4vw, 2.5rem);
  border: 1px solid var(--ink-150);
  border-radius: var(--radius-lg);
  background: var(--moss-soft);
}

.stage-transition h2 {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  letter-spacing: -0.02em;
}

.stage-transition p {
  max-inline-size: 40rem;
  margin-block-start: var(--space-2xs);
  color: var(--ink-850);
}

.stage-transition .primary-button {
  justify-self: start;
}

@media (min-width: 40rem) {
  .stage-transition {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .stage-transition .primary-button {
    justify-self: end;
  }
}

/* Dashboard */
.dashboard-hero {
  display: grid;
  gap: var(--space-xl);
  padding-block: var(--space-2xl);
  border-block-end: 1px solid var(--ink-150);
}

.dashboard-hero > div:first-child {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.dashboard-hero h1 {
  max-inline-size: 13ch;
  font-size: clamp(2.5rem, 10vw, 4.3rem);
}

.dashboard-hero p:not(.eyebrow) {
  max-inline-size: 44rem;
  color: var(--ink-700);
  font-size: var(--text-lg);
}

.dashboard-hero-side {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-lg);
}

.dashboard-download {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  min-block-size: 2.75rem;
}

.dashboard-download svg {
  inline-size: 1.05rem;
  block-size: 1.05rem;
}

.date-stamp {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2xs);
  color: var(--ink-700);
}

.date-stamp span {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.date-stamp strong {
  color: var(--ink-950);
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

.dashboard-layout {
  display: grid;
  gap: var(--space-3xl);
  padding-block: var(--space-2xl) var(--space-4xl);
}

.dashboard-main {
  min-inline-size: 0;
}

.next-section,
.journey-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
}

.journey-section {
  padding-block-start: var(--space-4xl);
}

.section-heading {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.section-heading > div:first-child {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.section-heading > span {
  color: var(--ink-700);
  font-size: var(--text-sm);
  font-weight: 700;
}

.next-actions {
  display: flex;
  flex-direction: column;
  border-block-start: 1px solid var(--ink-300);
}

.next-action {
  display: grid;
  grid-template-columns: 2.25rem 1fr;
  gap: var(--space-md);
  padding-block: var(--space-lg);
  border-block-end: 1px solid var(--ink-300);
}

.next-index {
  color: var(--terracotta);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

.next-action-copy {
  display: flex;
  min-inline-size: 0;
  flex-direction: column;
  gap: var(--space-sm);
}

.next-action-copy h3 {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 600;
  letter-spacing: -0.025em;
}

.next-action-copy > p {
  color: var(--ink-700);
}

.action-kicker {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
  color: var(--ink-700);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.next-action-footer {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-md);
  padding-block-start: var(--space-xs);
}

.next-action-footer > span {
  display: flex;
  align-items: flex-start;
  gap: var(--space-xs);
  color: var(--ink-700);
  font-size: var(--text-xs);
}

.next-action-footer > span svg {
  flex: 0 0 auto;
  inline-size: 1rem;
  block-size: 1rem;
  margin-block-start: 0.1rem;
}

/* Pricing */
/* Reusable "go back" affordance for secondary views (Pricing, Planning overview).
   The negative block-end margin trims the parent's large flex gap so it sits near
   the top instead of floating far above the content. */
.back-link {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  gap: var(--space-2xs);
  min-block-size: 2.75rem;
  margin-block-end: calc(var(--space-md) - var(--space-2xl));
  padding: 0.4rem 0.9rem 0.4rem 0.5rem;
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--ink-700);
  font-size: var(--text-sm);
  font-weight: 700;
  transition: color 150ms var(--ease-out), background-color 150ms var(--ease-out), transform 150ms var(--ease-out);
}

.back-link svg {
  inline-size: 1.15rem;
  block-size: 1.15rem;
}

@media (hover: hover) {
  .back-link:hover {
    color: var(--primary);
    background: var(--ink-075);
    transform: translateX(-2px);
  }
}

.pricing-shell {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xl);
  padding-block: var(--space-2xl) var(--space-4xl);
}

.pricing-intro {
  display: flex;
  max-inline-size: 48rem;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-md);
}

.pricing-intro h1 {
  max-inline-size: 13ch;
  font-size: clamp(2.5rem, 10vw, 4.3rem);
}

.pricing-intro > p:not(.eyebrow) {
  color: var(--ink-700);
  font-size: var(--text-lg);
}

.pricing-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-lg);
}

.pricing-card {
  display: flex;
  min-inline-size: 0;
  flex-direction: column;
  gap: var(--space-xl);
  padding: clamp(var(--space-lg), 5vw, var(--space-xl));
  border: 1px solid var(--ink-300);
  border-radius: var(--radius-lg);
  background: var(--paper-raised);
}

.pricing-card-premium {
  border-color: var(--primary);
}

.pricing-card-topline {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-md);
}

.pricing-card h2 {
  font-size: var(--text-xl);
  line-height: 1.2;
}

.pricing-card h2:focus {
  outline: none;
}

.pricing-chip {
  flex: 0 0 auto;
  background: var(--primary);
  color: var(--paper-raised);
  letter-spacing: 0;
  text-transform: none;
}

.pricing-card-header {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.pricing-price {
  color: var(--ink-950);
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1;
}

.pricing-price-note {
  color: var(--ink-700);
  font-size: var(--text-sm);
  font-weight: 700;
}

.pricing-tagline {
  color: var(--ink-700);
}

.pricing-tagline strong {
  color: var(--ink-850);
}

.pricing-feature-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  padding: 0;
  list-style: none;
}

.pricing-feature-list li {
  display: grid;
  grid-template-columns: 1.25rem minmax(0, 1fr);
  align-items: start;
  gap: var(--space-sm);
  color: var(--ink-850);
}

.pricing-feature-list svg {
  inline-size: 1.15rem;
  block-size: 1.15rem;
  margin-block-start: 0.15rem;
  color: var(--moss);
  stroke-width: 2.4;
}

/* Compact feature list reused on the dashboard upsell and the checkout dialog. */
.premium-feature-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  margin: 0;
  padding: 0;
  list-style: none;
}

.premium-feature-list li {
  display: grid;
  grid-template-columns: 1.15rem minmax(0, 1fr);
  align-items: start;
  gap: var(--space-sm);
  color: var(--ink-850);
  font-size: var(--text-sm);
  line-height: 1.4;
}

.premium-feature-list svg {
  inline-size: 1.05rem;
  block-size: 1.05rem;
  margin-block-start: 0.12rem;
  color: var(--moss);
  stroke-width: 2.4;
}

.pricing-cta,
.premium-unlocked-state {
  inline-size: 100%;
  min-block-size: 2.75rem;
  margin-block-start: auto;
}

.premium-unlocked-state {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  padding: 0.7rem 1rem;
  border: 1px solid var(--moss);
  border-radius: var(--radius-pill);
  background: var(--moss-soft);
  color: oklch(34% 0.07 151);
  font-weight: 700;
}

.premium-unlocked-state svg {
  inline-size: 1rem;
  block-size: 1rem;
  stroke-width: 2.4;
}

.pricing-footnote {
  max-inline-size: 62ch;
  color: var(--ink-700);
  font-size: var(--text-sm);
}

.premium-panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
  margin-block-start: var(--space-2xl);
  padding: clamp(var(--space-lg), 4vw, var(--space-xl));
  border: 1px solid var(--ink-150);
  border-radius: var(--radius-lg);
  background: var(--paper-raised);
}

.premium-unlocked {
  border-color: color-mix(in oklch, var(--moss) 30%, var(--ink-150));
  background: color-mix(in oklch, var(--moss-soft) 62%, var(--paper-raised));
}

.premium-panel-heading {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-md);
}

.premium-panel-heading > div {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.premium-panel h3 {
  max-inline-size: 28ch;
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 600;
  letter-spacing: -0.025em;
}

.premium-panel h3:focus {
  outline: none;
}

.premium-panel > p {
  color: var(--ink-700);
}

.premium-panel .status svg {
  inline-size: 0.85rem;
  block-size: 0.85rem;
}






.plan-download-button {
  min-block-size: 3rem;
}


.premium-dialog-notes {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm) var(--space-lg);
  padding: 0;
  list-style: none;
}

.premium-dialog-notes li {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  color: var(--ink-850);
  font-size: var(--text-sm);
  font-weight: 700;
}

.premium-dialog-notes svg {
  flex: 0 0 auto;
  inline-size: 1rem;
  block-size: 1rem;
  color: var(--moss);
}


.premium-tool-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
  gap: var(--space-sm);
}

.premium-tool-list .secondary-button {
  inline-size: 100%;
  min-block-size: 2.75rem;
  justify-content: flex-start;
  text-align: start;
}

.premium-tool-list .plan-download-button {
  inline-size: 100%;
  justify-content: flex-start;
  text-align: start;
}

/* Partner sharing (feature 003). At rest the panel carries one row: the entry point when sharing is
   off, the standing state plus the off switch when it is on. Everything else lives in the dialog. */
.premium-panel-sub {
  margin: 0;
  color: var(--ink-700);
  font-size: var(--text-sm);
}

.premium-tool-list svg {
  flex: 0 0 auto;
  inline-size: 1.15rem;
  block-size: 1.15rem;
}

.share-row {
  margin-block-start: var(--space-lg);
  padding-block-start: var(--space-lg);
  border-block-start: 1px solid var(--ink-150);
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.share-row p { margin: 0; color: var(--ink-700); }
.share-row-state { color: var(--ink-850); }
.share-note { font-size: var(--text-sm); }

.share-entry {
  align-self: flex-start;
  min-block-size: 2.75rem;
}

.share-entry svg {
  inline-size: 1.15rem;
  block-size: 1.15rem;
}

.share-row-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-md);
}

/* Text buttons sit at the AA target floor otherwise; give them room to be hit on a phone. */
.share-row-actions .text-button,
.share-dialog .text-button {
  min-block-size: 2.75rem;
  min-inline-size: 3rem;
}

/* The live token is printed only inside the dialog, never on the resting page. */
.share-link {
  overflow-wrap: anywhere;
  padding: var(--space-sm);
  border-radius: var(--radius-sm);
  background: var(--paper-deep);
}

.share-link code { font-size: var(--text-sm); color: var(--ink-850); }

.share-dialog-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
}

/* One rhythm for the whole dialog body, so nothing ever sits glued to the control below it. */
#share-dialog-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

#share-dialog-body p { margin: 0; }

/* The email route sits under the primary copy action, separated by a rule. */
.share-dialog .share-invite {
  gap: var(--space-xs);
  padding-block-start: var(--space-lg);
  border-block-start: 1px solid var(--ink-150);
}

.share-dialog .share-invite label { font-weight: 600; color: var(--ink-850); }

.share-invite-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
}

.share-invite-row input { flex: 1 1 12rem; }

/* Always a column: the label sits above its field, both starting at the left edge like every other
   block in the dialog. (An early version turned this into a row above 34rem, which pushed the whole
   email block to the right.) */
.share-invite {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-sm);
}

/* Share status message: green for success, terracotta for anything that failed. */
.share-status {
  display: block;
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-md);
  background: var(--moss-soft);
}

.share-status[hidden] { display: none; }
.share-status-warn { background: var(--terracotta-soft); }
.share-status p { margin: 0; color: var(--ink-850); font-size: var(--text-sm); }

.key-dates-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.key-dates-title {
  color: var(--ink-950);
  font-size: var(--text-sm);
  font-weight: 700;
}

.key-dates-dl {
  display: flex;
  flex-direction: column;
  margin: 0;
  border-block-start: 1px solid var(--ink-150);
}

.key-dates-dl > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-sm);
  min-block-size: 2.75rem;
  padding-block: var(--space-xs);
  border-block-end: 1px solid var(--ink-150);
}

.key-dates-dl dt {
  color: var(--ink-700);
  font-size: var(--text-sm);
}

.key-dates-dl dd {
  display: flex;
  align-items: baseline;
  gap: var(--space-sm);
  margin: 0;
  text-align: end;
}

.kd-value {
  color: var(--ink-950);
  font-size: var(--text-sm);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.kd-value.is-empty {
  color: var(--ink-500);
  font-weight: 600;
}

.kd-edit {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  min-block-size: 24px;
  padding: 0 var(--space-2xs);
  border: 0;
  background: transparent;
  color: var(--primary);
  font-size: var(--text-xs);
  font-weight: 700;
}

@media (hover: hover) {
  .kd-edit:hover {
    color: var(--primary-hover);
    text-decoration: underline;
    text-underline-offset: 0.2em;
  }
}

.deadline-date {
  color: var(--primary);
  font-weight: 700;
}

/* Inline "Add date" affordance shown in place of a deadline that depends on a date the
   user hasn't entered yet. Opens the same editor as the Key dates panel. */
.deadline-add {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  min-block-size: 1.9rem;
  padding: 0.1rem 0.6rem;
  border: 1px solid var(--primary);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--primary);
  font-size: var(--text-xs);
  font-weight: 700;
  line-height: 1.2;
  vertical-align: middle;
  transition: background-color 150ms var(--ease-toggle), color 150ms var(--ease-toggle);
}

.next-action-footer .deadline-add svg,
.deadline-row .deadline-add svg {
  flex: 0 0 auto;
  margin-block-start: 0;
  inline-size: 0.9rem;
  block-size: 0.9rem;
}

@media (hover: hover) {
  .deadline-add:hover {
    background: var(--primary);
    color: var(--paper-raised);
  }
}

.printable-plan {
  display: none;
}

.premium-dev-panel {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-sm);
  padding: var(--space-md);
  border: 1px solid color-mix(in oklch, var(--amber) 35%, var(--ink-150));
  border-radius: var(--radius-md);
  background: var(--amber-soft);
}

.premium-dev-panel h3 {
  font-size: var(--text-base);
}

.premium-dev-panel code {
  font-family: inherit;
  font-weight: 700;
}

.premium-dev-panel small {
  color: var(--ink-700);
}

.premium-dev-status {
  display: flex;
  inline-size: 100%;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-md);
  color: var(--ink-700);
  font-size: var(--text-xs);
}

.premium-dev-status strong {
  color: var(--ink-950);
}

.premium-dialog {
  overflow: auto;
  inline-size: min(calc(100% - 2rem), 35rem);
  max-block-size: min(90dvh, 44rem);
  padding: 0;
  border: 1px solid var(--ink-300);
  border-radius: var(--radius-lg);
  background: var(--paper-raised);
  color: var(--ink-950);
  box-shadow: 0 1.5rem 4rem oklch(23% 0.018 160 / 0.22);
}

.premium-dialog::backdrop {
  background: oklch(23% 0.018 160 / 0.58);
}

.premium-dialog-inner {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
  padding: clamp(var(--space-lg), 5vw, var(--space-xl));
}

.premium-dialog-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-md);
}

.premium-dialog-header > div {
  display: flex;
  min-inline-size: 0;
  flex-direction: column;
  gap: var(--space-sm);
}

.premium-dialog-header h2 {
  font-size: var(--text-2xl);
}

.premium-dialog-inner > p {
  color: var(--ink-700);
}

.premium-dialog form {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

/* Feedback trigger. Mobile: floating dot with "?"; desktop: right-edge "Feedback" tab. */
.feedback-trigger {
  position: fixed;
  z-index: 40;
  inset-block-end: max(var(--space-lg), env(safe-area-inset-bottom));
  inset-inline-end: var(--space-lg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 3.25rem;
  block-size: 3.25rem;
  border: 1px solid var(--primary-hover);
  border-radius: 50%;
  background: var(--primary);
  color: var(--paper-raised);
  font-size: var(--text-xl);
  font-weight: 700;
  line-height: 1;
  box-shadow: 0 0.5rem 1.5rem oklch(23% 0.018 160 / 0.2);
  cursor: pointer;
  transition: background-color 160ms var(--ease-out), transform 160ms var(--ease-out);
}

.feedback-trigger-label {
  display: none;
}

@media (hover: hover) {
  .feedback-trigger:hover {
    background: var(--primary-hover);
  }
}

@media (min-width: 40rem) {
  .feedback-trigger {
    /* Physical props here on purpose: writing-mode: vertical-rl remaps the logical
       inset/border properties, which would push the tab to the centre. Anchored to the
       lower-right so it clears the vertically-centred dashboard sidebar controls. */
    inset: auto;
    bottom: 3.5rem;
    right: 0;
    inline-size: auto;
    block-size: auto;
    padding: var(--space-md) var(--space-xs);
    border-right: 0;
    border-radius: var(--radius-md) 0 0 var(--radius-md);
    writing-mode: vertical-rl;
    transform: none;
    font-size: var(--text-sm);
    letter-spacing: 0.03em;
  }

  .feedback-trigger-label {
    display: inline;
  }

  .feedback-trigger-icon {
    display: none;
  }

  .feedback-trigger:hover {
    transform: translateX(-2px);
  }
}

/* Feedback dialog */
.feedback-dialog {
  overflow: auto;
  inline-size: min(calc(100% - 2rem), 32rem);
  max-block-size: min(90dvh, 44rem);
  padding: 0;
  border: 1px solid var(--ink-300);
  border-radius: var(--radius-lg);
  background: var(--paper-raised);
  color: var(--ink-950);
  box-shadow: 0 1.5rem 4rem oklch(23% 0.018 160 / 0.22);
}

.feedback-dialog::backdrop {
  background: oklch(23% 0.018 160 / 0.58);
}

.feedback-dialog-inner {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
  padding: clamp(var(--space-lg), 5vw, var(--space-xl));
}

.feedback-dialog-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-md);
}

.feedback-dialog-header > div {
  display: flex;
  min-inline-size: 0;
  flex-direction: column;
  gap: var(--space-xs);
}

.feedback-dialog-header h2 {
  font-size: var(--text-2xl);
}

.feedback-dialog-header p {
  color: var(--ink-700);
  font-size: var(--text-sm);
  line-height: 1.45;
}

.feedback-dialog form {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.feedback-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.feedback-field label {
  color: var(--ink-850);
  font-size: var(--text-sm);
  font-weight: 700;
}

.feedback-field label span {
  color: var(--ink-700);
  font-weight: 600;
}

/* Base field styling (size, border, focus) comes from the shared
   input/textarea/select rules; only the multi-line specifics live here. */
.feedback-dialog textarea {
  min-block-size: 6.5rem;
  font-weight: 400;
  line-height: 1.5;
  resize: vertical;
}

.feedback-note {
  color: var(--ink-700);
  font-size: var(--text-xs);
}

/* Honest post-submit hand-off (mailto can't confirm delivery). */
.feedback-handoff {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.feedback-handoff > p {
  color: var(--ink-700);
  font-size: var(--text-sm);
}

.feedback-handoff-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
}

.feedback-handoff-actions .primary-button,
.feedback-handoff-actions .secondary-button {
  flex: 1 1 auto;
  justify-content: center;
}

/* Honeypot: hidden from people and assistive tech, but present in the DOM so bots
   fill it; a filled value marks the submission as spam. Not display:none, which some
   bots skip. */
.feedback-hp {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.premium-price {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-lg);
  padding-block: var(--space-lg);
  border-block: 1px solid var(--ink-150);
}

.premium-price > span {
  max-inline-size: 18ch;
  color: var(--ink-700);
  font-size: var(--text-sm);
}

.premium-price strong {
  display: flex;
  flex: 0 0 auto;
  flex-direction: column;
  align-items: flex-end;
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

.premium-price small {
  color: var(--ink-700);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 600;
}

.premium-dialog-notes {
  flex-direction: column;
}

.status {
  display: inline-flex;
  inline-size: fit-content;
  align-items: center;
  min-block-size: 1.65rem;
  padding-inline: 0.6rem;
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* Priority ladder for status badges: overdue (loudest) → ready → waiting → done.
   Informational states (good-to-know / special route) stay calm and neutral. */
.status-overdue { background: var(--danger-soft); color: oklch(45% 0.16 25); }
.status-ready   { background: var(--terracotta-soft); color: oklch(40% 0.12 42); }
.status-waiting { background: var(--ink-075); color: var(--ink-700); }
.status-done    { background: var(--moss-soft); color: oklch(34% 0.07 151); }
.status-info    { background: var(--amber-soft); color: oklch(39% 0.08 84); }
.status-route   { background: var(--ink-075); color: var(--ink-700); }
/* Retained for the Premium lock badge, which hard-codes status-blocked. */
.status-blocked { background: var(--ink-075); color: var(--ink-700); }

.complete-state,
.journey-empty {
  display: flex;
  align-items: flex-start;
  gap: var(--space-md);
  padding: var(--space-xl);
  border: 1px solid var(--ink-150);
  border-radius: var(--radius-lg);
  background: var(--paper-raised);
}

.complete-state > svg {
  flex: 0 0 auto;
  inline-size: 2rem;
  block-size: 2rem;
  color: var(--moss);
}

.complete-state div,
.journey-empty {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.complete-state p,
.journey-empty p {
  color: var(--ink-700);
}

.journey-heading-row {
  gap: var(--space-lg);
}

.filter-group {
  display: flex;
  inline-size: fit-content;
  gap: var(--space-2xs);
  padding: var(--space-2xs);
  border: 1px solid var(--ink-150);
  border-radius: var(--radius-pill);
  background: var(--paper-deep);
}

.filter-group button {
  min-block-size: 2.75rem;
  padding-inline: var(--space-md);
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--ink-700);
  font-size: var(--text-sm);
  font-weight: 700;
}

.filter-group button[aria-pressed="true"] {
  background: var(--paper-raised);
  color: var(--ink-950);
  box-shadow: 0 1px 3px oklch(25% 0.03 327 / 0.1);
}

.journey-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xl);
}

.stage-group {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-md);
}

.stage-label {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.stage-label > span {
  display: block;
  inline-size: 0.65rem;
  block-size: 0.65rem;
  border-radius: 50%;
  background: var(--terracotta);
}

.stage-label h3 {
  color: var(--ink-700);
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.stage-label small {
  display: grid;
  inline-size: 1.6rem;
  block-size: 1.6rem;
  place-items: center;
  border: 1px solid var(--ink-150);
  border-radius: 50%;
  color: var(--ink-700);
  font-size: var(--text-xs);
}

.stage-actions {
  position: relative;
  display: flex;
  flex-direction: column;
}

.stage-actions::before {
  content: '';
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0.55rem;
  inline-size: 1px;
  background: var(--ink-300);
}

.journey-action {
  position: relative;
  display: grid;
  grid-template-columns: 1.2rem 1fr;
  gap: var(--space-md);
  padding-block-end: var(--space-md);
  /* When "View this step" scrolls here, leave a little air above the title instead of butting it
     against the top of the viewport. */
  scroll-margin-block-start: var(--space-xl);
}

.journey-node {
  position: relative;
  z-index: 1;
  display: grid;
  inline-size: 1.15rem;
  block-size: 1.15rem;
  place-items: center;
  margin-block-start: 1.45rem;
  border: 2px solid var(--paper);
  border-radius: 50%;
  background: var(--ink-300);
  color: var(--paper-raised);
  box-shadow: 0 0 0 1px var(--ink-300);
}

.journey-node svg {
  inline-size: 0.7rem;
  block-size: 0.7rem;
  stroke-width: 2.5;
}

.journey-action.is-done .journey-node {
  background: var(--moss);
  box-shadow: 0 0 0 1px var(--moss);
}

.journey-action > details {
  min-inline-size: 0;
  border-block-end: 1px solid var(--ink-150);
}

.journey-action > details > summary {
  display: flex;
  min-block-size: 4.5rem;
  flex-direction: column;
  gap: var(--space-sm);
  padding-block: var(--space-md) var(--space-lg);
  list-style: none;
}

.journey-action > details > summary > p {
  color: var(--ink-700);
  font-size: var(--text-sm);
}

.action-title-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-md);
}

.action-title-row > div {
  display: flex;
  min-inline-size: 0;
  flex-direction: column;
  gap: var(--space-xs);
}

.action-title-row h4 {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
  letter-spacing: -0.02em;
}

.summary-chevron {
  display: grid;
  flex: 0 0 auto;
  inline-size: 2.75rem;
  block-size: 2.75rem;
  place-items: center;
  border: 1px solid var(--ink-150);
  border-radius: 50%;
  transition: transform 240ms var(--ease-toggle), background-color 150ms var(--ease-toggle);
}

.journey-action details[open] .summary-chevron {
  background: var(--paper-deep);
  transform: rotate(180deg);
}

.blocked-note {
  display: flex;
  align-items: flex-start;
  gap: var(--space-xs);
  color: oklch(39% 0.08 84);
  font-size: var(--text-xs);
  font-weight: 700;
}

.blocked-note svg {
  flex: 0 0 auto;
  inline-size: 1rem;
  block-size: 1rem;
}

.action-details {
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
  padding: var(--space-sm) 0 var(--space-xl);
}

/* Each detail section is a labelled surface with a small role icon, so the card
   reads as organised blocks (context / timing / do / outcome) rather than flat text. */
.detail-box {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  padding: var(--space-md);
  border-radius: var(--radius-md);
}

.detail-head {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

.detail-head svg {
  flex: 0 0 auto;
  inline-size: 1.05rem;
  block-size: 1.05rem;
}

.detail-head strong,
.detail-head h5 {
  margin: 0;
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 0.01em;
}

.deadline-row p {
  font-size: var(--text-sm);
  line-height: 1.5;
}

/* Timing: soft amber "time" callout; the concrete date stays the green accent */
.deadline-row {
  background: var(--amber-soft);
}

.deadline-row .detail-head svg,
.deadline-row .detail-head strong {
  color: oklch(40% 0.075 74);
}

.deadline-row p {
  color: oklch(38% 0.05 78);
}

/* What to do: the focal, framed surface */
.steps-block {
  gap: var(--space-md);
  padding: var(--space-lg);
  border: 1px solid var(--ink-150);
  background: var(--paper-raised);
}

.steps-block .detail-head svg {
  color: var(--terracotta-deep);
}

.steps-block ol {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  margin: 0;
  padding-inline-start: 1.5rem;
}

.steps-block li {
  padding-inline-start: var(--space-xs);
  color: var(--ink-850);
  line-height: 1.5;
}

.steps-block li::marker {
  color: var(--terracotta-deep);
  font-family: var(--font-display);
  font-weight: 700;
}

/* Premium step-by-step walkthrough (unlocked) */
.walkthrough {
  gap: var(--space-md);
  padding: var(--space-lg);
  border: 1px solid color-mix(in oklch, var(--primary) 32%, var(--ink-150));
  background: color-mix(in oklch, var(--moss-soft) 55%, var(--paper-raised));
}

.walkthrough .detail-head svg {
  color: var(--primary);
}

/* The Premium badge: warm ochre against the green surfaces, so it reads as a label on the card
   rather than another piece of the card. Ink text, not white, for contrast on a pale ground. */
.premium-tag {
  flex: 0 0 auto;
  margin-inline-start: auto;
  padding: 0.15rem 0.55rem;
  border: 1px solid color-mix(in oklch, var(--amber) 55%, transparent);
  border-radius: var(--radius-pill);
  background: var(--amber-soft);
  color: var(--ink-950);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
}

.walk-where {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.walk-where > span,
.walk-col > span {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--ink-950);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.walk-col > span svg {
  flex: 0 0 auto;
  inline-size: 0.95rem;
  block-size: 0.95rem;
  color: var(--primary);
}

.walk-where p,
.walk-col p {
  color: var(--ink-850);
  font-size: var(--text-sm);
  line-height: 1.5;
}

.walk-steps {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  margin: 0;
  padding-inline-start: 1.5rem;
}

.walk-steps li {
  padding-inline-start: var(--space-2xs);
  color: var(--ink-850);
  line-height: 1.5;
}

.walk-steps li::marker {
  color: var(--primary);
  font-weight: 700;
}

.walk-grid {
  display: grid;
  gap: var(--space-md);
}

.walk-col {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.walk-col ul {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  margin: 0;
  padding-inline-start: 1.1rem;
  color: var(--ink-850);
  font-size: var(--text-sm);
}

.walk-warn {
  display: flex;
  align-items: flex-start;
  gap: var(--space-xs);
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-sm);
  background: var(--amber-soft);
  color: oklch(38% 0.05 78);
  font-size: var(--text-sm);
  line-height: 1.45;
}

.walk-warn svg {
  flex: 0 0 auto;
  inline-size: 1.05rem;
  block-size: 1.05rem;
  margin-block-start: 0.1rem;
  color: oklch(45% 0.09 74);
}

@media (min-width: 40rem) {
  .walk-grid {
    grid-template-columns: 1fr 1fr;
  }
}

/* Premium walkthrough teaser (locked, free users) */
.walkthrough-locked {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  padding: var(--space-lg);
  border: 1px dashed color-mix(in oklch, var(--primary) 35%, var(--ink-300));
  border-radius: var(--radius-md);
  background: var(--ink-075);
}

.walkthrough-locked .detail-head svg {
  color: var(--primary);
}

.walkthrough-locked p {
  color: var(--ink-700);
  font-size: var(--text-sm);
  line-height: 1.5;
}

.walkthrough-locked .secondary-button {
  align-self: flex-start;
}

/* Premium employer-letter tool */
/* Every unlocked Premium block wears the same surface, so Premium is recognisable at a glance
   rather than looking like three unrelated cards. Matches .walkthrough above. */
.letter-cta,
.premium-cta {
  gap: var(--space-md);
  padding: var(--space-lg);
  border: 1px solid color-mix(in oklch, var(--primary) 32%, var(--ink-150));
  background: color-mix(in oklch, var(--moss-soft) 55%, var(--paper-raised));
}

.letter-cta .detail-head svg,
.premium-cta .detail-head svg {
  color: var(--primary);
}

.letter-cta p,
.premium-cta p {
  color: var(--ink-700);
  font-size: var(--text-sm);
  line-height: 1.5;
}

.letter-cta .secondary-button,
.premium-cta .secondary-button {
  align-self: flex-start;
}

/* Inside the dialog the walkthrough is the whole content, so it drops its card surface and lets
   the dialog provide the frame. It also needs its own layout: the card version got display:flex
   from .detail-box, and without it every section sat glued to the next. */
.walkthrough-in-dialog {
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
  padding: 0;
  border: 0;
  background: transparent;
}

/* Reading a route is a task in itself, so the numbered steps get more air than in the card. */
.walkthrough-in-dialog .walk-steps {
  gap: var(--space-md);
  padding-inline-start: 1.75rem;
}

.walkthrough-in-dialog .walk-steps li {
  padding-inline-start: var(--space-xs);
  font-size: var(--text-sm);
}

/* What to bring and what to expect are reference, not narrative: a rule sets them apart. */
.walkthrough-in-dialog .walk-grid {
  gap: var(--space-xl);
  padding-block-start: var(--space-lg);
  border-block-start: 1px solid var(--ink-150);
}

/* Give each label room above its content, and lift it off the block before it. */
.walkthrough-in-dialog .walk-where,
.walkthrough-in-dialog .walk-col {
  gap: var(--space-sm);
}

.letter-preview {
  max-block-size: 42vh;
  overflow-y: auto;
  padding: var(--space-md);
  border: 1px solid var(--ink-150);
  border-radius: var(--radius-md);
  background: var(--paper);
  color: var(--ink-850);
  font-size: var(--text-sm);
  line-height: 1.6;
  white-space: pre-wrap;
}

/* Collapsed context (Why / What happens next / Important exceptions): free, but
   tucked away by default so the step leads with the actionable essentials. */
.detail-more {
  display: flex;
  flex-direction: column;
}

.detail-collapse {
  border-block-start: 1px solid var(--ink-150);
}

.detail-collapse:last-child {
  border-block-end: 1px solid var(--ink-150);
}

.detail-collapse > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  min-block-size: 3rem;
  padding-block: var(--space-sm);
  color: var(--ink-950);
  font-size: var(--text-sm);
  font-weight: 700;
  list-style: none;
  transition: color 150ms var(--ease-out);
}

.detail-collapse > summary::-webkit-details-marker {
  display: none;
}

.detail-collapse > summary svg {
  flex: 0 0 auto;
  inline-size: 1.25rem;
  block-size: 1.25rem;
  color: var(--ink-500);
  transition: transform 200ms var(--ease-out), color 150ms var(--ease-out);
}

.detail-collapse[open] > summary svg {
  transform: rotate(180deg);
}

@media (hover: hover) {
  .detail-collapse > summary:hover,
  .detail-collapse > summary:hover svg {
    color: var(--terracotta-deep);
  }
}

.detail-collapse-body {
  padding-block: 0 var(--space-md);
}

.detail-collapse-body p {
  color: var(--ink-700);
  font-size: var(--text-sm);
  line-height: 1.5;
}

.detail-collapse-body ul {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  margin: 0;
  padding: 0 0 0 1.25rem;
  color: var(--ink-700);
  font-size: var(--text-sm);
  line-height: 1.5;
}

/* Sub-headings inside the single "More about this step" drawer. These used to be three separate
   collapsibles, so their labels were summary rows; inside one drawer they need to stay
   distinguishable from the body text without shouting, hence small caps-ish weight rather than size. */
.detail-more-heading {
  margin-block: var(--space-md) var(--space-2xs);
  color: var(--ink-850);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.detail-more-heading:first-child {
  margin-block-start: 0;
}

/* Inline glossary marker: a small info button that sits right after a complex word.
   Click opens an anchored popover with the plain-English explanation. */
.term-inline {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  vertical-align: text-top;
  inline-size: 1.15em;
  block-size: 1.15em;
  margin-inline-start: 0.15em;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  /* terracotta-deep, not terracotta: the icon is the only visual cue for a glossary term, so it is
     a non-text UI component and needs 3:1. Plain --terracotta measures 2.9:1 on paper; the deep
     variant is 5.7:1. */
  color: var(--terracotta-deep);
  line-height: 0;
  transition: color 140ms var(--ease-out), transform 140ms var(--ease-out);
}

.term-inline svg {
  inline-size: 1.15em;
  block-size: 1.15em;
}

@media (hover: hover) {
  .term-inline:hover {
    color: var(--primary);
    transform: translateY(-1px);
  }
}

/* Larger tap area on touch devices without growing the visual glyph (WCAG 2.5.8). */
@media (pointer: coarse) {
  .term-inline {
    inline-size: 1.6em;
    block-size: 1.6em;
  }
}

/* Fallback line for terms that only appear in the action title. */
.term-leftovers {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xs);
  margin-block-start: var(--space-xs);
  color: var(--ink-700);
  font-size: var(--text-sm);
}

.term-leftovers-label {
  margin-inline-end: var(--space-2xs);
  font-weight: 700;
}

.term-leftover {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  min-block-size: 2.25rem;
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--ink-300);
  border-radius: var(--radius-pill);
  background: var(--paper-raised);
  color: var(--ink-700);
  font-size: var(--text-sm);
  font-weight: 700;
  transition: border-color 160ms var(--ease-toggle), color 160ms var(--ease-toggle);
}

.term-leftover svg {
  inline-size: 0.95rem;
  block-size: 0.95rem;
  color: var(--terracotta-deep);
}

@media (hover: hover) {
  .term-leftover:hover {
    border-color: var(--primary);
    color: var(--primary);
  }

  .term-leftover:hover svg {
    color: var(--primary);
  }
}

/* Anchored term popover: placed in the top layer by the Popover API, so it escapes
   the journey list's clipping and light-dismisses on outside click / Escape.
   position/left/top are set from JS (positionTermPopover). */
.term-popover {
  position: fixed;
  inset: auto;
  margin: 0;
  inline-size: min(22rem, calc(100vw - 20px));
  max-block-size: min(26rem, calc(100vh - 20px));
  overflow-y: auto;
  padding: var(--space-lg);
  border: 1px solid var(--ink-150);
  border-radius: var(--radius-md);
  background: var(--paper-raised);
  color: var(--ink-850);
  box-shadow: 0 12px 32px oklch(23% 0.018 160 / 0.18);
}

.term-popover:popover-open {
  animation: reveal 180ms var(--ease-out) both;
}

.term-pop-inner {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.term-pop-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-sm);
}

.term-pop-head h6 {
  margin: 0;
  color: var(--ink-950);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

.term-pop-head h6:focus {
  outline: none;
}

.term-pop-close {
  display: grid;
  flex: 0 0 auto;
  inline-size: 2rem;
  block-size: 2rem;
  place-items: center;
  padding: 0;
  border: 1px solid var(--ink-300);
  border-radius: 50%;
  background: transparent;
  color: var(--ink-700);
}

.term-pop-close svg {
  inline-size: 0.9rem;
  block-size: 0.9rem;
}

.term-pop-def {
  color: var(--ink-850);
  font-size: var(--text-sm);
  line-height: 1.55;
}

.term-pop-where {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.term-pop-where > span {
  color: var(--ink-950);
  font-size: var(--text-xs);
  font-weight: 850;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.term-pop-where p {
  color: var(--ink-700);
  font-size: var(--text-sm);
}

.term-pop-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  min-block-size: 2.5rem;
  color: var(--primary);
  font-size: var(--text-sm);
  font-weight: 850;
  text-underline-offset: 0.2em;
}

.term-pop-link svg {
  inline-size: 1rem;
  block-size: 1rem;
}

.term-pop-source {
  color: var(--ink-500);
  font-size: var(--text-xs);
}

.source-row {
  display: grid;
  gap: var(--space-md);
  padding-block-start: var(--space-md);
  border-block-start: 1px solid var(--ink-150);
}

.source-row > div {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.source-row span,
.source-row small {
  color: var(--ink-700);
  font-size: var(--text-xs);
}

.source-row a {
  display: inline-flex;
  min-block-size: 2.75rem;
  align-items: center;
  gap: var(--space-xs);
  color: var(--primary);
  font-size: var(--text-sm);
  font-weight: 700;
  text-underline-offset: 0.2em;
}

.source-row a svg {
  inline-size: 1rem;
  block-size: 1rem;
}

.journey-action.is-done > details > summary {
  opacity: 0.72;
}

.journey-action.is-done h4 {
  text-decoration: line-through;
  text-decoration-color: var(--ink-500);
  text-decoration-thickness: 1px;
}

.journey-sidebar {
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
  padding-block-start: var(--space-2xl);
  border-block-start: 1px solid var(--ink-300);
}

.summary-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.summary-topline {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-md);
  font-size: var(--text-sm);
  font-weight: 700;
}

.summary-topline strong {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-variant-numeric: tabular-nums;
}

progress {
  overflow: hidden;
  inline-size: 100%;
  block-size: 0.55rem;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--ink-150);
}

progress::-webkit-progress-bar {
  border-radius: inherit;
  background: var(--ink-150);
}

progress::-webkit-progress-value {
  border-radius: inherit;
  background: var(--moss);
}

progress::-moz-progress-bar {
  border-radius: inherit;
  background: var(--moss);
}

.summary-block p {
  color: var(--ink-700);
  font-size: var(--text-xs);
}

.summary-support-note {
  padding: var(--space-md);
  border-radius: var(--radius-md);
  background: var(--moss-soft);
}

.summary-support-note p {
  margin: 0;
  color: var(--ink-850);
  font-size: var(--text-sm);
}

.household-summary {
  display: flex;
  flex-direction: column;
  border-block: 1px solid var(--ink-150);
}

.household-summary > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-lg);
  padding-block: var(--space-sm);
  border-block-end: 1px solid var(--ink-150);
}

.household-summary > div:last-child {
  border-block-end: 0;
}

.household-summary dt {
  color: var(--ink-700);
  font-size: var(--text-sm);
}

.household-summary dd {
  text-align: end;
  font-size: var(--text-sm);
  font-weight: 700;
}




.delete-zone {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  padding-block-start: var(--space-md);
  border-block-start: 1px solid var(--ink-150);
}

.delete-zone p {
  color: var(--danger);
  font-size: var(--text-sm);
  font-weight: 700;
}

.delete-zone > div {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
}

.toast {
  position: fixed;
  z-index: 500;
  inset-inline: var(--space-md);
  inset-block-end: max(var(--space-md), env(safe-area-inset-bottom));
  max-inline-size: 26rem;
  margin-inline: auto;
  padding: var(--space-md) var(--space-lg);
  border-radius: var(--radius-pill);
  background: var(--ink-950);
  color: var(--paper-raised);
  font-size: var(--text-sm);
  font-weight: 700;
  text-align: center;
  opacity: 0;
  pointer-events: none;
  transform: translateY(1rem);
  transition: opacity 180ms var(--ease-out), transform 220ms var(--ease-out);
}

.toast.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.reveal {
  animation: reveal 600ms var(--ease-out) both;
}

.reveal-delay-1 {
  animation-delay: 80ms;
}

.reveal-delay-2 {
  animation-delay: 160ms;
}

.reveal-delay-3 {
  animation-delay: 240ms;
}

@keyframes reveal {
  from { opacity: 0; transform: translateY(0.7rem); }
  to { opacity: 1; transform: translateY(0); }
}

/* Reduced-motion alternative: opacity-only, no positional movement. */
@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@media (min-width: 40rem) {
  .jurisdiction {
    display: inline-flex;
  }

  .pricing-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: stretch;
  }


  .choice-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .choice-grid-stage {
    grid-template-columns: 1fr;
    max-inline-size: 34rem;
  }

  .planning-hero,
  .planning-hse-signpost,
  .planning-next-step {
    grid-template-columns: minmax(0, 1.1fr) minmax(16rem, 0.9fr);
  }

  .planning-now-list {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .planning-now-list > li {
    grid-template-columns: 1fr;
    align-content: start;
    padding-inline: var(--space-lg);
    border-block-end: 0;
  }

  .planning-now-list > li + li {
    border-inline-start: 1px solid var(--ink-300);
  }

  .planning-map-heading {
    flex-direction: row;
    align-items: end;
    justify-content: space-between;
  }

  .planning-next-step .primary-button {
    justify-self: end;
  }

  .choice-grid-compact {
    grid-template-columns: 1fr;
  }

  .account-field .segmented-field label {
    flex-basis: auto;
  }

  .date-field input,
  .select-field select {
    max-inline-size: 28rem;
  }

  .dashboard-hero {
    grid-template-columns: 1fr auto;
    align-items: end;
    gap: var(--space-3xl);
  }

  .date-stamp {
    align-items: flex-end;
    text-align: end;
  }

  .section-heading,
  .journey-heading-row {
    flex-direction: row;
    align-items: flex-end;
    justify-content: space-between;
  }

  .next-action {
    grid-template-columns: 3rem 1fr;
    gap: var(--space-lg);
    padding-block: var(--space-xl);
  }

  .next-action-footer {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }

  .source-row {
    grid-template-columns: 1fr auto;
    align-items: center;
  }

  .footer-top {
    flex-direction: row;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-2xl);
  }

  .footer-legal {
    flex-direction: column;
    align-items: flex-end;
    gap: var(--space-xs);
  }

  .footer-bottom {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
}

/* Policy links stay stacked vertically at every width, right-aligned on wider screens. */

@media (max-width: 34rem) {
  .site-header {
    flex-wrap: wrap;
    padding-block: var(--space-xs);
  }

  .header-meta {
    margin-inline-start: auto;
    /* Tighten the two controls so the wordmark, Guides and Edit answers stay on one row
       instead of wrapping the bar onto a second line. Both labels are kept: an icon-only
       or hidden-behind-a-menu nav costs more in clarity than the row costs in width. */
    gap: var(--space-2xs);
  }

  .header-meta .quiet-button {
    padding-inline: 0.6rem;
    font-size: var(--text-sm);
  }
}

@media (min-width: 56rem) {
  .onboarding-shell {
    grid-template-columns: 15rem minmax(0, 1fr);
    gap: clamp(3rem, 8vw, 7rem);
    padding-block: var(--space-3xl) var(--space-4xl);
  }

  .onboarding-progress {
    position: sticky;
    inset-block-start: var(--space-xl);
    align-self: start;
    min-block-size: 30rem;
  }

  .onboarding-progress > span,
  .onboarding-progress .progress-track {
    display: none;
  }

  .onboarding-progress ol {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
  }


  .dashboard-layout {
    grid-template-columns: minmax(0, 1fr) 18rem;
    align-items: start;
    gap: clamp(3rem, 6vw, 6rem);
  }

  /* Stacked on mobile; two blocks wide on desktop; never a horizontal scroll. */
  .planning-timeline {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-lg);
  }

  .journey-sidebar {
    position: sticky;
    inset-block-start: var(--space-xl);
    padding-block-start: 0;
    border-block-start: 0;
  }

  .stage-group {
    grid-template-columns: 9rem minmax(0, 1fr);
    gap: var(--space-xl);
  }

  .stage-label {
    align-self: start;
    padding-block-start: 1.25rem;
  }

  .stage-label > span {
    display: none;
  }
}

@media (min-width: 72rem) {
  .site-header,
  #app,
  .site-footer {
    inline-size: min(100% - 4rem, var(--page-max));
  }

  .dashboard-layout {
    grid-template-columns: minmax(0, 1fr) 20rem;
  }
}

@media (pointer: coarse) {
  .primary-button,
  .secondary-button,
  .quiet-button,
  .complete-button,
  .danger-button,
  .text-button {
    min-block-size: 3rem;
  }
}

/* ===== Consent (ePrivacy) ================================================
   Bottom-anchored, non-blocking banner (deliberately not a cookie wall, the
   site stays usable without a choice) plus a preferences dialog reachable any
   time from the footer. */
.consent-banner {
  position: fixed;
  z-index: 60; /* above the feedback trigger (40), below modal dialogs */
  inset-inline: 0;
  inset-block-end: 0;
  padding: var(--space-md) clamp(var(--space-md), 4vw, var(--space-xl));
  padding-block-end: max(var(--space-md), env(safe-area-inset-bottom));
  border-block-start: 1px solid var(--ink-150);
  background: var(--paper-raised);
  box-shadow: 0 -0.75rem 2.5rem oklch(23% 0.018 160 / 0.16);
  animation: consent-rise 320ms var(--ease-out) both;
}

@keyframes consent-rise {
  from { transform: translateY(1rem); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

.consent-banner-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-md) var(--space-xl);
  max-inline-size: var(--page-max);
  margin-inline: auto;
}

.consent-banner-copy {
  flex: 1 1 22rem;
  min-inline-size: 0;
}

.consent-banner-copy h2 {
  margin: 0 0 var(--space-2xs);
  font-size: var(--text-lg);
}

.consent-banner-copy p {
  margin: 0;
  max-inline-size: 60ch;
  color: var(--ink-700);
  font-size: var(--text-sm);
  line-height: 1.5;
}

.consent-policy-link {
  min-block-size: 0;
  font-size: inherit;
}

.consent-banner-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xs);
}

.consent-banner-actions .primary-button,
.consent-banner-actions .secondary-button {
  flex: 1 1 auto;
  padding-block: 0.65rem;
  white-space: nowrap;
}

/* Reject must be as easy and prominent as Accept: same size, solid fill, just a
   neutral hue so neither choice is visually nudged. */
.consent-reject {
  background: var(--ink-850);
  color: var(--paper-raised);
}

@media (hover: hover) {
  .consent-reject:hover {
    background: var(--ink-950);
  }
}

/* Preferences dialog */
.consent-prefs {
  overflow: auto;
  inline-size: min(calc(100% - 2rem), 34rem);
  max-block-size: min(90dvh, 46rem);
  padding: 0;
  border: 1px solid var(--ink-300);
  border-radius: var(--radius-lg);
  background: var(--paper-raised);
  color: var(--ink-950);
  box-shadow: 0 1.5rem 4rem oklch(23% 0.018 160 / 0.22);
}

.consent-prefs::backdrop {
  background: oklch(23% 0.018 160 / 0.58);
}

.consent-prefs-inner {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
  padding: clamp(var(--space-lg), 5vw, var(--space-xl));
}

.consent-prefs-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-md);
}

.consent-prefs-header h2 {
  margin: 0 0 var(--space-2xs);
  font-size: var(--text-xl);
}

.consent-prefs-header p {
  margin: 0;
  color: var(--ink-700);
  font-size: var(--text-sm);
}

.consent-prefs form {
  display: flex;
  flex-direction: column;
}

.consent-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-md);
  padding-block: var(--space-md);
  border-block-start: 1px solid var(--ink-150);
}

.consent-row:first-of-type {
  border-block-start: 0;
}

.consent-row-text {
  display: flex;
  min-inline-size: 0;
  flex-direction: column;
  gap: var(--space-2xs);
}

.consent-row-label {
  font-weight: 700;
}

.consent-row-detail {
  color: var(--ink-700);
  font-size: var(--text-sm);
  line-height: 1.45;
}

.consent-badge {
  display: inline-block;
  margin-inline-start: var(--space-2xs);
  padding: 0.05rem 0.5rem;
  border-radius: var(--radius-pill);
  background: var(--moss-soft);
  color: oklch(36% 0.06 152);
  font-size: var(--text-xs);
  font-weight: 700;
  vertical-align: middle;
}

.consent-locked-note {
  flex: none;
  color: var(--ink-500);
  font-size: var(--text-sm);
  font-weight: 600;
  white-space: nowrap;
}

.consent-empty {
  margin: 0;
  padding-block: var(--space-sm);
  color: var(--ink-700);
  font-size: var(--text-sm);
  line-height: 1.5;
}

.consent-switch {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: var(--space-xs);
  cursor: pointer;
}

.consent-switch input {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  opacity: 0;
}

.consent-switch-track {
  position: relative;
  display: inline-block;
  inline-size: 2.75rem;
  block-size: 1.6rem;
  border-radius: var(--radius-pill);
  background: var(--ink-300);
  transition: background-color 160ms var(--ease-toggle);
}

.consent-switch-track::after {
  content: "";
  position: absolute;
  inset-block-start: 0.2rem;
  inset-inline-start: 0.2rem;
  inline-size: 1.2rem;
  block-size: 1.2rem;
  border-radius: 50%;
  background: var(--paper-raised);
  box-shadow: 0 1px 2px oklch(23% 0.018 160 / 0.3);
  transition: transform 160ms var(--ease-toggle);
}

.consent-switch input:checked + .consent-switch-track {
  background: var(--primary);
}

.consent-switch input:checked + .consent-switch-track::after {
  transform: translateX(1.15rem);
}

.consent-switch input:focus-visible + .consent-switch-track {
  outline: 3px solid var(--terracotta-deep);
  outline-offset: 2px;
}

.consent-switch-text {
  color: var(--ink-700);
  font-size: var(--text-sm);
  font-weight: 600;
}

.consent-prefs-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin-block-start: var(--space-lg);
}

.consent-prefs-actions .secondary-button {
  flex: 1 1 8rem;
}

.consent-prefs-actions .primary-button {
  flex: 1 1 100%;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
    transition-duration: 0.01ms !important;
  }

  /* Section entrances keep a gentle opacity fade (no positional motion) rather than
     snapping in; an intentional reduced-motion alternative. */
  .reveal {
    animation: fade-in 240ms var(--ease-out) both !important;
  }
}

@media print {
  @page {
    margin: 14mm;
  }

  html,
  body {
    min-block-size: auto;
    margin: 0;
    padding: 0;
    background: #fff !important;
    color: #1e2622 !important;
    font-family: -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
    font-size: 10pt;
    line-height: 1.5;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  /* Only strip the page down when a printable plan was actually built. Otherwise (the
     planning route, or JS not running) let the page print as it is, rather than blank. */
  .has-printable-plan body > *:not(main),
  .has-printable-plan #app > *:not(.printable-plan) {
    display: none !important;
  }

  main,
  #app {
    display: block;
    inline-size: 100%;
    max-inline-size: none;
    min-block-size: auto;
    margin: 0;
  }

  .printable-plan {
    display: block !important;
  }

  .pp-doc {
    color: #1e2622;
  }

  .pp-doc *,
  .pp-doc *::before,
  .pp-doc *::after {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  /* Branded header band */
  .pp-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8mm;
    padding: 7mm 8mm;
    margin-block-end: 6mm;
    border-radius: 3mm;
    background: #2f6e5e;
    color: #f6f8f6;
  }

  .pp-brand {
    display: flex;
    align-items: center;
    gap: 3mm;
  }

  .pp-mark {
    display: grid;
    place-items: center;
    inline-size: 9mm;
    block-size: 9mm;
    border-radius: 2.4mm;
    background: #f6f8f6;
    color: #2f6e5e;
    font-family: Georgia, "Times New Roman", serif;
    font-size: 14pt;
    font-weight: 700;
  }

  .pp-word {
    font-family: Georgia, "Times New Roman", serif;
    font-size: 16pt;
    font-weight: 700;
    letter-spacing: -0.01em;
  }

  .pp-header-meta {
    text-align: right;
  }

  .pp-doc-title {
    margin: 0;
    font-family: Georgia, "Times New Roman", serif;
    font-size: 13pt;
    font-weight: 700;
  }

  .pp-doc-sub {
    margin: 1mm 0 0;
    font-size: 8.5pt;
    color: #dbe7e0;
  }

  .pp-intro {
    margin: 0 0 6mm;
    max-inline-size: none;
    color: #3c4a44;
    font-size: 9.5pt;
    line-height: 1.55;
  }

  /* Summary chips */
  .pp-summary {
    display: flex;
    flex-wrap: wrap;
    gap: 4mm;
    margin: 0 0 8mm;
    padding: 0;
  }

  .pp-summary div {
    flex: 1 1 34mm;
    min-inline-size: 34mm;
    padding: 3mm 4mm;
    border-radius: 2mm;
    background: #eaf1ec;
  }

  .pp-summary dt {
    margin: 0;
    color: #2f6e5e;
    font-size: 7.5pt;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
  }

  .pp-summary dd {
    margin: 1mm 0 0;
    color: #1e2622;
    font-size: 10.5pt;
    font-weight: 700;
  }

  /* Stage */
  .pp-stage {
    margin-block-start: 7mm;
  }

  .pp-stage:first-of-type {
    margin-block-start: 0;
  }

  .pp-stage-title {
    margin: 0 0 4mm;
    padding-block-end: 2mm;
    border-block-end: 0.6mm solid #2f6e5e;
    color: #2f6e5e;
    font-family: Georgia, "Times New Roman", serif;
    font-size: 15pt;
    font-weight: 700;
    letter-spacing: -0.01em;
    break-after: avoid;
  }

  /* Action card */
  .pp-action {
    break-inside: avoid;
    margin-block-end: 5mm;
    padding: 5mm;
    border: 0.3mm solid #d6ded8;
    border-radius: 2.5mm;
    background: #fff;
  }

  .pp-action-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 4mm;
    margin-block-end: 2mm;
  }

  .pp-action-head h3 {
    margin: 0;
    color: #1e2622;
    font-family: Georgia, "Times New Roman", serif;
    font-size: 12.5pt;
    line-height: 1.25;
  }

  .pp-badge {
    flex: 0 0 auto;
    padding: 0.8mm 2.4mm;
    border-radius: 999px;
    font-size: 7pt;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
  }

  .pp-badge-overdue {
    background: #f7dcd8;
    color: #8a2b21;
  }

  .pp-badge-ready {
    background: #f3e3d6;
    color: #8a4a24;
  }

  .pp-badge-waiting,
  .pp-badge-route {
    background: #eef0ee;
    color: #55635c;
  }

  .pp-badge-info {
    background: #f6e7cf;
    color: #8a5a16;
  }

  .pp-badge-done {
    background: #e2efe4;
    color: #2f6e5e;
  }

  .pp-summary-line {
    margin: 0 0 3mm;
    color: #3c4a44;
    font-size: 9.5pt;
  }

  .pp-label {
    display: block;
    margin-block-end: 1mm;
    color: #5c6a63;
    font-size: 7.5pt;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
  }

  .pp-why {
    margin-block: 3mm;
    padding: 2.5mm 3mm;
    border-radius: 2mm;
    background: #f6f1e9;
  }

  .pp-why p {
    margin: 0;
    color: #4a3f33;
    font-size: 9pt;
  }

  .pp-do {
    margin-block: 3mm;
  }

  .pp-do ol {
    margin: 0;
    padding-inline-start: 5mm;
  }

  .pp-do li {
    margin-block-start: 1.2mm;
    color: #1e2622;
    font-size: 9.5pt;
  }

  .pp-do li::marker {
    color: #d08159;
    font-weight: 700;
  }

  .pp-meta {
    display: grid;
    grid-template-columns: 34mm 1fr;
    gap: 5mm;
    margin-block: 3mm;
    padding: 3mm;
    border-radius: 2mm;
    background: #eaf1ec;
  }

  .pp-meta p {
    margin: 0;
    color: #1e2622;
    font-size: 9pt;
  }

  .pp-url {
    color: #2f6e5e;
    font-size: 8.5pt;
    word-break: break-all;
  }

  .pp-meta .pp-when-date {
    margin: 1mm 0 0;
    color: #2f6e5e;
    font-weight: 700;
    font-size: 8.5pt;
  }

  .pp-next,
  .pp-exceptions {
    margin-block-start: 3mm;
  }

  .pp-next p {
    margin: 0;
    color: #3c4a44;
    font-size: 9pt;
  }

  .pp-exceptions ul {
    margin: 0;
    padding-inline-start: 5mm;
  }

  .pp-exceptions li {
    margin-block-start: 1mm;
    color: #3c4a44;
    font-size: 9pt;
  }

  .pp-footer {
    margin-block-start: 8mm;
    padding-block-start: 4mm;
    border-block-start: 0.3mm solid #d6ded8;
  }

  .pp-footer p {
    margin: 0;
    color: #5c6a63;
    font-size: 8pt;
    line-height: 1.5;
  }

  .pp-doc a {
    color: #2f6e5e;
    text-decoration: none;
  }
}

@media (forced-colors: active) {
  .choice-indicator,
  .journey-node,
  .stage-label > span {
    forced-color-adjust: none;
  }
}
