/*
  shuffl: one stylesheet for every page.

  The same design language as the app: flat neutral greys, one violet for the
  thing you came to press, generous rounding, SF Pro Rounded, and the Icons8
  Puffy Filled icons. Depth comes from one surface sitting on another, never
  from a border. The violet panels are the one place colour fills an area, the
  way the violet card back fills a card.
*/

/* Nunito, served from this site, for every browser that cannot reach Apple's
   rounded system face. Safari picks up SF Pro Rounded through ui-rounded and
   never downloads these. OFL, licence beside the files. */
@font-face {
  font-family: "Nunito";
  font-style: normal;
  font-weight: 200 1000;
  font-display: swap;
  src: url("/assets/fonts/nunito-vietnamese-wght-normal.woff2") format("woff2-variations");
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: "Nunito";
  font-style: normal;
  font-weight: 200 1000;
  font-display: swap;
  src: url("/assets/fonts/nunito-latin-ext-wght-normal.woff2") format("woff2-variations");
  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: "Nunito";
  font-style: normal;
  font-weight: 200 1000;
  font-display: swap;
  src: url("/assets/fonts/nunito-latin-wght-normal.woff2") format("woff2-variations");
  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;
}

:root {
  --bg: #121315;
  --surface: #1a1b1e;
  --raised: #232528;
  --raised-high: #2d2f33;
  --label: #f2f3f4;
  --secondary: #a0a3a8;
  --tertiary: #8a8d92;
  --divider: rgba(255, 255, 255, 0.07);

  --violet: #4729ab;
  --violet-hi: #5534c4;
  --violet-ink: #b9a7e6;
  --on-violet: #ffffff;
  --paper: #ffffff;
  --ink: #141517;

  --radius-sm: 16px;
  --radius: 28px;
  --radius-lg: 40px;

  --font: ui-rounded, "SF Pro Rounded", "Nunito", "Varela Round", system-ui,
    -apple-system, "Segoe UI", Roboto, sans-serif;

  --spring: cubic-bezier(0.34, 1.4, 0.64, 1);
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --shadow-card: 0 18px 40px -12px rgba(0, 0, 0, 0.55), 0 4px 10px -4px rgba(0, 0, 0, 0.4);
  --shadow-float: 0 30px 60px -18px rgba(12, 6, 40, 0.55), 0 8px 18px -8px rgba(12, 6, 40, 0.45);

  --wrap: 1160px;
  --gutter: clamp(16px, 4vw, 32px);

  color-scheme: dark;
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 88px;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--label);
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

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

a {
  color: inherit;
}

:focus-visible {
  outline: 3px solid var(--violet-ink);
  outline-offset: 3px;
  border-radius: 10px;
}

.skip {
  position: absolute;
  left: 16px;
  top: -60px;
  z-index: 100;
  padding: 10px 16px;
  border-radius: 999px;
  background: var(--paper);
  color: var(--ink);
  font-weight: 700;
  text-decoration: none;
  transition: top 0.2s var(--ease-out);
}
.skip:focus {
  top: 16px;
}

.wrap {
  width: 100%;
  max-width: calc(var(--wrap) + var(--gutter) * 2);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ---------------------------------------------------------------- Icons */

/* The icons are black shapes on transparency, the way the app imports them as
   template images, so they take whatever colour they are given. */
.icon {
  display: inline-block;
  flex: none;
  width: var(--size, 22px);
  height: var(--size, 22px);
  background: currentColor;
  -webkit-mask: var(--src) center / contain no-repeat;
  mask: var(--src) center / contain no-repeat;
}

.mark {
  display: inline-block;
  flex: none;
  height: var(--size, 26px);
  aspect-ratio: 212 / 180;
  background: currentColor;
  -webkit-mask: url("/assets/mark.png") center / contain no-repeat;
  mask: url("/assets/mark.png") center / contain no-repeat;
}

/* --------------------------------------------------------- Progressive blur */

/* Content softens as it reaches the top and bottom of the window, the way it
   dissolves into the chrome in the app. Eight stacked blur layers, each masked
   to its own band, so the radius climbs smoothly across the whole band rather
   than arriving as a step. No tint on any of them: a tinted layer compounds
   and reads as fog, where this should read as focus falling away. */
.edge {
  position: fixed;
  left: 0;
  right: 0;
  z-index: 40;
  pointer-events: none;
}
.edge--top {
  top: 0;
  height: 112px;
}
.edge--bottom {
  bottom: 0;
  height: 52px;
  transition: opacity 0.4s;
}
/* The footer melts its own name into the bottom edge. The window's band on top
   of that would blur it twice, which on a phone is most of the word. */
.at-end .edge--bottom {
  opacity: 0;
}
:is(.edge, .melt, .arch__edge) > i {
  position: absolute;
  inset: 0;
  -webkit-backdrop-filter: blur(var(--b));
  backdrop-filter: blur(var(--b));
  -webkit-mask-image: linear-gradient(var(--dir), transparent var(--a), #000 var(--c), #000 var(--d), transparent var(--e));
  mask-image: linear-gradient(var(--dir), transparent var(--a), #000 var(--c), #000 var(--d), transparent var(--e));
}
.edge--top > i { --dir: to top; }
.edge--bottom > i { --dir: to bottom; }
:is(.edge, .melt, .arch__edge) > i:nth-child(1) { --b: 0.5px; --a: 0%; --c: 12.5%; --d: 25%; --e: 37.5%; }
:is(.edge, .melt, .arch__edge) > i:nth-child(2) { --b: 1px; --a: 12.5%; --c: 25%; --d: 37.5%; --e: 50%; }
:is(.edge, .melt, .arch__edge) > i:nth-child(3) { --b: 2px; --a: 25%; --c: 37.5%; --d: 50%; --e: 62.5%; }
:is(.edge, .melt, .arch__edge) > i:nth-child(4) { --b: 4px; --a: 37.5%; --c: 50%; --d: 62.5%; --e: 75%; }
:is(.edge, .melt, .arch__edge) > i:nth-child(5) { --b: 8px; --a: 50%; --c: 62.5%; --d: 75%; --e: 87.5%; }
:is(.edge, .melt, .arch__edge) > i:nth-child(6) { --b: 16px; --a: 62.5%; --c: 75%; --d: 87.5%; --e: 100%; }
:is(.edge, .melt, .arch__edge) > i:nth-child(7) { --b: 32px; --a: 75%; --c: 87.5%; --d: 100%; --e: 101%; }
:is(.edge, .melt, .arch__edge) > i:nth-child(8) { --b: 48px; --a: 87.5%; --c: 100%; --d: 100%; --e: 101%; }

/* The fade sits well clear of the blur: content is already soft before it
   starts to go, and it finishes past the window's edge rather than leaving a
   clean strip of background above the blur. */
.edge--top::after {
  content: "";
  position: absolute;
  inset: 0 0 30% 0;
  background: linear-gradient(to bottom, rgba(18, 19, 21, 0.9) 0%, rgba(18, 19, 21, 0.62) 55%, rgba(18, 19, 21, 0));
}

/* ------------------------------------------------------------------- Nav */

.nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
}
.nav__inner {
  display: flex;
  align-items: center;
  gap: 24px;
  height: 72px;
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  color: var(--label);
  text-decoration: none;
  font-weight: 900;
  font-size: 25px;
  letter-spacing: -0.02em;
}
.brand .mark {
  --size: 25px;
}
.nav__links {
  display: flex;
  gap: 4px;
  margin-left: auto;
}
.nav__links a {
  padding: 9px 14px;
  border-radius: 999px;
  color: var(--secondary);
  font-weight: 600;
  font-size: 15px;
  text-decoration: none;
  transition: color 0.2s, background-color 0.2s;
}
.nav__links a:hover {
  color: var(--label);
  background: rgba(255, 255, 255, 0.06);
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  min-height: 48px;
  padding: 0 22px;
  border: 0;
  border-radius: 999px;
  font: inherit;
  font-weight: 800;
  font-size: 16px;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: transform 0.35s var(--spring), background-color 0.2s, opacity 0.2s;
  touch-action: manipulation;
}
.btn:active {
  transform: scale(0.96);
}
.btn--violet {
  background: var(--violet);
  color: var(--on-violet);
}
.btn--violet:hover {
  background: var(--violet-hi);
}
.btn--paper {
  background: var(--paper);
  color: var(--ink);
}
.btn--paper:hover {
  transform: translateY(-2px);
}
.btn--ghost {
  background: rgba(255, 255, 255, 0.14);
  color: var(--on-violet);
}
.btn--ghost:hover {
  background: rgba(255, 255, 255, 0.22);
}
.btn--quiet {
  background: var(--raised);
  color: var(--label);
}
.btn--quiet:hover {
  background: var(--raised-high);
}
.btn .icon {
  --size: 18px;
}
.nav .btn {
  min-height: 42px;
  padding: 0 18px;
  font-size: 15px;
}
.soon {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  line-height: 1.1;
}
.soon small {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.6;
}

@media (max-width: 760px) {
  .nav__links {
    display: none;
  }
  .nav .btn {
    margin-left: auto;
  }
}

/* ------------------------------------------------------------ Type bits */

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 14px 7px 10px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.14);
  font-size: 14px;
  font-weight: 700;
}
.eyebrow .icon {
  --size: 18px;
}

.kicker {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 14px;
  color: var(--secondary);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.kicker .icon {
  --size: 17px;
}

.h-display {
  margin: 0;
  font-weight: 900;
  font-size: clamp(54px, 8.4vw, 108px);
  line-height: 0.92;
  letter-spacing: -0.035em;
}
.h-section {
  margin: 0;
  font-weight: 900;
  font-size: clamp(38px, 5.4vw, 68px);
  line-height: 0.98;
  letter-spacing: -0.03em;
}
.h-card {
  margin: 0;
  font-weight: 800;
  font-size: 24px;
  line-height: 1.15;
  letter-spacing: -0.01em;
}
.lead {
  margin: 0;
  color: var(--secondary);
  font-size: clamp(18px, 1.6vw, 20px);
  line-height: 1.55;
  max-width: 34em;
}

/* --------------------------------------------------------------- Layout */

main {
  padding-top: 88px;
}
/* Top only: these sit on `.wrap`, whose sides carry the gutter. */
.section {
  padding-top: clamp(72px, 10vw, 128px);
}
.section__head {
  display: grid;
  gap: 18px;
  margin-bottom: clamp(32px, 4vw, 48px);
  max-width: 760px;
}

.surface {
  background: var(--surface);
  border-radius: var(--radius-lg);
}

/* ----------------------------------------------------------------- Hero */

.hero__panel {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 640px;
  padding: clamp(40px, 7vw, 88px) clamp(20px, 6vw, 72px);
  border-radius: 48px;
  background: var(--violet);
  color: var(--on-violet);
  text-align: center;
  overflow: hidden;
  isolation: isolate;
}
.hero__copy {
  position: relative;
  z-index: 2;
  display: grid;
  justify-items: center;
  gap: 24px;
  max-width: 760px;
}
.hero .h-display {
  font-size: clamp(50px, 8.2vw, 104px);
}
.hero__copy .lead {
  color: rgba(255, 255, 255, 0.84);
  max-width: 30em;
}
.hero__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  margin-top: 6px;
}
@media (max-width: 900px) {
  .hero__panel {
    min-height: 0;
  }
}

/* -------------------------------------------------------------- Marquee */

.marquee {
  display: grid;
  gap: 12px;
  margin-top: 28px;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 10%, #000 90%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 10%, #000 90%, transparent);
}
.marquee__row {
  display: flex;
  gap: 12px;
  width: max-content;
  animation: slide 60s linear infinite;
}
.marquee__row:nth-child(2) {
  animation-direction: reverse;
  animation-duration: 70s;
}
.marquee:hover .marquee__row {
  animation-play-state: paused;
}
@keyframes slide {
  to { transform: translateX(-50%); }
}
.pill {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 12px 20px;
  border-radius: 999px;
  background: var(--surface);
  color: var(--label);
  font-size: 17px;
  font-weight: 700;
  white-space: nowrap;
}
.pill .icon {
  --size: 17px;
  color: var(--tertiary);
}

/* ---------------------------------------------------------------- Bento */

.bento {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}
.tile {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 30px;
  border-radius: var(--radius-lg);
  background: var(--surface);
  overflow: hidden;
}
.tile p {
  margin: 0;
  color: var(--secondary);
}
.tile__step {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 13px;
  background: var(--raised-high);
  color: var(--label);
  font-weight: 900;
  font-size: 17px;
}
.tile__visual {
  flex: 1;
  display: grid;
  place-items: center;
  min-height: 210px;
  margin: 8px -30px -30px;
  padding: 24px;
  background: var(--raised);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}
@media (max-width: 900px) {
  .bento {
    grid-template-columns: 1fr;
  }
}

/* The code panel, drawn the way the room sheet draws it: one tile a letter. */
.code {
  display: flex;
  gap: 8px;
  cursor: pointer;
  border: 0;
  padding: 0;
  background: none;
  font: inherit;
  color: inherit;
}
.code b {
  display: grid;
  place-items: center;
  width: 56px;
  height: 68px;
  border-radius: 20px;
  background: var(--raised-high);
  font-size: 32px;
  font-weight: 900;
  transition: transform 0.4s var(--spring), background-color 0.3s;
}
.code b.is-landing {
  transform: translateY(-6px);
  background: var(--violet);
}
.code-hint {
  margin-top: 14px;
  color: var(--tertiary);
  font-size: 13px;
  font-weight: 600;
}
/* Three tiles across leave the code less room than one tile across does. */
@media (min-width: 901px) and (max-width: 1180px) {
  .code {
    gap: 6px;
  }
  .code b {
    width: 44px;
    height: 56px;
    border-radius: 16px;
    font-size: 26px;
  }
}
@media (max-width: 400px) {
  .code b {
    width: 48px;
    height: 60px;
    font-size: 28px;
  }
}

.mini-game {
  display: grid;
  justify-items: center;
  gap: 16px;
}
.fan {
  position: relative;
  width: 150px;
  height: 120px;
}
/* Card pictures are clipped rounder than the corners printed on them, to the
   softer card the app draws. Given as a share of the card so it holds at any
   size: 16% of the width across, the same length down a 5:7 card. */
.fan img {
  border-radius: 16% / 11.4%;
}
.fan img {
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 76px;
  transform-origin: 50% 120%;
  filter: drop-shadow(0 10px 14px rgba(0, 0, 0, 0.45));
  transition: transform 0.5s var(--spring);
}
.fan img:nth-child(1) { transform: translateX(-50%) rotate(-14deg); }
.fan img:nth-child(2) { transform: translateX(-50%) rotate(0deg); }
.fan img:nth-child(3) { transform: translateX(-50%) rotate(14deg); }
.tile:hover .fan img:nth-child(1) { transform: translateX(-50%) rotate(-22deg); }
.tile:hover .fan img:nth-child(3) { transform: translateX(-50%) rotate(22deg); }

.start-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 190px;
  height: 46px;
  border-radius: 999px;
  background: var(--violet);
  color: #fff;
  font-weight: 800;
}

.table-ring {
  display: flex;
  align-items: center;
}
.table-ring img {
  width: 68px;
  height: 68px;
  margin-left: -14px;
  border-radius: 24px;
  background: var(--raised-high);
  padding: 4px;
  box-shadow: 0 0 0 5px var(--raised);
  transition: transform 0.4s var(--spring);
}
.table-ring img:first-child {
  margin-left: 0;
}
.tile:hover .table-ring img:nth-child(odd) {
  transform: translateY(-6px);
}
.table-caption {
  margin-top: 16px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--secondary);
  font-weight: 700;
  font-size: 14px;
}
.table-caption .icon {
  --size: 16px;
}

/* ---------------------------------------------------------------- Games */

.games {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
}
.game {
  display: grid;
  gap: 4px;
  padding: 22px 22px 24px;
  border-radius: var(--radius);
  background: var(--surface);
  transition: transform 0.4s var(--spring), background-color 0.2s;
}
.game:hover {
  transform: translateY(-4px);
  background: var(--raised);
}
.game .fan {
  width: 100%;
  height: 112px;
  margin-bottom: 14px;
}
.game .fan img {
  width: 64px;
}
.game strong {
  font-size: 20px;
  font-weight: 800;
}
.game span {
  color: var(--secondary);
  font-size: 14px;
  font-weight: 600;
}
.stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin-top: 16px;
}
.stat {
  padding: 26px 28px;
  border-radius: var(--radius);
  background: var(--surface);
}
.stat b {
  display: block;
  font-size: clamp(40px, 5vw, 56px);
  font-weight: 900;
  line-height: 1;
  letter-spacing: -0.03em;
}
.stat span {
  color: var(--secondary);
  font-weight: 600;
}
@media (max-width: 980px) {
  .games {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 560px) {
  .games {
    gap: 12px;
  }
  .game {
    padding: 16px 16px 18px;
  }
  .game .fan {
    height: 92px;
  }
  .game .fan img {
    width: 52px;
  }
  .stats {
    grid-template-columns: 1fr;
  }
}

/* ----------------------------------------------------------------- Bots */

.bots {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}
.bot {
  display: grid;
  justify-items: center;
  text-align: center;
  gap: 6px;
  padding: 34px 24px 30px;
  border-radius: var(--radius-lg);
  background: var(--surface);
}
.bot img {
  width: 116px;
  height: 116px;
  margin-bottom: 10px;
  transition: transform 0.5s var(--spring);
}
.bot:hover img {
  transform: translateY(-8px) rotate(-4deg);
}
.bot strong {
  font-size: 24px;
  font-weight: 900;
}
.pips {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--secondary);
  font-size: 14px;
  font-weight: 700;
}
.pips i {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--raised-high);
}
.pips i.on {
  background: var(--label);
}
.thinking {
  margin-top: 10px;
  padding: 8px 14px;
  border-radius: 999px;
  background: var(--raised);
  color: var(--secondary);
  font-size: 14px;
  font-weight: 600;
  font-style: italic;
}
@media (max-width: 860px) {
  .bots {
    grid-template-columns: 1fr;
  }
  .bot {
    grid-template-columns: auto 1fr;
    justify-items: start;
    text-align: left;
    column-gap: 20px;
    padding: 22px;
  }
  .bot img {
    grid-row: span 3;
    width: 88px;
    height: 88px;
    margin: 0;
  }
  .thinking {
    margin-top: 4px;
  }
}

/* ----------------------------------------------------------------- Deck */

/* The deck section opens on its own: one of the app's icons on a tile, the
   title, one line under it, and nothing boxed in after that; the cards carry
   the rest. */
.shead {
  display: grid;
  justify-items: center;
  gap: 18px;
  max-width: 760px;
  margin: 0 auto clamp(44px, 5.5vw, 68px);
  text-align: center;
}
.shead__icon {
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  border-radius: 22px;
  background: var(--raised);
  color: var(--label);
}
.shead__icon .icon {
  --size: 32px;
}
.shead .lead {
  margin: 0 auto;
}

/* The arch: cards travelling up from the left, over the top and down to the
   right. The script places them; each tilts to the slope it is on and grows a
   little towards the top, so the curve reads as depth and not only as a path.
   At both sides they pass through the same progressive blur as the window's
   edges, softening before they fade, so none of them simply appears. */
.arch {
  --cw: clamp(72px, 9.2vw, 128px);
  position: relative;
  height: clamp(270px, 29vw, 420px);
  overflow: hidden;
}
/* On a phone only the top of the arch is on screen, so it needs less height. */
@media (max-width: 600px) {
  .arch {
    height: 205px;
  }
}
.arch__cards img {
  position: absolute;
  left: 0;
  top: 0;
  width: var(--cw);
  border-radius: 16% / 11.4%;
  filter: drop-shadow(0 16px 20px rgba(0, 0, 0, 0.45));
  will-change: transform;
}
.arch__edge {
  position: absolute;
  top: 0;
  bottom: 0;
  z-index: 2;
  width: clamp(56px, 14vw, 220px);
  pointer-events: none;
}
.arch__edge--left {
  left: 0;
}
.arch__edge--right {
  right: 0;
}
.arch__edge--left > i {
  --dir: to left;
}
.arch__edge--right > i {
  --dir: to right;
}
.arch__edge::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 42%;
}
.arch__edge--left::after {
  left: 0;
  background: linear-gradient(to right, var(--bg), rgba(18, 19, 21, 0));
}
.arch__edge--right::after {
  right: 0;
  background: linear-gradient(to left, var(--bg), rgba(18, 19, 21, 0));
}

/* ------------------------------------------------------------------ Pro */

.pro {
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: 16px;
}
.pro__main {
  padding: clamp(28px, 4vw, 48px);
  border-radius: var(--radius-lg);
  background: var(--surface);
}
.pro__crown {
  display: inline-grid;
  place-items: center;
  width: 58px;
  height: 58px;
  margin-bottom: 22px;
  border-radius: 20px;
  background: var(--violet);
  color: #fff;
}
.pro__crown .icon {
  --size: 30px;
}
.perks {
  display: grid;
  gap: 2px;
  margin: 28px 0 0;
  padding: 6px;
  list-style: none;
  border-radius: var(--radius);
  background: var(--raised);
}
.perks li {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px;
}
.perks li + li {
  border-top: 1px solid var(--divider);
}
.perks__icon {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 14px;
  background: var(--raised-high);
  flex: none;
}
.perks__icon .icon {
  --size: 22px;
}
.perks strong {
  display: block;
  font-weight: 800;
}
.perks span {
  color: var(--secondary);
  font-size: 15px;
}
.pro__free {
  display: grid;
  align-content: space-between;
  gap: 24px;
  padding: clamp(28px, 4vw, 48px);
  border-radius: var(--radius-lg);
  background: var(--raised);
}
.pro__free ul {
  display: grid;
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.pro__free li {
  display: flex;
  gap: 12px;
  align-items: center;
  font-weight: 700;
}
.pro__free li .icon {
  --size: 20px;
  color: var(--violet-ink);
}
.fine {
  color: var(--tertiary);
  font-size: 14px;
}
@media (max-width: 900px) {
  .pro {
    grid-template-columns: 1fr;
  }
}

/* ------------------------------------------------------------ Download */

.cta {
  position: relative;
  display: grid;
  justify-items: center;
  gap: 22px;
  padding: clamp(56px, 8vw, 96px) var(--gutter);
  border-radius: 48px;
  background: var(--violet);
  text-align: center;
  overflow: hidden;
  isolation: isolate;
}
.cta::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='64' height='64' viewBox='0 0 64 64'%3E%3Cpath d='M20 20l24 24M44 20L20 44' stroke='%23b9a7e6' stroke-width='6' stroke-linecap='round' fill='none'/%3E%3C/svg%3E");
  background-size: 64px 64px;
  opacity: 0.08;
}
.cta__icon {
  width: 104px;
  height: 104px;
  border-radius: 24px;
  box-shadow: var(--shadow-float);
}
.cta .lead {
  color: rgba(255, 255, 255, 0.82);
}

/* --------------------------------------------------------------- Footer */

.footer {
  margin-top: clamp(72px, 10vw, 128px);
  color: var(--secondary);
  overflow: hidden;
}
.footer__top {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 40px 64px;
  align-items: start;
}
.footer__lead {
  display: grid;
  justify-items: start;
  gap: 22px;
}
.footer__line {
  margin: 0;
  max-width: 12em;
  color: var(--label);
  font-size: clamp(26px, 3vw, 34px);
  font-weight: 900;
  line-height: 1.08;
  letter-spacing: -0.02em;
}
.footer__cols {
  display: grid;
  grid-template-columns: repeat(3, minmax(120px, auto));
  gap: 32px 56px;
}
.footer__cols > div {
  display: grid;
  align-content: start;
  gap: 10px;
}
.footer__head {
  margin: 0 0 4px;
  color: var(--tertiary);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.footer a {
  font-weight: 600;
  text-decoration: none;
  transition: color 0.2s;
}
.footer__cols a {
  font-size: 16px;
}
.footer a:hover,
.footer a[aria-current="page"] {
  color: var(--label);
}
.footer__base {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px 24px;
  margin-top: clamp(48px, 6vw, 72px);
  color: var(--tertiary);
  font-size: 13px;
}
.footer__base a {
  color: var(--secondary);
}

/* The name as wide as the page, in the heaviest weight, going down into the
   bottom edge the way content dissolves into the chrome in the app: softening
   first, over the lower half, and fading only once it is already soft, with
   the fade running out past the page's own edge. */
.footer__giant {
  position: relative;
  display: flex;
  justify-content: center;
  height: 0.74em;
  margin-top: clamp(4px, 1.5vw, 20px);
  font-size: clamp(84px, 24.5vw, 350px);
  overflow: hidden;
  user-select: none;
}
.footer__word {
  display: inline-flex;
  align-items: center;
  gap: 0.07em;
  color: var(--label);
  font-weight: 900;
  line-height: 0.86;
  letter-spacing: -0.055em;
  white-space: nowrap;
}
.footer__word .mark {
  --size: 0.66em;
  margin-top: 0.04em;
  color: var(--violet-ink);
}
.melt {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 64%;
  pointer-events: none;
}
.melt > i {
  --dir: to bottom;
}
.footer__giant::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 34%;
  background: linear-gradient(to bottom, rgba(18, 19, 21, 0), var(--bg) 92%);
  pointer-events: none;
}

@media (max-width: 860px) {
  .footer__top {
    grid-template-columns: 1fr;
  }
}
@media (max-width: 520px) {
  /* The word is small enough here that half of it melting leaves too little to
     read, so less of it goes under. */
  .melt {
    height: 50%;
  }
  .footer__giant::after {
    height: 26%;
  }
  .footer__cols {
    grid-template-columns: repeat(2, 1fr);
    gap: 28px 24px;
  }
  .footer__base {
    flex-direction: column;
  }
}

/* --------------------------------------------------------------- Reveal */

.reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 0.7s var(--ease-out), transform 0.8s var(--ease-out);
  transition-delay: var(--stagger, 0s);
}
.reveal.is-in {
  opacity: 1;
  transform: none;
}

/* ------------------------------------------------------------- Documents */

.doc {
  max-width: 760px;
  margin: 0 auto;
  /* Clear of the nav and the blur under it, which `main`'s own padding would
     have done if this did not replace it. */
  padding: 132px var(--gutter) 0;
}
.doc__head {
  display: grid;
  gap: 16px;
  margin-bottom: 36px;
}
.doc__head .h-section {
  font-size: clamp(44px, 7vw, 72px);
}
.updated {
  color: var(--tertiary);
  font-size: 14px;
  font-weight: 600;
}
.summary {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
  margin-bottom: 20px;
}
.summary div {
  display: grid;
  gap: 6px;
  padding: 22px;
  border-radius: var(--radius);
  background: var(--surface);
}
.summary .icon {
  --size: 24px;
  margin-bottom: 6px;
  color: var(--violet-ink);
}
.summary strong {
  font-weight: 800;
  font-size: 17px;
}
.summary p {
  margin: 0;
  color: var(--secondary);
  font-size: 15px;
}
@media (max-width: 600px) {
  .summary {
    grid-template-columns: 1fr;
  }
}
.doc section {
  margin-top: 12px;
  padding: clamp(22px, 3.4vw, 34px);
  border-radius: var(--radius);
  background: var(--surface);
}
.doc h2 {
  margin: 0 0 12px;
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.01em;
}
.doc h3 {
  margin: 22px 0 8px;
  font-size: 17px;
  font-weight: 800;
}
.doc p,
.doc li {
  color: var(--secondary);
  font-size: 16px;
}
.doc p {
  margin: 0 0 12px;
}
.doc p:last-child {
  margin-bottom: 0;
}
.doc ul {
  margin: 0 0 12px;
  padding-left: 20px;
}
.doc li {
  margin: 4px 0;
}
.doc strong {
  color: var(--label);
}
.doc a {
  color: var(--label);
  text-decoration-color: rgba(255, 255, 255, 0.3);
  text-underline-offset: 3px;
}
.doc a:hover {
  text-decoration-color: currentColor;
}
.todo {
  padding: 1px 6px;
  border-radius: 6px;
  background: #ffd76a;
  color: #141517;
  font-weight: 700;
}

.faq details {
  margin-top: 10px;
  border-radius: var(--radius);
  background: var(--surface);
}
.faq summary {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 64px;
  padding: 16px 22px;
  font-size: 17px;
  font-weight: 800;
  cursor: pointer;
  list-style: none;
}
.faq summary::-webkit-details-marker {
  display: none;
}
.faq summary::after {
  content: "";
  margin-left: auto;
  width: 14px;
  height: 14px;
  flex: none;
  background: var(--tertiary);
  -webkit-mask: url("/assets/icons/forward.png") center / contain no-repeat;
  mask: url("/assets/icons/forward.png") center / contain no-repeat;
  transition: transform 0.3s var(--spring);
}
.faq details[open] summary::after {
  transform: rotate(90deg);
}
.faq details > div {
  padding: 0 22px 22px;
  color: var(--secondary);
}
.faq details > div p {
  margin: 0 0 10px;
}
.contact {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 18px;
  margin-top: 12px;
  padding: 26px;
  border-radius: var(--radius);
  background: var(--violet);
}
.contact p {
  margin: 0;
  color: rgba(255, 255, 255, 0.85);
}
.contact strong {
  display: block;
  color: #fff;
  font-size: 20px;
  font-weight: 900;
}
.contact .btn {
  margin-left: auto;
}

/* --------------------------------------------------------------- Motion */

/* Everything here moves with the separate translate, rotate and scale
   properties, so an entrance never fights the transform a hover is already
   using. Keyframes give only where a thing comes from; where it ends is its own
   resting style, which is also exactly what is left when motion is turned off. */

@keyframes rise {
  from { opacity: 0; translate: 0 22px; }
}
@keyframes word {
  from { opacity: 0; translate: 0 0.42em; rotate: 4deg; }
}
@keyframes panel-in {
  from { opacity: 0; scale: 0.97; }
}
@keyframes pop {
  from { opacity: 0; scale: 0.4; }
}
@keyframes hop {
  from { opacity: 0; translate: 0 40px; rotate: -14deg; scale: 0.8; }
}
@keyframes slide-in {
  from { opacity: 0; translate: -18px 0; }
}
@keyframes drop {
  from { opacity: 0; translate: 0 -48px; rotate: -18deg; scale: 0.7; }
}
@keyframes fan-open {
  from { transform: translateX(-50%) rotate(0deg); }
}

/* The hero on arrival: the panel settles, then the words come up one by one. */
.hero__panel {
  animation: panel-in 1s var(--ease-out) backwards;
}
.hero__copy > * {
  animation: rise 0.9s var(--ease-out) backwards;
}
.hero__copy > .eyebrow { animation-delay: 0.15s; }
.hero__copy > .h-display { animation: none; }
.hero__copy > .lead { animation-delay: 0.6s; }
.hero__copy > .hero__actions { animation-delay: 0.72s; }
.hero .w {
  display: inline-block;
  animation: word 1s var(--spring) backwards;
  animation-delay: calc(0.28s + var(--k, 0) * 0.1s);
}
.hero .marquee {
  animation: rise 1s var(--ease-out) backwards 0.85s;
}

/* A heading arrives line by line rather than as one block. */
:is(.section__head, .shead).reveal {
  opacity: 1;
  transform: none;
}
:is(.section__head, .shead).reveal:not(.is-in) > * {
  opacity: 0;
}
:is(.section__head, .shead).reveal.is-in > * {
  animation: rise 0.8s var(--ease-out) backwards;
}
.shead.reveal.is-in > .shead__icon {
  animation: pop 0.8s var(--spring) backwards;
}
:is(.section__head, .shead).reveal.is-in > :nth-child(2) { animation-delay: 0.08s; }
:is(.section__head, .shead).reveal.is-in > :nth-child(3) { animation-delay: 0.16s; }

/* Card fans are closed until they arrive, then open like a hand being spread. */
.reveal:not(.is-in) .fan img {
  transform: translateX(-50%) rotate(0deg);
}
.reveal.is-in .fan img {
  animation: fan-open 0.9s var(--spring) backwards;
  animation-delay: calc(0.25s + var(--stagger, 0s));
}

/* The people at the table sit down one after another. */
.reveal:not(.is-in) .table-ring img {
  opacity: 0;
}
.reveal.is-in .table-ring img {
  animation: pop 0.7s var(--spring) backwards;
}
.reveal.is-in .table-ring img:nth-child(1) { animation-delay: 0.35s; }
.reveal.is-in .table-ring img:nth-child(2) { animation-delay: 0.45s; }
.reveal.is-in .table-ring img:nth-child(3) { animation-delay: 0.55s; }
.reveal.is-in .table-ring img:nth-child(4) { animation-delay: 0.65s; }
.reveal.is-in .table-caption {
  animation: rise 0.6s var(--ease-out) backwards 0.8s;
}
.reveal.is-in .start-pill {
  animation: pop 0.6s var(--spring) backwards 0.5s;
}

/* Bots hop into their chairs, then say what they are thinking. */
.bot.reveal:not(.is-in) img {
  opacity: 0;
}
.bot.reveal.is-in img {
  animation: hop 0.9s var(--spring) backwards;
  animation-delay: calc(0.15s + var(--stagger, 0s));
}
.bot.reveal.is-in .thinking {
  animation: rise 0.6s var(--ease-out) backwards;
  animation-delay: calc(0.55s + var(--stagger, 0s));
}

/* Pro: the crown lands, then the lists read themselves in. */
.reveal.is-in .pro__crown {
  animation: drop 0.9s var(--spring) backwards 0.1s;
}
.reveal:not(.is-in) :is(.perks, .pro__free ul) li {
  opacity: 0;
}
.reveal.is-in :is(.perks, .pro__free ul) li {
  animation: slide-in 0.6s var(--ease-out) backwards;
}
.reveal.is-in :is(.perks, .pro__free ul) li:nth-child(1) { animation-delay: 0.25s; }
.reveal.is-in :is(.perks, .pro__free ul) li:nth-child(2) { animation-delay: 0.32s; }
.reveal.is-in :is(.perks, .pro__free ul) li:nth-child(3) { animation-delay: 0.39s; }
.reveal.is-in :is(.perks, .pro__free ul) li:nth-child(4) { animation-delay: 0.46s; }
.reveal.is-in :is(.perks, .pro__free ul) li:nth-child(5) { animation-delay: 0.53s; }
.reveal.is-in :is(.perks, .pro__free ul) li:nth-child(6) { animation-delay: 0.6s; }

/* The app icon drops onto the last panel. */
.cta.reveal.is-in .cta__icon {
  animation: drop 1s var(--spring) backwards 0.15s;
}

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

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