/* ==========================================================================
   OnTheTools homepage - "the app, as a website".

   The page is built the way the app's screens are: the orange gradient band
   at the top with the white wordmark (site.css .site-head--band), and a white
   sheet with rounded top corners sitting over the band. Everything after it
   is sheets and cards: white, hairline edges, soft black shadows, real app
   screens in slim device frames. The page ends the way it starts: a white
   sheet lifts off a band of orange (the launch lockup), and the footer is a
   last sheet over it.

   Colour: white, ink, grey, the app's page grey behind white cards. Orange
   is the band, the launch moment, and small marks (a dot, a drawn line, a
   page dot). No other colour slab.

   Motion echoes the app: the sheet rises, cards lift, screens slide up like
   the app's sheets, the nut turns. All of it is transform/opacity, all of it
   is off under prefers-reduced-motion, and nothing is hidden without the
   script (the "js" class comes off after 2.5 s if home.js never runs).

   Layout only: tokens come from brand.css, shared parts from site.css.
   Breakpoints (px): 600 / 900 / 1200.
   ========================================================================== */

:root {
  --band-grad: linear-gradient(90deg, var(--c-band-1) 0%, var(--c-band-2) 56%, var(--c-band-3) 100%);
  --sheet-r: 32px;
  --ink-soft: rgba(28, 28, 30, 0.9);
  --card-shadow: 0 0 0 1px rgba(28, 28, 30, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04), 0 10px 30px -12px rgba(28, 28, 30, 0.18);
  --card-shadow-up: 0 0 0 1px rgba(28, 28, 30, 0.06), 0 2px 4px rgba(0, 0, 0, 0.05), 0 26px 50px -18px rgba(28, 28, 30, 0.3);
  --head-w: 560; /* headlines: the app's titles are bold; on the web a step lighter */
}
@media (max-width: 599px) { :root { --sheet-r: 22px; } }

/* ------------------------------------------------------------------ shared bits */
.soft { color: var(--text-2); }

.eyebrow {
  display: flex;
  align-items: center;
  color: var(--text-2);
  font-size: var(--fs-eyebrow);
  line-height: var(--lh-eyebrow);
  font-weight: var(--fw-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
}

/* the round arrow on every door (quiet grey disc, ink on hover) */
.go {
  display: grid;
  place-items: center;
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--btn-quiet-bg);
  color: var(--c-ink);
  transition: background-color var(--dur-fade) var(--ease-standard), color var(--dur-fade) var(--ease-standard),
    transform var(--dur-screen) var(--ease-out);
}
.go svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.go--sm { width: 32px; height: 32px; }
.go--sm svg { width: 15px; height: 15px; }

/* a cut-out of one card from a screen: lifted, like the app's cards */
.crop {
  width: 100%;
  border-radius: 16px;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05), 0 2px 4px rgba(0, 0, 0, 0.04), 0 30px 60px -18px rgba(28, 28, 30, 0.36);
  background: var(--c-white);
}
.crop--sheet { border-radius: 22px; }

/* the one sticker on the page: a white label with an ink icon tile */
.sticker {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 6px 15px 6px 6px;
  border-radius: 14px;
  background: var(--c-white);
  color: var(--c-ink);
  font-size: var(--fs-small);
  line-height: 1.2;
  font-weight: var(--fw-semibold);
  letter-spacing: -0.012em;
  white-space: nowrap;
  box-shadow: 0 0 0 1px rgba(28, 28, 30, 0.07), 0 1px 2px rgba(0, 0, 0, 0.06), 0 14px 30px -12px rgba(28, 28, 30, 0.38);
}
.sticker__icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 30px;
  height: 30px;
  border-radius: 9px;
  background: var(--c-ink);
  color: var(--c-white);
}
.sticker__icon svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* pause control for anything that moves on its own (WCAG 2.2.2) */
.motion-btn {
  display: grid;
  place-items: center;
  flex: none;
  width: var(--tap-min);
  height: var(--tap-min);
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--c-ink);
  color: var(--c-white);
  cursor: pointer;
  transition: transform var(--dur-press) var(--ease-standard), background-color var(--dur-fade);
}
.motion-btn[hidden] { display: none; }
.motion-btn:active { transform: var(--lift-press); }
.motion-btn--quiet { background: var(--btn-quiet-bg); color: var(--c-ink); }
.motion-btn--quiet:hover { background: var(--btn-quiet-bg-hover); }
.motion-btn svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.motion-btn__play { display: none; }
.is-still .motion-btn__play { display: block; }
.is-still .motion-btn__pause { display: none; }

/* headlines */
.display {
  max-width: 14em;
  font-size: var(--fs-display);
  line-height: 1.02;
  font-weight: var(--head-w);
  letter-spacing: -0.038em;
  text-wrap: balance;
}
/* a sentence (or a closing phrase) wraps as one piece while it fits, so a
   line of two or three sentences breaks between them, never inside one */
.phrase { display: inline-block; }
.lead {
  max-width: 24em;
  text-wrap: balance;
  color: var(--text-2);
  font-size: var(--fs-lead);
  line-height: var(--lh-lead);
  letter-spacing: var(--ls-lead);
}

/* ------------------------------------------------------------------ the hero: band, then the sheet */
/* the band carries on below the header (same left-to-right gradient, so no
   seam), and the white sheet sits over its bottom edge */
.hero {
  /* the band below the header: deep enough on phones that the whole icon
     (and its white ring) clears the condensed header */
  --ext: clamp(46px, 3.9vw, 56px);
  padding-top: var(--ext); /* padding, not the sheet's margin: a margin would collapse through */
  background: var(--band-grad) 0 0 / 100% calc(var(--ext) + var(--sheet-r) + 72px) no-repeat var(--c-white);
}
.hero__sheet {
  position: relative;
  padding-top: clamp(62px, 5.4vw, 78px);
  border-radius: var(--sheet-r) var(--sheet-r) 0 0;
  background: var(--c-white);
}
/* the app icon sits on the sheet's edge, half on the band */
.hero__mark {
  position: absolute;
  z-index: 2;
  left: 50%;
  top: 0;
  width: clamp(64px, 5.6vw, 84px);
  translate: -50% -50%;
}
.hero__mark img {
  width: 100%;
  height: auto;
  border-radius: var(--r-app-icon);
  box-shadow: 0 0 0 4px var(--c-white), 0 2px 4px rgba(120, 40, 0, 0.12), 0 14px 30px -10px rgba(120, 40, 0, 0.45);
}

.hero__top {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
/* The owner's line. Always two lines, broken after "for". */
.hero__title {
  font-size: clamp(2.875rem, 1.6rem + 6.6vw, 7.5rem); /* 48 at 320, 51 at 390 -> 120 at 1440 */
  line-height: 0.95;
  font-weight: 500; /* huge and calm: lighter than the other headlines */
  letter-spacing: -0.052em;
}
.hero__title > span { display: block; white-space: nowrap; }
/* the one stylised accent on the slogan: its full stop is the band's orange */
.hero__stop { color: var(--c-band-1); }
/* the quiet line for people hiring */
.hero__for {
  margin-top: clamp(14px, 1.5vw, 22px);
  color: var(--text-2);
  font-size: clamp(1.25rem, 1.111rem + 0.571vw, 1.625rem); /* 20 -> 26 */
  line-height: 1.25;
  font-weight: var(--fw-regular);
  letter-spacing: -0.022em;
  text-wrap: balance;
}

/* The two doors: the app's white cards, each with its own side of the app
   rising out of its bottom edge. Phones: one above the other, showing the
   top of each screen. From 900 px side by side; from 1200 px each screen
   stands almost whole in its card, with the callouts beside it (the screens
   lean in towards each other, the callouts point out).
   The link covers the whole card (::after), so the screen keeps its own
   description and the link's name stays the door's words. */
.doors {
  display: grid;
  gap: 14px;
  max-width: 1040px;
  margin: clamp(32px, 3.6vw, 52px) auto 0;
}
.door {
  --door-r: 26px;
  --pw: 206px;       /* frame width */
  --vis: 0.34;       /* how much of the frame shows above the card's edge */
  position: relative;
  display: flex;
  flex-direction: column;
  border-radius: var(--door-r);
  background: var(--c-white);
  box-shadow: var(--card-shadow);
  transition: transform var(--dur-screen) var(--ease-out);
}
/* the lifted shadow fades in (opacity only), the card rises 3 px */
.door::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: var(--card-shadow-up);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-screen) var(--ease-out);
}
.door__link {
  display: grid;
  justify-items: center;
  row-gap: 10px;
  padding: 22px 20px 0;
  color: var(--text);
  text-align: center;
  text-decoration: none;
}
.door__link::after {
  content: "";
  position: absolute;
  z-index: 4;
  inset: 0;
  border-radius: var(--door-r);
}
/* focus: an ink ring drawn inside the card's edge, never clipped */
.door__link:focus-visible { outline: none; }
.door__link:focus-visible::after { box-shadow: inset 0 0 0 2px var(--c-ink), inset 0 0 0 4px var(--c-white); }
.door__label {
  color: var(--text-2);
  font-size: var(--fs-eyebrow);
  line-height: var(--lh-eyebrow);
  font-weight: var(--fw-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
}
.door__line {
  display: block;
  max-width: 15em;
  font-size: clamp(1.5rem, 1.2rem + 0.95vw, 2.125rem); /* 24 -> 34 */
  line-height: 1.1;
  font-weight: var(--head-w);
  letter-spacing: -0.032em;
  text-wrap: balance;
}
.door__sub {
  display: block;
  margin-top: 2px;
  color: var(--text-2);
  font-size: var(--fs-body);
  line-height: 1.4;
}
/* the second sentence never splits, and its arrow rides with it */
.door__sub > span { white-space: nowrap; }
.door__sub .go { display: inline-grid; vertical-align: middle; margin: -3px 0 0 12px; }
/* the screen, cut by the card's bottom edge */
.door__media {
  position: relative;
  display: flex;
  justify-content: center;
  /* The phone keeps its full height and the card cuts it: stretched to the
     cut height, the frame's rounded bottom landed inside the visible part. */
  align-items: flex-start;
  height: calc(var(--pw) * 2.113 * var(--vis) + 14px);
  margin-top: 10px;
  padding-top: 14px; /* room for the hover lift */
  overflow: hidden;
  border-radius: 0 0 var(--door-r) var(--door-r);
  /* a soft studio light under the screen: the page grey, fading out */
  background: radial-gradient(64% 58% at 50% 100%, var(--c-page), rgba(242, 242, 247, 0));
}
@media (min-width: 1200px) {
  .door--hiring .door__media { background-position: calc(50% + 70px) 0; }
  .door--tradies .door__media { background-position: calc(50% - 70px) 0; }
}
.door__media .phone { transition: translate 600ms var(--ease-out); }
@media (hover: hover) {
  .door:hover { transform: translateY(-3px); }
  .door:hover::before { opacity: 1; }
  .door:hover .go,
  .hero__pay:hover .go { background: var(--c-ink); color: var(--c-white); }
  .door:hover .go { transform: translateY(2px); }
  .door:hover .door__media .phone { translate: 0 -10px; }
}
.door:active { transform: scale(0.99); }
/* --vis is set per screen and width so the card's edge always falls in a
   gap between two of the screen's rows, never through one: phones, under
   the search bar (hiring) and the first job's title (tradies); 600-899,
   under the first trade row and the first job's text; 900-1199 (one shared
   row, so one value), the gap both screens have there; from 1200, just
   above the app's floating tab bar. */
.door--hiring { --vis: 0.321; }
@media (min-width: 600px) {
  .door { --pw: 250px; --vis: 0.435; }
  .door--hiring { --vis: 0.42; }
}
@media (min-width: 900px) {
  /* label, line, sub and screen of both doors on shared rows (subgrid),
     so they line up across the two cards */
  .doors {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: repeat(4, auto);
    gap: 0 20px;
  }
  .doors > li { grid-row: span 4; display: grid; grid-template-rows: subgrid; }
  .door__link { grid-row: span 3; grid-template-rows: subgrid; row-gap: 12px; padding: 28px clamp(24px, 3vw, 44px) 0; }
  .door__line { align-self: center; }
  .door__sub { align-self: end; }
  .door { --pw: 236px; --vis: 0.423; }
}
@media (min-width: 1200px) {
  .doors { max-width: none; gap: 0 24px; }
  .door { --pw: 268px; --vis: 0.901; }
  .door--hiring .door__media { justify-content: flex-end; padding-right: clamp(40px, 5vw, 80px); }
  .door--tradies .door__media { justify-content: flex-start; padding-left: clamp(40px, 5vw, 80px); }
}
.hero__note { margin-top: 14px; text-align: center; }

/* Short wide screens (a laptop browser's window is often about 1440 x 790
   or 1366 x 768): the slogan and the air round it shrink with the window's
   height, so the real screens still show in the first view. From 900 px
   tall nothing changes. */
@media (min-width: 900px) and (max-height: 899px) {
  .hero { --ext: max(44px, min(clamp(46px, 3.9vw, 56px), calc(7vh - 7px))); }
  .hero__sheet { padding-top: max(52px, min(clamp(62px, 5.4vw, 78px), calc(14vh - 48px))); }
  .hero__title { font-size: min(clamp(2.875rem, 1.6rem + 6.6vw, 7.5rem), max(4.5rem, calc(18vh - 42px))); }
  .hero__for { margin-top: min(clamp(14px, 1.5vw, 22px), 1.8vh); }
  .doors { margin-top: max(26px, min(clamp(32px, 3.6vw, 52px), calc(8vh - 22px))); }
  .door__link { padding-top: 22px; row-gap: 8px; }
  .door__media { margin-top: 4px; }
}

/* the payment line, for both sides, then the App Store */
.hero__foot {
  display: grid;
  justify-items: center;
  gap: 14px;
  padding-top: clamp(28px, 3vw, 40px);
  text-align: center;
}
.hero__pay {
  display: block;
  padding: 6px 0; /* a 44 px target */
  color: var(--text);
  font-size: clamp(1.1875rem, 1rem + 0.62vw, 1.5rem);
  line-height: 1.35;
  font-weight: var(--fw-regular);
  letter-spacing: -0.016em;
  text-decoration: none;
  text-wrap: balance;
}
.hero__pay .go { display: inline-grid; vertical-align: middle; margin: -4px 0 0 12px; }
.hero__cta { display: grid; justify-items: center; gap: 6px; }
@media (min-width: 900px) {
  .hero__cta { display: flex; align-items: center; gap: 16px; }
}
.hero__free {
  color: var(--text-2);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
}

/* load-in, pure CSS (never waits for the script): the sheet rises over the
   band, the icon lifts, the slogan follows */
@media (prefers-reduced-motion: no-preference) {
  .hero__sheet { animation: sheet-up 1000ms var(--ease-out) both; }
  .hero__mark { animation: mark-lift 1100ms var(--ease-out) 120ms both; }
  .hero__title > span { animation: ht-in 1100ms var(--ease-out) 160ms both; }
  .hero__title > span + span { animation-delay: 260ms; }
  .hero__for { animation: fade-up 900ms var(--ease-out) 420ms both; }
  /* "backwards": once arrived, the cards answer hover and press again */
  .door { animation: fade-up 900ms var(--ease-out) 480ms backwards; }
  .door--tradies { animation-delay: 580ms; }
  .door__media .phone { animation: phone-rise 1300ms var(--ease-out) 640ms backwards; }
  .door--tradies .door__media .phone { animation-delay: 760ms; }
}
@keyframes phone-rise { from { transform: translate3d(0, 64px, 0); } to { transform: none; } }
@keyframes sheet-up { from { transform: translate3d(0, 56px, 0); } to { transform: none; } }
@keyframes mark-lift {
  from { opacity: 0; transform: translate3d(0, 18px, 0) scale(0.86); }
  to { opacity: 1; transform: none; }
}
@keyframes ht-in {
  from { opacity: 0; transform: translateY(0.18em); }
  to { opacity: 1; transform: none; }
}
@keyframes fade-up {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

/* Callout pins: a hairline from a label to an orange dot on the element.
   They sit on the screen itself (.phone__glass), so the dots stay exact. */
.pin { display: none; }
@media (min-width: 1200px) {
  .pin {
    --reach: 176px;
    --d: 0ms;
    position: absolute;
    z-index: 2;
    top: var(--y);
    display: block;
    height: 1px;
  }
  .pin--tile { --reach: 112px; }
  .pin--l { left: calc(-1 * var(--reach)); right: calc(100% - var(--x)); }
  .pin--r { left: var(--x); right: calc(-1 * var(--reach)); }
  .pin::before {
    content: "";
    position: absolute;
    inset: 0;
    background: rgba(28, 28, 30, 0.4);
    transform-origin: right center;
  }
  .pin--r::before { transform-origin: left center; }
  .pin::after {
    content: "";
    position: absolute;
    top: -5px;
    width: 11px;
    height: 11px;
    border-radius: 50%;
    background: var(--c-orange);
    box-shadow: 0 0 0 3px var(--c-white), 0 1px 6px rgba(0, 0, 0, 0.26);
  }
  .pin--l::after { right: -5px; }
  .pin--r::after { left: -5px; }
  .pin__label {
    position: absolute;
    bottom: 8px;
    white-space: nowrap;
    color: var(--text);
    font-size: var(--fs-small);
    font-weight: var(--fw-medium);
    letter-spacing: -0.01em;
  }
  .pin--l .pin__label { left: 0; }
  .pin--r .pin__label { right: 0; }
  .pin__label b {
    margin-right: 7px;
    color: var(--text-2);
    font-weight: var(--fw-semibold);
    font-feature-settings: var(--font-features-tabular);
  }
  .pin:nth-of-type(2) { --d: 160ms; }
  .pin:nth-of-type(3) { --d: 320ms; }
  .door .pin { --reach: 150px; --d: 900ms; }
  .door .pin:nth-of-type(2) { --d: 1060ms; }
  .door--tradies .pin { --d: 1220ms; }
  .door--tradies .pin:nth-of-type(2) { --d: 1380ms; }

  .js .pin::before { transform: scaleX(0); transition: transform 900ms var(--ease-out) calc(300ms + var(--d)); }
  .js .pin::after { transform: scale(0); transition: transform 500ms var(--ease-out) calc(200ms + var(--d)); }
  .js .pin__label { opacity: 0; transition: opacity 600ms var(--ease-out) calc(700ms + var(--d)); }
  .js .is-in .pin::before { transform: scaleX(1); }
  .js .is-in .pin::after { transform: scale(1); }
  .js .is-in .pin__label { opacity: 1; }
}

/* Spec strip: four facts on four small white cards */
.spec {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin-top: clamp(16px, 1.6vw, 22px);
}
@media (min-width: 900px) {
  .spec { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
}
.spec__cell {
  padding: 16px 16px 18px;
  border-radius: 18px;
  background: var(--c-page);
}
@media (min-width: 900px) { .spec__cell { padding: 20px 22px 22px; border-radius: 20px; } }
.js .spec__cell { transition: opacity 700ms var(--ease-out), translate 900ms var(--ease-out); }
.js .spec:not(.is-in) .spec__cell { opacity: 0; translate: 0 16px; }
.js .spec.is-in .spec__cell:nth-child(2) { transition-delay: 90ms; }
.js .spec.is-in .spec__cell:nth-child(3) { transition-delay: 180ms; }
.js .spec.is-in .spec__cell:nth-child(4) { transition-delay: 270ms; }
.spec dt {
  color: var(--text-2);
  font-size: var(--fs-eyebrow);
  line-height: var(--lh-eyebrow);
  font-weight: var(--fw-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
}
.spec dd {
  margin-top: 8px;
  font-size: clamp(1.0625rem, 0.95rem + 0.4vw, 1.3125rem);
  line-height: 1.3;
  font-weight: var(--fw-semibold);
  letter-spacing: -0.02em;
  text-wrap: balance;
}

/* ------------------------------------------------------------------ sections */
.section { padding: var(--section-y) 0; }
/* a section that is its own sheet: rounded top corners over the one before */
.sheet {
  position: relative;
  z-index: 1;
  margin-top: calc(-1 * var(--sheet-r));
  border-radius: var(--sheet-r) var(--sheet-r) 0 0;
}
.sheet--grey { background: var(--c-page); }
/* the sheets and the story already carry their own air: a shorter beat */
#hiring { padding-bottom: clamp(64px, 7vw, 112px); }
.sheet { padding-top: clamp(72px, 7.5vw, 120px); }
#payment { padding-bottom: clamp(88px, 8.5vw, 136px); }
.sheet--white { background: var(--c-white); }

.sec-head {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: clamp(24px, 3vw, 40px);
  color: var(--text-2);
  font-size: var(--fs-eyebrow);
  line-height: var(--lh-eyebrow);
  font-weight: var(--fw-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
}
.sec-head__num { color: var(--text); font-feature-settings: var(--font-features-tabular); }
.sec-head__rule { flex: 1; height: 1px; background: var(--hairline); }

.intro { display: grid; gap: var(--stack-md); }
@media (min-width: 900px) {
  .intro { grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr); align-items: end; gap: 48px; }
  .intro .lead { padding-bottom: 0.4em; }
}

/* ------------------------------------------------------------------ 01 hiring: the story
   One phone, three steps. As each step reaches the middle of the screen,
   its screen slides up inside the phone like one of the app's sheets (the
   one before settles back and dims), and the cards it talks about lift
   out beside it.
   Without the script (no .is-live) each step simply shows its own phone,
   so nothing depends on it. */
.story { position: relative; margin-top: var(--stack-lg); }
.story__device { display: none; }
.story__steps { display: grid; gap: clamp(56px, 8vw, 96px); }
.story__step { position: relative; display: grid; gap: 28px; }
.story__copy { max-width: 26rem; }
.story__title {
  margin-top: 12px;
  font-size: var(--fs-title);
  line-height: var(--lh-title);
  font-weight: var(--head-w);
  letter-spacing: var(--ls-title);
  text-wrap: balance;
}
.story__sub {
  max-width: 22em;
  margin-top: 10px;
  color: var(--text-2);
  font-size: var(--fs-lead);
  line-height: var(--lh-lead);
  letter-spacing: var(--ls-lead);
  text-wrap: pretty;
}
.story__shot { --pw: min(300px, 74vw); position: relative; justify-self: center; }
.story__note { margin-top: clamp(40px, 5vw, 64px); }

.facts { margin-top: clamp(22px, 2.6vw, 32px); border-top: 1px solid var(--ink-soft); }
.facts > div {
  display: grid;
  grid-template-columns: 6rem minmax(0, 1fr);
  align-items: baseline;
  gap: 12px;
  padding: 13px 0 14px;
  border-bottom: 1px solid var(--hairline);
}
.facts dt {
  color: var(--text-2);
  font-size: var(--fs-eyebrow);
  font-weight: var(--fw-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
}
.facts dd {
  font-size: var(--fs-card-title);
  line-height: 1.35;
  font-weight: var(--fw-medium);
  letter-spacing: -0.015em;
}

/* The lifted cards of step 2 (their past work): without the script they
   sit beside that step's own phone. Heights are set in the frame's width
   (--pw), so each card lands on the same part of the screen at any size:
   the ABN card just under the "Posts" header, the sticker on the photo's
   lower edge (phones: beside the caption's short last lines), never over
   the header or the caption. Sideways a card stops about 20 px short of the
   window's edge: --room / --room-l are the space from the frame's left
   edge to that limit on the right / left (cqw: the story, or the phone's
   column when the story is pinned on a wide screen). */
.story { container-type: inline-size; }
.lift { position: absolute; z-index: 3; }
.lift--abn { width: 92%; left: 58%; top: calc(var(--pw) * 0.32); rotate: 2deg; }
/* (wide screens) the quote card's edge falls in the gap between the photo
   and the post's icon row: the icons and the caption stay whole */
.lift--quote { width: 88%; left: 52%; top: calc(var(--pw) * 0.96); rotate: -2deg; }
.lift--sticker { left: -10%; top: calc(var(--pw) * 1.5); rotate: -6deg; }
.lift--sticker .sticker { font-size: var(--fs-label); }

@media (max-width: 899px) {
  /* the frame is centred in the story (set on the card, where --pw is
     the frame's) */
  .lift {
    --room: calc(50cqw + var(--pw) / 2 + var(--gutter) - 22px);
    --room-l: calc(50cqw - var(--pw) / 2 + var(--gutter) - 22px);
  }
  .story__shot { --pw: min(250px, 62vw); }
  .lift--abn { width: 80%; left: 40%; top: calc(var(--pw) * 0.31); }
  .lift--quote { width: 80%; left: -26%; top: calc(var(--pw) * 1.04); }
  .lift--sticker { left: auto; right: -22%; top: calc(var(--pw) * 1.94); rotate: -4deg; }
  /* each step's own phone: the sticker sits 5 px lower, clear of
     "wastes."; below 403 px the frame narrows but the sticker keeps its
     size, so it reaches further over the caption and slides down by a sixth
     of what the frame lost too, clear of "fit-off." (320 px: 14 px in all) */
  .story:not(.is-live) .lift--sticker { top: calc(var(--pw) * 1.94 + 5px + (250px - var(--pw)) / 6); }
}
@media (min-width: 900px) {
  /* the frame starts its column's margin into the second of two columns */
  .lift { --room: calc((100cqw - clamp(40px, 6vw, 96px)) * 6 / 11 - clamp(0px, 4vw, 64px) + var(--gutter) - 24px); }
  .story__step { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); align-items: center; column-gap: clamp(40px, 6vw, 96px); }
  .story__shot { --pw: 300px; justify-self: start; margin-left: clamp(0px, 4vw, 64px); }
}
/* the edge limits need container units; without them the plain places
   above stand */
@supports (width: 1cqw) {
  .lift--abn { left: min(58%, calc(var(--room) - 92%)); }
  .lift--quote { left: min(52%, calc(var(--room) - 88%)); }
  @media (max-width: 899px) {
    .lift--abn { left: min(40%, calc(var(--room) - 80%)); }
    .lift--quote { left: max(-26%, calc(-1 * var(--room-l))); }
    .lift--sticker { right: max(-22%, calc(-1 * var(--room-l))); }
  }
}

/* --- live: the script has copied the screens into one phone. Each step's
   own figure stays where it is for screen readers (the phone is hidden from
   them), out of sight only, so a step's words come before its screen. */
.story.is-live .story__shot {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.story.is-live .story__device { display: block; }
.story__sticky { position: relative; width: var(--pw); margin-inline: auto; }
.story__device .phone__glass {
  aspect-ratio: 860 / 1870;
  overflow: hidden;
  background: #000;
  isolation: isolate;
}
/* A screen is below the phone (waiting), on, or under the one that came
   after it (settled back and dimmed, like a sheet the app stacked over it).
   Only the screen arriving and the one it covers ever move: home.js snaps
   every other screen to its place, so a fast scroll or a nav click never
   shows a screen it skipped. Going back, the top screen slides down off the
   one beneath, which rises to meet you. */
.scr {
  position: absolute;
  inset: 0;
  transform: translate3d(0, 104%, 0);
  transition: transform 760ms var(--ease-out), opacity 240ms var(--ease-standard);
  will-change: transform;
}
.scr picture, .scr img { width: 100%; height: 100%; }
.scr img { object-fit: cover; }
.scr::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 15.6% / 7.17%;
  background: #000;
  opacity: 0;
  transition: opacity 760ms var(--ease-out);
  pointer-events: none;
}
.scr.is-on { transform: none; }
.scr.is-under { transform: scale(0.93); }
.scr.is-under::after { opacity: 0.45; }
.scr.is-hidden { opacity: 0; }
.scr.is-snap, .scr.is-snap::after { transition: none; }
/* the step bar under the phone: steps done in ink, this one orange */
.story__bar { display: flex; gap: 6px; width: 100%; margin-top: 22px; }
.story__bar i { position: relative; flex: 1; height: 3px; border-radius: 2px; background: rgba(28, 28, 30, 0.12); }
.story__bar i::before,
.story__bar i::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  opacity: 0;
  transform-origin: left center;
  transition: opacity 360ms var(--ease-out), transform 600ms var(--ease-out);
}
.story__bar i::before { background: var(--c-ink); }
.story__bar i::after { background: var(--c-orange); transform: scaleX(0.2); }
.story__bar i.is-past::before { opacity: 1; }
.story__bar i.is-on::after { opacity: 1; transform: none; }
/* the lifted cards, in the phone's layer: they rise in on their step */
.story__lifts { position: absolute; inset: 0; pointer-events: none; }
.story.is-live .lift {
  opacity: 0;
  translate: 0 28px;
  transition: opacity 520ms var(--ease-out), translate 820ms var(--ease-out);
}
.story.is-live .lift.is-on { opacity: 1; translate: 0 0; transition-delay: 180ms; }
.story.is-live .lift--quote.is-on { transition-delay: 320ms; }
.story.is-live .lift--sticker.is-on { transition-delay: 460ms; }

@media (min-width: 900px) {
  .story.is-live {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    column-gap: clamp(40px, 6vw, 96px);
  }
  .story.is-live .story__steps { grid-column: 1; grid-row: 1; gap: 0; }
  /* every step as tall as the phone's stuck run, its words centred on the
     phone: the last one is read while its screen is still held */
  .story.is-live .story__step { display: flex; align-items: center; min-height: clamp(680px, 84vh, 920px); }
  .story.is-live .story__device { grid-column: 2; grid-row: 1; container-type: inline-size; }
  .story.is-live .lift { --room: calc(100cqw - clamp(0px, 4vw, 64px) + var(--gutter) - 24px); }
  .story.is-live .story__sticky {
    --pw: clamp(240px, calc((100vh - 220px) / 2.113), 300px);
    position: sticky;
    top: clamp(104px, calc(50vh - var(--pw) * 2.113 / 2 - 4px), 180px);
    margin-left: clamp(0px, 4vw, 64px);
    width: var(--pw);
  }
  .story.is-live .story__copy { transition: opacity 500ms var(--ease-out); }
  .story.is-live .story__step:not(.is-current) .story__copy { opacity: 0.28; }
}

/* Phones (only when the screen is tall enough; home.js decides): the phone
   sticks under the band, and the steps are white cards that dock under it,
   each one sliding up over the last (which then fades). The phone is never
   covered, so a screen and its words are always on screen together. */
@media (max-width: 899px) {
  .story.is-live {
    --top: 72px;              /* under the condensed band */
    --bar: 40px;              /* the bar under the phone, and air */
    --cards: 262px;           /* room kept for the docked card */
    --pw: clamp(180px, calc((100svh - var(--top) - var(--bar) - var(--cards)) / 2.113), 228px);
    --dock: calc(var(--top) + var(--pw) * 2.113 + var(--bar));
  }
  .story.is-live .story__device { position: sticky; z-index: 2; top: var(--top); }
  .story.is-live .story__sticky { width: var(--pw); }
  .story.is-live .story__bar { margin-top: 16px; }
  /* A block list (a sticky card is held inside its parent's content box):
     the spacer after the last card is its run. The list runs about one card
     past the story's content box (the phone's limit) into its padding, so
     the phone and the last card leave together and a card never slides up
     under the phone. */
  .story.is-live { padding-bottom: 150px; }
  .story.is-live .story__steps { position: relative; z-index: 1; display: block; margin-bottom: -150px; }
  .story.is-live .story__steps::after { content: ""; display: block; height: 30svh; }
  .story.is-live .story__step {
    position: sticky;
    top: var(--dock);
    display: block;
    padding: 18px 20px 18px;
    border-radius: 22px;
    background: var(--c-white);
    box-shadow: 0 0 0 1px rgba(28, 28, 30, 0.06), 0 2px 6px rgba(0, 0, 0, 0.05), 0 -18px 40px -24px rgba(28, 28, 30, 0.32);
    transition: opacity 320ms var(--ease-standard);
  }
  .story.is-live .story__step + .story__step { margin-top: 58svh; }
  .story.is-live .story__step.is-past { opacity: 0; }
  .story.is-live .story__copy { max-width: none; }
  .story.is-live .story__title { margin-top: 8px; font-size: 1.375rem; line-height: 1.2; }
  .story.is-live .story__sub { margin-top: 6px; font-size: var(--fs-label); line-height: 1.45; }
  /* the profile facts as three short columns, so that card stays short */
  .story.is-live .facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--hairline); }
  .story.is-live .facts > div { display: block; padding: 0; border: 0; }
  .story.is-live .facts dt { font-size: var(--fs-eyebrow); }
  .story.is-live .facts dd { margin-top: 4px; font-size: var(--fs-small); line-height: 1.35; }
  /* the cards lift over the phone's edges, the way the collage did */
  .story.is-live .lift--abn { left: 46%; }
  .story.is-live .lift--quote { width: 84%; left: -40%; top: calc(var(--pw) * 1.01); }
  .story.is-live .lift--sticker { right: -26%; }
  @supports (width: 1cqw) {
    .story.is-live .lift--abn { left: min(46%, calc(var(--room) - 80%)); }
    .story.is-live .lift--quote { left: max(-40%, calc(-1 * var(--room-l))); }
    .story.is-live .lift--sticker { right: max(-26%, calc(-1 * var(--room-l))); }
  }
  .story.is-live .lift--sticker .sticker { font-size: var(--fs-small); }
}
@media (max-width: 899px) and (min-width: 600px) {
  .story.is-live .story__step { max-width: 30rem; margin-inline: auto; }
}
/* a shorter phone screen (700-759 px): the same layout, set tighter, so the
   phone stays 180 px wide and the longest card still fits under it */
@media (max-width: 899px) and (max-height: 759px) {
  .story.is-live { --top: 64px; --bar: 32px; --cards: 226px; }
  .story.is-live .story__bar { margin-top: 12px; }
  .story.is-live .story__step { padding: 14px 18px; }
  .story.is-live .story__title { margin-top: 6px; font-size: 1.25rem; }
  .story.is-live .story__sub { margin-top: 4px; font-size: var(--fs-small); line-height: 1.4; }
  .story.is-live .facts { margin-top: 10px; padding-top: 10px; }
  .story.is-live .facts dd { font-size: var(--fs-fine); }
  /* a smaller sticker, so it still clears the step bar under the phone */
  .story.is-live .lift--sticker .sticker { gap: 8px; padding: 4px 12px 4px 4px; border-radius: 12px; }
  .story.is-live .lift--sticker .sticker__icon { width: 24px; height: 24px; border-radius: 7px; }
  .story.is-live .lift--sticker .sticker__icon svg { width: 14px; height: 14px; }
}

/* ------------------------------------------------------------------ 02 payment (a grey sheet, white cards) */
.pay-head { display: grid; gap: var(--stack-md); }
.display--pay {
  max-width: 13em;
  font-size: clamp(2.5rem, 1rem + 4.6vw, 5.25rem);
  line-height: 1.0;
  letter-spacing: -0.045em;
}
/* wide screens: the headline holds still beside the steps */
@media (min-width: 900px) {
  .pay-grid {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    align-items: start;
    column-gap: clamp(40px, 6vw, 96px);
  }
  .pay-head { position: sticky; top: clamp(112px, 18vh, 180px); }
  .display--pay { font-size: clamp(2.75rem, 0.9rem + 3.4vw, 4.375rem); }
  .pay-head .lead { max-width: 18em; }
}
/* the one accent: a drawn orange line under "held" (the word stays ink) */
.hl { position: relative; display: inline-block; }
.hl::after {
  content: "";
  position: absolute;
  left: 0.02em;
  right: 0.02em;
  bottom: 0.02em;
  height: 0.09em;
  border-radius: 1em;
  background: var(--c-orange);
  transform-origin: left center;
}
.js .pay-head .hl::after { transform: scaleX(0); transition: transform 900ms var(--ease-in-out) 450ms; }
.js .pay-head.is-in .hl::after { transform: none; }

/* The timeline: four white cards on one track, top to bottom. Each card
   rises in as it arrives, its node fills, and the track draws on down to
   the next one; the last node is orange: done. */
.timeline {
  --node: 13px;
  --gap: 14px;
  position: relative;
  margin-top: clamp(40px, 6vw, 72px);
}
@media (min-width: 900px) { .timeline { --gap: 16px; margin-top: 6px; } }
.steps { display: grid; gap: var(--gap); }
.step {
  position: relative;
  padding: 22px 22px 24px 54px;
  border-radius: 22px;
  background: var(--c-white);
  box-shadow: var(--card-shadow);
}
@media (min-width: 900px) { .step { padding: 30px 36px 32px 76px; border-radius: 26px; } }
/* the track: from this node down to the next one, through the gap */
.step::before,
.step::after {
  content: "";
  position: absolute;
  left: 25px;
  top: 30px;
  bottom: calc(-1 * var(--gap) - 30px);
  width: 1px;
  background: rgba(28, 28, 30, 0.14);
  z-index: 1;
}
.step::after { background: var(--c-orange); transform-origin: top center; }
.step:last-child::before,
.step:last-child::after { display: none; }
.step__node {
  position: absolute;
  z-index: 2;
  left: 19px;
  top: 24px;
  width: var(--node);
  height: var(--node);
  border-radius: 50%;
  background: var(--c-ink);
  border: 1px solid var(--c-ink);
}
@media (min-width: 900px) {
  .step::before, .step::after { left: 38px; top: 40px; bottom: calc(-1 * var(--gap) - 40px); }
  .step__node { left: 32px; top: 34px; }
}
.step:last-child .step__node {
  background: var(--c-orange);
  border-color: var(--c-orange);
  box-shadow: 0 0 0 6px rgba(255, 107, 0, 0.18);
}
.step__num {
  display: block;
  color: var(--text-2);
  font-size: var(--fs-eyebrow);
  line-height: 1.5;
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-eyebrow);
  font-feature-settings: var(--font-features-tabular);
}
.step__title {
  margin-top: 10px;
  font-size: clamp(1.75rem, 1.4rem + 1vw, 2.375rem);
  line-height: 1.05;
  font-weight: var(--head-w);
  letter-spacing: -0.035em;
}
.step__text {
  max-width: 24em;
  margin-top: 8px;
  color: var(--text-2);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
}
@media (min-width: 900px) { .step__text { font-size: var(--fs-lead); line-height: var(--lh-lead); } }
/* the app's own words for each step, as a small lifted card, big enough
   to read (the crops are 640 px wide) */
.step__proof {
  max-width: 360px;
  margin-top: 18px;
  overflow: hidden;
  border-radius: 12px;
  background: var(--c-white);
  box-shadow: 0 0 0 1px rgba(28, 28, 30, 0.08), 0 16px 32px -18px rgba(28, 28, 30, 0.45);
}
@media (min-width: 900px) { .step__proof { margin-top: 22px; border-radius: 14px; } }
.step__proof img { width: 100%; }

/* the draw, card by card, as each one arrives */
.js .step { transition: transform 800ms var(--ease-out), opacity 600ms var(--ease-out); }
.js .step:not(.is-in) { opacity: 0; transform: translateY(26px); }
.js .step::after { transform: scaleY(0); transition: transform 900ms var(--ease-in-out) 350ms; }
.js .step.is-in::after { transform: none; }
.js .step__node { background: var(--c-white); border-color: rgba(28, 28, 30, 0.3); box-shadow: none; transition: background-color 250ms 200ms, border-color 250ms 200ms, box-shadow 400ms 200ms; }
.js .step.is-in .step__node { background: var(--c-ink); border-color: var(--c-ink); }
.js .step.is-in:last-child .step__node { background: var(--c-orange); border-color: var(--c-orange); box-shadow: 0 0 0 6px rgba(255, 107, 0, 0.18); }

.pay-foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px 24px;
  margin-top: clamp(40px, 5vw, 64px);
  padding-top: 18px;
  border-top: 1px solid rgba(28, 28, 30, 0.12);
  color: var(--text-2);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
}
.pay-foot__fine { font-size: var(--fs-fine); }

/* ------------------------------------------------------------------ 03 tradies */
/* the annotated job card (page grey behind the app's white card) */
.tile {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
  padding: var(--tile-pad) var(--tile-pad) 0;
  background: var(--c-page);
  border-radius: var(--sheet-r);
}
.tile__text { position: relative; z-index: 2; }
.tile__eyebrow {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
  color: var(--text-2);
  font-size: var(--fs-eyebrow);
  line-height: var(--lh-eyebrow);
  font-weight: var(--fw-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
}
.tile__title {
  font-size: clamp(1.5rem, 1.2rem + 0.9vw, 2.5rem);
  line-height: 1.12;
  font-weight: var(--head-w);
  letter-spacing: -0.03em;
}
.tile__sub {
  margin-top: 8px;
  color: var(--text-2);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
}
.tile__media {
  position: relative;
  display: flex;
  justify-content: center;
  margin-top: auto;
  padding-top: clamp(28px, 3vw, 44px);
}
.tile--find { margin-top: var(--stack-lg); padding-bottom: 0; }
.spec-media {
  flex: 1 1 auto;
  align-items: center;
  padding-bottom: clamp(32px, 3.4vw, 52px);
}
.spec-card { position: relative; width: min(420px, 100%); }
.job-card {
  width: 100%;
  border-radius: 5% / 6.1%; /* the app's own card corners */
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.04), 0 2px 4px rgba(0, 0, 0, 0.04), 0 30px 60px -24px rgba(28, 28, 30, 0.4);
  transition: transform var(--dur-screen) var(--ease-out);
}
@media (hover: hover) and (min-width: 900px) {
  .tile--find:hover .job-card { transform: translateY(-6px); }
}
@media (min-width: 900px) {
  .tile--find {
    display: grid;
    grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
    align-items: center;
    gap: 32px;
    padding: clamp(48px, 5vw, 80px) var(--tile-pad);
  }
  .tile--find .tile__media { margin-top: 0; padding: 0; }
}
.js .tile--find .job-card { transition: transform 1000ms var(--ease-out) 150ms; }
.js .tile--find:not(.is-in) .job-card { transform: translateY(36px) rotate(-1.5deg); }

/* on the tools / off them */
.lives { margin-top: clamp(80px, 10vw, 152px); }
.statement {
  max-width: 15em;
  font-size: clamp(2.375rem, 0.9rem + 5vw, 5.5rem);
  line-height: 1.0;
  font-weight: var(--head-w);
  letter-spacing: -0.05em;
  text-wrap: balance;
}
.statement .soft { display: block; }
.split {
  display: grid;
  gap: 14px;
  margin-top: var(--stack-lg);
}
.split__half {
  position: relative;
  display: grid;
  grid-template-rows: auto 1fr auto auto;
  justify-items: center;
  overflow: hidden;
  padding: 22px 20px 28px;
  border-radius: var(--sheet-r);
  background: var(--c-page);
  text-align: center;
}
.split__label {
  justify-self: start;
  color: var(--text-2);
  font-size: var(--fs-eyebrow);
  font-weight: var(--fw-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
}
.split__visual {
  position: relative;
  width: 100%;
  display: grid;
  place-items: center;
  padding: clamp(24px, 3vw, 48px) 0 clamp(24px, 3vw, 40px);
  min-height: clamp(320px, 32vw, 500px);
}
.split__sheet { width: min(80%, 360px); }
.split__line {
  font-size: clamp(1.625rem, 1.2rem + 1.4vw, 2.5rem);
  line-height: 1.08;
  font-weight: var(--head-w);
  letter-spacing: -0.035em;
  text-wrap: balance;
}
.split__small {
  margin-top: 8px;
  color: var(--text-2);
  font-size: var(--fs-body);
}
.split__pause { position: absolute; right: 0; bottom: clamp(16px, 2vw, 32px); }
@media (min-width: 900px) {
  .split { grid-template-columns: 1fr 1fr; gap: 20px; }
  .split__half { padding: 28px 32px 36px; }
}
/* the quote sheet rises into its card as it arrives */
.js .split__sheet { transition: transform 1000ms var(--ease-out) 200ms; }
.js .split__half:not(.is-in) .split__sheet { transform: translateY(48px); }

/* off them: one TradeMate at a time, a slow crossfade */
.lifecycle {
  position: relative;
  width: min(80%, 360px);
  aspect-ratio: 1 / 1;
}
.lifecycle__f {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  opacity: 0;
}
.lifecycle__f img { max-width: 100%; max-height: 100%; width: auto; height: auto; }
.lifecycle__f:first-child { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  .js .lifecycle__f {
    animation: life-turn 21s var(--ease-in-out) infinite both;
    animation-delay: calc(var(--i) * 3.5s - 1s);
  }
  .js .lifecycle__f:first-child { opacity: 0; }
  .is-still .lifecycle__f { animation-play-state: paused; }
}
@keyframes life-turn {
  0%     { opacity: 0; transform: translate3d(0, 14px, 0); }
  4%     { opacity: 1; transform: none; }
  16.67% { opacity: 1; transform: none; }
  20%    { opacity: 0; transform: translate3d(0, -10px, 0); }
  100%   { opacity: 0; transform: translate3d(0, -10px, 0); }
}

/* ------------------------------------------------------------------ 04 social: two feeds, the line between them */
.social { padding-top: 0; }
.social__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-areas: "head head" "left right";
  gap: 48px 14px;
  align-items: start;
}
.social__head {
  grid-area: head;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--stack-md);
  text-align: center;
}
.social__head .display { max-width: none; }
.social__head .lead { max-width: 20em; margin-inline: auto; }
.social__phone { --pw: min(290px, 42vw); }
.social__phone--left { grid-area: left; justify-self: end; }
.social__phone--right { grid-area: right; justify-self: start; margin-top: clamp(48px, 9vw, 120px); }
@media (min-width: 1000px) {
  .social__grid {
    grid-template-columns: 1fr minmax(0, 24rem) 1fr;
    grid-template-areas: "left head right";
    gap: 0 clamp(40px, 5vw, 80px);
    align-items: center;
  }
  .social__phone--left { margin-bottom: 140px; }
  .social__phone--right { margin-top: 140px; }
}
/* the phones fan open once as they arrive */
.js .social__phone { transition: rotate 1100ms var(--ease-out) 250ms, translate 1100ms var(--ease-out) 250ms; }
.js .social__grid:not(.is-in) .social__phone--left { rotate: 5deg; translate: 24px 0; }
.js .social__grid:not(.is-in) .social__phone--right { rotate: -5deg; translate: -24px 0; }
.social__grid.is-in .social__phone--left { rotate: -2deg; }
.social__grid.is-in .social__phone--right { rotate: 2deg; }

/* ------------------------------------------------------------------ 05 rewards */
.rewards { padding-top: 0; }
.rewards__tile {
  position: relative;
  display: grid;
  gap: 24px;
  overflow: hidden;
  padding: clamp(28px, 5vw, 80px) clamp(22px, 5vw, 80px) 0;
  border-radius: var(--sheet-r);
  background: var(--c-page);
}
.rewards__copy .lead { margin-top: var(--stack-md); }
.ladder { margin-top: clamp(28px, 3.4vw, 44px); }
.ladder__h {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  row-gap: 6px;
  color: var(--text-2);
  font-size: var(--fs-eyebrow);
  line-height: var(--lh-eyebrow);
  font-weight: var(--fw-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
}
.ladder__h-sep { width: 18px; height: 1px; margin: 0 10px; background: var(--c-card-edge); }
.ladder__h--hiring { margin-top: clamp(28px, 3.4vw, 40px); }
/* the prizes on one white card, rows ruled like the app's settings lists */
.ladder__list {
  margin-top: 12px;
  padding: 0 18px;
  border-radius: 18px;
  background: var(--c-white);
  box-shadow: var(--card-shadow);
}
.ladder__list li {
  display: grid;
  grid-template-columns: 5.25rem minmax(0, 1fr);
  align-items: baseline;
  gap: 12px;
  padding: 13px 0 14px;
}
.ladder__list li + li { border-top: 1px solid var(--hairline); }
.ladder__tier {
  color: var(--text-2);
  font-size: var(--fs-small);
  font-weight: var(--fw-medium);
}
.ladder__prize {
  font-size: var(--fs-body);
  line-height: 1.3;
  font-weight: var(--fw-medium);
  letter-spacing: -0.015em;
  font-feature-settings: var(--font-features-tabular);
}
@media (max-width: 599px) {
  .rewards__tile { padding-inline: 16px; }
  .rewards__copy { padding-inline: 6px; }
  .ladder__list { padding: 0 14px; }
  .ladder__list li { grid-template-columns: 4.75rem minmax(0, 1fr); }
  .ladder__prize { font-size: var(--fs-label); }
}
@media (min-width: 600px) {
  .ladder__list li { grid-template-columns: 6.5rem minmax(0, 1fr); }
  .ladder__prize { font-size: var(--fs-card-title); }
}
.ladder__foot {
  margin-top: 12px;
  color: var(--text-2);
  font-size: var(--fs-small);
}

/* the composition: the points screen, the tool reward card over it,
   and TradeMate on the ground line. They lift in one after another. */
.rewards__stage { position: relative; height: 470px; }
.rewards__phone { --pw: 184px; position: absolute; right: 0; top: 10px; rotate: 5deg; }
.rewards__card { position: absolute; width: min(250px, 66%); left: 0; top: 80px; rotate: -3deg; z-index: 2; }
.rewards__mate { position: absolute; z-index: 3; width: 104px; left: 6%; bottom: 0; }
.rewards__mate img { width: 100%; }
@media (min-width: 600px) {
  .rewards__stage { height: 580px; max-width: 560px; width: 100%; margin-inline: auto; }
  .rewards__phone { --pw: 250px; right: 4%; top: 20px; }
  .rewards__card { width: 330px; top: 120px; }
  .rewards__mate { width: 140px; }
}
@media (min-width: 960px) {
  .rewards__tile { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); align-items: start; gap: 48px; }
  .rewards__copy { padding-bottom: clamp(40px, 5vw, 80px); }
  .rewards__stage { height: 100%; min-height: 660px; max-width: none; }
  .rewards__phone { --pw: 272px; right: 0; top: 40px; }
  .rewards__card { width: 352px; left: -2%; top: 160px; }
  .rewards__mate { width: 160px; left: 6%; }
}
.js .ladder__list li { transition: opacity 600ms var(--ease-out), translate 800ms var(--ease-out); }
.js .rewards__tile:not(.is-in) .ladder__list li { opacity: 0; translate: -14px 0; }
.js .rewards__tile.is-in .ladder__list li:nth-child(2) { transition-delay: 110ms; }
.js .rewards__tile.is-in .ladder__list li:nth-child(3) { transition-delay: 220ms; }
.js .rewards__tile.is-in .ladder__list li:nth-child(4) { transition-delay: 330ms; }
.js .rewards__tile.is-in .ladder__list li:nth-child(5) { transition-delay: 440ms; }
.js .rewards__phone,
.js .rewards__card,
.js .rewards__mate { transition: opacity 700ms var(--ease-out), translate 1000ms var(--ease-out); }
.js .rewards__card { transition-delay: 220ms; }
.js .rewards__mate { transition-delay: 440ms; }
.js .rewards__stage:not(.is-in) > * { opacity: 0; translate: 0 40px; }

/* ------------------------------------------------------------------ close: the sheet lifts off the orange */
.close { padding: 0; }
.close__top {
  position: relative;
  z-index: 1;
  padding: clamp(24px, 3vw, 48px) 0 clamp(56px, 8vw, 128px);
  border-radius: 0 0 var(--sheet-r) var(--sheet-r);
  background: var(--c-white);
}
.close__line {
  max-width: 14em;
  margin-inline: auto;
  text-align: center;
  font-size: var(--fs-display);
  line-height: 1.02;
  font-weight: var(--head-w);
  letter-spacing: -0.04em;
  text-wrap: balance;
}
.close__line .soft { display: block; }
/* TradeMate's van, parked at the sheet's bottom corner. On phones it gets
   its own room under the line; on wide screens it sits in the corner. */
.close__van {
  position: relative;
  width: 132px;
  margin: 26px auto -16px;
}
.close__van img { width: 100%; }
.close__van::before {
  content: "";
  position: absolute;
  z-index: -1;
  left: 8%;
  right: 4%;
  bottom: 3%;
  height: 12%;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(28, 28, 30, 0.22), rgba(28, 28, 30, 0));
}
@media (min-width: 900px) {
  .close__van { position: absolute; left: max(var(--gutter), calc(50% - 600px)); bottom: 18px; width: 224px; margin: 0; }
}
/* it pulls up once: in from the left, slowing to a stop, a small settle */
@media (prefers-reduced-motion: no-preference) {
  .js .close__van { transition: transform 1700ms cubic-bezier(0.16, 1, 0.3, 1) 250ms; }
  .js .close__top:not(.is-in) .close__van { transform: translate3d(calc(-100% - 50vw), 0, 0); }
  .js .close__top.is-in .close__van img { animation: van-settle 700ms var(--ease-out) 1450ms both; transform-origin: 70% 100%; }
}
@keyframes van-settle {
  0% { transform: none; }
  35% { transform: rotate(-1.4deg); }
  70% { transform: rotate(0.5deg); }
  100% { transform: none; }
}
/* the launch moment: full width, the brand gradient, the lockup and its nut */
.close__band {
  position: relative;
  background: var(--c-band-2) var(--band-grad);
  color: var(--c-white);
  margin-top: calc(-1 * var(--sheet-r));
  padding: calc(var(--sheet-r) + clamp(56px, 9vw, 136px)) var(--gutter) calc(var(--sheet-r) + clamp(132px, 14vw, 216px));
  overflow: hidden;
  overflow: clip;
}
.close__panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
.close__lockup { width: clamp(260px, 30vw, 420px); }
.close__lockup svg { width: 100%; height: auto; overflow: visible; }
/* the lockup's own nut turns, slowly: one turn every two minutes */
.lockup__nut { transform-box: fill-box; transform-origin: 50% 50%; }
@media (prefers-reduced-motion: no-preference) {
  .js .is-in .lockup__nut { animation: nut-in 1600ms var(--ease-out) both, nut-turn 120s linear 1600ms infinite; }
  .is-still .lockup__nut { animation-play-state: paused; }
}
@keyframes nut-in { from { transform: rotate(-60deg); } to { transform: rotate(0deg); } }
@keyframes nut-turn { to { transform: rotate(360deg); } }

.store--on-orange { margin-top: clamp(32px, 4vw, 48px); }
.store--on-orange img { height: 58px; }
.store-soon--on-orange { margin: clamp(32px, 4vw, 48px) 0 -8px; color: var(--c-ink); }
/* ink on the gradient: 5.1:1 at its darkest; white at this size would fail */
.close__fine {
  margin-top: 16px;
  color: var(--c-ink);
  font-size: var(--fs-small);
  font-weight: var(--fw-medium);
}

/* the tape: a tilted white strip of trades across the band, edge to edge */
.tape {
  position: absolute;
  z-index: 3;
  left: -60px;
  right: -60px;
  bottom: calc(var(--sheet-r) + clamp(36px, 4vw, 64px));
  display: flex;
  align-items: center;
  rotate: -2.5deg;
  background: var(--c-white);
  color: var(--c-ink);
  box-shadow: 0 0 0 1px rgba(28, 28, 30, 0.05), 0 16px 28px -16px rgba(120, 40, 0, 0.45);
}
.marquee { flex: 1; min-width: 0; overflow: hidden; padding-block: clamp(10px, 1vw, 16px); }
.marquee__track { display: flex; align-items: center; width: max-content; }
.marquee__track.is-looping { animation: marquee 60s linear infinite; }
.is-still .marquee__track { animation-play-state: paused; }
@keyframes marquee { to { transform: translateX(-50%); } }
.tape__item {
  display: flex;
  align-items: center;
  flex: none;
  gap: 0.3em;
  margin-right: 0.7em;
  font-size: clamp(1.625rem, 1rem + 2.4vw, 3.25rem);
  line-height: 1;
  font-weight: var(--fw-medium);
  letter-spacing: -0.045em;
  white-space: nowrap;
}
.tape__item picture { flex: none; }
.tape__item img { width: auto; height: 1.5em; max-width: 1.6em; object-fit: contain; }
.tape__pause {
  position: absolute;
  z-index: 2;
  right: calc(60px + var(--gutter));
  top: 50%;
  translate: 0 -50%;
}
.tape::after {
  content: "";
  position: absolute;
  z-index: 1;
  top: 0;
  bottom: 0;
  right: 0;
  width: calc(60px + var(--gutter) + 120px);
  pointer-events: none;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0), var(--c-white) 55%);
}
.tape:not(:has(.tape__pause:not([hidden])))::after { display: none; }

/* the footer: one last white sheet over the orange */
.site-foot--sheet {
  position: relative;
  z-index: 1;
  margin-top: calc(-1 * var(--sheet-r));
  border-top: 0;
  border-radius: var(--sheet-r) var(--sheet-r) 0 0;
  background: var(--c-white);
}

/* ------------------------------------------------------------------ reveal */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity var(--dur-reveal) var(--ease-out), transform 900ms var(--ease-out);
}
.js [data-reveal].is-in { opacity: 1; transform: none; }

/* gentle parallax where the browser links animation to scroll: the two
   two feeds drift apart a little. Transform only; off under reduced
   motion; without support they simply stand still. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .social__phone--left .phone { animation: drift-up linear both; animation-timeline: view(); animation-range: cover; }
    .social__phone--right .phone { animation: drift-down linear both; animation-timeline: view(); animation-range: cover; }
  }
}
@keyframes drift-up { from { transform: translateY(36px); } to { transform: translateY(-36px); } }
@keyframes drift-down { from { transform: translateY(-28px); } to { transform: translateY(28px); } }

@media (prefers-reduced-motion: reduce) {
  .js [data-reveal] { opacity: 1; transform: none; transition: none; }
  .door, .door::before, .go, .door__media .phone { transition: none; }
  .door:hover, .door:active { transform: none; }
  .door:hover .go { transform: none; }
  .door:hover .door__media .phone { translate: none; }
  .js .pin::before, .js .pin::after, .js .pin__label { transition: none !important; }
  .js .step::after { transform: none; transition: none; }
  .js .step, .js .step__node { transition: none !important; }
  .js .step:not(.is-in) { opacity: 1; transform: none; }
  .js .step__node { background: var(--c-ink); border-color: var(--c-ink); }
  .js .step:last-child .step__node { background: var(--c-orange); border-color: var(--c-orange); box-shadow: 0 0 0 6px rgba(255, 107, 0, 0.18); }
  .js .pay-head .hl::after { transform: none; transition: none; }
  .scr, .scr::after, .story__bar i::before, .story__bar i::after, .story.is-live .story__step { transition: none; }
  .story.is-live .lift, .story.is-live .story__copy { transition: none !important; }
  .js .tile--find .job-card, .js .split__sheet { transition: none; transform: none !important; }
  .tile--find:hover .job-card { transform: none; }
  .js .social__phone { transition: none; }
  .js .rewards__phone, .js .rewards__card, .js .rewards__mate { transition: none; }
  .js .rewards__stage:not(.is-in) > * { opacity: 1; translate: none; }
  .js .ladder__list li, .js .spec__cell { transition: none; }
  .js .rewards__tile:not(.is-in) .ladder__list li, .js .spec:not(.is-in) .spec__cell { opacity: 1; translate: none; }
  .marquee__track.is-looping { animation: none; }
  .motion-btn { display: none !important; }
  .tape::after { display: none; }
}
