/* ==========================================================================
   IMPRINT — the intro page (v6; §13 is what v6 added)
   Sits on top of ../assets/app.css (the design system). Spec: ../DESIGN.md

   ⚠️ NOTHING HERE BELONGS IN app.css. That file is byte-identical to
   ../../redesign/assets/app.css by rule; everything this page invents — the
   stages, the phone frame, the notification cards — lives here. Same precedent
   as overview.css.

   ⚠️ EVERY "NOT YET SHOWN" STATE IS SCOPED TO `.is-live`, a class that ONLY
   intro.js adds, per deck, once it has checked the deck is well-formed. With no
   script — blocked, failed to load, threw — no rule here hides anything: each
   stage shows its first recording's poster and its first cards, which is a
   correct picture. Scoping these to a class set in <head> instead would make a
   failed script a page of black phones.
   ========================================================================== */

/* ---------- 1. Page shell ---------- */

/* v4's accent: the brand ramp as one gradient, peach → orange → ember. Every
   accent word, the stat numbers and the progress bars wear it.
   ⚠️ BRAND ONLY. `--rose`, `--sky`, `--violet`, `--jade` and `--amber` each
   MEAN something inside the product (likes, live aviation data, pins, on time,
   late), and spending them as decoration here is what CLAUDE.md records the
   landing page getting wrong once already. A rainbow would read younger for a
   week and teach the reader nothing about the app. */
:root { --glow: linear-gradient(96deg, #FF9A5C 0%, var(--brand) 48%, var(--brand-lo) 100%); }

body { background: var(--bg); color: var(--text); }

.in-wrap { max-width: 1200px; margin: 0 auto; padding: 0 20px; }
@media (min-width: 640px) { .in-wrap { padding: 0 28px; } }

.in-band { padding: 72px 0; position: relative; }
@media (min-width: 960px) { .in-band { padding: 104px 0; } }
.in-band--sunk { background: var(--bg-sunk); border-block: 1px solid var(--line); }

.btn--lg { height: 52px; padding: 0 26px; font-size: 15.5px; border-radius: 999px; gap: 8px; }
/* Pill buttons with a lift. The primary wears the brand's own ramp and a soft
   glow of itself — a button that looks pressable before it is hovered. */
.in-nav .btn, .in-ctas .btn { border-radius: 999px; font-weight: 650; letter-spacing: -.01em;
  transition: transform .2s var(--ease), box-shadow .25s var(--ease), background .2s var(--ease); }
.in-nav .btn--primary, .in-ctas .btn--primary {
  background: linear-gradient(135deg, var(--brand-hi), var(--brand) 45%, var(--brand-lo)); color: #fff;
  box-shadow: 0 12px 30px -12px rgba(255,91,41,.75), inset 0 1px 0 rgba(255,255,255,.28); }
.in-nav .btn:hover, .in-ctas .btn:hover { transform: translateY(-1px); }
.in-ctas .btn--primary:hover { box-shadow: 0 18px 38px -12px rgba(255,91,41,.85), inset 0 1px 0 rgba(255,255,255,.28); }
.in-ctas .btn--outline { background: var(--surface); border: 1px solid var(--line-strong); box-shadow: var(--shadow-sm); }
.btn--glass { background: rgba(255,255,255,.14); color: #fff; border: 1px solid rgba(255,255,255,.3);
  backdrop-filter: blur(14px) saturate(1.5); -webkit-backdrop-filter: blur(14px) saturate(1.5); }
.btn--glass:hover { background: rgba(255,255,255,.22); }

/* ---------- 2. Nav ---------- */

/* A floating pill, not a bar across the page: the band behind it shows round
   its ends. The nav keeps its blur (DESIGN.md §7) — it is small and rarely
   over a recording. `pointer-events` is off on the full-width sticky shell so
   the strips beside the pill do not swallow clicks meant for the page. */
.in-nav { position: sticky; top: 0; z-index: 80; padding-top: 12px; pointer-events: none; }
.in-nav__in {
  pointer-events: auto;
  display: flex; align-items: center; justify-content: space-between; height: 58px; gap: 18px;
  width: calc(100% - 24px); max-width: 1160px; padding: 0 9px 0 16px; border-radius: 999px;
  background: color-mix(in srgb, var(--surface) 76%, transparent);
  backdrop-filter: blur(20px) saturate(1.6); -webkit-backdrop-filter: blur(20px) saturate(1.6);
  border: 1px solid var(--line); box-shadow: 0 12px 34px -18px rgba(16,18,24,.35);
}
.in-mark { display: flex; align-items: center; gap: 9px; flex: none; }
.in-mark img { width: 28px; height: 28px; border-radius: 8px; }
.in-mark b { font-size: 15.5px; font-weight: 700; letter-spacing: -.03em; }
.in-nav__links { display: none; gap: 2px; margin-left: auto; }
@media (min-width: 880px) { .in-nav__links { display: flex; } }
.in-nav__links a { font-size: 13.5px; font-weight: 600; color: var(--text-2); padding: 8px 13px; border-radius: 999px;
  transition: color .15s var(--ease), background .15s var(--ease); }
.in-nav__links a:hover { color: var(--text); background: var(--surface-2); }
.in-nav__act { display: flex; align-items: center; gap: 10px; flex: none; }
@media (max-width: 400px) { .in-nav__act .btn { display: none; } }

/* ---------- 3. Section heads ---------- */

/* A chip, with a dot of the glow — the section's name as a tag, not a label. */
.in-kicker {
  display: inline-flex; align-items: center; gap: 9px; height: 32px; padding: 0 14px 0 11px;
  border-radius: 999px; background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow-sm);
  font-size: 12px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--text);
  margin-bottom: 18px;
}
.in-kicker::before { content: ""; width: 8px; height: 8px; border-radius: 50%; flex: none;
  background: var(--glow); box-shadow: 0 0 0 3px var(--brand-soft); }
/* The section's number, so the four read as the app's four tabs, in order. */
.in-kicker__n { font-weight: 800; color: var(--text-3); padding-right: 9px;
  border-right: 1px solid var(--line-strong); }
/* ⚠️ The Pro tag is not decoration: live tracking and flight alerts are Pro,
   and a page that shows the live flight as a headline and mentions the price
   only in the footer sells the wrong thing twice (DESIGN.md §9). */
.pro-tag { display: inline-block; margin-left: 8px; padding: 3px 8px; border-radius: 999px; vertical-align: 1px;
  font-size: 10.5px; letter-spacing: .08em; color: #fff; background: linear-gradient(90deg, var(--brand-lo), var(--brand)); }
/* ⚠️ px, NOT `ch`, for the head's width. `ch` resolves against the element's
   OWN font-size — 15px here, not the h2's 44px — and wrapped the heading into
   four words a line in v1. It reads as a broken grid, not a bad unit. */
.in-head { max-width: 900px; margin-bottom: 38px; }
.in-head h2 { font-size: clamp(34px, 5vw, 62px); font-weight: 800; letter-spacing: -.05em; line-height: 1.0;
  text-wrap: balance; }
.in-head p { font-size: 17px; color: var(--text-2); line-height: 1.6; margin-top: 18px; max-width: 620px;
  text-wrap: pretty; }
@media (min-width: 960px) { .in-head p { font-size: 19px; } }
/* The accent words. One gradient on the page, on every heading's second half. */
.hx h1 em, .in-head h2 em, .in-close h2 em {
  font-style: normal; background: var(--glow);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  /* The clipped background ends at the glyph box; descenders and the italic-ish
     overhang of a heavy "y" or "f" are painted by this padding, not cut. */
  padding-bottom: .08em; margin-bottom: -.08em;
}
/* Headings rise in once, with the stages (intro.js adds `.is-seen`). */
.io .in-head:not(.is-seen), .io .proof:not(.is-seen) {
  opacity: 0; transform: translateY(26px); }
.in-head, .proof { transition: opacity .8s var(--ease), transform .9s var(--ease); }

.in-ctas { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin-top: 28px; }

/* ---------- 4. The phone ---------- */
/* One frame for every recording. `--w` is the whole device's width; the bezel,
   the corner radii and the buttons are all fractions of it, so a phone at 210px
   and one at 292px are the same drawing. The screen's aspect ratio IS the
   capture's (1206×2622), so a recording fills it exactly — no letterbox, no
   crop. The Dynamic Island and the status bar are IN the recording; drawing
   them here as well would put two islands on one phone. */

.ph {
  --w: 254px;
  position: relative; width: var(--w); flex: none;
  padding: calc(var(--w) * .034);
  border-radius: calc(var(--w) * .172);
  background: linear-gradient(150deg, #57575c 0%, #242427 16%, #111113 48%, #2b2b2f 84%, #5c5c61 100%);
  box-shadow:
    inset 0 0 0 1.2px rgba(255,255,255,.18),
    inset 0 0 0 calc(var(--w) * .013) #060607,
    0 0 0 1px rgba(0,0,0,.5),
    0 60px 90px -40px rgba(0,0,0,.65),
    0 26px 40px -26px rgba(0,0,0,.5);
}
/* The side buttons: power on the right, the two volume keys on the left. */
.ph::before, .ph::after {
  content: ""; position: absolute; width: 3px; border-radius: 2px;
  background: linear-gradient(90deg, #1e1e21, #5d5d62);
}
.ph::before { right: -2.5px; top: 27%; height: 11%; }
.ph::after  { left: -2.5px; top: 21%; height: 6.5%; box-shadow: 0 calc(var(--w) * .13) 0 0 #3b3b3f; }

.ph__scr {
  position: relative; overflow: hidden; background: #000;
  aspect-ratio: 1206 / 2622;
  border-radius: calc(var(--w) * .138);
  /* ⚠️ clip-path as well as overflow + radius. A video in Chrome is promoted to
     its own compositing layer and can paint square corners over a rounded
     parent — the same failure v2 hit with a backdrop-filter'd tab bar. */
  clip-path: inset(0 round calc(var(--w) * .138));
}
.ph__scr > video, .ph__scr > img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: block;
}
/* A faint glass sheen, so the screen reads as glass rather than as a picture. */
.ph__scr::after {
  content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: linear-gradient(118deg, rgba(255,255,255,.10), rgba(255,255,255,0) 32%);
}
.ph--android { border-radius: calc(var(--w) * .11); }
.ph--android .ph__scr { aspect-ratio: 600 / 1333; border-radius: calc(var(--w) * .075);
  clip-path: inset(0 round calc(var(--w) * .075)); }
.ph--android::after { display: none; }

/* No script: the first recording's poster, nothing else. */
[data-deck]:not(.is-live) .ph__scr > [data-media]:not(:first-child) { display: none; }
/* With it: every scene's media stacked in the one screen, crossfading. */
.is-live .ph__scr > [data-media] { opacity: 0; transition: opacity .5s var(--ease); }
.is-live .ph__scr > [data-media].is-on { opacity: 1; }

/* ---------- 5. Stages — a photograph with the phone in front of it ---------- */

.stage-bg { position: absolute; inset: 0; z-index: -1; overflow: hidden; background: #0b0d12; }
.stage-bg > img { width: 100%; height: 100%; object-fit: cover; display: block; transform: scale(1.03); }
.stage-bg::after { content: ""; position: absolute; inset: 0; pointer-events: none; }
/* A slow push-in on the photograph while the stage is on screen. Paused
   off-screen by `.is-inview`, so eight stages do not animate at once. */
.is-inview .stage-bg:not(.wall) > img { animation: in-kb 26s ease-in-out infinite alternate; }
@keyframes in-kb {
  from { transform: scale(1.03); }
  to   { transform: scale(1.13) translate3d(-1.8%, -1.2%, 0); }
}

.stage-media { position: relative; }

/* Scroll-in. `.io` is added by intro.js only once its observer exists, so a
   page without it never waits on an observer that is not there. */
.io .fx:not(.is-seen) { opacity: 0; transform: translateY(34px) scale(.985); }
.fx { transition: opacity .9s var(--ease), transform 1.1s var(--ease); }

/* ---------- 6. Cards — the notification and the callout ---------- */

.cards { position: absolute; inset: 0; z-index: 3; pointer-events: none; }
[data-deck]:not(.is-live) .stage-media > .cards ~ .cards { display: none; }

/* ⚠️ Opacity and transform only — the two properties the compositor animates
   without repainting. The entrance used to blur in as well (`filter: blur(6px)`),
   which re-rasterised the card, its shadow and its glass on every frame of the
   transition, while a 60 fps recording played beside it. */
.is-live .cards > * {
  opacity: 0; transform: translate3d(0, 18px, 0) scale(.94);
  transition: opacity .3s var(--ease), transform .35s var(--ease);
}
.is-live .cards > .is-in {
  opacity: 1; transform: none;
  transition: opacity .55s var(--ease), transform .75s var(--ease-spring);
}
.is-live .cards > .is-out { opacity: 0; transform: translate3d(0, -10px, 0) scale(.97); }

/* The iOS banner, and the callout below it.

   ⚠️ NO `backdrop-filter` on either, and they are nearly opaque instead. Every
   card sits over something that moves on every frame — the photograph's
   push-in, or the recording itself when the banners stack over the phone — so
   a backdrop blur is recomputed at 60 Hz for as long as the card is up, for a
   frost that was 80–90% covered by the card's own fill anyway. Measured in
   Chrome's trace, not guessed (DESIGN.md §4.2). */
.nt {
  position: absolute; width: min(284px, var(--room, 284px));
  display: flex; gap: 11px; align-items: flex-start;
  padding: 11px 14px 12px 11px; border-radius: 24px;
  background: rgba(246,246,248,.95);
  box-shadow: 0 22px 44px -18px rgba(0,0,0,.45), inset 0 0 0 .5px rgba(255,255,255,.7);
  color: #111;
}
.nt__app { width: 38px; height: 38px; border-radius: 9px; flex: none; object-fit: cover;
  box-shadow: 0 0 0 .5px rgba(0,0,0,.12); }
.nt__app--mail { display: grid; place-items: center; color: #fff;
  background: linear-gradient(180deg, #2ea8ff, #1667f2); }
.nt__txt { flex: 1; min-width: 0; }
.nt__hd { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.nt__hd strong { font-size: 14px; font-weight: 650; letter-spacing: -.012em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nt__hd time { font-size: 12px; color: rgba(60,60,67,.6); flex: none; }
.nt p { font-size: 13.5px; line-height: 1.33; color: #1c1c1e; margin-top: 1px; }

/* The callout: a short fact about what the recording is showing. */
.co {
  position: absolute; max-width: min(262px, var(--room, 262px));
  display: flex; align-items: center; gap: 11px;
  padding: 10px 16px 10px 10px; border-radius: 18px;
  background: rgba(255,255,255,.97);
  box-shadow: 0 20px 40px -18px rgba(0,0,0,.42), inset 0 0 0 .5px rgba(255,255,255,.8);
  color: #101218;
}
/* ⚠️ The text rules are scoped to the text column (`.co__txt`). The icon and
   flag tiles are <span>s too, and a bare `.co span` outranks `.co__ico`
   (0,1,1 against 0,1,0) — it turned every tile to display:block with a 2px
   top margin, so each glyph sat in the tile's top-left corner, grey. */
.co__txt { min-width: 0; }
.co__txt b { display: block; font-size: 13.5px; font-weight: 680; letter-spacing: -.012em; line-height: 1.25; }
.co__txt span { display: block; font-size: 12px; color: #596072; line-height: 1.32; margin-top: 2px; }
.co__ico { width: 34px; height: 34px; border-radius: 11px; display: grid; place-items: center; flex: none;
  background: rgba(255,91,41,.14); color: var(--brand-lo); }
.co__ico--sky    { background: rgba(46,107,255,.14); color: var(--sky); }
.co__ico--jade   { background: rgba(0,179,126,.15); color: #00875F; }
.co__ico--violet { background: rgba(108,92,231,.15); color: var(--violet); }
.co__ico--rose   { background: rgba(255,45,111,.13); color: var(--rose); }
.co__art { width: 42px; height: 42px; object-fit: contain; flex: none;
  filter: drop-shadow(0 4px 8px rgba(0,0,0,.25)); }
.co__flag { width: 34px; height: 34px; display: grid; place-items: center; flex: none; }
.co__flag svg { border-radius: 50%; box-shadow: 0 0 0 1px rgba(0,0,0,.08); }
.fxb--night .co { background: rgba(32,33,38,.95); color: #fff;
  box-shadow: 0 20px 40px -18px rgba(0,0,0,.7), inset 0 0 0 .5px rgba(255,255,255,.12); }
.fxb--night .co__txt span { color: rgba(255,255,255,.62); }

/* ---------- 7. Hero ---------- */

.hx { position: relative; padding: 56px 0 0; overflow: hidden; }
/* An aurora of the brand's three tints, drifting — transform only, on its own
   layer, so it costs the compositor and never a repaint. */
.hx::before {
  content: ""; position: absolute; inset: -34% -22% auto; height: 1000px; pointer-events: none;
  background:
    radial-gradient(34% 42% at 30% 40%, rgba(255,91,41,.20), transparent 70%),
    radial-gradient(30% 40% at 72% 28%, rgba(255,154,92,.20), transparent 70%),
    radial-gradient(34% 44% at 56% 66%, rgba(232,65,15,.11), transparent 70%);
  animation: in-aurora 22s ease-in-out infinite alternate; will-change: transform;
}
@keyframes in-aurora { to { transform: translate3d(4%, 3%, 0) rotate(5deg) scale(1.08); } }
[data-theme="dark"] .hx::before { opacity: .8; }
@media (min-width: 960px) { .hx { padding-top: 76px; } }
.hx__copy { position: relative; text-align: center; max-width: 980px; }
.hx h1 { font-size: clamp(50px, 9vw, 118px); font-weight: 820; letter-spacing: -.06em; line-height: .94;
  text-wrap: balance; }
.hx__lede { font-size: clamp(16.5px, 1.8vw, 20.5px); color: var(--text-2); line-height: 1.55;
  max-width: 620px; margin: 22px auto 0; text-wrap: pretty; }

.hx__deck { position: relative; margin-top: 40px; }
.hx__stage {
  position: relative; isolation: isolate; overflow: hidden;
  height: 704px; border-radius: 40px;
  box-shadow: 0 60px 100px -50px rgba(16,18,24,.6), 0 0 0 1px rgba(16,18,24,.06);
}
.hx__stage .stage-bg::after {
  background:
    radial-gradient(ellipse 30% 55% at 50% 45%, rgba(8,10,16,.28), transparent 70%),
    linear-gradient(180deg, rgba(8,10,16,.18), rgba(8,10,16,.05) 35%, rgba(8,10,16,.6));
}
.hx__stage .stage-media { height: 100%; }
.hx__stage .ph { --w: 296px; position: absolute; left: 50%; top: 38px; margin-left: calc(var(--w) / -2); }

/* Four places around the phone. Clear of it on a wide screen — the recording is
   the subject and a card over it hides the thing it is describing.

   ⚠️ `--room` is the space from a card's anchor to the stage's edge, less a
   16px gutter, and `.nt` / `.co` size themselves `min(designed, --room)`. A
   card anchored at `left: 50% + X` is otherwise shrink-to-fit against the
   stage and lands FLUSH with its edge — which the stage's rounded clip then
   reads as a card cut off. Every position class sets its own; change an
   offset and change the `--room` beside it. */
.p-hl1 { --room: calc(50% - 206px); right: calc(50% + 190px); top: 104px; }
.p-hl2 { --room: calc(50% - 230px); right: calc(50% + 214px); top: 408px; }
.p-hr1 { --room: calc(50% - 206px); left:  calc(50% + 190px); top: 196px; }
.p-hr2 { --room: calc(50% - 230px); left:  calc(50% + 214px); top: 492px; }

.acts {
  position: relative; z-index: 6;
  display: flex; gap: 4px; width: max-content; max-width: calc(100% - 24px);
  margin: -30px auto 0; padding: 5px; border-radius: 999px;
  /* Opaque, not glass — the hero's photograph moves behind it (see `.nt`). */
  background: rgba(18,19,24,.95);
  box-shadow: 0 20px 44px -18px rgba(0,0,0,.55), inset 0 0 0 1px rgba(255,255,255,.08);
}
.acts button {
  position: relative; overflow: hidden;
  display: flex; align-items: center; gap: 8px;
  height: 48px; padding: 0 22px; border-radius: 999px;
  color: rgba(255,255,255,.7); font-size: 14.5px; font-weight: 640; letter-spacing: -.01em;
  white-space: nowrap; transition: color .2s var(--ease), background .35s var(--ease);
}
.acts button:hover { color: #fff; }
.acts button svg { flex: none; }
.acts button.is-active,
[data-deck]:not(.is-live) .acts button:first-child {
  background: linear-gradient(135deg, var(--brand-hi), var(--brand) 50%, var(--brand-lo)); color: #fff;
  box-shadow: 0 8px 22px -8px rgba(255,91,41,.8); }
/* The progress fill: a lighter wash sweeping the active pill as its act plays. */
.acts button i {
  position: absolute; inset: 0; pointer-events: none; display: none;
  background: rgba(255,255,255,.2); transform-origin: left; transform: scaleX(var(--p, 0));
}
.acts button.is-active i { display: block; }
.hx__note { text-align: center; font-size: 12.5px; color: var(--text-3); margin-top: 16px; }

/* The four numbers as cards — each a fact with room round it. */
.proof { position: relative; display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px;
  padding-top: 52px; padding-bottom: 8px; }
@media (min-width: 760px) { .proof { grid-template-columns: repeat(4, 1fr); gap: 14px; } }
.proof > div { padding: 22px 22px 20px; border-radius: 26px; background: var(--surface);
  border: 1px solid var(--line); box-shadow: var(--shadow-sm); }
.proof b { display: block; width: max-content; font-size: 46px; font-weight: 820; letter-spacing: -.055em; line-height: 1;
  background: var(--glow); -webkit-background-clip: text; background-clip: text; color: transparent;
  padding-bottom: .06em; }
.proof span { display: block; font-size: 14px; color: var(--text-2); line-height: 1.45; margin-top: 8px; }
@media (max-width: 640px) { .proof > div { padding: 18px 16px 16px; border-radius: 22px; } .proof b { font-size: 36px; } }

/* The ribbon of places between the hero and the first band. Filled and
   outlined names alternate; it moves only while on screen (`.is-inview`). */
.marquee { overflow: hidden; padding: 56px 0 8px; user-select: none;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
.marquee__track { display: flex; align-items: center; gap: 30px; width: max-content;
  font-size: clamp(40px, 6.4vw, 88px); font-weight: 820; letter-spacing: -.05em; line-height: 1.1; }
.marquee__track span { white-space: nowrap; color: var(--text); }
.marquee__track span.o { color: transparent; -webkit-text-stroke: 1.5px var(--text-3); }
.marquee__track i { font-style: normal; font-size: .5em; background: var(--glow);
  -webkit-background-clip: text; background-clip: text; color: transparent; }
.marquee.is-inview .marquee__track { animation: in-marquee 48s linear infinite; }
@keyframes in-marquee { to { transform: translate3d(calc(-50% - 15px), 0, 0); } }

/* ---------- 8. The four sections — a caption on the left, the phone on the right ---------- */
/* v5. Each section is one deck (`.px`): the stage (`.fx`), a photograph edge to
   edge with the active feature's caption over its darker side and the phone
   over its brighter side; and under it a row of small tabs (`.acts--sm`), one
   per feature. The tabs are the hero's control at a smaller size, so the page
   has one way of switching scenes. Until v5 the stage carried a list of rows
   that opened in turn — the names of six features stacked beside the phone,
   with only the open one readable. */

.px { position: relative; }
.fx {
  position: relative; isolation: isolate; overflow: hidden;
  display: grid; grid-template-columns: 430px 1fr;
  height: 640px; border-radius: 40px;
  box-shadow: 0 60px 100px -50px rgba(16,18,24,.6), 0 0 0 1px rgba(16,18,24,.06);
}
.fx .stage-bg::after {
  background: linear-gradient(90deg, rgba(8,10,16,.84) 0%, rgba(8,10,16,.66) 30%,
                                      rgba(8,10,16,.2) 58%, rgba(8,10,16,.06) 100%);
}

/* The captions share one grid cell, so the column is as tall as the longest
   one and changing scenes never moves anything below it. */
.fx__copy { position: relative; z-index: 2; display: grid; align-content: center;
  padding: 44px 30px 60px 44px; color: #fff; }
.fx__cap { grid-area: 1 / 1; min-width: 0; }
.fx__ico { width: 48px; height: 48px; border-radius: 16px; display: grid; place-items: center;
  background: var(--glow); color: #fff; box-shadow: 0 14px 30px -12px rgba(255,91,41,.7); }
.fx__step { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 0; margin-top: 22px;
  font-size: 12px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: rgba(255,255,255,.62); }
.fx__cap h3 { font-size: clamp(26px, 2.5vw, 34px); font-weight: 800; letter-spacing: -.04em;
  line-height: 1.08; margin-top: 10px; text-wrap: balance; }
.fx__cap p { font-size: 16px; line-height: 1.6; color: rgba(255,255,255,.82); margin-top: 14px;
  max-width: 360px; text-wrap: pretty; }
/* No script: the first caption, nothing else. With it, the captions crossfade,
   and `visibility` takes the hidden ones out of the accessibility tree too. */
[data-deck]:not(.is-live) .fx__cap:not(:first-child) { display: none; }
.is-live .fx__cap {
  opacity: 0; visibility: hidden; transform: translate3d(0, 12px, 0);
  transition: opacity .3s var(--ease), transform .4s var(--ease), visibility 0s linear .4s;
}
.is-live .fx__cap.is-on {
  opacity: 1; visibility: visible; transform: none;
  transition: opacity .5s var(--ease) .12s, transform .7s var(--ease-spring) .12s, visibility 0s;
}

.fx .stage-media { z-index: 1; }
.fx .ph { position: absolute; left: 50%; top: 50%; margin-left: calc(var(--w) / -2); transform: translateY(-50%); }

/* Cards beside the phone. The media column is ~720px and the phone ~280, so a
   card overlaps the bezel by a few pixels — enough to read as in front of it. */
.p-l1, .p-l2, .p-r1, .p-r2 { --room: calc(50% - 132px); }
.p-l1 { right: calc(50% + 116px); top: 15%; }
.p-l2 { right: calc(50% + 116px); top: 60%; }
.p-r1 { left:  calc(50% + 116px); top: 28%; }
.p-r2 { left:  calc(50% + 116px); top: 66%; }
.fx .nt { width: min(268px, var(--room, 268px)); }

/* The small tabs. Seven fit in one row on a laptop; on anything narrower the
   row scrolls sideways, and intro.js keeps the playing tab in view.
   ⚠️ A scrolling box clips what spills out of it, so the active pill drops
   the hero's glow here (it would be cut off at the bar's edge) and the focus
   ring is drawn inside the pill. */
.acts--sm { margin-top: -26px; overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain; }
.acts--sm::-webkit-scrollbar { display: none; }
.acts--sm button { flex: none; height: 42px; padding: 0 16px; gap: 7px; font-size: 13.5px; }
.acts--sm button.is-active,
[data-deck]:not(.is-live) .acts--sm button:first-child { box-shadow: none; }
.acts button:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.acts--sm button:focus-visible { outline-offset: -3px; }
/* The tabs arrive with their stage. */
.io .fx:not(.is-seen) + .acts--sm { opacity: 0; transform: translateY(20px); }
.fx + .acts--sm { transition: opacity .9s var(--ease) .1s, transform 1.1s var(--ease) .1s; }

/* The night band. `data-theme="dark"` on the section re-themes its tokens. */
.fxb--night { background: #05060a; color: var(--text); }
.fxb--night::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse 60% 40% at 70% 0%, rgba(46,107,255,.14), transparent 70%);
}
.fxb--night .fx { box-shadow: 0 50px 90px -40px rgba(0,0,0,.9), 0 0 0 1px rgba(255,255,255,.06); }

/* The Explore wall: four columns of the feed's own photographs drifting past,
   tilted, behind a scrim. Each column holds its pictures twice, so moving it up
   by half its height (plus half a gap) lands on an identical frame. */
.wall { display: flex; gap: 14px; padding: 0 14px;
  transform: rotate(-9deg) scale(1.35); transform-origin: 62% 50%; }
.wall__col { flex: 1; display: flex; flex-direction: column; gap: 14px; }
.wall__col img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; border-radius: 18px; display: block; }
/* A portrait crop of a landscape is mostly sky; pull these down onto the subject. */
.wall__col img.wall--sky { object-position: 50% 78%; }
.is-inview .wall__col { animation: in-wall 70s linear infinite; }
.is-inview .wall__col:nth-child(2n) { animation-duration: 86s; animation-direction: reverse; }
@keyframes in-wall { to { transform: translate3d(0, calc(-50% - 7px), 0); } }
/* ⚠️ ONE scrim on the wall, not two. `.fx .stage-bg::after` matches the wall's
   stage-bg as well, and stacked on this one it put the left third at ~98%
   black — every photograph there read as an empty navy tile. It is switched
   off for the wall (it would also rotate and scale with it); this one, on the
   unrotated stage, is the wall's whole scrim. */
.fx .stage-bg.wall::after { content: none; }
.fx--wall::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: linear-gradient(90deg, rgba(8,10,16,.8) 0%, rgba(8,10,16,.6) 34%, rgba(8,10,16,.24) 62%, rgba(8,10,16,.32) 100%);
}

/* ---------- 9. Narrow screens ---------- */

@media (max-width: 1080px) {
  .hx__stage .ph { --w: 270px; }
  .p-hl1, .p-hl2 { --room: calc(50% - 176px); right: calc(50% + 160px); }
  .p-hr1, .p-hr2 { --room: calc(50% - 176px); left: calc(50% + 160px); }
  .fx { grid-template-columns: 360px 1fr; }
  .fx__copy { padding: 40px 22px 56px 32px; }
  .fx .ph { --w: 244px; }
  .p-l1, .p-l2 { --room: calc(50% - 112px); right: calc(50% + 96px); }
  .p-r1, .p-r2 { --room: calc(50% - 112px); left: calc(50% + 96px); }
  .fx .nt { width: min(236px, var(--room, 236px)); }
  .co { max-width: min(224px, var(--room, 224px)); }
}
/* ⚠️ Below 900px the stage STACKS: the phone on the photograph, the list under
   it. The list stays inside the stage, so the scrim turns from left-to-right
   into top-to-bottom with it — a left scrim over a stacked stage darkens the
   middle of the phone's photograph and leaves the list on the bright part. */
@media (max-width: 900px) {
  .hx__stage { height: 640px; border-radius: 30px; }
  .hx__stage .ph { --w: 248px; top: 34px; }
  .fx { grid-template-columns: 1fr; height: auto; border-radius: 30px; }
  .fx .stage-media { order: -1; height: 580px; }
  .fx .ph { --w: 240px; }
  .fx .stage-bg::after, .fx--wall::before {
    background: linear-gradient(180deg, rgba(8,10,16,.12) 0%, rgba(8,10,16,.22) 52%,
                                        rgba(8,10,16,.86) 70%, rgba(8,10,16,.94) 100%);
  }
  /* Room at the foot for the tab row, which overlaps the stage's edge. */
  .fx__copy { padding: 4px 24px 54px; align-content: start; }
  .fx__ico { display: none; }
  .fx__step { margin-top: 0; }
  .fx__cap h3 { font-size: 25px; }
  .fx__cap p { font-size: 15px; max-width: 560px; }
  .nt, .fx .nt { width: min(250px, var(--room, 250px)); }
  .co { max-width: min(230px, var(--room, 230px)); }
}
/* On a phone the cards hug the screen edges and overlap the device. There is
   no room beside a 240px phone on a 375px screen, and a card that does not fit
   is better over the edge of the recording than off the side of the page. */
@media (max-width: 640px) {
  .in-head h2 { font-size: 30px; }
  .hx__stage { height: 590px; border-radius: 26px; margin-inline: -8px; }
  .hx__stage .ph { --w: 232px; }
  .fx { border-radius: 26px; margin-inline: -8px; }
  .fx .stage-media { height: 540px; }
  .fx .ph { --w: 226px; }
  .p-hl1, .p-hl2, .p-l1, .p-l2 { --room: calc(100% - 20px); left: 10px; right: auto; }
  .p-hr1, .p-hr2, .p-r1, .p-r2 { --room: calc(100% - 20px); right: 10px; left: auto; }
  .nt, .fx .nt { width: min(222px, var(--room, 222px)); padding: 9px 11px 10px 9px; border-radius: 20px; gap: 9px; }
  .nt__app { width: 32px; height: 32px; border-radius: 8px; }
  .nt__hd strong { font-size: 13px; } .nt p { font-size: 12.5px; }
  .co { max-width: min(200px, var(--room, 200px)); padding: 8px 12px 8px 8px; gap: 9px; border-radius: 15px; }
  .co__txt b { font-size: 12.5px; } .co__txt span { font-size: 11px; }
  .co__ico, .co__flag { width: 30px; height: 30px; } .co__art { width: 34px; height: 34px; }
  .acts button { padding: 0 14px; font-size: 13px; height: 44px; gap: 6px; }
  .acts button svg { display: none; }
  .acts--sm { max-width: calc(100% - 8px); }
  .acts--sm button { height: 40px; padding: 0 14px; font-size: 13px; }
  .fx__copy { padding: 2px 18px 52px; }
}

/* ---------- 11. Close + footer ---------- */

.in-close { position: relative; isolation: isolate; overflow: hidden; text-align: center; color: #fff; }
@media (min-width: 960px) { .in-close { padding: 140px 0; } }
.in-close .stage-bg::after { background:
  radial-gradient(ellipse 42% 50% at 50% 50%, rgba(6,8,12,.72), rgba(6,8,12,.35) 70%, transparent),
  linear-gradient(180deg, rgba(8,10,16,.5), rgba(8,10,16,.35) 50%, rgba(8,10,16,.75)); }
.in-close h2 { font-size: clamp(48px, 8.4vw, 112px); font-weight: 820; letter-spacing: -.06em; line-height: .96; }
/* On the photograph the ramp runs lighter, or its ember end sinks into the dusk. */
.in-close h2 em { background: linear-gradient(96deg, #FFC19A 0%, #FF9A5C 45%, var(--brand-hi) 100%);
  -webkit-background-clip: text; background-clip: text; }
.in-close p { font-size: 17px; color: rgba(255,255,255,.82); line-height: 1.6; max-width: 480px; margin: 16px auto 0; }
.in-close .in-close__fine { font-size: 12.5px; color: rgba(255,255,255,.6); max-width: 540px; margin-top: 22px; }

.in-foot { border-top: 1px solid var(--line); padding: 28px 0 34px; font-size: 12.5px; color: var(--text-3); }
.in-foot__in { display: flex; flex-wrap: wrap; gap: 14px 24px; align-items: center; justify-content: space-between; }
.in-foot a:hover { color: var(--text-2); }
.in-foot nav { display: flex; gap: 16px; flex-wrap: wrap; }
.in-credits { margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--line); }
.in-credits summary { cursor: pointer; font-weight: 620; color: var(--text-2); width: max-content; }
.in-credits p { margin-top: 10px; line-height: 1.6; max-width: 760px; }
.in-credits ul { margin-top: 8px; display: grid; gap: 4px; line-height: 1.5; }
.in-credits a { text-decoration: underline; text-underline-offset: 2px; }

/* ---------- 13. v6 — the livelier page ---------- */
/* Everything below moves by transform or opacity only (DESIGN.md §7's rule), runs only
   while its part of the page is on screen where it loops, and stops under reduced
   motion (§12). The glow stays brand-only: no product colour is spent as decoration. */

/* The reading line: how far down the page you are. intro.js sets --sp. */
.in-progress { position: fixed; z-index: 100; top: 0; left: 0; right: 0; height: 3px; pointer-events: none;
  background: var(--glow); transform-origin: 0 50%; transform: scaleX(var(--sp, 0)); }

/* The nav pill tightens once the page has moved. */
.in-nav__in { transition: height .35s var(--ease), box-shadow .35s var(--ease), background .35s var(--ease); }
.in-nav.is-scrolled .in-nav__in { height: 52px; background: color-mix(in srgb, var(--surface) 88%, transparent);
  box-shadow: 0 18px 40px -20px rgba(16,18,24,.45); }

/* Hero: the kicker's live dot. */
.in-kicker--live::before { display: none; }
/* Longer than a section's name, so on a phone it may wrap: the pill grows rather than spill. */
.in-kicker--live { height: auto; min-height: 32px; padding-block: 7px; max-width: 100%; line-height: 1.35; text-align: left; }
@media (max-width: 480px) { .in-kicker--live { font-size: 10.5px; letter-spacing: .07em; } }
.in-kicker__pulse { position: relative; width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--brand); }
.in-kicker__pulse::after { content: ""; position: absolute; inset: -4px; border-radius: 50%; border: 2px solid var(--brand);
  animation: in-pulse 2.2s var(--ease) infinite; }
@keyframes in-pulse { from { transform: scale(.4); opacity: .9; } to { transform: scale(1.6); opacity: 0; } }

/* Hero: the headline rises in, line by line. A CSS animation runs with no script, and
   `both` holds the first frame only while it plays, so nothing is left hidden. */
.rise { display: inline-block; animation: in-rise 1s var(--ease-spring) both; animation-delay: calc(var(--d, 0) * .12s + .08s); }
.hx__lede.rise, .in-ctas.rise { display: block; }
.in-ctas.rise { display: flex; }
@keyframes in-rise { from { opacity: 0; transform: translate3d(0, 28px, 0); } }
/* …and its accent line keeps a slow sheen moving through the brand ramp. */
.hx h1 em {
  background-image: linear-gradient(96deg, #FF9A5C 0%, var(--brand) 25%, var(--brand-lo) 50%, var(--brand) 75%, #FF9A5C 100%);
  background-size: 200% 100%;
  animation: in-rise 1s var(--ease-spring) both, in-shine 7s linear infinite;
  animation-delay: .2s, 1.2s;
}
@keyframes in-shine { to { background-position: -200% 0; } }

/* Hero: flight paths behind the headline, a dot flying each. */
.hx__routes { position: absolute; left: 0; top: 0; width: 100%; height: 640px; pointer-events: none; z-index: 0; }
.hx__route { fill: none; stroke: var(--line-strong); stroke-width: 1.4; stroke-dasharray: 2 9; stroke-linecap: round; opacity: .9; }
.hx__route--b { opacity: .6; }
.hx__route--c { opacity: .45; }
.hx__planes circle { fill: var(--brand); filter: drop-shadow(0 0 6px rgba(255,91,41,.7)); }
.hx__copy, .hx__deck, .hx .proof { z-index: 1; }

/* Hero: four of the app's badges floating round the headline, drifting with the pointer. */
.hx__floats { position: absolute; inset: 0 0 auto; height: 560px; pointer-events: none; z-index: 0; }
.hx__float { position: absolute; width: 86px; height: auto; display: none;
  filter: drop-shadow(0 18px 24px rgba(16,18,24,.28));
  translate: calc(var(--px, 0) * var(--depth, 14px)) calc(var(--py, 0) * var(--depth, 14px));
  transition: translate .6s var(--ease);
  animation: in-bob 7s ease-in-out infinite alternate; }
.hx__float--a { left: 6%;  top: 96px;  --depth: 22px; }
.hx__float--b { right: 7%; top: 70px;  width: 78px; --depth: 16px; animation-delay: -2.4s; }
.hx__float--c { left: 12%; top: 330px; width: 64px; --depth: 10px; animation-delay: -4.1s; opacity: .92; }
.hx__float--d { right: 12%; top: 350px; width: 70px; --depth: 26px; animation-delay: -1.2s; opacity: .92; }
@keyframes in-bob { from { transform: translate3d(0, -8px, 0) rotate(-5deg); } to { transform: translate3d(0, 10px, 0) rotate(5deg); } }
@media (min-width: 1100px) { .hx__float { display: block; } }

/* The proof cards lift a little under the pointer. */
.proof > div { transition: transform .35s var(--ease), box-shadow .35s var(--ease), border-color .35s var(--ease); }
@media (hover: hover) { .proof > div:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); border-color: var(--line-strong); } }

/* Buttons that lean towards the pointer (intro.js sets --mx / --my). */
[data-magnet] { transform: translate3d(var(--mx, 0px), calc(var(--my, 0px) - var(--lift, 0px)), 0); }
.in-ctas [data-magnet]:hover { --lift: 1px; transform: translate3d(var(--mx, 0px), calc(var(--my, 0px) - var(--lift, 0px)), 0); }

/* Stages tilt towards the pointer: the phone turns a few degrees, a soft light follows.
   Only where a fine pointer hovers (intro.js adds `.tilt`); --rx / --ry / --sx / --sy. */
.hx__stage .ph { transform: perspective(1400px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)); }
.fx .ph { transform: translateY(-50%) perspective(1400px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)); }
.hx__stage .ph, .fx .ph { transition: transform .7s var(--ease); }
.tilt.is-tilting .ph { transition: transform .12s linear; }
.tilt::after { content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none; opacity: 0;
  background: radial-gradient(520px circle at var(--sx, 50%) var(--sy, 50%), rgba(255,190,150,.16), transparent 60%);
  transition: opacity .5s var(--ease); }
.tilt.is-tilting::after { opacity: 1; }

/* ── The loop band ── */
.in-head--center { margin-inline: auto; text-align: center; }
.in-head--center p { margin-inline: auto; }
.loop { overflow: hidden; }
.loop::before { content: ""; position: absolute; inset: 10% -10% auto; height: 70%; pointer-events: none; z-index: -1;
  background: radial-gradient(40% 50% at 50% 50%, var(--brand-soft), transparent 70%); }
.loop__steps { position: relative; display: grid; grid-template-columns: repeat(5, 1fr); gap: 14px; margin-top: 8px; }
/* The track joining the five icons, with a light running along it. */
.loop__steps::before { content: ""; position: absolute; left: 10%; right: 10%; top: 50px; height: 2px; border-radius: 2px;
  background:
    linear-gradient(90deg, transparent 0%, rgba(255,91,41,0) 40%, var(--brand) 48%, #FF9A5C 50%, rgba(255,91,41,0) 58%, transparent 100%) 0 0 / 250% 100% no-repeat,
    repeating-linear-gradient(90deg, var(--line-strong) 0 6px, transparent 6px 14px); }
.loop.is-inview .loop__steps::before { animation: in-track 10s linear infinite; }
@keyframes in-track { from { background-position: 150% 0, 0 0; } to { background-position: -150% 0, 0 0; } }
.loop__steps li { position: relative; list-style: none; }
.loop__steps a { display: flex; flex-direction: column; align-items: center; text-align: center; height: 100%;
  padding: 18px 14px 22px; border-radius: 26px; border: 1px solid transparent;
  transition: transform .5s var(--ease), background .5s var(--ease), border-color .5s var(--ease), box-shadow .5s var(--ease); }
.loop__ico { position: relative; width: 64px; height: 64px; border-radius: 22px; display: grid; place-items: center;
  background: var(--surface); border: 1px solid var(--line); color: var(--brand-lo); box-shadow: var(--shadow-sm);
  transition: background .5s var(--ease), color .5s var(--ease), box-shadow .5s var(--ease), transform .5s var(--ease-spring); }
.loop__steps b { margin-top: 16px; font-size: 19px; font-weight: 780; letter-spacing: -.03em; }
.loop__steps span:not(.loop__ico) { margin-top: 6px; font-size: 14px; line-height: 1.5; color: var(--text-2); max-width: 210px; }
/* The light: each step glows in turn, two seconds each, while the band is on screen. */
.loop.is-inview .loop__steps li { animation: in-step 10s var(--ease) infinite; animation-delay: calc(var(--i) * 2s); }
.loop.is-inview .loop__steps .loop__ico { animation: in-step-ico 10s var(--ease) infinite; animation-delay: calc(var(--i) * 2s); }
@keyframes in-step { 0%, 20% { transform: translateY(-6px); } 26%, 100% { transform: none; } }
@keyframes in-step-ico {
  0%, 20% { background: linear-gradient(135deg, var(--brand-hi), var(--brand) 50%, var(--brand-lo)); color: #fff;
            box-shadow: 0 16px 34px -12px rgba(255,91,41,.75); border-color: transparent; transform: scale(1.06); }
  26%, 100% { }
}
.loop__steps a:hover { background: var(--surface); border-color: var(--line); box-shadow: var(--shadow-md); }
.loop__steps a:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* ── 01 · AI: the night band in the brand's own warm light, over a moving mesh ── */
.fxb--ai { background: #06070b; }
.fxb--ai::before { background:
  radial-gradient(ellipse 55% 40% at 22% 0%, rgba(255,91,41,.18), transparent 70%),
  radial-gradient(ellipse 45% 35% at 85% 10%, rgba(255,154,92,.10), transparent 70%); }
.mesh { background: #07080c; }
.mesh i { position: absolute; width: 70%; aspect-ratio: 1; border-radius: 50%; will-change: transform; }
.mesh i:nth-child(1) { left: 30%; top: -30%; background: radial-gradient(closest-side, rgba(255,91,41,.55), transparent); }
.mesh i:nth-child(2) { left: 52%; top: 30%; width: 60%; background: radial-gradient(closest-side, rgba(255,154,92,.38), transparent); }
.mesh i:nth-child(3) { left: 10%; top: 40%; width: 55%; background: radial-gradient(closest-side, rgba(232,65,15,.42), transparent); }
.is-inview .mesh i:nth-child(1) { animation: in-orb1 16s ease-in-out infinite alternate; }
.is-inview .mesh i:nth-child(2) { animation: in-orb2 19s ease-in-out infinite alternate; }
.is-inview .mesh i:nth-child(3) { animation: in-orb3 23s ease-in-out infinite alternate; }
@keyframes in-orb1 { to { transform: translate3d(-18%, 22%, 0) scale(1.15); } }
@keyframes in-orb2 { to { transform: translate3d(-24%, -18%, 0) scale(.9); } }
@keyframes in-orb3 { to { transform: translate3d(30%, -12%, 0) scale(1.2); } }
/* A faint grid over it, fading out towards the edges. */
.mesh::before { content: ""; position: absolute; inset: 0; z-index: 1; opacity: .5;
  background-image: linear-gradient(rgba(255,255,255,.06) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,.06) 1px, transparent 1px);
  background-size: 44px 44px;
  -webkit-mask-image: radial-gradient(ellipse 70% 70% at 62% 50%, #000, transparent 75%);
          mask-image: radial-gradient(ellipse 70% 70% at 62% 50%, #000, transparent 75%); }
.fx--ai .stage-bg::after { z-index: 2; }

/* The AI chat around the phone: the prompt, the tool's answer, and Imprint's trip card. */
.ai-bubble { position: absolute; width: min(258px, var(--room, 258px)); padding: 12px 15px 13px; color: #fff;
  border-radius: 22px 22px 22px 6px; background: rgba(30,31,37,.97);
  box-shadow: 0 22px 44px -18px rgba(0,0,0,.75), inset 0 0 0 1px rgba(255,255,255,.1); }
.ai-bubble__who { display: flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 650; color: rgba(255,255,255,.55);
  letter-spacing: .01em; }
.ai-bubble p { margin-top: 6px; font-size: 14px; line-height: 1.42; letter-spacing: -.01em; }
.ai-tool { position: absolute; width: min(250px, var(--room, 250px)); display: flex; align-items: center; gap: 11px;
  padding: 10px 12px 10px 10px; border-radius: 18px; background: rgba(30,31,37,.97); color: #fff;
  box-shadow: 0 20px 40px -18px rgba(0,0,0,.75), inset 0 0 0 1px rgba(255,255,255,.1); }
.ai-tool img { width: 34px; height: 34px; border-radius: 10px; flex: none; }
.ai-tool div { min-width: 0; flex: 1; }
.ai-tool code { display: block; font: 600 11px/1.3 ui-monospace, "SF Mono", Menlo, monospace; color: #FFB08A;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ai-tool b { display: block; margin-top: 2px; font-size: 13.5px; font-weight: 680; letter-spacing: -.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* The tick sits on the icon's corner, so the two lines keep the chip's whole width. */
.ai-tool__ok { position: absolute; left: 32px; top: 30px; width: 18px; height: 18px; padding: 3.5px; border-radius: 50%;
  color: #fff; background: #00B37E; box-shadow: 0 0 0 2px rgba(30,31,37,1); }
.ai-card { position: absolute; width: min(228px, var(--room, 228px)); }
.ai-card__label { display: block; margin: 0 0 7px 4px; font-size: 11.5px; font-weight: 650; color: rgba(255,255,255,.62); }
.ai-card__win { height: 300px; overflow: hidden; border-radius: 18px; background: #fff;
  box-shadow: 0 28px 54px -20px rgba(0,0,0,.8), 0 0 0 1px rgba(255,255,255,.08); }
.ai-card__win img { display: block; width: 100%; height: auto; }
.is-live .cards > .ai-card.is-in .ai-card__win img { animation: in-card-scroll 5.2s ease-in-out .8s both; }
@keyframes in-card-scroll { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(0, calc(-100% + 300px), 0); } }
.fx--ai .p-r1 { top: 18%; }

@media (max-width: 1080px) {
  .ai-card__win { height: 250px; }
  @keyframes in-card-scroll { to { transform: translate3d(0, calc(-100% + 250px), 0); } }
}
@media (max-width: 900px) {
  .loop__steps { grid-template-columns: 1fr; gap: 6px; max-width: 520px; margin-inline: auto; }
  .loop__steps::before { left: 45px; right: auto; top: 30px; bottom: 30px; width: 2px; height: auto;
    background:
      linear-gradient(180deg, transparent 0%, rgba(255,91,41,0) 40%, var(--brand) 48%, #FF9A5C 50%, rgba(255,91,41,0) 58%, transparent 100%) 0 0 / 100% 250% no-repeat,
      repeating-linear-gradient(180deg, var(--line-strong) 0 6px, transparent 6px 14px); }
  @keyframes in-track { from { background-position: 0 150%, 0 0; } to { background-position: 0 -150%, 0 0; } }
  .loop__steps a { display: grid; grid-template-columns: 64px 1fr; column-gap: 16px; align-items: center; text-align: left; padding: 12px; }
  .loop__ico { grid-row: span 2; }
  .loop__steps b { margin-top: 0; align-self: end; }
  .loop__steps span:not(.loop__ico) { margin-top: 2px; max-width: none; align-self: start; }
  @keyframes in-step { 0%, 20% { transform: translateX(6px); } 26%, 100% { transform: none; } }
}
@media (max-width: 640px) {
  .ai-card { display: none; }
  .ai-bubble { width: min(220px, var(--room, 220px)); padding: 10px 12px 11px; }
  .ai-bubble p { font-size: 12.5px; }
  .ai-tool { width: min(210px, var(--room, 210px)); padding: 8px 10px 8px 8px; }
  .ai-tool img { width: 28px; height: 28px; }
  .ai-tool__ok { left: 26px; top: 24px; width: 16px; height: 16px; padding: 3px; }
  .ai-tool b { font-size: 12.5px; }
}

/* ---------- 12. Reduced motion ---------- */
/* intro.js does not play a single video under reduced motion and shows every
   card of the chosen scene at once; this takes away the CSS half — the push-in,
   the wall, the scroll-in and the card entrances. Switching scenes still works
   and is instant. */
@media (prefers-reduced-motion: reduce) {
  .is-inview .stage-bg > img, .is-inview .wall__col, .hx::before,
  .marquee.is-inview .marquee__track { animation: none !important; }
  .io .fx:not(.is-seen), .io .in-head:not(.is-seen), .io .proof:not(.is-seen),
  .io .fx:not(.is-seen) + .acts--sm { opacity: 1; transform: none; }
  .fx, .fx + .acts--sm, .is-live .cards > *, .is-live .ph__scr > [data-media], .is-live .fx__cap,
  .in-head, .proof { transition: none !important; }
  /* v6 */
  .rise, .hx h1 em, .hx__float, .in-kicker__pulse::after, .is-inview .mesh i,
  .loop.is-inview .loop__steps::before, .loop.is-inview .loop__steps li, .loop.is-inview .loop__steps .loop__ico,
  .is-live .cards > .ai-card.is-in .ai-card__win img { animation: none !important; }
  .hx__planes { display: none; }
  .hx__float { translate: none; }
  [data-magnet], .hx__stage .ph, .fx .ph, .tilt .ph { transition: none !important; }
  .tilt::after { display: none; }
}
