/* PureGym case study, motion test.
   Page chrome comes from site.css + case.css (same column, TOC and top bar as
   the live case pages). This file only adds the stage, the phone and the motion.

   System draft
   - page type: DM Sans (site.css)
   - app type: Lexend + Roboto Condensed (the PureGym UI, as in Figma)
   - case accent: PureGym teal #00C1C6, progress gradient teal -> coral
   - stages: rounded 12px panels inside the column, never wider than it */

:root {
  --pg-teal: #00C1C6;
  --pg-teal-2: #0EBABF;
  --pg-coral: #FB7572;
  --pg-ink: #013739;
  --pg-stage: #F3F5F5;
  --pg-leader: #B4BBBD;
  --pg-ease: cubic-bezier(.22, 1, .36, 1);
}
:root[data-theme="dark"] { --pg-stage: #1C1E1F; --pg-leader: #5A5F62; --pg-card: #26292B; }
:root:not([data-theme="dark"]) { --pg-card: #FFFFFF; }

/* ---------- stage panels (column width, rounded like the case media) ---------- */
.pg-stage {
  position: relative;
  margin: 40px 0 0;
  border-radius: 12px;
  background: var(--pg-stage);
  overflow: hidden;
}
.pg-hero {
  margin-top: 0;
  height: clamp(460px, 68vh, 620px);
  display: flex; align-items: center; justify-content: center;
}
.pg-fit { position: relative; }
.pg-cap {
  position: absolute; left: 0; right: 0; bottom: 18px;
  text-align: center; font-size: 13px; color: var(--caption);
}

/* ---------- iPhone frame (CSS only) ---------- */
.iphone {
  position: relative;
  width: 393px; height: 852px;
  isolation: isolate;
  transform-origin: 0 0;
}
.iphone::before {               /* titanium band + black bezel */
  content: ''; position: absolute; inset: -13px; z-index: -1;
  border-radius: 62px;
  background: #0b0c0d;
  box-shadow:
    inset 0 0 0 1px #3a3e42,
    0 0 0 2px #8a8f94,
    0 0 0 3px #50555a,
    0 36px 70px -28px rgba(1, 55, 57, .38),
    0 10px 22px -10px rgba(0, 0, 0, .28);
}
.iphone .btn {
  position: absolute; width: 4px; border-radius: 2px; z-index: -2;
  background: linear-gradient(90deg, #6a6f74, #2f3236);
}
.iphone .btn.l { left: -17px; }
.iphone .btn.r { right: -17px; background: linear-gradient(270deg, #6a6f74, #2f3236); }
.iphone .screen {
  position: absolute; inset: 0; border-radius: 50px; overflow: hidden;
  background: #FAF8F7;
  /* overflow + radius alone can let moving layers (the pages pushing in the
     Progress demo) spill past the rounded corners in some browsers; a
     clip-path to the same shape always holds */
  clip-path: inset(0 round 50px); isolation: isolate;
}
.iphone .island {
  position: absolute; top: 11px; left: 50%; width: 124px; height: 36px; margin-left: -62px;
  border-radius: 20px; background: #000; z-index: 20;
}
.iphone .status {
  position: absolute; top: 0; left: 0; right: 0; height: 52px; z-index: 19;
  display: flex; align-items: center; justify-content: space-between;
  padding: 4px 30px 0 52px;
  font: 600 16px/1 -apple-system, 'SF Pro Text', 'DM Sans', system-ui, sans-serif;
  color: #0F1A1B; pointer-events: none;
}
.iphone .status svg { display: block; }
.iphone .home {
  position: absolute; bottom: 8px; left: 50%; width: 134px; height: 5px; margin-left: -67px;
  border-radius: 3px; background: #0F1A1B; z-index: 19;
}

/* ---------- the PureGym app screen, from Figma "iPhone 16 - 33" ---------- */
.app { position: absolute; inset: 0; font-family: 'Lexend', sans-serif; color: #345F61; }
.app p { margin: 0; }
.app-top {
  position: absolute; top: 0; left: 0; right: 0; height: 120px; z-index: 3;
  background: #FEFEFD; box-shadow: 0 2px 4px rgba(103, 135, 136, .1);
}
.app-gymname {
  position: absolute; top: 86px; left: calc(50% + 11.5px); transform: translateX(-50%);
  display: flex; align-items: center; gap: 12px; height: 23px; padding: 1px 9px;
  border: 0; background: none; font: 500 14px/1 'Lexend', sans-serif; color: #345F61;
  width: max-content; white-space: nowrap;
}
.gymname-roll { position: relative; display: block; height: 18px; overflow: hidden; text-align: center; transition: width .7s var(--pg-ease); }
.gymname-roll span { display: block; width: max-content; margin: 0 auto; height: 18px; line-height: 18px; white-space: nowrap; transition: transform .7s var(--pg-ease); }
.app-bell { position: absolute; left: 331px; top: 84px; }

.app-col {
  position: absolute; left: 27px; top: 151px; width: 334px;
  display: flex; flex-direction: column; gap: 18px;
}

.gym-card {
  position: relative; width: 334px; height: 88px; flex: none;
  display: flex; align-items: center; gap: 12px; padding: 0 20px;
  background: #fff; border-radius: 20px;
}
/* switching gyms: the card stays put, its contents roll up to the next gym */
.gym-roll { position: relative; flex: 1; min-width: 0; height: 88px; overflow: hidden; }
.gym-row { height: 88px; display: flex; align-items: center; gap: 12px; transition: transform .7s var(--pg-ease); }
.iphone.wh .gym-row { transform: translateY(-100%); }
.gym-photo { width: 51px; height: 50px; border-radius: 8px; object-fit: cover; flex: none; }
.gym-text { flex: 1; min-width: 0; }
.gym-name {
  font: 700 20px/1.17 'Roboto Condensed', sans-serif; letter-spacing: .4px;
  text-transform: uppercase; color: var(--pg-teal); white-space: nowrap;
}
.gym-addr { font: 500 14px/1.25 'Lexend', sans-serif; color: #66DADD; opacity: .8; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gym-chev { transform: rotate(-90deg); flex: none; }

.qr-card { position: relative; height: 463px; background: #fff; border-radius: 16px; }
.seg {
  position: absolute; top: 24px; left: 50%; width: 298px; height: 60px; margin-left: -149px;
  display: flex; align-items: center; padding: 8px; border-radius: 100px; background: #F4F9F9;
}
.seg-thumb { position: absolute; left: 8px; top: 8px; width: 142px; height: 44px; border-radius: 100px; background: #fff; }
.seg-opt {
  position: relative; flex: 1; text-align: center;
  font: 600 18px/1 'Roboto Condensed', sans-serif; letter-spacing: .36px; text-transform: uppercase; color: #99AFB0;
}
.seg-opt.on { color: #33CDD1; }
.qr-wrap { position: absolute; left: 44px; top: 99px; width: 247px; display: flex; flex-direction: column; align-items: center; gap: 6px; }
.qr { display: block; border-radius: 24px; }
.member { font: 500 14px/1.25 'Lexend', sans-serif; color: #678788; }
.member b { font-weight: 500; color: var(--pg-ink); margin-left: 2px; }
.wallet {
  position: absolute; left: 44px; top: 390px; width: 247px; height: 44px;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  border-radius: 62px; background: var(--pg-teal-2); color: #fff;
  font: 600 20px/1 'Roboto Condensed', sans-serif; letter-spacing: .4px; text-transform: uppercase;
}

.tiles { display: flex; gap: 12px; }
.tile {
  flex: 1; height: 158px; border-radius: 24px; background: #fff;
  box-shadow: inset 0 0 4px rgba(153, 175, 176, .5);
  padding-top: 16px; text-align: center;
  font: 500 14px/1.2 'Lexend', sans-serif; color: #678788;
}

.app-tabs {
  position: absolute; left: 0; right: 0; bottom: 0; height: 94px; z-index: 3;
  display: flex; justify-content: center; gap: 60px; padding: 4px 20px 0;
  background: #FEFEFD; box-shadow: 0 -2px 4px rgba(103, 135, 136, .1);
}
.tab {
  width: 60px; height: 60px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 7px;
  font: 400 11px/1 'Lexend', sans-serif; letter-spacing: -.11px; color: #99AFB0;
}
.tab.on { color: var(--pg-ink); }



/* ---------- lifted pieces: the real element rises, its own shape outlined ---------- */
.iphone [data-part] {
  z-index: 1;
  transition: transform .7s var(--pg-ease), box-shadow .7s var(--pg-ease);
}
.qr { position: relative; }
.iphone [data-part].lift {
  z-index: 5;
  transform: translateY(-6px) scale(1.035);
  box-shadow: 0 0 0 2px var(--pg-teal), 0 22px 36px -14px rgba(1, 55, 57, .38);
}
.seg[data-part].lift { transform: translateY(-6px) scale(1.035); }
.qr[data-part].lift { box-shadow: 0 0 0 2px var(--pg-teal), 0 22px 36px -14px rgba(1, 55, 57, .3); }
/* the empty slot it leaves behind, same radius as the piece */
.slot {
  position: absolute; pointer-events: none; z-index: 0; opacity: 0;
  border: 1.5px dashed rgba(0, 193, 198, .55);
  transition: opacity .4s ease;
}
.slot.on { opacity: 1; }

/* ---------- zoom section ---------- */
.zoom { position: relative; height: 420vh; margin-top: 40px; }
.zoom-stage {
  position: sticky;
  top: max(72px, calc(50vh - var(--zh) / 2 + 24px));
  margin: 0;
  --zh: clamp(480px, calc(100vh - 140px), 680px);
  height: var(--zh);
}
.camera { position: absolute; left: 0; top: 0; transform-origin: 0 0; will-change: transform; }

.leaders { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 2; overflow: visible; }
.leaders path { fill: none; stroke: var(--pg-leader); stroke-width: 1.5; transition: stroke-dashoffset .6s var(--pg-ease), opacity .3s ease; }
.leaders circle { fill: var(--pg-leader); transition: opacity .3s ease; }

.callouts { position: absolute; inset: 0; pointer-events: none; z-index: 3; }
.callout {
  position: absolute; width: 250px;
  opacity: 0; transform: translateY(8px);
  transition: opacity .45s ease, transform .55s var(--pg-ease);
}
.callout.on { opacity: 1; transform: none; }
.callout .num { font-size: 12px; font-weight: 400; letter-spacing: .04em; color: var(--pg-teal); }
.callout .c-title { margin: 6px 0; font-size: 19px; font-weight: 400; letter-spacing: -.015em; color: var(--head); }
.callout .c-body { margin: 0; font-size: 14px; line-height: 1.45; color: var(--body); }

/* where you are: the steps named in a quiet row (like the feature tabs on
   linear.app), the current one in ink with a hairline that fills under it */
.zoom-progress { position: absolute; right: 26px; bottom: 20px; display: flex; gap: 18px; z-index: 3; }
.zoom-progress i { position: relative; display: block; padding-bottom: 7px; font-style: normal; }
.zoom-progress em {
  font-style: normal; font-size: 12px; font-weight: 500; letter-spacing: .01em; white-space: nowrap;
  color: var(--faint); transition: color .35s ease;
}
.zoom-progress i::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1.5px; border-radius: 1px; background: rgba(var(--ink-rgb), .1); }
.zoom-progress b { position: absolute; left: 0; bottom: 0; z-index: 1; height: 1.5px; width: 0; border-radius: 1px; background: var(--head); }
.zoom-progress i.on em { color: var(--head); }
.zoom-progress i:not(.on) b { background: rgba(var(--ink-rgb), .28); }
/* visual 1: the step names are clickable (bigger hit area, quiet hover) */
.zoom-progress.clickable i { cursor: pointer; padding-top: 8px; margin-top: -8px; outline: none; }
.zoom-progress.clickable i:hover:not(.on) em { color: var(--body); }
.zoom-progress.clickable i:focus-visible em { color: var(--head); text-decoration: underline; text-underline-offset: 3px; }

/* ---------- visual 1: the old home screen, the real screenshot ---------- */
.old-phone .screen { background: #06393B; }
/* the screenshot already has its own status bar, island and home bar */
.old-phone .status, .old-phone .island, .old-phone .home { display: none; }
.old { position: absolute; inset: 0; }
.old-shot { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
/* everything else steps back while one piece is up */
.old::after {
  content: ''; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: rgba(2, 20, 21, .55); opacity: 0; transition: opacity .6s ease;
}
.old.dim::after { opacity: 1; }
/* a piece is a cut of the same screenshot, sitting exactly on top of it */
.old-piece { position: absolute; background-repeat: no-repeat; background-size: 393px 852px; }
.old-phone .old-piece { transition: transform .8s var(--pg-ease), box-shadow .8s var(--pg-ease); }
/* it floats up, outlined in coral in its own shape; a thin dark gap first so
   the coral still reads on the red Scan button */
.old-phone .old-piece.lift {
  z-index: 5;
  transform: translateY(-18px) scale(1.05);
  box-shadow: 0 0 0 2px #06393B, 0 0 0 4px var(--pg-coral), 0 26px 40px -14px rgba(0, 0, 0, .7);
}
.old-phone .old-piece[data-part="tabs"].lift,
.old-phone .old-piece[data-part="promo"].lift { transform: translateY(-18px) scale(1.025); }
.old-phone .old-piece.pg-mark { box-shadow: 0 0 0 1.5px #06393B, 0 0 0 3px var(--pg-coral); }
/* the hole it leaves behind */
.old-phone .slot { z-index: 1; border-color: rgba(251, 117, 114, .6); background: rgba(2, 20, 21, .6); }

/* no scroll motion here: a normal panel that plays once it is on screen */
.story { height: auto; }
.story .zoom-stage { position: relative; top: auto; --zh: clamp(540px, 78vh, 660px); }
.story .callout { width: 240px; }
.story .callout .num { color: var(--pg-coral); }
.callout .c-quote { margin: 8px 0 0; font-size: 19px; line-height: 1.35; font-weight: 400; letter-spacing: -.012em; color: var(--head); }

/* the ending: every piece outlined, one line */
.p-close {
  position: absolute; z-index: 3; pointer-events: none;
  opacity: 0; transform: translateY(10px);
  transition: opacity .55s ease, transform .7s var(--pg-ease);
}
.p-close.on { opacity: 1; transform: none; }
.p-close-q { margin: 0; font-size: clamp(28px, 3.2vw, 40px); line-height: 1.12; font-weight: 500; letter-spacing: -.025em; color: var(--head); }
.p-close-note { margin: 14px 0 0; font-size: 12px; color: var(--caption); }



/* narrow column: notes sit at the bottom of the stage, no leader lines */
@media (max-width: 700px) {
  .callout { left: 20px !important; right: 20px; width: auto; top: auto !important; bottom: 52px; }
  .leaders { display: none; }
  .zoom-progress { left: 20px; right: 20px; bottom: 18px; gap: 12px; justify-content: space-between; }
  .zoom-progress em { font-size: 11px; }
  .p-close { left: 20px !important; right: 20px; width: auto !important; top: auto !important; bottom: 52px; }
  .p-close-q { font-size: 26px; }
  /* the old screen is busy, so on a phone each quote sits on its own card */
  .story .callout, .story .p-close {
    padding: 12px 14px; border-radius: 12px; background: var(--pg-card);
    box-shadow: 0 12px 28px -12px rgba(0, 0, 0, .35);
  }
  .story .callout .c-quote { font-size: 16px; }
  /* span the panel like the closing card (the desktop 240px width would pin it left) */
  .story .callout { width: auto; }
  /* solution zoom: the phone runs under the notes, so a soft blur fades up
     from the bottom of the panel, above the phone and behind the text */
  #zoom .zoom-stage::after {
    content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 250px;
    z-index: 2; pointer-events: none;
    -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 42%);
    mask-image: linear-gradient(to bottom, transparent 0%, #000 42%);
    background: linear-gradient(to bottom,
      color-mix(in srgb, var(--pg-stage) 0%, transparent) 0%,
      color-mix(in srgb, var(--pg-stage) 78%, transparent) 40%,
      color-mix(in srgb, var(--pg-stage) 94%, transparent) 70%,
      var(--pg-stage) 100%);
  }
}

/* ================================================================
   The rest of the page. Motion idea taken from amberlle.com's home
   tiles: the real UI on a soft painted panel, doing the thing on a
   loop (a finger instead of her mouse pointer, since this is a phone),
   typing, steps ticking in one at a time.
   ================================================================ */

/* meta row: the timeline sits on two lines (December 2025 / January 2026) so
   it never runs into "7 gym members" next to it */
@media (min-width: 761px) {
  .case-head .meta { grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: 24px; }
}
.case-head .meta dd { line-height: 1.4; }
.case-head .meta dd span { white-space: nowrap; }

/* ---------- challenge: the question types itself out ---------- */
.ask {
  margin: 0; max-width: 720px;
  font-size: clamp(26px, 3.3vw, 36px); line-height: 1.25; font-weight: 500; letter-spacing: -.018em;
  color: var(--head); min-height: 2.5em;
}
.ask-caret {
  display: inline-block; width: 2px; height: .95em; margin-left: 3px; vertical-align: -.1em;
  background: var(--accent); animation: pg-blink 1s steps(1) infinite;
}
.ask.done .ask-caret { animation: pg-blink 1s steps(1) 3, pg-fade .3s 3s forwards; }
@keyframes pg-blink { 50% { opacity: 0; } }
@keyframes pg-fade { to { opacity: 0; } }

/* ---------- decision demos ---------- */
.demo { margin: 40px 0 0; }
.demo + .demo { margin-top: 64px; }
.demo-stage {
  position: relative; overflow: hidden; border-radius: 12px;
  height: clamp(460px, 64vh, 580px);
  background: var(--pg-stage);
}
/* the painted ground: two soft glows, like the cover cards */
.demo-stage::before {
  content: ''; position: absolute; inset: -20%; pointer-events: none;
  filter: blur(10px);
}
.glow-coral::before {
  background:
    radial-gradient(38% 46% at 40% 52%, rgba(253, 204, 203, .95), transparent 70%),
    radial-gradient(34% 40% at 62% 44%, rgba(198, 222, 255, .8), transparent 70%);
}
.glow-teal::before {
  background:
    radial-gradient(40% 46% at 58% 50%, rgba(181, 237, 238, .95), transparent 70%),
    radial-gradient(30% 40% at 38% 40%, rgba(207, 224, 255, .75), transparent 70%);
}
.glow-warm::before {
  background:
    radial-gradient(40% 46% at 50% 56%, rgba(245, 184, 70, .45), transparent 70%),
    radial-gradient(28% 34% at 50% 50%, rgba(255, 134, 41, .28), transparent 70%);
}
:root[data-theme="dark"] .demo-stage::before { opacity: .42; }

.demo-phone { position: absolute; left: 0; top: 0; }
.demo-phone .iphone { position: absolute; left: 0; top: 0; }

/* the finger: a soft touch dot that travels, presses and ripples */
.finger {
  position: absolute; left: 0; top: 0; z-index: 10; pointer-events: none;
  width: 34px; height: 34px; margin: -17px 0 0 -17px; border-radius: 50%;
  background: rgba(255, 255, 255, .38);
  border: 2px solid rgba(255, 255, 255, .95);
  box-shadow: 0 6px 18px rgba(1, 40, 42, .28), inset 0 0 0 1px rgba(1, 55, 57, .12);
  backdrop-filter: blur(2px);
  opacity: 0;
  transition: transform .75s var(--pg-ease), opacity .35s ease;
}
.finger.on { opacity: 1; }
.finger::before { /* the press */
  content: ''; position: absolute; inset: 5px; border-radius: 50%;
  background: rgba(255, 255, 255, .9); transform: scale(0); transition: transform .14s ease;
}
.finger.press::before { transform: scale(1); }
.finger::after { /* the ripple */
  content: ''; position: absolute; inset: -2px; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .9); opacity: 0;
}
.finger.ripple::after { animation: pg-ripple .55s ease-out; }
@keyframes pg-ripple { from { opacity: .9; transform: scale(1); } to { opacity: 0; transform: scale(2.1); } }

/* caption row, amberlle-style: title, a small tag, then grey copy */
.demo-cap { margin-top: 18px; }
.demo-title { margin: 0; font-size: 20px; line-height: 1.35; font-weight: 400; letter-spacing: -.015em; color: var(--head); }
.demo-body { margin: 8px 0 0; max-width: 660px; font-size: 16px; line-height: 1.55; color: var(--body); }
.tag {
  display: inline-block; margin-left: 6px; padding: 2px 8px; vertical-align: 2px;
  border-radius: 6px; border: 1px solid; font-size: 13px; font-weight: 500; letter-spacing: 0; white-space: nowrap;
}
/* outside the grey frames = portfolio branding: the site's blue (yellow in dark) */
.tag { background: transparent; color: var(--accent); border-color: currentColor; font-family: "Play", sans-serif; text-transform: uppercase; font-size: 12px; letter-spacing: .02em; }

/* -- demo 1: guest pass toggle (from Figma: Version=Bring a Friend) -- */
.seg-thumb { transition: transform .5s var(--pg-ease); }
.seg-opt { transition: color .35s ease; }
.qr-card.is-guest .seg-thumb { transform: translateX(140px); }
.qr-card.is-guest .seg-opt.on { color: #99AFB0; }
.qr-card.is-guest .seg-opt:not(.on) { color: var(--pg-coral); }
/* one leaves, then the other arrives (no cross-fade through each other) */
.qr-wrap, .qr-card .wallet { transition: opacity .22s ease .2s, transform .45s var(--pg-ease) .2s; }
.qr-card.is-guest .qr-wrap, .qr-card.is-guest .wallet { opacity: 0; transform: translateY(8px); transition-delay: 0s; }
.guest {
  position: absolute; left: 0; right: 0; top: 100px; text-align: center;
  opacity: 0; transform: translateY(10px); pointer-events: none;
  transition: opacity .22s ease, transform .45s var(--pg-ease);
}
.qr-card.is-guest .guest { opacity: 1; transform: none; transition-delay: .2s; }
.g-ticket {
  position: relative; margin: 0 22px; height: 150px; border-radius: 20px;
  display: flex; align-items: center; justify-content: center;
  background: #fff; box-shadow: inset 0 0 0 1.5px #E3EEEE;
  /* the punched notches top and bottom, like a real ticket */
  -webkit-mask: radial-gradient(circle 13px at 50% 0, transparent 12px, #000 12.5px) top / 100% 51% no-repeat,
                radial-gradient(circle 13px at 50% 100%, transparent 12px, #000 12.5px) bottom / 100% 51% no-repeat;
          mask: radial-gradient(circle 13px at 50% 0, transparent 12px, #000 12.5px) top / 100% 51% no-repeat,
                radial-gradient(circle 13px at 50% 100%, transparent 12px, #000 12.5px) bottom / 100% 51% no-repeat;
}
.g-big { display: flex; align-items: center; justify-content: center; gap: 12px; }
.g-big b { font: 700 78px/1 'Roboto Condensed', sans-serif; color: var(--pg-ink); letter-spacing: -1px; }
.g-big span { font: 600 25px/1.05 'Roboto Condensed', sans-serif; color: #345F61; text-transform: uppercase; text-align: left; letter-spacing: .4px; }
.g-valid { margin-top: 16px !important; font: 500 17px/1 'Lexend', sans-serif; color: #678788; }
.g-copy { margin: 12px 34px 0 !important; font: 400 12px/1.45 'Lexend', sans-serif; color: #99AFB0; }
.g-valid + .g-copy { margin-top: 18px !important; }
.g-share {
  position: relative; margin: 20px auto 0; width: 247px; height: 44px;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  border-radius: 62px; background: var(--pg-coral); color: #fff;
  font: 600 20px/1 'Roboto Condensed', sans-serif; letter-spacing: .4px; text-transform: uppercase;
}
.toast {
  position: absolute; left: 50%; bottom: 118px; z-index: 8;
  padding: 11px 18px; border-radius: 100px; white-space: nowrap;
  background: rgba(1, 55, 57, .94); color: #fff; font: 500 14px/1 'Lexend', sans-serif;
  transform: translate(-50%, 14px); opacity: 0;
  transition: opacity .3s ease, transform .5s var(--pg-ease);
}
.toast.on { opacity: 1; transform: translate(-50%, 0); }

/* -- demo 2: saved gyms, bottom sheet (Figma: Select your gym / Add gym) -- */
.iphone.wh .gymname-roll span { transform: translateY(-100%); }

.scrim {
  position: absolute; inset: 0; z-index: 30; background: rgba(1, 30, 31, .38);
  opacity: 0; transition: opacity .45s ease; pointer-events: none;
}
.sheet {
  position: absolute; left: 0; right: 0; bottom: 0; height: 712px; z-index: 31;
  background: #FAF8F7; border-radius: 30px 30px 0 0; overflow: hidden;
  transform: translateY(102%); transition: transform .62s var(--pg-ease);
  font-family: 'Lexend', sans-serif; color: #345F61;
}
.open .scrim { opacity: 1; }
.open .sheet { transform: none; }
.sheet-grab { width: 40px; height: 5px; border-radius: 3px; background: #CBD5D5; margin: 10px auto 0; }
.sheet-page { position: absolute; left: 0; right: 0; top: 24px; bottom: 0; transition: transform .55s var(--pg-ease), opacity .4s ease; }
.sheet-page.add { transform: translateX(100%); }
.to-add .sheet-page.select { transform: translateX(-28%); opacity: 0; }
.to-add .sheet-page.add { transform: none; }
.sheet h4 {
  margin: 14px 0 22px; text-align: center;
  font: 700 27px/1 'Roboto Condensed', sans-serif; letter-spacing: .5px; text-transform: uppercase; color: #345F61;
}
.sheet .more { position: absolute; right: 28px; top: 14px; font: 700 18px/1 'Lexend', sans-serif; color: #678788; letter-spacing: 1px; }
.g-row {
  display: flex; align-items: center; gap: 14px; margin: 0 24px 12px; height: 76px; padding: 0 16px;
  background: #fff; border-radius: 16px;
}
.g-row img { width: 46px; height: 46px; border-radius: 8px; object-fit: cover; flex: none; }
.g-row .t { flex: 1; min-width: 0; }
.g-row .n { display: block; font: 700 19px/1.1 'Roboto Condensed', sans-serif; letter-spacing: .4px; text-transform: uppercase; color: #345F61; white-space: nowrap; }
.g-row .a { display: block; font: 400 12px/1.4 'Lexend', sans-serif; color: #99AFB0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.g-row.sel .n { color: var(--pg-teal); }
.g-check {
  width: 20px; height: 20px; border-radius: 50%; background: var(--pg-teal); flex: none;
  display: flex; align-items: center; justify-content: center;
}
.g-add { display: flex; align-items: center; gap: 12px; margin: 0 24px; height: 58px; padding: 0 18px; background: #fff; border-radius: 16px; font: 400 15px/1 'Lexend', sans-serif; color: #345F61; }
.g-add .plus { font-size: 22px; font-weight: 300; color: #678788; }
.g-search {
  display: flex; align-items: center; justify-content: space-between;
  margin: 0 24px; height: 46px; padding: 0 16px; border-radius: 23px;
  background: #fff; box-shadow: inset 0 0 0 1px #E2EAEA; font: 400 15px/1 'Lexend', sans-serif; color: #345F61;
}
.g-search .ph { color: #99AFB0; }
.g-search .caret { display: inline-block; width: 1.5px; height: 18px; margin-left: 1px; vertical-align: -3px; background: var(--pg-teal); opacity: 0; }
.typing .g-search .caret { opacity: 1; animation: pg-blink 1s steps(1) infinite; }
.g-map { position: relative; margin: 14px 24px 0; height: 238px; border-radius: 18px; overflow: hidden; box-shadow: 0 0 0 4px #fff; }
.g-map img { width: 100%; height: 100%; object-fit: cover; display: block; }
.g-pin { position: absolute; left: 61%; top: 40%; width: 26px; height: 34px; margin: -34px 0 0 -13px; opacity: 0; transform: translateY(-38px); }
.pinned .g-pin { animation: pg-drop .55s cubic-bezier(.3, 1.6, .5, 1) forwards; }
@keyframes pg-drop { from { opacity: 0; transform: translateY(-38px); } 60% { opacity: 1; } to { opacity: 1; transform: none; } }
.g-result { margin-top: 16px; height: 66px; opacity: 0; transform: translateY(8px); transition: opacity .35s ease, transform .5s var(--pg-ease); }
.pinned .g-result { opacity: 1; transform: none; }
.g-result .n { font: 500 15px/1.2 'Lexend', sans-serif; text-transform: none; letter-spacing: 0; color: #345F61; }
.g-result .g-plus { font: 300 24px/1 'Lexend', sans-serif; color: #678788; width: 22px; text-align: center; }
.g-result .g-check { display: none; }
.added .g-result .g-plus { display: none; }
.added .g-result .g-check { display: flex; animation: pg-pop .35s cubic-bezier(.3, 1.6, .5, 1); }
@keyframes pg-pop { from { transform: scale(.3); } to { transform: none; } }
.g-save {
  position: absolute; left: 50%; bottom: 70px; width: 196px; height: 54px; margin-left: -98px;
  display: flex; align-items: center; justify-content: center; border-radius: 30px;
  background: var(--pg-teal-2); color: #fff; font: 700 22px/1 'Roboto Condensed', sans-serif; letter-spacing: .6px;
}

/* -- demo 3: the Progress tab (Figma: Progress) -- */
.demo[data-demo="progress"] .app-tabs { z-index: 6; }
.tab { transition: color .3s ease; }
/* the tab icons have their colours baked in (grey off, dark teal on), so the
   switch in this demo only nudges them: dim the one left, darken the one picked */
.tab img { transition: opacity .3s ease, filter .3s ease; }
.on-progress .tab.t-check img { opacity: .45; }
.on-progress .tab.t-progress img { filter: brightness(.42); }
.prog {
  position: absolute; left: 0; right: 0; top: 0; bottom: 0; z-index: 5;
  background: #FAF8F7; transform: translateX(-100%); transition: transform .6s var(--pg-ease);
  font-family: 'Lexend', sans-serif;
}
.prog.on { transform: none; }
/* a real tab push: as Progress slides in from the left, the check-in page is
   pushed out to the right at the same speed (their edges stay touching), and
   on the way back check-in pushes Progress out. The tab bar stays put. */
.demo[data-demo="progress"] .app-top,
.demo[data-demo="progress"] .app-col { transition: transform .6s var(--pg-ease); }
.demo[data-demo="progress"] .on-progress > .app-top,
.demo[data-demo="progress"] .on-progress > .app-col { transform: translateX(393px); }
.prog-top { position: absolute; top: 0; left: 0; right: 0; height: 120px; background: #FEFEFD; box-shadow: 0 2px 4px rgba(103, 135, 136, .1); }
.prog-top p { position: absolute; top: 88px; left: 0; right: 0; text-align: center; font: 500 14px/1 'Lexend', sans-serif; color: #345F61; }
.prog-top img { position: absolute; left: 331px; top: 84px; }
.prog-banner {
  position: absolute; left: 27px; top: 146px; width: 334px; height: 196px; border-radius: 22px; overflow: hidden;
  background: linear-gradient(0deg, rgba(4, 20, 21, .78), rgba(4, 20, 21, .05) 62%), url('assets/puregym/v2/ui/gym-photo.png') center 30% / cover;
  display: flex; align-items: flex-end; justify-content: space-between; padding: 0 20px 20px;
  color: #fff; font: 600 20px/1.2 'Lexend', sans-serif;
}
.prog-tiles { position: absolute; left: 27px; top: 360px; width: 334px; display: flex; gap: 12px; }
.prog-tile {
  flex: 1; height: 158px; border-radius: 24px; background: #fff; box-shadow: inset 0 0 4px rgba(153, 175, 176, .5);
  padding-top: 16px; text-align: center; font: 500 13px/1.25 'Lexend', sans-serif; color: #678788;
}
.prog-tile b { display: block; margin-top: 16px; font: 700 62px/1 'Roboto Condensed', sans-serif; color: var(--pg-coral); }
.prog-tile.t2 b { color: var(--pg-teal); }
.prog-ach { position: absolute; left: 33px; top: 540px; right: 33px; }
.prog-ach h5 { margin: 0; font: 600 21px/1 'Lexend', sans-serif; color: #345F61; }
.prog-ach small { display: block; margin-top: 12px; font: 400 13px/1 'Lexend', sans-serif; color: #678788; }
.badges { display: flex; justify-content: space-between; padding: 14px 8px 0; }
.badge { width: 86px; text-align: center; font: 400 10px/1.2 'Lexend', sans-serif; color: var(--pg-coral); opacity: 0; transform: scale(.4); }
.badge svg { display: block; margin: 0 auto 6px; }
.prog.on .badge { animation: pg-badge .5s cubic-bezier(.3, 1.6, .5, 1) forwards; }
.prog.on .badge:nth-child(2) { animation-delay: .15s; }
.prog.on .badge:nth-child(3) { animation-delay: .3s; }
@keyframes pg-badge { to { opacity: 1; transform: none; } }

/* ---------- iterations rail ---------- */
.rail { position: relative; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; margin-top: 36px; }

.rail-step { margin: 0; opacity: .38; transform: translateY(6px); transition: opacity .5s ease, transform .6s var(--pg-ease); }
.rail-step.on, .rail-step.seen { opacity: 1; transform: none; }
.rail-step.seen:not(.on) { opacity: .35; }
.rail-shot {
  height: 330px; border-radius: 12px; background: var(--pg-stage);
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  box-shadow: 0 0 0 0 rgba(0, 193, 198, 0); transition: box-shadow .5s ease;
}
/* selected: a thin, light hairline; the opacity gap does the real work */
.rail { --rail-on: #D3D8D9; }
:root[data-theme="dark"] .rail { --rail-on: #44484B; }
.rail-step.on .rail-shot { box-shadow: 0 0 0 1px var(--rail-on); }
/* every version is clickable: picking one stops the loop and keeps it lit */
.rail-step { cursor: pointer; outline: none; }
.rail-step:hover { opacity: 1; }
.rail-step:hover:not(.on) .rail-shot { box-shadow: 0 0 0 1px var(--rail-on); }
.rail-step:focus-visible .rail-shot { box-shadow: 0 0 0 2px var(--pg-leader); }
.rail.manual .rail-step:not(.on) { opacity: .35; transform: none; }
.rail.manual .rail-step:not(.on):hover { opacity: 1; }
.rail-shot > img { display: block; width: auto; height: 300px; max-width: 92%; object-fit: contain; border-radius: 10px; }
.rail-mini { position: relative; width: 146px; height: 306px; }
.rail-mini .iphone { position: absolute; left: 0; top: 0; }
.rail-step figcaption { margin-top: 12px; font-size: 15px; line-height: 1.4; color: var(--head); font-weight: 400; letter-spacing: -.01em; }
.rail-v { display: block; margin-bottom: 4px; font-family: "Play", sans-serif; font-size: 13px; color: var(--accent); text-transform: uppercase; }

/* ---------- testing ---------- */
.test-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; margin-top: 32px; }
.test-card { margin: 0; padding: 24px; border-radius: 12px; background: var(--pg-stage); display: flex; flex-direction: column; }
.test-card figcaption { margin-top: auto; padding-top: 20px; }
/* the popular times chart sits centred in the space above its caption,
   level with the A/B phones beside it */
#times-card .times { margin-block: auto; }
#times-card figcaption { margin-top: 0; }
.test-q { margin: 0; font-size: 17px; line-height: 1.4; font-weight: 400; letter-spacing: -.01em; color: var(--head); }
.test-a { margin: 6px 0 0; font-size: 14px; line-height: 1.5; color: var(--body); }

.times { background: #fff; border-radius: 18px; padding: 16px 18px 12px; box-shadow: 0 10px 26px -16px rgba(1, 55, 57, .35); font-family: 'Lexend', sans-serif; }
.times-head { display: flex; justify-content: space-between; align-items: center; font: 400 15px/1 'Lexend', sans-serif; color: #345F61; }
.times-day { padding: 5px 10px; border-radius: 12px; background: #F4F9F9; font-size: 12px; color: #345F61; }
/* the plot keeps the app's own chart proportions (302 x 92 in the Figma card)
   instead of a fixed height, so a narrower card never stretches the bars tall */
.times-plot { position: relative; aspect-ratio: 302 / 92; margin-top: 26px; --w: 0%; }
.times-layer { position: absolute; inset: 0; display: flex; align-items: flex-end; gap: 5px; }
.times-layer.after { clip-path: inset(0 calc(100% - var(--w)) 0 0); }
.times-layer i { flex: 1; border-radius: 6px 6px 3px 3px; position: relative; }
.times-layer i.now::after {
  content: attr(data-l); position: absolute; left: 50%; bottom: calc(100% + 18px); transform: translateX(-50%);
  font: 400 9px/1 'Lexend', sans-serif; color: inherit; white-space: nowrap;
}
.times-layer i.now::before {
  content: ''; position: absolute; left: 50%; bottom: 100%; height: 16px; border-left: 1px dashed currentColor;
}
.times-wipe {
  position: absolute; top: -10px; bottom: 0; left: var(--w); width: 2px; margin-left: -1px;
  background: var(--pg-ink); border-radius: 1px;
}
.times-wipe::before {
  content: attr(data-l); position: absolute; top: -16px; left: 50%; transform: translateX(-50%);
  padding: 3px 7px; border-radius: 8px; background: var(--pg-ink); color: #fff;
  font: 500 10px/1 'Lexend', sans-serif; white-space: nowrap;
}
.times-axis { display: flex; justify-content: space-between; margin-top: 8px; font: 400 10px/1 'Lexend', sans-serif; color: #33CDD1; }

.ab { display: flex; gap: 22px; justify-content: center; }
.ab-opt { flex: 1; max-width: 168px; text-align: center; transition: opacity .5s ease, transform .6s var(--pg-ease); }
.ab-label { display: block; margin-bottom: 14px; font-size: 13px; font-weight: 400; color: var(--head); }
.ab-phone { position: relative; width: 100%; }
.ab-phone .iphone { position: absolute; left: 0; top: 0; }
.ab-phone .iphone::before { transition: box-shadow .5s ease; }
.ab.decided .ab-opt.win .iphone::before {
  box-shadow: inset 0 0 0 1px #3a3e42, 0 0 0 2px #8a8f94, 0 0 0 3px #50555a, 0 0 0 12px var(--pg-teal), 0 36px 70px -28px rgba(1, 55, 57, .38);
}
.ab-opt.win::after {
  content: '\2713'; display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; margin-top: 14px; border-radius: 50%;
  background: var(--pg-teal); color: #fff; font-size: 14px; font-weight: 700;
  transform: scale(0); transition: transform .45s cubic-bezier(.3, 1.6, .5, 1);
}
.ab-opt:not(.win)::after { content: ''; display: block; height: 38px; }
.ab.decided .ab-opt.win::after { transform: none; }
.ab.decided .ab-opt:not(.win) { opacity: .45; transform: scale(.96); }
/* B is shown as a still: the guest pass is already picked */
.ab-b .qr-wrap, .ab-b .qr-card .wallet { transition: none; }

/* Version A: the check-in page scrolled down, Bring a friend at the bottom */
.vera { background: #FAF8F7; }
.va-col { position: absolute; left: 27px; top: 64px; width: 334px; display: flex; flex-direction: column; gap: 14px; }
.va-wallet { position: relative; left: 44px; top: 0; }
.va-col .tiles { margin-top: 10px; }
.va-col .tile { position: relative; }
.va-ring {
  position: absolute; left: 50%; top: 52px; width: 84px; height: 84px; margin-left: -42px; border-radius: 50%;
  background: conic-gradient(var(--pg-teal) 0 75%, #E3F4F4 75% 100%);
  display: flex; align-items: center; justify-content: center;
}
.va-ring::before { content: ''; position: absolute; inset: 9px; border-radius: 50%; background: #fff; }
.va-ring b { position: relative; font: 500 15px/1 'Lexend', sans-serif; color: #66DADD; }
.va-big { display: block; margin-top: 18px; font: 700 62px/1 'Roboto Condensed', sans-serif; color: var(--pg-coral); }
.va-card { background: #fff; border-radius: 22px; box-shadow: inset 0 0 4px rgba(153, 175, 176, .5); }
.va-times { padding: 14px 16px 16px; }
.va-times-head { display: flex; justify-content: space-between; align-items: center; font: 500 13px/1 'Lexend', sans-serif; color: #678788; }
.va-day { padding: 4px 9px; border-radius: 10px; background: #F4F9F9; font-size: 11px; color: #345F61; }
.va-bars { height: 92px; margin-top: 16px; display: flex; align-items: flex-end; gap: 4px; }
.va-bars i { flex: 1; border-radius: 5px 5px 3px 3px; }
.va-friend { position: relative; padding: 16px 0 22px; text-align: center; }
.va-label { margin: 0 0 14px 18px !important; text-align: left; font: 500 13px/1 'Lexend', sans-serif; color: #678788; }
.va-friend .g-big b { font-size: 60px; }
.va-friend .g-big span { font-size: 20px; }
.va-share { margin-top: 18px; }
/* ---------- success means ---------- */
.metrics { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; margin-top: 32px; }
.metric { padding: 22px; border-radius: 12px; background: var(--pg-stage); }
.m-viz { height: 64px; display: flex; align-items: center; gap: 10px; }
.m-name { margin: 14px 0 0; font-size: 17px; line-height: 1.35; font-weight: 400; letter-spacing: -.01em; color: var(--head); }
.m-why { margin: 6px 0 0; font-size: 14px; line-height: 1.5; color: var(--body); }
/* time to the code: tap the app icon, it opens straight onto the QR, the
   timer beside it stops (loop 3.2s, timer driven from JS in step) */
.m-open { position: relative; width: 44px; height: 64px; }
.m-icon {
  position: absolute; left: 6px; top: 16px; width: 32px; height: 32px; border-radius: 9px;
  background: var(--pg-teal);
  box-shadow: 0 6px 14px -6px rgba(0, 120, 124, .55);
}
.m-icon::after { /* the PureGym mark, simplified: a white P */
  content: 'P'; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font: 700 17px/1 'Roboto Condensed', sans-serif; color: #fff;
}
.m-scr {
  position: absolute; left: 4px; top: 0; width: 36px; height: 64px; border-radius: 8px;
  background: #fff; box-shadow: 0 0 0 1.5px #D7E6E6, 0 8px 18px -10px rgba(1, 55, 57, .45);
  opacity: 0; transform: scale(.45); transform-origin: 50% 50%;
}
.m-scr i { position: absolute; left: 7px; top: 19px; width: 22px; height: 22px; background: url('assets/puregym/v2/ui/qr.svg') center / contain no-repeat; }
.metrics.in .m-icon { animation: pg-app 3.2s var(--pg-ease) infinite; }
.metrics.in .m-scr { animation: pg-scr 3.2s var(--pg-ease) infinite; }
@keyframes pg-app { 0%, 8% { transform: none; opacity: 1; } 12% { transform: scale(.86); } 22%, 92% { transform: scale(1.4); opacity: 0; } 100% { transform: none; opacity: 1; } }
@keyframes pg-scr { 0%, 14% { opacity: 0; transform: scale(.45); } 30%, 88% { opacity: 1; transform: none; } 100% { opacity: 0; transform: scale(.45); } }
.m-secs {
  margin-left: 6px; padding: 7px 12px; border-radius: 20px; min-width: 62px; text-align: center;
  font-size: 14px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--head);
  background: rgba(var(--ink-rgb), .06); transition: background .3s ease, color .3s ease;
}
.m-secs.done { background: rgba(0, 193, 198, .14); color: #0A8A8E; }
:root[data-theme="dark"] .m-secs.done { color: #6FE0E3; }.m-gate { display: flex; gap: 8px; }
.m-gate i { width: 22px; height: 22px; border-radius: 7px; background: rgba(var(--ink-rgb), .08); position: relative; }
.metrics.in .m-gate i { animation: pg-gate 3s ease infinite; }
.m-gate i:nth-child(2) { animation-delay: .25s !important; }
.m-gate i:nth-child(3) { animation-delay: .5s !important; }
.m-gate i:nth-child(4) { animation-delay: .75s !important; }
.m-gate i:nth-child(5) { animation-delay: 1s !important; }
@keyframes pg-gate { 0%, 8% { background: rgba(var(--ink-rgb), .08); } 18%, 85% { background: var(--pg-teal); } 100% { background: rgba(var(--ink-rgb), .08); } }
.metrics.in .m-gate i.x { animation-name: pg-gate-x; }
@keyframes pg-gate-x { 0%, 8% { background: rgba(var(--ink-rgb), .08); } 18%, 40% { background: var(--pg-coral); } 55%, 85% { background: var(--pg-teal); } 100% { background: rgba(var(--ink-rgb), .08); } }
.m-link { width: 34px; height: 34px; border-radius: 50%; background: var(--pg-coral) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2.2' stroke-linecap='round'%3E%3Cpath d='M10 13a5 5 0 0 0 7 0l3-3a5 5 0 0 0-7-7l-1 1'/%3E%3Cpath d='M14 11a5 5 0 0 0-7 0l-3 3a5 5 0 0 0 7 7l1-1'/%3E%3C/svg%3E") center no-repeat; }
.m-dots { display: flex; gap: 6px; }
.m-dots i { width: 14px; height: 14px; border-radius: 50%; background: var(--pg-coral); opacity: 0; transform: scale(.3); }
.metrics.in .m-dots i { animation: pg-share 3s cubic-bezier(.3, 1.6, .5, 1) infinite; }
.m-dots i:nth-child(2) { animation-delay: .3s !important; }
.m-dots i:nth-child(3) { animation-delay: .6s !important; }
.m-dots i:nth-child(4) { animation-delay: .9s !important; }
.m-dots i:nth-child(5) { animation-delay: 1.2s !important; }
@keyframes pg-share { 0% { opacity: 0; transform: scale(.3); } 12%, 80% { opacity: 1; transform: none; } 100% { opacity: 0; transform: scale(.3); } }
/* Add to Wallet: a light pass sliding into a soft teal wallet; the front
   pocket is lighter than the back, with an edge, so it reads as two layers */
.m-pass { position: relative; width: 74px; height: 50px; border-radius: 10px; background: #CDEFEF; overflow: hidden; }
.m-pass::before {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 24px; z-index: 2;
  background: #F3FBFB; border-radius: 8px 8px 10px 10px;
  box-shadow: 0 -1px 0 rgba(0, 150, 155, .18), 0 -6px 10px -6px rgba(1, 55, 57, .25);
}
.m-pass i { position: absolute; left: 9px; right: 9px; top: 7px; height: 30px; border-radius: 5px; background: var(--pg-teal-2); transform: translateY(-48px); }
.m-pass i::after { content: ''; position: absolute; left: 6px; top: 6px; width: 12px; height: 12px; border-radius: 2px; background: rgba(255, 255, 255, .8); }
:root[data-theme="dark"] .m-pass { background: #20484A; }
:root[data-theme="dark"] .m-pass::before { background: #2E5F61; }
.metrics.in .m-pass i { animation: pg-pass 2.6s var(--pg-ease) infinite; }
@keyframes pg-pass { 0%, 10% { transform: translateY(-48px); } 45%, 85% { transform: none; } 100% { transform: translateY(-48px); } }
/* ---------- what I'd do next: a list with a header, like a backlog ---------- */
.todo { margin-top: 32px; border-radius: 12px; background: var(--pg-stage); overflow: hidden; }
.todo-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 16px 24px; border-bottom: 1px solid var(--rule);
}
.todo-title { font-size: 15px; font-weight: 400; color: var(--head); }
.todo-count { font-size: 13px; color: var(--caption); font-variant-numeric: tabular-nums; }
.todo ul { list-style: none; margin: 0; padding: 6px 24px 10px; }
.todo li {
  display: grid; grid-template-columns: minmax(0, 220px) 1fr; gap: 4px 24px; align-items: baseline;
  padding: 13px 0;
  opacity: 0; transform: translateY(6px); transition: opacity .4s ease, transform .5s var(--pg-ease);
}
.todo li + li { border-top: 1px solid var(--rule); }
.todo li.in { opacity: 1; transform: none; }
.todo li b { font-size: 15px; font-weight: 400; color: var(--head); }
.todo li em { font-style: normal; font-size: 14px; line-height: 1.5; color: var(--body); }
@media (max-width: 600px) { .todo li { grid-template-columns: 1fr; } }
/* ---------- reflection ---------- */
.lessons { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 32px; margin-top: 8px; }
/* outside the frames: the portfolio label style (Play, site blue), as in the meta row */
.lesson-n { font-family: "Play", sans-serif; font-size: 16px; color: var(--accent); }
.lesson-t { margin: 8px 0 0; font-size: 20px; line-height: 1.3; font-weight: 400; letter-spacing: -.015em; color: var(--head); }
.lesson-b { margin: 8px 0 0; font-size: 15px; line-height: 1.55; color: var(--body); }


/* ---------- narrow column ---------- */
@media (max-width: 760px) {
  .rail { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 28px; }
  .rail-shot { height: 280px; }
  .rail-shot > img { height: 256px; }
  .test-grid, .metrics, .lessons { grid-template-columns: 1fr; }
  .demo-stage { height: 520px; }
  .demo-title { font-size: 18px; }
}

@media (prefers-reduced-motion: reduce) {
  .finger, .sheet, .sheet-page, .prog, .rail-step, .todo li { transition: none; }
  .metrics.in * { animation: none !important; }
}

@media (prefers-reduced-motion: reduce) {
  .gym-row, .gymname-roll, .gymname-roll span, .iphone [data-part], .callout, .leaders path, .p-close, .old::after, .old-phone .old-piece { transition: none; }
}



/* ---------- final design: Jen's screen recordings in the same iPhone frame ----------
   The recordings are 1920x1080 with the phone drawn in them. The video is
   scaled so the recorded screen (416 x 902 px, top edge at y 88, left edge at
   data-x) lands exactly on this phone's 393 x 852 screen; the frame, island and
   status bar on top are the page's own, so it matches the demos above. */
.iphone.rec .screen { background: #FAF8F7; border-radius: 53px; } /* the recording's own screen corners are a touch rounder */
.iphone.rec video {
  position: absolute; left: 0; top: 0; max-width: none;
  width: 1814px; height: 1020px;                /* 1920 x 1080 at 393/416 */
  transform: translate(var(--rx, 0px), -83px);
  pointer-events: none;
}
/* the recording's island sits exactly under the page's own (124 x 36 at top 11) */
