/* ─────────────────────────────────────────────────────────────
   app.topzmedia.com
   Layout after scalers.org: centered composition, one accent,
   pill CTAs, rule-divided column rows, alternating dark bands.
   Accent #24D6FF · Display Merriweather · Body Inter
   ───────────────────────────────────────────────────────────── */

:root {
  --base: #08090b;
  --band: #0e1013;
  --surface: #141619;
  --surface-2: #191c20;
  --line: #23262b;
  --line-soft: #1a1d21;

  --ink: #ffffff;
  --ink-2: #ffffff;
  --ink-3: #99a1ab;

  --accent: #24d6ff;
  --accent-hi: #6fe4ff;
  --accent-ink: #04222c;

  --radius: 999px;
  --maxw: 1200px;

  --sans: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  /* Paragraph face — Montserrat. UI chrome (buttons, labels, nav) stays on Inter,
     headlines on Merriweather. */
  --body: Montserrat, Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    sans-serif;
  --display: Merriweather, Georgia, "Times New Roman", serif;
}

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

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--base);
  color: var(--ink-2);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}

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

a {
  color: var(--accent);
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.wrap {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 24px;
}

/* ── Type ───────────────────────────────────────────────────── */

h1,
h2,
h3,
h4 {
  font-family: var(--display);
  font-weight: 900;
  color: var(--ink);
  line-height: 1.14;
  margin: 0 0 20px;
  letter-spacing: -0.015em;
}

h1 {
  font-size: clamp(30px, 4.6vw, 56px);
}

h2 {
  font-size: clamp(28px, 4vw, 46px);
}

h3 {
  font-size: 19px;
  font-weight: 700;
  line-height: 1.3;
}

/* Accent-colored emphasis inside a headline. Color only — no italics. */
.hl {
  color: var(--accent);
}

p {
  margin: 0 0 18px;
  font-family: var(--body);
}

li,
figcaption,
.lede,
.prose p,
.prose li,
.disclaimer p {
  font-family: var(--body);
}

.lede {
  font-size: clamp(16.5px, 1.5vw, 19px);
  color: var(--ink-2);
  line-height: 1.75;
}

/* Small tracked uppercase label above a section heading */
.label {
  display: block;
  font-size: clamp(13px, 1.15vw, 16.5px);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.28em;
  color: var(--accent);
  margin: 0 0 18px;
}

/* The labels used to carry gradient rays either side of the text. They are gone:
   the section separator now does the dividing, and the rays competed with it. */
.label::before,
.label::after,
.label-name::before,
.label-name::after,
.label-stack::before,
.label-stack::after {
  content: none;
}

.label-name,
.label-stack .on {
  display: block;
}

/* The group name is a headline, not an eyebrow: Merriweather, set large in the
   words' own capitalization. Everything the .label wrapper imposes on small
   tracked-out labels — uppercase, wide tracking, the accent color — is undone
   here, so only the descriptor underneath keeps that treatment. */
.label-name {
  font-family: var(--display);
  font-size: clamp(24px, 2.9vw, 34px);
  font-weight: 900;
  line-height: 1.16;
  letter-spacing: -0.015em;
  text-transform: none;
  color: var(--ink);
}

.label-stack .on {
  margin-top: 12px;
}

.label-muted {
  color: var(--ink-3);
  letter-spacing: 0.22em;
}

/* ── Centered section scaffold ───────────────────────────────── */

section {
  padding: 96px 0;
  position: relative;
}

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

.center {
  text-align: center;
}

.sec-head {
  max-width: 760px;
  margin: 0 auto 56px;
  text-align: center;
}

.sec-head p {
  margin: 0;
}

/* ── Header ─────────────────────────────────────────────────── */

.site-head {
  position: sticky;
  top: 0;
  z-index: 60;
  background: rgba(8, 9, 11, 0.9);
  backdrop-filter: saturate(140%) blur(12px);
  border-bottom: 1px solid var(--line-soft);
}

.site-head .wrap {
  display: flex;
  align-items: center;
  gap: 20px;
  height: 72px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 11px;
  flex: 0 0 auto;
}

.brand:hover {
  text-decoration: none;
}

/* The logo is a lockup — cyan mark plus the wordmark — supplied on transparency
   in its final colors. It is sized by height and never inverted or recolored. */
.brand img {
  height: 26px;
  width: auto;
  display: block;
}

.site-foot .brand img {
  height: 30px;
}

.nav {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 30px;
}

.nav a {
  font-size: 14px;
  font-weight: 500;
  color: var(--ink-2);
}

.nav a:hover {
  color: var(--ink);
  text-decoration: none;
}

/* ── Buttons (pill) ─────────────────────────────────────────── */

.btn {
  display: inline-block;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 15px 34px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  color: var(--ink);
  background: transparent;
  white-space: nowrap;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}

.btn:hover {
  text-decoration: none;
  border-color: var(--accent);
  color: var(--accent);
}

/* `.nav a` (0,1,1) beats `.btn-accent` (0,1,0); two classes settles it so the
   header CTA keeps its dark-on-accent text. */
.btn.btn-accent,
.nav a.btn.btn-accent {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}

.btn.btn-accent:hover,
.nav a.btn.btn-accent:hover {
  background: var(--accent-hi);
  border-color: var(--accent-hi);
  color: var(--accent-ink);
  text-decoration: none;
}

.site-head .btn {
  padding: 12px 24px;
  font-size: 12px;
}

/* ── Hero ───────────────────────────────────────────────────── */

.hero {
  position: relative;
  /* Tight top padding so the product screenshot clears the fold on short
     laptops (1280x720) and small phones (360x640). */
  padding: 52px 0 84px;
  overflow: hidden;
  text-align: center;
  border-bottom: 1px solid var(--line-soft);
}

.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(58% 62% at 50% 8%, rgba(36, 214, 255, 0.16), transparent 68%),
    radial-gradient(70% 60% at 50% 108%, rgba(36, 214, 255, 0.09), transparent 70%),
    linear-gradient(180deg, #0d1116 0%, var(--base) 74%);
  pointer-events: none;
}

.hero .wrap {
  position: relative;
}

/* The lockup sits between the eyebrow and the headline. Sized off the viewport
   so it stays subordinate to the h1 at every width — it introduces the name,
   it does not compete with the promise underneath it. */
/* ── Hero: screenshot beside the module list (desktop only) ──────────────
   Below 1000px the rail is hidden and the tapered .module-strip above the
   screenshot carries the names instead, so a phone never gets a 20% column. */
.hero-main {
  display: block;
}

.module-rail {
  display: none;
}

@media (min-width: 1000px) {
  .module-strip {
    display: none;
  }

  /* Flex rather than a 70/30 grid. With grid columns the list is narrower than
     its track, so all the leftover space lands on the right and the composition
     reads as sitting left of center. Here the image keeps its 70% and the list
     takes only the width it needs, so the slack splits evenly either side and
     the block centers under the headline. */
  .hero-main {
    display: flex;
    justify-content: center;
    align-items: stretch;
    gap: 40px;
    /* Reserves the space the caption occupies once it is taken out of the flow
       below — without it the next section rides up over the caption. */
    padding-bottom: 42px;
  }

  .hero-main .hero-shot {
    flex: 0 1 70%;
    margin: 0;
    position: relative;
  }

  /* The caption is lifted out of the flow so the row's height is the height of
     the screenshot itself. Otherwise the list would be stretched to image plus
     caption and its last entry would sit below the image's bottom edge. */
  .hero-main /* Extra screenshots on a module page (GALLERY in build.py). */
.gallery {
  display: grid;
  gap: 40px 28px;
  max-width: 1060px;
  margin: 0 auto;
  text-align: left;
}
.gallery .gshot {
  margin: 0;
}
.gallery .gshot img {
  width: 100%;
  height: auto;
  display: block;
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
}
.gallery .gshot figcaption {
  margin-top: 14px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-3);
}
.gallery .gshot figcaption strong {
  display: block;
  color: var(--ink);
  font-weight: 700;
  margin-bottom: 2px;
}

.hero-shot figcaption {
    position: absolute;
    left: 0;
    right: 0;
    top: calc(100% + 14px);
    margin: 0;
  }

  /* The names are narrower than the 30% column they sit in, so the list is
     shrink-wrapped and centered inside it. Without this the whole hero — image
     plus list — reads as sitting left of center, because the leftover space all
     falls on one side. The items stay left-aligned so the dots line up. */
  /* Spread over the full height of the screenshot: the first name's top edge
     lines up with the top of the image, the last name's bottom edge with the
     bottom of it, and the spacing between falls out evenly. */
  .module-rail {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    flex: 0 0 auto;
    margin: 0;
    padding: 0;
    list-style: none;
    text-align: left;
  }

  /* Every name sits on a single line (see HERO_NAMES in build.py). No fixed
     margin between rows: the column is stretched to the screenshot's height and
     space-between spreads the names over it, so the list always starts at the
     image's top edge and ends at its bottom edge, at every viewport width. */
  .module-rail li {
    font-family: var(--display);
    font-weight: 700;
    font-size: clamp(15px, 1.35vw, 19px);
    line-height: 1.3;
    color: var(--ink);
    white-space: nowrap;
    margin: 0;
  }

  .module-rail .sep {
    margin: 0 10px 0 0;
    width: 8px;
    height: 8px;
  }

  .module-rail li {
    display: flex;
    align-items: center;
  }

  .module-rail .rail-name {
    flex: 1 1 auto;
    margin-right: 16px;
  }

  /* "Try It" pill beside every hero name -> that module's page. */
  .module-rail .try {
    flex: 0 0 auto;
    margin-left: auto;
    font-family: var(--display);
    font-size: 11.5px;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    line-height: 1;
    padding: 7px 14px;
    border-radius: var(--radius);
    background: var(--accent);
    border: 1px solid var(--accent);
    color: var(--accent-ink);
    white-space: nowrap;
    transition: background 0.15s ease, border-color 0.15s ease;
  }

  .module-rail .try:hover {
    background: var(--accent-hi);
    border-color: var(--accent-hi);
    text-decoration: none;
  }
}

/* "Coming soon" tag on modules still being built (hero list, cards, page h1). */
.soon {
  display: inline-block;
  vertical-align: middle;
  margin-left: 8px;
  padding: 2px 8px 3px;
  border: 1px solid var(--accent);
  border-radius: 999px;
  font-family: var(--body, inherit);
  font-size: 0.55em;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  line-height: 1;
  color: var(--accent);
  white-space: nowrap;
}
.module-strip .soon { font-size: 0.6em; margin-left: 6px; }
h1 .soon { font-size: 0.3em; vertical-align: middle; position: relative; top: -0.15em; }

.hero-logo {
  display: block;
  height: clamp(24px, 3.2vw, 40px);
  width: auto;
  margin: 8px auto 26px;
}

.hero h1 {
  /* Two lines, broken at the comma. The <br class="hbr"> only applies once the
     line actually fits — narrow phones wrap naturally instead. */
  max-width: 22ch;
  margin-left: auto;
  margin-right: auto;
}

.hbr {
  display: initial;
}

@media (min-width: 760px) {
  .hero h1 {
    max-width: none;
  }
}

/* Below 760px the headline must shrink to keep "Every Tool A Media Buyer Needs,"
   on one line — ~17em of Merriweather 900, so ~5.1vw. */
@media (max-width: 759px) {
  .hero h1 {
    max-width: none;
    font-size: clamp(17px, 5.1vw, 27px);
  }
}

.hero .lede {
  max-width: 62ch;
  margin: 0 auto;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  justify-content: center;
  margin-top: 24px;
}

/* ── Hero screenshot ────────────────────────────────────────── */

/* Every module name on one line under the hero headline */
/* Held to the width of the screenshot underneath — the type is sized so the
   longest row lands inside 1060px rather than running past the image edges. */
.module-strip {
  max-width: 1060px;
  margin: 26px auto 0;
  font-family: var(--display);
  font-size: clamp(12px, 1.45vw, 19px);
  font-weight: 700;
  letter-spacing: 0.01em;
  line-height: 1.9;
  color: var(--ink-2);
  text-align: center;
}

.module-strip .mrow {
  display: block;
}

/* A dot in the label's own colors: white core fading out through the accent,
   with a soft halo so it reads as lit rather than as a full stop. */
/* The dot itself — shared by the horizontal strip and the vertical hero rail.
   Only the spacing differs between the two, and that is set on each. */
.sep {
  display: inline-block;
  width: 0.52em;                       /* em, so the dots track the text size */
  height: 0.52em;
  border-radius: 50%;
  vertical-align: middle;
  position: relative;
  top: -0.08em;
  background: radial-gradient(circle at 50% 50%,
    #fff 0%, var(--accent) 55%, rgba(36, 214, 255, 0.25) 100%);
  box-shadow: 0 0 7px rgba(36, 214, 255, 0.45);
}

.module-strip .sep {
  margin: 0 0.95em;
}

.hero-shot {
  position: relative;
  max-width: 1060px;
  margin: 34px auto 0;
  padding: 0;
}

/* `.hero .lede { margin: 0 auto }` (0,2,0) outranks a single class, so these need
   the same specificity or their spacing is silently dropped. */
.hero .lede-short {
  max-width: 52ch;
  margin: 34px auto 0;
}

.hero-shot img {
  width: 100%;
  height: auto;
  display: block;
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: 0 34px 90px rgba(0, 0, 0, 0.6);
}

/* ── Module detail: overview prose, feature grid, benefit list ─── */

.prose {
  max-width: 74ch;
  margin: 0 auto;
}

.prose .lede {
  margin: 0 0 22px;
  text-align: left;
}

.prose .lede:last-child {
  margin-bottom: 0;
}

.flist {
  display: grid;
  gap: 28px;
  margin: 44px auto 0;
  padding: 0;
  max-width: 860px;
  text-align: left;
  list-style: none;
}

/* The check is a ::before in its own grid column rather than a list marker, so
   a wrapped headline and its body text keep the same hanging indent. */
.flist li {
  display: grid;
  grid-template-columns: 32px 1fr;
  column-gap: 16px;
  align-items: start;
}

.flist li::before {
  content: "\2713";
  color: var(--accent-hi);
  font-size: 28px;
  font-weight: 700;
  line-height: 1.15;
}

/* Both text rows sit in the wide column — otherwise the paragraph falls into
   the 32px check column on the next grid row and wraps one word per line. */
.flist h3,
.flist p {
  grid-column: 2;
}

.flist h3 {
  font-family: var(--display);
  font-size: 19px;
  font-weight: 900;
  line-height: 1.3;
  margin: 0 0 8px;
  color: var(--ink);
}

.flist p {
  margin: 0;
  font-size: 15px;
  line-height: 1.65;
  color: var(--ink-3);
}

.blist {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 40px 44px;
  margin: 44px auto 0;
  max-width: 1060px;
  text-align: left;
}

.bitem h3 {
  font-family: var(--display);
  font-size: 20px;
  font-weight: 900;
  line-height: 1.3;
  margin: 0 0 12px;
  color: var(--accent);
}

.bitem p {
  margin: 0;
  font-size: 15.5px;
  line-height: 1.7;
  color: var(--ink-2);
}

/* Screenshot of a single module, shown at the top of its detail page */
.shot-band {
  padding: 0 0 8px;
}

.module-shot {
  max-width: 1060px;
  margin: 0 auto;
  padding: 0;
}

.module-shot img {
  width: 100%;
  height: auto;
  display: block;
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: 0 34px 90px rgba(0, 0, 0, 0.6);
}

.module-shot figcaption {
  margin-top: 16px;
  font-size: 13px;
  color: var(--ink-3);
  text-align: center;
}

.hero-shot figcaption {
  margin-top: 16px;
  font-size: 13px;
  color: var(--ink-3);
}

/* ── Readout strip ──────────────────────────────────────────── */

.readout {
  margin: 56px auto 0;
  max-width: 940px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.readout div {
  padding: 26px 18px;
  border-right: 1px solid var(--line-soft);
  text-align: center;
}

.readout div:last-child {
  border-right: 0;
}

.readout dt {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 10px;
}

.readout dd {
  font-family: var(--display);
  font-size: 26px;
  font-weight: 900;
  margin: 0;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.readout dd.on {
  color: var(--accent);
}

/* ── Rule-divided column row ────────────────────────────────── */

.cols {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  max-width: 1080px;
  margin: 0 auto;
}

.cols > div {
  padding: 0 34px;
  text-align: center;
  border-right: 1px solid var(--line);
}

.cols > div:last-child {
  border-right: 0;
}

.cols h3 {
  margin-bottom: 10px;
}

.cols p {
  color: var(--ink-3);
  font-size: 15px;
  margin: 0;
}

/* ── Access request form ────────────────────────────────────── */

.form,
.form-done {
  max-width: 620px;
  margin: 0 auto;
}

.form-row {
  display: flex;
  gap: 16px;
}

.form-row .field {
  flex: 1 1 0;
  min-width: 0;
}

.field {
  margin-bottom: 20px;
}

.field label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-2);
  margin-bottom: 8px;
}

.field input,
.field select {
  width: 100%;
  padding: 13px 14px;
  font-family: var(--body);
  font-size: 16px;                     /* 16px or iOS zooms the page on focus */
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 4px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

/* Safari and iOS ignore the background on a native select, so it renders as a
   light system control on the dark base. Drop the native chrome and draw the
   caret as a background image instead. */
.field select {
  -webkit-appearance: none;
  appearance: none;
  padding-right: 40px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%238A93A6' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round' d='M1.4 1.8 6 6.4l4.6-4.6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 12px 8px;
  /* Left to the same padding as an input rather than given a fixed height, so
     the two controls stay the same size if that padding is ever changed. */
  line-height: normal;
  cursor: pointer;
}

/* The menu itself is drawn by the OS, so the options need their own colors or
   they inherit the light system palette on Windows and Linux. */
.field select option {
  background: var(--surface);
  color: var(--ink);
}

.field input:focus,
.field select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(36, 214, 255, 0.16);
}

.field input[aria-invalid="true"],
.field select[aria-invalid="true"] {
  border-color: #ff6b6b;
}

.field-hint {
  margin: 7px 0 0;
  font-size: 13px;
  color: var(--ink-3);
}

.field-error,
.form-error {
  margin: 7px 0 0;
  font-size: 13px;
  color: #ff8585;
}

.form-error {
  margin-bottom: 16px;
}

.form-submit {
  width: 100%;
  margin-top: 4px;
  font-family: var(--body);
  cursor: pointer;
  border: 0;
}

.form-submit:disabled {
  opacity: 0.6;
  cursor: default;
  transform: none;
}

.form-note {
  margin: 16px 0 0;
  font-size: 13px;
  color: var(--ink-3);
  text-align: center;
}

/* The honeypot has to be reachable by a bot parsing the HTML, so it cannot be
   display:none — it is moved out of sight and out of the tab order instead. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-done {
  text-align: center;
}

@media (max-width: 520px) {
  .form-row {
    display: block;
  }
}

/* ── Module grid ────────────────────────────────────────────── */

.group {
  margin-bottom: 56px;
}

.group:last-child {
  margin-bottom: 0;
}

/* A hairline between sections. White at the center, fading out through the
   accent to nothing at both ends — the same lit-not-ruled treatment as the
   rays either side of a section label, so it separates without boxing. */
.group + .group {
  position: relative;
  padding-top: 52px;
}

.group + .group::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: min(100%, 1060px);
  height: 1px;
  background: linear-gradient(to right,
    rgba(36, 214, 255, 0) 0%,
    var(--accent) 24%,
    #fff 50%,
    var(--accent) 76%,
    rgba(36, 214, 255, 0) 100%);
}

.group > .label {
  text-align: center;
  margin-bottom: 26px;
}

/* Flex rather than grid so a short final row (or a 3-card sibling row) centers
   instead of hugging the left edge. */
.grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 16px;
}

.grid .card {
  flex: 1 1 272px;
  max-width: 330px;
}

.card {
  display: block;
  padding: 30px 26px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--surface);
  color: var(--ink-2);
  text-align: center;
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.15s ease;
}

.card:hover {
  text-decoration: none;
  border-color: var(--accent);
  background: var(--surface-2);
  transform: translateY(-2px);
}

.chip {
  display: inline-block;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: 0.16em;
  padding: 5px 11px;
  border-radius: var(--radius);
  border: 1px solid rgba(36, 214, 255, 0.35);
  color: var(--accent);
  background: rgba(36, 214, 255, 0.08);
  margin-bottom: 16px;
}

.card h3 {
  margin: 0 0 10px;
  font-size: 18px;
}

.card p {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.65;
  color: var(--ink-3);
}

.card .more {
  display: inline-block;
  margin-top: 20px;
  font-size: 15px;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
}

/* ── Interior page head ─────────────────────────────────────── */

.page-head {
  position: relative;
  padding: 76px 0 68px;
  overflow: hidden;
  text-align: center;
  border-bottom: 1px solid var(--line-soft);
}

.page-head::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(56% 68% at 50% 0%, rgba(36, 214, 255, 0.13), transparent 70%),
    linear-gradient(180deg, #0d1116 0%, var(--base) 82%);
  pointer-events: none;
}

.page-head .wrap {
  position: relative;
}

.page-head .lede {
  max-width: 62ch;
  margin: 0 auto;
}

.crumb {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 20px;
}

.crumb a {
  color: var(--ink-3);
}

.crumb a:hover {
  color: var(--accent);
}

/* ── Feature list ───────────────────────────────────────────── */

.feature-list {
  list-style: none;
  padding: 0;
  margin: 0 auto;
  max-width: 760px;
  border-top: 1px solid var(--line);
}

.feature-list li {
  padding: 22px 0 22px 34px;
  border-bottom: 1px solid var(--line);
  color: var(--ink-2);
  position: relative;
  font-size: 16px;
  text-align: left;
}

.feature-list li::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 31px;
  width: 14px;
  height: 2px;
  background: var(--accent);
}

/* ── Prose (legal) ──────────────────────────────────────────── */

.prose {
  max-width: 760px;
  margin: 0 auto;
  text-align: left;
}

.prose h2 {
  font-size: 24px;
  margin-top: 52px;
  margin-bottom: 14px;
}

.prose h3 {
  font-size: 17px;
  margin-top: 30px;
  margin-bottom: 8px;
}

.prose p,
.prose li {
  color: var(--ink-2);
  font-size: 15.5px;
}

.prose ul,
.prose ol {
  padding-left: 20px;
  margin: 0 0 20px;
}

.prose li {
  margin-bottom: 9px;
}

.prose table {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 22px;
  font-size: 14.5px;
}

.prose th,
.prose td {
  text-align: left;
  padding: 12px 14px;
  border: 1px solid var(--line);
  vertical-align: top;
  color: var(--ink-2);
}

.prose th {
  background: var(--surface);
  color: var(--ink);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 800;
}

.tablewrap {
  overflow-x: auto;
}

.updated {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.callout {
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: 10px;
  background: var(--surface);
  padding: 20px 22px;
  margin: 0 0 24px;
}

.callout p:last-child {
  margin-bottom: 0;
}

/* ── Footer ─────────────────────────────────────────────────── */

.site-foot {
  padding: 40px 0 44px;
  background: var(--base);
  border-top: 2px solid var(--accent);
}

.foot-bar {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  text-align: center;
  padding-bottom: 30px;
  border-bottom: 1px solid var(--line-soft);
}

.foot-links {
  display: flex;
  gap: 22px;
  flex-wrap: wrap;
  justify-content: center;
}

.foot-links a {
  font-size: 13px;
  color: var(--ink-3);
}

.foot-links a:hover {
  color: var(--accent);
  text-decoration: none;
}

.foot-contact {
  font-size: 13px;
  color: var(--ink-3);
}

.disclaimer {
  padding-top: 26px;
  max-width: 96ch;
  margin: 0 auto;
}

.disclaimer p {
  color: var(--ink-3);
  font-size: 12.5px;
  line-height: 1.7;
  margin: 0 0 10px;
}

.legal-line {
  margin-top: 18px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--ink-3);
  text-transform: uppercase;
}

/* ── Responsive ─────────────────────────────────────────────── */

@media (max-width: 900px) {
  .cols {
    grid-template-columns: 1fr;
  }
  .cols > div {
    border-right: 0;
    border-bottom: 1px solid var(--line);
    padding: 30px 0;
  }
  .cols > div:last-child {
    border-bottom: 0;
  }
  .readout {
    grid-template-columns: repeat(2, 1fr);
  }
  .readout div:nth-child(2) {
    border-right: 0;
  }
  .readout div:nth-child(-n + 2) {
    border-bottom: 1px solid var(--line-soft);
  }
}

@media (max-width: 640px) {
  section {
    padding: 68px 0;
  }
  .hero {
    padding: 34px 0 56px;
  }
  h1 {
    margin-bottom: 14px;
  }
  .hero-shot {
    margin-top: 22px;
  }
  .nav {
    gap: 16px;
  }
  .nav a.hide-sm {
    display: none;
  }
  .site-head .wrap {
    height: 64px;
    gap: 12px;
    padding: 0 16px;
  }
  .site-head .btn {
    padding: 10px 16px;
    font-size: 11px;
    letter-spacing: 0.06em;
  }
}

/* Very small phones: squeeze the hero further so the screenshot still clears the
   fold once browser chrome (~100px) is accounted for. */
@media (max-width: 400px) {
  .hero {
    padding: 22px 0 48px;
  }
  h1 {
    margin-bottom: 10px;
  }
  .label {
    margin-bottom: 12px;
    letter-spacing: 0.2em;
  }
  .lede-short {
    font-size: 15px;
    line-height: 1.5;
  }
  .hero-actions {
    margin-top: 18px;
    gap: 10px;
  }
  .hero-shot {
    margin-top: 16px;
  }
  .btn {
    padding: 12px 20px;
  }
}

/* 320px-class phones (iPhone SE 1st gen): drop the eyebrow label and shrink the
   headline so the screenshot still shows above the fold. */
@media (max-width: 345px) {
  .hero {
    padding: 14px 0 40px;
  }
  h1 {
    margin-bottom: 8px;
  }
  .lede-short {
    font-size: 14px;
  }
  .hero-actions {
    margin-top: 14px;
  }
  .hero-shot {
    margin-top: 12px;
  }
}

/* Small phones: brand + link + CTA do not fit. Keep brand and CTA. */
@media (max-width: 460px) {
  .nav a:not(.btn) {
    display: none;
  }
}

@media (max-width: 365px) {
  .brand img {
    height: 22px;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  * {
    transition: none !important;
  }
}

/* ── Pricing ────────────────────────────────────────────────── */

.plans {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(255px, 1fr));
  gap: 18px;
  align-items: start;
}

/* Single-plan pricing (2026-08-14): one Early Bird card instead of a ladder.
   The .plans grid is built for four columns, so a lone card would stretch the
   full width and read like a banner rather than a plan. */
.plans:has(.plan-solo) { grid-template-columns: minmax(0, 460px); justify-content: center; }
.plan-solo { padding: 34px 30px 32px; }
.plan-solo .plan-flag { white-space: nowrap; }
.plan-solo .amt { font-size: 56px; }

/* The teaser strip shows one price too — let it be wider than a tier chip. */
.price-strip-solo .price-mini-solo { flex: 0 1 340px; max-width: 340px; }

.plan {
  position: relative;
  padding: 32px 26px 30px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--surface);
  display: flex;
  flex-direction: column;
  height: 100%;
}

/* The featured plan sits proud of the row rather than being a different color —
   one accent on the page, and the border does the pointing. */
.plan-hi {
  border-color: var(--accent);
  background: var(--surface-2);
}

.plan-quiet {
  background: transparent;
}

.plan-flag {
  position: absolute;
  top: -11px;
  left: 26px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 5px 12px;
  border-radius: var(--radius);
  background: var(--accent);
  color: var(--accent-ink);
}

.plan h3 {
  font-size: 21px;
  margin: 0 0 6px;
}

/* The single launch plan: its name is the headline of the card. */
.plan-solo h3 {
  font-size: clamp(40px, 4.4vw, 60px);
  line-height: 1.05;
  margin: 6px 0 12px;
  letter-spacing: -0.01em;
}

.plan-who {
  font-family: var(--body);
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--ink-3);
  margin: 0 0 20px;
  min-height: 42px;
}

.plan-price {
  margin: 0 0 4px;
  display: flex;
  align-items: baseline;
  gap: 7px;
  flex-wrap: wrap;
}

.plan-price .amt {
  font-family: var(--display);
  font-weight: 900;
  font-size: 40px;
  line-height: 1;
  color: var(--ink);
  letter-spacing: -0.02em;
}

.plan-price .amt-word {
  font-size: 30px;
}

.plan-price .per {
  font-size: 13px;
  color: var(--ink-3);
}

.plan-annual {
  font-family: var(--body);
  font-size: 12.5px;
  color: var(--ink-3);
  margin: 0 0 22px;
}

.plan-annual .save {
  color: var(--accent);
  font-weight: 600;
}

.plan-list {
  list-style: none;
  margin: 0 0 26px;
  padding: 0;
  border-top: 1px solid var(--line-soft);
}

.plan-list li {
  font-size: 13.5px;
  line-height: 1.5;
  padding: 11px 0 11px 24px;
  border-bottom: 1px solid var(--line-soft);
  position: relative;
  color: var(--ink-2);
}

.plan-list li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 18px;
  width: 9px;
  height: 5px;
  border-left: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(-45deg);
}

/* Pin the button to the bottom so the four cards line up despite different
   list lengths. */
.plan .btn {
  margin-top: auto;
  text-align: center;
}

.fineprint {
  font-family: var(--body);
  font-size: 12.5px;
  color: var(--ink-3);
  margin-top: 26px;
}

/* ── Founding offer ─────────────────────────────────────────── */

.founding {
  text-align: center;
  max-width: 760px;
  margin: 0 auto;
  padding: 40px 28px;
  border: 1px solid rgba(36, 214, 255, 0.35);
  border-radius: 16px;
  background: rgba(36, 214, 255, 0.05);
}

.founding h2 {
  font-size: clamp(24px, 3.2vw, 36px);
}

.founding .lede {
  margin-bottom: 26px;
}

/* ── Tables ─────────────────────────────────────────────────── */

/* Wide tables scroll inside their own box; the page itself never does. */
.table-scroll {
  overflow-x: auto;
  margin-top: 28px;
  border: 1px solid var(--line);
  border-radius: 14px;
}

.ptable {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--body);
  font-size: 14px;
  min-width: 420px;
}

.ptable th,
.ptable td {
  padding: 14px 20px;
  text-align: left;
  border-bottom: 1px solid var(--line-soft);
}

.ptable thead th {
  font-family: var(--sans);
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
  background: var(--surface);
}

.ptable .num {
  text-align: right;
  white-space: nowrap;
}

.ptable tfoot td {
  border-top: 1px solid var(--line);
  border-bottom: none;
  color: var(--ink);
}

.ptable tbody tr:last-child td {
  border-bottom: none;
}

.ptable-hi td {
  color: var(--accent);
  background: rgba(36, 214, 255, 0.05);
}

/* ── Home pricing strip ─────────────────────────────────────── */

.price-strip {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 14px;
  margin-bottom: 30px;
}

.price-mini {
  flex: 1 1 190px;
  max-width: 260px;
  padding: 22px 18px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--surface);
  color: var(--ink-2);
  text-align: center;
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.price-mini:hover {
  text-decoration: none;
  border-color: var(--accent);
  transform: translateY(-2px);
}

.pm-name {
  display: block;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 10px;
}

.pm-amt {
  display: block;
  font-family: var(--display);
  font-weight: 900;
  font-size: 30px;
  line-height: 1;
  color: var(--ink);
}

.pm-per {
  display: block;
  font-family: var(--body);
  font-size: 12px;
  color: var(--ink-3);
  margin-top: 6px;
}

@media (max-width: 560px) {
  .plan-who {
    min-height: 0;
  }
  .plan {
    padding: 28px 22px 26px;
  }
}

/* Plan CTAs are full-width blocks, not shrink-to-fit pills. At the four-up
   breakpoint a card is ~222px wide inside its padding, while an uppercase,
   letter-spaced label like "START A CONVERSATION" measures ~268px — as an
   inline-block with `white-space: nowrap` the text simply painted straight
   through the border. Block + normal wrapping means any label the plan data
   ever carries stays inside the pill, and the four buttons line up. */
.plan .btn {
  display: block;
  width: 100%;
  white-space: normal;
  padding-left: 18px;
  padding-right: 18px;
  overflow-wrap: break-word;
}

/* ── Live demo window (module pages with an in-browser demo) ───────
   Same footprint as the screenshot it replaces. The iframe is a live, non-interactive preview;
   the whole window is one link that opens the full-screen working demo in a new tab. */
.demo-band {
  padding: 0 0 8px;
}

.demo-window {
  position: relative;
  display: block;
  max-width: 1060px;
  margin: 0 auto;
  aspect-ratio: 16 / 9.6;
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
  background: #0a0a0a;
  box-shadow: 0 34px 90px rgba(0, 0, 0, 0.6);
  text-decoration: none;
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.demo-window:hover {
  border-color: var(--accent);
  text-decoration: none;
}

.demo-window iframe {
  position: absolute;
  inset: 0;
  width: 200%;
  height: 200%;
  border: 0;
  background: #0a0a0a;
  transform: scale(0.5);
  transform-origin: 0 0;
  pointer-events: none;
}

.demo-window::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(4, 12, 18, 0.42);
  transition: background 0.15s ease;
}

.demo-window:hover::after {
  background: rgba(4, 12, 18, 0.28);
}

.demo-cta {
  position: absolute;
  z-index: 1;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  max-width: calc(100% - 48px);
  padding: 16px 28px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-ink);
  font-family: var(--display);
  font-size: clamp(14px, 1.4vw, 19px);
  font-weight: 800;
  letter-spacing: 0.02em;
  text-align: center;
  line-height: 1.3;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
}

.demo-window:hover .demo-cta {
  background: var(--accent-hi);
}

.demo-note {
  margin-top: 16px;
  font-size: 13px;
  color: var(--ink-3);
  text-align: center;
}

/* ── HERO WALKTHROUGH VIDEO (2026-08-20) ────────────────────────────────────
   Replaces the composite screenshot + name rail. The video is the hero: full
   width of the page, responsive by aspect-ratio, and it downloads NOTHING until
   the play button is pressed (preload="none" + poster). The module names moved
   underneath it, centered on two lines. */
.hero-video {
  margin: 38px auto 0;
  width: min(100% , 1440px);
  padding: 0;
}
.wt-frame {
  position: relative;
  width: 100%;
  aspect-ratio: 1502 / 860;
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
  background: #05070a;
  box-shadow: 0 34px 90px rgba(0, 0, 0, 0.6);
}
.wt-frame .wt {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  border: 0;
}
/* Ramprig-blue play button. Sized in vw so it stays proportional on a phone,
   clamped so it is never a postage stamp or a beach ball. */
.wt-play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: clamp(64px, 8vw, 104px);
  height: clamp(64px, 8vw, 104px);
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: transform 0.18s ease, filter 0.18s ease;
}
.wt-play svg { width: 100%; height: 100%; display: block; }
.wt-play circle { fill: #6FE5FF; }
.wt-play path   { fill: #05141b; }
.wt-play:hover  { transform: scale(1.06); filter: drop-shadow(0 0 22px rgba(111, 229, 255, 0.55)); }
.wt-play:focus-visible { outline: 3px solid #6FE5FF; outline-offset: 6px; border-radius: 50%; }
.wt-play[hidden] { display: none; }
.hero-video figcaption {
  margin-top: 16px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-3);
  text-align: center;
}

/* The names now sit UNDER the video at every width — the old rule hid this strip
   on desktop because the names lived in a side rail there. */
.hero .module-strip { display: block; margin-top: 30px; }
@media (min-width: 1000px) {
  .hero .module-strip { display: block; }
}

/* Two lines, not four. The rows are explicit (6 / 5) but at hero type size the
   first row ran past the container and wrapped, so the "two lines" read as four.
   Size the strip to fit its longest row, and let it wrap only on small screens. */
.hero .module-strip {
  width: 100%;
  max-width: none;
  margin-left: auto;
  margin-right: auto;
  font-size: clamp(12px, 1.02vw, 16px);
  line-height: 1.5;
}
.hero .module-strip .mrow {
  display: block;
  white-space: nowrap;
}
.hero .module-strip .sep { margin: 0 0.55em; }
@media (max-width: 860px) {
  /* Nowrap would push a phone into a horizontal scroll — let it flow instead. */
  .hero .module-strip .mrow { white-space: normal; }
}

/* ── MODULE NAMES UNDER THE VIDEO (2026-08-20) ──────────────────────────────
   Loris: "make these 30px size on desktop and 25px on mobile. On desktop,
   distribute them in 3 columns. 1 column on mobile." */
.module-grid {
  list-style: none;
  margin: 34px auto 0;
  padding: 0;
  width: min(100%, 1440px);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px 28px;
  text-align: center;
  /* A two-line name must not push its one-line neighbours down: rows align to the
     TOP so every item's first line sits on the same baseline (Loris 2026-08-20). */
  align-items: start;
}
.module-grid li {
  font-family: var(--serif, Georgia, serif);
  font-size: 30px;
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--ink);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: 10px;
  flex-wrap: wrap;
}
@media (max-width: 860px) {
  .module-grid {
    grid-template-columns: 1fr;
    gap: 14px;
    margin-top: 26px;
  }
  .module-grid li { font-size: 25px; }
}

/* Left-aligned in the column, each behind the blue dot (Loris 2026-08-20).
   The dot is the shared .sep — it sizes in em, so it tracks 30px/25px on its own.
   align-items:flex-start keeps the dot on the FIRST line of a two-line name. */
.module-grid { text-align: left; }
/* nowrap: the NAME wraps its own text, the dot never gets pushed onto its own line. */
.module-grid li { justify-content: flex-start; gap: 0; flex-wrap: nowrap; }
.module-grid .sep { flex: 0 0 auto; margin: 0.45em 0.5em 0 0; top: 0; }
.module-grid .mg-name { flex: 1 1 auto; min-width: 0; }
@media (min-width: 861px) {
  /* Columns are wider than the longest name, so the three of them are packed to
     the middle instead of being stranded at the page edges. */
  .module-grid { grid-template-columns: repeat(3, minmax(0, 430px)); justify-content: center; }
}

/* The "Coming soon" chip wraps under its name and made that grid row taller, so the row
   below it sat further down than every other row. Take the chip out of the flow: the row
   is one text line like the others, and the chip hangs in the (now larger) row gap.
   Loris 2026-08-20: "bring lead router and media buyer intel up to match the distance". */
.module-grid { row-gap: 34px; }
.module-grid li { position: relative; }
.module-grid .soon {
  position: absolute;
  top: 100%;
  left: 1.02em;              /* clears the dot, so it lines up under the name */
  margin-left: 0;
  margin-top: 1px;
  white-space: nowrap;
}
