/* The landing, in SIGNAL.
 *
 * Replaces `nocturne.css`, which was the cyan-and-Geist identity the app left
 * behind on 2026-09-09. Tokens come from `tokens.css`, which is generated from
 * `DESIGN.md`; nothing here invents a colour.
 *
 * ---------------------------------------------------------------------------
 * Dials, declared once and held to the last section:
 * ENERGY 2, RHYTHM 3, MOTION 1.
 *
 * ENERGY 2 because this sells a product to people who already have the problem,
 * not a portfolio to an awards jury. RHYTHM 3 because uniform section rhythm is
 * exactly what was wrong with the old page: every section was kicker, heading,
 * lede, card grid, so eight sections read as one. MOTION 1 because the whole
 * app ships one deliberate animation, and a landing that moves more than the
 * product is a promise the product does not keep.
 *
 * The motif, repeated and specific: the bevelled top-right corner. It is
 * SIGNAL's signature in the app, so the page it advertises wears the same cut.
 * Everything that is a surface has it; nothing else does.
 *
 * The accent is spent once: violet fills the download button and nothing else
 * on the page. Cyan marks figures and never an action. That is the system's own
 * rule, and it is the reason the button is findable without being loud.
 * ------------------------------------------------------------------------- */

@font-face {
  font-family: "Unbounded";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("/fonts/unbounded-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Unbounded";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("/fonts/unbounded-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Unbounded";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("/fonts/unbounded-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Wix Madefor Text";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("/fonts/madefor-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Wix Madefor Text";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("/fonts/madefor-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Wix Madefor Text";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("/fonts/madefor-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Martian Mono";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/fonts/martian-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Martian Mono";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/fonts/martian-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Martian Mono";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/fonts/martian-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ── ground ─────────────────────────────────────────────────────────────── */

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

html {
  scroll-behavior: smooth;
  /* The header is sticky, so an anchor that lands flush lands underneath it. */
  scroll-padding-top: 84px;
  color-scheme: dark;
}
:root[data-theme="light"] {
  color-scheme: light;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  background: var(--c-ground);
  color: var(--c-ink);
  font-family: "Wix Madefor Text", system-ui, -apple-system, sans-serif;
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* `height: auto` is not optional here: every picture on this page carries its
   natural `width` and `height` as attributes, which is what stops the layout
   jumping when it loads. Without this the attribute wins on one axis and the
   cap wins on the other, and a 1272x820 screenshot renders 600x820. */
img,
video {
  max-width: 100%;
  height: auto;
  display: block;
}

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

/* One ring for the whole page, drawn once rather than remembered per control.
   Never removed: a landing that cannot be tabbed is a landing half its readers
   cannot use. */
:focus-visible {
  outline: 2px solid var(--c-violet-ink);
  outline-offset: 2px;
}

.wrap {
  width: 100%;
  max-width: 1180px;
  margin: 0 auto;
  padding-inline: 24px;
}

/* **The motif.** A cut top-right corner, and only there. `corner-shape` makes
   it a true bevel where the browser has it; everywhere else the corner is
   square, which is the same language spoken plainly rather than a rounded
   corner contradicting it. */
.cut {
  border-radius: 0 var(--r-chamfer-md) 0 0;
  corner-shape: bevel;
}
.cut-sm {
  border-radius: 0 var(--r-chamfer-sm) 0 0;
  corner-shape: bevel;
}
.cut-lg {
  border-radius: 0 var(--r-chamfer-lg) 0 0;
  corner-shape: bevel;
}

/* ── type ───────────────────────────────────────────────────────────────── */

h1,
h2,
h3 {
  font-family: "Unbounded", "Wix Madefor Text", system-ui, sans-serif;
  margin: 0;
  text-wrap: balance;
}

/* Міжрядок більший за одиницю, і це не смак. В Unbounded виносні літери
   виходять за межу рядкового боксу, тож при 0.9 хвіст «y» з одного рядка
   лягає на «b» наступного. Українською це майже не видно, бо рядки короткі;
   англійською, німецькою та французькою заголовок переходить у два-три
   рядки, і вони злипались. Значення підібрані так, щоб виносні розходились
   на будь-якій з одинадцяти мов. */
h1 {
  font-size: clamp(44px, 8.2vw, 96px);
  font-weight: 800;
  line-height: 1.02;
  letter-spacing: -0.05em;
}

h2 {
  font-size: clamp(28px, 4vw, 40px);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.04em;
}

h3 {
  font-size: 22px;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.02em;
  font-family: "Wix Madefor Text", system-ui, sans-serif;
}

p {
  margin: 0;
}

/* Uppercase with tracking is the one place this page uses it, and it is a
   label rather than a heading: the mono face and 11px say "this is machine
   text about the section", which is what SIGNAL's labels are for. */
.kicker {
  font-family: "Martian Mono", ui-monospace, monospace;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  color: var(--c-ink-faint);
  margin: 0;
}

.lede {
  font-size: clamp(16px, 1.6vw, 19px);
  color: var(--c-ink-muted);
  max-width: 58ch;
  text-wrap: pretty;
}

.fine {
  font-size: 13px;
  color: var(--c-ink-faint);
}

/* Figures. Cyan marks data and never an action; this is the only class that
   carries it, so the rule cannot leak into a button. */
.figure {
  font-family: "Martian Mono", ui-monospace, monospace;
  color: var(--c-mint);
  font-variant-numeric: tabular-nums;
}

/* ── controls ───────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 40px;
  padding: 0 18px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--c-ink);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  border-radius: 0 var(--r-chamfer-sm) 0 0;
  corner-shape: bevel;
  transition:
    background-color 120ms ease,
    border-color 120ms ease,
    color 120ms ease,
    translate 120ms ease;
}
/* One pixel down on press. It is the whole of the system's feedback on a
   control in the app, so it is the whole of it here. */
.btn:active {
  translate: 0 1px;
}

/* The page's single filled action. Violet is spent here and nowhere else. */
.btn-primary {
  background: var(--c-violet);
  border-color: var(--c-violet);
  color: var(--c-violet-on);
}
.btn-primary:hover {
  background: var(--c-violet-hi);
  border-color: var(--c-violet-hi);
}
.btn-primary:active {
  background: var(--c-violet-lo);
  border-color: var(--c-violet-lo);
}

.btn-secondary {
  border-color: var(--c-line);
  color: var(--c-ink);
}
.btn-secondary:hover {
  border-color: var(--c-line-strong);
  background: var(--c-plate-2);
}

.btn-block {
  width: 100%;
}

.input {
  width: 100%;
  height: 42px;
  padding: 0 12px;
  background: var(--c-plate-2);
  border: 1px solid var(--c-line);
  color: var(--c-ink);
  font: inherit;
  font-size: 14px;
  border-radius: 0 var(--r-chamfer-sm) 0 0;
  corner-shape: bevel;
}
.input::placeholder {
  color: var(--c-ink-faint);
}
.input:focus {
  border-color: var(--c-violet);
  outline: none;
}

.field label {
  display: block;
  margin-bottom: 6px;
  font-family: "Martian Mono", ui-monospace, monospace;
  font-size: 11px;
  text-transform: uppercase;
  color: var(--c-ink-faint);
}

/* ── the mark, the first line of the hero ──────────────────────────────────
 *
 * The wordmark, not the sentence: `.brand` in the bar already says "Hrateka"
 * at reading size and stays in the reader's language. This is the same name
 * as a title card - always Latin, because a logotype does not translate any
 * more than a Nike swoosh does.
 *
 * **It is the hero's focal point, and the h1 is its caption.** Two display
 * sizes stacked (190px word over a 96px headline) had no winner, so the eye
 * bounced between them. The headline below is sized down to read as what the
 * word means, and sits one step of the spacing scale under it, not a screen.
 *
 * **The glitch is SIGNAL's own**, ported from `apps/theme/theme.css` rather
 * than invented for this page: same three bursts, same violet/ice split, same
 * bound - it runs once and ends. The app fires it on a five-second hover,
 * which a one-time visitor to a landing page will not sit through; here it
 * fires once, shortly after paint, so the moment is not missed. */
.mark-word {
  display: block;
  margin-bottom: clamp(28px, 4vw, 48px);
  font-family: "Unbounded", system-ui, sans-serif;
  font-weight: 800;
  font-size: clamp(52px, 13vw, 190px);
  line-height: 0.86;
  letter-spacing: -0.04em;
  color: var(--c-ink);
}
@keyframes signal-glitch {
  0%,
  24%,
  38%,
  52%,
  74%,
  100% {
    transform: none;
    filter: none;
    clip-path: none;
  }
  26% {
    transform: translate3d(-2px, 0, 0) skewX(-4deg);
    filter: drop-shadow(2px 0 0 var(--c-violet)) drop-shadow(-2px 0 0 var(--c-ice));
  }
  30% {
    transform: translate3d(3px, 0, 0) skewX(3deg);
    filter: drop-shadow(-3px 0 0 var(--c-violet)) drop-shadow(2px 0 0 var(--c-ice));
  }
  34% {
    transform: translate3d(-1px, 1px, 0);
    filter: drop-shadow(1px 0 0 var(--c-ice));
  }
  40% {
    transform: translate3d(4px, 0, 0);
    clip-path: inset(38% 0 42% 0);
    filter: drop-shadow(-3px 0 0 var(--c-violet));
  }
  44% {
    transform: translate3d(-4px, 0, 0);
    clip-path: inset(12% 0 68% 0);
    filter: drop-shadow(3px 0 0 var(--c-ice));
  }
  48% {
    transform: translate3d(2px, 0, 0);
    clip-path: inset(70% 0 8% 0);
  }
  56% {
    transform: translate3d(-2px, 0, 0);
    filter: drop-shadow(2px 0 0 var(--c-violet)) drop-shadow(-1px 0 0 var(--c-ice));
  }
  62% {
    transform: translate3d(1px, 0, 0) skewX(-2deg);
    filter: drop-shadow(-1px 0 0 var(--c-ice));
  }
}
.mark-word {
  animation: signal-glitch 640ms linear 900ms 1;
}
@media (prefers-reduced-motion: reduce) {
  .mark-word {
    animation: none;
  }
}

/* ── header ─────────────────────────────────────────────────────────────── */

.bar {
  position: sticky;
  top: 0;
  z-index: 40;
  background: color-mix(in srgb, var(--c-ground) 88%, transparent);
  /* The one blurred surface on the page. It earns it: content scrolls under a
     bar that has to stay legible over a wall of cover art. Nothing else is
     glass, which is what keeps this readable as a layer rather than a style. */
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--c-line-soft);
}
.bar .wrap {
  display: flex;
  align-items: center;
  gap: 20px;
  height: 64px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: "Unbounded", system-ui, sans-serif;
  font-weight: 700;
  font-size: 16px;
  letter-spacing: -0.03em;
  color: var(--c-ink);
  text-decoration: none;
}

.bar nav {
  display: flex;
  gap: 22px;
  margin-left: 12px;
}
.bar nav a {
  color: var(--c-ink-muted);
  text-decoration: none;
  font-size: 14px;
  transition: color 120ms ease;
}
.bar nav a:hover {
  color: var(--c-ink);
}

.bar .lang {
  position: relative;
  margin-left: auto;
}
.lang-pop {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  min-width: 190px;
  max-height: 60vh;
  overflow-y: auto;
  padding: 6px;
  background: var(--c-raised);
  border: 1px solid var(--c-line);
  border-radius: 0 var(--r-chamfer-md) 0 0;
  corner-shape: bevel;
}
.lang-pop button {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  background: transparent;
  color: var(--c-ink-muted);
  font: inherit;
  font-size: 14px;
  text-align: left;
  cursor: pointer;
}
.lang-pop button:hover,
.lang-pop button[aria-selected="true"] {
  background: var(--c-plate-2);
  color: var(--c-ink);
}
/* The two-letter code and the tick are machine labels, not prose, so they take
   the mono face and sit clear of the name instead of running into it. */
.lang-pop button .code {
  flex: none;
  width: 20px;
  font-family: "Martian Mono", ui-monospace, monospace;
  font-size: 10px;
  letter-spacing: 0.03em;
  color: var(--c-ink-faint);
}
.lang-pop button .tick {
  margin-left: auto;
  flex: none;
  width: 14px;
  text-align: center;
  font-size: 12px;
  color: var(--c-mint);
}

/* Two labels rather than one truncated: on a phone the full sentence is wider
   than the bar can give it. */
.dl-short {
  display: none;
}

/* ── hero ───────────────────────────────────────────────────────────────── */

.hero {
  padding-block: clamp(28px, 4vw, 48px) 0;
}
.hero .kicker {
  margin-bottom: 16px;
}
.hero h1 {
  max-width: 22ch;
  font-size: clamp(32px, 5vw, 64px);
  line-height: 1.06;
  letter-spacing: -0.04em;
}
/* Мовний пак дає заголовок двома рядками, і вони мають лишитись двома.
   Інлайнові спани зліплювались в один потік і рвались там, де випаде:
   українською випадало вдало, англійською «Every game you own - in one
   library.» ламалось посеред думки. */
.hero h1 span {
  display: block;
}
.hero .lede {
  margin-top: 22px;
}
.hero-act {
  margin-top: 32px;
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}
.hero-note {
  font-size: 13.5px;
  color: var(--c-ink-faint);
}

/* The product shot is the hero image. There is no glow behind it and no
   gradient over it: the screen is the argument, and anything laid on top of it
   is an admission that it is not. */
.hero-shot {
  margin: clamp(40px, 6vw, 72px) 0 0;
  border: 1px solid var(--c-line);
  border-radius: 0 var(--r-chamfer-lg) 0 0;
  corner-shape: bevel;
  overflow: hidden;
  background: var(--c-plate);
}
.hero-shot video,
.hero-shot img {
  width: 100%;
  height: auto;
}
.shot-cap {
  margin: 12px 2px 0;
  font-size: 13px;
  color: var(--c-ink-faint);
}

/* ── the band ───────────────────────────────────────────────────────────── */

/* Three short claims, plain text on a rule rather than three cards - the
   grid this page already spends on `.statements` further down, kept to a
   single row here so the two do not read as the same section twice. */
.band {
  border-block: 1px solid var(--c-line-soft);
}
.band .wrap {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  padding-block: 26px;
}
.band h3 {
  font-size: 15px;
  letter-spacing: -0.01em;
}
.band p {
  margin-top: 5px;
  font-size: 13px;
  color: var(--c-ink-muted);
}
@media (max-width: 760px) {
  .band .wrap {
    grid-template-columns: 1fr;
    gap: 16px;
    padding-block: 20px;
  }
}

/* ── the six things, as a list rather than a second card grid ─────────────
 * `.statements` already owns the card-free list further down; this one stays
 * single-column, inside the split's own text column, so "why" keeps its own
 * composition instead of borrowing privacy's. */
.why-list {
  list-style: none;
  margin: 28px 0 0;
  padding: 0;
  display: grid;
  gap: 15px;
}
.why-list li {
  padding-top: 15px;
  border-top: 1px solid var(--c-line-soft);
}
.why-list li:first-child {
  padding-top: 0;
  border-top: 0;
}
.why-list b {
  display: block;
  font-size: 14.5px;
  font-weight: 700;
  color: var(--c-ink);
  margin-bottom: 3px;
}
.why-list span {
  display: block;
  font-size: 13.5px;
  color: var(--c-ink-muted);
  text-wrap: pretty;
}

/* ── sections ───────────────────────────────────────────────────────────── */

section {
  padding-block: clamp(64px, 9vw, 120px);
}
section > .wrap > .kicker + h2 {
  margin-top: 14px;
}
section > .wrap > h2 + .lede {
  margin-top: 18px;
}

/* A plate: the surface every grouped thing sits on. One elevation on the
   whole page, so elevation still means something when it appears. */
.plate {
  background: var(--c-plate);
  border: 1px solid var(--c-line);
  padding: 24px;
  border-radius: 0 var(--r-chamfer-md) 0 0;
  corner-shape: bevel;
}

/* **Why it exists: the reason a shelf is one list.** Two columns, text left,
   picture right, and the picture is allowed to run past the column into the
   gutter. That asymmetry is the section's whole job: it does not look like the
   one below it. */
.split {
  display: grid;
  gap: clamp(28px, 5vw, 56px);
  align-items: center;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
}
.split-flip {
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
}
.split-flip .split-text {
  order: 2;
}
.frame {
  border: 1px solid var(--c-line);
  border-radius: 0 var(--r-chamfer-lg) 0 0;
  corner-shape: bevel;
  overflow: hidden;
  background: var(--c-plate);
}

/* ── the screens ────────────────────────────────────────────────────────── */

.tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 28px 0 20px;
}
.tabs button {
  height: 32px;
  padding: 0 13px;
  background: transparent;
  border: 1px solid var(--c-line);
  color: var(--c-ink-muted);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
  border-radius: 0 var(--r-chamfer-sm) 0 0;
  corner-shape: bevel;
  transition:
    border-color 120ms ease,
    color 120ms ease;
}
.tabs button:hover {
  border-color: var(--c-line-strong);
  color: var(--c-ink);
}
/* The chosen tab is marked by the accent's *edge*, not its fill: the fill is
   the download button's, and spending it twice would make neither read as the
   thing to press. */
.tabs button[aria-selected="true"] {
  border-color: var(--c-violet);
  color: var(--c-ink);
}

/* ── statements ─────────────────────────────────────────────────────────── */

/* Privacy is a list of promises, and a promise reads worse inside a card: the
   card makes it look like a feature. Plain rules, generous measure, nothing
   between the reader and the sentence. */
.statements {
  margin: 34px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0;
}
.statements li {
  border-top: 1px solid var(--c-line-soft);
  padding-block: 22px;
  display: grid;
  gap: 6px 32px;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.4fr);
}
.statements li:last-child {
  border-bottom: 1px solid var(--c-line-soft);
}
.statements dt {
  font-weight: 700;
  font-size: 17px;
  letter-spacing: -0.01em;
}
.statements dd {
  margin: 0;
  color: var(--c-ink-muted);
  text-wrap: pretty;
}

/* ── the ask ────────────────────────────────────────────────────────────── */

.get {
  padding-block: clamp(72px, 10vw, 128px);
  border-top: 1px solid var(--c-line-soft);
}
.get .lede {
  margin-top: 18px;
}
.get-form {
  display: flex;
  gap: 10px;
  align-items: flex-end;
  margin-top: 28px;
  max-width: 460px;
}
.get-form .field {
  flex: 1;
  min-width: 0;
}

/* ── footer ─────────────────────────────────────────────────────────────── */

footer {
  border-top: 1px solid var(--c-line-soft);
  padding-block: 28px;
  font-size: 13.5px;
  color: var(--c-ink-faint);
}
footer .wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 22px;
}
.foot-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 18px;
  margin-left: auto;
}
footer a {
  color: var(--c-ink-faint);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
footer a:hover {
  color: var(--c-ink);
}

/* ── the sheet ──────────────────────────────────────────────────────────── */

.scrim {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: none;
  place-items: center;
  padding: 20px;
  background: color-mix(in srgb, var(--c-ground) 78%, transparent);
  backdrop-filter: blur(3px);
}
.scrim.open {
  display: grid;
}
.sheet {
  position: relative;
  width: 100%;
  max-width: 440px;
  background: var(--c-plate);
  border: 1px solid var(--c-line);
  padding: 28px;
  border-radius: 0 var(--r-chamfer-lg) 0 0;
  corner-shape: bevel;
}
.sheet h3 {
  margin-bottom: 10px;
}
.sheet p {
  color: var(--c-ink-muted);
  font-size: 14.5px;
}
.sheet .field {
  margin-top: 18px;
}
.sheet form .btn {
  margin-top: 14px;
}
.sheet .fine {
  margin-top: 12px;
}
.sheet .x {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  background: transparent;
  border: 0;
  color: var(--c-ink-faint);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}
.sheet .x:hover {
  color: var(--c-ink);
}
.step {
  display: none;
}
.step.show {
  display: block;
}
.opts {
  display: flex;
  gap: 8px;
  margin-top: 18px;
}
.opts.stack {
  flex-direction: column;
}
.opts button {
  flex: 1;
  min-height: 44px;
  padding: 10px 14px;
  background: transparent;
  border: 1px solid var(--c-line);
  color: var(--c-ink);
  font: inherit;
  font-size: 14px;
  text-align: left;
  cursor: pointer;
  border-radius: 0 var(--r-chamfer-sm) 0 0;
  corner-shape: bevel;
  transition:
    border-color 120ms ease,
    background-color 120ms ease;
}
.opts:not(.stack) button {
  text-align: center;
}
.opts button:hover {
  border-color: var(--c-violet);
  background: var(--c-violet-wash);
}

/* The last step of the sheet: the survey is over and the only thing left to
   say is thank you. Cyan, because this is the one moment on the page that is
   a reading rather than an action. */
.thanks {
  text-align: center;
  padding-block: 8px;
}
.thanks .mk {
  width: 44px;
  height: 44px;
  margin: 0 auto 14px;
  display: grid;
  place-items: center;
  font-size: 20px;
  color: var(--c-signal-on);
  background: var(--c-mint);
  border-radius: 0 var(--r-chamfer-sm) 0 0;
  corner-shape: bevel;
}

/* ── narrow ─────────────────────────────────────────────────────────────── */

@media (max-width: 900px) {
  .split,
  .split-flip {
    grid-template-columns: minmax(0, 1fr);
  }
  .split-flip .split-text {
    order: 0;
  }
  .statements li {
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
  }
}

@media (max-width: 760px) {
  .bar nav {
    display: none;
  }
  .dl-long {
    display: none;
  }
  .dl-short {
    display: inline;
  }
  .bar .wrap {
    gap: 10px;
  }
  .wrap {
    padding-inline: 18px;
  }
  .get-form {
    flex-direction: column;
    align-items: stretch;
  }
  .get-form .btn {
    width: 100%;
  }

  /* **44px, because a finger is not a cursor.** The tabs are 32px on a desktop
     where they are clicked and 44 here where they are tapped, and the footer's
     links get the height from padding rather than from a box, so the rule they
     sit on does not move. Both were under the minimum until the page was
     actually measured at 390px. */
  .tabs button {
    height: 44px;
    padding-inline: 16px;
  }
  /* The design system's button is 40px, which is a click. A tap is 44, and
     the four pixels are the whole reason this block exists. */
  .btn {
    height: 44px;
  }
  .brand {
    min-height: 44px;
  }
  .foot-links a,
  footer > .wrap > span {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
  .foot-links {
    gap: 6px 18px;
  }
}

/* **The bar has three things and a phone has room for two and a half.**
   At 375px the language button's full name pushed the download button past
   the right edge, and the page scrolled sideways. The globe and the label the
   button already carries say the same thing in a third of the width. */
@media (max-width: 480px) {
  #langcur {
    display: none;
  }
  .bar .lang .btn {
    padding-inline: 10px;
  }
  .brand span {
    display: none;
  }
}

/* ── motion, raised to 2 ────────────────────────────────────────────────────
 * The owner asked for the page to move (2026-09-26), so MOTION goes from 1 to
 * 2 - and only in the two ways that cannot hide the page:
 *
 * 1. The hero arrives once, in order: the two lines of the headline, the
 *    button, the screenshot. `both`, so the first frame is already the start
 *    and nothing flashes in.
 * 2. Sections rise into place as they scroll in - driven by the scroll itself
 *    (`animation-timeline: view()`), not by an observer. Twice an observer did
 *    not fire here and left whole sections at opacity 0; a scroll timeline has
 *    no callback to miss, and a browser without it draws the page as before.
 *
 * `t-heavy` and `ease-heavy`, because these are the biggest things on screen.
 * Reduced motion turns all of it off through the rule at the top. */
@keyframes land-rise {
  from {
    opacity: 0;
    transform: translateY(16px);
  }
}
.hero h1 > span,
.hero .lede,
.hero-act,
.hero-shot {
  animation: land-rise 640ms cubic-bezier(0.215, 0.61, 0.355, 1) both;
}
.hero h1 > span + span { animation-delay: 90ms; }
.hero .lede { animation-delay: 160ms; }
.hero-act { animation-delay: 220ms; }
.hero-shot { animation-delay: 300ms; }

@supports (animation-timeline: view()) {
  section .kicker,
  section h2,
  section .lede,
  section .frame,
  .why-list > li,
  .statements > *,
  .get .wrap > * {
    animation: land-rise linear both;
    animation-timeline: view();
    animation-range: entry 0% entry 70%;
  }
}
@media (prefers-reduced-motion: reduce) {
  .hero h1 > span,
  .hero .lede,
  .hero-act,
  .hero-shot,
  section .kicker,
  section h2,
  section .lede,
  section .frame,
  .why-list > li,
  .statements > *,
  .get .wrap > * {
    animation: none !important;
  }
}
