/* ============================================================
   Point to Point — styles
   Scale system: 1rem = 10px of the 1920px Figma design.
   html font-size = 100vw / 192, so the desktop layout scales
   proportionally at any desktop width ("scale to fit").
   ≤1024px switches to a stacked tablet/mobile layout.
   ============================================================ */

:root {
  --green: #66E27D;
  --title: #1a1a1a;
  --body: #191919;
  --gray-text: #717171;
  --tag-gray: #E7E8E7;
  --muted: #999;
  --line-light: #ECECEC;
}

* { box-sizing: border-box; }

html {
  font-size: calc(100vw / 192);
  overflow-x: clip; /* clip, not hidden — hidden breaks position:sticky */
}

body {
  margin: 0;
  font-family: 'Satoshi', ui-sans-serif, system-ui, sans-serif;
  font-weight: 500;
  background: #fcfcfc;
  color: var(--body);
  overflow-x: clip;
}

h1, h2, h3, p, ul, figure { margin: 0; }
ul { padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
img { display: block; }

/* ============ Buttons ============ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: 1.05rem;
  width: 15.739rem;
  height: 3.677rem;
  padding-right: 0.72rem;
  font-size: 1.775rem;
  font-weight: 400;
}

.btn__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.066rem;
  height: 2.066rem;
}

.btn__icon svg { width: 1.2rem; height: auto; }

.btn--light { background: #fcfcfc; color: var(--body); }
.btn--light .btn__icon { background: #000; color: #fcfcfc; }

.btn--dark { background: #000; color: #fcfcfc; }
.btn--dark .btn__icon { background: #fcfcfc; color: var(--body); }

.btn--ghost {
  width: 9.232rem;
  justify-content: center;
  padding-right: 0;
  border: 0.75px solid #fcfcfc;
  background: transparent;
  color: #fcfcfc;
}

.square-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 4.132rem;
  height: 4.132rem;
  padding: 0;
  border: none;
  background: #000;
  color: #fcfcfc;
  cursor: pointer;
}
.square-btn svg { width: 2.4rem; height: auto; }
.square-btn--small { width: 2.066rem; height: 2.066rem; }
.square-btn--small svg { width: 1.2rem; }

/* ============ Feature list (How it works / Showcase) ============ */

.feature-list { width: 56.026rem; }

.feature-list__item {
  display: flex;
  align-items: center;
  height: 7.09rem;
  border-top: 1px solid #000;
  font-size: 2rem;
  line-height: 3.4rem;
}
.feature-list__item:last-child { border-bottom: 1px solid #000; }
.feature-list__item.is-active { font-weight: 700; padding-left: 2.8rem; }

.feature-list--light { color: #fcfcfc; }
.feature-list--light .feature-list__item {
  border-color: #fcfcfc;
  font-weight: 500;
}
.feature-list--light .feature-list__item.is-active {
  font-weight: 400;
  padding-left: 0;
}

/* ============ Header / Nav ============ */

/* Fixed header that inverts against the section behind it: JS reads the
   data-nav of the section under the header and toggles .theme-light. */
.site-header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 20;
  display: flex;
  align-items: center;
  padding: 3.25rem 7.35rem 0;
  --ink: #fcfcfc;
  --paper: #000;
  color: var(--ink);
}
.site-header.theme-light {
  --ink: #191919;
  --paper: #fcfcfc;
}

/* Gradient layer-blur behind the nav: strong at the top, weak at the
   bottom. Three stacked backdrop-filter bands approximate a progressive
   blur. Region ends 15px above the bottom of the Book-a-demo button
   (button bottom = 7.195rem, so height = 5.7rem). */
.site-header__blur {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 5.7rem;
  z-index: -1;
  pointer-events: none;
}
/* Six bands whose masks crossfade linearly (each ramp overlaps the next,
   summing to full coverage) so adjacent blur strengths blend seamlessly. */
.site-header__blur span {
  position: absolute;
  inset: 0;
}
.site-header__blur span:nth-child(1) {
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 16.7%, transparent 33.3%);
  mask-image: linear-gradient(180deg, #000 0%, #000 16.7%, transparent 33.3%);
}
.site-header__blur span:nth-child(2) {
  -webkit-backdrop-filter: blur(8.5px);
  backdrop-filter: blur(8.5px);
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 16.7%, #000 33.3%, transparent 50%);
  mask-image: linear-gradient(180deg, transparent 0%, #000 16.7%, #000 33.3%, transparent 50%);
}
.site-header__blur span:nth-child(3) {
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  -webkit-mask-image: linear-gradient(180deg, transparent 16.7%, #000 33.3%, #000 50%, transparent 66.7%);
  mask-image: linear-gradient(180deg, transparent 16.7%, #000 33.3%, #000 50%, transparent 66.7%);
}
.site-header__blur span:nth-child(4) {
  -webkit-backdrop-filter: blur(4.2px);
  backdrop-filter: blur(4.2px);
  -webkit-mask-image: linear-gradient(180deg, transparent 33.3%, #000 50%, #000 66.7%, transparent 83.3%);
  mask-image: linear-gradient(180deg, transparent 33.3%, #000 50%, #000 66.7%, transparent 83.3%);
}
.site-header__blur span:nth-child(5) {
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  -webkit-mask-image: linear-gradient(180deg, transparent 50%, #000 66.7%, #000 83.3%, transparent 100%);
  mask-image: linear-gradient(180deg, transparent 50%, #000 66.7%, #000 83.3%, transparent 100%);
}
.site-header__blur span:nth-child(6) {
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  /* tail fades out so the region ends without a hard cut */
  -webkit-mask-image: linear-gradient(180deg, transparent 66.7%, #000 83.3%, #000 88%, transparent 100%);
  mask-image: linear-gradient(180deg, transparent 66.7%, #000 83.3%, #000 88%, transparent 100%);
}

.logo {
  display: flex;
  align-items: center;
  gap: 1.05rem;
  color: inherit;
}
.logo__mark { width: 2.601rem; height: 4.213rem; }
.logo__word { font-size: 3rem; font-weight: 500; line-height: 1; }

.site-nav {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  top: 4.6rem;
  display: flex;
  gap: 5rem;
  font-size: 1.75rem;
  font-weight: 400;
  color: inherit;
}

.site-header .btn--ghost {
  border-color: currentColor;
  color: inherit;
}
.site-header .btn--ghost:hover {
  background: var(--ink);
  color: var(--paper);
}
.site-header .btn--light {
  background: var(--ink);
  color: var(--paper);
  transition: background 0.35s ease, color 0.35s ease;
}
.site-header .btn--light .btn__icon {
  background: var(--paper);
  color: var(--ink);
  transition: background 0.35s ease, color 0.35s ease;
}
.site-header .nav-toggle span { background: var(--ink); }

.site-header__ctas {
  display: flex;
  align-items: center;
  gap: 1.16rem;
  margin-left: auto;
}

.nav-toggle {
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.9rem;
  width: 4.4rem;
  height: 4.4rem;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  z-index: 60;
}
.nav-toggle span {
  width: 3.2rem;
  height: 2px;
  background: #fcfcfc;
  transition: transform 0.3s ease, opacity 0.3s ease;
}

/* ============ Hero ============ */

/* hero pins for one viewport of scroll (wrapper is 200svh, page-body
   overlaps via negative margin), then releases so the fixed footer can
   reveal at the page end without the hero showing through */
.hero-wrap { height: 200svh; }

.hero {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
  z-index: 2;
}

.hero__bg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 115%; /* extra height = headroom for the 15% scroll parallax */
  object-fit: cover;
  object-position: 50% 19%;
  will-change: transform;
}

.hero__title {
  position: absolute;
  left: 7.31rem;
  bottom: 5.4rem;
  color: #fcfcfc;
  font-size: 6rem;
  font-weight: 300;
  line-height: 1.05;
}
.hero__title em {
  font-weight: 900;
  font-style: italic;
}

/* Content that slides over the pinned hero */
.page-body {
  position: relative;
  z-index: 3;
  background: #fcfcfc;
  margin-top: -100svh;
  margin-bottom: 85rem; /* scroll room that reveals the fixed footer */
}

/* ============ Intro ============ */

.intro {
  position: relative;
  /* the copy sits flush with this bottom edge, so while it is offset
     downward it overflows the section; z-index lifts it above .how,
     which is also positioned and would otherwise paint over it */
  z-index: 1;
  height: 60.5rem; /* ends flush with the paragraph bottom (copy top 40.09 + ~20.4) */
  background: #fcfcfc;
}

/* Hands the screen over to "For businesses, players…": the intro content fades
   as that title rises toward the middle of the screen. JS scrubs --intro-fade
   per frame (initIntroFade). The *content* fades, never the section itself —
   .intro's background is what hides the pinned hero sitting behind it. */
.intro__swap,
.intro__label,
.intro__copy { opacity: var(--intro-fade, 1); }

/* Scroll-scrubbed phrase swap. Both phrases share the stationary "the":
   phrase A rests on the line, gets nudged up + grayed as phrase B arrives
   from below. JS drives --p per frame; parts sit around the "the" gap. */
.intro__swap {
  color: var(--title);
  position: absolute;
  inset: 0;
  font-size: 6rem;
  font-weight: 300;
  line-height: 1.35;
  white-space: nowrap;
  /* gap start = where the left parts end; JS sets it to
     50% + width("You focus on") so phrase A starts at screen centre */
  --gap-start: 135.456rem;
}

.intro__phrase {
  position: absolute;
  left: 0;
  right: 0;
  /* em, not rem: these offsets were measured against the 6rem phrase, so in em
     the whole composition rescales from .intro__swap's font-size alone —
     which is what lets the tablet tier keep the swap instead of stacking it */
  top: 3.235em;
  will-change: transform;
}
.intro__phrase--b { opacity: 0; }

.intro__part { position: absolute; }
.intro__part--left {
  right: calc(100% - var(--gap-start)); /* right-aligned, ending at the gap */
}
.intro__part--right { left: calc(var(--gap-start) + 1.9965em); }

.intro__the {
  position: absolute;
  left: var(--gap-start);
  top: 3.235em;
  width: 1.9965em;
  text-align: center;
  /* inherits its size from .intro__swap so the em offsets above stay true */
  font-weight: 300;
  line-height: 1.35;
}

/* inline "the" only exists in the stacked mobile layout */
.intro__the-inline { display: none; }

.intro__label {
  position: absolute;
  left: 5rem;
  top: 40.09rem;
  font-size: 2.5rem;
  line-height: 3.4rem;
  font-weight: 400;
  --ro: 0.35;
  opacity: 0.35;
}

.intro__copy {
  position: absolute;
  left: 96rem; /* centre of the screen */
  top: 40.09rem;
  width: 91rem; /* keeps the 5rem gap to the right edge */
  font-size: 2.5rem;
  line-height: 3.4rem;
  font-weight: 400;
}

/* ============ Product frames (full-bleed editorial) ============ */

/* One capability per screen: eyebrow, one line, one sentence — on black, with
   the state card riding them on the right. Nothing is pinned; they stack and
   scroll, and the App Store block closes the section on the same black. */

.frames {
  position: relative;
  background: #0d0d0d; /* shows only if an image is slow to paint */
}

/* The card rides the whole section, above the photographs, changing state as
   each frame passes (initArtifact).

   The layer is absolutely positioned over the section so it adds no height,
   and the sticky box lives inside it. That nesting is what bounds the card:
   sticky is constrained by its containing block, so the card releases exactly
   one viewport before the section ends and rides the last frame out. Sticking
   a zero-height wrapper directly on .frames instead lets the card outlive the
   photographs and hang over the App Store card below. */
.frames__card {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}
.frames__card-in {
  position: sticky;
  top: 0;
  height: 100svh;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 0 19.8rem; /* lines its right edge up with the type's left gutter */
}
/* an accent on a photograph, not the main event — smaller than it is on its
   own page, and lifted off the image with a deeper shadow */
.frames__card .art {
  max-width: 44rem;
  box-shadow: 0 5rem 10rem rgba(0, 0, 0, 0.45);
}

.frame {
  position: relative;
  height: 100svh;
  overflow: hidden;
  display: flex;
  align-items: flex-end;
}
/* without photographs there is no edge between them at all — this is what
   makes three frames read as three rather than one long black stretch */
.frame + .frame { border-top: 1px solid rgba(252, 252, 252, 0.12); }


.frame__body {
  position: relative;
  z-index: 1;
  padding: 0 19.8rem 12rem; /* the page's structural gutter */
}

.frame__eyebrow {
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--green);
  margin-bottom: 2.6rem;
}

/* 6rem/300 is the hero's scale — the site's established size for type set
   over a photograph. Section titles stay at 8.8rem, on flat backgrounds. */
.frame__title {
  font-size: 6rem;
  font-weight: 300;
  line-height: 1.05;
  color: #fcfcfc;
  margin-bottom: 2.8rem;
}

/* rests at 0.75 via --ro on the element — [data-reveal] would otherwise
   force it to full opacity when it lands */
.frame__copy {
  font-size: 2rem;
  line-height: 1.5;
  font-weight: 400;
  color: #fcfcfc;
  max-width: 52rem;
}

/* ============ The card ============ */
/* One object with three states, riding over the product frames. The point of
   difference from the pinned-phone tour this replaced: the shell, the heading
   row, the meta row and the chip are never swapped out — they persist and
   their contents change. Only the middle slot swaps, and it opens and closes
   on a grid-row transition, so the card's own height animates.

   Selectors are deliberately unscoped: this began life beside scrolling text
   on a comparison page, and moving it onto the photographs needed no CSS
   change at all. Keep it that way. */


.art {
  width: 100%;
  max-width: 52rem;
  background: #fff;
  border-radius: 1.6rem;
  box-shadow: 0 4.5rem 9rem rgba(0, 0, 0, 0.1);
  padding: 4rem;
}

.art__head {
  display: flex;
  align-items: center;
  gap: 1.6rem;
}
.art__mark {
  width: 4.4rem;
  height: 4.4rem;
  border-radius: 1.2rem;
  background: var(--title);
  flex: none;
}
.art__heading { flex: 1; }

/* Labels stack in one grid cell, so a row never changes height as its text
   swaps — the row stays put and only the wording crossfades. */
.art__heading,
.art__meta { display: grid; }
.art__heading > .art__label,
.art__meta > .art__label { grid-area: 1 / 1; }
.art__label {
  opacity: 0;
  transition: opacity 0.45s ease;
}
.art__label.is-on { opacity: 1; }

.art__heading .art__label {
  font-size: 2.2rem;
  font-weight: 600;
  color: var(--title);
}
.art__meta { margin-top: 2.4rem; }
.art__meta .art__label {
  font-size: 1.7rem;
  color: var(--gray-text);
}

/* one element the whole way through — the colour change is the clearest
   signal that this is the same object in a new state */
.art__chip {
  flex: none;
  padding: 0.9rem 1.6rem;
  border-radius: 3rem;
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  white-space: nowrap;
  background: var(--green);
  color: #10331a;
  transition: background 0.6s ease, color 0.6s ease;
}
.art__chip.is-paid { background: #A8502C; color: #fff; }
.art__chip.is-member { background: #8B7FD6; color: #fff; }

.art__rule {
  height: 1px;
  background: #ececec;
  margin: 2.8rem 0;
}

/* 0fr -> 1fr is the height animation: the card grows and shrinks around the
   slot instead of the slots crossfading inside a fixed box */
.art__slot {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows 0.7s cubic-bezier(0.16, 1, 0.3, 1),
              opacity 0.35s ease;
}
.art__slot-in {
  overflow: hidden;
  min-height: 0;
}
.art[data-state="0"] .art__slot[data-for="0"],
.art[data-state="1"] .art__slot[data-for="1"],
.art[data-state="2"] .art__slot[data-for="2"] {
  grid-template-rows: 1fr;
  opacity: 1;
  /* contents fade in after the card has opened for them */
  transition: grid-template-rows 0.7s cubic-bezier(0.16, 1, 0.3, 1),
              opacity 0.5s ease 0.18s;
}

/* slot 0 — the week */
.art__week { display: flex; gap: 0.8rem; }
.art__week span {
  flex: 1;
  height: 4.4rem;
  border-radius: 0.8rem;
  background: #f3f3f3;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.4rem;
  font-weight: 600;
  color: var(--gray-text);
}
.art__week span.is-on { background: var(--green); color: #10331a; }
.art__note {
  margin-top: 1.8rem;
  font-size: 1.6rem;
  color: var(--gray-text);
}

/* slot 1 — the money */
.art__amount {
  font-size: 4.6rem;
  font-weight: 300;
  color: var(--title);
  line-height: 1;
}
.art__lines {
  margin-top: 2.4rem;
  display: flex;
  flex-direction: column;
  gap: 1.2rem;
}
.art__lines li {
  display: flex;
  justify-content: space-between;
  font-size: 1.6rem;
  color: var(--gray-text);
}
.art__lines li.is-total {
  color: var(--title);
  font-weight: 600;
  padding-top: 1.2rem;
  border-top: 1px solid #ececec;
}

/* slot 2 — the player */
.art__dots {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 0.6rem;
}
.art__dots i {
  aspect-ratio: 1;
  border-radius: 50%;
  background: #ececec;
}
.art__dots i.is-on { background: var(--green); }
.art__figs {
  margin-top: 2.6rem;
  display: flex;
  gap: 4rem;
}
.art__figs span {
  display: flex;
  flex-direction: column;
  font-size: 1.4rem;
  color: var(--gray-text);
}
.art__figs strong {
  font-size: 3rem;
  font-weight: 300;
  color: var(--title);
  line-height: 1.3;
}

/* ============ How it works ============ */

.how {
  position: relative;
  background: #fcfcfc;
  /* 14rem is the house section padding. Note the gap you SEE below the
     feature list is this plus the picker's own 5rem offset, since the picker
     floats above the foot of the pin rather than sitting on it. Retune this
     value, never the picker — that 5rem is a composition offset the scroll
     hold and the Product nav landing both measure from. */
  padding: 20rem 19.8rem 14rem;
}

/* One viewport tall, so the title/graphic/list composition lands in place as
   it passes — but NOT sticky. Nothing is held; the page scrolls straight
   through. The graphic still opens the moment the frame reaches the top. */
.how__pin {
  position: relative;
  height: 100vh;
  margin: 0 -19.8rem;
  padding: 0 19.8rem;
}


.how__title {
  position: absolute;
  left: 19.8rem;
  right: 19.8rem;
  top: 10rem; /* 100px from the top of the screen while pinned */
  color: var(--title);
  text-align: center;
  font-size: 8.8rem;
  font-weight: 300;
  line-height: 1.05;
  margin: 0;
  /* hands off to the list: fades as the list arrives, returns on the way back */
  transition: opacity 0.55s ease 0.1s;
}
.how.is-handoff .how__title { opacity: 0; }

/* --- horizontal feature list: the original text-list treatment (hairline
   dividers, black fill sweeping up on hover, bold + nudge when active) laid
   out in a centred row instead of a column. --- */
.how__picker {
  position: absolute;
  left: 19.8rem;
  right: 19.8rem;
  bottom: 5rem; /* 50px from the bottom of the screen */
}

.how__list {
  display: flex;
  justify-content: center;
  width: max-content;
  margin: 0 auto;
}

/* items arrive one by one, left to right (opacity carries their divider too).
   Durations here are mirrored by HOW_STAGGER_MS in main.js — change both. */
.how__list li {
  opacity: 0;
  transform: translateY(2rem);
  transition: opacity 0.5s ease, transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.how__list.is-in li { opacity: 1; transform: none; }
.how__list.is-in li:nth-child(1) { transition-delay: 0.00s; }
.how__list.is-in li:nth-child(2) { transition-delay: 0.06s; }
.how__list.is-in li:nth-child(3) { transition-delay: 0.12s; }
.how__list.is-in li:nth-child(4) { transition-delay: 0.18s; }

.how__item {
  position: relative;
  z-index: 0;
  display: block;
  padding: 1.4rem 2.2rem;
  border: none;
  background: none;
  text-align: center;
  cursor: pointer;
  color: var(--title);
  overflow: hidden;
  font-family: inherit;
  transition: color 0.5s ease;
}
/* fill rises from the bottom edge, and exits upward on leave (mirrored by
   HOW_SWIPE_MS in main.js) */
.how__item::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--title);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.how__item:hover,
.how__item.is-active { color: #fcfcfc; }
.how__item:hover::before,
.how__item.is-active::before {
  transform: scaleY(1);
  transform-origin: bottom;
}

.how__name {
  display: block;
  white-space: nowrap;
  font-size: 1.4rem;
  font-weight: 400;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1.2;
  transition: font-weight 0.3s ease;
}
/* An invisible copy of the label at the bold weight, holding the width open.
   Without it, going bold on hover/active widens the item and shoves its
   neighbours sideways. Zero height, so it costs nothing vertically. */
.how__name::after {
  content: attr(data-text);
  display: block;
  height: 0;
  overflow: hidden;
  visibility: hidden;
  font-weight: 700;
}
.how__item.is-active .how__name,
.how__item:hover .how__name { font-weight: 700; }

/* --- graphic, centred under the list ---
   Bottom-anchored: the graphic sits on a fixed baseline 28rem above the foot
   of the frame (where the panels averaged out when they were centred), so the
   1.5x sizing grows upward into the space the faded title leaves behind and
   sideways from the centre — the bottom edge never moves, and the panels no
   longer jump vertically as you switch between them. */
.how__stage {
  position: absolute;
  left: 19.8rem;
  right: 19.8rem;
  top: 4rem;     /* headroom only — the title is gone by the time this opens */
  bottom: 28rem; /* the baseline the graphic sits on */
  overflow: visible;
  transition: transform 0.3s ease-out;
  will-change: transform;
}

.how__panel {
  position: absolute;
  inset: 0;
  margin: 0;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 0;
  opacity: 0;
  transform: scale(0.98);
  /* mirrored by HOW_REVEAL_MS in main.js */
  transition: opacity 0.4s ease, transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);
  pointer-events: none;
}
.how__panel.is-active {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}

/* ---- panel 0: schedule ----
   All four graphics are drawn at 1.5x the original dimensions (real sizes, not
   a transform, so the type and hairlines stay crisp). */
.sched {
  width: 100%;
  max-width: 69rem;
  background: #fff;
  border-radius: 1.5rem;
  box-shadow: 0 4.5rem 9rem rgba(0, 0, 0, 0.1);
  padding: 3.6rem;
}
.sched__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 3rem;
}
.sched__title { font-size: 2.55rem; font-weight: 700; }
.sched__live {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  font-size: 1.95rem;
  font-weight: 600;
  color: var(--gray-text);
}
.sched__live i {
  width: 1.2rem; height: 1.2rem; border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 0 0 rgba(102, 226, 125, 0.6);
  animation: sched-pulse 1.8s ease-out infinite;
}
@keyframes sched-pulse {
  0% { box-shadow: 0 0 0 0 rgba(102,226,125,0.6); }
  70%, 100% { box-shadow: 0 0 0 1.35rem rgba(102,226,125,0); }
}
.sched__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 6.3rem;
  gap: 0.9rem;
}
.sched__col {
  font-size: 1.725rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--gray-text);
  text-transform: uppercase;
  align-self: center;
}
.sched__slot {
  grid-column: var(--c);
  grid-row: calc(var(--r) + 1) / span var(--span);
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 0.75rem;
  background: var(--green);
  color: #10331a;
  font-size: 1.95rem;
  font-weight: 600;
  text-align: center;
  padding: 0.45rem;
  animation: slot-in 0.5s cubic-bezier(0.16, 1, 0.3, 1) backwards;
}
.sched__slot:nth-of-type(2) { animation-delay: 0.06s; background: #cdEBd4; color: #204d2e; }
.sched__slot:nth-of-type(3) { animation-delay: 0.12s; }
.sched__slot:nth-of-type(4) { animation-delay: 0.18s; background: #A8502C; color: #fff; }
.sched__slot:nth-of-type(5) { animation-delay: 0.24s; background: #cdEBd4; color: #204d2e; }
.sched__slot:nth-of-type(6) { animation-delay: 0.30s; }
@keyframes slot-in { from { opacity: 0; transform: translateY(1.2rem); } }
.sched__slot--ghost {
  background: transparent;
  border: 1.5px dashed #c9c9c9;
  color: var(--gray-text);
  font-weight: 500;
}

/* ---- panel 1: tracked booking ---- */
.track__card {
  width: 100%;
  max-width: 57rem;
  background: #fff;
  border-radius: 1.5rem;
  box-shadow: 0 4.5rem 9rem rgba(0, 0, 0, 0.1);
  padding: 4.5rem;
}
.track__eyebrow { font-size: 1.8rem; font-weight: 700; letter-spacing: 0.12em; color: var(--gray-text); }
.track__name { font-size: 3.9rem; font-weight: 600; margin-top: 1.2rem; }
.track__time { font-size: 2.4rem; color: var(--gray-text); margin-top: 0.6rem; margin-bottom: 3.6rem; }
.track__steps { display: flex; flex-direction: column; gap: 2.1rem; }
.track__steps li {
  display: flex;
  align-items: center;
  gap: 1.8rem;
  font-size: 2.55rem;
  font-weight: 500;
}
.track__steps li::before {
  content: "";
  width: 3.3rem; height: 3.3rem;
  border-radius: 50%;
  border: 3px solid #d8d8d8;
  flex: none;
}
.track__steps li.is-done::before {
  background: var(--green) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 10' fill='none'%3E%3Cpath d='M1 5l3.5 3.5L11 1' stroke='%2310331a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 1.65rem no-repeat;
  border-color: var(--green);
}
.track__steps li.is-now { color: var(--gray-text); }
.track__steps li.is-now::before { border-style: dashed; animation: sched-pulse 1.8s ease-out infinite; }

/* ---- panel 2: scalable grid ---- */
.scale { position: relative; width: 100%; max-width: 60rem; }
.scale__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2.1rem;
}
.scale__grid span {
  aspect-ratio: 1;
  border-radius: 1.2rem;
  background: #fff;
  box-shadow: 0 2.1rem 4.5rem rgba(0, 0, 0, 0.07);
  border-top: 4.5px solid var(--green);
  animation: scale-pop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) backwards;
}
.scale__grid span:nth-child(n+4) { border-top-color: #A8502C; }
.scale__grid span:nth-child(n+7) { opacity: 0.45; }
.how__panel[data-panel="2"].is-active .scale__grid span:nth-child(1){animation-delay:.00s}
.how__panel[data-panel="2"].is-active .scale__grid span:nth-child(2){animation-delay:.04s}
.how__panel[data-panel="2"].is-active .scale__grid span:nth-child(3){animation-delay:.08s}
.how__panel[data-panel="2"].is-active .scale__grid span:nth-child(4){animation-delay:.12s}
.how__panel[data-panel="2"].is-active .scale__grid span:nth-child(5){animation-delay:.16s}
.how__panel[data-panel="2"].is-active .scale__grid span:nth-child(6){animation-delay:.20s}
.how__panel[data-panel="2"].is-active .scale__grid span:nth-child(7){animation-delay:.24s}
.how__panel[data-panel="2"].is-active .scale__grid span:nth-child(8){animation-delay:.28s}
.how__panel[data-panel="2"].is-active .scale__grid span:nth-child(9){animation-delay:.32s}
@keyframes scale-pop { from { opacity: 0; transform: scale(0.4); } }
.scale__badge {
  position: absolute;
  right: -2.25rem;
  bottom: -2.25rem;
  background: #101010;
  color: #fff;
  border-radius: 1.2rem;
  padding: 2.1rem 2.7rem;
  box-shadow: 0 3rem 6rem rgba(0, 0, 0, 0.25);
}
.scale__badge strong { display: block; font-size: 4.2rem; font-weight: 900; color: var(--green); }
.scale__badge span { font-size: 1.95rem; color: #c9c9c9; }

/* ---- panel 3: support chat ---- */
.support {
  width: 100%;
  max-width: 60rem;
  display: flex;
  flex-direction: column;
  gap: 2.1rem;
}
.support__msg {
  max-width: 80%;
  padding: 2.4rem 3rem;
  border-radius: 2.4rem;
  font-size: 2.55rem;
  line-height: 1.35;
  box-shadow: 0 2.1rem 4.5rem rgba(0, 0, 0, 0.07);
}
.support__msg--in { align-self: flex-start; background: #fff; border-bottom-left-radius: 0.6rem; }
.support__msg--out {
  align-self: flex-end;
  background: var(--green);
  color: #10331a;
  border-bottom-right-radius: 0.6rem;
}
.support__typing {
  align-self: flex-start;
  display: flex;
  gap: 0.75rem;
  background: #fff;
  padding: 2.4rem 2.7rem;
  border-radius: 2.4rem;
  border-bottom-left-radius: 0.6rem;
  box-shadow: 0 2.1rem 4.5rem rgba(0, 0, 0, 0.07);
}
.support__typing i {
  width: 1.35rem; height: 1.35rem;
  border-radius: 50%;
  background: #c4c4c4;
  animation: type-bounce 1.2s infinite;
}
.support__typing i:nth-child(2) { animation-delay: 0.15s; }
.support__typing i:nth-child(3) { animation-delay: 0.3s; }
@keyframes type-bounce { 0%, 60%, 100% { transform: translateY(0); opacity: 0.5; } 30% { transform: translateY(-0.75rem); opacity: 1; } }
.support__foot {
  display: flex;
  align-items: center;
  gap: 1.2rem;
  margin-top: 1.5rem;
  font-size: 2.1rem;
  font-weight: 500;
  color: var(--gray-text);
}
.support__dot { width: 1.35rem; height: 1.35rem; border-radius: 50%; background: var(--green); }

/* ============ App store CTA ============ */

/* Closes the product section, on the frames' own black — no background, no
   radius: it is the foot of that section rather than a surface of its own. */
.appcta {
  position: relative;
  color: #fcfcfc;
  padding: 12rem 5rem 14rem;
}

.appcta__foot {
  /* the wide-band box, so this lines up with the platform list above it
     rather than sitting on the 19.8rem section gutter */
  max-width: 172rem;
  margin: 0 auto;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 4rem;
  flex-wrap: wrap;
  padding-top: 5rem;
  border-top: 1px solid rgba(252, 252, 252, 0.16);
}
.appcta__title {
  font-size: 4.5rem;
  font-weight: 300; /* Satoshi Light, as the section titles are */
  line-height: 1.05;
  /* the -0.01em tracking went with the 500 weight; Light wants the air back */
  margin-bottom: 1.4rem;
}
.appcta__copy {
  font-size: 2rem;
  font-weight: 400;
  line-height: 1.5;
  color: #c9c9c9;
  max-width: 48rem;
}

.appcta__buttons { display: flex; gap: 1.6rem; }

/* light on the black, matching the header's Book a demo */
.store-btn {
  display: inline-flex;
  align-items: center;
  gap: 1.4rem;
  padding: 1.4rem 2.6rem;
  border-radius: 1.2rem;
  background: #fcfcfc;
  color: #0d0d0d;
  transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.25s ease;
}
.store-btn:hover { transform: translateY(-0.3rem); opacity: 0.92; }
.store-btn__glyph { width: 2.8rem; height: auto; flex: none; }
.store-btn__text { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.1; }
.store-btn__text small { font-size: 1.2rem; font-weight: 400; }
.store-btn__text strong { font-size: 2rem; font-weight: 700; }

/* ============ Our approach ============ */

/* Pulled up the width of its own radius so the corners are cut against the
   last photograph rather than the page background. This is the sheet that
   opens the white surface; .appcta continues it and carries no radius. */
.approach {
  position: relative;
  /* above .frames__card (2) — .frames creates no stacking context, so the card
     layer competes with this one directly. The card has ridden out well before
     the sheet reaches it, but the paint order shouldn't rest on that timing. */
  z-index: 3;
  margin-top: -5rem;
  background: #fcfcfc;
  border-radius: 5rem 5rem 0 0;
  padding: 17rem 5rem 12rem;
  color: var(--title);
}

.approach__inner {
  max-width: 172rem;
  margin: 0 auto;
  /* how far the row fill runs past the text column on each side */
  --apr-bleed: 3rem;
}

.approach__title {
  margin: 0 0 8rem; /* the house title->content gap */
  font-size: 8.8rem;
  font-weight: 300;
  line-height: 1.05;
}

/* --- the accordion --- */
/* The fill sits on the whole ROW, not just its head. inset: 0 tracks the row's
   height, and the row's height is what the panel animates — so opening a row
   grows the black downward with the panel for free, and closing it shrinks
   back before wiping upward. */
.apr {
  position: relative;
  z-index: 0;
  overflow: hidden;
  margin: 0 calc(var(--apr-bleed) * -1);
  border-bottom: 1px solid #e6e6e6; /* the light-section hairline */
}
.apr::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--title);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
/* origin flips and is deliberately not transitioned: it rises from the bottom
   and exits upward, rather than retracing its own entry */
.apr:hover::before,
.apr[data-open]::before {
  transform: scaleY(1);
  transform-origin: bottom;
}

/* The row is bled out by --apr-bleed and the head pads back in by the same
   amount, so the fill runs wider than the text column while the type stays
   aligned with the title above it. */
.apr__head {
  display: flex;
  align-items: baseline;
  gap: 1.6rem;
  width: 100%;
  padding: 4rem var(--apr-bleed);
  border: none;
  background: none;
  color: var(--title);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: color 0.5s ease;
}
.apr:hover .apr__head,
.apr[data-open] .apr__head { color: #fcfcfc; }

/* The subhead tier, all of it Light. Name and tagline are now the same size
   and weight, so the dash is the only thing separating them — which reads as
   one editorial line rather than a label and a gloss. */
.apr__name {
  font-size: 4.5rem;
  font-weight: 300;
  line-height: 1.05;
}
/* White at all times — so at rest only the phase name shows, and the tagline
   is revealed by the fill rising behind it rather than fading in separately.
   Note this means it is invisible against the resting background by design. */
.apr__dash,
.apr__desc {
  font-size: 4.5rem;
  font-weight: 300;
  line-height: 1.05;
  color: #fcfcfc;
}
.apr__dash { opacity: 0.45; }

/* 0fr -> 1fr, the same height animation the state card uses */
.apr__panel {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows 0.6s cubic-bezier(0.16, 1, 0.3, 1),
              opacity 0.35s ease;
}
.apr__panel-in {
  overflow: hidden;
  min-height: 0;
}
.apr[data-open] .apr__panel {
  grid-template-rows: 1fr;
  opacity: 1;
  transition: grid-template-rows 0.6s cubic-bezier(0.16, 1, 0.3, 1),
              opacity 0.45s ease 0.15s;
}
/* On the fill once open, so white. Indented to line up with the TAGLINE above
   it, not the phase name — which is a different distance on every row, since
   the names differ in width. initApproach measures it per row into
   --apr-indent; the bleed is the fallback before that lands, and what the
   stacked tier resolves to anyway once the tagline wraps to its own line. */
.apr__panel p {
  max-width: 92rem;
  padding: 0 var(--apr-bleed) 4rem var(--apr-indent, var(--apr-bleed));
  /* the intro lead paragraph's tier — matched at every breakpoint, so the two
     move together if that one is ever retuned */
  font-size: 2.5rem;
  font-weight: 400;
  line-height: 3.4rem;
  color: #fcfcfc;
}

/* ============ Platforms ============ */

/* Same sheet as the values grid: rounded top, in flow, corners cut against the
   white above it. No negative margin needed — the page background is #fcfcfc,
   which is what sits behind those corners anyway. */
.platforms {
  background: #0d0d0d;
  border-radius: 5rem 5rem 0 0;
  /* the 19.8rem section gutter, matching .frame__body below — not the 5rem
     wide-band gutter the approach sheet uses */
  padding: 17rem 19.8rem 14rem;
  color: #fcfcfc;
}

/* no cap: at a 19.8rem gutter the content box is 152.4rem, so a 172rem
   max-width could never bind anyway */
.platforms__inner {
  margin: 0 auto;
}

.platforms__title {
  margin: 0 0 8rem;
  font-size: 8.8rem;
  font-weight: 300;
  line-height: 1.05;
}

/* 2rem under the title at every tier. Rests at 60% via --ro on the element —
   a plain opacity here would be overwritten by [data-reveal] the moment it
   lands. The dashes are not dimmed further; the list already sits back far
   enough. Note a fixed rem delta is not a fixed ratio: this is 77% of the
   title on desktop but 55% of it at the smallest tier, where the title is
   itself much smaller. */
.platforms__list {
  font-size: 6.8rem; /* .platforms__title - 2rem */
  font-weight: 300;
  line-height: 1.2;
}
.platforms__list i {
  font-style: normal;
  margin: 0 0.6rem;
}

/* ============ Stats ============ */

.stats {
  background: #fcfcfc;
  color: var(--title);
  padding: 14rem 0; /* +50px back under the stat pills */
  overflow: hidden;
}

/* intro-style layout, flipped: title + copy on the left, label on the right;
   same 5rem gutters, 91rem textbox, and 2.5rem/3.4rem type as the intro */
.stats__intro {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  max-width: 182rem; /* 172rem + the 5rem gutters, so the text lands where
                        .values__title lands inside its padded sheet */
  margin: 0 auto 10rem;
  padding: 0 5rem;
}

.stats__head { max-width: 91rem; }

.stats__title {
  font-size: 8.8rem;
  font-weight: 300;
  line-height: 1.05;
}

.stats__copy {
  margin-top: 4rem;
  font-size: 2.5rem;
  font-weight: 400;
  line-height: 3.4rem;
  color: var(--body);
}


/* marquee band of stat pills, panning right -> left */
.stats__marquee { width: 100%; overflow: hidden; }
.stats__track {
  display: flex;
  gap: 3rem;
  width: max-content;
  will-change: transform;
}

.stat-pill {
  display: inline-flex;
  align-items: center;
  padding: 3.3rem 8.1rem;
  border: 3px solid var(--c);
  border-radius: var(--r, 15rem); /* varied per pill: some pill, some rounded-rect */
  color: var(--c);
  font-size: 6.6rem;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
}

/* ============ Testimonials ============ */

.testimonials {
  background: #fcfcfc;
  padding: 4rem 0 19rem; /* -100px to stats above, +50px of white above the dark sheet */
}

.testimonials__title {
  color: var(--title);
  text-align: left;
  max-width: 182rem; /* matches .stats__intro and .values__title — see above */
  margin: 0 auto 8rem;
  padding: 0 5rem;
  font-size: 8.8rem;
  font-weight: 300;
}

/* Three drifting rows carrying the stats band's shapes: same size, same 3px
   outline, same type, no fills. Names take the pill radius, quotes the rounded
   rect, and colour pairs a name to its own quote.

   A shape is nowrap, exactly like a stat pill — which is the whole constraint
   on the copy. A quote that will not carry in one line does not belong in one. */
.testimonials__rows {
  display: flex;
  flex-direction: column;
  gap: 3rem; /* the stats track's gap, vertically */
}

.tq-row {
  width: 100%;
  overflow: hidden;
}

.tq-track {
  display: flex;
  gap: 3rem;
  width: max-content;
  will-change: transform;
}

/* deliberately the same box as .stat-pill — if that changes, change this */
.tq {
  display: inline-flex;
  align-items: center;
  padding: 3.3rem 8.1rem;
  border: 3px solid var(--c);
  color: var(--c);
  font-size: 6.6rem;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
}

.tq--name { border-radius: 15rem; }   /* who — full pill */
.tq--quote { border-radius: 2.4rem; } /* what — rounded rect */

/* ============ Values grid (dark sheet) ============ */

.values {
  background: #0d0d0d;
  border-radius: 5rem 5rem 0 0;
  padding: 17rem 5rem 4rem; /* +50px inside the sheet before the cards */
}

.values__title {
  max-width: 172rem;
  margin: 0 auto 8rem;
  font-size: 8.8rem;
  font-weight: 300;
  line-height: 1.05;
  color: #fcfcfc;
}

.values__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 2rem;
  max-width: 172rem;
  margin: 0 auto;
}

.vcard {
  display: flex;
  flex-direction: column;
  min-height: 52rem;
  padding: 3rem;
  border: 1px solid rgba(252, 252, 252, 0.18);
  border-radius: 2.4rem;
}

.vcard__tags { display: flex; gap: 0.8rem; }
.vcard__tag {
  padding: 0.9rem 1.8rem;
  border: 1px solid rgba(252, 252, 252, 0.28);
  border-radius: 10rem;
  font-size: 1.5rem;
  font-weight: 400;
  color: #fcfcfc;
  line-height: 1;
}

.vcard__tag--num { border-radius: 0.8rem; }

.vcard__title {
  margin-top: 3.4rem;
  font-size: 3.2rem;
  font-weight: 500;
  line-height: 1.15;
  color: #fcfcfc;
}

/* animated wireframe shapes at each card's foot */
.vcard__shape {
  margin-top: auto;
  align-self: center;
  width: 17rem;
  height: 17rem;
}
.vcard__shape svg { width: 100%; height: 100%; display: block; overflow: visible; }

/* sphere: latitude bands sweep as it turns */
.vcard__shape--sphere svg { animation: vs-spin 22s linear infinite; }
.vcard__shape--sphere ellipse { transform-origin: 100px 100px; animation: vs-lat 7s ease-in-out infinite; }
@keyframes vs-lat { 50% { transform: scaleY(0.35); } }

/* crossing ellipses rotate as a pair */
.vcard__shape--cross .vs-a { transform-origin: 100px 100px; animation: vs-spin 16s linear infinite; }

/* orbit rings tilt around a fixed core */
.vcard__shape--orbit .vs-o1 { transform-origin: 100px 100px; animation: vs-tilt 9s ease-in-out infinite; }
.vcard__shape--orbit .vs-o2 { transform-origin: 100px 100px; animation: vs-tilt 9s ease-in-out infinite reverse; }
@keyframes vs-tilt { 50% { transform: rotate(180deg) scaleY(0.6); } }

/* hexagon slowly rotates */
.vcard__shape--cube svg { animation: vs-spin 26s linear infinite; }

/* globe meridians breathe */
.vcard__shape--globe ellipse { transform-origin: 100px 100px; animation: vs-mer 11s ease-in-out infinite; }
@keyframes vs-mer { 50% { transform: scaleX(0.25); } }

/* concentric rings pulse outward in sequence */
.vcard__shape--rings .vs-r {
  transform-origin: 100px 100px;
  animation: vs-pulse 3.2s ease-in-out infinite;
  animation-delay: calc(var(--i) * 0.18s);
}
@keyframes vs-pulse { 50% { transform: scale(1.14); opacity: 0.45; } }

/* dome grid drifts */
.vcard__shape--dome svg { animation: vs-breathe 8s ease-in-out infinite; }
@keyframes vs-breathe { 50% { transform: translateY(-0.8rem) scale(1.04); } }

/* stacked waves travel */
.vcard__shape--helix .vs-h { animation: vs-wave 5s ease-in-out infinite; }
@keyframes vs-wave { 50% { transform: translateX(1.6rem); } }

@keyframes vs-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .vcard__shape svg, .vcard__shape * { animation: none !important; }
}

/* ============ Plans & pricing ============ */

.plans {
  position: relative;
  padding: 20rem 19.8rem 10rem; /* 200px below testimonials; half the 200px to the CTA */
  background: #0d0d0d;
}


.plans__title {
  color: #fcfcfc;
  text-align: center;
  font-size: 8.8rem;
  font-weight: 300;
  line-height: 1.05;
  margin-bottom: 8rem;
}
.plans__lead {
  display: block;
  margin-top: 1.6rem;
  font-size: 2.5rem;
  font-weight: 400;
  color: var(--muted);
}

.plans__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4rem;
  max-width: 124rem;
  margin: 0 auto;
}

.plan {
  display: flex;
  flex-direction: column;
  min-height: 56rem;
  padding: 5rem;
  border-radius: 1.6rem;
  background: #fff;
  border: 1px solid #e6e6e6;
}

.plan--plus {
  background: #0d0d0d;
  border-color: rgba(252, 252, 252, 0.24); /* visible edge on the dark section */
  color: #fcfcfc;
}

.plan__name {
  font-size: 4.5rem;
  font-weight: 500;
  color: var(--title);
  line-height: 1;
}

.plan__brand {
  display: flex;
  align-items: center;
  gap: 1.6rem;
}
.plan__mark { width: 2.6rem; height: 4.213rem; color: #fcfcfc; }
.plan__pill {
  padding: 0.7rem 1.8rem;
  border-radius: 10rem;
  background: #fcfcfc;
  color: #0d0d0d;
  font-size: 1.7rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1;
}

.plan__desc {
  margin-top: 3rem;
  font-size: 2rem;
  line-height: 1.4;
  font-weight: 400;
  color: var(--body);
  max-width: 42rem;
}
.plan--plus .plan__desc { color: #fcfcfc; }

.plan__price {
  margin-top: auto; /* pushes price + button to the bottom */
  padding-top: 6rem;
}
.plan__was {
  display: inline-block;
  font-size: 2rem;
  font-weight: 500;
  color: #8a8a8a;
  text-decoration: line-through;
  margin-bottom: 0.6rem;
}
.plan__amount {
  font-size: 6.4rem;
  font-weight: 500;
  color: var(--title);
  line-height: 1;
  letter-spacing: -0.02em;
}
.plan--plus .plan__amount { color: #fcfcfc; }
.plan__per {
  font-size: 2.2rem;
  font-weight: 400;
  color: #8a8a8a;
  margin-left: 1rem;
}

/* identical to the Book-a-demo button (.btn rules); box hugs the label,
   with the same lead space Book a demo carries before its text */
.plan__cta {
  align-self: flex-start;
  margin-top: 3.6rem;
  width: auto;
  padding-left: 1.6rem; /* hug the label; mirrors the 0.72rem right edge + icon */
}

/* ============ Built for you ============ */

.built {
  position: relative;
  background: #0d0d0d;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6rem;
  /* top 10rem + plans' bottom 10rem = 200px gap to the pricing cards */
  padding: 10rem 5rem 14rem;
}

/* Typewriter word cycle: JS backspaces the word and types the next one
   (Built → Tailored → Optimized → …). "for you" is a flex sibling aligned
   to the baseline, so it follows the word length automatically.
   Both halves carry the house section-title style (8.8rem / 300), so the line
   reads as one title rather than a display word with a tagline hung off it.
   The gap is sized to a word space: the caret's own margin + width already
   accounts for ~11px of it, so this is the remainder. */
.built__words {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 1.1rem;
}

.built__word {
  color: #fcfcfc;
  font-size: 8.8rem;
  font-weight: 300;
  line-height: 1.05;
  white-space: nowrap;
}

.built__caret {
  display: inline-block;
  width: 0.055em;
  height: 0.72em;
  margin-left: 0.07em;
  background: #fcfcfc;
  animation: caret-blink 1.05s steps(1) infinite;
  transition: opacity 0.2s ease;
}
.built__caret.is-hidden {
  opacity: 0;
  animation: none;
}
@keyframes caret-blink {
  0%, 60% { opacity: 1; }
  61%, 100% { opacity: 0; }
}

.built__foryou {
  font-size: 8.8rem;
  font-weight: 300;
  line-height: 1.05;
  color: #fcfcfc;
}

.built__cta {
  /* centred in the flex column */
}

/* ============ Footer ============ */

.footer {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  height: 85rem;
  background: #000; /* JS fades this in from #ACACAC during the reveal */
  color: #fcfcfc;
  overflow: hidden;
  z-index: 1; /* under page-body (3) and hero (2), above the canvas */
}

.footer__inner {
  position: relative;
  width: 100%;
  height: 100%;
  will-change: transform;
}

.footer__mark {
  position: absolute;
  left: 2.4rem;
  top: 12.5rem; /* 125px above the logo */
  width: 43.516rem;
  height: 70.48rem;
  color: #fcfcfc;
  z-index: 1;
}

.footer__cols {
  position: absolute;
  left: 51.645rem;
  right: 5rem;
  top: 11.35rem;
  display: flex;
  gap: 20rem; /* 200px between lists */
  z-index: 1;
}
.footer__col { min-width: 18rem; }
.footer__col--spacer { min-width: 18rem; }
.footer__col-title {
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  line-height: 3.4rem;
  color: var(--muted);
  margin-bottom: 5.1rem;
}
.footer__col a {
  display: block;
  font-size: 1.4rem;
  line-height: 1.4rem;
  margin-bottom: 0.5rem;
}

.footer__newsletter {
  position: absolute;
  left: 51.556rem;
  top: 66.81rem;
  z-index: 1;
}
.footer__loop {
  font-size: 1.4rem;
  line-height: 3.4rem;
  color: var(--muted);
  margin-left: 0.1rem;
}
.footer__newsletter-row { display: flex; }
.footer__newsletter input {
  width: 30.888rem;
  height: 3.057rem;
  background: transparent;
  border: 1px solid #fcfcfc;
  color: #fcfcfc;
  font-family: inherit;
  font-size: 1.4rem;
  padding: 0 0.8rem;
}
.footer__newsletter input::placeholder { color: var(--muted); }
.footer__newsletter button {
  width: 9.049rem;
  height: 3.057rem;
  margin-left: 1.1rem;
  background: #fcfcfc;
  color: var(--body);
  border: none;
  font-family: inherit;
  font-size: 1.4rem;
  cursor: pointer;
}

.footer__legal {
  position: absolute;
  left: 51.645rem;
  top: 79.72rem;
  font-size: 1.4rem;
  line-height: 3.4rem;
  color: var(--muted);
  z-index: 1;
}

/* ============================================================
   Animation layer
   ============================================================ */

/* --- Loader --- */
.loader {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fcfcfc;
  transition: transform 0.9s cubic-bezier(0.76, 0, 0.24, 1);
}
.loader__mark { width: 8rem; height: auto; color: #1a1a1a; }
.loader__piece {
  opacity: 0;
  animation: loader-piece 0.55s cubic-bezier(0.16, 1, 0.3, 1) forwards;
  animation-delay: 0.15s;
}
.loader__piece:nth-child(2) { animation-delay: 0.4s; }
.loader__piece:nth-child(3) { animation-delay: 0.65s; }

@keyframes loader-piece {
  from { opacity: 0; transform: translateY(12%); }
  to   { opacity: 1; transform: none; }
}

body.loading { overflow: hidden; }
body.loaded .loader { transform: translateY(-101%); }
.loader.is-removed { display: none; }

/* hero entrance after the loader lifts */
.hero__title {
  opacity: 0;
  transform: translateY(3rem);
  transition: opacity 0.9s ease 0.35s, transform 0.9s cubic-bezier(0.16, 1, 0.3, 1) 0.35s;
}
.site-header {
  opacity: 0;
  transition: opacity 0.8s ease 0.55s, color 0.35s ease;
}
body.loaded .hero__title { opacity: 1; transform: none; }
body.loaded .site-header { opacity: 1; }

/* --- scroll reveals --- */
[data-reveal] {
  opacity: 0;
  transition: opacity 0.9s ease, transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: var(--rd, 0s);
}
[data-reveal]:not([data-reveal="fade"]) { transform: translateY(3.5rem); }
[data-reveal].is-revealed { opacity: var(--ro, 1); }
[data-reveal]:not([data-reveal="fade"]).is-revealed { transform: translateY(0); }

/* --- hovers --- */
.btn__icon svg { transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1); }
.btn:hover .btn__icon svg { transform: translateX(0.25rem); }
.btn__label { transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1); }
.btn:hover .btn__label { transform: translateX(0.3rem); }

.btn--ghost { transition: background 0.3s ease, color 0.3s ease; }
.btn--ghost:hover { background: #fcfcfc; color: var(--body); }

/* One bar for the whole nav — it marks the section you are in and takes over
   on hover, so there is never more than one underline on screen. Positioned by
   transform from initNavActive; width 1px and scaled, to keep it off the
   layout path on every frame. */
.site-nav a { position: relative; transition: opacity 0.4s ease; }
.site-nav__bar {
  position: absolute;
  left: 0;
  bottom: -0.5rem;
  width: 1px;
  height: 1px;
  background: currentColor;
  transform-origin: left center;
  opacity: 0;
  pointer-events: none;
  will-change: transform, opacity;
}

.square-btn { transition: background 0.25s ease; }
.square-btn:hover { background: #2b2b2b; }
.square-btn svg { transition: transform 0.3s ease; }
.square-btn:hover svg { transform: translateX(0.3rem); }



.footer__col a { transition: opacity 0.25s ease; }
.footer__col a:hover { opacity: 0.6; }
.footer__newsletter button { transition: background 0.25s ease, color 0.25s ease, box-shadow 0.25s ease; }
.footer__newsletter button:hover {
  background: #000;
  color: #fcfcfc;
  box-shadow: inset 0 0 0 1px #fcfcfc;
}

/* --- footer entrance: logo builds like the loader, then content fades up --- */
.footer__mark rect,
.footer__mark path { opacity: 0; }

.footer.is-live .footer__mark path:nth-of-type(1) {
  animation: loader-piece 0.5s cubic-bezier(0.16, 1, 0.3, 1) forwards 0.1s;
}
.footer.is-live .footer__mark rect {
  animation: loader-piece 0.5s cubic-bezier(0.16, 1, 0.3, 1) forwards 0.3s;
}
.footer.is-live .footer__mark path:nth-of-type(2) {
  animation: loader-piece 0.5s cubic-bezier(0.16, 1, 0.3, 1) forwards 0.5s;
}

.footer__cols,
.footer__newsletter,
.footer__legal {
  opacity: 0;
  transform: translateY(3rem);
  transition: opacity 0.9s ease, transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}
.footer.is-live .footer__cols       { opacity: 1; transform: translateY(0); transition-delay: 0.9s; }
.footer.is-live .footer__newsletter { opacity: 1; transform: translateY(0); transition-delay: 1s; }
.footer.is-live .footer__legal      { opacity: 1; transform: translateY(0); transition-delay: 1.1s; }

/* --- reduced motion --- */
@media (prefers-reduced-motion: reduce) {
  .loader { display: none; }
  body.loading { overflow: auto; }
  .hero__title, .site-header { opacity: 1; transform: none; transition: none; }
  [data-reveal] { opacity: var(--ro, 1) !important; transform: none !important; transition: none !important; }
  .how { height: auto !important; padding-bottom: 14rem; }
  .how__list li { opacity: 1; transform: none; transition: none; }
  .how.is-handoff .how__title { opacity: 1; }
  .how__pin { position: static; height: auto; }
  .how__title { position: static; margin-bottom: 8rem; }
  .how__stage { position: relative; left: auto; right: auto; top: auto; bottom: auto; height: 64rem; }
  .how__panel { align-items: center; } /* stacked layout: no baseline to sit on */
  .how__picker { position: static; margin-top: 4rem; }

  .footer__mark rect, .footer__mark path { opacity: 1; animation: none; }
  .footer__cols, .footer__newsletter, .footer__legal { opacity: 1; transform: none; transition: none; }
}

/* ============================================================
   Tablet (641–1024px) — the desktop composition, tightened

   Everything that makes the page what it is stays: the intro's phrase swap,
   the How-it-works pinned frame, the full-bleed photographic frames. What
   changes is scale — gutters go 19.8rem -> 6rem, titles come down a tier,
   and the type shrinks. Nothing here unwinds a layout; that is the mobile
   tier's job.

   Two things do drop out, on purpose:
   - the header CTAs, for the hamburger (this tier is touch)
   - the card riding the frames, which cannot share this width with the type
   ============================================================ */

@media (max-width: 1024px) {
  html { font-size: 8px; }

  /* --- header / hamburger --- */
  .site-header { padding: 2.4rem 3rem 0; }
  .site-header__ctas { display: none; }
  .nav-toggle { display: flex; margin-left: auto; }

  .site-nav {
    position: fixed;
    inset: 0;
    transform: translateY(-100%);
    flex-direction: column;
    justify-content: center;
    align-items: flex-start;
    gap: 3rem;
    padding: 6rem 4rem;
    background: #000;
    font-size: 4.2rem;
    transition: transform 0.45s cubic-bezier(0.65, 0, 0.35, 1);
    z-index: 50;
  }
  body.nav-open .site-nav { transform: translateY(0); }
  body.nav-open { overflow: hidden; }
  body.nav-open .nav-toggle span:first-child { transform: translateY(0.55rem) rotate(45deg); }
  body.nav-open .nav-toggle span:last-child { transform: translateY(-0.55rem) rotate(-45deg); }
  /* overlay is always black — keep its contents white whatever the theme */
  .site-header .site-nav { color: #fcfcfc; }
  body.nav-open .site-header .nav-toggle span { background: #fcfcfc; }
  /* comfortable targets in the overlay */
  .site-nav a { padding: 0.6rem 0; }
  /* the overlay is a stacked menu, and you cannot scroll while it is open */
  .site-nav__bar { display: none; }

  /* --- hero --- */
  .hero__title { left: 6rem; bottom: 5rem; font-size: 4.4rem; }

  /* --- intro: the swap survives. Its internals are em-based off this one
         declaration, so the phrase, the shared "the" and the right-hand part
         all rescale together. --- */
  .intro { height: 52rem; }
  .intro__swap { font-size: 3.4rem; }
  .intro__label { display: none; } /* no room for the side label at this width */
  .intro__copy {
    left: 50%;
    top: 24rem;
    width: calc(50% - 6rem);
    font-size: 2rem;
    line-height: 3rem;
  }

  /* --- how it works: the pinned frame is kept, pulled in --- */
  .how { padding: 12rem 6rem; }
  .how__pin { margin: 0 -6rem; padding: 0 6rem; }
  .how__title { left: 6rem; right: 6rem; top: 8rem; font-size: 5.6rem; }
  .how__stage { left: 6rem; right: 6rem; top: 4rem; bottom: 22rem; }
  .how__picker { left: 6rem; right: 6rem; bottom: 4rem; }
  /* The four labels need ~620px on one row and only ~545px exists at the
     narrow end. Wrapping to two rows beats shrinking the type to 9.6px to
     force the row — and it only happens below ~720px. The hold measures the
     picker's rect at runtime, so a taller picker is handled. */
  .how__list { flex-wrap: wrap; }
  .how__item { padding: 1.4rem 1.6rem; }

  /* --- product frames --- */
  .frame__body { padding: 0 6rem 8rem; }
  .frame__title { font-size: 4rem; }
  .frame__copy { font-size: 1.9rem; max-width: 46rem; }
  /* a 44rem card plus the headline does not fit this width — the photographs
     and the type carry the section on their own here */
  .frames__card { display: none; }

  /* --- app cta --- */
  .appcta { padding: 10rem 6rem 12rem; }
  .appcta__title { font-size: 3.6rem; }

  /* --- stats: the 91rem textbox cannot sit beside the label at this width --- */
  .stats { padding: 12rem 0; }
  .stats__intro { flex-direction: column; padding: 0 6rem; margin-bottom: 8rem; }
  .stats__head { max-width: none; }
  .stats__title { font-size: 5.6rem; }
  .stats__copy { font-size: 2.2rem; }
  .stat-pill, .tq { padding: 2.7rem 5.4rem; font-size: 4.8rem; }

  /* --- testimonials: swipe rather than drift, since this tier is touch --- */
  .testimonials { padding: 4rem 0 12rem; }
  .testimonials__title { font-size: 5.6rem; margin-bottom: 6rem; padding: 0 6rem; }

  /* --- values: four across is too narrow here, two is not --- */
  .values { padding: 14rem 6rem 4rem; border-radius: 4rem 4rem 0 0; }
  .values__title { font-size: 5.6rem; margin-bottom: 6rem; }
  .values__grid { grid-template-columns: 1fr 1fr; gap: 2rem; }
  .vcard { min-height: 44rem; padding: 3rem; border-radius: 2rem; }
  .vcard__title { font-size: 2.8rem; margin-top: 3rem; }
  .vcard__shape { width: 14rem; height: 14rem; }

  /* --- plans: both cards stay side by side --- */
  .plans { padding: 14rem 6rem 8rem; }
  .plans__title { font-size: 5.6rem; margin-bottom: 6rem; }
  .plans__grid { gap: 3rem; }
  .plan { min-height: 46rem; padding: 4rem; }
  .plan__name { font-size: 3.6rem; }
  .plan__desc { font-size: 1.9rem; }
  .plan__amount { font-size: 5.2rem; }

  /* --- built --- */
  .built { padding: 10rem 6rem 12rem; gap: 5rem; }
  .built__word, .built__foryou { font-size: 5.6rem; }

  /* --- footer: static. Its reveal is laid out in absolute rem against a
         192rem screen, so it cannot be tightened — it is rebuilt as flow. --- */
  .footer { position: static; height: auto; padding: 6rem 6rem 4rem; z-index: auto; }
  .page-body { margin-bottom: 0; }
  .footer__inner { transform: none !important; }
  .footer__mark { position: static; width: 18rem; height: auto; }
  .footer__cols {
    position: static;
    flex-wrap: wrap;
    justify-content: flex-start;
    gap: 4rem 8rem;
    margin-top: 6rem;
  }
  .footer__col { width: auto; min-width: 18rem; }
  .footer__col--spacer { display: none; }
  .footer__col-title { margin-bottom: 2rem; }
  .footer__newsletter { position: static; margin-top: 6rem; }
  .footer__legal { position: static; margin-top: 4rem; }
}

/* ============================================================
   Mobile (≤640px) — one column, stacked

   This is where the compositions unwind: the pinned frame becomes a normal
   block, the phrase swap becomes two static lines sharing an inline "the",
   the feature list becomes a vertical list. Also where the interactive
   minimums live — 9.8px type and 13px tap targets were the two worst
   findings in the last review, and both came from rem-scaled values that
   had no floor under them.
   ============================================================ */

@media (max-width: 640px) {
  html { font-size: 7px; }

  /* Floors. The rem base drops to 7px here, so a 1.4rem label lands at 9.8px
     and a footer link at a 13px tap target. These stop that. */
  .footer__col a,
  .footer__col-title,
  .footer__legal,
  .footer__loop,
  .frame__eyebrow,
  .vcard__tag,
  .how__name,
  .appcta__copy { font-size: max(1.6rem, 12px); }

  .logo__word { font-size: 2.6rem; }

  /* --- hero --- */
  .hero__title { left: 3rem; bottom: 4rem; font-size: 3.4rem; }

  /* --- intro: two static lines, sharing an inline "the" --- */
  .intro { height: auto; padding: 10rem 3rem 8rem; }
  .intro__swap {
    position: static;
    font-size: 4.4rem;
    white-space: normal;
  }
  .intro__phrase, .intro__part { position: static; }
  .intro__phrase {
    transform: none !important;
    opacity: 1 !important;
  }
  .intro__phrase--a { color: var(--gray-text); }
  .intro__the { display: none; }
  .intro__the-inline { display: inline; margin: 0 1.1rem; }
  .intro__label, .intro__copy { position: static; width: auto; }
  .intro__label { display: none; }
  .intro__copy { margin-top: 6rem; font-size: 2.2rem; line-height: 3.4rem; }

  /* --- how it works: no pin, plain stacked block --- */
  .how { height: auto; padding: 8rem 3rem; }
  .how__pin { position: static; height: auto; margin: 0; padding: 0; }
  .how__title { position: static; font-size: 4.4rem; margin-bottom: 6rem; }
  .how__stage {
    position: relative;
    left: auto; right: auto; top: auto; bottom: auto;
    height: 54rem;
    margin-bottom: 4rem;
    transform: none !important;
  }
  .how__panel { align-items: center; } /* no baseline to sit on once stacked */
  .how__picker { position: static; }
  .how__list { flex-direction: column; width: 100%; }
  .how__list li + li { border-top: 1px solid #e2e2e2; }
  /* 45px tall at this rem base (2.2rem x2 + a 12px label at 1.2) */
  .how__item { padding: 2.2rem; width: 100%; text-align: left; }
  /* .how__name size comes from the floor rule at the top of this block —
     restating it here would override the max() and undo it */

  /* --- product frames --- */
  .frame__body { padding: 0 3rem 8rem; }
  .frame__title { font-size: 3.2rem; }
  .frame__copy { font-size: 1.9rem; max-width: none; }

  /* --- app cta --- */
  .appcta { padding: 8rem 3rem; }
  .appcta__title { font-size: 3.2rem; }
  .appcta__foot { flex-direction: column; align-items: flex-start; gap: 2.4rem; }
  .appcta__buttons { margin-left: 0; flex-wrap: wrap; width: 100%; }
  .store-btn { flex: 1 1 auto; justify-content: center; min-height: 44px; }

  /* --- our approach / platforms --- */
  .approach, .platforms { padding: 14rem 6rem 12rem; border-radius: 4rem 4rem 0 0; }
  .approach { margin-top: -4rem; }
  .approach__title, .platforms__title { font-size: 5.6rem; margin: 3rem 0 6rem; }
  .approach__inner { --apr-bleed: 2rem; }
  .apr__head { padding: 3rem var(--apr-bleed); gap: 1.2rem; }
  .apr__name, .apr__dash, .apr__desc { font-size: 3.2rem; }
  .apr__panel p { font-size: 2rem; line-height: 3rem; }
  .platforms__list { font-size: 3.6rem; } /* title 5.6 - 2 */

  /* --- our approach / platforms: the row stacks under its own name --- */
  .approach, .platforms { padding: 10rem 3rem 9rem; border-radius: 3rem 3rem 0 0; }
  .approach { margin-top: -3rem; }
  .approach__title, .platforms__title { font-size: 4.4rem; margin: 3rem 0 5rem; }
  .approach__inner { --apr-bleed: 1.5rem; }
  .apr__head { padding: 2.6rem var(--apr-bleed); flex-wrap: wrap; gap: 0 1rem; }
  .apr__name, .apr__desc { font-size: 2.8rem; }
  .apr__dash { display: none; } /* the wrap already separates them */
  .apr__desc { width: 100%; opacity: 0.7; }
  .apr__panel p { font-size: 2.2rem; line-height: 3.4rem; padding-bottom: 3rem; }
  .platforms__list { font-size: 2.4rem; line-height: 1.3; } /* title 4.4 - 2 */

  /* --- stats --- */
  .stats { padding: 10rem 0; }
  .stats__intro { padding: 0 3rem; margin-bottom: 6rem; }
  .stats__title { font-size: 4.4rem; }
  .stats__copy { font-size: 2.2rem; }
  .stat-pill, .tq { padding: 2.4rem 4.4rem; font-size: 4rem; }

  /* --- testimonials --- */
  .testimonials { padding: 4rem 0 10rem; }
  .testimonials__title { font-size: 4.4rem; margin-bottom: 5rem; padding: 0 3rem; }

  /* --- values: one column --- */
  .values { padding: 10rem 3rem 3rem; border-radius: 3rem 3rem 0 0; }
  .values__title { font-size: 4.4rem; margin-bottom: 5rem; }
  .values__grid { grid-template-columns: 1fr; gap: 1.6rem; }
  .vcard { min-height: 0; padding: 3rem; border-radius: 1.8rem; }
  .vcard__title { font-size: 2.8rem; margin-top: 2.4rem; margin-bottom: 4rem; }
  .vcard__shape { width: 14rem; height: 14rem; }

  /* --- plans: one column --- */
  .plans { padding: 10rem 3rem 8rem; }
  .plans__title { font-size: 4.4rem; margin-bottom: 5rem; }
  .plans__grid { grid-template-columns: 1fr; gap: 3rem; }
  .plan { min-height: 0; padding: 4rem 3rem; }
  .plan__name { font-size: 3.6rem; }
  .plan__desc { font-size: 2.2rem; }
  .plan__price { padding-top: 5rem; }

  /* --- built --- */
  .built { min-height: 0; padding: 12rem 3rem; gap: 5rem; }
  .built__word, .built__foryou { font-size: 5.6rem; }
  .built__words { flex-wrap: wrap; }

  /* --- footer --- */
  .footer { padding: 5rem 3rem 3rem; }
  .footer__mark { width: 16rem; }
  .footer__cols { gap: 4rem 6rem; margin-top: 5rem; }
  .footer__col { min-width: 14rem; }
  /* 13px tap targets before this; 1.8rem x2 + a 12px link at 1.6 clears 44px */
  .footer__col a { padding: 1.8rem 0; margin-bottom: 0; line-height: 1.6; }
  .footer__newsletter input,
  .footer__newsletter button { height: 44px; }
  .footer__newsletter input { max-width: 55vw; }
  .footer__newsletter button { width: auto; padding: 0 2.4rem; margin-left: 1rem; }
}
