/* ============================================================================
   Clockwell — clockwell.io landing.

   BRAND.md §11.4 leaves the marketing site undesigned on purpose: "the .io
   landing page needs its own layout system, and nothing here decides it." This
   is that system. Everything the brand book DOES decide is inherited exactly —
   the teal ramp and its role split (§5.2), Inter (§7), the logo rules (§6),
   the voice (§8), and the one accent used sparingly (§9).

   Display type sizes above 24px are new here and deliberate: §7's scale governs
   product UI, where 24 is a page title. A landing page has a headline, which is
   a different job.
   ========================================================================= */

/* ── Inter, self-hosted ──────────────────────────────────────────────────
   Latin subset of the same variable file the app serves via next/font. No
   request leaves the page: a marketing site that phones a font CDN hands a
   visitor log to a third party before anyone has agreed to anything. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("assets/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ── Tokens ─────────────────────────────────────────────────────────────── */
:root {
  /* The ramp, verbatim from brand/tokens.css. */
  --teal-50: #eaf7f8;
  --teal-100: #c7eaee;
  --teal-200: #9fd8de;
  --teal-300: #4fd1db;
  --teal-400: #34c3d1;
  --teal-500: #0e9aa7;
  --teal-600: #0e7c86;
  --teal-700: #0b6e78;
  --teal-800: #0a5c66;
  --teal-900: #06343a;

  /* Roles. --brand is a FILL (3.39:1). --brand-ink carries TEXT (5.97:1).
     Keeping them apart is the single easiest thing to get wrong — §5.2. */
  --brand: var(--teal-500);
  --brand-ink: var(--teal-700);
  --brand-wash: var(--teal-50);
  --brand-edge: var(--teal-100);
  --brand-on: #ffffff;

  --bg: #ffffff;
  --bg-sunken: #f6f8f9;
  --surface: #ffffff;
  --text: #1a1d21;
  --text-muted: #5b6470;
  --text-faint: #8b949e;
  --border: #e4e7eb;
  --border-strong: #cbd2d9;

  --radius: 10px;
  --radius-lg: 14px;
  --radius-xl: 22px;

  --shadow-sm: 0 1px 2px rgba(16, 24, 32, 0.05);
  --shadow-md: 0 4px 16px -4px rgba(16, 24, 32, 0.09), 0 1px 3px rgba(16, 24, 32, 0.05);
  --shadow-lg: 0 24px 60px -20px rgba(9, 40, 46, 0.22), 0 4px 12px rgba(16, 24, 32, 0.05);

  --container: 1140px;
  --header-h: 68px;

  /* One easing everywhere. Calm, not springy — §3 personality. */
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

:root[data-theme="dark"] {
  --brand: var(--teal-400);
  --brand-ink: var(--teal-300);
  --brand-wash: #0c2429;
  --brand-edge: #14454d;
  --brand-on: #06282e;

  --bg: #0e1116;
  --bg-sunken: #0a0d12;
  --surface: #171b22;
  --text: #e8eaed;
  --text-muted: #9aa4b2;
  --text-faint: #6b7684;
  --border: #262c36;
  --border-strong: #3a424f;

  --shadow-md: 0 4px 16px -4px rgba(0, 0, 0, 0.5), 0 1px 3px rgba(0, 0, 0, 0.4);
  --shadow-lg: 0 24px 60px -20px rgba(0, 0, 0, 0.7), 0 4px 12px rgba(0, 0, 0, 0.4);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    --brand: var(--teal-400);
    --brand-ink: var(--teal-300);
    --brand-wash: #0c2429;
    --brand-edge: #14454d;
    --brand-on: #06282e;

    --bg: #0e1116;
    --bg-sunken: #0a0d12;
    --surface: #171b22;
    --text: #e8eaed;
    --text-muted: #9aa4b2;
    --text-faint: #6b7684;
    --border: #262c36;
    --border-strong: #3a424f;

    --shadow-md: 0 4px 16px -4px rgba(0, 0, 0, 0.5), 0 1px 3px rgba(0, 0, 0, 0.4);
    --shadow-lg: 0 24px 60px -20px rgba(0, 0, 0, 0.7), 0 4px 12px rgba(0, 0, 0, 0.4);
  }
}

/* ── Reset ──────────────────────────────────────────────────────────────── */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  scroll-behavior: smooth;
  /* Anchors must not land under the fixed header. */
  scroll-padding-top: calc(var(--header-h) + 16px);
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 16px;
  line-height: 1.6;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img,
svg {
  display: block;
  max-width: 100%;
}
a {
  color: inherit;
  text-decoration: none;
}
button {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  cursor: pointer;
}
ul {
  list-style: none;
}

:focus-visible {
  /* --brand, not --brand-edge: a focus ring carries meaning, so it needs the
     3:1 fill, not the 1.38:1 decorative edge (§5.3). */
  outline: 2px solid var(--brand);
  outline-offset: 3px;
  border-radius: 4px;
}

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

/* ── Layout ─────────────────────────────────────────────────────────────── */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: 24px;
}

section {
  position: relative;
  padding-block: clamp(64px, 9vw, 120px);
}

.skip-link {
  position: absolute;
  left: 12px;
  top: -80px;
  z-index: 200;
  padding: 10px 16px;
  background: var(--surface);
  color: var(--brand-ink);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-weight: 600;
  transition: top 0.15s var(--ease);
}
.skip-link:focus-visible {
  top: 12px;
}

/* ── Type ───────────────────────────────────────────────────────────────── */
h1,
h2,
h3 {
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1.12;
  text-wrap: balance;
}

h1 {
  font-size: clamp(2.35rem, 6.2vw, 4rem);
}
h2 {
  font-size: clamp(1.85rem, 3.9vw, 2.7rem);
}
h3 {
  font-size: 1.125rem;
  line-height: 1.35;
  letter-spacing: -0.015em;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--brand-ink);
}
.eyebrow::before {
  content: "";
  width: 18px;
  height: 1.5px;
  background: var(--brand);
  border-radius: 2px;
}

.lede {
  font-size: clamp(1.0625rem, 1.6vw, 1.1875rem);
  color: var(--text-muted);
  max-width: 56ch;
  text-wrap: pretty;
}

.section-head {
  max-width: 60ch;
  margin-bottom: clamp(40px, 5vw, 64px);
}
.section-head .lede {
  margin-top: 18px;
}
.section-head h2 {
  margin-top: 14px;
}
.section-head.center {
  margin-inline: auto;
  text-align: center;
}
.section-head.center .lede {
  margin-inline: auto;
}

/* ── Buttons ────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  min-height: 46px;
  padding: 0 22px;
  border-radius: var(--radius);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: -0.005em;
  white-space: nowrap;
  transition:
    transform 0.16s var(--ease),
    background-color 0.16s var(--ease),
    border-color 0.16s var(--ease),
    box-shadow 0.16s var(--ease);
}
.btn:active {
  transform: translateY(1px);
}

.btn-primary {
  /* Text on a fill needs --brand-ink beneath it, not --brand: the pair
     --brand-ink / --brand-on is the one measured at 5.97 light, 8.50 dark. */
  background: var(--brand-ink);
  color: var(--brand-on);
  box-shadow: var(--shadow-sm);
}
.btn-primary:hover {
  background: var(--teal-800);
}
:root[data-theme="dark"] .btn-primary:hover {
  background: var(--teal-200);
}

.btn-ghost {
  border: 1px solid var(--border-strong);
  color: var(--text);
  background: var(--surface);
}
.btn-ghost:hover {
  border-color: var(--brand);
  color: var(--brand-ink);
}

.btn-sm {
  min-height: 38px;
  padding: 0 16px;
  font-size: 0.875rem;
}

.btn .arrow {
  transition: transform 0.2s var(--ease);
}
.btn:hover .arrow {
  transform: translateX(3px);
}

/* ── Header ─────────────────────────────────────────────────────────────── */
.header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  height: var(--header-h);
  display: flex;
  align-items: center;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid transparent;
  transition:
    border-color 0.25s var(--ease),
    background-color 0.25s var(--ease);
}
.header.is-scrolled {
  border-bottom-color: var(--border);
  background: color-mix(in srgb, var(--bg) 94%, transparent);
}

.header .container {
  display: flex;
  align-items: center;
  gap: 28px;
}

/* §6.2: horizontal lockup minimum 100px wide. This is 132. The explicit
   width/height matter — the app shipped a 0×0 logo twice because a flex parent
   plus a preflight reset collapsed an SVG with no intrinsic size. */
.logo {
  display: block;
  width: 132px;
  height: 26px;
  flex: none;
}
.logo img {
  width: 132px;
  height: 26px;
}
.logo .on-dark {
  display: none;
}
:root[data-theme="dark"] .logo .on-light {
  display: none;
}
:root[data-theme="dark"] .logo .on-dark {
  display: block;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .logo .on-light {
    display: none;
  }
  :root:not([data-theme]) .logo .on-dark {
    display: block;
  }
}

.nav {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-left: auto;
}
.nav a {
  position: relative;
  padding: 8px 13px;
  border-radius: 8px;
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--text-muted);
  transition: color 0.15s var(--ease);
}
.nav a:hover {
  color: var(--text);
}
.nav a.is-active {
  color: var(--brand-ink);
  font-weight: 600;
}
/* Scroll-spy underline. Colour is never the sole signal (DESIGN.md §2.6): the
   weight changes too, so it survives a monochrome display. */
.nav a.is-active::after {
  content: "";
  position: absolute;
  left: 13px;
  right: 13px;
  bottom: 2px;
  height: 2px;
  border-radius: 2px;
  background: var(--brand);
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

.icon-btn {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 9px;
  color: var(--text-muted);
  border: 1px solid transparent;
  transition:
    background-color 0.15s var(--ease),
    color 0.15s var(--ease);
}
.icon-btn:hover {
  background: var(--bg-sunken);
  color: var(--text);
}
:root[data-theme="dark"] .icon-btn:hover {
  background: var(--surface);
}

.theme-toggle .moon {
  display: none;
}
:root[data-theme="dark"] .theme-toggle .sun {
  display: none;
}
:root[data-theme="dark"] .theme-toggle .moon {
  display: block;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .theme-toggle .sun {
    display: none;
  }
  :root:not([data-theme]) .theme-toggle .moon {
    display: block;
  }
}

.menu-btn {
  display: none;
}

/* Shown only inside the mobile menu panel. */
.nav-signup {
  display: none;
}

/* ── Mobile nav ─────────────────────────────────────────────────────────── */
@media (max-width: 860px) {
  .nav {
    position: fixed;
    inset: var(--header-h) 0 auto 0;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    padding: 12px 20px 20px;
    background: var(--bg);
    border-bottom: 1px solid var(--border);
    box-shadow: var(--shadow-md);
    transform: translateY(-12px);
    opacity: 0;
    visibility: hidden;
    transition:
      transform 0.22s var(--ease),
      opacity 0.22s var(--ease),
      visibility 0.22s;
  }
  .nav.is-open {
    transform: translateY(0);
    opacity: 1;
    visibility: visible;
  }
  .nav a {
    padding: 13px 12px;
    font-size: 1rem;
  }
  .nav a.is-active::after {
    display: none;
  }
  .menu-btn {
    display: grid;
  }
  /* .nav is fixed on mobile, so it leaves the flex row and stops pushing the
     controls right — they were sitting against the logo, mid-header. */
  .header-actions {
    margin-left: auto;
  }
  .nav-signup {
    display: block;
  }
  /* Log in stays in the header at every width — it is the one thing a
     returning user opens the site to do, and burying it behind a hamburger
     costs a tap for the most frequent action on the page. "Create an account"
     is the one that hides, and it reappears inside the menu below. */
  .header-actions .signup-link {
    display: none;
  }
  .nav-signup {
    margin-top: 8px;
    justify-content: center;
    color: var(--brand-ink) !important;
    font-weight: 600 !important;
    background: var(--brand-wash);
    border: 1px solid var(--brand-edge);
    border-radius: var(--radius);
  }
}

/* ── Hero ───────────────────────────────────────────────────────────────── */
.hero {
  padding-top: calc(var(--header-h) + clamp(48px, 7vw, 96px));
  padding-bottom: clamp(56px, 7vw, 104px);
  overflow: hidden;
}

/* Two soft teal washes. Decorative only, so --brand-edge is legitimate here —
   it carries no meaning and needs no contrast (§5.3). */
.hero::before,
.hero::after {
  content: "";
  position: absolute;
  z-index: -1;
  border-radius: 50%;
  filter: blur(70px);
  opacity: 0.5;
  pointer-events: none;
}
.hero::before {
  width: 620px;
  height: 620px;
  top: -280px;
  right: -180px;
  background: radial-gradient(circle, var(--brand-edge), transparent 70%);
}
.hero::after {
  width: 460px;
  height: 460px;
  bottom: -240px;
  left: -200px;
  background: radial-gradient(circle, var(--brand-wash), transparent 70%);
}
:root[data-theme="dark"] .hero::before,
:root[data-theme="dark"] .hero::after {
  opacity: 0.28;
}

.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.02fr) minmax(0, 1fr);
  gap: clamp(36px, 5vw, 68px);
  align-items: center;
}

.hero h1 {
  margin-top: 20px;
}
.hero .lede {
  margin-top: 22px;
  font-size: clamp(1.0625rem, 1.7vw, 1.25rem);
}

.hero-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 34px;
}

.hero-note {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 20px;
  font-size: 0.875rem;
  /* Not --text-faint: at 3.08:1 it failed AA, and this line makes the
     product's strongest commitment. Faint is for decoration, not claims. */
  color: var(--text-muted);
}
.hero-note svg {
  color: var(--brand);
  flex: none;
}

@media (max-width: 900px) {
  .hero-grid {
    grid-template-columns: 1fr;
    gap: 44px;
  }
  .hero-visual {
    order: 2;
  }
}

/* ── The week demo ──────────────────────────────────────────────────────── */
.demo {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}

.demo-bar {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 13px 16px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-sunken);
}
.demo-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--border-strong);
}
.demo-title {
  margin-left: 8px;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text-muted);
}
.demo-elapsed {
  margin-left: auto;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--brand-ink);
  font-variant-numeric: tabular-nums;
}

.demo-body {
  padding: 18px 16px 20px;
}

.wk {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8125rem;
}
.wk th {
  padding: 0 0 10px;
  font-weight: 600;
  font-size: 0.6875rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-faint);
  text-align: center;
}
.wk th:first-child {
  text-align: left;
  min-width: 112px;
}
.wk td {
  padding: 3px 2px;
  text-align: center;
}
.wk td:first-child {
  text-align: left;
  padding-right: 10px;
}

.wk-project {
  font-weight: 600;
  color: var(--text);
  line-height: 1.25;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 128px;
}
.wk-client {
  font-size: 0.6875rem;
  font-weight: 400;
  color: var(--text-faint);
}

/* Cells are the whole animation. A cell is empty, then focused, then filled —
   nothing "loads", nothing spins. §6.3 forbids animating the mark into a
   spinner; this shows the product working instead of the brand waiting. */
.cell {
  display: grid;
  place-items: center;
  width: 100%;
  min-height: 34px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text-faint);
  transition:
    background-color 0.28s var(--ease),
    border-color 0.28s var(--ease),
    color 0.28s var(--ease),
    box-shadow 0.28s var(--ease);
}
.cell.is-focused {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 22%, transparent);
  color: var(--text);
}
.cell.is-filled {
  background: var(--brand-wash);
  border-color: var(--brand-edge);
  color: var(--brand-ink);
}
:root[data-theme="dark"] .cell.is-filled {
  border-color: var(--brand-edge);
}
.cell.is-off {
  background: repeating-linear-gradient(
    -45deg,
    transparent,
    transparent 4px,
    var(--border) 4px,
    var(--border) 5px
  );
  color: var(--text-faint);
  font-size: 0.6875rem;
}

.wk tfoot td {
  padding-top: 12px;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.wk tfoot td:first-child {
  font-size: 0.6875rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-faint);
  font-weight: 600;
}
.wk-total {
  color: var(--brand-ink);
}

.demo-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  border-top: 1px solid var(--border);
  background: var(--bg-sunken);
  font-size: 0.75rem;
  color: var(--text-muted);
}
.demo-kbd {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
kbd {
  display: inline-block;
  min-width: 20px;
  padding: 2px 6px;
  border: 1px solid var(--border-strong);
  border-bottom-width: 2px;
  border-radius: 5px;
  background: var(--surface);
  font-family: inherit;
  font-size: 0.6875rem;
  font-weight: 600;
  text-align: center;
  color: var(--text-muted);
}

.demo-replay {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--brand-ink);
}
.demo-replay:hover {
  text-decoration: underline;
}

/* ── Cards ──────────────────────────────────────────────────────────────── */
/* Explicit breakpoints, not auto-fit. auto-fit with minmax(260px) resolved to
   three columns inside a 1092px content box, which left the fourth card alone
   on its own row directly under a heading that says "Four things". */
.grid-3 {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
}
@media (min-width: 620px) {
  .grid-3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (min-width: 1020px) {
  .grid-3 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.card {
  padding: 28px 26px 30px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  transition:
    transform 0.22s var(--ease),
    border-color 0.22s var(--ease),
    box-shadow 0.22s var(--ease);
}
.card:hover {
  transform: translateY(-3px);
  border-color: var(--brand-edge);
  box-shadow: var(--shadow-md);
}
.card h3 {
  margin-bottom: 10px;
}
.card p {
  color: var(--text-muted);
  font-size: 0.9375rem;
}

/* Spot illustrations: same language as the app's EmptyState — 2px currentColor
   base, 2.5px --brand accent, round caps, no faces, no scenes. */
.spot {
  width: 56px;
  height: 56px;
  margin-bottom: 18px;
  color: var(--border-strong);
}
.card:hover .spot {
  color: var(--text-faint);
}

/* ── The commitment band ────────────────────────────────────────────────── */
.band {
  background: var(--teal-900);
  color: #eaf7f8;
  overflow: hidden;
}
.band::before {
  content: "";
  position: absolute;
  inset: auto auto -50% -10%;
  width: 560px;
  height: 560px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(52, 195, 209, 0.16), transparent 68%);
  filter: blur(50px);
  pointer-events: none;
}
.band h2 {
  color: #ffffff;
}
.band .eyebrow {
  color: var(--teal-300);
}
.band .eyebrow::before {
  background: var(--teal-300);
}
.band .lede {
  color: #b8dde2;
}

.band-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.95fr) minmax(0, 1fr);
  gap: clamp(36px, 5vw, 72px);
  align-items: center;
}
@media (max-width: 880px) {
  .band-grid {
    grid-template-columns: 1fr;
    gap: 36px;
  }
}

/* The band does not use .section-head, so it was inheriting none of its
   spacing — the heading sat flush against the paragraph below it. */
.band-grid h2 {
  margin: 14px 0 18px;
}

.nope {
  display: grid;
  gap: 10px;
}
.nope li {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 15px 18px;
  background: rgba(255, 255, 255, 0.045);
  border: 1px solid rgba(199, 234, 238, 0.14);
  border-radius: var(--radius);
  font-size: 0.9375rem;
  font-weight: 500;
  color: #d7edf0;
}
.nope svg {
  flex: none;
  color: var(--teal-300);
}
.nope .why {
  display: block;
  font-size: 0.8125rem;
  font-weight: 400;
  color: #8fbcc3;
  margin-top: 2px;
}

/* ── Steps ──────────────────────────────────────────────────────────────── */
.steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 20px;
  counter-reset: step;
}
.step {
  position: relative;
  padding: 26px 24px 28px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}
.step::before {
  counter-increment: step;
  content: counter(step);
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  margin-bottom: 16px;
  border-radius: 50%;
  background: var(--brand-wash);
  border: 1px solid var(--brand-edge);
  color: var(--brand-ink);
  font-size: 0.875rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.step h3 {
  margin-bottom: 8px;
}
.step p {
  color: var(--text-muted);
  font-size: 0.9375rem;
}

/* ── Quote ──────────────────────────────────────────────────────────────── */
.quote {
  max-width: 46ch;
  margin-inline: auto;
  text-align: center;
}
.quote blockquote {
  font-size: clamp(1.375rem, 2.8vw, 1.875rem);
  font-weight: 600;
  letter-spacing: -0.022em;
  line-height: 1.28;
  text-wrap: balance;
}
.quote .mark-rule {
  width: 34px;
  height: 3px;
  margin: 0 auto 26px;
  border-radius: 2px;
  background: var(--brand);
}
.quote figcaption {
  margin-top: 20px;
  font-size: 0.875rem;
  color: var(--text-faint);
}

/* ── Coming soon ────────────────────────────────────────────────────────── */
.cta {
  text-align: center;
}
.cta-panel {
  position: relative;
  max-width: 720px;
  margin-inline: auto;
  padding: clamp(38px, 5vw, 60px) clamp(24px, 4vw, 56px);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.cta-panel::before {
  content: "";
  position: absolute;
  inset: -1px -1px auto -1px;
  height: 3px;
  background: linear-gradient(90deg, transparent, var(--brand), transparent);
}
.cta-panel h2 {
  margin-bottom: 16px;
}
.cta-panel .lede {
  margin-inline: auto;
  margin-bottom: 30px;
}

/* The pill states what the button does before it is pressed. A control whose
   label promises an account and then refuses is a small lie, so the promise is
   never made — §8 ("say what happened and what to do"). */
.soon-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 15px 7px 12px;
  margin-bottom: 22px;
  background: var(--brand-wash);
  border: 1px solid var(--brand-edge);
  border-radius: 999px;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--brand-ink);
}
.soon-pill .dot {
  position: relative;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--brand);
}
.soon-pill .dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--brand);
  animation: pulse 2.6s var(--ease) infinite;
}
@keyframes pulse {
  0% {
    transform: scale(1);
    opacity: 0.7;
  }
  70%,
  100% {
    transform: scale(2.6);
    opacity: 0;
  }
}

.soon-note {
  margin-top: 20px;
  font-size: 0.875rem;
  color: var(--text-faint);
}

/* ── Footer ─────────────────────────────────────────────────────────────── */
.footer {
  padding-block: 56px 40px;
  border-top: 1px solid var(--border);
  background: var(--bg-sunken);
}
.footer-top {
  display: flex;
  flex-wrap: wrap;
  gap: 32px;
  justify-content: space-between;
  align-items: flex-start;
}
.footer-tag {
  margin-top: 14px;
  font-size: 0.9375rem;
  color: var(--text-muted);
  max-width: 34ch;
}
.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 28px;
}
.footer-col h4 {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 12px;
}
.footer-col li {
  margin-bottom: 8px;
}
.footer-col a {
  font-size: 0.9375rem;
  color: var(--text-muted);
}
.footer-col a:hover {
  color: var(--brand-ink);
}
.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 24px;
  justify-content: space-between;
  align-items: center;
  margin-top: 44px;
  padding-top: 24px;
  border-top: 1px solid var(--border);
  font-size: 0.8125rem;
  color: var(--text-muted); /* --text-faint measured 2.89:1 on --bg-sunken. */
}
.footer-bottom a {
  color: var(--text-muted);
}
.footer-bottom a:hover {
  color: var(--brand-ink);
}

/* ── Reveal on scroll ───────────────────────────────────────────────────── */
/* Scoped to .js, which the head script sets. A reveal that starts hidden and
   waits for JS to un-hide it means no JS renders a blank page — 13 sections of
   this one, measured. The hidden state only exists if something can undo it. */
.js .reveal {
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity 0.6s var(--ease),
    transform 0.6s var(--ease);
}
.js .reveal.is-in {
  opacity: 1;
  transform: none;
}

/* Motion is decoration here — every animated thing is also legible still.
   Nothing below moves for someone who asked for less of it. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .js .reveal {
    opacity: 1;
    transform: none;
  }
}

/* ── Small screens ──────────────────────────────────────────────────────── */
@media (max-width: 560px) {
  .container {
    padding-inline: 18px;
  }
  .hero-cta .btn {
    width: 100%;
  }
  .wk th:first-child,
  .wk-project {
    min-width: 0;
    max-width: 96px;
  }
  .wk {
    font-size: 0.75rem;
  }
  .cell {
    min-height: 30px;
  }
  .footer-links {
    gap: 24px;
  }
}
