/* =========================================================================
   DUAL — Marketing v3
   Implemented from Figma "DUAL Content" → MARKETING SITE (node 743:31),
   desktop frame 1440 x 7244. Every number below that looks arbitrary came
   off that frame.

   This sheet STANDS ALONE. v3 used to link ../v2/styles.css first and add on
   top of it, so the two pages could not drift into different visual
   languages. The Figma redesign IS a different visual language — its nav,
   buttons, type scale, card radii and section rhythm all differ from v2's —
   so inheriting v2 would have meant overriding almost every rule it defines
   and still carrying its weight. The only things v3 still borrows from v2
   are two brand marks by absolute path (`/marketing/v2/assets/logo-*.svg`).

   Layout scale, all from the frame:
     page      1440 max, 80px gutter, so content is 1280
     sections  96px top and bottom (the convert rail, FAQ and footer differ,
               and each says so at its own rule)
     radii     8 chip / 24 card / 32 panel / 40 button / 999 pill
     buttons   51px tall, 24px side padding, 16px Inter Medium
   ========================================================================= */

:root {
  --black: #000;
  --white: #fff;
  --orange: #fe7527; /* DUAL brand orange — the hero action */
  --orange-lit: #ff9300; /* the Figma slider fill + the footer's fee link */
  --grey-chip: #f3f3f3;
  --muted: #b9b9b9;

  /* Every panel in the design is white at 10% over black. That resolves to
     #1a1a1a, which matters: the phone-bezel image is a rectangle of exactly
     that colour with the handset drawn on it, so a card painted with the
     translucent value over ANY other backdrop would show a visible seam
     around the phone. Panels are therefore painted with the solid colour and
     the translucent one is kept for surfaces that sit on photography. */
  --panel: #1a1a1a;
  --glass-08: rgba(255, 255, 255, 0.08);
  --glass-10: rgba(255, 255, 255, 0.1);
  --glass-15: rgba(255, 255, 255, 0.15);
  --glass-20: rgba(255, 255, 255, 0.2);
  --glass-50: rgba(255, 255, 255, 0.5);

  --font-display: 'Montserrat', system-ui, sans-serif;
  --font-body: 'Inter', system-ui, sans-serif;
  --font-mono: 'Source Code Pro', ui-monospace, monospace;

  --gutter: 80px;
  --content: 1280px;
  --sec: 96px; /* the standard distance above and below a section */
  --col-gap: 80px; /* the gap between a 600px visual and its copy */
}

*,
*::before,
*::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

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

body {
  background: var(--black);
  color: var(--white);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img,
video {
  display: block;
  max-width: 100%;
}

/* The `hidden` ATTRIBUTE has to beat any `display` a component sets on
   itself. Without this, `.quote { display: flex }` silently defeats
   `[hidden]` and both athlete testimonials render at once — which is exactly
   the failure this page exists to avoid, since one voice reads as a person
   and a stack reads as marketing. Any component given an explicit `display`
   is one `hidden` away from the same bug, so the guard is global. */
[hidden] {
  display: none !important;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font-family: inherit;
  cursor: pointer;
  border: none;
  background: none;
  color: inherit;
}

:focus-visible {
  outline: 2px solid var(--orange-lit);
  outline-offset: 3px;
  border-radius: 4px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.page {
  width: 100%;
  max-width: 1440px;
  margin: 0 auto;
  position: relative;
}

/* The one horizontal measure. Everything that is not full-bleed sits in it. */
.wrap {
  width: 100%;
  max-width: calc(var(--content) + var(--gutter) * 2);
  margin: 0 auto;
  padding-inline: var(--gutter);
}

/* ---- recolourable brand mark (CSS mask over v2's SVGs) ----------------- */
.ic {
  display: inline-block;
  flex: none;
  background-color: currentColor;
  -webkit-mask: var(--ic) center / contain no-repeat;
  mask: var(--ic) center / contain no-repeat;
}

/* =========================================================================
   Buttons — one shape, four fills (Figma: h 51, px 24, py 16, r 40)
   ========================================================================= */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 51px;
  padding: 16px 24px;
  border-radius: 40px;
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  transition:
    transform 0.15s ease,
    opacity 0.15s ease,
    background-color 0.15s ease;
}
.btn:hover {
  transform: translateY(-1px);
}
.btn:active {
  transform: translateY(0);
}
.btn svg {
  width: 24px;
  height: 24px;
  flex: none;
}

.btn--orange {
  background: var(--orange);
  color: var(--white);
}
.btn--orange:hover {
  background: #ff8440;
}
.btn--light {
  background: var(--white);
  color: var(--black);
}
.btn--light:hover {
  background: #ececec;
}
.btn--glass {
  background: var(--glass-20);
  color: var(--white);
}
.btn--glass:hover {
  background: rgba(255, 255, 255, 0.28);
}
.btn--outline {
  border: 1px solid var(--white);
  color: var(--white);
}
.btn--outline:hover {
  background: rgba(255, 255, 255, 0.12);
}

.btnrow {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}

/* =========================================================================
   VIEW SWITCHING — the same vocabulary v2 uses
   =========================================================================
   `body[data-view]` says which audience is showing; `.v-athlete` / `.v-coach`
   only ever HIDE. The nav, the hero photograph and its band, the community
   row and the whole footer are mounted ONCE and never re-render, so the
   toggle reads as one site changing its mind rather than two sites. Only the
   hero COPY and the body sections swap.

   `!important` because these have to beat any `display` a component sets on
   itself (`.btn` is inline-flex, `.faq__list` is flex, `.prog` is block).
   ========================================================================= */
body[data-view='coach'] .v-athlete,
body[data-view='athlete'] .v-coach {
  display: none !important;
}

/* =========================================================================
   NAV — sits OVER the hero (the frame has it at y 0 with the hero behind).
   It is not sticky: the design gives it no solid or scrolled state, and a
   translucent bar over section photography would need one.
   ========================================================================= */
.nav {
  position: absolute;
  inset: 0 0 auto 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 24px var(--gutter) 0;
}

.nav__logo {
  width: 193px;
  height: 40px;
  --ic: url('/marketing/v2/assets/logo-wordmark.svg');
}

/* Audience switch. Both halves are real anchors carrying ?view=, so a copied
   link opens the right view and a middle-click still works; main.js
   intercepts the click and swaps in place rather than reloading. The active
   half carries aria-current. */
.nav__switch {
  display: flex;
  gap: 10px;
  padding: 4px;
  background: var(--glass-20);
  border-radius: 40px;
}
.nav__switch a {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 50px;
  padding: 10px 16px;
  border-radius: 80px;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 500;
  color: var(--white);
  white-space: nowrap;
}
.nav__switch a[aria-current='page'] {
  background: var(--white);
  color: var(--black);
  padding-inline: 24px;
}

.nav__right {
  display: flex;
  align-items: center;
  gap: 22px;
}
/* Download shows on every device from 761px up (Brian, 2026-09-28): on a
   Mac it opens the App Store listing, so a desktop visitor still finds DUAL
   there. Phones are narrowed to iPhone in the 760px block below. */

/* =========================================================================
   HERO (coach view) — the content studio's "gloss" ground, Sonata kneeling on
   it, her cards round her (Brian, 2026-09-25; replaced the Figma 756:2385
   room-and-cutout hero). Back to front:
     1. the gloss       (.hero__gloss, marketing/social/studio.html's `gloss`
                         treatment, gradient for gradient)
     2. three cards     (.hero__stage, coach view only)
     3. the creator     (.hero__stage--front: floor glow, reflection, her)
     4. the copy        (.hero__inner, left-aligned on the coach view)
   The cards and the creator sit on 1440 x 843 stages pinned to the hero's
   bottom edge, so below 1180px they shrink together by --stage-s.
   ========================================================================= */
.hero {
  position: relative;
  /* FULL-BLEED: break out of `.page`'s 1440 cap so the ground spans the
     whole viewport. The nav, the copy and the stages stay on the 1440
     measure. */
  width: 100vw;
  margin-left: calc(50% - 50vw);
  height: 843px;
  overflow: hidden;
  isolation: isolate;
  border-radius: 0 0 64px 64px;
  background: #111113;
  --stage-s: 1;
}
/* studio.html draws, in order: a charcoal fall, a radial sheen from 10% down,
   a faint diagonal specular over the top 55%, then a vignette centred 62%
   down. CSS lists layers top-first, so the order here is reversed. */
.hero__gloss {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(
      circle 85vw at 50% 62%,
      rgba(0, 0, 0, 0) 23.5%,
      rgba(0, 0, 0, 0.5) 100%
    ),
    linear-gradient(
        to bottom right,
        rgba(255, 255, 255, 0.05),
        rgba(255, 255, 255, 0) 50%
      )
      0 0 / 100% 55% no-repeat,
    radial-gradient(
      circle 95vw at 50% 10%,
      rgba(255, 255, 255, 0.12) 0%,
      rgba(255, 255, 255, 0.03) 40%,
      rgba(255, 255, 255, 0) 100%
    ),
    linear-gradient(to bottom, #26262c 0%, #161619 48%, #08080a 100%);
}

/* ---- the studio photograph (coach hero) -------------------------------
   The widened room (3584 x 2016) at 1892 x 1064 on the stage: that puts her
   ~620px tall (about 2 image pixels per screen pixel, retina-sharp), her
   knee at x 1340, the floor on the hero's bottom edge. The room covers the
   stage's whole left side; the right edge feathers out for screens wider
   than it, the top slightly so the nav reads. */
.hero__shot {
  position: absolute;
  left: -281px;
  top: -221px;
  width: 1892px;
  height: 1064px;
  max-width: none;
  filter: brightness(0.93); /* Brian's tuning, 2026-09-25 */
  -webkit-mask-image: linear-gradient(to right, #000 92%, transparent);
  mask-image: linear-gradient(to right, #000 92%, transparent);
}
/* Shadow behind the copy: the windows' reflections sit right behind the
   headline. 70% at the edge, gone by 61% across (Brian's tuning,
   2026-09-25). */
.hero__scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(
      to right,
      rgba(0, 0, 0, 0.7) 0%,
      rgba(0, 0, 0, 0.385) 36.6%,
      rgba(0, 0, 0, 0) 61%
    ),
    linear-gradient(to bottom, rgba(0, 0, 0, 0.45) 0%, rgba(0, 0, 0, 0) 22%);
}
/* Back to front: room, copy shadow, the drift, her, the copy. The copy's
   box takes no clicks outside its own block, so it never swallows a tap
   meant for a card. */
.hero__stage--front {
  z-index: 0;
}
.hero__scrim {
  z-index: 1;
}
.hero__stage--person {
  z-index: 3;
}
.hero__inner {
  z-index: 4;
  pointer-events: none;
}
/* Her, laid exactly over herself in the room photo (same image, same
   scale): 1065 x 1207 cropped from x 2047 y 539 of the 3584 original. The
   room's brightness, so the two are one picture. */
.hero__person {
  position: absolute;
  left: 799.6px;
  top: 63.5px;
  width: 562.2px;
  height: 637.2px;
  max-width: none;
  filter: brightness(0.93);
}
.hero__copy {
  pointer-events: auto;
}

/* ---- the athlete hero ----------------------------------------------------
   The original v3 hero, restored for the athlete view only (2026-09-25):
   full-bleed video, 764px in the frame, black falling from the top so the
   nav reads and rising from the bottom so the page joins without a seam, the
   copy centred 25px below the middle. No bottom radius: it melts into the
   black page instead. */
.hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Never let the video take a tap: iOS reads one as "show controls". */
  pointer-events: none;
}
.hero__video::-webkit-media-controls,
.hero__video::-webkit-media-controls-start-playback-button,
.hero__video::-webkit-media-controls-panel,
.hero__video::-webkit-media-controls-overlay-play-button {
  display: none !important;
  -webkit-appearance: none;
  appearance: none;
}
.hero__fade {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to bottom, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0) 64.6%),
    linear-gradient(to top, #000 0%, rgba(0, 0, 0, 0) 64.6%);
  pointer-events: none;
}
body[data-view='athlete'] .hero {
  height: clamp(580px, 53vw, 764px);
  border-radius: 0;
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
}
body[data-view='athlete'] .hero__inner {
  width: 100%;
  padding-top: 0;
  transform: translateY(25px);
}
.hero__store {
  display: inline-block;
  margin-top: 24px;
  line-height: 0;
}
.hero__store img {
  height: 44px;
  width: auto;
}
/* v2's hero type: Montserrat Bold 64, 1.2, one line. */
body[data-view='athlete'] .hero__title {
  font-weight: 700;
  font-size: 64px;
  line-height: 1.2;
  padding-block: 0;
}
@media (max-width: 760px) {
  body[data-view='athlete'] .hero__title {
    font-size: clamp(24px, 7.4vw, 40px);
    line-height: 1.1;
  }
}

/* ---- the copy ----------------------------------------------------------
   The frame centres a 301px block 149px above the hero's midpoint, so its
   top edge is at 122px. */
.hero__inner {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 122px var(--gutter) 0;
}
.hero__copy {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}
.hero__title {
  /* Montserrat SemiBold 88, set in capitals. The frame stacks two 1.174
     line boxes 16px into each other, i.e. an 87px pitch; 8px of padding
     either side puts each baseline exactly where the frame has it. */
  font-family: var(--font-display);
  font-weight: 600;
  text-transform: uppercase;
  font-size: clamp(34px, 6.11vw, 88px);
  line-height: 0.989;
  padding-block: 0.091em;
}
/* The designed break holds down to ~520px, where the clamp floors the type
   and the line stops fitting; below that the headline reflows freely. */
@media (max-width: 520px) {
  .hero__br {
    display: none;
  }
}
.hero__sub {
  font-family: var(--font-display);
  font-size: 16px;
  line-height: 1.25;
  /* 863 in the frame, set on one line. Google's Montserrat sets ~10% wider
     than the frame's, so the measure is widened to keep it to one line
     rather than stranding "sell." on a second. */
  max-width: 960px;
}
.hero__copy .btn {
  margin-top: 24px; /* 32 in the frame, less the copy's own 8 */
}
.hero__copy .btn--orange {
  background: linear-gradient(102.88deg, #fe7527 1.35%, #fdb58b 100%);
}
/* The hero's "Start sharing" lands here; a little air above the mark. */
#join {
  scroll-margin-top: 48px;
}

/* ---- the stage -----------------------------------------------------------
   A 1440 x 843 box pinned to the hero's bottom edge; the room photo and her
   cutout sit at fixed coordinates inside it, so they scale as one. */
.hero__stage {
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 1440px;
  height: 843px;
  transform: translateX(-50%) scale(var(--stage-s));
  transform-origin: 50% 100%;
  pointer-events: none;
}
/* ---- Sonata's four offers, drawn as the app draws them ------------------
   Glass over the photograph, at 85% of the app's size. Shared by both
   motions below. */
.hcard {
  overflow: hidden;
  background: rgba(22, 22, 24, 0.5);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  color: var(--white);
  text-decoration: none;
  box-shadow:
    0 8px 28px rgba(0, 0, 0, 0.28),
    inset 0 0 0 1px rgba(255, 255, 255, 0.22);
  pointer-events: auto;
  transition: box-shadow 0.3s ease;
}
a.hcard:hover {
  box-shadow:
    0 14px 34px rgba(0, 0, 0, 0.36),
    inset 0 0 0 1px rgba(255, 255, 255, 0.5);
}
a.hcard:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 3px;
}
.hcard > span,
.hcard span {
  display: flex;
}
/* 354 in the frame; grows rather than wrap a longer title (the class). */
.hcard--program {
  width: max-content;
  min-width: 354px;
  padding: 16px;
  border-radius: 16px;
  flex-direction: column;
  gap: 20px;
}
.hcard__row {
  align-items: center;
  gap: 16px;
}
.hcard__thumb {
  width: 80px;
  height: 80px;
  flex-shrink: 0;
  border-radius: 8px;
  object-fit: cover;
}
.hcard__meta {
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
.hcard__title {
  white-space: nowrap;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 18px;
  line-height: 1.22;
  text-transform: uppercase;
  color: var(--grey-chip);
}
.hcard__date {
  font-size: 14px;
  line-height: 1.21;
  color: var(--grey-chip);
}
.hcard__chips {
  gap: 8px;
}
.hcard span.hcard__chip {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 4px;
  background: var(--black);
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.25;
  text-transform: uppercase;
  white-space: nowrap;
}
.hcard span.hcard__chip--orange {
  background: var(--orange);
}
.hcard span.hcard__chip--green {
  background: #489966;
}
.hcard span.hcard__chip--grey {
  background: #ececec;
  color: #585858;
}
.hcard__actions {
  align-items: center;
}
.hcard__view,
.hcard__share {
  align-items: center;
  padding: 8px 16px;
  border-radius: 20px;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.21;
  white-space: nowrap;
}
.hcard__view {
  gap: 4px;
  background: var(--grey-chip);
  color: var(--black);
}
.hcard__share {
  gap: 8px;
}
.hcard--trial {
  width: 370px;
  padding: 16px 48px 16px 16px;
  border-radius: 16px;
  flex-direction: column;
  gap: 12px;
}
.hcard--trial .hcard__chips {
  gap: 12px;
}
.hcard__session {
  align-items: center;
  gap: 8px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 20px;
  line-height: 1.2;
  white-space: nowrap;
}
.hcard__by {
  align-items: center;
  gap: 8px;
  font-family: var(--font-display);
  font-size: 16px;
  line-height: 1.25;
  white-space: nowrap;
}
.hcard span.hcard__avatar {
  position: relative;
  display: block;
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  overflow: hidden;
  border-radius: 50%;
}
.hcard__avatar img {
  position: absolute;
  left: -4px;
  top: 0;
  width: 26px;
  height: 27px;
  object-fit: cover;
}
/* CreatorPublicProfileScreen subscribeCard*: Montserrat 18 title, Inter 14
   body, Inter 12 terms, the orange Subscribe button. */
/* Wide enough that the body is two lines and the terms one. */
.hcard--sub {
  width: 400px;
  padding: 16px 16px 20px;
  border-radius: 20px;
  flex-direction: column;
  gap: 8px;
}
.hcard__subtitle {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 18px;
  line-height: 1.22;
  color: var(--grey-chip);
}
.hcard__subbody {
  font-size: 14px;
  line-height: 20px;
  color: var(--grey-chip);
}
.hcard__subterms {
  white-space: nowrap;
  margin-top: 4px;
  font-size: 12px;
  line-height: 16px;
  color: var(--grey-chip);
}
.hcard span.hcard__subcta {
  display: block;
  margin-top: 4px;
  padding: 14px 16px;
  border-radius: 20px;
  background: var(--orange);
  font-size: 16px;
  font-weight: 500;
  line-height: 1.2;
  text-align: center;
}
/* coachingCard*: title, one line of plain words, a chevron. */
/* Title, then each sentence on its own line (Brian, 2026-09-25). */
.hcard--coach {
  width: 330px;
  padding: 16px;
  border-radius: 20px;
  align-items: center;
  gap: 8px;
}
.hcard__coachbody {
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
.hcard__coachtitle {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 18px;
  line-height: 1.22;
}
.hcard__coachsub {
  flex-direction: column;
  font-size: 14px;
  line-height: 20px;
  white-space: nowrap;
}
.hcard--coach > img {
  flex: none;
}
.hcard,
.hcard--trial,
.hcard--program,
.hcard--sub,
.hcard--coach {
  display: flex;
}

/* Coach copy sits left of her, on the nav's gutter. The athlete view keeps
   its centred copy over the video. */
body[data-view='coach'] .hero__inner {
  align-items: flex-start;
  text-align: left;
  max-width: 1440px;
  margin: 0 auto;
  padding: 200px var(--gutter) 0;
}
body[data-view='coach'] .hero__copy {
  align-items: flex-start;
}
/* Two lines on desktop, "Let your audience" / "train with you." (Brian,
   2026-09-25). The first line is the long one, so the size is set by it:
   scaled with the screen so it always ends before her hair. */
body[data-view='coach'] .hero__title {
  font-size: clamp(34px, 3.75vw, 56px);
  white-space: nowrap;
}
/* One line on desktop (Brian, 2026-09-25): at 16px it runs ~650px, which
   ends before her hair from 1100px up. Narrower screens let it wrap. */
body[data-view='coach'] .hero__sub {
  max-width: none;
  white-space: nowrap;
}
@media (max-width: 1099px) {
  body[data-view='coach'] .hero__sub {
    max-width: min(500px, 46vw);
    white-space: normal;
  }
}

/* =========================================================================
   Sections
   ========================================================================= */
.sec {
  padding: var(--sec) 0;
}
.sec__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 40px;
  margin-bottom: 40px;
}
.sec__h {
  font-family: var(--font-display);
  font-size: 32px;
  font-weight: 500;
  line-height: 1.2;
  max-width: 661px;
}
.prose {
  font-family: var(--font-display);
  font-size: 16px;
  line-height: 1.5;
  max-width: 555px;
}
.prose + .prose {
  margin-top: 12px;
}

/* =========================================================================
   §1 CONVERT — a horizontal rail of three 512 x 808 cards, 32px apart,
   wider than the 1280 measure on purpose so the third card is cut off and
   the rail reads as scrollable before the arrows are touched.

   It is a real scroll container, so a trackpad, a touch swipe, the arrows
   and the keyboard all move it and none of them need JavaScript to work.
   The section has 140px above it in the frame rather than the usual 96.
   ========================================================================= */
#s-convert {
  padding-top: 140px;
}

.rail {
  display: flex;
  list-style: none;
  gap: 32px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  /* Bleed the rail out of the wrap to the page gutter, then pad it back, so a
     card can sit flush with the gutter at rest and still scroll past it. */
  margin-inline: calc(var(--gutter) * -1);
  padding-inline: var(--gutter);
  padding-bottom: 4px;
  /* Without this the snapport starts at the padding-box edge, so the browser
     snaps the FIRST card flush to the viewport and the rail loads already
     scrolled by one gutter — the cards sit a gutter left of the heading. */
  scroll-padding-inline: var(--gutter);
}
.rail::-webkit-scrollbar {
  display: none;
}

.rcard {
  flex: none;
  width: 512px;
  max-width: 86vw;
  background: var(--panel);
  border-radius: 24px;
  padding: 32px 29px;
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* "1. CONVERT YOUR TRAINING" — Source Code Pro on the light chip, the one
   place this page uses v2's monospace label. The number is a real <li> so
   the order is in the markup, not just in the copy. */
.rcard__step {
  align-self: flex-start;
  list-style: none;
  background: var(--grey-chip);
  color: var(--black);
  border-radius: 8px;
  padding: 6px 16px;
  font-family: var(--font-mono);
  font-size: 18px;
  line-height: 1.3;
  text-transform: uppercase;
}

.rcard__body {
  margin-top: 30px;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.rcard__cap {
  margin-top: 29px;
  font-family: var(--font-display);
  font-size: 16px;
  line-height: 1.4;
  width: 100%;
}

/* ---- the handset --------------------------------------------------------
   `device-bezel.webp` is the iPhone mockup exported from the Figma frame,
   drawn on a solid #1a1a1a ground — the same colour as the card behind it,
   which is why the card is painted solid and not translucent. The recording
   is laid INTO the screen aperture, whose insets and corner radius are
   measured off that file — by finding the near-black bezel ring, not by
   trusting the Figma node, which reports a radius for a differently scaled
   instance and is less than HALF the real one:
     aperture  top 2.68% · right 5.01% · bottom 2.34% · left 5.36%
     radius    12% of the frame's width (~103px on the 858px export)
     island    36.4% from the left, 27.5% wide, 3.82% down, 3.88% tall
   The radius is the one that bites. Too small and the square corners of the
   content show THROUGH the bezel's rounded inner curve — invisible on the
   dark recordings in §1, obvious on the lighter billboards in §4.
   Change the image and every one of these has to be re-measured. */
.dev {
  --dev-w: 286px;
  position: relative;
  /* Explicit, because §4 hangs this off a <span>: an inline box ignores
     `width` and `aspect-ratio` outright, so the handsets simply do not
     render. §1 gets away without it only because there it is a <figure>. */
  display: block;
  width: var(--dev-w);
  max-width: 100%;
  aspect-ratio: 858 / 1753;
  background: url('/marketing/v3/assets/device-bezel.webp') center / 100% 100%
    no-repeat;
}
.dev__screen {
  position: absolute;
  inset: 2.68% 5.01% 2.34% 5.36%;
  overflow: hidden;
  border-radius: calc(var(--dev-w) * 0.12);
  background: #0e0e0e;
}
.dev__screen video,
.dev__screen img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.35s ease;
}
/* A frame that has not loaded shows the neutral screen, never a path, a
   broken-image glyph or a caption about the file. Missing, slow and broken
   therefore all look the same, which is the point. */
.dev.is-loaded .dev__screen video,
.dev.is-loaded .dev__screen img {
  opacity: 1;
}
.dev__island {
  position: absolute;
  left: 36.4%;
  width: 27.5%;
  top: 3.82%;
  height: 3.88%;
  background: #000;
  border-radius: 999px;
  pointer-events: none;
}

/* Pause / replay. The clips carry no sound and a scrubber on a 286px frame
   is a worse replay button, so those are the only two controls. */
.dev__ctrls {
  position: absolute;
  top: 5%;
  right: 9%;
  display: flex;
  gap: 8px;
  opacity: 0;
  transition: opacity 0.2s ease;
}
.dev:hover .dev__ctrls,
.dev:focus-within .dev__ctrls {
  opacity: 1;
}
/* A touch screen has no hover, so a control only revealed by one is a control
   that does not exist there. Every phone gets them permanently. */
@media (hover: none) {
  .dev__ctrls {
    opacity: 1;
  }
}
.dev__ctrl {
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(8px);
  color: var(--white);
}
.dev__ctrl svg {
  width: 17px;
  height: 17px;
  fill: currentColor;
}
.dev__ctrl svg[fill='none'] {
  fill: none;
}

/* ---- rail arrows (42px circles; the leading one is dim until it can move) */
.rail__nav {
  display: flex;
  gap: 16px;
  flex: none;
}
.rail__btn {
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: var(--white);
  color: var(--black);
  box-shadow: 0 0 16.8px rgba(0, 0, 0, 0.16);
  transition:
    background-color 0.15s ease,
    color 0.15s ease;
}
.rail__btn svg {
  width: 25px;
  height: 25px;
}
.rail__btn[disabled] {
  background: var(--glass-15);
  color: var(--white);
  cursor: default;
  box-shadow: none;
}

/* =========================================================================
   §2 / §3 SPLIT — a 600px square visual beside its copy, 80px apart. The
   visual leads on the creator section and follows on the audience one.
   ========================================================================= */
/* Both splits are written COPY-FIRST in the markup so a stacked phone always
   meets the heading before the picture it describes, and a screen reader
   reads them in that order too. The desktop columns are therefore placed
   explicitly rather than taken from source order. */
.split {
  display: grid;
  align-items: center;
  gap: var(--col-gap);
}
.split--media-left {
  grid-template-columns: 600px minmax(0, 1fr);
}
.split--media-left .split__media {
  grid-area: 1 / 1;
}
.split--media-left .split__copy {
  grid-area: 1 / 2;
}
.split--media-right {
  grid-template-columns: minmax(0, 1fr) 600px;
}
.split__media {
  width: 100%;
  aspect-ratio: 1;
  border-radius: 32px;
  overflow: hidden;
  background: #17110d;
}
.split__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.split__copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 32px;
}

/* ---- two billboards, one panel ----------------------------------------
   The §4 visual. Geometry off the frame (746:1800, a 600 square):
     back  phone at 71,126 · front phone at 225,66 · both 303 wide
   expressed as percentages so the pair scales with the panel. The panel is a
   container so `cqw` can drive the handset width — `.dev` needs `--dev-w` to
   be a real length, because its screen radius is calculated from it.

   Both handsets bleed off the bottom, exactly as the frame draws them: the
   billboard is a long page and cropping it at the fold is what says so. */
.split__media--pair {
  background: linear-gradient(to bottom, #999 0%, #d9814b 100%);
  container-type: inline-size;
}
.pair {
  position: relative;
  width: 100%;
  height: 100%;
}
.pair__slot {
  position: absolute;
  display: block;
}
/* Spread wider than the frame draws them: at the frame's offsets the front
   handset covers half the one behind, and the point of the pair is that a
   visitor can read BOTH billboards and see they are different programs. */
.pair__slot--back {
  left: 3%;
  top: 23%;
}
.pair__slot--front {
  left: 49%;
  top: 8%;
  /* The only thing separating two identical handsets on one ground. */
  filter: drop-shadow(-14px 0 26px rgba(0, 0, 0, 0.4));
}
.pair .dev {
  --dev-w: 48cqw;
}

/* ---- DUAL vs the rest (Figma 801:3677) --------------------------------
   Columns 653 / 1fr / 1fr on the 1280 measure, 72px rows, hairlines at 20%
   of #bdbdbd. The DUAL column's gradient card sits behind the table at the
   same left and width as that column, running 24px past the last row. */
.cmp {
  position: relative;
  --cmp-label: 51%; /* 653 of 1280 */
  --cmp-col: 24.5%;
}
.cmp__card {
  position: absolute;
  top: 0;
  bottom: -24px;
  left: var(--cmp-label);
  width: var(--cmp-col);
  border-radius: 16px;
  background: linear-gradient(-26.9deg, #d7814d 0.85%, #4a2d1b 99.08%);
}
.cmp__table {
  position: relative;
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
  font-family: var(--font-display);
}
.cmp__table th,
.cmp__table td {
  height: 72px;
  padding: 12px 30px;
  font-size: 16px;
  font-weight: 400;
  line-height: 1.25;
  text-align: center;
  vertical-align: middle;
}
.cmp__table thead th,
.cmp__table thead td {
  font-size: 20px;
  font-weight: 500;
}
.cmp__table tbody th {
  width: var(--cmp-label);
  padding-left: 0;
  text-align: left;
}
.cmp__table thead td:first-child {
  width: var(--cmp-label);
}
.cmp__table tbody tr:not(:last-child) > * {
  border-bottom: 1px solid rgba(189, 189, 189, 0.2);
}
.cmp__logo {
  width: 116px;
  height: 24px;
  vertical-align: middle;
  color: var(--white);
  --ic: url('/marketing/v2/assets/logo-wordmark.svg');
}
.cmp__yes {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--white);
  vertical-align: middle;
}
.cmp__no {
  display: inline-block;
  width: 22px;
  height: 2px;
  vertical-align: middle;
}

/* "Others" + its info button; the panel names them (designer, 2026-09-28).
   Opens on hover where there is a mouse, and on tap everywhere (main.js
   sets data-open). Drawn with opacity, not [hidden], so hover can show it. */
.cmp__others {
  position: relative;
}
.cmp__others-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.cmp__info {
  display: inline-flex;
  padding: 4px;
  margin: -4px;
  border: 0;
  background: none;
  color: var(--white);
  cursor: pointer;
}
.cmp__info svg {
  width: 18px;
  height: 18px;
}
.cmp__pop {
  position: absolute;
  z-index: 2;
  top: calc(50% + 20px);
  left: 50%;
  width: max-content;
  max-width: min(260px, 90%);
  padding: 10px 16px;
  border-radius: 12px;
  background: rgba(40, 40, 44, 0.78);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.12);
  font-size: 15px;
  font-weight: 500;
  line-height: 1.35;
  text-align: center;
  opacity: 0;
  visibility: hidden;
  transform: translate(-50%, -4px);
  transition:
    opacity 0.15s ease,
    transform 0.15s ease,
    visibility 0s linear 0.15s;
  pointer-events: none;
}
.cmp__others[data-open] .cmp__pop {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
  transition:
    opacity 0.15s ease,
    transform 0.15s ease;
}
@media (hover: hover) {
  .cmp__others:hover .cmp__pop,
  .cmp__info:focus-visible ~ .cmp__pop {
    opacity: 1;
    visibility: visible;
    transform: translate(-50%, 0);
    transition:
      opacity 0.15s ease,
      transform 0.15s ease;
  }
}
@media (max-width: 760px) {
  .cmp__info svg {
    width: 15px;
    height: 15px;
  }
  .cmp__others-label {
    gap: 6px;
  }
  /* The column is the last one and ~95px wide: pin the panel to its right
     edge so it opens leftward over the table, never off the screen. */
  .cmp__pop {
    top: calc(50% + 16px);
    left: auto;
    right: 0;
    max-width: none;
    width: 190px;
    font-size: 13px;
    transform: translateY(-4px);
  }
  .cmp__others[data-open] .cmp__pop {
    transform: none;
  }
}

/* =========================================================================
   §4 COMMUNITY — four 308 x 502 portrait cards. Same rail mechanics as the
   convert section so a phone gets a swipe instead of four stacked cards.
   ========================================================================= */
.comm {
  display: flex;
  gap: 16px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  margin-inline: calc(var(--gutter) * -1);
  padding-inline: var(--gutter);
  padding-bottom: 4px;
  scroll-padding-inline: var(--gutter);
}
.comm::-webkit-scrollbar {
  display: none;
}
.commcard {
  position: relative;
  flex: 1 1 0;
  min-width: 262px;
  aspect-ratio: 308 / 502;
  border-radius: 24px;
  overflow: hidden;
  background: #2a2320;
  scroll-snap-align: start;
  display: block;
}
.commcard__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* The scrim starts 31.5% down (158 of 502 in the frame) and lands at 90%
   black, which is what makes Joe's quote readable over the photograph. */
.commcard::after {
  content: '';
  position: absolute;
  inset: 31.5% 0 0 0;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.9));
  pointer-events: none;
}
.commcard__who,
.commcard__go,
.commcard__quote {
  position: absolute;
  z-index: 2;
}
.commcard__who {
  top: 16px;
  left: 16px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 24px 8px 8px;
  border-radius: 32px;
  background: rgba(0, 0, 0, 0.4);
  backdrop-filter: blur(8px);
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 500;
}
.commcard__av {
  width: 32px;
  height: 32px;
  border-radius: 999px;
  object-fit: cover;
  background: var(--white);
  flex: none;
}
.commcard__go {
  top: 16px;
  right: 16px;
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  border-radius: 40px;
  background: var(--white);
  color: var(--black);
}
.commcard__go svg {
  width: 24px;
  height: 24px;
}
.commcard__quote {
  left: 16px;
  right: 16px;
  bottom: 24px;
  font-family: var(--font-display);
  font-size: 14px;
  line-height: 1.35;
}
.commcard__quote cite {
  font-style: normal;
}

/* =========================================================================
   ATHLETE VIEW — the sections ported from v2, reset in this design system
   ========================================================================= */

/* ---- program cards on the same rail mechanics as §1 -------------------- */
.rail--prog {
  align-items: stretch;
}
.prog {
  position: relative;
  flex: none;
  width: 420px;
  max-width: 86vw;
  min-height: 520px;
  border-radius: 24px;
  overflow: hidden;
  background: var(--panel);
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}
.prog__photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.prog__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0.15) 0%,
    rgba(0, 0, 0, 0.75) 45%,
    rgba(0, 0, 0, 0.92) 100%
  );
}
.prog__body {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 24px;
}
.prog__title {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 600;
  line-height: 1.2;
}
.prog__by {
  display: block;
  margin-top: 6px;
  font-family: var(--font-display);
  font-size: 14px;
  color: var(--muted);
}
.prog__price {
  align-self: flex-start;
  padding: 6px 14px;
  border-radius: 999px;
  background: var(--glass-15);
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 600;
}
.prog__feats {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.feat {
  padding: 6px 12px;
  border-radius: 8px;
  background: var(--glass-10);
  font-family: var(--font-display);
  font-size: 13px;
  line-height: 1.2;
}

/* The trial block IS the call to action on a card — a whole tappable panel
   rather than a description sitting under a pill somewhere else. */
.trial {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px;
  border-radius: 16px;
  background: var(--glass-10);
  backdrop-filter: blur(8px);
}
.trial__main {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1;
  min-width: 0;
}
.trial__badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.tag {
  padding: 3px 8px;
  border-radius: 6px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.tag--green {
  background: #489966;
  color: var(--white);
}
.tag--grey {
  background: var(--glass-20);
  color: var(--white);
}
.trial__title {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 600;
  line-height: 1.25;
}
.trial__sub {
  font-family: var(--font-display);
  font-size: 13px;
  line-height: 1.35;
  color: var(--muted);
}
.trial__go {
  flex: none;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: var(--white);
  color: var(--black);
}
.trial__go svg {
  width: 18px;
  height: 18px;
}

/* ---- the athlete quote ------------------------------------------------- */
/* One voice, centred, with room around it. A stack of quotes reads as
   marketing; one person reads as a person. main.js reveals exactly one. */
.quote {
  max-width: 820px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
  text-align: center;
}
.quote__avatar {
  width: 88px;
  height: 88px;
  border-radius: 999px;
  object-fit: cover;
}
.quote__text {
  font-family: var(--font-display);
  font-size: clamp(20px, 2.2vw, 28px);
  font-weight: 500;
  line-height: 1.4;
}
.quote__who {
  font-family: var(--font-display);
  font-size: 16px;
  color: var(--muted);
}

/* ---- the follow section's chips ---------------------------------------- */
.chiprow {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
.chip {
  padding: 10px 18px;
  border-radius: 999px;
  background: var(--glass-10);
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 500;
}

/* The follow phone is a product still on a transparent-ish ground, not a
   photographic square like §2 and §3 — it gets contained, not cropped. */
.split__media--contain {
  aspect-ratio: auto;
  background: none;
  border-radius: 0;
  display: grid;
  place-items: center;
}
.split__media--contain img {
  width: min(420px, 100%);
  height: auto;
  object-fit: contain;
}

/* =========================================================================
   §5 EARNINGS — one panel, sliders left, the estimate right.
   The arithmetic and every claim in it live in main.js; this only dresses
   them. The one rule the markup and the script share: the figure shown is
   what reaches the creator AFTER DUAL's 10%, and the note under it names
   that rate. Never restate it as the creator's share.
   ========================================================================= */
.calc {
  display: grid;
  grid-template-columns: 1fr 510px;
  gap: var(--col-gap);
  align-items: stretch;
  background: var(--panel);
  border-radius: 24px;
  padding: 48px 64px;
}
.calc__left {
  display: flex;
  flex-direction: column;
  gap: 40px;
}
.calc__fields {
  display: flex;
  flex-direction: column;
  gap: 40px;
}
.field {
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.field__top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
}
.field__label {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 500;
}
.field__val {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 600;
}

/* A real <input type=range>, so it is keyboard- and screen-reader-operable
   by construction; only the furniture is restyled. */
.field input[type='range'] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 16px;
  background: transparent;
  cursor: pointer;
}
.field input[type='range']::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 4px;
  background: linear-gradient(
    to right,
    var(--orange-lit) 0 var(--fill, 50%),
    var(--glass-20) var(--fill, 50%) 100%
  );
}
.field input[type='range']::-moz-range-track {
  height: 4px;
  border-radius: 4px;
  background: var(--glass-20);
}
.field input[type='range']::-moz-range-progress {
  height: 4px;
  border-radius: 4px;
  background: var(--orange-lit);
}
.field input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 16px;
  height: 16px;
  margin-top: -6px;
  border-radius: 999px;
  background: var(--orange-lit);
  border: none;
}
.field input[type='range']::-moz-range-thumb {
  width: 16px;
  height: 16px;
  border-radius: 999px;
  background: var(--orange-lit);
  border: none;
}

.calc__right {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.calc__figure {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(48px, 5.6vw, 80px);
  line-height: 1.2;
}
.calc__figure small {
  font-weight: 400;
  font-size: 16px;
  margin-left: 8px;
  /* The frame hangs "/ month" off the bottom of the numeral, not its cap. */
  vertical-align: baseline;
  position: relative;
  top: -0.12em;
}
.calc__range {
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 500;
  margin-top: 8px;
}
.calc__reveal {
  margin-top: 16px;
}
.calc__reveal summary {
  display: flex;
  align-items: center;
  gap: 8px;
  list-style: none;
  cursor: pointer;
  color: var(--muted);
  font-family: var(--font-display);
  font-size: 14px;
  line-height: 1.2;
  padding-bottom: 12px;
}
.calc__reveal summary::-webkit-details-marker {
  display: none;
}
.calc__reveal summary svg {
  width: 24px;
  height: 24px;
  transition: transform 0.2s ease;
}
.calc__reveal[open] summary svg {
  transform: rotate(180deg);
}
.calc__rows {
  border-top: 1px solid var(--glass-20);
  padding-top: 16px;
  display: flex;
  flex-direction: column;
  font-size: 14px;
  line-height: 1.2;
}
.calc__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 8px 0;
  font-family: var(--font-display);
}
.calc__row dt {
  color: var(--muted);
}
.calc__row dd {
  font-weight: 500;
  text-align: right;
}
.calc__note {
  font-family: var(--font-display);
  font-size: 12px;
  line-height: 1.4;
  color: var(--muted);
  margin-top: auto;
  padding-top: 16px;
}
.calc__cta {
  margin-top: 24px;
  align-self: flex-start;
}

/* =========================================================================
   §6 FAQ — the list on the left, the word on the right. 140 above, 112
   below in the frame.
   ========================================================================= */
#s-faq {
  padding: 140px 0 112px;
}
.faq {
  display: grid;
  grid-template-columns: 943px 1fr;
  gap: 40px;
  align-items: start;
}
.faq__list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.faq__item {
  border-radius: 20px;
  transition: background-color 0.2s ease;
}
.faq__item[data-open='1'] {
  background: var(--glass-08);
}
.faq__q {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 40px;
  text-align: left;
  padding: 24px 24px 24px 32px;
}
.faq__item[data-open='1'] .faq__q {
  padding-block: 32px 16px;
  align-items: flex-start;
}
.faq__q-text {
  /* The frame sets these in Haas Grot Display, which DUAL does not license.
     Montserrat is the display face everywhere else on this page and is the
     nearest thing the project actually ships. */
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 500;
  line-height: 1.25;
}
.faq__toggle {
  flex: none;
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: var(--glass-50);
  color: var(--black);
  transition: background-color 0.2s ease;
}
.faq__item[data-open='1'] .faq__toggle {
  background: var(--white);
}
.faq__toggle svg {
  width: 21px;
  height: 21px;
  transition: transform 0.2s ease;
}
/* The plus becomes a cross. One icon, one rotation — see initFaq. */
.faq__item[data-open='1'] .faq__toggle svg {
  transform: rotate(45deg);
}
.faq__a {
  display: grid;
  grid-template-rows: 0fr;
  /* `visibility` takes a collapsed answer out of the tab order as well as out
     of view, but it has to wait for the height transition or the close reads
     as a jump rather than a collapse. */
  visibility: hidden;
  transition:
    grid-template-rows 0.25s ease,
    visibility 0s linear 0.25s;
}
.faq__item[data-open='1'] .faq__a {
  grid-template-rows: 1fr;
  visibility: visible;
  transition:
    grid-template-rows 0.25s ease,
    visibility 0s;
}
.faq__a > div {
  overflow: hidden;
}
.faq__a p {
  font-family: var(--font-display);
  font-size: 16px;
  line-height: 1.4;
  max-width: 687px;
  padding: 0 32px 32px;
}
.faq__a a {
  color: var(--orange-lit);
  text-decoration: underline;
}
.faq__word {
  font-family: var(--font-display);
  font-size: 48px;
  font-weight: 500;
  text-align: right;
}

/* =========================================================================
   FOOTER — the close, then the marks. 140 above the close in the frame.
   ========================================================================= */
.footer {
  padding: 140px 0 64px;
}
.foot__close {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
  text-align: center;
}
.foot__mark {
  width: 88px;
  height: 88px;
  border-radius: 22px;
  background: rgba(0, 0, 0, 0.2);
  display: grid;
  place-items: center;
}
.foot__mark span {
  width: 80px;
  height: 17px;
  --ic: url('/marketing/v2/assets/logo-wordmark.svg');
}
.foot__h {
  font-family: var(--font-display);
  font-size: clamp(28px, 3.4vw, 40px);
  font-weight: 500;
  line-height: 1.2;
}
.foot__lines {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 500;
  line-height: 1.5;
  max-width: 680px;
}
.foot__lines strong {
  font-weight: 600;
}

/* The fee detail. Collapsed by default and native, so it opens from a tap,
   the keyboard or find-in-page without any script. The summary is the
   design's "See full details." link, which is why it is inline and orange
   rather than a row of its own. */
.fees {
  display: inline;
}
.fees > summary {
  display: inline;
  list-style: none;
  cursor: pointer;
  color: var(--orange-lit);
  text-decoration: underline;
}
.fees > summary::-webkit-details-marker {
  display: none;
}
.fees__body {
  display: block;
  margin: 24px auto 0;
  max-width: 760px;
  text-align: left;
  background: var(--panel);
  border-radius: 24px;
  padding: 24px 32px;
}
.fees__body li {
  font-family: var(--font-display);
  font-size: 15px;
  line-height: 1.5;
  margin-left: 18px;
}
.fees__body li + li {
  margin-top: 12px;
}

.foot__fine {
  font-family: var(--font-display);
  font-size: 14px;
  line-height: 1.4;
  color: var(--muted);
}

.foot__shot {
  margin: 56px auto 0;
  width: min(578px, 100%);
}
.foot__shot img {
  width: 100%;
  height: auto;
}

.foot__bottom {
  margin-top: 96px;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 80px;
}
.foot__wordmark {
  width: min(696px, 52vw);
  height: auto;
  aspect-ratio: 695.7 / 144;
  --ic: url('/marketing/v2/assets/logo-wordmark.svg');
}
.foot__links {
  display: flex;
  gap: 133px;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 500;
}
.foot__col {
  display: flex;
  flex-direction: column;
  gap: 43px;
}
.foot__col a:hover {
  color: var(--muted);
}

/* =========================================================================
   Responsive. The frame is desktop-only; everything below is this build's
   reading of it. Order: the 1280 measure gives way first, then the two-up
   splits, then the gutter.
   ========================================================================= */
@media (max-width: 1439px) {
  .foot__bottom {
    gap: 48px;
  }
  .foot__links {
    gap: 64px;
  }
}

@media (max-width: 1180px) {
  :root {
    --gutter: 48px;
    --col-gap: 48px;
  }
  /* Photo and cards shrink as one group and pin to the RIGHT edge, so the
     cards on her right stay on screen and the copy keeps the left. */
  .hero {
    --stage-s: 0.78;
  }
  .hero__stage {
    left: auto;
    right: 0;
    transform: scale(var(--stage-s));
    transform-origin: 100% 100%;
  }
  /* Scaled down, the stage no longer reaches the hero's top, so the room's
     top edge would show as a line: feather it into the gloss. */
  .hero__shot {
    -webkit-mask-image:
      linear-gradient(to right, #000 92%, transparent),
      linear-gradient(to bottom, transparent 18%, #000 34%);
    -webkit-mask-composite: source-in;
    mask-image:
      linear-gradient(to right, #000 92%, transparent),
      linear-gradient(to bottom, transparent 18%, #000 34%);
    mask-composite: intersect;
  }
  .split--media-left {
    grid-template-columns: minmax(0, 520px) minmax(0, 1fr);
  }
  .split--media-right {
    grid-template-columns: minmax(0, 1fr) minmax(0, 520px);
  }
  .calc {
    grid-template-columns: 1fr minmax(0, 420px);
    padding: 40px;
  }
  .faq {
    grid-template-columns: 1fr auto;
  }
}

@media (max-width: 980px) {
  :root {
    --sec: 72px;
  }
  .hero {
    --stage-s: 0.62;
  }
  /* Stacked: one column, and the explicit desktop placement is dropped so
     the markup's copy-first order stands. */
  .split--media-left,
  .split--media-right {
    grid-template-columns: minmax(0, 1fr);
  }
  .split--media-left .split__media,
  .split--media-left .split__copy {
    grid-area: auto;
  }
  .split {
    gap: 32px;
  }
  .split__media {
    max-width: 520px;
  }
  .calc {
    grid-template-columns: 1fr;
    gap: 40px;
  }
  .calc__cta {
    align-self: stretch;
  }
  .faq {
    grid-template-columns: 1fr;
  }
  .faq__word {
    order: -1;
    text-align: left;
  }
  #s-faq {
    padding: 96px 0 72px;
  }
  #s-convert {
    padding-top: 96px;
  }
  .foot__bottom {
    flex-direction: column;
    gap: 48px;
  }
  .foot__wordmark {
    width: min(696px, 100%);
  }
}

@media (max-width: 760px) {
  :root {
    --gutter: 24px;
  }
  /* Phone: copy on top, her centred below on the gloss, the two cards
     tucked beside her. Both stages become a 402 x 843 box scaled to the
     screen by --phone-s (main.js sets it to width / 402; CSS cannot make a
     unitless ratio from 100vw), and the hero is that box's height. */
  .hero {
    --phone-s: 0.97;
    height: calc(843px * var(--phone-s));
    border-radius: 0 0 40px 40px;
  }
  .hero__stage {
    left: 50%;
    right: auto;
    width: 402px;
    transform: translateX(-50%) scale(var(--phone-s));
    transform-origin: 50% 100%;
  }
  /* In 402-box pixels: the room 1150 wide, bottom-anchored, her knee 30px
     in from the right, so she sits under the copy with the stick rising
     into its lower edge. Feathered at the top into the page. */
  .hero__shot {
    left: -613px;
    top: 196px;
    width: 1150px;
    height: 647px;
    -webkit-mask-image: linear-gradient(to bottom, transparent 18%, #000 36%);
    mask-image: linear-gradient(to bottom, transparent 18%, #000 36%);
  }
  .hero__scrim {
    display: none;
  }
  /* Her, on the phone's room box: left -613 top 196 at 647/2016 scale. */
  .hero__person {
    left: 43.9px;
    top: 369px;
    width: 341.8px;
    height: 387.4px;
  }
  body[data-view='coach'] .hero__inner {
    padding-top: 112px;
  }
  body[data-view='coach'] .hero__copy {
    max-width: none;
  }
  body[data-view='coach'] .hero__title {
    white-space: normal;
  }
  body[data-view='coach'] .hero__sub {
    max-width: none;
  }
  .hero__inner {
    padding-top: 112px;
  }
  body[data-view='athlete'] .hero__inner {
    transform: none;
  }
  .nav {
    padding-top: 16px;
    gap: 12px;
  }
  .nav__logo {
    width: 116px;
    height: 24px;
  }
  /* The switch is the page's only way back to the athlete site, so it stays;
     the two buttons on the right collapse to Sign In, and the download route
     on iOS is the Smart App Banner the <head> already declares. */
  .nav__switch a {
    height: 40px;
    padding-inline: 12px;
    font-size: 14px;
  }
  .nav__switch a[aria-current='page'] {
    padding-inline: 16px;
  }
  .nav__right {
    gap: 12px;
  }
  .nav .btn {
    height: 40px;
    padding-inline: 16px;
    font-size: 14px;
  }
  /* Phone: one button. iPhone gets Download (the App Store is the way in);
     anything else keeps Sign In. */
  .nav__download {
    display: none;
  }
  html.is-ios .nav__download {
    display: inline-flex;
  }
  html.is-ios #cta-signin {
    display: none;
  }

  .hero__sub {
    font-size: 15px;
  }

  /* Phones: the label column gives up width, text wraps, rows grow. */
  .cmp {
    --cmp-label: 48%;
    --cmp-col: 26%;
  }
  .cmp__table th,
  .cmp__table td {
    height: 64px;
    padding: 12px 8px;
    font-size: 14px;
  }
  .cmp__table thead th,
  .cmp__table thead td {
    font-size: 14px;
  }
  .cmp__table tbody th {
    padding-right: 12px;
  }
  .cmp__logo {
    width: 72px;
    height: 15px;
  }
  .sec__head {
    flex-direction: column;
    gap: 24px;
    margin-bottom: 28px;
  }
  .sec__h,
  .faq__word {
    font-size: 26px;
  }
  .faq__q-text {
    font-size: 18px;
  }
  .faq__q {
    gap: 16px;
    padding: 20px 16px 20px 20px;
  }
  .faq__item[data-open='1'] .faq__q {
    padding-block: 24px 12px;
  }
  .faq__a p {
    padding: 0 20px 24px;
  }
  .faq__toggle {
    width: 40px;
    height: 40px;
  }

  .rcard {
    padding: 24px 20px;
  }
  .dev {
    --dev-w: 232px;
  }
  .calc {
    padding: 28px 20px;
    border-radius: 20px;
  }
  .foot__links {
    gap: 40px;
  }
  .foot__col {
    gap: 24px;
  }
  .footer {
    padding-top: 96px;
  }
  .foot__shot {
    margin-top: 40px;
  }
  .foot__bottom {
    margin-top: 64px;
  }
}

/* Phone. The nav is the only row on the page that cannot wrap — the switch
   is the sole route back to the athlete site, so everything else in the bar
   gives way to keep all three controls on screen at 390px. */
@media (max-width: 480px) {
  .nav {
    padding-inline: 16px;
    gap: 8px;
  }
  .nav__logo {
    width: 92px;
    height: 19px;
  }
  .nav__switch {
    gap: 4px;
    padding: 3px;
  }
  .nav__switch a {
    height: 34px;
    padding-inline: 10px;
    font-size: 13px;
  }
  .nav__switch a[aria-current='page'] {
    padding-inline: 12px;
  }
  .nav .btn {
    height: 34px;
    padding-inline: 12px;
    font-size: 13px;
  }
}

/* The clips and the rail both animate. Honour a request not to. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  .rail,
  .comm {
    scroll-behavior: auto;
  }
  .btn:hover {
    transform: none;
  }
  .faq__a {
    transition: none;
  }
}

/* =========================================================================
   SHARE VIEW: VIDEO HERO + STUDIO SECTION (Brian, 2026-09-26)
   The Share view opens on a clean video hero (v2's film in black and white,
   one centred line, one button). Sonata's studio, with her cards gliding
   behind her, sits below it as its own rounded section and carries the
   "See how Sonata shares her training" copy that used to be section 3.
   Kept at the END of the sheet on purpose: these override the coach hero
   rules above, including the ones inside the width breakpoints.
   ========================================================================= */

/* ---- 1. the video hero --------------------------------------------------- */
.vhero {
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  height: clamp(600px, 56vw, 820px);
  overflow: hidden;
  isolation: isolate;
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
}
.vhero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) contrast(1.05);
  pointer-events: none;
}
.vhero__video::-webkit-media-controls,
.vhero__video::-webkit-media-controls-start-playback-button,
.vhero__video::-webkit-media-controls-panel,
.vhero__video::-webkit-media-controls-overlay-play-button {
  display: none !important;
  -webkit-appearance: none;
  appearance: none;
}
.vhero__fade {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(
      ellipse 60% 40% at 50% 50%,
      rgba(0, 0, 0, 0.5) 0%,
      rgba(0, 0, 0, 0) 100%
    ),
    linear-gradient(to bottom, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0) 35%),
    linear-gradient(to top, #000 0%, rgba(0, 0, 0, 0) 45%);
}
.vhero__inner {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 8px;
  padding: 40px var(--gutter) 0;
}
/* One line on desktop (~22.4em in Montserrat SemiBold caps): 3.5vw leaves
   air either side at any width, capped at 56px. */
body[data-view='coach'] .vhero__title {
  font-size: clamp(28px, 3.5vw, 56px);
  line-height: 1.1;
  white-space: nowrap;
}
.vhero__br {
  display: none;
}
body[data-view='coach'] .vhero__sub {
  white-space: nowrap;
  max-width: none;
  margin-bottom: 24px;
}
@media (max-width: 1099px) {
  body[data-view='coach'] .vhero__sub {
    white-space: normal;
    max-width: 520px;
  }
}
@media (max-width: 760px) {
  .vhero__br {
    display: inline;
  }
  body[data-view='coach'] .vhero__title {
    white-space: normal;
    font-size: clamp(30px, 8.4vw, 44px);
  }
}

/* ---- 2. the studio, now a section under the hero ------------------------- */
/* A panel with all four corners rounded and a gap above it. The nav sits on
   the video now, so the copy rises to the top. */
body[data-view='coach'] .hero {
  margin-top: 24px;
  border-radius: 64px;
}
body[data-view='coach'] .hero__inner {
  padding-top: 110px;
}
body[data-view='coach'] .hero__copy {
  gap: 24px;
  max-width: 560px;
}
/* Desktop: taller than the old hero (843) so the copy block and the card
   lane each get their own band. The room runs 221px above the stage, so
   up to 1064 it still fills the panel. */
@media (min-width: 1181px) {
  body[data-view='coach'] .hero {
    height: 960px;
    /* The room's own floor tone at its bottom edge, so the band the lift
       opens under the photograph reads as more floor, not a seam. */
    background: #212122;
  }
  /* Her head up level with the heading: the room, her cutout and her two
     cards all rise together, so she still sits on her own reflection. */
  body[data-view='coach'] .hero__stage--front,
  body[data-view='coach'] .hero__stage--cards,
  body[data-view='coach'] .hero__stage--person {
    bottom: 120px;
  }
  body[data-view='coach'] .hero__shot {
    -webkit-mask-image:
      linear-gradient(to right, #000 92%, transparent),
      linear-gradient(to top, transparent 0%, #000 12%);
    -webkit-mask-composite: source-in;
    mask-image:
      linear-gradient(to right, #000 92%, transparent),
      linear-gradient(to top, transparent 0%, #000 12%);
    mask-composite: intersect;
  }
}
@media (max-width: 760px) {
  body[data-view='coach'] .hero {
    border-radius: 40px;
  }
  body[data-view='coach'] .hero__inner {
    padding-top: 56px;
  }
  /* Stacked: the copy in flow at the top, the studio stage (pinned to the
     bottom, 843 tall before scaling) underneath it rather than behind it. */
  body[data-view='coach'] .hero {
    height: auto;
    padding-bottom: calc(843px * var(--stage-s));
  }
  body[data-view='coach'] .hero__scrim {
    display: none;
  }
}

/* =========================================================================
   2026-09-29 PASS — Figma "MARKETING PAGE" 801:3745
   Hero type and eyebrow, the studio's big number and two floating cards,
   the four-card convert rail, and "Everything Sonata offers". Kept at the
   end so it overrides the blocks above.
   ========================================================================= */

/* ---- the orange mono eyebrow (hero, studio) ------------------------------ */
.eyebrow {
  display: inline-flex;
  align-self: center;
  align-items: center;
  gap: 10px;
  padding: 6px 16px;
  border-radius: 8px;
  background: var(--glass-10);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  font-family: var(--font-mono);
  font-size: 16px;
  line-height: 1.25;
  color: #ff7f37;
  text-transform: uppercase;
  white-space: nowrap;
}
.eyebrow__dot {
  width: 6px;
  height: 6px;
  flex: none;
  border-radius: 50%;
  background: currentColor;
}

/* ---- hero ----------------------------------------------------------------
   The frame sets the headline in Otoiwo Grotesk ExtraBold Wide, which it
   uses as a FONTSPRING DEMO: not licensed for the web. Archivo at its
   widest (125) and 800 is the stand-in, from Google Fonts like the rest. */
.vhero {
  border-radius: 0 0 64px 64px;
  /* The film's greyscale filter puts it on its own layer, which Chrome does
     not clip to a border-radius; clip-path clips it. */
  clip-path: inset(0 round 0 0 64px 64px);
}
/* The film runs to the hero's edge so its rounded corners read (the frame's
   own screenshot, 2026-09-29): black only from the top, under the nav, and
   a soft pool behind the copy. No fade into the page below. */
.vhero__fade {
  background:
    radial-gradient(
      ellipse 55% 40% at 50% 52%,
      rgba(0, 0, 0, 0.45) 0%,
      rgba(0, 0, 0, 0) 100%
    ),
    linear-gradient(to bottom, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0) 19%);
}
.vhero__inner {
  gap: 0;
}
.vhero__eyebrow {
  margin-bottom: 24px;
}
body[data-view='coach'] .vhero__title {
  font-family: 'Archivo', var(--font-display);
  font-stretch: 125%;
  font-variation-settings: 'wdth' 125;
  font-weight: 800;
  font-size: clamp(30px, 5vw, 72px);
  line-height: 1.07;
  text-transform: uppercase;
  white-space: nowrap;
}
.vhero__br {
  display: inline;
}
body[data-view='coach'] .vhero__sub {
  margin: 16px 0 32px;
  font-size: 16px;
}
@media (max-width: 760px) {
  .vhero {
    border-radius: 0 0 40px 40px;
    clip-path: inset(0 round 0 0 40px 40px);
  }
  .vhero__eyebrow {
    font-size: 13px;
    margin-bottom: 20px;
  }
  body[data-view='coach'] .vhero__title {
    font-size: clamp(22px, 6vw, 44px);
  }
}

/* ---- studio: the number is the headline (879:8630) ----------------------- */
.bigstat {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
}
.bigstat[hidden] {
  display: none;
}
.bigstat .eyebrow {
  align-self: flex-start;
}
.bigstat__n {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 104px;
  line-height: 1.2;
}
.bigstat__l {
  max-width: 450px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 20px;
  line-height: 1.25;
}
body[data-view='coach'] .hero__copy {
  gap: 24px;
}
body[data-view='coach'] .hero__copy .btnrow {
  margin-top: 8px;
}
@media (max-width: 760px) {
  .bigstat__n {
    font-size: 72px;
  }
  .bigstat__l {
    font-size: 18px;
  }
}

/* ---- the glass cards, as the 09-29 frame draws them ----------------------
   The frame's cards are the app's at 0.75-0.8 scale, lighter glass, titles
   in capitals at 75% white and a translucent View button. `zoom` keeps the
   app's own numbers in the rules above. */
.hero__card,
.offers__card {
  background: rgba(48, 48, 48, 0.2);
  box-shadow:
    0 0 16px rgba(0, 0, 0, 0.08),
    inset 0 0 0 1px rgba(255, 255, 255, 0.16);
  zoom: 0.8;
}
.hero__card.hcard--program,
.offers__card.hcard--program {
  zoom: 0.75;
}
.hero__card .hcard__title,
.hero__card .hcard__date,
.offers__card .hcard__title,
.offers__card .hcard__date {
  color: rgba(243, 243, 243, 0.75);
}
.hero__card .hcard__thumb,
.offers__card .hcard__thumb {
  opacity: 0.75;
}
.hero__card .hcard__view,
.offers__card .hcard__view {
  background: rgba(243, 243, 243, 0.2);
  color: var(--white);
}
.hero__card .hcard__view img,
.offers__card .hcard__view img {
  filter: invert(1);
}
.hero__card .hcard__share,
.offers__card .hcard__share {
  opacity: 0.75;
}
.hero__card
  span.hcard__chip:not(.hcard__chip--orange):not(.hcard__chip--green):not(
    .hcard__chip--grey
  ),
.offers__card
  span.hcard__chip:not(.hcard__chip--orange):not(.hcard__chip--green):not(
    .hcard__chip--grey
  ) {
  background: rgba(0, 0, 0, 0.3);
}
a.hero__card:hover,
a.offers__card:hover {
  box-shadow:
    0 14px 34px rgba(0, 0, 0, 0.36),
    inset 0 0 0 1px rgba(255, 255, 255, 0.45);
}
.offers__card.hcard--trial {
  width: max-content;
  padding: 16px 24px 20px 16px;
}
.offers__card .hcard__session {
  font-size: 20px;
  text-transform: uppercase;
  color: rgba(243, 243, 243, 0.7);
}
.offers__card .hcard__by {
  font-size: 13px;
  color: #bdbdbd;
}
.offers__card.hcard--coach {
  width: 322px;
  padding: 16px 16px 20px;
  border-radius: 16px;
}
.offers__card .hcard__coachtitle {
  text-transform: uppercase;
  color: rgba(243, 243, 243, 0.7);
}
.offers__card .hcard__coachsub {
  white-space: normal;
  color: rgba(243, 243, 243, 0.7);
}
/* The subscribe pitch, short form: title, one line, the button. */
.hcard--pitch {
  width: 340px;
  padding: 16px 16px 20px;
  border-radius: 16px;
  flex-direction: column;
  gap: 8px;
}
.hcard__pitchtitle {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 18px;
  line-height: 1.22;
  text-transform: uppercase;
  color: rgba(243, 243, 243, 0.7);
}
.hcard__pitchbody {
  font-size: 14px;
  line-height: 1.21;
  color: rgba(243, 243, 243, 0.7);
}
.hcard span.hcard__pitchcta {
  display: block;
  margin-top: 4px;
  padding: 16px;
  border-radius: 40px;
  background: rgba(243, 243, 243, 0.2);
  font-size: 16px;
  font-weight: 500;
  line-height: 1.21;
  text-align: center;
  color: #f3f3f3;
}

/* ---- studio: two cards on the stage, between the room and her ------------
   Stage pixels: the pitch half behind her hair, the program behind her
   back, as the frame places them relative to her. */
.hero__stage--cards {
  z-index: 2;
}
.hero__card {
  position: absolute;
  pointer-events: auto;
}
.hero__card--pitch {
  left: calc(730px / 0.8);
  top: calc(180px / 0.8);
}
.hero__card--program {
  left: calc(1140px / 0.75);
  top: calc(284px / 0.75);
}
@media (max-width: 760px) {
  /* A phone draws her at 0.6 of desktop, which would put the cards' text at
     9px. The next section shows all five full size, so here they go. */
  .hero__stage--cards {
    display: none;
  }
}

/* ---- §1 convert: four 430 x 678 cards (874:7895) ------------------------- */
#s-convert {
  padding-top: 160px;
}
#s-convert .sec__h {
  max-width: none;
}
#s-convert .rail {
  gap: 16px;
}
.rcard {
  width: 430px;
  padding: 24px;
  border-radius: 32px;
  background: #0f0f0f;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.28);
}
.rcard__step {
  background: var(--glass-10);
  color: #ff7f37;
  padding: 6px 16px;
  font-size: 14px;
  line-height: 1.3;
}
.rcard__body {
  margin-top: 24px;
}
#s-convert .dev {
  --dev-w: 240px;
}
.rcard__cap {
  margin-top: 24px;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 18px;
  line-height: 1.2;
}
@media (max-width: 760px) {
  #s-convert {
    padding-top: 96px;
  }
  .rcard {
    padding: 20px;
  }
  .rcard__cap {
    font-size: 16px;
  }
}

/* ---- 3b. EVERYTHING SONATA OFFERS (869:5867) -----------------------------
   The frame's 788 x 620 stage, zoomed as one by --offers-s (main.js: the
   cards reach 121px left of it and 79px right, so it fits a 988px span).
   Three layers per card: the slot (placement + the scroll drift, --py),
   the card's own bob (`translate`), and the hover lift (`scale`), so the
   three never fight over one transform. */
.offers__head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  text-align: center;
  margin-bottom: 96px;
}
.offers__head .sec__h {
  max-width: none;
}
.offers__head .prose {
  font-size: 16px;
  line-height: 1.25;
}
.offers__stage {
  position: relative;
  width: 788px;
  height: 620px;
  margin: 0 auto;
  zoom: var(--offers-s, 1);
}
.offers__cards {
  position: absolute;
  inset: 0;
  z-index: 1;
}
.offers__slot {
  position: absolute;
  left: var(--x);
  top: var(--y);
  transform: translate3d(0, var(--py, 0px), 0);
  will-change: transform;
}
.offers__card {
  display: flex;
  animation: offers-bob 6.5s ease-in-out var(--d, 0s) infinite;
  transition:
    scale 0.3s ease,
    box-shadow 0.3s ease;
}
.offers__slot:hover .offers__card {
  scale: 1.04;
  animation-play-state: paused;
}
@keyframes offers-bob {
  0%,
  100% {
    translate: 0 0;
  }
  50% {
    translate: 0 -8px;
  }
}
.offers__phone {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  transform: translate3d(0, var(--rise, 0px), 0);
  will-change: transform;
}
.offers__phone img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.offers__phone::after {
  content: '';
  position: absolute;
  left: 73px;
  top: 323px;
  width: 683px;
  height: 297px;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0), #000);
}
/* Phone: the hand on top, the five cards as a swipe row under it. */
@media (max-width: 760px) {
  .offers__head {
    margin-bottom: 40px;
  }
  .offers__stage {
    zoom: 1;
    width: auto;
    height: auto;
    display: flex;
    flex-direction: column;
    gap: 24px;
  }
  .offers__phone {
    position: relative;
    inset: auto;
    order: -1;
    width: 100%;
    aspect-ratio: 788 / 620;
    transform: none;
  }
  .offers__phone::after {
    left: 9%;
    top: 52%;
    width: 87%;
    height: 48%;
  }
  .offers__cards {
    position: static;
    display: flex;
    align-items: flex-start;
    gap: 12px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    margin-inline: calc(var(--gutter) * -1);
    padding: 4px var(--gutter) 12px;
    scroll-padding-inline: var(--gutter);
  }
  .offers__cards::-webkit-scrollbar {
    display: none;
  }
  .offers__slot {
    position: static;
    flex: none;
    transform: none;
    scroll-snap-align: start;
  }
  .offers__card {
    animation: none;
  }
}
@media (prefers-reduced-motion: reduce) {
  .offers__card {
    animation: none;
  }
  .offers__slot,
  .offers__phone {
    transform: none;
  }
}
