/* ==========================================================================
   Caelia — site styles
   --------------------------------------------------------------------------
   One stylesheet, hand-written, no framework. The whole site is ~9 static
   pages; a build step and a utility framework would cost more than they save,
   and a marketing site that needs `npm install` to fix a typo is a site that
   stops getting fixed.

   The palette is taken from the product itself — near-black panels with a
   violet accent — so the site and the app look like the same thing. That is
   deliberate: the strongest thing a product site can do is look like the
   product.
   ========================================================================== */

:root {
  --bg: #07090c;
  --bg-2: #0b0f14;
  --panel: #0d1218;
  --line: rgba(255, 255, 255, 0.08);
  --line-2: rgba(255, 255, 255, 0.14);

  --text: rgba(255, 255, 255, 0.92);
  --muted: rgba(255, 255, 255, 0.56);
  --faint: rgba(255, 255, 255, 0.34);

  --accent: #a855f7;
  --accent-soft: rgba(168, 85, 247, 0.14);
  --accent-line: rgba(168, 85, 247, 0.34);
  --accent-2: #22d3ee;

  --ok: #34d399;
  --warn: #fbbf24;

  --radius: 16px;
  --radius-lg: 24px;
  --maxw: 1140px;

  --sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, "JetBrains Mono", "Cascadia Mono", Consolas, monospace;
}

* {
  box-sizing: border-box;
}

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* A single soft glow behind the page, fixed, so scrolling feels like moving
   through one space rather than past a series of panels. */
body::before {
  content: "";
  position: fixed;
  inset: -20% -10% auto -10%;
  height: 70vh;
  background:
    radial-gradient(60% 60% at 20% 0%, rgba(168, 85, 247, 0.13), transparent 70%),
    radial-gradient(50% 50% at 85% 10%, rgba(34, 211, 238, 0.07), transparent 70%);
  pointer-events: none;
  z-index: 0;
}

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

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

h1,
h2,
h3,
h4 {
  margin: 0;
  line-height: 1.15;
  letter-spacing: -0.02em;
  font-weight: 600;
}
p {
  margin: 0;
}

::selection {
  background: var(--accent-soft);
  color: #fff;
}

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

/* ── layout ─────────────────────────────────────────────────────────────── */

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

section {
  padding: 96px 0;
  position: relative;
  z-index: 1;
}
section.tight {
  padding: 64px 0;
}

.eyebrow {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 18px;
}

.lead {
  color: var(--muted);
  font-size: 18px;
  max-width: 62ch;
}
.small {
  font-size: 14px;
  color: var(--faint);
}
.center {
  text-align: center;
}
.center .lead {
  margin-left: auto;
  margin-right: auto;
}

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

/* A `.g2` row whose first column carries a wide screenshot and needs the extra width.
   Written as a class inside a min-width query rather than an inline style, because an
   inline `grid-template-columns` outranks the max-width rule further down that collapses
   these grids to one column, and the row would stay two-up on a phone. */
@media (min-width: 721px) {
  .g2-wide {
    grid-template-columns: 1.32fr 1fr;
  }
}
.g3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.g4 {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

/* ── skip link ──────────────────────────────────────────────────────────── */

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  background: var(--accent);
  color: #fff;
  padding: 10px 16px;
  border-radius: 0 0 10px 0;
}
.skip:focus {
  left: 0;
}

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

header.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(7, 9, 12, 0.72);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}

/* Height comes from padding, not a fixed number, so the bar grows with whatever
   --mark is set to. A fixed height plus a larger logo is an overflow, and it is
   the kind that only shows up after somebody adjusts the logo by eye. */
.nav-in {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 13px 0;
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  font-weight: 650;
  letter-spacing: -0.01em;
  font-size: 17px;
  margin-right: auto;
}
/* The logo is a JPEG with its background baked in — it has no transparency, so it
   cannot float on the dark bar. Rendered as a rounded tile it reads as an app
   icon, which is what it is, and the baked background becomes deliberate.
   
   Size lives in a custom property because this is the one number on the site
   most likely to be adjusted by eye. */
/* The logo as a wordmark: 120 x 30, no border, no rounding.
   
   `cover` rather than `contain`, and the reason matters. The source file is a
   1024x1024 square with the wordmark sitting in the middle and empty space above
   and below it. In a 120x30 box `contain` would shrink the whole square to 30x30
   and leave 90px of nothing beside it. `cover` fills the box and trims the empty
   top and bottom instead — which is exactly the part that should go.
   
   The file's own background is near-black, and so is the bar, so it reads as if
   it were transparent even though a JPEG cannot be. */
.brand-mark {
  width: var(--mark-w);
  height: var(--mark-h);
  flex: 0 0 var(--mark-w);
  object-fit: cover;
}

/* ────────────────────────────────────────────────────────────────────────────
   THE LOGO SIZE. This is the only line to change.
   The bar sizes itself around it, so any value here is safe.
   ──────────────────────────────────────────────────────────────────────────── */
/* ────────────────────────────────────────────────────────────────────────────
   THE LOGO SIZE. These two lines are the only ones to change.
   The bar sizes itself around them, so any value here is safe.
   ──────────────────────────────────────────────────────────────────────────── */
:root {
  --mark-w: 120px;
  --mark-h: 30px;
}

.foot .brand-mark {
  --mark-w: 104px;
  --mark-h: 26px;
}

/* Kept from the earlier dot mark in case a plain accent bullet is wanted again. */
.brand .dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 12px var(--accent);
  flex: 0 0 9px;
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 4px;
}
.nav-links a {
  padding: 8px 12px;
  border-radius: 10px;
  font-size: 14.5px;
  color: var(--muted);
  transition:
    color 0.18s,
    background 0.18s;
}
.nav-links a:hover {
  color: var(--text);
  background: rgba(255, 255, 255, 0.05);
}
.nav-links a[aria-current="page"] {
  color: var(--text);
  background: rgba(255, 255, 255, 0.06);
}

.burger {
  display: none;
  width: 40px;
  height: 40px;
  align-items: center;
  justify-content: center;
  background: none;
  border: 1px solid var(--line);
  border-radius: 11px;
  color: var(--text);
  cursor: pointer;
}

/* ── buttons ────────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 13px 24px;
  border-radius: 999px;
  border: 1px solid transparent;
  font-size: 14.5px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  transition:
    transform 0.16s,
    background 0.18s,
    border-color 0.18s,
    color 0.18s;
  white-space: nowrap;
}
.btn:active {
  transform: translateY(1px);
}

.btn-primary {
  background: #fff;
  color: #000;
}
.btn-primary:hover {
  background: rgba(255, 255, 255, 0.9);
}

.btn-accent {
  background: linear-gradient(135deg, #a855f7, #7c3aed);
  color: #fff;
  box-shadow: 0 10px 30px rgba(168, 85, 247, 0.22);
}
.btn-accent:hover {
  filter: brightness(1.08);
}

.btn-ghost {
  background: rgba(255, 255, 255, 0.03);
  border-color: var(--line-2);
  color: var(--text);
}
.btn-ghost:hover {
  background: rgba(255, 255, 255, 0.07);
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
}

/* ── cards ──────────────────────────────────────────────────────────────── */

.card {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0.012));
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 26px;
  transition:
    border-color 0.2s,
    transform 0.2s;
}
.card:hover {
  border-color: var(--line-2);
  transform: translateY(-2px);
}
.card h3 {
  font-size: 17.5px;
  margin-bottom: 9px;
}
.card p {
  color: var(--muted);
  font-size: 14.5px;
}

.icon {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  color: var(--accent);
  margin-bottom: 16px;
}
.icon svg {
  width: 19px;
  height: 19px;
}

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

.hero {
  padding: 108px 0 84px;
}
.hero h1 {
  font-size: clamp(2.4rem, 6vw, 4.1rem);
  font-weight: 620;
  max-width: 20ch;
}

/* ── full-width centred hero ─────────────────────────────────────────────────
   One column, centred, tall enough to own the first screen — then the product
   video directly beneath it at full width. The words get the whole stage, and the
   video is the first thing a visitor scrolls to rather than something competing
   for attention beside the headline. */

.hero-full {
  padding: 92px 0 64px;
  text-align: center;
  position: relative;
}
.hero-full .wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.hero-full h1 {
  font-size: clamp(2.5rem, 6.6vw, 4.9rem);
  font-weight: 620;
  max-width: 24ch;
  margin: 0 auto;
  letter-spacing: -0.035em;
  line-height: 1.06;
}
.hero-full .lead {
  margin: 24px auto 0;
  max-width: 56ch;
  font-size: 18.5px;
}
.hero-full .btn-row {
  justify-content: center;
  margin-top: 36px;
}

/* The licence line: present, readable, and deliberately quieter than the
   headline it sits under. */
.hero-note {
  margin-top: 20px;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--faint);
}

.plats {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
  margin-top: 30px;
}
.plat {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 15px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.03);
  font-size: 12.5px;
  color: var(--muted);
}
.plat svg {
  width: 14px;
  height: 14px;
  opacity: 0.75;
}
/* They are links now, so they need to look like something you can press. */
a.plat {
  transition:
    color 0.18s,
    border-color 0.18s,
    background 0.18s;
}
a.plat:hover {
  color: var(--text);
  border-color: var(--line-2);
  background: rgba(255, 255, 255, 0.07);
}
a.plat:hover svg {
  opacity: 1;
}

/* A soft vignette so the centred block sits in its own pool of light. Drawn with
   a gradient rather than an image: nothing extra to download. */
.hero-full::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(58% 62% at 50% 34%, rgba(168, 85, 247, 0.1), transparent 72%);
}

/* The video, under the headline, at the width of the page. */
.hero-reel {
  padding: 0 0 92px;
}
.hero-reel .frame {
  margin-top: 0;
}
.hero-reel .frame-video {
  aspect-ratio: 16 / 9;
}

/* Kept for reference: the earlier two-column hero. Unused now, and small enough
   to leave in place in case the split layout is ever wanted back. */
.hero-split {
  display: grid;
  grid-template-columns: 1.02fr 0.98fr;
  gap: 52px;
  align-items: center;
}
.hero-split .hero-copy h1 {
  font-size: clamp(2.1rem, 4.2vw, 3.35rem);
  max-width: 18ch;
}
.hero-split .hero-copy .lead {
  font-size: 17.5px;
  max-width: 46ch;
}
.hero-split .frame {
  margin-top: 0;
}

/* The video sits in the same frame chrome as the screenshots, so the page has
   one visual language rather than two. */
.frame-video {
  position: relative;
  aspect-ratio: 16 / 9; /* the file is 1920×1080 — matched, so no black bars */
  background: #000;
}
.frame-video video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* The hero's sound control is `.v-sound`, at the foot of this file. */

.hero h1 .hl {
  background: linear-gradient(120deg, #a855f7 15%, #22d3ee 85%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
.hero .lead {
  margin-top: 22px;
  font-size: 19px;
}
.hero .btn-row {
  margin-top: 34px;
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 6px 14px 6px 10px;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.03);
  font-size: 12.5px;
  color: var(--muted);
  margin-bottom: 26px;
}
.badge .pip {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--ok);
  box-shadow: 0 0 8px var(--ok);
}

/* ── the app frame (screenshot holder) ──────────────────────────────────── */

.frame {
  margin-top: 56px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
  overflow: hidden;
  box-shadow: 0 40px 120px rgba(0, 0, 0, 0.6);
}
.frame-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.02);
}
.frame-bar i {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.14);
  display: block;
}
.frame-bar span {
  margin-left: 10px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--faint);
}
/* A screenshot on its own: a border, rounded corners, and nothing else. Used by every
   screenshot on the site.

   Deliberately NOT wrapped in `.frame`. That class draws a fake window title bar with
   three dots in it, which is right for the video of the desktop but wrong here - these
   screenshots already contain the application's own title bar, so the mock chrome was a
   second window drawn around a window.

   No `aspect-ratio` and no `object-fit`, so each image keeps its own shape. The agent
   screenshot is 1731x762 and the voice one is 508x489; a single forced ratio would crop
   a fifth of the width off one of them, which on a screenshot means cutting away the
   panels it exists to show. A different screenshot dropped in later needs no CSS change.

   `.frame-body` and its placeholder used to live here, holding "SCREENSHOT: ..." captions
   until the real images arrived. Both are in now, so both rules are gone. */
.shot {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--line-2);
  border-radius: var(--radius);
  background: var(--bg-2);
}

/* ── stat strip ─────────────────────────────────────────────────────────── */

.stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
.stats div {
  padding: 24px;
  border-right: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.015);
}
.stats div:last-child {
  border-right: none;
}
.stats b {
  display: block;
  font-size: 26px;
  font-weight: 620;
  letter-spacing: -0.02em;
}
.stats span {
  font-size: 13px;
  color: var(--faint);
}

/* ── pricing ────────────────────────────────────────────────────────────── */

.price-card {
  border: 1px solid var(--accent-line);
  border-radius: var(--radius-lg);
  background:
    radial-gradient(120% 100% at 50% 0%, rgba(168, 85, 247, 0.12), transparent 60%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.04), rgba(255, 255, 255, 0.01));
  padding: 40px;
  max-width: 520px;
  margin: 0 auto;
  text-align: center;
}
.price-amount {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 8px;
  margin: 18px 0 4px;
}
.price-amount b {
  font-size: 62px;
  font-weight: 620;
  letter-spacing: -0.03em;
  line-height: 1;
}
.price-amount .cur {
  font-size: 24px;
  color: var(--muted);
}
.price-alt {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--faint);
}

.ticks {
  list-style: none;
  margin: 28px 0 0;
  padding: 0;
  text-align: left;
  display: grid;
  gap: 11px;
}
.ticks li {
  display: flex;
  gap: 11px;
  font-size: 14.5px;
  color: var(--muted);
}
.ticks svg {
  width: 17px;
  height: 17px;
  color: var(--ok);
  flex: 0 0 17px;
  margin-top: 4px;
}

.pay-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
  margin-top: 26px;
}
.chip {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--faint);
}

/* ── faq ────────────────────────────────────────────────────────────────── */

.faq {
  border-top: 1px solid var(--line);
}
.faq details {
  border-bottom: 1px solid var(--line);
  padding: 20px 0;
}
.faq summary {
  cursor: pointer;
  font-size: 16.5px;
  font-weight: 550;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 14px;
}
.faq summary::-webkit-details-marker {
  display: none;
}
.faq summary::after {
  content: "+";
  margin-left: auto;
  color: var(--accent);
  font-size: 22px;
  line-height: 1;
  transition: transform 0.2s;
}
.faq details[open] summary::after {
  transform: rotate(45deg);
}
.faq details p {
  color: var(--muted);
  font-size: 15px;
  margin-top: 12px;
  max-width: 76ch;
}

/* ── "you say / Caelia does" demo rows ──────────────────────────────────────
   Built to read as a demonstration rather than a marketing claim: the sentence
   a customer would actually say, then the steps that follow from it. */

.say {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0.012));
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition:
    border-color 0.2s,
    transform 0.2s;
}
.say:hover {
  border-color: var(--line-2);
  transform: translateY(-2px);
}

.say-tag {
  display: block;
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: 9px;
}
.say-you {
  padding: 22px 22px 18px;
}
.say-you p {
  font-size: 16px;
  line-height: 1.5;
  color: var(--text);
  font-weight: 500;
}

.say-does {
  padding: 18px 22px 22px;
  border-top: 1px solid var(--line);
  background: rgba(168, 85, 247, 0.05);
  margin-top: auto;
}
.say-does .say-tag {
  color: var(--accent);
}
.say-does p {
  font-size: 14px;
  color: var(--muted);
}

/* The step chain. Kept as text with a separator element so it wraps cleanly on a
   narrow screen instead of overflowing sideways. */
.chain {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 7px;
}
.chain span {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.78);
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: 4px 9px;
  white-space: nowrap;
}
.chain i {
  color: var(--accent);
  font-style: normal;
  font-size: 12px;
}

/* ── steps ──────────────────────────────────────────────────────────────── */

.steps {
  counter-reset: s;
  display: grid;
  gap: 18px;
}
.step {
  display: grid;
  grid-template-columns: 42px 1fr;
  gap: 18px;
  align-items: start;
  padding: 22px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.015);
}
.step::before {
  counter-increment: s;
  content: counter(s);
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  color: var(--accent);
  font-family: var(--mono);
  font-size: 15px;
}
.step h3 {
  font-size: 16.5px;
  margin-bottom: 6px;
}
.step p {
  color: var(--muted);
  font-size: 14.5px;
}

/* ── callout ────────────────────────────────────────────────────────────── */

.callout {
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--radius) var(--radius) 0;
  background: rgba(168, 85, 247, 0.05);
  padding: 20px 24px;
}
.callout p {
  color: var(--muted);
  font-size: 14.5px;
}
.callout strong {
  color: var(--text);
}

/* ── cta band ───────────────────────────────────────────────────────────── */

.cta {
  border: 1px solid var(--accent-line);
  border-radius: var(--radius-lg);
  background: radial-gradient(100% 120% at 50% 100%, rgba(168, 85, 247, 0.16), transparent 65%), var(--bg-2);
  padding: 64px 32px;
  text-align: center;
}
.cta h2 {
  font-size: clamp(1.8rem, 4vw, 2.6rem);
}
.cta .lead {
  margin: 16px auto 0;
}
.cta .btn-row {
  justify-content: center;
  margin-top: 30px;
}

/* ── legal / prose pages ────────────────────────────────────────────────── */

.prose {
  max-width: 78ch;
}
.prose h2 {
  font-size: 22px;
  margin: 40px 0 12px;
}
.prose h3 {
  font-size: 17px;
  margin: 26px 0 8px;
}
.prose p,
.prose li {
  color: var(--muted);
  font-size: 15.5px;
}
.prose p {
  margin: 12px 0;
}
.prose ul {
  margin: 12px 0;
  padding-left: 22px;
}
.prose li {
  margin: 7px 0;
}
.prose a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.prose strong {
  color: var(--text);
}
.updated {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--faint);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

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

footer.foot {
  border-top: 1px solid var(--line);
  padding: 62px 0 34px;
  margin-top: 40px;
  position: relative;
  z-index: 1;
}
.foot-grid {
  display: grid;
  grid-template-columns: 1.6fr repeat(3, 1fr);
  gap: 36px;
}
.foot h4 {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: 14px;
  font-weight: 600;
}
.foot ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 9px;
}
.foot ul a {
  color: var(--muted);
  font-size: 14.5px;
}
.foot ul a:hover {
  color: var(--text);
}
.foot-note {
  margin-top: 44px;
  padding-top: 22px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  align-items: center;
  justify-content: space-between;
  font-size: 13.5px;
  color: var(--faint);
}

/* ── reveal on scroll ───────────────────────────────────────────────────── */

.reveal {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity 0.55s ease,
    transform 0.55s ease;
}
.reveal.in {
  opacity: 1;
  transform: none;
}

/* ── responsive ─────────────────────────────────────────────────────────── */

@media (max-width: 940px) {
  .g4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .g3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .stats div:nth-child(2) {
    border-right: none;
  }
  .stats div:nth-child(1),
  .stats div:nth-child(2) {
    border-bottom: 1px solid var(--line);
  }
  .foot-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 1000px) {
  /* Stack before the columns get too narrow to read. The video keeps its place
     under the buttons rather than above them. */
  .hero-split {
    grid-template-columns: minmax(0, 1fr);
    gap: 40px;
  }
  .hero-split .hero-copy h1 {
    max-width: 22ch;
  }
  .hero-split .hero-copy .lead {
    max-width: 60ch;
  }
}

@media (max-width: 720px) {
  section {
    padding: 68px 0;
  }
  .hero {
    padding: 74px 0 56px;
  }
  .hero-full {
    padding: 62px 0 44px;
  }
  .hero-full h1 {
    max-width: 20ch;
    letter-spacing: -0.03em;
  }
  .hero-full .lead {
    font-size: 16.5px;
  }
  .hero-full .btn-row {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
  }
  .hero-full .btn-row .btn {
    width: 100%;
  }
  .hero-reel {
    padding-bottom: 62px;
  }
  .plat {
    font-size: 11.5px;
    padding: 7px 12px;
  }
  .burger {
    display: inline-flex;
  }
  :root {
    --mark-w: 104px;
    --mark-h: 26px;
  }
  .nav-links {
    /* Anchored to the bottom of the bar rather than a hard pixel offset, so it
       stays put whatever the logo size makes the bar. */
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    padding: 12px;
    background: rgba(7, 9, 12, 0.98);
    border-bottom: 1px solid var(--line);
    display: none;
  }
  .nav-links.open {
    display: flex;
  }
  .nav-links a {
    padding: 12px 14px;
    font-size: 15.5px;
  }
  .g2,
  .g3,
  .g4 {
    grid-template-columns: minmax(0, 1fr);
  }
  .price-card {
    padding: 30px 22px;
  }
  .price-amount b {
    font-size: 50px;
  }
  .cta {
    padding: 46px 22px;
  }
  .step {
    grid-template-columns: 36px 1fr;
    gap: 14px;
    padding: 18px;
  }
  .step::before {
    width: 36px;
    height: 36px;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .card:hover {
    transform: none;
  }
}

/* ── the download stage ─────────────────────────────────────────────────────
   The download page's first screen. Its own block, prefixed `dl-`, because it is
   the one place on the site where a single button has to beat everything else on
   the screen — so it does not reuse `.hero`, whose job is to introduce a product
   rather than to hand over a file.

   Appended at the end of the file on purpose: this stylesheet is edited from both
   sides, and a new block at the bottom is the edit least likely to collide with
   one in progress further up.
   ────────────────────────────────────────────────────────────────────────── */

.dl-hero {
  padding: 76px 0 84px;
  position: relative;
  text-align: center;
  overflow: hidden;
}

/* The same pool of light the home page hero sits in, so the two pages feel like
   one site. Drawn with a gradient — nothing extra to download. */
.dl-hero::before {
  content: "";
  position: absolute;
  inset: -30% -10% auto -10%;
  height: 120%;
  pointer-events: none;
  background: radial-gradient(52% 54% at 50% 26%, rgba(168, 85, 247, 0.13), transparent 70%);
}

.dl-stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  max-width: 620px;
}

/* The source file is a square with the wordmark centred in it, so at this size it
   reads as an application icon — which is what it is. Rounded rather than square
   for the same reason. `alt` is empty because the headline beside it says the same
   thing, and a screen reader announcing "Caelia" twice is noise. */
.dl-mark {
  width: 76px;
  height: 76px;
  border-radius: 20px;
  object-fit: cover;
  border: 1px solid var(--line-2);
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.55);
}

.dl-hero h1 {
  margin-top: 30px;
  font-size: clamp(2.3rem, 6vw, 3.6rem);
  font-weight: 620;
  letter-spacing: -0.035em;
  line-height: 1.08;
}
.dl-hero h1 .hl {
  background: linear-gradient(120deg, #a855f7 15%, #22d3ee 85%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

.dl-sub {
  margin-top: 18px;
  max-width: 44ch;
  color: var(--muted);
  font-size: 16.5px;
}

/* ── the checksum strip ──────────────────────────────────────────────────────
   What a "verified build" badge should have been. It is the hash of the file the
   button points at, read from the updater feed, so it cannot drift out of date —
   and it stays hidden unless the feed answers, because a hash that no longer
   matches the file is worse than none at all. */

.dl-verify {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  margin-top: 30px;
  padding: 11px 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.025);
  font-family: var(--mono);
  font-size: 11.5px;
  text-align: left;
}
.dl-verify > svg {
  width: 15px;
  height: 15px;
  color: var(--ok);
  flex: 0 0 15px;
}
.dl-verify-label {
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--faint);
  flex: 0 0 auto;
}
/* The hash is 128 characters. It is truncated on screen and complete on the
   clipboard — a wrapped hash nobody can read is not more honest than a short one
   with a copy button. */
.dl-verify-hash {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--muted);
}
.dl-copy {
  flex: 0 0 auto;
  font: inherit;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text);
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--line-2);
  border-radius: 8px;
  padding: 5px 10px;
  cursor: pointer;
  transition:
    background 0.18s,
    color 0.18s;
}
.dl-copy:hover {
  background: rgba(255, 255, 255, 0.1);
}

/* ── platform tabs ──────────────────────────────────────────────────────────
   Two tabs rather than one, because "is there a Mac version" is a question every
   visitor has — and the honest answer is worth more than a tidier control. The
   second tab is not a button and not clickable: there is nothing behind it. */

.dl-os {
  display: inline-flex;
  gap: 4px;
  margin-top: 26px;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.03);
}
.dl-os-tab {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 8px 18px;
  border-radius: 999px;
  white-space: nowrap;
}
.dl-os-tab.is-on {
  background: #fff;
  color: #000;
  font-weight: 600;
}
.dl-os-tab.is-off {
  color: var(--faint);
  cursor: not-allowed;
}

/* ── the button ─────────────────────────────────────────────────────────────
   Wide, white and on its own. Nothing beside it: a second button of equal weight
   next to a download button is a decision the visitor did not come here to make.
   The way to the pricing page is the quiet link underneath. */

.dl-cta {
  margin-top: 22px;
  width: 100%;
  max-width: 420px;
  padding: 17px 28px;
  border-radius: 14px;
  font-size: 15px;
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.5);
}
.dl-cta-arrow {
  margin-left: auto;
  opacity: 0.55;
}
.dl-cta > svg:first-of-type {
  margin-right: auto;
}

.dl-meta {
  margin-top: 16px;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--faint);
}

.dl-alt {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 34px;
  padding: 13px 22px;
  border: 1px solid var(--line);
  border-radius: 12px;
  font-size: 13.5px;
  color: var(--muted);
  transition:
    border-color 0.18s,
    color 0.18s,
    background 0.18s;
}
.dl-alt:hover {
  color: var(--text);
  border-color: var(--line-2);
  background: rgba(255, 255, 255, 0.04);
}

@media (max-width: 720px) {
  .dl-hero {
    padding: 52px 0 64px;
  }
  .dl-mark {
    width: 64px;
    height: 64px;
    border-radius: 17px;
  }
  .dl-hero h1 {
    margin-top: 24px;
  }
  .dl-sub {
    font-size: 15.5px;
  }
  .dl-cta {
    max-width: none;
  }
  /* The label and the copy button stay on the first line; the hash gets the second,
     because at this width three items in a row leaves nothing legible. */
  .dl-verify {
    flex-wrap: wrap;
  }
  .dl-verify-hash {
    flex-basis: 100%;
    order: 3;
  }
  .dl-os-tab {
    padding: 8px 13px;
    font-size: 10px;
  }
}

/* A command to be typed. Selectable, wrapping, and visibly a command rather than
   prose — the one thing that must not happen is a customer copying half of it. */
.dl-cmd {
  margin-top: 12px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: rgba(0, 0, 0, 0.35);
  font-family: var(--mono);
  font-size: 12.5px;
  color: rgba(255, 255, 255, 0.82);
  overflow-wrap: anywhere;
  user-select: all;
}

/* ── the plan card ──────────────────────────────────────────────────────────
   The pricing page's one card. Two-tone on purpose: the price and the promise sit
   on the lighter half, and what you actually get on the darker one below it, so a
   visitor who only reads the top still leaves with the whole offer.

   Its own `plan-` block rather than an extension of `.price-card`, which was a
   single centred panel and could not hold sections. `.price-card` is left in place
   and unused; it is small, and deleting shared styles from under other pages is
   how a stylesheet breaks a page nobody was looking at.
   ────────────────────────────────────────────────────────────────────────── */

.plan {
  max-width: 560px;
  margin: 0 auto;
  border: 1px solid var(--accent-line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: 0 40px 110px rgba(0, 0, 0, 0.55);
}

.plan-top {
  padding: 26px 28px 24px;
  background:
    radial-gradient(120% 130% at 0% 0%, rgba(168, 85, 247, 0.16), transparent 62%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.055), rgba(255, 255, 255, 0.02));
  border-bottom: 1px solid var(--line);
}

.plan-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.plan-tag {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 15px;
  border-radius: 999px;
  border: 1px solid var(--line-2);
  background: rgba(255, 255, 255, 0.04);
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--muted);
}
.plan-tag svg {
  width: 12px;
  height: 12px;
}
.plan-tag.is-lead {
  background: linear-gradient(135deg, #a855f7, #7c3aed);
  border-color: transparent;
  color: #fff;
  font-weight: 600;
  box-shadow: 0 8px 22px rgba(168, 85, 247, 0.3);
}

/* The price, and the local figure beside it rather than a crossed-out one. This is
   the row a fake "was" price would have gone in; what fills it instead is a fact. */
.plan-price {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 20px;
}
.plan-price b {
  font-size: clamp(2.6rem, 8vw, 3.5rem);
  font-weight: 650;
  letter-spacing: -0.035em;
  line-height: 1;
}
.plan-alt {
  font-family: var(--mono);
  font-size: 15px;
  color: var(--muted);
}

.plan-say {
  margin-top: 14px;
  color: var(--muted);
  font-size: 15px;
  max-width: 42ch;
}

.plan-note {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  font-size: 14px;
  color: var(--text);
}
.plan-note .pip {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ok);
  box-shadow: 0 0 9px var(--ok);
  flex: 0 0 7px;
}

/* ── the lower half ─────────────────────────────────────────────────────── */

.plan-body {
  padding: 26px 28px 30px;
  background: rgba(0, 0, 0, 0.28);
}

.plan-h {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
  font-weight: 600;
}
.plan-h + .plan-list,
.plan-h + .plan-chips {
  margin-top: 16px;
}
.plan-body .plan-h ~ .plan-h {
  margin-top: 26px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
}

.plan-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 13px;
}
.plan-list li {
  display: flex;
  gap: 12px;
  align-items: flex-start;
}
.plan-list span {
  font-size: 14.5px;
  font-weight: 500;
  color: var(--text);
}

/* A filled disc rather than a bare tick. At this size a stroke-only check reads as
   a stray mark; a disc reads as a list of things that are settled. */
.plan-list i {
  flex: 0 0 21px;
  width: 21px;
  height: 21px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  color: var(--accent);
  margin-top: 2px;
}
.plan-list i svg {
  width: 11px;
  height: 11px;
}

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

.plan-own {
  margin: 28px 0 14px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
  font-size: 21px;
  font-weight: 620;
  letter-spacing: -0.02em;
}

/* One button, full width, with the arrow in its own disc at the end — so the thing
   to press is unmistakable rather than one of several equal options. */
.plan-cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 8px 8px 8px 24px;
  border-radius: 14px;
  background: linear-gradient(135deg, #a855f7, #7c3aed);
  color: #fff;
  font-size: 15px;
  font-weight: 650;
  letter-spacing: -0.01em;
  box-shadow: 0 14px 36px rgba(168, 85, 247, 0.3);
  transition:
    filter 0.18s,
    transform 0.16s;
}
.plan-cta:hover {
  filter: brightness(1.08);
}
.plan-cta:active {
  transform: translateY(1px);
}
.plan-go {
  flex: 0 0 46px;
  width: 46px;
  height: 46px;
  border-radius: 11px;
  background: #fff;
  color: #1a0b2e;
  display: grid;
  place-items: center;
}
.plan-go svg {
  width: 18px;
  height: 18px;
}

.plan-pay {
  margin-top: 16px;
  text-align: center;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--faint);
}

.plan-legal {
  max-width: 560px;
  margin: 24px auto 0;
  text-align: center;
  font-size: 13.5px;
  color: var(--faint);
}
.plan-legal strong {
  color: var(--muted);
}
.plan-legal a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}

@media (max-width: 720px) {
  .plan-top {
    padding: 22px 20px 20px;
  }
  .plan-body {
    padding: 22px 20px 26px;
  }
  .plan-list span {
    font-size: 14px;
  }
  .plan-cta {
    padding-left: 18px;
    font-size: 14.5px;
  }
  .plan-go {
    flex-basis: 42px;
    width: 42px;
    height: 42px;
  }
}

/* ── two plans, side by side ─────────────────────────────────────────────────
   The second tier is a pre-order, and the styling says so rather than leaving it
   to the words: an amber tag, an amber caveat where the first card has a green
   one, and a "Soon" chip on every line that is not shipping yet. A tier that
   looked identical to the finished one would be the page's one dishonest pixel.
   ────────────────────────────────────────────────────────────────────────── */

.plans {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 22px;
  align-items: stretch;
  max-width: 960px;
  margin: 0 auto;
}

/* ── keeping the two cards level ─────────────────────────────────────────────
   The tiers do not have the same amount to say — nine bullets against seven — so
   left alone their buttons land at different heights and the pair reads as a
   mistake.

   Fixed by making each card a column and letting the *body* stretch, then pushing
   the closing block down with `margin-top: auto`. So the two buttons sit on one
   line whatever is written above them, and adding a bullet to either tier later
   cannot knock them out of alignment again.

   The two upper halves are kept level a different way: both carry the same
   one-line note under the same two-line sentence, so their heights match by
   construction rather than by a hard-coded height that a longer line would break.
   ────────────────────────────────────────────────────────────────────────── */
.plans .plan {
  max-width: none;
  margin: 0;
  display: flex;
  flex-direction: column;
}
.plans .plan-body {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
}

/* The slack goes into the bullet list, not below the button. That is what levels
   "Best for" as well as the button: the list of each card grows to absorb the
   difference, so everything after it starts at the same height in both columns.
   
   `align-content: start` matters. The list is a grid, and a stretched grid would
   spread its rows to fill the new height — bullets drifting apart down the card.
   This packs them at the top and leaves the spare space empty underneath. */
.plans .plan-list {
  flex: 1 1 auto;
  align-content: start;
}

/* The pre-order tier: amber edge rather than violet, so the two are told apart
   before a word is read. */
.plan.is-pro {
  border-color: rgba(251, 191, 36, 0.34);
}
.plan.is-pro .plan-top {
  background:
    radial-gradient(120% 130% at 0% 0%, rgba(251, 191, 36, 0.13), transparent 62%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.055), rgba(255, 255, 255, 0.02));
}
.plan.is-pro .plan-tag.is-lead {
  background: linear-gradient(135deg, #fbbf24, #f59e0b);
  color: #1a1206;
  box-shadow: 0 8px 22px rgba(251, 191, 36, 0.26);
}
.plan.is-pro .plan-h {
  color: var(--warn);
}

.plan-tag.is-soon {
  border-color: rgba(251, 191, 36, 0.4);
  background: rgba(251, 191, 36, 0.1);
  color: var(--warn);
}

/* The pre-order tier's markers match the first card's — the per-line "Soon" chips
   and the amber caveat were removed as visual noise. The timing now lives in the
   card's own sentence, the PRE-ORDER tag, the chip inside the button, and the FAQ. */

/* "Soon", inside the button. Amber-on-amber would vanish, so it is a dark chip on
   the light button rather than the reverse of the chips it replaced. */
.cta-soon {
  display: inline-block;
  margin-left: 9px;
  padding: 2px 9px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.22);
  color: #1a1206;
  font-family: var(--mono);
  font-size: 9.5px;
  font-style: normal;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  vertical-align: 1px;
}
.plan-cta-txt {
  display: inline-flex;
  align-items: center;
}

/* The amber button, for the trading card. It matches that card's own amber tag and lead
   badge, so the second tier reads as one colour from top to bottom instead of wearing an
   amber hat on a purple button. Same values as `.is-soon` below, under a name that says
   what it is rather than when it ships - the forex module is live now. */
.plan-cta.is-amber {
  background: linear-gradient(135deg, #fbbf24, #f59e0b);
  color: #1a1206;
  box-shadow: 0 14px 36px rgba(251, 191, 36, 0.24);
}
.plan-cta.is-amber .plan-go {
  background: rgba(26, 18, 6, 0.16);
  color: #1a1206;
}

/* The pre-order button is deliberately quieter than the one that hands over a
   finished product. */
.plan-cta.is-soon {
  background: linear-gradient(135deg, #fbbf24, #f59e0b);
  color: #1a1206;
  box-shadow: 0 14px 36px rgba(251, 191, 36, 0.24);
}
.plan-cta.is-soon .plan-go {
  color: #1a1206;
}

/* Nothing to click. The hover and press states are removed rather than left to
   fire on an element that does nothing, and the cursor says so. */
.plan-cta.is-off {
  cursor: default;
}
.plan-cta.is-off:hover {
  filter: none;
}
.plan-cta.is-off:active {
  transform: none;
}

@media (max-width: 900px) {
  .plans {
    grid-template-columns: minmax(0, 1fr);
    max-width: 560px;
  }
}

/* ── the subscription strip ──────────────────────────────────────────────────
   Credits, billed monthly, sitting above two licences that are paid once. It is a
   wide strip rather than a third column on purpose: the shape itself says "this is
   a different kind of thing", which is worth more than a label, because the whole
   pricing page rests on Caelia not having a monthly fee.

   Cyan is `--accent-2`, already in the palette. A fourth colour would have made the
   page look like three unrelated offers.
   ────────────────────────────────────────────────────────────────────────── */

.addon {
  max-width: 960px;
  margin: 0 auto 22px;
  border: 1px solid rgba(34, 211, 238, 0.3);
  border-radius: var(--radius);
  background:
    radial-gradient(90% 140% at 0% 0%, rgba(34, 211, 238, 0.1), transparent 60%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0.01));
  padding: 18px;
}

/* The price block and the copy sit side by side; the price column is sized to its
   content so the description gets everything left over. */
.addon-in {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 24px;
  align-items: center;
}

.addon-price {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-right: 24px;
  border-right: 1px solid var(--line);
  min-width: 150px;
}
.addon-name {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent-2);
  font-weight: 600;
}
.addon-fig {
  display: flex;
  align-items: baseline;
  gap: 3px;
}
.addon-fig b {
  font-size: 30px;
  font-weight: 650;
  letter-spacing: -0.03em;
  line-height: 1.1;
}
/* "/mo" is the load-bearing part of this card. Small, but never hidden: it is the
   only thing on the page that recurs. */
.addon-fig i {
  font-style: normal;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--muted);
}

.addon-copy h3 {
  font-size: 16px;
  margin-bottom: 5px;
}
.addon-copy p {
  color: var(--muted);
  font-size: 14px;
  max-width: 74ch;
}

.addon-cta {
  display: block;
  margin-top: 18px;
  padding: 13px 20px;
  border-radius: 11px;
  text-align: center;
  background: linear-gradient(135deg, #22d3ee, #0891b2);
  color: #04222a;
  font-size: 14.5px;
  font-weight: 650;
  transition:
    filter 0.18s,
    transform 0.16s;
}
.addon-cta:hover {
  filter: brightness(1.07);
}
.addon-cta:active {
  transform: translateY(1px);
}

@media (max-width: 720px) {
  .addon {
    padding: 16px;
  }
  /* Stacked, and the divider moves under the price rather than beside it. */
  .addon-in {
    grid-template-columns: minmax(0, 1fr);
    gap: 14px;
  }
  .addon-price {
    flex-direction: row;
    align-items: baseline;
    gap: 12px;
    padding: 0 0 14px;
    border-right: none;
    border-bottom: 1px solid var(--line);
    min-width: 0;
  }
}

/* ── checkout ────────────────────────────────────────────────────────────────
   One page, one job: take a payment and get the receipt back. It does not reuse the
   site header, and the styles are prefixed `co-` so nothing here can leak onto a
   marketing page.
   ────────────────────────────────────────────────────────────────────────── */

.co-top {
  padding: 18px 0;
  border-bottom: 1px solid var(--line);
}
.co-top-in {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.co-back {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 16px;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.03);
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  transition:
    color 0.18s,
    background 0.18s;
}
.co-back:hover {
  color: var(--text);
  background: rgba(255, 255, 255, 0.07);
}
.co-back svg {
  width: 13px;
  height: 13px;
}

.co-wrap {
  padding: 44px 0 80px;
}

.co-card {
  max-width: 760px;
  margin: 0 auto;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0.012));
  padding: 32px;
}

.co-head {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  align-items: flex-start;
  justify-content: space-between;
}
.co-head h1 {
  font-size: clamp(1.6rem, 4vw, 2.1rem);
  font-weight: 650;
  letter-spacing: -0.03em;
}
.co-sub {
  margin-top: 7px;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--faint);
}

/* What is being bought, kept in view the whole way down. A checkout that stops
   showing the price is a checkout people abandon to go and check it. */
.co-plan {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px 18px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: rgba(0, 0, 0, 0.25);
}
.co-plan-k {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  font-weight: 600;
}
.co-plan-v {
  display: flex;
  align-items: baseline;
  gap: 14px;
}
.co-plan-v b {
  font-size: 14.5px;
  font-weight: 600;
}
.co-plan-v i {
  font-style: normal;
  font-size: 26px;
  font-weight: 650;
  letter-spacing: -0.03em;
  padding-left: 14px;
  border-left: 1px solid var(--line-2);
}

.co-rule {
  height: 1px;
  background: var(--line);
  margin: 26px 0;
}

/* ── method tabs ────────────────────────────────────────────────────────── */

/* `auto-fit` rather than a fixed count, so adding or removing a payment method in the
   config needs no CSS change. A hard-coded `repeat(4)` left one empty column the moment
   two methods were dropped. */
.co-tabs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 6px;
  padding: 6px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: rgba(0, 0, 0, 0.25);
}
/* Icon above the label, the way a payment selector normally reads. The icon inherits
   `currentColor`, so the selected state needs no second version of it. */
.co-tab {
  font: inherit;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  padding: 12px 8px 11px;
  border: 1px solid transparent;
  border-radius: 10px;
  background: none;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: center;
  transition:
    background 0.18s,
    color 0.18s,
    border-color 0.18s;
}
.co-tab-ic {
  display: block;
  width: 22px;
  height: 22px;
  opacity: 0.8;
}
.co-tab-ic svg {
  width: 22px;
  height: 22px;
  display: block;
}
.co-tab:hover {
  color: var(--text);
  background: rgba(255, 255, 255, 0.04);
}
.co-tab:hover .co-tab-ic {
  opacity: 1;
}
.co-tab.is-on {
  background: var(--accent-soft);
  border-color: var(--accent-line);
  color: #fff;
  font-weight: 600;
}
.co-tab.is-on .co-tab-ic {
  opacity: 1;
  color: var(--accent);
}

/* ── the chosen method ──────────────────────────────────────────────────── */

.co-body {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: 26px;
  margin-top: 26px;
}

.co-detail {
  padding: 18px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: rgba(0, 0, 0, 0.3);
}
.co-detail-h {
  display: block;
  font-size: 15px;
  margin-bottom: 14px;
}

.co-row {
  padding: 10px 0;
  border-top: 1px solid var(--line);
}
.co-row:first-of-type {
  border-top: none;
  padding-top: 0;
}
.co-row-k {
  display: block;
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: 5px;
}
.co-row-v {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14.5px;
  font-weight: 500;
}
/* An account number is copied character for character, so it is set in the mono face
   and allowed to wrap anywhere rather than being cut off. */
.co-row-v.is-mono {
  font-family: var(--mono);
  font-size: 13px;
  overflow-wrap: anywhere;
}
.co-row-v.is-amt {
  font-size: 19px;
  font-weight: 650;
  color: var(--accent);
}
.co-row-amt {
  border-top: 1px solid var(--line-2);
  margin-top: 4px;
}

.co-copy {
  flex: 0 0 auto;
  margin-left: auto;
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  padding: 6px 11px;
  border: 1px solid var(--line-2);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.05);
  color: var(--text);
  transition: background 0.18s;
}
.co-copy:hover {
  background: rgba(255, 255, 255, 0.11);
}

/* Shown when a method has no published details. It is not an error state - this is
   how every order was taken before the page existed. */
.co-pending b {
  display: block;
  font-size: 15px;
  margin-bottom: 10px;
}
.co-pending p {
  color: var(--muted);
  font-size: 14px;
}
.co-amt-line {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--line-2);
}
.co-amt-line b {
  display: inline;
  font-size: 19px;
  color: var(--accent);
  margin: 0;
}

.co-steps-h {
  display: block;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  font-weight: 600;
  margin-bottom: 14px;
}
.co-steps ol {
  counter-reset: co;
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 13px;
}
.co-steps li {
  counter-increment: co;
  display: grid;
  grid-template-columns: 26px 1fr;
  gap: 11px;
  font-size: 13.5px;
  color: var(--muted);
  line-height: 1.5;
}
.co-steps li::before {
  content: "0" counter(co);
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--accent);
  padding-top: 2px;
}

.co-warn {
  margin-top: 20px;
  padding: 13px 16px;
  border: 1px solid rgba(251, 191, 36, 0.34);
  border-left: 3px solid var(--warn);
  border-radius: 0 10px 10px 0;
  background: rgba(251, 191, 36, 0.07);
  color: #ffd98a;
  font-size: 13.5px;
}

/* ── agreement and the buttons ──────────────────────────────────────────── */

.co-agree {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  margin-top: 24px;
  cursor: pointer;
}
.co-agree input {
  width: 18px;
  height: 18px;
  margin-top: 2px;
  flex: 0 0 18px;
  accent-color: var(--accent);
}
.co-agree span {
  font-size: 14px;
  color: var(--muted);
}
.co-agree a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.co-send {
  display: grid;
  gap: 10px;
}

.co-go {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 8px 8px 8px 20px;
  border-radius: 14px;
  font-size: 15px;
  font-weight: 650;
  transition:
    filter 0.18s,
    transform 0.16s,
    opacity 0.18s;
}
.co-go span {
  margin-right: auto;
}
.co-go-ic {
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
}
.co-go-ic svg {
  width: 22px;
  height: 22px;
}
.co-go-arrow {
  flex: 0 0 44px;
  width: 44px;
  height: 44px;
  border-radius: 11px;
  background: rgba(255, 255, 255, 0.9);
  display: grid;
  place-items: center;
}
.co-go-arrow svg {
  width: 18px;
  height: 18px;
}

.co-go.is-wa {
  background: linear-gradient(135deg, #25d366, #12a150);
  color: #04240f;
}
.co-go.is-wa .co-go-arrow {
  color: #04240f;
}
.co-go.is-tg {
  background: linear-gradient(135deg, #2aabee, #1e87c4);
  color: #04202c;
}
.co-go.is-tg .co-go-arrow {
  color: #04202c;
}
.co-go:not(.is-off):hover {
  filter: brightness(1.06);
}
.co-go:not(.is-off):active {
  transform: translateY(1px);
}

/* Not `pointer-events: none`. The click still lands, so it can move focus to the
   checkbox and explain itself - a button that silently does nothing teaches nobody
   what is missing. */
.co-go.is-off {
  opacity: 0.4;
  cursor: not-allowed;
}

.co-note {
  margin-top: 12px;
  text-align: center;
  font-size: 13px;
  color: var(--warn);
}

.co-trust {
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 8px 22px;
  justify-content: center;
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--faint);
}

.co-foot {
  max-width: 760px;
  margin: 20px auto 0;
  text-align: center;
  font-size: 13.5px;
  color: var(--faint);
}
.co-foot a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}

@media (max-width: 780px) {
  .co-card {
    padding: 22px 18px;
  }
  .co-tabs {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .co-body {
    grid-template-columns: minmax(0, 1fr);
    gap: 22px;
  }
  .co-plan {
    width: 100%;
  }
  .co-go {
    padding-left: 16px;
    font-size: 14.5px;
  }
  .co-go-arrow {
    flex-basis: 40px;
    width: 40px;
    height: 40px;
  }
}

/* ── how many licences ──────────────────────────────────────────────────────
   Asked on the page rather than in the chat, so the amount shown is already the
   amount to transfer. The explanation sits beside the control because "one licence,
   one PC" is the thing people get wrong, not the arithmetic.
   ────────────────────────────────────────────────────────────────────────── */

.co-qty {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  align-items: center;
  justify-content: space-between;
}
.co-qty-h {
  display: block;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  font-weight: 600;
  margin-bottom: 6px;
}
.co-qty-copy p {
  color: var(--muted);
  font-size: 13.5px;
  max-width: 46ch;
}

.co-stepper {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--line-2);
  border-radius: 11px;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.3);
}
.co-step {
  font: inherit;
  cursor: pointer;
  width: 42px;
  border: none;
  background: rgba(255, 255, 255, 0.04);
  color: var(--text);
  font-size: 19px;
  line-height: 1;
  transition:
    background 0.16s,
    color 0.16s;
}
.co-step:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.1);
}
.co-step:disabled {
  color: var(--faint);
  cursor: not-allowed;
}

/* The number is typed as well as stepped, so the field stays a real input. The
   browser's own spinners are removed because there are already two buttons doing that
   job, and two sets of controls on one field is how people mis-click. */
.co-stepper input {
  width: 62px;
  padding: 11px 0;
  border: none;
  border-left: 1px solid var(--line);
  border-right: 1px solid var(--line);
  background: transparent;
  color: var(--text);
  font-family: var(--mono);
  font-size: 16px;
  font-weight: 600;
  text-align: center;
  -moz-appearance: textfield;
  appearance: textfield;
}
.co-stepper input::-webkit-outer-spin-button,
.co-stepper input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.co-stepper input:focus {
  outline: none;
  background: rgba(168, 85, 247, 0.08);
}

/* The multiplication, shown beside the total. Somebody transferring $180 should be
   able to see at a glance where the number came from. */
.co-mult {
  font-family: var(--mono);
  font-style: normal;
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--faint);
  font-weight: 400;
  margin-left: auto;
}

@media (max-width: 560px) {
  .co-qty {
    flex-direction: column;
    align-items: stretch;
  }
  .co-stepper {
    align-self: flex-start;
  }
}

/* ── legal pages ─────────────────────────────────────────────────────────────
   Refund and privacy share a shape: an "at a glance" summary, a table of contents,
   then numbered binding sections. The summary is there because almost nobody reads a
   legal page top to bottom, and the numbered sections are there because the summary
   is not what a dispute is settled on.
   ────────────────────────────────────────────────────────────────────────── */

.legal-lead {
  max-width: 74ch;
}
.legal-lead p {
  color: var(--muted);
  font-size: 15.5px;
  margin: 14px 0;
}

/* The summary box. Deliberately the accent colour rather than a warning colour: it is
   the useful part of the page, not a caution. */
.glance {
  max-width: 74ch;
  margin: 34px 0;
  border: 1px solid var(--accent-line);
  border-radius: var(--radius);
  background:
    radial-gradient(120% 100% at 0% 0%, rgba(168, 85, 247, 0.08), transparent 60%), rgba(255, 255, 255, 0.02);
  padding: 26px 28px;
}
.glance-h {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
  font-weight: 600;
  margin-bottom: 16px;
}
.glance ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 12px;
}
.glance li {
  display: flex;
  gap: 12px;
  font-size: 14.5px;
  color: var(--muted);
  line-height: 1.6;
}
.glance li strong {
  color: var(--text);
}
/* A dot rather than a tick. A tick reads as "good news", and some of these lines are
   not good news - they are just the facts. */
.glance li::before {
  content: "";
  flex: 0 0 6px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  margin-top: 9px;
}
.glance-note {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  font-size: 13px;
  color: var(--faint);
}

/* Contents. A plain ordered list of links, numbered by CSS so the numbers can never
   disagree with the headings they point at. */
.toc {
  max-width: 74ch;
  margin: 0 0 44px;
}
.toc-h {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--faint);
  font-weight: 600;
  margin-bottom: 14px;
}
.toc ol {
  counter-reset: toc;
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 2px;
  border-top: 1px solid var(--line);
}
.toc li {
  counter-increment: toc;
  border-bottom: 1px solid var(--line);
}
.toc a {
  display: flex;
  gap: 14px;
  padding: 11px 4px;
  font-size: 14.5px;
  color: var(--muted);
  transition:
    color 0.18s,
    background 0.18s;
}
.toc a::before {
  content: counter(toc);
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--accent);
  min-width: 18px;
  padding-top: 3px;
}
.toc a:hover {
  color: var(--text);
  background: rgba(255, 255, 255, 0.03);
}

/* The binding sections. Numbered by CSS from the same counter idea, so inserting a
   section renumbers everything after it without a hand edit. */
.clauses {
  counter-reset: clause;
  max-width: 74ch;
}
.clause {
  counter-increment: clause;
  padding: 30px 0;
  border-top: 1px solid var(--line);
}
.clause:first-child {
  border-top: none;
  padding-top: 0;
}
.clause h2 {
  display: flex;
  gap: 14px;
  font-size: 20px;
  margin-bottom: 14px;
  scroll-margin-top: 90px;
}
.clause h2::before {
  content: counter(clause) ".";
  font-family: var(--mono);
  font-size: 14px;
  color: var(--accent);
  padding-top: 4px;
}
.clause h3 {
  font-size: 16px;
  margin: 22px 0 8px;
  color: var(--text);
}
.clause p,
.clause li {
  color: var(--muted);
  font-size: 15px;
}
.clause p {
  margin: 12px 0;
}
.clause ul {
  margin: 12px 0;
  padding-left: 20px;
  display: grid;
  gap: 8px;
}
.clause strong {
  color: var(--text);
}
.clause a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Related documents, at the foot of each legal page. */
.related {
  max-width: 74ch;
  margin-top: 44px;
  padding-top: 26px;
  border-top: 1px solid var(--line);
}
.related-h {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--faint);
  font-weight: 600;
  margin-bottom: 14px;
}
.related .btn-row {
  gap: 10px;
}

@media (max-width: 720px) {
  .glance {
    padding: 20px;
  }
  .clause h2 {
    font-size: 18px;
  }
}

/* ── legal pages: contents as a sidebar ──────────────────────────────────────
   The clauses are capped at 74ch because that is the width prose stays readable
   at, which on a wide screen left the whole right-hand side of these pages empty
   with the contents list stacked above the text. The list belongs beside it: it is
   navigation, and navigation that scrolls away stops being navigation.

   The aside comes FIRST in the markup and is moved to column two by grid, so that
   a keyboard or screen-reader user meets the contents before the eighteen sections
   it indexes, and so the mobile stack puts it there too without a second rule.
   ────────────────────────────────────────────────────────────────────────── */

.legal-grid {
  display: grid;
  grid-template-columns: minmax(0, 74ch) minmax(0, 246px);
  gap: 54px;
  align-items: start;
}
.legal-main {
  grid-column: 1;
  grid-row: 1;
  min-width: 0;
}
.legal-side {
  grid-column: 2;
  grid-row: 1;
}

/* Sticky, and its own scrollbar. Eighteen rows is taller than a laptop viewport, so
   without the max-height the bottom of the list is simply unreachable while stuck. */
.legal-side .toc {
  position: sticky;
  top: 88px;
  margin: 0;
  max-width: none;
  max-height: calc(100vh - 116px);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.legal-side .toc a {
  padding: 8px 8px;
  font-size: 13.5px;
  line-height: 1.35;
}
.legal-side .toc a::before {
  font-size: 10.5px;
  min-width: 15px;
  padding-top: 2px;
}

/* Below the two-column threshold the sidebar is just the old stacked list again. */
@media (max-width: 1060px) {
  .legal-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }
  .legal-main {
    grid-column: 1;
    grid-row: 2;
  }
  .legal-side {
    grid-column: 1;
    grid-row: 1;
  }
  .legal-side .toc {
    position: static;
    max-height: none;
    overflow: visible;
    max-width: 74ch;
    margin-bottom: 44px;
  }
  .legal-side .toc a {
    padding: 11px 4px;
    font-size: 14.5px;
  }
  .legal-side .toc a::before {
    font-size: 11.5px;
    min-width: 18px;
  }
}

/* ── hero video: the sound control ───────────────────────────────────────────
   Autoplay with sound is refused by every current browser, and no attribute or
   setting gets around it. The clip therefore starts muted, and the complaint that
   followed was fair: the sound arrived only if you happened to click somewhere,
   and nothing on screen said so.

   This is the fix - a real control, sitting on the video. It reads "Sound" until
   it has been used, because a bare speaker icon is a guess, and shrinks to the
   icon alone afterwards so it stops competing with the clip. It is a button, not
   an overlay, so it is reachable by keyboard and announces its state.
   ────────────────────────────────────────────────────────────────────────── */

.v-sound {
  position: absolute;
  right: 14px;
  bottom: 14px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 13px 8px 11px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 999px;
  background: rgba(8, 10, 14, 0.62);
  backdrop-filter: blur(10px);
  color: #fff;
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition:
    background 0.18s,
    border-color 0.18s,
    opacity 0.18s,
    transform 0.18s;
}
.v-sound:hover {
  background: rgba(8, 10, 14, 0.82);
  border-color: rgba(255, 255, 255, 0.3);
}
.v-sound:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.v-sound:active {
  transform: scale(0.97);
}

.v-ico {
  display: block;
  flex: 0 0 auto;
}
.v-ico-on {
  display: none;
}

/* Sound on: swap the icon, drop the word, and sit back so it is available without
   being an advertisement. */
.v-sound.is-on .v-ico-off {
  display: none;
}
.v-sound.is-on .v-ico-on {
  display: block;
}
.v-sound.is-on .v-sound-t {
  display: none;
}
.v-sound.is-on {
  padding: 8px;
  opacity: 0.55;
}
.v-sound.is-on:hover {
  opacity: 1;
}

@media (max-width: 620px) {
  .v-sound {
    right: 10px;
    bottom: 10px;
    padding: 7px 11px 7px 9px;
    font-size: 11.5px;
  }
}

/* ── laptop mockup ───────────────────────────────────────────────────────────
   A screenshot sitting in a laptop, drawn in CSS rather than shipped as a second
   picture: no extra download, it stays sharp at any size, and the screenshot can be
   swapped without re-cutting a mockup in an image editor.

   Three parts. The lid is a thick dark bezel with the image inside it. The base is a
   trapezium made with borders, wider than the lid so it reads as the body of the
   machine seen slightly from above. The `i` inside it is the notch on the front edge.

   No aspect-ratio on the screen: the lid takes whatever shape the image has. The
   layout screenshot is 3434x1386, much wider than a real laptop panel, and the choice
   was between an unusually wide device or throwing away a third of the picture. The
   picture wins - it is the reason the section exists.
   ────────────────────────────────────────────────────────────────────────── */

.laptop {
  margin: 0;
  display: block;
}
.laptop-lid {
  position: relative;
  padding: 12px 12px 12px;
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: 16px 16px 6px 6px;
  background: linear-gradient(180deg, #1b1f27 0%, #12151b 60%, #0d1014 100%);
  box-shadow:
    0 2px 0 rgba(255, 255, 255, 0.05) inset,
    0 40px 110px rgba(0, 0, 0, 0.65);
}
/* The camera dot, centred in the top bezel. Two pixels of detail that make the bezel
   read as a lid rather than as a border. */
.laptop-lid::before {
  content: "";
  position: absolute;
  top: 5px;
  left: 50%;
  width: 4px;
  height: 4px;
  margin-left: -2px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.22);
}
.laptop-lid picture,
.laptop-lid img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 4px;
}
.laptop-lid img {
  background: var(--bg-2);
}

/* The body. `border-left`/`right` slanted inwards is the trapezium; the width is
   pushed past the lid with negative margins so it overhangs on both sides. */
.laptop-base {
  position: relative;
  height: 13px;
  margin: 0 -3.4%;
  border-radius: 0 0 12px 12px;
  border-top: none;
  background: linear-gradient(180deg, #23272f 0%, #15181e 55%, #0b0d11 100%);
  box-shadow: 0 22px 40px rgba(0, 0, 0, 0.5);
  clip-path: polygon(0 0, 100% 0, 96.5% 100%, 3.5% 100%);
}
.laptop-base i {
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 13%;
  height: 4px;
  margin-left: -6.5%;
  border-radius: 0 0 6px 6px;
  background: rgba(0, 0, 0, 0.55);
}

@media (max-width: 720px) {
  .laptop-lid {
    padding: 7px;
    border-radius: 11px 11px 4px 4px;
  }
  .laptop-lid::before {
    display: none;
  }
  .laptop-base {
    height: 9px;
  }
}

/* ── hero video: the stage button ────────────────────────────────────────────
   Sits over the whole clip while the sound is off, so the target a visitor has to
   hit is the video itself rather than a small pill in a corner. Hidden with the
   `hidden` attribute from script once sound is on, which leaves the pill as the
   toggle and stops this swallowing clicks it no longer has a reason to take.
   ────────────────────────────────────────────────────────────────────────── */

.v-stage {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.v-stage[hidden] {
  display: none;
}
.v-stage:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -4px;
}

.v-cue {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 11px 18px 11px 15px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 999px;
  background: rgba(8, 10, 14, 0.66);
  backdrop-filter: blur(10px);
  color: #fff;
  font-family: var(--sans);
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1;
  transition:
    background 0.18s,
    border-color 0.18s,
    transform 0.18s;
}
.v-stage:hover .v-cue {
  background: rgba(8, 10, 14, 0.86);
  border-color: rgba(255, 255, 255, 0.34);
  transform: scale(1.03);
}
.v-cue svg {
  display: block;
  flex: 0 0 auto;
}

@media (max-width: 620px) {
  .v-cue {
    padding: 9px 14px 9px 12px;
    font-size: 12.5px;
  }
}

/* ── changelog / release timeline ────────────────────────────────────────────
   A vertical timeline of releases, newest first, the same shape as a good
   product changelog: version number, a date (and a LATEST badge on the newest),
   a one-line title, a short description, then tagged change lines. The tags are
   three fixed kinds - NEW, IMPROVED, FIXED - each its own colour, so the page is
   scannable without reading every line.
   ────────────────────────────────────────────────────────────────────────── */

.log {
  max-width: 760px;
  margin: 0 auto;
}

.rel {
  position: relative;
  padding: 0 0 48px 36px;
  border-left: 1px solid var(--line);
}
.rel:last-child {
  border-left-color: transparent;
  padding-bottom: 0;
}
/* The dot on the line. The ring is the page background so it reads as sitting on
   top of the line rather than threaded onto it. */
.rel::before {
  content: "";
  position: absolute;
  left: -6px;
  top: 7px;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 4px var(--bg);
}
.rel.rel-latest-dot::before {
  box-shadow:
    0 0 0 4px var(--bg),
    0 0 14px var(--accent);
}

.rel-ver {
  font-family: var(--mono);
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--text);
}
.rel-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 9px 0 2px;
  flex-wrap: wrap;
}
.rel-badge {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #fff;
  background: linear-gradient(135deg, #a855f7, #7c3aed);
  padding: 3px 9px;
  border-radius: 999px;
}
.rel-date {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--faint);
}
.rel-title {
  font-size: 19px;
  margin: 14px 0 10px;
}
.rel-desc {
  color: var(--muted);
  font-size: 15px;
  line-height: 1.6;
  margin-bottom: 20px;
  max-width: 66ch;
}

.rel-changes {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 12px;
}
.rel-changes li {
  display: flex;
  gap: 12px;
  align-items: baseline;
  font-size: 14.5px;
  color: var(--muted);
  line-height: 1.55;
}
.tag {
  flex: 0 0 auto;
  min-width: 68px;
  text-align: center;
  font-family: var(--mono);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 6px;
  transform: translateY(1px);
}
.tag-new {
  color: #c084fc;
  background: rgba(168, 85, 247, 0.14);
  border: 1px solid var(--accent-line);
}
.tag-improved {
  color: #22d3ee;
  background: rgba(34, 211, 238, 0.12);
  border: 1px solid rgba(34, 211, 238, 0.3);
}
.tag-fixed {
  color: #34d399;
  background: rgba(52, 211, 153, 0.12);
  border: 1px solid rgba(52, 211, 153, 0.3);
}

@media (max-width: 560px) {
  .rel {
    padding-left: 28px;
  }
  .rel-changes li {
    flex-direction: column;
    gap: 5px;
  }
  .tag {
    min-width: 0;
    align-self: flex-start;
  }
}

/* ── release archive cards ───────────────────────────────────────────────────
   The releases page: one card per build, newest first. Each carries the version,
   the date, a one-line title and description, and a download row. Only the current
   build has a working download; every older card shows an unavailable state, on
   purpose - Caelia updates itself, and a stale installer in circulation is a
   support problem, not a feature.
   ────────────────────────────────────────────────────────────────────────── */

.rls {
  max-width: 820px;
  margin: 0 auto;
  display: grid;
  gap: 16px;
}
.rls-card {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0.012));
  padding: 24px 26px;
}
/* The current build gets the accent edge so it is the obvious one to take. */
.rls-card.is-latest {
  border-color: var(--accent-line);
  background:
    radial-gradient(120% 130% at 0% 0%, rgba(168, 85, 247, 0.1), transparent 55%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.04), rgba(255, 255, 255, 0.012));
}

.rls-head {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.rls-badge {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #fff;
  background: linear-gradient(135deg, #a855f7, #7c3aed);
  padding: 3px 9px;
  border-radius: 999px;
}
.rls-badge-stable {
  color: var(--ok);
  background: rgba(52, 211, 153, 0.12);
  border: 1px solid rgba(52, 211, 153, 0.3);
}
.rls-ver {
  font-family: var(--mono);
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--text);
}
.rls-plat {
  margin-left: auto;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--faint);
}
.rls-title {
  font-size: 17px;
  margin: 16px 0 8px;
}
.rls-desc {
  color: var(--muted);
  font-size: 14.5px;
  line-height: 1.6;
  max-width: 68ch;
}

.rls-foot {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
}
.rls-size {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--faint);
}
/* The unavailable state on older builds. Deliberately looks inert - no hover, a
   muted border, a small lock - so it never reads as a button that failed. */
.rls-na {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 11px 18px;
  border: 1px dashed var(--line-2);
  border-radius: 999px;
  color: var(--faint);
  font-size: 13.5px;
  font-weight: 500;
  cursor: not-allowed;
  user-select: none;
}
.rls-na svg {
  width: 14px;
  height: 14px;
}
.rls-note {
  font-size: 12.5px;
  color: var(--faint);
}
