/* mono — the marketing site.
 *
 * One file. There is no `.mono` wrapper the way mono-web's stylesheet has,
 * because this whole file IS the design system for this site: the page has no
 * other styling to be scoped away from.
 *
 * Two things are copied from mono-web rather than shared, and each is pinned by
 * a test in internal/site/guards_test.go so the copy cannot drift:
 *
 *   - The --mono-* colour ramp, character-for-character.
 *   - The three woff2 faces under fonts/.
 *
 * Copied rather than shared because a shared stylesheet would have to be served
 * from two origins with two different cache lifetimes, and a Go module cannot
 * embed a file outside its own tree. Pinned rather than left alone because these
 * are values that MUST agree: the day mono-web retints the blue or upgrades a
 * font, the guard goes red and forces a decision instead of quietly splitting the
 * brand in two.
 */

/* ---------- fonts: self-hosted, never a CDN ----------
 * The front-end stack spec's R6 is binding — production runtime dependencies are
 * self-hosted and version-pinned. The design file this page came from linked
 * Google Fonts; that link is deliberately gone.
 */
@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/space-grotesk-latin.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/ibm-plex-mono-400-latin.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/ibm-plex-mono-500-latin.woff2") format("woff2");
}

:root {
  /* ---------- colour: the shared ramp ---------- */
  --mono-white: #ffffff;
  --mono-bg: #fbfbfc;
  --mono-surface: #ffffff;
  --mono-line: #e6e8ee;
  --mono-line-2: #f0f1f5;
  --mono-ink: #15171c;
  --mono-body: #3a3f4d;
  --mono-muted: #697086;
  --mono-blue: #3457c5;
  --mono-green: #12805c;
  --mono-red: #c14a3d;

  /* Two surfaces this page has and the app does not: the ruling on the hero's
   * grid, and the hover fill on an outlined control. Deliberately NOT named
   * --mono-*: they are not part of the shared ramp, and the guard that pins that
   * ramp would then have to find them in mono-web's stylesheet, where they have
   * no business existing. (--mono-wash is #f4f5f8, which is close enough to be
   * worth saying is a different value, not a rounding of this one.) */
  --grid-line: #f2f3f7;
  --surface-hover: #f5f6f9;

  /* The two focus rings, as tokens rather than rgb() literals. Written inline
     they were invisible to the raw-colour guard, which matches #rrggbb only —
     and the blue one was character-for-character --mono-blue, which is the
     exact mistake AGENTS.md names. */
  --focus-ring: rgb(52 87 197 / 0.2);
  --danger-ring: rgb(193 74 61 / 0.2);

  /* On the dark band the ramp above has no readable steps, so the band gets its
   * own three. They are not app colours — nothing in mono-web renders on ink —
   * which is why they live here rather than in the shared set above. */
  --band-ink: var(--mono-ink);
  --band-text: #f4f4f6;
  --band-body: #b6bac6;
  --band-muted: #8b91a4;
  --band-line: rgba(255, 255, 255, 0.13);

  /* ---------- type ----------
   * This is a MARKETING scale and is deliberately not mono-web's. The app's
   * --text-base is 14px because it is a dense operator UI read at a desk; a
   * landing page's job is a 52px headline. The token names differ from the app's
   * for the same reason: two scales sharing names would invite copying a value
   * from one into the other.
   */
  --font-sans: "Space Grotesk", system-ui, -apple-system, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, Menlo, monospace;

  --text-display: 52px;  /* the hero headline, once on the page */
  --text-h2: 30px;       /* the dark band's heading */
  --text-h3: 24px;       /* the closing call to action */
  --text-stat: 22px;     /* a figure in the stat grid */
  --text-h4: 19px;       /* the partners card, the origins columns */
  --text-h5: 17px;       /* a feature column's title */
  --text-lead: 17px;     /* the hero's opening paragraph */
  --text-base: 14px;
  --text-sm: 12.5px;
  --text-xs: 11.5px;     /* mono labels and the footer */
  --text-micro: 10.5px;  /* uppercase eyebrows, the 01/02/03 marks */

  --fw-regular: 400;
  --fw-medium: 500;
  --fw-semibold: 600;

  --lh-tight: 1.08;
  --lh-heading: 1.25;
  --lh-body: 1.65;

  --label-tracking: 0.07em;

  /* ---------- space ---------- */
  --space-1: 8px;
  --space-2: 10px;
  --space-3: 14px;
  --space-4: 18px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 40px;
  --space-8: 56px;
  --space-9: 72px;
  --space-10: 96px;
  --space-11: 112px;

  --measure: 880px;
  --gutter: 24px;

  --radius-md: 7px;
  --radius-lg: 8px;
  --radius-xl: 12px;
  --radius-pill: 999px;

  --control-h: 42px;
  /* The header's controls are shorter than the hero's: a nav sits beside a
     44px brand mark, and a 42px button there reads as a second primary action
     competing with the one the page is actually about. */
  --control-h-sm: 36px;
  --badge-h: 28px;

  /* The hero grid's cell. One token because two properties have to agree about
     it — the size of the repeat and, if it ever gains one, its offset. */
  --grid-cell: 64px;

  color-scheme: light;
}

/* --text-h5 and --text-lead are both 17px and are deliberately two tokens: a
 * column heading and a lead paragraph are not required to agree, and the day the
 * lead grows the heading must not follow it. */

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

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

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

body {
  margin: 0;
  background: var(--mono-bg);
  color: var(--mono-ink);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--mono-blue);
  text-decoration: none;
}
a:hover { color: var(--mono-ink); }

h1, h2, h3 {
  margin: 0;
  font-weight: var(--fw-semibold);
  letter-spacing: -0.02em;
}
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }

:focus-visible {
  outline: 2px solid var(--mono-blue);
  outline-offset: 2px;
}

/* The measure lives in exactly one rule. Every section is full width and puts
 * one of these inside it, which is what lets the dark band bleed to the edges
 * without a single negative margin. */
.wrap {
  max-width: var(--measure);
  margin: 0 auto;
  padding-inline: var(--gutter);
}

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

/* The uppercase mono label used by five sections. */
.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  text-transform: uppercase;
  letter-spacing: var(--label-tracking);
  color: var(--mono-muted);
}
.eyebrow--onDark { color: var(--band-muted); }

/* ---------- header ---------- */
.siteheader { border-bottom: 1px solid var(--mono-line); }
.siteheader__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-block: var(--space-3);
}
.brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  color: var(--mono-ink);
}
.brand:hover { color: var(--mono-ink); }
.brand__mark {
  width: 44px;
  height: 44px;
  border-radius: var(--radius-xl);
  background: var(--mono-ink);
  color: var(--mono-white);
  font-family: var(--font-mono);
  font-size: var(--text-h2);
  font-weight: var(--fw-medium);
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
.brand__word {
  font-size: var(--text-h3);
  font-weight: var(--fw-semibold);
  letter-spacing: -0.02em;
}

.sitenav {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}
.sitenav__link {
  font-size: var(--text-base);
  font-weight: var(--fw-medium);
  color: var(--mono-body);
}
.sitenav__link:hover { color: var(--mono-ink); }
/* Outlined, not solid. The one solid dark control on this page is the thing it
   is asking for; a second would make the header compete with the hero. */
.sitenav__cta {
  display: inline-flex;
  align-items: center;
  height: var(--control-h-sm);
  padding-inline: var(--space-3);
  border: 1px solid var(--mono-line);
  border-radius: var(--radius-md);
  background: var(--mono-surface);
  font-size: var(--text-base);
  font-weight: var(--fw-medium);
  color: var(--mono-ink);
}
.sitenav__cta:hover { background: var(--surface-hover); color: var(--mono-ink); }

/* ---------- hero ---------- */

/* A full-width band, so the grid and the closing hairline run edge to edge while
   the content inside keeps the measure. The two gradients draw a 1px rule every
   --grid-cell: the first horizontal, the second vertical. */
.hero {
  background: var(--mono-surface);
  border-bottom: 1px solid var(--mono-line);
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: var(--grid-cell) var(--grid-cell);
  background-position: center top;
}
.hero__inner {
  padding-block: var(--space-11) var(--space-10);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-5);
  text-align: center;
}
.hero__title {
  font-size: var(--text-display);
  line-height: var(--lh-tight);
  letter-spacing: -0.028em;
  /* Deliberately tight. The headline is meant to break into a stack of short
     lines rather than run the full measure; balance then evens them out. */
  max-width: 16ch;
  text-wrap: balance;
}
.hero__lead {
  font-size: var(--text-lead);
  line-height: var(--lh-body);
  color: var(--mono-body);
  max-width: 66ch;
  text-wrap: pretty;
}

/* The status pill above the headline. The dot is ornament — the words carry the
   meaning — so it is aria-hidden in the markup. */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  height: var(--badge-h);
  padding-inline: var(--space-2);
  border: 1px solid var(--mono-line);
  border-radius: var(--radius-pill);
  background: var(--mono-surface);
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  text-transform: uppercase;
  letter-spacing: var(--label-tracking);
  color: var(--mono-muted);
}
.badge__dot {
  width: 6px;
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--mono-green);
}

.waitlist {
  display: flex;
  gap: var(--space-1);
  flex-wrap: wrap;
  width: 460px;
  max-width: 100%;
  margin-top: var(--space-1);
}
.waitlist__input {
  flex: 1 1 240px;
  min-width: 0;
  height: var(--control-h);
  padding-inline: var(--space-3);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  color: var(--mono-ink);
  background: var(--mono-surface);
  border: 1px solid var(--mono-line);
  border-radius: var(--radius-md);
  /* Clears the header when the closing link jumps focus back up here. */
  scroll-margin-top: var(--space-10);
}
.waitlist__input:focus {
  outline: none;
  border-color: var(--mono-blue);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
/* Red, not blue. The failure path focuses the field, so :focus has already
   painted it blue — an "invalid" style in the same colour is invisible, which
   left the error state signalled only by grey 12.5px text while success got
   green. The ring is repeated because the focus rule above wins otherwise. */
.waitlist__input[aria-invalid="true"],
.waitlist__input[aria-invalid="true"]:focus {
  border-color: var(--mono-red);
  box-shadow: 0 0 0 3px var(--danger-ring);
}
.waitlist__note--bad { color: var(--mono-red); }
.waitlist__input:disabled { color: var(--mono-muted); }

.waitlist__submit {
  height: var(--control-h);
  padding-inline: var(--space-4);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  font-weight: var(--fw-medium);
  color: var(--mono-white);
  background: var(--mono-ink);
  border: 1px solid var(--mono-ink);
  border-radius: var(--radius-md);
  cursor: pointer;
}
.waitlist__submit:hover { background: #000000; }
.waitlist__submit:disabled { opacity: 0.55; cursor: default; }

.waitlist__note {
  font-size: var(--text-sm);
  color: var(--mono-muted);
}
.waitlist__note--ok { color: var(--mono-green); }
/* The note is focused on success so the outcome is announced; it is not a
 * control, so it should not look like one. */
.waitlist__note:focus { outline: none; }
.waitlist__note:focus-visible { outline: 2px solid var(--mono-blue); outline-offset: 2px; }

/* ---------- features ---------- */
/* No border-top: the hero band above is closed by its own hairline, and a second
   rule 72px below the first reads as an empty section between them. */
.features > .wrap { padding-block: var(--space-9); }
.features__list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-7);
}
.feature { display: flex; flex-direction: column; gap: var(--space-2); }
.feature__num {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--mono-muted);
}
.feature__title {
  font-size: var(--text-h5);
  letter-spacing: -0.01em;
}
.feature__body { color: var(--mono-body); }

/* ---------- origins ---------- */
.origins > .wrap { border-top: 1px solid var(--mono-line); padding-block: var(--space-9); }
.origins__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-8);
}
.origins__col { display: flex; flex-direction: column; gap: var(--space-4); }
.origins__title {
  font-size: var(--text-h4);
  line-height: var(--lh-heading);
}
.hairlist > li {
  border-top: 1px solid var(--mono-line-2);
  padding-block: var(--space-2);
  color: var(--mono-body);
  line-height: 1.55;
}
.hairlist > li:last-child { border-bottom: 1px solid var(--mono-line-2); }

/* ---------- partners ---------- */
.partners > .wrap { border-top: 1px solid var(--mono-line); padding-block: var(--space-8) var(--space-9); }
.card {
  border: 1px solid var(--mono-line);
  border-radius: var(--radius-lg);
  background: var(--mono-surface);
  padding: var(--space-6);
}
.partners__card {
  display: flex;
  gap: var(--space-6);
  align-items: center;
  flex-wrap: wrap;
}
.partners__copy { flex: 1 1 380px; display: flex; flex-direction: column; gap: var(--space-2); }
.partners__title { font-size: var(--text-h4); letter-spacing: -0.015em; }
.partners__body { color: var(--mono-body); max-width: 60ch; }
.partners__action { display: flex; flex-direction: column; gap: var(--space-1); align-items: center; }
.partners__addr {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--mono-muted);
}

.btn {
  display: inline-flex;
  align-items: center;
  height: var(--control-h);
  padding-inline: var(--space-4);
  border-radius: var(--radius-md);
  font-size: var(--text-base);
  font-weight: var(--fw-medium);
}
.btn--dark {
  background: var(--mono-ink);
  color: var(--mono-white);
  border: 1px solid var(--mono-ink);
}
.btn--dark:hover { background: #000000; color: var(--mono-white); }

/* ---------- the dark band ---------- */
.band { background: var(--band-ink); color: var(--band-text); }
.band > .wrap { padding-block: var(--space-10); }
.band__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-5);
  flex-wrap: wrap;
  margin-bottom: var(--space-7);
}
.band__title { font-size: var(--text-h2); }

.stats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1px;
  margin: 0;
  background: var(--band-line);
  border: 1px solid var(--band-line);
}
.stat {
  background: var(--band-ink);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.stat__value {
  font-family: var(--font-mono);
  font-size: var(--text-h2);
  font-weight: var(--fw-regular);
  letter-spacing: -0.02em;
  color: var(--mono-white);
}
.stat__value sup { font-size: var(--text-stat); }
.stat__desc {
  margin: 0;
  color: var(--band-body);
  line-height: var(--lh-body);
}
.band__disclaimer {
  margin-top: var(--space-5);
  font-size: var(--text-sm);
  line-height: var(--lh-body);
  color: var(--band-muted);
  max-width: 64ch;
}

/* ---------- closing ---------- */
.closing > .wrap { padding-block: var(--space-10); }
.closing__inner {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  /* Capped inside the measure, left-aligned within it. */
  max-width: 560px;
}
.closing__title { font-size: var(--text-h3); }
.closing__body { font-size: var(--text-h5); color: var(--mono-body); }
.closing__link { font-weight: var(--fw-medium); }

/* ---------- footer ---------- */
.sitefooter { border-top: 1px solid var(--mono-line); }
.sitefooter__inner {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding-block: var(--space-4);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--mono-muted);
}
/* The sentence is one line at the measure and two below it. Balanced rather than
   left to fill, because the ragged version drops a single word onto the second
   line and reads as a mistake. */
.sitefooter__id { text-wrap: balance; }
/* The company name is the one word here that is not muted: it is what the block
   exists to say, and at 11.5px muted mono it would read as a footnote. */
.sitefooter__org {
  color: var(--mono-ink);
  font-weight: var(--fw-medium);
}
/* The address and the domain sit on one line and never break: the identity
   sentence beside them is the part that should wrap when the measure runs out. */
.sitefooter__contact {
  display: flex;
  gap: var(--space-3);
  white-space: nowrap;
}

/* ---------- narrow ----------
 * The design this page came from is a fixed-width mock with no mobile treatment,
 * so this is the specified one. It moves TOKENS rather than adding per-rule
 * overrides, so the relationships between sizes survive the breakpoint instead of
 * being re-invented at it.
 *
 * One breakpoint, deliberately. A one-page site with three grids does not need a
 * second, and every extra step is another state nobody re-checks. The 2x2 stat
 * grid stays 2x2 between 720px and the measure — it is already narrow enough
 * there.
 */
@media (max-width: 720px) {
  :root {
    --text-display: 34px;
    --text-h2: 24px;
    --text-h3: 20px;
    --text-lead: 16px;
    --gutter: 20px;
    --space-10: 64px;
    --space-11: 72px;
  }

  .features__list { grid-template-columns: 1fr; }
  .origins__grid { grid-template-columns: 1fr; }
  .stats { grid-template-columns: 1fr; }

  .waitlist { flex-direction: column; align-items: stretch; }
  .waitlist__input { flex: 1 1 auto; }

  .band__head { margin-bottom: var(--space-5); }

  /* The two section links drop; the waitlist control stays. A one-page site does
     not earn a disclosure menu — that is a whole interactive component, with a
     focus trap and an escape key to get right, standing in for two anchors the
     page already scrolls to. What it is asking for stays reachable. */
  .sitenav__link { display: none; }

  /* Two blocks that no longer fit side by side. Stacking keeps the identity
     sentence on a readable measure rather than squeezing it into a column. */
  .sitefooter__inner {
    flex-direction: column;
    align-items: flex-start;
  }
}

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