:root {
  --bg: #fffffd;
  --ink: #2a2a2a;
  --font-display: "Bricolage Grotesque", system-ui, sans-serif;
  --font-text: "DM Sans", system-ui, sans-serif;
  --font-script: "Hilbert", "Mrs Saint Delafield", cursive; /* Hilbert not licensed yet — Google fallback */
  --gutter: clamp(16px, 2.12vw, 32px);
  --dock-space: 102px; /* room the framed hero leaves for the dock */
}

*, *::before, *::after { box-sizing: border-box; }

html { background: var(--bg); }
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-text);
  font-size: 16px;
  line-height: 1.2;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;
}

a { color: inherit; text-decoration: none; }
img, video { display: block; }

/* ───────────── Hero ───────────── */

.hero { height: 170vh; } /* 100vh screen + 70vh of scroll for the framing */

.hero__sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
}

.hero__media {
  position: absolute;
  inset: 0;
  clip-path: inset(0px 0px 0px 0px round 0px 0px 0px 0px);
  will-change: clip-path;
}

.hero__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 100%;
  transform-origin: 50% 100%; /* the frame closes in from above: the floor she walks on never gets cropped */
  will-change: transform;
}

.hero__ui {
  position: absolute;
  inset: 0;
  color: #fff;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: var(--gutter);
}

.hero__top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
}

.hero__menu {
  display: flex;
  gap: 24px;
  white-space: nowrap;
  /* optical alignment with the cap height of the title */
  padding-top: 2px;
}


.hero__title {
  margin: 0;
  font-family: var(--font-display);
  font-variation-settings: "opsz" 96, "wdth" 100; /* Figma: Bricolage 96pt ExtraBold */
  font-weight: 800;
  font-size: clamp(28px, 4.1vw, 62px);
  line-height: 1;
  letter-spacing: -0.04em;
  text-transform: uppercase;
  text-align: center;
  white-space: nowrap;
  margin-top: -0.12em; /* trim the ascender gap so caps sit on the 32px line */
}

.hero__bottom {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
}

.hero__logo {
  font-family: var(--font-display);
  font-variation-settings: "opsz" 96, "wdth" 100;
  font-weight: 800;
  font-size: 20px;
  line-height: 1;
  text-transform: uppercase;
}

.hero__logo, .hero__download { cursor: default; user-select: none; }

/* ───────────── Story stage ───────────── */

.story {
  position: relative;
  /* starts right under the framed hero card, so the dock band belongs to the stage
     and tiles can fly through it without being cut */
  margin-top: calc(-1 * var(--dock-space));
  height: calc(5960vh + var(--dock-space)); /* = story timeline duration × 100vh, kept in sync by main.js */
}

.story__sticky {
  position: sticky;
  top: calc(-1 * var(--dock-space));
  height: calc(100vh + var(--dock-space));
  overflow: clip;
}

/* Fixed 1512×826 design canvas, scaled to fit the viewport */
.canvas {
  --s: 1;
  position: absolute;
  left: 50%;
  top: calc(var(--dock-space) + 50vh);
  width: 1512px;
  height: 826px;
  margin: -413px 0 0 -756px;
  transform: scale(var(--s));
  transform-origin: 50% 50%;
}

.canvas > *, .act > * { position: absolute; left: 0; top: 0; }

/* Acts: groups that leave the stage upwards as one block. They overlap, so an act must
   never swallow pointer events meant for an earlier one — only its hover targets do. */
.act { width: 1512px; height: 826px; will-change: transform; pointer-events: none; }

/* Tiles */
.tile {
  position: absolute;
  left: 0;
  top: 0;
  width: 160px;
  height: 160px;
  opacity: 0;
  will-change: transform, opacity;
}

.tile img {
  width: 100%;
  height: 100%;
  border-radius: 32px;
  will-change: transform;
}

/* Lead text */
.lead {
  margin: 0;
  font-family: var(--font-display);
  font-variation-settings: "opsz" 14, "wdth" 100;
  font-weight: 400;
  font-size: 54px;
  line-height: normal;
  letter-spacing: -0.06em;
  color: var(--ink);
  transform-origin: 0 0;
  white-space: nowrap;
  pointer-events: none;
}

.lead__line {
  display: block;
  width: max-content;
}

.blur-text .char { opacity: 0; filter: blur(12px); will-change: filter, opacity; }

/* Second and third statements: 60px, black, left/right aligned */
.lead2, .lead3, .lead4, .lead5, .lead6a {
  margin: 0;
  font-family: var(--font-display);
  font-variation-settings: "opsz" 14, "wdth" 100;
  font-weight: 400;
  font-size: 60px;
  line-height: normal;
  letter-spacing: -0.06em;
  color: var(--ink);
  white-space: nowrap;
  pointer-events: none;
}
.lead2 { left: 64px; top: 543px; width: 851px; }
.lead3 { left: 917px; top: 474px; width: 531px; text-align: right; }
.lead4 { left: 64px; top: 615px; width: 919px; }
.lead5 { left: 502px; top: 618px; width: 946px; text-align: right; }
.lead6a { left: 64px; top: 615px; width: 470px; }
.lead2 .lead__line, .lead3 .lead__line, .lead4 .lead__line, .lead5 .lead__line, .lead6a .lead__line { width: auto; }

/* Chip + caption next to each statement (Figma: pink chip, DM Sans 16/24 caption).
   Positioned as in the file; the chip is anchored to the side the block aligns to. */
.meta {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 19px;
  pointer-events: none;
}
.meta2 { right: 64px; top: 631px; }
.meta3 { right: 64px; top: 64px; }
.meta4 { right: 64px; top: 631px; }
.meta5 { left: 434px; top: 338px; align-items: flex-start; }
.meta6 { right: 64px; top: 631px; }
.meta2 .caption, .meta3 .caption { width: 386px; }
.meta4 .caption, .meta5 .caption, .meta6 .caption { width: 332px; }
.meta5 .caption { text-align: left; }

.caption {
  margin: 0;
  font-family: var(--font-text);
  font-size: 16px;
  line-height: 24px;
  text-align: right;
  color: var(--ink);
  opacity: 0;
  filter: blur(12px);
  will-change: filter, opacity;
}

/* The chip unrolls from its anchored end to the width of its text, then the text fades in.
   Width is animated (overflow hidden, content pinned to the anchor), so the ends stay round. */
.chip {
  position: relative;
  display: block;
  height: 28px;
  width: 0;
  border-radius: 10px;
  background: #fff4fc;
  overflow: hidden;
  will-change: width;
}
.chip__in {
  position: absolute;
  top: 0;
  right: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  height: 28px;
  padding: 0 10px;
  white-space: nowrap;
  opacity: 0;
  filter: blur(6px);
}
.meta5 .chip__in { right: auto; left: 0; }
.chip__label, .chip__num {
  font-family: var(--font-text);
  font-weight: 500;
  font-size: 16px;
  line-height: 1;
  color: #e57fca;
}
.chip__dash { display: block; width: 22px; height: 4px; border-radius: 50%; background: #e57fca; } /* the Figma ellipse, not a capsule */

/* ───────────── Route (act 5) ───────────── */

.route { pointer-events: none; }
/* A link between two stops: the Figma ellipse (15px wide), rotated about its centre.
   It is revealed lengthwise from the previous stop by a clip that slides along it;
   the pink fill on top is revealed the same way when the route is walked. */
.link {
  position: absolute;
  left: 0;
  top: 0;
  width: 15px;
  margin-left: -7.5px; /* cx/cy address the centre; height and margin-top are set per link */
  border-radius: 50%;
  background: #c7dbf3;
  visibility: hidden;
  will-change: clip-path;
}
.link__fill {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: #ffdffd;
}

.stop {
  position: absolute;
  left: 0;
  top: 0;
  width: 100px;
  height: 100px;
  margin: -50px 0 0 -50px; /* x/y address the centre */
  visibility: hidden;
  will-change: transform;
}
.stop {
  border-radius: 24px; /* the export came out without alpha; clip the corners here */
  overflow: hidden;
  transform: translateZ(0);
}
.stop img { width: 100%; height: 100%; display: block; }

/* ───────────── Phone & social icons (act 6) ───────────── */

.phone5 {
  position: absolute;
  left: 0;
  top: 0;
  width: 425.5px;
  height: 877.5px;
  margin: -438.75px 0 0 -212.75px; /* x/y address the centre */
  visibility: hidden;
  will-change: transform;
}
.phone5__img, .phone5__gl { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.phone5__gl { display: none; }
.phone5.has-gl .phone5__gl { display: block; }
.phone5.has-gl .phone5__img { display: none; }

.icons { pointer-events: none; }
.icon {
  position: absolute;
  left: 0;
  top: 0;
  width: 100px;
  height: 100px;
  margin: -50px 0 0 -50px; /* x/y address the centre */
  visibility: hidden;
  filter: drop-shadow(0 4px 10px rgba(0, 0, 0, .10));
  will-change: transform, opacity;
}
.icon img { width: 100%; height: 100%; display: block; object-fit: cover; }
.icon--round img { border-radius: 20px; }
.icon--white { background: #fff; border-radius: 20px; }
.icon--white img { position: absolute; left: 15px; top: 15px; width: 70px; height: 70px; }
/* the X source has a white margin around the black square; Figma crops it 119% into a rounded frame */
.icon--x { border-radius: 20px; overflow: hidden; }
.icon--x img { position: absolute; left: -9.52%; top: -9.42%; width: 119.05%; height: 119.05%; }

/* ───────────── Notes (act 4) ───────────── */

.photos, .notes { pointer-events: none; }

.photo {
  position: absolute;
  left: 0;
  top: 0;
  width: 258px;
  height: 258px;
  margin: -129px 0 0 -129px; /* x/y address the centre */
  border-radius: 46px;
  overflow: hidden;
  background: #d9d9d9;
  visibility: hidden;
  will-change: transform, opacity;
  transform: translateZ(0);
}
.photo img { width: 100%; height: 100%; object-fit: cover; }

/* A sticky note. .note holds position/rotation; .note__paper is the sheet itself.
   A sticky note is glued only along its top strip, so the sheet sits with a slight
   permanent lift at the bottom and, on hover, lifts further as if a corner were pulled. */
.note {
  position: absolute;
  left: 0;
  top: 0;
  width: 250px;
  height: 250px;
  margin: -125px 0 0 -125px; /* x/y address the centre */
  visibility: hidden;
  pointer-events: none; /* switched on by the timeline once the note is on */
  outline: none;
  will-change: transform;
}

.note__paper {
  position: absolute;
  inset: 0;
  perspective: 700px;
  transform-style: preserve-3d;
  transform-origin: 50% 0; /* hinged along the glued top strip */
}

/* The sheet is cut into horizontal strips, each hinged on the bottom edge of the one
   above and turned by a share of the total bend — so the paper curves instead of
   tilting like a board. Each strip shows its own slice of the note picture. */
.note__strip {
  position: absolute;
  left: 0;
  top: 0;
  width: 250px;
  background-size: 250px 250px;
  background-repeat: no-repeat;
  transform-origin: 50% 0;
  transform-style: preserve-3d;
  backface-visibility: hidden;
}
.note__strip + .note__strip { top: 100%; }

/* ───────────── Collections (act 3) ───────────── */

.colls { pointer-events: none; }

/* .coll is the hit area and the scroll-in animation; .coll__shape is what morphs into a petal */
.coll {
  position: absolute;
  left: 0;
  top: 0;
  width: 333px;
  height: 333px;
  margin: -166.5px 0 0 -166.5px; /* x/y address the centre */
  visibility: hidden;
  pointer-events: none; /* switched on by the timeline once the tile is landing — until then it must not sit over the cards below */
  outline: none;
  will-change: transform, opacity;
}

.coll__shape {
  position: absolute;
  inset: 0;
  border-radius: 52px;
  overflow: hidden;
  background: #d9d9d9;
  transform: translateZ(0);
  will-change: transform, border-radius;
}

.coll__img {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 380px;                 /* a little larger than the tile: room for the blur to bleed */
  height: 380px;
  margin: -190px 0 0 -190px;
  object-fit: cover;
  filter: blur(22px) saturate(1.1);
  transform-origin: 50% 50%;
}

.coll__shape::before { /* Figma's tint over the frost */
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(51, 89, 187, .1);
}

.coll__text {
  position: absolute;
  inset: 0;
  color: #fff;
  text-align: center;
}
.coll__text p { margin: 0; position: absolute; left: 50%; transform: translateX(-50%); }
.coll__title {
  top: 82px;
  width: 254px;
  font-size: 32px;
  line-height: 1.2;
}
.coll__count {
  top: 160px;
  font-family: var(--font-script);
  font-size: 40px;
  line-height: 62px;
  color: #ffdffd;
  white-space: nowrap;
}
.coll__cat {
  top: 286px;
  font-size: 18px;
  font-style: italic;
  line-height: 1.2;
  white-space: nowrap;
}

/* Pile of places for the hovered collection: rides with the pointer, drawn above the petal */
.stack {
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  perspective: 900px;
  pointer-events: none;
}

.stack__deck {
  position: absolute;
  left: 0;
  top: 0;
  transform-style: preserve-3d;
  transform: rotateY(-18deg); /* the pile turns away into depth on the left */
}

/* the pictures carry their own rounded corners — no box, no background */
.stack__card {
  position: absolute;
  left: -110px;
  top: -140px;
  width: 220px;
  height: 220px;
  opacity: 0;
  will-change: transform, opacity;
}
.stack__card img {
  width: 100%;
  height: 100%;
  display: block;
  filter: drop-shadow(0 16px 22px rgba(19, 33, 68, .10)); /* airy: wide and faint */
}


/* Phones */
.phones { pointer-events: none; }

.phone {
  position: absolute;
  left: 0;
  top: 0;
  width: 395px;
  height: 814px;
  margin: -407px 0 0 -197.5px; /* x/y address the centre */
  visibility: hidden;
  will-change: transform;
}

/* .phone carries position and size; .phone__body only ever turns in 3D, around its own
   centre — so a phone at rest is strictly frontal wherever it stands */
.phone__body {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  will-change: transform;
}

.phone img { position: relative; width: 100%; height: 100%; }

/* Body thickness: silhouettes of the device stacked behind the face (built in main.js) */
.phone__edge {
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, #8d7565 0%, #4a3a31 22%, #2b211c 60%, #5e4b40 100%);
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
}

/* Orbit */
.orbit { pointer-events: none; }

.oval {
  position: absolute;
  left: 0;
  top: 0;
  width: 172px;
  height: 100px;
  margin: -50px 0 0 -86px; /* x/y address the centre */
  border-radius: 50%;
  overflow: hidden;
  visibility: hidden;
  will-change: transform;
}

/* The image is its own layer under the mask: it never rotates with the oval */
.oval i {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 470px;
  height: 263px;
  margin: -131.5px 0 0 -235px;
  background-size: cover;
  background-position: center;
  will-change: transform;
}

/* Place cards */
.cards { pointer-events: none; }

.card {
  --mx: 50%;
  --my: 50%;
  --r: 0px;     /* radius of the clear hole in the frost */
  --wave: 0;    /* brightness of the ring running ahead of the hole */
  position: absolute;
  left: 0;
  top: 0;
  width: 328px;
  height: 411px;
  margin: -205.5px 0 0 -164px; /* x/y address the centre */
  border-radius: 52px;
  overflow: hidden;
  background: #d9d9d9;
  box-shadow: 0 2px 3px rgba(19, 33, 68, .32);
  visibility: hidden;
  pointer-events: auto;
  will-change: transform;
  transform: translateZ(0); /* keeps the rounded clip crisp on the blurred layer */
}

.card::after { /* hairline from Figma, drawn above the veil */
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 1px solid rgba(255, 250, 254, .24);
  pointer-events: none;
}

.card__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* WebGL layer: frosted picture that clears through a liquid-glass bubble (glass.js).
   Shown once its textures are ready; until then, and without WebGL, the CSS frost below does the job. */
.card__gl {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: none;
}
.card.has-gl .card__gl { display: block; }
.card.has-gl .card__veil, .card.has-gl .card__wave { display: none; }
/* fully revealed: nothing but the picture stays */
.card.is-clear .card__gl, .card.is-clear .card__veil, .card.is-clear .card__wave { display: none; }
/* the hint's fade-in is scroll-driven; an opened card must never show it again */
.card.is-open .card__hint { display: none; }

/* CSS frost (fallback). Its mask is a hole that grows from --mx/--my — the point where the pointer landed. */
.card__veil {
  position: absolute;
  inset: 0;
  background: rgba(51, 89, 187, .12);
  -webkit-backdrop-filter: blur(30px) saturate(1.15);
  backdrop-filter: blur(30px) saturate(1.15);
  -webkit-mask-image: radial-gradient(circle at var(--mx) var(--my), transparent calc(var(--r) - 110px), #000 var(--r));
  mask-image: radial-gradient(circle at var(--mx) var(--my), transparent calc(var(--r) - 110px), #000 var(--r));
}

.card__hint {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  text-align: center;
  font-size: 16px;
  line-height: 1.2;
  color: #fff;
  opacity: 0;
  pointer-events: none;
}

/* A ring of light that runs just ahead of the clearing edge — the "epicentre" wave */
.card__wave {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: var(--wave);
  background: radial-gradient(circle at var(--mx) var(--my),
    transparent calc(var(--r) - 90px),
    rgba(255, 223, 253, .22) calc(var(--r) - 40px),
    rgba(255, 255, 255, .62) calc(var(--r) - 4px),
    rgba(255, 223, 253, .28) calc(var(--r) + 30px),
    transparent calc(var(--r) + 70px));
  mix-blend-mode: screen;
}

/* Download button */
.cta {
  width: 200px;
  height: 52px;
  margin: -26px 0 0 -100px; /* x/y address the centre */
  border-radius: 18px;
  display: grid;
  place-items: center;
  font-family: var(--font-text);
  font-weight: 500;
  font-size: 18px;
  line-height: 1;
  white-space: nowrap;
  visibility: hidden;
  cursor: default;
  user-select: none;
  pointer-events: auto; /* the act ignores the pointer; the button needs it for the "Soon" tip */
}

.cta__skin {
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

.cta__skin--grad {
  /* Figma's radial gradient, transform matrix included */
  background: url("data:image/svg+xml;utf8,<svg viewBox='0 0 199 52' xmlns='http://www.w3.org/2000/svg' preserveAspectRatio='none'><rect x='0' y='0' height='100%' width='100%' fill='url(%23grad)' opacity='1'/><defs><radialGradient id='grad' gradientUnits='userSpaceOnUse' cx='0' cy='0' r='10' gradientTransform='matrix(3.2162 5.1179 -19.586 1.0153 67.338 0.82088)'><stop stop-color='rgba(51,89,187,1)' offset='0'/><stop stop-color='rgba(92,133,215,1)' offset='0.22596'/><stop stop-color='rgba(133,177,244,1)' offset='0.45192'/><stop stop-color='rgba(194,193,243,1)' offset='0.72596'/><stop stop-color='rgba(255,209,243,1)' offset='1'/></radialGradient></defs></svg>") center / 100% 100% no-repeat;
  overflow: hidden;
}

/* Figma's inner shadows are additive (they read as a soft light rim, not a dark one) */
.cta__glow {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 2px -2px 4px 0 #8375b0, inset -2px -2px 4px 0 rgba(131, 117, 176, .3);
  mix-blend-mode: plus-lighter;
}

.cta__skin--white {
  background: #fff;
  border: .4px solid rgba(255, 148, 226, .5);
  box-shadow: inset -4px -4px 4px 0 rgba(255, 209, 243, .1);
  filter: drop-shadow(-2px -2px 3px rgba(255, 211, 253, .3)) drop-shadow(4px 4px 4px rgba(255, 211, 253, .3));
  opacity: 0;
}

.cta__label {
  grid-area: 1 / 1;
  position: relative;
  padding-bottom: 1px;
}

.cta__label--white { color: #fff; }

.cta__label--grad {
  background: url("data:image/svg+xml;utf8,<svg viewBox='0 0 155 23' xmlns='http://www.w3.org/2000/svg' preserveAspectRatio='none'><rect x='0' y='0' height='100%' width='100%' fill='url(%23grad)' opacity='1'/><defs><radialGradient id='grad' gradientUnits='userSpaceOnUse' cx='0' cy='0' r='10' gradientTransform='matrix(2.5051 2.2637 -15.255 0.44908 52.449 0.36308)'><stop stop-color='rgba(51,89,187,1)' offset='0'/><stop stop-color='rgba(92,133,215,1)' offset='0.5'/><stop stop-color='rgba(133,177,244,1)' offset='1'/></radialGradient></defs></svg>") center / 100% 100% no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  opacity: 0;
}

/* ───────────── Veil (section jumps) ───────────── */

.veil {
  position: fixed;
  inset: 0;
  z-index: 9;
  background: var(--bg);
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
}

/* ───────────── Newsletter (act 7) ───────────── */

/* Mesh gradient: Figma's blurred ellipse export (2228×1045 + blur margin = 2628×1445, centred
   on the stage) on a WebGL canvas that a roaming lens bulges (bulge.js, local + roam); the
   plain picture is the fallback. Its own alpha fades it into the page — no masks. */
.mesh {
  left: 50%;
  top: 413px;
  width: 2628px;
  height: 1445px;
  transform: translate(-50%, -50%);
  pointer-events: none;
}
.mesh__img, .mesh__gl { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.mesh__gl { display: none; }
.mesh.has-gl .mesh__gl { display: block; }
.mesh.has-gl .mesh__img { display: none; }

/* Two endless rows: the top one drifts left, the bottom one right (main.js) */
.row {
  display: flex;
  gap: 30px;
  width: max-content;
  will-change: transform;
}
.row--top { top: -53px; }
.row--bottom { top: 609px; }

.article {
  display: flex;
  align-items: center;
  gap: 24px;
  width: 597px;
  padding: 32px;
  border-radius: 52px;
  background: rgba(255, 255, 255, .3);
  border: .5px solid #fff;
  color: #fff;
  flex: none;
}
.article__pic { width: 175px; height: 206px; border-radius: 26px; object-fit: cover; flex: none; }
.article__body { display: flex; flex-direction: column; gap: 32px; width: 334px; }
.article__text { display: flex; flex-direction: column; gap: 12px; }
.article__title {
  margin: 0;
  font-family: var(--font-display);
  font-variation-settings: "opsz" 14, "wdth" 100;
  font-weight: 400;
  font-size: 32px;
  line-height: 32px;
  letter-spacing: -0.06em;
}
.article__sub { margin: 0; font-size: 16px; line-height: 1.2; }
/* Figma trims these text boxes to cap height, so its 12/10px gaps are measured from the glyphs */
.article__sub, .article__name, .article__date, .chip__label, .chip__num { text-box: trim-both cap alphabetic; }
.article__title { min-height: 64px; } /* every title is two lines — copy is written to fit */
.article__by { display: flex; align-items: center; gap: 12px; }
.article__by > div { display: flex; flex-direction: column; gap: 10px; }
.article__avatar { width: 52px; height: 52px; border-radius: 50%; border: 1.5px solid #fff; background: #fff; object-fit: cover; flex: none; }
.article__name { margin: 0; font-weight: 500; font-size: 16px; line-height: 1.2; }
.article__date { margin: 0; font-size: 16px; line-height: 1.2; opacity: .6; }

/* Sign-up: title, glass field with a white button, a note. Centred on the stage. */
.signup {
  left: 50%;
  top: 413px;
  transform: translate(-50%, -50%);
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px; /* 30 in the file; brought down by the designer */
  color: #fff;
  pointer-events: auto;
}
.signup__title {
  margin: 0;
  font-family: var(--font-display);
  font-variation-settings: "opsz" 14, "wdth" 100;
  font-weight: 400;
  font-size: 56px;
  line-height: normal;
  letter-spacing: -0.06em;
  white-space: nowrap;
}
.signup__field {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 640px;
  height: 100px;
  padding: 12px;
  border-radius: 30px;
  background: rgba(255, 255, 255, .3);
  border: .5px solid #fff;
  -webkit-backdrop-filter: blur(50px);
  backdrop-filter: blur(50px);
}
.signup__input-wrap { flex: 1; height: 100%; display: flex; align-items: center; min-width: 0; }
.signup__input {
  width: 100%;
  height: 100%;
  padding: 16px 32px;
  border: 0;
  border-radius: 20px;
  background: transparent;
  color: #fff;
  font: inherit;
  font-size: 16px;
  outline: none;
}
.signup__input::placeholder { color: #fff; opacity: 1; }
.signup__input:focus-visible { box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .7); }
.signup__button {
  height: 100%;
  padding: 16px 32px;
  border: 0;
  border-radius: 20px;
  background: #fff;
  color: #a5726a;
  font: inherit;
  font-weight: 500;
  font-size: 16px;
  cursor: default;
  outline: none;
}
.signup__button:focus-visible { box-shadow: inset 0 0 0 2px #a5726a; }
.signup__note { margin: -8px 0 0; /* 12px under the field */ width: 640px; font-size: 16px; line-height: 24px; text-align: center; opacity: .7; }
.signup__title, .signup__field, .signup__note { will-change: transform, opacity, filter; }
.signup > * { position: relative; left: auto; top: auto; } /* undo the stage's absolute default for the column */

.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ───────────── Partnership (act 8) ───────────── */

.partners {
  left: 64px;
  top: 64px;
  display: flex;
  gap: 30px;
}
/* One card: the blurred picture (plain img, or the bulge canvas over it), white type on top */
.partner {
  position: relative;
  width: 677px;
  height: 695px;
  border-radius: 52px;
  overflow: hidden;
  background: #fff;
  color: #fff;
  pointer-events: auto;
  cursor: default;
  outline: none;
  transform: translateZ(0); /* keeps the rounded clip crisp while the canvas repaints */
}
.partner:focus-visible { box-shadow: inset 0 0 0 2px #fff; }
.partner__bg, .partner__gl { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.partner__gl { display: none; }
.partner.has-gl .partner__gl { display: block; }
.partner.has-gl .partner__bg { display: none; }

.partner__eyebrow {
  position: absolute;
  left: 70px;
  top: 70px;
  font-weight: 500;
  font-size: 16px;
  line-height: 24px;
  text-transform: uppercase;
  text-box: trim-both cap alphabetic;
}
.partner__symbol { position: absolute; left: 70px; top: 286px; width: 149.36px; height: 108px; }
.partner__text {
  position: absolute;
  left: 70px;
  top: 490px;
  width: 350px;
  display: flex;
  flex-direction: column;
  gap: 36px;
}
.partner__title {
  margin: 0;
  font-family: var(--font-display);
  font-variation-settings: "opsz" 14, "wdth" 100;
  font-weight: 400;
  font-size: 60px;
  line-height: normal;
  letter-spacing: -0.06em;
  text-box: trim-both cap alphabetic;
}
.partner__copy { margin: 0 4px; font-size: 16px; line-height: 24px; text-box: trim-both cap alphabetic; }

/* The mark at the top-right: an oval at rest; on hover two more ovals swing out of it, up and
   down, hinged at the right tip — so all three leave from exactly one point and read as an
   arrow. Figma: oval 26×4 at (578, 73). */
.partner__arrow {
  position: absolute;
  left: 578px;
  top: 61px;
  width: 27px;
  height: 28px;
  overflow: visible;
  fill: #fff;
}
.partner__wing {
  transform-box: fill-box;
  transform-origin: 100% 50%; /* the right tip */
  transform: rotate(0deg);
  transition: transform .5s cubic-bezier(.22, 1, .36, 1);
}
.partner:hover .partner__wing--up, .partner:focus-visible .partner__wing--up { transform: rotate(-30deg); transition-timing-function: cubic-bezier(.34, 1.45, .64, 1); }
.partner:hover .partner__wing--down, .partner:focus-visible .partner__wing--down { transform: rotate(30deg); transition-timing-function: cubic-bezier(.34, 1.45, .64, 1); }

/* ───────────── Footer / Contact (act 9) ───────────── */

/* The Figma gradient oval (export incl. its blur margin: 2628×1732 at −558, −160) on a WebGL
   canvas that a slowly roaming lens bulges — the same distortion as the partnership cards,
   without a pointer. The plain picture stays as the fallback. */
.foot__grad {
  left: 50%;
  top: 706px;
  width: 2628px;
  height: 1732px;
  transform: translate(-50%, -50%);
  pointer-events: none; /* no mask: the oval's own soft alpha shapes it, as drawn in Figma */
}
.foot__grad-img, .foot__grad-gl { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.foot__grad-gl { display: none; }
.foot__grad.has-gl .foot__grad-gl { display: block; }
.foot__grad.has-gl .foot__grad-img { display: none; }

/* The flower: two marks, six petals. Hover pushes the petals away from the centre, the ones
   nearer the pointer further (main.js); a padded hit area keeps it from flickering. */
.flower {
  left: 704.52px;
  top: 180px;
  width: 102.825px;
  height: 86px;
  padding: 34px;
  margin: -34px 0 0 -34px;
  pointer-events: auto;
}
.flower__svg { display: block; width: 102.825px; height: 86px; overflow: visible; fill: #fff; }
.flower__petal { will-change: transform; }

.foot {
  left: 130px;
  top: 425px;
  width: 1252px;
  display: flex;
  align-items: flex-start;
  color: #fff;
  pointer-events: auto;
}
.foot__brand { display: flex; flex-direction: column; align-items: flex-start; gap: 16px; width: 332px; margin-right: 362px; } /* link columns start at 694 */
.foot__logo {
  margin: 0;
  font-family: var(--font-display);
  font-variation-settings: "opsz" 96, "wdth" 100;
  font-weight: 800;
  font-size: 44px;
  line-height: normal;
  text-transform: uppercase;
  text-box: trim-both cap alphabetic;
}
.foot__about { margin: 0; font-size: 16px; line-height: 24px; }
.foot__download {
  position: relative;
  display: block;
  margin-top: 24px; /* 40 under the text */
  height: 21px;
  width: 180px;
  font-weight: 500;
  font-size: 16px;
  line-height: normal;
  white-space: nowrap;
  cursor: default;
  outline: none;
}
.foot__download:focus-visible { box-shadow: 0 0 0 2px #fff; border-radius: 4px; }
.foot__arrow { position: absolute; left: 154px; top: -2px; width: 27px; height: 28px; overflow: visible; fill: #fff; }
.foot__download:hover .partner__wing--up, .foot__download:focus-visible .partner__wing--up { transform: rotate(-30deg); transition-timing-function: cubic-bezier(.34, 1.45, .64, 1); }
.foot__download:hover .partner__wing--down, .foot__download:focus-visible .partner__wing--down { transform: rotate(30deg); transition-timing-function: cubic-bezier(.34, 1.45, .64, 1); }

.foot__col { display: flex; flex-direction: column; align-items: flex-start; gap: 24px; margin-right: 150px; white-space: nowrap; }
.foot__col:last-child { margin-right: 0; }
.foot__head { margin: 0; font-weight: 500; font-size: 14px; line-height: 1.2; text-transform: uppercase; text-box: trim-both cap alphabetic; }
.foot__col a, .foot__link { font-weight: 300; font-size: 16px; line-height: 1.2; text-box: trim-both cap alphabetic; cursor: pointer; outline: none; }
.foot__link { cursor: default; }
.foot__col a:focus-visible, .foot__link:focus-visible { box-shadow: 0 0 0 2px #fff; border-radius: 3px; }

/* Lists where hovering one item dims the others to 50% (footer nav, hero nav) */
[data-dim] { transition: opacity .25s ease; }
[data-dim].is-dim { opacity: .5; }

/* The closing line: grows up from the bottom edge, flattened at first (main.js scales it) */
.foot__title {
  left: 50%;
  top: 745px; /* baseline 2px past the stage edge: flat-bottomed letters touch it, round ones are clipped a touch */
  margin: 0;
  transform: translateX(-50%);
  font-family: var(--font-display);
  font-variation-settings: "opsz" 96, "wdth" 100;
  font-weight: 800;
  font-size: 126px;
  line-height: normal;
  letter-spacing: -0.04em;
  text-transform: uppercase;
  text-align: center;
  white-space: nowrap;
  color: #fff;
  text-box: trim-both cap alphabetic;
  transform-origin: 50% 100%;
  will-change: transform;
}

/* ───────────── Dock ───────────── */

/* The dock is one box whose width/height main.js animates between the folded capsule
   (53×21, a grip inside) and the full bar (items + 4px padding). Centred by auto margins,
   so it stays centred while it grows; no CSS transform here, GSAP owns y/opacity. */
.dock {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 24px;
  z-index: 10;
  width: 53px;
  height: 21px;
  margin: 0 auto;
  visibility: hidden;
  will-change: width, height;
}

/* glass frame — lassie.ai values 1:1: warm translucent tint, 13px blur, hairline light border */
.dock__frame {
  position: absolute;
  inset: 0;
  border-radius: 16px;
  background: rgba(227, 221, 207, .4);
  border: 1px solid rgba(255, 255, 255, .1);
  -webkit-backdrop-filter: blur(13px);
  backdrop-filter: blur(13px);
  /* ours sits on a white page (theirs on photos), so a whisper of shadow keeps it from dissolving */
  box-shadow: 0 0 0 .5px rgba(42, 42, 42, .06), 0 8px 24px -8px rgba(42, 42, 42, .12);
  pointer-events: none;
}

/* the folded state: Figma's 25×5 ellipse */
.dock__grip {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 25px;
  height: 5px;
  margin: -2.5px 0 0 -12.5px;
  border-radius: 50%;
  background: var(--ink);
  pointer-events: none;
}

.dock__items {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  white-space: nowrap;
  will-change: opacity, filter;
}

.dock__pill {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  width: 0;
  border-radius: 12px;
  background: #fff;
  pointer-events: none;
  transition: transform .45s cubic-bezier(.22, 1, .36, 1), width .45s cubic-bezier(.22, 1, .36, 1);
}

.dock__item {
  position: relative;
  height: 43px;
  padding: 0 16px;
  display: flex;
  align-items: center;
  border-radius: 12px;
  font-size: 16px;
  line-height: 1;
  color: rgba(42, 42, 42, .58); /* quiet until the pill is under it */
  white-space: nowrap;
  transition: color .15s cubic-bezier(.4, 0, .2, 1), background-color .3s cubic-bezier(0, 0, .2, 1);
  outline: none;
  cursor: pointer;
}
.dock__item[data-soon] { cursor: default; }

.dock__item.is-lit { color: var(--ink); }
.dock__item--logo img { opacity: .58; transition: opacity .15s cubic-bezier(.4, 0, .2, 1), transform .45s cubic-bezier(.22, 1, .36, 1); }
.dock__item--logo.is-lit img { opacity: 1; }

.dock__item:active { background-color: rgba(255, 255, 255, .55); }
.dock__item:focus-visible { box-shadow: inset 0 0 0 2px var(--ink); }

.dock__item--logo img { width: 33px; height: 29px; }
.dock__item--logo:hover img { transform: rotate(-12deg) scale(1.06); }

/* hairline between the sections and the download item (Figma: 0.5px white, 6px gaps) */
.dock__sep {
  width: 1px;
  height: 21px;
  margin: 0 6px;
  border-radius: 1px;
  background: rgba(255, 255, 255, .7);
  flex: none;
}

/* ───────────── "Soon" tooltip ───────────── */

.soon {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 20;
  padding: 8px 10px;
  border-radius: 10px;
  background: #e5f1ff;
  font-family: var(--font-text);
  font-weight: 500;
  font-size: 16px;
  line-height: 1;
  color: #508fd8;
  white-space: nowrap;
  visibility: hidden;
  pointer-events: none;
  transform-origin: 50% 100%; /* grows out of the button beneath */
  will-change: transform, opacity;
}

@media (max-width: 520px) {
  .dock__item { padding: 0 11px; font-size: 14px; }
  .hero__menu { display: none; }
  .hero__top { justify-content: center; }
}
