/* ============================================================
   ATAIHQ Portfolio — styles.css
   ------------------------------------------------------------
   Cohesion tokens pulled verbatim from the live landing site
   (ATAIHQ-LANDING-V2). Page two must match page one exactly.

   Fonts to load in <head>:
   Syne (display) · DM Sans (body) · Share Tech Mono (labels)
   ============================================================ */

:root {
  /* ---- Palette (exact hex from landing site) ---- */
  --bg: #08090d;
  --surface: #0f1117;
  --surface-2: #141722;
  --line: rgba(255, 255, 255, 0.08);
  --text: #eef0f6;
  --text-dim: #9aa1b5;
  --blue: #08aaff;        /* brand blue (#08aaff per Phase B update) */
  --purple: #7b2fff;
  --cyan: #59e6d4;
  --grad: linear-gradient(100deg, var(--blue), var(--purple));

  /* ---- Typography ---- */
  --font-display: "Syne", sans-serif;
  --font-body: "DM Sans", sans-serif;
  --font-mono: "Share Tech Mono", monospace;

  /* ---- Spacing & shape ---- */
  --container: 1180px;
  --pad: clamp(1.25rem, 4vw, 2.5rem);
  --section-gap: clamp(5rem, 12vh, 9rem);
  --radius: 18px;
}

/* ============================================================
   BASE / RESET
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html { -webkit-text-size-adjust: 100%; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-weight: 300;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img, video, canvas { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
em { font-style: normal; }

.mono-label {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--text-dim);
}

/* ============================================================
   SITE-HOME BADGE — persistent link back to ataihq.com
   Fixed top-left on every scroll position; sits under the ship
   cursor/beam (z 998/999) but above all page content.
   ============================================================ */
.site-home {
  position: fixed;
  top: clamp(0.9rem, 2.5vw, 1.4rem);
  left: clamp(0.9rem, 2.5vw, 1.4rem);
  z-index: 900;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--text);
  padding: 0.55em 1em;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(15, 17, 23, 0.55);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  transition: border-color 0.25s ease, color 0.25s ease,
              box-shadow 0.25s ease;
}
.site-home:hover,
.site-home:focus-visible {
  color: var(--cyan);
  border-color: rgba(8, 170, 255, 0.55);
  box-shadow: 0 0 14px rgba(8, 170, 255, 0.25);
}

/* ============================================================
   PHASE B — HERO (scroll-scrubbed video + space layout)
   ============================================================ */
.space-stage { position: relative; }

.hero {
  position: sticky;
  top: 0;
  height: 100vh;
  width: 100%;
  overflow: hidden;
  will-change: opacity;
}

/* Scroll-scrubbed video background */
.hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 1;
}

/* Scroll-driven dive film (space -> Trades). Sits over the held intro
   video, under the scrim/copy/controls. main.js fades it in over the
   first ~8% of the dive and draws the matching frame per scroll; it
   leaves with the hero's own end-of-dive fade onto the blueprint. */
.dive-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;              /* above .hero-video (same layer, later in DOM) */
  opacity: 0;
  pointer-events: none;
}

/* ---- Hero backdrop image (final-frame fallback if the video element
   can't render at all; the intro video sits above this) ---- */
.hero-sky {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: #04050a url("../images/webp/ataihq-intro-final-frame.webp") center center / cover no-repeat;
}
/* synthetic starfield + CSS earth retired — the image carries both */
.hero-earth {
  display: none;
  position: absolute;
  left: 50%;
  bottom: -62vh;
  transform: translateX(-50%);
  width: 150vh;
  height: 150vh;
  border-radius: 50%;
  z-index: 0;
  will-change: transform, opacity;
  background:
    radial-gradient(circle at 50% 30%, rgba(89, 230, 212, 0.25), transparent 45%),
    radial-gradient(circle at 38% 40%, #1f6fd6 0%, #123b7a 38%, #0a1f44 60%, #050c1f 78%);
  box-shadow:
    0 -30px 140px 20px rgba(0, 170, 255, 0.28),
    inset 0 30px 120px rgba(89, 230, 212, 0.12),
    inset -40px -20px 160px rgba(0, 0, 0, 0.7);
}
.hero-earth::before {
  content: "";
  position: absolute;
  inset: -2%;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 24%, rgba(0, 170, 255, 0.4), transparent 30%);
  filter: blur(14px);
  opacity: 0.6;
}

/* ---- Legibility scrim (#11): darken top + bottom, clear middle ---- */
.hero-scrim {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background:
    linear-gradient(to bottom,
      rgba(4, 5, 10, 0.55) 0%,
      rgba(4, 5, 10, 0.12) 22%,
      rgba(4, 5, 10, 0) 42%,
      rgba(4, 5, 10, 0) 55%,
      rgba(4, 5, 10, 0.35) 74%,
      rgba(4, 5, 10, 0.72) 100%);
}

/* ---- Hero copy (#10) — frames the worlds + the journey ---- */
.hero-copy {
  position: absolute;
  /* Sits in the clear band BELOW the video's baked-in ATAI HEADQUARTERS
     wordmark (top third) and ABOVE the controls on the Earth horizon. */
  top: clamp(39vh, 41vh, 43vh);
  left: 50%;
  transform: translateX(-50%);
  z-index: 5;
  width: min(var(--container), 92vw);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.7rem;
  will-change: opacity, transform;
}
.hero-copy__eyebrow {
  color: rgba(238, 240, 246, 0.78);
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.7);
}
.hero-copy__title {
  font-family: var(--font-display);
  font-weight: 800;
  /* Supporting tagline under the video's wordmark — deliberately smaller
     than the brand reveal so the two don't compete. */
  font-size: clamp(1.25rem, 3vw, 2.1rem);
  line-height: 1.12;
  letter-spacing: -0.015em;
  max-width: 100%;        /* wrap within the hero-copy, never overflow */
  overflow-wrap: break-word;
  color: #fff;
  text-shadow: 0 2px 26px rgba(0, 0, 0, 0.65), 0 1px 4px rgba(0, 0, 0, 0.5);
}
.hero-copy__title em {
  /* brighter gradient (cyan -> light violet) reads clearly on the dark
     earth; drop-shadow gives a clean glow instead of a muddy text-shadow */
  background: linear-gradient(100deg, #6df0e0, #8fb4ff 45%, #c79bff);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  text-shadow: none;
  filter: drop-shadow(0 2px 14px rgba(0, 0, 0, 0.55));
}
.hero-copy__sub {
  max-width: 46ch;
  font-size: clamp(0.98rem, 1.5vw, 1.18rem);
  color: rgba(238, 240, 246, 0.86);
  text-shadow: 0 1px 14px rgba(0, 0, 0, 0.7);
}

/* ---- Controls on the horizon ---- */
.hero-controls {
  position: absolute;
  left: 50%;
  bottom: clamp(7vh, 12vh, 16vh);
  transform: translateX(-50%);
  z-index: 5;
  width: min(var(--container), 92vw);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.25rem;
  text-align: center;
  will-change: opacity, transform;
}

.cat-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(0.6rem, 1.5vw, 1rem);
  width: min(100%, 760px);
}
/* each cell anchors its button (and, for cell 3, the alien above it) */
.cat-cell { position: relative; display: flex; }
.catbtn {
  width: 100%;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(0.78rem, 1.3vw, 0.95rem);
  color: var(--text);
  padding: 0.9rem 1rem;
  border-radius: 14px;
  border: 1px solid rgba(8, 170, 255, 0.45);
  background: rgba(15, 17, 23, 0.42);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.55);
  cursor: pointer;
  transition: transform 0.25s ease, border-color 0.25s ease, background-color 0.25s ease, box-shadow 0.25s ease;
}
.catbtn:hover {
  transform: translateY(-3px);
  border-color: var(--blue);
  background: rgba(15, 17, 23, 0.62);
  box-shadow: 0 10px 30px rgba(8, 170, 255, 0.25);
}

/* The DOMINANT CTA (#5) — clearly bigger/brighter than the category boxes */
.view-all {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.15rem;
  font-family: var(--font-display);
  color: #fff;
  width: min(100%, 760px);
  padding: 1.45rem 2.25rem;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 18px;
  background: var(--grad);
  cursor: pointer;
  box-shadow:
    0 0 0 1px rgba(8, 170, 255, 0.25),
    0 18px 60px rgba(8, 170, 255, 0.5),
    0 8px 30px rgba(123, 47, 255, 0.5);
  transition: transform 0.25s ease, box-shadow 0.25s ease, filter 0.25s ease;
  animation: viewAllPulse 3.2s ease-in-out infinite;
}
.view-all__label {
  font-weight: 800;
  font-size: clamp(1.25rem, 2.6vw, 1.75rem);
  letter-spacing: 0.005em;
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
}
.view-all__hint {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.82);
}
.view-all:hover {
  transform: translateY(-4px) scale(1.025);
  filter: brightness(1.08);
  box-shadow:
    0 0 0 1px rgba(8, 170, 255, 0.4),
    0 26px 80px rgba(8, 170, 255, 0.62),
    0 12px 40px rgba(123, 47, 255, 0.62);
}
@keyframes viewAllPulse {
  0%, 100% { box-shadow: 0 0 0 1px rgba(8,170,255,0.25), 0 18px 60px rgba(8,170,255,0.5), 0 8px 30px rgba(123,47,255,0.5); }
  50%      { box-shadow: 0 0 0 1px rgba(8,170,255,0.45), 0 22px 72px rgba(8,170,255,0.65), 0 10px 38px rgba(123,47,255,0.65); }
}

/* The scroll cue (#6) — an IMPORTANT SECONDARY element, in the same
   visual weight class as the nav row (Syne, near-white), so visitors
   don't click "View Full Portfolio" and miss the scroll journey.
   Sized below the View-All pill so it never outranks the primary CTA. */
.scroll-whisper {
  margin-top: 0.6rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1rem, 1.7vw, 1.2rem);
  letter-spacing: 0.02em;
  color: rgba(238, 240, 246, 0.92);
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.7);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
}
/* A clearly noticeable chevron with a gentle PULSE (pure fade, no
   bounce — animation style approved, prominence raised). Soft
   brand-blue glow lifts it off the dark backdrop. */
.scroll-whisper__arrow {
  width: 28px;
  height: 28px;
  border-right: 3px solid rgba(238, 240, 246, 0.95);
  border-bottom: 3px solid rgba(238, 240, 246, 0.95);
  transform: rotate(45deg);
  filter: drop-shadow(0 0 8px rgba(8, 170, 255, 0.55));
  animation: arrowpulse 2.2s ease-in-out infinite;
}
@keyframes arrowpulse {
  0%, 100% { opacity: 0.35; }
  50%      { opacity: 1; }
}

/* The dive-zone: pure scroll length (≈4 page heights, #12) */
#dive-zone { height: 400vh; }

/* ============================================================
   ALIEN (#9) — sits on its planet ABOVE the 3rd category button,
   arm points toward the cursor (default rest points down at button)
   ============================================================ */
#alien {
  position: absolute;
  bottom: calc(100% + 4px);
  /* right-aligned above the button (was centred, left: 50%): the
     viewport-centred hero title's "£599" line reaches over this cell's
     centre on desktop and the alien sat on top of it (Champ screenshot,
     5 Jul 2026). The cell's right end is the farthest point from the
     centred title that still reads as "above the Individual & Personal
     Brands button". The laser's anchor follows automatically — alien.js
     reads the fingertip's live position every frame. */
  left: auto;
  right: 0;
  z-index: 6;
  pointer-events: none;
  filter: drop-shadow(0 0 12px rgba(8, 170, 255, 0.35));
  will-change: transform, opacity;
}
#alien svg { width: 76px; height: 76px; }
.alien-pupil { transition: transform 0.08s linear; }
#alien-arm { transition: transform 0.12s ease-out; }

/* ============================================================
   SHIP CURSOR + BEAM — while the space hero is active (desktop
   only), the real cursor is hidden and a small ship drifts after
   the mouse; the alien fires a beam from fingertip to ship.
   Both elements are created by alien.js and sit on <body> so the
   hero's opacity/overflow can't clip them. Click-through always.
   ============================================================ */
body.ship-cursor .hero,
body.ship-cursor .hero *,
body.ship-cursor .closing,
body.ship-cursor .closing * { cursor: none; }

#beam-overlay {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 998;              /* just under the ship */
  pointer-events: none;
}
#ship-cursor {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 999;
  pointer-events: none;
  will-change: transform, opacity;
  filter: drop-shadow(0 0 10px rgba(8, 170, 255, 0.45));
}

/* ============================================================
   WORLDS (shared shell) — Phase C+ fill these in
   ============================================================ */
.world {
  position: relative;
  z-index: 2;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--pad);
  background: var(--bg);
}
.world__inner {
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.2rem;
  max-width: 60ch;
}
.world__title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2rem, 5vw, 3.2rem);
  letter-spacing: -0.01em;
}
.world__note { color: var(--text-dim); font-size: 1.1rem; }

/* ============================================================
   WORLD 01 — TRADES (Phase C)
   Blueprint environment + sticky pin + 7 crossfading plates.
   ============================================================ */
.world--trades {
  display: block;            /* override the .world flex-centre shell */
  padding: 0;
  background: var(--bg);
}

/* Tall scroll track — its height sets how long the world lasts.
   ~110vh of scroll per plate gives an unhurried, cinematic pace. */
.trades-stage { position: relative; height: 770vh; }

/* Sticky blueprint viewport that holds still during the scrub */
.trades-pin {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
}

/* ---- Blueprint atmosphere ---- */
.bp-grid {
  position: absolute;
  inset: -2px;
  z-index: 0;
  pointer-events: none;
  background:
    linear-gradient(rgba(8, 170, 255, 0.06) 1px, transparent 1px) 0 0 / 48px 48px,
    linear-gradient(90deg, rgba(8, 170, 255, 0.06) 1px, transparent 1px) 0 0 / 48px 48px,
    linear-gradient(rgba(8, 170, 255, 0.10) 1px, transparent 1px) 0 0 / 240px 240px,
    linear-gradient(90deg, rgba(8, 170, 255, 0.10) 1px, transparent 1px) 0 0 / 240px 240px;
  -webkit-mask-image: radial-gradient(120% 100% at 50% 45%, #000 55%, transparent 100%);
          mask-image: radial-gradient(120% 100% at 50% 45%, #000 55%, transparent 100%);
}
.bp-glow {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(55% 55% at 50% 38%, rgba(8, 170, 255, 0.16), transparent 70%),
    radial-gradient(80% 60% at 50% 120%, rgba(123, 47, 255, 0.12), transparent 70%);
}
/* faint schematic line-art drifting in a corner — pure CSS, decorative */
.bp-schematic {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  top: 8%;
  right: 4%;
  width: 320px;
  height: 320px;
  opacity: 0.5;
  background:
    radial-gradient(circle, transparent 58px, rgba(8,170,255,0.18) 59px, transparent 61px),
    radial-gradient(circle, transparent 96px, rgba(8,170,255,0.12) 97px, transparent 99px),
    linear-gradient(45deg, transparent 49%, rgba(8,170,255,0.12) 50%, transparent 51%),
    linear-gradient(-45deg, transparent 49%, rgba(8,170,255,0.12) 50%, transparent 51%);
  background-position: center;
  background-repeat: no-repeat;
  animation: bpDrift 14s ease-in-out infinite alternate;
}
@keyframes bpDrift {
  from { transform: translateY(-10px) rotate(-1deg); }
  to   { transform: translateY(10px) rotate(1deg); }
}

/* ---- The plate stack ---- */
.trades-plates {
  position: relative;
  z-index: 2;
  width: min(1480px, 96vw);
  height: 88vh;
}

/* Each mockup plate — stacked, JS crossfades opacity + scale.
   Layout: framed mockup sits on the LEFT (name directly underneath),
   the write-up fills the empty space to the RIGHT. The website itself
   sits FLAT, straight-on, never tilted (Absolute Rule 1). */
.plate {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: clamp(1rem, 2.5vw, 2.25rem);
  opacity: 0;
  transform: scale(0.94);
  will-change: opacity, transform;
}

/* Left block: the framed screen (the dominant element) with its business
   name beneath it. Pulled slightly left of centre so the write-up has room. */
.plate__frame {
  flex: 0 1 auto;
  min-width: 0;
  max-width: 80%;
  margin-left: clamp(-1.5rem, -2vw, -0.4rem);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(0.7rem, 1.8vh, 1.2rem);
}
.plate__media {
  /* Wrap the image exactly so the FULL mockup is always visible —
     never cropped. The frame shrinks to fit the image. */
  position: relative;          /* anchor overlays (volt spark, before/after) */
  display: inline-block;
  max-width: 100%;
  border-radius: 14px;
  border: 1px solid rgba(8, 170, 255, 0.5);
  background: var(--surface);
  overflow: hidden;
  box-shadow:
    0 0 0 1px rgba(8, 170, 255, 0.18),
    0 36px 90px rgba(0, 0, 0, 0.6),
    0 0 80px rgba(8, 170, 255, 0.22);
}
.plate__img {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 82vh;       /* fills the viewport; whole image stays in view */
  object-fit: contain;
}
.plate__meta {
  flex: 0 1 300px;
  min-width: 0;
  text-align: left;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.35rem;
  max-width: 32ch;
}
.plate__tag { color: rgba(89, 230, 212, 0.85); }
/* Category label — the right-hand stack's heading (was the top marker) */
.plate__cat {
  align-self: stretch;
  color: rgba(89, 230, 212, 0.95);
  font-size: 0.95rem;
  letter-spacing: 0.02em;
  padding-bottom: 0.5rem;
  margin-bottom: 0.3rem;
  border-bottom: 1px solid rgba(8, 170, 255, 0.28);
}
.plate__name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.4rem, 3.4vw, 2.2rem);
  letter-spacing: -0.01em;
}
.plate__desc {
  color: var(--text-dim);
  font-size: clamp(0.95rem, 1.6vw, 1.1rem);
  line-height: 1.5;
}

/* ============================================================
   VOLT PRO — ambient electrical current looping around the logo
   Positioned over the VOLT PRO ELECTRICAL brand lockup inside the
   site header (NOT the browser chrome above it). Percentages are of
   the media box. Pure ambience: a spark rides a rounded-rect path.
   ============================================================ */
.volt-fx {
  position: absolute;
  top: 14.5%;
  left: 16.5%;
  width: 13%;
  height: 9.5%;
  border-radius: 8px;
  pointer-events: none;
  z-index: 3;
  /* faint conduit the current runs along */
  box-shadow: inset 0 0 0 1px rgba(255, 209, 71, 0.10);
}
.volt-spark {
  position: absolute;
  top: 0;
  left: 0;
  width: 7px;
  height: 7px;
  margin: -3.5px;
  border-radius: 50%;
  background: #ffd147;
  box-shadow:
    0 0 6px 2px rgba(255, 209, 71, 0.9),
    0 0 14px 5px rgba(255, 176, 32, 0.55);
  offset-path: inset(0 round 8px);
  offset-rotate: 0deg;
  animation: voltRun 3.6s linear infinite;
}
@keyframes voltRun {
  from { offset-distance: 0%; }
  to   { offset-distance: 100%; }
}
/* Fallback for engines without CSS Motion Path: a gentle pulse so the
   hero still reads as "live" rather than showing a stuck dot. */
@supports not (offset-path: inset(0)) {
  .volt-spark {
    top: 6%; left: 6%;
    animation: voltPulse 2.4s ease-in-out infinite;
  }
  @keyframes voltPulse {
    0%, 100% { opacity: 0.35; transform: scale(0.8); }
    50%      { opacity: 1;    transform: scale(1.2); }
  }
}

/* ============================================================
   BRUSHWORKS — before/after drag-slider (HERO ROOM PHOTO ONLY)
   The base layer is the full Brushworks site mockup; the two
   room photos (same room, same camera angle — dated 1990s decor
   wipes to the modern refit) overlay JUST the hero-photo
   rectangle, located by --rx/--ry (top-left) and --rw/--rh
   (size). --ba-pos is 0..100 across that rectangle.
   ============================================================ */
.ba-slider {
  --rx: 50%; --ry: 13.5%; --rw: 49.5%; --rh: 37%;  /* hero room rectangle */
  --ba-pos: 50;                                     /* 0..100 across room */
  position: relative;
  display: block;
  line-height: 0;
  touch-action: pan-y;       /* let vertical page scroll through; we own X */
}
/* Both room photos fill the room rectangle exactly, covering the
   mockup's baked hero photo — like the Louis Barbers panel overlay. */
.ba__after,
.ba__before {
  position: absolute;
  left: var(--rx);
  top: var(--ry);
  width: var(--rw);
  height: var(--rh);
  object-fit: cover;
}
.ba__after { z-index: 1; }
.ba__before {
  z-index: 2;
  /* the dated look is baked into the before photo itself — no filter.
     Revealed from the photo's left edge to the handle. */
  clip-path: inset(0 calc(100% - var(--ba-pos) * 1%) 0 0);
}
.ba__divider {
  position: absolute;
  top: var(--ry);
  height: var(--rh);
  left: calc(var(--rx) + var(--rw) * var(--ba-pos) / 100);
  width: 2px;
  margin-left: -1px;
  z-index: 3;                /* above both room-photo layers */
  background: rgba(255, 255, 255, 0.92);
  box-shadow: 0 0 10px rgba(8, 170, 255, 0.7);
  pointer-events: none;
}
.ba__handle {
  position: absolute;
  top: 50%;                  /* centre of the room-height divider */
  left: 50%;
  transform: translate(-50%, -50%);
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: -1px;
  color: #04050a;
  background: #fff;
  border: 2px solid rgba(8, 170, 255, 0.9);
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.5);
}
/* the control: a transparent range slider laid over the ROOM rectangle only */
.ba__range {
  position: absolute;
  left: var(--rx);
  top: var(--ry);
  width: var(--rw);
  height: var(--rh);
  margin: 0;
  z-index: 4;
  opacity: 0;
  cursor: ew-resize;
  touch-action: pan-y;       /* keep vertical page scroll working on mobile */
}
.ba-slider:focus-within .ba__handle {
  outline: 2px solid #59e6d4;
  outline-offset: 2px;
}

/* Pulsing "Try it" cue — the shared interactive-demo badge used across the
   whole page (Trades Brushworks + every High Street demo) so the design
   language is identical everywhere. Sits off the mockup, in the background. */
.plate__cue,
.demo-cue {
  align-self: flex-start;
  margin-top: 0.2rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.8rem;
  color: #04050a;
  padding: 0.4rem 0.8rem;
  border-radius: 999px;
  background: linear-gradient(100deg, #6df0e0, #8fb4ff);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.45);
  white-space: nowrap;
  animation: cuePulse 2s ease-in-out infinite;
}
/* High Street: the badge sits OUTSIDE the caption box, floated off its
   right edge and vertically centred. Taking it out of the flow means every
   caption keeps the same height whether or not the card has a demo — this
   is what keeps all six cards level. Vertical centring uses the individual
   `translate` property so the cuePulse `transform: scale()` animation
   doesn't fight it. */
.shop__caption .demo-cue {
  position: absolute;
  left: calc(100% + clamp(0.7rem, 1.4vw, 1.3rem));
  top: 50%;
  translate: 0 -50%;
  margin-top: 0;
}
@keyframes cuePulse {
  0%, 100% { transform: scale(1);    box-shadow: 0 4px 14px rgba(0,0,0,0.45), 0 0 0 0 rgba(105,240,224,0.5); }
  50%      { transform: scale(1.06); box-shadow: 0 4px 14px rgba(0,0,0,0.45), 0 0 0 8px rgba(105,240,224,0); }
}

.trades-liftoff {
  position: absolute;
  z-index: 4;
  bottom: clamp(1.6rem, 4vh, 2.6rem);
  /* Right-hand side (blueprint space) so it never collides with the
     business name centred under the mockup. */
  right: clamp(1.5rem, 4vw, 3rem);
  left: auto;
  transform: none;
}

/* ---- Static fallback (mobile / reduced-motion): a clean vertical
   stack of all 7 plates, no pin, no scrub (set by worlds.js) ---- */
.world--trades.trades--static .trades-stage { height: auto; }
.world--trades.trades--static .trades-pin {
  position: static;
  height: auto;
  display: block;
  padding: clamp(5rem, 12vh, 8rem) var(--pad);
}
.world--trades.trades--static .trades-plates {
  width: 100%;              /* fill the padded pin — no overflow past the edge */
  height: auto;
  display: flex;
  flex-direction: column;
  gap: clamp(4rem, 10vh, 7rem);
  margin: 4rem auto 0;
}
.world--trades.trades--static .plate {
  position: relative;
  inset: auto;
  opacity: 1;
  transform: none;
  flex-direction: column;   /* stack frame + write-up vertically on mobile */
  gap: clamp(1.2rem, 4vh, 2rem);
}
.world--trades.trades--static .plate__frame {
  max-width: 100%;
  margin-left: 0;
}
.world--trades.trades--static .plate__meta {
  flex: none;
  max-width: min(60ch, 100%);
  text-align: center;
  align-items: center;
}
.world--trades.trades--static .plate__media,
.world--trades.trades--static .plate__img { max-height: none; }
.world--trades.trades--static .trades-liftoff {
  position: relative;
  bottom: auto;
  right: auto;
  left: auto;
  transform: none;
  margin: clamp(4rem, 10vh, 6rem) auto 0;
}

/* Home control — one compact, unobtrusive round icon button, identical
   in every world (replaces the old wordy "lift off" pills). main.js
   wires every .liftoff to scroll back to the top / hero. */
.liftoff {
  width: 42px;
  height: 42px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(238, 240, 246, 0.8);
  border-radius: 50%;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.05);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  cursor: pointer;
  transition: transform 0.25s ease, border-color 0.25s ease, color 0.25s ease;
}
.liftoff svg { display: block; }
.liftoff:hover {
  transform: translateY(-2px);
  border-color: rgba(89, 230, 212, 0.6);
  color: #fff;
}

/* ============================================================
   WORLD 02 — HIGH STREET & LOCAL (Phase D-1)
   Warm night-street environment + sticky pin + horizontal slide.
   The websites stay flat/square-on; only the street has depth.
   ============================================================ */
.world--highstreet {
  display: block;            /* override the .world flex-centre shell */
  padding: 0;
  background: var(--bg);
}

/* Tall vertical track — its height sets how long the slide lasts.
   ~105vh of scroll per shopfront gives an unhurried, cinematic pace. */
.hs-stage { position: relative; height: 640vh; }

/* Sticky night-street viewport that holds still while the row slides.
   The night-street environment is a generated image painted directly on
   this container (master: images/high-street-bg.png). A legibility
   overlay is stacked in the SAME background declaration, so the whole
   scene is one paint layer — no child divs, no z-index to fight. The
   image anchors to the bottom so the lit shopfronts and wet-cobble
   reflections stay under the carousel at any viewport height. */
.hs-pin {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  display: flex;
  align-items: center;
  background:
    linear-gradient(180deg,
      rgba(8, 9, 13, 0.50) 0%,
      rgba(8, 9, 13, 0.18) 38%,
      rgba(8, 9, 13, 0.30) 72%,
      rgba(8, 9, 13, 0.55) 100%),
    var(--bg) url("../images/webp/high-street-bg.webp") center bottom / cover no-repeat;
}

/* Mobile-only street backdrop — hidden on desktop, where the image is
   baked onto the sticky pin above. See the .hs--static block below. */
.hs-backdrop { display: none; }

/* Section label on frosted glass (stays put while the street slides) */
.hs-marker {
  position: absolute;
  z-index: 4;
  top: clamp(1.5rem, 4vh, 2.6rem);
  left: 50%;
  transform: translateX(-50%);
  padding: 0.5rem 1.05rem;
  border-radius: 999px;
  background: rgba(22, 14, 20, 0.42);
  border: 1px solid rgba(255, 255, 255, 0.10);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: rgba(255, 200, 150, 0.92);
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.6);
}

/* ---- The sliding row of shopfronts ---- */
.hs-track {
  --shopw: min(72vw, 1100px);   /* one shop dominant, neighbours peek */
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: clamp(2rem, 4vw, 4rem);
  /* side padding so the first & last shop can sit dead-centre */
  padding: 0 calc((100vw - var(--shopw)) / 2);
  will-change: transform;
}

/* Each shopfront — flat-facing website + glass caption beneath it */
.shop {
  flex: 0 0 var(--shopw);
  width: var(--shopw);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(1rem, 2.2vh, 1.6rem);
}
.shop__frame {
  position: relative;
  display: inline-block;
  max-width: 100%;
  border-radius: 14px;
  border: 1px solid rgba(255, 157, 60, 0.35);
  background: var(--surface);
  overflow: hidden;
  box-shadow:
    0 0 0 1px rgba(255, 157, 60, 0.12),
    0 36px 90px rgba(0, 0, 0, 0.62),
    0 0 90px rgba(255, 120, 60, 0.20);
}
.shop__img {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 60vh;          /* whole design stays in view, never cropped */
  object-fit: contain;
}
/* Glass caption — the "what's special" line, cohesive with the site type */
.shop__caption {
  position: relative;        /* anchor for the floated "Try it" badge */
  max-width: min(54ch, 100%);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  padding: 0.85rem 1.4rem;
  border-radius: 14px;
  background: rgba(22, 14, 20, 0.42);
  border: 1px solid rgba(255, 255, 255, 0.10);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.shop__tag { color: rgba(255, 184, 122, 0.9); }
.shop__name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.4rem, 3vw, 2.1rem);
  letter-spacing: -0.01em;
}
.shop__desc {
  color: var(--text-dim);
  font-size: clamp(0.95rem, 1.5vw, 1.08rem);
  line-height: 1.5;
}

.hs-liftoff {
  position: absolute;
  z-index: 4;
  bottom: clamp(1.6rem, 4vh, 2.6rem);
  right: clamp(1.5rem, 4vw, 3rem);
}

/* ---- Static fallback: one continuous VERTICAL stack — same rhythm
   as Trades (real-user testing showed nobody noticed the sideways
   swipe and people scrolled straight past the retail sites).
   Applied by worlds.js (.hs--static) for reduced-motion, and by the
   @media(max-width:900px) block below for phones/tablets. Desktop
   keeps the pinned horizontal slide untouched. ---- */
.world--highstreet.hs--static .hs-stage { height: auto; }
.world--highstreet.hs--static .hs-pin {
  position: static;
  height: auto;
  display: block;
  padding: clamp(4rem, 10vh, 7rem) var(--pad);
  /* the street scene moves to the sticky backdrop below — a multi-
     screen strip can't wear a cover background without smearing it */
  background: none;
}
/* Sticky viewport-sized backdrop: the SAME one-declaration street
   background as the desktop pin, sized to one screen and stuck to the
   top while the shopfronts scroll past. Mirrors .pb-backdrop. */
.world--highstreet.hs--static .hs-backdrop {
  display: block;
  position: sticky;
  top: 0;
  z-index: -1;
  height: 100vh;
  height: 100svh;
  margin-bottom: -100vh;
  margin-bottom: -100svh;
  background:
    linear-gradient(180deg,
      rgba(8, 9, 13, 0.50) 0%,
      rgba(8, 9, 13, 0.18) 38%,
      rgba(8, 9, 13, 0.30) 72%,
      rgba(8, 9, 13, 0.55) 100%),
    var(--bg) url("../images/webp/high-street-bg.webp") center bottom / cover no-repeat;
}
.world--highstreet.hs--static .hs-track {
  --shopw: 100%;
  transform: none !important;
  flex-direction: column;
  align-items: center;
  gap: clamp(4rem, 10vh, 7rem);
  padding: 0;
  will-change: auto;
}
.world--highstreet.hs--static .shop { flex: none; width: 100%; }
.world--highstreet.hs--static .shop__img { max-height: 56vh; }
.world--highstreet.hs--static .hs-marker {
  position: static;
  transform: none;
  display: table;
  margin: 0 auto clamp(2rem, 5vh, 3rem);
}
.world--highstreet.hs--static .hs-liftoff {
  position: relative;
  right: auto;
  bottom: auto;
  margin: clamp(3rem, 8vh, 5rem) auto 0;
}

/* ============================================================
   HIGH STREET — INTERACTIVE DEMOS (Phase D-2)
   Overlays positioned by % of the mockup frame (which wraps the
   image exactly), so they stay aligned as the frame scales.
   ============================================================ */

/* ---- Burgerboys: order flow ---- */
/* Ambient hero video: pinned to the old still's true 1344×768 (7:4) box
   so the %-positioned hotspots and order panel don't shift; the 16:9
   footage covers the box (≈0.8% crop per side — invisible on the dark
   backdrop, no baked UI element sits that close to the edge). */
.shop__img[data-bb-video] { aspect-ratio: 1344 / 768; object-fit: cover; }
.bbx__hot {
  position: absolute;
  z-index: 5;
  border: 0;
  background: transparent;
  border-radius: 999px;
  cursor: pointer;
  transition: box-shadow 0.25s ease, transform 0.25s ease;
}
/* Hover = an AMBIENT GLOW BLOB behind the button: a big, soft radial
   gradient centred on the hotspot's centre (≈ the baked pill's centre),
   bright in the middle and fading to fully transparent long before any
   edge. Nothing here traces an outline, so nothing can misalign with
   the baked art — box-shadow and edge-hugging washes were tried and
   abandoned (they inherently read as an asymmetric ring/border).
   Extends well past the hotspot; the faint outer fringe that meets the
   frame's clip is already near-invisible. */
.bbx__hot::before {
  content: "";
  position: absolute;
  inset: -120% -60%;         /* button is wide+short — reach further vertically */
  background: radial-gradient(closest-side,
    rgba(255, 165, 70, 0.30), rgba(255, 150, 60, 0.10) 55%, transparent);
  opacity: 0;
  transition: opacity 0.3s ease;
  pointer-events: none;
}
/* Sized/positioned to hug the baked "Order Now" pill exactly, so the
   blob's centre = the button's rendered centre. */
.bbx__hot--cta { left: 43.7%; top: 85.6%; width: 12.7%; height: 7.9%; }
.bbx__hot--nav { left: 88%; top: 3%; width: 10%; height: 8%; border-radius: 8px; }
.bbx__hot:hover,
.bbx__hot:focus-visible { outline: none; }
.bbx__hot:hover::before,
.bbx__hot:focus-visible::before { opacity: 1; }
.bbx {
  /* A neat card contained INSIDE the frame (top/right/bottom insets), not a
     full-height panel that covers half the site or spills off the edge. */
  position: absolute;
  z-index: 6;
  top: 5%;
  right: 3.5%;
  bottom: 5%;
  width: min(38%, 300px);
  display: flex;
  flex-direction: column;
  padding: clamp(0.55rem, 1.3vw, 1.05rem);
  gap: clamp(0.35rem, 0.8vw, 0.7rem);
  border-radius: 14px;
  background: rgba(14, 9, 8, 0.9);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid rgba(255, 157, 60, 0.4);
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.55);
  color: var(--text);
  font-size: clamp(0.58rem, 0.95vw, 0.9rem);
  overflow-y: auto;            /* content always reachable, never clipped */
  opacity: 0;
  visibility: hidden;
  transform: translateX(6%);
  transition: opacity 0.3s ease, transform 0.3s ease, visibility 0.3s;
}
.bbx[aria-hidden="false"] { opacity: 1; visibility: visible; transform: none; }
.bbx__head { display: flex; align-items: center; justify-content: space-between; }
.bbx__title { font-family: var(--font-display); font-weight: 700; font-size: 1.15em; }
.bbx__close {
  background: transparent; border: 0; color: var(--text-dim);
  font-size: 1.6em; line-height: 1; cursor: pointer;
}
.bbx__items { list-style: none; display: flex; flex-direction: column; gap: 0.5em; }
.bbx__item {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "name price" "qty qty";
  gap: 0.15em 0.5em;
  padding: 0.55em 0.65em;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.08);
}
.bbx__name { grid-area: name; font-weight: 600; }
.bbx__price { grid-area: price; color: rgba(255, 184, 122, 0.95); }
.bbx__qty { grid-area: qty; display: flex; align-items: center; gap: 0.7em; margin-top: 0.2em; }
.bbx__qty button {
  width: 1.9em; height: 1.9em; border-radius: 50%;
  border: 1px solid rgba(255, 157, 60, 0.5);
  background: rgba(255, 157, 60, 0.12); color: var(--text);
  font-size: 1em; line-height: 1; cursor: pointer;
}
.bbx__qty b { min-width: 1.2em; text-align: center; }
.bbx__foot {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: auto; padding-top: 0.5em;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  font-family: var(--font-display); font-weight: 700; font-size: 1.1em;
}
.bbx__cta {
  padding: 0.7em 1em; border: 0; border-radius: 999px; cursor: pointer;
  font-family: var(--font-display); font-weight: 700; color: #2a1400;
  background: linear-gradient(100deg, #ffb020, #ff7a2f);
}
.bbx__cta:hover { filter: brightness(1.06); }
.bbx__toast {
  opacity: 0; transform: translateY(6px); transition: opacity 0.3s, transform 0.3s;
  text-align: center; color: var(--cyan); font-size: 0.95em;
}
.bbx__toast.is-show { opacity: 1; transform: none; }

/* ---- Louis Barbers: booking calendar (covers the baked panel) ---- */
.lbk {
  /* Fully inside the frame: top 20% → bottom 95%. Covers the baked panel. */
  position: absolute;
  z-index: 5;
  left: 72%; top: 20%; width: 24.5%; height: 75%;
  display: flex;
  flex-direction: column;
  gap: 0.4em;
  padding: 0.75em 0.8em;
  border-radius: 14px;
  background: rgba(18, 12, 9, 0.72);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid rgba(216, 178, 122, 0.28);
  font-size: clamp(6px, 0.7vw, 10px);
  color: var(--text);
}
.lbk__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 0.15em; }
.lbk__dow { text-align: center; color: rgba(216, 178, 122, 0.75); font-weight: 600; padding-bottom: 0.2em; }
.lbk__day {
  aspect-ratio: 1 / 1;
  display: flex; align-items: center; justify-content: center;
  border: 0; border-radius: 50%;
  background: transparent; color: var(--text);
  cursor: pointer; font: inherit;
}
.lbk__day:hover { background: rgba(216, 178, 122, 0.18); }
.lbk__day.is-muted { color: rgba(255, 255, 255, 0.25); pointer-events: none; }
.lbk__day.is-sel { background: linear-gradient(100deg, #e6c48c, #c8933f); color: #2a1400; font-weight: 700; }
.lbk__times {
  /* 18 slots (09:00–17:30 every 30 min) as a 6×3 grid — fills the panel
     between the calendar and the Book button, all visible, no scrollbar. */
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 0.3em;
  margin-top: 0.2em;
}
.lbk__time {
  padding: 0.45em 0; border-radius: 7px;
  border: 1px solid rgba(216, 178, 122, 0.35);
  background: rgba(255, 255, 255, 0.04); color: var(--text);
  cursor: pointer; font: inherit; text-align: center;
}
.lbk__time.is-sel { background: linear-gradient(100deg, #e6c48c, #c8933f); color: #2a1400; font-weight: 700; border-color: transparent; }
/* Already-taken slots: dimmed + struck through, not clickable */
.lbk__time.is-booked {
  opacity: 0.35;
  text-decoration: line-through;
  cursor: not-allowed;
  background: rgba(255, 255, 255, 0.02);
  border-color: rgba(216, 178, 122, 0.15);
}
.lbk__book {
  margin-top: auto; padding: 0.75em; border: 0; border-radius: 999px; cursor: pointer;
  font-family: var(--font-display); font-weight: 700; font-size: 1.15em; color: #2a1400;
  background: linear-gradient(100deg, #e6c48c, #c8933f);
}
.lbk__book:hover { filter: brightness(1.05); }
.lbk__done {
  position: absolute; inset: 0; z-index: 2;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 0.4em; text-align: center;
  border-radius: 14px;
  background: rgba(18, 12, 9, 0.92);
  color: var(--text);
}
.lbk__done[hidden] { display: none; }
.lbk__done b { font-family: var(--font-display); font-size: 1.6em; color: #e6c48c; }
.lbk__done span { color: var(--text-dim); font-size: 1.05em; }

/* ---- Capital Coffee: steam + hover menu + bakery pop-up ---- */
.cc-steam {
  position: absolute; z-index: 5; pointer-events: none;
  left: 57%; top: 10%; width: 20%; height: 34%;
}
.cc-steam span {
  position: absolute; bottom: 0; left: 50%;
  width: 17%; height: 70%;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255,255,255,0.72), rgba(255,255,255,0));
  filter: blur(6px);
  opacity: 0;
  animation: ccSteam 3.8s ease-in-out infinite;
}
.cc-steam span:nth-child(1) { left: 40%; animation-delay: 0s; }
.cc-steam span:nth-child(2) { left: 52%; animation-delay: 0.9s; }
.cc-steam span:nth-child(3) { left: 63%; animation-delay: 1.8s; }
.cc-steam span:nth-child(4) { left: 47%; animation-delay: 2.7s; }
@keyframes ccSteam {
  0%   { opacity: 0; transform: translate(-50%, 0) scale(0.6); }
  22%  { opacity: 0.9; }
  55%  { opacity: 0.7; }
  100% { opacity: 0; transform: translate(-72%, -165%) scale(1.6); }
}
/* Hotspot sized/positioned (in % of the frame) to hug the baked "Menu"
   nav text exactly — the highlight must never bleed into the mockup's
   browser-chrome strip above the nav row. */
.cc-menu { position: absolute; z-index: 6; left: 39%; top: 7.4%; width: 5.6%; height: 4.4%; }
.cc-menu__trigger {
  display: block; width: 100%; height: 100%; min-height: 16px;
  border: 0; background: transparent; border-radius: 6px; cursor: pointer;
  transition: box-shadow 0.2s ease, background 0.2s ease;
}
.cc-menu__trigger:hover,
.cc-menu__trigger:focus-visible {
  background: rgba(216, 178, 122, 0.14);
  box-shadow: 0 0 0 2px rgba(216, 178, 122, 0.55);
  outline: none;
}
.cc-menu__list {
  position: absolute; left: 0; top: 100%; min-width: 330%;
  list-style: none; margin-top: 0.4em; padding: 0.5em;
  white-space: nowrap;
  border-radius: 12px;
  background: rgba(24, 16, 10, 0.9);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border: 1px solid rgba(216, 178, 122, 0.3);
  font-size: clamp(0.6rem, 0.95vw, 0.9rem);
  opacity: 0; visibility: hidden; transform: translateY(-6px);
  transition: opacity 0.22s ease, transform 0.22s ease, visibility 0.22s;
}
.cc-menu:hover .cc-menu__list,
.cc-menu:focus-within .cc-menu__list,
.cc-menu.is-open .cc-menu__list { opacity: 1; visibility: visible; transform: none; }
.cc-menu__list li {
  display: flex; justify-content: space-between; gap: 1.2em;
  padding: 0.4em 0.5em; border-radius: 7px;
}
.cc-menu__list li + li { border-top: 1px solid rgba(255, 255, 255, 0.07); }
.cc-menu__list li:hover { background: rgba(216, 178, 122, 0.16); }
.cc-menu__list b { color: rgba(255, 200, 150, 0.95); }
/* ---- Capital Coffee: drink photo cards over the baked bottom boxes.
   Positioned (in % of the frame) to fully cover the mockup's baked
   "Flat White / Cortado / Filter" strip. Like the baked boxes they run
   flush to the frame's bottom edge, so only the top corners round. ---- */
.cc-drinks {
  position: absolute; z-index: 6;
  left: 6.4%; top: 78.4%; width: 33.4%; height: 21.6%;
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 5%;
}
.cc-drink {
  display: flex; flex-direction: column;
  border: 0; padding: 0; cursor: pointer;
  border-radius: 8px 8px 0 0; overflow: hidden;
  background: #f7f0e2;
  box-shadow: 0 4px 16px rgba(60, 35, 10, 0.22);
  font-family: var(--font-body);
  transition: transform 0.22s ease, box-shadow 0.22s ease;
}
.cc-drink img {
  width: 100%; flex: 1; min-height: 0;
  object-fit: cover; display: block;
}
.cc-drink__name {
  font-weight: 700; color: #3c2a18;
  /* 5px floor so "Cappuccino" fits the tiny phone-width cards un-clipped */
  font-size: clamp(5px, 0.72vw, 11px);
  white-space: nowrap;
  padding: 0.5em 0.3em 0.1em;
}
.cc-drink__price {
  color: #8a6a42;
  font-size: clamp(4.5px, 0.66vw, 10px);
  padding-bottom: 0.55em;
}
.cc-drink:hover,
.cc-drink:focus-visible {
  transform: translateY(-3px);
  box-shadow: 0 10px 24px rgba(60, 35, 10, 0.3), 0 0 0 2px rgba(200, 147, 63, 0.55);
  outline: none;
}
.cc-rec {
  position: absolute; z-index: 6; left: 56%; top: 60%; width: 32%;
  display: flex; align-items: center; gap: 0.6em;
  padding: 0.7em 0.9em; border-radius: 14px;
  background: rgba(24, 16, 10, 0.86);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border: 1px solid rgba(216, 178, 122, 0.35);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
  font-size: clamp(0.62rem, 1vw, 0.95rem);
  color: var(--text);
  /* Hidden by default — worlds.js adds .is-show while a menu item is
     hovered (the "pair it with" upsell reacts to browsing the menu). */
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition: opacity 0.25s ease, transform 0.25s ease, visibility 0.25s;
}
.cc-rec.is-show {
  opacity: 1;
  visibility: visible;
  transform: none;
  animation: ccRec 3.2s ease-in-out infinite;
}
.cc-rec.is-hidden { display: none; }   /* × = dismissed for good */
.cc-rec__emoji { font-size: 1.5em; }
.cc-rec__txt b { color: rgba(255, 200, 150, 0.95); }
.cc-rec__x {
  margin-left: auto; background: transparent; border: 0; color: var(--text-dim);
  font-size: 1.3em; line-height: 1; cursor: pointer;
}
@keyframes ccRec {
  0%, 100% { transform: translateY(0); box-shadow: 0 12px 40px rgba(0,0,0,0.5), 0 0 0 0 rgba(216,178,122,0.4); }
  50%      { transform: translateY(-4px); box-shadow: 0 16px 46px rgba(0,0,0,0.55), 0 0 0 6px rgba(216,178,122,0); }
}

/* ============================================================
   WORLD 03 — INDIVIDUAL & PERSONAL BRANDS (Phase E)
   Dark photography-studio environment + sticky pin + turntable.
   The websites stay flat/square-on; only their position, size
   and lighting change as they sweep through the spotlight.
   ============================================================ */
.world--personal {
  display: block;            /* override the .world flex-centre shell */
  padding: 0;
  background: var(--bg);
}

/* Tall scroll track — ~115vh of scroll per site keeps the same
   unhurried, cinematic pace as the other two worlds, plus a 100vh
   lights-out stretch at the end: the star sweep finishes at 87.5%
   of the stage (STAR_END in worlds.js) and the .pb-dim overlay
   fades the studio to the base dark over the remainder. */
.pb-stage { position: relative; height: 800vh; }

/* Sticky studio viewport. The studio environment is a generated image
   painted directly on this container (master: images/studio-bg.png) in
   ONE background declaration with a legibility gradient stacked above
   it — same baked pattern as High Street: no separate layers, nothing
   to fight. Anchored bottom so the lit floor stays under the mockups. */
.pb-pin {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    linear-gradient(180deg,
      rgba(8, 9, 13, 0.55) 0%,
      rgba(8, 9, 13, 0.10) 30%,
      rgba(8, 9, 13, 0.16) 70%,
      rgba(8, 9, 13, 0.58) 100%),
    var(--bg) url("../images/webp/studio-bg.webp") center bottom / cover no-repeat;
}

/* Lights-out dissolve — a base-dark cover scrubbed 0 -> 1 by worlds.js
   over the last stretch of the stage, so the studio fades to black IN
   PLACE (over the still-spotlit final site) before the closing screen.
   Sits above everything in the pin; always click-through. */
.pb-dim {
  position: absolute;
  inset: 0;
  z-index: 500;
  background: var(--bg);
  opacity: 0;
  pointer-events: none;
  will-change: opacity;
}

/* Mobile-only studio backdrop — hidden on desktop, where the image is
   baked onto the sticky pin above. See the .pb--static block below. */
.pb-backdrop { display: none; }

/* Section label on frosted glass (static element, safe for blur —
   it never sits over a mockup frame or inside an animated card) */
.pb-marker {
  position: absolute;
  z-index: 4;
  top: clamp(1.5rem, 4vh, 2.6rem);
  left: 50%;
  transform: translateX(-50%);
  padding: 0.5rem 1.05rem;
  border-radius: 999px;
  background: rgba(14, 14, 20, 0.42);
  border: 1px solid rgba(255, 255, 255, 0.10);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: rgba(255, 231, 191, 0.92);
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.6);
}

/* ---- The star stack (Trades-scale: the website is the hero) ---- */
.pb-plates {
  position: relative;
  z-index: 2;
  width: min(1480px, 96vw);
  height: 88vh;
}

/* Each star — stacked, JS sweeps them along a flat arc. The caption
   sits LEFT (studio shadow); the framed site sits right-of-centre so
   it lands under the image's baked light beam (~60% across). The
   website itself is FLAT, straight-on, never tilted (Absolute Rule 1);
   the turntable lives in translateX/scale/brightness only. */
.star {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: clamp(1rem, 2.5vw, 2.25rem);
  opacity: 0;
  will-change: transform, opacity, filter;
}

/* Left block: the write-up. A translucent panel (NO backdrop-filter —
   the card is opacity/transform-animated, which is exactly where
   Chromium white-boxes blur; a plain rgba fill reads as glass against
   the dark studio without the risk). */
.star__meta {
  order: -1;                 /* caption left of the frame, in the shadow */
  flex: 0 1 300px;
  min-width: 0;
  max-width: 32ch;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.35rem;
  text-align: left;
  padding: 1rem 1.2rem;
  border-radius: 14px;
  background: rgba(10, 10, 16, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.09);
}
.star__tag { color: rgba(255, 215, 150, 0.9); }
.star__cat {
  align-self: stretch;
  color: rgba(255, 225, 175, 0.95);
  font-size: 0.95rem;
  letter-spacing: 0.02em;
  padding-bottom: 0.5rem;
  margin-bottom: 0.3rem;
  border-bottom: 1px solid rgba(255, 215, 150, 0.28);
}
.star__desc {
  color: var(--text-dim);
  font-size: clamp(0.95rem, 1.6vw, 1.1rem);
  line-height: 1.5;
}

/* Right block: the framed screen with its name beneath (Trades scale) */
.star__frame {
  flex: 0 1 auto;
  min-width: 0;
  max-width: 78%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(0.7rem, 1.8vh, 1.2rem);
}
/* Warm rim light — the studio spotlight's answer to Trades' blue glow
   and High Street's amber. The frame wraps the image exactly so the
   full design is always visible, never cropped. */
.star__media {
  position: relative;
  display: inline-block;
  max-width: 100%;
  border-radius: 14px;
  border: 1px solid rgba(255, 215, 150, 0.42);
  background: var(--surface);
  overflow: hidden;
  box-shadow:
    0 0 0 1px rgba(255, 215, 150, 0.14),
    0 36px 90px rgba(0, 0, 0, 0.65),
    0 0 100px rgba(255, 200, 120, 0.2);
}
.star__img {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 78vh;          /* dominant, whole design stays in view */
  object-fit: contain;
}
/* Jay Carter click-to-play demo: the whole mockup is the trigger */
.star__img[data-jc-video] { cursor: pointer; }
.star__name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.4rem, 3.4vw, 2.2rem);
  letter-spacing: -0.01em;
  text-shadow: 0 2px 18px rgba(0, 0, 0, 0.7);
}

.pb-liftoff {
  position: absolute;
  z-index: 4;
  bottom: clamp(1.6rem, 4vh, 2.6rem);
  right: clamp(1.5rem, 4vw, 3rem);
}

/* ---- Static fallback (mobile / reduced-motion): a plain vertical
   stack, same continuous-scroll rhythm as Trades and High Street. ---- */
.world--personal.pb--static .pb-stage { height: auto; }
/* no pinned scrub on mobile — no lights-out dissolve either */
.world--personal.pb--static .pb-dim { display: none; }
.world--personal.pb--static .pb-pin {
  position: static;
  height: auto;
  display: block;
  padding: clamp(4rem, 10vh, 7rem) var(--pad);
  /* the studio scene moves to the sticky backdrop below — a ~600vh
     strip can't wear a cover background without smearing it */
  background: none;
  overflow: visible;
}
/* Sticky viewport-sized backdrop: the SAME one-declaration studio
   background as the desktop pin, but sized to one screen and stuck to
   the top while the cards scroll past — every screenful shows the
   complete studio. z-index -1 keeps it behind every card; it leaves
   with the section. Zero layout height (negative bottom margin). */
.world--personal.pb--static .pb-backdrop {
  display: block;
  position: sticky;
  top: 0;
  z-index: -1;
  height: 100vh;
  height: 100svh;
  margin-bottom: -100vh;
  margin-bottom: -100svh;
  background:
    linear-gradient(180deg,
      rgba(8, 9, 13, 0.55) 0%,
      rgba(8, 9, 13, 0.10) 30%,
      rgba(8, 9, 13, 0.16) 70%,
      rgba(8, 9, 13, 0.58) 100%),
    var(--bg) url("../images/webp/studio-bg.webp") center bottom / cover no-repeat;
}
.world--personal.pb--static .pb-plates {
  width: 100%;
  height: auto;
  display: flex;
  flex-direction: column;
  gap: clamp(4rem, 10vh, 7rem);
}
.world--personal.pb--static .star {
  position: relative;
  inset: auto;
  opacity: 1;
  transform: none;
  filter: none;
  flex-direction: column;    /* frame on top, write-up below */
  gap: clamp(1.2rem, 4vh, 2rem);
}
.world--personal.pb--static .star__frame { max-width: 100%; }
.world--personal.pb--static .star__img { max-height: 62vh; }
.world--personal.pb--static .star__meta {
  order: 0;                  /* caption drops back below the frame */
  flex: none;
  max-width: min(60ch, 100%);
  text-align: center;
  align-items: center;
}
.world--personal.pb--static .pb-marker {
  position: static;
  transform: none;
  display: table;
  margin: 0 auto clamp(2rem, 5vh, 3rem);
}
.world--personal.pb--static .pb-liftoff {
  position: relative;
  right: auto;
  bottom: auto;
  margin: clamp(3rem, 8vh, 5rem) auto 0;
}

/* ============================================================
   CLOSING CTA (Phase F) — journey's end. A clean screen on the
   base dark, revealed after the studio dims out (same colour, so
   the hand-off is seamless). Content fades up once on arrival
   (.is-in added by an IntersectionObserver in main.js).
   Deliberately no lift-off control — the journey ends on the ask.
   ============================================================ */
.closing {
  position: relative;
  /* Same paint layer as the .world sections: being later in the page,
     this covers the mobile studio backdrop's legal one-screen overhang
     (sticky + negative margin) — exactly how each world already covers
     the previous one's. Without it the overhang paints over this
     screen on mobile. */
  z-index: 2;
  overflow: hidden;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  background: var(--bg);
  padding: var(--section-gap) var(--pad);
}

/* ---- Deep-space scene (calmer echo of the hero) ---- */
/* Star field: two tiled layers of tiny radial-gradient stars at
   co-prime tile sizes so no repeating grid reads through. The ::after
   layer carries a slow twinkle (killed under reduced motion). */
.closing-sky {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image:
    radial-gradient(circle at 22px 34px,  rgba(238, 240, 246, 0.60) 0.8px, transparent 1.6px),
    radial-gradient(circle at 118px 80px, rgba(238, 240, 246, 0.40) 0.7px, transparent 1.4px),
    radial-gradient(circle at 63px 151px, rgba(238, 240, 246, 0.50) 0.6px, transparent 1.2px),
    radial-gradient(circle at 170px 22px, rgba(89, 230, 212, 0.35) 0.7px, transparent 1.4px),
    radial-gradient(circle at 205px 189px, rgba(238, 240, 246, 0.30) 0.6px, transparent 1.2px),
    radial-gradient(circle at 149px 235px, rgba(238, 240, 246, 0.55) 0.8px, transparent 1.6px);
  background-size: 260px 260px;
}
.closing-sky::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    radial-gradient(circle at 40px 60px,  rgba(238, 240, 246, 0.50) 0.9px, transparent 1.8px),
    radial-gradient(circle at 200px 140px, rgba(0, 170, 255, 0.35) 0.8px, transparent 1.6px),
    radial-gradient(circle at 300px 40px, rgba(238, 240, 246, 0.40) 0.7px, transparent 1.4px),
    radial-gradient(circle at 110px 260px, rgba(123, 47, 255, 0.30) 0.8px, transparent 1.6px),
    radial-gradient(circle at 260px 300px, rgba(238, 240, 246, 0.45) 0.7px, transparent 1.4px);
  background-size: 340px 340px;
  animation: closingTwinkle 7s ease-in-out infinite alternate;
}
@keyframes closingTwinkle {
  from { opacity: 0.45; }
  to   { opacity: 1; }
}

/* Distant Earth + the far alien, top-right. One group container so
   the pair scales and moves together across viewports. */
.closing-far {
  position: absolute;
  z-index: 0;
  top: clamp(3.5rem, 9vh, 6.5rem);
  right: clamp(2rem, 9vw, 8rem);
  width: clamp(110px, 12vw, 170px);
}
/* Same palette as the hero's (retired) CSS Earth, shrunk to a distant
   sphere with a faint brand rim glow. */
.closing-planet {
  width: 100%;
  aspect-ratio: 1;
  border-radius: 50%;
  background:
    radial-gradient(circle at 42% 26%, rgba(89, 230, 212, 0.22), transparent 46%),
    radial-gradient(circle at 38% 34%, #1f6fd6 0%, #123b7a 40%, #0a1f44 62%, #050c1f 82%);
  box-shadow:
    0 0 36px rgba(0, 170, 255, 0.18),
    0 0 90px rgba(123, 47, 255, 0.10),
    inset -20px -16px 55px rgba(0, 0, 0, 0.65),
    inset 0 16px 55px rgba(89, 230, 212, 0.10);
}
/* The alien stands on the planet's upper-left arc */
#alien-far {
  position: absolute;
  left: 8%;
  bottom: 86%;
  filter: drop-shadow(0 0 8px rgba(8, 170, 255, 0.35));
}

.closing__inner {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.3rem;
  max-width: 46rem;
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 0.9s ease, transform 0.9s ease;
}
.closing.is-in .closing__inner {
  opacity: 1;
  transform: none;
}
/* Same header voice as the world titles (.world__title) */
.closing__title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2rem, 5vw, 3.2rem);
  letter-spacing: -0.01em;
}
.closing__price {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.15rem, 2.6vw, 1.6rem);
}
/* Gradient numbers — brand gradient clipped to the text. The solid
   --blue is the fallback: if a browser can't clip, text-fill-color
   is equally unsupported, so the colour simply shows through. */
.closing__num {
  color: var(--blue);
  background: var(--grad);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  font-weight: 800;
}
.closing__sub {
  font-size: 0.95rem;
  color: var(--text-dim);
}
.closing__pricelist {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  color: var(--text-dim);
  text-decoration: underline;
  text-underline-offset: 4px;
  transition: color 0.25s ease;
}
.closing__pricelist:hover { color: var(--text); }
/* Main CTA — same gradient-pill DNA as .view-all in the hero */
.closing__cta {
  margin-top: 0.7rem;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(1.1rem, 2.2vw, 1.45rem);
  color: #fff;
  padding: 1.15rem 2.6rem;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 18px;
  background: var(--grad);
  box-shadow:
    0 0 0 1px rgba(8, 170, 255, 0.25),
    0 18px 60px rgba(8, 170, 255, 0.5),
    0 8px 30px rgba(123, 47, 255, 0.5);
  transition: transform 0.25s ease, box-shadow 0.25s ease, filter 0.25s ease;
}
.closing__cta:hover {
  transform: translateY(-4px) scale(1.025);
  filter: brightness(1.08);
  box-shadow:
    0 0 0 1px rgba(8, 170, 255, 0.4),
    0 22px 70px rgba(8, 170, 255, 0.6),
    0 10px 36px rgba(123, 47, 255, 0.6);
}

/* ============================================================
   RESPONSIVE
   ============================================================ */
/* ---- Trades: stack frame + write-up on tablets / phones ----
   Belt-and-suspenders for the .trades--static JS fallback: even if the
   class isn't applied (e.g. an in-between width or a live resize), the
   inner plate stacks image-on-top, write-up below at narrow widths.
   Breakpoint matches worlds.js (900px) so the two never disagree. */
@media (max-width: 900px) {
  .world--trades .plate {
    flex-direction: column;
    gap: clamp(1.2rem, 4vh, 2rem);
  }
  .world--trades .plate__frame {
    max-width: 100%;
    margin-left: 0;
  }
  .world--trades .plate__meta {
    flex: none;
    max-width: min(60ch, 100%);   /* never wider than the phone viewport */
    text-align: center;
    align-items: center;
  }

  /* High Street: fall back to the vertical stack even if worlds.js
     hasn't added .hs--static (JS-off / in-between width). Mirrors
     the .hs--static rules; breakpoint matches worlds.js (900px). */
  .world--highstreet .hs-stage { height: auto; }
  .world--highstreet .hs-pin {
    position: static;
    height: auto;
    display: block;
    padding: clamp(4rem, 10vh, 7rem) var(--pad);
    background: none;
  }
  .world--highstreet .hs-backdrop {
    display: block;
    position: sticky;
    top: 0;
    z-index: -1;
    height: 100vh;
    height: 100svh;
    margin-bottom: -100vh;
    margin-bottom: -100svh;
    background:
      linear-gradient(180deg,
        rgba(8, 9, 13, 0.50) 0%,
        rgba(8, 9, 13, 0.18) 38%,
        rgba(8, 9, 13, 0.30) 72%,
        rgba(8, 9, 13, 0.55) 100%),
      var(--bg) url("../images/webp/high-street-bg.webp") center bottom / cover no-repeat;
  }
  .world--highstreet .hs-track {
    --shopw: 100%;
    transform: none !important;
    flex-direction: column;
    align-items: center;
    gap: clamp(4rem, 10vh, 7rem);
    padding: 0;
    will-change: auto;
  }
  .world--highstreet .shop { flex: none; width: 100%; }
  .world--highstreet .shop__img { max-height: 56vh; }
  /* On narrow screens the floated badge would hang outside the
     viewport, so it drops back inside the caption, centred. */
  .world--highstreet .shop__caption .demo-cue {
    position: static;
    translate: none;
    margin-top: 0.3rem;
    align-self: center;
  }
  .world--highstreet .hs-marker {
    position: static;
    transform: none;
    display: table;
    margin: 0 auto clamp(2rem, 5vh, 3rem);
  }
  .world--highstreet .hs-liftoff {
    position: relative;
    right: auto;
    bottom: auto;
    margin: clamp(3rem, 8vh, 5rem) auto 0;
  }
  /* Louis Barbers booking panel: at phone sizes the fixed 75% height is
     shorter than the calendar + slots + Book stack (font is already at
     its 6px floor), so the Book button crossed the panel edge and was
     clipped by the frame. Let the panel hug its content and tighten the
     spacing instead — contained at any phone width, still no scrollbar. */
  /* min-height (not height) keeps the content-hugging fix above while
     stretching the panel's bottom edge back to 95% of the frame (12% +
     83%) — the same coverage as desktop — so the mockup's baked-in
     "Book Now" button can't peek out underneath the interactive one. */
  .world--highstreet .lbk { top: 12%; height: auto; min-height: 83%; padding: 0.5em 0.6em; gap: 0.3em; }
  .world--highstreet .lbk__time { padding: 0.35em 0; }
  .world--highstreet .lbk__book { margin-top: 0.2em; padding: 0.55em; }

  /* Six-column slot grid can't fit "09:00"-width labels in the tiny
     phone panel, so labels clipped. Show every third slot instead —
     09:00, 10:30, 12:00, 13:30, 15:00, 16:30 — in three wide columns.
     Desktop keeps all 18; the JS booking logic is untouched. */
  .world--highstreet .lbk__times { grid-template-columns: repeat(3, 1fr); }
  .world--highstreet .lbk__time { display: none; }
  .world--highstreet .lbk__time:nth-child(3n + 1) { display: block; }

  /* Burger Boys: the full 3-item list pushes the order total below the
     panel's visible area on phones, so drop the Double Stack row here.
     Desktop keeps all three; the JS totals logic is untouched (a hidden
     row just stays at qty 0). */
  .world--highstreet .bbx__item--stack { display: none; }

  /* Even with the Double Stack row hidden, the panel's content ran ~23px
     past its box at phone sizes, so the Checkout button showed as a
     clipped sliver (reachable only by scrolling inside the tiny panel).
     Tighten the panel's spacing scale so head → items → total → Checkout
     all fit in the visible box; desktop spacing is untouched. */
  .world--highstreet .bbx { padding: 0.4rem 0.45rem; gap: 0.22rem; }
  .world--highstreet .bbx__item { padding: 0.35em 0.5em; }
  .world--highstreet .bbx__foot { padding-top: 0.3em; }
  .world--highstreet .bbx__cta { padding: 0.5em 0.9em; }

  /* Personal Brands: fall back to the vertical stack even if
     worlds.js hasn't added .pb--static (JS-off / in-between width).
     Mirrors the .pb--static rules; breakpoint matches worlds.js. */
  .world--personal .pb-stage { height: auto; }
  .world--personal .pb-pin {
    position: static;
    height: auto;
    display: block;
    padding: clamp(4rem, 10vh, 7rem) var(--pad);
    background: none;
    overflow: visible;
  }
  .world--personal .pb-backdrop {
    display: block;
    position: sticky;
    top: 0;
    z-index: -1;
    height: 100vh;
    height: 100svh;
    margin-bottom: -100vh;
    margin-bottom: -100svh;
    background:
      linear-gradient(180deg,
        rgba(8, 9, 13, 0.55) 0%,
        rgba(8, 9, 13, 0.10) 30%,
        rgba(8, 9, 13, 0.16) 70%,
        rgba(8, 9, 13, 0.58) 100%),
      var(--bg) url("../images/webp/studio-bg.webp") center bottom / cover no-repeat;
  }
  .world--personal .pb-plates {
    width: 100%;
    height: auto;
    display: flex;
    flex-direction: column;
    gap: clamp(4rem, 10vh, 7rem);
  }
  .world--personal .star {
    position: relative;
    inset: auto;
    opacity: 1;
    transform: none;
    filter: none;
    flex-direction: column;
    gap: clamp(1.2rem, 4vh, 2rem);
  }
  .world--personal .star__frame { max-width: 100%; }
  .world--personal .star__img { max-height: 62vh; }
  .world--personal .star__meta {
    order: 0;
    flex: none;
    max-width: min(60ch, 100%);
    text-align: center;
    align-items: center;
  }
  .world--personal .pb-marker {
    position: static;
    transform: none;
    display: table;
    margin: 0 auto clamp(2rem, 5vh, 3rem);
  }
  .world--personal .pb-liftoff {
    position: relative;
    right: auto;
    bottom: auto;
    margin: clamp(3rem, 8vh, 5rem) auto 0;
  }
}

@media (max-width: 760px) {
  .cat-row { grid-template-columns: 1fr; width: min(100%, 360px); gap: 0.6rem; }
  /* Shrink + lower the controls so the button stack can't reach the headline. */
  .hero-controls { bottom: 4vh; gap: 0.7rem; }
  .catbtn { padding: 0.75rem 1rem; }
  /* Sit the tagline clear of the video's baked-in ATAI HEADQUARTERS wordmark
     (top third) AND well above the button stack, so nothing collides. */
  .hero-copy { top: 45vh; width: 94vw; gap: 0.35rem; }
  .hero-copy__title { font-size: clamp(1.15rem, 5.4vw, 1.6rem); }
  .hero-copy__sub { display: none; }   /* keep the small screen breathing */
  .view-all { padding: 0.95rem 1.4rem; }
  #alien { display: none; }   /* alien hidden on mobile (brief) */
  #alien-far { display: none; }   /* far alien too — no cursor to aim at */
  /* scroll cue: bigger still on phones — Champ flagged it was easy
     to miss there */
  .scroll-whisper__arrow { width: 34px; height: 34px; }
  /* CTA label + arrow are one unbreakable unit (&nbsp; in the HTML) —
     scale with the viewport on phones so it always fits on one line,
     down to 320px-wide devices */
  .closing__cta {
    font-size: clamp(0.85rem, 4.6vw, 1rem);
    padding: 1rem clamp(0.9rem, 4vw, 1.5rem);
    max-width: 100%;
  }
  .plate__cue,
  .demo-cue { font-size: 0.72rem; padding: 0.34rem 0.6rem; }
}

/* Short viewports (e.g. 1366×768 laptops): the wordmark, tagline, buttons
   and Earth horizon already fill the height — hide the alien so it can't
   graze the tagline. (Already hidden under 760px width.) */
@media (max-height: 820px) {
  #alien { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .scroll-whisper__arrow,
  .view-all,
  .volt-spark,
  .plate__cue,
  .demo-cue,
  .cc-steam span,
  .cc-rec { animation: none; }
  .cc-steam { display: none; }
  .cc-drink { transition: none; }
  /* closing content is simply there — no fade-up, no twinkle, and no
     far alien (his tracking/firing JS is off, so he'd just be frozen) */
  .closing__inner { opacity: 1; transform: none; transition: none; }
  .closing-sky::after { animation: none; }
  #alien-far { display: none; }
}
/* Touch devices: no cursor to track — the far alien stays home */
@media (hover: none), (pointer: coarse) {
  #alien-far { display: none; }
}
