/* Nuggt marketing site — tokens from the brand sheet in the "Nuggt logo
   design strategy" Claude Design project (v1, captured Jul 2026):
   Ink #0F1117 · Slate #3B4450 · Cream #F4EFE6
   Gold on dark: #FFD68C→#DD9026 · Gold on light: #EEA93C→#B0700F
   (the sheet's rule: pale gold washes out on cream — deep gold on light)
   Type: Jost (brand/wordmark) · Hanken Grotesk (body) · Space Grotesk (numerals)

   Theme: dark is default; [data-theme="light"] switches to the cream system
   the brand sheet designates for "big surfaces, marketing". Toggle via
   ?theme=light / ?theme=dark (persisted in localStorage) for review. */

/* Fonts are self-hosted rather than linked from Google: a third-party
   render-blocking request on every page is both a load-time and a privacy
   cost. All three are variable fonts, so one file covers every weight.
   Latin subset only (88KB total). */
@font-face {
  font-family: "Hanken Grotesk";
  src: url("/assets/fonts/hanken-grotesk-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
}
@font-face {
  font-family: "Jost";
  src: url("/assets/fonts/jost-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
}
@font-face {
  font-family: "Space Grotesk";
  src: url("/assets/fonts/space-grotesk-latin.woff2") format("woff2");
  font-weight: 300 700;
  font-display: swap;
}

:root {
  --bg: #0F1117;
  --bg-2: #171B23;
  --card-bg: #151A22;
  /* One step above a card, for the single card we want the eye to land on. */
  --card-bg-raised: #1B212B;
  --fg: #F6F2EA;
  --muted: #9AA1AD;
  --border: #262C37;
  --gold-hi: #FFD68C;
  --gold-lo: #DD9026;
  --accent: #DD9026;
  --accent-text: #EEA93C;
  --accent-fg: #1A1208;
  --mark-bar: #3B4450;
  --shadow-color: rgba(0, 0, 0, 0.6);
  --grain-opacity: 0.05;

  /* One radius scale, three steps, applied everywhere:
     pills and dots are fully round, everything else is 14px. Nothing else. */
  --r-pill: 999px;
  --r-lg: 14px;

  /* VERTICAL RHYTHM. Five steps, each roughly 1.5x the last, so any two are
     unmistakably different rather than merely unequal. The page had eleven
     ad-hoc values (72 next to 80 next to 88) accumulated over many rounds:
     close enough to look like a mistake, far enough apart to be visible.
     Sections vary by moving along this scale, never by inventing a number. */
  --s-tight: 1.5rem; /* 24 */
  --s-snug: 2.5rem; /* 40 */
  --s-mid: 4rem; /* 64 */
  --s-beat: 6rem; /* 96 — the default section rhythm */
  --s-pause: 9rem; /* 144 — reserved for a deliberate hold */

  /* GOLD IS RESERVED. The brand sheet's rule, which the product UI already
     follows: gold means "Nuggt found something", and must not be diluted by
     being on all the time. On this page gold appears ONLY on the brand mark
     and on moments where an answer surfaced. Anything merely interactive or
     emphatic uses the neutrals below, so the page behaves like the product:
     neutral conversation, colour at the payoff. */
  --strong-bg: #F6F2EA;
  --strong-fg: #0F1117;
  --line-strong: #3B4450; /* Slate, from the brand sheet */
}

:root[data-theme="light"] {
  --bg: #F4EFE6;
  --bg-2: #FBF9F4;
  --card-bg: #FFFFFF;
  /* White is already the top of the light scale, so the raised card cannot go
     lighter — it stays white and earns its emphasis from the border and the
     shadow against cream instead. */
  --card-bg-raised: #FFFFFF;
  --fg: #14171F;
  --muted: #6B6256;
  --border: #E7E0D2;
  --gold-hi: #EEA93C;
  --gold-lo: #B0700F;
  --accent: #B0700F;
  /* The brand sheet's darkest light-mode gold (#B0700F) only reaches 3.55:1
     on cream, which fails WCAG AA for small text. Borders, fills and
     gradients keep the brand value; text steps one shade darker to 5.07:1. */
  --accent-text: #8E5A08;
  --accent-fg: #231503;
  --mark-bar: #222A33;
  --shadow-color: rgba(31, 26, 15, 0.16);
  --grain-opacity: 0.03;
  --strong-bg: #14171F;
  --strong-fg: #F4EFE6;
  --line-strong: #C4B9A5;
}

/* `*` alone does not match pseudo-elements, so any ::before with a border
   silently keeps content-box and grows by its border width. That put the
   rail's dots 2px off the track they are meant to sit on. */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
}

body {
  font-family: "Hanken Grotesk", -apple-system, BlinkMacSystemFont, sans-serif;
  position: relative;
}

h1, h2, .display {
  font-family: "Jost", "Hanken Grotesk", sans-serif;
  font-weight: 500;
  letter-spacing: -0.02em;
}

a { color: inherit; }

/* subtle grain, no image asset needed */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: var(--grain-opacity);
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

.site-header, main, .site-footer { position: relative; z-index: 1; }

/* ---- header / nav ---- */
.site-header {
  border-bottom: 1px solid var(--border);
}
.site-nav {
  max-width: 1280px;
  margin: 0 auto;
  padding: 1.4rem 1.5rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.wordmark {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  font-family: "Jost", sans-serif;
  font-weight: 500;
  font-size: 1.55rem;
  letter-spacing: -0.02em;
  text-decoration: none;
  color: var(--fg);
}
/* 2x the original 22px; nudged down so the mark centres on the x-height
   of "nu" rather than the full line box (the 'gg' descenders pull the
   text's optical centre lower than the flexbox centre). */
.wordmark svg { width: 44px; height: 44px; transform: translateY(2px); }
.wm-bar { fill: var(--mark-bar); }
.wm-stop-hi { stop-color: var(--gold-hi); }
.wm-stop-lo { stop-color: var(--gold-lo); }
.nav-links { display: flex; gap: 1.75rem; }
.nav-links a {
  text-decoration: none;
  font-size: 0.92rem;
  color: var(--muted);
}
.nav-links a:hover { color: var(--fg); }

/* ---- shared page container ---- */
main { min-height: 60vh; }

.container {
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 1.5rem;
}

/* ---- hero: asymmetric, with a meeting running beside the pitch ----
   Centred stacks are the safe default and read as generic. The pitch sits
   left; a real conversation plays to the right of it, which is the product's
   actual subject matter rather than decoration. */
/* Single column by default. The two-column split is opt-IN above 1100px,
   because the right-hand column needs real width to hold a conversation:
   defining the grid unconditionally and only collapsing it at the 720px
   mobile breakpoint squeezed the scene into a 74px sliver, 1224px tall,
   across the whole tablet range. */
.hero {
  padding: var(--s-beat) 1.5rem;
  display: grid;
  gap: var(--s-mid);
  align-items: center;
  position: relative;
  overflow: hidden;
}
@media (min-width: 1100px) {
  .hero {
    /* The left column stays on the page's measure; the right one runs to the
       viewport edge and past it. Deliberately not a tidy 50/50. */
    grid-template-columns: minmax(0, 41rem) minmax(0, 1fr);
    gap: clamp(2.5rem, 6vw, 6.5rem);
    padding: var(--s-beat) 0 var(--s-beat) max(1.5rem, calc((100vw - 1280px) / 2));
  }
  /* Runs off the edge. The last few pixels of the conversation are cut by the
     viewport, which is the point: the meeting did not start on this page. */
  .hero-scene {
    margin-right: -6vw;
  }
}
.hero::before {
  content: "";
  position: absolute;
  top: -20%;
  left: 8%;
  width: 780px;
  max-width: 90vw;
  height: 620px;
  background: radial-gradient(ellipse at center, color-mix(in srgb, var(--accent) 8%, transparent) 0%, transparent 65%);
  z-index: -1;
  pointer-events: none;
  animation: glowBreathe 9s ease-in-out infinite alternate;
}
.hero h1 {
  font-size: clamp(2.4rem, 3.7vw, 3.25rem);
  line-height: 1.06;
  margin: 0 0 1.6rem;
}
/* "make" is the only full-strength word; the rest of the headline steps
   back. Emphasis without spending the accent. */
.hero h1 { color: color-mix(in srgb, var(--fg) 76%, transparent); }
.hero h1 em {
  font-style: normal;
  color: var(--fg);
}
.hero .subhead {
  font-size: 1.18rem;
  line-height: 1.65;
  color: var(--muted);
  margin: 0 0 2.6rem;
  max-width: 46ch;
}

/* The meeting itself. No fade mask: it used to soften the top so the scene
   read as a conversation joined partway through, but the "In the meeting"
   label sits at the top of this element and the mask truncated it. The scene
   is a complete composition now (label, the exchange, the answer), so there
   is nothing to imply continuing off-screen. */
.hero-scene {
  position: relative;
  padding-left: 0.25rem;
}
.hero-scene .voice-track { gap: 1.7rem; }
.hero-scene .scene-label { display: block; margin-bottom: 1.3rem; }

.cta-row {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.cta-band .cta-row { justify-content: center; }
.btn-primary {
  display: inline-block;
  background: var(--strong-bg);
  color: var(--strong-fg);
  text-decoration: none;
  font-weight: 700;
  padding: 0.9rem 1.9rem;
  border-radius: var(--r-lg);
  font-size: 1rem;
  box-shadow: 0 8px 24px -8px var(--shadow-color);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 14px 30px -10px var(--shadow-color);
}
.btn-secondary {
  display: inline-block;
  text-decoration: none;
  color: var(--muted);
  font-size: 0.95rem;
  padding: 0.9rem 0.5rem;
  transition: color 0.15s ease;
}
.btn-secondary:hover { color: var(--fg); }
/* The quieter sibling of btn-primary: still unmistakably a button, so a card
   whose CTA is not the one we are steering towards does not look unclickable. */
.btn-outline {
  display: inline-block;
  text-decoration: none;
  color: var(--fg);
  font-weight: 600;
  font-size: 0.95rem;
  padding: 0.75rem 1.4rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-lg);
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.btn-outline:hover { border-color: var(--fg); transform: translateY(-1px); }
.cta-note {
  margin: 1rem 0 0;
  font-size: 0.82rem;
  color: var(--muted);
}

.scene-label {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.35rem;
}

/* Voice lines, not chat bubbles: these words are spoken, so the visual
   language is a waveform and a speaking rail rather than a message bubble. */
.voice-track {
  display: flex;
  flex-direction: column;
  gap: 1.75rem;
}
.vline {
  position: relative;
  padding-left: 1.15rem;
}
.vline::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.2rem;
  bottom: 0.2rem;
  width: 2px;
  border-radius: var(--r-pill);
  background: var(--border);
  transition: background 0.4s ease;
}
.vline.-on::before,
.vline.-held::before {
  background: var(--line-strong);
}
.v-head {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 0.4rem;
}
.v-speaker {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--muted);
  transition: color 0.4s ease;
}
.vline.-on .v-speaker,
.vline.-held .v-speaker { color: var(--fg); }
.v-text {
  margin: 0;
  font-size: 1.12rem;
  line-height: 1.5;
  color: var(--muted);
  transition: color 0.4s ease;
}
.vline.-on .v-text,
.vline.-held .v-text { color: var(--fg); }
.vline.-live .v-text { font-style: italic; }

/* the waveform: a flat profile at rest, alive for whoever has the floor */
.v-wave {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  height: 16px;
}
.v-wave i {
  width: 2px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--muted) 40%, transparent);
  transition: background 0.4s ease;
}
.vline.-on .v-wave i {
  background: var(--fg);
  animation: vBar 0.9s ease-in-out infinite;
}
.v-wave i:nth-child(1) { height: 5px; animation-delay: 0s; }
.v-wave i:nth-child(2) { height: 9px; animation-delay: 0.08s; }
.v-wave i:nth-child(3) { height: 14px; animation-delay: 0.16s; }
.v-wave i:nth-child(4) { height: 7px; animation-delay: 0.24s; }
.v-wave i:nth-child(5) { height: 12px; animation-delay: 0.32s; }
.v-wave i:nth-child(6) { height: 4px; animation-delay: 0.4s; }
.v-wave i:nth-child(7) { height: 13px; animation-delay: 0.48s; }
.v-wave i:nth-child(8) { height: 8px; animation-delay: 0.56s; }
.v-wave i:nth-child(9) { height: 16px; animation-delay: 0.64s; }
.v-wave i:nth-child(10) { height: 6px; animation-delay: 0.72s; }
.v-wave i:nth-child(11) { height: 11px; animation-delay: 0.8s; }
.v-wave i:nth-child(12) { height: 14px; animation-delay: 0.88s; }
.v-wave i:nth-child(13) { height: 7px; animation-delay: 0.96s; }
.v-wave i:nth-child(14) { height: 5px; animation-delay: 1.04s; }

/* The finished state is the default. The play-through below is opt-in via
   .js-anim, which the script only adds once its observer has proven alive —
   so content is never hostage to the choreography.
   All three voice lines are always present — only the highlight travels.
   Nothing ever fades in from nothing, so a glancing visitor never mistakes
   a pending line for whitespace. */
/* ---- reveal-on-scroll ---- */
[data-reveal] {
  opacity: 0;
  transform: translateY(22px);
  filter: blur(7px);
  transition:
    opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.7s cubic-bezier(0.16, 1, 0.3, 1),
    filter 0.7s cubic-bezier(0.16, 1, 0.3, 1);
}
[data-reveal].is-visible {
  opacity: 1;
  transform: translateY(0);
  /* `none`, not `blur(0)`. Any filter value other than `none` creates a
     stacking context, which traps the z-index of anything inside — and the
     overlay in the first band deliberately overhangs into the next section,
     so it was being painted over and read as "cut off". Interpolates from
     blur(7px) just the same. */
  filter: none;
}

/* ---- the answer, inside the scene it answers ----
   Question and answer must be readable in one view. When they were split
   across two sections, the answer read as a non-sequitur to anyone who had
   not watched the loop play. Rendered editorially, so it states what Nuggt
   surfaced without pretending to be a screenshot of the app. */
.surfaced {
  position: relative;
  margin-top: 2.2rem;
  padding: 1.15rem 1.3rem 1.2rem 1.5rem;
  background: var(--card-bg);
  border-radius: var(--r-lg);
  box-shadow: 0 22px 50px -30px var(--shadow-color);
  overflow: hidden;
}
/* the gold edge marks it as something Nuggt raised, not something said */
.surfaced::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: linear-gradient(180deg, var(--gold-hi), var(--gold-lo));
}
.surfaced-label {
  display: block;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin-bottom: 0.6rem;
}
.s-answer {
  margin: 0 0 0.5rem;
  font-size: 1.22rem;
  line-height: 1.4;
}
.s-answer strong {
  font-weight: 600;
  color: var(--accent-text);
}

/* it arrives when the question has been asked; visible by default so the
   static fallback still shows the complete story */
.hero-scene.js-anim .surfaced {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.45s ease, transform 0.45s ease;
}
.hero-scene.js-anim.-answered .surfaced {
  opacity: 1;
  transform: none;
}

/* ---- waveform rule: the brand mark used as a section divider ---- */
.wave-rule {
  display: flex;
  align-items: center;
  gap: 3px;
  height: 26px;
  margin-bottom: 2.2rem;
}
.wave-rule i {
  width: 3px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--muted) 35%, transparent);
}
.wave-rule i:nth-child(4n+1) { height: 8px; }
.wave-rule i:nth-child(4n+2) { height: 18px; }
.wave-rule i:nth-child(4n+3) { height: 12px; }
.wave-rule i:nth-child(4n) { height: 24px; }
.wave-rule i:nth-child(7) {
  background: linear-gradient(180deg, var(--gold-hi), var(--gold-lo));
  height: 26px;
}

/* ---- provenance ----
   Where an answer came from, and when. This is the one thing a summariser
   structurally cannot show: it only saw this meeting, so it has nothing to
   cite. So it gets a voice of its own rather than a grey caption.

   Space Grotesk is the brand's numeral face and was doing nothing on this
   site; giving it exactly one job means a date and a source read as a
   different KIND of information from the sentence above them, without adding
   a colour, a box, or an ornament. The hairline ties back to the gold edge
   that marks the answer. */
.prov {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin: 0.75rem 0 0;
  font-family: "Space Grotesk", ui-monospace, monospace;
  font-size: 0.8rem;
  letter-spacing: 0.01em;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}
.prov-rule {
  flex: none;
  width: 1.1rem;
  height: 1px;
  background: var(--line-strong);
}
/* Solid, not an alpha mix: a translucent colour makes the real contrast
   depend on whatever is behind it, and this line sits on two different
   surfaces. The divider already separates it from the source. */
.prov-when {
  color: var(--muted);
}
.prov-when::before {
  content: "";
  display: inline-block;
  width: 1px;
  height: 0.75em;
  margin-right: 0.7rem;
  vertical-align: -0.05em;
  background: var(--border);
}

/* An answer from a document: same gold edge and same provenance signature as
   the one in the hero, but no card. The signature is the constant; the
   container is not. */
.doc-answer {
  position: relative;
  padding-left: 1.3rem;
  margin-top: 0.5rem;
  max-width: 46ch;
}
.doc-answer::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.15rem;
  bottom: 0.15rem;
  width: 3px;
  border-radius: var(--r-pill);
  background: linear-gradient(180deg, var(--gold-hi), var(--gold-lo));
}
.doc-answer > p:first-child {
  margin: 0;
  font-size: 1.12rem;
  line-height: 1.45;
}

/* ---- the in-meeting overlay ----
   Captured with a transparent background (it floats over the user's call), so
   it gets a drop-shadow rather than a box: the PNG's own rounded corners are
   the silhouette, and box-shadow would draw a rectangle behind them. */
.hud {
  margin: 0;
}
.hud img {
  display: block;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 26px 45px var(--shadow-color));
}

/* ---- showcase: copy above, product capture at full width ----
   A screenshot of a two-column app screen is unreadable at half a split, and
   this is the one place the real product is shown, so it gets the width. Also
   breaks the split rhythm: the feature area is now split, statement, sources,
   showcase. */
.showcase {
  border-top: 1px solid var(--border);
  padding: var(--s-beat) 0;
}
.showcase-copy {
  max-width: 62ch;
  margin: 0 auto 3rem;
  text-align: center;
}
.showcase-copy h2 {
  font-size: clamp(1.6rem, 3vw, 2.1rem);
  margin: 0 0 0.85rem;
}
.showcase-copy p {
  color: var(--muted);
  font-size: 1rem;
  line-height: 1.7;
  margin: 0;
}
/* The differentiator, set apart from the category pitch above it: the section
   has to sell note-taking on its own terms first, because that is what most
   readers arrived shopping for. */
.showcase-aside {
  margin-top: 1.1rem !important;
  color: var(--fg) !important;
  font-weight: 500;
}

/* ---- product screenshot ----
   A real capture of the app (see packages/app/capture/), so it is framed
   rather than bled: the app is dark-only, and on the cream theme an
   unframed dark rectangle would read as pasted on. The border and shadow
   make it deliberate. Width/height are set on the <img> so the space is
   reserved before it loads. */
.shot {
  /* Wider than the copy it belongs to, and centred independently of the
     container: the page was a stack of same-width rectangles, and letting the
     one real screenshot break that line is what stops it reading as another
     box in the pile. */
  width: min(100vw - 3rem, 1460px);
  margin-left: 50%;
  margin-top: -2.5rem;
  transform: translateX(-50%);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: 0 40px 90px -45px var(--shadow-color);
  background: #0f1117;
}
.shot img {
  display: block;
  width: 100%;
  height: auto;
}

/* ---- full-width statement: breaks the split rhythm between feature bands ---- */
.statement {
  border-top: 1px solid var(--border);
  /* The one hold on the page. */
  padding: var(--s-pause) 0;
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 0.85fr);
  gap: clamp(2rem, 6vw, 5rem);
  align-items: end;
  /* bleed the tone to the full viewport width from inside the padded
     container, so the page's biggest claim gets its own field */
  background: var(--bg-2);
  box-shadow: 0 0 0 100vmax var(--bg-2);
  clip-path: inset(0 -100vmax);
}
.statement p {
  font-family: "Jost", "Hanken Grotesk", sans-serif;
  font-weight: 500;
  letter-spacing: -0.02em;
  font-size: clamp(2.3rem, 5.4vw, 4.4rem);
  line-height: 1.02;
  max-width: 22ch;
  /* Off the centre line on purpose: centred text is the safest possible
     choice and reads as such. */
  margin: 0 0 0 clamp(0rem, 5vw, 4.5rem);
  position: relative;
}
.statement-note {
  display: block;
  color: var(--muted);
  font-size: 1rem;
  line-height: 1.7;
  max-width: 40ch;
  /* Sits opposite the big line, on its baseline: the counterweight. */
  padding-bottom: 0.4rem;
  position: relative;
}

.st-br { display: block; }

/* ---- connected sources ---- */
.sources {
  border-top: 1px solid var(--border);
  padding: var(--s-beat) 0;
  display: grid;
  grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr);
  gap: clamp(2rem, 6vw, 5rem);
  align-items: center;
}
.sources-proof {
  display: flex;
  flex-direction: column;
  gap: 1.75rem;
}
.sources h2 {
  font-size: clamp(1.6rem, 3vw, 2.1rem);
  margin: 0 0 0.85rem;
  max-width: 22ch;
}
.sources p {
  color: var(--muted);
  font-size: 1rem;
  line-height: 1.7;
  margin: 0;
  max-width: 60ch;
}
.chip-row {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
}
.chip {
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  padding: 0.55rem 1.15rem;
  font-size: 0.94rem;
  color: var(--muted);
}
.chip.-on {
  border-color: var(--line-strong);
  color: var(--fg);
  font-weight: 600;
}
.chip.-more { border-style: dashed; }

/* ---- full-width feature bands ---- */
.bands {
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 1.5rem;
}
.band {
  display: grid;
  grid-template-columns: 0.78fr 1.22fr;
  gap: 4.5rem;
  align-items: center;
  /* Bottom is deliberately short: the overlay overhangs into the next
     section, and a full beat here would leave it stranded in a gap. */
  padding: var(--s-beat) 0 var(--s-snug);
  border-top: 1px solid var(--border);
}
/* The overlay hangs below its own section and over the next one. Nothing else
   on the page crosses a boundary, which is exactly why the page read as
   tidy-but-lifeless.

   The band itself has to be raised, not just the overlay. [data-reveal]
   animates `filter`, and a filter value other than `none` creates a stacking
   context, so a z-index set on the overlay alone is trapped inside the band
   and the following section paints over the overhang — which read as the
   overlay being cut off. Raising the band works whether or not the filter has
   finished resolving to `none`. */
.band {
  position: relative;
  z-index: 2;
}
.statement {
  z-index: 1;
}
.band .hud {
  margin-bottom: -5.5rem;
}
.band.-flip .band-copy { order: 2; }
.band.-flip .band-visual { order: 1; }
.band h2 {
  font-size: clamp(1.6rem, 3vw, 2.1rem);
  margin: 0 0 0.85rem;
}
.band p {
  color: var(--muted);
  font-size: 1rem;
  line-height: 1.7;
  margin: 0;
}

/* ---- trust band ---- */
.trust-band {
  background: var(--bg-2);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  padding: var(--s-beat) 1.5rem;
  margin-bottom: 0;
}
.trust-inner {
  max-width: 1280px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: clamp(2rem, 6vw, 4rem);
  align-items: center;
}
.trust-link {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.85rem 1.3rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  font-size: 0.95rem;
  font-weight: 600;
  text-decoration: none;
  color: var(--fg);
  white-space: nowrap;
  transition: border-color 0.2s ease, transform 0.2s ease;
}
.trust-link:hover {
  border-color: var(--fg);
  transform: translateY(-1px);
}
.trust-arrow {
  transition: transform 0.2s ease;
}
.trust-link:hover .trust-arrow { transform: translateX(3px); }
.trust-band h2 {
  font-size: clamp(1.6rem, 3vw, 2.1rem);
  margin: 0 0 0.75rem;
}
.trust-band h2 { max-width: 20ch; }
.trust-band p {
  color: var(--muted);
  max-width: 58ch;
  margin: 0;
  line-height: 1.7;
}
.trust-band a { color: var(--fg); text-decoration-color: var(--line-strong); text-underline-offset: 3px; }

/* ---- closing CTA band ---- */
.cta-band {
  text-align: center;
  padding: var(--s-beat) 1.5rem var(--s-pause);
}
.cta-band h2 {
  font-size: clamp(1.7rem, 3.5vw, 2.3rem);
  margin: 0 0 2.25rem;
}

/* ---- pricing ---- */
/* ---- pricing ----
   Hero and cards share one left edge, the same rule the trust page's boundary
   figure had to learn: an element on its own measure reads as misaligned
   however well composed it is. Both are 1080px, which also stops three cards
   stretching as wide as the four they replaced. */
.pricing-hero {
  max-width: 1180px;
  margin: 0 auto;
  padding: 6.5rem 1.5rem 0;
}
.pricing-hero h1 {
  font-size: clamp(2rem, 4vw, 2.5rem);
  margin: 0 0 0.9rem;
  text-wrap: balance;
}
.pricing-lede {
  color: var(--muted);
  margin: 0;
  max-width: 52ch;
  line-height: 1.6;
  /* Short enough now that the default wrap orphans "weeks." on its own line. */
  text-wrap: balance;
}

/* Left-aligned rather than centred above the cards, because this page hangs
   off one left edge like the rest of the site. */
.billing-toggle {
  display: inline-flex;
  gap: 0.25rem;
  margin-top: 1.75rem;
  padding: 0.25rem;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--card-bg);
}
.billing-toggle[hidden] { display: none; }
.bt-opt {
  font: inherit;
  font-size: 0.88rem;
  color: var(--muted);
  background: none;
  border: 0;
  border-radius: var(--r-pill);
  padding: 0.5rem 1.1rem;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.bt-opt:hover { color: var(--fg); }
.bt-opt.is-on {
  background: var(--strong-bg);
  color: var(--strong-fg);
  font-weight: 600;
}
/* "up to" because the two paid tiers do not discount by the same amount:
   $20→$16 is 20%, $30→$25 is ~17%. */
.bt-save {
  font-size: 0.76rem;
  opacity: 0.75;
  margin-left: 0.15rem;
}

.pricing-grid {
  max-width: 1180px;
  margin: 0 auto;
  padding: 3.5rem 1.5rem 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1rem;
  align-items: stretch;
}
/* Four cards need more room than three; below this they pair up rather than
   squeezing to ~250px each, which is narrower than the longest price line. */
@media (max-width: 1080px) {
  .pricing-grid { grid-template-columns: repeat(2, 1fr); }
}
.plan {
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--card-bg);
  padding: 1.85rem 1.5rem;
  /* Column layout so the CTA can be pushed to the bottom: the three cards
     carry different amounts of copy, and buttons landing at three different
     heights is what made the old row look unfinished. */
  display: flex;
  flex-direction: column;
  transition: transform 0.2s ease, border-color 0.2s ease;
}
.plan:hover { transform: translateY(-2px); }
/* The old featured rule set the same background as .plan, so "featured" was a
   border colour nobody noticed. It now reads at a glance. */
.plan.-featured {
  border-color: var(--line-strong);
  background: var(--card-bg-raised);
  box-shadow: 0 18px 40px -24px var(--shadow-color);
}
/* Absolutely positioned so the badge does not push Pro's heading off the
   baseline the other two cards share — the old layout let it shunt the whole
   card down by its own height. */
.plan .badge {
  position: absolute;
  top: 1.85rem;
  right: 1.5rem;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--strong-fg);
  background: var(--strong-bg);
  border-radius: var(--r-pill);
  padding: 0.2rem 0.6rem;
}
.plan { position: relative; }
.plan h3 {
  font-family: "Hanken Grotesk", sans-serif;
  font-weight: 700;
  margin: 0 0 0.4rem;
  font-size: 1.05rem;
}
/* min-height reserves the second line for the two cards that quote a yearly
   price, so all four plan-lines — and the rules under them — sit on one
   baseline whether or not a card has one. */
.plan .price {
  font-family: "Space Grotesk", monospace;
  font-weight: 500;
  font-size: 1.85rem;
  margin: 0 0 0.6rem;
  line-height: 1.1;
  /* Room for the price plus a yearly line. Sizing is border-box everywhere on
     this site, so these floors have to include padding, not just the text. */
  min-height: 3.5rem;
}
.price-alt {
  display: block;
  font-family: "Hanken Grotesk", sans-serif;
  font-size: 0.78rem;
  font-weight: 400;
  line-height: 1.4;
  margin-top: 0.3rem;
  color: var(--muted);
}
/* Targets the unit by class, not by element. As a bare `span` rule it also
   caught the .amount wrapper the billing toggle needs, shrinking the price
   itself to unit size. */
.plan .price .per {
  font-family: "Hanken Grotesk", sans-serif;
  font-size: 0.8rem;
  font-weight: 400;
  color: var(--muted);
}
/* "Contact us" is not a number and must not shout like one, but the row still
   needs its three prices on one baseline — hence a smaller size that keeps the
   same line box. */
.plan .price.-contact {
  font-size: 1.15rem;
  padding: 0.35rem 0;
  color: var(--muted);
}
/* Two lines reserved: some of these wrap and some do not, and without a floor
   the rules beneath them landed at four different heights across the row. */
.plan-line {
  color: var(--fg);
  font-size: 0.92rem;
  line-height: 1.5;
  min-height: 4rem;
  margin: 0 0 1.1rem;
  padding-bottom: 1.1rem;
  border-bottom: 1px solid var(--border);
}
.plan-list {
  list-style: none;
  margin: 0 0 1.6rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.45;
}
.plan-list li {
  position: relative;
  padding-left: 1rem;
}
.plan-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.58em;
  width: 5px;
  height: 1px;
  background: var(--line-strong);
}
.plan-list strong { color: var(--fg); font-weight: 600; }
/* margin-top:auto pins every CTA to the bottom of its card regardless of how
   much copy sits above it, so the three buttons share one line. */
.plan-cta {
  margin-top: auto;
  align-self: flex-start;
}
/* Sits above the CTA, not below it. Below, its height pushed Pro's button off
   the baseline the other two shared. */
.plan-note {
  margin: 0 0 0.85rem;
  font-size: 0.8rem;
  line-height: 1.45;
  color: var(--muted);
}

.pricing-foot {
  max-width: 1180px;
  margin: 0 auto;
  padding: var(--s-mid) 1.5rem var(--s-pause);
  color: var(--muted);
  font-size: 0.9rem;
}
.pricing-foot p { margin: 0 0 0.5rem; }
.pricing-foot a { color: var(--fg); text-underline-offset: 3px; }

/* ---- the boundary ----
   A trust page made only of prose asks the reader to do all the emotional
   work. This is the one thing to look at rather than read: where the line
   sits. It carries no caption — the two labelled columns already say that
   sound stays and text travels, and the section below it says so a third
   time. It is a diagram of a fact, not an ornament, which is why it earns
   the space.

   Two rules govern the layout, and both were learned the hard way.

   First, the figure shares the page's one measure. Every heading and paragraph
   on this page hangs off a single left edge, so a figure on its own wider,
   centred measure reads as misaligned no matter how well balanced it is
   internally. Same max-width and padding as .doc, therefore same left edge.

   Second, the leftover space is split evenly rather than pooled on the right.
   The two lists are not the same length, and equal halves gave the shorter
   right-hand list far more dead space than the left, tipping the figure's
   weight leftwards. `flex: 1 1 auto` sizes each side to its own content and
   then shares the remainder equally, so neither column starves whichever way
   the copy is later edited. */
.boundary {
  max-width: 760px;
  margin: 0 auto var(--s-beat);
  padding: 0 1.5rem;
  display: flex;
  flex-wrap: wrap;
  gap: clamp(1.5rem, 5vw, 3.5rem);
  align-items: stretch;
}
.b-side {
  /* Basis is the column's own content width; equal grow shares the remainder. */
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  /* Tall enough that the rule shows above and below its label: the copy
     refers to "this line", so there has to be a visible line. */
  padding: 2rem 0;
}
.b-label {
  font-family: "Space Grotesk", ui-monospace, monospace;
  font-size: 0.76rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
/* Marked and tightly set, or three unbulleted lines with generous spacing
   read as free verse rather than as a list of facts. */
.b-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  font-size: 1rem;
  line-height: 1.4;
}
.b-list li {
  position: relative;
  padding-left: 1rem;
}
.b-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 5px;
  height: 1px;
  background: var(--line-strong);
}
/* The left-hand column is the reassuring one, so it reads at full strength
   and the right steps back. */
.b-side:first-child .b-list { color: var(--fg); }
.b-side:last-child .b-list { color: var(--muted); }

.b-line {
  flex: 0 0 1px;
  position: relative;
  width: 1px;
  background: linear-gradient(180deg, transparent, var(--line-strong) 18%, var(--line-strong) 82%, transparent);
}


@media (max-width: 720px) {
  .boundary { flex-direction: column; gap: 0; }
  /* Stacked: the divider becomes a plain rule between the two halves. */
  .b-line {
    flex: 0 0 1px;
    width: auto;
    height: 1px;
    margin: 1.25rem 0;
    background: linear-gradient(90deg, transparent, var(--line-strong) 18%, var(--line-strong) 82%, transparent);
  }
}

/* ---- long-form document pages (trust) ----
   Deliberately no gold anywhere on this page. Gold means "Nuggt found
   something" everywhere else on the site, and a trust page is not the place
   to spend that meaning on a table cell. Emphasis here is carried by weight
   and tone instead. */
.doc-hero {
  max-width: 760px;
  margin: 0 auto;
  padding: var(--s-beat) 1.5rem var(--s-mid);
}
.doc-hero h1 {
  font-size: clamp(2.4rem, 5vw, 3.4rem);
  line-height: 1.05;
  margin: 0 0 1.2rem;
  /* One line on desktop; where it has to wrap, break on the comma rather than
     leaving a one-word orphan. Ignored by older browsers, which simply wrap. */
  text-wrap: balance;
}
.doc-lede {
  font-size: 1.15rem;
  line-height: 1.65;
  color: var(--muted);
  margin: 0 0 1.6rem;
  max-width: 60ch;
}
.doc {
  max-width: 760px;
  margin: 0 auto;
  padding: 0 1.5rem var(--s-pause);
}
.doc-section {
  padding-top: var(--s-mid);
  margin-top: var(--s-mid);
  border-top: 1px solid var(--border);
}
.doc-section:first-child {
  border-top: 0;
  margin-top: 0;
  padding-top: 0;
}
.doc-section h2 {
  font-size: clamp(1.4rem, 2.6vw, 1.8rem);
  margin: 0 0 1.1rem;
}
.doc-section h3 {
  font-family: "Hanken Grotesk", sans-serif;
  font-size: 1.02rem;
  font-weight: 600;
  margin: 0 0 0.35rem;
}
.doc-section p {
  color: var(--muted);
  font-size: 1.02rem;
  line-height: 1.7;
  margin: 0 0 1rem;
  max-width: 68ch;
}
.doc-section p strong,
.doc-points strong {
  color: var(--fg);
  font-weight: 600;
}
.doc-section a {
  color: var(--fg);
  text-underline-offset: 3px;
}

/* the four headline facts */
.doc-points {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.doc-points li {
  position: relative;
  padding-left: 1.2rem;
  color: var(--muted);
  font-size: 1.02rem;
  line-height: 1.65;
  max-width: 68ch;
}
.doc-points li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 5px;
  height: 5px;
  border-radius: var(--r-pill);
  background: var(--line-strong);
}

/* the data-flow sequence: numerals in the brand's numeral face, which is the
   same voice provenance uses elsewhere on the site */
.doc-flow {
  list-style: none;
  counter-reset: flow;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1.9rem;
}
.doc-flow > li {
  counter-increment: flow;
  position: relative;
  padding-left: 2.9rem;
}
.doc-flow > li::before {
  content: counter(flow, decimal-leading-zero);
  position: absolute;
  left: 0;
  top: 0.1rem;
  font-family: "Space Grotesk", ui-monospace, monospace;
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}
.doc-flow > li::after {
  content: "";
  position: absolute;
  left: 0.55rem;
  top: 1.9rem;
  bottom: -1.4rem;
  width: 1px;
  background: var(--border);
}
.doc-flow > li:last-child::after { display: none; }
.doc-flow p { margin: 0; }

/* fact tables */
.doc-table {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--border);
}
.doc-row {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: 1.5rem;
  padding: 0.9rem 0;
  border-bottom: 1px solid var(--border);
  font-size: 0.98rem;
  line-height: 1.55;
  color: var(--muted);
}
.doc-row.-head {
  font-family: "Space Grotesk", ui-monospace, monospace;
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  padding-bottom: 0.6rem;
}
.doc-row > span:first-child { color: var(--fg); }
/* The reassuring answers are the ones worth reading, so they carry the
   weight. No red/green: this site has one accent and it is spoken for. */
.doc-row .-no {
  color: var(--fg);
  font-weight: 600;
}
.doc-row .-yes { color: var(--muted); }

.doc-caveat {
  border-left: 2px solid var(--line-strong);
  padding-left: 1.1rem;
  font-size: 0.96rem !important;
}

@media (max-width: 720px) {
  .doc-row { grid-template-columns: 1fr; gap: 0.3rem; }
  .doc-row.-head { display: none; }
}

/* ---- legal/trust shells ---- */
.legal-shell {
  max-width: 720px;
  margin: 0 auto;
  padding: 6.5rem 1.5rem 8rem;
}
.legal-shell h1 { margin: 0 0 1rem; font-size: 2.25rem; }
.legal-shell .placeholder-note {
  border: 1px dashed var(--border);
  border-radius: var(--r-lg);
  padding: 1.1rem 1.3rem;
  color: var(--muted);
  font-size: 0.95rem;
  background: var(--bg-2);
}
.legal-shell .placeholder-note a { color: var(--fg); text-underline-offset: 3px; }

/* ---- footer ---- */
.site-footer {
  border-top: 1px solid var(--border);
  padding: 3rem 1.5rem 3.5rem;
}
.footer-links {
  max-width: 1280px;
  margin: 0 auto;
  display: flex;
  gap: 1.25rem;
  flex-wrap: wrap;
  font-size: 0.88rem;
}
.footer-links a { text-decoration: none; color: var(--muted); }
.footer-links a:hover { color: var(--fg); }
.footer-copy {
  max-width: 1280px;
  margin: 0.75rem auto 0;
  color: var(--muted);
  font-size: 0.78rem;
}

/* ---- motion ---- */
@keyframes livePulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}
@keyframes glowBreathe {
  from { opacity: 0.72; transform: translateX(-50%) scale(1); }
  to { opacity: 1; transform: translateX(-50%) scale(1.06); }
}

@keyframes vBar {
  0%, 100% { transform: scaleY(0.35); }
  50% { transform: scaleY(1); }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }
  [data-reveal],
  .hero-scene .vline {
    opacity: 1 !important;
    transform: none !important;
    /* The reveal now blurs as well as rises, so the blur has to be cleared
       here too. Resetting only opacity and transform would leave content
       permanently out of focus for anyone who asked for less motion. */
    filter: none !important;
  }
}
/* applied by the reveal script when IntersectionObserver is dead */
.no-anim *, .no-anim *::before, .no-anim *::after {
  animation: none !important;
  transition: none !important;
}
.no-anim [data-reveal],
.no-anim .hero-scene .vline {
  opacity: 1 !important;
  transform: none !important;
  filter: none !important;
}

/* ---- mobile ---- */
@media (max-width: 720px) {
  .h1-br { display: none; }
  .band { grid-template-columns: 1fr; gap: 2rem; padding: 2.5rem 0; }
  .band.-flip .band-copy { order: 1; }
  .band.-flip .band-visual { order: 2; }
  .pricing-grid { grid-template-columns: 1fr; }
  .hero { padding-top: 3.5rem; }
  .hero-scene .voice-track { gap: 1.6rem; }
  .frag-answer { margin-left: 0.75rem; }
  .sources { grid-template-columns: 1fr; gap: 2rem; }
  .statement { grid-template-columns: 1fr; gap: 1.5rem; align-items: start; }
  .statement p { margin-left: 0; }
  .trust-inner { grid-template-columns: 1fr; gap: 2rem; }
  .trust-link { justify-self: start; }
  .showcase { padding: 3.5rem 0 3rem; }
  .showcase-copy { margin-bottom: 2rem; }
  .statement { padding: 3.5rem 0 3rem; }
}
