/* Rayfora landing page — Figma "Logo-Exploration" frame 160:2588 (1280 x 5569).
   Rules carry the node id they come from.

   LAYOUT
   The design exists only as a 1280px desktop frame, so the page is built in
   two registers:

   * .comp blocks are the parts Figma flattened into a single composition — the
     hero, the card frame, the offline band, the retailer grid, the footer art.
     They set `container-type: inline-size` and express every child offset in
     `--px`, one 1280th of their own width, so the composition is reproduced
     exactly and scales with the block at any viewport. At 1280px --px is 1px
     and the geometry is the frame's own, to the pixel.

   * Everything else is ordinary flow with fluid type, so headings, body copy
     and the format columns reflow and stay readable down to 320px.

   At >= 1280px the media query at the foot of this file pins each section to
   its frame height and its children to their frame coordinates.

   TYPE
   Figma anchors a text node at the top of its line box and centres the 1.21em
   font box inside the design's 84.635% line-height; Chrome resolves that
   negative leading differently, so text landing on an exact frame coordinate
   is offset by figma-y + var(--lead) x font-size. That value was calibrated by
   diffing a headless render against the Figma export. */

:root {
  --ink: #000;
  --ink-soft: #2a2a2a;
  --ink-subtle: #656c78;      /* text/subtle */
  --band: #0e1013;
  --band-body: #a2a4a9;
  --plate: #fffeff;
  --lh: 84.635%;
  --lead: 0.0985;
  --gutter: clamp(20px, 5.5vw, 105px);
}

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

html { background: #fff; -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: #fff;
  color: var(--ink);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
  /* Inter 4's optical axis tightens large text and pulls the headline ~7%
     narrower than the frame, so it is switched off deliberately. */
  font-optical-sizing: none;
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img { display: block; max-width: 100%; border: 0; }
h1, h2, p, ul { margin: 0; }
ul { list-style: none; padding: 0; }

#page { width: 100%; max-width: 1280px; margin: 0 auto; position: relative; }

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

/* ---- flattened compositions -------------------------------------------- */
/* --px is one frame pixel expressed in the block's own width, so a child
   written as calc(407 * var(--px)) sits where Figma put it, at any size. */

.comp {
  container-type: inline-size;
  position: relative;
  width: 100%;
  overflow: hidden;
  --px: calc(100cqw / 1280);
}
.comp > * { position: absolute; }
.comp img { max-width: none; }

/* ======================================================================== */
/* masthead                                                                 */
/* ======================================================================== */

/* Fixed, so it takes no space in the flow and the frame coordinates below it
   are untouched. The glass is invisible against the white top of the hero and
   only reads once photography or the dark band passes under it. */
.masthead {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  background: rgba(255, 255, 255, 0.72);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .masthead { background: rgba(255, 255, 255, 0.94); }
}

.masthead-inner {
  position: relative;
  max-width: 1280px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: clamp(10px, 1.6vw, 20px);
  padding: 14px var(--gutter);
}

/* 160:2596 */
.logo { flex: none; display: block; width: clamp(76px, 7.8vw, 100px); }
.logo img { width: 100%; height: auto; }

/* 160:2606 */
.partner {
  font-size: clamp(16px, 1.9vw, 24px);
  font-weight: 300;
  line-height: var(--lh);
  letter-spacing: -0.02em;
  white-space: nowrap;
}
.partner .x { font-size: 0.625em; font-weight: 400; margin-right: 0.45em; }

/* 160:2597 / 160:2598 — "Try Free", and an <a> to /try since 23 September
   2026. It was a <button> before that, for a reason worth keeping in view:
   as an anchor to "#" it navigated to the top of the document, so every
   click scrolled the page away under the person who pressed it. An anchor
   with a real destination has no such problem; an anchor to nowhere does.
   The rule below already sets `text-decoration` and centres its own text,
   so it works as either element. */
.btn-demo {
  /* `margin-left: auto` lives on `.btn-in` now — it comes first, so it is
     the one that takes the free space and carries both buttons right. */
  flex: none;
  appearance: none;
  border: 0;
  font-family: inherit;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10.612px 17.403px;
  border-radius: 13.052px;
  background-image: linear-gradient(169.055deg,
                    rgba(0, 161, 255, 0.81) 11.487%, rgb(0, 107, 255) 95.002%);
  font-size: clamp(13px, 1.2vw, 15.228px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: normal;
  color: #fff;
  text-decoration: none;
  white-space: nowrap;
}

/* The way into the app, beside Book Demo. Not in the Figma frame — added
   22 September 2026, when this page became what rayfora.com answers with.

   Quieter than Book Demo on purpose: that one is the page's single call to
   action and this is a door for people who already know where they are
   going, so it borrows the same shape and height and gives up the fill.
   `margin-left: auto` moves from `.btn-demo` to here, so the pair travels
   to the right edge together rather than drifting apart. */
.btn-in {
  margin-left: auto;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10.612px 17.403px;
  border: 1px solid rgba(0, 107, 255, 0.28);
  border-radius: 13.052px;
  background: transparent;
  font-family: inherit;
  font-size: clamp(13px, 1.2vw, 15.228px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: normal;
  color: rgb(0, 107, 255);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 120ms ease, border-color 120ms ease;
}
.btn-in:hover { background: rgba(0, 107, 255, 0.07); border-color: rgba(0, 107, 255, 0.5); }
@media (prefers-reduced-motion: reduce) { .btn-in { transition: none; } }

/* Below 420px "Go to Dashboard" beside "Book Demo" does not fit, and what
   it did was push Book Demo off the right edge of a 320px screen entirely —
   measured at 359px of masthead in 320px of viewport. "Log in" always fitted;
   only the signed-in label is the long one.
   So the words "Go to " go, leaving "Dashboard", and both buttons give up a
   little side padding. Nothing is hidden that carries meaning on its own. */
@media (max-width: 419.98px) {
  .btn-in-more { display: none; }
  .btn-in, .btn-demo { padding-left: 13px; padding-right: 13px; }
}

/* ======================================================================== */
/* hero                                                                     */
/* ======================================================================== */

.hero { position: relative; }
.hero-copy { position: relative; z-index: 2; padding: clamp(28px, 4vw, 44px) var(--gutter) 0; }

/* 160:2594 */
.hero h1 {
  font-size: clamp(34px, 5vw, 64px);
  font-weight: 700;
  line-height: var(--lh);
  letter-spacing: -0.02em;
}

/* 160:2595 */
.hero-copy p {
  margin-top: clamp(22px, 3.36vw, 43px);
  font-size: clamp(17px, 2.5vw, 32px);
  font-weight: 500;
  line-height: var(--lh);
  letter-spacing: -0.02em;
  color: var(--ink-soft);
}

/* the media block spans frame y 130..846; the phone runs off the right edge
   in the design, so the block clips */
.hero-media {
  aspect-ratio: 1280 / 716;
  margin-top: clamp(24px, 3.2vw, 40px);
}

/* 160:2590 — the fill is cropped: height 115.92%, top -15.9% */
.hero-shot {
  left: calc(284 * var(--px));
  top: 0;
  width: calc(711.723 * var(--px));
  height: calc(408.587 * var(--px));
  border-radius: calc(76.67 * var(--px));
  overflow: hidden;
}
.hero-shot img {
  position: absolute;
  left: 0; top: -15.9%;
  width: 100%; height: 115.92%;
  object-fit: cover;
}

/* 160:2591 — a thick white border, blurred, softening the photograph's edge */
.hero-shot-edge {
  left: calc(284 * var(--px));
  top: 0;
  width: calc(711.784 * var(--px));
  height: calc(408.553 * var(--px));
  border: calc(17.775 * var(--px)) solid #fff;
  border-radius: calc(55.446 * var(--px));
  filter: blur(calc(14.061 * var(--px)));
  pointer-events: none;
}

/* 160:2592 */
.hero-device {
  left: calc(407 * var(--px));
  top: calc(101 * var(--px));
  width: calc(1178 * var(--px));
  height: calc(615 * var(--px));
  object-fit: cover;
  pointer-events: none;
}

/* 160:2593 — frame y 602, inner inset -28.3% -2.95% -28.83% 2.58% */
.hero-fade {
  left: calc(-1176 * var(--px));
  top: calc(472 * var(--px));
  width: calc(2960 * var(--px));
  height: calc(665 * var(--px));
  pointer-events: none;
}
.hero-fade img {
  position: absolute;
  left: 2.58%; top: -28.3%;
  width: 100.37%;
  height: 157.13%;
}

/* ======================================================================== */
/* "One Workplace for Every Product"                                        */
/* ======================================================================== */

.workplace { padding-top: clamp(48px, 8vw, 118px); }

.workplace h2,
.offline h2,
.formats h2 {
  position: relative;
  z-index: 2;
  padding: 0 var(--gutter);
  font-size: clamp(27px, 3.75vw, 48px);
  font-weight: 700;
  line-height: var(--lh);
  letter-spacing: -0.02em;
  text-align: center;
  text-wrap: balance;
}

/* 160:2599 is one flattened export in Figma — card frame, both captions and
   the pager arrows baked together, on a flat #fefefe ground. It is a real
   horizontal scroller here, so it carries three tiles instead of two and
   scrolls by touch, trackpad, keyboard and the arrow buttons. */

/* --rail-pad is the leading gutter. It has to be both the track's padding and
   the container's scroll-padding: without the latter the first tile's snap
   position is the gutter rather than 0, and mandatory snapping drags every
   programmatic scroll back to the start. */
.rail {
  --rail-pad: var(--gutter);
  margin-top: clamp(38px, 5.94vw, 76px);
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--rail-pad);
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
.rail::-webkit-scrollbar { display: none; }
.rail:focus-visible { outline: 2px solid #006bff; outline-offset: 4px; }

.rail-track {
  display: flex;
  gap: 14px;
  padding-inline: var(--rail-pad);
  width: max-content;
}

.tile {
  flex: 0 0 auto;
  width: min(682px, 82vw);
  scroll-snap-align: start;
}

/* 160:2600 / 160:2625 — 682 x 400, 14px radius */
.tile-shot {
  position: relative;
  aspect-ratio: 682 / 400;
  border-radius: 14px;
  overflow: hidden;
  background: #efefef;
}
.tile-shot img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
}

.tile h3 {
  margin-top: clamp(20px, 1.9vw, 24px);
  font-size: clamp(16px, 1.45vw, 19px);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: #171717;
  text-wrap: pretty;
}
.tile p {
  margin-top: clamp(5px, 0.6vw, 8px);
  font-size: clamp(14px, 1.25vw, 16px);
  font-weight: 400;
  line-height: 1.45;
  letter-spacing: -0.005em;
  color: #8a8b90;
  text-wrap: pretty;
}

/* the pager, measured off the export: two 37px circles, 19px apart */
.rail-nav {
  display: flex;
  justify-content: center;
  gap: 19px;
  margin-top: clamp(24px, 2.89vw, 37px);
}
.rail-btn {
  width: 37px;
  height: 37px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: #dedee0;
  color: #4a4a4f;
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: background-color .18s ease, color .18s ease;
}
.rail-btn svg { width: 20px; height: 20px; display: block; }
.rail-btn:hover:not(:disabled) { background: #d2d2d6; }
.rail-btn:focus-visible { outline: 2px solid #006bff; outline-offset: 3px; }
.rail-btn:disabled { background: #f2f2f3; color: #c6c6cb; cursor: default; }

/* ======================================================================== */
/* "Keep going. Even without a signal."                                     */
/* ======================================================================== */

.offline { padding-top: clamp(44px, 7.2vw, 116px); }

/* 160:2624 — the design bleeds this 5px past each edge */
.offline-media { aspect-ratio: 1280 / 726; margin-top: clamp(40px, 6.33vw, 81px); }
.offline-media img {
  left: calc(-5 * var(--px)); top: 0;
  width: calc(1290 * var(--px)); height: 100%;
  object-fit: cover;
}

/* ======================================================================== */
/* "Your products. Their format."                                           */
/* ======================================================================== */

/* 160:2589 is a #fffeff plate behind this section */
.formats {
  padding-top: clamp(46px, 7.5vw, 119px);
  padding-bottom: clamp(34px, 5vw, 80px);
  background: var(--plate);
}

/* 160:2604 */
.formats-media {
  aspect-ratio: 1047 / 698;
  width: calc(1047 / 1280 * 100%);
  margin: clamp(26px, 4.14vw, 53px) auto 0;
}
.formats-media img { left: 0; top: 0; width: 100%; height: 100%; object-fit: cover; }

/* 160:2605 — overlaps the foot of the grid in the design, so it has to sit
   above .formats-media, which is positioned */
.more {
  position: relative;
  z-index: 1;
  margin-top: clamp(-55px, -4.3vw, -34px);
  font-size: clamp(27px, 3.75vw, 48px);
  font-weight: 400;
  line-height: var(--lh);
  letter-spacing: -0.02em;
  text-align: center;
}

/* ======================================================================== */
/* dark band — 160:2617                                                     */
/* ======================================================================== */

/* Figma assembles this band from one bitmap with flat #0e1013 rectangles
   masking the parts that should not show. None of that is reproduced here:
   the band is the colour, the type and the icons directly, with a faint lift
   behind the heading to match the export. */
.band {
  position: relative;
  background:
    radial-gradient(120% 70% at 50% 26%, rgba(255,255,255,0.04) 0%, rgba(255,255,255,0) 62%),
    var(--band);
  color: #fff;
  padding: clamp(60px, 15.9vw, 204px) var(--gutter) clamp(60px, 15.1vw, 194px);
}

.band-head {
  font-size: clamp(26px, 3.75vw, 48px);
  font-weight: 700;
  line-height: var(--lh);
  letter-spacing: -0.02em;
  text-align: center;
  text-wrap: balance;
}

/* 160:2623 — the separators are CSS, so the line wraps cleanly on a phone */
.band-line {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0 clamp(8px, 1vw, 12px);
  margin: clamp(18px, 2.66vw, 34px) auto 0;
  max-width: 685px;
  font-size: clamp(14px, 1.25vw, 16px);
  font-weight: 500;
  line-height: 1.45;
  letter-spacing: -0.02em;
  text-align: center;
}
.band-line span { position: relative; }
.band-line span + span { padding-left: clamp(9px, 1.05vw, 13px); }
.band-line span + span::before {
  content: "";
  position: absolute; left: 0; top: 0.16em; bottom: 0.12em;
  border-left: 1px solid rgba(255, 255, 255, 0.5);
}

.formats-grid {
  --fmt-icon: clamp(38px, 3.83vw, 49px);
  --fmt-gap: clamp(12px, 1.56vw, 20px);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  margin: clamp(48px, 8.6vw, 110px) auto 0;
  max-width: 1050px;
}
.formats-grid > li { padding: 0 clamp(14px, 2.4vw, 31px); }
.formats-grid > li + li { border-left: 1px solid rgba(255, 255, 255, 0.10); }

.fmt-icon { width: var(--fmt-icon); height: auto; }

.fmt-name {
  /* pulls the label up alongside the icon; keyed to the icon so the two never
     drift. The previous clamp(-31px, -2.9vw, -37px) had its minimum above its
     maximum, so it resolved to -31px at every width and never ramped. */
  margin-top: calc(var(--fmt-icon) * -0.87);
  margin-left: calc(var(--fmt-icon) + var(--fmt-gap));
  font-size: clamp(15px, 1.48vw, 19px);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.01em;
}
.fmt-kind {
  margin-top: 0.2em;
  margin-left: calc(var(--fmt-icon) + var(--fmt-gap));
  font-size: clamp(14px, 1.25vw, 16px);
  font-weight: 400;
  line-height: 1;
}
.fmt-lead {
  margin-top: clamp(20px, 2.4vw, 31px);
  font-size: clamp(24px, 2.5vw, 32px);
  font-weight: 700;
  line-height: var(--lh);
  letter-spacing: -0.02em;
}
.fmt-body {
  margin-top: clamp(9px, 0.86vw, 11px);
  font-size: clamp(14px, 1.25vw, 16px);
  font-weight: 400;
  line-height: 1.625;
  color: var(--band-body);
}

/* ======================================================================== */
/* footer — 160:2607                                                        */
/* ======================================================================== */

.foot { position: relative; background: #fff; }

/* 160:2615 sits on the white strip above the artwork */
.foot-copy {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: clamp(10px, 1.4vw, 18px);
  padding: clamp(30px, 3.9vw, 51px) var(--gutter) clamp(22px, 3.1vw, 40px);
  font-size: clamp(16px, 1.7vw, 21.67px);
  font-weight: 400;
  line-height: 1.2;
  color: var(--ink-subtle);
  white-space: nowrap;
}
.foot-copy img { width: clamp(72px, 7.8vw, 100px); height: auto; }

/* the gradient, the two ellipses and the oversized wordmark are one
   composition; it keeps its proportions and scales with the page */
.foot-art {
  container-type: inline-size;
  position: relative;
  width: 100%;
  aspect-ratio: 1280 / 554;
  overflow: hidden;
  --px: calc(100cqw / 1280);
}
.foot-art > * { position: absolute; }
.foot-art img { max-width: none; }

/* 160:2609 */
.foot-grad {
  left: calc(-385 * var(--px));
  top: calc(97 * var(--px));
  width: calc(1687 * var(--px));
  height: calc(432 * var(--px));
  border-radius: calc(8.042 * var(--px));
  background-image: linear-gradient(165.637deg,
                    rgb(65, 217, 248) 0%, rgb(226, 236, 255) 100%);
}

/* 160:2611 — 2810.996 x 1872.344 box, contents rotated 23.48deg */
.foot-ellipse-3 {
  left: calc(-644 * var(--px));
  top: calc(-481 * var(--px));
  width: calc(2810.996 * var(--px));
  height: calc(1872.344 * var(--px));
  display: flex; align-items: center; justify-content: center;
}
.foot-ellipse-3 img {
  flex: none;
  width: calc(2920.5 * var(--px));
  height: calc(1730.8 * var(--px));
  transform: rotate(23.48deg) skewX(-11.77deg) scaleY(0.98);
}

/* 160:2612 — 2015.122 x 1278.048 box, contents rotated -20.71deg */
.foot-ellipse-2 {
  left: calc(-197.45 * var(--px));
  top: calc(-196.44 * var(--px));
  width: calc(2015.122 * var(--px));
  height: calc(1278.048 * var(--px));
  display: flex; align-items: center; justify-content: center;
}
.foot-ellipse-2 img {
  flex: none;
  width: calc(1845.9 * var(--px));
  height: calc(923.6 * var(--px));
  transform: rotate(-20.71deg) skewX(10.89deg) scaleY(0.98);
}

/* 160:2613 */
.foot-wordmark {
  left: calc(-47 * var(--px));
  top: calc(250 * var(--px));
  width: calc(1356 * var(--px));
  height: calc(385 * var(--px));
}
.foot-wordmark img { width: 100%; height: 100%; }

/* ======================================================================== */
/* wrapped text                                                             */
/* ======================================================================== */

/* The design's 84.635% leading is a tight display setting, and it works in the
   frame because every heading there is a single line or broken by hand. It is
   0.846em, and Inter's cap height plus descender is about 0.94em — so the
   moment a line actually wraps, the descenders of one line collide with the
   capitals of the next. Everything narrower than the frame wraps.

   Below 1280px, text that can wrap gets a leading that clears. At 1280px the
   frame's own value comes back, because there the second line of each hand
   broken heading has to land on its exact frame coordinate. */

.hero h1,
.workplace h2,
.offline h2,
.formats h2,
.band-head,
.more,
.fmt-lead { line-height: 1.05; }

.hero-copy p { line-height: 1.35; }

/* ======================================================================== */
/* >= 768px — the hero keeps its overlaid composition                       */
/* ======================================================================== */

/* Below 1280px the hero used to reorganise completely: the copy dropped out
   of the photograph and stacked above it. That is right on a phone and wrong
   on a laptop, and it made a hard cliff at exactly 1280px. Here the whole
   arrangement is held together with percentages of the hero's own box, so it
   scales instead of breaking apart, while the type stays on its own fluid
   ramp. Only under 768px does the hero stack. */

@media (min-width: 768px) {
  .hero { aspect-ratio: 1280 / 1189; }

  /* the hero's trailing space is where the heading lives, so the section pulls
     up into it instead of padding away from it */
  .workplace { padding-top: 0; margin-top: clamp(-42px, -3.28vw, -25px); }

  .hero-copy {
    position: absolute;
    inset: 0;
    padding: 0;
    pointer-events: none;
  }
  .hero-copy > * {
    position: absolute;
    left: var(--gutter);
    pointer-events: auto;
  }

  .hero h1      { top: 50.63%; }                 /* frame y 602 / 1189 */
  .hero-copy p  { top: 63.58%; margin-top: 0; }  /* frame y 756 / 1189 */

  .hero-media {
    position: absolute;
    left: 0;
    top: 10.93%;                                 /* frame y 130 / 1189 */
    width: 100%;
    margin: 0;
  }
}

/* ======================================================================== */
/* >= 1280px — each section pinned to its frame height, children to their    */
/* frame coordinates                                                        */
/* ======================================================================== */

@media (min-width: 1280px) {
  :root { --gutter: 105px; }

  #page { width: 1280px; }

  /* masthead: 160:2596 at (105,39), 160:2606 centred on x 303.5,
     160:2597 at (1030,31) — 31px of clearance above and below the button */
  .masthead-inner { display: block; padding: 0; height: 105.5px; }
  .masthead-inner > * { position: absolute; }
  .logo { left: 105px; top: 39px; width: 100px; }
  .partner {
    left: 303.5px;
    top: calc(39px + var(--lead) * 24px);
    transform: translateX(-50%);
    font-size: 24px;
    letter-spacing: -0.48px;
  }
  .partner .x { font-size: 15px; }
  .btn-demo {
    left: 1030px; top: 31px; height: 43.508px;
    margin-left: 0; font-size: 15.228px; letter-spacing: -0.3046px;
  }
  /* Pinned by its RIGHT edge rather than its left, so it grows leftwards
     into the empty middle of the masthead and Book Demo keeps the frame
     coordinate 160:2597 puts it on. 1280 - 1030 = 250 is Book Demo's left
     edge measured from the right; 16 more is the gap between them. Set this
     from `left` instead and a longer word — "Go to Dashboard" is the long
     one — would push Book Demo off its mark. */
  .btn-in {
    left: auto; right: 266px; top: 31px; height: 43.508px;
    margin-left: 0; font-size: 15.228px; letter-spacing: -0.3046px;
  }

  /* hero occupies frame y 0..1189; the copy sits over the media */
  .hero { height: 1189px; aspect-ratio: auto; }
  .hero-copy { position: absolute; inset: 0; padding: 0; pointer-events: none; }
  .hero-copy > * { position: absolute; pointer-events: auto; }
  .hero h1 {
    left: 105px;
    top: calc(602px + var(--lead) * 64px);
    font-size: 64px;
    line-height: var(--lh);
    letter-spacing: -1.28px;
    white-space: nowrap;
  }
  .hero-copy p {
    left: 105px;
    top: calc(756px + var(--lead) * 32px);
    margin-top: 0;
    font-size: 32px;
    line-height: var(--lh);
    letter-spacing: -0.64px;
    white-space: nowrap;
  }
  .hero-media { position: absolute; left: 0; top: 130px; width: 1280px; margin: 0; z-index: 0; }

  /* workplace occupies 1189..2158; 160:2601 at 1147, 160:2599 at 1189 */
  .workplace { position: relative; height: 969px; padding-top: 0; margin-top: 0; }
  .workplace h2 {
    line-height: var(--lh);
    position: absolute; left: 50%;
    top: calc(-42px + var(--lead) * 48px);
    transform: translateX(-50%);
    padding: 0; font-size: 48px; letter-spacing: -0.96px; white-space: nowrap;
  }
  /* the rail sits where 160:2600 does, the pager where the export draws it */
  .rail { --rail-pad: 100px; position: absolute; left: 0; top: 119px; width: 1280px; margin: 0; z-index: 0; }
  .rail-track { gap: 14px; }
  .tile { width: 682px; }
  .tile h3 { font-size: 19px; }
  .tile p  { font-size: 16px; }
  .rail-nav { position: absolute; left: 0; top: 646px; width: 1280px; margin: 0; }

  /* offline occupies 2158..3222; 160:2603 at 2032, 160:2624 at 2158 */
  .offline { position: relative; height: 1064px; padding-top: 0; }
  .offline h2 {
    line-height: var(--lh);
    position: absolute; left: calc(50% + 0.5px);
    top: calc(-126px + var(--lead) * 48px);
    transform: translateX(-50%);
    padding: 0; font-size: 48px; letter-spacing: -0.96px; white-space: nowrap;
  }
  .offline-media { position: absolute; left: 0; top: 0; width: 1280px; margin: 0; }

  /* formats occupies 3222..4189 (the 160:2589 plate); 160:2602 at 3126,
     160:2604 at 3224, 160:2605 at 3862 */
  .formats { position: relative; height: 967px; padding: 0; }
  .formats h2 {
    line-height: var(--lh);
    position: absolute; left: calc(50% - 1px);
    top: calc(-96px + var(--lead) * 48px);
    transform: translateX(-50%);
    padding: 0; font-size: 48px; letter-spacing: -0.96px; white-space: nowrap;
  }
  .formats-media { position: absolute; left: 116px; top: 2px; width: 1047px; margin: 0; }
  .more {
    line-height: var(--lh);
    position: absolute; left: 50%;
    top: calc(640px + var(--lead) * 48px);
    transform: translateX(-50%);
    margin-top: 0; font-size: 48px; letter-spacing: -0.96px; white-space: nowrap;
  }

  /* dark band occupies 4189..4990 */
  .band { height: 801px; padding: 0; }
  .band > * { position: absolute; }
  .band-head {
    line-height: var(--lh);
    left: 50%; top: 204.2px;
    transform: translateX(-50%);
    font-size: 49px; letter-spacing: -0.96px; white-space: nowrap;
  }
  .band-line {
    left: 50%; top: 279.1px;
    transform: translateX(-50%);
    width: max-content; max-width: none; margin: 0;
    font-size: 16px; letter-spacing: -0.32px; line-height: var(--lh);
    flex-wrap: nowrap; gap: 0 8px;
  }
  .band-line span + span { padding-left: 9px; }
  .band-line span { white-space: nowrap; }

  /* the three columns: icons at frame x 137 / 515 / 894, y 4591, and the
     rules Figma draws at x 455 and x 831 */
  .formats-grid {
    left: 137px; top: 402px;
    width: 1013px; max-width: none; margin: 0;
    grid-template-columns: 378px 379px 256px;
  }
  .formats-grid > li { position: relative; height: 167px; padding: 0; border: 0; }
  .formats-grid > li + li { border: 0; }
  .formats-grid > li + li::before {
    content: ""; position: absolute; top: 0; bottom: 0;
    border-left: 1px solid rgba(255, 255, 255, 0.10);
  }
  .formats-grid > li:nth-child(2)::before { left: -60px; }
  .formats-grid > li:nth-child(3)::before { left: -63px; }
  .formats-grid > li > * { position: absolute; margin: 0; }
  .formats-grid > li > .fmt-icon { left: 0;    top: 0; width: 49px; height: auto; }
  .formats-grid > li > .fmt-name { left: 69px; top: 6.4px;   font-size: 19px; line-height: 1; white-space: nowrap; }
  .formats-grid > li > .fmt-kind { left: 69px; top: 28.8px;  font-size: 15.5px; line-height: 1; white-space: nowrap; }
  .formats-grid > li > .fmt-lead { left: 3px;  top: 73.6px;  font-size: 31px; line-height: 1; letter-spacing: -0.64px; white-space: nowrap; }
  .formats-grid > li > .fmt-body { left: 3px;  top: 115.8px; font-size: 16px; line-height: 26px; white-space: nowrap; }

  /* footer occupies 4990..5569; 160:2615 at 5066, the art from 5112 */
  .foot { height: 579px; }
  .foot-copy { padding: 0; position: absolute; left: 69px; top: 76px; font-size: 21.67px; line-height: 26px; }
  .foot-copy img { width: 100px; }
  .foot-art { position: absolute; left: 0; top: 25px; width: 1280px; height: 554px; aspect-ratio: auto; }
}

/* ======================================================================== */
/* phones                                                                   */
/* ======================================================================== */

@media (max-width: 767px) {
  /* the hero stacks here, but keeps the design's order: photography first,
     then the copy. It must not be hoisted above the imagery.
     The padding clears the fixed masthead, which would otherwise sit over the
     top of the photograph — the only place on the page where content starts
     at y 0. */
  .hero {
    display: flex;
    flex-direction: column;
    padding-top: clamp(78px, 21vw, 104px);
  }
  .hero-media { order: 1; margin-top: 0; }
  .hero-copy  { order: 2; padding-top: clamp(22px, 6vw, 36px); }

  .formats-grid {
    grid-template-columns: 1fr;
    gap: clamp(34px, 8vw, 48px);
    max-width: 420px;
  }
  .formats-grid > li { padding: 0; }
  .formats-grid > li + li {
    border-left: 0;
    border-top: 1px solid rgba(255, 255, 255, 0.10);
    padding-top: clamp(34px, 8vw, 48px);
  }
  .foot-copy { justify-content: center; }
}

@media (max-width: 479px) {
  .partner { display: none; }
}

/* ======================================================================== */
/* scroll reveal                                                            */
/* ======================================================================== */

/* Everything is visible until the inline script in <head> sets .js, so the
   page reads correctly with JavaScript off or blocked.

   The motion uses the `translate` and `scale` properties rather than
   `transform`, because several of these elements are centred with
   `transform: translateX(-50%)` and the independent properties compose with it
   instead of overwriting it.

   Per-variant distances are set as custom properties rather than as competing
   `translate`/`scale` declarations: a variant selector is more specific than
   the `.is-in` rule, so declaring the property directly would pin the block to
   its hidden state and it would never arrive. */

.js [data-reveal],
.js [data-reveal-children] > * {
  opacity: 0;
  translate: 0 var(--rv-y, 64px);
  scale: var(--rv-s, 1);
  transition:
    opacity   .9s cubic-bezier(.16, 1, .3, 1),
    translate .9s cubic-bezier(.16, 1, .3, 1),
    scale     .9s cubic-bezier(.16, 1, .3, 1);
  transition-delay: calc(var(--rv, 0) * 130ms);
  will-change: opacity, translate, scale;
}

/* photographic blocks settle in from slightly under-size as well */
.js [data-reveal="media"],
.js .rail-track[data-reveal-children] > .tile { --rv-y: 52px; --rv-s: 0.93; }

.js [data-reveal].is-in,
.js [data-reveal-children].is-in > * {
  opacity: 1;
  translate: 0 0;
  scale: 1;
  will-change: auto;
}

/* children of a group stagger behind one another */
.js .rail-track > .tile:nth-child(2),
.js .formats-grid > li:nth-child(2) { --rv: 1; }
.js .rail-track > .tile:nth-child(3),
.js .formats-grid > li:nth-child(3) { --rv: 2; }

/* the hero is above the fold, so it comes in on load rather than on scroll */
.js .hero-copy > p { --rv: 1; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js [data-reveal],
  .js [data-reveal-children] > * {
    opacity: 1;
    translate: none;
    scale: none;
    transition: none;
  }
}

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}
