/* Hero: copy beside the Today screen on an iPhone that rests flat and sharp, leans toward a
   pointer that comes near it, and is lit from behind by brand-blue light. hero.js writes four
   custom properties on the stage: --tilt-x / --tilt-y (degrees) and --shift-x / --shift-y
   (-1..1, where the light sits). At rest the device carries no transform at all, so the
   screenshot is drawn pixel for pixel. */
.s-hero {
  --hero-header-height: 56px;
  --hero-phone-width: var(--phone-width);
  --hero-pad-bottom: 64px;
  --hero-screen-ratio: 0.4613; /* screenshot width / height: 1179 / 2556 */
  --hero-chrome: 196px; /* desktop height not given to the phone: header, padding, caption */
  --hero-reach: 420px; /* how far the light may spread above the stage */
  --hero-fade: 260px; /* the light dissolves into the canvas over this distance */
  --hero-phone-min: 240px;
  --hero-cta-gap: 6px;
  --hero-step: 28px;
  --hero-tile: 112px;
  --hero-metal: color-mix(in srgb, var(--ink) 82%, white);
  --hero-edge: 5px; /* thickness of the frame's side, seen when the phone is turned */
  position: relative;
  /* The hero starts behind the sticky header so its wash runs to the top of the page. */
  margin-top: calc(-1 * var(--hero-header-height));
  padding-block: calc(var(--hero-header-height) + var(--space-lg)) var(--hero-pad-bottom);
  overflow: clip;
  isolation: isolate;
}

.s-hero .hero-wash {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(180deg, var(--jet-tint) 0%, var(--canvas) 88%);
}

.s-hero .hero-layout {
  display: grid;
  gap: var(--hero-step);
  justify-items: center;
}

/* Copy */
.s-hero .hero-copy {
  display: grid;
  justify-items: center;
  text-align: center;
  max-width: 36rem;
  /* Above the stage, whose light spills up behind the copy. */
  position: relative;
  z-index: 1;
}

/* The mascot: the take-off scene on a tinted tile, bobbing gently. */
.s-hero .hero-mascot {
  width: var(--hero-tile);
  padding: var(--space-md);
  background: color-mix(in srgb, var(--jet) 16%, white);
  border-radius: var(--radius-card-large);
}

.s-hero .hero-mascot-art {
  display: block;
  width: 100%;
  height: auto;
}

.s-hero .hero-title {
  margin-top: var(--space-lg);
  max-width: 11em;
}

.s-hero .hero-lede {
  margin-top: var(--space-xl);
  max-width: 21rem;
  text-wrap: balance;
}

.s-hero .hero-cta {
  display: grid;
  justify-items: center;
  gap: var(--hero-cta-gap);
  margin-top: var(--hero-step);
}

/* A status, not a button: a little lower and quieter than the shared pill. */
.s-hero .hero-cta .pill {
  min-height: 48px;
  padding-inline: var(--space-xxl);
  font-size: 16px;
  letter-spacing: -0.01em;
}

.s-hero .hero-meta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  margin-top: var(--hero-cta-gap);
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-secondary);
}

.s-hero .hero-meta li {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}

.s-hero .hero-meta li + li::before {
  content: "";
  width: 3px;
  height: 3px;
  margin-inline: 6px;
  background: var(--ink-quaternary);
  border-radius: 50%;
}

/* Stage */
.s-hero .hero-stage {
  --tilt-x: 0;
  --tilt-y: 0;
  --shift-x: 0;
  --shift-y: 0;
  --phone-width: var(--hero-phone-width);
  --stage-pad-start: 0px;
  --stage-pad-end: 0px;
  /* The phone's centre line: the light is built around it, not around the stage box. */
  --axis: calc(50% + (var(--stage-pad-start) - var(--stage-pad-end)) / 2);
  --pool-size: 720px;
  --pool-top: 46%;
  --bloom-size: 420px;
  --rings-size: 880px;
  --ring-gap: 56px;
  position: relative;
  display: grid;
  justify-items: center;
  gap: var(--space-xxxl);
  padding-inline: var(--stage-pad-start) var(--stage-pad-end);
  perspective: 1500px;
}

/* The light behind the phone, in three layers: a wide blue pool set low, fine rings that
   echo the readiness ring, and a white bloom close to the glass. They slide by different
   amounts as the light moves, which is what gives depth. The layer is far larger than the
   stage and masked at the bottom, so the light always dissolves into the canvas and is
   never cut by the section edge. */
.s-hero .hero-atmosphere {
  position: absolute;
  inset: calc(-1 * var(--hero-reach)) -50vw calc(-1 * var(--hero-pad-bottom));
  z-index: -1;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to top, transparent, #000 var(--hero-fade));
  mask-image: linear-gradient(to top, transparent, #000 var(--hero-fade));
}

/* The stage box again, so the layers can be placed against the phone. */
.s-hero .hero-field {
  position: absolute;
  inset: var(--hero-reach) 50vw var(--hero-pad-bottom);
}

.s-hero .hero-pool,
.s-hero .hero-rings,
.s-hero .hero-bloom {
  --size: var(--pool-size);
  position: absolute;
  top: var(--pool-top);
  left: var(--axis);
  width: var(--size);
  height: var(--size);
  margin: calc(var(--size) / -2) 0 0 calc(var(--size) / -2);
  border-radius: 50%;
}

.s-hero .hero-pool {
  background: radial-gradient(
    closest-side,
    color-mix(in srgb, var(--jet) 38%, transparent) 0%,
    color-mix(in srgb, var(--jet) 24%, transparent) 34%,
    color-mix(in srgb, var(--jet) 9%, transparent) 66%,
    transparent 100%
  );
  transform: translate3d(calc(var(--shift-x) * -36px), calc(var(--shift-y) * -24px), 0);
}

.s-hero .hero-rings {
  --size: var(--rings-size);
  background: repeating-radial-gradient(
    circle,
    transparent 0,
    transparent calc(var(--ring-gap) - 1.5px),
    color-mix(in srgb, var(--surface) 60%, transparent) calc(var(--ring-gap) - 1px),
    color-mix(in srgb, var(--surface) 60%, transparent) var(--ring-gap)
  );
  -webkit-mask-image: radial-gradient(closest-side, #000 30%, transparent 96%);
  mask-image: radial-gradient(closest-side, #000 30%, transparent 96%);
  transform: translate3d(calc(var(--shift-x) * -14px), calc(var(--shift-y) * -10px), 0);
}

.s-hero .hero-bloom {
  --size: var(--bloom-size);
  top: 16%;
  background: radial-gradient(closest-side, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.5) 45%, transparent 100%);
  transform: translate3d(calc(var(--shift-x) * 64px - 16%), calc(var(--shift-y) * 40px), 0);
}

/* --rest-x / --rest-y: the pose the phone holds when nothing moves it. Flat on small screens,
   turned a little toward the copy on wide ones, so the device reads as an object with depth. */
.s-hero .hero-device {
  --rest-x: 0deg;
  --rest-y: 0deg;
  position: relative;
  transform: rotateX(calc(var(--tilt-x) * 1deg + var(--rest-x))) rotateY(calc(var(--tilt-y) * 1deg + var(--rest-y)));
  transform-style: preserve-3d;
  touch-action: pan-y;
}

/* Small screens: no lean means no transform, so the screenshot is drawn flat and sharp. */
@media (max-width: 899px) {
  .s-hero .hero-stage:not(.is-live) > .hero-device,
  .s-hero .hero-stage.is-flat > .hero-device {
    transform: none;
  }
}

/* The shadow where the phone meets the ground. */
.s-hero .hero-ground {
  position: absolute;
  inset: auto 4% -22px;
  height: 40px;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--jet-ink) 42%, transparent), transparent);
  transform: translate3d(calc(var(--shift-x) * -10px), 0, 0);
}

.s-hero .phone {
  position: relative;
  background: none;
  box-shadow:
    0 2px 4px color-mix(in srgb, var(--jet-ink) 20%, transparent),
    0 22px 40px -20px color-mix(in srgb, var(--jet-ink) 38%, transparent),
    0 60px 100px -36px color-mix(in srgb, var(--jet-ink) 46%, transparent);
}

/* Side buttons: one bar per side, the rest drawn as shadows of it. */
.s-hero .phone::before,
.s-hero .phone::after {
  content: "";
  position: absolute;
  width: 3px;
  background: var(--hero-metal);
  border-radius: 2px;
}

.s-hero .phone::before {
  top: 17%;
  left: -2px;
  height: 4.5%;
  box-shadow:
    0 calc(var(--phone-width) * 0.17) 0 var(--hero-metal),
    0 calc(var(--phone-width) * 0.34) 0 var(--hero-metal);
}

.s-hero .phone::after {
  top: 27%;
  right: -2px;
  height: 11%;
}

/* The frame: a metal edge, a black bezel inside it, and a small light that travels along the edge. */
.s-hero .hero-rim {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: inherit;
  background: linear-gradient(
    140deg,
    color-mix(in srgb, var(--ink) 46%, white) 0%,
    color-mix(in srgb, var(--ink) 78%, white) 20%,
    color-mix(in srgb, var(--ink) 94%, white) 50%,
    color-mix(in srgb, var(--ink) 74%, white) 80%,
    color-mix(in srgb, var(--ink) 54%, white) 100%
  );
}

.s-hero .hero-rim::after {
  content: "";
  position: absolute;
  inset: 2px;
  background: var(--ink);
  border-radius: calc(var(--phone-screen-radius) + var(--phone-bezel) - 2px);
}

.s-hero .hero-rim-light {
  position: absolute;
  z-index: 1;
  top: -18%;
  left: 30%;
  width: 40%;
  aspect-ratio: 1;
  background: radial-gradient(closest-side, rgba(255, 255, 255, 0.78), rgba(255, 255, 255, 0.22) 45%, transparent 72%);
  transform: translate3d(calc(var(--shift-x) * 125%), calc(var(--shift-y) * 90%), 0);
}

.s-hero .phone-screen {
  z-index: 1;
}

/* A faint shade on the glass that slides opposite the light. */
.s-hero .hero-sheen {
  position: absolute;
  inset: -40%;
  background: linear-gradient(
    115deg,
    transparent 36%,
    color-mix(in srgb, var(--jet-ink) 7%, transparent) 60%,
    transparent 84%
  );
  transform: translate3d(calc(var(--shift-x) * -30%), calc(var(--shift-y) * -16%), 0);
  pointer-events: none;
}

/* Two notes that say what the screen cannot: the plan moved, and the coach can say why.
   Decorative. They appear only where there is room beside the phone, hang off its right
   edge and overlap the frame, never the screen content. The caption under the phone marks
   the whole scene as an example. */
.s-hero .hero-chip {
  --chip-overlap: calc(var(--phone-bezel) + 10px);
  --chip-drift: 10px;
  --chip-lift: 36px; /* how far the notes float in front of the glass when the phone is turned */
  position: absolute;
  z-index: 2;
  left: calc(100% - var(--chip-overlap));
  display: none;
  padding: 13px 18px 14px 16px;
  background: var(--surface);
  border-radius: 18px;
  box-shadow:
    0 1px 2px color-mix(in srgb, var(--jet-ink) 10%, transparent),
    0 18px 40px -14px color-mix(in srgb, var(--jet-ink) 38%, transparent);
  white-space: nowrap;
  transform: translate3d(calc(var(--shift-x) * var(--chip-drift)), calc(var(--shift-y) * var(--chip-drift) * 0.6), var(--chip-lift));
}

.s-hero .hero-chip-plan {
  top: 13%;
  align-items: center;
  gap: var(--space-md);
}

.s-hero .hero-chip-coach {
  top: 61%;
}

.s-hero .hero-chip-label,
.s-hero .hero-chip-name,
.s-hero .hero-chip-detail,
.s-hero .hero-chip-text {
  display: block;
}

.s-hero .hero-chip-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--ink-tertiary);
}

.s-hero .hero-chip-coach .hero-chip-label {
  color: var(--jet);
}

.s-hero .hero-chip-name {
  margin-top: 2px;
  font-size: 15px;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.01em;
}

.s-hero .hero-chip-detail {
  font-size: 13px;
  line-height: 1.4;
  color: var(--ink-secondary);
}

/* Reps per set, week by week: eight, eight, then ten. */
.s-hero .hero-chip-bars {
  display: flex;
  align-items: flex-end;
  gap: 4px;
  height: 42px;
}

.s-hero .hero-chip-bar {
  width: 8px;
  height: 80%;
  background: var(--ink-quaternary);
  border-radius: 4px;
  transform-origin: bottom;
}

.s-hero .hero-chip-bar:last-child {
  height: 100%;
  background: var(--jet);
}

.s-hero .hero-note {
  position: relative;
  text-align: center;
  text-wrap: balance;
}

/* The narrowest phones: the three facts stay on one line. */
@media (max-width: 359px) {
  .s-hero .hero-cta .pill {
    padding-inline: var(--space-xl);
    font-size: 15px;
    white-space: nowrap;
  }

  .s-hero .hero-meta {
    flex-wrap: nowrap;
    margin-inline: calc(-1 * var(--space-sm));
    font-size: 12px;
    letter-spacing: -0.01em;
  }

  .s-hero .hero-meta li + li::before {
    margin-inline: 5px;
  }
}

@media (min-width: 640px) {
  .s-hero {
    --hero-header-height: 64px;
    --hero-pad-bottom: 72px;
    padding-top: calc(var(--hero-header-height) + var(--space-xxxl));
  }

  .s-hero .hero-layout {
    gap: 44px;
  }

  .s-hero .hero-lede {
    max-width: 33rem;
  }


  .s-hero .hero-cta {
    margin-top: var(--space-xxl);
  }

  .s-hero .hero-cta .pill {
    min-height: 50px;
    padding-inline: var(--hero-step);
  }

  .s-hero .hero-meta li + li::before {
    margin-inline: 10px;
  }

  .s-hero .hero-stage {
    --pool-size: 920px;
    --bloom-size: 520px;
    --rings-size: 1100px;
  }
}

@media (min-width: 900px) {
  .s-hero {
    /* As tall as the first screen allows, with room above it under the header and below it
       for the caption. */
    --hero-phone-width: clamp(var(--hero-phone-min), calc((100svh - var(--hero-chrome)) * var(--hero-screen-ratio)), 340px);
    padding-top: calc(var(--hero-header-height) + var(--space-xxxl));
  }

  .s-hero .hero-layout {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    justify-items: start;
    gap: var(--space-xxxl);
  }

  .s-hero .hero-copy {
    justify-items: start;
    text-align: left;
    padding-bottom: var(--space-xxl);
  }

  .s-hero .hero-title {
    font-size: clamp(54px, 5.6vw, 72px);
    max-width: 8.6em;
  }

  .s-hero .hero-lede {
    margin-top: var(--hero-step);
    max-width: 29rem;
    text-wrap: pretty;
  }

  /* One action group: 16px from the status to the link, 20px from the link to the facts
     (the link's own 44px box supplies the rest). */
  .s-hero .hero-cta {
    justify-items: start;
    margin-top: var(--space-xxxl);
  }

  .s-hero .hero-meta {
    justify-content: flex-start;
    margin-top: var(--space-md);
  }

  .s-hero .hero-stage {
    --stage-pad-start: 40px;
    --stage-pad-end: 40px;
    --pool-size: 1040px;
    --pool-top: 46%;
    --bloom-size: 560px;
    --rings-size: 1240px;
    --ring-gap: 64px;
    gap: var(--hero-step);
  }

  .s-hero .hero-ground {
    inset: auto 6% -16px;
    height: 32px;
  }

  /* The resting pose: turned toward the copy, with the near edge of the frame catching light
     and a longer shadow falling away from it. */
  .s-hero .hero-device {
    --rest-x: 2deg;
    --rest-y: 7deg;
  }

  .s-hero .phone {
    box-shadow:
      var(--hero-edge) 0 0 0 var(--hero-metal),
      calc(var(--hero-edge) + 1px) 0 0 0 color-mix(in srgb, var(--ink) 55%, white),
      0 2px 4px color-mix(in srgb, var(--jet-ink) 20%, transparent),
      24px 22px 40px -20px color-mix(in srgb, var(--jet-ink) 40%, transparent),
      40px 40px 64px -30px color-mix(in srgb, var(--jet-ink) 46%, transparent);
  }
}

/* Room beside the phone for the two notes. */
@media (min-width: 1100px) {
  .s-hero .hero-stage {
    --stage-pad-start: 16px;
    --stage-pad-end: 212px;
  }

  .s-hero .hero-chip {
    display: block;
  }

  .s-hero .hero-chip-plan {
    display: flex;
  }
}

/* Short laptop screens: the copy starts at the top and tightens so the status, the mail
   link and the three facts all stay on the first screen beside a smaller phone, and the
   caption sits whole above the fold. */
@media (min-width: 900px) and (max-height: 720px) {
  .s-hero {
    --hero-chrome: 150px;
    --hero-phone-min: 212px;
    padding-top: calc(var(--hero-header-height) + var(--space-md));
  }

  .s-hero .hero-layout {
    align-items: start;
  }

  .s-hero .hero-copy {
    padding-block: var(--space-lg) 0;
  }

  .s-hero .hero-title {
    font-size: clamp(48px, 4.4vw, 56px);
  }

  .s-hero .hero-lede {
    margin-top: var(--space-xl);
    font-size: 17px;
  }

  .s-hero .hero-cta {
    --hero-cta-gap: 2px;
    margin-top: var(--space-xl);
  }

  .s-hero .hero-meta {
    margin-top: var(--space-sm);
  }

  .s-hero .hero-stage {
    gap: var(--space-lg);
  }
}

/* Entrance: copy rises in sequence; the phone settles into place and is never hidden. */
@media (prefers-reduced-motion: no-preference) {
  .js .s-hero .hero-label,
  .js .s-hero .hero-title,
  .js .s-hero .hero-lede,
  .js .s-hero .hero-cta,
  .js .s-hero .hero-meta,
  .js .s-hero .hero-note {
    animation: hero-rise 0.9s var(--ease-standard) both;
  }

  .js .s-hero .hero-title {
    animation-delay: 0.08s;
  }

  .js .s-hero .hero-lede {
    animation-delay: 0.18s;
  }

  .js .s-hero .hero-cta {
    animation-delay: 0.28s;
  }

  .js .s-hero .hero-meta {
    animation-delay: 0.38s;
  }

  .js .s-hero .hero-note {
    animation-delay: 0.9s;
  }

  /* The device turns once as it lands, which shows that it can be turned. */
  .js .s-hero .hero-stage > .hero-device {
    animation: hero-settle 1.3s var(--ease-standard) backwards;
  }

  .js .s-hero .hero-atmosphere {
    animation: hero-fade 1.6s var(--ease-standard) both;
  }

  /* The notes arrive once the phone has settled. */
  .js .s-hero .hero-chip {
    animation: hero-note-in 0.8s var(--ease-standard) 1.15s both;
  }

  .js .s-hero .hero-chip-coach {
    animation-delay: 1.6s;
  }

  .js .s-hero .hero-chip-bar {
    animation: hero-grow 0.7s var(--ease-standard) 1.35s backwards;
  }

  .js .s-hero .hero-chip-bar:nth-child(2) {
    animation-delay: 1.45s;
  }

  .js .s-hero .hero-chip-bar:nth-child(3) {
    animation-delay: 1.55s;
  }
}

/* Once the entrance is done, hero.js drives the lean and the easing lives there. */
.js .s-hero .hero-stage.is-live > .hero-device {
  animation: none;
}

@keyframes hero-rise {
  from {
    opacity: 0;
    transform: translateY(16px);
  }
}

@keyframes hero-settle {
  from {
    transform: translateY(28px) rotateX(calc(var(--rest-x) + 4deg)) rotateY(calc(var(--rest-y) - 9deg)) scale(0.97);
  }

  to {
    transform: rotateX(var(--rest-x)) rotateY(var(--rest-y));
  }
}

@keyframes hero-note-in {
  from {
    opacity: 0;
    translate: 0 10px;
  }
}

@keyframes hero-fade {
  from {
    opacity: 0;
  }
}

@keyframes hero-grow {
  from {
    transform: scaleY(0);
  }
}

@media (min-width: 900px) {
  .s-hero {
    --hero-tile: 148px;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .s-hero .hero-mascot-art {
    animation: hero-float 3s ease-in-out infinite alternate;
  }
}

@keyframes hero-float {
  from {
    transform: translateY(4px) rotate(-1.5deg);
  }

  to {
    transform: translateY(-4px) rotate(1.5deg);
  }
}
