/*
 * Opportunora landing page.
 *
 * Palette: plum and ink on a white page. Plum is everything you click and
 * every highlight; the near-black ink is the headings, the active steps and
 * the small dark panels; the grays lean faintly toward the plum. Display type
 * is Archivo; body is Instrument Sans; numerals are Spline Sans Mono.
 */

:root {
  --plum: #6c3e73;
  --plum-deep: #5c3263;
  --plum-light: #d7addd;
  --plum-tint: #f8eefa;
  --ink: #050609;
  --paper: #ffffff;
  --wash: #f7f7f9;
  --inset: #f5f5f7;
  --line: #e7e5e8;
  --line-strong: #d5d3d7;
  --body: #33353b;
  --label: #4b4d53;
  --muted: #5f6268;
  --on-ink: #ffffff;
  --on-ink-2: #c9cace;
  --on-plum: #ffffff;
  --success: #2c7043;
  --success-tint: #e1f1e6;
  --warn: #885509;
  --warn-tint: #fbefd3;
  --error: #b23a2a;
  --error-tint: #fbe3df;

  --font-display: 'Archivo', 'Instrument Sans', system-ui, sans-serif;
  --font-body: 'Instrument Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono: 'Spline Sans Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;

  --wrap: 1180px;
  --gutter: clamp(20px, 4vw, 40px);
  --section: clamp(72px, 9vw, 132px);
  --pavement: 110px;
  /* The street box the town draws in, at 2400:420. It follows the window from
     1400px up to 2560px, so the shops stop growing at the size a 2560px
     screen shows them. A wider window looks past the ends of the box, where
     tools/town.js draws half a street again on each side, enough for a 5120px
     window. Past that, the box grows again at half the window's width, so the
     ends of the street never show. */
  --street: clamp(1400px, 100vw, max(2560px, 50vw));
  /* The hero stops this far short of the window, so the screenshot under it
     stands in the opening screen instead of waiting below the fold. */
  --peek: clamp(64px, 11svh, 140px);
  /* How far that screenshot stands in front of the storefronts: a tenth of the
     street box's height. It covers the lower half of the doors and shop
     windows and leaves the awnings clear. */
  --stage-rise: calc(var(--street) * 0.0175);
  /* How far the stage climbs into the hero: the pavement, then the rise. */
  --stage-overlap: calc(var(--pavement) + var(--stage-rise));
  --radius: 12px;
  --radius-lg: 20px;
  --shadow-frame: 0 30px 70px -30px rgba(5, 6, 9, 0.3), 0 10px 24px -14px rgba(5, 6, 9, 0.18);
  --shadow-card: 0 14px 34px -22px rgba(5, 6, 9, 0.32);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --sk: rgba(5, 6, 9, 0.11);
  --sk-strong: rgba(5, 6, 9, 0.2);
}

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

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

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.55;
  color: var(--body);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}

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

a {
  color: inherit;
}

button {
  font: inherit;
  color: inherit;
}

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

h1,
h2,
h3 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.025em;
  color: var(--ink);
  margin: 0;
  text-wrap: balance;
}

h2 {
  font-size: clamp(2rem, 1.3rem + 2.8vw, 3.25rem);
}

h3 {
  font-size: 1.25rem;
  letter-spacing: -0.01em;
  line-height: 1.25;
}

p {
  margin: 0;
}

.mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

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

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 100;
  padding: 10px 14px;
  border-radius: 8px;
  background: var(--plum);
  color: var(--on-plum);
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-200%);
}

.skip-link:focus {
  transform: none;
}

[id] {
  scroll-margin-top: 96px;
}

.nowrap {
  white-space: nowrap;
}

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 48px;
  padding: 0 1.25rem;
  border-radius: 10px;
  border: 1px solid transparent;
  font-weight: 600;
  font-size: 0.975rem;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
  white-space: nowrap;
}

.btn:active {
  transform: translateY(1px);
}

.btn-primary {
  background: var(--plum);
  color: var(--on-plum);
}

.btn-primary:hover {
  background: var(--plum-deep);
  box-shadow: 0 8px 20px -10px rgba(108, 62, 115, 0.7);
}

.btn-ghost {
  background: rgba(255, 255, 255, 0.4);
  color: var(--ink);
  border-color: rgba(5, 6, 9, 0.34);
}

.btn-ghost:hover {
  border-color: rgba(5, 6, 9, 0.62);
  background: rgba(5, 6, 9, 0.04);
}

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

.btn-outline:hover {
  background: var(--inset);
}

.btn svg {
  width: 18px;
  height: 18px;
}

/* ---------- Navigation ---------- */

.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 50;
  padding-block: 14px;
  color: var(--ink);
  pointer-events: none;
  transition: background-color 0.25s ease, color 0.25s ease, box-shadow 0.25s ease;
}

.nav > * {
  pointer-events: auto;
}

.nav-primary {
  display: contents;
}

.nav-inner {
  display: flex;
  align-items: center;
  gap: 1.5rem;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.brand-mark {
  width: 34px;
  height: 34px;
  border-radius: 9px;
  background: var(--plum);
  color: var(--on-plum);
  display: grid;
  place-items: center;
}

.brand-mark svg {
  width: 100%;
  height: 100%;
}

.brand-word {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.05em;
  text-transform: lowercase;
}

.brand-dot {
  color: var(--plum);
}

.nav-links {
  display: flex;
  gap: 0.25rem;
  margin-left: auto;
  list-style: none;
  padding: 0;
  margin-block: 0;
}

.nav-links a {
  display: inline-block;
  padding: 8px 12px;
  border-radius: 8px;
  text-decoration: none;
  font-weight: 500;
  font-size: 0.95rem;
  opacity: 0.85;
  transition: opacity 0.15s ease, background-color 0.15s ease;
}

.nav-links a:hover {
  opacity: 1;
  background: rgba(5, 6, 9, 0.05);
}

.nav .btn {
  min-height: 40px;
  padding-inline: 1rem;
  font-size: 0.9rem;
}

/* Sign in sits beside the button rather than among the links, because it
   leaves the page for the app instead of scrolling to a section. */
.nav-actions {
  display: flex;
  align-items: center;
  gap: 0.25rem;
}

.nav-signin {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 40px;
  padding-inline: 12px;
  border-radius: 8px;
  font-weight: 600;
  font-size: 0.9rem;
  text-decoration: none;
  transition: background-color 0.15s ease;
}

.nav-signin:hover {
  background: rgba(5, 6, 9, 0.05);
}

.nav.is-solid .nav-signin:hover {
  background: var(--inset);
}

.nav.is-solid {
  background: rgba(255, 255, 255, 0.88);
  color: var(--ink);
  backdrop-filter: saturate(160%) blur(10px);
  -webkit-backdrop-filter: saturate(160%) blur(10px);
  box-shadow: 0 1px 0 var(--line);
}

.nav.is-solid .nav-links a:hover {
  background: var(--inset);
}

.nav-toggle {
  display: none;
  margin-left: auto;
  width: 44px;
  height: 44px;
  border-radius: 10px;
  border: 1px solid currentColor;
  background: transparent;
  place-items: center;
}

/* ---------- Hero and the town ---------- */

.hero {
  position: relative;
  /* One screen, less the peek, plus the overlap the stage below takes back:
     the top of that screenshot lands --peek above the fold. A floor, not a
     height, so copy that needs more room still gets it. */
  min-height: calc(100svh - var(--peek) + var(--stage-overlap));
  display: flex;
  flex-direction: column;
  color: var(--ink);
  overflow: hidden;
  isolation: isolate;
}

.hero-sky {
  position: absolute;
  inset: 0;
  z-index: -3;
  background: linear-gradient(180deg, var(--paper) 0%, var(--paper) 58%, #fbfafb 100%);
}

.hero-copy {
  position: relative;
  z-index: 2;
  padding-top: clamp(80px, 10.5svh, 124px);
  text-align: center;
  max-width: 900px;
  margin-inline: auto;
}

.hero h1 {
  color: var(--ink);
  /* The headline answers to the window's height as well as its width. At the
     old size a laptop spent four lines on it, which left the street and the
     screenshot below with nothing. Three lines fit, one per phrase, and the
     street keeps the room it needs under them. */
  font-size: clamp(2.4rem, min(1.5rem + 4vw, 5.9svh), 4rem);
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 0.98;
}

/* The plum clause is the payoff, so it starts its own line at every width:
   the sentence above it takes one line on a desktop and two on a phone. */
.hero h1 em {
  display: block;
  font-style: normal;
  color: var(--plum);
}

.hero-sub {
  margin: clamp(0.9rem, 2svh, 1.35rem) auto 0;
  max-width: 640px;
  font-size: clamp(1.05rem, 0.95rem + 0.5vw, 1.3rem);
  line-height: 1.5;
  color: var(--body);
  text-wrap: pretty;
}

.hero-actions {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: clamp(1.25rem, 2.6svh, 1.75rem);
}

.hero-note {
  margin: clamp(0.75rem, 1.5svh, 1rem) auto 0;
  max-width: 520px;
  font-size: 0.85rem;
  color: var(--body);
  text-wrap: pretty;
}

/* The town: three silhouette layers pinned to the bottom of the hero, in
   daylight grays under plum awnings. */

.town {
  position: relative;
  z-index: 1;
  flex: 1;
  /* What the street needs above the pavement: the highest pin stands on 53.4%
     of the street box, and a pin is its chip, its stem and its dot. The clamp
     is the gap that keeps the chips off the copy above them. Together they
     decide where the street lands, and with it how much of the screenshot
     below shows. tools/town.js prints fresh percentages whenever the street
     is regenerated: if the highest pin moves, move the 0.0935 with it. */
  --pin-stem: 34px;
  --pin-reach: calc(var(--street) * 0.0935 + 55px + var(--pin-stem));
  min-height: calc(var(--pin-reach) + clamp(16px, 3svh, 40px) + var(--pavement));
  pointer-events: none;
}

.town-layer {
  position: absolute;
  left: 50%;
  bottom: var(--pavement);
  width: var(--street);
  line-height: 0;
  transform: translate3d(calc(-50% + var(--px, 0px)), calc(var(--lift, 0px) + var(--py, 0px)), 0);
  will-change: transform;
}

/* Each layer draws past both ends of its viewBox, so a window wider than the
   street box sees the street run on instead of stopping. */
.town-svg {
  width: 100%;
  height: auto;
  overflow: visible;
}

.town-far {
  --lift: -150px;
  fill: #f4f3f5;
  z-index: 1;
}

.town-mid {
  --lift: -68px;
  fill: #eae9ec;
  z-index: 2;
}

.town-front {
  --lift: 0px;
  fill: #dddbe0;
  z-index: 3;
}

.town-front .awning {
  fill: var(--plum);
}

.town-front .sign {
  fill: var(--paper);
}

.win {
  fill: var(--paper);
  opacity: 0;
  animation: light-up 0.7s var(--ease-out) forwards;
  animation-delay: calc(0.7s + var(--d, 0) * 1.7s);
}

.town-mid .win {
  fill: #f7f7f8;
}

.town-front .win.door {
  fill: var(--ink);
}

@keyframes light-up {
  from {
    opacity: 0;
  }
  to {
    opacity: 0.92;
  }
}

.town-ground {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--pavement);
  background: var(--wash);
  z-index: 5;
}

/* Lead pins that drop onto three storefronts. */

.pins {
  position: absolute;
  left: 50%;
  bottom: var(--pavement);
  transition: opacity 0.35s ease;
  width: var(--street);
  transform: translate3d(calc(-50% + var(--px, 0px)), var(--py, 0px), 0);
  z-index: 6;
  aspect-ratio: 2400 / 420;
  pointer-events: none;
}

.pins.is-faded {
  opacity: 0;
}

.pin {
  position: absolute;
  left: var(--x);
  bottom: var(--y);
  transform: translate(-50%, 0);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  opacity: 0;
  animation: drop 0.6s var(--ease-out) forwards;
  animation-delay: calc(1s + var(--d, 0) * 1.7s);
  pointer-events: auto;
}

@keyframes drop {
  from {
    opacity: 0;
    transform: translate(-50%, -26px);
  }
  to {
    opacity: 1;
    transform: translate(-50%, 0);
  }
}

/* Each pin hangs over a storefront near the middle of the street. The
   positions are percentages of the street box, so they scale with it, and
   tools/town.js prints a fresh set whenever the town is regenerated. They live
   here rather than in the markup so the narrow-screen layout below can move
   them. --d staggers the drop from left to right. */
.pin:nth-child(1) {
  --x: 24.1%;
  --y: 50.9%;
  --d: 0.24;
}

.pin:nth-child(2) {
  --x: 47.1%;
  --y: 44.9%;
  --d: 0.47;
}

.pin:nth-child(3) {
  --x: 69.6%;
  --y: 53.4%;
  --d: 0.7;
}

.pin-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-radius: 10px;
  background: var(--paper);
  color: var(--ink);
  font-size: 0.85rem;
  font-weight: 600;
  white-space: nowrap;
  /* The ring is a shadow rather than a border, so a white chip keeps its edge
     against the white sky without changing size. */
  box-shadow: 0 0 0 1px var(--line), var(--shadow-card);
}

.pin-chip .badge {
  font-size: 0.7rem;
}

.pin-stem {
  width: 2px;
  height: var(--pin-stem, 34px);
  background: linear-gradient(180deg, var(--plum), rgba(108, 62, 115, 0));
}

.pin-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--plum);
  box-shadow: 0 0 0 6px rgba(108, 62, 115, 0.22);
  margin-top: -6px;
}

/* ---------- Badges ---------- */

.badge {
  display: inline-block;
  padding: 3px 8px;
  border-radius: 99px;
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: 0.01em;
}

.badge-warn {
  background: var(--warn-tint);
  color: var(--warn);
}

.badge-error {
  background: var(--error-tint);
  color: var(--error);
}

.badge-dark {
  background: var(--ink);
  color: var(--on-ink);
}

.badge-success {
  background: var(--success-tint);
  color: var(--success);
}

.badge-accent {
  background: var(--plum-tint);
  color: var(--plum);
}

.badge-neutral {
  background: var(--inset);
  color: var(--label);
}

/* ---------- Screenshot frames ---------- */

.shot {
  border-radius: var(--radius);
  border: 1px solid rgba(5, 6, 9, 0.12);
  background: var(--paper);
  box-shadow: var(--shadow-frame);
  overflow: hidden;
}

.shot img {
  width: 100%;
  height: auto;
}

/* ---------- The stage: the first screenshot stands in front of the street ---------- */

.stage {
  position: relative;
  z-index: 3;
  margin-top: calc(-1 * var(--stage-overlap));
  padding-bottom: var(--section);
}

/* In front of the storefronts the frame needs an edge of its own, or the
   app's pale top bar runs into the white shop windows behind it: a white
   bezel inside the hairline, and a shadow that also rises over the street. */
.stage .shot {
  --bezel: clamp(4px, 0.5vw, 7px);
  padding: var(--bezel);
  border-color: rgba(5, 6, 9, 0.14);
  border-radius: var(--radius-lg);
  box-shadow: 0 -12px 30px -18px rgba(5, 6, 9, 0.3), var(--shadow-frame);
}

.stage .shot img {
  border-radius: calc(var(--radius-lg) - var(--bezel));
  box-shadow: 0 0 0 1px rgba(5, 6, 9, 0.08);
}

.stage-caption {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem 1.5rem;
  margin-top: 1.25rem;
  font-size: 0.9rem;
  color: var(--muted);
}

.stage-caption span {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.stage-caption span::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--plum);
}

/* ---------- Section headers ---------- */

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

.section-head {
  max-width: 760px;
  margin-bottom: clamp(40px, 5vw, 64px);
}

.section-head p {
  margin-top: 1.1rem;
  font-size: clamp(1.05rem, 0.95rem + 0.4vw, 1.2rem);
  color: var(--muted);
  max-width: 600px;
  text-wrap: pretty;
}

.section-head.center {
  margin-inline: auto;
  text-align: center;
}

.section-head.center p {
  margin-inline: auto;
}

.section-tight {
  padding-top: calc(var(--section) * 0.5);
}

/* ---------- The loop: four steps, one storyboard ---------- */

.loop {
  background: var(--paper);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.loop-grid {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(32px, 5vw, 80px);
  align-items: start;
}

.steps {
  list-style: none;
  margin: 0;
  padding: 0;
}

.step {
  position: relative;
  padding: clamp(28px, 4vw, 44px) 0 clamp(28px, 4vw, 44px) 76px;
  border-top: 1px solid var(--line);
  transition: opacity 0.3s ease;
}

.step:last-child {
  border-bottom: 1px solid var(--line);
}

.step-num {
  position: absolute;
  left: 0;
  top: clamp(28px, 4vw, 44px);
  width: 52px;
  height: 52px;
  border-radius: 14px;
  display: grid;
  place-items: center;
  background: var(--inset);
  color: var(--ink);
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.15rem;
  transition: background-color 0.3s ease, color 0.3s ease, transform 0.3s var(--ease-out);
}

.step.is-active .step-num {
  background: var(--ink);
  color: var(--on-ink);
  transform: scale(1.06);
}

.step h3 {
  font-size: clamp(1.4rem, 1.2rem + 0.9vw, 1.9rem);
  letter-spacing: -0.02em;
}

.step p {
  margin-top: 0.7rem;
  color: var(--muted);
  max-width: 48ch;
  text-wrap: pretty;
}

.step-click {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-top: 1.1rem;
  font-size: 0.9rem;
  color: var(--label);
}

.ui-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 12px;
  border-radius: 8px;
  background: var(--ink);
  color: var(--on-ink);
  font-weight: 600;
  font-size: 0.85rem;
  white-space: nowrap;
  box-shadow: 0 1px 2px rgba(5, 6, 9, 0.18), 0 4px 10px -6px rgba(5, 6, 9, 0.3);
}

/* The mock app button inside the product illustrations, in the plum the page
   clicks with. */
.ui-btn.accent {
  background: var(--plum);
  color: var(--on-plum);
}

.ui-btn svg {
  width: 14px;
  height: 14px;
}

.step-shot {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  margin-top: 1.25rem;
}

.storyboard {
  position: sticky;
  top: 110px;
}

.storyboard-stack {
  position: relative;
  aspect-ratio: 16 / 10;
}

.storyboard-stack .shot {
  position: absolute;
  inset: 0;
  opacity: 0;
  transform: translateY(18px) scale(0.985);
  transition: opacity 0.5s var(--ease-out), transform 0.6s var(--ease-out);
}

.storyboard-stack .shot.is-active {
  opacity: 1;
  transform: none;
  z-index: 1;
}

.storyboard-rail {
  display: flex;
  gap: 6px;
  margin-top: 14px;
}

.storyboard-rail span {
  flex: 1;
  height: 4px;
  border-radius: 99px;
  background: var(--line-strong);
  transition: background-color 0.3s ease;
}

.storyboard-rail span.is-active {
  background: var(--plum);
}

/* ---------- Sample sites: ten frames on one scroll ---------- */

/* Two layouts share the markup. Without JavaScript, on a phone, or when the
   visitor asks for less motion, the frames are a strip that scrolls sideways.
   With JavaScript and room for it, main.js adds `is-scene`: the section then
   holds for a few screens while the frames slide past in depth, the centred
   one flat and its neighbours turned away, and the page's own scroll sets
   every position. */

.gallery {
  /* The fixed bar the pinned stage has to clear. */
  --gallery-nav: 84px;
  /* Nine moves between ten frames, and the scroll each one takes. */
  --gallery-steps: 9;
  --gallery-step: 36vh;
  --gallery-word: clamp(3rem, 7.5vw, 8.5rem);
  /* As wide as the window allows, and no taller than what is left of the
     stage once the bar, the trade and the caption have their rows. */
  --card-w: min(84vw, 1100px, calc((100vh - 320px) * 1.6));
  --card-w: min(84vw, 1100px, calc((100svh - 320px) * 1.6));
}

.gallery .section-head {
  margin-bottom: clamp(28px, 4vw, 48px);
}

.gallery-cards {
  position: relative;
  display: flex;
  gap: 18px;
  list-style: none;
  margin: 0;
  /* The first frame lines up with the copy above on a wide screen, and the
     bottom padding leaves room for the frames' shadows inside the scroller. */
  padding: 12px max(var(--gutter), (100% - var(--wrap)) / 2) 36px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: max(var(--gutter), (100% - var(--wrap)) / 2);
}

.gallery-card {
  flex: 0 0 min(84vw, 640px);
  scroll-snap-align: start;
}

.gallery-card figure {
  margin: 0;
}

.gallery-window {
  position: relative;
  border-radius: var(--radius);
}

/* The browser bar: three dots and a pill with the business name. It
   stands above the picture, which the scene scales past the bar's edge. */
.gallery-bar {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  height: 32px;
  padding: 0 12px;
  background: var(--wash);
  border-bottom: 1px solid var(--line);
}

.gallery-dots {
  display: flex;
  gap: 6px;
}

.gallery-dots i {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--line-strong);
}

.gallery-url {
  grid-column: 2;
  min-width: 160px;
  padding: 0 12px;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: var(--paper);
  font-size: 0.7rem;
  line-height: 18px;
  text-align: center;
  color: var(--muted);
  white-space: nowrap;
}

.gallery-window img {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  object-position: top;
  background: var(--inset);
}

.gallery-card figcaption {
  margin-top: 12px;
  font-size: 0.92rem;
  color: var(--muted);
}

.gallery-card figcaption b {
  margin-right: 6px;
  color: var(--ink);
  font-weight: 600;
}

/* Parts the scene draws and the strip has no use for. */
.gallery-trade,
.gallery-count,
.gallery-name,
.gallery-rail {
  display: none;
}

.gallery-status {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 18px;
  width: min(var(--wrap), 100% - 2 * var(--gutter));
  margin-inline: auto;
}

.gallery-controls {
  display: flex;
  gap: 8px;
  margin-left: auto;
}

html:not(.js) .gallery-controls {
  display: none;
}

.gallery-btn {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: var(--paper);
  color: var(--ink);
  cursor: pointer;
  transition: border-color 0.2s ease, opacity 0.2s ease;
}

.gallery-btn svg {
  width: 18px;
  height: 18px;
}

.gallery-btn[data-gallery-dir='-1'] svg {
  transform: scaleX(-1);
}

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

.gallery-btn[aria-disabled='true'] {
  opacity: 0.35;
  cursor: default;
  border-color: var(--line-strong);
}

/* The scene. */

.gallery.is-scene .gallery-track {
  height: calc(100vh + var(--gallery-steps) * var(--gallery-step));
  height: calc(100svh + var(--gallery-steps) * var(--gallery-step));
}

/* Stuck below the fixed bar rather than padded down from the top of the
   window, so the stage sits right under the copy until the pin begins.
   main.js reads the offset back, so the row starts moving as the stage
   sticks and the last frame is centred as it lets go. */
.gallery.is-scene .gallery-stage {
  position: sticky;
  top: var(--gallery-nav);
  display: grid;
  grid-template-rows: auto auto minmax(0, 1fr);
  height: calc(100vh - var(--gallery-nav));
  height: calc(100svh - var(--gallery-nav));
  padding: 0 0 clamp(16px, 3vh, 28px);
  overflow: hidden;
  background: radial-gradient(55% 45% at 50% 58%, rgba(108, 62, 115, 0.07), rgba(108, 62, 115, 0) 70%);
}

/* The trade, set large above the frames. */
.gallery.is-scene .gallery-trade {
  display: block;
  position: relative;
  z-index: 0;
  grid-row: 1;
  height: 0.92em;
  margin: 0;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--gallery-word);
  line-height: 1;
  letter-spacing: -0.04em;
  text-align: center;
  color: rgba(108, 62, 115, 0.16);
  white-space: nowrap;
  pointer-events: none;
  user-select: none;
}

.gallery.is-scene .gallery-trade span {
  display: inline-block;
}

.gallery.is-scene .gallery-trade span.is-in {
  animation: gallery-word 0.55s var(--ease-out) both;
}

@keyframes gallery-word {
  from {
    opacity: 0;
    transform: translateY(0.12em);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

.gallery.is-scene .gallery-scene {
  position: relative;
  z-index: 1;
  grid-row: 3;
}

/* Perspective belongs on the frames' parent: it only reaches children. */
.gallery.is-scene .gallery-cards {
  position: absolute;
  inset: 0;
  display: block;
  padding: 0;
  overflow: visible;
  perspective: 1400px;
}

.gallery.is-scene .gallery-card {
  position: absolute;
  top: 50%;
  left: 50%;
  width: var(--card-w);
  cursor: pointer;
  will-change: transform, opacity;
}

.gallery.is-scene .gallery-card.is-active {
  cursor: default;
}

/* The caption stays for a screen reader; the status row below shows it. */
.gallery.is-scene .gallery-card figcaption {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

.gallery.is-scene .gallery-window img {
  transform-origin: 50% 0;
  will-change: transform;
}

/* Upright, the window is far taller than the frame is; a stage that ends
   under the frame keeps it from floating in the middle of the screen. */
@media (orientation: portrait) {
  .gallery.is-scene .gallery-stage {
    height: min(100vh - var(--gallery-nav), calc(var(--card-w) * 0.625 + 300px));
    height: min(100svh - var(--gallery-nav), calc(var(--card-w) * 0.625 + 300px));
  }
}

/* A veil that thickens as a frame turns away, so the centred one reads
   first. Its opacity is what main.js moves, on a layer of its own, so the
   frame behind it is not painted again on every step. */
.gallery.is-scene .gallery-window::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--paper);
  opacity: var(--dim, 0);
  pointer-events: none;
  will-change: opacity;
}

/* The caption sits between the trade and the frame, clear of the consent
   banner that stands at the foot of the window on a first visit. */
.gallery.is-scene .gallery-status {
  grid-row: 2;
  margin-top: 10px;
}

.gallery.is-scene .gallery-count {
  display: inline;
  font-size: 0.85rem;
  color: var(--label);
}

.gallery.is-scene .gallery-name {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
}

.gallery.is-scene .gallery-name b {
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.gallery.is-scene .gallery-name span {
  font-size: 0.92rem;
  color: var(--muted);
}

/* How far along the ten the visitor is, along the foot of the stage. */
.gallery.is-scene .gallery-rail {
  display: block;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 3px;
  background: var(--line);
}

.gallery.is-scene .gallery-rail i {
  display: block;
  height: 100%;
  background: var(--plum);
  transform-origin: left;
  transform: scaleX(0);
}

/* ---------- The morning screen: annotated dashboard ---------- */

.morning-figure {
  position: relative;
  margin: 0;
  /* The callouts are sized in cqw so they keep the same share of the
     screenshot at every width the annotations are shown at. */
  container-type: inline-size;
}

.callout {
  position: absolute;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: clamp(7px, 0.85cqw, 10px);
  padding: clamp(7px, 0.85cqw, 10px) clamp(10px, 1.2cqw, 14px);
  border-radius: 10px;
  background: var(--ink);
  color: var(--on-ink);
  font-size: clamp(0.72rem, 1.22cqw, 0.9rem);
  font-weight: 600;
  line-height: 1.35;
  box-shadow: var(--shadow-card);
  transform: translate(0, -50%);
  max-width: min(280px, 25cqw);
  text-wrap: pretty;
}

.callout::before {
  content: '';
  width: clamp(8px, 0.85cqw, 10px);
  height: clamp(8px, 0.85cqw, 10px);
  border-radius: 50%;
  background: var(--plum-light);
  box-shadow: 0 0 0 5px rgba(215, 173, 221, 0.25);
  flex: none;
}

.callout-list {
  display: none;
  list-style: none;
  padding: 0;
  margin: 1.25rem 0 0;
  gap: 10px;
}

.callout-list li {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  font-size: 0.95rem;
}

.callout-list li::before {
  content: '';
  flex: none;
  margin-top: 8px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--plum);
}

/* ---------- Product bento ---------- */

.bento {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 18px;
}

.tile {
  grid-column: span 4;
  display: flex;
  flex-direction: column;
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  background: var(--paper);
  overflow: hidden;
  transition: transform 0.35s var(--ease-out), box-shadow 0.35s ease, border-color 0.2s ease;
}

.tile:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-card);
  border-color: var(--line-strong);
}

.tile.half {
  grid-column: span 6;
}

.tile.wide {
  grid-column: span 8;
}

.tile.full {
  grid-column: span 12;
}

.tile.tall {
  grid-row: span 2;
}

.tile.tall .snip {
  flex: 1;
}

.tile-body {
  padding: 20px 22px 24px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.tile-body p {
  color: var(--muted);
  font-size: 0.975rem;
  max-width: 46em;
  text-wrap: pretty;
}

.tile-body-only {
  padding: 26px 28px 30px;
  gap: 10px;
}

.tile-list {
  list-style: none;
  padding: 0;
  margin: 8px 0 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 0.95rem;
}

.tile-list li {
  display: flex;
  gap: 10px;
  align-items: flex-start;
}

.tile-list svg {
  flex: none;
  width: 18px;
  height: 18px;
  margin-top: 3px;
  color: var(--plum);
}

.tile-list-cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px 32px;
}

/* ---------- Snippets: small authored pictures of the product ---------- */

.snip {
  position: relative;
  background: var(--wash);
  border-bottom: 1px solid var(--line);
  padding: 22px;
  min-height: 220px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.snip-card {
  width: 100%;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 10px 24px -18px rgba(5, 6, 9, 0.35);
  font-size: 0.8rem;
  color: var(--label);
}

.sk {
  display: inline-block;
  height: 8px;
  border-radius: 4px;
  background: var(--sk);
  vertical-align: middle;
}

.sk.dark {
  background: var(--sk-strong);
}

.sk.accent {
  background: rgba(108, 62, 115, 0.6);
}

.sk-block {
  border-radius: 6px;
  background: var(--sk);
}

/* Leads table */

.snip-leads .snip-card {
  overflow: hidden;
}

.snip-row {
  display: grid;
  grid-template-columns: 1.3fr 0.9fr 0.8fr 0.5fr 0.5fr 1.6fr;
  gap: 12px;
  align-items: center;
  padding: 12px 16px;
  border-top: 1px solid var(--line);
}

.snip-row.head {
  border-top: 0;
  background: var(--wash);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}

.snip-row .num {
  font-family: var(--font-mono);
  font-weight: 600;
  color: var(--ink);
}

.snip-row .num.hot {
  color: var(--plum);
}

.snip-row .reason {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

/* The first result stays put; the next two stream in, so the table is never
   empty between cycles. */
.snip-leads .snip-row:nth-child(n + 3) {
  opacity: 0;
  transform: translateY(6px);
}

.is-on .snip-leads .snip-row:nth-child(n + 3) {
  animation: appear 7s var(--ease-out) infinite;
}

.is-on .snip-leads .snip-row:nth-child(3) {
  animation-delay: 0.6s;
}

.is-on .snip-leads .snip-row:nth-child(4) {
  animation-delay: 1.6s;
}

@keyframes appear {
  0% {
    opacity: 0;
    transform: translateY(6px);
  }
  8%,
  86% {
    opacity: 1;
    transform: none;
  }
  94%,
  100% {
    opacity: 0;
    transform: translateY(6px);
  }
}

/* Editor chat */

.snip-chat .snip-card {
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.bubble {
  width: 82%;
  padding: 10px 12px;
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.bubble.you {
  align-self: flex-end;
  background: var(--ink);
}

.bubble.you .sk {
  background: rgba(255, 255, 255, 0.35);
}

.bubble.ai {
  align-self: flex-start;
  background: var(--inset);
}

.applied {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border-radius: 8px;
  background: var(--success-tint);
  color: var(--success);
  font-weight: 600;
  font-size: 0.78rem;
}

.applied svg {
  width: 14px;
  height: 14px;
}

/* A change log only grows, so the thread writes itself top to bottom and then
   holds. Nothing fades back out while later messages are still on screen. */
.snip-chat .bubble,
.snip-chat .applied {
  opacity: 0;
}

/* Each message owns its own keyframes rather than sharing one set with a
   delay, because a delay would stagger the exit too. Every message enters at
   its own moment and they all clear together at 80%, so the thread is only
   ever growing or empty. */
.is-on .snip-chat .bubble.you:not(.second) {
  animation: write-in-1 10s linear infinite;
}

.is-on .snip-chat .bubble.ai:not(.second) {
  animation: write-in-2 10s linear infinite;
}

.is-on .snip-chat .applied:not(.second) {
  animation: write-in-3 10s linear infinite;
}

.is-on .snip-chat .bubble.you.second {
  animation: write-in-4 10s linear infinite;
}

.is-on .snip-chat .bubble.ai.second {
  animation: write-in-5 10s linear infinite;
}

.is-on .snip-chat .applied.second {
  animation: write-in-6 10s linear infinite;
}

@keyframes write-in-1 {
  0%,
  4% {
    opacity: 0;
    transform: translateY(6px);
  }
  8.5%,
  80% {
    opacity: 1;
    transform: none;
  }
  85%,
  100% {
    opacity: 0;
    transform: none;
  }
}

@keyframes write-in-2 {
  0%,
  9% {
    opacity: 0;
    transform: translateY(6px);
  }
  13.5%,
  80% {
    opacity: 1;
    transform: none;
  }
  85%,
  100% {
    opacity: 0;
    transform: none;
  }
}

@keyframes write-in-3 {
  0%,
  14% {
    opacity: 0;
    transform: translateY(6px);
  }
  18.5%,
  80% {
    opacity: 1;
    transform: none;
  }
  85%,
  100% {
    opacity: 0;
    transform: none;
  }
}

@keyframes write-in-4 {
  0%,
  21% {
    opacity: 0;
    transform: translateY(6px);
  }
  25.5%,
  80% {
    opacity: 1;
    transform: none;
  }
  85%,
  100% {
    opacity: 0;
    transform: none;
  }
}

@keyframes write-in-5 {
  0%,
  26% {
    opacity: 0;
    transform: translateY(6px);
  }
  30.5%,
  80% {
    opacity: 1;
    transform: none;
  }
  85%,
  100% {
    opacity: 0;
    transform: none;
  }
}

@keyframes write-in-6 {
  0%,
  31% {
    opacity: 0;
    transform: translateY(6px);
  }
  35.5%,
  80% {
    opacity: 1;
    transform: none;
  }
  85%,
  100% {
    opacity: 0;
    transform: none;
  }
}

.snip-input {
  margin-top: 4px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
}

.snip-input .send {
  margin-left: auto;
  width: 22px;
  height: 22px;
  border-radius: 6px;
  background: var(--ink);
}

/* Validation checks */

.snip-checks .snip-card {
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

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

.check i {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 1.5px solid var(--line-strong);
  display: grid;
  place-items: center;
  color: #fff;
  flex: none;
}

.check i svg {
  width: 11px;
  height: 11px;
  opacity: 0;
}

.is-on .snip-checks .check i {
  animation: tick 6s ease-out infinite;
}

.is-on .snip-checks .check i svg {
  animation: tick-mark 6s ease-out infinite;
}

.is-on .snip-checks .check:nth-child(1) i,
.is-on .snip-checks .check:nth-child(1) i svg {
  animation-delay: 0.2s;
}

.is-on .snip-checks .check:nth-child(2) i,
.is-on .snip-checks .check:nth-child(2) i svg {
  animation-delay: 0.7s;
}

.is-on .snip-checks .check:nth-child(3) i,
.is-on .snip-checks .check:nth-child(3) i svg {
  animation-delay: 1.2s;
}

.is-on .snip-checks .check:nth-child(4) i,
.is-on .snip-checks .check:nth-child(4) i svg {
  animation-delay: 1.7s;
}

.is-on .snip-checks .check:nth-child(5) i,
.is-on .snip-checks .check:nth-child(5) i svg {
  animation-delay: 2.2s;
}

@keyframes tick {
  0%,
  4% {
    background: transparent;
    border-color: var(--line-strong);
  }
  8%,
  88% {
    background: var(--success);
    border-color: var(--success);
  }
  96%,
  100% {
    background: transparent;
    border-color: var(--line-strong);
  }
}

@keyframes tick-mark {
  0%,
  4% {
    opacity: 0;
  }
  8%,
  88% {
    opacity: 1;
  }
  96%,
  100% {
    opacity: 0;
  }
}

.check-total {
  margin-top: 4px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: space-between;
  font-size: 0.78rem;
  color: var(--muted);
}

.check-total b {
  font-family: var(--font-mono);
  color: var(--ink);
}

/* Company page */

.snip-company .snip-card {
  overflow: hidden;
}

.company-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
}

.company-head .avatar {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  background: var(--plum-tint);
  flex: none;
}

.company-head .titles {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1;
}

.next-step {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  background: var(--ink);
  color: var(--on-ink);
  font-size: 0.75rem;
}

.next-step .label {
  color: var(--on-ink-2);
}

.next-step .ui-btn {
  margin-left: auto;
  padding: 5px 9px;
  font-size: 0.72rem;
}

.company-grid {
  display: grid;
  /* The Opportunities label is the widest of the three, so column one gets the extra room. */
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr) minmax(0, 1fr);
  gap: 8px;
  padding: 12px 16px 14px;
}

.company-grid > div {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.company-grid .cap {
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 2px;
}

/* Opportunities board */

.snip-board {
  padding: 18px;
}

.board {
  width: 100%;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
  position: relative;
}

.col {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 8px;
  min-height: 176px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.col-head {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--label);
  padding: 2px 4px 6px;
}

.col-head i {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--line-strong);
}

.col:nth-child(2) .col-head i {
  background: #5b9cba;
}

.col:nth-child(3) .col-head i {
  background: var(--plum);
}

.col:nth-child(4) .col-head i {
  background: var(--success);
}

.card {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: var(--paper);
}

.card.ghost {
  border-style: dashed;
  background: transparent;
}

.card.mover {
  position: absolute;
  top: 36px;
  left: 8px;
  width: calc(25% - 22px);
  border-color: var(--plum);
  box-shadow: 0 10px 20px -12px rgba(5, 6, 9, 0.45);
  z-index: 2;
}

.is-on .card.mover {
  animation: move 9s var(--ease-out) infinite;
}

@keyframes move {
  0%,
  18% {
    transform: translateX(0);
  }
  30%,
  48% {
    transform: translateX(calc(100% + 16px));
  }
  60%,
  78% {
    transform: translateX(calc(200% + 32px));
  }
  90%,
  100% {
    transform: translateX(calc(300% + 48px));
  }
}

/* Invoice */

.snip-invoice .snip-card {
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: 300px;
}

.inv-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
}

.inv-head .logo {
  width: 28px;
  height: 28px;
  border-radius: 7px;
  background: var(--plum);
}

.inv-status {
  position: relative;
  width: 58px;
  height: 22px;
}

.inv-status .badge {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  opacity: 0;
}

.inv-status .badge:nth-child(1) {
  opacity: 1;
}

.is-on .inv-status .badge:nth-child(1) {
  animation: cycle 9s steps(1) infinite;
}

.is-on .inv-status .badge:nth-child(2) {
  animation: cycle 9s steps(1) 3s infinite;
}

.is-on .inv-status .badge:nth-child(3) {
  animation: cycle 9s steps(1) 6s infinite;
}

@keyframes cycle {
  0%,
  33% {
    opacity: 1;
  }
  34%,
  100% {
    opacity: 0;
  }
}

.inv-lines {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.inv-line {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
}

.inv-total {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-top: 10px;
  border-top: 1px solid var(--line-strong);
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--ink);
}

/* ---------- Pricing ---------- */

.pricing {
  background: var(--paper);
  border-top: 1px solid var(--line);
}

.billing-toggle {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px;
  border-radius: 99px;
  background: var(--inset);
  border: 1px solid var(--line);
  margin: 0 auto 3.25rem;
}

.billing-toggle button {
  border: 2px solid transparent;
  background: transparent;
  padding: 6px 14px;
  border-radius: 99px;
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--label);
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease;
}

.billing-toggle button[aria-pressed='true'] {
  background: var(--ink);
  color: var(--on-ink);
}

.billing-toggle button[aria-pressed='true'] .save {
  color: var(--plum-light);
}

.billing-toggle .save {
  margin-left: 6px;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--plum);
}

.tiers {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
  align-items: stretch;
}

.tier {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 28px 28px 30px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  background: var(--wash);
}

/* The recommended plan rides above the row. The negative margin grows the card
   upward while grid stretch keeps its foot on the same line as its neighbors.
   It stays white; a plum ring sets it apart. */
.tier.featured {
  margin-top: -18px;
  padding-top: 36px;
  background: var(--paper);
  border-color: var(--plum);
  box-shadow: 0 0 0 1px var(--plum), 0 36px 70px -30px rgba(5, 6, 9, 0.38);
}

.tier h3 {
  font-size: 1.25rem;
}

/* Two lines whatever the plan, so every card's price sits on the same line. */
.tier-audience {
  margin-top: 6px;
  min-height: 3.1em;
  font-size: 0.95rem;
  color: var(--muted);
  max-width: 30ch;
}

.tier-price {
  margin-top: 22px;
  display: flex;
  align-items: baseline;
  gap: 6px;
}

.tier-price .amount {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 2.6rem;
  letter-spacing: -0.03em;
  color: var(--ink);
}

.tier-price .per {
  color: var(--muted);
  font-size: 0.95rem;
}

.tier-billed {
  font-size: 0.82rem;
  color: var(--muted);
  min-height: 1.4em;
  margin-top: 4px;
}

.tier .btn {
  margin-top: 22px;
}

.tier-includes {
  list-style: none;
  padding: 0;
  margin: 24px 0 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  font-size: 0.95rem;
}

.tier-includes li {
  display: flex;
  gap: 10px;
  align-items: flex-start;
}

.tier-includes svg {
  flex: none;
  width: 18px;
  height: 18px;
  margin-top: 3px;
  color: var(--success);
}

.tier.featured .tier-includes svg {
  color: var(--plum);
}

.tier-flag {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translate(-50%, -50%);
  padding: 5px 14px;
  background: var(--plum);
  color: var(--on-plum);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  box-shadow: 0 8px 18px -10px rgba(5, 6, 9, 0.55);
}

.pricing-notes {
  margin-top: 28px;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
}

.pricing-capacity {
  max-width: 65ch;
  margin: 24px auto 0;
  text-align: center;
}

.note {
  padding: 20px 22px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--wash);
  font-size: 0.95rem;
  color: var(--label);
  text-wrap: pretty;
}

.note strong {
  color: var(--ink);
}

.packages {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
}

.packages span {
  display: inline-flex;
  gap: 8px;
  align-items: baseline;
  padding: 6px 10px;
  border-radius: 8px;
  background: var(--paper);
  border: 1px solid var(--line);
  font-size: 0.88rem;
}

.packages b {
  font-family: var(--font-mono);
  font-weight: 600;
  color: var(--ink);
}

/* ---------- FAQ ---------- */

.faq-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 0 40px;
  align-items: start;
}

.faq {
  border-top: 1px solid var(--line);
}

.faq-col > .faq:last-child {
  border-bottom: 1px solid var(--line);
}

.faq summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 20px 0;
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--ink);
}

.faq summary::-webkit-details-marker {
  display: none;
}

.faq summary:hover {
  color: var(--plum);
}

.faq summary svg {
  flex: none;
  width: 20px;
  height: 20px;
  color: var(--plum);
  transition: transform 0.3s var(--ease-out);
}

.faq summary:hover svg {
  transform: scale(1.12);
}

.faq[open] summary svg,
.faq[open] summary:hover svg {
  transform: rotate(45deg);
}

.faq-body {
  padding: 0 0 22px;
  color: var(--body);
  max-width: 60ch;
  text-wrap: pretty;
}

.faq-body p + p {
  margin-top: 0.75rem;
}

.faq-body code {
  font-family: var(--font-mono);
  font-size: 0.88em;
  background: var(--inset);
  padding: 1px 6px;
  border-radius: 5px;
}

/* ---------- Final CTA: the street again ---------- */

.cta {
  position: relative;
  color: var(--ink);
  overflow: hidden;
  isolation: isolate;
  padding-top: var(--section);
}

.cta-sky {
  position: absolute;
  inset: 0;
  z-index: -2;
  background: linear-gradient(180deg, var(--paper) 0%, #fbfafb 100%);
}

.cta .town {
  z-index: 1;
  min-height: clamp(260px, 34vh, 380px);
  margin-top: 72px;
}

.cta .town-far {
  --lift: -60px;
}

.cta .town-mid {
  --lift: -26px;
}

.cta .win {
  animation-delay: calc(0.2s + var(--d, 0) * 1.2s);
  animation-play-state: paused;
}

.cta.is-visible .win {
  animation-play-state: running;
}

.cta-copy {
  position: relative;
  z-index: 2;
  text-align: center;
  max-width: 760px;
  margin-inline: auto;
}

.cta h2 {
  color: var(--ink);
  font-size: clamp(2.2rem, 1.5rem + 3.4vw, 4rem);
}

.cta p {
  margin-top: 1.1rem;
  color: var(--body);
  font-size: 1.1rem;
  max-width: 560px;
  margin-inline: auto;
}

.cta-actions {
  display: flex;
  justify-content: center;
  margin-top: 2rem;
}

.cta .cta-small {
  margin-top: 0.9rem;
  font-size: 0.85rem;
  color: var(--body);
}

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

.footer {
  background: var(--wash);
  color: var(--body);
  padding: 48px 0 32px;
  font-size: 0.92rem;
}

/* The brand block plus the three lists in .footer-nav, which is display:contents
   and so puts its own children on this grid. Add a list, add a column. */
.footer-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: 32px;
}

.footer-nav {
  display: contents;
}

.footer-heading {
  margin: 0 0 12px;
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink);
}

.footer ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.footer ul a,
.footer-link {
  display: inline-block;
  padding: 3px 0;
  text-decoration: none;
  opacity: 0.85;
}

.footer-link {
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  text-align: left;
}

.footer ul a:hover,
.footer-link:hover {
  opacity: 1;
  text-decoration: underline;
}

.footer .brand {
  color: var(--ink);
}

.footer-tagline {
  margin-top: 12px;
  max-width: 34ch;
  text-wrap: pretty;
}

.footer-bottom {
  margin-top: 40px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 12px 24px;
  justify-content: space-between;
  font-size: 0.85rem;
}

/* ---------- Cookie consent ---------- */

.cookie-consent[hidden] {
  display: none;
}

/* A wide, low bar of a card, centred above the bottom edge. Wide keeps it out
   of the hero copy; a capped width keeps it from spanning the page, which read
   as a second footer. Insetting both sides and letting the inline margins take
   the slack centres it without a transform, which would fight the entrance
   animation below. */
.cookie-consent {
  position: fixed;
  z-index: 100;
  left: 16px;
  right: 16px;
  bottom: 20px;
  margin-inline: auto;
  max-width: 880px;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 20px;
  padding: 18px 22px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--paper);
  color: var(--body);
  box-shadow: var(--shadow-frame);
  animation: cookie-rise 0.4s var(--ease-out) both;
}

@keyframes cookie-rise {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
}

.cookie-consent-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: var(--plum-tint);
  color: var(--plum);
}

.cookie-consent-icon svg {
  width: 20px;
  height: 20px;
}

.cookie-consent h2 {
  font-size: 1.05rem;
  line-height: 1.25;
  letter-spacing: -0.01em;
}

.cookie-consent p {
  margin: 4px 0 0;
  color: var(--muted);
  font-size: 0.875rem;
  line-height: 1.45;
  text-wrap: pretty;
}

.cookie-consent-actions {
  display: flex;
  gap: 10px;
}

.cookie-consent-actions .btn {
  flex: 0 0 auto;
  min-height: 42px;
  padding-inline: 1rem;
  font-size: 0.9rem;
}

/* Below this the row would squeeze the copy into a narrow column and the card
   would grow taller than the wide layout saves. Drop the copy and the buttons
   to their own rows, but keep the icon beside the heading rather than above it,
   which costs a whole row for a 36px mark. */
@media (max-width: 820px) {
  .cookie-consent {
    grid-template-columns: auto minmax(0, 1fr);
    align-items: start;
    gap: 12px 14px;
    padding: 20px;
    max-width: 420px;
  }

  /* Promote the heading and the paragraph to grid items so the paragraph can
     run the full width of the card rather than sit in the narrow column beside
     the icon, where it ran to five lines. */
  .cookie-consent-copy {
    display: contents;
  }

  .cookie-consent h2 {
    align-self: center;
  }

  .cookie-consent-copy p,
  .cookie-consent-actions {
    grid-column: 1 / -1;
  }

  .cookie-consent-copy p {
    margin: 0;
  }

  .cookie-consent-actions {
    flex-wrap: wrap;
  }

  /* Sized by their own labels, so the pair splits onto two rows only when the
     card really is too narrow for both. */
  .cookie-consent-actions .btn {
    flex: 1 1 auto;
    padding-inline: 0.75rem;
  }
}

/* ---------- Responsive ---------- */

@media (max-width: 1080px) {
  .tile,
  .tile.wide,
  .tile.half {
    grid-column: span 6;
  }

  .tile.full {
    grid-column: span 12;
  }

  .tile.tall {
    grid-row: span 1;
  }

  .step {
    padding-left: 64px;
  }

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

/* The street is 1400px wide, so on a narrower screen its ends hang off both
   edges and pins placed on it land out of sight. Below this width the pins
   measure against the viewport instead and cascade down the street, so all
   three finds stay on screen. */
@media (max-width: 960px) {
  .pins {
    width: 100%;
    /* The street layers are 1400px wide here, which makes them 245px tall. */
    height: 245px;
  }

  /* The screenshot below covers the bottom tenth of this box, so the cascade
     starts at 15%, where the lowest dot still clears the frame, and keeps its
     even 32-point steps from there. */
  .pin:nth-child(1) {
    --x: 34%;
    --y: 79%;
  }

  .pin:nth-child(2) {
    --x: 62%;
    --y: 47%;
  }

  .pin:nth-child(3) {
    --x: 40%;
    --y: 15%;
  }

  /* Shorter stems keep the three chips from running into each other, and the
     street the cascade hangs on is that fixed 245px, not the window's width. */
  .town {
    --pin-stem: 22px;
    --pin-reach: calc(245px * 0.79 + 55px + var(--pin-stem));
  }
}

/* A window this short needs the chips closer to the street than a full stem
   holds them, and every pixel it saves goes to the screenshot below. */
@media (max-height: 820px) {
  .hero .town {
    --pin-stem: 22px;
  }
}

@media (max-width: 900px) {
  .nav-links,
  .nav-actions {
    display: none;
  }

  .nav-toggle {
    display: grid;
  }

  /* The open menu is a white panel over a white page, so it carries its own
     edge and a shadow to sit above the copy behind it. */
  .nav.is-open {
    background: var(--paper);
    color: var(--ink);
    box-shadow: 0 1px 0 var(--line), 0 20px 40px -30px rgba(5, 6, 9, 0.5);
  }

  .nav.is-open .nav-inner {
    flex-wrap: wrap;
  }

  .nav.is-open .nav-links {
    display: flex;
    flex-direction: column;
    width: 100%;
    margin: 12px 0 8px;
    gap: 2px;
  }

  .nav.is-open .nav-links a {
    padding: 12px;
    font-size: 1.05rem;
  }

  /* In the open menu, both actions become full-width buttons under the
     links, Sign in outlined and the trial filled. */
  .nav.is-open .nav-actions {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    width: 100%;
    gap: 8px;
  }

  .nav.is-open .nav-signin {
    border: 1px solid var(--line-strong);
    border-radius: 10px;
  }

  .nav.is-open .btn {
    display: inline-flex;
    width: 100%;
  }

  .loop-grid,
  .pricing-notes,
  .faq-grid {
    grid-template-columns: 1fr;
  }

  .storyboard {
    display: none;
  }

  .step-shot {
    position: static;
    width: auto;
    height: auto;
    overflow: hidden;
    clip: auto;
    clip-path: none;
  }

  .step {
    padding-left: 0;
    padding-top: 84px;
  }

  .step-num {
    top: 22px;
  }

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

  .tier.featured {
    order: -1;
    margin-top: 0;
  }

  .callout {
    display: none;
  }

  .callout-list {
    display: flex;
    flex-direction: column;
  }

  .tile-list-cols {
    grid-template-columns: 1fr;
  }

  .snip-row {
    grid-template-columns: 1.3fr 0.9fr 0.8fr 0.5fr 0.5fr;
  }

  .snip-row .reason {
    display: none;
  }
}

@media (max-width: 640px) {
  .tile,
  .tile.wide,
  .tile.half {
    grid-column: span 12;
  }

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

  /* On :root rather than .town, so the stage's overlap, which is worked out
     there, climbs the phone's shorter pavement and not the desktop one. */
  :root {
    --pavement: 56px;
  }

  /* A phone is too narrow to hold "Find local businesses" on one line at the
     2.4rem floor above, so the headline breaks mid-phrase and spends five
     lines on three clauses. This sizes it to the window instead: the first
     line fills, and each clause gets a line of its own. */
  .hero h1 {
    font-size: clamp(1.6rem, 9.4vw - 3.9px, 2.4rem);
  }

  /* A phone gets one button. The second action only jumps down the page, so
     it reads as a link instead of a second block competing with the first. */
  .hero-actions {
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
  }

  .hero-actions .btn-primary {
    width: 100%;
  }

  .hero-actions .btn-ghost {
    background: none;
    border-color: transparent;
    text-decoration: underline;
    text-decoration-color: rgba(5, 6, 9, 0.35);
    text-underline-offset: 5px;
  }

  /* A phone spends its first screen on the headline and the intro, so the
     street follows the copy rather than closing the screen. The height the
     pins need comes from .town above; this adds a little air under the note. */
  .town {
    margin-top: clamp(12px, 2vh, 28px);
  }

  .town-far {
    --lift: -50px;
  }

  .town-mid {
    --lift: -24px;
  }

  /* Three chips only fit across a phone once the lead score drops off. The
     name and the verdict on the website are what the pins are there to show. */
  .pin-chip {
    padding: 6px 10px;
    font-size: 0.78rem;
  }

  .pin-chip .mono {
    display: none;
  }

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

  /* Four columns leave about 50px of card, which cuts the badge labels. */
  .board {
    grid-template-columns: 1fr 1fr;
  }

  .card.mover {
    display: none;
  }
}

@media (forced-colors: active) {
  .billing-toggle button[aria-pressed='true'],
  .step.is-active .step-num {
    outline: 2px solid ButtonText;
    outline-offset: -2px;
  }
}

/* ---------- Without JavaScript ---------- */

/* The snippets and the storyboard reveal on an IntersectionObserver, so with
   no script they would sit at opacity 0 forever. Show their resting state. */

html:not(.js) .snip-leads .snip-row:nth-child(n + 3),
html:not(.js) .snip-chat .bubble,
html:not(.js) .snip-chat .applied,
html:not(.js) .snip-checks .check i svg,
html:not(.js) .storyboard-stack .shot:first-child,
html:not(.js) .inv-status .badge:first-child {
  opacity: 1;
  transform: none;
}

html:not(.js) .snip-checks .check i {
  background: var(--success);
  border-color: var(--success);
}

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

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

  .win,
  .pin,
  .cookie-consent {
    animation: none;
  }

  .win {
    opacity: 0.92;
  }

  .pin {
    opacity: 1;
  }

  .is-on .snip-leads .snip-row:nth-child(n + 3),
  .is-on .snip-chat .bubble,
  .is-on .snip-chat .applied,
  .is-on .snip-checks .check i,
  .is-on .snip-checks .check i svg,
  .is-on .card.mover,
  .is-on .inv-status .badge {
    animation: none;
  }

  .snip-leads .snip-row:nth-child(n + 3),
  .snip-chat .bubble,
  .snip-chat .applied,
  .snip-checks .check i svg {
    opacity: 1;
    transform: none;
  }

  .snip-checks .check i {
    background: var(--success);
    border-color: var(--success);
  }

  .inv-status .badge:nth-child(3) {
    opacity: 1;
  }

  .inv-status .badge:nth-child(1),
  .inv-status .badge:nth-child(2) {
    opacity: 0;
  }

  .storyboard-stack .shot,
  .tile,
  .step-num {
    transition: none;
  }
}

/* ---------- Page shell: legal pages and the blog ---------- */

/* privacy.html and terms.html carry these class names by hand; the
   generated blog pages carry them alongside their own, so a post reads
   `legal-hero post-hero` and the two page types cannot drift apart. */

/* The band a page opens on, under the fixed bar. */
.legal-hero {
  position: relative;
  padding: calc(68px + clamp(48px, 7vw, 88px)) 0 clamp(40px, 6vw, 72px);
  background: linear-gradient(180deg, var(--paper) 0%, var(--paper) 70%, #fbfafb 100%);
  color: var(--ink);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
}

.legal-hero > .wrap {
  position: relative;
  z-index: 1;
}

.legal-eyebrow {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--plum);
}

.legal-hero h1 {
  margin-top: 14px;
  font-size: clamp(2.25rem, 1.5rem + 3vw, 3.5rem);
  color: var(--ink);
}

.legal-dates {
  margin-top: 16px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 20px;
  font-size: 0.9rem;
  color: var(--body);
}

.legal-lede {
  margin-top: 20px;
  max-width: 62ch;
  font-size: 1.08rem;
  color: var(--body);
  text-wrap: pretty;
}

.legal-layout {
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr);
  gap: clamp(32px, 5vw, 72px);
  padding-block: clamp(48px, 6vw, 80px);
  align-items: start;
}

.legal-toc {
  position: sticky;
  top: 92px;
  font-size: 0.9rem;
  min-width: 0;
}

.legal-toc h2 {
  font-family: var(--font-body);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 12px;
}

.legal-toc ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  border-left: 1px solid var(--line);
}

.legal-toc a {
  display: block;
  padding: 6px 12px;
  margin-left: -1px;
  border-left: 2px solid transparent;
  color: var(--label);
  text-decoration: none;
  text-wrap: pretty;
}

.legal-toc a:hover {
  color: var(--ink);
  border-left-color: var(--plum);
}

.legal-body {
  max-width: 72ch;
  color: var(--body);
  /* Without this the 520px table below stretches the grid column past the
     viewport, and the whole page scrolls sideways instead of the table. */
  min-width: 0;
}

.legal-body > section + section {
  margin-top: 44px;
}

.legal-body h2 {
  font-size: clamp(1.35rem, 1.1rem + 0.8vw, 1.75rem);
  scroll-margin-top: 92px;
}

.legal-body h3 {
  margin-top: 28px;
  font-family: var(--font-body);
  font-size: 1.02rem;
  font-weight: 700;
  letter-spacing: 0;
  color: var(--ink);
}

.legal-body h2 + * {
  margin-top: 16px;
}

.legal-body p,
.legal-body ul,
.legal-body ol {
  margin-top: 14px;
  line-height: 1.65;
  text-wrap: pretty;
}

.legal-body ul,
.legal-body ol {
  padding-left: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.legal-body li::marker {
  color: var(--muted);
}

.legal-body a {
  color: var(--plum);
  text-underline-offset: 2px;
}

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

.legal-note {
  margin-top: 20px;
  padding: 18px 20px;
  border-radius: var(--radius);
  background: var(--inset);
  border-left: 3px solid var(--plum);
  font-size: 0.95rem;
}

.legal-note strong {
  color: var(--ink);
}

.legal-summary {
  margin-top: 28px;
  padding: 22px 24px;
  border-radius: var(--radius-lg);
  background: var(--wash);
  border: 1px solid var(--line);
  max-width: 68ch;
}

.legal-summary h2 {
  font-family: var(--font-body);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--plum);
}

.legal-summary ul {
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  color: var(--body);
  font-size: 0.98rem;
}

.legal-summary li {
  display: flex;
  gap: 12px;
  align-items: baseline;
}

.legal-summary li::before {
  content: '';
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--plum);
  transform: translateY(-2px);
}

.legal-table-wrap {
  margin-top: 18px;
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.legal-table {
  width: 100%;
  min-width: 520px;
  border-collapse: collapse;
  font-size: 0.92rem;
}

.legal-table th,
.legal-table td {
  padding: 11px 14px;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--line);
}

.legal-table thead th {
  background: var(--inset);
  color: var(--ink);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.legal-table tbody tr:last-child td {
  border-bottom: 0;
}

.legal-table td:first-child {
  color: var(--ink);
  font-weight: 600;
}

.legal-contact {
  margin-top: 18px;
  padding: 20px 22px;
  border-radius: var(--radius);
  border: 1px solid var(--line-strong);
  background: var(--paper);
  font-style: normal;
  line-height: 1.7;
}

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

  /* Sticky under a bar that is only 68px tall wastes a phone screen. */
  .legal-toc {
    position: static;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--line);
  }

  .legal-toc ol {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    border-left: 0;
  }

  .legal-toc a {
    margin-left: 0;
    border-left: 0;
    padding-inline: 0;
  }
}

/* ---------- Blog ---------- */

/* The hero, the sidebar and the prose come from the shell above. What is
   here is only the part that is the blog: the cards on /blog/, the metadata
   around an article, and the block that sends a reader into the product. */

.post-eyebrow a {
  color: var(--plum);
  text-decoration: none;
}

.post-eyebrow a:hover {
  text-decoration: underline;
}

.blog-hero h1,
.post-hero h1 {
  max-width: 24ch;
}

.post-tags {
  list-style: none;
  margin: 22px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.post-tags li {
  padding: 4px 11px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--body);
}

/* The index, and the "Keep reading" row under an article. */

.blog-list {
  padding-block: clamp(48px, 6vw, 80px);
}

.post-cards {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
}

.post-card {
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 24px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--paper);
  box-shadow: var(--shadow-card);
}

.post-card:hover {
  border-color: var(--line-strong);
}

.post-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted);
}

.post-card h2,
.post-card h3 {
  font-size: 1.3rem;
  text-wrap: pretty;
}

.post-card a {
  text-decoration: none;
}

.post-card a:hover {
  color: var(--plum);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.post-card > p {
  font-size: 0.98rem;
  line-height: 1.6;
  text-wrap: pretty;
}

/* Pushed to the bottom, so the tags line up across cards of unequal height. */
.post-card-tags {
  list-style: none;
  margin: auto 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  font-size: 0.82rem;
  color: var(--muted);
}

.post-card-tags li::before {
  content: '#';
  color: var(--line-strong);
}

.post-empty {
  color: var(--muted);
}

/* The article body. */

.post-layout-plain {
  grid-template-columns: minmax(0, 1fr);
}

/* The opening paragraph carries the weight of a lede without the author
   having to mark it as one. */
.post-body > p:first-child {
  font-size: 1.12rem;
  color: var(--ink);
}

/* A post is one run of prose rather than the numbered <section>s the legal
   pages are built from, so the air before a heading has to come from the
   heading itself. */
.post-body h2,
.doc-body h2 {
  margin-top: 48px;
}

.post-body h2:first-child,
.doc-body h2:first-child {
  margin-top: 0;
}

.post-body blockquote,
.doc-body blockquote {
  margin: 26px 0 0;
  padding: 16px 22px;
  border-left: 3px solid var(--plum);
  border-radius: 0 var(--radius) var(--radius) 0;
  background: var(--inset);
}

.post-body blockquote p,
.doc-body blockquote p {
  font-size: 1.02rem;
  color: var(--ink);
}

.post-body code,
.doc-body code {
  padding: 1px 5px;
  border-radius: 5px;
  background: var(--inset);
  font-family: var(--font-mono);
  font-size: 0.92em;
  color: var(--ink);
}

.post-body pre,
.doc-body pre {
  margin: 20px 0 0;
  padding: 16px 18px;
  overflow-x: auto;
  border-radius: var(--radius);
  background: var(--ink);
  color: var(--on-ink);
}

.post-body pre code,
.doc-body pre code {
  padding: 0;
  background: none;
  color: inherit;
  font-size: 0.88rem;
}

.post-body hr,
.doc-body hr {
  margin: 36px 0 0;
  border: 0;
  border-top: 1px solid var(--line);
}

.post-figure {
  margin: 26px 0 0;
}

.post-figure img {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.post-figure figcaption {
  margin-top: 10px;
  font-size: 0.9rem;
  color: var(--muted);
}

/* The way out of the article and into the product. */

.post-related {
  margin-top: 46px;
  padding: 24px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--paper);
}

.post-related h2 {
  font-family: var(--font-body);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.post-related ul {
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
  display: grid;
  gap: 10px;
}

.post-related a {
  display: grid;
  gap: 3px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--wash);
  color: var(--body);
  text-decoration: none;
}

.post-related a:hover {
  border-color: var(--plum);
  background: var(--plum-tint);
}

.post-related b {
  color: var(--ink);
}

.post-related span {
  font-size: 0.93rem;
  color: var(--muted);
}

/* The closing band, which is the landing page's closing band without the
   street. */

.post-cta {
  padding-block: clamp(56px, 7vw, 96px);
  background: linear-gradient(180deg, var(--paper) 0%, #fbfafb 100%);
  border-top: 1px solid var(--line);
  color: var(--ink);
  text-align: center;
}

.post-cta h2 {
  color: var(--ink);
  margin-inline: auto;
  max-width: 16ch;
}

.post-cta p {
  margin: 18px auto 0;
  max-width: 56ch;
  color: var(--body);
  text-wrap: pretty;
}

.post-cta .btn {
  margin-top: 26px;
}

/* ---------- Documentation ---------- */

/* The hero, the prose and the cards come from the shell and the blog above.
   What is here is only the part that is the documentation: the sidebar that
   carries every page, the reference tables, the callouts, and the pager. */

.doc-eyebrow a {
  color: var(--plum);
  text-decoration: none;
}

.doc-eyebrow a:hover {
  text-decoration: underline;
}

.doc-eyebrow span {
  margin-inline: 4px;
  opacity: 0.6;
}

.doc-layout {
  display: grid;
  grid-template-columns: 244px minmax(0, 1fr);
  gap: clamp(32px, 5vw, 72px);
  padding-block: clamp(40px, 5vw, 72px);
  align-items: start;
}

.doc-nav {
  position: sticky;
  top: 92px;
  font-size: 0.9rem;
  min-width: 0;
  /* Twenty pages plus the headings of one of them outgrow a laptop screen,
     and a sidebar that cannot reach its own last link is a broken sidebar. */
  max-height: calc(100vh - 112px);
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* Open by default, so the list is there without JavaScript. The marker and
   the tap target only exist where the sidebar is in the way of the reading. */
.doc-nav-shell > summary {
  display: none;
}

.doc-nav-list,
.doc-nav-list ol {
  list-style: none;
  margin: 0;
  padding: 0;
}

.doc-nav-list > li + li {
  margin-top: 22px;
}

.doc-nav-section {
  font-family: var(--font-body);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 8px;
}

.doc-nav-list a {
  display: block;
  padding: 5px 12px;
  margin-left: -1px;
  border-left: 2px solid var(--line);
  color: var(--label);
  text-decoration: none;
  text-wrap: pretty;
}

.doc-nav-list a:hover {
  color: var(--ink);
  border-left-color: var(--plum);
}

.doc-nav-list a[aria-current='page'] {
  color: var(--ink);
  font-weight: 600;
  border-left-color: var(--plum);
}

/* The page you are on opens into its own headings. They are one step in and
   a size down, so the eye reads them as part of that entry, not as pages. */
.doc-nav-outline {
  margin: 2px 0 2px 12px;
  font-size: 0.85rem;
}

.doc-nav-outline a {
  padding-block: 3px;
  color: var(--muted);
}

.doc-nav-outline .doc-nav-h3 a {
  padding-left: 24px;
}

.doc-body > h2:first-child {
  margin-top: 0;
}

.doc-body h3 {
  margin-top: 30px;
}

/* A step list is the shape most of these pages are in, so it gets room to
   breathe rather than the tight spacing prose lists have. */
.doc-body > ol > li + li {
  margin-top: 10px;
}

/* Reference tables: DNS records, environment variables, plan sizes. */

.doc-table {
  margin: 22px 0 0;
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--paper);
}

.doc-table:focus-visible {
  outline: 2px solid var(--plum);
  outline-offset: 2px;
}

.doc-table table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.94rem;
}

.doc-table th,
.doc-table td {
  padding: 10px 14px;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--line);
}

.doc-table thead th {
  font-family: var(--font-body);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--inset);
  white-space: nowrap;
}

.doc-table tbody tr:last-child th,
.doc-table tbody tr:last-child td {
  border-bottom: 0;
}

.doc-table code {
  white-space: nowrap;
}

/* Callouts. The kind is a word rather than an icon, because a coloured
   triangle means whatever the reader has been trained to think it means. */

.doc-callout {
  margin: 24px 0 0;
  padding: 14px 18px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--muted);
  border-radius: 0 var(--radius) var(--radius) 0;
  background: var(--inset);
}

.doc-callout-kind {
  font-family: var(--font-body);
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 4px;
}

.doc-callout p + p {
  margin-top: 0;
}

.doc-callout-note,
.doc-callout-tip {
  border-left-color: var(--plum);
}

.doc-callout-note .doc-callout-kind,
.doc-callout-tip .doc-callout-kind {
  color: var(--plum);
}

.doc-callout-important,
.doc-callout-warning,
.doc-callout-caution {
  border-left-color: var(--warn);
}

.doc-callout-important .doc-callout-kind,
.doc-callout-warning .doc-callout-kind,
.doc-callout-caution .doc-callout-kind {
  color: var(--warn);
}

/* The way on to the next page. */

.doc-pager {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
  margin-top: 48px;
  padding-top: 26px;
  border-top: 1px solid var(--line);
}

.doc-pager-link {
  display: block;
  padding: 14px 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--paper);
  text-decoration: none;
  color: var(--ink);
}

.doc-pager-link:hover {
  border-color: var(--line-strong);
}

.doc-pager-next {
  text-align: right;
}

.doc-pager-label {
  display: block;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.doc-pager-title {
  display: block;
  margin-top: 3px;
  font-weight: 600;
  text-wrap: pretty;
}

.doc-help {
  padding: clamp(36px, 5vw, 56px) 0;
  border-top: 1px solid var(--line);
  background: var(--wash);
}

.doc-help h2 {
  font-size: clamp(1.25rem, 2.4vw, 1.6rem);
}

.doc-help p {
  margin: 10px 0 0;
  max-width: 60ch;
  color: var(--body);
  text-wrap: pretty;
}

/* The index at /docs/. */

.doc-index {
  padding-block: clamp(40px, 5vw, 72px);
}

.doc-section + .doc-section {
  margin-top: clamp(36px, 4vw, 56px);
}

.doc-section-head h2 {
  font-size: clamp(1.3rem, 2.6vw, 1.75rem);
}

.doc-section-head p {
  margin: 6px 0 0;
  color: var(--muted);
  text-wrap: pretty;
}

.doc-cards {
  list-style: none;
  margin: 18px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 14px;
}

.doc-card {
  height: 100%;
  padding: 20px 22px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--paper);
}

.doc-card h3 {
  font-size: 1.05rem;
  margin: 0;
}

.doc-card h3 a {
  color: var(--ink);
  text-decoration: none;
}

.doc-card h3 a:hover {
  color: var(--plum);
  text-decoration: underline;
}

.doc-card p {
  margin: 8px 0 0;
  font-size: 0.94rem;
  color: var(--muted);
  text-wrap: pretty;
}

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

  /* On a phone the sidebar is twenty links between the title and the first
     sentence, so it becomes a disclosure. main.js folds it on arrival; with
     JavaScript off it stays open, so the page is never without navigation. */
  .doc-nav {
    position: static;
    max-height: none;
    overflow: visible;
    padding-bottom: 4px;
    border-bottom: 1px solid var(--line);
  }

  .doc-nav-shell > summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 10px 0;
    font-weight: 600;
    color: var(--ink);
    cursor: pointer;
  }

  .doc-nav-shell > summary::after {
    content: '▾';
    color: var(--muted);
  }

  .doc-nav-shell[open] > summary::after {
    content: '▴';
  }

  .doc-nav-list {
    padding-bottom: 12px;
  }

  .doc-pager {
    grid-template-columns: minmax(0, 1fr);
  }

  .doc-pager-next {
    text-align: left;
  }
}
