/* ==========================================================================
   Obstoon — Effects: 3D scene, depth, scroll reveals

   Depth stack (5 levels, per art direction):
     1 background field ....... body::before / body::after
     2 atmospheric layer ...... .hero-aura, section washes
     3 section surface ........ .panel / .ecosystem__item
     4 product object ......... .scene  (CSS 3D object)
     5 foreground controls .... .btn / nav / foreground text

   All 3D is progressive enhancement: every layer is laid out in 2D first,
   and the perspective/transforms are additive. With JS disabled the scene
   renders as a flat, fully composed object.
   ========================================================================== */

/* ==========================================================================
   Scroll reveals — only active once JS has confirmed support
   ========================================================================== */
.js [data-reveal] {
  opacity: 0;
  transform: translate3d(0, 20px, 0);
  transition: opacity var(--dur-5) var(--ease-out),
    transform var(--dur-5) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}

.js [data-reveal].is-revealed {
  opacity: 1;
  transform: none;
  will-change: auto;
}

.js [data-reveal-scale] {
  opacity: 0;
  transform: scale(0.965);
  transition: opacity var(--dur-5) var(--ease-out),
    transform var(--dur-5) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

.js [data-reveal-scale].is-revealed {
  opacity: 1;
  transform: none;
}

/* ==========================================================================
   Hero
   ========================================================================== */
.hero {
  position: relative;
  padding-block: clamp(2.5rem, 1.5rem + 5vw, 5.5rem) clamp(3rem, 2rem + 6vw, 7rem);
}

.hero__grid {
  display: grid;
  gap: clamp(2.5rem, 1.5rem + 5vw, 4.5rem);
  align-items: center;
}

@media (min-width: 68rem) {
  .hero__grid {
    /* The text column carries the headline, so it gets the larger share while
       the layout is narrowing (68-80rem). Above 80rem the rule in
       responsive.css widens the visual instead, which is the presence the
       large-desktop block is there for. */
    grid-template-columns: minmax(0, 1.06fr) minmax(0, 0.94fr);
  }
}

.hero__content {
  display: grid;
  gap: var(--space-md);
  align-content: center;
  max-width: 40rem;
}

.hero__title {
  /* An explicitly composed editorial headline, not a column that happens to
     wrap. The desktop statement is three controlled lines — `Three focused
     tools for` / `speaking, study,` / `and progress.` — sized to the text
     column (~500px of measure) plus a font-stack guard band, because no webfont
     ships and system fonts spread by a few percent. The old 4.9rem cap pushed
     the first line to three wrapped fragments and turned the statement into a
     five-line tower that drove the CTA stack down the page. */
  font-size: clamp(2.5rem, 1.4rem + 3vw, 2.9rem);
  /* Bring the headline up to its eyebrow and let it stand off the lead: the
     label reads as part of the headline block, the lead as a separate
     paragraph. */
  margin-block: -0.02em 0.07em;
}

/* One idea per line (spec line rhythm): the sans runs carry the subject, the
   italic serif runs carry the verbs, and each new idea starts on its own line
   regardless of where the column wraps. */
.hero__title .hero__line {
  display: block;
}

/* From tablet up the column is wide enough for all three lines to hold their
   proved widths, so the cadence is fixed: line one never decays back into three
   accidental fragments. */
@media (min-width: 48rem) {
  .hero__title .hero__line {
    white-space: nowrap;
  }
}

/* Mobile: the same wording and hierarchy, but an intentional narrow measure.
   Line one is allowed to fold into two balanced short lines rather than hung
   across a nowrap that would overflow the gutter, so the statement stays one
   editorial block and no line is orphaned. */
@media (max-width: 47.99rem) {
  .hero__title {
    font-size: 2.25rem;
  }

  .hero__title .hero__line:nth-child(1) {
    text-wrap: balance;
  }
}

.hero__title em {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  letter-spacing: -0.012em;
}

.hero__lead {
  font-size: var(--text-lg);
  line-height: var(--leading-relaxed);
  color: var(--text-soft);
  max-width: 50ch;
}

/* CTA stack — vertical, strong left alignment, compact 7-10px rhythm. One
   filled primary, two outlined ghosts; same width family but deliberately NOT
   equalised in prominence. */
.hero__cta {
  display: grid;
  gap: 0.5rem;
  justify-items: start;
  width: min(100%, 22rem);
  margin-top: var(--space-2xs);
}

.hero__cta .btn {
  width: 100%;
  justify-content: center;
}

.hero__meta {
  display: grid;
  gap: var(--space-3xs);
  justify-items: start;
  margin-top: var(--space-2xs);
}

/* Hero backdrop: a wide, low-frequency light band (level 2) */
/* Atmosphere, not a single glow. Four stacked layers:
   1. a fine technical grid, so the backdrop carries readable structure instead
      of being an undifferentiated dark field;
   2. two coloured light pools, one behind the object and one under the text;
   3. a horizon band that separates the hero from the section below;
   4. a corner falloff that keeps the edges quiet.
   The grid is intentionally faint but not invisible — it is what stops the
   right-hand column from reading as dead space. */
.hero__glow {
  position: absolute;
  z-index: -1;
  inset: -18% 0 -10%;
  pointer-events: none;
  background:
    repeating-linear-gradient(
      90deg,
      var(--grid-line) 0 1px,
      transparent 1px 72px
    ),
    repeating-linear-gradient(
      0deg,
      var(--grid-line) 0 1px,
      transparent 1px 72px
    ),
    radial-gradient(
      42% 44% at 68% 34%,
      color-mix(in srgb, var(--obj-2) 30%, transparent) 0%,
      transparent 72%
    ),
    radial-gradient(
      40% 40% at 20% 72%,
      color-mix(in srgb, var(--accent-2) 22%, transparent) 0%,
      transparent 74%
    ),
    linear-gradient(
      180deg,
      transparent 0%,
      transparent 68%,
      color-mix(in srgb, var(--obj-1) 12%, transparent) 86%,
      transparent 100%
    );
  mask-image: radial-gradient(120% 96% at 50% 34%, #000 42%, transparent 92%);
  -webkit-mask-image: radial-gradient(120% 96% at 50% 34%, #000 42%, transparent 92%);
  filter: blur(0.4px);
}

/* Almost-perceived light drift: the atmospheric pools slowly breathe so the
   hero is alive but never moving. 30s+ means no single frame change registers;
   reduced-motion users get the settled static pose. */
@media (prefers-reduced-motion: no-preference) {
  .hero__glow {
    animation: hero-glow-drift 34s var(--ease-in-out) infinite alternate;
  }
}

@keyframes hero-glow-drift {
  from {
    transform: translate3d(-0.5%, 0, 0) scale(1);
  }
  to {
    transform: translate3d(0.7%, 0.4%, 0) scale(1.02);
  }
}

/* ==========================================================================
   The Obstoon Ecosystem Object — real CSS 3D
   Composition is brand-specific: the Library open-book geometry carries the
   object, the Speech waveform and conversation card orbit in front of it, and
   emission rings plus the tracker's path glow sit behind. No orb, no generic
   AI imagery.
   ========================================================================== */
.hero-visual {
  position: relative;
  display: grid;
  place-items: center;
  min-height: clamp(360px, 50vw, 700px);
  perspective: var(--perspective-scene);
  perspective-origin: 50% 44%;
  touch-action: pan-y;
}

.scene {
  position: relative;
  width: min(100%, 660px);
  aspect-ratio: 1 / 1;
  transform-style: preserve-3d;
  transform: rotateX(var(--scene-rx, 0deg)) rotateY(var(--scene-ry, 0deg));
  transition: transform var(--dur-5) var(--ease-out);
}

.scene__float {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  animation: scene-float 16s var(--ease-in-out) infinite alternate;
}

@keyframes scene-float {
  from {
    transform: translate3d(0, -10px, 0) rotateZ(-0.7deg);
  }
  to {
    transform: translate3d(0, 12px, 0) rotateZ(0.7deg);
  }
}

.layer {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  transform-style: preserve-3d;
  pointer-events: none;
}

/* Per-layer parallax multiplier, driven by JS custom properties */
.layer[data-depth] {
  transform: translate3d(
      calc(var(--px, 0) * var(--depth-x, 0) * 1px),
      calc(var(--py, 0) * var(--depth-y, 0) * 1px),
      var(--layer-z, 0px)
    )
    translateZ(calc(var(--parallax, 0) * 1px));
  transition: transform var(--dur-4) var(--ease-out);
}

/* ---- Aura: soft light behind the object ---- */
.layer--aura {
  --layer-z: -150px;
  --parallax: 26;
  background: radial-gradient(
    closest-side,
    color-mix(in srgb, var(--obj-3) 46%, transparent) 0%,
    color-mix(in srgb, var(--obj-2) 26%, transparent) 44%,
    transparent 76%
  );
  transform: scale(1.14);
  filter: blur(26px);
  opacity: 0.9;
}

/* A tight hot core inside the aura. This is what makes the object read as lit
   rather than merely outlined. */
.layer--aura::after {
  content: "";
  position: absolute;
  width: 46%;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  background: radial-gradient(
    closest-side,
    color-mix(in srgb, var(--obj-spec) 62%, transparent) 0%,
    color-mix(in srgb, var(--obj-3) 30%, transparent) 52%,
    transparent 78%
  );
  filter: blur(6px);
}

/* ---- Floor plate: a real horizontal plane in 3D ---- */
.layer--floor {
  --layer-z: var(--z-depth-floor);
  --parallax: -14;
  align-items: end;
}

.floor__plate {
  position: relative;
  width: 108%;
  aspect-ratio: 2 / 1;
  border-radius: 50%;
  transform: rotateX(74deg) translateZ(-40px);
  transform-origin: 50% 50%;
  background:
    radial-gradient(
      closest-side,
      color-mix(in srgb, var(--obj-2) 42%, transparent) 0%,
      transparent 68%
    ),
    repeating-conic-gradient(
      from 0deg,
      var(--plate-line) 0deg 0.6deg,
      transparent 0.6deg 6deg
    );
  border: 1px solid color-mix(in srgb, var(--obj-2) 46%, transparent);
  mask-image: radial-gradient(closest-side, #000 42%, transparent 78%);
  -webkit-mask-image: radial-gradient(closest-side, #000 42%, transparent 78%);
  box-shadow: inset 0 0 70px color-mix(in srgb, var(--obj-3) 26%, transparent);
}

/* Contact shadow: tightens the object onto the plate */
.layer--shadow {
  --layer-z: calc(var(--z-depth-floor) + 8px);
  --parallax: -10;
  align-items: end;
}

.floor__shadow {
  width: 62%;
  aspect-ratio: 2 / 1;
  border-radius: 50%;
  transform: rotateX(74deg) translateZ(-36px);
  background: radial-gradient(
    closest-side,
    rgba(0, 0, 0, 0.55) 0%,
    rgba(0, 0, 0, 0.22) 42%,
    transparent 74%
  );
  filter: blur(10px);
}

[data-theme="light"] .floor__shadow {
  background: radial-gradient(
    closest-side,
    rgba(21, 38, 66, 0.24) 0%,
    rgba(21, 38, 66, 0.1) 44%,
    transparent 74%
  );
}

/* ---- Emission rings: concentric light geometry behind the object ---- */
.layer--rings {
  --layer-z: var(--z-depth-rings);
  --parallax: 18;
}

.rings {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  display: grid;
  place-items: center;
  transform: rotateX(66deg);
}

.rings i {
  position: absolute;
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--obj-3) 62%, transparent);
  opacity: calc(0.95 - var(--i) * 0.16);
  transform: scale(calc(0.42 + var(--i) * 0.24));
  box-shadow: 0 0 24px -6px color-mix(in srgb, var(--obj-3) 46%, transparent);
}

.rings i:nth-child(2) {
  border-color: color-mix(in srgb, var(--obj-2) 66%, transparent);
  box-shadow: 0 0 24px -6px color-mix(in srgb, var(--obj-2) 42%, transparent);
}

.rings i:nth-child(3) {
  border-color: color-mix(in srgb, var(--ob-mint) 56%, transparent);
  box-shadow: 0 0 24px -6px color-mix(in srgb, var(--ob-mint) 38%, transparent);
}

/* ---- Library: the open book, built from real page planes ---- */
.layer--book {
  --layer-z: var(--z-depth-book);
  --parallax: 8;
}

.book {
  position: relative;
  width: min(74%, 400px);
  aspect-ratio: 1.42 / 1;
  transform-style: preserve-3d;
  transform: rotateX(13deg);
}

/* Page block thickness: stacked leaves under the covers */
.book__leaf {
  position: absolute;
  inset: 0;
  border-radius: 3px 6px 6px 3px;
  background: linear-gradient(
    90deg,
    var(--obj-1) 0%,
    color-mix(in srgb, var(--obj-2) 70%, var(--ob-mint)) 100%
  );
  border: 1px solid color-mix(in srgb, var(--obj-3) 40%, transparent);
  box-shadow: var(--shadow-sm);
  transform: translate3d(calc(var(--i) * -1.5px), calc(var(--i) * 3.4px), calc(var(--i) * -3px));
}

.book__page {
  position: absolute;
  top: 0;
  width: 51%;
  height: 100%;
  padding: 12px;
  border-radius: 4px 8px 8px 4px;
  /* Lit paper: bright specular edge falling into a mid tone. This is the
     largest lit surface in the composition, so it carries the hero. */
  background: linear-gradient(
    var(--page-angle, 155deg),
    var(--obj-spec) 0%,
    var(--obj-3) 34%,
    var(--obj-2) 78%,
    var(--obj-1) 100%
  );
  border: 1px solid color-mix(in srgb, var(--obj-hot) 46%, transparent);
  box-shadow: var(--shadow-md), var(--shadow-inset),
    0 0 42px -14px color-mix(in srgb, var(--obj-3) 60%, transparent);
  overflow: hidden;
}

.book__page--left {
  left: 0;
  transform-origin: 100% 50%;
  transform: rotateY(27deg);
  border-right-color: color-mix(in srgb, var(--border-strong) 40%, transparent);
}

.book__page--right {
  right: 0;
  transform-origin: 0% 50%;
  transform: rotateY(-27deg);
  border-left-color: color-mix(in srgb, var(--border-strong) 40%, transparent);
}

.book__page--left {
  --page-angle: 200deg;
}

/* Page content: ruled lines, a heading and a mint accent — reads as a document.
   The pages are now a lit surface, so the "ink" has to be dark. */
.book__head {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-bottom: 9px;
  padding-bottom: 7px;
  border-bottom: 1px solid color-mix(in srgb, var(--obj-shadow) 46%, transparent);
}

.book__head span {
  height: 4px;
  border-radius: 2px;
  background: var(--ob-mint);
  opacity: 0.95;
}

.book__rules {
  display: grid;
  gap: 5px;
}

.book__rules i {
  height: 3px;
  border-radius: 2px;
  background: color-mix(in srgb, var(--obj-shadow) 62%, transparent);
}

.book__rules i:nth-child(3n) {
  width: 78%;
}

.book__rules i:nth-child(4n) {
  width: 58%;
}

.book__rules i.is-accent {
  background: color-mix(in srgb, var(--ob-mint) 88%, var(--obj-shadow));
  width: 44%;
}

/* Spine: a genuine 3D box face between the pages */
.book__spine {
  position: absolute;
  left: 50%;
  top: 3%;
  width: 12px;
  height: 94%;
  margin-left: -6px;
  transform: translateZ(-16px);
  border-radius: 3px;
  background: linear-gradient(
    90deg,
    var(--obj-shadow) 0%,
    var(--obj-1) 42%,
    var(--obj-2) 62%,
    var(--obj-shadow) 100%
  );
  border: 1px solid color-mix(in srgb, var(--obj-3) 44%, transparent);
  box-shadow: var(--shadow-sm);
}

/* ---- Speech: waveform ribbon plane ---- */
.layer--wave {
  --layer-z: var(--z-depth-wave);
  --parallax: 34;
  align-items: center;
}

.wave-plane {
  position: relative;
  /* Full bleed only where there is room for it. At narrower widths the 128%
     bleed, amplified by the scene's perspective, projects past the viewport and
     widens the document, so it is capped to the scene box instead. */
  width: min(128%, 100%);
  aspect-ratio: 5 / 1;
  transform-style: preserve-3d;
}

@media (min-width: 68rem) {
  .wave-plane {
    width: 128%;
  }
}

.wave-plane svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.wave-plane__ghost {
  opacity: 0.42;
  transform: translateZ(-46px) scale(0.97);
  filter: blur(1px);
}

.wave-plane__mid {
  opacity: 0.7;
  transform: translateZ(-22px);
}

.wave-plane__lead {
  transform: translateZ(0);
  filter: drop-shadow(0 0 16px color-mix(in srgb, var(--ob-coral) 58%, transparent))
    drop-shadow(0 0 34px color-mix(in srgb, var(--ob-blue) 44%, transparent));
}

@keyframes wave-drift-lead {
  from {
    transform: translateZ(0) translateX(-1.2%);
  }
  to {
    transform: translateZ(0) translateX(1.2%);
  }
}

@keyframes wave-drift-mid {
  from {
    transform: translateZ(-22px) translateX(1.4%);
  }
  to {
    transform: translateZ(-22px) translateX(-1.4%);
  }
}

@keyframes wave-drift-ghost {
  from {
    transform: translateZ(-46px) scale(0.97) translateX(-1.8%);
  }
  to {
    transform: translateZ(-46px) scale(0.97) translateX(1.8%);
  }
}

.is-inview .wave-plane__lead {
  animation: wave-drift-lead 9s var(--ease-in-out) infinite alternate;
}

.is-inview .wave-plane__mid {
  animation: wave-drift-mid 12s var(--ease-in-out) infinite alternate;
}

.is-inview .wave-plane__ghost {
  animation: wave-drift-ghost 17s var(--ease-in-out) infinite alternate;
}

/* ---- Speech: conversation card carrying the real Speech mark ---- */
.layer--bubble {
  --layer-z: var(--z-depth-bubble);
  --parallax: 52;
}

.bubble-card {
  position: relative;
  align-self: center;
  justify-self: start;
  margin-left: 2%;
  width: min(60%, 232px);
  padding: var(--space-xs);
  display: grid;
  gap: var(--space-2xs);
  background: linear-gradient(
    170deg,
    var(--obj-2) 0%,
    var(--obj-1) 58%,
    var(--obj-shadow) 100%
  );
  border: 1px solid color-mix(in srgb, var(--obj-3) 52%, transparent);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg), var(--shadow-inset),
    0 0 46px -16px color-mix(in srgb, var(--obj-3) 66%, transparent);
  transform: rotateY(-13deg) rotateX(5deg);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.bubble-card::after {
  content: "";
  position: absolute;
  left: 22px;
  bottom: -7px;
  width: 14px;
  height: 14px;
  background: var(--obj-shadow);
  border-right: 1px solid color-mix(in srgb, var(--obj-3) 52%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--obj-3) 52%, transparent);
  transform: rotate(45deg);
  border-bottom-right-radius: 3px;
}

.bubble-card__top {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
}

.bubble-card__mark {
  width: 26px;
  height: 26px;
  border-radius: var(--radius-3xs);
  object-fit: contain;
  flex: none;
}

.bubble-card__label {
  font-family: var(--font-mono);
  font-size: var(--text-3xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--obj-spec);
}

.bubble-card__lines {
  display: grid;
  gap: 5px;
}

.bubble-card__lines i {
  height: 5px;
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--obj-spec) 46%, transparent);
}

.bubble-card__lines i:nth-child(2) {
  width: 84%;
}

.bubble-card__lines i:nth-child(3) {
  width: 56%;
}

.bubble-card__meter {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 20px;
  margin-top: 2px;
}

.bubble-card__meter i {
  flex: 1;
  border-radius: 1px;
  background: linear-gradient(
    180deg,
    var(--ob-coral),
    color-mix(in srgb, var(--ob-coral) 35%, var(--ob-blue))
  );
  transform-origin: bottom;
  opacity: 0.85;
  animation: bubble-meter 2.8s var(--ease-in-out) infinite alternate;
}

.bubble-card__meter i:nth-child(1) { animation-delay: 0ms; }
.bubble-card__meter i:nth-child(2) { animation-delay: 90ms; }
.bubble-card__meter i:nth-child(3) { animation-delay: 180ms; }
.bubble-card__meter i:nth-child(4) { animation-delay: 270ms; }
.bubble-card__meter i:nth-child(5) { animation-delay: 360ms; }
.bubble-card__meter i:nth-child(6) { animation-delay: 450ms; }
.bubble-card__meter i:nth-child(7) { animation-delay: 540ms; }
.bubble-card__meter i:nth-child(8) { animation-delay: 630ms; }
.bubble-card__meter i:nth-child(9) { animation-delay: 720ms; }
.bubble-card__meter i:nth-child(10) { animation-delay: 810ms; }
.bubble-card__meter i:nth-child(11) { animation-delay: 900ms; }
.bubble-card__meter i:nth-child(12) { animation-delay: 990ms; }

.is-inview .bubble-card__meter i,
.is-inview .fragment__meter i {
  animation-play-state: running;
}

.bubble-card__meter i,
.fragment__meter i {
  animation-play-state: paused;
}

@keyframes bubble-meter {
  from {
    transform: scaleY(0.22);
  }
  to {
    transform: scaleY(1);
  }
}

/* Caption strip under the object, inside the visual region */
.hero-visual__caption {
  position: absolute;
  left: 50%;
  bottom: -0.35rem;
  transform: translateX(-50%);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3xs) var(--space-md);
  font-family: var(--font-mono);
  font-size: var(--text-3xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-faint);
  text-align: center;
  max-width: 100%;
}

.hero-visual__caption span {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
}

.hero-visual__caption i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.7;
}

.hero-visual__caption .is-speech { color: var(--ink-speech); }
.hero-visual__caption .is-library { color: var(--ink-library); }
.hero-visual__caption .is-tracker { color: var(--ink-tracker); }

/* ==========================================================================
   Product showcase rows
   ========================================================================== */
.showcase {
  position: relative;
  padding-block: var(--space-3xl);
  overflow: hidden;
}

.showcase__grid {
  display: grid;
  gap: clamp(2rem, 1.4rem + 3vw, 4rem);
  align-items: center;
}

@media (min-width: 62rem) {
  .showcase__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .showcase--reverse .showcase__media {
    order: -1;
  }
}

.showcase__body > * + * {
  margin-top: var(--space-sm);
}

.showcase__stage {
  position: relative;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: linear-gradient(
    180deg,
    var(--surface-2) 0%,
    color-mix(in srgb, var(--surface) 92%, var(--bg-deep)) 100%
  );
  box-shadow: var(--shadow-lg), var(--shadow-inset);
  overflow: hidden;
  isolation: isolate;
}

/* Per-product stage lighting */
.showcase--speech .showcase__stage::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(
    74% 62% at 18% 8%,
    color-mix(in srgb, var(--ob-cobalt) 30%, transparent) 0%,
    transparent 66%
  );
}

.showcase--library .showcase__stage::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(
    78% 70% at 84% 12%,
    color-mix(in srgb, var(--ob-mint) 24%, transparent) 0%,
    transparent 66%
  );
}

.showcase--tracker .showcase__stage::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(
    78% 70% at 80% 18%,
    color-mix(in srgb, var(--ob-violet) 26%, transparent) 0%,
    transparent 66%
  );
}

.showcase__stage-body {
  padding: clamp(1.25rem, 0.9rem + 1.6vw, 2rem);
}

/* Speech stage: conversation fragments in dimensional layers */
.fragments {
  position: relative;
  display: grid;
  gap: var(--space-2xs);
  perspective: var(--perspective-card);
}

.fragment {
  position: relative;
  padding: 0.7rem 0.9rem;
  border-radius: var(--radius-xs);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
  font-size: var(--text-xs);
  color: var(--text-soft);
  transform-origin: 0% 50%;
  transition: transform var(--dur-4) var(--ease-out),
    box-shadow var(--dur-4) var(--ease-out),
    border-color var(--dur-3) var(--ease-out);
}

.fragment--user {
  margin-left: auto;
  max-width: 82%;
  background: color-mix(in srgb, var(--ob-cobalt) 16%, var(--surface));
  border-color: color-mix(in srgb, var(--ob-cobalt) 34%, transparent);
  border-bottom-right-radius: var(--radius-3xs);
}

.fragment--partner {
  max-width: 88%;
  border-bottom-left-radius: var(--radius-3xs);
}

.fragment__who {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-3xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 0.3rem;
}

.fragment--partner .fragment__who {
  color: var(--ink-speech);
}

.fragment__meter {
  display: flex;
  align-items: center;
  gap: 2px;
  height: 14px;
  margin-top: 0.5rem;
}

.fragment__meter i {
  flex: 1;
  max-width: 4px;
  height: 100%;
  border-radius: 2px;
  background: color-mix(in srgb, var(--accent) 70%, transparent);
  transform-origin: left center;
  transform: scaleY(0.3);
}

.is-inview .fragment__meter i {
  animation: frag-pulse 2.6s var(--ease-in-out) infinite alternate;
}

@keyframes frag-pulse {
  from {
    transform: scaleY(0.18);
  }
  to {
    transform: scaleY(1);
  }
}

/* Library stage: a shelving grid of document spines */
.shelf {
  display: grid;
  gap: var(--space-sm);
}

.shelf__row {
  display: grid;
  gap: var(--space-2xs);
  padding-bottom: var(--space-2xs);
  border-bottom: 2px solid var(--border);
}

.shelf__row:last-child {
  border-bottom: 0;
}

.spine {
  position: relative;
  height: 34px;
  border-radius: 3px;
  background: linear-gradient(
    170deg,
    color-mix(in srgb, var(--surface-3) 90%, var(--ob-mint)) 0%,
    var(--surface-2) 100%
  );
  border: 1px solid var(--border);
  border-left: 2px solid var(--ink-library);
  display: flex;
  align-items: center;
  padding-inline: 0.55rem;
  overflow: hidden;
  transition: transform var(--dur-3) var(--ease-out),
    border-color var(--dur-3) var(--ease-out);
}

.spine i {
  display: block;
  height: 4px;
  border-radius: 2px;
  background: color-mix(in srgb, var(--text) 22%, transparent);
  width: 100%;
}

.spine span {
  position: absolute;
  right: 0.5rem;
  padding: 0.1rem 0.34rem;
  border-radius: 2px;
  border: 1px solid var(--border);
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  font-family: var(--font-mono);
  font-size: var(--text-3xs);
  color: var(--text-muted);
  opacity: 0.78;
  transition: opacity var(--dur-3) var(--ease-out),
    color var(--dur-3) var(--ease-out);
}

@media (hover: hover) {
  .shelf__row:hover .spine {
    transform: translateX(4px);
    border-left-color: var(--ob-mint);
  }

  .shelf__row:hover .spine span {
    opacity: 1;
    color: var(--ink-library);
  }
}

.shelf__legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3xs) var(--space-sm);
  font-family: var(--font-mono);
  font-size: var(--text-3xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-faint);
}

.shelf__legend b {
  color: var(--ink-library);
  font-weight: 600;
}

/* ==========================================================================
   Tracker experience — planned product. Visual only: no accounts, no data,
   no dashboard. The scene states a concept (study → progress → certificates
   → profile) and stays under review.
   ========================================================================== */
.track-field {
  position: relative;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  background:
    radial-gradient(
      64% 78% at 50% 104%,
      color-mix(in srgb, var(--ob-indigo) 32%, transparent) 0%,
      transparent 70%
    ),
    radial-gradient(
      50% 60% at 82% 6%,
      color-mix(in srgb, var(--ob-violet) 26%, transparent) 0%,
      transparent 68%
    ),
    linear-gradient(
      180deg,
      color-mix(in srgb, var(--bg-deep) 62%, var(--surface)) 0%,
      color-mix(in srgb, var(--surface) 88%, transparent) 100%
    );
  box-shadow: var(--shadow-lg), var(--shadow-inset);
  overflow: hidden;
  isolation: isolate;
}

.track-field__grid {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: 56px 56px;
  mask-image: radial-gradient(80% 72% at 50% 42%, #000 22%, transparent 80%);
  -webkit-mask-image: radial-gradient(80% 72% at 50% 42%, #000 22%, transparent 80%);
  opacity: 0.55;
  pointer-events: none;
}

/* Same honest footer strip as the other product fields. */
.track-field__status {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  border-top: 1px solid var(--border);
  background: var(--surface-inset);
  font-size: var(--text-2xs);
  color: var(--text-muted);
}

/* ==========================================================================
   Editorial / brand statement
   ========================================================================== */
.statement {
  position: relative;
  display: grid;
  gap: var(--space-lg);
}

.statement__quote {
  font-family: var(--font-serif);
  font-size: var(--text-xl);
  line-height: 1.42;
  letter-spacing: -0.012em;
  color: var(--text);
  max-width: 30ch;
  text-wrap: balance;
}

.statement__body {
  color: var(--text-soft);
  line-height: var(--leading-relaxed);
  max-width: 52ch;
}

.statement__body p + p {
  margin-top: var(--space-sm);
}

.statement__aside {
  display: grid;
  gap: var(--space-md);
  align-content: start;
  padding: var(--space-md);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md), var(--shadow-inset);
}

@media (min-width: 62rem) {
  .statement {
    grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr);
    gap: var(--space-2xl);
    align-items: start;
  }
}

.pillar {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-sm);
  align-items: start;
}

.pillar + .pillar {
  padding-top: var(--space-sm);
  border-top: 1px solid var(--border);
}

.pillar__num {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  color: var(--accent);
  padding-top: 0.2em;
}

.pillar__title {
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: var(--tracking-snug);
}

.pillar__body {
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
  color: var(--text-muted);
  margin-top: 0.2rem;
}

/* Oversized numeral watermark for the About section */
.about-mark {
  position: absolute;
  right: 0;
  bottom: -0.34em;
  font-family: var(--font-display);
  font-size: clamp(9rem, 30vw, 26rem);
  font-weight: 700;
  line-height: 0.72;
  letter-spacing: -0.05em;
  color: transparent;
  -webkit-text-stroke: 1px var(--border);
  pointer-events: none;
  user-select: none;
  z-index: -1;
}

/* ==========================================================================
   Magnetic CTA (desktop, fine pointer only)
   ========================================================================== */
@media (hover: hover) and (pointer: fine) {
  .js .btn--magnetic[data-magnet="true"] {
    transform: translate3d(var(--mx, 0px), var(--my, 0px), 0);
    transition: transform var(--dur-3) var(--ease-out),
      box-shadow var(--dur-3) var(--ease-out),
      border-color var(--dur-2) var(--ease-out),
      background-color var(--dur-2) var(--ease-out),
      color var(--dur-2) var(--ease-out);
  }

  .js .btn--magnetic[data-magnet="true"]:hover {
    transform: translate3d(var(--mx, 0px), var(--my, 0px), 0) scale(1.02);
  }
}

/* ==========================================================================
   Reduced motion — 3D settles into a designed static pose
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .scene {
    transform: rotateX(6deg);
  }

  .scene__float,
  .wave-plane svg,
  .bubble-card__meter i,
  .vis-wave__bars i,
  .trk-node--on,
  .vis-path__node--done,
  .trackpath__node--done,
  .fragment__meter i,
  .badge--soon .badge__dot {
    animation: none !important;
  }

  .trackpath .route-done,
  .vis-path__done {
    animation: none !important;
    stroke-dashoffset: 0;
  }

  .js [data-reveal],
  .js [data-reveal-scale] {
    opacity: 1 !important;
    transform: none !important;
  }

  .layer[data-depth] {
    transform: translateZ(var(--layer-z, 0px));
  }
}