/* ============================================================================
   artefact-overrides.css — everything the site does to an artefact
   ----------------------------------------------------------------------------
   Load order is load-bearing:

       style.css                     the site
       artefacts/oc-doc.css          the artefact components, artifact-native
       artefacts/artefact-overrides.css   <- this file, LAST

   This file is the complete record of the difference between "how the artefact
   looks on claude.ai" and "how it looks on opencues.com". If it is short, the
   two are close. That is the point of keeping it separate: read this, and you
   know the whole delta without going near the 39KB of components next door.

   NO SPECIFICITY TRICKS ARE NEEDED, and none are used. Every selector here is
   written exactly as oc-doc.css writes it, so the two tie on specificity and
   this file wins on source order alone. If you ever find yourself reaching for
   !important, the selector has drifted from its counterpart; fix the selector.

   TO RESTYLE: change a token in the first block. Every component rule in
   oc-doc.css reads from the tokens and none of them hard-codes a colour, so a
   token is the whole dial. Only drop to a component rule (second block) when a
   token genuinely cannot express what you want.
   ============================================================================ */


/* ── 1. TOKENS: the artefact palette, remapped onto the site's ───────────────
   Every colour is expressed as a site variable rather than a hex, so an edit
   to the :root block in style.css carries through to the artefact pages
   automatically and the two can never drift apart.

   Some of these are the same colour written two ways (the artefact's #9ec0ff
   IS --code-blue, its #252525 IS --border). They are restated anyway: the
   value being equal today is a coincidence worth pinning, not a reason to let
   the artefact hold its own private copy of your palette. */
.oc-doc{
  /* Surfaces. --paper goes transparent because the site's .base-grid already
     paints the page; an artefact painting its own #111 behind itself would be
     an invisible no-op today and a visible seam the day the site background
     changes. */
  --paper: transparent;
  /* Panels are RECESSED, not raised: #0c0c0c sits below the #111 page rather
     than above it, matching .brand-resources-example on assets.html, which is
     the site's one existing "content in a box" treatment. The artefact ships
     the opposite idea (#181818, a hair lighter than the page) and the site's
     own --subtle-grey #212121 is lighter still; both were tried and neither is
     what the assets page does.
     This makes --panel and --panel-2 the same colour. They are kept as two
     tokens rather than collapsed into one, so the cards (--panel) and the hero
     frame (--panel-2) can be pulled apart again without editing components. */
  --panel: var(--dark-backing);
  /* EXCEPT the hero/live-demo frame (--panel-2's only consumer): its ground is
     the terminal's own black, so the animated demo reads as one surface with
     the plain .terms beside it rather than a lighter panel (review,
     2026-08-11). Cards and callouts stay on the recessed --panel above. */
  --panel-2: var(--black);
  --hair: var(--border);

  /* The seven site values oc-doc.css restates for standalone use, re-linked
     here so a style.css palette edit still carries through. Without these, the
     artefact's own #000 / #111 / #B5B5B5 copies sit on .oc-doc and SHADOW the
     :root values for everything inside it, so the site palette stops reaching
     the content — and oc-doc.css's own comment, which promises these copies are
     "inert on the site", becomes untrue. `inherit` takes the :root value;
     naming the variable (--black: var(--black)) would be a self-reference
     cycle, which is invalid and falls back to nothing. */
  --black: inherit;
  --bg-colour: inherit;
  --off-white: inherit;
  --base-grey: inherit;
  --code-grey: inherit;
  --dark-grey: inherit;
  --code-purple-hover: inherit;

  /* Text. THIS IS THE BIG ONE, and it inverts the artefact's hierarchy.
     The artefact runs conventionally: white headings, near-white body copy
     (#e6e6e6), grey secondary. The site runs the other way round: headings are
     the LIGHTEST thing (--off-white #B5B5B5), body copy is the DARKEST
     (--base-grey #5B5B5B, what style.css sets on <p>), and emphasis sits
     between them (--code-grey #838383, what style.css sets on <strong>).
     Emphasis on this site is a lift in colour, never in weight.

     If an artefact page ever reads too dim next to its source, --ink is the
     dial. Moving it back toward #e6e6e6 is a one-line change here, but it will
     read brighter than every other page on the site, which is the trade. */
  --heading: var(--off-white);
  --ink: var(--base-grey);
  --strong: var(--code-grey);
  --muted: var(--base-grey);
  --faint: var(--base-grey);

  /* Accents. --accent-2 has no site variable to point at; it is the approved
     violet from the comparison page's range and stays a literal. */
  --accent: var(--code-blue);
  /* The key-press state: the fill the hero caption's keycap takes while it is
     being pressed on "press _ to nudge it up", and the same fill .hkey:active
     uses when you click it. Off-white rather than the artefact's purple.

     This overrules a decision oc-doc.css argues for at length, so the argument
     is worth answering rather than just overwriting. Its case was that the
     press must be a SOLID fill (a tint disappears at video size and in a
     thumbnail) and that of the two site purples the resting --code-purple
     #BE6EEC had to be used over the hover --code-purple-hover #DEA4FF, because
     white on the lighter one is only ~1.9:1. Both points survive: this is still
     a solid fill, and still legible — but off-white puts the press in the
     site's neutral range rather than spending its one accent colour on a
     keycap, and it is brighter than either purple, so it reads harder at
     thumbnail size, not softer.

     --press-fg has to move with it. It was #fff, which on an off-white fill is
     invisible; the ground colour gives ~9.2:1 instead. */
  --press-bg: var(--off-white);
  --press-fg: var(--bg-colour);

  /* Terminal + state */
  --term-bg: var(--black);
  /* The selection fill on a cued value, the tint behind "26%".

     DELIBERATELY NOT --panel. Every other filled surface on an artefact is the
     recessed #0c0c0c, but this one lives mostly INSIDE .term, whose background
     is #000, and #0c0c0c on #000 is a contrast ratio of 1.07:1 — for practical
     purposes invisible. --subtle-grey gives 1.30:1 there, roughly four times
     the separation, which is what lets a selected value still read as
     selected. That is the whole reason --term-hl and --panel are separate
     tokens rather than one; resist the urge to collapse them.

     It also has to work outside the terminal: .term-selected is not scoped to .term, and
     marks values in table cells and captions too, where #212121 sits on the
     #111 page and reads as a lift. */
  --term-hl: var(--subtle-grey);
  --live: var(--code-blue);
  --edge: var(--salmon-accent);
  --mute: var(--base-grey);

  /* Type. The site guarantees all three faces via its own @font-face block, so
     the long system fallback stacks the artifact carries (for the case where
     the base64 fonts fail) are not needed and only muddy what is actually
     rendering. */
  --doc-sans: 'TWK Lausanne', sans-serif;
  --doc-display: 'TWK Lausanne 200', 'TWK Lausanne', sans-serif;
  --doc-mono: 'Ufficio Mono', ui-monospace, monospace;
}


/* ── 2. COMPONENT RULES: where a token could not do the job ──────────────────
   Keep this block short. Anything added here is a place the artefact and the
   site have genuinely diverged in structure, not just in colour. */

/* ── Titles and body text, matched to features.html ──────────────────────────
   The artefact ships a display-led type scale: a 2.8rem/3.5rem h1 in the light
   200 face and a 2rem/3rem h2, which is the BLOG scale (h1.blog-post-title,
   .blog-headline h2). Next to a features page it reads a full step too large.
   These are measured off features.html, not inferred from the cascade:

                   features.html                 artefact, before
     h1     TWK Lausanne   24px / normal / 300    TWK Lausanne 200  44.8px / 56px / 200
     h2     TWK Lausanne 200   24px / 35.2px / 300    same face     32px   / 48px / 200
     p      TWK Lausanne   19.2px / 28.8px / 300  already identical
     strong --code-grey, weight inherited        already identical

   Body copy and emphasis already match exactly once the tokens above are
   applied, so only the two headings and the standfirst move.

   Note h2 keeps the 'TWK Lausanne 200' FAMILY: that is what features.html
   uses too (it inherits .blog-headline h2), and only the size and line-height
   differ. h1 does change family, to the regular face. Weight goes to 300 in
   both cases because that is what features.html computes, and because
   'TWK Lausanne' only declares a 300 face, so asking for 200 there would
   invite a synthesised weight.

   MONO IS DELIBERATELY UNTOUCHED. .eyebrow, h3, th, .badge, .term and the hero
   caption all stay exactly as the artefact draws them. */
.oc-doc h1{
  font-family: var(--doc-sans);
  font-weight: 300;
  font-size: 1.5rem;
  line-height: normal;
}
/* h2 carries the SECTION RHYTHM as well as its type, in this one rule rather
   than two places to cross-check.

   The 12rem is measured, not read off features.html's class names, because its
   spacers collapse into each other: `.features-item` carries .large-spacer
   (12rem) and `.features-item-body` inside it carries .small-spacer (2.2rem),
   and since the item has no padding or border the two adjoining bottom margins
   collapse to the larger. The 2.2rem never appears on screen. The rendered gap
   between one section and the next heading is a flat 192px, on every one of the
   four gaps measured. The artefact shipped 6rem, exactly half, which is what
   made its sections read cramped next to a features page.

   Only margin-top is set. The previous sibling's bottom margin (.6rem after a
   paragraph or a .term, 1.4rem after .column-pair) is adjoining, so it collapses into
   this and the gap stays a flat 12rem whatever component ends the section. All
   15 gaps in the gallery measure 192px on that basis.

   THE DIVIDER SITS UNDER THE TITLE, not over it. oc-doc.css draws it as a
   border-TOP on the heading itself, which puts the rule above the words and
   reads as the previous section being closed off rather than this one being
   opened. features.html does the opposite, and it is the page these are
   measured against: .features-item-body > p:first-of-type (style.css:1215)
   carries the border, so the rule lands beneath the title.

   The site's own note at style.css:1707 says to draw it as a border-top on the
   block AFTER the title, never a border-bottom on the heading. That rule exists
   because comparison's anchored headings are shrink-wrapped to their text, so a
   border on the heading would stop at the last word instead of running the
   column. Artefact headings carry no .heading-anchor and nothing sizes them to
   their content, so they are full-width blocks and the hazard does not arise.

   Taking it on the heading rather than the sibling is also what makes it
   reliable here: a features section always opens with a <p>, but an artefact
   section can open with .column-pair, .stats, .keys or .note-callout (all four occur
   in the gallery). A border-top on .note-callout would hug the top of its
   panel, and on a .scroll wrapper the padding lands inside the scrollport,
   which is the same trap comparison had to special-case at style.css:1736.
   One rule on the heading covers every one of those cases.

   Gap is .6rem on both sides of the line, matching comparison's title pair.
   The sibling's top margin is zeroed so that gap stays flat whatever component
   follows, rather than collapsing to .stats' 2.2rem on some sections.

   ⚠ The class is repeated in that sibling selector on purpose. `.oc-doc h2 + *`
   computes to (0,1,1), and every component that can open a section declares its
   margin at (0,2,0) — .column-pair and .keys and .note-callout at 1.4rem, .stats at
   2.2rem. The plain selector loses to all four, which is precisely the set it
   exists to flatten, and it loses silently. Repeating the class takes it to
   (0,2,1) and it wins on the tie-break instead. Nothing in either sheet targets
   these at three classes, so this is sufficient; it is also why the gap is not
   worth chasing with !important. */
.oc-doc h2{
  font-weight: 300;
  font-size: 1.5rem;
  line-height: 2.2rem;
  margin-top: 12rem;
  margin-bottom: .6rem;
  border-top: 0;
  padding-top: 0;
  border-bottom: 1px solid var(--hair);
  padding-bottom: .6rem;
}
/* The anchor sits inside span.heading-text (title text + anchor), NOT as a direct child
   of the h2 — which keeps these headings out of the site's
   h2:has(> .heading-anchor) shrink-wrap, so the heading stays a full-width
   block and its divider runs the column. The site's row-wide hover reveal is
   neutralised and re-gated on the text span, so the # appears under exactly
   open-standard's conditions: cursor on the words, not the empty row. */
.oc-doc h2:hover .heading-anchor{
  color: var(--bg-colour);
}
.oc-doc .heading-text:hover .heading-anchor,
.oc-doc .heading-anchor:focus-visible{
  color: var(--base-grey);
}
.oc-doc .heading-text:hover .heading-anchor:hover{
  color: var(--code-purple-hover);
}
.oc-doc.oc-doc h2 + *{
  margin-top: 0;
}
/* The standfirst was 1.5rem, which after the change above would make it the
   same size as both headings. features.html has no standfirst at all, so there
   is nothing to match; body size is the congruent choice, and the 6rem it
   already carries underneath still sets it apart as an opener. */
.oc-doc .page-standfirst{
  font-size: 1.2rem;
  line-height: 1.8rem;
}
/* The provenance note that closes a page. oc-doc.css sets it in Ufficio Mono at
   .8rem, which is the artefact's convention for a footnote and worked when the
   page around it was mono too. It no longer is — headers, action links and table
   cells have all moved to the site's faces — and this is 250 words of prose, a
   length monospace at .8rem is genuinely hard to read at. Same figure styling
   as the action links (style.css:161): 1.7rem leading, --base-grey, face and
   weight inherited.

   Like a figure, it does NOT take the 1080px step-down that .oc-doc p gets.
   A figure declares no font-size at all, so it holds the inherited default at
   every width, and this holds 1rem the same way.

   max-width:none is the second half of the ask and the reason it never reached
   the column edge: .foot is a <p class="foot">, so `.oc-doc p` was handing it a
   66ch measure. Releasing it lets the note span the column like every other
   block on the page — same move .oc-doc .card p already makes. The hairline
   above it and its spacing are oc-doc.css's and stay as they are; only the type
   and the measure change. */
.oc-doc .foot{
  font-family: inherit;
  font-size: 1rem;
  line-height: 1.7rem;
  color: var(--base-grey);
  max-width: none;
}
/* Stat figures, brought down to the blog post title's size. Measured on a real
   article rather than read off style.css, because h1.blog-post-title resolves
   through several rules: 44.8px / 56px, TWK Lausanne 200, weight 300.

   The artefact shipped these at 3.2rem, which was fine when its own h1 was
   2.8rem, but the heading pass took that h1 down to features.html's 1.5rem and
   left the figure untouched. A stat was then 51.2px against a 24px page title —
   more than twice it, and bigger than anything on opencues.com. This is the
   largest type the site uses, which is the right ceiling for the one component
   whose whole job is for the number to lead.

   Weight is deliberately NOT set. oc-doc.css asks for 200 and the blog title
   for 300, but 'TWK Lausanne 200' declares a single face, so both resolve to
   the same glyphs; changing it would be a diff with no rendered effect.

   letter-spacing is likewise left at the component's -.02em. That is tracking,
   not size, and it exists because the display face sets bare numerals loosely
   enough that "44" can read as two separate digits. */
.oc-doc .stat b{
  font-size: 2.8rem;
  line-height: 3.5rem;
}
/* Colour is NOT set here on purpose. --heading is already remapped to
   --off-white and --ink to --base-grey in the token block above, which is
   exactly what features.html computes (181,181,181 and 91,91,91). Restating it
   would be a second place to keep in step. Margins are likewise left alone:
   they are rhythm, not type, and the artefact's 6rem section spacing is the
   same 6rem the site puts above its own h2s. */

/* ── Tables, matched to the site's own ───────────────────────────────────────
   style.css:2393-2420 is the site's global table styling and every table on
   opencues.com renders through it, comparison's included — its page-scoped
   block is freeze-pane machinery (sticky panes, inset-shadow dividers), not
   type. So the referent for an artefact table is that global rule, and these
   restate it rather than inventing a third treatment:

                       site (style.css)        artefact, before
     table margin      2.2rem 0                1.4rem 0
     cell padding      .48rem .75rem .48rem 0  .6rem .8rem  (both sides)
     last cell         padding-right: 0        .8rem
     th face           inherited TWK Lausanne  Ufficio Mono
     th size           inherited from table    .8rem / 1.7rem, fixed
     th case           as typed                UPPERCASE, .1rem tracked
     th colour         --off-white             --faint (= --base-grey here)
     last row          border-bottom: none     hairline, same as every row

   Cell TEXT already matched before this block: the global `table` rule sets
   1rem/1.7rem and --base-grey on the table element itself, which beats .oc-doc
   inheriting down, so body cells were never the problem. The header row was.

   th takes `inherit` for size and leading rather than the literal 1rem/1.7rem
   on purpose: that is how the site's own th behaves, and it is what makes the
   two responsive steps work. style.css shrinks `table` at 1000px (1.1/1.5) and
   again at 640px (.9/1.3) and lets cells inherit — but `.oc-doc th` at (0,1,1)
   outranked those bare-element rules, so artefact headers held .8rem at every
   width while their own body cells stepped down around them. The 640px header
   padding is mirrored below for the same reason.

   th.mono and td.mono keep the mono FACE. A cell showing `volume 40 _` is
   showing a literal, which the site sets in mono too (the `code` rule at
   style.css:2385) — dropping it would lose the distinction between a typed
   string and prose about it. Only the colour moves, see below. */
.oc-doc table{
  margin: 2.2rem 0;
}
/* Every artefact table is .scroll-wrapped (5 of 5 across both pages). A table's
   own margin would sit INSIDE the scroll container, so the spacing moves to the
   container — the same swap comparison.html makes for .table-viewport. */
.oc-doc .scroll{
  margin: 2.2rem 0;
}
.oc-doc .scroll table{
  margin: 0;
}
.oc-doc th,
.oc-doc td{
  padding: .48rem .75rem .48rem 0;
}
.oc-doc th:last-child,
.oc-doc td:last-child{
  padding-right: 0;
}
/* ── Small labels are not mono capitals on the site ──────────────────────────
   The artefact sets every small label in Ufficio Mono, uppercase and kerned:
   table headers and the h3 subheadings inside an entry.
   The site does not label anything that way — its own tables run sentence-case
   in the body face — so all three take the same treatment here rather than the
   table alone, and no mono capitals are left anywhere in an artefact.

   The text itself is already authored sentence-case ("With a how-to hint"); it
   was the CSS capitalising it, so dropping text-transform is what produces the
   first-word-only case rather than any rewriting of the markup.

   Face, size and leading are `inherit` deliberately: the label sits at body
   scale and takes whatever the page is set in, which is what stops this from
   becoming a second type scale to maintain.

   COLOUR IS THE ONE THING THEY DO NOT SHARE, and the split is deliberate. A
   table header is read against the cells below it, so it stays --off-white,
   exactly as the site's own `th` does (style.css:2456) — an artefact table and
   a table on comparison.html look the same. A subheading is read against the
   prose it introduces and is already set apart by the space around it, so it
   sits at --base-grey with the body copy instead of standing over it.

   ⚠ Deliberately NOT included: .term-rail-label, the "status line" label inside
   a terminal block. That one is part of the terminal's own artwork, depicting
   what a host prints, so it keeps the mono capitals the product actually
   renders. Mono there is the content, not a label style. */
.oc-doc h3,
.oc-doc .eyebrow,
.oc-doc th{
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  font-weight: 300;
  letter-spacing: normal;
  text-transform: none;
}
/* SUBHEADINGS take body SCALE explicitly, not inherit: the doc's base is
   1rem while body copy is 1.2rem, so `inherit` landed an h3 a step SMALLER
   than the prose it heads — small and grey together read as hard-to-read,
   not as quiet. 1.2rem/1.8rem is the p rule's own pair. Deliberately NOT
   applied to th (a header sits at its table's scale, beside its cells). */
.oc-doc h3,
.oc-doc .eyebrow{
  font-size: 1.2rem;
  line-height: 1.8rem;
}
/* Table headers keep the site's header colour. */
.oc-doc th{
  color: var(--off-white);
}
/* Subheadings sit with the prose at body scale, lifted one step in colour:
   --code-grey, the same lift emphasis takes (#838383 between body #5B5B5B
   and headings #B5B5B5). Decided 2026-08-12 — body-colour subheadings read
   as hard-to-find, not as quiet.
   The LEAD takes the same lift (2026-08-12): oc-doc.css styles p and .lead
   in one rule and this layer maps --ink and --muted both to --base-grey,
   which had flattened the lead into body copy — a set-up line identical to
   the prose it sets up stops earning its place in the grammar. One lift,
   reused: emphasis, subheadings, the lead. */
.oc-doc h3,
.oc-doc .eyebrow,
.oc-doc .lead{
  color: var(--code-grey);
}
/* The zeroed vertical padding is the TABLE's, not the shared label treatment:
   it exists only to beat the `th, td` padding pair further up on source order.
   Kept in its own rule so a future change to cell padding cannot travel out
   along the selector list above and start moving subheadings. */
.oc-doc th{
  padding-top: 0;
  padding-bottom: 0;
}
@media (max-width: 640px){
  .oc-doc th{
    padding-bottom: .2rem;
  }
}
.oc-doc tbody tr:last-child td{
  border-bottom: none;
}
/* ── Cell vocabulary: only what comparison uses ──────────────────────────────
   "The six hosts" is the shape to copy — plain <th>, plain <td>, and literals
   marked with <code>. That is the whole vocabulary comparison's tables have,
   and .oc-doc code already matches style.css's code rule exactly (Ufficio Mono,
   .9em, --black, --code-grey), so a table written that way needs nothing here.

   What the artefact adds on top is a .mono CELL, and the two below bring it
   onto the same footing. Everything else already lands on a site token: .badge
   is --strong on --black, and --strong is remapped to --code-grey in the block
   above, so a badge IS the code pair; .term-selected is --off-white on --subtle-grey.

   th.mono loses the mono face outright. A header is a header — comparison sets
   none of its own in mono, and in practice this put "Value" in Ufficio Mono
   beside "Placement" in TWK Lausanne, one row, two faces. The distinction it
   was drawing belongs to the cells under it, which keep it.

   td.mono keeps mono and takes code's size, so a literal in a cell reads the
   same whether it was written as a .mono cell or as <code>. It does NOT take
   code's --black chip: inline in a sentence that chip marks a few characters,
   but stretched across every cell of a column it becomes a filled band and
   starts competing with the .term-selected fill that marks the selected value. Face and
   size carry the meaning; the ground is what would collide.

   ── TWO COLOURS IN A TABLE, AND NO THIRD ──
   --off-white #B5B5B5 for the header row, --base-grey #5B5B5B for everything
   under it. Nothing in between, which specifically rules out --code-grey
   #838383: it is the site's colour for literal text in PROSE, and every route
   into a cell was quietly bringing it along — .mono cells directly, <code> from
   style.css:2385, .badge through --strong. Three different mechanisms, one
   symptom: a column of values a step lighter than the sentences around them.

   `color: inherit` does the enforcing rather than naming either colour. A
   literal in a <th> inherits the header's --off-white, the same literal in a
   <td> inherits --base-grey, and neither can drift if the table's own colours
   are ever restated. Backgrounds are untouched: --black behind a code chip or a
   badge is a ground, not text, and it still reads at 3.6:1 against --base-grey.

   .term-selected is deliberately still --off-white. It is not an in-between — it is the
   header colour, used in a body cell to mark the one value the row is about,
   and it needs to sit above the --base-grey words beside it to read as
   selected at all. That is also why the artefact's own --term-fg #d6d6d6 is
   gone from cells entirely: it was brighter than the header row. */
.oc-doc th.mono{
  font-family: inherit;
  font-variant-numeric: normal;
}
.oc-doc td.mono{
  font-size: .9em;
}
.oc-doc td.mono,
.oc-doc th code,
.oc-doc td code,
.oc-doc th .badge,
.oc-doc td .badge{
  color: inherit;
}

/* ── Terminal blocks: space around them, on the site's scale ─────────────────
   .term ships with no margin at all, so a terminal butts straight onto the
   paragraph above and below it at whatever those elements bring. 2.2rem is
   .small-spacer (style.css:286), the measure the site puts between stacked
   elements, so a terminal now sits in the page the way any other block does.

   OUTSIDE the block only. Padding is untouched: the .term interior is a picture
   of a terminal, and its .8rem is that terminal's own rhythm, not the page's.
   Growing it would enlarge the depicted surface — and for the .term[data-live]
   blocks it would re-frame the animation captured from them.

   Scoped to terminals in the TOP-LEVEL flow, which is what a margin is for.
   The two selectors cover both pages' structures: gallery terminals are direct
   children of .oc-doc, the features page wraps each entry in a <section class
   ="sec">. Every other .term is a component's own content — 3 inside .hero, 2
   in .before-after cells, 2 in .strip > .reel-frame rows — where an outer margin would push it
   off the frame edge or out of line with the label beside it. Naming the flow
   positions rather than excluding those three keeps any future nesting correct
   by default. */
.oc-doc > .term,
.oc-doc .entry-section > .term{
  margin: 2.2rem 0;
}
/* The section-divider gap wins over the margin above, the same way it does for
   every other component that can open a section. Needed explicitly here because
   `.oc-doc .entry-section > .term` is (0,3,0) and outranks the (0,2,1) sibling reset in
   the h2 block; at (0,3,1) this settles it. No artefact currently opens a
   section with a terminal, so this is a guard, not a fix. */
.oc-doc.oc-doc h2 + .term{
  margin-top: 0;
}

/* Body-copy links. style.css:169 sets `a{text-decoration:none}` and nothing
   else; link COLOUR is applied per content container, in the list beside
   .blog-post-body / .page-body / .faq-fold-answer. .oc-doc deliberately stays
   out of that list so the artefact styling lives in these two files rather
   than being spread into style.css, but the treatment is theirs exactly: blue
   at rest, warming to the purple on hover. Without this, links inherit --ink
   and are not identifiable as links at all. */
.oc-doc a{color:var(--code-blue)}
@media (hover:hover){.oc-doc a:hover{color:var(--code-purple-hover)}}

/* Action links read as COPY, not as labels. oc-doc.css sets .oc-actions in
   Ufficio Mono at .8rem with .06rem tracking, on the reasoning that it matches
   the small mono labels elsewhere on the page (.eyebrow, h3, th). That was true
   of the labels, but these are sentences you click — "Learn about the six hosts
   →", and the section nav at the top of a page — and every link in both
   artefacts is one of them: 61 of 61, all inside .oc-actions.

   The target is your figure styling, style.css:161 — line-height 1.7rem and
   --base-grey, with face, size and weight all left to inherit. That is the
   whole rule, so this mirrors it the same way: `inherit` for the face rather
   than naming TWK Lausanne, 1rem to undo the .8rem (a figure declares no size,
   so it sits at the inherited default), and no font-weight at all, because
   .oc-doc already carries 300 and a figure gets its weight by inheritance too.

   Restating the colour rather than leaving it: it is already --base-grey from
   oc-doc.css, but it is part of the figure rule, so it belongs in the copy of
   it. The hover is untouched and still warms to the purple, which is the
   "Download ↓" treatment on assets.html that oc-doc.css modelled these on.

   Ties with oc-doc.css at (0,2,1) and wins on source order, the same way the
   table rules above do. */
.oc-doc .oc-actions a,
.oc-doc .oc-actions button{
  font-family: inherit;
  font-size: 1rem;
  line-height: 1.7rem;
  letter-spacing: normal;
  color: var(--base-grey);
}
/* An action link that follows a PARAGRAPH is pushed off it by 1.1rem, half of
   .small-spacer. Nothing else gets the push, and the adjacent-sibling
   combinator is what draws that line: a link following a .term, a .scroll or
   any other block keeps the tight .oc-actions rhythm, because those already
   carry their own space and the link reads as attached to the thing above it —
   which is the point when the thing above it is what the link is about.

   The two cases are 34 and 19 across the pages as they stand, so both halves of
   the condition are live; this is not a rule written for a hypothetical.

   The rendered gap is 1.1rem, not 1.7rem: a <p> brings .6rem of bottom margin
   and adjoining margins collapse to the larger of the two. Setting margin-top
   here rather than margin-bottom on the paragraph is what keeps that true — the
   paragraph's own spacing is left alone, so a <p> not followed by a link is
   unaffected.

   (0,2,1) against .oc-doc .oc-actions at (0,2,0), so it wins on specificity
   rather than order and cannot be undone by a later edit to the base rule.
   `p` is deliberate rather than `*:not(div)`: .page-standfirst is a <p> too, so the nav at
   the top of a features page is caught by the same rule — and its 6rem bottom
   margin is the larger, so it collapses to 6rem and nothing moves there. */
.oc-doc p + .oc-actions{
  margin-top: 1.1rem;
}

/* The tablet type step. style.css:174 drops `p` to 1.1rem/1.5rem below 1080px,
   but `.oc-doc p` (0,1,1) outranks a bare `p` (0,0,1) whatever the source
   order, so without this an artefact would hold 1.2rem while every other page
   on the site stepped down around it. */
@media (max-width:1080px){.oc-doc p,.oc-doc .lead{font-size:1.1rem;line-height:1.5rem}}

/* (The hero wordmark rules were removed 2026-09-05: no design carries the mark inside the terminal block.) */

/* Gauges fill on scroll rather than arriving full. artefact-gauges.js zeroes
   the bar at load and restores its authored width when the gauge is scrolled
   to; this is the curve that restore rides.

   cubic-bezier(0.25, 0.1, 0.25, 1) is the contact panel's, and the site's house
   easing generally: 28 of style.css's 39 timing functions are this one,
   including the panel slide, the nav hovers and the download links.

   The transition is gated behind .oc-gauge-armed, which the script adds in the
   very same task as the fill, never earlier. A CSS transition is decided by the
   AFTER-change style, so a class and a width arriving together do animate —
   which is what is wanted going 0 -> target. Arming the class up front instead
   made the browser animate the script's own zeroing, and the bars visibly
   drained from full to empty on page load. Do not hoist this to an
   unconditional rule on .gauge-fill.

   --oc-gauge-dur is duplicated as DURATION_MS in artefact-gauges.js, because
   the number's switch has to land on the same frame as the bar. Change both. */
.oc-doc .gauge{
  --oc-gauge-dur: 1.2s;
}
.oc-doc .gauge.oc-gauge-armed .gauge-fill{
  transition: width var(--oc-gauge-dur) cubic-bezier(0.25, 0.1, 0.25, 1);
}
/* A gauge that never gets its class back (script blocked, JS off) keeps the
   authored width from the markup, so the static page is still correct. */
/* No reduced-motion carve-out: this system ignores the OS switch (the
   animations are the content; see artefact-motion.js). */

/* Breathing room inside the selection fill. oc-doc.css gives .term-selected no padding at
   all, so the grey ends flush against the digits. Colour is left alone: the
   fill is --term-hl in the token block and the text is oc-doc.css's own
   --off-white. */
.oc-doc .term-selected{
  padding: .2rem;
}

/* The PROPOSED qualifier on a heading. The artefact draws it as a mono label,
   kerned like every other small-caps label on the site. Here it becomes a
   superscript in the heading's own face instead, so it reads as an annotation
   ON the title rather than a chip parked beside it.

   Three decisions, each with a referent on this site rather than a number
   picked by eye:
     font    the title's face, var(--doc-display), at weight 300 — the same
             pair .oc-doc h2 computes above.
     size    1rem, which style.css:2959 names as the site's bare <figure> size,
             "inherited TWK Lausanne 300 at the 1rem/1.7rem default".
     raise   vertical-align:super plus line-height:0, exactly the technique
             .comparison-page sup uses at style.css:1661. The zero is
             load-bearing, not tidiness: a raised inline box otherwise grows
             the line it sits in, so the four headings carrying a PROPOSED tag
             would stand taller than the eleven that do not.

   letter-spacing goes back to normal: the .1rem tracking is a mono-label
   convention and reads as a defect on the display face. Colour is left alone,
   still --faint from oc-doc.css, so the tag stays subordinate to its title.

   Case is enforced here rather than left to the markup. The artefact writes
   PROPOSED in capitals, because in mono-and-kerned form it was a small-caps
   label; as a superscript in the display face, capitals shout. Doing it with
   text-transform means it is lowercase whatever any future artefact types
   into the span, which is what "always" has to mean. */
.oc-doc h2 .tag{
  font-family: var(--doc-display);
  font-weight: 300;
  font-size: 1rem;
  line-height: 0;
  letter-spacing: normal;
  vertical-align: super;
  text-transform: lowercase;
  padding-left: .1rem;
}

/* Keycaps are labels, not controls. oc-doc.css draws <kbd> with a 2px bottom
   box-shadow for depth and then, in its own words, follows the promise through:
   "the chips that look pressable, are" — cursor:pointer, user-select:none and
   an :active state that fills the cap purple and drops it 2px. Nothing happens
   when you click, by design; it is tactility.

   On the site that is the wrong promise to make. The depth reads as an
   underline in running prose (Ctrl+Alt+↑ in the Typography lead sits in the
   middle of a sentence), and a pointer cursor over something inert invites a
   click that does nothing. So: flat, inert, and selectable like any other text.

   Both rules tie with their counterparts on specificity and win on source
   order, per the note at the top of this file. The :active rule restates the
   two resting values rather than deleting the declarations, which is the only
   way to neutralise a state rule from a later sheet; keep the values in step
   with .oc-doc kbd in oc-doc.css if that ever changes. */
.oc-doc kbd{
  box-shadow: none;
  cursor: auto;
  user-select: auto;
  -webkit-user-select: auto;
}
.oc-doc kbd:active{
  background: var(--black);
  color: var(--strong);
  transform: none;
  box-shadow: none;
}


/* ── 3. PER-PAGE VARIANTS ────────────────────────────────────────────────────
   When one artefact needs to differ from the rest, add a modifier here and put
   it on that page's wrapper: <div class="oc-doc oc-doc--bright">. A modifier
   beats a fourth stylesheet, because the variant sits next to the tokens it is
   varying. Nothing uses this yet; the example is commented out.

   .oc-doc--bright{ --ink:#e6e6e6; --muted:#8a8a8a }
   ============================================================================ */
