/* Homepage sections, matching the 1680px wireframe frame. */

/* Anchor-nav offset: the nav is fixed, so anchored sections reserve space
   above them (scrollIntoView / hash landing honour this) — nav bottom is
   ~70px desktop, ~42px mobile. */
#top, #about, #work, #contact {
  scroll-margin-top: calc(80 * var(--px));
}
@media (max-width: 768px) {
  #top, #about, #work, #contact {
    scroll-margin-top: calc(56 * var(--pxm));
  }
}

/* Hold the hero's entrance animations while the loader is covering the
   page, so the reveal plays from the start once it fades. */
body.is-loading .hero__title .char,
body.is-loading .hero__statue,
body.is-loading .hero__row {
  animation-play-state: paused;
}

/* ============ HERO (956 design-px tall) ============ */
.hero {
  position: relative;
  height: calc(956 * var(--px));
  /* 30px page pad + 40px nav height (nav is fixed, out of flow) */
  padding-top: calc(70 * var(--px));
  display: flex;
  flex-direction: column;
  overflow: clip;
}

.hero__inner {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.hero .nav {
  flex: 0 0 auto;
}

.hero__block {
  margin-top: calc(200 * var(--px));
  display: flex;
  flex-direction: column;
  align-items: center;
}

.hero__title {
  font-weight: 400;
  font-size: calc(328.57 * var(--px));
  line-height: calc(400 * var(--px));
  letter-spacing: 0;
  display: flex;
  justify-content: center;
  width: 100%;
  padding: 0 calc(14 * var(--px));
  user-select: none;
  white-space: nowrap;
}

.hero__title .char {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.25em);
  animation: hero-char 0.7s var(--ease-out) forwards;
  animation-delay: calc(0.08s * var(--i));
}

/* Statue: 466x624 at (516, 169) in the 1680 frame */
.hero__statue-wrap {
  position: absolute;
  top: calc(169 * var(--px));
  left: calc(516 * var(--px));
  width: calc(466 * var(--px));
  pointer-events: none;
  will-change: transform;
  z-index: 2;
}

.hero__statue {
  width: 100%;
  height: auto;
  opacity: 0;
  animation: hero-fade 1.4s var(--ease-out) 0.35s forwards;
  filter: grayscale(1) contrast(1.05);
  /* Eases the mouse-parallax tilt so it trails the cursor smoothly. */
  transition: transform 0.4s var(--ease-out);
  transform-origin: center 40%;
}

/* ---- Hero letters: individual hover -------------------------------------
   Once the entrance finishes, JS adds .is-ready to free each letter from
   its entrance animation. Each letter then lifts only on its own hover —
   the word never moves as a whole, and the statue is untouched. Reversible:
   remove this block and the .is-ready line in hero.js. */
.hero__title.is-ready .char {
  animation: none;
  opacity: 1;
  transform: translateY(0) scale(1);
  transition: transform 0.4s var(--ease-out);
  cursor: pointer;
}

.hero__title.is-ready .char:hover {
  transform: translateY(-0.12em) scale(1.06);
}

@media (prefers-reduced-motion: reduce) {
  .hero__title.is-ready .char { transition: none; }
}

/* Tagline + CTA row (padding 0 100 inside the 1620 column) */
.hero__row {
  width: 100%;
  margin-top: calc(100 * var(--px));
  padding: 0 calc(100 * var(--px));
  display: flex;
  justify-content: space-between;
  align-items: center;
  opacity: 0;
  animation: hero-fade 0.9s var(--ease-out) 1.1s forwards;
}

.hero__tagline {
  font-size: calc(36 * var(--px));
  line-height: calc(46 * var(--px));
  font-weight: 400;
}

/* Socials + scroll progress: fixed to the viewport, difference-blended so
   it stays legible over any backdrop (photos, dark footer, white sections)
   without manually tracking which sections are dark. Own compositor layer
   to keep the blend's repaint scoped to this strip. */
.page-foot {
  position: fixed;
  left: var(--edge);
  right: var(--edge);
  bottom: calc(30 * var(--px));
  z-index: 40;
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: #fff;
  mix-blend-mode: difference;
  transform: translateZ(0);
  opacity: 0;
  animation: hero-fade 0.9s var(--ease-out) 1.25s forwards;
}

.page-foot__socials {
  display: flex;
  align-items: center;
  gap: calc(20 * var(--px));
}

.page-foot__socials .imask {
  width: calc(22 * var(--px));
  height: calc(20 * var(--px));
}

.page-foot__progress {
  position: relative;
  width: calc(70 * var(--px));
  height: calc(70 * var(--px));
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: calc(17.9 * var(--px));
}

.page-foot__progress svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transform: rotate(-90deg);
}

.page-foot__progress circle {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
}

.page-foot__ring-bg { opacity: 0.25; }

.page-foot__ring-fg {
  stroke-dasharray: 213.63;
  stroke-dashoffset: 213.63;
}

@keyframes hero-char {
  to { opacity: 1; transform: translateY(0); }
}

@keyframes hero-fade {
  to { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .hero__title .char,
  .hero__statue,
  .hero__row,
  .hero__tagline,
  .hero__row .btn,
  .hero__socials,
  .page-foot {
    animation: none;
    opacity: 1;
    transform: none;
  }
}

/* ============ IMAGE SWITCHER ============ */
/* Single frame (1178x876, #DEDEDE, square corners) that cycles images
   on a timer. It grows to fill the viewport as it scrolls into view —
   no pinning, the page keeps flowing (sized by JS). */
.switcher {
  margin-top: calc(100 * var(--px));
  height: 100svh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: clip;
  /* The stage resizes per-frame while growing; contain scopes that reflow
     to this section (fixed-height, full-width) instead of the whole page. */
  contain: layout;
}

.switcher__stage {
  position: relative;
  width: calc(1178 * var(--px));
  height: calc(876 * var(--px));
  background: var(--color-card);
  overflow: hidden;
}

.switcher__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.4s var(--ease-out);
  /* Own GPU layer so the crossfade composites (no per-frame repaint) and the
     raster stays warm — prevents the hitch when a new image fades in mid-scroll. */
  transform: translateZ(0);
  backface-visibility: hidden;
  will-change: opacity;
}

.switcher__img.is-active { opacity: 1; }

/* ============ METRICS (351) + ABOUT (706) ============ */
.stats {
  margin-top: calc(120 * var(--px));
}

.stats .frame__inner {
  border-top: 1px solid var(--stroke-10);
  padding: calc(100 * var(--px)) calc(50 * var(--px));
  display: flex;
  justify-content: center;
}

.stats__group {
  display: flex;
  gap: calc(120 * var(--px));
  align-items: center;
}

.metric {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  opacity: 0;
  transform: translateY(calc(50 * var(--px)));
  transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out);
  transition-delay: calc(0.12s * var(--i, 0));
}

.metric.is-inview {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .metric {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

.metric__value {
  font-weight: 400;
  font-size: calc(94.09 * var(--px));
  line-height: calc(114.5 * var(--px));
  /* Equal-width digits + a JS-locked width so the count-up never resizes
     the column (which would shove the neighbouring metrics sideways). */
  font-variant-numeric: tabular-nums;
  text-align: center;
}

.metric__label {
  font-size: calc(20 * var(--px));
  line-height: calc(35.45 * var(--px));
  color: var(--color-black-50);
}

.about .frame__inner {
  border-bottom: 1px solid var(--stroke-10);
  padding: calc(100 * var(--px)) 0 calc(100 * var(--px)) calc(100 * var(--px));
  display: flex;
  justify-content: space-between;
  position: relative;
}

.about__left {
  position: relative;
  width: calc(771 * var(--px));
  z-index: 1;
}

/* display-regular-4: 400 / 70 / 80 / letter-spacing 0, left-aligned (JSON) */
.about__title {
  font-weight: 400;
  font-size: calc(70 * var(--px));
  line-height: calc(80 * var(--px));
  letter-spacing: 0;
  text-align: left;
}

.about__title-cursor {
  display: inline-block;
  width: calc(3 * var(--px));
  height: 0.68em;
  background: currentColor;
  vertical-align: baseline;
  margin-left: calc(4 * var(--px));
  animation: cursor-blink 0.9s step-end infinite;
}

@keyframes cursor-blink {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0; }
}

/* Two images behind the title: ionic column + statue (design coords) */
.about__column {
  position: absolute;
  top: calc(24 * var(--px));
  left: calc(180 * var(--px));
  width: calc(627 * var(--px));
  height: calc(627 * var(--px));
  object-fit: contain;
  filter: grayscale(1);
  pointer-events: none;
}

.about__statue {
  position: absolute;
  top: calc(259 * var(--px));
  left: calc(126 * var(--px));
  width: calc(447 * var(--px));
  height: calc(447 * var(--px));
  object-fit: contain;
  filter: grayscale(1);
  pointer-events: none;
}

/* Body text fills from gray to black as the user scrolls (see home.js) */
.about__body {
  width: calc(800 * var(--px));
  font-size: calc(36 * var(--px));
  line-height: calc(46 * var(--px));
  white-space: pre-line;
  position: relative;
  z-index: 1;
}

.about__body .word {
  display: inline-block;
  color: #000;
  opacity: var(--o, 0.15);
  will-change: opacity;
}

/* ============ SELECTED WORKS HEADER (710) ============ */
.works-header {
  padding: calc(200 * var(--px)) calc(50 * var(--px)) calc(100 * var(--px));
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(90 * var(--px));
  position: relative;
}

/* Cupid (from JSON 2147238419): 402.51² sitting over the "D" in SELECTED.
   Three nested layers so their motions never fight:
     .works-header__cupid      — scroll parallax (JS --py)
     .works-header__cupid-fly  — entrance glide on X (ease-out)
     img                       — entrance drop on Y + rotate, then the
                                  floating bob; recoil is layered on via JS.
   Splitting X and Y across two layers with different easings makes the
   entrance one continuous curved swoop (no keyframe waypoints to snap at). */
.works-header__cupid {
  position: absolute;
  top: calc(221 * var(--px));
  left: 50%;
  margin-left: calc(256.5 * var(--px));
  width: calc(402.51 * var(--px));
  height: calc(402.51 * var(--px));
  z-index: 3;
  pointer-events: none;
  transform: translateY(var(--py, 0));
  will-change: transform;
}

.works-header__cupid-fly {
  display: block;
  width: 100%;
  height: 100%;
  will-change: transform;
}

.works-header__cupid img {
  width: 100%;
  height: 100%;
  opacity: 0;
  /* The image is the hover target that fires the arrow (the wrapper stays
     click-through so it never blocks the heading beneath it). */
  pointer-events: auto;
  will-change: transform, opacity;
}

/* Fired arrow: a fixed, click-through element so it can fly across the
   whole viewport without affecting layout. Positioned + rotated by JS. */
.cupid-arrow {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 90;
  pointer-events: none;
  transform-origin: 0 50%;
  will-change: transform, opacity;
}

/* Entrance fires with the SELECTED WORKS slide-up (.is-inview):
   X glides in and decelerates (ease-out) while Y eases in and drops —
   together a smooth curved swoop. The img then eases straight into an
   endless gentle bob so it reads as floating in place. */
.works-header.is-inview .works-header__cupid-fly {
  animation: cupid-fly-x 1s var(--ease-out) both;
}

.works-header.is-inview .works-header__cupid img {
  animation:
    cupid-fly-y 1s cubic-bezier(0.45, 0, 0.35, 1) both,
    cupid-fade 0.55s ease-out both,
    cupid-bob 5s ease-in-out 1.05s infinite;
}

@keyframes cupid-fly-x {
  from { transform: translateX(155%); }
  to   { transform: translateX(0); }
}

@keyframes cupid-fly-y {
  from { transform: translateY(52%) rotate(-9deg); }
  to   { transform: translateY(0) rotate(0deg); }
}

@keyframes cupid-fade {
  0%   { opacity: 0; }
  100% { opacity: 1; }
}

/* Floating bob: a slow rise-and-fall with a hair of sway. Its 0% is the
   resting transform, so it hands off seamlessly from the fly-in. */
@keyframes cupid-bob {
  0%   { transform: translateY(0) rotate(0deg); }
  50%  { transform: translateY(calc(-24 * var(--px))) rotate(-1.4deg); }
  100% { transform: translateY(0) rotate(0deg); }
}

@media (prefers-reduced-motion: reduce) {
  .works-header__cupid img { opacity: 1; }
  .works-header.is-inview .works-header__cupid-fly,
  .works-header.is-inview .works-header__cupid img { animation: none; }
}

.works-header__meta {
  display: flex;
  align-items: center;
  gap: calc(20 * var(--px));
  font-size: calc(20 * var(--px));
  line-height: calc(30 * var(--px));
}

/* Meta row + title slide up as the section scrolls into view (.is-inview). */
.works-header__meta,
.works-header__title {
  opacity: 0;
  transform: translateY(calc(60 * var(--px)));
  transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out);
}

.works-header.is-inview .works-header__meta,
.works-header.is-inview .works-header__title {
  opacity: 1;
  transform: none;
}

.works-header.is-inview .works-header__title {
  transition-delay: 0.12s;
}

@media (prefers-reduced-motion: reduce) {
  .works-header__meta,
  .works-header__title {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

.works-header__line {
  width: calc(432 * var(--px));
  border-top: 1px solid var(--stroke-10);
}

.works-header__title {
  font-weight: 400;
  font-size: calc(171.88 * var(--px));
  line-height: calc(189 * var(--px));
  text-align: center;
  white-space: nowrap;
}


/* ============ WORKS LIST ============ */
.works-list {
  display: flex;
  flex-direction: column;
  gap: calc(80 * var(--px));
}

.work-item__inner {
  display: flex;
  flex-direction: column;
  gap: calc(30 * var(--px));
}

/* Works scale with the scroll: JS drives --ws/--wo per frame, so each
   item grows in as it approaches the viewport middle and shrinks back
   out as it leaves — in both scroll directions. No transition here;
   the smoothness comes from the eased scroll + per-frame updates. */
.work-item {
  opacity: var(--wo, 1);
  transform: scale(var(--ws, 1));
  will-change: opacity, transform;
}

.work-item__head {
  display: flex;
  align-items: center;
  gap: calc(50 * var(--px));
}

.work-item__index {
  font-weight: 400;
  font-size: calc(94.09 * var(--px));
  line-height: calc(114.5 * var(--px));
}

.work-item__line {
  flex: 1;
  border-top: 1px solid var(--stroke-10);
}

.work-item__meta {
  display: flex;
  flex-direction: column;
  justify-content: center;
  text-align: right;
  white-space: nowrap;
}

.work-item__name {
  font-weight: 400;
  font-size: calc(40 * var(--px));
  line-height: calc(50 * var(--px));
}

.work-item__desc {
  font-size: calc(16 * var(--px));
  line-height: calc(26 * var(--px));
  opacity: 0.5;
}

.work-item__media {
  display: block;
  width: 100%;
  aspect-ratio: 1620 / 1250;
  background: var(--color-card);
  overflow: hidden;
}

.work-item__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.6s var(--ease-out);
}

.work-item__media:hover img {
  transform: scale(1.02);
}

/* ============ APP STORE SCREENSHOTS STRIP (500) ============ */
.shots-strip {
  margin-top: calc(90 * var(--px));
  border-top: 1px solid var(--stroke-10);
  border-bottom: 1px solid var(--stroke-10);
}

.shots-strip .frame__inner {
  height: calc(498 * var(--px));
  padding: 0 calc(50 * var(--px));
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.shots-strip__intro {
  width: calc(335 * var(--px));
  font-size: calc(16 * var(--px));
  line-height: calc(26 * var(--px));
}

.shots-strip__cam {
  position: relative;
  width: calc(470 * var(--px));
  flex: 0 0 auto;
}

.shots-strip__camimg {
  display: block;
  width: 100%;
  height: auto;
}

.shots-strip__right {
  display: flex;
  align-items: center;
  gap: calc(70 * var(--px));
}

.shots-strip__title {
  font-weight: 400;
  font-size: calc(70 * var(--px));
  line-height: calc(80 * var(--px));
  text-align: right;
  white-space: pre-line;
}

.shots-strip__title:hover { opacity: 0.6; }

.shots-strip__year {
  font-size: calc(20 * var(--px));
  line-height: calc(50 * var(--px));
}

/* ============ SCREENSHOTS BAND (996, full-bleed) ============ */
.shots-band {
  display: block;
  margin-top: calc(100 * var(--px));
  background: var(--color-card);
  overflow: hidden;
}

.shots-band img {
  width: 100%;
  height: auto;
  transition: transform 0.6s var(--ease-out);
}

.shots-band:hover img {
  transform: scale(1.02);
}

/* ============ TESTIMONIALS ============ */
.testimonials {
  margin-top: calc(100 * var(--px));
}

.testimonials__head {
  border-top: 1px solid var(--stroke-10);
}

.testimonials__head .frame__inner {
  position: relative;
  padding: calc(50 * var(--px));
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.testimonials__title {
  font-weight: 400;
  font-size: calc(70 * var(--px));
  line-height: calc(80 * var(--px));
  max-width: calc(470 * var(--px));
}

.testimonials__intro {
  /* Absolutely placed so its left edge lands exactly on the quote
     column's left edge below (50% of the padded box + the 10 gap),
     vertically centered against the title beside it. */
  position: absolute;
  top: 50%;
  left: calc(50% + 10 * var(--px));
  transform: translateY(-50%);
  width: calc(330 * var(--px));
  text-align: left;
  font-weight: 300;
  font-size: calc(16 * var(--px));
  line-height: calc(26 * var(--px));
}

.testimonials__slider {
  border-bottom: 1px solid var(--stroke-10);
}

.testimonials__slider .frame__inner {
  border-top: 1px solid var(--stroke-10);
  padding: calc(50 * var(--px));
  display: flex;
  gap: calc(10 * var(--px));
}

.testimonials__names {
  width: 50%;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: calc(10 * var(--px));
}

.testimonials__names button {
  display: block;
  text-align: left;
  font-size: calc(16 * var(--px));
  line-height: calc(26 * var(--px));
  color: var(--color-black-20);
  text-transform: uppercase;
  transition: color 0.25s;
}

.testimonials__names button.is-active,
.testimonials__names button:hover {
  color: var(--color-text);
}

.testimonials__panel {
  width: 50%;
  display: flex;
  flex-direction: column;
  gap: calc(10 * var(--px));
}

.testimonials__quote {
  min-height: calc(230 * var(--px));
  display: flex;
  align-items: flex-start;
  font-size: calc(36 * var(--px));
  line-height: calc(46 * var(--px));
}

.testimonials__who {
  display: flex;
  align-items: flex-end;
  gap: calc(20 * var(--px));
}

.testimonials__avatar {
  width: calc(70 * var(--px));
  height: calc(70 * var(--px));
  background: var(--color-card);
  border-radius: 50%;
  object-fit: cover;
  flex: 0 0 auto;
}

.testimonials__person {
  font-size: calc(20 * var(--px));
  line-height: calc(26 * var(--px));
}

.testimonials__role {
  font-size: calc(16 * var(--px));
  line-height: calc(26 * var(--px));
  color: var(--color-black-50);
}

/* Company label is a mobile-only element; desktop keeps it in .role */
.testimonials__company { display: none; }

/* Thin spacer bar under the slider (146 design-px, as in the frame) */
.testimonials__foot {
  height: calc(146 * var(--px));
}

/* Mobile-only hero elements (meta row + socials + line break): desktop
   hides them — DESIGNER stays a single line on desktop */
@media (min-width: 769px) {
  .hero__meta,
  .hero__socials,
  .hero__break { display: none; }
}

/* Mobile-only shots-strip meta row, view button, camera badge, band copy */
@media (min-width: 769px) {
  .shots-strip__meta,
  .shots-strip__view,
  .shots-strip__badge,
  .shots-band-m { display: none; }
}

/* Mobile-only testimonials heading row (quote + line): desktop hides it */
@media (min-width: 769px) {
  .testimonials__meta { display: none; }
}

/* Mobile-only about avatar: desktop keeps its own two-image layout untouched.
   display:contents means this wrapper never affects desktop's box model —
   its children (the title) sit exactly where they did before this wrapper
   was introduced. */
.about__head-row { display: contents; }
.about__avatar { display: none; }
/* The header-box corner markers are a mobile-only detail */
.about__plus-tl,
.about__plus-tr,
.about__plus-bl,
.about__plus-br { display: none; }

/* ============================================================
   MOBILE  ≤ 768px — 1:1 from the 440px Figma mobile wireframe.
   --pxm scales the 440 design frame to the viewport, mirroring
   how --px scales the 1680 frame on desktop. All figures below are
   literal JSON pixel values (already native to the 440 frame) or,
   for the two oversized display words (DESIGNER / PLAYGROUND), a
   font-size solved so the real Britti Sans renders at the JSON's
   measured text-box width — the JSON's font-size token is Figma's
   pre-layout value and does not by itself reproduce that width.
   ============================================================ */
@media (max-width: 768px) {
  :root { --pxm: calc(100vw / 440); }

  /* ----- Hero (frame: 440x808, pad 0/16/50/16) ----- */
  .hero {
    height: calc(803 * var(--pxm));
    /* nav footprint: 10 top + 40 height = content clears the fixed nav */
    padding-top: calc(50 * var(--pxm));
  }

  .hero__block {
    margin-top: 0;
    align-items: center;
    /* 65 between the nav's bottom edge and the meta row */
    padding: calc(65 * var(--pxm)) calc(16 * var(--pxm)) 0;
  }

  /* Meta row above DESIGNER: EST 2021 —— local time. Mobile-only. */
  .hero__meta {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: calc(20 * var(--pxm));
    font-size: calc(16 * var(--pxm));   /* body-lg-regular 16/26 */
    line-height: calc(26 * var(--pxm));
    margin-bottom: calc(15 * var(--pxm)); /* 2147238611 gap-15 */
    opacity: 0;
    animation: hero-fade 0.9s var(--ease-out) 0.3s forwards;
  }

  body.is-loading .hero__meta { animation-play-state: paused; }

  .hero__meta-line {
    width: calc(121 * var(--pxm));
    border-top: 1px solid var(--stroke-10);
  }

  /* DESIGNER breaks as "DESIG / NER" (the wireframe's text node is
     literally two lines at display-regular 140/140/-2 — that's why its
     box is 280 tall = 2 x 140 line-height). The .hero__break span forces
     the flex line break after the G; with two lines the token's literal
     140/-2 fits the 408 box. */
  .hero__title {
    min-height: calc(280 * var(--pxm));
    flex-wrap: wrap;
    align-content: flex-start;
    align-items: flex-start;
    font-size: calc(140 * var(--pxm));
    line-height: calc(140 * var(--pxm));
    letter-spacing: calc(-2 * var(--pxm));
    justify-content: center;
    padding: 0;
  }

  .hero__break {
    flex-basis: 100%;
    height: 0;
  }

  /* Tagline + CTAs (2147238409/2147238410: gap-100 above, pad 0/40) */
  .hero__row {
    flex-direction: column;
    align-items: center;
    gap: calc(40 * var(--pxm));
    margin-top: calc(100 * var(--pxm));
    padding: 0 calc(40 * var(--pxm));
    /* the row itself doesn't fade as one block on mobile — its children
       rise in sequence below */
    opacity: 1;
    animation: none;
  }

  .hero__tagline,
  .hero__row .btn {
    opacity: 0;
    transform: translateY(calc(18 * var(--pxm)));
    animation: hero-rise 0.7s var(--ease-out) forwards;
  }

  .hero__tagline { animation-delay: 0.9s; }
  .hero__row .btn:nth-child(1) { animation-delay: 1.05s; }
  .hero__row .btn:nth-child(2) { animation-delay: 1.2s; }

  body.is-loading .hero__tagline,
  body.is-loading .hero__row .btn { animation-play-state: paused; }

  @keyframes hero-rise {
    to { opacity: 1; transform: translateY(0); }
  }

  .hero__tagline {
    font-size: calc(20 * var(--pxm));   /* h3-regular 20/30 */
    line-height: calc(30 * var(--pxm));
    text-align: center;
  }

  .hero__row .btn-row {
    flex-direction: column;
    width: calc(230 * var(--pxm));
    gap: calc(10 * var(--pxm));
  }

  .hero__row .btn {
    width: 100%;
    height: calc(46 * var(--pxm));
    font-size: calc(16 * var(--pxm));
  }


  /* Julius (289.53x387.66): top 6.42 within 2147238408, which itself
     starts at nav(60)+gap(30)=90 from .hero's own top → 96.42 total.
     Left 59.23 within the 408 content box (page pad 16) → 75.23 from
     .hero's left edge — i.e. horizontally centered in that content box. */
  .hero__statue-wrap {
    top: calc(91.42 * var(--pxm)); /* rides down 20 with the wider 65 gap */
    left: calc(75.23 * var(--pxm));
    width: calc(289.53 * var(--pxm));
  }

  /* Socials (2147238412, 20 tall): sit 50px above the hero's bottom edge
     (758 content + 50 bottom pad = 808 frame height). */
  .hero__socials {
    position: absolute;
    bottom: calc(50 * var(--pxm));
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    gap: calc(20 * var(--pxm));
    opacity: 0;
    animation: hero-fade 0.9s var(--ease-out) 1.25s forwards;
  }

  body.is-loading .hero__socials { animation-play-state: paused; }

  .hero__socials .imask {
    width: calc(22 * var(--pxm));
    height: calc(20 * var(--pxm));
    background: var(--color-text);
  }

  /* Fixed socials + progress ring: hidden (socials live in hero + footer) */
  .page-foot { display: none; }

  /* ----- Framed sections: 10px side inset (2147238418 et al), visible
     vertical rules, and the wireframe's 12x15 plus markers. Scoped so
     the hero (also .frame) keeps its own padding. ----- */
  .about.frame { padding: 0 calc(16 * var(--pxm)); }
  .testimonials__head.frame,
  .testimonials__slider.frame { padding: 0 calc(16 * var(--pxm)); }

  .plus {
    width: calc(12 * var(--pxm));
    height: calc(15 * var(--pxm));
    -webkit-mask: url("/assets/icons/plus-mobile.svg") center / contain no-repeat;
    mask: url("/assets/icons/plus-mobile.svg") center / contain no-repeat;
  }

  /* ----- Switcher: fixed 550px band, gap-20 below the hero. The image
     fills the height and scales its width proportionally (overflow is
     clipped by the stage) rather than being letterboxed. ----- */
  .switcher {
    margin-top: calc(20 * var(--pxm));
    height: calc(550 * var(--pxm));
    padding: 0;
  }

  .switcher__stage {
    width: 100%;
    height: calc(550 * var(--pxm));   /* matches the switcher frame exactly */
  }

  .switcher__img {
    inset: auto;
    left: 50%;
    right: auto;
    width: auto;
    height: 110%;
    max-width: none;
    object-fit: cover;
  }

  .switcher__img--top,
  .switcher__img--center,
  .switcher__img--bottom { top: 50%; bottom: auto; transform: translate(-50%, -50%); }

  /* ----- About (2147238399 440x737; pad 0/10/0/10 → 2147238403 gap-50
     pad 50/0/50/0): heading row (ABOUT DESIGNER ELO + 160x160 avatar,
     space-between) then a centered body paragraph. ----- */
  .about {
    padding: 0 calc(10 * var(--pxm));
  }

  .about__column,
  .about__statue { display: none; }

  /* Only a bottom stroke beneath the whole section — no top/side rules */
  .about .frame__inner {
    position: relative;
    flex-direction: column;
    gap: calc(50 * var(--pxm));
    padding: calc(50 * var(--pxm)) 0;
    border-left: 0;
    border-right: 0;
    border-top: 0;
    border-bottom: 1px solid var(--stroke-10);
  }

  /* + at the left and right ends of the section's bottom stroke */
  .about .frame__inner > .plus--bl,
  .about .frame__inner > .plus--br { display: block; }

  .about__left {
    width: 100%;
    margin-bottom: 0;
  }

  /* Header cell (2147238589): an 83px box stroked all the way round, with
     a + at each of its four corners */
  .about__head-row {
    position: relative;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: calc(10 * var(--pxm));
    padding: 0 calc(30 * var(--pxm)) 0 calc(10 * var(--pxm));
    border: 1px solid var(--stroke-10);
    height: calc(83 * var(--pxm));
  }

  .about__plus-tl,
  .about__plus-tr,
  .about__plus-bl,
  .about__plus-br { display: block; }
  .about__plus-tl,
  .about__plus-bl { left: 0; right: auto; }
  .about__plus-tr,
  .about__plus-br { left: 100%; right: auto; }
  .about__plus-tl,
  .about__plus-tr { top: 0; }
  .about__plus-bl,
  .about__plus-br { top: 100%; }

  /* ABOUT / <typed> on two lines (h3-regular-2 20/26, box 138.75 wide) */
  .about__title {
    font-size: calc(20 * var(--pxm));   /* h3-regular-2 20/26 */
    line-height: calc(26 * var(--pxm));
    letter-spacing: 0;
  }

  /* Statue photo in a 160x160 crop box: the source art is 256.22 wide,
     shifted -45.47/+34.36 inside the frame (2147238612/AboutStatueMobile) */
  .about__avatar {
    display: block;
    position: relative;
    width: calc(160 * var(--pxm));
    height: calc(160 * var(--pxm));
    overflow: visible;
    flex: 0 0 auto;
    align-self: flex-end;
  }

  .about__avatar img {
    position: absolute;
    bottom: 0;
    top: auto;
    left: calc(-45.47 * var(--pxm));
    width: calc(256.22 * var(--pxm));
    max-width: none;
  }

  .about__body {
    width: 100%;
    max-width: calc(400 * var(--pxm));
    padding: 0;
    font-size: calc(28 * var(--pxm));   /* h2-regular 28/36 */
    line-height: calc(36 * var(--pxm));
    margin: 0 auto;
  }

  /* ----- Selected works header (2147238419 440x380 pad 80/20/80/20;
     content 400x220 centered, gap-30) ----- */
  .works-header {
    padding: calc(80 * var(--pxm)) calc(20 * var(--pxm)) calc(75 * var(--pxm));
    gap: calc(10 * var(--pxm));
  }

  .works-header__meta {
    font-size: calc(16 * var(--pxm));   /* body-lg-regular 16/26 */
    line-height: calc(26 * var(--pxm));
    gap: calc(20 * var(--pxm));
    margin-bottom: calc(30 * var(--pxm));
  }

  .works-header__line { width: calc(101 * var(--pxm)); }

  .works-header__title {
    font-size: calc(74.2 * var(--pxm));  /* display-regular-3 74.2/81.6 */
    line-height: calc(81.6 * var(--pxm));
    text-align: center;
  }

  /* Cupid (137.4x137.4): top 76.97 within the 220-tall centered content
     block (which starts at the section's 80 pad-top) → 156.97 from the
     section top; left 270.6 within the 400 box (+20 section pad) */
  .works-header { position: relative; }

  .works-header__cupid {
    top: calc(156.97 * var(--pxm));
    left: calc(290.6 * var(--pxm));
    margin-left: 0;
    width: calc(137.4 * var(--pxm));
    height: calc(137.4 * var(--pxm));
  }

  /* ----- Works list (each item 440x411, pad 0/16/0/16; image 408x360,
     gap-15, caption row gap-13.1: index (h2-regular-2 26/36) —— name
     (h3-regular-3 20/30, right-aligned). No description on mobile. ----- */
  .works-list { gap: calc(40 * var(--pxm)); }

  .work-item {
    padding: 0 calc(16 * var(--pxm));
    display: flex;
    justify-content: center;
  }

  /* Mobile order (2147238433): image first, caption (index — name) below */
  .work-item__inner {
    width: 100%;
    display: flex;
    flex-direction: column;
  }

  .work-item__media { order: 1; }

  .work-item__head {
    order: 2;
    gap: calc(13.1 * var(--pxm));
    margin-bottom: 0;
    margin-top: calc(15 * var(--pxm));   /* 2147238433 gap-15 */
  }

  .work-item__index {
    font-size: calc(26 * var(--pxm));
    line-height: calc(36 * var(--pxm));
  }

  .work-item__name {
    font-size: calc(20 * var(--pxm));
    line-height: calc(30 * var(--pxm));
  }

  .work-item__desc { display: none; }

  .work-item__meta {
    display: flex;
    flex-direction: column;
    text-align: right;
  }

  .work-item__media {
    aspect-ratio: 408 / 360;
  }

  .work-item__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  /* ----- App Store screenshots strip (2147238594 440x718, pad-top 100,
     gap-30, centered): meta row, title, intro, recor band, view button,
     floating camera badge (2147238595 → title left-aligned at 50/60). ----- */
  .shots-strip {
    padding: calc(55 * var(--pxm)) 0 calc(65 * var(--pxm));
    position: relative;
    border-top: 0;      /* no section rules on mobile */
    border-bottom: 0;
  }

  /* No frame rules or + markers on this section at all */
  .shots-strip .frame__inner {
    height: auto;
    padding: 0 calc(30 * var(--pxm));
    display: flex;
    flex-direction: column;
    gap: 0;
    align-items: center;
    border-left: 0;
    border-right: 0;
  }

  .shots-strip .plus { display: none; }

  .shots-strip__right {
    order: 1;
    flex-direction: column;
    align-items: center;          /* 2147238596 items=center */
    gap: calc(20 * var(--pxm));   /* 2147238596 gap-20 */
    width: 100%;
    position: relative;
    z-index: 1;
    margin-bottom: calc(20 * var(--pxm));
  }

  .shots-strip__meta {
    display: flex;
    align-items: center;
    gap: calc(20 * var(--pxm));
    font-size: calc(16 * var(--pxm));  /* body-lg-regular 16/26 */
    line-height: calc(26 * var(--pxm));
  }

  .shots-strip__meta-line {
    width: calc(154 * var(--pxm));
    border-top: 1px solid var(--stroke-10);
  }

  /* Title spans the full 380 header width, left-aligned (the meta row
     above it stays centered — 2147238596 items=center, title align=left) */
  .shots-strip__title {
    width: 100%;
    font-size: calc(50 * var(--pxm));   /* display-regular 50/60 */
    line-height: calc(60 * var(--pxm));
    text-align: left;
  }

  .shots-strip__year { display: none; }

  .shots-strip__intro {
    order: 2;
    width: 100%;
    max-width: calc(330 * var(--pxm));  /* wider so the copy sits on 3 lines */
    font-size: calc(14 * var(--pxm));   /* body-md-regular-3 14/22 */
    line-height: calc(22 * var(--pxm));
    text-align: center;
    color: rgba(0, 0, 0, 0.5);
    margin: 0 auto;
    padding: 0 calc(16 * var(--pxm));
  }

  .shots-strip__cam {
    display: none; /* replaced by the floating badge below */
  }

  /* Floating camera badge (137.2x137.2). In the 718-tall wireframe it was
     at top 117.36; this section drops that frame's 100px top offset, so
     the camera lands at 17.36 — overlapping the right of APP STORE down
     into SCREENSHOTS. In front of the title (transparent PNG). */
  .shots-strip__badge {
    position: absolute;
    top: calc(17.36 * var(--pxm));
    left: calc(287.76 * var(--pxm));
    width: calc(137.2 * var(--pxm));
    pointer-events: none;
    z-index: 2;
  }

  .shots-strip__badge img {
    display: block;
    width: 100%;
    height: auto;
  }

  /* Recor band inside the strip (order 3; "8": 408x250, 16px inset) */
  .shots-band { display: none; } /* desktop's sibling band */

  .shots-band-m {
    order: 3;
    display: block;
    width: calc(408 * var(--pxm));
    height: calc(250 * var(--pxm));
    margin: 30px calc(-14 * var(--pxm)) 0;
    overflow: hidden;
  }

  .shots-band-m img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }

  /* VIEW SCREENSHOTS button (2147238597/2147238413: 177x46) */
  .shots-strip__view {
    order: 4;
    margin-top: 30px;
    width: calc(177 * var(--pxm));
    height: calc(46 * var(--pxm));
    font-size: calc(14 * var(--pxm));   /* body-md-regular-2 14/44 */
  }

  .shots-strip__arrow {
    width: calc(12 * var(--pxm));
    height: calc(12 * var(--pxm));
    flex-shrink: 0;
    align-self: center;
    margin-left: -3px;
  }

  .shots-strip__arrow line,
  .shots-strip__arrow polyline { stroke: #fff; stroke-width: 1.2; }

  /* ----- Testimonials (2147238589 440x491.64, pad 70/10/50/10 → content
     420x371.64 centered, pad-top/bottom 30 → 2147238600 420x311.64
     gap-45: head row (quote + line + heading) then quote + person) ----- */
  /* The whole section reads as ONE bordered box (2147238444): top rule
     here (30px of space above the meta row — no rule directly on it),
     the bottom rule lives under the person row in the slider below. No
     rule or markers between the meta row and the reviews — just space. */
  /* Single top rule: the box border lives on the frame__inner only (the
     outer .testimonials__head carries a desktop border-top that would
     double it up on mobile — clear it) */
  .testimonials__head { border-top: 0; }
  .testimonials__slider { border-bottom: 0; }

  .testimonials__head .frame__inner {
    padding: calc(30 * var(--pxm)) calc(26 * var(--pxm)) 0;
    border-top: 1px solid var(--stroke-10);
  }

  .testimonials__meta {
    width: 100%;   /* fill the frame so the rule expands + title sits right */
    display: flex;
    align-items: center;
    gap: calc(20 * var(--pxm));
    margin-bottom: calc(45 * var(--pxm));  /* 2147238600 gap-45 → space, not a rule */
  }

  /* The exported quote glyph (its 0.1 opacity is baked into the SVG, so
     it renders as an image — a mask + faint fill would make it invisible) */
  .testimonials__meta-quote {
    width: calc(37.2 * var(--pxm));
    height: calc(32.64 * var(--pxm));
    flex: 0 0 auto;
    background: url("/assets/icons/quote-mark.svg") left center / contain no-repeat;
  }

  .testimonials__meta-line {
    flex: 1 1 auto;
    height: 1px;
    background: var(--stroke-10);
  }

  .testimonials__meta-title {
    flex: 0 0 auto;
    font-size: calc(16 * var(--pxm));   /* body-lg-medium 16/22 */
    line-height: calc(22 * var(--pxm));
    font-weight: 500;
    text-align: right;
    white-space: nowrap;
  }

  .testimonials__title,
  .testimonials__intro { display: none; }

  /* No top rule here and no top + markers (hidden below) — the reviews
     just sit in space below the meta row */
  .testimonials__slider .frame__inner {
    padding: 0 calc(16 * var(--pxm)) calc(30 * var(--pxm));
    border-top: 0;   /* no rule between the meta row and the reviews */
    border-bottom: 1px solid var(--stroke-10);
  }

  .testimonials__slider .plus--tl,
  .testimonials__slider .plus--tr { display: none; }

  .testimonials__names { display: none; }

  .testimonials__panel {
    width: 100%;
    gap: calc(40 * var(--pxm));         /* 2147238602 gap-40 */
  }

  .testimonials__quote {
    min-height: 0;
    font-size: calc(28 * var(--pxm));   /* h2-regular 28/36 */
    line-height: calc(36 * var(--pxm));
  }

  /* Person row (2147238445): avatar + name/title left, company label
     pulled to the far right, all bottom-aligned (items=end) */
  .testimonials__who {
    gap: calc(10 * var(--pxm));
    align-items: flex-end;
  }

  .testimonials__avatar {
    width: calc(50 * var(--pxm));
    height: calc(50 * var(--pxm));
    border-radius: 50%;
    object-fit: cover;
  }

  .testimonials__person {
    font-size: calc(16 * var(--pxm));   /* body-lg-regular 16/26 */
    line-height: calc(26 * var(--pxm));
  }

  .testimonials__role {
    font-size: calc(14 * var(--pxm));   /* body-md-regular 14/22 */
    line-height: calc(22 * var(--pxm));
    color: rgba(0, 0, 0, 0.5);
  }

  /* AURA FORGE — right-aligned company label (819:269788) */
  .testimonials__company {
    display: block;
    margin-left: auto;
    font-size: calc(14 * var(--pxm));   /* body-md-regular-2 14/22 */
    line-height: calc(22 * var(--pxm));
    color: rgba(0, 0, 0, 0.5);
    text-align: right;
    white-space: nowrap;
  }

  .testimonials__foot { height: calc(60 * var(--pxm)); }
}
