/* v22: the hero, Moth's entry screen when signed out (#join-screen): the app's tokens (app.css :root),
   its layout, the Moth-and-light scene (since v25 one birthday seen from around the table, assets/landing/moment),
   the start/join panel and the footer. v25: the turning word in the headline, the Moth's path between the
   photos, "or scan a friend's code" and Your Moments. The three proofs below it are in css/hero-story.css. Every rule
   is scoped to .hero-screen and the hero's own classes are prefixed, so nothing here reaches the app. */
.hero-screen {
  --gutter: 22px;
  --word: #a8573f; /* the turning word: a muted coral, warm like the light */
  --lamp-core: #fff8e6;
  --print-edge: #fffefb;
  --mono: ui-monospace, "SF Mono", Menlo, monospace;
  display: block; min-height: 100svh; overflow-x: clip; font-size: 16px; line-height: 1.55; color: var(--ink);
}
/* Resets without weight (:where), so every hero rule below keeps its own margins. */
:where(.hero-screen) :where(h1, h2, p, ol, ul) { margin: 0; }
:where(.hero-screen) :where(ol, ul) { padding: 0; list-style: none; }
:where(.hero-screen) img { user-select: none; -webkit-user-drag: none; }

/* ---------- Top bar ---------- */
.hero-top {
  display: flex; align-items: center; gap: 6px; height: calc(56px + env(safe-area-inset-top)); position: relative; z-index: 3;
  padding: env(safe-area-inset-top) max(var(--gutter), env(safe-area-inset-right)) 0 max(calc(var(--gutter) - 6px), env(safe-area-inset-left));
}
.hero-top-logo { width: 34px; height: 34px; }
.hero-top .wordmark { font-size: 24px; line-height: 1; }

/* ---------- Hero ---------- */
/* Phones: the scene on top, then the words, then Start and the code. */
.hero {
  display: grid; grid-template-areas: "scene" "copy" "actions";
  /* The scene's height is fixed by the viewport, not by the panel, so changing step never moves the moth. */
  grid-template-rows: clamp(220px, calc(100svh - 56px - 480px), 440px) auto auto; align-content: start;
  min-height: calc(100svh - 56px - env(safe-area-inset-top));
  padding: 0 max(var(--gutter), env(safe-area-inset-right)) max(24px, env(safe-area-inset-bottom)) max(var(--gutter), env(safe-area-inset-left));
}

/* ---------- The scene: the Moth drawn toward a soft light, the birthday's photos around it at three depths ---------- */
.hero-scene {
  grid-area: scene; position: relative; min-width: 0; margin: 0 calc(var(--gutter) * -1);
  font-size: clamp(9px, 2.6vw, 15px); overflow: hidden; isolation: isolate;
}
/* The table of photos dissolves into the page instead of ending at a hard edge. A still veil in the
   page's colour, not a mask: a mask over moving layers is redrawn every frame (about 3x the cost). */
.hero-scene::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, var(--bg) 0, #fafaf700 14%, #fafaf700 80%, var(--bg) 100%);
}
.hero-layer { position: absolute; inset: 0; will-change: transform; }
.hero-enter { position: absolute; inset: 0; }
.hero-lamp {
  position: absolute; left: 62%; top: 20%; width: 34em; height: 34em; margin: -17em 0 0 -17em; border-radius: 50%;
  background: radial-gradient(circle, var(--lamp-core) 0 7%, #fff1cc 14%, #ffe7ad9e 30%, #ffe7ad3d 48%, #ffe7ad00 68%);
}
/* A print: the outer box drifts (composited, transform only); the card inside carries the tilt, the
   frame, the shadow and the blur, so all of that is painted once into the print's layer instead of every
   frame. The drift's keyframes hold plain pixels and some prints run them the other way round with
   their own keyframes, never animation-direction: alternate-reverse, which WebKit keeps off the GPU
   (it repainted the blurred cards every frame: ~17% of a core on a Mac, 0.1% without). */
.hero-print { --r: 0deg; position: absolute; }
.hero-card {
  display: block; width: 100%; height: 100%; padding: 4px; border-radius: 4px; background: var(--print-edge); transform: rotate(var(--r));
  box-shadow: 0 10px 24px -12px #3a3a2a52, 0 1px 2px #3a3a2a1f;
}
.hero-card img { display: block; width: 100%; height: 100%; object-fit: cover; border-radius: 2px; background: #e4e1d6; }
/* Out of focus by distance: far and near soft, the middle nearly sharp. */
.layer-far .hero-card { filter: blur(4px) saturate(.9); opacity: .55; }
.layer-mid .hero-card { filter: blur(1.2px); opacity: .92; }
.layer-near .hero-card { filter: blur(4px); opacity: .95; }
.hero-print.p-f1 { --r: -7deg; left: 3%; top: 7%; width: 8.2em; height: 6.2em; }
.hero-print.p-f2 { --r: 6deg; right: 3%; top: 5%; width: 8em; height: 5.8em; }
.hero-print.p-f3 { --r: 4deg; left: 33%; bottom: 6%; width: 6.8em; height: 5.2em; }
.hero-print.p-m1 { --r: -6deg; left: 3%; top: 40%; width: 10em; height: 6.7em; }
.hero-print.p-m2 { --r: 5deg; right: 1%; top: 25%; width: 12.6em; height: 8.4em; }
.hero-print.p-m3 { --r: -3deg; right: 22%; bottom: 2%; width: 9.2em; height: 6.1em; }
/* v25: the birthday room, out of focus: one photo, framed five ways (far and near). The three views in
   the middle are the photos as taken (3:2, uncropped). */
.crop-room-left img { object-position: 0% 30%; }
.crop-room-right img { object-position: 100% 20%; }
.crop-room-table img { object-position: 50% 70%; }
.crop-room-backs img { object-position: 15% 95%; }
.crop-room-lamp img { object-position: 85% 0%; }
.hero-print.p-n1 { --r: 9deg; left: -8%; bottom: -12%; width: 14em; height: 10em; }
.hero-print.p-n2 { --r: -11deg; right: -9%; top: -8%; width: 12em; height: 9.4em; }
.layer-moth .hero-enter { display: grid; place-items: center; }
/* v25: the path is carried by a box the Moth's own size (and one the shadow's size), never a box the size
   of the scene: moving a big layer every frame costs ~3x the CPU where compositing is in software. Both
   are sized in the scene's em, so the path scales with the scene. */
.hero-moth-enter { padding-top: 2%; }
.hero-moth-path { position: relative; }
.hero-moth-hop { position: relative; width: 14em; transform-origin: 50% 70%; }
.hero-moth-float { position: relative; transform: rotate(5deg); }
.hero-moth-img { width: 100%; height: auto; filter: drop-shadow(0 .7em .9em #6b55301f); }
.hero-moth-happy { position: absolute; inset: 0; opacity: 0; transition: opacity .5s ease; }
.hero-scene.is-happy .hero-moth-happy { opacity: 1; }
.hero-scene.is-flutter .hero-moth-happy { transition-duration: .15s; } /* Start pressed: the coral Moth at once */
/* The Moth's shadow lives one layer further back, so the Moth moves over it as the page scrolls or the
   pointer moves: that small gap is what makes it read as flying. */
.hero-shadow-path { position: absolute; left: 50%; top: 51%; width: 9.4em; height: 1.4em; margin: 7.1em 0 0 -4.7em; } /* v25: sized to the 14em Moth */
.hero-moth-shadow {
  position: absolute; inset: 0; border-radius: 50%;
  background: radial-gradient(ellipse, #5b4b302b 0, #5b4b3000 70%);
}
.hero-scene.is-happy .hero-moth-shadow { opacity: .8; }

/* The one page-load moment: the light comes up, the photos settle in from far to near, then the
   moth rises toward the light. Only once hero.js runs (.hero-js), so nothing hides without it. */
.hero-js .hero-enter { opacity: 0; transition: opacity 1.2s ease, transform 1.6s var(--settle); }
.hero-js .layer-light .hero-enter { transform: scale(.82); transition-duration: 1.8s, 2.4s; }
.hero-js .layer-far .hero-enter { transform: translateY(14px); transition-delay: .25s; }
.hero-js .layer-mid .hero-enter { transform: translateY(22px); transition-delay: .4s; }
.hero-js .layer-near .hero-enter { transform: translateY(40px) scale(1.04); transition-delay: .55s; }
.hero-js .hero-shade-enter { transition-duration: 1.6s; transition-delay: .9s; }
.hero-js .hero-moth-enter { transform: translateY(46px) scale(.94); transition-duration: 1s, 1.9s; transition-delay: .7s; }
.hero-js .hero-copy { opacity: 0; transform: translateY(10px); transition: opacity .9s ease .9s, transform 1.2s var(--settle) .9s; }
.hero-js.is-ready .hero-enter, .hero-js.is-ready .hero-copy { opacity: 1; transform: none; }
/* If hero.js never arrives, the scene and the words still show after a moment. */
.hero-js:not(.is-ready) .hero-enter, .hero-js:not(.is-ready) .hero-copy { animation: hero-late 0s 3s forwards; }
@keyframes hero-late { to { opacity: 1; transform: none; } }

/* ---------- Copy and actions ---------- */
.hero-copy { grid-area: copy; padding-top: 6px; }
.hero-copy h1 {
  font-family: var(--serif); font-weight: 400; font-size: clamp(34px, 9.4vw, 62px); line-height: 1.04;
  letter-spacing: -.035em; text-wrap: balance; max-width: 13ch;
}
/* v25: "Same moment. / Different eyes." Two lines that never wrap; the word's box keeps the width of
   "memories." so nothing moves when it turns. Without hero.js (or with reduced motion) "eyes." stays. */
.hero-copy h1.hero-title { max-width: none; }
.hero-line { display: block; white-space: nowrap; }
.hero-word { position: relative; display: inline-block; font-style: italic; color: var(--word); }
.hero-word-size { visibility: hidden; }
/* The word rises and fades, the next comes up from below and settles: transform and opacity only. A blur
   was tried and dropped (any filter on these words cost ~9-16% of a core in Chrome while the scene moves). */
.hero-word-text { position: absolute; left: 0; top: 0; white-space: nowrap; opacity: 0; transform: translateY(.32em); }
.hero-word-text.is-in { opacity: 1; transform: none; }
.hero-word-text.is-out { opacity: 0; transform: translateY(-.22em); }
.hero-word.is-turning .hero-word-text { transition: opacity .7s ease, transform 1s var(--settle); }
.hero-lede { margin-top: 14px; color: #4c534f; font-size: 16px; line-height: 1.6; max-width: 38em; text-wrap: balance; } /* never "view." alone on a line */

.hero-actions { grid-area: actions; padding-top: 24px; outline: none; min-width: 0; }
.hero-state { display: grid; gap: 0; min-width: 0; }
.hero-state > .text-button { justify-self: start; }
/* Steps move focus to their heading for screen readers; that is not a control, so no ring. */
.hero-screen [tabindex="-1"]:focus-visible { outline: none; }
.hero-state.state-in { animation: hero-state-in .45s var(--settle); }
@keyframes hero-state-in { from { opacity: 0; transform: translateY(8px); } }

.hero-screen .button { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 54px; padding: 12px 24px; border-radius: 28px; font-size: 16px; white-space: nowrap; }
.hero-screen .hero-wide { width: 100%; }
.hero-outline { border: 1.5px solid var(--ink); color: var(--ink); background: #fff; }
.hero-outline:hover:not(:disabled) { background: var(--surface); }
.hero-screen .secondary:hover:not(:disabled) { background: #e7e9e3; }
.hero-screen .text-button { font-size: 14px; color: var(--muted); text-decoration: underline; text-underline-offset: 4px; text-decoration-color: var(--line); }
.hero-screen .text-button:hover { color: var(--ink); text-decoration-color: currentColor; }
.hero-screen .error { font-size: 14px; line-height: 1.5; }

.hero-note { margin-bottom: 14px; font-size: 14px; color: var(--muted); }
.hero-note:empty { display: none; }

.hero-join { margin-top: 20px; }
.hero-label { display: block; font-size: 14px; color: var(--muted); margin-bottom: 8px; }
.hero-label.big { font-family: var(--serif); font-size: 24px; letter-spacing: -.025em; color: var(--ink); margin-bottom: 12px; line-height: 1.25; }
.hero-code-row { display: grid; grid-template-columns: 1fr auto; gap: 10px; }
.hero-code-box { position: relative; min-width: 0; height: 54px; }
/* One real field over eight drawn slots: paste, autofill and the keyboard all reach the field. */
.hero-code-box input {
  position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; padding: 0; border: 0; margin: 0; border-radius: 12px;
  background: transparent; color: transparent; caret-color: transparent; font-size: 16px; outline: none;
  -webkit-text-fill-color: transparent;
}
.hero-code-box input::selection { background: transparent; }
.hero-code-box input:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.hero-slots { display: grid; grid-template-columns: repeat(4, 1fr) 4px repeat(4, 1fr); gap: 4px; height: 100%; }
.hero-slot {
  position: relative; display: grid; place-items: center; min-width: 0; border-radius: 10px; background: #fff;
  border: 1px solid var(--line); font-family: var(--mono); font-size: clamp(15px, 4.6vw, 22px); font-weight: 600; color: var(--ink);
  transition: border-color .15s, background-color .15s;
}
.hero-slot:nth-child(5) { grid-column: 6; }
.hero-code-box.focused .hero-slot { border-color: #cfd3cb; }
.hero-code-box.focused .hero-slot.next { border-color: var(--accent); }
.hero-code-box.focused .hero-slot.next::after { content: ""; width: 2px; height: 24px; border-radius: 1px; background: var(--accent); animation: hero-caret 1.1s steps(1) infinite; }
.hero-code-box.full .hero-slot { border-color: var(--mine-line); background: #f4f8f4; }
.hero-code-box.wrong .hero-slot { border-color: #e2b4ae; }
@keyframes hero-caret { 50% { opacity: 0; } }
#hero-code-submit { min-width: 84px; }
@media (max-width: 400px) { .hero-code-row { gap: 8px; } #hero-code-submit { min-width: 0; padding-left: 16px; padding-right: 16px; } .hero-slot { border-radius: 8px; } }
.hero-error { margin-top: 10px; }
/* v25: the code is the fallback; in person, a friend's QR is quicker. */
.hero-scan-hint { display: flex; align-items: center; gap: 7px; margin-top: 10px; font-size: 14px; color: var(--muted); line-height: 1.4; }
.hero-scan-hint svg { flex-shrink: 0; width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }
.hero-scan-hint path + path { fill: currentColor; stroke: none; }
/* v25 Your Moments: "Back to Pooja's Birthday" for each Moment this device has joined. */
.your-moments { margin-top: 24px; }
.your-moments-title { margin-bottom: 8px; font-size: 14px; font-weight: 400; letter-spacing: 0; color: var(--muted); }
.your-moments-list { display: grid; gap: 8px; }
.your-moment {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; min-height: 54px; padding: 12px 14px 12px 18px;
  border-radius: 14px; background: #fff; border: 1px solid var(--line); font-size: 16px; font-weight: 550; text-align: left; color: var(--ink);
}
.your-moment:hover:not(:disabled) { background: var(--surface-soft); }
.your-moment-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.your-moment svg { flex-shrink: 0; width: 18px; height: 18px; fill: none; stroke: var(--muted); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.hero-promise { display: flex; align-items: center; gap: 8px; margin-top: 18px; font-size: 14px; color: var(--muted); line-height: 1.4; }
.hero-lock { flex-shrink: 0; width: 15px; height: 15px; fill: none; stroke: var(--accent); stroke-width: 1.5; }

.hero-state input[type="text"]:not(#hero-code), .hero-state #join-name {
  height: 54px; padding: 12px 16px; border-radius: 14px; font-size: 18px;
}
.hero-state input::placeholder { color: var(--faint); }
.hero-hint { margin-top: 10px; font-size: 14px; color: var(--muted); line-height: 1.5; text-wrap: pretty; }
.hero-row { display: flex; align-items: center; gap: 12px; margin-top: 18px; }
.hero-row .text-button { padding: 10px 8px; }
.hero-state > .hero-link { margin-top: 10px; }
.hero-step-trip { margin-bottom: 6px; font-size: 14px; color: var(--muted); overflow-wrap: anywhere; }
.hero-step-trip:empty { display: none; }

/* The Moment that code opens, then the usual name steps (welcome back, selfie, Moth Key, new). */
.hero-found { margin-bottom: 20px; font-family: var(--serif); font-size: 26px; line-height: 1.2; letter-spacing: -.03em; overflow-wrap: anywhere; outline: none; }
.hero-found-count { color: var(--muted); }
.hero-found-count:not(:empty)::before { content: " · "; }
.hero-state #join-form label { font-size: 14px; color: var(--muted); }
.hero-state #join-form .button { margin-top: 16px; }
.hero-state .join-switch { font-size: 14px; margin-top: 12px; }
.hero-state .join-links { margin-top: 6px; }

/* ---------- Proofs: the product itself, small (the demos are in hero-story.css) ---------- */
.hero-proofs { padding: 72px var(--gutter) 24px; display: grid; gap: 88px; }
.hero-proof { display: grid; gap: 26px; align-items: center; min-width: 0; }
.hero-proof h2 { font-family: var(--serif); font-weight: 400; font-size: clamp(27px, 7vw, 40px); line-height: 1.1; letter-spacing: -.03em; text-wrap: balance; }
.hero-proof-text p { margin-top: 12px; color: #4c534f; max-width: 34em; text-wrap: pretty; }

/* ---------- Footer ---------- */
.hero-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 20px; margin: 72px var(--gutter) 0; padding: 28px 0 max(32px, env(safe-area-inset-bottom)); border-top: 1px solid var(--line); }
.hero-foot-line { color: var(--muted); font-size: 15px; }
.hero-foot-line .wordmark { color: var(--ink); font-size: 20px; }

/* ---------- Slow ambient motion, only when the reader allows it ---------- */
/* hero-story.js pauses all of it while the scene is off screen, the tab is hidden or a dialog is up. */
@media (prefers-reduced-motion: no-preference) {
  .hero-moth-float { animation: hero-hover 6.5s ease-in-out infinite; }
  .hero-moth-shadow { animation: hero-hover-shadow 6.5s ease-in-out infinite; }
  .hero-lamp { animation: hero-breathe 9s ease-in-out infinite; }
  /* v25 (the owner's numbers): the room out of focus only breathes in scale, 1.000 → 1.015; the three
     views in the middle drift 2-3 px with a little turn. */
  .layer-far .hero-print { animation: hero-room 23s ease-in-out infinite alternate; }
  .layer-mid .hero-print { animation: hero-drift 17s ease-in-out infinite alternate; }
  .layer-near .hero-print { animation: hero-room 13s ease-in-out infinite alternate; }
  .hero-scene .p-m2 { animation-name: hero-drift-back; }
  .hero-scene .p-f2, .hero-scene .p-m2, .hero-scene .p-n2 { animation-delay: -6s; }
  .hero-scene .p-f3, .hero-scene .p-m3 { animation-delay: -11s; }
  .hero-scene.is-happy .hero-moth-hop { animation: hero-hop .8s var(--spring); }
  .hero-scene.is-happy.is-flutter .hero-moth-hop { animation: hero-flutter .75s ease-out; }
  /* v25: the Moth drifts between the photos, 13 s a round: near the laugh on the left, a pause, up toward
     the light and her face, a dip, down past the candles, and home. Slow, uneven, never a bounce.
     Its shadow follows on the table below, smaller and fainter while the Moth is high. */
  .hero-moth-path { animation: hero-moth-path 13s infinite; }
  .hero-shadow-path { animation: hero-shadow-path 13s infinite; }
}
/* A wing-like float: up a little, a breath wider, a degree of sway (in the Moth's own size, so it scales). */
@keyframes hero-hover {
  0%, 100% { transform: translateY(0) rotate(5deg) scale(1, 1); }
  30% { transform: translateY(-3.3%) rotate(3.6deg) scale(1.012, .995); }
  60% { transform: translateY(-1.5%) rotate(5.8deg) scale(.994, 1.004); }
}
@keyframes hero-hover-shadow { 0%, 100% { transform: scale(1); opacity: 1; } 30% { transform: scale(.88); opacity: .7; } 60% { transform: scale(.95); opacity: .85; } }
@keyframes hero-breathe { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.04); opacity: .88; } }
@keyframes hero-drift { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(2px, -3px, 0) rotate(.6deg); } }
@keyframes hero-drift-back { from { transform: translate3d(2px, -3px, 0) rotate(.6deg); } to { transform: translate3d(0, 0, 0); } }
@keyframes hero-room { from { transform: scale(1); } to { transform: scale(1.015); } }
@keyframes hero-hop { 40% { transform: translateY(-4.8%) scale(1.04); } }
/* Start pressed: a quick flutter, the wings (its width) beating three times as it lifts a little. */
@keyframes hero-flutter {
  12% { transform: translateY(-2.5%) scale(.93, 1.02) rotate(-3deg); }
  26% { transform: translateY(-4.5%) scale(1.05, .99) rotate(2deg); }
  40% { transform: translateY(-5%) scale(.94, 1.02) rotate(-2deg); }
  55% { transform: translateY(-4%) scale(1.04, .99) rotate(1.5deg); }
  72% { transform: translateY(-2%) scale(.98, 1.01) rotate(-.5deg); }
}
@keyframes hero-moth-path { /* in the Moth's own width and height */
  0%, 100% { transform: translate(-48%, 11%) rotate(-4deg); animation-timing-function: cubic-bezier(.37, 0, .63, 1); }
  15% { transform: translate(-42%, 4%) rotate(-2deg); animation-timing-function: cubic-bezier(.45, 0, .4, 1); }
  41% { transform: translate(39%, -20%) rotate(5deg); animation-timing-function: cubic-bezier(.37, 0, .63, 1); }
  53% { transform: translate(45%, -15%) rotate(3deg); animation-timing-function: cubic-bezier(.45, 0, .55, 1); }
  66% { transform: translate(22%, 18%) rotate(1deg); animation-timing-function: cubic-bezier(.37, 0, .63, 1); }
  83% { transform: translate(-11%, 24%) rotate(-2deg); animation-timing-function: cubic-bezier(.45, 0, .55, 1); }
}
@keyframes hero-shadow-path { /* in the shadow's own size: the same ground distance, a third of the height */
  0%, 100% { transform: translate(-72%, 33%) scale(.96); opacity: .95; animation-timing-function: cubic-bezier(.37, 0, .63, 1); }
  15% { transform: translate(-63%, 12%) scale(.92); opacity: .9; animation-timing-function: cubic-bezier(.45, 0, .4, 1); }
  41% { transform: translate(58%, -60%) scale(.74); opacity: .55; animation-timing-function: cubic-bezier(.37, 0, .63, 1); }
  53% { transform: translate(67%, -45%) scale(.78); opacity: .6; animation-timing-function: cubic-bezier(.45, 0, .55, 1); }
  66% { transform: translate(33%, 54%) scale(1.04); opacity: 1; animation-timing-function: cubic-bezier(.37, 0, .63, 1); }
  83% { transform: translate(-16%, 72%) scale(1.08); opacity: 1; animation-timing-function: cubic-bezier(.45, 0, .55, 1); }
}

/* Short phones (an SE, a small Android, Safari's toolbars): the scene gives up height, its Moth shrinks
   with it and the words tighten, so "Start a Moment" and the code field stay on the first screen. */
@media (max-width: 899px) and (max-height: 700px) {
  .hero { grid-template-rows: clamp(150px, calc(100svh - 56px - 480px), 440px) auto auto; }
  .hero-scene { font-size: clamp(7px, 2.05vw, 15px); }
  .hero-lede { margin-top: 10px; font-size: 15px; line-height: 1.5; }
  .hero-actions { padding-top: 18px; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-js .hero-scene .hero-enter, .hero-js .hero-copy { opacity: 1; transform: none; transition: none; }
  .hero-moth-happy { transition: none; }
  .hero-state.state-in { animation: none; }
  .hero-code-box.focused .hero-slot.next::after { animation: none; }
}

/* ---------- Desktop: copy on the left, the lamp-lit table of photos on the right ---------- */
@media (min-width: 900px) {
  .hero-screen { --gutter: 48px; }
  .hero-top { height: 72px; max-width: 1240px; margin: 0 auto; }
  .hero {
    max-width: 1240px; margin: 0 auto; min-height: min(calc(100svh - 72px), 860px);
    grid-template-areas: "copy scene" "actions scene"; grid-template-columns: minmax(380px, 1fr) 1.15fr;
    grid-template-rows: 1fr auto; align-content: stretch; column-gap: 40px; padding-bottom: 48px;
  }
  .hero-scene {
    margin: 0 calc(var(--gutter) * -1) 0 0; font-size: clamp(13px, 1.3vw, 18px);
  }
  .hero-scene::after { background: radial-gradient(ellipse 58% 56% at 54% 48%, #fafaf700 62%, var(--bg) 100%); }
  /* The tall column: the photos gather closer around the Moth, and the near ones come in from the
     corners, where the soft edge would otherwise hide them. */
  .hero-print.p-f1 { left: 12%; top: 14%; }
  .hero-print.p-f2 { right: 34%; top: 3%; }
  .hero-print.p-f3 { left: 38%; bottom: 14%; }
  .hero-print.p-m1 { left: 8%; top: 44%; }
  .hero-print.p-m2 { right: 6%; top: 30%; }
  .hero-print.p-m3 { right: 18%; bottom: 13%; }
  .hero-print.p-n1 { left: 2%; bottom: 8%; }
  .hero-print.p-n2 { right: 2%; top: 6%; }
  .hero-copy { align-self: end; padding-top: 0; }
  .hero-copy h1 { font-size: clamp(48px, 5vw, 70px); }
  .hero-lede { font-size: 18px; max-width: 30em; margin-top: 20px; }
  .hero-actions { align-self: start; padding-top: 32px; max-width: 440px; min-height: 360px; }
  .hero-proofs { max-width: 1080px; margin: 0 auto; padding-top: 120px; gap: 140px; }
  .hero-proof { grid-template-columns: 1fr 1fr; gap: 72px; }
  .hero-proof:nth-child(even) .hero-proof-text { order: 2; }
  .hero-foot { max-width: 1080px; margin: 120px auto 0; padding-left: 0; padding-right: 0; }
}
@media (min-width: 900px) and (max-width: 1140px) { .hero-foot { margin-left: var(--gutter); margin-right: var(--gutter); } }
