/* Landing layout. Tokens and chrome come from `_style.css`.

   The structure is taken from two references rather than invented: an inset
   dark hero panel with a row of cards docked across its bottom edge, and a
   hairline-divided stat bar over a full-bleed strip of content cards. The
   finish stays the app's - white ground, black ink, system type ramp, a
   raised surface is white plus a hairline. */

section { padding: clamp(56px, 7vw, 96px) 0; }

/* Two plain sections in a row share one band of air rather than stacking two. */
section.tight { padding-top: 0; }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 20px;
  color: var(--accent);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
}

/* Aligned to the first line rather than to the middle of the block, so a label
   that wraps on a phone does not leave the dot floating between its two rows. */
.eyebrow::before {
  content: '';
  flex: none;
  align-self: flex-start;
  width: 7px; height: 7px;
  margin-top: .5em;
  border-radius: 50%;
  background: currentColor;
}

h1, h2, h3 { letter-spacing: -.035em; text-wrap: balance; }

h1 {
  font-size: clamp(36px, 5.4vw, 62px);
  line-height: 1.02;
  font-weight: 700;
  margin: 0 0 22px;
}

h2 {
  font-size: clamp(28px, 4vw, 40px);
  line-height: 1.08;
  font-weight: 700;
  margin: 0 0 14px;
}

h3 {
  font-size: 19px;
  line-height: 1.25;
  font-weight: 600;
  letter-spacing: -.02em;
  margin: 0 0 8px;
}

.lede {
  font-size: clamp(18px, 2vw, 21px);
  line-height: 1.5;
  color: var(--ink-2);
  margin: 0 0 32px;
  max-width: 36ch;
}

p { margin: 0 0 12px; }

/* --- hero panel --------------------------------------------------------- */

.hero { padding: clamp(8px, 1.5vw, 16px) 0 0; }

.panel {
  position: relative;
  overflow: hidden;
  border-radius: clamp(24px, 3vw, 40px);
  background: var(--panel);
  color: #fff;
  padding: clamp(40px, 5vw, 76px) clamp(24px, 4vw, 64px) clamp(44px, 5vw, 76px);
}

.panel .eyebrow { color: var(--accent-on-panel); }
.panel .lede { color: var(--on-panel); }

.panel-grid {
  display: grid;
  gap: clamp(40px, 5vw, 64px);
  align-items: center;
}

@media (min-width: 900px) {
  .panel { padding-bottom: clamp(96px, 9vw, 132px); }
  .panel-grid {
    grid-template-columns: minmax(0, 1.06fr) minmax(0, .94fr);
    align-items: end;
  }
  .panel .lede { max-width: 30ch; }

  /* The phone runs off the bottom of the panel rather than being scaled down
     to fit inside it. A whole 19.5:9 device drawn small enough to fit is
     600-odd pixels of column and unreadable at the end of it; cut off by the
     panel's own edge it stays legible and the panel stays the height of its
     text. `overflow: hidden` on the panel is what does the cutting. */
  .panel .shot-stage { align-self: end; margin-bottom: -190px; }
}

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

/* The scrim the app draws over the bottom half, so the name keeps its
   contrast against whatever the photograph is doing under it. */
.strip figcaption {
  position: absolute;
  inset: auto 0 0 0;
  padding: 46px 14px 12px;
  background: linear-gradient(to top, rgba(0, 0, 0, .8), rgba(0, 0, 0, 0));
  color: #fff;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -.01em;
}

/* --- app screenshots ---------------------------------------------------- */

/* A capture off the simulator is the screen only, with no bezel, so the device
   is drawn here: two rings for the frame and its highlight, and the corner
   radius stated as a share of the frame so it stays the phone's own corner at
   every size. */
.shot {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 300px;
  margin-inline: auto;
  aspect-ratio: 1290 / 2796;
  border-radius: 12.5% / 5.8%;
  overflow: hidden;
  background: #000;
  box-shadow:
    0 0 0 6px #16161a,
    0 0 0 7px rgba(255, 255, 255, .16),
    0 40px 80px -28px rgba(0, 0, 0, .7);
}

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

.shot-stage { position: relative; display: grid; place-items: center; }

/* The hero phone runs off the panel on a phone too, or the panel alone is a
   whole screen of scrolling before the first word underneath it. */
@media (max-width: 899px) {
  .panel .shot { max-width: 260px; }
  .panel .shot-stage { margin-bottom: calc(-1 * clamp(30px, 22vw, 150px)); }
}

/* The accent, thrown behind the phone. It is the one place on the page the
   brand blue is used as light rather than as ink. */
.shot-stage::before {
  content: '';
  position: absolute;
  inset: 4% -14%;
  background: radial-gradient(closest-side,
              rgba(77, 163, 255, .34), rgba(77, 163, 255, 0) 72%);
  pointer-events: none;
}

/* --- alternating feature rows ------------------------------------------- */

.feature .wrap {
  display: grid;
  gap: clamp(36px, 5vw, 80px);
  align-items: center;
}

.feature p { color: var(--muted); max-width: 42ch; }
.feature .shot { max-width: 264px; }

@media (min-width: 900px) {
  .feature .wrap { grid-template-columns: minmax(0, 1fr) minmax(0, .78fr); }

  /* Flipping puts the phone on the left, so the column widths swap with it -
     otherwise the narrow column keeps the prose and the wide one holds a
     264px image. */
  .feature.flip .wrap { grid-template-columns: minmax(0, .78fr) minmax(0, 1fr); }
  .feature.flip .wrap > :first-child { order: 2; }
}

.feature .shot-stage::before {
  background: radial-gradient(closest-side,
              rgba(0, 93, 191, .12), rgba(0, 93, 191, 0) 72%);
}

/* --- the three halves, docked over the panel ---------------------------- */

.trio {
  display: grid;
  gap: 14px;
  margin: 24px 0 0;
  padding: 0;
  list-style: none;
}

.trio li {
  padding: 24px;
  border: 1px solid var(--rule);
  border-radius: 22px;
  background: var(--ground);
  box-shadow: var(--shadow);
}

.trio h3 { margin-bottom: 6px; }
.trio p { color: var(--muted); font-size: 16px; margin: 0; }

.trio .tag {
  display: block;
  margin-bottom: 12px;
  color: var(--accent);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
}

@media (min-width: 860px) {
  .trio {
    position: relative;
    z-index: 2;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    margin-top: -68px;
  }
}

/* --- store badges ------------------------------------------------------- */

/* Apple's and Google's own artwork, unaltered beyond trimming the transparent
   padding Google bakes into theirs - which is the only reason two badges set
   to one height used to read as two different sizes. */
.stores { display: flex; flex-wrap: wrap; gap: 12px; }

.stores a {
  display: block;
  border-radius: 8px;
  transition: transform .18s var(--ease);
}

.stores a:active { transform: scale(.97); }
.stores img { height: 46px; width: auto; }

/* Two badges side by side measure 304px at full height, which is 10px more
   than a 390pt phone leaves inside the panel - so they wrapped into a column.
   Four pixels off each brings the pair back onto one row. */
@media (max-width: 480px) {
  .stores { gap: 10px; }
  .stores img, .close .stores img { height: 42px; }
}

.close .stores { justify-content: center; margin-top: 28px; }
.close .stores img { height: 50px; }

/* The price objection, answered where it is felt - under the badges, at the
   moment of the tap - rather than announced before the product is. */
.reassure {
  margin: 16px 0 0;
  color: var(--on-panel);
  font-size: 15px;
}

/* --- wedge -------------------------------------------------------------- */

.wedge { background: var(--bed); }

.wedge p {
  font-size: clamp(24px, 3.6vw, 38px);
  line-height: 1.18;
  letter-spacing: -.035em;
  font-weight: 600;
  max-width: 26ch;
  margin: 0 0 20px;
  color: var(--muted);
}

.wedge p.hit { color: var(--ink); margin: 0; }

/* --- the short four ------------------------------------------------------ */

/* Four columns of one line each, which is what both references do with the
   features that do not earn a screenshot of their own. No cards: the columns
   are held apart by space, and by a rule on the wide layout only. */
.quad {
  display: grid;
  gap: 32px 28px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 900px) {
  .quad { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 40px; }
  .quad li + li { border-left: 1px solid var(--rule); padding-left: 40px; }
}

.quad h3 { margin-bottom: 6px; }
.quad p { color: var(--muted); font-size: 16px; margin: 0; }

/* --- category strip ----------------------------------------------------- */

/* Full bleed on purpose: the point of the row is that it runs past the edge of
   the screen, the same way the floor does. The left edge still lines up with
   the text column above it, so only the right side reads as unfinished. */
.strip {
  display: flex;
  gap: 14px;
  margin: 28px 0 0;
  padding: 4px var(--gutter) 12px
           max(var(--gutter), calc(50vw - var(--page) / 2 + var(--gutter)));
  overflow-x: auto;
  scroll-snap-type: x proximity;
  /* Without this the first card snaps its own start edge to the scroll port
     and the inset above is scrolled straight past, which lands the row hard
     against the window while every other section starts at the text column. */
  scroll-padding-inline-start:
    max(var(--gutter), calc(50vw - var(--page) / 2 + var(--gutter)));
  scrollbar-width: none;
  overscroll-behavior-x: contain;
}

.strip::-webkit-scrollbar { display: none; }

.strip figure {
  position: relative;
  flex: 0 0 clamp(168px, 21vw, 232px);
  margin: 0;
  aspect-ratio: 2 / 3;
  border-radius: 22px;
  overflow: hidden;
  background: var(--raised);
  scroll-snap-align: start;
}

/* --- coaches ------------------------------------------------------------ */

.coaches .wrap {
  display: grid;
  gap: clamp(32px, 5vw, 64px);
  align-items: center;
}

@media (min-width: 860px) {
  .coaches .wrap { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); }
}

.coaches p { color: var(--muted); max-width: 48ch; }
.coaches .mark-plinth { justify-self: center; }
.coaches .mark-plinth img { width: clamp(150px, 22vw, 220px); height: auto; }

/* --- closing call ------------------------------------------------------- */

.close { background: var(--bed); }

/* Raised is white plus a hairline and a drop, never a tinted fill.
   See CLAUDE.md `Design Target`. */
.close .card {
  background: var(--ground);
  border: 1px solid var(--rule);
  border-radius: clamp(26px, 3vw, 36px);
  padding: clamp(40px, 6vw, 76px) clamp(26px, 5vw, 64px);
  box-shadow: var(--shadow);
  text-align: center;
}

.close h2 { margin-bottom: 12px; }
.close .lede { color: var(--muted); margin: 0 auto; max-width: 40ch; }

/* --- mobile sticky call ------------------------------------------------- */

.dock {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 20;
  display: none;
  padding: 10px var(--gutter) calc(10px + env(safe-area-inset-bottom));
  background: color-mix(in srgb, var(--ground) 86%, transparent);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-top: 1px solid var(--rule);
  transform: translateY(110%);
  transition: transform .35s var(--ease);
}

.dock .btn { width: 100%; }

@media (max-width: 760px) {
  .dock { display: block; }
  .dock.show { transform: none; }
  body.has-dock { padding-bottom: 76px; }
}

/* --- entrance ----------------------------------------------------------- */

/* The hidden state is applied only once the script has claimed the document,
   so a reader with no JavaScript gets the page rather than a blank one. */
.js .rise {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity .6s var(--ease), transform .6s var(--ease);
  transition-delay: calc(var(--i, 0) * 70ms);
}

.js .rise.in { opacity: 1; transform: none; }

/* The hero panel keeps the travel and drops the fade. Chrome will not record
   a largest-contentful-paint candidate while the element is transparent, so
   fading the headline in costs the whole transition in the one metric a cold
   visitor is measured on. Everything below the fold still gets both.
   https://web.dev/articles/lcp#what-elements-are-considered */
.js .panel .rise { opacity: 1; }

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