/* ==========================================================================
   CueSpot — design tokens
   ========================================================================== */

:root {
  /* Surfaces. Lifted out of near-black so the page reads as graphite,
     not as a void. */
  --bg: #14181c;
  --bg-soft: #1a1f24;
  --bg-deep: #0f1317;
  --surface: #20262c;

  /* Light band surfaces. The paper is a shade below white so the raised
     CueSpot column in the comparison reads as lifted off it. */
  --paper: #eaedf0;
  --paper-soft: #dfe3e8;

  --ink: #f4f7f9;
  --ink-muted: #a9b4bb;
  --ink-faint: #7c888f;

  --ink-dark: #0f1418;
  --ink-dark-muted: #4f5b64;

  --line: rgba(255, 255, 255, 0.11);
  --line-strong: rgba(255, 255, 255, 0.2);

  --accent: #3ca1ff;
  --accent-soft: #8ec8ff;
  --accent-ink: #8ec8ff;
  --accent-on: #041524;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-soft: cubic-bezier(0.4, 0, 0.2, 1);

  --gutter: clamp(1.25rem, 4.5vw, 4rem);
  --wrap: 1200px;
  --nav-height: 68px;
  --section-pad: clamp(5.5rem, 11vw, 9.5rem);
}

/* Any element carrying this attribute flips the whole token set to the
   light band, so every component below inherits without a variant class. */
[data-tone="paper"] {
  --bg: var(--paper);
  --bg-soft: var(--paper-soft);
  --surface: #ffffff;
  --ink: var(--ink-dark);
  --ink-muted: var(--ink-dark-muted);
  --ink-faint: #6d7a83;
  --line: rgba(15, 20, 24, 0.12);
  --line-strong: rgba(15, 20, 24, 0.22);
  --accent-ink: #0b62c2;
  background: var(--paper);
  color: var(--ink);
}

/* ==========================================================================
   Base
   ========================================================================== */

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

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  overflow-x: hidden;
  background: var(--bg);
  color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display",
    "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  font-size: 17px;
  line-height: 1.55;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

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

a {
  color: inherit;
  text-decoration: none;
}

h1,
h2,
h3,
p,
figure {
  margin: 0;
}

h1,
h2,
h3 {
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

::selection {
  background: var(--accent);
  color: var(--accent-on);
}

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

.wrap {
  width: min(100%, var(--wrap));
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section {
  padding-block: var(--section-pad);
}

/* Anchors land below the sticky bar rather than behind it. */
section[id] {
  scroll-margin-top: var(--nav-height);
}

/* Display type. One scale, used everywhere, so hierarchy comes from size
   and space instead of labels. */

.display {
  font-size: clamp(2.5rem, 5.4vw, 4.4rem);
  letter-spacing: -0.042em;
  line-height: 1.02;
}

.lede {
  max-width: 46ch;
  color: var(--ink-muted);
  font-size: clamp(1.02rem, 1.35vw, 1.18rem);
  line-height: 1.62;
  letter-spacing: -0.005em;
}

/* ==========================================================================
   Navigation
   ========================================================================== */

.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  height: var(--nav-height);
  border-bottom: 1px solid transparent;
  background: color-mix(in srgb, #14181c 62%, transparent);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  transition: background 400ms var(--ease-soft), border-color 400ms var(--ease-soft),
    color 400ms var(--ease-soft);
}

.nav[data-scrolled="true"] {
  border-bottom-color: var(--line);
}

.nav[data-theme="light"] {
  color: var(--ink-dark);
  background: color-mix(in srgb, #eaedf0 72%, transparent);
  border-bottom-color: rgba(15, 20, 24, 0.08);
}

.nav[data-theme="light"] .nav__links {
  color: var(--ink-dark-muted);
}

.nav[data-theme="light"] .nav__links a:hover {
  color: var(--ink-dark);
}

.nav[data-theme="light"] .brand__mark {
  border-color: rgba(15, 20, 24, 0.14);
}

.nav__inner {
  width: min(100%, calc(var(--wrap) + 2 * var(--gutter)));
  height: 100%;
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  font-size: 1.02rem;
  font-weight: 700;
  letter-spacing: -0.028em;
}

.brand__mark {
  width: 30px;
  height: 30px;
  border: 1px solid var(--line);
  border-radius: 8px;
}

.nav__links {
  display: flex;
  align-items: center;
  gap: 1.9rem;
  color: var(--ink-muted);
  font-size: 0.88rem;
  letter-spacing: -0.008em;
}

.nav__links a,
.footer__links a {
  transition: color 200ms ease;
}

.nav__links a:hover,
.footer__links a:hover {
  color: currentColor;
  opacity: 1;
}

.nav__links a:hover {
  color: var(--ink);
}

/* ==========================================================================
   Buttons and links
   ========================================================================== */

.btn {
  display: inline-flex;
  min-height: 50px;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 0.85rem 1.45rem;
  border: 1px solid transparent;
  border-radius: 999px;
  font-size: 0.95rem;
  font-weight: 650;
  letter-spacing: -0.012em;
  transition: transform 260ms var(--ease), background 220ms ease,
    box-shadow 260ms var(--ease), border-color 220ms ease;
}

.btn--compact {
  min-height: 38px;
  padding: 0.5rem 1.05rem;
  font-size: 0.85rem;
}

.btn--primary {
  background: var(--accent);
  color: var(--accent-on);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.22) inset;
}

.btn--primary:hover {
  transform: translateY(-1px);
  background: #59b0ff;
}

.btn--primary:active {
  transform: translateY(0) scale(0.985);
}

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

.btn--ghost:hover {
  border-color: var(--ink-faint);
}

.btn__icon {
  width: 17px;
  height: 17px;
  flex: none;
  margin-top: -1px;
}

.text-link {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  color: var(--ink);
  font-size: 0.95rem;
  font-weight: 620;
  letter-spacing: -0.012em;
}

.text-link::after {
  content: "";
  width: 7px;
  height: 7px;
  border-right: 1.6px solid var(--accent-ink);
  border-bottom: 1.6px solid var(--accent-ink);
  rotate: 45deg;
  translate: 0 -1px;
  transition: translate 260ms var(--ease);
}

.text-link:hover::after {
  translate: 0 2px;
}

.text-link--out::after {
  border: 0;
  border-top: 1.6px solid var(--accent-ink);
  border-right: 1.6px solid var(--accent-ink);
  rotate: 45deg;
}

.text-link--out:hover::after {
  translate: 2px -3px;
}

/* ==========================================================================
   Hero
   ========================================================================== */

.hero {
  position: relative;
  overflow: clip;
  isolation: isolate;
  display: grid;
  align-items: center;
  min-height: calc(100svh - var(--nav-height));
  background: linear-gradient(170deg, #1c2228 0%, var(--bg) 55%);
}

/* The shader canvas mounts in here. Until it does — or if WebGL is not
   available — the hero's own gradient is what shows, so nothing depends on
   it arriving. */
.hero__shader {
  position: absolute;
  z-index: -1;
  inset: 0;
  opacity: 0;
  transition: opacity 1200ms var(--ease-soft);
}

.hero__shader[data-ready="true"] {
  opacity: 1;
}

/* Holds the type off the moving background: darkens the left side where
   the copy sits and lifts the corners back to the page colour so the hero
   still joins the section below it. */
.hero__scrim {
  position: absolute;
  z-index: 0;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(100deg, rgba(15, 19, 23, 0.92) 0%, rgba(15, 19, 23, 0.55) 38%, transparent 68%),
    linear-gradient(0deg, var(--bg) 0%, transparent 22%);
}

.hero__inner {
  position: relative;
  z-index: 2;
  width: min(100%, calc(var(--wrap) + 2 * var(--gutter)));
  margin-inline: auto;
  padding: clamp(3rem, 8vh, 5rem) var(--gutter);
}

.hero__content {
  max-width: 33rem;
}

/* Two lines locked into one block: tight leading so they read as a single
   shape rather than two sentences that happen to be stacked. */
.hero__title {
  font-size: clamp(2.4rem, 4.4vw, 3.9rem);
  font-weight: 700;
  letter-spacing: -0.045em;
  line-height: 1.0;
}

.hero__dot {
  color: var(--accent);
}

.hero__title > span {
  display: block;
}

.hero__lede {
  margin-top: clamp(1.2rem, 2vw, 1.6rem);
  max-width: 40ch;
}

.hero__actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 1rem 1.6rem;
  margin-top: clamp(1.6rem, 2.6vw, 2.2rem);
}

/* Anchored to the bottom-right and pushed past both edges, so the device
   reads as physically present in the frame instead of placed in it. The
   hero clips the overflow. */
.hero__stage {
  --tilt-x: 0;
  --tilt-y: 0;
  position: absolute;
  z-index: 1;
  top: 50%;
  /* Anchored to the right edge of the content column, not the window, so it
     stays part of the layout instead of drifting into the corner. */
  right: max(0px, calc((100% - var(--wrap)) / 2));
  width: min(42vw, 545px);
  transform: perspective(2000px)
    rotateX(calc(var(--tilt-y) * -1deg))
    rotateY(calc(var(--tilt-x) * 1deg))
    translate3d(0, calc(var(--hero-shift, 0) * -1px), 0);
  will-change: transform;
}

/* A slow idle drift, so the device reads as held in the frame rather than
   pasted onto it. It lives on the image while the pointer tilt lives on the
   stage, so the two never write to the same property. `translate` is a
   separate longhand, which is what leaves `transform` free here. */
@keyframes hero-float {
  from {
    transform: translate3d(0, 6px, 0) rotate(-0.3deg);
  }
  to {
    transform: translate3d(0, -10px, 0) rotate(0.3deg);
  }
}

.hero__mockup {
  width: 100%;
  max-width: none;
  height: auto;
  translate: 5% -47%;
  filter: drop-shadow(0 36px 70px rgba(0, 0, 0, 0.55));
  animation: hero-float 7s ease-in-out infinite alternate;
}

/* ==========================================================================
   The comparison
   ========================================================================== */

/* The section is meant to hold one screen, so the heading sits beside its
   lede rather than above it and the table takes what is left. */
.versus {
  display: grid;
  align-content: center;
  min-height: 100svh;
  padding-block: clamp(3.5rem, 7vh, 5.5rem);
}

.versus__head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: start;
}

/* Both columns start at the same y, but their first lines did not: the
   heading's line-height of 1 sits above its box while the lede's 1.62 sits
   8px below it. Trimming to the cap height removes the half-leading from
   both, so the two first lines share one top edge. Browsers without
   text-box just fall back to the old offset. */
.versus__head h2,
.versus__head .lede {
  text-box: trim-start cap alphabetic;
}

.versus__head h2 {
  max-width: 15ch;
  font-size: clamp(2rem, 3.4vw, 3rem);
}

.versus__head .lede {
  max-width: 52ch;
}

.matrix {
  width: 100%;
  margin-top: clamp(2.25rem, 4.5vh, 3.5rem);
  border-collapse: separate;
  border-spacing: 0;
  table-layout: fixed;
  text-align: left;
}

.matrix caption {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.matrix th,
.matrix td {
  padding: clamp(0.85rem, 1.5vh, 1.35rem) clamp(1rem, 2.2vw, 1.9rem);
  font-weight: 400;
  vertical-align: top;
}

.matrix thead th {
  padding-bottom: 1rem;
  color: var(--ink);
  font-size: clamp(1.05rem, 1.6vw, 1.28rem);
  font-weight: 650;
  letter-spacing: -0.028em;
  line-height: 1.25;
}

/* Row label. Narrower than the two answer columns, and quieter. */
.matrix tbody th {
  width: 25%;
  color: var(--ink-muted);
  font-size: 1rem;
  line-height: 1.45;
}

.matrix tbody td {
  color: var(--ink-muted);
  font-size: 1.06rem;
  line-height: 1.5;
  letter-spacing: -0.014em;
}

.matrix tbody tr + tr th,
.matrix tbody tr + tr td {
  border-top: 1px solid var(--line);
}

.matrix tbody tr:first-child th,
.matrix tbody tr:first-child td {
  border-top: 1px solid var(--line-strong);
}

/* The CueSpot column is lifted onto its own surface so the eye lands there
   first and stays in one place down the table. */
.matrix__us {
  position: relative;
  background: var(--surface);
  color: var(--ink);
  box-shadow: 0 1px 2px rgba(15, 20, 24, 0.06),
    0 26px 50px -30px rgba(15, 20, 24, 0.55);
}

.matrix tbody td.matrix__us {
  color: var(--ink);
  font-weight: 500;
}

.matrix thead th {
  padding-top: 1.2rem;
}

/* Painted as a background layer rather than a border or an overlaid child.
   A border would push the label down out of line with the column beside it,
   and a positioned child is not clipped by its parent's radius — which left
   the bar's square ends hanging past the curve at both top corners. As a
   background it is clipped to the same 14px arc as the surface under it. */
.matrix thead .matrix__us {
  border-radius: 14px 14px 0 0;
  background:
    linear-gradient(var(--accent), var(--accent)) top / 100% 3px no-repeat,
    var(--surface);
}

.matrix thead .matrix__us span {
  display: block;
  margin-top: 0.3rem;
  color: var(--accent-ink);
  font-size: 0.85rem;
  font-weight: 620;
  letter-spacing: -0.01em;
}

.matrix tbody tr:last-child .matrix__us {
  border-radius: 0 0 14px 14px;
  padding-bottom: 1.6rem;
}

.matrix tbody .matrix__us {
  border-top-color: rgba(15, 20, 24, 0.09);
}

/* ==========================================================================
   Workflow
   ========================================================================== */

.workflow {
  position: relative;
  background: var(--bg);
}

.workflow__title {
  max-width: 16ch;
  margin-bottom: clamp(3rem, 6vw, 5rem);
}

.workflow__layout {
  display: grid;
  grid-template-columns: minmax(300px, 0.9fr) minmax(0, 1.1fr);
  gap: clamp(3rem, 8vw, 8rem);
  align-items: start;
  /* Keeps the stage stuck through the last step instead of releasing it
     early and letting the render slide under the navigation. */
  padding-bottom: 16svh;
}

/* Only a box below 860px; above it the grid must still see the stage and
   the steps as its two columns. */
.workflow__pane {
  display: contents;
}

.workflow__stage {
  position: sticky;
  top: calc(var(--nav-height) + 2.5rem);
  height: calc(100svh - var(--nav-height) - 5rem);
  display: grid;
  place-items: center;
}

.workflow__visual {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
}

/* --flux is set from the scroll handler and peaks halfway through a wipe,
   so the light lifts while the screen changes and settles again after. */
.workflow__glow {
  --flux: 0;
  position: absolute;
  z-index: 0;
  width: min(120%, 460px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(60, 161, 255, 0.2), transparent 70%);
  filter: blur(40px);
  opacity: calc(0.55 + var(--flux) * 0.75);
  scale: calc(1 + var(--flux) * 0.06);
}

/* The three renders share a pixel-identical device frame; only the screen
   differs. So the sequence is not a crossfade between phones — it is one
   phone whose screen is wiped, bottom to top, by the scroll itself. The
   frame never moves, which is what stops it looking like a slideshow. */
.workflow__mockup {
  --wipe: 0;
  --edge: calc(-14% + var(--wipe) * 128%);
  position: relative;
  grid-area: 1 / 1;
  width: min(300px, 68vw, 42svh);
  max-width: none;
  height: auto;
  -webkit-mask-image: linear-gradient(
    to top,
    #000 var(--edge),
    transparent calc(var(--edge) + 13%)
  );
  mask-image: linear-gradient(
    to top,
    #000 var(--edge),
    transparent calc(var(--edge) + 13%)
  );
}

/* The bottom-most render has nothing underneath it, so it never wipes — and
   because the three silhouettes are pixel identical, it is also the only one
   that needs a shadow. Giving each render its own stacked three copies of the
   same shadow as the wipes completed, which darkened into a hard square
   around the rounded corners of a cut-out image. One shadow, cast by the
   layer that is always fully visible, reads as the single phone it is. */
.workflow__mockup:first-of-type {
  -webkit-mask-image: none;
  mask-image: none;
  filter: drop-shadow(0 38px 55px rgba(0, 0, 0, 0.5));
}

/* Steps */

.workflow__steps {
  --fill: 0px;
  position: relative;
  list-style: none;
  margin: 0;
  padding: 0 0 0 clamp(1.75rem, 3vw, 2.75rem);
}

.workflow__steps::before,
.workflow__steps::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
}

.workflow__steps::before {
  height: 100%;
  background: var(--line);
}

.workflow__steps::after {
  height: var(--fill);
  background: linear-gradient(180deg, transparent, var(--accent) 14%, var(--accent));
  box-shadow: 0 0 12px rgba(60, 161, 255, 0.6);
}

.workflow-step {
  position: relative;
  min-height: 74svh;
  display: grid;
  align-content: center;
  opacity: 0.3;
  transition: opacity 550ms var(--ease);
}

.workflow-step::before {
  content: "";
  position: absolute;
  top: 50%;
  left: calc(clamp(1.75rem, 3vw, 2.75rem) * -1);
  width: 9px;
  height: 9px;
  translate: -50% -50%;
  border-radius: 50%;
  background: var(--bg);
  box-shadow: 0 0 0 1px var(--line-strong);
  transition: background 450ms var(--ease), box-shadow 450ms var(--ease),
    scale 450ms var(--ease);
}

.workflow-step[data-state="current"] {
  opacity: 1;
}

.workflow-step[data-state="current"]::before {
  background: var(--accent);
  box-shadow: 0 0 0 1px var(--accent), 0 0 16px rgba(60, 161, 255, 0.8);
  scale: 1.25;
}

.workflow-step[data-state="past"] {
  opacity: 0.45;
}

.workflow-step[data-state="past"]::before {
  background: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
}

.workflow-step h3 {
  font-size: clamp(1.9rem, 3.6vw, 3rem);
  letter-spacing: -0.042em;
}

.workflow-step p {
  max-width: 38ch;
  margin-top: 1.1rem;
  color: var(--ink-muted);
  font-size: 1.05rem;
  line-height: 1.6;
}

/* ==========================================================================
   Details
   ========================================================================== */

.details__layout {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: start;
}

/* Sized down from the full display scale: the column is half the page, and
   at the larger size this heading breaks into six short lines. */
.details h2 {
  position: sticky;
  top: calc(var(--nav-height) + 3rem);
  max-width: 15ch;
  font-size: clamp(2.1rem, 3.8vw, 3.2rem);
}

.detail-list {
  display: grid;
  border-top: 1px solid var(--line);
}

.detail-row {
  display: grid;
  grid-template-columns: minmax(140px, 0.72fr) minmax(220px, 1.28fr);
  gap: 1rem 2rem;
  padding-block: clamp(1.6rem, 2.6vw, 2.2rem);
  border-bottom: 1px solid var(--line);
}

.detail-row h3 {
  font-size: 1.18rem;
  letter-spacing: -0.028em;
  line-height: 1.25;
}

.detail-row p {
  color: var(--ink-muted);
  font-size: 1rem;
  line-height: 1.6;
}

/* ==========================================================================
   Privacy
   ========================================================================== */

.privacy {
  border-block: 1px solid rgba(60, 161, 255, 0.16);
  background:
    radial-gradient(90% 130% at 12% 0%, rgba(60, 161, 255, 0.14), transparent 62%),
    #141c24;
}

.privacy__layout {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2.5rem, 8vw, 7rem);
  align-items: end;
}

.privacy h2 {
  max-width: 11ch;
}

.privacy__statement > p {
  margin-bottom: 1.8rem;
  color: #cdd8de;
  font-size: clamp(1.1rem, 1.8vw, 1.4rem);
  line-height: 1.5;
  letter-spacing: -0.02em;
}

/* ==========================================================================
   Closing
   ========================================================================== */

.closing {
  position: relative;
  overflow: clip;
  display: grid;
  place-items: center;
  text-align: center;
  background:
    radial-gradient(70% 60% at 50% 62%, rgba(60, 161, 255, 0.16), transparent 62%),
    linear-gradient(180deg, var(--bg) 0%, var(--bg-deep) 100%);
}

.closing__content {
  display: grid;
  justify-items: center;
  padding-block: clamp(6rem, 14vw, 10rem);
}

.closing__mark {
  width: 68px;
  height: 68px;
  margin-bottom: 2.2rem;
  border: 1px solid var(--line-strong);
  border-radius: 18px;
  box-shadow: 0 26px 50px -26px rgba(60, 161, 255, 0.7);
}

.closing__title {
  max-width: 14ch;
  font-size: clamp(2.5rem, 6.2vw, 5.1rem);
  font-weight: 800;
  letter-spacing: -0.052em;
  line-height: 1.02;
}

.closing__content > p:not(.btn-note) {
  max-width: 34ch;
  margin-top: 1.4rem;
  color: var(--ink-muted);
}

.closing .btn {
  margin-top: 2.2rem;
}

.btn-note {
  margin-top: 1.1rem;
  color: var(--ink-faint);
  font-size: 0.82rem;
}

/* ==========================================================================
   Footer
   ========================================================================== */

.footer {
  padding-block: 3.5rem 2rem;
  border-top: 1px solid var(--line);
  background: var(--bg-deep);
  color: var(--ink-faint);
  font-size: 0.86rem;
}

.footer__grid {
  display: grid;
  grid-template-columns: 0.7fr 1.3fr 1fr;
  gap: 2rem;
  align-items: start;
}

.footer__grid > p {
  max-width: 32ch;
  color: var(--ink-muted);
}

.footer__links {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 1.4rem;
  color: var(--ink-muted);
}

.footer__bottom {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 3rem;
  padding-top: 1.35rem;
  border-top: 1px solid var(--line);
}

/* ==========================================================================
   Legal pages
   ========================================================================== */

.legal {
  min-height: 70svh;
  padding-block: clamp(3.5rem, 9vw, 5.5rem) clamp(4rem, 9vw, 7rem);
}

.legal h1 {
  margin-bottom: 0.9rem;
  font-size: clamp(2.4rem, 6vw, 4rem);
  letter-spacing: -0.045em;
}

.legal__meta {
  margin-bottom: clamp(2.5rem, 5vw, 3.5rem);
  color: var(--ink-faint);
  font-size: 0.92rem;
}

.legal__body {
  max-width: 68ch;
  color: var(--ink-muted);
  font-size: 1.02rem;
  line-height: 1.68;
}

.legal__body > * + * {
  margin-top: 1.15rem;
}

.legal__body h2 {
  margin-top: clamp(2.75rem, 5vw, 3.75rem);
  padding-top: 1.6rem;
  border-top: 1px solid var(--line);
  color: var(--ink);
  font-size: clamp(1.35rem, 2.4vw, 1.7rem);
  letter-spacing: -0.032em;
  line-height: 1.2;
}

.legal__body h3 {
  margin-top: 2rem;
  color: var(--ink);
  font-size: 1.08rem;
  letter-spacing: -0.02em;
  line-height: 1.35;
}

.legal__body a {
  color: var(--accent-ink);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}

.legal__body strong {
  color: var(--ink);
  font-weight: 620;
}

.legal__body ul {
  margin-left: 0;
  padding-left: 1.15rem;
  list-style: none;
}

.legal__body li + li {
  margin-top: 0.6rem;
}

.legal__body ul > li {
  position: relative;
}

.legal__body ul > li::before {
  content: "";
  position: absolute;
  top: 0.72em;
  left: -1.15rem;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
}

/* Postal blocks, contact details and anything else that has to keep its
   own line breaks. */
.legal__block {
  padding: 1.4rem 1.5rem;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--bg-soft);
  color: var(--ink);
  line-height: 1.65;
}

/* The short version at the top of the privacy policy. */
.legal__summary {
  padding: clamp(1.4rem, 3vw, 1.9rem);
  border: 1px solid rgba(60, 161, 255, 0.28);
  border-radius: 16px;
  background: rgba(60, 161, 255, 0.06);
}

.legal__summary h2 {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
  font-size: 1.05rem;
  letter-spacing: -0.02em;
}

.legal__summary ul {
  margin-top: 0.9rem;
}

.legal__summary > p:last-child {
  margin-top: 1rem;
  color: var(--ink-faint);
  font-size: 0.92rem;
}

/* Sub-processor list */
.legal__table {
  width: 100%;
  margin-top: 1.4rem;
  border-collapse: collapse;
  font-size: 0.95rem;
  text-align: left;
}

.legal__table th,
.legal__table td {
  padding: 0.85rem 1rem 0.85rem 0;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

.legal__table thead th {
  padding-top: 0;
  border-bottom-color: var(--line-strong);
  color: var(--ink);
  font-size: 0.85rem;
  font-weight: 620;
}

.legal__table tbody th {
  width: 30%;
  color: var(--ink);
  font-weight: 500;
}

.legal__table td:last-child,
.legal__table th:last-child {
  padding-right: 0;
}

.placeholder {
  padding: 1.5rem;
  border: 1px dashed var(--line-strong);
  border-radius: 14px;
  color: var(--ink-faint);
  font-size: 0.9rem;
  line-height: 1.65;
}

.back-link {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 2.2rem;
  color: var(--ink-muted);
  font-size: 0.92rem;
}

.back-link svg {
  width: 15px;
  height: 15px;
}

@media (max-width: 620px) {
  .legal__table,
  .legal__table tbody,
  .legal__table tr {
    display: block;
  }

  .legal__table thead {
    display: none;
  }

  .legal__table tr {
    padding-block: 1rem;
    border-bottom: 1px solid var(--line);
  }

  .legal__table th,
  .legal__table td {
    display: block;
    width: auto;
    padding: 0;
    border: 0;
  }

  .legal__table td {
    margin-top: 0.35rem;
  }
}

/* ==========================================================================
   Reveals
   ========================================================================== */

[data-reveal="on"] .reveal {
  opacity: 0;
  translate: 0 18px;
  transition: opacity 900ms var(--ease), translate 900ms var(--ease);
  transition-delay: calc(var(--index, 0) * 80ms);
}

[data-reveal="on"] .reveal.is-visible {
  opacity: 1;
  translate: 0 0;
}

/* ==========================================================================
   Responsive
   ========================================================================== */

@media (max-width: 1080px) {
  .workflow__layout {
    grid-template-columns: minmax(270px, 0.85fr) 1fr;
    gap: 3rem;
  }

  .workflow__mockup {
    width: min(290px, 60vw, 42svh);
  }
}

@media (max-width: 860px) {
  :root {
    --nav-height: 62px;
  }

  .nav__links {
    display: none;
  }

  /* The device comes out of the corner and back into the flow, under the
     copy, still cropped by the fold. */
  .hero {
    display: flex;
    flex-direction: column;
    align-items: stretch;
  }

  .hero__inner {
    flex: 0 0 auto;
    padding-block: clamp(2rem, 5vh, 3rem) 0;
  }

  .hero__content {
    max-width: none;
  }

  .hero__scrim {
    background:
      linear-gradient(180deg, rgba(15, 19, 23, 0.88) 0%, rgba(15, 19, 23, 0.5) 46%, transparent 72%),
      linear-gradient(0deg, var(--bg) 0%, transparent 26%);
  }

  .hero__stage {
    position: relative;
    right: auto;
    bottom: auto;
    flex: 1 1 auto;
    width: 100%;
    min-height: clamp(160px, 26svh, 300px);
    margin-top: clamp(1.75rem, 4vh, 2.75rem);
  }

  .hero__mockup {
    position: absolute;
    top: 0;
    left: 50%;
    width: min(430px, 96vw);
    translate: -50% -4%;
  }

  /* Transposed: instead of five separate label-plus-pair blocks stacked down
     the page, the table becomes two columns read top to bottom. Dropping the
     repeated row labels is what makes it fit one screen. display: contents
     on the table rows hands the cells straight to this grid, and they
     auto-place into the two columns in DOM order. */
  .versus {
    min-height: 100svh;
    padding-block: clamp(3.25rem, 7.5vh, 5rem);
  }

  .versus__head {
    grid-template-columns: 1fr;
    gap: 0.9rem;
    align-items: start;
  }

  .versus__head h2 {
    max-width: 15ch;
    font-size: clamp(1.85rem, 7.6vw, 2.4rem);
  }

  .versus__head .lede {
    font-size: 1rem;
    line-height: 1.55;
  }

  .matrix {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 0.6rem;
    margin-top: clamp(1.75rem, 4vh, 2.5rem);
  }

  .matrix thead,
  .matrix tbody,
  .matrix tr {
    display: contents;
  }

  /* The spacer cell in the head row has nothing to say. */
  .matrix thead td {
    display: none;
  }

  /* The row labels come out of the grid rather than out of the document:
     absolute positioning takes them off the flow, so a screen reader still
     hears which pair it is in. */
  .matrix tbody th {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .matrix th,
  .matrix td {
    padding: 0.7rem 0.55rem 0.7rem 0;
    border: 0;
  }

  /* Matches the padding the card carries, so the two column headings sit on
     one line rather than the left one riding higher. */
  .matrix thead th {
    padding-top: 1rem;
    padding-bottom: 0.9rem;
    font-size: 0.98rem;
    line-height: 1.3;
  }

  .matrix tbody td {
    font-size: 0.88rem;
    line-height: 1.42;
    letter-spacing: -0.014em;
  }

  /* Hairlines run between the pairs, not around every cell. */
  .matrix tbody tr + tr td {
    border-top: 1px solid var(--line);
  }

  .matrix tbody tr:first-child td {
    border-top: 1px solid var(--line-strong);
  }

  /* One continuous card down the second column, as on desktop. */
  .matrix .matrix__us {
    padding-inline: 0.85rem;
  }

  .matrix tbody .matrix__us {
    border-top-color: rgba(15, 20, 24, 0.09);
  }

  .matrix tbody tr:last-child .matrix__us {
    padding-bottom: 1.2rem;
    border-radius: 0 0 14px 14px;
  }

  /* Stacked: the render pins to the top of the screen and one step of text
     sits under it, swapping as you scroll.

     Both live in a single sticky flex column rather than two sticky boxes
     whose heights are tuned not to collide. The text takes the height it
     needs, the render gets everything that is left, and overlap is not
     possible at any viewport height. */
  .workflow__title {
    max-width: 14ch;
    margin-bottom: clamp(1.5rem, 4vh, 2.5rem);
  }

  .workflow__layout {
    position: relative;
    display: block;
    gap: 0;
    padding-bottom: 0;
    min-height: 320svh;
  }

  .workflow__pane {
    position: sticky;
    top: var(--nav-height);
    height: calc(100svh - var(--nav-height));
    display: flex;
    flex-direction: column;
    padding-bottom: clamp(1.75rem, 5vh, 3rem);
  }

  .workflow__stage {
    position: static;
    flex: 1 1 auto;
    min-height: 0;
    height: auto;
    margin-inline: 0;
    padding-inline: 0;
    background: none;
  }

  .workflow__stage::after {
    display: none;
  }

  /* The row has to be a definite size, otherwise height: 100% on the render
     resolves against its own intrinsic height and does nothing. */
  .workflow__visual {
    min-height: 0;
    height: 100%;
    grid-template-rows: minmax(0, 1fr);
    grid-template-columns: minmax(0, 1fr);
  }

  /* Sized off the available height instead of the width, so the render grows
     into whatever the text leaves behind. */
  .workflow__mockup {
    width: auto;
    height: 100%;
    /* Stops just short of filling the space, so the render has air around it
       and does not run into the progress bar. */
    max-height: 86%;
    max-width: 100%;
    justify-self: center;
    align-self: center;
  }

  .workflow__glow {
    width: min(90%, 300px);
  }

  /* relative, not static: the progress bar is drawn with this element's own
     pseudo-elements, and they would otherwise anchor to the layout. */
  .workflow__steps {
    position: relative;
    flex: 0 0 auto;
    display: grid;
    height: auto;
    padding: 1.5rem 0 0;
  }

  /* All three steps share one grid cell: the block is as tall as the tallest
     of them and they cross-fade in place. */
  /* Staggered rather than a straight cross-fade: the outgoing step clears in
     180ms and the incoming one only starts after 150ms, so the two are never
     both legible on top of each other. */
  .workflow-step {
    grid-area: 1 / 1;
    min-height: 0;
    align-content: start;
    opacity: 0;
    translate: 0 14px;
    pointer-events: none;
    transition: opacity 180ms var(--ease-soft), translate 420ms var(--ease);
  }

  .workflow-step::before {
    display: none;
  }

  .workflow-step[data-state="past"] {
    opacity: 0;
    translate: 0 -14px;
  }

  .workflow-step[data-state="current"] {
    opacity: 1;
    translate: 0 0;
    pointer-events: auto;
    transition: opacity 320ms var(--ease-soft) 150ms,
      translate 520ms var(--ease) 90ms;
  }

  .workflow-step h3 {
    font-size: clamp(1.85rem, 8vw, 2.35rem);
  }

  .workflow-step p {
    max-width: none;
    margin-top: 0.7rem;
    font-size: 1rem;
  }

  /* The vertical rail becomes a horizontal one above the text. */
  .workflow__steps::before,
  .workflow__steps::after {
    width: 100%;
    height: 2px;
    border-radius: 2px;
  }

  .workflow__steps::after {
    width: calc(var(--progress, 0) * 100%);
    height: 2px;
    background: var(--accent);
  }

  .details__layout,
  .privacy__layout {
    grid-template-columns: 1fr;
    gap: 2.5rem;
  }

  .details h2 {
    position: static;
  }

  .detail-row {
    grid-template-columns: 1fr;
    gap: 0.5rem;
  }

  .footer__grid {
    grid-template-columns: 1fr;
  }

  .footer__links {
    justify-content: flex-start;
  }
}

@media (max-width: 520px) {
  .matrix tbody td {
    font-size: 0.9rem;
    letter-spacing: -0.016em;
  }

  .hero__actions {
    align-items: stretch;
    flex-direction: column;
  }

  .hero__actions .btn {
    width: 100%;
  }

  .hero__actions .text-link {
    justify-content: center;
  }

  .footer__bottom {
    flex-direction: column;
  }
}

/* ==========================================================================
   Reduced motion
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
    transition-duration: 0.01ms !important;
  }

  [data-reveal="on"] .reveal {
    opacity: 1;
    translate: none;
  }

  /* The blanket rule above would collapse this to its end frame and hold it
     there, off its resting position. Better to never start it. */
  .hero__mockup {
    animation: none;
  }
}
