/* OneTwo components, 2026-10-10 (D51). The public classes named in DESIGN.md section 9.
   Needs onetwo-fonts.css and onetwo.css first.
   Weight: each component is one class (0,1,0), so it beats element resets such as Tailwind's preflight (a { color: inherit })
   and a host's a {} rules. Resets of margin and padding, and the plain-link rule, sit in :where() and carry no weight, so a
   page's own class wins over them. Values read only the semantic tokens; each component-only number is a space step or an em
   of the element's own size, so it scales on the slide stage too. Sources: build/components.py (D47), build/scale.py (D45, D46).
   Never add a class here without adding it to DESIGN.md. */

/* ---------- the page and its grounds ---------- */
.ot-page {
  margin: 0;
  background: var(--ot-ground);
  color: var(--ot-text-body);
  font-family: var(--ot-font-sans);
  font-feature-settings: var(--ot-features-words);
  font-size: var(--ot-body-size);
  line-height: var(--ot-body-line);
  letter-spacing: var(--ot-body-track);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
/* Any element that switches the ground also paints it, so its text never lands on the wrong colour */
[data-ot-ground], .ot-ground { background: var(--ot-ground); color: var(--ot-text-body); }
.ot-page, .ot-page *, .ot-page *::before, .ot-page *::after { box-sizing: border-box; }
:where(.ot-page) :where(h1, h2, h3, h4, p, ul, ol, figure, blockquote, hr) { margin: 0; }
:where(.ot-list, .ot-steps, .ot-parts) { margin: 0; padding: 0; }

/* ---------- layout (D45, D51): 1200 content; margins 120 at 1440 easing to 24 on phones; two columns fold to one ---------- */
.ot-container { width: 100%; max-width: calc(var(--ot-web-content) + 2 * var(--ot-web-margin)); margin-inline: auto; padding-inline: var(--ot-web-margin); }
.ot-section { padding-block: var(--ot-space-9); }
.ot-split { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--ot-space-7) var(--ot-space-9); align-items: start; }
.ot-table-wrap { overflow-x: auto; }
@media (max-width: 759px) {
  .ot-split { grid-template-columns: minmax(0, 1fr); }
}

/* The rhythm: put .ot-stack on any column of content and the gaps follow the system (DESIGN.md section 6, Rhythm) */
.ot-stack > * + * { margin-top: var(--ot-space-5); }
.ot-stack > p + p { margin-top: var(--ot-space-4); }
.ot-stack > .ot-lede + * { margin-top: var(--ot-space-6); }
.ot-stack > p:not(.ot-lede) + :is(.ot-list, .ot-steps) { margin-top: var(--ot-space-2); }   /* a lead-in and its list; a lede keeps its space 6 */
.ot-stack > * + :is(.ot-table-wrap, .ot-table, .ot-quote, .ot-note, .ot-parts, .ot-figure, .ot-spec, .ot-key, .ot-actions, .ot-code-frame, .ot-summary, .ot-rows) { margin-top: var(--ot-space-7); }
.ot-stack > :is(.ot-cover, .ot-title) + .ot-lede { margin-top: var(--ot-space-4); }
.ot-stack > :is(.ot-title, .ot-heading) + :not(.ot-lede) { margin-top: var(--ot-space-4); }
.ot-stack > * + :is(.ot-title, .ot-heading) { margin-top: var(--ot-space-8); }
.ot-stack > .ot-section-line + :is(.ot-cover, .ot-title, .ot-heading) { margin-top: var(--ot-space-2); }

/* ---------- the bar: the website nav and the portal bar (D46): lockup left, the client's name or the links right ---------- */
.ot-bar { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: var(--ot-space-2) var(--ot-space-5); padding-block: var(--ot-space-5); border-bottom: var(--ot-line-hairline) solid var(--ot-rule); }
.ot-bar-end { font-size: var(--ot-small-size); line-height: var(--ot-small-line); color: var(--ot-text-secondary); }
/* The lockup: use the Tight files in mark/ (no clear space inside); the surface sets the type size it is fitted to */
.ot-lockup { display: block; color: var(--ot-mark); height: calc(var(--ot-lockup-type) * var(--ot-lockup-ratio)); width: auto; max-width: 100%; object-fit: contain; object-position: left center; }
.ot-object { display: block; max-width: 100%; height: auto; }

/* ---------- type roles: one class per role; sizes come from the surface (web, doc, slide) ---------- */
.ot-cover, .ot-title, .ot-heading { color: var(--ot-text); font-weight: var(--ot-weight-medium); text-wrap: balance; }
.ot-cover   { font-size: var(--ot-cover-size);   line-height: var(--ot-cover-line);   letter-spacing: var(--ot-cover-track); }
.ot-title   { font-size: var(--ot-title-size);   line-height: var(--ot-title-line);   letter-spacing: var(--ot-title-track); }
.ot-heading { font-size: var(--ot-heading-size); line-height: var(--ot-heading-line); letter-spacing: var(--ot-heading-track); }
.ot-lede    { font-size: var(--ot-lede-size);    line-height: var(--ot-lede-line);    letter-spacing: var(--ot-lede-track); color: var(--ot-text-body); }
.ot-body    { font-size: var(--ot-body-size);    line-height: var(--ot-body-line);    letter-spacing: var(--ot-body-track); color: var(--ot-text-body); }
.ot-small   { font-size: var(--ot-small-size);   line-height: var(--ot-small-line);   letter-spacing: var(--ot-small-track); color: var(--ot-text-body); }
.ot-measure { max-width: var(--ot-measure); }
.ot-strong  { font-weight: var(--ot-weight-medium); color: var(--ot-text); }
.ot-figures { font-variant-numeric: tabular-nums; }

/* The mono: captions, part, section and page numbers, real code. Never a sentence, a title or emphasis; never in colour. */
.ot-label, .ot-caption, .ot-source {
  font-family: var(--ot-font-mono);
  font-feature-settings: var(--ot-features-label);
  font-size: var(--ot-label-size); line-height: var(--ot-label-line); letter-spacing: var(--ot-label-track);
  text-transform: uppercase;
  color: var(--ot-text-secondary);
}
.ot-code {
  font-family: var(--ot-font-mono);
  font-feature-settings: normal;   /* code keeps the slashed zero */
  font-size: var(--ot-code-size); line-height: var(--ot-code-line); letter-spacing: 0;
  color: var(--ot-text);
}
.ot-section-number {
  font-size: var(--ot-section-number-size); line-height: var(--ot-section-number-line); letter-spacing: var(--ot-section-number-track);
  font-weight: var(--ot-weight-medium); font-variant-numeric: tabular-nums; color: var(--ot-text-quiet);
}
/* The section line (D44): slides and dense documents only, never the web. The section's name, sentence case, plain Geist, grey. */
.ot-section-line { font-size: var(--ot-small-size); line-height: var(--ot-small-line); letter-spacing: var(--ot-small-track); color: var(--ot-text-secondary); }

/* ---------- links, the one statement, focus (D47) ---------- */
:where(.ot-page) a:where(:not(.ot-button, .ot-button-second)), .ot-link {
  color: var(--ot-text);
  text-decoration: underline;
  text-decoration-color: var(--ot-underline);
  text-decoration-thickness: var(--ot-line-underline);
  text-underline-offset: var(--ot-line-underline-offset);
}
:where(.ot-page) a:where(:not(.ot-button, .ot-button-second)):hover, .ot-link:hover { text-decoration-color: currentColor; }
/* Once per page: the one statement that matters, or a key number inside a sentence (D47). Not on a page with a blue key number. */
.ot-statement {
  color: var(--ot-text);
  text-decoration: underline;
  text-decoration-color: var(--ot-lead);
  text-decoration-thickness: var(--ot-line-statement);
  text-underline-offset: var(--ot-line-statement-offset);
  text-decoration-skip-ink: none;
}
.ot-statement.ot-figures { font-weight: var(--ot-weight-medium); }
/* Strong enough (0,3,0) to survive a host's a:focus { outline: none } */
.ot-page :is(a, button, input, select, textarea, summary, [tabindex]):focus-visible { outline: var(--ot-line-focus) solid var(--ot-focus); outline-offset: var(--ot-line-focus-offset); }

/* ---------- buttons: square, 48 px on the web (2.8 times the text on any surface), sentence case ---------- */
.ot-button, .ot-button-second {
  display: inline-flex; align-items: center;
  font: inherit; font-size: var(--ot-body-size); font-weight: var(--ot-weight-medium); letter-spacing: 0; line-height: 1;
  height: max(var(--ot-button-height), 2.8em); padding: 0 max(var(--ot-button-pad-x), 1.4em);
  border: 0; border-radius: var(--ot-radius);
  text-decoration: none; cursor: pointer; white-space: nowrap;
}
.ot-button              { background: var(--ot-text); color: var(--ot-ground); }
.ot-button:hover        { background: var(--ot-action-hover); color: var(--ot-action-hover-text); }
.ot-button-second       { background: transparent; color: var(--ot-text); box-shadow: inset 0 0 0 var(--ot-line-button-outline) var(--ot-text); }
.ot-button-second:hover { background: var(--ot-second-hover-fill); color: var(--ot-second-hover); box-shadow: inset 0 0 0 var(--ot-line-button-outline) var(--ot-second-hover); }
.ot-actions { display: flex; flex-wrap: wrap; gap: var(--ot-space-4); align-items: center; }

/* ---------- lists: an open ring (the end of the mark); numbers for steps, hung in a gutter so the text keeps one edge ---------- */
.ot-list, .ot-steps { list-style: none; }
.ot-list > li, .ot-steps > li { position: relative; padding-left: 1.65em; }
.ot-list > li + li { margin-top: 0.35em; }
.ot-steps > li + li { margin-top: 0.47em; }
.ot-list > li::before {
  content: ""; position: absolute; left: 0.24em; top: calc(0.5lh - 0.13em);
  width: 0.38em; height: 0.38em; border-radius: 50%;
  box-shadow: inset 0 0 0 0.082em var(--ot-text-secondary);
}
.ot-steps { counter-reset: ot-step; }
.ot-steps > li { counter-increment: ot-step; }
.ot-steps > li::before {
  content: counter(ot-step); position: absolute; left: 0; width: 1.06em; text-align: right;
  color: var(--ot-text-secondary); font-variant-numeric: tabular-nums;
}

/* ---------- tables: rules only; sentence-case headings; numbers right, tabular; a total in tfoot ---------- */
.ot-table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; color: var(--ot-text); }
.ot-table th {
  text-align: left; font-weight: var(--ot-weight-medium); color: var(--ot-text-secondary);
  font-size: var(--ot-small-size); line-height: var(--ot-small-line);
  padding: 0 var(--ot-space-4) var(--ot-space-2) 0; border-bottom: var(--ot-line-hairline) solid var(--ot-rule-strong); vertical-align: bottom;
}
.ot-table td { padding: calc(var(--ot-space-2) + var(--ot-space-1) / 2) var(--ot-space-4) calc(var(--ot-space-2) + var(--ot-space-1) / 2) 0; border-bottom: var(--ot-line-hairline) solid var(--ot-rule); vertical-align: baseline; }
.ot-table :is(th, td):last-child { padding-right: 0; }
.ot-table .ot-num { text-align: right; }
.ot-table .ot-part { font-family: var(--ot-font-mono); font-feature-settings: var(--ot-features-label); font-size: 0.76em; letter-spacing: 0.04em; color: var(--ot-text-secondary); }
.ot-table tfoot td { font-weight: var(--ot-weight-medium); border-bottom-color: var(--ot-rule-strong); }

/* ---------- figures: the drawing, then FIG. n · what it shows · parts by number ---------- */
.ot-figure { display: flex; flex-direction: column; gap: var(--ot-space-3); }
.ot-figure > :where(img, svg) { display: block; max-width: 100%; height: auto; }
/* Documents put the caption beside the figure, in the side column */
[data-ot-surface="doc"] .ot-figure { display: grid; grid-template-columns: var(--ot-doc-side) minmax(0, 1fr); column-gap: var(--ot-doc-gutter); margin-left: calc(-1 * (var(--ot-doc-side) + var(--ot-doc-gutter))); }
[data-ot-surface="doc"] .ot-figure > .ot-caption { grid-column: 1; grid-row: 1; align-self: end; }
[data-ot-surface="doc"] .ot-figure > :where(img, svg, .ot-drawing) { grid-column: 2; grid-row: 1; }

/* ---------- quotes: an ink rule down the left; real words with permission ---------- */
.ot-quote { border-left: var(--ot-line-quote-rule) solid var(--ot-rule-strong); padding-left: calc(var(--ot-space-4) + var(--ot-space-1)); }
.ot-quote > p { font-size: var(--ot-lede-size); line-height: var(--ot-lede-line); letter-spacing: var(--ot-lede-track); color: var(--ot-text); }
.ot-quote-name { margin-top: var(--ot-space-3); font-size: var(--ot-small-size); line-height: var(--ot-small-line); font-weight: var(--ot-weight-medium); color: var(--ot-text); }
.ot-quote-role { font-size: var(--ot-small-size); line-height: var(--ot-small-line); color: var(--ot-text-secondary); }

/* ---------- key numbers (D47, D51) ---------- */
/* One number: .ot-key holds the number (blue, the page's one blue thing), what it counts (.ot-body), and .ot-source */
.ot-key-number { font-size: var(--ot-cover-size); line-height: 1; letter-spacing: var(--ot-cover-track); font-weight: var(--ot-weight-medium); font-variant-numeric: tabular-nums; color: var(--ot-lead); }
.ot-key > * + * { margin-top: var(--ot-space-3); }
.ot-key > .ot-source, .ot-spec + .ot-source { margin-top: var(--ot-space-2); }
/* Several numbers: a spec sheet, in ink */
.ot-spec { border-top: var(--ot-line-hairline) solid var(--ot-rule-strong); }
.ot-spec > div { display: flex; justify-content: space-between; align-items: baseline; gap: var(--ot-space-4); padding-block: calc(var(--ot-space-2) + var(--ot-space-1) / 2); border-bottom: var(--ot-line-hairline) solid var(--ot-rule); }
.ot-spec > div > :first-child { color: var(--ot-text-body); }
.ot-spec > div > :last-child { font-size: var(--ot-heading-size); line-height: var(--ot-heading-line); letter-spacing: var(--ot-heading-track); font-variant-numeric: tabular-nums; color: var(--ot-text); }

/* ---------- a note: between two hairlines; the stylesheet writes "Note." (don't type it); one per page at most ---------- */
.ot-note { border-top: var(--ot-line-hairline) solid var(--ot-rule); border-bottom: var(--ot-line-hairline) solid var(--ot-rule); padding-block: var(--ot-space-3); color: var(--ot-text-body); }
.ot-note > p + p { margin-top: var(--ot-space-3); }
.ot-note:not(:has(> p))::before, .ot-note > p:first-child::before { content: "Note. "; font-weight: var(--ot-weight-medium); color: var(--ot-text); }

/* ---------- code: a parts list by default; a hairline frame when a file is shown whole; never tinted ---------- */
.ot-parts { list-style: none; border-top: var(--ot-line-hairline) solid var(--ot-rule-strong); counter-reset: ot-part; }
.ot-parts > li { display: grid; grid-template-columns: minmax(var(--ot-space-4), max-content) minmax(0, 0.9fr) minmax(0, 1.1fr); gap: var(--ot-space-4); padding-block: calc(var(--ot-space-2) + var(--ot-space-1) / 2); border-bottom: var(--ot-line-hairline) solid var(--ot-rule); counter-increment: ot-part; }
.ot-parts > li::before { content: counter(ot-part); font-family: var(--ot-font-mono); font-feature-settings: var(--ot-features-label); font-size: var(--ot-label-size); color: var(--ot-text-secondary); padding-top: 0.15em; }
.ot-parts code { font-family: var(--ot-font-mono); font-size: calc(var(--ot-code-size) * 0.93); line-height: 1.54; color: var(--ot-text); overflow-wrap: anywhere; }
.ot-parts .ot-gloss { font-size: var(--ot-small-size); line-height: var(--ot-small-line); color: var(--ot-text-body); }
@media (max-width: 759px) {
  [data-ot-surface="web"] .ot-parts > li, :root:not([data-ot-surface]) .ot-parts > li { grid-template-columns: minmax(var(--ot-space-4), max-content) minmax(0, 1fr); row-gap: var(--ot-space-1); }
  [data-ot-surface="web"] .ot-parts .ot-gloss, :root:not([data-ot-surface]) .ot-parts .ot-gloss { grid-column: 2; }
}
.ot-code-frame { box-shadow: inset 0 0 0 var(--ot-line-hairline) var(--ot-rule); padding: var(--ot-space-3) var(--ot-space-4); font-family: var(--ot-font-mono); font-size: var(--ot-code-size); line-height: var(--ot-code-line); color: var(--ot-text); white-space: pre-wrap; overflow-wrap: anywhere; }
:where(.ot-page) :where(p, li, td) > code { font-family: var(--ot-font-mono); font-size: 0.88em; letter-spacing: 0; }

/* ---------- portal page parts (D56, D57); the page itself is templates/portal-page/ ---------- */
/* "On this page": a contents list down the side; the section in view is marked in ink and weight, never blue */
.ot-toc { position: sticky; top: var(--ot-space-6); }
.ot-toc-title { font-size: var(--ot-small-size); line-height: var(--ot-small-line); color: var(--ot-text-secondary); }
.ot-toc ol { list-style: none; margin: var(--ot-space-3) 0 0; padding: 0; border-top: var(--ot-line-hairline) solid var(--ot-rule-strong); }
.ot-toc li { border-bottom: var(--ot-line-hairline) solid var(--ot-rule); }
.ot-toc a { display: block; padding-block: var(--ot-space-2); font-size: var(--ot-small-size); line-height: var(--ot-small-line); color: var(--ot-text-body); text-decoration: none; }
.ot-toc a:hover { color: var(--ot-text); }
.ot-toc a[aria-current] { color: var(--ot-text); font-weight: var(--ot-weight-medium); }
/* A summary list (a dl): ruled key and value rows for scope, price and terms. Never a box. */
.ot-summary { margin: 0; border-top: var(--ot-line-hairline) solid var(--ot-rule-strong); }
.ot-summary > div { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); gap: var(--ot-space-1) var(--ot-space-5); padding-block: var(--ot-space-3); border-bottom: var(--ot-line-hairline) solid var(--ot-rule); }
.ot-summary dt { color: var(--ot-text-secondary); font-size: var(--ot-small-size); line-height: var(--ot-body-line); }
.ot-summary dd { margin: 0; color: var(--ot-text); }
/* The arc (an ol): the work as a line of numbered stops, the slide kit's agenda line for the web. The current stop, if any,
   takes aria-current="step" and the blue, as the page's one blue thing in that view. Upright on a phone. */
.ot-arc { list-style: none; margin: 0; padding: 0; display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); }
.ot-arc > li { position: relative; display: flex; flex-direction: column; align-items: center; gap: var(--ot-space-1); padding-inline: var(--ot-space-1); text-align: center; }
.ot-arc > li:not(:last-child)::after { content: ""; position: absolute; left: 50%; width: 100%; top: calc(var(--ot-label-line) + var(--ot-space-1) + var(--ot-space-2) + var(--ot-space-3) / 2 - var(--ot-line-pass) / 2); border-top: var(--ot-line-pass) solid var(--ot-text); }
.ot-arc-n { font-family: var(--ot-font-mono); font-feature-settings: var(--ot-features-label); font-size: var(--ot-label-size); line-height: var(--ot-label-line); color: var(--ot-text-secondary); }
.ot-arc-dot { position: relative; z-index: 1; width: var(--ot-space-3); height: var(--ot-space-3); border-radius: 50%; background: var(--ot-text); margin-block: var(--ot-space-2); }
.ot-arc-name { font-size: var(--ot-small-size); line-height: var(--ot-small-line); font-weight: var(--ot-weight-medium); color: var(--ot-text); }
.ot-arc-note { font-size: var(--ot-small-size); line-height: var(--ot-small-line); color: var(--ot-text-secondary); }
.ot-arc > li[aria-current] .ot-arc-dot { background: var(--ot-lead); }
.ot-arc > li[aria-current] .ot-arc-name { color: var(--ot-lead); }
/* Rows (the sessions): when and how long on the left, what happens on the right; always open */
.ot-rows { border-top: var(--ot-line-hairline) solid var(--ot-rule-strong); }
.ot-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 3fr); gap: var(--ot-space-1) var(--ot-space-5); padding-block: var(--ot-space-4); border-bottom: var(--ot-line-hairline) solid var(--ot-rule); }
.ot-row-when { font-size: var(--ot-small-size); line-height: var(--ot-body-line); color: var(--ot-text-secondary); font-variant-numeric: tabular-nums; }
.ot-row-what > * { max-width: var(--ot-measure); }
.ot-row-what > * + * { margin-top: var(--ot-space-2); }
/* A field: label, an error if any, then the input (and a Show button for a password). Square, 48 px, an outline, no fill. */
.ot-field { display: flex; flex-direction: column; gap: var(--ot-space-2); }
.ot-field > label { font-weight: var(--ot-weight-medium); color: var(--ot-text); }
.ot-field-row { display: flex; gap: var(--ot-space-2); }
.ot-input { flex: 1; min-width: 0; height: var(--ot-button-height); padding: 0 var(--ot-space-4); font: inherit; color: var(--ot-text); background: var(--ot-ground); border: 0; border-radius: var(--ot-radius); box-shadow: inset 0 0 0 var(--ot-line-button-outline) var(--ot-rule-strong); }
.ot-input[aria-invalid="true"] { box-shadow: inset 0 0 0 2px var(--ot-text); }
/* An error says what happened and what to do, in ink at weight 500. Never red. */
.ot-error { color: var(--ot-text); font-weight: var(--ot-weight-medium); }
@media (max-width: 759px) {
  .ot-toc { position: static; }
  .ot-summary > div, .ot-row { grid-template-columns: minmax(0, 1fr); }
  .ot-arc { grid-auto-flow: row; }
  .ot-arc > li { display: grid; grid-template-columns: var(--ot-space-3) 1.2em minmax(0, 1fr); column-gap: var(--ot-space-3); align-items: baseline; padding: 0 0 var(--ot-space-4); text-align: left; }
  .ot-arc > li:not(:last-child)::after { left: calc(var(--ot-space-3) / 2 - var(--ot-line-pass) / 2); width: 0; top: calc(var(--ot-small-line) / 2); bottom: calc(var(--ot-small-line) / -2); border-top: 0; border-left: var(--ot-line-pass) solid var(--ot-text); }
  .ot-arc-dot { grid-column: 1; grid-row: 1; align-self: start; margin: calc((var(--ot-small-line) - var(--ot-space-3)) / 2) 0 0; }
  .ot-arc-n { grid-column: 2; grid-row: 1; }
  .ot-arc-name, .ot-arc-note { grid-column: 3; }
}
@media print {
  .ot-toc { display: none; }
  .ot-summary > div, .ot-row { break-inside: avoid; }
}
/* ---------- rules ---------- */
.ot-rule { border: 0; border-top: var(--ot-line-hairline) solid var(--ot-rule); }

/* ---------- slides: the 1920 x 1080 stage; scale the whole stage to the screen with one transform (DESIGN.md section 5) ---------- */
.ot-slide {
  position: relative; box-sizing: border-box; width: var(--ot-slide-width); height: var(--ot-slide-height); overflow: hidden;
  background: var(--ot-ground); color: var(--ot-text-body);
  padding: var(--ot-slide-margin-top) var(--ot-slide-margin-x) var(--ot-slide-margin-bottom);
}
.ot-slide-grid { display: grid; grid-template-columns: repeat(var(--ot-slide-columns), var(--ot-slide-column)); column-gap: var(--ot-slide-gutter); align-items: start; }
.ot-slide-foot {
  position: absolute; left: var(--ot-slide-margin-x); right: var(--ot-slide-margin-x); top: var(--ot-slide-footer-rule);
  border-top: 2px solid var(--ot-rule);
  display: flex; justify-content: space-between; align-items: flex-start; padding-top: 26px;   /* the mark sits 28 px under the rule (scale.py s_foot) */
}
/* Inline the -Inline mark files: their lines take this colour and the ring takes the ground, on any ground */
.ot-mark { display: block; color: var(--ot-mark); }
.ot-slide-foot .ot-mark { height: 30px; width: auto; }
.ot-slide-foot .ot-page-number { font-family: var(--ot-font-mono); font-feature-settings: var(--ot-features-label); font-size: var(--ot-label-size); line-height: var(--ot-label-line); color: var(--ot-text-quiet); }

/* ---------- document pages: US Letter, the text column with a side column for captions and the section line ---------- */
.ot-doc-page {
  position: relative; width: var(--ot-doc-width); min-height: var(--ot-doc-height);
  padding: var(--ot-doc-margin-top) var(--ot-doc-margin-x) var(--ot-doc-margin-bottom) var(--ot-doc-text-x);
}
.ot-doc-side { position: absolute; left: var(--ot-doc-margin-x); width: var(--ot-doc-side); }

/* ---------- drawn motion (D50): opt-in per figure; see DESIGN.md "Motion" ---------- */
.ot-draw [data-ot-step] { transition: opacity var(--ot-duration-fade) linear; }

/* ---------- the website (D67 to D70): the bar's links, page headers, the home page's top, rows with a small object, chapters with
   margin headings, people, posts, questions, quotes, the way on, the footer. Templates: templates/website/. ---------- */
/* The bar's links; the section the reader is in is marked in ink at weight 500 with a 2 px rule beneath, never blue. */
.ot-nav { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ot-space-3) var(--ot-space-6); }
.ot-nav a:not([class]) { font-size: var(--ot-small-size); line-height: var(--ot-small-line); text-decoration: none; color: var(--ot-text); }
.ot-nav a[aria-current] { font-weight: var(--ot-weight-medium); text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: var(--ot-space-2); }
/* A section that follows another on the same page: a hairline above it. */
.ot-divided { border-top: var(--ot-line-hairline) solid var(--ot-rule); }
/* A figure in a spec sheet never breaks across lines ("2 h → 15 min" on a phone). */
.ot-spec > div > :last-child { white-space: nowrap; }
/* A block that follows text (the rhythm table's "text and a block": space 7). */
.ot-block { margin-top: var(--ot-space-7); }
/* Small secondary text: a byline, a date, a line under a button. */
.ot-meta { font-size: var(--ot-small-size); line-height: var(--ot-small-line); color: var(--ot-text-secondary); }
/* The home page's top: the title and its text on the left, the one-two on its map on the right (D69). */
.ot-hero { display: grid; grid-template-columns: minmax(0, 6fr) minmax(0, 6fr); grid-template-areas: "title pic" "text pic"; gap: var(--ot-space-7) var(--ot-space-5); align-items: start; }
.ot-hero > h1 { grid-area: title; }
.ot-hero > .ot-stack { grid-area: text; }
.ot-hero > .ot-scene { grid-area: pic; align-self: center; }
.ot-scene svg { display: block; width: 100%; height: auto; }
/* A page's header, and any section with its picture: the text on the left, the object (or Harry's photo on About) on the right. */
.ot-head { display: grid; grid-template-columns: minmax(0, 8fr) minmax(0, 4fr); gap: var(--ot-space-7) var(--ot-space-5); align-items: center; }
.ot-head > .ot-figure, .ot-head > .ot-object, .ot-head > .ot-photo { width: 100%; max-width: 320px; margin-left: auto; }
/* Harry's photo, square (D49). */
.ot-photo { display: block; width: 100%; max-width: 240px; aspect-ratio: 1; object-fit: cover; }
/* Rows with a small object on the right (the home page's "What happens in the workshops"). */
.ot-work-list { border-top: var(--ot-line-hairline) solid var(--ot-rule-strong); }
.ot-work { display: grid; grid-template-columns: minmax(0, 8fr) minmax(0, 4fr); gap: var(--ot-space-4) var(--ot-space-5); align-items: center;
           padding-block: var(--ot-space-6); border-bottom: var(--ot-line-hairline) solid var(--ot-rule); }
.ot-mini { display: block; width: 100%; max-width: 200px; height: auto; margin-left: auto; }
/* Who you'll work with: the photo on the left, the words on the right. */
.ot-person { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 9fr); gap: var(--ot-space-5) var(--ot-space-7); align-items: start; }
/* A list of posts: the date, then the title and one line. */
.ot-posts { list-style: none; margin: 0; padding: 0; border-top: var(--ot-line-hairline) solid var(--ot-rule-strong); }
.ot-posts > li { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 9fr); gap: var(--ot-space-1) var(--ot-space-5); padding-block: var(--ot-space-4); border-bottom: var(--ot-line-hairline) solid var(--ot-rule); }
.ot-posts-when { color: var(--ot-text-secondary); font-size: var(--ot-small-size); line-height: var(--ot-body-line); font-variant-numeric: tabular-nums; }
/* Questions with plain answers, two across. */
.ot-qa { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--ot-space-7) var(--ot-space-9); }
.ot-qa > div > * + * { margin-top: var(--ot-space-3); }
/* Quotes laid out together: two across, or three. */
.ot-quotes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--ot-space-8) var(--ot-space-9); align-items: start; }
.ot-quotes-three { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--ot-space-7); align-items: start; }
/* A closing group inside a section, set off by a hairline ("What leaders say" under the case study). */
.ot-leaders { margin-top: var(--ot-space-8); padding-top: var(--ot-space-7); border-top: var(--ot-line-hairline) solid var(--ot-rule); display: flex; flex-direction: column; gap: var(--ot-space-6); }
/* Chapters with margin headings (case studies, About, posts): the heading on the left stays in view; the text runs on the right two thirds. */
.ot-chapters > .ot-chapter { display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); gap: var(--ot-space-4) var(--ot-space-5); align-items: start;
                             padding-block: var(--ot-space-7); border-top: var(--ot-line-hairline) solid var(--ot-rule); }
.ot-chapters > .ot-chapter:first-child { border-top: 0; padding-top: 0; }
.ot-chapter > h2, .ot-chapter-side { position: sticky; top: var(--ot-space-5); }
/* The way on, at the end of a case study or a post: back to the section on the left, the next one on the right. */
.ot-onward { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--ot-space-5); padding-top: var(--ot-space-6); margin-top: var(--ot-space-8); border-top: var(--ot-line-hairline) solid var(--ot-rule-strong); }
.ot-onward > div { display: flex; flex-direction: column; gap: var(--ot-space-1); }
.ot-onward > div:last-child { text-align: right; }
.ot-onward-label { color: var(--ot-text-secondary); font-size: var(--ot-small-size); line-height: var(--ot-small-line); }
/* The site's footer: who OneTwo is in one sentence, and the ways to reach Harry. */
.ot-foot { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--ot-space-3) var(--ot-space-6); padding-block: var(--ot-space-6) var(--ot-space-8); border-top: var(--ot-line-hairline) solid var(--ot-rule); }
.ot-foot p { margin: 0; }
/* The phone menu (D73): under 760 px the bar's links fold behind a Menu button (the menu icon beside the word) that opens them in a list on the right
   of the bar's width; Close folds them back. The page adds the class "ot-js" to <html> and toggles [data-open] on the .ot-bar; without script the
   links stay visible. */
.ot-menu-button { display: none; }
/* Long-form text that arrives as plain HTML (a post from the newsletter's feed): the reading roles applied to bare elements. */
.ot-prose > * + * { margin-top: var(--ot-space-4); }
.ot-prose > :where(h2, h3) { margin-top: var(--ot-space-7); }
.ot-prose :where(p, li) { font-size: var(--ot-body-size); line-height: var(--ot-body-line); color: var(--ot-text-body); max-width: var(--ot-measure); }
.ot-prose :where(h2) { font-size: var(--ot-heading-size); line-height: var(--ot-heading-line); letter-spacing: var(--ot-heading-track); font-weight: var(--ot-weight-medium); color: var(--ot-text); max-width: var(--ot-measure); }
.ot-prose :where(h3, h4) { font-size: var(--ot-body-size); line-height: var(--ot-body-line); font-weight: var(--ot-weight-medium); color: var(--ot-text); }
.ot-prose :where(strong, b) { font-weight: var(--ot-weight-medium); color: var(--ot-text); }
.ot-prose :where(ul, ol) { padding-left: var(--ot-space-5); }
.ot-prose :where(blockquote) { margin: 0; border-left: var(--ot-line-quote-rule) solid var(--ot-rule-strong); padding-left: calc(var(--ot-space-4) + var(--ot-space-1)); }
.ot-prose :where(img, video) { display: block; max-width: 100%; height: auto; }
.ot-prose :where(figure) { margin: 0; }
.ot-prose :where(figcaption) { font-size: var(--ot-small-size); line-height: var(--ot-small-line); color: var(--ot-text-secondary); margin-top: var(--ot-space-2); }
.ot-prose :where(hr) { border: 0; border-top: var(--ot-line-hairline) solid var(--ot-rule); }
.ot-prose :where(pre, code) { font-family: var(--ot-font-mono); font-size: var(--ot-code-size); }
.ot-prose :where(pre) { overflow-x: auto; }
@media (max-width: 759px) {
  .ot-hero { grid-template-columns: minmax(0, 1fr); grid-template-areas: "title" "text" "pic"; }   /* on a phone the words and Book a call come before the drawing (D73) */
  .ot-head, .ot-work, .ot-person, .ot-posts > li, .ot-qa, .ot-quotes, .ot-quotes-three, .ot-chapters > .ot-chapter, .ot-onward { grid-template-columns: minmax(0, 1fr); }
  .ot-head > .ot-figure, .ot-head > .ot-object, .ot-head > .ot-photo { max-width: 220px; margin: 0; }
  .ot-mini { max-width: 140px; margin: 0; }
  .ot-photo { max-width: 160px; }
  .ot-chapter > h2, .ot-chapter-side { position: static; }
  .ot-onward > div:last-child { text-align: left; }
  .ot-bar:has(.ot-menu-button) { flex-wrap: wrap; }
  .ot-menu-button { display: inline-flex; align-items: center; gap: var(--ot-space-2); height: var(--ot-button-height); padding: 0; margin: 0; background: none; border: 0;
                    font: inherit; font-weight: var(--ot-weight-medium); color: var(--ot-text); cursor: pointer; }
  .ot-menu-button svg { width: var(--ot-space-6); height: var(--ot-space-6); }
  .ot-menu-button .ot-icon-close, .ot-menu-button .ot-menu-close { display: none; }
  .ot-bar[data-open] .ot-menu-button .ot-icon-menu, .ot-bar[data-open] .ot-menu-button .ot-menu-open { display: none; }
  .ot-bar[data-open] .ot-menu-button .ot-icon-close, .ot-bar[data-open] .ot-menu-button .ot-menu-close { display: inline; }
  .ot-js .ot-bar .ot-nav { display: none; }
  .ot-bar .ot-nav { width: 100%; flex-direction: column; align-items: stretch; gap: 0; }
  .ot-js .ot-bar[data-open] .ot-nav { display: flex; }
  .ot-bar .ot-nav a:not([class]) { font-size: var(--ot-body-size); line-height: var(--ot-body-line); padding-block: var(--ot-space-3); border-top: var(--ot-line-hairline) solid var(--ot-rule); }
  .ot-bar .ot-nav a[aria-current] { text-decoration: none; }
  .ot-bar .ot-nav .ot-button-second { margin-top: var(--ot-space-4); justify-content: center; }
}
