/* rosenbound.com on the Open Stacks design system.
   Every colour, radius, duration, face and type role resolves to a custom property declared
   in tokens.css; this file declares no custom property that holds a colour. Class names carry the
   os- prefix; the patterns the system lacked as React components are rendered here as CSS +
   a small behaviour module in site.js: Instrument, Range, Tabs, Accordion, Track, Article.

   Motion budget. Hover, focus and press use the four duration tokens on opacity, transform,
   colour, border and one surface step. Two things move on their own: <main> fades in once at
   load (os-enter, the only @keyframes rule in the system), and a section's index line and
   heading rise 8px into place the first time the section is scrolled to. Body text, cards and
   instruments never animate on scroll. All of it is inert under prefers-reduced-motion. */

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-padding-top: calc(var(--header-h) + 16px); }
body {
  margin: 0; background: var(--bg); color: var(--text); font: var(--type-body);
  -webkit-font-smoothing: antialiased; overflow-wrap: break-word;
}
h1, h2, h3, h4, p, ul, ol, figure, blockquote, dl, dd { margin: 0; }
ul, ol { padding: 0; } ul { list-style: none; }
a { color: var(--link); text-decoration: none; }
a:hover { color: var(--link-hover); text-decoration: underline; }
code, kbd, pre { font: var(--type-code); }
strong { font-weight: 600; }
img, svg, canvas { max-width: 100%; }
[hidden] { display: none !important; }
:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
/* Text for assistive technology only: kept in the accessibility tree, removed from layout. */
.os-visually-hidden { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }

/* ---------- type roles ---------- */
.os-meta   { font: var(--type-meta); letter-spacing: var(--track-meta); text-transform: uppercase; color: var(--text-muted); }
.os-callnum{ font: var(--type-meta); letter-spacing: var(--track-meta); text-transform: uppercase; color: var(--brass-text); }
.os-num    { font-variant-numeric: tabular-nums lining-nums; }
.os-h2     { font: var(--type-page-title); letter-spacing: var(--track-display); color: var(--text); text-wrap: balance; }
.os-h3     { font: var(--type-panel-title); letter-spacing: var(--track-display); color: var(--text); }
.os-lede   { max-width: var(--measure-prose); color: var(--text-muted); text-wrap: pretty; }
.os-small  { font: var(--type-body-sm); }
.os-prose  { max-width: var(--measure-prose); color: var(--text-muted); }
.os-prose p + p { margin-top: 14px; }

/* ---------- layout ---------- */
.os-wrap { max-width: var(--container-max); margin-inline: auto; padding-inline: var(--gutter); }
@media (min-width: 768px) { .os-wrap { padding-inline: var(--gutter-md); } }
.os-section { padding-block: var(--space-13); border-top: var(--hairline); }
@media (min-width: 768px) { .os-section { padding-block: var(--space-14); } }
.os-section__head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 8px; }
.os-section__idx { font: var(--type-meta); letter-spacing: var(--track-meta); text-transform: uppercase; color: var(--brass-text); }
.os-section .os-lede { margin-top: 12px; }
.os-row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }

/* ---------- card (system card: surface, hairline, brass rule under the head) ---------- */
.os-card { background: var(--surface); border: var(--hairline); border-radius: var(--r-md); box-shadow: var(--shadow-card); }
.os-card__head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 14px; border-bottom: var(--rule);
}
.os-card__body { padding: 16px 18px; }
/* Interactive card: one surface step lighter, a stronger edge and a 2% scale. Keyboard focus
   gets the same treatment as the pointer (:focus-within covers a link inside the card,
   :focus-visible a card that is itself the link); press settles to 99%. The pointer half sits
   behind (hover: hover) so a tap on a touch screen does not leave a card stuck in its hover
   state. --shadow-lift is `none` in the dark scheme, so dark cards separate by surface alone. */
.os-card--hover { transition: background-color var(--dur-hover) var(--ease-out), border-color var(--dur-hover) var(--ease-out), box-shadow var(--dur-hover) var(--ease-out), transform var(--dur-hover) var(--ease-out); }
.os-card--hover:focus-within, .os-card--hover:focus-visible { background: var(--surface-raised); border-color: var(--border-strong); box-shadow: var(--shadow-lift); transform: scale(1.02); }
@media (hover: hover) {
  .os-card--hover:hover { background: var(--surface-raised); border-color: var(--border-strong); box-shadow: var(--shadow-lift); transform: scale(1.02); }
}
.os-card--hover:active { transform: scale(.99); }

/* ---------- controls (system Button, Chip, Badge, NavPill as CSS) ---------- */
.os-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: var(--hit-min); padding: 8px 16px; border-radius: var(--r-md);
  border: 1px solid var(--btn-secondary-border); background: transparent; color: var(--btn-secondary-fg);
  font: var(--type-control); cursor: pointer; white-space: nowrap; text-decoration: none;
  transition: background-color var(--dur-hover) var(--ease-out), opacity var(--dur-hover) var(--ease-out);
}
/* Secondary (the default): an outline that fills one surface step on hover; label and edge keep
   their colour. Primary: the inverse of the ground — ink on paper in the light scheme, paper on
   ink in the dark one — and it answers hover and press with opacity alone, never a colour
   change. No button is filled with the accent; in the dark scheme the accent is brass, and brass
   is identity (wordmark, call numbers, card-head rules) and the focus ring, not an action.
   .os-btn--accent is the earlier name of the primary button and is kept as a selector so markup
   written against it renders the same. */
.os-btn:hover { color: var(--btn-secondary-fg); text-decoration: none; }
.os-btn:not([disabled]):hover { background: var(--surface-raised); }
.os-btn--primary, .os-btn--accent { padding: 8px 18px; background: var(--btn-primary-bg); border-color: var(--btn-primary-bg); color: var(--btn-primary-fg); }
.os-btn--primary:hover, .os-btn--accent:hover { color: var(--btn-primary-fg); }
.os-btn--primary:not([disabled]):hover, .os-btn--accent:not([disabled]):hover { background: var(--btn-primary-bg); opacity: .92; }
.os-btn--primary:not([disabled]):active, .os-btn--accent:not([disabled]):active { opacity: .86; }
.os-btn.os-btn--fired, .os-btn.os-btn--fired:hover { background: var(--ok-soft); border-color: var(--ok-soft); color: var(--ok-text); }
.os-btn[disabled] { opacity: .5; cursor: not-allowed; }

.os-chip { border: none; background: none; padding: 6px 0; cursor: pointer; font: inherit; color: inherit; -webkit-tap-highlight-color: transparent; }
.os-chip__body {
  display: inline-flex; align-items: center; gap: 6px; height: var(--chip-h); padding: 0 12px;
  border-radius: var(--r-sm); border: 1px solid transparent; background: var(--chip-bg); color: var(--chip-text);
  font: var(--type-control);
  transition: background-color var(--dur-tint) linear, color var(--dur-tint) linear, border-color var(--dur-tint) linear;
}
.os-chip:hover .os-chip__body { border-color: var(--border-strong); }
.os-chip[aria-pressed="true"] .os-chip__body { background: var(--accent-soft); color: var(--accent-ink); border-color: var(--accent); font-weight: 600; }

.os-badge {
  display: inline-flex; align-items: center; border-radius: var(--r-sm); padding: 2px 7px;
  font: var(--type-badge); letter-spacing: var(--track-meta); text-transform: uppercase;
  background: var(--chip-bg); color: var(--chip-text); white-space: nowrap;
}
.os-badge--ok    { background: var(--ok-soft);    color: var(--ok-text); }
.os-badge--warn  { background: var(--warn-soft);  color: var(--warn-text); }
.os-badge--brass { background: var(--brass-soft); color: var(--brass-text); }

/* Standalone text link that must meet the 44px target floor without looking like a button. */
.os-link--target { display: inline-flex; align-items: center; min-height: var(--hit-min); }
.os-pill {
  position: relative; display: inline-flex; align-items: center; justify-content: center; min-height: var(--hit-min); min-width: var(--hit-min); padding: 0 12px;
  border-radius: var(--r-sm); font: var(--type-control); color: var(--text-muted); white-space: nowrap;
  transition: color var(--dur-tint) linear;
}
.os-pill:hover { color: var(--text); text-decoration: none; }
.os-pill[aria-current] { color: var(--text); }
.os-pill[aria-current]::after { content: ""; position: absolute; left: 12px; right: 12px; bottom: 6px; height: 2px; background: var(--accent); }

/* ---------- ledger stat strip: the rules are 1px grid gaps over --border ---------- */
.os-ledger { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1px; background: var(--border); border: var(--hairline); border-radius: var(--r-md); overflow: hidden; }
@media (min-width: 768px) { .os-ledger { grid-template-columns: repeat(var(--os-ledger-cols, 4), minmax(0, 1fr)); } }
.os-ledger__cell { background: var(--surface); padding: 16px 18px; display: flex; flex-direction: column; gap: 4px; min-height: var(--hit-min); }
.os-ledger__value { font: var(--type-stat); font-variant-numeric: tabular-nums; color: var(--text); overflow-wrap: anywhere; }
.os-ledger__label { font: var(--type-badge); letter-spacing: var(--track-meta); text-transform: uppercase; color: var(--text-muted); }

/* =====================================================================================
   PATTERN 1 · Instrument
   A framed stage for a live canvas. Caption row on top (call number left, state right)
   with the brass rule under it; the stage holds a <canvas> and a mandatory fallback slot.
   site.js sets data-mode="live" or "fallback"; without JS the fallback is what renders,
   so the frame is never empty.
   ===================================================================================== */
.os-instrument { background: var(--surface); border: var(--hairline); border-radius: var(--r-md); box-shadow: var(--shadow-card); overflow: hidden; }
.os-instrument__head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 14px;
  border-bottom: var(--rule); font: var(--type-meta); letter-spacing: var(--track-meta); text-transform: uppercase;
}
.os-instrument__callnum { color: var(--brass-text); flex: none; }
.os-instrument__state { color: var(--text-muted); text-align: right; }
.os-instrument__stage { position: relative; aspect-ratio: var(--os-stage-ratio, 16 / 10); background: var(--surface); }
.os-instrument__stage > canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.os-instrument__fallback { position: absolute; inset: 0; overflow: auto; padding: 14px; color: var(--text-muted); font: var(--type-body-sm); }
.os-instrument__fallback svg { display: block; width: 100%; height: 100%; }
.os-instrument__fallback table { border-collapse: collapse; width: 100%; font: var(--type-code); font-variant-numeric: tabular-nums; }
.os-instrument__fallback th, .os-instrument__fallback td { text-align: left; padding: 6px 8px; border-bottom: var(--hairline); }
.os-instrument__fallback th { font: var(--type-meta); letter-spacing: var(--track-meta); text-transform: uppercase; color: var(--text-muted); }
.os-instrument:not([data-mode="live"]) .os-instrument__stage > canvas { display: none; }
.os-instrument[data-mode="live"] .os-instrument__fallback { display: none; }
.os-instrument__body { padding: 14px 14px 16px; border-top: var(--hairline); }
.os-instrument__caption { margin-top: 10px; font: var(--type-body-sm); color: var(--text-muted); }

/* =====================================================================================
   PATTERN 2 · Range
   A labelled slider with a tabular mono readout. Track --border, filled portion --accent
   (site.js writes --os-fill as a percentage), thumb --surface-raised with a
   --border-strong edge. The input itself is 44px tall so the hit height meets the floor;
   the visible track stays 2px.
   ===================================================================================== */
.os-range { display: grid; gap: 4px; }
.os-range__row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.os-range__label { font: var(--type-meta); letter-spacing: var(--track-meta); text-transform: uppercase; color: var(--text-muted); }
.os-range__value { font: var(--type-stat); font-variant-numeric: tabular-nums; color: var(--text); }
.os-range__input {
  --os-fill: 0%;
  -webkit-appearance: none; appearance: none; width: 100%; height: var(--hit-min); margin: 0;
  background: transparent; cursor: pointer; border-radius: var(--r-sm);
}
.os-range__input::-webkit-slider-runnable-track {
  height: 2px; border-radius: 1px;
  background: linear-gradient(90deg, var(--accent) var(--os-fill), var(--border) var(--os-fill));
}
.os-range__input::-webkit-slider-thumb {
  -webkit-appearance: none; width: 18px; height: 18px; margin-top: -8px; border-radius: 50%;
  background: var(--surface-raised); border: 1px solid var(--border-strong); box-shadow: var(--shadow-card);
}
.os-range__input::-moz-range-track { height: 2px; border-radius: 1px; background: var(--border); }
.os-range__input::-moz-range-progress { height: 2px; border-radius: 1px; background: var(--accent); }
.os-range__input::-moz-range-thumb { width: 18px; height: 18px; border-radius: 50%; background: var(--surface-raised); border: 1px solid var(--border-strong); }
.os-range__ticks { display: flex; justify-content: space-between; font: var(--type-meta); letter-spacing: var(--track-meta); color: var(--text-muted); }

/* =====================================================================================
   PATTERN 3 · Tabs
   role="tablist" with roving focus and arrow keys (site.js). The active tab is the nav-pill
   treatment: a 2px --accent underline at a 6px offset. Never a filled tab. Horizontal by
   default; aria-orientation="vertical" turns the list into a rail.
   ===================================================================================== */
.os-tabs { display: flex; gap: 2px; flex-wrap: wrap; border-bottom: var(--hairline); }
.os-tabs__tab {
  position: relative; display: inline-flex; align-items: center; gap: 10px;
  min-height: var(--hit-min); padding: 0 12px; border: none; background: none; border-radius: var(--r-sm);
  color: var(--text-muted); font: var(--type-control); cursor: pointer; white-space: nowrap; text-align: left;
  transition: color var(--dur-tint) linear;
}
.os-tabs__tab:hover { color: var(--text); }
.os-tabs__tab[aria-selected="true"] { color: var(--text); }
.os-tabs__tab[aria-selected="true"]::after { content: ""; position: absolute; left: 12px; right: 12px; bottom: 6px; height: 2px; background: var(--accent); }
.os-tabs__num { font: var(--type-meta); letter-spacing: var(--track-meta); color: var(--brass-text); min-width: 22px; }
.os-tabs[aria-orientation="vertical"] { flex-direction: column; flex-wrap: nowrap; border-bottom: none; border-right: var(--hairline); padding-right: 8px; }
.os-tabs[aria-orientation="vertical"] .os-tabs__tab { width: 100%; }
.os-tabpanel { padding-top: 22px; }
.os-tabpanel:focus-visible { outline-offset: 4px; }
.os-tabs-layout { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0 24px; }
@media (min-width: 900px) {
  .os-tabs-layout { grid-template-columns: 240px minmax(0, 1fr); }
  .os-tabs-layout .os-tabpanel { padding-top: 0; }
}
@media (max-width: 899.98px) {
  .os-tabs[aria-orientation="vertical"] { flex-direction: row; flex-wrap: nowrap; overflow-x: auto; border-right: none; border-bottom: var(--hairline); padding-right: 0; scrollbar-width: none; }
  .os-tabs[aria-orientation="vertical"]::-webkit-scrollbar { display: none; }
  .os-tabs[aria-orientation="vertical"] .os-tabs__tab { width: auto; flex: none; }
}

/* =====================================================================================
   PATTERN 4 · Accordion
   Built on <details>/<summary>. The disclosure marker is the system's CSS triangle and
   rotates 90 degrees when open. Enter and Space are native to <summary>.
   ===================================================================================== */
.os-accordion { border-top: var(--hairline); }
.os-accordion__item { border-bottom: var(--hairline); }
.os-accordion__summary {
  list-style: none; display: flex; align-items: center; gap: 14px; min-height: 56px; padding: 12px 2px;
  cursor: pointer; font: var(--type-subhead); color: var(--text); border-radius: var(--r-sm);
}
.os-accordion__summary::-webkit-details-marker { display: none; }
.os-accordion__summary::before {
  content: ""; flex: none; width: 0; height: 0;
  border-left: 6px solid var(--text-muted); border-top: 4px solid transparent; border-bottom: 4px solid transparent;
  transition: transform var(--dur-tint) linear;
}
.os-accordion__item[open] > .os-accordion__summary::before { transform: rotate(90deg); }
.os-accordion__summary .os-badge { margin-left: auto; }
.os-accordion__body { padding: 0 2px 22px 20px; max-width: var(--measure-prose); color: var(--text-muted); }
.os-accordion__body p + p, .os-accordion__body p + ul { margin-top: 14px; }
.os-accordion--inline { border-top: none; }
.os-accordion--inline .os-accordion__item { border-bottom: none; }
.os-accordion--inline .os-accordion__summary { display: inline-flex; min-height: var(--hit-min); padding: 8px 2px; font: var(--type-control); color: var(--accent); }
.os-accordion--inline .os-accordion__summary::before { border-left-color: currentColor; }
.os-accordion--inline .os-accordion__body { padding: 8px 2px 0 20px; }

/* =====================================================================================
   PATTERN 5 · Track
   A horizontal strip of cards, one per vertical, each with the brass rule and a `when`
   badge. Touch and trackpad scroll the strip with scroll-snap; the dots are nav pills that
   jump to a panel. Wide viewports without a reduced-motion preference pin the strip and
   let page scroll drive it (site.js). Below 768px, and whenever reduced motion is on,
   the strip is a plain vertical stack and the dots are gone.
   ===================================================================================== */
.os-track { position: relative; }
.os-track__pin { display: flex; flex-direction: column; }
/* The wrap is a flex item; without min-width:0 its automatic minimum is the strip's intrinsic
   width (four panels side by side), which would push the section wider than the viewport. */
.os-track__pin > .os-wrap { min-width: 0; width: 100%; }
.os-track__strip {
  display: flex; gap: var(--grid-gap); margin-top: 32px; padding-block: 4px 8px;
  overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding-inline: var(--gutter); scrollbar-width: none;
}
.os-track__strip::-webkit-scrollbar { display: none; }
/* Trailing spacer so the last panel can start-align: the strip must be able to scroll to
   the last panel's left edge, which needs (container width − one panel − one gap) of slack
   after it. Without this, the final dots share one scroll position. */
.os-track__strip::after { content: ""; flex: 0 0 calc(100% - var(--os-panel-w) - var(--grid-gap)); }
.os-track__strip { --os-panel-w: clamp(280px, 32vw, 420px); }
.os-track__panel { flex: 0 0 var(--os-panel-w); scroll-snap-align: start; display: flex; flex-direction: column; }
.os-track__panel .os-card__body { display: flex; flex-direction: column; flex: 1; padding: 16px 16px 18px; }
.os-track__panel h3 { font: var(--type-card-title); color: var(--text); margin: 4px 0 8px; }
.os-track__panel p { font: var(--type-body-sm); color: var(--text-muted); }
.os-track__panel .os-track__go { margin-top: auto; padding-top: 16px; }
.os-track__dots { display: flex; gap: 2px; margin-top: 16px; flex-wrap: wrap; }
.os-track__dot { border: none; background: none; cursor: pointer; }
@media (min-width: 1024px) and (prefers-reduced-motion: no-preference) {
  .os-track--pinned { min-height: 220vh; }
  .os-track--pinned .os-track__pin { position: sticky; top: 0; min-height: 100vh; justify-content: center; }
  .os-track--pinned .os-track__strip { scroll-snap-type: none; }
}
@media (max-width: 767.98px), (prefers-reduced-motion: reduce) {
  .os-track__strip { flex-direction: column; overflow: visible; scroll-snap-type: none; }
  .os-track__strip::after { display: none; }
  .os-track__panel { flex-basis: auto; }
  .os-track__dots { display: none; }
}

/* =====================================================================================
   PATTERN 6 · Article
   The long-form template for a page that is read rather than operated. Markup:
     <article class="os-article">
       <header class="os-article__head">  call number, optional badge, h1, lede, button row
       <section class="os-article__section">  call number, h2, then prose and the blocks below
   Head and sections are three-column grids — gutter, a 680px measure, gutter — and every child
   lands in the measure. A child marked .os-article__wide spans all three columns and is sized
   like .os-wrap, so a card grid or a broad table lines up with the header container instead of
   being squeezed into the measure. No viewport units are involved, so a wide block can never
   push the page sideways.
   Type: h1 at the page-title role, h2 at the panel-title role, h3 at the card-title role, body
   at 1.7 leading in the full ink (long reading, so not the muted ink the homepage ledes use).
   Links inside running text are underlined: colour alone does not separate them from the ink.
   Blocks: .os-callout (1px brass rule on the left, no fill; may carry a button row),
   .os-table-wrap > table.os-table (each table scrolls inside its own box; give the wrap
   tabindex="0", role="region" and an aria-label so the box is reachable and named),
   dl.os-deftable (term / definition rows, one <div> per row), .os-article__grid (card grid,
   normally combined with .os-article__wide), .os-article__source and .os-article__refs (a
   citation line under a heading; notes under a block), and the system's cards, badges, lists
   and accordions unchanged. Article sections are not .os-section, so they take no scroll reveal.
   ===================================================================================== */
.os-article__head, .os-article__section { display: grid; grid-template-columns: minmax(var(--gutter), 1fr) minmax(0, 680px) minmax(var(--gutter), 1fr); }
@media (min-width: 768px) { .os-article__head, .os-article__section { grid-template-columns: minmax(var(--gutter-md), 1fr) minmax(0, 680px) minmax(var(--gutter-md), 1fr); } }
.os-article__head > *, .os-article__section > * { grid-column: 2; min-width: 0; }
.os-article__head > .os-article__wide, .os-article__section > .os-article__wide { grid-column: 1 / -1; justify-self: center; width: 100%; max-width: var(--container-max); padding-inline: var(--gutter); }
@media (min-width: 768px) { .os-article__head > .os-article__wide, .os-article__section > .os-article__wide { padding-inline: var(--gutter-md); } }
.os-article__head { padding-block: 40px var(--space-13); }
@media (min-width: 768px) { .os-article__head { padding-block: 56px var(--space-14); } }
.os-article__section { padding-block: var(--space-13); border-top: var(--hairline); }
@media (min-width: 768px) { .os-article__section { padding-block: var(--space-14); } }
.os-article__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.os-article h1 { font: var(--type-page-title); letter-spacing: var(--track-display); color: var(--text); text-wrap: balance; margin: 12px 0 16px; }
.os-article h2 { font: var(--type-panel-title); letter-spacing: var(--track-display); color: var(--text); text-wrap: balance; margin: 8px 0 14px; }
.os-article h3 { font: var(--type-card-title); color: var(--text); margin: 28px 0 8px; }
.os-article h4 { font: var(--type-subhead); color: var(--text); margin: 20px 0 6px; }
.os-article p, .os-article li, .os-article dd { line-height: 1.7; color: var(--text); text-wrap: pretty; }
.os-article p + p, .os-article p + ul, .os-article p + ol, .os-article ul + p, .os-article ol + p { margin-top: 14px; }
.os-article ol { list-style: decimal; padding-left: 22px; }
.os-article li + li { margin-top: 8px; }
.os-article p a, .os-article li a, .os-article dd a, .os-article td a { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.os-article .os-article__lede { font-size: clamp(1.0625rem, 0.8825rem + 0.2vw, 1.17rem); color: var(--text-muted); }
.os-article .os-row { margin-top: 24px; }
.os-article .os-list li { font: inherit; line-height: 1.7; color: var(--text); }
.os-article .os-list li::before { top: 11px; }
.os-article .os-card h3 { margin-top: 4px; }
.os-article .os-card p, .os-article .os-card li { font: var(--type-body-sm); line-height: 1.6; color: var(--text-muted); }
/* A citation or qualifier line directly under a heading (mono meta role, not uppercased: these
   are statute numbers and dates, and case carries meaning). Notes and reference lists under a
   block take the small body role in the muted ink. .os-check is the tick that opens a heading
   whose item is satisfied; it is text, so it is read out, and takes the ok ink. */
.os-article .os-article__source { margin: -2px 0 10px; font: var(--type-code); line-height: 1.5; color: var(--text-muted); }
.os-article .os-article__refs { font: var(--type-body-sm); line-height: 1.6; color: var(--text-muted); }
.os-article .os-table-wrap + .os-article__refs, .os-article .os-article__wide + .os-article__refs { margin-top: 12px; }
.os-check { color: var(--ok-text); margin-right: 6px; }
.os-article__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--grid-card-min), 1fr)); gap: var(--grid-gap); margin-top: 24px; }
@media (min-width: 1280px) { .os-article__grid { gap: var(--grid-gap-xl); } }

.os-callout { margin-top: 24px; padding: 2px 0 2px 20px; border-left: 1px solid var(--brass); }
.os-callout > :first-child { margin-top: 0; }
.os-article .os-callout + p, .os-article .os-callout + ul, .os-article .os-callout + ol, .os-article .os-callout + .os-article__refs { margin-top: 20px; }
.os-callout__title { font: var(--type-subhead); color: var(--text); margin: 0 0 6px; }
.os-article .os-callout h2, .os-article .os-callout h3 { font: var(--type-subhead); letter-spacing: 0; margin: 0 0 6px; }
.os-callout .os-row { margin-top: 16px; }

/* position: relative for the same reason as the ledger scroll box: an absolutely positioned
   descendant (a visually hidden header cell) must be clipped by the box that scrolls. */
.os-table-wrap { position: relative; overflow-x: auto; margin-top: 20px; border: var(--hairline); border-radius: var(--r-md); background: var(--surface); }
/* A table keeps a readable minimum width and lets its box scroll, rather than squeezing every
   cell into three-line wraps on a phone. */
.os-table-wrap > .os-table { min-width: 600px; }
.os-table { width: 100%; border-collapse: collapse; font: var(--type-body-sm); font-variant-numeric: tabular-nums lining-nums; }
.os-table caption { text-align: left; padding: 10px 14px 0; font: var(--type-meta); letter-spacing: var(--track-meta); text-transform: uppercase; color: var(--text-muted); }
.os-table th { text-align: left; white-space: nowrap; padding: 10px 14px; border-bottom: var(--hairline); font: var(--type-meta); letter-spacing: var(--track-meta); text-transform: uppercase; color: var(--text-muted); }
.os-table td { padding: 10px 14px; border-top: var(--hairline); vertical-align: top; color: var(--text); line-height: 1.5; }
.os-table tbody tr:first-child td { border-top: none; }
.os-table .os-num { font-family: var(--font-mono); white-space: nowrap; }
.os-table .os-table__muted { color: var(--text-muted); }

.os-deftable { margin-top: 20px; border-top: var(--hairline); }
.os-deftable > div { display: grid; grid-template-columns: minmax(0, 1fr); gap: 4px 24px; padding: 14px 0; border-bottom: var(--hairline); }
@media (min-width: 640px) { .os-deftable > div { grid-template-columns: 148px minmax(0, 1fr); } }
.os-deftable dt { padding-top: 5px; font: var(--type-meta); letter-spacing: var(--track-meta); text-transform: uppercase; color: var(--text-muted); }

/* =====================================================================================
   Homepage layout. Composition only — every treatment above is reused; nothing below
   introduces a colour, radius, face or duration of its own.
   ===================================================================================== */
/* header: sticky, wordmark row + pill row (pills scroll horizontally under 1100px) */
.os-header { position: sticky; top: 0; z-index: 40; background: var(--bg); border-bottom: var(--hairline); transition: background-color var(--dur-hover) var(--ease-out); }
/* Once the page has scrolled (site.js sets data-scrolled past 8px) the header lets 18% of what
   passes under it through a 20px blur, so the pills stay legible over any section. Height,
   layout and the hairline are unchanged. Engines without backdrop-filter keep the solid ground:
   a translucent header with nothing blurring behind it would put page text under the pills. */
@supports ((backdrop-filter: blur(20px)) or (-webkit-backdrop-filter: blur(20px))) {
  .os-header[data-scrolled] { background: color-mix(in srgb, var(--bg) 82%, transparent); -webkit-backdrop-filter: blur(20px); backdrop-filter: blur(20px); }
}
.os-nav { position: relative; display: flex; align-items: center; gap: 12px; min-height: 60px; flex-wrap: wrap; }
.os-wordmark { display: inline-flex; align-items: center; gap: 10px; font: var(--type-wordmark); letter-spacing: var(--track-display); color: var(--text); min-height: var(--hit-min); }
.os-wordmark:hover { text-decoration: none; color: var(--text); }
.os-wordmark svg { color: var(--brass); flex: none; }
.os-nav__pills { margin-left: auto; position: relative; }
.os-nav__pills ul { display: flex; gap: 2px; }
.os-nav__actions { display: flex; gap: 8px; align-items: center; }
.os-nav__progress { position: absolute; left: 0; bottom: -1px; height: 2px; width: 0; background: var(--accent); }
@media (max-width: 1099.98px) {
  .os-nav { padding-top: 8px; }
  .os-nav__actions { margin-left: auto; }
  .os-nav__actions .os-btn:not(.os-btn--primary):not(.os-btn--accent) { display: none; }
  .os-nav__pills { order: 9; flex-basis: 100%; margin-left: 0; width: calc(100% + 2 * var(--gutter)); margin-inline: calc(-1 * var(--gutter)); }
  .os-nav__pills::after { content: ""; position: absolute; top: 0; right: 0; bottom: 0; width: 32px; pointer-events: none; background: linear-gradient(90deg, transparent, var(--bg)); }
  .os-nav__pills ul { flex-wrap: nowrap; overflow-x: auto; padding: 0 40px 4px var(--gutter); scrollbar-width: none; }
  .os-nav__pills ul::-webkit-scrollbar { display: none; }
}
@media (max-width: 767.98px) { .os-nav__actions .os-btn--primary, .os-nav__actions .os-btn--accent { padding-inline: 12px; } }

/* hero */
.os-hero { border-top: none; padding-block: 40px 56px; }
@media (min-width: 768px) { .os-hero { padding-block: 56px 64px; } }
.os-hero__grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 32px; align-items: center; }
@media (min-width: 1024px) { .os-hero__grid { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 40px; } }
.os-h1 { font: 600 clamp(32px, 4vw, 46px)/1.12 var(--font-display); letter-spacing: var(--track-display); color: var(--text); text-wrap: balance; max-width: 20ch; margin: 12px 0 18px; }
/* 17px at a 1440px viewport, fluid on the same rule as the type roles in tokens.css. */
.os-hero .os-lede { font-size: clamp(1.0625rem, 0.8825rem + 0.2vw, 1.17rem); }
.os-hero .os-row { margin-top: 24px; }
.os-readouts { display: flex; flex-wrap: wrap; gap: 6px 18px; margin-top: 10px; font: var(--type-code); color: var(--text-muted); }
.os-readouts div { display: flex; gap: 6px; }
.os-readouts dd { color: var(--text); font-weight: 500; }
.os-readouts .is-hold { color: var(--ok-text); }
.os-readouts .is-flip { color: var(--warn-text); }
#surface { cursor: grab; } #surface:active { cursor: grabbing; }

/* Wide hero: from 1440px the instrument keeps its place on the right and its frame runs on to
   the edge of the viewport, so the wide-screen margin carries the instrument rather than empty
   ground. The copy column does not move and nothing is ever laid over the canvas.
   The grid is built from tracks, not from 100vw: margin | copy | instrument | margin, with the
   instrument spanning the last two. 100vw includes a classic scrollbar, so a bleed sized from
   it overflows the page by the scrollbar's width; 1fr tracks cannot. --os-hero-copy and
   --os-hero-inst are the widths the 5fr / 7fr columns have inside the 1200px container, so at
   exactly 1440 the layout is the narrower one with the frame's right edge extended.
   The stage takes a fixed height instead of its 16:10 ratio, or a frame twice as wide would be
   twice as tall; the camera aspect follows the canvas, and the fallback SVG letterboxes inside
   the same stage, so both render at the same scale as below 1440. The caption row and the
   controls keep their right edge on the container line; only the stage and the rules bleed. */
@media (min-width: 1440px) {
  .os-hero__grid {
    --os-hero-gap: 40px;
    --os-hero-inner: calc(var(--container-max) - 2 * var(--gutter-md) - var(--os-hero-gap));
    --os-hero-copy: calc(var(--os-hero-inner) * 5 / 12);
    --os-hero-inst: calc(var(--os-hero-inner) * 7 / 12);
    max-width: none; padding-inline: 0; gap: 0;
    grid-template-columns: minmax(var(--gutter-md), 1fr) calc(var(--os-hero-copy) + var(--os-hero-gap)) var(--os-hero-inst) minmax(var(--gutter-md), 1fr);
  }
  .os-hero__grid > :first-child { grid-column: 2; padding-right: var(--os-hero-gap); min-width: 0; }
  .os-hero__grid > .os-instrument { grid-column: 3 / 5; min-width: 0; border-right: none; border-radius: var(--r-md) 0 0 var(--r-md); }
  .os-hero__grid > .os-instrument .os-instrument__stage { aspect-ratio: auto; height: 440px; }
  .os-hero__grid > .os-instrument .os-instrument__head,
  .os-hero__grid > .os-instrument .os-instrument__body { padding-right: max(14px, calc(100% - var(--os-hero-inst) + 14px)); }
}

/* Headline stagger, homepage h1 only. page.js wraps each word in .os-word, sets --os-word-i on
   it and --os-word-step on the h1, then adds .is-in on the next frame; each word fades and rises
   6px with a delay of its index times the step. Words are inline-block so they can take a
   transform; they keep their spaces between them, so line breaks and the height of the h1 are
   the same as for the unsplit text and nothing shifts. The hidden state exists only once page.js
   has marked the h1 .os-stagger, and the whole rule only without a reduced-motion preference. */
@media (prefers-reduced-motion: no-preference) {
  .js .os-stagger .os-word { display: inline-block; opacity: 0; transform: translateY(6px); }
  .js .os-stagger.is-in .os-word { opacity: 1; transform: none; transition: opacity var(--dur-tint) var(--ease-out), transform var(--dur-tint) var(--ease-out); transition-delay: calc(var(--os-word-i) * var(--os-word-step)); }
}
.os-instrument .os-row { margin-top: 12px; }

/* verticals: one card per vertical, in a single column until 1280px and 2 x 2 from there.
   Cards in a row stretch to the same height and the link sits on the bottom edge of each. */
.os-verticals { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--grid-gap); margin-top: 32px; }
@media (min-width: 1280px) { .os-verticals { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--grid-gap-xl); } }
.os-vertical { display: flex; flex-direction: column; }
.os-vertical .os-card__body { display: flex; flex-direction: column; flex: 1; padding: 16px 18px 18px; }
.os-vertical h3 { font: var(--type-card-title); color: var(--text); margin: 4px 0 8px; }
.os-vertical p { font: var(--type-body-sm); color: var(--text-muted); max-width: var(--measure-foot); }
.os-vertical .os-vertical__go { margin-top: auto; padding-top: 16px; }

/* numbers */
.os-numbers .os-ledger { margin-top: 16px; }

/* quote and callout */
.os-quote { border-left: 3px solid var(--brass); padding-left: 20px; margin-top: 28px; max-width: var(--measure-prose); }
.os-quote p { font: 500 clamp(20px, 2.2vw, 26px)/1.35 var(--font-display); letter-spacing: var(--track-display); color: var(--text); }
.os-quote .os-attrib { margin-top: 14px; font: var(--type-meta); letter-spacing: var(--track-meta); text-transform: uppercase; color: var(--text-muted); }
.os-note { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; align-items: center; margin-top: 32px; padding: 18px 20px; border-left: 3px solid var(--brass); background: var(--surface); border-radius: 0 var(--r-md) var(--r-md) 0; }
@media (min-width: 900px) { .os-note { grid-template-columns: minmax(0, 1fr) auto; gap: 20px; } }
.os-note p { max-width: var(--measure-prose); color: var(--text-muted); }
.os-section .os-accordion--inline { margin-top: 12px; }
.os-section .os-accordion { margin-top: 24px; }
.os-cta { margin-top: 24px; }

/* platform */
.os-platform .os-tabs-layout { margin-top: 32px; padding: 8px; }
.os-platform .os-tabpanel h3 { font: var(--type-panel-title); letter-spacing: var(--track-display); color: var(--text); margin: 10px 0 12px; }
.os-platform .os-tabpanel p { color: var(--text-muted); max-width: var(--measure-prose); }
.os-platform .os-tabpanel { padding: 20px 22px 24px; }
@media (min-width: 900px) { .os-platform .os-tabpanel { padding: 20px 30px 28px; } }

/* methodology */
.os-method { display: grid; grid-template-columns: minmax(0, 1fr); gap: 24px; margin-top: 32px; align-items: start; }
@media (min-width: 1024px) { .os-method { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
.os-method .os-instrument__stage { --os-stage-ratio: 4 / 3; }
.os-plabel {
  position: absolute; transform: translate(-50%, -50%); pointer-events: none; white-space: nowrap;
  padding: 2px 6px; border-radius: var(--r-sm); background: var(--surface); color: var(--text-muted);
  font: var(--type-badge); letter-spacing: var(--track-meta); text-transform: uppercase;
  transition: background-color var(--dur-tint) linear, color var(--dur-tint) linear;
}
.os-plabel.is-on { background: var(--accent-soft); color: var(--accent-ink); }
.os-method-detail .os-card__body h3 { font: var(--type-card-title); color: var(--text); margin: 6px 0 8px; }
.os-method-detail .os-card__body p { color: var(--text-muted); }
.os-method-detail [data-method] + [data-method] { margin-top: 18px; padding-top: 18px; border-top: var(--hairline); }
.os-method-detail [data-method][hidden] + [data-method] { border-top: none; padding-top: 0; margin-top: 0; }

/* benchmarks */
.os-bench { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; margin-top: 32px; }
@media (min-width: 640px) { .os-bench { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .os-bench { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.os-bench__val { display: block; font: var(--type-stat); font-variant-numeric: tabular-nums; color: var(--text); margin-bottom: 8px; overflow-wrap: anywhere; }
.os-bench .os-card__body { padding: 14px 16px 16px; color: var(--text-muted); font: var(--type-body-sm); }

/* ledger demo */
.os-ledger-demo .os-instrument__body { border-top: none; }
.os-ledger-demo .os-h3 { margin: 8px 0 10px; }
/* position: relative makes the scroll box the containing block of any absolutely positioned
   descendant (the visually hidden column header). Without it that 1px box is positioned against
   an ancestor outside the scroll box, is not clipped by it, and widens the page by the table's
   overflow on a narrow screen. */
.os-ledger-demo__wrap { position: relative; margin-top: 20px; border: var(--hairline); border-radius: var(--r-md); overflow-x: auto; background: var(--surface-raised); }
/* The table already sits on the raised surface, so its buttons step down to show their hover. */
.os-ledger-demo__wrap .os-btn:not([disabled]):hover { background: var(--surface); }
.os-ledger-demo table { width: 100%; border-collapse: collapse; font: var(--type-code); min-width: 640px; }
.os-ledger-demo th { text-align: left; font: var(--type-meta); letter-spacing: var(--track-meta); text-transform: uppercase; color: var(--text-muted); padding: 10px 14px; border-bottom: var(--hairline); background: var(--surface-raised); }
.os-ledger-demo td { padding: 8px 14px; border-top: var(--hairline); vertical-align: middle; transition: background-color var(--dur-tint) linear; }
.os-ledger-demo tr.is-broken td { background: var(--warn-soft); }
.os-ledger-demo__seq { font: var(--type-meta); letter-spacing: var(--track-meta); color: var(--brass-text); }
.os-ledger-demo__ev { font-weight: 500; color: var(--text); white-space: nowrap; }
.os-ledger-demo__pay { color: var(--text-muted); overflow-wrap: anywhere; }
.os-ledger-demo__pay em { font-style: normal; color: var(--warn-text); font-weight: 500; }
.os-ledger-demo__hash { white-space: nowrap; color: var(--text-muted); }
.os-ledger-demo__hash.is-ok { color: var(--ok-text); }
.os-ledger-demo__hash.is-bad { color: var(--warn-text); }
.os-ledger-demo__act { text-align: right; }
.os-ledger-demo__act:empty { display: none; }
.os-ledger-demo table:not([data-live]) .os-ledger-demo__act { display: none; }
.os-btn--small { padding: 8px 12px; }
.os-ledger-demo__diff { margin: 12px 0 0; padding: 12px 14px; border-left: 3px solid var(--warn-text); background: var(--warn-soft); color: var(--warn-text); font: var(--type-code); white-space: pre-wrap; overflow-wrap: anywhere; }

/* sdk */
.os-h2--mono { font: 500 clamp(24px, 3vw, 32px)/1.15 var(--font-mono); letter-spacing: 0; }
.os-install { display: inline-flex; align-items: center; gap: 12px; background: var(--surface); border: var(--hairline); border-radius: var(--r-md); padding: 6px 6px 6px 14px; font: 500 clamp(0.9375rem, 0.8025rem + 0.15vw, 1.03rem)/1 var(--font-mono); margin-top: 20px; max-width: 100%; }
.os-install code { font: inherit; }
.os-section .os-badges { margin-top: 18px; display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.os-sdk .os-tabs { margin-top: 28px; }
.os-sdk .os-tabpanel ul, .os-sdk .os-tabpanel ol { display: flex; flex-direction: column; gap: 14px; max-width: var(--measure-foot); color: var(--text-muted); }
.os-sdk .os-tabpanel ol { list-style: decimal; padding-left: 22px; }
.os-sdk .os-tabpanel pre { margin: 8px 0; padding: 12px 14px; border-radius: var(--r-sm); background: var(--surface); border: var(--hairline); color: var(--accent-ink); font: var(--type-code); white-space: pre-wrap; overflow-x: auto; }
.os-footnote { margin-top: 26px; }

/* design partners */
.os-partners { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; margin-top: 32px; }
@media (min-width: 768px) { .os-partners { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.os-list li { position: relative; padding-left: 18px; color: var(--text-muted); font: var(--type-body-sm); }
.os-list li + li { margin-top: 10px; }
.os-list li::before { content: ""; position: absolute; left: 0; top: 8px; width: 6px; height: 6px; border-radius: 1px; background: var(--brass); }

/* footer */
.os-footer { border-top: var(--hairline); padding-block: 44px 52px; background: var(--surface); }
.os-footer__grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 28px; }
@media (min-width: 640px) { .os-footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .os-footer__grid { grid-template-columns: minmax(0, 1.4fr) repeat(3, minmax(0, 1fr)); } }
.os-footer h2 { font: var(--type-meta); letter-spacing: var(--track-meta); text-transform: uppercase; color: var(--text-muted); margin-bottom: 8px; }
.os-footer p { max-width: var(--measure-foot); color: var(--text-muted); }
.os-footer p + p { margin-top: 12px; }
.os-footer__links a { display: inline-flex; align-items: center; min-height: var(--hit-min); font: var(--type-body-sm); }
.os-footer__legal { margin-top: 32px; padding-top: 18px; border-top: var(--hairline); font: var(--type-code); color: var(--text-muted); }

/* ---------- page entry, page-to-page transition, section reveal ----------
   Declared only for viewers with no reduced-motion preference, so under `reduce` these rules do
   not exist rather than being switched off afterwards.
   os-enter: <main> fades from transparent once at load. It is the single @keyframes rule in the
   system. Opacity only, so it cannot shift layout.
   @view-transition: same-origin page-to-page navigations cross-fade with the browser's default
   group; no named groups. Engines without cross-document view transitions ignore the rule.
   The entry and the reveal both run for --dur-exit. */
@media (prefers-reduced-motion: no-preference) {
  @keyframes os-enter { from { opacity: 0; } }
  main { animation: os-enter var(--dur-exit) var(--ease-standard) both; }
  @view-transition { navigation: auto; }
}
/* Section reveal. site.js marks a section's index line and heading .os-reveal only when they
   are still below the fold at start-up, then adds .is-in the first time each one intersects the
   viewport; it never removes it. The hidden state needs the .js class that site.js puts on
   <html>, so a page whose script did not run shows every heading. Screen only (a printed page
   is never scrolled), 768px and up, and never under reduced motion. */
@media screen and (min-width: 768px) and (prefers-reduced-motion: no-preference) {
  .js .os-reveal { opacity: 0; transform: translateY(8px); }
  .js .os-reveal.is-in { opacity: 1; transform: none; transition: opacity var(--dur-exit) var(--ease-out), transform var(--dur-exit) var(--ease-out); }
}

/* ---------- more contrast ----------
   A viewer who asks for more contrast gets every control drawn with a 2px outline in its own
   text colour, whatever its resting border is. Because that outline is always present, keyboard
   focus on the same element doubles it to 4px so focus is still told apart by more than hue.
   Two controls cannot use their own text colour: the primary button's label is the ground colour,
   which would draw the outline invisibly on the ground, so it takes the button's fill instead;
   and a range input's text colour is a browser default rather than a token. */
@media (prefers-contrast: more) {
  .os-btn, .os-chip__body, .os-pill, .os-tabs__tab, .os-accordion__summary, .os-range__input, .os-table-wrap { outline: 2px solid currentColor; outline-offset: 2px; }
  .os-btn--primary, .os-btn--accent { outline-color: var(--btn-primary-bg); }
  .os-range__input { outline-color: var(--text); }
  :is(.os-btn, .os-pill, .os-tabs__tab, .os-accordion__summary, .os-range__input, .os-table-wrap):focus-visible { outline-width: 4px; }
}

/* ---------- motion floor ----------
   Transitions collapse to effectively zero, smooth scrolling is off, and a view transition the
   browser has already started is stripped of its animation. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: .01ms !important; transition-delay: 0ms !important; scroll-behavior: auto !important; }
  html { scroll-behavior: auto; }
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
}
