/* ============================================================
   BLOC landing page
   Every style value comes from tokens.css (the brand sheet), which
   governs all style rules. Layout follows SPEC §6.3 where the sheet
   is silent. The approved exceptions are listed at the top of SPEC §6
   and marked "Exception" below.
   No hex values here: colours only via tokens.
   ============================================================ */


/* ---------- Fonts: self-hosted, Latin only, SIL Open Font Licence ---------- */

@font-face {
  font-family: 'Newsreader';
  src: url('/fonts/newsreader.03fe9e9a.woff2') format('woff2');
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('/fonts/plex-mono-400.0bae798c.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('/fonts/plex-mono-500.b869de80.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('/fonts/plex-mono-600.4e80292f.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}


/* ---------- Grid and spacing: the sheet's mobile, tablet and desktop grids ---------- */

:root {
  --cols: var(--bloc-grid-columns-mobile);
  --gutter: var(--bloc-grid-gutter-mobile);
  --margin: var(--bloc-grid-margin-mobile);
  --section-space: var(--bloc-space-6);
  --header-height: var(--bloc-control-height);  /* 48px on mobile */
  --muted-ink: var(--bloc-ink-muted);           /* switched per ground below */
}
@media (min-width: 48rem) {
  :root {
    --cols: var(--bloc-grid-columns-tablet);
    --gutter: var(--bloc-grid-gutter-tablet);
    --margin: var(--bloc-grid-margin-tablet);
    --section-space: var(--bloc-space-7);
    --header-height: var(--bloc-space-5);       /* 64px on tablet and desktop */
  }
}
@media (min-width: 64rem) {
  :root {
    --cols: var(--bloc-grid-columns);
    --gutter: var(--bloc-grid-gutter);
    --margin: var(--bloc-grid-margin);
  }
}

/* Every text block starts at this container's left edge, at every width. */
.container {
  width: 100%;
  max-width: calc(var(--bloc-grid-max) + 2 * var(--margin));
  margin-inline: auto;
  padding-inline: max(var(--margin), env(safe-area-inset-left)) max(var(--margin), env(safe-area-inset-right));
}

/* Vertical rhythm inside a text block: paragraph to paragraph. */
.flow > * + * { margin-top: var(--bloc-space-3); }


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

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: var(--header-height);
}
body {
  margin: 0;
  overflow-x: clip;
  background: var(--bloc-stone);
  color: var(--bloc-charcoal);
  font-family: var(--bloc-voice);
  font-size: var(--bloc-body-size);
  line-height: var(--bloc-body-line);
  font-weight: var(--bloc-body-weight);
  font-variation-settings: 'opsz' var(--bloc-body-opsz);
}

h1, h2, h3, p, ul { margin: 0; }
h1, h2, h3 { color: var(--bloc-graphite); }
ul { padding: 0; list-style: none; }
img { display: block; max-width: 100%; height: auto; border-radius: var(--bloc-radius); }

a {
  color: inherit;
  text-decoration-thickness: var(--bloc-rule-width);
  text-underline-offset: 0.2em;
}

:focus-visible {
  outline: var(--bloc-focus-width) solid var(--bloc-graphite);
  outline-offset: var(--bloc-focus-offset);
}

/* Dark grounds: Stone text, Stone focus rings, Stone for muted text. */
.on-dark { color: var(--bloc-stone); --muted-ink: var(--bloc-stone); }
.on-dark h2,
.on-dark h3 { color: var(--bloc-stone); }
.on-dark :focus-visible { outline-color: var(--bloc-stone); }

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

/* The skip link (WCAG 2.4.1): the first thing a keyboard reaches, hidden
   until it has focus. Charcoal with Stone text, like the header, never Oxide. */
.skip-link {
  position: fixed;
  top: var(--bloc-space-1);
  left: var(--bloc-space-1);
  z-index: 100;
  display: inline-flex;
  align-items: center;
  min-height: var(--bloc-control-height);
  padding: 0 var(--bloc-control-pad-x);
  background: var(--bloc-charcoal);
  color: var(--bloc-stone);
  text-decoration: none;
  transform: translateY(-200%);
}
.skip-link:focus { transform: none; }
/* The skip link's target takes focus so the next Tab starts there, but it is
   not a control, so it shows no ring. */
main:focus { outline: none; }


/* ---------- Type: one class per style in the sheet ---------- */

/* Newsreader styles. Each declares its optical size, as the sheet requires. */

.t-display {
  font-size: clamp(var(--bloc-display-size), 2rem + 3.5vw, 4.5rem); /* 48px, scaling to 72px */
  line-height: var(--bloc-display-line);
  font-weight: var(--bloc-display-weight);
  letter-spacing: var(--bloc-display-track);
  font-variation-settings: 'opsz' var(--bloc-display-opsz);
}
.t-h1 {
  font-size: var(--bloc-h1-size);
  line-height: var(--bloc-h1-line);
  font-weight: var(--bloc-h1-weight);
  letter-spacing: var(--bloc-h1-track);
  font-variation-settings: 'opsz' var(--bloc-h1-opsz);
}
.t-h2 {
  font-size: var(--bloc-h2-size);
  line-height: var(--bloc-h2-line);
  font-weight: var(--bloc-h2-weight);
  letter-spacing: var(--bloc-h2-track);
  font-variation-settings: 'opsz' var(--bloc-h2-opsz);
}
.t-lead {
  font-size: var(--bloc-lead-size);
  line-height: var(--bloc-lead-line);
  font-weight: var(--bloc-lead-weight);
  font-variation-settings: 'opsz' var(--bloc-lead-opsz);
}
.t-body {
  font-size: var(--bloc-body-size);
  line-height: var(--bloc-body-line);
  font-weight: var(--bloc-body-weight);
  font-variation-settings: 'opsz' var(--bloc-body-opsz);
  max-width: var(--bloc-measure);
}
.t-body-long {
  font-size: var(--bloc-body-long-size);
  line-height: var(--bloc-body-long-line);
  font-weight: var(--bloc-body-long-weight);
  font-variation-settings: 'opsz' var(--bloc-body-long-opsz);
  max-width: var(--bloc-measure-long);
}
.t-small {
  font-size: var(--bloc-small-size);
  line-height: var(--bloc-small-line);
  font-weight: var(--bloc-small-weight);
  font-variation-settings: 'opsz' var(--bloc-small-opsz);
}

/* IBM Plex Mono styles. On mobile the sheet's 10-11px sizes are raised
   to 12px, so no text is ever smaller than 12px on a phone. */

.t-eyebrow {
  font-family: var(--bloc-info);
  font-size: max(0.75rem, var(--bloc-h3-size));
  line-height: var(--bloc-h3-line);
  font-weight: var(--bloc-h3-weight);
  letter-spacing: var(--bloc-h3-track);
  text-transform: uppercase;
  color: var(--bloc-graphite);
}
.t-label {
  font-family: var(--bloc-info);
  font-size: max(0.75rem, var(--bloc-label-size));
  line-height: var(--bloc-label-line);
  font-weight: var(--bloc-label-weight);
  letter-spacing: var(--bloc-label-track);
  text-transform: uppercase;
}
.t-caption {
  font-family: var(--bloc-info);
  font-size: max(0.75rem, var(--bloc-caption-size));
  line-height: var(--bloc-caption-line);
  font-weight: var(--bloc-caption-weight);
  letter-spacing: var(--bloc-caption-track);
  color: var(--muted-ink);
}
@media (min-width: 48rem) {
  .t-body-long { max-width: var(--bloc-measure); }
  .t-eyebrow { font-size: var(--bloc-h3-size); }
  .t-label { font-size: var(--bloc-label-size); }
  .t-caption { font-size: var(--bloc-caption-size); }
}


/* ---------- Controls ---------- */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--bloc-control-height);
  padding: 0 var(--bloc-control-pad-x);
  border: var(--bloc-rule-width) solid transparent;
  border-radius: var(--bloc-radius);
  font-family: var(--bloc-info);
  font-size: var(--bloc-button-size);
  font-weight: var(--bloc-button-weight);
  letter-spacing: var(--bloc-button-track);
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--bloc-t-ui) var(--bloc-ease), color var(--bloc-t-ui) var(--bloc-ease);
}

/* The one Oxide element on any screen. Nothing else may use Oxide. */
.button--primary {
  background: var(--bloc-oxide-action);
  color: var(--bloc-stone);
}
.button--primary:hover { background: var(--bloc-oxide-hover); }
.button--primary:disabled { cursor: progress; }

.button--secondary {
  background: transparent;
  color: var(--bloc-graphite);
  border-color: var(--bloc-graphite);
}
.button--secondary:hover { background: var(--bloc-panel); }
.section--panel .button--secondary:hover { background: var(--bloc-stone); }

/* Stone outline on a dark ground: the header CTA. Never Oxide. */
.button--on-dark {
  background: transparent;
  color: var(--bloc-stone);
  border-color: var(--bloc-stone);
}
.button--on-dark:hover { background: var(--bloc-stone); color: var(--bloc-charcoal); }

.field {
  width: 100%;
  min-height: var(--bloc-control-height);
  padding: 0 var(--bloc-space-2);
  border: var(--bloc-rule-width) solid var(--bloc-control-rule);
  border-radius: var(--bloc-radius);
  background: transparent;
  color: var(--bloc-charcoal);
  font-family: var(--bloc-info);
  font-size: var(--bloc-body-size); /* 16px: smaller makes iPhones zoom in on focus */
  -webkit-appearance: none;
  appearance: none;
}
.field::placeholder { color: var(--bloc-ink-muted); opacity: 1; }

/* Standalone links (footer, terms): a full-height tap target. */
.text-link {
  display: inline-flex;
  align-items: center;
  min-height: var(--bloc-control-height);
  text-decoration: none;
}
.text-link:hover,
.text-link:focus-visible { text-decoration: underline; }

/* Links inside sentences: extra padding widens the tap area to 44px+
   without moving the text around it. */
.t-caption a,
.t-body-long a,
.link-button {
  padding-block: var(--bloc-space-2);
  margin-block: calc(-1 * var(--bloc-space-2));
}
.link-button {
  padding-inline: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: var(--bloc-rule-width);
  text-underline-offset: 0.2em;
  cursor: pointer;
}

/* Line icons: 1.25px strokes in Graphite (Stone on dark grounds), no fills. */
.icon { display: block; width: 2rem; height: 2rem; color: var(--bloc-graphite); }
.on-dark .icon { color: var(--bloc-stone); }
.icon--3 { width: 2.125rem; }  /* three people */
.icon--5 { width: 3.5rem; }    /* five people */


/* ---------- 0. Header ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--bloc-charcoal);
  /* Exception 3 (SPEC §6): on mobile the header slides away on scroll down. */
  transition: transform var(--bloc-t-ui) var(--bloc-ease);
}
.site-header.is-hidden:not(:focus-within) { transform: translateY(-100%); }
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: var(--header-height);
}
.site-header__home {
  display: inline-flex;
  align-items: center;
  min-height: var(--bloc-control-height);
}
.site-header__home img { width: auto; height: 1.25rem; }
.site-header__cta { display: none; }
@media (min-width: 48rem) {
  .site-header__home img { height: var(--bloc-space-3); }
  .site-header__cta { display: inline-flex; }
}


/* ---------- 1. Hero ---------- */

.hero { padding-top: var(--bloc-space-3); }

/* Exception 4 (SPEC §6): the eyebrow is 12px on phones, with the sheet's
   minimum uppercase tracking (0.14em) so it fits one line from 360px wide,
   and 14px from 768px. */
.hero__eyebrow { font-size: 0.75rem; letter-spacing: 0.14em; }

/* The headline block: one H1, two lines, 16px below the eyebrow. */
.hero__title { margin-top: var(--bloc-space-2); }
.hero__line1 { display: block; max-width: 9.5em; text-wrap: pretty; } /* no one-word last line */
/* Exception 4 (SPEC §6): the second line is set at 60% of the first,
   in the sheet's display weight, so it reads as a headline. */
.hero__line2 {
  display: block;
  margin-top: var(--bloc-space-3);
  max-width: 14em;
  font-size: clamp(1.8rem, 1.2rem + 2.1vw, 2.7rem);   /* 60% of the H1 */
  line-height: var(--bloc-display-line);
  font-weight: var(--bloc-display-weight);
  letter-spacing: var(--bloc-display-track);
  font-variation-settings: 'opsz' var(--bloc-display-opsz);
  text-wrap: balance;
}

/* Mobile: the image runs edge to edge straight after the hero block. */
.hero__media { margin: var(--bloc-space-5) calc(-1 * var(--margin)) 0; }

/* From 768px: two columns, so the image is in the first screen. */
@media (min-width: 48rem) {
  .hero { padding-top: var(--bloc-space-4); }
  .hero__eyebrow { font-size: 0.875rem; letter-spacing: var(--bloc-h3-track); }
  .hero__grid {
    display: grid;
    grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
    column-gap: var(--gutter);
    align-items: start;
  }
  .hero__text { grid-column: 1 / 6; padding-bottom: var(--bloc-space-5); }
  .hero__media { grid-column: 6 / -1; margin: 0 calc(-1 * var(--margin)) 0 0; }
}
/* From 1024px: 7 / 5 columns, the image bleeding off the right edge.
   Text and image both start at the top, just under the header. */
@media (min-width: 64rem) {
  .hero__text { grid-column: 1 / 8; }
  .hero__media {
    grid-column: 8 / -1;
    margin: 0 calc(-1 * max(var(--margin), (100vw - var(--bloc-grid-max)) / 2)) 0 0;
  }
}

/* The form: "Join the waitlist." with the launch line beside it, the email
   entry, the consent line directly under it, then the list and the hook. */
.join { margin-top: var(--bloc-space-4); max-width: 36rem; }
.join__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 var(--bloc-space-1);   /* side by side from 375px wide; stacks below that */
  margin-bottom: var(--bloc-space-2);
}
.join__fields {
  display: grid;
  gap: var(--bloc-space-1);
  grid-template-areas: 'email' 'name' 'submit';
}
.join__email { grid-area: email; }
.join__name { grid-area: name; }
.join__submit { grid-area: submit; }
/* Side by side only once the column is wide enough for both. */
@media (min-width: 64rem) {
  .join__fields {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: 'email submit' 'name .';
  }
}
.join__name label { display: block; margin-block: var(--bloc-space-1); color: var(--bloc-graphite); }
.join__error:not(:empty) { margin-top: var(--bloc-space-2); }

/* Form errors (COPY §1): a Charcoal ribbon with Stone text at body size, so
   a problem can't be missed. The sheet makes things stand out by shifting
   the ground; Oxide stays on the one button. Hidden while empty. */
.form-error {
  padding: var(--bloc-space-1) var(--bloc-space-2);
  background: var(--bloc-charcoal);
  color: var(--bloc-stone);
}
.form-error:empty { display: none; }
.join__consent { margin-top: var(--bloc-space-2); }
.join__referral { margin: 0 0 var(--bloc-space-1); } /* above "Join the waitlist.", only with ?ref= */

.joined > * + * { margin-top: var(--bloc-space-2); }

/* Cloudflare's bot check. Invisible unless Cloudflare needs a box ticked;
   then the box appears here, under the button. */
.turnstile.is-asking { margin-top: var(--bloc-space-2); }

/* What the first 200 get: a heading and a ticked list. */
.perks { margin-top: var(--bloc-space-4); }
.perks__list { display: grid; gap: var(--bloc-space-1); margin-top: var(--bloc-space-2); }
.perks__list li {
  display: grid;
  grid-template-columns: 1.25rem minmax(0, 1fr);
  column-gap: var(--bloc-space-2);
  align-items: start;
}
.tick { width: 1.25rem; height: 1.25rem; margin-top: 0.2em; color: var(--bloc-graphite); }

/* The referral hook: a recessed panel with the five-people icon, so it
   stands apart from the small print. Emphasis is weight, per the sheet. */
.hook {
  display: grid;
  gap: var(--bloc-space-2);
  margin-top: var(--bloc-space-4);
  padding: var(--bloc-space-3);
  background: var(--bloc-panel);
}
.hook strong { font-weight: var(--bloc-h2-weight); }
.hook .icon { width: 4.375rem; height: 2.5rem; }   /* the five people, larger */
@media (min-width: 64rem) {
  .hook { grid-template-columns: auto minmax(0, 1fr); align-items: center; column-gap: var(--bloc-space-3); }
}

/* A signed-in member's panel (#ledger, SPEC §3.3). It takes the form's
   place: status, then the referral block on a recessed Panel ground (like
   the hook above), then the quiz prompt. */
.ledger > * + * { margin-top: var(--bloc-space-4); }
.ledger__status > * + * { margin-top: var(--bloc-space-2); }
.ledger__heading > span { display: block; }
.ledger__number { margin-top: var(--bloc-space-1); font-variant-numeric: lining-nums tabular-nums; }

/* Non-founders: the two founding benefits, as a ticked list. */
.ledger__aim .perks__list { margin-top: var(--bloc-space-1); }

/* The referral block. */
.ledger__referral {
  padding: var(--bloc-space-3);
  background: var(--bloc-panel);
  --muted-ink: var(--bloc-charcoal);   /* muted ink is under AA on Panel */
}
.ledger__referral > * + * { margin-top: var(--bloc-space-2); }

/* Progress, for everyone: five steps, filled as friends confirm. Then the
   count, with what's unlocked so far directly under it, in bold. */
.meter {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--bloc-space-1);
  max-width: 20rem;
}
.meter__step { height: var(--bloc-space-1); border: var(--bloc-rule-width) solid var(--bloc-graphite); }
.meter__step.is-done { background: var(--bloc-graphite); }
.ledger__progress [data-progress] { margin-top: var(--bloc-space-2); }
.ledger__progress .ledger__unlocked { margin-top: var(--bloc-space-1); }
.ledger__progress strong,
.ledger__unlocked { font-weight: var(--bloc-h2-weight); }   /* emphasis is weight */

/* The link: "Here's your personal link:", then the link in Mono at the
   share buttons' size, wrapping between its parts (js/ledger.js). */
.ledger__link-label { margin-top: var(--bloc-space-3); }
.ledger__referral > .ledger__link { margin-top: var(--bloc-space-1); }
.ledger__link {
  font-family: var(--bloc-info);
  font-size: var(--bloc-button-size);
  font-weight: var(--bloc-button-weight);
  letter-spacing: var(--bloc-caption-track);
  line-height: var(--bloc-caption-line);
  color: var(--bloc-charcoal);
  overflow-wrap: anywhere;   /* a last resort; the breaks above come first */
}
/* Copy (the panel's one Oxide button), WhatsApp, message: stacked on
   phones; from 768px, Copy across the top and the other two side by side. */
.ledger__share { display: grid; gap: var(--bloc-space-1); }
.ledger__referral .button--secondary:hover { background: var(--bloc-stone); }
@media (min-width: 48rem) {
  .ledger__share { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ledger__share [data-copy] { grid-column: 1 / -1; }
}
.ledger__quiz > * + * { margin-top: var(--bloc-space-2); }
.ledger__quiz strong { font-weight: var(--bloc-h2-weight); }   /* the scent's name: emphasis is weight (05/10/2026) */


/* ---------- The quiz (SPEC §3.4): a full-screen step flow ---------- */

.quiz-open { overflow: hidden; }   /* the page behind doesn't scroll */

/* Sized to the part of the screen you can see (js/quiz.js sets the two
   values from the visual viewport), so a phone's keyboard or an in-app
   browser's bars never hide the question or its buttons. */
.quiz {
  inset: var(--quiz-top, 0) 0 auto 0;
  width: 100%;
  max-width: none;
  height: var(--quiz-height, 100%);
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: var(--bloc-stone);
  color: var(--bloc-charcoal);
  overflow-y: auto;
}
.quiz::backdrop { background: var(--bloc-stone); }
.quiz :focus-visible { outline-color: var(--bloc-graphite); }

/* A column as tall as the screen. */
.quiz__inner {
  display: flex;
  flex-direction: column;
  min-height: 100%;
}

/* Back, progress, close: one bar across the top. */
.quiz__bar {
  display: flex;
  align-items: center;
  gap: var(--bloc-space-3);
  min-height: var(--header-height);
}
.quiz__back { min-height: var(--bloc-control-height); padding-block: 0; margin-block: 0; }
.quiz__progress { margin-right: auto; }
.quiz__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--bloc-control-height);
  height: var(--bloc-control-height);
  margin-left: auto;
  margin-right: calc(-1 * var(--bloc-space-1));
  padding: 0;
  border: 0;
  background: none;
  color: var(--bloc-graphite);
  cursor: pointer;
}

.quiz__stage { padding-top: var(--bloc-space-2); padding-bottom: var(--bloc-space-4); }
@media (min-width: 48rem) {
  .quiz__stage { padding-top: var(--bloc-space-4); }
}
.quiz__step { max-width: var(--bloc-measure); }
.quiz__step > * + * { margin-top: var(--bloc-space-2); }
.quiz__stage > .section__label + .quiz__step { margin-top: var(--bloc-space-2); }
.quiz__fieldset { min-width: 0; margin: 0; padding: 0; border: 0; }
.quiz__fieldset legend { display: block; padding: 0; color: var(--bloc-graphite); }

/* An option: the whole row is the tap target, at least 44px tall. The radio
   itself is visually hidden; its row shows the state. */
.quiz__options { display: grid; gap: var(--bloc-space-1); margin-top: var(--bloc-space-3); }
.quiz__option { display: block; cursor: pointer; }
.quiz__option-text {
  display: flex;
  align-items: center;
  min-height: var(--bloc-control-height);
  padding: var(--bloc-space-1) var(--bloc-space-2);
  border: var(--bloc-rule-width) solid var(--bloc-control-rule);
  border-radius: var(--bloc-radius);
}
.quiz__option:hover .quiz__option-text { background: var(--bloc-panel); }
.quiz__option input:checked + .quiz__option-text {
  background: var(--bloc-graphite);
  border-color: var(--bloc-graphite);
  color: var(--bloc-stone);
}
.quiz__option input:focus-visible + .quiz__option-text {
  outline: var(--bloc-focus-width) solid var(--bloc-graphite);
  outline-offset: var(--bloc-focus-offset);
}

/* The free-text question: a heading, the hint and the limit, then the box. */
.quiz__fix > * + * { margin-top: var(--bloc-space-1); }
.quiz__fix > .quiz__text { margin-top: var(--bloc-space-2); }
.quiz__text { min-height: 8rem; padding: var(--bloc-space-2); resize: vertical; font-family: var(--bloc-voice); line-height: var(--bloc-body-line); }
/* With the keyboard open, everything tightens so the question, the hint, the
   limit, the box, Skip and Finish all fit in what's left of the screen. */
.quiz.is-keyboard-open .quiz__stage { padding-top: 0; padding-bottom: var(--bloc-space-2); }
.quiz.is-keyboard-open .quiz__fix-title {
  font-size: var(--bloc-h2-size);
  line-height: var(--bloc-h2-line);
  font-weight: var(--bloc-h2-weight);
  font-variation-settings: 'opsz' var(--bloc-h2-opsz);
}
.quiz.is-keyboard-open .quiz__text { min-height: 0; height: 5rem; }
.quiz.is-keyboard-open .quiz__actions { margin-top: var(--bloc-space-2); }

.quiz__actions { display: flex; flex-wrap: wrap; gap: var(--bloc-space-1); margin-top: var(--bloc-space-4); }
.quiz__actions .button { flex: 1 1 8rem; }
@media (min-width: 48rem) {
  .quiz__actions .button { flex: 0 0 auto; min-width: 10rem; }
}
/* Next waits for an answer. */
.quiz .button--primary:disabled {
  background: var(--bloc-disabled);
  color: var(--bloc-disabled-ink);
  cursor: default;
}

.quiz__error:not(:empty) { margin-top: var(--bloc-space-2); }
.quiz__email { display: grid; gap: var(--bloc-space-2); margin-top: var(--bloc-space-3); max-width: var(--bloc-measure); }
.quiz__email label.t-label { display: block; margin-bottom: var(--bloc-space-1); color: var(--bloc-graphite); }
.quiz__consent { margin-top: var(--bloc-space-2); }

/* Finding your scent: a bar tied to the real request. It fills to 85% over
   the first 2 seconds and completes only when the reply is in (js/quiz.js).
   Exception 5 in SPEC §6: the one movement beyond the header slide. */
.quiz__meter {
  max-width: 20rem;
  height: var(--bloc-space-1);
  margin-top: var(--bloc-space-3);
  border: var(--bloc-rule-width) solid var(--bloc-graphite);
}
.quiz__meter-fill {
  height: 100%;
  background: var(--bloc-graphite);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 2s var(--bloc-ease);
}
.quiz__meter-fill.is-filling { transform: scaleX(0.85); }
.quiz__meter-fill.is-done { transform: scaleX(1); transition-duration: 0.2s; }
/* Reduced motion: a still bar, part filled, then full when the reply is in. */
@media (prefers-reduced-motion: reduce) {
  .quiz__meter-fill { transition: none; transform: scaleX(0.85); }
  .quiz__meter-fill.is-done { transform: scaleX(1); }
}

/* The reveal: compact. The name, notes and strength line first; the line;
   the way on to Part 2; then "You might also like". */
.quiz__reveal > * + * { margin-top: var(--bloc-space-1); }
.quiz__reveal .section__title { margin-top: 0; }
.quiz__reveal .quiz__strength { margin-top: var(--bloc-space-2); }
.quiz__also {
  margin-top: var(--bloc-space-3);
  padding-top: var(--bloc-space-2);
  border-top: var(--bloc-rule-width) solid var(--bloc-hairline-ink);
}
.quiz__also > * + * { margin-top: var(--bloc-space-1); }

/* The way on to Part 2 (05/10/2026): straight under the result, before
   "You might also like", so it can't be missed. A line in the lead style,
   bold and underlined (the sheet's emphasis is weight), with a line-drawn
   arrow, rather than a full-width block. */
.quiz__next { margin-top: var(--bloc-space-3); }
.quiz__next > * + * { margin-top: var(--bloc-space-1); }
.quiz__next-button {
  display: inline-block;
  min-height: var(--bloc-control-height);
  padding: var(--bloc-space-1) 0;
  border: 0;
  background: none;
  color: var(--bloc-graphite);
  font-family: var(--bloc-voice);
  font-size: var(--bloc-lead-size);
  line-height: var(--bloc-lead-line);
  font-weight: var(--bloc-h2-weight);
  font-variation-settings: 'opsz' var(--bloc-lead-opsz);
  text-align: left;
  text-decoration: underline;
  text-decoration-thickness: var(--bloc-rule-width);
  text-underline-offset: 0.2em;
  cursor: pointer;
}
.quiz__arrow { display: inline-block; width: 1.1em; height: 1.1em; margin-left: 0.3em; vertical-align: -0.2em; }   /* follows the last word */
.quiz__next .t-caption { margin-top: 0; }
.quiz__skip { display: inline-flex; align-items: center; min-height: var(--bloc-control-height); padding-block: 0; margin-block: 0; }


/* ---------- Section system (SPEC §6.3) ---------- */

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

/* Grounds alternate Stone and Panel between the dark bands. Muted ink falls
   just under AA contrast on Panel (4.44:1), so muted text is Charcoal there. */
.section--panel { background: var(--bloc-panel); --muted-ink: var(--bloc-charcoal); }

/* Every section opens with a hairline rule, a label, then the H2. */
.section__head {
  border-top: var(--bloc-rule-width) solid var(--bloc-hairline-ink);
  padding-top: var(--bloc-space-3);
  margin-bottom: var(--bloc-space-3); /* heading to body */
}
.section__label {
  font-family: var(--bloc-info);
  font-size: 0.75rem;                            /* 12px, 13px from tablet up */
  line-height: var(--bloc-caption-line);
  font-weight: var(--bloc-caption-weight);
  letter-spacing: var(--bloc-caption-track);
  color: var(--muted-ink);
}
/* Exception 2 (SPEC §6): section H2s are larger than the sheet's 22px h2,
   in the sheet's display weight, so a long page keeps its hierarchy. */
.section__title {
  margin-top: var(--bloc-space-1);
  max-width: 16em;
  font-size: clamp(2rem, 5vw, 3.5rem);
  line-height: var(--bloc-display-line);
  font-weight: var(--bloc-display-weight);
  letter-spacing: var(--bloc-display-track);
  font-variation-settings: 'opsz' var(--bloc-display-opsz);
  text-wrap: balance;
}
.section__intro { max-width: var(--bloc-measure); }
@media (min-width: 48rem) {
  .section__head { margin-bottom: var(--bloc-space-4); }
  .section__label { font-size: 0.8125rem; }
}

/* Text on the left, image on the right on desktop. */
.split { display: grid; gap: var(--bloc-space-5); }
@media (min-width: 64rem) {
  .split {
    grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
    column-gap: var(--gutter);
    align-items: center;
  }
  .split__text { grid-column: 1 / 7; grid-row: 1; }
  .split__media { grid-column: 8 / -1; grid-row: 1; }
}

/* Statement band: one line set large, Stone on Charcoal. Not a heading. */
.statement {
  padding-block: var(--section-space);
  background: var(--bloc-charcoal);
}
.statement__text { max-width: 12em; text-wrap: balance; }

/* 3. The bar: 2 x 2 on tablet and desktop, stacked on mobile. */
.highlights {
  display: grid;
  gap: var(--bloc-space-5) var(--gutter);
  margin-top: var(--bloc-space-5);
}
@media (min-width: 48rem) {
  .highlights { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.highlight__title { margin-top: var(--bloc-space-2); color: var(--bloc-graphite); }
.highlight p { margin-top: var(--bloc-space-1); }

/* 4. The scents */
.scents__intro { margin-top: var(--bloc-space-5); }
.scents {
  display: grid;
  gap: var(--bloc-space-5) var(--gutter);
  margin-top: var(--bloc-space-3);
}
.scent > * + * { margin-top: var(--bloc-space-1); }
.scents__cta { margin-top: var(--bloc-space-5); }
.scents__quiz { margin-top: var(--bloc-space-2); }   /* the line under the quiz button */
@media (min-width: 48rem) {
  .scents { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* 5. How it works: three points in a row on desktop, then the
   before-and-after image across the full content width. */
.how__grid { display: grid; gap: var(--bloc-space-5) var(--gutter); }
.how__item .icon { margin-bottom: var(--bloc-space-2); }
.how__item h3 { margin-bottom: var(--bloc-space-1); }
.how__media { margin-top: var(--bloc-space-5); }
@media (min-width: 64rem) {
  .how__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* 6. Founding: the one section on a Graphite ground. */
.founding { background: var(--bloc-graphite); }
.founding__intro { max-width: var(--bloc-measure); }
/* The benefits follow the H2 directly; in the full state, the two lines
   above them come first. */
.benefits {
  display: grid;
  gap: var(--bloc-space-4) var(--gutter);
}
.founding .flow:not([hidden]) + .benefits { margin-top: var(--bloc-space-5); }
.benefit h3 { margin-bottom: var(--bloc-space-1); }
@media (min-width: 48rem) {
  .benefits { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* Referral block: heading, body, the two reward tiers and the terms link. */
.referral { margin-top: var(--bloc-space-6); max-width: var(--bloc-measure); }
.referral h3 { margin-bottom: var(--bloc-space-2); }
.tiers {
  display: grid;
  gap: var(--bloc-space-3) var(--bloc-space-5);
  margin-block: var(--bloc-space-4) var(--bloc-space-2);
}
.tier {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--bloc-space-1) var(--bloc-space-2);
}
@media (min-width: 48rem) {
  .tiers { grid-template-columns: repeat(2, max-content); }
}

.founding .counter { margin-top: var(--bloc-space-5); }
.founding__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--bloc-space-2) var(--bloc-space-4);
  margin-top: var(--bloc-space-5);
}
/* Oxide and Graphite are close in brightness, so the button gets a
   1px Stone outline here to keep its edge visible. */
.founding .button--primary { border-color: var(--bloc-stone); }


/* 8. Founder note */
.founder .split__media { max-width: 20rem; }
.founder__sign > * { display: block; }
.founder__sign .t-caption { margin-top: var(--bloc-space-1); }
@media (min-width: 64rem) {
  .founder .split__media { max-width: none; }
  .founder .split__media { grid-column: 9 / -1; }
}

/* 9. FAQ: native details, separated by hairlines. */
@media (min-width: 64rem) {
  .faq__list { max-width: calc(8 / 12 * 100%); }
}
.faq__item { border-top: var(--bloc-hairline) solid var(--bloc-hairline-ink); }
.faq__item:last-child { border-bottom: var(--bloc-hairline) solid var(--bloc-hairline-ink); }
.faq__item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--bloc-space-2);
  min-height: var(--bloc-control-height);
  padding-block: var(--bloc-space-2);
  color: var(--bloc-graphite);
  list-style: none;
  cursor: pointer;
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__item summary::after {
  content: '+';
  content: '+' / '';
  font-family: var(--bloc-info);
}
.faq__item[open] summary::after {
  content: '\2212';
  content: '\2212' / '';
}
.faq__item p { padding-bottom: var(--bloc-space-3); }


/* ---------- Legal pages: /terms and /privacy ---------- */

.legal { padding-block: var(--section-space); }
.legal__body { max-width: var(--bloc-measure); }
.legal__part { margin-top: var(--bloc-space-5); }
.legal__part > * + * { margin-top: var(--bloc-space-2); }
.legal ol,
.legal ul { padding-left: 1.5em; }
.legal ol { list-style: decimal; }
.legal ul { list-style: disc; }
.legal li + li,
.legal li > ul { margin-top: var(--bloc-space-1); }

/* ---------- Confirm page: /confirm ---------- */

/* One state at a time, each opening with the section system's hairline. */
.confirm { padding-block: var(--section-space); }
.confirm__state {
  max-width: var(--bloc-measure);
  border-top: var(--bloc-rule-width) solid var(--bloc-hairline-ink);
  padding-top: var(--bloc-space-3);
}
.confirm__state > * + * { margin-top: var(--bloc-space-3); }
.confirm__form { display: grid; gap: var(--bloc-space-1); max-width: 36rem; }
.confirm__form .turnstile.is-asking { margin-top: 0; } /* the grid gap spaces it */

/* What we collect: a hairline table, stacked into blocks on phones. */
.data-table { width: 100%; margin-top: var(--bloc-space-3); border-collapse: collapse; }
.data-table th,
.data-table td {
  padding: var(--bloc-space-2) var(--bloc-space-2) var(--bloc-space-2) 0;
  border-bottom: var(--bloc-hairline) solid var(--bloc-hairline-ink);
  text-align: left;
  vertical-align: top;
}
.data-table th { color: var(--bloc-graphite); }
@media (max-width: 47.99rem) {
  .data-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .data-table tr { display: block; padding-block: var(--bloc-space-2); border-bottom: var(--bloc-hairline) solid var(--bloc-hairline-ink); }
  .data-table td { display: block; padding: 0; border: 0; }
  .data-table td + td { margin-top: var(--bloc-space-1); }
  /* Each cell names its column, in the section-label style. */
  .data-table td::before {
    content: attr(data-label);
    display: block;
    font-family: var(--bloc-info);
    font-size: 0.75rem;
    font-weight: var(--bloc-caption-weight);
    letter-spacing: var(--bloc-caption-track);
    color: var(--muted-ink);
  }
}


/* ---------- 10. Footer ---------- */

/* Content and wordmark share one grid cell: text in front, wordmark behind. */
.footer {
  display: grid;
  overflow: hidden;
  background: var(--bloc-charcoal);
}
.footer > * { grid-area: 1 / 1; }
.footer__content {
  position: relative;
  z-index: 1;
  padding-block: var(--bloc-space-5);
}
.footer__links {
  display: flex;
  flex-wrap: wrap;
  column-gap: var(--bloc-space-4);
}
.footer__legal {
  margin-top: var(--bloc-space-3);
  padding-top: var(--bloc-space-3);
  border-top: var(--bloc-hairline) solid var(--bloc-hairline-ink);
  opacity: 0.7;
}

/* The signature: the outlined BLOC wordmark, edge to edge, set into the floor.
   The SVG file is used as a mask, so its colour comes from the token.
   Exception 1 (SPEC §6): Aluminium at 20%, its one use on screen.
   The numbers crop the SVG's own margins so the B and C touch both edges,
   and cut the letters about 6% into their baseline (SPEC §6.4). */
.footer__wordmark {
  position: relative;
  z-index: 0;
  align-self: end;
  width: 100%;
  aspect-ratio: 5980 / 1336;
  background-color: var(--bloc-aluminium);
  opacity: 0.2;
  -webkit-mask: url('/assets/bloc-wordmark.svg') 50% 27.2% / 102.98% auto no-repeat;
  mask: url('/assets/bloc-wordmark.svg') 50% 27.2% / 102.98% auto no-repeat;
}


/* ---------- Mobile sticky join bar ---------- */

.sticky-join {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 10;
  /* Extra bottom padding clears the iPhone home indicator. */
  padding: var(--bloc-space-1) var(--margin) calc(var(--bloc-space-1) + env(safe-area-inset-bottom));
  background: var(--bloc-stone);
  border-top: var(--bloc-hairline) solid var(--bloc-hairline-ink);
}
.sticky-join .button { width: 100%; }
@media (max-width: 47.99rem) {
  /* Keeps focused fields clear of the sticky bar. */
  html { scroll-padding-bottom: var(--bloc-space-6); }
}
@media (min-width: 48rem) {
  .sticky-join { display: none; }
}


/* ---------- Reduced motion ---------- */

/* People who ask for less motion get none: the header's slide and the hover
   changes are instant. (The quiz's progress bar has its own rule above.) */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
