/* Shared layout primitives. Scaffolding only — not final visual design. */

.sb-container {
  width: 100%;
  max-width: var(--sb-container-max-width);
  margin-inline: auto;
  padding-inline: var(--sb-space-md);
}

.sb-site {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.sb-main {
  flex: 1;
  padding-block: var(--sb-space-lg);
}

.sb-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-block: var(--sb-space-md);
}

.sb-footer__inner {
  display: flex;
  flex-direction: column;
  gap: var(--sb-space-xs);
  padding-block: var(--sb-space-md);
}

/* ==========================================================================
   Main hero prototype — scoped to the Main site only.
   Everything below is namespaced under `.main-hero*` or scoped behind the
   `.sb-site--main` body class so Worlds/FirstMove (which reuse the same
   shared/includes/header.php, shared/components/logo.php and
   navigation.php) are completely unaffected. The shared placeholder
   header is hidden on Main only; main-hero__header replaces it with its
   own markup rendered from public/main/index.php.
   ========================================================================== */

.sb-site--main {
  /* The .main-hero full-bleed breakout below uses a 100vw/negative-margin
     trick, which can overhang by the scrollbar width on desktop browsers
     with classic (non-overlay) scrollbars. Contain that here rather than
     touching shared reset.css. */
  overflow-x: hidden;
}

.sb-site--main .sb-header {
  display: none;
}

.sb-site--main .sb-footer {
  display: none;
}

.sb-site--main .sb-main {
  padding-block: 0;
}

/* --- Custom glass header (Main only) ---
   A floating panel that shares the hero content's grid, not an
   independent capsule floating in the middle: the outer element carries
   a small constant inset (`--sb-space-md` on the sides, so the panel
   never touches the true viewport edge) plus the top floating gap, and
   `.main-hero__header-inner` is sized so that — at every viewport width,
   capped or uncapped — its own left/right padding lands the logo/nav
   exactly on `.main-hero__content`'s padding edge (where the headline
   starts). The max-width and padding-inline below are deliberately
   `calc()`'d off the same tokens `.main-hero__content` uses
   (`--sb-container-wide` / `--sb-space-lg`), minus the outer inset
   (`--sb-space-md` on each side), so the two stay in lockstep: if either
   token changes, this alignment keeps holding without retuning. See
   components.css for the visual (glass/blur/shadow) treatment. */

.main-hero__header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  padding: 1.25rem var(--sb-space-md) 0;
}

/* Top scrim: the header's own footprint only covers the glass panel
   itself (inset from the true edges), so without this, scrolling text
   is still visible through the gaps above/around the floating panel —
   the "tab/overlap" artifact.

   `position: fixed` (not `absolute`) is deliberate: an absolutely
   positioned `::before` resolves `top: 0` against the nearest positioned
   ancestor's padding-box edge, which *should* coincide with the
   viewport top here (the header has no border), but that makes the
   scrim's anchoring dependent on the header's box model staying exactly
   as-is — fragile, and a real gap was still visible in practice.
   `position: fixed; top: 0;` anchors directly and unambiguously to the
   viewport itself, with no dependency on the parent's padding/border at
   all, guaranteeing full coverage from y=0 regardless of header box
   changes later.

   Stacking still nests correctly even though this is now `fixed`: a
   pseudo-element's containing block for *position* can be the viewport,
   but its stacking context is still determined by DOM ancestry — since
   `.main-hero__header` (the parent) already creates a stacking context
   via `z-index: 50`, this `z-index: -1` descendant still paints *below*
   its static sibling `.main-hero__header-inner` (which always paints
   above negative-z-index descendants in the same context) while the
   whole `z-index: 50` layer paints above ordinary page content.

   Taller than the header's own ~81px footprint so the gradient has room
   to fade out below it, not cut off sharply. `pointer-events: none` so
   it never intercepts clicks. See components.css for the gradient
   itself. */

.main-hero__header::before {
  content: "";
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 7.5rem;
  z-index: -1;
  pointer-events: none;
}

.main-hero__header-inner {
  width: 100%;
  max-width: calc(var(--sb-container-wide) - 2 * var(--sb-space-md));
  margin-inline: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sb-space-md);
  padding: 0.65rem calc(var(--sb-space-lg) - var(--sb-space-md));
}

.main-hero__nav {
  display: flex;
  align-items: center;
  gap: var(--sb-space-lg);
}

/* --- Hero: full-bleed, breaks out of the shared .sb-container --- */

.main-hero {
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  align-items: center;
  overflow: hidden;
  background-color: var(--sb-color-bg);
}

.main-hero__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-size: cover;
  background-position: center;
}

.main-hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (prefers-reduced-motion: reduce) {
  .main-hero__video {
    display: none;
  }
}

.main-hero__overlay,
.main-hero__glow {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}

.main-hero__content {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--sb-container-wide);
  margin-inline: auto;
  padding-inline: var(--sb-space-lg);
  padding-block: 6rem var(--sb-space-xl);
}

.main-hero__content-inner {
  display: flex;
  flex-direction: column;
  gap: var(--sb-space-sm);
  max-width: 36rem;
}

/* Graduated rhythm: each boundary gets a deliberate amount of extra space
   on top of the content-inner's base gap, instead of one uniform gap for
   every element — eyebrow stays close to the headline, while the actions
   and supporting line get clearer separation. */

.main-hero__subheadline {
  margin-block-start: 0.375rem;
}

.main-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sb-space-md);
  margin-block-start: 1.25rem;
}

.main-hero__supporting {
  margin-block-start: 0.5rem;
}

.main-hero__scrollhint {
  position: absolute;
  left: 50%;
  bottom: var(--sb-space-lg);
  transform: translateX(-50%);
  z-index: 2;
}

/* --- First continuation section: "Conversation becomes a place."
   Editorial two-column split (intro text / three short points), not a
   features grid — kept compact rather than a long section. Background
   is the same `--sb-color-bg` the hero overlay already fades into, so
   there's no hard seam between hero and section.

   Top padding: the fixed header renders at ~89px tall on desktop (~70px
   on mobile) and never leaves the viewport — `6rem` (96px) clears it
   with margin at both breakpoints, matching the value
   `.main-hero__content` already uses for the same purpose. (No
   `scroll-margin-top` here anymore — `#request-access` now lives on
   `.main-cta`, the actual final CTA section, see below.) --- */

.main-continuation {
  background-color: var(--sb-color-bg);
  padding-block: 6rem calc(var(--sb-space-xl) * 1.5);
}

.main-continuation__inner {
  width: 100%;
  max-width: var(--sb-container-wide);
  margin-inline: auto;
  padding-inline: var(--sb-space-lg);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: var(--sb-space-xl);
  align-items: start;
}

.main-continuation__intro {
  display: flex;
  flex-direction: column;
  gap: var(--sb-space-sm);
  max-width: 28rem;
}

.main-continuation__points {
  display: flex;
  flex-direction: column;
}

.main-continuation__point {
  padding-block: var(--sb-space-md);
  border-top: 1px solid var(--sb-color-border);
}

@media (max-width: 768px) {
  .main-continuation__inner {
    grid-template-columns: 1fr;
    gap: var(--sb-space-lg);
  }
}

/* --- Second continuation section: "One platform. Many kinds of worlds."
   Centered intro above a three-column editorial row, divided by hairline
   rules instead of cards — deliberately a different arrangement from
   `.main-continuation` above (which splits intro/list left-right) so the
   page doesn't repeat the same block twice, while staying in the same
   restrained, border-only visual language. Kept compact: one intro
   block plus three short items, no grid of boxes. --- */

.main-platform {
  background-color: var(--sb-color-bg);
  /* Top value matches `.main-continuation`'s fixed-header safe-area fix
     above — same reasoning, this section can also become the top-of-
     viewport content during normal scroll. */
  padding-block: 6rem var(--sb-space-xl);
}

.main-platform__inner {
  width: 100%;
  max-width: var(--sb-container-wide);
  margin-inline: auto;
  padding-inline: var(--sb-space-lg);
}

.main-platform__intro {
  display: flex;
  flex-direction: column;
  gap: var(--sb-space-sm);
  max-width: 38rem;
  margin-inline: auto;
  margin-bottom: var(--sb-space-xl);
  text-align: center;
}

.main-platform__cases {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sb-space-lg);
}

.main-platform__case {
  padding-inline-start: var(--sb-space-lg);
  border-left: 1px solid var(--sb-color-border);
}

.main-platform__case:first-child {
  padding-inline-start: 0;
  border-left: none;
}

@media (max-width: 768px) {
  .main-platform__cases {
    grid-template-columns: 1fr;
    gap: var(--sb-space-md);
  }

  .main-platform__case {
    padding-inline-start: 0;
    padding-block-start: var(--sb-space-md);
    border-left: none;
    border-top: 1px solid var(--sb-color-border);
  }

  .main-platform__case:first-child {
    padding-block-start: 0;
    border-top: none;
  }
}

/* --- Final CTA: "Build the first worlds with us."
   A single compact, centered panel — not a full-width signup banner —
   so it reads as one last deliberate moment, not another content
   section. `#request-access` (the hero/header CTA anchor target) now
   lives here; same fixed-header safe-area reasoning as the two sections
   above applies, hence the matching `6rem` top padding and
   `scroll-margin-top`. --- */

.main-cta {
  background-color: var(--sb-color-bg);
  padding-block: 6rem var(--sb-space-xl);
  scroll-margin-top: 6rem;
}

.main-cta__inner {
  width: 100%;
  /* Widened from the original 36rem to comfortably fit the two-column
     field rows in the early-access form without feeling cramped — still
     a compact, centered panel, not a full-width banner. */
  max-width: 40rem;
  margin-inline: auto;
  padding: var(--sb-space-xl) var(--sb-space-lg);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sb-space-md);
  text-align: center;
}

/* --- Legal pages (Main only): Privacy, Cookies, AI Notice, Terms, Do Not
   Sell or Share (public/main/{privacy,cookies,ai-notice,terms,do-not-
   sell-or-share}.php). Same fixed-header safe-area top padding as the
   other sections; narrower than the page's other sections since this is
   long-form reading content, not a wide layout. --- */

.main-legal {
  background-color: var(--sb-color-bg);
  padding-block: 6rem var(--sb-space-xl);
}

.main-legal__shell {
  width: 100%;
  max-width: 42rem;
  margin-inline: auto;
}

@media (max-width: 640px) {
  .main-legal__shell {
    max-width: 100%;
  }
}

/* --- Real footer (Main only) — replaces the shared scaffolding footer,
   which is hidden for this site via `.sb-site--main .sb-footer` above.
   Same top safe-area padding as the other sections for consistency,
   even though the footer being the last element on the page makes a
   persistent overlap unlikely — avoids even a brief flicker during the
   scroll motion that reaches the bottom of the page. --- */

.main-footer {
  background-color: var(--sb-color-bg);
  border-top: 1px solid var(--sb-color-border);
}

.main-footer__inner {
  width: 100%;
  max-width: var(--sb-container-wide);
  margin-inline: auto;
  padding-inline: var(--sb-space-lg);
  /* Bottom value trimmed from --sb-space-xl now that the legal links row
     below adds its own padding-block — keeps the total gap between the
     copyright line and the legal row proportionate instead of doubling
     up on bottom spacing. */
  padding-block: 6rem var(--sb-space-lg);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sb-space-md);
}

.main-footer__brand {
  display: flex;
  flex-direction: column;
  gap: var(--sb-space-xs);
}

.main-footer__nav {
  display: flex;
  gap: var(--sb-space-lg);
}

@media (max-width: 640px) {
  .main-footer__inner {
    flex-direction: column;
    align-items: center;
    text-align: center;
  }
}

/* --- Quiet legal links row (Main only) — visually subordinate to the
   main footer row above it: smaller text, muted color (see
   components.css), separated by a thin top border instead of competing
   for attention with the brand/nav/copyright row. --- */

.main-footer__legal-row {
  border-top: 1px solid var(--sb-color-border);
}

.main-footer__legal {
  width: 100%;
  padding-inline: var(--sb-space-lg);
  padding-block: var(--sb-space-md);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sb-space-sm) var(--sb-space-lg);
}

/* --- Responsive --- */

@media (max-width: 640px) {
  .main-hero__nav-link {
    display: none;
  }

  .main-hero__header {
    padding: 0.75rem 0.75rem 0;
  }

  .main-hero__header-inner {
    /* Same alignment logic as the base rule above: outer 0.75rem +
       inner 1.25rem = content's 2rem padding, so the logo still lines
       up with the headline at this breakpoint too. */
    padding: 0.55rem 1.25rem;
  }

  .main-hero__content {
    padding-block: 5rem var(--sb-space-lg);
  }

  .main-hero__actions {
    flex-direction: column;
    align-items: stretch;
  }
}

/* ==========================================================================
   Worlds hero v1 — scoped to the Worlds site only, mirrors the Main hero's
   structural pattern (fixed glass header, full-bleed video hero, content
   sections, custom footer) but entirely namespaced under `.worlds-*` so
   nothing here can collide with or affect `.main-*` selectors. See
   components.css for the colour/gradient treatment that differentiates
   Worlds (cyan-led, grid-textured) from Main despite sharing the same
   hero-background video assets on purpose.
   ========================================================================== */

.sb-site--worlds {
  /* Same scrollbar-overhang containment as `.sb-site--main` above, needed
     for the same reason: `.worlds-hero`'s 100vw/negative-margin breakout. */
  overflow-x: hidden;
}

.sb-site--worlds .sb-header {
  display: none;
}

.sb-site--worlds .sb-footer {
  display: none;
}

.sb-site--worlds .sb-main {
  padding-block: 0;
}

/* --- Custom glass header (Worlds only). Unlike Main's header, this has
   no scroll-linked "firms up" state — shared/scripts/main.js only
   targets `.main-hero__header` by exact class name, and extending that
   shared script is out of scope here, so this header just renders in a
   single, already-legible glass state at all scroll positions. --- */

.worlds-hero__header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  padding: 1.25rem var(--sb-space-md) 0;
}

.worlds-hero__header::before {
  content: "";
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 7.5rem;
  z-index: -1;
  pointer-events: none;
}

.worlds-hero__header-inner {
  width: 100%;
  max-width: calc(var(--sb-container-wide) - 2 * var(--sb-space-md));
  margin-inline: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sb-space-md);
  padding: 0.65rem calc(var(--sb-space-lg) - var(--sb-space-md));
}

.worlds-hero__nav {
  display: flex;
  align-items: center;
  gap: var(--sb-space-lg);
}

/* --- Hero: full-bleed, breaks out of the shared .sb-container, same
   technique as `.main-hero`. --- */

.worlds-hero {
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  align-items: center;
  overflow: hidden;
  background-color: var(--sb-color-bg);
}

.worlds-hero__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-size: cover;
  background-position: center;
}

.worlds-hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (prefers-reduced-motion: reduce) {
  .worlds-hero__video {
    display: none;
  }
}

.worlds-hero__overlay,
.worlds-hero__grid,
.worlds-hero__glow {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}

.worlds-hero__content {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--sb-container-wide);
  margin-inline: auto;
  padding-inline: var(--sb-space-lg);
  padding-block: 6rem var(--sb-space-xl);
}

.worlds-hero__content-inner {
  display: flex;
  flex-direction: column;
  gap: var(--sb-space-sm);
  max-width: 36rem;
}

.worlds-hero__subheadline {
  margin-block-start: 0.375rem;
}

/* --- Hero early-access form: reuses `.worlds-cta__form`'s structural
   properties (flex column, gap, text-align) and `.worlds-cta__row`'s
   two-column-collapsing-to-one grid (see the `.worlds-cta__row` mobile
   override below) for the field/row/button mechanics; this rule adds
   the breathing room from the subheadline above. This is the only
   early-access form on the page. The `#request-access` anchor target is
   `.worlds-hero__form-wrap` (below), not the form/success element
   itself — that wrapper is the common ancestor of the success message,
   the form-level error message, and the form, so a nav-CTA jump or a
   failed/succeeded POST back to `#request-access` always lands with
   whichever of those is showing fully in view, not scrolled past it. */

.worlds-hero__form {
  margin-block-start: 1.25rem;
}

.worlds-hero__form-success {
  margin-block-start: 1.25rem;
}

/* `scroll-margin-top` matches the fixed header's height so the jump
   lands below it instead of being covered, on both desktop and mobile
   (mobile's header is shorter, so this conservative value still clears
   it with a little extra room to spare). */
.worlds-hero__form-wrap {
  scroll-margin-top: 6rem;
}

/* Visually-hidden label for the compact hero fields — placeholder text
   carries the visible cue ("Name" / "Email") to keep the hero form
   compact, while this keeps an accessible label in the a11y tree. */
.worlds-hero__form-label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.worlds-hero__scrollhint {
  position: absolute;
  left: 50%;
  bottom: var(--sb-space-lg);
  transform: translateX(-50%);
  z-index: 2;
}

/* --- Value proposition section, right after the hero ("From a word to
   a world."): headline + body + three step cards + a "Learn more" anchor
   jump down to `.worlds-details`. Replaces the earlier
   conversation/process/cases sections (same `.worlds-cta__inner`-style
   glass-card treatment reused for the step cards — see components.css). --- */

.worlds-value {
  background-color: var(--sb-color-bg);
  padding-block: 6rem var(--sb-space-xl);
}

.worlds-value__inner {
  width: 100%;
  max-width: var(--sb-container-wide);
  margin-inline: auto;
  padding-inline: var(--sb-space-lg);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sb-space-lg);
}

/* `.worlds-value__headline` intentionally has no max-width here: at this
   headline's font-size, "From a word to a world." is ~500px on one
   line — a 30rem (480px) cap used to force an awkward two-line break
   ("...to a" / "world."). Letting it size off the actual available
   width keeps it on one line on desktop and lets it wrap naturally (not
   via an arbitrary cap) once the viewport is genuinely narrow. */

.worlds-value__body {
  max-width: 42rem;
}

.worlds-value__steps {
  width: 100%;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sb-space-lg);
}

.worlds-value__step {
  padding: var(--sb-space-lg);
  border-radius: var(--sb-radius-lg);
}

@media (max-width: 768px) {
  .worlds-value {
    padding-block: 3.5rem var(--sb-space-lg);
  }

  .worlds-value__steps {
    grid-template-columns: 1fr;
    gap: var(--sb-space-md);
  }
}

/* --- Detailed "how it works" content, unfolded by `.worlds-value`'s
   "Learn more" button (`#worlds-details` — see shared/scripts/main.js
   for the small progressive-enhancement script that collapses it via
   the `hidden` attribute and toggles it on click). With no JS, the
   `hidden` attribute is never applied in the first place, so this stays
   fully visible and reachable by scrolling — see main.js for why this
   approach was chosen over baking a collapsed state into the markup
   itself. A flat sequence of heading+list/copy groups rather than
   nested subsections, matching how the content itself is structured.
   `scroll-margin-top` matches the fixed header's height, same
   convention as the hero form below. --- */

.worlds-details {
  background-color: var(--sb-color-bg);
  padding-block: var(--sb-space-xl);
  scroll-margin-top: 6rem;
}

.worlds-details__inner {
  width: 100%;
  max-width: var(--sb-container-wide);
  margin-inline: auto;
  padding-inline: var(--sb-space-lg);
  display: flex;
  flex-direction: column;
  /* ~50% more than the previous 4rem (var(--sb-space-xl)) — breathing
     room between groups, not inside any single group's own rows; this
     is the only gap that changed here, .worlds-details's own
     padding-block (the space before the footer) is untouched. */
  gap: calc(var(--sb-space-xl) * 1.5);
}

/* Restored immersive-creation visual (see source-media/visuals/worlds/
   for the source and assets/visuals/worlds/ for the deployed webp/jpg)
   — now a right-side panel paired with the "How a world takes shape"
   copy via `.worlds-details__group--visual` below, not the full-width
   standalone banner it briefly was, and not a revival of the old
   two-column layout's chat-bubble/orbit UI either (just the right-side
   image relationship). `aspect-ratio` switches per breakpoint exactly
   as before — wide cinematic 5:3 on desktop, 4:3 (the source image's
   native ratio) on mobile, so the full composition stays visible with
   no meaningful crop. The crop itself is `object-fit: cover` on the one
   underlying image, not separate cropped files. */
.worlds-details__visual {
  position: relative;
  overflow: hidden;
  border-radius: var(--sb-radius-lg);
  aspect-ratio: 5 / 3;
}

.worlds-details__visual-image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (max-width: 768px) {
  .worlds-details__visual {
    aspect-ratio: 4 / 3;
  }
}

.worlds-details__group {
  display: flex;
  flex-direction: column;
  gap: var(--sb-space-md);
}

/* First group only ("How a world takes shape") — copy/steps on the
   left, the restored visual on the right. Text column kept wider than
   the image column (1.4fr vs 1fr) so the panel reads as a supporting
   visual, not a competing hero image. */
.worlds-details__group--visual {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  align-items: center;
  gap: var(--sb-space-xl);
}

.worlds-details__group-copy {
  display: flex;
  flex-direction: column;
  gap: var(--sb-space-md);
}

.worlds-details__group-body {
  max-width: 42rem;
}

.worlds-details__steps {
  display: flex;
  flex-direction: column;
}

.worlds-details__step {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--sb-space-sm);
  padding-block: var(--sb-space-md);
  border-top: 1px solid var(--sb-color-border);
}

.worlds-details__step:first-child {
  border-top: none;
  padding-top: 0;
}

.worlds-details__list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sb-space-md) var(--sb-space-xl);
}

.worlds-details__item {
  display: flex;
  align-items: flex-start;
  gap: var(--sb-space-sm);
}

.worlds-details__item-mark {
  flex-shrink: 0;
  margin-top: 0.5rem;
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 50%;
}

@media (max-width: 768px) {
  .worlds-details {
    padding-block: 3.5rem var(--sb-space-lg);
  }

  .worlds-details__inner {
    /* Same ~50% increase as the desktop gap above, scaled from this
       breakpoint's own previous value (var(--sb-space-lg), 2rem). */
    gap: calc(var(--sb-space-lg) * 1.5);
  }

  .worlds-details__group--visual {
    grid-template-columns: 1fr;
    gap: var(--sb-space-md);
  }

  .worlds-details__list {
    grid-template-columns: 1fr;
  }
}

/* --- Early-access form field mechanics (Worlds only). The form itself
   now lives in the hero (`.worlds-hero__form`, the `#request-access`
   anchor target — see its `scroll-margin-top` above), but these
   `.worlds-cta__*` field/row/honeypot/success classes are kept and
   reused there since the field styling intentionally mirrors Main's
   `.main-cta__*` values exactly (border, background, focus ring already
   Lucid Cyan there too), so the form doesn't need a separate
   "Worlds-ified" visual pass — see components.css. --- */

.worlds-cta__form {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--sb-space-md);
  text-align: left;
}

.worlds-cta__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sb-space-md);
}

.worlds-cta__field {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.worlds-cta__hp {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  left: -9999px;
}

.worlds-cta__success {
  width: 100%;
  padding: var(--sb-space-md) var(--sb-space-lg);
  border: 1px solid var(--sb-color-border);
  border-radius: var(--sb-radius-sm);
  background-color: rgba(85, 221, 251, 0.08);
}

@media (max-width: 640px) {
  .worlds-cta__row {
    grid-template-columns: 1fr;
  }
}

/* --- Inline action row next to "Learn more" — a plain flex row, not a
   new section/card, so the default collapsed view gets a "Request
   access" action without adding any new visual block. Sits inside
   `.worlds-value__inner` (itself `align-items: flex-start`), so this row
   stays left-aligned with the rest of the value-prop content instead of
   stretching/centering. `flex-wrap` lets it wrap on narrow screens
   instead of overflowing. --- */
.worlds-value__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sb-space-md);
}

/* --- Closing CTA at the end of the expanded details content (after
   "Who it's for"), before the footer. A compact divider-strip, same
   hairline pattern as `.worlds-details__step`'s own `border-top`, not a
   bordered/shadowed card — deliberately lighter than the page's glass-
   card treatment so it reads as a closing line, not a second hero. --- */
.worlds-final-cta {
  padding-block: var(--sb-space-lg) 0;
  border-top: 1px solid var(--sb-color-border);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--sb-space-sm);
}

.worlds-final-cta__subtext {
  max-width: 30rem;
}

.worlds-final-cta__btn {
  margin-block-start: var(--sb-space-xs);
}

/* --- Worlds footer — same structural pattern as Main's `.main-footer`
   (brand/nav/copyright row + a quieter legal-links row below a thin
   border), namespaced separately. Legal links point at Main's actual
   legal pages (Worlds has none of its own). --- */

.worlds-footer {
  background-color: var(--sb-color-bg);
  border-top: 1px solid var(--sb-color-border);
}

.worlds-footer__inner {
  width: 100%;
  max-width: var(--sb-container-wide);
  margin-inline: auto;
  padding-inline: var(--sb-space-lg);
  /* Trimmed top padding from 6rem to var(--sb-space-xl) (4rem) — too
     much empty space sat between the border-top and the footer text;
     still breathable, just tighter. Bottom is untouched. */
  padding-block: var(--sb-space-xl) var(--sb-space-lg);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sb-space-md);
}

.worlds-footer__brand {
  display: flex;
  flex-direction: column;
  gap: var(--sb-space-xs);
}

.worlds-footer__nav {
  display: flex;
  gap: var(--sb-space-lg);
}

.worlds-footer__legal-row {
  border-top: 1px solid var(--sb-color-border);
}

.worlds-footer__legal {
  width: 100%;
  padding-inline: var(--sb-space-lg);
  padding-block: var(--sb-space-md);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sb-space-sm) var(--sb-space-lg);
}

@media (max-width: 640px) {
  .worlds-footer__inner {
    flex-direction: column;
    align-items: center;
    text-align: center;
  }
}

/* --- Worlds responsive --- */

@media (max-width: 640px) {
  .worlds-hero__header {
    padding: 0.75rem 0.75rem 0;
  }

  .worlds-hero__header-inner {
    padding: 0.55rem 1.25rem;
  }

  .worlds-hero__content {
    padding-block: 5rem var(--sb-space-lg);
  }
}
