/* ============================================================================
   /manufacturing, Clearer draft: the story in chapters, and the thread through
   them. Rules of the expression layer apply (see expression.css): motion carries
   meaning, the HTML holds the true final state, once, quiet, reduced motion gets
   the final state at once, external scripts only.

   WHAT MOVES AND WHY
   - The thread (.mx-rail): a line in the left gutter that fills with the page,
     and the chapter you are in lights up. It is the table of contents, so it
     shows where you are in the argument, not decoration. Wide screens only; the
     hero's chapter list does the same job everywhere else.
   - Chapter numerals and bridge rules arrive as their chapter enters. The words
     never move; only the graphics do (the homepage's rule).
   - Three diagrams play once in view, each labelled "Proposed" and as a
     mechanism, never data: the shape of the work (wide across the steps, one
     piece deep: the tooling), the blueprint travelling with its identical jigs,
     and one order split across qualified hubs into one trail.
   Scroll-driven parts sit behind @supports, so Firefox and reduced motion get
   the page as written. Driven by /js/ex-mfg.js.
   ============================================================================ */

/* ---- Hero ----------------------------------------------------------------- */
.ed .mx-hero__line { font-family: var(--font-display); font-size: clamp(1.9rem, 4.6vw, 3.4rem); line-height: 1.04; letter-spacing: -.02em; color: var(--ed-ink); margin: var(--space-4) 0 0; max-width: 26ch; text-wrap: balance; }
.ed .mx-hero__line span { display: block; color: var(--ed-accent); }
.ed .mx-hero .project-summary { margin-top: var(--space-6); max-width: 40rem; }
.ed .mx-truth { margin: var(--space-4) 0 0; font-family: var(--font-mono); font-size: var(--ed-small, 13px); letter-spacing: .02em; color: var(--ed-quiet); }
.ed .mx-truth strong { color: var(--mo-warning, #e6a100); font-weight: 500; }

/* The chapter list under the hero: the same nine stops as the rail. */
.ed .mx-toc { list-style: none; margin: var(--space-8) 0 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(13.5rem, 1fr)); gap: 0 var(--space-6); counter-reset: mx; }
.ed .mx-toc li { counter-increment: mx; border-top: 1px solid var(--ed-rule); }
.ed .mx-toc a { display: flex; gap: .75rem; align-items: baseline; padding: .7rem 0; color: var(--ed-body); text-decoration: none; transition: color 200ms var(--ed-ease); }
.ed .mx-toc a::before { content: counter(mx, decimal-leading-zero); font-family: var(--font-mono); font-size: var(--ed-label); letter-spacing: .1em; color: var(--ed-quiet); }
.ed .mx-toc a:hover, .ed .mx-toc a:focus-visible { color: var(--ed-accent); }

/* ---- Chapters ------------------------------------------------------------- */
.ed .mx-ch .section-header { position: relative; }
.ed .mx-num { display: block; font-family: var(--font-display); font-size: clamp(2.6rem, 6vw, 4.25rem); line-height: .9; letter-spacing: -.03em; color: transparent; -webkit-text-stroke: 1px var(--ed-rule-strong); margin: 0 0 var(--space-3); }
.ed .mx-ch .kicker { color: var(--ed-accent); }
.ed .mx-body { max-width: 44rem; display: grid; gap: var(--space-4); }
.ed .mx-body p { margin: 0; }
.ed .mx-lead { font-size: var(--ed-lede); color: var(--ed-ink); }
.ed .mx-evidence { font-size: var(--text-sm); color: var(--ed-quiet); border-left: 1px solid var(--ed-rule-strong); padding-left: var(--space-4); }
.ed .mx-evidence a, .ed .mx-body a { color: var(--ed-accent); }
.ed .mx-fig + .mx-body, .ed .tier-grid + .mx-body, .ed .mx-pay + .mx-body { margin-top: var(--space-6); }

/* The first chapter follows the hero's own bottom rule. On the review build it
   sits alone in a variant wrapper, where variants.css restores a top rule meant
   for sections that are not first once promoted; this one is first, so take it
   back off and the review shows what ships. */
.ed .mfg-sections > [data-variant-block] > .mfg-section.mx-ch--first:first-of-type { border-top: 0; padding-top: 0; }

/* The bridge: the sentence that hands one chapter to the next. */
.ed .mx-bridge { margin: var(--space-12) 0 0; max-width: 40rem; font-family: var(--font-display); font-size: var(--ed-h3); line-height: 1.3; color: var(--ed-ink); }
.ed .mx-bridge::before { content: ""; display: block; width: 3rem; height: 1px; margin-bottom: var(--space-4); background: var(--ed-accent); transform-origin: left; }
.ed .mx-bridge--lead { margin: 0 0 var(--space-8); }

/* ---- 02: the time ladder ------------------------------------------------------ */
.ed .mx-ladder { margin: var(--space-8) 0 0; max-width: 52rem; }
.ed .mx-ladder__title { margin: 0 0 var(--space-3); font-family: var(--font-mono); font-size: var(--ed-label); letter-spacing: .14em; text-transform: uppercase; color: var(--ed-quiet); }
.ed .mx-ladder ol { list-style: none; margin: 0; padding: 0; }
.ed .mx-ladder li { display: grid; grid-template-columns: minmax(0, 15rem) minmax(0, 1fr); gap: 2px var(--space-6); padding: .85rem 0; border-top: 1px solid var(--ed-rule); }
.ed .mx-ladder li:last-child { border-bottom: 1px solid var(--ed-rule); }
.ed .mx-ladder__kind { grid-row: span 2; color: var(--ed-ink); font-weight: 500; }
.ed .mx-ladder__range { color: var(--ed-accent); font-family: var(--font-display); }
.ed .mx-ladder__note { grid-column: 2; font-size: var(--text-sm); color: var(--ed-quiet); }
.ed .mx-ladder__note a { color: var(--ed-quiet); text-decoration: underline; text-underline-offset: 2px; }
.ed .mx-ladder__note a:hover, .ed .mx-ladder__note a:focus-visible { color: var(--ed-accent); }
.ed .mx-ladder__cap { margin: var(--space-3) 0 0; font-size: var(--text-sm); color: var(--ed-quiet); }
.ed .mx-ladder + .mx-body { margin-top: var(--space-6); }

.ed .mx-sub { margin: var(--space-12) 0 var(--space-4); font-family: var(--font-display); font-size: var(--ed-h3); color: var(--ed-ink); }

/* ---- 05: who pays ----------------------------------------------------------- */
.ed .mx-pay { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: var(--space-6); margin-top: var(--space-6); }
.ed .mx-pay__col h3 { font-family: var(--font-mono); font-size: var(--ed-label); letter-spacing: .14em; text-transform: uppercase; font-weight: 400; color: var(--ed-quiet); margin: 0 0 var(--space-3); }
.ed .mx-pay ul { list-style: none; margin: 0; padding: 0; }
.ed .mx-pay li { padding: .8rem 0; border-top: 1px solid var(--ed-rule); color: var(--ed-body); }
.ed .mx-pay li strong { display: block; color: var(--ed-ink); font-weight: 500; }
.ed .mx-pay--earn li { box-shadow: inset 2px 0 0 var(--ed-accent); padding-left: .9rem; }


/* ---- 09: your move ------------------------------------------------------------ */
/* Four doors: one, two or four columns, never three plus a gap. */
@media (min-width: 40rem) { .ed .mx-doors { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 72rem) { .ed .mx-doors { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.ed .mx-doors { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1px; background: var(--ed-rule); border: 1px solid var(--ed-rule); margin-top: var(--space-6); }
.ed .mx-door { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-6); background: var(--bg-page, #111312); text-decoration: none; color: var(--ed-body); transition: background-color 200ms var(--ed-ease); }
.ed .mx-door b { font-family: var(--font-mono); font-size: var(--ed-label); letter-spacing: .14em; text-transform: uppercase; font-weight: 400; color: var(--ed-quiet); }
.ed .mx-door strong { font-family: var(--font-display); font-size: var(--ed-h3); font-weight: 500; color: var(--ed-ink); }
.ed .mx-door em { font-style: normal; font-family: var(--font-mono); font-size: var(--ed-label); letter-spacing: .14em; text-transform: uppercase; color: var(--ed-accent); margin-top: auto; padding-top: var(--space-2); }
.ed .mx-door:hover, .ed .mx-door:focus-visible { background: var(--ed-raised, rgba(255,255,255,.03)); }

/* 07 shares the Stage 0 section with the live page. In this draft the chapter
   opener above it carries the label, so the section's own kicker would be a
   second label in a row. Hidden in the Clearer view and on production after
   promotion (no data-variant attribute), never in the Current view. */
html:not([data-variant="current"]) .ed .mfg-section:has(> .timeline) > .section-header .kicker { display: none; }
html:not([data-variant="current"]) .ed .mfg-section:has(> .timeline) { border-top: 0; padding-top: var(--space-6); }
.ed .mx-ch--lead { padding-top: clamp(2.25rem, 5vw, 4.5rem); border-top: 1px solid var(--ed-rule); }
.ed .mx-ch--lead .kicker { margin: 0 0 var(--space-4); }
.ed .mx-tail { padding-bottom: clamp(2.25rem, 5vw, 4.5rem); max-width: 44rem; }
.ed .mx-tail p { margin: 0; }
.ed .mx-tail .mx-bridge { margin-top: var(--space-8); }
.ed .mx-locked { font-family: var(--font-mono); font-size: var(--ed-label); letter-spacing: .14em; text-transform: uppercase; color: var(--mo-warning, #e6a100); margin-right: .5rem; }

/* The build log is shared with the live page and grows every month. ex-mfg.js
   folds it to the latest three in the Clearer view (and on production once
   promoted); the Current view, and any page without the script, shows all. */
@media screen { html:not([data-variant="current"]) .ed .mx-log-folded .log-entry:nth-child(n+4) { display: none; } }
html[data-variant="current"] .ed .mx-log-more { display: none; }
.ed .mx-log-more { margin-top: var(--space-4); font-family: var(--font-mono); font-size: var(--ed-label); letter-spacing: .14em; text-transform: uppercase; color: var(--ed-accent); background: none; border: 1px solid var(--ed-rule-strong); padding: 10px 16px; cursor: pointer; }
.ed .mx-log-more:hover, .ed .mx-log-more:focus-visible { border-color: var(--ed-accent); }

/* ---- The diagrams: today and proposed ------------------------------------------ */
.ed .mx-fig { margin: var(--space-8) 0 0; max-width: 34rem; padding: var(--space-4) var(--space-6) var(--space-6); border: 1px solid var(--ed-rule-strong); }
.ed .mx-fig.mx-armed { cursor: pointer; }
.ed .mx-fig:focus-visible { outline: 2px solid var(--ed-accent); outline-offset: 4px; }
.ed .mx-fig__head { display: flex; justify-content: space-between; gap: 12px; font-family: var(--font-mono); font-size: var(--ed-label); letter-spacing: .14em; text-transform: uppercase; color: var(--ed-quiet); margin-bottom: var(--space-3); }
.ed .mx-fig__head span:last-child { color: var(--mo-warning, #e6a100); }
.ed .mx-fig svg { display: block; width: 100%; height: auto; overflow: visible; }
.ed .mx-fig figcaption { margin-top: var(--space-3); font-size: var(--text-sm); color: var(--ed-quiet); }
.ed .mx-d__rail { stroke: var(--ed-rule-strong); stroke-width: 1; stroke-dasharray: 3 4; }
.ed .mx-d__wall { stroke: var(--mo-warning, #e6a100); stroke-width: 1.25; stroke-dasharray: 2 3; }
.ed .mx-d__walllabel { font-family: var(--font-mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase; fill: var(--mo-warning, #e6a100); }
.ed .mx-d__hub { fill: var(--bg-page, #111312); stroke: var(--ed-rule-strong); stroke-width: 1.25; }
.ed .mx-d__hub--lit { stroke: var(--ed-accent); }
.ed .mx-d__name { font-family: var(--font-mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; fill: var(--ed-quiet); }
.ed .mx-d__tile { fill: var(--ed-accent); }
.ed .mx-d__seal { fill: none; stroke: var(--ed-accent); stroke-width: 1.5; }
.ed .mx-d__cap { font-family: var(--font-mono); font-size: 12px; letter-spacing: .04em; fill: var(--ed-body); }
.ed .mx-d__cap--warn { fill: var(--mo-warning, #e6a100); }
.ed .mx-d__hub--home { stroke: var(--ed-accent); }

/* Final state is the default: with no script, every diagram shows the end of the
   story. ex-mfg.js arms a figure (.mx-armed) and plays it (.is-play) once in
   view; a click or Enter replays it. */
/* Geometry lives in the SVG's own units: CSS lengths in an SVG transform are
   user units, so the travel scales with the figure.
   Proposed: A at 40, B at 260, C at 480. */
@keyframes mx-travel-abc { 0% { transform: translateX(0); } 40%, 55% { transform: translateX(220px); } 100% { transform: translateX(440px); } }
@keyframes mx-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes mx-cap { 0% { opacity: 0; } 12%, 88% { opacity: 1; } 100% { opacity: 0; } }
@keyframes mx-lit { from { stroke: var(--ed-rule-strong); } to { stroke: var(--ed-accent); } }

/* The true final state, shown with no script. */
.ed .mx-fig .mx-d__cap { opacity: 0; }
.ed .mx-fig .mx-d__cap--final { opacity: 1; }
.ed .mx-fig--proposed .mx-d__mover { transform: translateX(440px); }

/* Armed: back to the start, waiting to be seen. */
.ed .mx-armed .mx-d__mover { transform: translateX(0); }
.ed .mx-armed .mx-d__cap--final { opacity: 0; }
.ed .mx-armed .mx-d__hub--lit { stroke: var(--ed-rule-strong); }


/* Proposed: the qualification travels with the blueprint, and each hub it
   reaches lights. */
.ed .mx-fig--proposed.mx-armed.is-play .mx-d__mover { animation: mx-travel-abc 3.2s var(--ex-ease, ease-in-out) .9s both; }
.ed .mx-fig--proposed.mx-armed.is-play .mx-d__hub--b { animation: mx-lit .36s linear 2.1s both; }
.ed .mx-fig--proposed.mx-armed.is-play .mx-d__hub--c { animation: mx-lit .36s linear 4s both; }
.ed .mx-fig--proposed.mx-armed.is-play .mx-d__cap--1 { animation: mx-cap 1.5s linear .2s both; }
.ed .mx-fig--proposed.mx-armed.is-play .mx-d__cap--2 { animation: mx-cap 1.5s linear 1.9s both; }
.ed .mx-fig--proposed.mx-armed.is-play .mx-d__cap--final { animation: mx-fade-in .4s linear 4.2s both; }

/* ---- The journey frame (2026-10-05) ------------------------------------------ */
.ed .mx-promises { list-style: none; margin: var(--space-6) 0 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 0 var(--space-6); max-width: 60rem; }
.ed .mx-promises li { border-top: 1px solid var(--ed-rule); }
.ed .mx-promises a { display: flex; flex-direction: column; gap: 4px; padding: .9rem 0; color: var(--ed-body); text-decoration: none; transition: color 200ms var(--ed-ease); }
.ed .mx-promises b { font-family: var(--font-display); font-size: var(--ed-h3); font-weight: 500; color: var(--ed-accent); }
.ed .mx-promises a:hover, .ed .mx-promises a:focus-visible { color: var(--ed-ink); }
.ed .mx-journey__title { margin: var(--space-8) 0 0; font-family: var(--font-mono); font-size: var(--ed-label); letter-spacing: .14em; text-transform: uppercase; color: var(--ed-quiet); }
.ed .mx-journey__title + .mx-toc { margin-top: var(--space-3); }
.ed .mx-toc li.mx-toc__after a::before { color: var(--ed-rule-strong); }
.ed .mx-toc li.mx-toc__after a { color: var(--ed-quiet); }
.ed .mx-rail li.mx-rail__after { margin-top: .6rem; }

/* ---- 01: the scope, two lists */
.ed .mx-scope { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: var(--space-6); margin: var(--space-6) 0; max-width: 52rem; }
.ed .mx-scope h3 { font-family: var(--font-mono); font-size: var(--ed-label); letter-spacing: .14em; text-transform: uppercase; font-weight: 400; color: var(--ed-accent); margin: 0 0 var(--space-3); }
.ed .mx-scope--not h3 { color: var(--ed-quiet); }
.ed .mx-scope ul { list-style: none; margin: 0; padding: 0; }
.ed .mx-scope li { padding: .7rem 0; border-top: 1px solid var(--ed-rule); color: var(--ed-body); }
.ed .mx-scope li:last-child { border-bottom: 1px solid var(--ed-rule); }
.ed .mx-scope--not li { color: var(--ed-quiet); }
.ed .mx-scope a { color: var(--ed-accent); }

/* ---- 03: the ladder, folded */
.ed .mx-more { margin: var(--space-6) 0 0; max-width: 52rem; border-top: 1px solid var(--ed-rule); padding-top: var(--space-4); }
.ed .mx-more > summary { cursor: pointer; font-family: var(--font-mono); font-size: var(--ed-label); letter-spacing: .14em; text-transform: uppercase; color: var(--ed-accent); }
.ed .mx-more > summary:focus-visible { outline: 2px solid var(--ed-accent); outline-offset: 4px; }
.ed .mx-more[open] > .mx-ladder, .ed .mx-more[open] > .mx-more__body { margin-top: var(--space-4); }

/* ---- Figure parts for the scope and route diagrams */
.ed .mx-d__bar { stroke: var(--ed-accent); stroke-width: 2; transform-box: fill-box; transform-origin: left center; }
.ed .mx-d__stop { fill: var(--bg-page, #111312); stroke: var(--ed-accent); stroke-width: 1.25; }
.ed .mx-d__stop--end { fill: var(--ed-accent); }
.ed .mx-d__notch { stroke: var(--mo-warning, #e6a100); stroke-width: 1.5; }
.ed .mx-d__jigbox { fill: none; stroke: var(--mo-warning, #e6a100); stroke-width: 1.5; }
.ed .mx-d__jig { fill: none; stroke: var(--mo-warning, #e6a100); stroke-width: 1.5; }
.ed .mx-d__hub--no { fill: var(--bg-page, #111312); stroke: var(--mo-warning, #e6a100); stroke-width: 1.25; stroke-dasharray: 3 3; opacity: .7; }
.ed .mx-d__tile--half { fill: var(--ed-accent); opacity: .75; }
.ed .mx-d__trail { stroke: var(--ed-accent); stroke-width: 2; transform-box: fill-box; transform-origin: left center; }

/* Final states (no script): the scope bar drawn, the route halves at their hubs. */
.ed .mx-fig--route .mx-d__mover--a { transform: translateX(140px); }
.ed .mx-fig--route .mx-d__mover--b { transform: translateX(290px); }

/* Armed: back to the start. */
.ed .mx-fig--scope.mx-armed .mx-d__bar, .ed .mx-fig--route.mx-armed .mx-d__trail { transform: scaleX(0); }
.ed .mx-fig--route.mx-armed .mx-d__mover { transform: translateX(0); }
.ed .mx-fig--scope.mx-armed :is(.mx-d__notch, .mx-d__jigbox, .mx-d__notchlabel) { opacity: 0; }

@keyframes mx-draw-x { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes mx-to-a { from { transform: translateX(0); } to { transform: translateX(140px); } }
@keyframes mx-to-b { from { transform: translateX(0); } to { transform: translateX(290px); } }

/* Scope: the bar crosses the work, then the one deep notch drops at Assemble. */
.ed .mx-fig--scope.mx-armed.is-play .mx-d__bar { animation: mx-draw-x 1.4s var(--ex-ease, ease-in-out) .4s both; }
.ed .mx-fig--scope.mx-armed.is-play :is(.mx-d__notch, .mx-d__jigbox, .mx-d__notchlabel) { animation: mx-fade-in .4s linear 2s both; }
.ed .mx-fig--scope.mx-armed.is-play .mx-d__cap--1 { animation: mx-cap 1.2s linear .1s both; }
.ed .mx-fig--scope.mx-armed.is-play .mx-d__cap--2 { animation: mx-cap 1.2s linear 1.3s both; }
.ed .mx-fig--scope.mx-armed.is-play .mx-d__cap--final { animation: mx-fade-in .4s linear 2.5s both; }

/* Route: one order splits, the halves reach the qualified hubs, one trail draws. */
.ed .mx-fig--route.mx-armed.is-play .mx-d__mover--a { animation: mx-to-a 1.3s var(--ex-ease-out, ease-out) .9s both; }
.ed .mx-fig--route.mx-armed.is-play .mx-d__mover--b { animation: mx-to-b 1.7s var(--ex-ease-out, ease-out) .9s both; }
.ed .mx-fig--route.mx-armed.is-play .mx-d__hub--b { animation: mx-lit .36s linear 1.9s both; }
.ed .mx-fig--route.mx-armed.is-play .mx-d__hub--c { animation: mx-lit .36s linear 2.4s both; }
.ed .mx-fig--route.mx-armed.is-play .mx-d__trail { animation: mx-draw-x .8s var(--ex-ease, ease-in-out) 2.8s both; }
.ed .mx-fig--route.mx-armed.is-play .mx-d__cap--1 { animation: mx-cap 1.2s linear .1s both; }
.ed .mx-fig--route.mx-armed.is-play .mx-d__cap--2 { animation: mx-cap 1.6s linear 1.3s both; }
.ed .mx-fig--route.mx-armed.is-play .mx-d__cap--final { animation: mx-fade-in .4s linear 3.4s both; }

/* ---- Entrances that follow the scroll (compositor only) ------------------------- */
@supports (animation-timeline: view()) {
  @keyframes mx-num-in { from { opacity: 0; transform: translateY(.35em); } to { opacity: 1; transform: none; } }
  @keyframes mx-rule-in { from { transform: scaleX(0); } to { transform: scaleX(1); } }
  .ed .mx-num { animation: mx-num-in linear both; animation-timeline: view(); animation-range: entry 10% cover 28%; }
  .ed .mx-bridge::before { animation: mx-rule-in linear both; animation-timeline: view(); animation-range: entry 20% cover 35%; }
}

/* ---- The thread: the chapter rail in the left gutter ----------------------------- */
.ed .mx-rail { display: none; }
@media (min-width: 96rem) {
  .ed .mx-rail {
    display: block; position: fixed; z-index: 2;
    top: 50%; transform: translateY(-50%);
    left: max(16px, calc((100vw - 1080px) / 2 - 12.5rem));
    width: 11rem;
  }
  .ed .mx-rail__track { position: relative; }
  .ed .mx-rail ol { list-style: none; margin: 0; padding: 0 0 0 1.1rem; position: relative; }
  .ed .mx-rail ol::before { content: ""; position: absolute; left: 0; top: .5rem; bottom: .5rem; width: 1px; background: var(--ed-rule-strong); }
  .ed .mx-rail__fill { position: absolute; left: 0; top: .5rem; bottom: .5rem; width: 1px; background: var(--ed-accent); transform-origin: top; transform: scaleY(0); z-index: 1; }
  .ed .mx-rail a { display: block; padding: .32rem 0; font-family: var(--font-mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--ed-quiet); text-decoration: none; transition: color 200ms var(--ed-ease); }
  .ed .mx-rail a:hover, .ed .mx-rail a:focus-visible { color: var(--ed-ink); }
  .ed .mx-rail a[aria-current="true"] { color: var(--ed-accent); }
  .ed .mx-rail a span { display: inline-block; width: 2.1em; color: var(--ed-quiet); }
  .ed .mx-rail a[aria-current="true"] span { color: var(--ed-accent); }
  @supports (animation-timeline: scroll()) {
  }
}

@media (max-width: 40rem) {
  .ed .mx-ladder li { grid-template-columns: minmax(0, 1fr); }
  .ed .mx-ladder__note { grid-column: 1; }
  .ed .mx-ladder__kind { grid-row: auto; }
  .ed .mx-fig { padding: var(--space-3) var(--space-4) var(--space-4); }
  /* SVG text scales with the figure: at phone width 12 units render near 7px.
     Larger units keep the captions readable; the longest still fits 520. */
  .ed .mx-d__cap { font-size: 19px; }
  .ed .mx-d__name, .ed .mx-d__walllabel { font-size: 16px; }
}

/* Print and reduced motion show the complete mechanism, including figures
   still waiting for their observer or interrupted halfway through a replay. */
@media print, (prefers-reduced-motion: reduce) {
  .ed .mx-fig *, .ed .mx-num, .ed .mx-bridge::before { animation: none !important; transition: none !important; }
  .ed .mx-fig--scope .mx-d__bar, .ed .mx-fig--route .mx-d__trail { transform: none !important; }
  .ed .mx-fig--scope :is(.mx-d__notch, .mx-d__jigbox, .mx-d__notchlabel) { opacity: 1 !important; }
  .ed .mx-fig--route .mx-d__mover--a { transform: translateX(140px) !important; }
  .ed .mx-fig--route .mx-d__mover--b { transform: translateX(290px) !important; }
  .ed .mx-num, .ed .mx-bridge::before { opacity: 1 !important; transform: none !important; }
  .ed .mx-fig--proposed .mx-d__mover { transform: translateX(440px) !important; }
  .ed .mx-fig .mx-d__hub--lit { stroke: var(--ed-accent) !important; }
  .ed .mx-fig .mx-d__cap { opacity: 0 !important; }
  .ed .mx-fig .mx-d__cap--final { opacity: 1 !important; }
}

@media print {
  .ed .mx-rail, .ed .mx-log-more { display: none; }
}
