/* Landing page layout (Figma: Pages / Landingpage). A composition of components, tokens only.
 * Page sections (hero, marquee, universe) are layout, not components; the marquee is a candidate to promote
 * to a component (see components/README.md). Figma frame is 1440 wide. */

.page {
  --hero-margin: clamp(var(--space-md), 8.47vw, var(--size-page-margin)); /* 122px at 1440 */
  --section-gap: clamp(var(--space-2xl), 13.89vw, var(--space-section)); /* 200px at 1440 */
  --page-max: var(--size-page); /* 1440px: on wider screens the content stays this wide and centred (the hero background and the logo strip stay full-bleed). */
  position: relative;
  margin: 0;
  background-color: var(--color-bg-page);
  color: var(--color-text-primary);
}

/* Phones (48em is a placeholder): 20px at the left and right (16 + 4; the margin was 8.47% of the width, about 32px at 375). The header and the
 * footer take the same edge, so the logo, the title, the panels and the footer line up. Tablet and desktop keep the fluid margin. */
@media (max-width: 47.99em) {
  .page {
    --hero-margin: calc(var(--space-md) + var(--space-xs));
  }

  .header,
  .footer {
    padding-inline: var(--hero-margin);
  }
}

/* The header and the footer span the full width (Figma: Header and Footer are 1920 wide in the 1920 frame, edge to edge), with their items at
 * the usual 24px / 40px from the screen's edges, in line with the About Nollie panel. Only the content below them stays in the 1440px column:
 * they read the same --page-max as the content unless it is reset here. */
.header,
.footer {
  --page-max: 100%;
}

/* Figma renders text in greyscale; without this, macOS browsers draw it a touch heavier. */
html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.page h1,
.page h2,
.page p {
  margin: 0;
}

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

/* ---- Hero: the only full-bleed section ---- */
.hero {
  position: relative;
  display: flex;
  flex-direction: column;
  min-block-size: 56.25rem; /* 900px frame */
  min-block-size: 100vh; /* fallback */
  min-block-size: 100svh; /* the first screen is the hero only (the pinned panel never lands on the section below it) and ends with the logo strip, which is visible at once */
  overflow: hidden;
}

/* The floor plane is wider than the hero (2554px in a 1440px frame) and centred. */
.hero__floor {
  position: absolute;
  inset: 0 -38.68%;
}

.hero__copy {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2xl);
  box-sizing: border-box;
  padding: clamp(var(--space-2xl), 18svh, calc(var(--space-section) + var(--space-md))) 0 var(--space-lg); /* 216px top in the frame, less on a shorter screen so the chevron stays clear of the logo strip */
  padding-inline: max(var(--hero-margin), calc((100% - var(--page-max)) / 2 + var(--hero-margin)));
}

.hero__titles {
  display: grid;
  gap: var(--space-xl);
  max-inline-size: 56.125rem; /* 898px in Figma: the headline breaks after "scale," */
}

.hero__titles > p {
  max-inline-size: 44.375rem; /* 710px */
}

.hero__clients {
  margin-block-start: auto;
}

/* Tablet and desktop: the logos come out from behind the pinned panel, their centre line on the panel's. The panel (collapsed: 218px tall, no token)
 * sits 24px above the bottom of the screen and the hero is the screen tall, so the strip's bottom edge is 24px + half the panel less half the
 * strip (200px) above the bottom of the hero. */
@media (min-width: 48em) {
  .hero__clients {
    --dock-height: 13.625rem;
    margin-block-end: calc(var(--space-lg) + var(--dock-height) / 2 - 6.25rem);
  }
}

/* Phones (48em is a placeholder): the first screen ends with the logo strip. The hero is as tall as the screen less 88px (svh: the visible height
 * with the browser bars showing; the 900px minimum would push the strip below the fold) and the strip is pinned to its bottom, so the logos sit in
 * the lower part of the screen, a little above the bottom edge, and the space between Learn more and the logos is whatever is left over. There is also 24px less above the title and 48px between the subline and Learn more
 * instead of 88px. */
@media (max-width: 47.99em) {
  .hero {
    min-block-size: calc(100vh - var(--space-2xl)); /* fallback */
    min-block-size: calc(100svh - var(--space-2xl));
  }

  .hero__copy {
    padding-block-start: calc(var(--space-section) + var(--space-md) - var(--space-lg));
    padding-block-end: var(--space-lg); /* was 88px: the least space the strip can have below the buttons, on a short screen */
    gap: calc(var(--space-lg) * 2);
  }
}

/* Intro: the first view fades in and rises 16px, one after the other: the logo and the headline together, then the subline, the buttons, the logo
 * strip, and last the About Nollie panel, a second in. Contact starts with the logo. Quick and small on purpose: the headline is the largest paint,
 * so it starts at once. Off under reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  .header__home,
  .hero__titles > h1,
  .hero__titles > p,
  .hero__copy > .button-group,
  .hero__clients,
  .header .contact,
  .dock > .panel {
    animation: rise-in 0.6s cubic-bezier(0.2, 0.8, 0.2, 1) backwards;
  }

  .hero__titles > p {
    animation-delay: 0.08s;
  }

  .hero__copy > .button-group {
    animation-delay: 0.16s;
  }

  .hero__clients {
    animation-delay: 0.24s;
  }

  .dock > .panel {
    animation-delay: 1s;
  }
}

@keyframes rise-in {
  from {
    opacity: 0;
    transform: translateY(var(--space-md));
  }
}

/* "About Nollie" panel: a small panel pinned to the bottom right of the screen on tablet and desktop. A sticky, full-viewport-high wrapper
 * keeps it pinned while the page scrolls and releases it at the end of <main>, so it never covers the footer; the hero is pulled up
 * under it. 248px wide and 211px tall, 28px / 12px from the edges, it grows upward only when expanded. On phones (48em is a placeholder) it
 * would sit on top of the text, so it is hidden there and the same story is a container in the page instead (.promise, above About). */
.dock {
  position: sticky;
  top: 0;
  z-index: 3;
  block-size: 100vh; /* fallback */
  block-size: 100svh;
  padding: 0;
  pointer-events: none;
}

.dock + .hero {
  margin-block-start: -100vh;
  margin-block-start: -100svh;
}

.dock > .panel {
  --panel-stacked-width: calc((var(--size-panel-pinned) + var(--size-panel-stacked)) / 2); /* between the old 248px and 305px: 276.5px, a point is four lines at most */
  position: absolute;
  right: var(--space-lg); /* the same 24px as the header's Contact pill, so their right edges line up */
  bottom: var(--space-lg); /* 24px from the right and the bottom: the right edge is the Contact pill's */
  max-block-size: calc(100svh - var(--space-2xl));
  overflow-y: auto;
  pointer-events: auto;
}

@media (max-width: 47.99em) {
  .dock {
    display: none;
  }

  .dock + .hero {
    margin-block-start: 0; /* it was pulled up under the dock */
  }
}

/* ---- Client logo marquee ---- */
.marquee {
  position: relative;
  overflow: hidden;
}

/* Fades go from bg/page to transparent. */
.marquee::before,
.marquee::after {
  content: "";
  position: absolute;
  inset-block: 0;
  z-index: 1;
  inline-size: 24%; /* 345px of 1440 */
  pointer-events: none;
}

.marquee::before {
  inset-inline-start: 0;
  background: linear-gradient(to right, var(--color-bg-page), transparent);
}

.marquee::after {
  inset-inline-end: 0;
  background: linear-gradient(to left, var(--color-bg-page), transparent);
}

.marquee__track {
  display: flex;
  inline-size: max-content;
  animation: marquee 60s linear infinite; /* 12 logos at the speed 8 had in 40s */
}

.marquee__set {
  display: flex;
  flex: none;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* 200x200 cells with 20px between them in the frame (no token yet for the cell size). */
.marquee__item {
  display: grid;
  place-items: center;
  inline-size: 12.5rem;
  block-size: 12.5rem;
  margin-inline-end: calc(var(--space-md) + var(--space-xs));
}

/* Phones: logos at 80% of the component width, with 24px between them (the cell is only as wide as the logo plus that) and a strip about half
 * as tall, so it comes into the first screen. The loop time stays, so a logo still passes every 5s. */
@media (max-width: 47.99em) {
  .marquee .client-logo {
    inline-size: calc(var(--size-client-logo) * 0.8);
  }

  .marquee__item {
    inline-size: calc(var(--size-client-logo) * 0.8 + var(--space-lg));
    block-size: 6rem;
    margin-inline-end: 0;
  }
}

/* The second set is an exact copy, so moving by half the track loops seamlessly. */
@keyframes marquee {
  to {
    transform: translateX(-50%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .marquee__track {
    animation: none;
  }
}

/* ---- Sections below the hero: 1196 wide, 200px apart ---- */
.sections {
  display: grid;
  gap: var(--section-gap);
  box-sizing: border-box;
  inline-size: min(100% - 2 * var(--hero-margin), var(--size-content)); /* the same left and right edge as the hero text */
  margin-inline: auto;
  padding-block: var(--section-gap);
}

.promise {
  display: none; /* tablet and desktop have the pinned panel instead (.dock) */
}

@media (max-width: 47.99em) {
  .promise {
    display: flex;
  }
}

/* Laid out like the About panel on a phone: the eyebrow, then the media, then the text. The media is the film from the pinned panel, in a 16:9 frame
 * (media inside a panel uses --radius-md). Set explicitly so it does not depend on the panel's own width. */
.promise .panel__header {
  order: 0;
}

.promise .panel__media {
  position: static;
  transform: none;
  order: 1;
  inline-size: auto;
  aspect-ratio: 16 / 9;
  margin: var(--space-md) 0 0;
  overflow: hidden;
  border-radius: var(--radius-md);
  background-color: var(--color-bg-surface-solid);
}

.promise .panel__content {
  order: 2;
  max-inline-size: none;
  padding: var(--space-lg) var(--space-sm);
}

.promise .panel__content {
  gap: var(--space-md); /* the three points sit close together; the 40px of a Split panel is for text plus actions */
}

/* ---- How it works: a scroll track with one screen pinned in it. The pin (stage window at the left 663px, heading + steps + the step's sentence at the
 * right 453px, 80px apart, like Figma) stays on screen while the page scrolls through the four steps; components/configurator.js turns the
 * scroll position into the current step. Nothing below the section moves. Below 64em (placeholder) the stage window sits over the text; on
 * tablet and phone the steps become four numbers. On a short screen (the pin would not fit) it is not pinned and the steps are only clicked. ---- */
.how-it-works {
  --hiw-step: 60svh; /* scrolling distance per step */
  --hiw-gaps: 3; /* steps less one that can be reached (set by components/configurator.js: a hidden or disabled step has no stretch) */
  min-block-size: calc(100svh + var(--hiw-gaps) * var(--hiw-step));
}

.how-it-works__pin {
  position: sticky;
  top: 0;
  display: grid;
  grid-template-columns: minmax(0, 663fr) minmax(0, 453fr);
  grid-template-areas:
    "window title"
    "window list";
  grid-template-rows: auto auto;
  column-gap: calc(var(--space-xl) * 2);
  align-content: center;
  box-sizing: border-box;
  min-block-size: 100svh;
  padding-block: var(--space-2xl) var(--space-lg); /* clear of the fixed header above, 24px below */
}

.how-it-works > .how-it-works__pin > .how-it-works__title {
  grid-area: title;
  margin-block-end: var(--space-xl);
}

/* The window is as tall as the column at its right (heading to the last divider), so the two sides share a top and a bottom edge; the stage and
 * its controls are centred in it. */
.how-it-works__pin > .stage-window {
  grid-area: window;
  align-self: stretch;
  align-content: center;
}

.how-it-works__list {
  grid-area: list;
}

/* Tablet and desktop: every step's sentence is part of its list row (dimmed until the step is current), so the text belongs to its step. The
 * single slot below is for phones, where the list is four numbers. */
.how-it-works__texts {
  display: none;
}

.how-it-works__text {
  grid-area: 1 / 1;
  max-inline-size: 24.625rem; /* 394px in Figma */
  visibility: hidden;
  opacity: 0;
  transform: translateY(var(--space-sm));
  transition: opacity 0.3s ease, transform 0.35s cubic-bezier(0.2, 0.8, 0.2, 1), visibility 0s 0.3s;
}

.how-it-works__text[data-active] {
  visibility: visible;
  opacity: 1;
  transform: none;
  transition-delay: 0.1s, 0.1s, 0s;
}

.how-it-works__step {
  display: none; /* phones: the steps are numbers only, so the sentence carries the step's name */
  margin-block-end: var(--space-sm);
}

/* Desktop: the pin is as tall as its content (not a full screen), and sticks with its middle at the middle of the screen (never under the header), so the
 * space above and below the section is the same 200px as between the other sections. --hiw-pin is the pin's height, set by components/configurator.js. */
@media (min-width: 64em) {
  .how-it-works {
    min-block-size: calc(var(--hiw-pin, 36rem) + var(--hiw-gaps) * var(--hiw-step));
  }

  .how-it-works__pin {
    top: max(var(--space-2xl), calc((100svh - var(--hiw-pin, 36rem)) / 2));
    min-block-size: 0;
    padding-block: 0;
  }
}

@media (max-width: 63.99em) {
  .how-it-works__pin {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "title"
      "window"
      "list"
      "text";
    grid-template-rows: none;
    row-gap: var(--space-md);
    padding-block-start: calc(var(--space-2xl) + var(--space-sm));
    padding-block-end: var(--space-lg);
  }

  .how-it-works > .how-it-works__pin > .how-it-works__title {
    margin-block-end: 0;
  }

  /* One screen has to hold the heading, the stage, the numbers and a sentence: on a short screen the stage gets narrower (16:9) instead of taller. */
  .how-it-works__pin > .stage-window {
    align-self: start;
    justify-self: center;
    inline-size: min(100%, calc((100svh - 22rem) * 16 / 9 + 2 * var(--space-md)));
  }
}

@media (max-width: 63.99em) {
  .how-it-works__texts {
    grid-area: text;
    display: grid;
    align-content: start;
    padding-block-start: var(--space-md);
  }

  .how-it-works__text {
    max-inline-size: 40rem; /* wider than the 394px of the desktop list, so it takes fewer lines */
  }

  .how-it-works__list .index-list__more {
    display: none;
  }

  .how-it-works__list {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr); /* as many equal columns as there are steps (one may be hidden) */
  }

  .how-it-works__list .index-list__item {
    border-bottom: 0;
    border-block-start: var(--border-width) solid var(--color-border-default);
  }

  .how-it-works__list .index-list__item[data-open]::after {
    inset: calc(var(--border-width) * -1) 0 auto 0; /* the progress line runs along the top divider */
  }

  .how-it-works__list .index-list__row {
    padding-inline: 0;
    justify-items: start;
  }

  .how-it-works__list .index-list__title {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .how-it-works__step {
    display: block;
  }

  .how-it-works__step span {
    margin-inline-end: var(--space-md);
  }
}

/* A screen too short for the pin (stage, steps and sentence need about 46em): no pinning, the steps are clicked. */
@media (max-height: 46em) and (max-width: 63.99em) {
  .how-it-works {
    min-block-size: 0;
  }

  .how-it-works__pin {
    position: static;
    min-block-size: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .how-it-works__text {
    transition: none;
    transform: none;
  }
}

/* Keep the scrollbar's space so the page does not jump when it appears or goes (panel morph). */
html {
  scrollbar-gutter: stable;
}
