/* Gaun marketing site — tokens lifted from the iOS app (ios-app/gaun/Theme/GaunColors.swift)
   so the page and the screenshots on it are the same product. Light is the default theme;
   the dark pair follows the system unless the toggle has been used.

   Layout in one paragraph: a hero with the copy beside a fanned trio of phones over an accent
   wash (stacked under it on narrow screens), a strip of the app's evidence vocabulary, three
   reasons, then alternating feature rows where the art is a phone on a lit stage with one real
   card from the app floating over its corner. Two sections are a colour so the scroll has
   landmarks: the problem on ink, Capture on solid teal because it is the one action. The
   feature rows alternate page and panel, with the evidence hue they are about on the details
   only (see "section tones"). Capture has
   one spoken example above the button; Ask is preceded by a slow strip of the questions the
   sample world has been asked. */

:root {
  color-scheme: light;
  --bg: #f5f5f3;
  --panel: #fafaf8;
  --band: #eeeeea;
  --intel: #ffffff;
  --fill: #efefec;
  --line: #e4e4e0;
  --hairline: rgba(23, 24, 26, 0.06);
  --fg: #17181a;
  --fg2: #4a4d52;
  --fg3: #7d8187;
  --accent: #1f6f66;
  --accent-tint: #e4f1ee;
  --accent-wash: rgba(31, 111, 102, 0.13);
  --fact: #1f7a4a;
  --est: #a5690f;
  --inf: #6b46b8;
  --rep: #2b5fa8;
  --bezel: #deded8;
  --bezel-in: rgba(23, 24, 26, 0.1);
  --shadow: 0 1px 2px rgba(23, 24, 26, 0.04), 0 8px 24px rgba(23, 24, 26, 0.06);
  --shadow-lift: 0 2px 6px rgba(23, 24, 26, 0.06), 0 24px 60px rgba(23, 24, 26, 0.12);
  --shadow-float: 0 2px 8px rgba(23, 24, 26, 0.08), 0 18px 44px rgba(23, 24, 26, 0.18);
  --radius: 16px;
  --radius-lg: 28px;
  --maxw: 1120px;
}

:root[data-theme='dark'] {
  color-scheme: dark;
  --bg: #111214;
  --panel: #161719;
  --band: #0c0d0f;
  --intel: #1b1c20;
  --fill: #232529;
  --line: #26282c;
  --hairline: rgba(255, 255, 255, 0.07);
  --fg: #e7e7e4;
  --fg2: #aeb2b8;
  --fg3: #7b7f86;
  --accent: #5fbfb2;
  --accent-tint: #17302d;
  --accent-wash: rgba(95, 191, 178, 0.14);
  --fact: #5fc48f;
  --est: #e2a84a;
  --inf: #b393f0;
  --rep: #7ba6ec;
  --bezel: #2b2d32;
  --bezel-in: rgba(255, 255, 255, 0.08);
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.35);
  --shadow-lift: 0 2px 6px rgba(0, 0, 0, 0.45), 0 24px 60px rgba(0, 0, 0, 0.55);
  --shadow-float: 0 2px 8px rgba(0, 0, 0, 0.5), 0 18px 44px rgba(0, 0, 0, 0.6);
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  /* The topbar is sticky: keep anchor targets clear of it. */
  scroll-padding-top: 88px;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font:
    400 17px/1.6 -apple-system,
    BlinkMacSystemFont,
    'SF Pro Text',
    'Segoe UI',
    Roboto,
    Helvetica,
    Arial,
    sans-serif;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1,
h2,
h3 {
  margin: 0;
  letter-spacing: -0.021em;
  line-height: 1.12;
  font-weight: 620;
}

p {
  margin: 0;
}

a {
  color: inherit;
}

img {
  max-width: 100%;
  display: block;
}

/* Every screenshot is a <picture> (WebP with a PNG fallback); the wrapper must not take part
   in layout, or the phone frames and floats would get an inline box around their image. */
picture {
  display: contents;
}

/* With the wrapper gone, a <source> would become a layout box of its own — a phantom grid
   item that pushes the image onto a new row in .split. */
picture > source {
  display: none;
}

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 24px;
}

/* ---------- chrome ---------- */

.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: saturate(1.4) blur(16px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s ease;
}

.topbar.scrolled {
  border-bottom-color: var(--line);
}

.topbar .wrap {
  display: flex;
  align-items: center;
  gap: 20px;
  height: 64px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 640;
  letter-spacing: -0.02em;
  font-size: 19px;
  text-decoration: none;
}

/* The app icon itself. The PNG has the iOS rounded square on a white field, so it is clipped
   to that shape here; on the dark page the white corners would otherwise show. */
.brand .mark {
  width: 28px;
  height: 28px;
  border-radius: 7px;
  overflow: hidden;
}

.topnav {
  position: relative;
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 15px;
  color: var(--fg2);
}

/* The lit link's background is one element that glides between links. site.js writes --x
   and --w from the lit link; .on is off while the reader is above the first section. */
.topnav .pill {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: var(--w, 0px);
  transform: translateX(var(--x, 0px));
  border-radius: 8px;
  background: var(--accent-tint);
  opacity: 0;
  transition:
    transform 0.45s cubic-bezier(0.22, 0.8, 0.3, 1),
    width 0.45s cubic-bezier(0.22, 0.8, 0.3, 1),
    opacity 0.25s ease;
  pointer-events: none;
}

.topnav .pill.on {
  opacity: 1;
}

.topnav a {
  position: relative;
  text-decoration: none;
  padding: 6px 12px;
  border-radius: 8px;
  transition:
    color 0.18s ease,
    background-color 0.18s ease;
}

.topnav a:hover {
  color: var(--fg);
  background: var(--fill);
}

/* Set by site.js as sections pass under the bar. */
.topnav a.here {
  color: var(--accent);
}

.iconbtn {
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--fg2);
  width: 34px;
  height: 34px;
  border-radius: 10px;
  cursor: pointer;
  display: grid;
  place-items: center;
  font-size: 15px;
}

.iconbtn:hover {
  color: var(--fg);
}

/* Narrow screens lose the link row and get a "where you are" button instead: it names the
   section under the bar as the reader scrolls, and opens a list of all of them. */
.where {
  display: none;
  position: relative;
  margin-left: auto;
  min-width: 0;
}

.where-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 100%;
  height: 34px;
  padding: 0 10px 0 12px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--fg);
  font: inherit;
  font-size: 14.5px;
  font-weight: 560;
  cursor: pointer;
}

.where-btn span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.where-btn svg {
  flex: none;
  color: var(--fg3);
  transition: transform 0.18s ease;
}

.where-btn[aria-expanded='true'] svg {
  transform: rotate(180deg);
}

.where-menu {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  min-width: 200px;
  padding: 6px;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--intel);
  box-shadow: var(--shadow-float);
  display: grid;
}

.where-menu[hidden] {
  display: none;
}

.where-menu a {
  display: block;
  padding: 9px 12px;
  border-radius: 9px;
  font-size: 15px;
  text-decoration: none;
  color: var(--fg2);
}

.where-menu a:hover {
  background: var(--fill);
  color: var(--fg);
}

.where-menu a.here {
  color: var(--accent);
  background: var(--accent-tint);
}

.btn-sm .short {
  display: none;
}

@media (max-width: 860px) {
  .topnav {
    display: none;
  }
  .where {
    display: block;
  }
  .topbar .wrap {
    gap: 10px;
  }
}

@media (max-width: 480px) {
  .brand .word {
    display: none;
  }
  .btn-sm .long {
    display: none;
  }
  .btn-sm .short {
    display: inline;
  }
  .btn-sm {
    padding: 0 12px;
  }
}

/* ---------- buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 48px;
  padding: 0 24px;
  border-radius: 12px;
  border: 1px solid transparent;
  font: inherit;
  font-size: 16px;
  font-weight: 560;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition:
    transform 0.18s ease,
    box-shadow 0.18s ease,
    filter 0.18s ease,
    background-color 0.18s ease;
}

.btn-primary {
  background: var(--accent);
  color: #fff;
  box-shadow:
    0 1px 2px var(--accent-wash),
    0 10px 24px var(--accent-wash);
}

:root[data-theme='dark'] .btn-primary {
  color: #10221f;
}

.btn-primary:hover {
  filter: brightness(1.06);
  transform: translateY(-1px);
  box-shadow:
    0 2px 4px var(--accent-wash),
    0 16px 32px var(--accent-wash);
}

.btn-ghost {
  background: transparent;
  border-color: var(--line);
  color: var(--fg);
}

.btn-ghost:hover {
  background: var(--fill);
  transform: translateY(-1px);
}

.btn:active {
  transform: translateY(0);
}

.btn-sm {
  height: 38px;
  padding: 0 16px;
  font-size: 15px;
  box-shadow: none;
}

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

.hero {
  position: relative;
  padding: 92px 0 96px;
  isolation: isolate;
}

/* Two soft accent washes and a faint dot grid. Everything is a background layer on a
   pointer-events-free pseudo-element, so nothing here can catch a click. */
.hero::before {
  content: '';
  position: absolute;
  inset: -160px 0 0;
  z-index: -1;
  background:
    radial-gradient(62rem 34rem at 18% 0%, var(--accent-wash), transparent 62%),
    radial-gradient(48rem 30rem at 92% 12%, var(--accent-wash), transparent 60%);
}

.hero::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: radial-gradient(currentColor 1px, transparent 1px);
  background-size: 26px 26px;
  color: var(--fg3);
  opacity: 0.12;
  -webkit-mask-image: linear-gradient(180deg, #000, transparent 72%);
  mask-image: linear-gradient(180deg, #000, transparent 72%);
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: 13px;
  font-weight: 560;
  letter-spacing: 0.02em;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent-tint) 80%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
  border-radius: 999px;
  padding: 6px 14px 6px 11px;
  margin-bottom: 24px;
}

.eyebrow .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 0 0 currentColor;
  animation: pulse 2.8s ease-out infinite;
}

@keyframes pulse {
  0% {
    box-shadow: 0 0 0 0 color-mix(in srgb, currentColor 55%, transparent);
  }
  70%,
  100% {
    box-shadow: 0 0 0 7px transparent;
  }
}

.hero h1 {
  font-size: clamp(40px, 6.4vw, 68px);
  max-width: 15ch;
  letter-spacing: -0.03em;
}

/* One word underscored in the accent, rather than a second colour of type. The swash is a
   pseudo-element so it can sit under the descenders instead of through them. */
.hl {
  position: relative;
  white-space: nowrap;
}

.hl::after {
  content: '';
  position: absolute;
  left: -0.02em;
  right: -0.02em;
  bottom: -0.09em;
  height: 0.1em;
  border-radius: 999px;
  background: var(--accent);
  opacity: 0.55;
}

/* The one plain sentence that says what Gaun is, before the lede says why it matters. */
.hero .what {
  margin-top: 22px;
  font-size: clamp(17px, 2vw, 19.5px);
  font-weight: 540;
  line-height: 1.45;
  color: var(--fg);
  max-width: 48ch;
}

.hero .lede {
  margin-top: 16px;
  font-size: clamp(17px, 2vw, 19px);
  color: var(--fg2);
  max-width: 56ch;
}

.hero-cta {
  margin-top: 36px;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
}

.hero-for {
  margin-top: 22px;
  font-size: 15px;
  color: var(--fg2);
  max-width: 48ch;
}

.hero-note {
  margin-top: 10px;
  font-size: 14px;
  color: var(--fg3);
}

/* An address quoted in running text. */
.addr {
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: 0.92em;
  color: var(--accent);
  white-space: nowrap;
}

/* ---------- phones ---------- */

.phone {
  position: relative;
  border-radius: 44px;
  padding: 7px;
  background: linear-gradient(160deg, var(--bezel), color-mix(in srgb, var(--bezel) 55%, var(--bg)));
  box-shadow:
    inset 0 0 0 1px var(--bezel-in),
    var(--shadow-lift);
  width: 100%;
}

/* A whole iPhone screen is 2.17× as tall as it is wide, which next to a paragraph of text
   reads as a column of pixels rather than a product. Show the top of the screen at a
   calmer aspect and let the bottom fade out, so the crop is obviously deliberate.
   --win is that window; every phone on the page sets it or takes this default. */
.phone img {
  border-radius: 38px;
  width: 100%;
  height: var(--win, 600px);
  object-fit: cover;
  object-position: top;
  -webkit-mask-image: linear-gradient(180deg, #000 86%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 86%, transparent 100%);
}

/* In dark the screen is as dark as the page, so fading only the picture leaves the bezel's
   bottom edge and its drop shadow sitting under nothing. Fade the whole phone instead; the
   mask clips the shadow with it, which on a dark ground is no loss. */
:root[data-theme='dark'] .phone:not(.foot) {
  -webkit-mask-image: linear-gradient(180deg, #000 78%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 78%, transparent 100%);
}

:root[data-theme='dark'] .phone:not(.foot) img,
:root[data-theme='dark'] .phone:not(.foot) video {
  -webkit-mask-image: none;
  mask-image: none;
}

/* The fanned trio under the hero. The middle screen is forward and upright; the outer two sit
   lower, turned and slightly smaller, so the group reads as one object. --p is a parallax
   offset written by site.js on scroll; it is 0 until then and stays 0 for reduced motion. */
.hero-shots {
  --p: 0px;
  position: relative;
  margin-top: 72px;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
  align-items: end;
  padding-bottom: 8px;
}

.hero-shots::before {
  content: '';
  position: absolute;
  left: 8%;
  right: 8%;
  bottom: -6%;
  height: 62%;
  z-index: -1;
  background: radial-gradient(50% 50% at 50% 60%, var(--accent-wash), transparent 70%);
  filter: blur(10px);
}

.hero-shots .phone {
  transition:
    transform 0.4s cubic-bezier(0.22, 0.8, 0.3, 1),
    scale 0.35s cubic-bezier(0.22, 0.8, 0.3, 1),
    box-shadow 0.35s ease;
}

/* On arrival the fan opens, once: the phones rise from below and from closer together, the
   outer two first and the front one last. `translate` composes with the transform below, so
   the fan and the parallax are untouched. */
.hero-shots .phone:nth-child(1) {
  animation: arrive-l 0.9s cubic-bezier(0.22, 0.8, 0.3, 1) both;
}

.hero-shots .phone:nth-child(2) {
  animation: arrive-m 0.9s 0.18s cubic-bezier(0.22, 0.8, 0.3, 1) both;
}

.hero-shots .phone:nth-child(3) {
  animation: arrive-r 0.9s cubic-bezier(0.22, 0.8, 0.3, 1) both;
}

@keyframes arrive-l {
  from {
    translate: 48px 36px;
    opacity: 0;
  }
}

@keyframes arrive-m {
  from {
    translate: 0 44px;
    opacity: 0;
  }
}

@keyframes arrive-r {
  from {
    translate: -48px 36px;
    opacity: 0;
  }
}

/* A pointer over a phone lifts it a little and brings it to the front. */
.hero-shots .phone.phone:hover {
  scale: 1.03;
  z-index: 4;
  box-shadow:
    inset 0 0 0 1px var(--bezel-in),
    0 24px 48px -12px rgba(0, 0, 0, 0.28);
}

/* Parallax as the hero leaves: the front phone climbs at about the speed of the scroll, the
   two behind it lag, so the fan has depth. --p is 0 at the top and 100px a viewport down. */
.hero-shots .phone:nth-child(1) {
  transform: translateY(calc(52px + var(--p) * 0.28)) rotate(-3.4deg) scale(0.93);
  transform-origin: bottom right;
  z-index: 1;
}

.hero-shots .phone:nth-child(2) {
  transform: translateY(calc(-14px + var(--p) * -0.9));
  z-index: 3;
}

.hero-shots .phone:nth-child(3) {
  transform: translateY(calc(52px + var(--p) * 0.28)) rotate(3.4deg) scale(0.93);
  transform-origin: bottom left;
  z-index: 1;
}

.hero-shots .phone img {
  --win: 500px;
}

@media (max-width: 980px) {
  .hero-shots .phone img {
    --win: 420px;
  }
}

/* On a phone the same fan, smaller: the front phone in the middle, the other two peeking out
   behind it. One screenshot on its own looked like a stock mock-up. */
@media (max-width: 720px) {
  .hero-shots {
    display: block;
    height: 500px;
    max-width: 400px;
    margin-inline: auto;
    margin-top: 48px;
    padding-bottom: 0;
  }
  .hero-shots::before {
    left: 4%;
    right: 4%;
    bottom: -4%;
    height: 70%;
  }
  .hero-shots .phone {
    position: absolute;
    bottom: 0;
  }
  .hero-shots .phone:nth-child(1) {
    left: 0;
    width: 54%;
    transform: translateY(calc(24px + var(--p) * 0.2)) rotate(-4.5deg) scale(0.96);
  }
  .hero-shots .phone:nth-child(2) {
    left: 50%;
    width: 64%;
    transform: translateX(-50%) translateY(calc(var(--p) * -0.3));
  }
  .hero-shots .phone:nth-child(3) {
    right: 0;
    width: 54%;
    transform: translateY(calc(24px + var(--p) * 0.2)) rotate(4.5deg) scale(0.96);
  }
  .hero-shots .phone img {
    --win: 360px;
  }
  .hero-shots .phone:nth-child(2) img {
    --win: 450px;
  }
}

/* On a wide screen the copy and the phones share the first viewport: text on the left, the
   trio stacked on the right with the middle phone forward. Below 1040px the phones drop
   under the copy in the fanned row above. */
@media (min-width: 1040px) {
  .hero {
    padding-top: 56px;
  }
  .hero .wrap {
    display: grid;
    /* The fan is 540px on a wide screen and shrinks with the window below about 1290px, so
       the copy column never drops under the width its paragraphs need. */
    grid-template-columns: minmax(0, 1fr) min(540px, 42vw);
    gap: 40px;
    align-items: center;
  }
  .hero h1 {
    font-size: clamp(44px, 4.5vw, 60px);
  }
  /* The left phone leans out of its column towards the copy, so the paragraphs stop short of the
     column's edge; the headline keeps the full width. */
  .hero .what,
  .hero .lede {
    max-width: 450px;
  }
  .hero-shots {
    display: block;
    height: min(640px, 50vw);
    margin-top: 0;
    padding-bottom: 0;
  }
  .hero-shots::before {
    left: 4%;
    right: 4%;
    bottom: -4%;
    height: 70%;
  }
  .hero-shots .phone {
    position: absolute;
    bottom: 0;
  }
  .hero-shots .phone:nth-child(1) {
    left: -5%;
    width: 54%;
    transform: translateY(calc(28px + var(--p) * 0.28)) rotate(-4.5deg) scale(0.96);
  }
  .hero-shots .phone:nth-child(2) {
    left: 50%;
    width: 63%;
    transform: translateX(-50%) translateY(calc(var(--p) * -0.9));
  }
  .hero-shots .phone:nth-child(3) {
    right: -5%;
    width: 54%;
    transform: translateY(calc(28px + var(--p) * 0.28)) rotate(4.5deg) scale(0.96);
  }
  .hero-shots .phone img {
    --win: min(470px, 36.5vw);
  }
  .hero-shots .phone:nth-child(2) img {
    --win: min(580px, 45vw);
  }
}

/* ---------- the evidence strip under the hero ---------- */

.vocab {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 22px;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding: 22px 0;
  margin-bottom: 48px;
}

.vocab p {
  font-size: 15px;
  color: var(--fg3);
  margin-right: auto;
}

.evidence {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.chip {
  font-size: 13.5px;
  font-weight: 560;
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, currentColor 40%, transparent);
  background: color-mix(in srgb, currentColor 8%, transparent);
  white-space: nowrap;
}

.chip.fact {
  color: var(--fact);
}
.chip.rep {
  color: var(--rep);
}
.chip.est {
  color: var(--est);
}
.chip.inf {
  color: var(--inf);
}
.chip.unk {
  color: var(--fg3);
}

/* ---------- sections ---------- */

section {
  padding: 104px 0;
}

.section-head {
  max-width: 62ch;
  margin-bottom: 48px;
}

.kicker {
  display: inline-block;
  font-size: 12.5px;
  font-weight: 620;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg3);
  margin-bottom: 14px;
}

.feature .kicker,
.band .kicker {
  color: var(--accent);
}

.section-head h2 {
  font-size: clamp(28px, 4vw, 42px);
}

.section-head p {
  margin-top: 18px;
  font-size: 18px;
  color: var(--fg2);
}

/* ---------- section tones ----------

   Each feature sits on its own colour so the page has landmarks instead of one long scroll.
   The hues are the app's evidence vocabulary, matched to what the section is about: Ask in
   Reported blue (cited answers), Meetings in Estimate amber (names waiting on you), You in
   Inference purple (Gaun's interpretation of you), Evidence in Confirmed green. --tone drives
   the kicker, the bullets, the stage glow and the card borders. It deliberately does not tint
   the background: five washes in a row read as a rainbow, so the sections alternate between
   the page and the panel colour (.alt) and the hue stays on the details. */

.tone-accent {
  --tone: var(--accent);
}
.tone-rep {
  --tone: var(--rep);
}
.tone-est {
  --tone: var(--est);
}
.tone-inf {
  --tone: var(--inf);
}
.tone-fact {
  --tone: var(--fact);
}
.tone-plain {
  --tone: var(--accent);
}

.alt {
  background: var(--panel);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

[class*='tone-'] .kicker,
[class*='tone-'] .card .num {
  color: var(--tone);
}

[class*='tone-'] .feature li::before,
[class*='tone-'] .feature li::after {
  background: var(--tone);
}

[class*='tone-'] .stage::before {
  background: radial-gradient(60% 46% at 50% 42%, color-mix(in srgb, var(--tone) 22%, transparent), transparent 72%);
}

[class*='tone-'] .card {
  border-color: color-mix(in srgb, var(--tone) 16%, var(--line));
}

[class*='tone-'] .card::before {
  background: linear-gradient(90deg, var(--tone), transparent);
}

[class*='tone-'] .card:hover {
  border-color: color-mix(in srgb, var(--tone) 40%, var(--line));
}

/* The one dark section: the problem, set on ink so the hero and the product sections around
   it read as the light. Local tokens so cards and text need no rules of their own. In dark
   theme it is a deep teal-black, one step further than the page rather than the same. */
.ink {
  --bg: #17181a;
  --panel: #1f2023;
  --intel: #1f2023;
  --line: #2c2e33;
  --fg: #f2f2ef;
  --fg2: #b9bcc2;
  --fg3: #82868d;
  --accent: #5fbfb2;
  --accent-wash: rgba(95, 191, 178, 0.16);
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.35);
  color-scheme: dark;
  position: relative;
  background: var(--bg);
  color: var(--fg);
  overflow: hidden;
}

:root[data-theme='dark'] .ink {
  --bg: #0b1c1a;
  --panel: #122623;
  --intel: #122623;
  --line: #1e3834;
}

.ink::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(52rem 26rem at 88% 100%, var(--accent-wash), transparent 64%);
}

.ink .wrap {
  position: relative;
}

.ink .kicker {
  color: var(--accent);
}

.ink .card {
  background: color-mix(in srgb, #ffffff 5%, transparent);
  border-color: color-mix(in srgb, #ffffff 10%, transparent);
  backdrop-filter: blur(6px);
}

.ink .card:hover {
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
}

/* Three fragments, three wires, one knot. A diagram in the section's own materials — it is
   the one drawn thing on a page of real screens, and it must look drawn. The fragments and
   the knot fade up in order, the wires draw from left to right between them. */
.threads {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) 120px minmax(0, 1fr);
  align-items: center;
  gap: 0;
  margin: 0 0 56px;
}

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

.frag {
  display: grid;
  gap: 4px;
  padding: 14px 18px;
  border: 1px solid color-mix(in srgb, #ffffff 10%, transparent);
  border-radius: 12px;
  background: color-mix(in srgb, #ffffff 5%, transparent);
  opacity: 0;
  transform: translateX(-10px);
  transition:
    opacity 0.6s cubic-bezier(0.22, 0.8, 0.3, 1),
    transform 0.6s cubic-bezier(0.22, 0.8, 0.3, 1);
  transition-delay: calc(var(--i, 0) * 160ms);
}

.frag .when {
  font-size: 12px;
  font-weight: 620;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg3);
}

.frag .said {
  font-size: 15.5px;
  color: var(--fg);
}

/* The wires are stretched to the column (preserveAspectRatio="none"), which throws off
   dash-length maths, so they draw by unclipping left to right instead. */
.wires {
  width: 100%;
  height: 100%;
  min-height: 200px;
  overflow: visible;
  clip-path: inset(0 100% 0 0);
  transition: clip-path 1s cubic-bezier(0.22, 0.8, 0.3, 1);
  transition-delay: 420ms;
}

.wires path {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.5;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
  opacity: 0.85;
}

.knot {
  display: grid;
  justify-items: start;
  gap: 8px;
  padding: 18px 20px;
  border-radius: 14px;
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 30%, transparent);
  opacity: 0;
  transform: translateX(10px);
  transition:
    opacity 0.6s cubic-bezier(0.22, 0.8, 0.3, 1),
    transform 0.6s cubic-bezier(0.22, 0.8, 0.3, 1),
    box-shadow 1.2s ease;
  transition-delay: 1s;
}

.knot strong {
  font-size: 19px;
  font-weight: 640;
  letter-spacing: -0.01em;
  color: var(--fg);
}

.knot > span:last-child {
  font-size: 14.5px;
  color: var(--fg2);
}

.threads.in .frag,
.threads.in .knot {
  opacity: 1;
  transform: none;
}

.threads.in .wires {
  clip-path: inset(0 -2px 0 0);
}

.threads.in .knot {
  box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent) 0%, transparent);
}

@media (max-width: 720px) {
  .threads {
    grid-template-columns: 1fr;
    gap: 0;
  }
  .wires {
    display: none;
  }
  .knot {
    position: relative;
    margin-top: 32px;
    transform: translateY(10px);
  }
  /* A short stem from the last fragment to the knot stands in for the wires. */
  .knot::before {
    content: '';
    position: absolute;
    top: -26px;
    left: 28px;
    width: 1.5px;
    height: 24px;
    background: var(--accent);
    opacity: 0.85;
  }
}

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

.feature-sec {
  padding: 88px 0;
}

.feature {
  display: grid;
  grid-template-columns: 1fr 400px;
  gap: 80px;
  align-items: center;
}

.feature.flip .feature-art {
  order: -1;
}

.feature h2 {
  font-size: clamp(25px, 3vw, 33px);
  max-width: 22ch;
}

.feature .body {
  margin-top: 18px;
  font-size: 18px;
  color: var(--fg2);
  max-width: 50ch;
}

.feature ul {
  margin: 26px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 12px;
  max-width: 50ch;
}

.feature li {
  position: relative;
  padding-left: 28px;
  color: var(--fg2);
  font-size: 16px;
}

.feature li::before {
  content: '';
  position: absolute;
  left: 3px;
  top: 8px;
  width: 10px;
  height: 10px;
  border-radius: 4px;
  background: var(--accent);
  opacity: 0.28;
  box-shadow: inset 0 0 0 10px transparent;
}

.feature li::after {
  content: '';
  position: absolute;
  left: 6px;
  top: 11px;
  width: 4px;
  height: 4px;
  border-radius: 2px;
  background: var(--accent);
}

/* A slow strip of the questions the sample world has actually been asked, lifted from the Ask
   screen. The track holds the list twice so the loop is seamless; the copy is aria-hidden. */
.asked {
  padding: 48px 0 8px;
}

.asked-label {
  font-size: 12.5px;
  font-weight: 620;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg3);
  text-align: center;
  margin-bottom: 18px;
}

.ticker {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}

.ticker-track,
.ticker .dup {
  display: flex;
  gap: 12px;
  width: max-content;
}

.ticker-track {
  animation: ticker 48s linear infinite;
}

.ticker:hover .ticker-track {
  animation-play-state: paused;
}

.ticker .dup {
  margin-left: 12px;
}

.ticker-track > span:not(.dup),
.ticker .dup > span {
  white-space: nowrap;
  font-size: 15.5px;
  color: var(--fg);
  background: var(--intel);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 10px 18px;
  box-shadow: var(--shadow);
}

@keyframes ticker {
  to {
    transform: translateX(calc(-50% - 6px));
  }
}

/* The art half: a lit stage, the phone on it, and one real card from the app floating over
   a corner so the row is a composition rather than a pasted screenshot. */
.stage {
  position: relative;
  padding: 8px 0;
}

.stage::before {
  content: '';
  position: absolute;
  inset: 6% -14% 2%;
  z-index: -1;
  border-radius: 40px;
  background: radial-gradient(60% 46% at 50% 42%, var(--accent-wash), transparent 72%);
}

.float {
  position: absolute;
  z-index: 2;
  width: 88%;
  border-radius: 14px;
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--intel);
  box-shadow: var(--shadow-float);
}

.float img {
  width: 100%;
  height: auto;
}

.float.bl {
  left: -16%;
  bottom: 4%;
}

.float.br {
  right: -16%;
  bottom: 4%;
}

/* The Ask phone shows the answer the float is lifted from, so the float is a line of what
   the phone shows, enlarged. The window is an aspect ratio rather than a fixed height so that
   at every width it ends at the same place in the capture: the answer's opening and its first
   line in full, the second line beginning, and the third, the one in the float, under it. */
#ask .phone img {
  height: auto;
  aspect-ratio: 1206 / 1720;
}
#ask .float.br {
  width: 80%;
  bottom: 2%;
}

@media (max-width: 900px) {
  .feature-sec {
    padding: 64px 0;
  }
  .feature {
    grid-template-columns: 1fr;
    gap: 44px;
  }
  .feature.flip .feature-art {
    order: 0;
  }
  .feature-art {
    max-width: 340px;
  }
  .float {
    width: 82%;
  }
  .float.bl {
    left: -8%;
  }
  .float.br {
    right: -8%;
  }
}

@media (max-width: 560px) {
  .float.bl {
    left: 0;
  }
  .float.br {
    right: 0;
  }
}

/* ---------- full-bleed band (Capture) ---------- */

/* Solid accent, white type: the one section that is a colour rather than a wash, because it
   is the one action in the product. Local tokens keep the quote card and the phone frame
   readable on it. In dark theme the teal is deep instead of bright, so white text still
   has contrast. */
.band {
  --band-bg: #1f6f66;
  --band-glow: rgba(255, 255, 255, 0.16);
  --fg: #ffffff;
  --fg2: rgba(255, 255, 255, 0.8);
  --fg3: rgba(255, 255, 255, 0.62);
  --line: rgba(255, 255, 255, 0.22);
  --intel: #ffffff;
  --shadow: 0 2px 6px rgba(0, 0, 0, 0.12), 0 24px 60px rgba(0, 0, 0, 0.22);
  --bezel: #d8e6e3;
  --bezel-in: rgba(0, 0, 0, 0.12);
  position: relative;
  background: var(--band-bg);
  color: var(--fg);
  overflow: hidden;
}

:root[data-theme='dark'] .band {
  --band-bg: #163f3a;
  --band-glow: rgba(95, 191, 178, 0.22);
  --bezel: #2b4744;
}

.band::before {
  content: '';
  position: absolute;
  left: 50%;
  bottom: -30%;
  width: min(1000px, 120%);
  aspect-ratio: 1;
  transform: translateX(-50%);
  background: radial-gradient(50% 50% at 50% 50%, var(--band-glow), transparent 66%);
  pointer-events: none;
}

.band .kicker {
  color: #b9e6df;
}

.band .band-points div {
  border-top-color: rgba(255, 255, 255, 0.35);
}

.band .capture-stage::before {
  background: radial-gradient(50% 50% at 50% 50%, var(--band-glow), transparent 68%);
}

.band .band-head {
  max-width: 60ch;
  margin: 0 auto;
  text-align: center;
  position: relative;
}

.band h2 {
  font-size: clamp(28px, 4vw, 42px);
}

.band .band-head p {
  margin-top: 18px;
  font-size: 18px;
  color: var(--fg2);
}

.capture-stage {
  position: relative;
  margin: 48px auto 0;
  max-width: 520px;
}

/* A ring of accent light under the raised capture button, roughly where it sits in the crop. */
.capture-stage::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 74%;
  width: 380px;
  height: 380px;
  transform: translate(-50%, -50%);
  background: radial-gradient(50% 50% at 50% 50%, var(--accent-wash), transparent 68%);
  pointer-events: none;
}

/* The capture film: a whole screen in a phone, looping on its own, muted, while it is in view,
   with the flow strip under it. The stage is three phones wide for the strip; the film is one
   phone in the middle of it, the same size as the stills. */
.capture-stage {
  max-width: 980px;
}

.capture-stage::before {
  top: 235px;
  width: 460px;
  height: 460px;
}

/* The film is the same phone as the three stills under it: 600x940 of the recording, so the
   window is 470px at 300px wide. */
.phone.film {
  max-width: 300px;
  margin: 0 auto;
}

.phone video {
  display: block;
  border-radius: 38px;
  width: 100%;
  height: var(--win, 600px);
  object-fit: cover;
  object-position: top;
  background: #f3f4f2;
  -webkit-mask-image: linear-gradient(180deg, #000 86%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 86%, transparent 100%);
}

.phone.film video {
  --win: 470px;
  -webkit-mask-image: linear-gradient(180deg, #000 84%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 84%, transparent 100%);
}

/* The flow strip: three stills from the recording with arrows between them, under the film. */
.flow {
  position: relative;
  margin: 40px 0 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 40px minmax(0, 1fr) 40px minmax(0, 1fr);
  gap: 16px;
  align-items: start;
}

.flow .phone {
  max-width: 300px;
  margin: 0 auto;
}

.flow .phone img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 38px;
  -webkit-mask-image: linear-gradient(180deg, #000 84%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 84%, transparent 100%);
}

/* The still the film is on: lit with a ring, the other two stepped back a little. */
.flow-step .phone,
.flow figcaption {
  transition:
    opacity 0.45s ease,
    box-shadow 0.45s ease,
    transform 0.45s ease;
}

.following .flow-step:not(.on) .phone,
.following .flow-step:not(.on) figcaption {
  opacity: 0.55;
}

.following .flow-step.on .phone {
  transform: translateY(-4px);
  box-shadow:
    inset 0 0 0 1px var(--bezel-in),
    0 0 0 3px var(--accent),
    0 0 44px color-mix(in srgb, var(--accent) 45%, transparent),
    var(--shadow-lift);
}

.band .following .flow-step.on .phone {
  box-shadow:
    inset 0 0 0 1px var(--bezel-in),
    0 0 0 3px #fff,
    0 0 44px rgba(255, 255, 255, 0.4),
    var(--shadow-lift);
}

.flow figcaption {
  margin: 14px auto 0;
  max-width: 300px;
  text-align: center;
  font-size: 14px;
  line-height: 1.45;
  color: var(--fg2);
}

.flow figcaption b {
  font-weight: 640;
  color: var(--fg);
}

.flow-arrow {
  align-self: start;
  margin-top: 200px;
  color: var(--fg3);
}

.band .flow figcaption {
  color: rgba(255, 255, 255, 0.78);
}

.band .flow figcaption b,
.band .flow-arrow {
  color: #fff;
}

/* On a phone the film and the strip have to share one screen, or the lit still changes with
   the film already scrolled away and nothing explains why. So the strip stays a row, small,
   with just the lead of each caption. */
@media (max-width: 720px) {
  .flow {
    margin-top: 24px;
    grid-template-columns: minmax(0, 1fr) 22px minmax(0, 1fr) 22px minmax(0, 1fr);
    gap: 6px;
  }
  .flow .phone {
    max-width: 112px;
    border-radius: 22px;
    padding: 4px;
  }
  .flow .phone img {
    --win: 172px;
    border-radius: 18px;
  }
  .flow figcaption {
    margin-top: 8px;
    font-size: 12.5px;
  }
  .flow figcaption span {
    display: none;
  }
  .flow-arrow {
    margin-top: 76px;
  }
  .flow-arrow svg {
    width: 22px;
  }
  .following .flow-step.on .phone {
    transform: translateY(-3px);
    box-shadow:
      inset 0 0 0 1px var(--bezel-in),
      0 0 0 2px var(--accent),
      0 0 24px color-mix(in srgb, var(--accent) 45%, transparent),
      var(--shadow-lift);
  }
  .band .following .flow-step.on .phone {
    box-shadow:
      inset 0 0 0 1px var(--bezel-in),
      0 0 0 2px #fff,
      0 0 24px rgba(255, 255, 255, 0.4),
      var(--shadow-lift);
  }
}

/* Under the film: pause, a scrubber with the two screen changes ticked on it, and the clock. */
.film-bar {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: 300px;
  margin: 14px auto 0;
}

.film-bar[hidden] {
  display: none;
}

.film-seek {
  --at: 0%;
  flex: 1;
  height: 20px;
  margin: 0;
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  cursor: pointer;
}

.film-seek::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 2px;
  background:
    linear-gradient(90deg, var(--fg3) 0 1px, transparent 1px) var(--beat-1, -10px) 0 / 1px 100% no-repeat,
    linear-gradient(90deg, var(--fg3) 0 1px, transparent 1px) var(--beat-2, -10px) 0 / 1px 100% no-repeat,
    linear-gradient(90deg, var(--accent) var(--at), var(--line) var(--at));
}

.film-seek::-moz-range-track {
  height: 4px;
  border-radius: 2px;
  background:
    linear-gradient(90deg, var(--fg3) 0 1px, transparent 1px) var(--beat-1, -10px) 0 / 1px 100% no-repeat,
    linear-gradient(90deg, var(--fg3) 0 1px, transparent 1px) var(--beat-2, -10px) 0 / 1px 100% no-repeat,
    linear-gradient(90deg, var(--accent) var(--at), var(--line) var(--at));
}

.film-seek::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 14px;
  height: 14px;
  margin-top: -5px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--bg);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
}

.film-seek::-moz-range-thumb {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--bg);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
}

.film-seek:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
  border-radius: 4px;
}

.film-time {
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
  color: var(--fg3);
  min-width: 3ch;
}

/* One rule per engine: a selector list with the other engine's pseudo-element is dropped whole. */
.band .film-seek::-webkit-slider-runnable-track {
  background:
    linear-gradient(90deg, rgba(0, 0, 0, 0.4) 0 1px, transparent 1px) var(--beat-1, -10px) 0 / 1px 100% no-repeat,
    linear-gradient(90deg, rgba(0, 0, 0, 0.4) 0 1px, transparent 1px) var(--beat-2, -10px) 0 / 1px 100% no-repeat,
    linear-gradient(90deg, #fff var(--at), rgba(255, 255, 255, 0.28) var(--at));
}

.band .film-seek::-moz-range-track {
  background:
    linear-gradient(90deg, rgba(0, 0, 0, 0.4) 0 1px, transparent 1px) var(--beat-1, -10px) 0 / 1px 100% no-repeat,
    linear-gradient(90deg, rgba(0, 0, 0, 0.4) 0 1px, transparent 1px) var(--beat-2, -10px) 0 / 1px 100% no-repeat,
    linear-gradient(90deg, #fff var(--at), rgba(255, 255, 255, 0.28) var(--at));
}

.band .film-seek::-webkit-slider-thumb {
  background: #fff;
  border-color: var(--band-bg, #1f6f66);
}

.band .film-seek::-moz-range-thumb {
  background: #fff;
  border-color: var(--band-bg, #1f6f66);
}

.band .film-time {
  color: rgba(255, 255, 255, 0.7);
}

.film-btn {
  position: relative;
  display: block;
  margin: 0;
  flex: none;
  padding: 6px 14px;
  font: inherit;
  font-size: 13.5px;
  color: var(--fg2);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
}

.film-btn:hover {
  color: var(--fg);
  border-color: var(--fg3);
}

.film-btn[hidden] {
  display: none;
}

.band-points {
  position: relative;
  margin: 72px auto 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 28px;
  max-width: 940px;
}

.band-points div {
  border-top: 2px solid color-mix(in srgb, var(--accent) 40%, transparent);
  padding-top: 16px;
}

.band-points h4 {
  margin: 0;
  font-size: 17px;
  font-weight: 620;
  letter-spacing: -0.015em;
}

.band-points p {
  margin-top: 8px;
  font-size: 15.5px;
  color: var(--fg2);
}

@media (max-width: 900px) {
  .band-points {
    margin-top: 56px;
    grid-template-columns: 1fr;
    gap: 24px;
  }
}

/* CC your assistant: copy beside a drawn email with the alias on its Cc line. The email is a
   diagram in the page's type, not a screenshot of any mail client. */
.cc {
  position: relative;
  margin: 48px auto 0;
  max-width: 940px;
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: 48px;
  align-items: center;
}

.cc h3 {
  font-size: clamp(24px, 3vw, 32px);
  letter-spacing: -0.02em;
}

.cc p {
  margin-top: 14px;
  font-size: 16.5px;
  color: var(--fg2);
}

.mail {
  margin: 0;
  border-radius: 18px;
  overflow: hidden;
  background: var(--intel);
  color: #17181a;
  border: 1px solid rgba(255, 255, 255, 0.25);
  box-shadow: var(--shadow);
}

:root[data-theme='dark'] .mail {
  --intel: #1b1c20;
  color: #e7e7e4;
  border-color: rgba(255, 255, 255, 0.12);
}

.mail-head {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: 14px;
  row-gap: 6px;
  padding: 16px 20px;
  font-size: 14px;
  border-bottom: 1px solid rgba(23, 24, 26, 0.1);
}

:root[data-theme='dark'] .mail-head {
  border-bottom-color: rgba(255, 255, 255, 0.1);
}

.mail-k {
  color: #7d8187;
}

.mail-cc {
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: 13.5px;
  color: #1f6f66;
  background: #e4f1ee;
  border-radius: 6px;
  padding: 1px 7px;
  justify-self: start;
  word-break: break-all;
}

:root[data-theme='dark'] .mail-cc {
  color: #5fbfb2;
  background: #17302d;
}

.mail-subj {
  font-weight: 620;
}

.mail-body {
  padding: 16px 20px 18px;
  font-size: 14.5px;
  line-height: 1.5;
}

/* .cc p styles the copy column; the email's own paragraphs must not inherit that. */
.cc .mail-body p {
  margin: 0;
  font-size: inherit;
  color: inherit;
}

.cc .mail-body p + p {
  margin-top: 10px;
}

.mail figcaption {
  padding: 12px 20px 14px;
  font-size: 13.5px;
  color: #4a4d52;
  background: rgba(23, 24, 26, 0.04);
  border-top: 1px solid rgba(23, 24, 26, 0.1);
}

:root[data-theme='dark'] .mail figcaption {
  color: #aeb2b8;
  background: rgba(255, 255, 255, 0.04);
  border-top-color: rgba(255, 255, 255, 0.1);
}

@media (max-width: 900px) {
  .cc {
    margin-top: 40px;
    grid-template-columns: 1fr;
    gap: 28px;
  }
}

/* A cropped detail rather than a whole screen — used where the point is one control. */
.detail {
  border-radius: 20px;
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
  width: 100%;
  /* Without this the img's height attribute wins over the scaled width and squashes the
     screenshot. .phone img gets away with it because it sets an explicit height. */
  height: auto;
}

/* ---------- cards ---------- */

.cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 20px;
}

.cards.four {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (max-width: 900px) {
  .cards {
    grid-template-columns: 1fr;
  }
}

.card {
  position: relative;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 28px;
  overflow: hidden;
  transition:
    transform 0.22s ease,
    box-shadow 0.22s ease,
    border-color 0.22s ease;
}

.card::before {
  content: '';
  position: absolute;
  inset: 0 0 auto;
  height: 2px;
  background: linear-gradient(90deg, var(--accent), transparent);
  opacity: 0;
  transition: opacity 0.22s ease;
}

.card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow);
  border-color: color-mix(in srgb, var(--accent) 26%, var(--line));
}

.card:hover::before {
  opacity: 1;
}

.card .num {
  display: block;
  font-size: 12.5px;
  font-weight: 620;
  letter-spacing: 0.1em;
  color: var(--accent);
  margin-bottom: 12px;
}

.card h3 {
  font-size: 19px;
}

.card a,
.section-head a {
  color: var(--accent);
}

.card p {
  margin-top: 12px;
  color: var(--fg2);
  font-size: 16px;
}

/* ---------- evidence section ---------- */

.split {
  display: grid;
  grid-template-columns: 1fr 460px;
  gap: 80px;
  align-items: center;
  margin-bottom: 56px;
}

.split .section-head {
  margin-bottom: 0;
}

.split .detail {
  box-shadow: var(--shadow-lift);
}

/* A sheet lifted out of a screen: the capture keeps its full width, so its own rounded top
   corners (with the dimmed screen showing through them) are in the image. The top radius is a
   percentage so it scales with the image like the capture's own does, and is a little larger
   than the sheet's, so the page's corner covers the capture's at every width. */
.detail.sheet {
  border-radius: 8.5% 8.5% 20px 20px / 9% 9% 20px 20px;
}

@media (max-width: 900px) {
  .split {
    grid-template-columns: 1fr;
    gap: 36px;
  }
}

/* ---------- waitlist ---------- */

.tail {
  padding-top: 40px;
}

.waitlist {
  position: relative;
  background: var(--intel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 64px 40px;
  text-align: center;
  box-shadow: var(--shadow-lift);
  overflow: hidden;
}

.waitlist::before {
  content: '';
  position: absolute;
  left: 50%;
  top: -60%;
  width: 760px;
  height: 760px;
  transform: translateX(-50%);
  background: radial-gradient(50% 50% at 50% 50%, var(--accent-wash), transparent 62%);
  pointer-events: none;
}

.waitlist > * {
  position: relative;
}

.waitlist h2 {
  font-size: clamp(28px, 4vw, 40px);
}

.waitlist p {
  margin: 18px auto 0;
  color: var(--fg2);
  max-width: 48ch;
}

.wl-form {
  margin: 32px auto 0;
  display: flex;
  gap: 10px;
  max-width: 470px;
}

.wl-form input {
  flex: 1;
  height: 48px;
  padding: 0 16px;
  font: inherit;
  font-size: 16px;
  color: var(--fg);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 12px;
}

.wl-form input:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.wl-form button[disabled] {
  opacity: 0.6;
  cursor: default;
}

/* Always rendered, never display:none — a live region that starts hidden is unreliably
   announced. Empty it collapses to nothing, so it costs no space until there is a message. */
.wl-status {
  margin: 0;
  font-size: 15px;
  color: var(--fg2);
}

.wl-status:not(:empty) {
  margin-top: 16px;
}

.wl-status.ok {
  color: var(--fact);
}

.wl-status.bad {
  color: var(--est);
}

.wl-note {
  margin-top: 16px;
  font-size: 14px;
  color: var(--fg3);
}

@media (max-width: 520px) {
  .wl-form {
    flex-direction: column;
  }
  .waitlist {
    padding: 44px 22px;
  }
}

/* ---------- narrow screens: shorter sections ----------

   Stacked, every feature is a heading, a paragraph, three bullets and then a phone, and at
   the desktop crop height that is a screen and a half per feature. Shorter phone windows,
   tighter padding and slightly smaller body copy bring the page to roughly two thirds of
   its stacked length without dropping anything. */
@media (max-width: 900px) {
  section {
    padding: 72px 0;
  }
  .section-head {
    margin-bottom: 32px;
  }
  .section-head p,
  .feature .body,
  .band .band-head p {
    font-size: 16.5px;
  }
  .feature-sec {
    padding: 56px 0;
  }
  .feature {
    gap: 28px;
  }
  .feature ul {
    margin-top: 18px;
    gap: 8px;
  }
  .feature li {
    font-size: 15.5px;
  }
  .phone.film {
    max-width: 240px;
  }
  .phone.film video {
    --win: 376px;
  }
  .feature .phone img {
    --win: 400px;
  }
  .card {
    padding: 18px 20px;
  }
  .card h3 {
    font-size: 17.5px;
  }
  .card p {
    margin-top: 6px;
    font-size: 15.5px;
  }
  .card .num {
    margin-bottom: 6px;
  }
  .cards {
    gap: 10px;
  }
  .hero .lede {
    margin-top: 18px;
    font-size: 17.5px;
  }
  .hero-cta {
    margin-top: 28px;
  }
  .capture-stage {
    margin-top: 32px;
  }
  .band-points {
    margin-top: 40px;
    gap: 18px;
  }
  .asked {
    padding-top: 24px;
  }
  .split {
    margin-bottom: 32px;
  }
  .tail {
    padding-top: 24px;
  }
  .hero {
    padding-top: 64px;
  }
  .hero-shots {
    margin-top: 48px;
  }
}

/* ---------- footer ---------- */

footer {
  border-top: 1px solid var(--line);
  padding: 40px 0 56px;
  color: var(--fg3);
  font-size: 14px;
}

footer .wrap {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  align-items: center;
}

footer nav {
  margin-left: auto;
  display: flex;
  gap: 20px;
}

footer a {
  text-decoration: none;
}

footer a:hover {
  color: var(--fg2);
}

/* ---------- the legal pages ---------- */

/* Privacy and terms: one column of prose in the page's own type, with the same bar above. */
.doc {
  max-width: 68ch;
  margin: 0 auto;
  padding: 56px 0 96px;
}

.doc h1 {
  font-size: clamp(30px, 4.5vw, 44px);
  letter-spacing: -0.03em;
  line-height: 1.1;
}

.doc .stamp {
  margin-top: 12px;
  color: var(--fg3);
  font-size: 14.5px;
}

.doc h2 {
  margin-top: 44px;
  font-size: 22px;
  letter-spacing: -0.015em;
}

.doc p,
.doc li {
  margin-top: 14px;
  font-size: 16.5px;
  color: var(--fg2);
}

.doc ul {
  padding-left: 1.2em;
}

.doc li {
  margin-top: 8px;
}

.doc a {
  color: var(--accent);
}

.doc .back {
  display: inline-block;
  margin-top: 48px;
  color: var(--fg2);
  text-decoration: none;
}

.doc .back:hover {
  color: var(--fg);
}

/* ---------- motion ---------- */

/* --i staggers children of the same revealed group; unset it is 0 and nothing is delayed. */
.reveal {
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity 0.7s cubic-bezier(0.22, 0.8, 0.3, 1),
    transform 0.7s cubic-bezier(0.22, 0.8, 0.3, 1);
  transition-delay: calc(var(--i, 0) * 90ms);
}

.reveal.in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .flow-step .phone,
  .flow figcaption {
    transition: none;
  }
  html {
    scroll-behavior: auto;
  }
  .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .eyebrow .dot {
    animation: none;
  }
  .hero-shots .phone {
    transition: none;
    animation: none;
  }
  .topnav .pill {
    transition: none;
  }
  .threads .frag,
  .threads .knot,
  .threads .wires {
    transition: none;
    opacity: 1;
    transform: none;
    clip-path: none;
  }
  .ticker {
    -webkit-mask-image: none;
    mask-image: none;
  }
  .ticker-track {
    animation: none;
    flex-wrap: wrap;
    justify-content: center;
    width: auto;
  }
  .ticker .dup {
    display: none;
  }
  .ticker-track > span:not(.dup) {
    white-space: normal;
    text-align: center;
  }
}
