/* ===========================================================================
   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%; }

/* Reserve an equal gutter on both sides so a classic scrollbar does not pull
   the centred column half a scrollbar to the left. Ignored where unsupported,
   which simply leaves the previous behaviour. Not on phones: they use overlay
   scrollbars, so there is no offset to correct, and reserving two gutters
   would cost 30px of a 390px screen. */
@media (min-width: 561px) {
  html { scrollbar-gutter: stable both-edges; }
}

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) var(--space-4);
}

.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);
}

/* --- outline toggle (phone only) ------------------------------------------ */
/* Hidden everywhere by default: only the max-width:560px block reveals it, so
   the desktop sidebar is untouched. The bars are drawn with borders rather
   than an icon font or SVG — the design system ships no icon set, and plain
   rectangles are the one shape vocabulary it already uses. */

.toc__toggle {
  display: none;
  align-items: center;
  gap: var(--space-2);
  margin: 0 auto;
  padding: 8px 14px;
  background: none;
  border: 1px solid var(--border-hairline);
  border-radius: 0;
  font: inherit;
  color: var(--text-body);
  cursor: pointer;
}

.toc__bars { position: relative; width: 16px; height: 1px; background: currentColor; }
.toc__bars::before,
.toc__bars::after {
  content: "";
  position: absolute;
  left: 0;
  width: 16px;
  height: 1px;
  background: currentColor;
}
.toc__bars::before { top: -5px; }
.toc__bars::after { top: 5px; }

/* Open: the bars fold into a close mark. */
.toc[data-open] .toc__bars { background: transparent; }
.toc[data-open] .toc__bars::before { top: 0; transform: rotate(45deg); }
.toc[data-open] .toc__bars::after { top: 0; transform: rotate(-45deg); }

/* --- 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: bottom;
}

.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 size label takes a fixed measure so every range starts on the same
   vertical, left-aligned, rather than each hugging the column's right edge. */
.results tbody th .size {
  display: inline-block;
  min-width: 4ch;
}

.results tbody th .range {
  margin-left: var(--space-2);
  font-size: 14px;
  /* A 14px inline on a 16px line enlarges the line box by a pixel, which left
     this table a pixel taller per row than the summary below it. */
  vertical-align: top;
  color: var(--text-muted);
  white-space: nowrap;
}

/* The rule under the column headers is ink, as in the environment tables. */
.results thead th { border-bottom-color: var(--ink); }

/* Fixed layout, so widths are set here. Only the label column is sized — it
   must hold the label and its longest range ("XL 5,000–10,000 lines") on one
   line. Every other column is left unsized, so under table-layout: fixed they
   share the remainder equally and stay evenly spread however many agents the
   table carries. */
.results th:first-child { width: 24%; }
/* 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-3) 0;
  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. Row padding matches the results table it sits beneath — the
   two are close enough together that unequal row heights read as an error. */
.dist.summary .env th,
.dist.summary .env td {
  padding: 13px 0;
  border-bottom: 1px solid var(--border-hairline);
}

/* Domain names here are row labels, not entries the reader scans for, so they
   stay regular weight. The environment table keeps its bold names. */
.dist.summary .env th { font-weight: var(--weight-regular); }

/* Auto layout hands slack to the widest columns, which left Domain at 336px of
   800 and S/M/L crushed to 34px. Fixed layout instead: the four text-bearing
   columns are sized to their content, and the five size classes share what is
   left equally, so they come out even. */
.dist.summary { table-layout: fixed; }
.dist.summary th:first-child { width: 28%; }  /* "Implementation correctness" */
.dist.summary th:nth-child(2) { width: 13%; } /* "Environments" */
.dist.summary th:nth-child(3) { width: 12%; } /* "2,547,364" */
.dist.summary th:nth-child(4) { width: 11%; } /* "1,569" */

/* No left inset: the row rules set `padding: 13px 0` on the cells, so any
   inset here would apply to the headers only and shift them half of it off
   centre from the figures beneath. Column widths do the spacing instead. */
.dist.summary .num {
  text-align: center;
  padding-left: 0;
}

/* In the summary table the totals row sits among only two domain rows, so it
   takes their padding: three rows of equal height rather than a taller first. */
.dist.summary .grand-total th,
.dist.summary .grand-total td { padding: 13px 0; }

/* 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);
}

/* In the environment table the totals row is the seam above the first domain
   group, so it carries the same ink rule the other group seams do. The summary
   table keeps its hairline — its totals row leads straight into domain rows. */
.dist:not(.summary) .grand-total th,
.dist:not(.summary) .grand-total td { border-bottom-color: var(--ink); }

/* --- 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: var(--space-4);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border-hairline);
  text-align: center;
}

.footer__legal { margin-top: var(--space-2); 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); }
}

/* --- phone (<=560px) ------------------------------------------------------ */
/* Everything below this line applies to phones only. A laptop never evaluates
   this block, so the desktop rendering cannot regress. */
@media (max-width: 560px) {
  /* A step down across the board: the design system's 16/26 becomes 14/22.
     Overriding the tokens scales every element that uses them at once. */
  :root { --text-size: 14px; --text-leading: 22px; }

  /* At 14px the three meta segments fit one row, so they no longer stack. */
  .masthead__meta { font-size: 13px; }
  .masthead__meta .sep { padding: 0 var(--space-1); }

  /* The outline folds behind a menu button, as on most phone sites. */
  /* Full width of the content column: a bigger tap target, and it reads as a
     control rather than as a stray chip. */
  .toc__toggle { display: flex; justify-content: center; width: 100%; }
  .toc ul { display: none; }

  /* The 52-104px section breaks are desktop spacing; on a phone they leave the
     button marooned. One line above and below is enough here. */
  .masthead { margin-bottom: var(--space-3); }
  .toc { margin-bottom: var(--space-3); }

  /* Four separate spacings stack up under the last section — the footer's
     margin and padding, the legal line's margin, and the shell's bottom
     padding — for ~230px of empty screen. Roughly halved here. */
  .shell { padding-bottom: var(--space-3); }

  /* The logo ran to 66vw — two thirds of a phone screen — with ~60px of air
     above and ~68px below. Smaller mark, tighter on both sides. */
  .masthead__logo { width: min(196px, 50vw); margin-bottom: var(--space-4); }
  .shell { padding-top: var(--space-4); }

  .toc[data-open] ul {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-2);
    margin-top: var(--space-3);
  }
}

/* --- 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; }
}
