/**
 * styles.css — the public site.
 *
 * One stylesheet for three pages: the landing page, the page Stripe returns a
 * buyer to, and the one it returns them to if they change their mind.
 *
 * ── The look, and the reasoning behind it ──────────────────────────────────
 *
 * The product's one idea is a *thread*: research is a line you follow, and the
 * thing ContextTab does is keep hold of it. So the site has a literal thread —
 * drawn down the page in SVG, drawn again in WebGL behind the hero, and used
 * as the accent on every heading. One idea, said three ways, is what a brand
 * is; a page of tastefully arranged grey boxes is not.
 *
 * Colour is a signature, not decoration. Three hues in a fixed order —
 * mint → violet → coral — always in that order, always the same gradient. The
 * demo's depth pips walk through them, so the palette teaches the hierarchy
 * rather than merely brightening it.
 *
 * Type carries the personality, because there is no webfont to carry it: a
 * very large, very tight system sans against one italic serif word. The serif
 * is doing all the work of looking like a person made this, and it costs
 * nothing to download.
 *
 * ── The constraints it is built inside ─────────────────────────────────────
 *
 * No inline styles anywhere: the CSP is `style-src 'self'`, which forbids them
 * outright. No webfont, no framework, no build step. Everything that moves
 * moves on `transform` and `opacity` only — never a property that triggers
 * layout — so the animation cannot cost a millisecond of Cumulative Layout
 * Shift, and the compositor can run it off the main thread.
 *
 * Dark by default, light when the machine asks for it.
 */

/* ══ Tokens ═══════════════════════════════════════════════════════════════ */

:root {
  /* The signature triad, always in this order. */
  --mint: #00e5a0;
  --violet: #7c5cff;
  --coral: #ff7a5a;
  --amber: #ffc24b;

  --thread: linear-gradient(104deg, var(--mint) 0%, var(--violet) 52%, var(--coral) 100%);

  --bg: #06080c;
  --bg-soft: #0d1117;
  --bg-lift: #141a22;
  --fg: #f2f5fa;
  --fg-dim: #a3adbe;
  --fg-faint: #6f7889;
  --line: rgba(255, 255, 255, 0.09);
  --line-strong: rgba(255, 255, 255, 0.18);

  --accent: var(--mint);
  --accent-ink: #05130b;
  --accent-soft: rgba(0, 229, 160, 0.13);
  --glow: 0 0 60px rgba(0, 229, 160, 0.22);

  --shadow: 0 30px 80px rgba(0, 0, 0, 0.55);
  --radius: 16px;

  --font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Inter, system-ui, sans-serif;
  --serif: ui-serif, 'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia, serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --ease: 260ms cubic-bezier(0.22, 0.61, 0.36, 1);

  color-scheme: dark;
}

@media (prefers-color-scheme: light) {
  :root {
    --mint: #00875a;
    --violet: #5b45cc;
    --coral: #d1503a;
    --amber: #a5730a;

    --bg: #fcfbf9;
    --bg-soft: #ffffff;
    --bg-lift: #f2f1ee;
    --fg: #0b0e14;
    --fg-dim: #4c5464;
    --fg-faint: #737b8a;
    --line: rgba(11, 14, 20, 0.11);
    --line-strong: rgba(11, 14, 20, 0.2);

    --accent: var(--mint);
    --accent-ink: #ffffff;
    --accent-soft: rgba(0, 135, 90, 0.10);
    --glow: 0 0 60px rgba(0, 135, 90, 0.14);

    --shadow: 0 24px 60px rgba(11, 14, 20, 0.13);
    color-scheme: light;
  }
}

* { box-sizing: border-box; }

/*
 * `hidden` has to win.
 *
 * The attribute is styled by the user agent as `display: none`, and any class
 * rule that sets `display` beats it — so `.eyebrow { display: inline-flex }`
 * silently made `<p class="eyebrow" hidden>` visible. That is exactly what
 * happened to "Nothing was charged" on the pricing page: the element's
 * `hidden` property was still true, so the test asserting it passed, while
 * every visitor saw a line about a payment they had not made.
 */
[hidden] { display: none !important; }

html { scroll-behavior: smooth; }

/*
 * Reduced motion is honoured as a *setting*, not as a stylistic afterthought.
 * The scripts check the same query and never start; this covers whatever CSS
 * would still have moved.
 */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font);
  font-size: 16.5px;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

a { color: inherit; }

.wrap { width: min(1120px, 100% - 44px); margin-inline: auto; }
.wrap.narrow { width: min(740px, 100% - 44px); }

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

/* ══ The layers ═══════════════════════════════════════════════════════════
   Four of them, back to front: the WebGL thread, a colour veil, a film of
   grain, and the page. Each is `position: fixed` and `pointer-events: none`
   so none of them can intercept a click or move anything in the document —
   which is what keeps a decorative background from costing layout shift. */

.layers {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}

/*
 * The canvas is sized entirely in CSS and never by the script, so its box
 * exists before WebGL does. A canvas that arrives late and sizes itself is a
 * layout shift on the largest element on the page.
 */
#threads {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  opacity: 0;
  transition: opacity 900ms ease;
}
#threads.on { opacity: 1; }

/*
 * The veil: the signature gradient, very dilute, pooled behind the hero.
 *
 * No `filter: blur()`. It had one, and it was the single most expensive thing
 * on the page — measured: a click in the demo went from 64 ms before the
 * redesign to 280 ms with it, and to 128 ms with the blur alone removed. A
 * blur filter over a 130vh fixed surface has to be re-rasterised whenever
 * anything above it repaints, and a radial gradient is already soft, so the
 * filter was paying a large cost for an effect that was almost invisible.
 * Wider, softer colour stops do the same job for nothing.
 *
 * `will-change: transform` is here for the other half of it: the parallax
 * writes a transform to this element, and promoting it to its own compositor
 * layer means the document repainting above it does not repaint this.
 */
.veil {
  position: absolute;
  inset: -20% -10% auto;
  height: 130vh;
  background:
    radial-gradient(62% 52% at 18% 10%, rgba(0, 229, 160, 0.19), rgba(0, 229, 160, 0.06) 46%, transparent 76%),
    radial-gradient(58% 48% at 80% 2%, rgba(124, 92, 255, 0.20), rgba(124, 92, 255, 0.06) 48%, transparent 78%),
    radial-gradient(52% 46% at 56% 48%, rgba(255, 122, 90, 0.13), rgba(255, 122, 90, 0.04) 50%, transparent 80%);
  will-change: transform;
}
@media (prefers-color-scheme: light) {
  .veil {
    background:
      radial-gradient(62% 52% at 18% 10%, rgba(0, 135, 90, 0.13), rgba(0, 135, 90, 0.04) 46%, transparent 76%),
      radial-gradient(58% 48% at 80% 2%, rgba(91, 69, 204, 0.13), rgba(91, 69, 204, 0.04) 48%, transparent 78%),
      radial-gradient(52% 46% at 56% 48%, rgba(209, 80, 58, 0.10), rgba(209, 80, 58, 0.03) 50%, transparent 80%);
  }
}

/*
 * Grain. A flat gradient reads as a rendering; a gradient with a film of noise
 * over it reads as a printed thing. Generated by the browser from a filter, so
 * it costs no request and no bytes beyond this rule.
 */
.grain {
  position: absolute;
  inset: -50%;
  opacity: 0.5;
  will-change: transform;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)' opacity='0.36'/%3E%3C/svg%3E");
  mix-blend-mode: overlay;
}
@media (prefers-color-scheme: light) { .grain { opacity: 0.28; mix-blend-mode: multiply; } }

/* Everything the reader reads sits above all of it. */
.site-head, main, .site-foot { position: relative; z-index: 2; }

/* ══ Type ═════════════════════════════════════════════════════════════════ */

h1, h2, h3 { margin: 0; font-weight: 640; line-height: 1.08; letter-spacing: -0.035em; }
/*
 * The very large size belongs to the hero, not to `h1`. The pricing page's own
 * h1 inherited it and filled a screen on its own, which is a poster rather than
 * a heading.
 */
h1 { font-size: clamp(2.1rem, 5vw, 3.4rem); }
.hero h1 { font-size: clamp(2.9rem, 8.4vw, 6.2rem); }
h2 { font-size: clamp(1.9rem, 4.4vw, 3.1rem); letter-spacing: -0.032em; margin-bottom: 16px; }
h3 { font-size: 1.12rem; letter-spacing: -0.012em; line-height: 1.3; }
p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

/*
 * The one serif word.
 *
 * A single italic serif inside a wall of tight sans is the whole typographic
 * idea: it is the thread, and it is the thing that stops the page looking
 * generated. It carries the gradient too, which is why the gradient never has
 * to appear as a full-width band.
 */
.thread-word {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 500;
  letter-spacing: -0.02em;
  /*
   * A shallower angle than the site's `--thread`. At 104 degrees across a box
   * only as wide as one word, the ramp's far end falls outside the glyphs and
   * the coral never appears — the word reads mint-to-violet and the third hue
   * of the signature is simply missing.
   */
  background: linear-gradient(94deg, var(--mint) 2%, var(--violet) 48%, var(--coral) 96%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  /*
   * The italic's overhang needs paint space or the gradient clips its tail —
   * but adding padding also pushes the full stop after it visibly away. The
   * negative margin gives the space back to the layout and keeps it for the
   * paint, so "thread." reads as one word.
   */
  padding-right: 0.07em;
  margin-right: -0.07em;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: 0.76rem;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  font-weight: 620;
  color: var(--fg-dim);
  font-family: var(--mono);
  border: 1px solid var(--line);
  border-radius: 100px;
  padding: 6px 14px 6px 10px;
  background: color-mix(in srgb, var(--bg-soft) 70%, transparent);
}
.eyebrow .dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--mint);
  box-shadow: 0 0 0 3px var(--accent-soft);
  flex: none;
}

.lede { font-size: clamp(1.06rem, 1.6vw, 1.28rem); color: var(--fg-dim); max-width: 56ch; }
.small { font-size: 0.88rem; color: var(--fg-dim); }
.faint { color: var(--fg-faint); }

/* A section's number, set in mono and hung off the left the way a printed
   thing would hang it. */
.kicker {
  font-family: var(--mono);
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-faint);
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 18px;
}
.kicker::after {
  content: '';
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, var(--line-strong), transparent);
}

/* ══ Buttons ══════════════════════════════════════════════════════════════ */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 13px 22px;
  border-radius: 12px;
  border: 1px solid var(--line-strong);
  background: color-mix(in srgb, var(--bg-soft) 60%, transparent);
  color: var(--fg);
  font: inherit;
  font-size: 0.95rem;
  font-weight: 560;
  text-decoration: none;
  cursor: pointer;
  overflow: hidden;
  transition: border-color var(--ease), color var(--ease), background var(--ease);
}
.btn:hover { border-color: color-mix(in srgb, var(--mint) 60%, var(--line-strong)); }
.btn:focus-visible { outline: 2px solid var(--mint); outline-offset: 3px; }

/* The primary action carries the signature gradient, and is the only thing on
   the page that does at full strength. */
.btn.primary {
  border-color: transparent;
  background: var(--thread);
  background-size: 180% 100%;
  background-position: 0% 50%;
  color: var(--accent-ink);
  font-weight: 640;
  box-shadow: var(--glow);
  transition: background-position 600ms var(--ease), box-shadow var(--ease);
}
.btn.primary:hover { background-position: 100% 50%; }
@media (prefers-color-scheme: light) { .btn.primary { color: #fff; } }

.btn.ghost { border-color: transparent; background: transparent; color: var(--fg-dim); padding-inline: 12px; }
.btn.ghost:hover { color: var(--fg); }
.btn.small { padding: 8px 14px; font-size: 0.86rem; border-radius: 9px; }
.btn .arrow { transition: transform var(--ease); }
.btn:hover .arrow { transform: translateX(3px); }

/* ══ Header ═══════════════════════════════════════════════════════════════ */

.site-head {
  position: sticky;
  top: 0;
  z-index: 30;
  backdrop-filter: blur(16px) saturate(150%);
  background: color-mix(in srgb, var(--bg) 74%, transparent);
  border-bottom: 1px solid transparent;
  transition: border-color var(--ease), background var(--ease);
}
/* Set by the motion layer once the page has scrolled — a class, so the rule
   still lives here and nothing writes style attributes the CSP forbids. */
.site-head.lifted { border-bottom-color: var(--line); background: color-mix(in srgb, var(--bg) 90%, transparent); }
.site-head .wrap { display: flex; align-items: center; gap: 18px; height: 64px; }

.brand { display: flex; align-items: center; gap: 10px; font-weight: 660; letter-spacing: -0.03em; text-decoration: none; font-size: 1.02rem; }
.brand svg { display: block; color: var(--mint); }

.site-nav { margin-left: auto; display: flex; align-items: center; gap: 4px; }
.site-nav a { text-decoration: none; color: var(--fg-dim); font-size: 0.91rem; padding: 8px 12px; border-radius: 9px; transition: color var(--ease), background var(--ease); }
.site-nav a:hover { color: var(--fg); background: var(--bg-lift); }
.site-nav .btn { margin-left: 8px; }
@media (max-width: 720px) { .site-nav .hide-sm { display: none; } }

/* ══ Hero ═════════════════════════════════════════════════════════════════
   Deliberately asymmetric and deliberately not centred: a centred stack of
   headline, sub and two buttons is the shape every generated landing page
   has. The headline runs wide, the sub is inset under it, and the proof sits
   off to one side. */

.hero { padding: clamp(56px, 10vw, 104px) 0 clamp(30px, 5vw, 56px); }
.hero h1 { margin: 20px 0 0; max-width: 15ch; }
.hero .lede { margin-top: 26px; margin-left: clamp(0px, 4vw, 64px); }

.cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 34px; margin-left: clamp(0px, 4vw, 64px); }

/* The three claims, as a row of hairline-separated facts rather than a list of
   ticks. Ticks in a row is the most template-shaped element there is. */
.facts {
  margin: 34px 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  border-top: 1px solid var(--line);
}
.facts li {
  flex: 1 1 190px;
  padding: 16px 20px 0 0;
  border-right: 1px solid var(--line);
  padding-left: 0;
}
.facts li:first-child { padding-left: 0; }
.facts li + li { padding-left: 20px; }
.facts li:last-child { border-right: 0; }
.facts b { display: block; font-size: 0.95rem; font-weight: 600; letter-spacing: -0.01em; }
.facts span { display: block; font-size: 0.85rem; color: var(--fg-faint); margin-top: 2px; }
.facts .n { font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.12em; color: var(--mint); display: block; margin-bottom: 7px; }
.facts li:nth-child(2) .n { color: var(--violet); }
.facts li:nth-child(3) .n { color: var(--coral); }
@media (max-width: 640px) {
  .facts li { border-right: 0; border-bottom: 1px solid var(--line); padding: 14px 0; flex-basis: 100%; }
  .facts li + li { padding-left: 0; }
  .facts li:last-child { border-bottom: 0; }
}

/* ══ The spine ════════════════════════════════════════════════════════════
   A single line running down the page, drawn as the reader scrolls. It is the
   product's own metaphor used as navigation furniture — and it is the element
   that makes the page feel like one continuous thing rather than a stack of
   sections. Purely decorative, so it is hidden from assistive technology and
   removed entirely on a narrow screen where there is no margin to hang it in. */

.spine {
  position: absolute;
  left: max(14px, calc(50% - 622px));
  top: 0;
  bottom: 0;
  width: 2px;
  pointer-events: none;
  z-index: 1;
  border-radius: 2px;
  background: var(--line);
  overflow: hidden;
}
/*
 * The drawn part is a second bar scaled from the top, not a stroke-dashoffset:
 * `scaleY` is a compositor property, so the whole length of the page can be
 * drawn on scroll without ever asking the main thread to repaint.
 */
.spine-live {
  position: absolute;
  inset: 0;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--mint) 0%, var(--violet) 55%, var(--coral) 100%);
  transform: scaleY(0);
  transform-origin: top center;
  will-change: transform;
}
@media (max-width: 1180px) { .spine { display: none; } }

/* ══ The demo ═════════════════════════════════════════════════════════════ */

.demo-shell { position: relative; margin-top: clamp(36px, 5vw, 58px); }

/* The stacked-paper effect: two offset sheets behind the real one. It is what
   makes the demo read as "a thing you can pick up" rather than a screenshot in
   a rounded rectangle. */
.demo-shell::before,
.demo-shell::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 20px;
  border: 1px solid var(--line);
  background: var(--bg-soft);
  z-index: -1;
}
.demo-shell::before { transform: translate(0, 14px) scale(0.985); opacity: 0.6; }
.demo-shell::after { transform: translate(0, 27px) scale(0.968); opacity: 0.3; }

/*
 * Opaque, and deliberately not backdrop-filtered. The demo is the one thing on
 * the page that repaints when somebody clicks, and a backdrop filter means
 * every one of those repaints re-blurs everything behind the card. The surface
 * is 92% opaque, so the blur was buying almost nothing.
 */
.demo {
  position: relative;
  border: 1px solid var(--line-strong);
  border-radius: 20px;
  background: var(--bg-soft);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.demo-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--bg-lift) 80%, transparent);
}
.dots { display: flex; gap: 6px; }
.dots i { width: 10px; height: 10px; border-radius: 50%; background: var(--line-strong); }
.dots i:first-child { background: color-mix(in srgb, var(--coral) 70%, transparent); }
.dots i:nth-child(2) { background: color-mix(in srgb, var(--amber) 60%, transparent); }
.dots i:nth-child(3) { background: color-mix(in srgb, var(--mint) 60%, transparent); }
.demo-title { font-size: 0.83rem; color: var(--fg-faint); font-family: var(--mono); }
.demo-hint { margin-left: auto; font-size: 0.79rem; color: var(--fg-faint); display: inline-flex; align-items: center; gap: 7px; }
.demo-hint::before {
  content: '';
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--mint);
  box-shadow: 0 0 0 0 var(--accent-soft);
  animation: pulse 2.4s ease-out infinite;
}
@keyframes pulse {
  0% { box-shadow: 0 0 0 0 rgba(0, 229, 160, 0.5); }
  70% { box-shadow: 0 0 0 8px rgba(0, 229, 160, 0); }
  100% { box-shadow: 0 0 0 0 rgba(0, 229, 160, 0); }
}

.demo-body { display: grid; grid-template-columns: minmax(0, 340px) minmax(0, 1fr); min-height: 432px; }
@media (max-width: 860px) { .demo-body { grid-template-columns: 1fr; } }

.demo-tree { border-right: 1px solid var(--line); padding: 14px 12px; display: flex; flex-direction: column; }
@media (max-width: 860px) { .demo-tree { border-right: 0; border-bottom: 1px solid var(--line); } }

.tree-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 0 6px 10px;
  font-size: 0.72rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--fg-faint);
  font-family: var(--mono);
}
.tree-head .count { margin-left: auto; text-transform: none; letter-spacing: 0.02em; }

.tree { list-style: none; margin: 0; padding: 0; flex: 1; overflow: auto; }
.node {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 10px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: 0.9rem;
  text-align: left;
  cursor: pointer;
  transition: background var(--ease), opacity var(--ease), transform 120ms var(--ease);
}
.node:hover { background: var(--bg-lift); transform: translateX(2px); }
.node:focus-visible { outline: 2px solid var(--mint); outline-offset: -2px; }
.node[aria-current='true'] { background: var(--accent-soft); }

/* Depth walks the signature triad, so the colour is teaching the hierarchy
   rather than just brightening the page. */
.node .pip { width: 8px; height: 8px; border-radius: 50%; background: var(--mint); flex: none; transition: background var(--ease), box-shadow var(--ease); }
.node[data-depth='1'] .pip { background: var(--violet); }
.node[data-depth='2'] .pip { background: var(--coral); }
.node[data-depth='3'] .pip { background: var(--amber); }
.node .label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.node .tag {
  margin-left: auto;
  font-size: 0.68rem;
  font-family: var(--mono);
  color: var(--fg-faint);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 1px 6px;
  flex: none;
}
.node.frozen { opacity: 0.42; }
.node.frozen .pip { background: var(--fg-faint); }
.node.has-note .pip { box-shadow: 0 0 0 3px var(--accent-soft); }

.node[data-depth='1'] { padding-left: 28px; }
.node[data-depth='2'] { padding-left: 46px; }
.node[data-depth='3'] { padding-left: 64px; }
.tree li { position: relative; }
.tree li[data-depth]:not([data-depth='0'])::before {
  content: '';
  position: absolute;
  left: calc(10px + (var(--d) - 1) * 18px + 4px);
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--line);
}

.demo-panel { padding: 22px 24px; display: flex; flex-direction: column; gap: 15px; min-width: 0; }
.panel-kicker { font-size: 0.72rem; letter-spacing: 0.13em; text-transform: uppercase; color: var(--fg-faint); font-family: var(--mono); }
.panel-title { font-size: 1.24rem; font-weight: 640; letter-spacing: -0.028em; }
.panel-why {
  position: relative;
  padding: 3px 0 3px 14px;
  color: var(--fg-dim);
  font-size: 0.93rem;
}
.panel-why::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
  border-radius: 2px;
  background: var(--thread);
}
.panel-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: auto; padding-top: 12px; }

.note-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.note-list li {
  background: color-mix(in srgb, var(--bg-lift) 70%, transparent);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 10px 13px;
  font-size: 0.89rem;
  color: var(--fg-dim);
}
.note-list li b { color: var(--fg); font-weight: 570; }

.export {
  margin: 0;
  background: color-mix(in srgb, var(--bg-lift) 70%, transparent);
  border: 1px solid var(--line);
  border-radius: 11px;
  padding: 15px 17px;
  font-family: var(--mono);
  font-size: 0.78rem;
  line-height: 1.72;
  color: var(--fg-dim);
  overflow-x: auto;
  white-space: pre;
  max-height: 262px;
}
.export b { color: var(--mint); font-weight: 500; }

.demo-status {
  padding: 10px 16px;
  border-top: 1px solid var(--line);
  background: color-mix(in srgb, var(--bg-lift) 80%, transparent);
  font-size: 0.84rem;
  color: var(--fg-dim);
  min-height: 40px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.demo-status b { color: var(--mint); font-weight: 570; }

/* ══ Bands ════════════════════════════════════════════════════════════════
   The rhythm is deliberately uneven — a wide band, a narrow one, a split one.
   Three identical full-width sections of three identical cards is the shape
   this page is trying not to have.

   `content-visibility` lets the browser skip layout and paint for a section
   that is still far below the fold. `contain-intrinsic-size` gives it a
   stand-in height so skipping costs no layout shift when it scrolls in — the
   two go together, and using the first without the second is how this
   optimisation turns into a CLS problem. */

.band { padding: clamp(64px, 9vw, 108px) 0; position: relative; }
.band.deferred { content-visibility: auto; contain-intrinsic-size: auto 720px; }
.band.alt { background: color-mix(in srgb, var(--bg-soft) 60%, transparent); border-block: 1px solid var(--line); }

/* ── The three pillars, as a zigzag rather than a card row ──────────────── */

.pillars { margin-top: 46px; display: flex; flex-direction: column; gap: clamp(38px, 6vw, 76px); }
.pillar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(24px, 5vw, 64px);
  align-items: center;
}
.pillar:nth-child(even) .pillar-text { order: 2; }
@media (max-width: 820px) { .pillar { grid-template-columns: 1fr; } .pillar:nth-child(even) .pillar-text { order: 0; } }

.pillar-text h3 { font-size: clamp(1.35rem, 2.6vw, 1.9rem); letter-spacing: -0.028em; margin-bottom: 12px; }
.pillar-text p { color: var(--fg-dim); font-size: 1rem; max-width: 46ch; }
.pillar-n {
  font-family: var(--mono);
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  color: var(--mint);
  display: block;
  margin-bottom: 14px;
}
.pillar:nth-child(2) .pillar-n { color: var(--violet); }
.pillar:nth-child(3) .pillar-n { color: var(--coral); }

/* Each pillar carries a small piece of the real interface rather than an icon.
   An icon says "there is a feature here"; this says what it looks like. */
.pillar-art {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--bg-soft) 80%, transparent);
  padding: 20px;
  min-height: 178px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  justify-content: center;
  font-size: 0.86rem;
  color: var(--fg-dim);
  overflow: hidden;
}
.art-row { display: flex; align-items: center; gap: 10px; }
.art-row .dot { width: 7px; height: 7px; border-radius: 50%; flex: none; background: var(--mint); }
.art-row.d1 { padding-left: 18px; }
.art-row.d1 .dot { background: var(--violet); }
.art-row.d2 { padding-left: 36px; }
.art-row.d2 .dot { background: var(--coral); }
.art-row .why { font-size: 0.78rem; color: var(--fg-faint); font-style: italic; }
.art-row.dim { opacity: 0.4; }
.art-chip {
  align-self: flex-start;
  font-family: var(--mono);
  font-size: 0.72rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 2px 7px;
  color: var(--fg-faint);
}
.art-md { font-family: var(--mono); font-size: 0.76rem; line-height: 1.85; color: var(--fg-faint); white-space: pre; overflow: hidden; }
.art-md b { color: var(--mint); font-weight: 500; }

/* ── Privacy, as three short statements on hairlines ────────────────────── */

.statements { margin-top: 42px; display: grid; gap: 0; grid-template-columns: repeat(auto-fit, minmax(258px, 1fr)); }
.statement { padding: 26px 24px 26px 0; border-top: 2px solid var(--mint); }
.statement + .statement { padding-left: 24px; border-top-color: var(--violet); }
.statement + .statement + .statement { border-top-color: var(--coral); }
.statement h3 { margin-bottom: 10px; }
.statement p { color: var(--fg-dim); font-size: 0.93rem; margin: 0; }
@media (max-width: 820px) { .statement, .statement + .statement { padding-left: 0; padding-right: 0; } }

/* ══ Pricing ══════════════════════════════════════════════════════════════ */

.tiers { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(276px, 1fr)); margin-top: 40px; align-items: start; }
.tier {
  position: relative;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 28px 26px;
  background: color-mix(in srgb, var(--bg-soft) 78%, transparent);
}
.tier.featured { border-color: transparent; }
/* The gradient border, drawn as a mask rather than a background so the card's
   own surface stays flat. */
.tier.featured::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: var(--radius);
  padding: 1px;
  background: var(--thread);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  pointer-events: none;
}
.tier .badge {
  position: absolute; top: -12px; left: 24px;
  background: var(--thread);
  color: var(--accent-ink);
  font-size: 0.71rem; font-weight: 680; letter-spacing: 0.04em;
  padding: 4px 11px; border-radius: 20px;
}
@media (prefers-color-scheme: light) { .tier .badge { color: #fff; } }
.price { font-size: 2.1rem; font-weight: 660; letter-spacing: -0.04em; margin: 8px 0 2px; }
.price small { font-size: 0.9rem; font-weight: 400; color: var(--fg-faint); letter-spacing: 0; }
.tier ul { list-style: none; margin: 20px 0 24px; padding: 0; display: flex; flex-direction: column; gap: 11px; }
.tier li { display: flex; gap: 11px; font-size: 0.93rem; color: var(--fg-dim); }
.tier li svg { flex: none; margin-top: 4px; color: var(--mint); }
.tier.featured li svg { color: var(--violet); }
.tier .btn { width: 100%; }

/* ══ Steps ════════════════════════════════════════════════════════════════ */

.steps { counter-reset: step; display: grid; gap: 28px; margin-top: 40px; grid-template-columns: repeat(auto-fit, minmax(236px, 1fr)); }
.step { counter-increment: step; position: relative; padding-top: 22px; border-top: 1px solid var(--line); }
.step::before {
  content: counter(step, decimal-leading-zero);
  font-family: var(--mono);
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  color: var(--mint);
  display: block;
  margin-bottom: 12px;
}
.step:nth-child(2)::before { color: var(--violet); }
.step:nth-child(3)::before { color: var(--coral); }
.step h3 { margin-bottom: 7px; }
.step p { color: var(--fg-dim); font-size: 0.93rem; margin: 0; }

/* ══ The closing line ═════════════════════════════════════════════════════ */

.closer { padding: clamp(72px, 11vw, 132px) 0; text-align: center; position: relative; }
.closer h2 { font-size: clamp(2.1rem, 6.4vw, 4.2rem); max-width: 14ch; margin-inline: auto; }
.closer .lede { margin: 22px auto 0; }
.closer .cta { justify-content: center; margin-left: 0; }

/* ══ FAQ ══════════════════════════════════════════════════════════════════ */

.faq { margin-top: 38px; display: grid; gap: 0; }
.faq details {
  border-top: 1px solid var(--line);
  padding: 18px 0;
}
.faq details:last-child { border-bottom: 1px solid var(--line); }
.faq summary {
  cursor: pointer;
  list-style: none;
  font-weight: 580;
  font-size: 1.02rem;
  letter-spacing: -0.015em;
  display: flex;
  align-items: center;
  gap: 12px;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::before {
  content: '+';
  font-family: var(--mono);
  color: var(--mint);
  font-size: 1.1rem;
  line-height: 1;
  transition: transform var(--ease);
  flex: none;
}
.faq details[open] summary::before { content: '−'; }
.faq summary:focus-visible { outline: 2px solid var(--mint); outline-offset: 3px; border-radius: 6px; }
.faq p { color: var(--fg-dim); font-size: 0.95rem; margin: 12px 0 0 24px; max-width: 62ch; }

/* ══ Outcome pages ════════════════════════════════════════════════════════ */

.outcome { min-height: 76vh; display: grid; place-items: center; padding: 60px 0; }
.outcome-card {
  width: min(580px, 100% - 44px);
  text-align: center;
  background: color-mix(in srgb, var(--bg-soft) 88%, transparent);
  backdrop-filter: blur(10px);
  border: 1px solid var(--line-strong);
  border-radius: 20px;
  padding: clamp(32px, 5vw, 52px);
  box-shadow: var(--shadow);
}
.outcome-mark {
  width: 66px; height: 66px;
  margin: 0 auto 24px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--thread);
  color: var(--accent-ink);
  box-shadow: var(--glow);
}
@media (prefers-color-scheme: light) { .outcome-mark { color: #fff; } }
.outcome-card h1 { font-size: clamp(1.9rem, 4.4vw, 2.6rem); margin-bottom: 14px; }
.outcome-card .lede { margin-inline: auto; }
.outcome-card .cta { justify-content: center; margin-left: 0; }
.next {
  margin-top: 32px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
  text-align: left;
}
.next h2 { font-size: 0.75rem; letter-spacing: 0.13em; text-transform: uppercase; color: var(--fg-faint); margin-bottom: 14px; font-family: var(--mono); }
.next ol { margin: 0; padding-left: 20px; color: var(--fg-dim); font-size: 0.93rem; display: flex; flex-direction: column; gap: 8px; }
.ref { margin-top: 22px; font-family: var(--mono); font-size: 0.75rem; color: var(--fg-faint); word-break: break-all; }

/* ══ Footer ═══════════════════════════════════════════════════════════════ */

.site-foot { border-top: 1px solid var(--line); padding: 44px 0; }
.site-foot .wrap { display: flex; flex-wrap: wrap; gap: 14px 28px; align-items: center; }
.site-foot .small { margin: 0; }
.site-foot nav { margin-left: auto; display: flex; gap: 20px; }
.site-foot nav a { color: var(--fg-faint); font-size: 0.87rem; text-decoration: none; }
.site-foot nav a:hover { color: var(--fg); }

kbd {
  font-family: var(--mono);
  font-size: 0.86em;
  border: 1px solid var(--line-strong);
  border-bottom-width: 2px;
  border-radius: 5px;
  padding: 0 5px;
  color: var(--fg);
}

/* ══ The reveal ═══════════════════════════════════════════════════════════
   Elements marked `data-reveal` start slightly down and transparent, and the
   motion layer animates them in when they scroll into view. Two rules matter:

   The offset is a `transform`, so nothing reflows and the reveal cannot
   contribute to layout shift.

   The hidden state is applied by script, not by this stylesheet. A CSS-only
   `opacity: 0` here would leave the content invisible for anyone whose
   JavaScript never runs — a crawler, a reader-mode view, a failed request —
   which is the classic way an animated landing page becomes a blank one. */

[data-reveal].armed { opacity: 0; transform: translate3d(0, 18px, 0); }
