/* Dominia — reset, type, grid, and the cartography layer. */

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

/* The family is set on html as well as body so the root element does not sit in the UA default.
   It set no glyphs, but it made the font audit report a third face — "Times New Roman", 1
   element — and an audit you have to explain away is an audit you stop trusting. */
html {
  background: var(--ink);
  font-family: var(--font-body);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--ink);
  color: var(--bone);
  font-family: var(--font-body);
  font-size: var(--t-body);
  line-height: 1.5;
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

h1, h2, h3, h4, p, figure, blockquote, ul, ol { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }

::selection { background: var(--claim); color: var(--bone); }

:focus-visible {
  outline: 1px solid var(--bone);
  outline-offset: 2px;
}

/* ---------------------------------------------------------------- grid */

.page {
  padding-inline: var(--page-margin);
}

.grid {
  display: grid;
  grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
  gap: var(--gutter);
}

/* ---------------------------------------------------------------- type */

/* Ceremony type, set the way inversa.com sets it: sentence case at regular weight, tight
   tracking, tight leading. The old 900-weight all-caps was the loudest thing on every screen
   and it was competing with the board for attention — which is backwards, because the board is
   the product. Line-heights come up with the case change: 0.86 was safe under all-caps and
   would have collided descenders the moment lowercase arrived. Both values are theirs — 0.9 on
   the display size, 1.06 on the headline.
   Re-measured 2026-08 off the reference shots: the four-line 72px headline on /origin sits on
   a 65.7px baseline (0.912) and the two-line home hero on 65px (0.903), so 0.9 was already
   right.

   ---- Display weight: 470, and it is face-compensation, not preference ----

   Round 1 shipped these at 400 and a blind critic read our hero as Light against the bar's
   Medium. Every number in the two stacks is already identical — 72px, -2.16px, 64.8px leading,
   weight 400 on both — so the difference is not spec, it is the FACE. NB International Pro
   draws a heavier stem at 400 than Instrument Sans does, and round 1 could not see that because
   it chose the face on WIDTH parity, which is the wrong axis for the thing the critic named.

   Measured rather than guessed (tools/shot/probes/stem.js): render a glyph at 400px on a
   canvas, take the ink bounding box for cap height, then scan the mid-height row and take the
   first ink run — the left stem. Ratios are against cap height, so they are scale-free.
   NB International Pro 400, measured on inversa.com where its own webfont is loaded:
   stem/cap 0.135 from I, 0.135 from n, x-height 0.733.
   Instrument Sans 400:  0.115 / 0.111  — 15% and 18% light. That is the gap the critic saw.
   Instrument Sans 470:  0.135 / 0.135  — dead on both.
   470 is where the variable wght axis crosses the reference, so 470 is what this is set to.
   Not 600: 600 measures 0.181, which overshoots the bar by 34% and would miss it in the other
   direction. The residual is width — "Environmental" sets 462.5px against the reference's
   447.3px, +3.4% — and it stays, because closing it would mean tracking past the bar's measured
   -2.16px to chase a 3.4% error, i.e. leaving a real spec to fix a smaller problem.

   Only the two display sizes are compensated. The bar tracks 72 and 57.6 negatively and sets
   everything else normal, so those two are the sizes it treats as display; at 18px body the
   same 15% stem deficit is under a pixel and reads as antialiasing rather than as weight. Body
   copy stays 400.

   Faces reconsidered before compensating, not after. Of round 1's nine, Public Sans 440 also
   lands on 0.135/0.135 and is 1.7% closer on width — a statistical tie, since the scanline
   resolves to +/-2.6% at this cap height. Stem could not separate them, so the tiebreak was
   letterform (shots/work/spec5.png, both at 2x under a crop of the reference): Public Sans
   carries Franklin traits the reference does not have — a spurred `a`, angled `s` and `t`
   terminals — where Instrument Sans cuts its terminals horizontally the way NB does. Host
   Grotesk 425 matches the stem too but runs 2.8% narrow with wider apertures. Staying also
   costs nothing: Instrument Sans is already the body face and is already loaded as a variable
   400..700, so 470 needs no new request and adds no third family.

   Leading. 1.06 on the headline, which is the bar's measured value: its 57.6px headings run a
   61.056px baseline. Round 1 set 1.0 here by interpolating between 72px and 18px instead of
   measuring the size in question, and 1.0 is the one leading value on this page that was
   invented rather than observed. 0.9 on the 72px display is measured and correct. */
/* CHANGING THE HERO HEADLINE? READ THIS FIRST.
 *
 * 0.9 leading on a 72px display means the line box is 64.8px — SHORTER than the em — so
 * descenders and the next line's ascenders overlap vertically by design. The gap between two
 * line boxes is exactly 0px and a descender drops about 15px into the line below, so whether
 * anything collides depends entirely on where the glyphs happen to fall horizontally.
 * The current copy — "Walk it to own it." — sidesteps it outright: the headline contains no
 * descender at all. The previous copy ("Your city is your playground.") did not, and cleared
 * only because the "y" of "city" happened to sit above a gap in "playground.".
 *
 * A blind type critic flagged this unprompted — it clears "only by horizontal luck" — and it is
 * right. This is not a bug and it is not loosened here, because 0.9 is measured off the bar
 * (its 72px display runs 64.8px too) and tight display leading is the whole reason the headline
 * reads as set type rather than as large UI text. It is a CONSTRAINT ON COPY, not on CSS.
 *
 * So: after any headline change, look at it at 1440 and check no descender lands on an ascender.
 * If one does, re-break the line rather than raising this number. */
.display {
  font-family: var(--font-display);
  font-weight: 470;
  font-size: var(--t-display);
  line-height: 0.9;
  letter-spacing: var(--track-display);
  color: var(--bone);
}

.headline {
  font-family: var(--font-display);
  font-weight: 470;
  font-size: var(--t-headline);
  line-height: 1.06;
  letter-spacing: var(--track-display);
}

/* 400 and normal tracking, not 500 and -0.02em. The bar tracks two sizes and two only, 72 and
   57.6; at 28.8 it sets normal like everything else, and it has no 500 anywhere on the site. */
.title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--t-title);
  line-height: 1.12;
  letter-spacing: normal;
}

/* Leading and measure both come off the bar's paragraphs, which are denser than anything we
   were setting. Two of its blocks measured independently — the mangrove overlay and the
   Efficiency panel — both set 18px on a 22.5px baseline (1.25) inside a 342px column, roughly
   42 characters. We were at 1.55 on 660px, so our paragraphs were airier AND twice as wide:
   long grey lines with big gaps, which reads as a document rather than a panel. 1.3 rather
   than their exact 1.25 because Instrument Sans carries a taller x-height than NB
   International and 1.25 closes the descenders up against the next line; 20em is 360px at
   18px, within 5% of their column. */
.body {
  font-family: var(--font-body);
  font-size: var(--t-body);
  line-height: 1.3;
  color: var(--bone-2);
  max-width: 20em;
}

.body--lg { font-size: var(--t-body-lg); line-height: 1.25; }
/* Emphasis is a colour step, not a weight step — 400 on 1,992 of the bar's 2,046 elements. */
.body em { font-style: normal; color: var(--bone); }

.data {
  font-family: var(--font-mono);
  font-size: var(--t-data);
  font-variant-numeric: tabular-nums;
  color: var(--bone);
}

.label {
  font-family: var(--font-mono);
  font-size: var(--t-label);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: var(--track-label);
  color: var(--slate-2);
}

.label--sm { font-size: var(--t-label-sm); letter-spacing: var(--track-label-wide); }

/* Section label: always followed by a hairline running to the container's right edge. */
.section-label {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  font-family: var(--font-mono);
  font-size: var(--t-label);
  text-transform: uppercase;
  letter-spacing: var(--track-label);
  color: var(--slate-2);
}

.section-label::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--hairline);
}

/* ---------------------------------------------------------------- wordmark */

.wordmark {
  display: inline-flex;
  align-items: baseline;
  gap: 0.28em;
  font-family: var(--font-display);
  /* 700 -> 400. Round 1 justified the bold by "the bar's one 700 element is its wordmark,
     so identity is allowed a weight nobody else gets". That was read off a 4x crop rather
     than off the DOM, and the DOM says otherwise on both halves of it.
     Probed on inversa.com/origin: the page's ONLY 700 element is a 1x1px absolutely
     positioned <h1>Origin</h1> in JetBrains Mono — an SEO title, not a design element. The
     bar has no visible bold anywhere. Its actual wordmark is `a.logo`, and it measures
     14.4px / weight 400 / letter-spacing normal / NB International Pro — i.e. the same
     weight as the 962 other elements on the page. Identity is not carried by weight there;
     it is carried by position and by the mark beside it, which is what our red square does.
     Ours is the same element at the same size (.footer__mark is var(--t-data) = 14.4), so it
     takes the same 400. Not the 470 the display sizes carry: that number is compensation for
     Instrument Sans's 15% stem deficit against NB at 72px, and at 14.4px the same deficit is
     0.15px of stem — below a pixel, so it renders as antialiasing rather than as weight.
     Bold here was also inverting the page: at 18px/700 in the nav it was the heaviest thing
     on a site whose headline runs 470, so the eye landed on the logo instead of the hero.
     The 0.02em went with the same probe — the reference logo sets letter-spacing normal. */
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: normal;
  color: var(--bone);
  line-height: 1;
}

/* SUPERSEDED BY BRAND GUIDELINES v3 (2026-09-26): the wordmark is Archivo Black 900, uppercase,
   +0.02em, on every page — the same face the footer sign-off already sets. The argument above is
   kept for the record; v3 made identity a brand rule rather than a measurement against the
   reference. */
.wordmark {
  font-family: var(--font-brand);
  font-weight: 900;
  letter-spacing: 0.02em;
}

/* Kept at 400 explicitly rather than left to inherit. It used to sit inside a 700 anchor and
   counted as two bold elements in the font audit without setting a single glyph; the anchor is
   400 now, but pinning it means a future weight change on .wordmark cannot re-introduce a
   phantom bold into the count. */
.wordmark__square {
  font-weight: 400;
  width: 0.2em;
  height: 0.2em;
  background: var(--claim);
  display: block;
}

/* ---------------------------------------------------------------- utilities */

.hairline { height: 1px; background: var(--hairline); border: 0; }
.hairline--strong { background: var(--hairline-strong); }

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

.skip-link {
  position: absolute;
  top: 0; left: 0;
  padding: var(--s-3) var(--s-4);
  background: var(--bone);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: var(--t-label);
  text-transform: uppercase;
  letter-spacing: var(--track-label);
  transform: translateY(-110%);
  z-index: 100;
}

.skip-link:focus { transform: translateY(0); }

/* ---------------------------------------------------------------- polarity compensation
 *
 * Everywhere mono is set as dark type on a light ground it takes --mono-on-light instead of 400.
 * See the token's note in css/tokens.css for the measurement: light-on-dark blooms ~1.25x, so
 * dark-on-light needs the weight back to look like the same typeface.
 *
 * Three contexts qualify: the two inverted sections (.get and the .invert utility, which 003
 * carries), and the hero's CTA chip, which is ink on bone while everything around it is bone on
 * ink. .proof was once a third inverted section and is gone: it became .founders, which is dark
 * and needs no compensation. */
.invert [class*="label"],
.invert .data,
.get [class*="label"],
.get .data {
  font-weight: var(--mono-on-light);
}
