/* ===========================================================================
   Intrinsic — Lean RL Environments
   Built on the Intrinsic Design System (_ds/intrinsic-design-system-853f4f…).

   The system's rules, followed literally here:
     · strictly monochrome — black ink on cool off-white, no accent exists
     · Inconsolata only, 16px / 26px, two weights; hierarchy is weight +
       whitespace, NEVER scale (there are no large headings on this page)
     · spacing derived from the 26px line: 13 / 26 / 52 / 104
     · one centered column, 684px prose measure
     · no cards, no shadows, radius 0

   Interim additions (flagged, per the system's own convention):
     · hairline rules on data tables — the source frames contain no tables, and
       reduced-alpha ink (--border-hairline) is the lightest honest way to rule
       one. Used for structure only, never decoration.
   =========================================================================== */

/* --- reset ---------------------------------------------------------------- */

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

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

body {
  margin: 0;
  background: var(--surface-page);
  color: var(--text-body);
  font-family: var(--font-mono);
  font-size: var(--text-size);
  line-height: var(--text-leading);
  font-weight: var(--weight-regular);
  -webkit-font-smoothing: antialiased;
}

/* Hierarchy is weight and whitespace only — headings are body size. */
h1, h2, h3 {
  font-size: var(--text-size);
  line-height: var(--text-leading);
  font-weight: var(--weight-bold);
  margin: 0;
}

p { margin: 0 0 var(--space-3); }

a { color: var(--link); text-decoration: none; }
a:hover { color: var(--link-hover); text-decoration: underline; text-underline-offset: 3px; }

/* Inline references inside body copy carry a standing underline so they are
   findable without hovering — the convention the main Intrinsic site already
   uses for links inside prose. Masthead and footer are excluded: a rule under
   a single short line there reads as an artefact rather than as a link. They
   still underline on hover. */
.content .autolink { text-decoration: underline; text-underline-offset: 3px; }

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

:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

/* --- layout --------------------------------------------------------------- */
/* Three columns: a flexible left margin carrying the sticky outline, the
   centred prose measure, and a flexible right margin. The design system
   specifies a single centred column and no sidebars; the outline is a
   deliberate departure, requested for a document this long, and it sits in
   the margin so the text column stays centred on the page. When the viewport
   is too narrow for two equal margins the left one keeps the outline's width
   and the right one gives way, so the column drifts slightly off-centre
   before collapsing to the system's single column below 900px. */

:root {
  --toc-w: 208px;
  --measure: 800px; /* widened from the system's 684px for this page */
  /* Shared by .layout and .masthead so the title and the text column always
     share a centreline, even when the margins are unequal. */
  --cols: minmax(var(--toc-w), 1fr) minmax(0, var(--measure)) minmax(0, 1fr);
}

.shell {
  max-width: calc(var(--measure) + 2 * (var(--toc-w) + var(--space-4)) + var(--page-pad) * 2);
  margin: 0 auto;
  padding: clamp(48px, 8vh, 60px) var(--page-pad) 60px;
}

.layout {
  display: grid;
  grid-template-columns: var(--cols);
  gap: 0 var(--space-4);
  align-items: start;
}

.content { min-width: 0; }

/* One blank line between paragraphs, section breaks at 52. */
section + section { margin-top: clamp(36px, 5.5vh, var(--space-4)); }

/* Anchor jumps land clear of the top edge. */
section[id],
.dist .env[id] { scroll-margin-top: var(--space-4); }

/* --- sidebar outline ------------------------------------------------------ */

.toc {
  position: sticky;
  top: var(--space-4);
  max-height: calc(100vh - var(--space-5));
  overflow-y: auto;
  overscroll-behavior: contain;
  /* Hug the text column from the margin rather than the page edge. */
  justify-self: end;
  width: var(--toc-w);
  /* A step below the body size: the outline is navigation, not copy. */
  font-size: 14px;
  line-height: 22px;
}

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

.toc li { margin: 0 0 var(--space-2); }
.toc li:last-child { margin-bottom: 0; }

.toc a {
  display: block;
  position: relative;
  padding-left: var(--space-2);
  color: var(--text-muted);
}

/* A mono bullet — the design system bans an invented icon set. */
.toc a::before {
  content: "\2022";
  position: absolute;
  left: 0;
}

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

/* The section in view is marked by weight, never colour — the system is
   strictly monochrome and has no accent to spend here. */
.toc a[aria-current="true"] {
  color: var(--ink);
  font-weight: var(--weight-bold);
}

/* --- masthead ------------------------------------------------------------- */

.masthead {
  text-align: center;
  margin-bottom: clamp(52px, 9vh, var(--space-5));
  /* Same columns as .layout: everything in the masthead sits over the text
     column, so the title is centred on the prose, not on the page. */
  display: grid;
  grid-template-columns: var(--cols);
  gap: 0 var(--space-4);
}
.masthead > * { grid-column: 2; }

.masthead__logo {
  display: block;
  width: min(260px, 66vw);
  margin: 0 auto clamp(52px, 8vh, 78px);
}

/* The one place the page steps off the design system's single type size. The
   system sets hierarchy by weight and whitespace alone; the page title is a
   deliberate exception, kept to a single step so it still reads as the same
   face rather than as a display headline. */
.masthead__title {
  /* Capped below the 800px measure so the title keeps breaking where it did
     at the system's 684px measure: at 20px the title is ~690px, and a 684px
     cap would break it one word early, orphaning "Verification". */
  max-width: 760px;
  margin: 0 auto;
  font-size: 20px;
  line-height: 30px;
}

.masthead__meta {
  margin: var(--space-3) auto 0;
  max-width: var(--measure);
  color: var(--text-muted);
}

/* The meta line's separators carry no meaning — keep them out of the way. */
.masthead__meta .sep { padding: 0 var(--space-1); color: var(--border-hairline); }
.masthead__meta a { color: var(--text-muted); }
.masthead__meta a:hover { color: var(--ink); }

/* --- section heads -------------------------------------------------------- */

.section-head { margin-bottom: var(--space-3); }

.subhead { font-weight: var(--weight-bold); margin: var(--space-4) 0 var(--space-3); }

/* --- prose ---------------------------------------------------------------- */

.prose { max-width: var(--measure); }
.prose > p:last-child { margin-bottom: 0; }

.lede { max-width: var(--measure); }

.muted { color: var(--text-muted); }

code {
  font-family: var(--font-mono);
  font-size: inherit;
  padding: 0 3px;
  background: var(--surface-card);
  box-shadow: inset 0 0 0 1px var(--border-hairline);
}

/* Lists sit on the 26px line like everything else. */
ul, ol { margin: 0 0 var(--space-3); padding-left: var(--space-3); }
li { margin-bottom: var(--space-1); }
li:last-child { margin-bottom: 0; }

/* A paragraph that resumes after a list starts a new thought, so it takes the
   same 52px break the subheads do. Without this it inherits the list's 26px
   while the block below it (a figure or a case box) opens at 52 — which reads
   as the paragraph being stuck to the list above it. */
.prose ul + p { margin-top: var(--space-4); }

ul.checks { list-style: none; padding-left: 0; }
ul.checks > li {
  position: relative;
  padding-left: var(--space-3);
  margin-bottom: var(--space-1);
}
/* A mono hyphen marker — the system has no icon set and forbids inventing one. */
ul.checks > li::before {
  content: "—";
  position: absolute;
  left: 0;
  color: var(--text-muted);
}

/* --- figures -------------------------------------------------------------- */

figure { margin: var(--space-4) 0 0; }

/* Prose that follows a figure gets the same air above it as the figure had,
   so a table never sits tight against the paragraph after it. */
figure + .prose { margin-top: var(--space-4); }

/* Both introduction tables open with a note paragraph, so what follows the
   lede is text; give that seam the text-to-text line, not the figure gap. */
.lede + figure { margin-top: var(--space-3); }


figcaption {
  margin-top: var(--space-3);
  color: var(--text-muted);
  max-width: var(--measure);
}

/* Wide content scrolls inside its own container; the page body never does. */
.scroll-x {
  overflow-x: auto;
  /* Bleed the scroll edge to the page padding so a clipped table looks
     intentional on a narrow screen. */
  margin-inline: calc(var(--page-pad) * -1);
  padding-inline: var(--page-pad);
}

/* --- data tables ---------------------------------------------------------- */

table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums; /* columns of numbers must align */
}

/* A table's caption is its title, so it carries full ink like the copy around
   it rather than the muted tone of supporting text. */
caption { text-align: left; color: var(--text-body); margin-bottom: var(--space-3); }

th, td { text-align: left; padding: 6px 0; vertical-align: baseline; }

thead th {
  font-weight: var(--weight-regular);
  color: var(--text-muted);
  border-bottom: 1px solid var(--border-hairline);
  padding-bottom: var(--space-1);
}

/* Row headers are content, not chrome — full ink, regular weight. */
tbody th { font-weight: var(--weight-regular); color: var(--text-body); }

tbody td, tbody th { border-bottom: 1px solid var(--border-hairline); }

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

/* --- results table -------------------------------------------------------- */
/* A difficulty label and task count, then one column per agent; a leading
   "All tasks" row and one row per bucket. Equal fixed columns so the agents
   read as a comparison rather than as differently-sized cells. */

.results {
  min-width: 560px;
  table-layout: fixed;
}

.results th,
.results td {
  text-align: center;
  padding: 13px var(--space-1);
}

/* Agent names are content, not chrome, so they take full ink and bold. */
.results thead th {
  font-weight: var(--weight-bold);
  color: var(--text-body);
  vertical-align: top;
}

.results thead th .model {
  display: block;
  font-weight: var(--weight-regular);
}

.results tbody td,
.results tbody th {
  font-variant-numeric: tabular-nums;
  border-bottom: 1px solid var(--border-hairline);
}

/* The first column names the row and reads left-aligned; the All-tasks row
   leads and is bold, as the totals rows of the other tables are. */
.results th:first-child { text-align: left; }
.results tbody th { font-weight: var(--weight-regular); }
/* The range sits against the right edge of the label column, so the ranges
   end together and the word "lines" lines up down the rows. */
.results tbody th .range {
  float: right;
  margin-left: var(--space-1);
  font-size: 14px;
  line-height: 26px; /* the body line: keeps the float on the label's line */
  color: var(--text-muted);
  white-space: nowrap;
}

/* Fixed layout, so widths are set here: the label column must hold the
   label and its longest range ("XL 5,000–10,000 lines") on one line, the
   Tasks column needs little, and the four agent columns share the rest. */
.results th:first-child { width: 24%; }
.results th:nth-child(2) { width: 8%; }
.results .all th,
.results .all td { font-weight: var(--weight-bold); }

/* These captions sit under their tables, centred — they read as footnotes on
   the figures rather than as titles above them. */
.results caption,
.summary caption {
  caption-side: bottom;
  text-align: center;
  margin: var(--space-2) 0 0;
}

/* --- distribution table --------------------------------------------------- */

.dist { min-width: 560px; }

/* A note that governs the whole table, so it sits above it. Full ink, not
   muted — it disambiguates two senses of "proof" and has to be read. */
.table-note {
  max-width: var(--measure);
  margin: 0 0 var(--space-3); /* one line above the table, as a caption sits */
  color: var(--text-body);
}

/* Only the numeric columns are inset, header and body alike, so each column's
   label sits directly over its values and no two columns touch. */
/* A gutter between numeric columns. Row rules below zero the side padding
   (`padding: … 0`), so this is written on the cell, not the class, to win. */
.dist tr th.num,
.dist tr td.num { padding-left: var(--space-3); }

/* Numeric columns size to their content (the .num cells never wrap) and the
   name column takes whatever is left, so seven columns share the measure
   without the names being squeezed. */
.dist thead th:first-child { width: 100%; }
.dist thead th.num { width: auto; }

/* Headers sit on the baseline of their last line, so the one-line and
   two-line labels align along the bottom. */
thead th { vertical-align: bottom; }

/* A label broken over two lines: the block sits flush with the column's right
   edge, so its longest line ends on the table border exactly where the digits
   below it do, while the shorter line centres over the longer one. */
thead th.stack > span {
  display: inline-block;
  text-align: center;
}

/* Domain group header. It sits directly under the rule above it (the totals
   row's hairline for the first group, an ink rule for the rest) and keeps its
   air below, before its own list. */
.dist .group th {
  padding: var(--space-1) 0 var(--space-4);
  font-weight: var(--weight-bold);
  border-bottom: none;
}

.dist .group .gloss {
  display: block;
  font-weight: var(--weight-regular);
  color: var(--text-muted);
}

/* Environment row: the name and its three counts. The hairline belongs under
   the description that follows, not between a row and its own description. */
.dist .env th,
.dist .env td {
  padding: var(--space-2) 0 0;
  border-bottom: none;
  vertical-align: baseline;
}

/* The first environment of a group takes its spacing from the header above it,
   so the gap below the gloss matches the gap above the group title. */
.dist .group + .env th,
.dist .group + .env td { padding-top: 0; }

.dist .env th { font-weight: var(--weight-bold); padding-right: var(--space-2); }

/* The description spans the full table width, so it keeps a readable measure. */
.dist .desc td {
  padding: var(--space-1) 0 var(--space-2);
  color: var(--text-muted);
  border-bottom: 1px solid var(--border-hairline);
}

/* Ink rules frame the table: above the totals, between the domain groups, and
   along the bottom. Borders collapse, and where two cells meet with the same
   width the upper cell's colour wins, so each rule is set on the row above the
   seam: the column headers, the description row that precedes a group header
   (:has, supported in all current browsers), and the last row. */
.dist thead th { border-bottom-color: var(--ink); }
.dist .desc:has(+ .group) td { border-bottom-color: var(--ink); }
.dist tbody tr:last-child th,
.dist tbody tr:last-child td { border-bottom-color: var(--ink); }

/* The summary table in the introduction reuses these rules with one change:
   its domain rows carry their own hairline, there being no description rows
   to carry one. */
.dist.summary .env th,
.dist.summary .env td {
  padding: var(--space-1) 0;
  border-bottom: 1px solid var(--border-hairline);
}

/* The totals lead the table, directly under the column headers. */
.dist .grand-total th,
.dist .grand-total td {
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--border-hairline);
  font-weight: var(--weight-bold);
}

/* --- pipeline ------------------------------------------------------------- */
/* The task-generation chart. An ordered list with a hairline spine — responsive
   and readable aloud, which a drawn diagram or an ASCII block would not be. */

.pipeline { list-style: none; margin: 0; padding: 0; max-width: var(--measure); }

.pipeline > li {
  position: relative;
  padding-left: calc(var(--space-3) + var(--space-2));
  padding-bottom: var(--space-3);
  margin: 0;
}

/* The spine, drawn between steps but not past the last one. */
.pipeline > li::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 17px;
  bottom: -4px;
  border-left: 1px solid var(--border-hairline);
}
.pipeline > li:last-child { padding-bottom: 0; }
.pipeline > li:last-child::before { display: none; }

/* The node. A 9px ink square — the system's only shape language is the
   rectangle at radius 0. */
.pipeline > li::after {
  content: "";
  position: absolute;
  left: 0;
  top: 9px;
  width: 9px;
  height: 9px;
  background: var(--ink);
}

.pipeline .step-label { font-weight: var(--weight-bold); }
.pipeline .step-detail { color: var(--text-muted); }

/* --- reward-hacking cases ------------------------------------------------- */

/* Each case sits in a grey-bordered box — outline only, no fill, radius 0.
   The design system has no card pattern; a hairline rule is the lightest way
   to fence three long quoted passages off from the body copy. */
.case {
  max-width: var(--measure);
  margin-top: var(--space-4);
  padding: var(--space-3);
  border: 1px solid var(--border-hairline);
}

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

.case__head { font-weight: var(--weight-bold); margin-bottom: var(--space-3); }
.case__id { overflow-wrap: anywhere; }

blockquote {
  margin: 0 0 var(--space-3);
  padding-left: var(--space-2);
  border-left: 1px solid var(--border-hairline);
  color: var(--text-muted);
}
blockquote p:last-child { margin-bottom: 0; }

/* --- pricing -------------------------------------------------------------- */

.pricing { max-width: var(--measure); min-width: 380px; }
.pricing .tier { font-weight: var(--weight-bold); }
.pricing .lines { color: var(--text-muted); }

.minimum-order { margin-top: var(--space-3); }

/* --- footer --------------------------------------------------------------- */

.footer {
  margin-top: clamp(72px, 11vh, var(--space-5));
  padding-top: var(--space-4);
  border-top: 1px solid var(--border-hairline);
  text-align: center;
}

.footer__legal { margin-top: var(--space-3); color: var(--text-muted); }

/* A link in the legal line takes the muted tone of the line it sits in, so the
   row reads as one colour — the same treatment the masthead meta line gets. */
.footer__legal .autolink { color: inherit; }
.footer__legal .autolink:hover { color: var(--ink); }

/* --- narrow screens ------------------------------------------------------- */

/* Below the two-column threshold the page returns to the design system's
   single centred column, and the outline becomes a wrapped row above it. */
@media (max-width: 900px) {
  .layout { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .masthead { display: block; }

  .toc {
    position: static;
    max-height: none;
    overflow: visible;
    justify-self: stretch;
    width: auto;
    margin-bottom: clamp(52px, 8vh, var(--space-5));
  }

  .toc ul {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-1) var(--space-3);
  }

  .toc li { margin: 0; }
  .toc a[aria-current="true"] { font-weight: var(--weight-regular); }
}

/* Four meta segments on one line wrap badly on a phone. */
@media (max-width: 560px) {
  .masthead__meta .sep { display: none; }
  .masthead__meta > span,
  .masthead__meta > a { display: block; }
}

/* --- print ---------------------------------------------------------------- */
/* This page will be read as a PDF at least as often as in a browser. */

@media print {
  @page { margin: 16mm; }
  body { background: #fff; }
  .shell { padding: 0; max-width: none; }
  .layout { display: block; }
  .toc { display: none; }
  section + section { margin-top: 26px; break-inside: avoid-page; }
  .scroll-x { overflow: visible; margin-inline: 0; padding-inline: 0; }
  figure, table, .case { break-inside: avoid; }
  a { text-decoration: underline; }
}
