/* system.css: the Mulholland system for mulholland.ai.
   One ground, one voice, one unit. Standalone: it loads nothing from lab/37/css or lab/37/js.
   Every value is a token in ../a/tokens.css, imported first below: the system's roles are the
   --system-* family there (the /a site's roles are the other family; the two never mix). Components
   name tokens; they never write a colour, size or duration of their own. The two @font-face rules
   keep their descriptors (a font file's own weight: var() is not allowed in a descriptor).
   Nineteen components, in this order: Frame, Fog, Link, Chrome, Film, Figure, Lede, Tag, Row, Empty,
   PageHead, Intro, Split, Prose, Facts, Table, Flow, Chart, Linework.

   Breakpoint policy, the only two queries in the system:
     (min-width: 64em)                      width decides size and layout: the unit t, the spine, the fog.
     (hover: hover) and (pointer: fine)     input decides hover: underline on hover, rows open on hover.
   Sibling dimming needs both, because it lowers a title to a contrast only large text may have.
   Preference queries (reduced motion) change values, never layout. */

@import url("/tokens.css?v=0418c4d5c7fd");


/* ---------------------------------------------------------------------------------------------
   Faces. Two files. No.1 is the voice (the file named Regular is Alliance No.1 Medium, weight
   class 500; the live site has shipped it since 09-14). No.2 Regular is the read face, fetched only
   by pages that set prose. */

@font-face {
  font-display: swap;
  font-family: 'Alliance No.1';
  font-style: normal;
  font-weight: 500;
  src: url('/fonts/AllianceNo1-Regular.woff2') format('woff2');
}

@font-face {
  font-display: swap;
  font-family: 'Alliance No.2';
  font-style: normal;
  font-weight: 400;
  src: url('/legacy-fonts/AllianceNo2-Regular.woff2') format('woff2');
}


/* ---------------------------------------------------------------------------------------------
   Tokens. They live in ../a/tokens.css (2026-09-25, the design skill's token pass), in the three
   tiers: primitives named for what they are; the system's roles as --system-* (the ground and the
   fore at four alphas, the unit t as --system-unit and its steps, the five type styles, three
   tracking bands, four spaces, the fog, the measure, the line and ring, the spine, the layers, the
   one duration and ease); and component tokens (the mark: --system-mark-size, --system-mark-stroke).
   tokens.css also holds the system's rebinds: [data-ground] recomputes the colour roles on every
   ground, [data-ground='film'] raises the two quiet alphas, [data-fog='index'] keeps the lower half
   of a desktop window for the film, and [data-face='helvetica'] swaps the faces (the /a homepage). */


/* ---------------------------------------------------------------------------------------------
   Base. */

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

/* The root keeps the browser's font size, so rem (and with it t) means what the reader set. */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  background: var(--system-background);
  /* focus and anchor jumps land in the clear band, never under the fog */
  scroll-padding-block: var(--system-fog-top) var(--system-fog-bottom);
  -webkit-tap-highlight-color: var(--system-clear);
}

body {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  background: var(--system-background);
  color: var(--system-foreground-soft);
  font: var(--system-type-small);
  font-feature-settings: normal;
  font-kerning: normal;
  font-synthesis: none;
  letter-spacing: var(--system-tracking-none);
  overflow-x: clip;
}

:where(ul[class], ol[class]) {
  list-style: none;
}

:where(img, video, svg) {
  display: block;
  max-inline-size: 100%;
}

:where(a) {
  color: inherit;
  text-decoration: none;
}

:where(button) {
  appearance: none;
  background: none;
  border: 0;
  color: inherit;
  cursor: pointer;
  font: inherit;
  letter-spacing: inherit;
  text-align: start;
}

:where(h1, h2, h3, h4, p, figure, blockquote) {
  font: inherit;
  letter-spacing: inherit;
}

:focus-visible {
  outline: var(--system-ring);
  outline-offset: var(--system-ring-offset);
}

/* a skip target takes focus without drawing it */
[tabindex='-1']:focus {
  outline: none;
}

::selection {
  background: var(--system-foreground);
  color: var(--system-background);
}

/* Visually hidden, still read: words a sighted reader gets from the layout, and the skip link
   until it is focused. */
.vh,
.skip:not(:focus, [data-state='focus']) {
  block-size: var(--system-unseen);
  clip-path: inset(50%);
  inline-size: var(--system-unseen);
  min-block-size: 0;
  overflow: hidden;
  padding: 0;
  position: absolute;
  white-space: nowrap;
}


/* ---------------------------------------------------------------------------------------------
   Frame. The page itself: the gutter at both edges, reading starts at the top fog and can scroll
   until the last line reaches the bottom one. */

.frame {
  display: block;
  padding-block: var(--system-fog-top) var(--system-fog-bottom);
  padding-inline: var(--system-space-2);
  position: relative;
}

.frame > * + * {
  margin-block-start: var(--system-space-4);
}


/* ---------------------------------------------------------------------------------------------
   Fog. Two ink scrims, fixed at the top and bottom edges. It never moves. On an ink page each is
   solid ink for the chrome's depth (--system-fog-hold), then fades to clear. */

.fog::before,
.fog::after {
  content: '';
  inset-inline: 0;
  pointer-events: none;
  position: fixed;
  z-index: var(--system-layer-fog);
}

.fog::before {
  background: linear-gradient(var(--system-background) var(--system-fog-hold), var(--system-background-clear));
  block-size: var(--system-fog-top);
  inset-block-start: 0;
}

.fog::after {
  background: linear-gradient(var(--system-background-clear), var(--system-background) calc(100% - var(--system-fog-hold)));
  block-size: var(--system-fog-bottom);
  inset-block-end: 0;
}

/* On a phone the index's fog is too light for the list to pass under the chrome, and its bottom
   links can wrap to two lines. There each chrome carries its own scrim: solid behind every line it
   has, fading over the fog's depth, so the list fades out before it reaches the links. */
@media (max-width: 63.99em) {
  [data-fog='index'] .chrome--bottom::before {
    background: linear-gradient(var(--system-background-clear), var(--system-background) var(--system-fog-bottom));
    content: '';
    inset-block: calc(var(--system-fog-bottom) * -1) 0;
    inset-inline: 0;
    pointer-events: none;
    position: absolute;
    z-index: var(--system-layer-behind);
  }

  /* The homepage's six bottom links sit as two even rows of three on a phone, so every link stays
     one tap away (Sam, 2026-09-27: option A, with Pause removed on every screen). */
  [data-fog='index'] .chrome--bottom .chrome__links {
    column-gap: var(--system-space-2);
    display: grid;
    grid-template-columns: repeat(3, max-content);
  }

  /* The same at the top: solid behind the nav, fading down over the top fog's depth. */
  [data-fog='index'] .nav::after {
    background: linear-gradient(var(--system-background) calc(100% - var(--system-fog-top)), var(--system-background-clear));
    content: '';
    inset-block: 0 calc(var(--system-fog-top) * -1);
    inset-inline: 0;
    pointer-events: none;
    position: absolute;
    z-index: var(--system-layer-behind);
  }
}

/* On a desktop the index's top fog is still clear at the nav's line, so a list wheeled up printed its
   names under the links. The same scrim, cut to the nav plus one pitch and solid only through the
   links' line: it fades over the chrome's depth below them, so the rows fade out before they reach the
   links and the film at rest keeps its top (Home proposal 2026-09-26, "I can do now" 1). */
@media (min-width: 64em) {
  [data-fog='index'] .nav::after {
    background: linear-gradient(var(--system-background) calc(100% - var(--system-chrome-block)), var(--system-background-clear));
    content: '';
    inset-block: 0 calc(var(--system-space-3) * -1);
    inset-inline: 0;
    pointer-events: none;
    position: absolute;
    z-index: var(--system-layer-behind);
  }
}


/* ---------------------------------------------------------------------------------------------
   Link. Every link and every text button: the chrome, the pause control, the skip link, links in
   prose. Rest, hover, focus-visible, active, current, unavailable, in that order. */

.link,
.prose a:not([class]) {
  color: var(--system-foreground);
  cursor: pointer;
  text-decoration-color: var(--system-clear);
  text-decoration-line: underline;
  text-decoration-thickness: from-font;
  transition: color var(--system-duration) var(--system-ease), text-decoration-color var(--system-duration) var(--system-ease);
  user-select: none;
}

.prose a:not([class]) {
  text-decoration-color: var(--system-muted-foreground);
  user-select: auto;
}

@media (hover: hover) and (pointer: fine) {

  .link:hover,
  .prose a:not([class]):hover {
    text-decoration-color: currentColor;
  }

}

.link[data-state='hover'],
.link:focus-visible,
.link[data-state='focus'],
.prose a:not([class]):focus-visible {
  text-decoration-color: currentColor;
}

.link[data-state='focus'] {
  outline: var(--system-ring);
  outline-offset: var(--system-ring-offset);
}

.link:active,
.link[data-state='active'] {
  color: var(--system-foreground-soft);
  text-decoration-color: currentColor;
}

.link[aria-current],
.link[data-state='current'] {
  text-decoration-color: currentColor;
}

.link[aria-disabled='true'],
.link[data-state='unavailable'] {
  color: var(--system-muted-foreground);
  cursor: default;
  text-decoration-color: var(--system-clear);
}


/* ---------------------------------------------------------------------------------------------
   Chrome. The fixed frame and the only navigation: three links and the mark on top, the company
   links and the pause control at the bottom. Nothing else is fixed. */

.chrome {
  align-items: center;
  display: flex;
  inset-inline: 0;
  justify-content: space-between;
  padding-inline: var(--system-space-2);
  pointer-events: none;
  position: fixed;
  user-select: none;
  z-index: var(--system-layer-chrome);
}

.chrome--top {
  inset-block-start: 0;
  padding-block-start: var(--system-space-2);
}

.chrome--bottom {
  inset-block-end: 0;
  padding-block-end: var(--system-space-2);
}

/* A line of links: the chrome's, and the Film cycle's controls, which are the same thing. Each link
   is padded s-1, so words sit 2 × s-1 apart and the first starts at the gutter; the hit area is the
   pitch tall. */
.chrome__links,
.film__controls {
  display: flex;
  flex-wrap: wrap;
  margin-inline-start: calc(var(--system-space-1) * -1);
}

.chrome .link,
.film__controls .link {
  align-items: center;
  display: inline-flex;
  font: var(--system-type-small);
  letter-spacing: var(--system-tracking-none);
  min-block-size: var(--system-space-3);
  padding-inline: var(--system-space-1);
}

.chrome .link {
  pointer-events: auto;
}

/* A control at the end of the chrome (the pause) aligns its text to the gutter, like the mark. */
.chrome > .link:last-child {
  margin-inline-end: calc(var(--system-space-1) * -1);
}

/* The mark sits smaller than a line of chrome text: on a phone the brain alone, 1.3 × the text size; on
   a desktop the lockup is one text size tall, which sets the wordmark at about the nav's cap height. */
.chrome__home {
  block-size: var(--system-mark-size);
  color: var(--system-foreground);
  display: block;
  flex: none;
  pointer-events: auto;
}

.chrome__home :is(img, svg) {
  block-size: 100%;
  inline-size: auto;
}

.chrome__mark {
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* the live mulholland.ai brain: a 1px line at any size */
.chrome__mark path {
  stroke-width: var(--system-mark-stroke);
  vector-effect: non-scaling-stroke;
}

.chrome__wordmark {
  display: none;
}

@media (min-width: 64em) {

  .chrome__home {
    block-size: var(--system-unit);
  }

  .chrome__wordmark {
    display: block;
  }

  .chrome__mark {
    display: none;
  }

}

/* The skip link comes first in the document and, while focused, takes the whole top line. */
.skip {
  align-items: center;
  background: var(--system-background);
  display: flex;
  font: var(--system-type-small);
  inset-block-start: 0;
  inset-inline: 0;
  letter-spacing: var(--system-tracking-none);
  min-block-size: var(--system-chrome-block);
  padding: var(--system-space-2) var(--system-space-2) 0;
  position: fixed;
  z-index: var(--system-layer-skip);
}

.skip[data-state='focus'] {
  position: relative;
}


/* ---------------------------------------------------------------------------------------------
   Film. Moving pictures, three ways: the brand film fixed under the home page behind the ink veil
   (ground); a recording in the flow of a page at its own ratio, with no veil and no text on it
   (figure); or screens of the product shown one at a time in the same place (cycle). A figure or a
   cycle is also a Figure, and carries the Figure's caption. */

.film {
  background: var(--system-background);
}

.film__video {
  block-size: 100%;
  inline-size: 100%;
  object-fit: cover;
}

.film--ground {
  inset: 0;
  pointer-events: none;
  position: fixed;
}

.film--ground::after {
  background: var(--system-film-veil);
  content: '';
  inset: 0;
  position: absolute;
}

.film--figure .film__video {
  block-size: auto;
}

/* The cycle: a line of links above (one a screen; the one showing is current), the screens, and
   their lines in the caption. Screens and lines are stacked in one cell each, so the figure never
   changes height as they turn, and they cross over on --system-duration. One screen is a still: no controls,
   nothing turns. As a grid, nothing in it collapses into its neighbour's margin. */
.film--cycle {
  display: grid;
}

.film__controls[hidden] {
  display: none;
}

.film__stage,
.film__texts {
  display: grid;
}

.film__item,
.film__text {
  grid-area: 1 / 1;
  opacity: 0;
  transition:
    opacity var(--system-duration) var(--system-ease),
    visibility 0ms var(--system-duration);
  visibility: hidden;
}

.film__item[data-state='current'],
.film__text[data-state='current'] {
  opacity: 1;
  transition: opacity var(--system-duration) var(--system-ease);
  visibility: visible;
}

.film__item {
  block-size: auto;
  inline-size: 100%;
}

/* the screen's own line reads a step above the note that follows it */
.film__text {
  color: var(--system-foreground-soft);
}

.film__note {
  margin-block-start: var(--system-space-1);
}


/* ---------------------------------------------------------------------------------------------
   Figure. Anything shown rather than read: a recording, the product's screens, a drawing, a chart,
   a record the product wrote. An optional head names it (a title, then a Tag); a caption says what
   it shows. No frame, no fill, no rule: a figure is set apart by its head and its caption. Parts sit
   s-2 apart; the caption keeps s-1 under what it captions. */

.figure > * + * {
  margin-block-start: var(--system-space-2);
}

.figure > .figure__caption {
  margin-block-start: var(--system-space-1);
}

/* the tag follows the title on its line, or starts the next line flush when there is no room */
.figure__head {
  align-items: baseline;
  color: var(--system-foreground);
  column-gap: var(--system-space-1);
  display: flex;
  flex-wrap: wrap;
  font: var(--system-type-small);
  letter-spacing: var(--system-tracking-none);
}

.figure__caption {
  color: var(--system-muted-foreground);
  font: var(--system-type-micro);
  letter-spacing: var(--system-tracking-open);
  max-inline-size: var(--system-measure);
}


/* ---------------------------------------------------------------------------------------------
   Lede. One quiet phrase that says something. Never a page name and never above a headline. */

.lede {
  color: var(--system-muted-foreground);
  font: var(--system-type-small);
  letter-spacing: var(--system-tracking-none);
  text-wrap: balance;
}

/* The /a homepage sets its line at the size of the names it heads, kept in the muted colour
   (Sam, 2026-09-27: "could be the same size"). */
.lede--title {
  font: var(--system-type-base);
  letter-spacing: var(--system-tracking-tight);
}

.lede + * {
  margin-block-start: var(--system-space-2);
}


/* ---------------------------------------------------------------------------------------------
   Tag. Micro metadata after a title: an industry, a date, a role. The label is always the real
   text. While the tag is hidden or decoding, the label is visually hidden but still read, and an
   aria-hidden copy takes its place to show the symbols; assistive tech never meets a symbol. */

.tag {
  color: var(--system-muted-foreground);
  display: inline-block;
  font: var(--system-type-micro);
  letter-spacing: var(--system-tracking-open);
  white-space: nowrap;
}

/* The gap before a row's tag is the title's trailing margin, not the tag's leading one, so a tag that has to drop
   to the line under its name starts flush with the name (2026-09-27: Horizon Dental Care's tag, under 400px). A
   hidden tag takes no gap, as before. */
.row__title:has(+ .tag:not([data-tag='hidden'])) {
  margin-inline-end: var(--system-space-1);
}

.tag:not([data-tag='decoding']) .tag__glyphs {
  display: none;
}

.tag[data-tag='hidden'] {
  margin-inline-start: 0;
}

.tag:is([data-tag='hidden'], [data-tag='decoding']) .tag__label {
  block-size: var(--system-unseen);
  clip-path: inset(50%);
  inline-size: var(--system-unseen);
  overflow: hidden;
  position: absolute;
}


/* ---------------------------------------------------------------------------------------------
   Row. The one list unit: a title at base size, a tag, and a detail that opens beneath it.
   Disclosure rows (clients, team) are buttons with aria-expanded; link rows (posts) are links whose
   detail shows on hover or while keyboard focus is anywhere in the row (so Tab reaches its links). On
   a touch screen system.js gives a link row aria-expanded and it peeks: the first tap opens it, the
   second follows the link. Without the script the detail stays open. */

.row__trigger {
  align-items: center;
  color: var(--system-foreground);
  display: grid;
  font: var(--system-type-base);
  inline-size: 100%;
  letter-spacing: var(--system-tracking-tight);
  min-block-size: var(--system-space-3);
  transition: color var(--system-duration) var(--system-ease);
  user-select: none;
}

/* a name that has to wrap wraps into even lines, with its tag after the last word */
.row__line {
  text-wrap: balance;
}

.row__detail {
  display: grid;
  grid-template-rows: 1fr;
  opacity: 1;
  transition:
    grid-template-rows var(--system-duration) var(--system-ease),
    opacity var(--system-duration) var(--system-ease);
}

.row__body {
  min-block-size: 0;
  overflow: hidden;
}

.row__trigger[aria-expanded='false'] + .row__detail {
  grid-template-rows: 0fr;
  opacity: 0;
  transition:
    grid-template-rows var(--system-duration) var(--system-ease),
    opacity var(--system-duration) var(--system-ease),
    visibility 0ms var(--system-duration);
  visibility: hidden;
}

@media (hover: hover) and (pointer: fine) {

  .row--link:not(:hover, [data-state='hover'], [data-state='focus'], :has(:focus-visible)) .row__detail {
    grid-template-rows: 0fr;
    opacity: 0;
    transition:
      grid-template-rows var(--system-duration) var(--system-ease),
      opacity var(--system-duration) var(--system-ease),
      visibility 0ms var(--system-duration);
    visibility: hidden;
  }

}

.row__items,
.row__dek {
  color: var(--system-foreground);
  font: var(--system-type-small);
  letter-spacing: var(--system-tracking-none);
  padding-block-end: var(--system-space-1);
}

.row__items {
  column-gap: var(--system-space-2);
  display: flex;
  flex-wrap: wrap;
}

.row__dek {
  max-inline-size: var(--system-measure);
}

.row__items [data-state='unavailable'],
.row__items [data-state='unavailable'] .link {
  color: var(--system-muted-foreground);
}

/* On a touch screen a link row peeks (system.js): the first tap opens it. Then each workflow link is a
   thumb's height (--system-tap), and the open row ends with .row__open, one more link to the page its
   title goes to, so the second tap has a name. With a fine pointer the title is the link and
   .row__open stays out of the way (Home proposal 2026-09-26, "I can do now" 5). */
.row__open {
  display: none;
}

@media not all and (hover: hover) and (pointer: fine) {

  .row--link .row__items .link {
    align-items: center;
    display: inline-flex;
    min-block-size: var(--system-tap);
  }

  .row--link .row__open {
    display: block;
  }

}

/* a link row's dek keeps s-2 from the next title while it is open */
.row--link .row__dek {
  padding-block-end: var(--system-space-2);
}

/* The ring frames the whole row, title and open detail together, so the detail never crosses it. */
.row__trigger:focus-visible {
  outline: none;
}

.row:has(> .row__trigger:focus-visible),
.row[data-state='focus'] {
  outline: var(--system-ring);
  outline-offset: var(--system-ring-offset);
}

.row__trigger[aria-disabled='true'],
.row[data-state='unavailable'] .row__trigger {
  color: var(--system-muted-foreground);
  cursor: default;
}

/* Siblings dim while one row is pointed at or focused. Pointer only, and only where titles are
   large text: dimming is a contrast drop that small text cannot afford. Dimmed rows hide their tag. */
.row[data-state='dim'] .row__trigger {
  color: var(--system-faint-foreground);
}

.row[data-state='dim'] .tag {
  opacity: 0;
}

@media (min-width: 64em) and (hover: hover) and (pointer: fine) {

  .rows:has(> .row:hover, .row__trigger:focus-visible) > .row:not(:hover, :has(.row__trigger:focus-visible)) .row__trigger {
    color: var(--system-faint-foreground);
  }

  .rows:has(> .row:hover, .row__trigger:focus-visible) > .row:not(:hover, :has(.row__trigger:focus-visible)) .tag {
    opacity: 0;
  }

}


/* ---------------------------------------------------------------------------------------------
   Empty. What a list shows before it has anything in it: one line where the first row would stand,
   at the row's size and pitch in --system-muted-foreground (what is not there yet), then one way out beneath it. It
   follows the lede exactly as the list would, so nothing above it moves when the first item lands. */

.empty__line {
  align-items: center;
  color: var(--system-muted-foreground);
  display: flex;
  font: var(--system-type-base);
  letter-spacing: var(--system-tracking-tight);
  min-block-size: var(--system-space-3);
}

.empty > * + * {
  margin-block-start: var(--system-space-1);
}


/* ---------------------------------------------------------------------------------------------
   PageHead. The one headline a page has, at display size, balanced, three lines at most. */

.pagehead {
  color: var(--system-foreground);
  font: var(--system-type-display);
  letter-spacing: var(--system-tracking-tight);
  text-wrap: balance;
}

.pagehead + .tag {
  display: block;
  margin-block-start: var(--system-space-2);
}

/* on a wide window the headline keeps to the gutter's half, like every other title */
@media (min-width: 64em) {

  .pagehead {
    max-inline-size: var(--system-spine);
  }

}

/* The mark variant: the MarzyOS wordmark is the headline, drawn in the text colour. It fills the
   h1, which already keeps to the spine from 64em. */
.pagehead--mark svg {
  block-size: auto;
  inline-size: 100%;
}


/* ---------------------------------------------------------------------------------------------
   Intro. A page's opening words beneath its headline: the lead in the voice at base size, and the
   sub one step quieter. From 64em they stand at the two edges, the lead at the gutter and the sub at
   the spine; below they stack. It sits s-3 under the headline, closer than the frame's block step. */

.intro {
  display: grid;
  row-gap: var(--system-space-2);
}

.intro__lead,
.intro__sub {
  font: var(--system-type-base);
  letter-spacing: var(--system-tracking-tight);
  max-inline-size: var(--system-measure);
  text-wrap: pretty;
}

.intro__lead {
  color: var(--system-foreground);
}

.intro__sub {
  color: var(--system-muted-foreground);
}

.pagehead + .intro {
  margin-block-start: var(--system-space-3);
}

@media (min-width: 64em) {

  .intro {
    grid-template-columns: var(--system-spine) 1fr;
  }

  .intro__lead {
    padding-inline-end: var(--system-space-2);
  }

}


/* ---------------------------------------------------------------------------------------------
   Split. The two edges: a label at the gutter and the body at the spine. Below 64em it stacks.
   A part too wide for the spine's half (a Table) follows the body and takes both edges. */

.split {
  display: grid;
  row-gap: var(--system-space-2);
}

@media (min-width: 64em) {

  .split {
    grid-template-columns: var(--system-spine) 1fr;
  }

  .split__label,
  .split__title {
    padding-inline-end: var(--system-space-2);
  }

}

.split__label {
  color: var(--system-muted-foreground);
  font: var(--system-type-small);
  letter-spacing: var(--system-tracking-none);
}

.split__title {
  color: var(--system-foreground);
  font: var(--system-type-base);
  letter-spacing: var(--system-tracking-tight);
  text-wrap: balance;
}

.split__lead {
  color: var(--system-foreground);
  font: var(--system-type-base);
  letter-spacing: var(--system-tracking-tight);
  max-inline-size: var(--system-measure);
  text-wrap: pretty;
}

.split__body > * + * {
  margin-block-start: var(--system-space-2);
}


/* ---------------------------------------------------------------------------------------------
   Prose. The only long-form text: the read face at the small size, a-2, one measure wide. */

.prose {
  color: var(--system-foreground-soft);
  font: var(--system-type-read);
  font-variant-ligatures: no-common-ligatures;
  letter-spacing: var(--system-tracking-none);
  max-inline-size: var(--system-measure);
  text-wrap: pretty;
}

.prose > * + * {
  margin-block-start: var(--system-space-2);
}

.prose :is(strong, em, b, i):not([class]) {
  color: var(--system-foreground);
  font-style: normal;
  font-weight: inherit;
}

.prose h2:not([class]) {
  color: var(--system-foreground);
  font: var(--system-type-base);
  letter-spacing: var(--system-tracking-tight);
}

.prose :is(h3, h4):not([class]) {
  color: var(--system-foreground);
  font: var(--system-type-small);
  letter-spacing: var(--system-tracking-none);
}

.prose > * + h2:not([class]) {
  margin-block-start: var(--system-space-4);
}

.prose > * + :is(h3, h4):not([class]) {
  margin-block-start: var(--system-space-3);
}

.prose > :is(h2, h3, h4):not([class]) + * {
  margin-block-start: var(--system-space-1);
}

.prose :is(ul, ol):not([class]) {
  padding-inline-start: var(--system-space-2);
}

.prose blockquote:not([class]) {
  color: var(--system-foreground);
  font: var(--system-type-base);
  letter-spacing: var(--system-tracking-tight);
}

.prose pre:not([class]) {
  color: var(--system-foreground-soft);
  font: var(--system-type-micro);
  letter-spacing: var(--system-tracking-open);
  white-space: pre-wrap;
}

.prose hr:not([class]) {
  border: 0;
  margin-block: var(--system-space-4);
}


/* ---------------------------------------------------------------------------------------------
   Facts. A definition list with no rules: the key in micro at a-3, the value in small at a-2,
   each pair on a line of its own. The receipt, the token tables, a post's meta. */

.facts {
  align-items: baseline;
  column-gap: var(--system-space-2);
  display: grid;
  grid-template-columns: max-content 1fr;
  row-gap: var(--system-space-1);
}

.facts dt {
  color: var(--system-muted-foreground);
  font: var(--system-type-micro);
  letter-spacing: var(--system-tracking-open);
}

.facts dd {
  color: var(--system-foreground-soft);
  font: var(--system-type-small);
  letter-spacing: var(--system-tracking-none);
}

/* a tag inside a value is its note: on its own line beneath the value */
.facts dd > .tag {
  display: block;
  margin-block-start: var(--system-space-1);
  white-space: normal;
}


/* ---------------------------------------------------------------------------------------------
   Table. Data in columns, for what Facts cannot carry: three columns or more, a header row, and rows
   in named groups. No rules, no boxes, no zebra: the header row and the group names are keys (micro,
   --system-muted-foreground), the cell that names its row is --system-foreground, the rest are values (small, --system-foreground-soft), as in
   Facts. Below 64em a row cannot hold three columns at a readable size, so each row reflows: its
   cells run on one line while they fit and the last takes a line of its own, and the header row
   reflows the same way, as the key to every row beneath it. Explicit roles on every part keep the
   table's semantics while its display changes. In a Split it follows the body and, from 64em, takes
   both edges, its last column starting at the spine. */

.table {
  border-spacing: 0;
  display: block;
  inline-size: 100%;
}

.table :is(thead, tbody) {
  display: block;
}

.table tr {
  column-gap: var(--system-space-2);
  display: flex;
  flex-wrap: wrap;
  padding-block-end: var(--system-space-2);
}

.table tr > :last-child:not(:first-child) {
  flex-basis: 100%;
}

.table :is(th, td) {
  font: var(--system-type-small);
  letter-spacing: var(--system-tracking-none);
  text-align: start;
}

.table td {
  color: var(--system-foreground-soft);
}

.table th {
  color: var(--system-foreground);
}

.table :is(thead th, th[scope='rowgroup']) {
  color: var(--system-muted-foreground);
  font: var(--system-type-micro);
  letter-spacing: var(--system-tracking-open);
}

.table th[scope='rowgroup'] {
  padding-block-start: var(--system-space-2);
}

@media (min-width: 64em) {

  .table {
    display: table;
  }

  .table thead {
    display: table-header-group;
  }

  .table tbody {
    display: table-row-group;
  }

  .table tr {
    display: table-row;
  }

  .table :is(th, td) {
    padding-block-end: var(--system-space-1);
    padding-inline-end: var(--system-space-2);
    vertical-align: baseline;
  }

  .table :is(th, td):last-child {
    padding-inline-end: 0;
  }

  .split > .table {
    grid-column: 1 / -1;
  }

  .split > .table :is(th, td):last-child:not(:first-child) {
    inline-size: var(--system-spine);
  }

}


/* ---------------------------------------------------------------------------------------------
   Flow. A drawing of three stages joined by wires, inside a Figure: what comes in, the one thing in
   the middle (the hub), and what works from it. Each stage is a label and a list. From 64em the
   stages stand side by side; every list spreads its items over the height they share, and the wires
   between two stages are one SVG stretched to that height, so each wire's ends sit on the middle of
   an item. The hub sets at base on the pitch, like the home list; the outer stages at small. Below
   64em the stages stack in reading order and the wires are left out: the three labelled lists say
   the same thing. There the outer lists run on as a line of words s-2 apart, like a row's items. */

.flow {
  display: grid;
  row-gap: var(--system-space-3);
}

.flow__stage {
  align-content: start;
  display: grid;
  row-gap: var(--system-space-1);
}

.flow__label {
  color: var(--system-muted-foreground);
  font: var(--system-type-micro);
  letter-spacing: var(--system-tracking-open);
}

.flow__items {
  color: var(--system-foreground-soft);
  column-gap: var(--system-space-2);
  display: flex;
  flex-wrap: wrap;
  font: var(--system-type-small);
  letter-spacing: var(--system-tracking-none);
}

.flow__stage--hub .flow__items {
  align-items: center;
  color: var(--system-foreground);
  display: grid;
  font: var(--system-type-base);
  grid-auto-rows: minmax(var(--system-space-3), 1fr);
  letter-spacing: var(--system-tracking-tight);
}

/* the drawing takes the lists' height and never lends them its own: out of flow, its viewBox ratio
   has no say in how tall the row is */
.flow__wires {
  display: none;
  position: relative;
}

.flow__wires svg {
  block-size: 100%;
  inline-size: 100%;
  inset: 0;
  position: absolute;
}

/* a drawn line of structure: the one line weight at --system-faint-foreground, however far the drawing stretches */
.flow__wires path {
  fill: none;
  stroke: var(--system-faint-foreground);
  stroke-width: var(--system-line);
  vector-effect: non-scaling-stroke;
}

@media (min-width: 64em) {

  /* a stage is as wide as its longest item, and gives way (its items wrap) before a wire is shorter
     than the pitch, so a Flow fits the spine's half as well as the whole frame */
  .flow {
    column-gap: var(--system-space-1);
    grid-template-columns: minmax(0, max-content) minmax(var(--system-space-3), 1fr) minmax(0, max-content) minmax(var(--system-space-3), 1fr) minmax(0, max-content);
    grid-template-rows: [label-start] auto [items-start] 1fr [items-end];
    row-gap: var(--system-space-1);
  }

  /* stages and wires share the two rows, so the labels line up and the lists share one height */
  .flow__stage,
  .flow__wires {
    display: grid;
    grid-row: label-start / items-end;
    grid-template-rows: subgrid;
  }

  /* every item gets an equal share of that height, its words centred on it: the wires aim there */
  .flow__items {
    align-items: center;
    display: grid;
    grid-auto-rows: 1fr;
  }

  .flow__wires svg {
    grid-row: items-start / items-end;
  }

}


/* ---------------------------------------------------------------------------------------------
   Chart. A quiet line plot inside a Figure: lines drawn in white at three steps of alpha, every word
   of it in HTML type (so each label sits on a named style and never scales with the drawing), and a
   key beneath. No axes, no gridlines, no fill, no dots: the two ends of each axis are labelled and
   the lines say the rest. The value axis's ends take at least the pitch, so charts stacked on a page
   start their drawings at one x. Invented data says so in the Figure's head, with a Tag. */

.chart > * + * {
  margin-block-start: var(--system-space-2);
}

.chart__frame {
  column-gap: var(--system-space-1);
  display: grid;
  grid-template-columns: minmax(var(--system-space-3), max-content) 1fr;
  row-gap: var(--system-space-1);
}

.chart__y,
.chart__x,
.chart__key {
  color: var(--system-muted-foreground);
  font: var(--system-type-micro);
  letter-spacing: var(--system-tracking-open);
}

/* the ends of the value axis, top and bottom of the drawing, set against it */
.chart__y {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  text-align: end;
}

.chart__x {
  display: flex;
  grid-column: 2;
  justify-content: space-between;
}

.chart__plot {
  block-size: auto;
  inline-size: 100%;
  overflow: visible;
}

/* three series, three alphas far enough apart to tell: --system-foreground, --system-muted-foreground, --system-faint-foreground */
.chart__line {
  fill: none;
  stroke: var(--system-foreground);
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: var(--system-line);
  vector-effect: non-scaling-stroke;
}

.chart__line[data-series='2'] {
  stroke: var(--system-muted-foreground);
}

.chart__line[data-series='3'] {
  stroke: var(--system-faint-foreground);
}

.chart__key {
  column-gap: var(--system-space-2);
  display: flex;
  flex-wrap: wrap;
  row-gap: var(--system-space-1);
}

.chart__key li {
  align-items: center;
  column-gap: var(--system-space-1);
  display: flex;
}

/* each key's swatch is an s-2 length of its line */
.chart__key li::before {
  background: var(--system-foreground);
  block-size: var(--system-line);
  content: '';
  flex: none;
  inline-size: var(--system-space-2);
}

.chart__key [data-series='2']::before {
  background: var(--system-muted-foreground);
}

.chart__key [data-series='3']::before {
  background: var(--system-faint-foreground);
}


/* ---------------------------------------------------------------------------------------------
   Linework. Mulholland's line drawing from the live site: parallel systems converging through one
   portal. The network is structure, at --system-faint-foreground; the signal route is --system-foreground. On the portal a
   rider runs a route through it and leaves a wall behind that fades from --system-foreground at its head
   through --system-foreground-soft to --system-muted-foreground; while it runs, the signal steps down into the network. Every line is
   the one line weight, non-scaling. It bleeds to both window edges, out of the gutter, so the
   systems arrive from beyond the page. From 64em it keeps the drawing's ratio; below, it is two s-4
   tall and crops to the portal. The live site's coral is cut: the signal is said with alpha. */

.linework {
  margin-inline: calc(var(--system-space-2) * -1);
}

.linework__drawing {
  block-size: calc(var(--system-space-4) * 2);
  inline-size: 100%;
}

@media (min-width: 64em) {

  .linework__drawing {
    block-size: auto;
  }

}

.linework path {
  fill: none;
  stroke: currentColor;
  stroke-width: var(--system-line);
  vector-effect: non-scaling-stroke;
}

.linework__network {
  color: var(--system-faint-foreground);
}

.linework__signal {
  color: var(--system-foreground);
  transition: color var(--system-duration) var(--system-ease);
}

.linework[data-state='moving'] .linework__signal {
  color: var(--system-faint-foreground);
}

.linework__rider {
  stroke-linecap: round;
  stroke-linejoin: round;
}

.linework__rider--far {
  color: var(--system-muted-foreground);
}

.linework__rider--wall {
  color: var(--system-foreground-soft);
}

.linework__rider--head {
  color: var(--system-foreground);
}
