/*
 * Moving Types Façade (/work/moving-types-facade/).
 * Shared building blocks (hero padding, eyebrow, facts, numbered circle,
 * stage, reflection, credits, next teaser) come from case-base.css; this
 * file only holds the page layout and the exhibits. Project accent: the LED
 * turquoise of the façade plan of 5 Aug 2011 (#58c0c8), used for exhibits
 * only, as --case-accent; the canvases read it from here. All other values
 * come from tokens.css; fixed values only inside graphics. Prefix mf-.
 *
 * A calm page (27.10.2026, after the Moving Types pilot, standard 3.5):
 * - No boxes around content: the quote, the six steps, the façade demo, the
 *   score, the venues and the hashtag code stand on the chapter surface.
 *   The figures, the stats and the related-project card of chapter 01 are
 *   gone; their facts live in the text and the captions.
 * - Surfaces set the rhythm: white, grey and the dark chapter 03 (the only
 *   dark surface besides the hero).
 * - No kickers or labels above blocks; their words live in the caption.
 *   One caption per figure or row, 12 px under the pictures.
 * - Rows of slides, plans and photos share one height: each picture grows
 *   with its aspect ratio (--ar on the image), so their edges line up.
 * - Interactive: the six steps (G02), the score (G03) and the hashtag code
 *   (G04) run once when they come into view, with one pause control in the
 *   caption; the façade (G01) is the one demo. The visit is a sticky scroll
 *   stage (js/case-stage.js), and chapter 04 is the one place where text
 *   stays while pictures pass.
 * Rules on shared case-base.css classes carry .mf-page, so they win there.
 */

:root {
  --mf-pink: #e0338f; /* second line colour in the venue sketches */
  --mf-night: #0f1316; /* hero ground and media placeholders */
}

.mf-page {
  --case-accent: #58c0c8; /* LED turquoise, exhibits only */
  margin: 0;
  background: var(--color-surface);
  color: var(--color-ink);
  font-family: var(--font-sans);
  overflow-x: clip;
}

.mf-page *,
.mf-page *::before,
.mf-page *::after {
  box-sizing: border-box;
}

.mf-page img,
.mf-page video,
.mf-page canvas {
  display: block;
  max-width: 100%;
}

.mf-page video {
  width: 100%;
  height: auto;
}

/* :where() keeps the reset weak, so component margins win. */
:where(.mf-page) figure {
  margin: 0;
}

.mf-page figcaption {
  margin: 12px 0 0;
  color: var(--color-ink-muted);
  font-size: var(--text-caption);
  line-height: var(--leading-caption);
  text-align: left;
}

.mf-page figcaption a {
  color: inherit !important;
  text-decoration: underline !important;
  text-underline-offset: 3px;
}

.mf-section--dark figcaption {
  color: var(--color-ink-on-dark-muted);
}

.mf-wrap {
  width: var(--content-width);
  margin-inline: auto;
}

/* ---------- Buttons ---------- */

/* !important: the global link rule in custom.css sets display and colour on
   every link with a much higher specificity. */
.mf-button {
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  gap: 12px;
  min-height: 48px;
  padding: 12px 26px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font: 600 16px/1.3 var(--font-sans);
  text-decoration: none !important;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-standard), color var(--dur-fast) var(--ease-standard), border-color var(--dur-fast) var(--ease-standard);
}

.mf-button--light {
  background: var(--color-surface);
  color: var(--color-ink) !important;
}

.mf-button--light:hover {
  background: var(--color-surface-alt);
}

.mf-button--solid {
  background: var(--color-accent);
  color: var(--color-ink-on-dark);
}

.mf-button--solid:hover {
  background: var(--color-accent-hover);
}

/* ---------- Hero ---------- */

.mf-hero {
  position: relative;
  min-height: max(720px, 100svh);
  background: var(--mf-night);
  color: var(--color-ink-on-dark);
  overflow: hidden;
}

/* The film sits on the right, so the glowing bridge (top left in the frame)
   stays visible next to the title instead of behind it. */
.mf-hero .mf-hero__video {
  position: absolute;
  top: 0;
  right: 0;
  width: 60%;
  height: 100%;
  object-fit: cover;
  object-position: 14% 35%;
}

.mf-hero__scrim {
  position: absolute;
  top: 0;
  right: 0;
  width: 60%;
  height: 100%;
  background:
    linear-gradient(90deg, #0f1316 0%, rgba(15, 19, 22, 0.55) 16%, rgba(15, 19, 22, 0) 36%),
    linear-gradient(0deg, #0f1316 0%, rgba(15, 19, 22, 0.7) 22%, rgba(15, 19, 22, 0) 46%),
    linear-gradient(180deg, rgba(15, 19, 22, 0.55) 0%, rgba(15, 19, 22, 0) 16%);
}

.mf-hero__content {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: max(720px, 100svh);
  padding-block: 120px 24px;
}

.mf-hero__main {
  max-width: 44%;
  margin-bottom: clamp(32px, 6vh, 72px);
}

.mf-hero__title {
  margin: 0;
  font-size: var(--text-h1);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-h1);
  letter-spacing: var(--tracking-heading);
  text-wrap: balance;
}

.mf-hero__lead {
  max-width: 640px;
  margin: 28px 0 36px;
  color: rgba(255, 255, 255, 0.88);
  font-size: var(--text-lead);
  line-height: var(--leading-lead);
}

.mf-hero .case-facts {
  color: var(--color-ink-on-dark);
}

.mf-hero__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 20px;
}

.mf-hero__credit {
  margin: 0;
  color: var(--color-ink-on-dark-muted);
  font-size: var(--text-caption);
  line-height: var(--leading-caption);
}

.mf-hero__toggle {
  flex: none;
  min-height: 36px;
  padding: 6px 16px;
  border: 1px solid rgba(255, 255, 255, 0.45);
  border-radius: var(--radius-pill);
  background: rgba(10, 13, 16, 0.35);
  color: #fff;
  font: 600 13px/1.2 var(--font-sans);
  cursor: pointer;
}

.mf-hero__toggle:hover {
  border-color: #fff;
}

/* ---------- Sections and headings ---------- */

/* Jump targets: the shared rule .case-chapters ~ section[id] sets the offset. */
.mf-section {
  padding-block: var(--space-section);
}

.mf-section--white {
  background: var(--color-surface);
}

.mf-section--grey {
  background: var(--color-surface-alt);
}

.mf-section--dark {
  background: var(--color-surface-dark);
  color: var(--color-ink-on-dark);
}

.mf-head {
  max-width: 940px;
  margin-bottom: var(--space-block);
}

.mf-head--split {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  gap: clamp(32px, 5vw, 88px);
  align-items: end;
  max-width: none;
}

.mf-h2 {
  margin: 0;
  font-size: var(--text-h2);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-h2);
  letter-spacing: var(--tracking-heading);
  text-wrap: balance;
}

.mf-h3 {
  margin: 0;
  font-size: var(--text-h3);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-h3);
  letter-spacing: var(--tracking-h3);
  text-wrap: balance;
}

.mf-head__text,
.mf-head__text p {
  margin: 0;
  color: var(--color-ink-body);
  font-size: var(--text-lead);
  line-height: var(--leading-lead);
}

.mf-section--dark .mf-head__text,
.mf-section--dark .mf-head__text p {
  color: var(--color-ink-on-dark-body);
}

/* Body copy beside pictures (chapters 04, 05, 06). */
.mf-pin__text p,
.mf-built__text p,
.mf-use p,
.mf-hashtag__text p {
  max-width: var(--measure-narrow);
  margin: var(--space-5) 0 0;
  color: var(--color-ink-body);
  font-size: var(--text-body);
  line-height: var(--leading-body);
}

/* ---------- Figures ---------- */

.mf-figure {
  min-width: 0;
}

.mf-figure img,
.mf-figure video,
.mf-row__images img {
  width: 100%;
  height: auto;
  border-radius: var(--radius-md);
}

.mf-figure video {
  background-color: var(--mf-night);
}

/* A row of pictures with one height: each one grows with its aspect ratio
   (--ar on the image), so top and bottom edges line up, and one caption
   runs under the whole row. */
.mf-row__images {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
}

.mf-row__images img {
  flex: calc(var(--ar)) 1 0%;
  min-width: 0;
}

.mf-row figcaption {
  max-width: var(--measure);
}

/* ---------- Caption with the pause control at its end ---------- */

.mf-caption-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  column-gap: var(--space-4);
}

.mf-caption-row > span {
  max-width: var(--measure);
}

.mf-control {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  /* The same width for "Pause" and "Play", so the caption never reflows. */
  min-width: 76px;
  min-height: var(--tap-min);
  /* Centre the 44 px target on the first caption line. */
  margin: -12px calc(-1 * var(--space-2)) -12px 0;
  padding: 0 var(--space-2);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-ink-muted);
  font: var(--weight-semibold) var(--text-caption)/var(--leading-caption) var(--font-sans);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-standard);
}

.mf-control[hidden] {
  display: none;
}

.mf-control:hover {
  color: var(--color-accent);
}

.mf-section--dark .mf-control {
  color: var(--color-ink-on-dark-muted);
}

.mf-section--dark .mf-control:hover {
  color: var(--color-accent-on-dark);
}

/* Two bars for "Pause", a triangle for "Play". */
.mf-control__icon {
  flex: none;
  width: 10px;
  height: 10px;
  border-right: 3px solid currentColor;
  border-left: 3px solid currentColor;
}

.mf-control[data-action="play"] .mf-control__icon {
  border: 0;
  background: currentColor;
  clip-path: polygon(0 0, 100% 50%, 0 100%);
}

/* A paused sequence also stops what is still moving inside the graphic. */
.mf-page .is-paused,
.mf-page .is-paused * {
  animation-play-state: paused !important;
}

/* Numbered circles (case-base.css): filled while their step is current. */
.mf-page li.is-current .case-num {
  background: var(--color-accent);
  color: var(--color-ink-on-dark);
}

/* ---------- 01 Starting point ---------- */

.mf-start {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(300px, 0.8fr);
  gap: clamp(40px, 7vw, 120px);
  align-items: start;
}

.mf-copy p {
  max-width: 680px;
  margin: 0 0 22px;
  color: var(--color-ink-body);
  font-size: var(--text-body);
  line-height: var(--leading-body);
}

.mf-copy p:last-child {
  margin-bottom: 0;
}

.mf-copy .mf-copy__lead {
  color: var(--color-ink);
  font-size: var(--text-lead);
  font-weight: var(--weight-medium);
  line-height: var(--leading-lead);
}

.mf-copy a {
  color: var(--color-accent) !important;
  font-weight: var(--weight-semibold);
  text-decoration: underline !important;
  text-underline-offset: 3px;
}

/* The brief of 2010 as a quote in large type, no box. The opening mark
   hangs into the margin, so the lines start flush. */
.mf-quote blockquote {
  margin: 0;
}

.mf-quote blockquote p {
  margin: 0;
  color: var(--color-ink);
  font-size: var(--text-quote);
  font-weight: var(--weight-medium);
  line-height: var(--leading-quote);
  letter-spacing: -0.01em;
  text-indent: -0.42em;
  text-wrap: pretty;
}

.mf-quote figcaption {
  margin-top: var(--space-5);
}

/* ---------- 02 Site: G02 six steps ---------- */

.mf-steps {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--space-8) var(--space-6);
  margin: 0;
  padding: 0;
  list-style: none;
}

.mf-steps li {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-content: start;
  align-items: center;
  gap: var(--space-3);
}

.mf-steps__icon {
  grid-column: 1 / -1;
  width: 88px;
  height: 70px;
  margin-bottom: var(--space-2);
  color: var(--color-accent);
  transition: opacity var(--dur-base) var(--ease-out);
}

.mf-steps__icon--muted {
  color: var(--color-ink-muted);
}

.mf-steps h3 {
  margin: 0;
  font-size: var(--text-h4);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-h4);
  letter-spacing: var(--tracking-h3);
  transition: color var(--dur-base) var(--ease-out);
}

.mf-steps p {
  grid-column: 1 / -1;
  margin: 0;
  color: var(--color-ink-body);
  font-size: var(--text-small);
  line-height: var(--leading-small);
  transition: color var(--dur-base) var(--ease-out);
}

/* While the sequence runs, the steps still to come wait muted; text keeps
   4.5 : 1 on the grey chapter. */
.mf-steps.is-live li:not(.is-done):not(.is-current) .mf-steps__icon {
  opacity: 0.22;
}

.mf-steps.is-live li:not(.is-done):not(.is-current) h3,
.mf-steps.is-live li:not(.is-done):not(.is-current) p {
  color: var(--color-ink-muted);
}

.mf-g02 > figcaption {
  margin-top: var(--space-10);
}

.mf-led-fill {
  fill: var(--case-accent);
}

.mf-led-stroke {
  stroke: var(--case-accent);
}

.mf-pink-stroke {
  stroke: var(--mf-pink);
}

.mf-row--site {
  margin-top: clamp(64px, 8vw, 112px);
}

/* ---------- 03 Encoding ---------- */

.mf-wide {
  margin-bottom: var(--space-block);
}

/* G01: the canvas stands on the dark chapter, the two fields below it. */
.mf-g01__canvas {
  width: 100%;
  height: auto;
  aspect-ratio: 1400 / 470;
}

.mf-g01__controls {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: var(--space-5) var(--space-10);
  align-items: start;
  margin-top: var(--space-6);
}

.mf-field label {
  display: block;
  margin: 0 0 10px;
  color: var(--color-ink-on-dark);
  font-size: var(--text-small);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-small);
}

.mf-field__row {
  display: flex;
  gap: 10px;
}

.mf-field input[type="text"] {
  flex: 1;
  min-width: 0;
  min-height: 48px;
  padding: 10px 16px;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: var(--radius-sm);
  background: #14181b;
  color: #fff;
  font: 600 16px/1.2 var(--font-sans);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.mf-field__hint {
  margin: 8px 0 0;
  color: var(--color-ink-on-dark-muted);
  font-size: var(--text-caption);
  line-height: var(--leading-caption);
}

.mf-field--range input {
  width: 100%;
  min-height: 48px;
  margin: 0;
  accent-color: var(--case-accent);
}

.mf-g01 > figcaption {
  margin-top: var(--space-4);
}

.mf-row--arrangement {
  margin-top: clamp(64px, 8vw, 112px);
}

.mf-arrangement-film {
  margin-top: var(--space-block);
}

/* The animation test is cut to its band of light and lies on the dark
   chapter: its black ground blends into the surface, so the points drift
   across the page instead of a black box. */
.mf-arrangement-film video {
  aspect-ratio: 1242 / 182;
  border-radius: 0;
  background-color: #000;
  mix-blend-mode: screen;
}

/* ---------- 04 Score ---------- */

.mf-score {
  display: grid;
  grid-template-columns: minmax(0, 1.65fr) minmax(0, 0.85fr);
  gap: clamp(32px, 4vw, 64px);
  align-items: end;
}

.mf-g03__canvas {
  width: 100%;
  height: auto;
  aspect-ratio: 1000 / 400;
}

/* Chapter 04 ends in the one place where text stays: from 1024 px the
   paragraph sticks while the model test, the passage and the four colours
   pass beside it, only on windows tall enough for the whole text. */
.mf-pin {
  display: grid;
  grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
  gap: var(--space-10) clamp(40px, 6vw, 96px);
  align-items: start;
  margin-top: clamp(80px, 10vw, 144px);
}

.mf-pin__media {
  display: grid;
  gap: var(--space-block);
}

.mf-colours__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
}

.mf-colours__grid img {
  width: 100%;
  height: auto;
  border-radius: var(--radius-md);
}

@media (min-width: 1024px) and (min-height: 720px) {
  .mf-pin__text {
    position: sticky;
    top: calc(var(--scroll-offset) + var(--space-6));
  }
}

/* ---------- 05 Build ---------- */

/* Column widths follow the films' aspect ratios (1280 × 540 and 1280 × 720),
   so both play at the same height. */
.mf-models {
  display: grid;
  grid-template-columns: minmax(0, 2.37fr) minmax(0, 1.78fr);
  gap: var(--space-6);
  align-items: start;
}

.mf-row--plans {
  margin-top: var(--space-block);
}

/* The finished bridge: the two photos first, the text beside them. */
.mf-built {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.75fr);
  gap: var(--space-10) clamp(40px, 6vw, 96px);
  align-items: center;
  margin-top: clamp(80px, 10vw, 144px);
}

.mf-built__pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
}

.mf-built__pair img {
  width: 100%;
  height: auto;
  aspect-ratio: 1200 / 1650;
  object-fit: cover;
  border-radius: var(--radius-md);
}

.mf-use {
  margin: clamp(80px, 10vw, 144px) 0 var(--space-block);
}

/* The stage (js/case-stage.js). All loops are 16 : 9, so the frame takes
   their shape on the dark of the films. From 1024 px the medium takes two
   thirds of the width; the frame sticks in the middle of the window below
   navigation and chapter bar, never taller than the window. */
.mf-page .case-stage__screen {
  aspect-ratio: 16 / 9;
  border: 0;
  background: var(--color-surface-dark);
}

.mf-page .case-stage__media video {
  border: 0;
  background-color: var(--mf-night);
}

.mf-page .mf-stage.is-staged {
  --mf-gap: var(--space-8);
  container-type: inline-size;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  column-gap: var(--mf-gap);
}

.mf-page .mf-stage.is-staged > .case-stage__frame {
  --mf-frame-w: min((100cqi - var(--mf-gap)) * 2 / 3, (100vh - var(--scroll-offset) - var(--space-24)) * 16 / 9);
  width: var(--mf-frame-w);
  top: calc(var(--scroll-offset) + max(var(--space-6), (100vh - var(--scroll-offset) - var(--mf-frame-w) * 9 / 16 - var(--space-12)) / 2));
}

@media (min-width: 1280px) {
  .mf-page .mf-stage.is-staged {
    --mf-gap: var(--space-12);
  }
}

/* As a list the paragraph above already names the film; the origin line
   shows under the frame on the stage only. */
.mf-page .mf-stage:not(.is-staged) .case-stage__origin {
  display: none;
}

/* The circles beside the steps and the bars under the frame show the
   position; the "01 / 03" counter is left out. */
.mf-page .case-stage__count {
  display: none;
}

/* case-base.css dims the inactive steps to 0.78, which keeps 4.5 : 1 on
   white; on the grey chapter 0.86 keeps text and numbers above 4.5 : 1. */
.mf-page .case-stage.is-staged .case-stage__step:not(.is-active) .case-stage__text {
  opacity: 0.86;
}

/* ---------- 06 Four venues ---------- */

.mf-venues {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-10) var(--space-8);
  margin: 0;
  padding: 0;
  list-style: none;
}

.mf-venue__art {
  display: block;
  width: 100%;
  height: auto;
  margin-bottom: var(--space-5);
}

.mf-venue h3 {
  margin: 0;
  font-size: var(--text-h4);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-h4);
  letter-spacing: var(--tracking-h3);
}

.mf-venue p {
  margin: var(--space-2) 0 0;
  color: var(--color-ink-body);
  font-size: var(--text-small);
  line-height: var(--leading-small);
}

.mf-venues-figure > figcaption {
  margin-top: var(--space-8);
}

.mf-row--prediger {
  max-width: 1040px;
  margin-top: clamp(64px, 8vw, 112px);
}

/* Dortmund: the text first, the code and the window beside it. */
.mf-hashtag {
  display: grid;
  grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
  gap: var(--space-10) clamp(40px, 6vw, 96px);
  align-items: start;
  margin-top: clamp(80px, 10vw, 144px);
}

/* G04: "#" and five digits, each with its name and meaning, over the
   window of the Dortmunder U. While the sequence runs, the digits still to
   come wait muted and the current one turns blue. */
.mf-g04__code {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  column-gap: var(--space-4);
}

.mf-g04__hash {
  color: var(--color-ink-muted);
  font-size: clamp(44px, 5vw, 72px);
  font-weight: 300;
  line-height: 1;
}

.mf-g04__digits {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.mf-g04__digits li {
  display: grid;
  gap: var(--space-1);
  min-width: 0;
}

.mf-g04__digit {
  color: var(--color-ink);
  font-size: clamp(44px, 5vw, 72px);
  font-weight: 300;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  transition: color var(--dur-base) var(--ease-out), opacity var(--dur-base) var(--ease-out);
}

.mf-g04__name {
  margin-top: var(--space-2);
  color: var(--color-ink-muted);
  font-size: var(--text-caption);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-caption);
}

.mf-g04__value {
  color: var(--color-ink-body);
  font-size: var(--text-small);
  line-height: var(--leading-small);
}

/* Muted by colour, not by opacity: the digits keep 4.5 : 1 while they wait. */
.mf-g04__digits.is-live li:not(.is-done):not(.is-current) .mf-g04__digit,
.mf-g04__digits.is-live li:not(.is-done):not(.is-current) .mf-g04__value {
  color: var(--color-ink-muted);
}

.mf-g04__digits li.is-current .mf-g04__digit {
  color: var(--color-accent);
}

/* The window shows the example as the code sets it; without JavaScript and
   at rest it stands still, set to #21850 (spacing: one random draw). */
.mf-window {
  margin-top: var(--space-6);
}

.mf-window__screen {
  display: flex;
  align-items: center;
  aspect-ratio: 2.4 / 1;
  overflow: hidden;
  border-radius: var(--radius-md);
  background: #d9343c;
  transition: background-color var(--dur-slow) var(--ease-standard);
}

.mf-window__text {
  width: 100%;
  margin: 0;
  overflow: hidden;
  color: #fff;
  /* Size 8 (+ + +); the script scales it down for the steps before. */
  font-size: calc(var(--mf-scale, 1) * clamp(36px, 5vw, 72px));
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: var(--mf-spacing, 0.12em);
  white-space: nowrap;
  text-shadow: 0 0 14px currentColor;
  transition: color var(--dur-slow) var(--ease-standard), font-size var(--dur-slow) var(--ease-standard), letter-spacing var(--dur-slow) var(--ease-standard);
}

.mf-window__text span {
  display: inline-block;
  padding-left: 5%;
}

/* The message runs only while the sequence plays. */
.mf-g04.is-running .mf-window__text span {
  padding-left: 100%;
  animation: mf-ticker var(--mf-speed, 9.5s) linear infinite;
}

@keyframes mf-ticker {
  from { transform: translateX(0); }
  to { transform: translateX(-100%); }
}

.mf-g04 > figcaption {
  margin-top: var(--space-4);
}

/* ---------- Reveal (only with JS and without reduced motion) ---------- */

@media (prefers-reduced-motion: no-preference) {
  .mf-motion-ready .mf-reveal {
    opacity: 0;
    transform: translateY(var(--reveal-distance));
    transition: opacity var(--dur-reveal) var(--ease-out), transform var(--dur-reveal) var(--ease-out);
  }

  .mf-motion-ready .mf-reveal.is-visible {
    opacity: 1;
    transform: none;
  }
}

/* ---------- Responsive ---------- */

@media (max-width: 1279.98px) {
  .mf-steps {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 1023.98px) {
  .mf-hero .mf-hero__video,
  .mf-hero__scrim {
    width: 100%;
    height: min(58svh, 560px);
  }

  .mf-hero .mf-hero__video {
    object-position: 16% 30%;
  }

  .mf-hero__scrim {
    background:
      linear-gradient(0deg, #0f1316 0%, rgba(15, 19, 22, 0.6) 30%, rgba(15, 19, 22, 0) 62%),
      linear-gradient(180deg, rgba(15, 19, 22, 0.6) 0%, rgba(15, 19, 22, 0) 22%);
  }

  .mf-hero__content {
    padding-top: calc(min(58svh, 560px) - 96px);
  }

  .mf-hero__main {
    max-width: 720px;
  }

  .mf-head--split,
  .mf-start,
  .mf-score,
  .mf-pin,
  .mf-built,
  .mf-hashtag {
    grid-template-columns: minmax(0, 1fr);
  }

  .mf-head--split {
    align-items: start;
  }

  .mf-score__slide {
    max-width: 560px;
  }

  .mf-venues {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .mf-built__text {
    order: -1;
  }
}

@media (max-width: 767.98px) {
  .mf-hero__foot {
    flex-wrap: wrap;
  }

  .mf-g01__controls,
  .mf-models {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Rows of slides and plans stack; only the two Prediger photos stay
     side by side down to 640 px. */
  .mf-row--site .mf-row__images,
  .mf-row--arrangement .mf-row__images,
  .mf-row--plans .mf-row__images {
    flex-direction: column;
    gap: var(--space-6);
  }

  .mf-row--site .mf-row__images img,
  .mf-row--arrangement .mf-row__images img,
  .mf-row--plans .mf-row__images img {
    flex: none;
    width: 100%;
  }

  /* The crossed-out projector is a sign, not a plan: smaller. */
  .mf-row--site .mf-row__images img:last-child {
    width: 56%;
  }

  .mf-steps {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-8) var(--space-5);
  }

  .mf-g01__canvas {
    aspect-ratio: 760 / 470;
  }

  .mf-g03__canvas {
    aspect-ratio: 600 / 400;
  }

  .mf-g04__code {
    grid-template-columns: minmax(0, 1fr);
  }

  .mf-g04__hash {
    display: none;
  }

  .mf-g04__digits {
    gap: var(--space-2);
  }

  .mf-g04__digit {
    font-size: 40px;
  }

  .mf-g04__name {
    font-size: 11px;
    hyphens: auto;
  }

  .mf-g04__value {
    font-size: var(--text-caption);
  }

  /* The stage as a list: a little less air between the steps on phones. */
  .mf-page .case-stage__steps {
    gap: var(--space-12);
  }
}

@media (max-width: 639.98px) {
  .mf-row--prediger .mf-row__images {
    flex-direction: column;
  }

  .mf-row--prediger .mf-row__images img {
    flex: none;
    width: 100%;
  }

  /* One venue per row, the drawing beside its text. */
  .mf-venues {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-8);
  }

  .mf-venue {
    display: grid;
    grid-template-columns: 112px minmax(0, 1fr);
    column-gap: var(--space-4);
    align-items: start;
  }

  .mf-venue__art {
    grid-row: span 2;
    margin: 4px 0 0;
  }
}

/* Narrow phones: one step per row, the sign beside its text. */
@media (max-width: 479.98px) {
  .mf-steps {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-6);
  }

  .mf-steps li {
    grid-template-columns: 64px auto minmax(0, 1fr);
    column-gap: var(--space-3);
    row-gap: var(--space-2);
  }

  .mf-steps__icon {
    grid-column: 1;
    grid-row: 1 / span 2;
    align-self: start;
    width: 64px;
    height: 51px;
    margin: 0;
  }

  .mf-steps p {
    grid-column: 2 / -1;
  }
}

/* ---------- Reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  .mf-page *,
  .mf-page *::before,
  .mf-page *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  .mf-reveal {
    opacity: 1 !important;
    transform: none !important;
  }

  .mf-g04.is-running .mf-window__text span {
    padding-left: 5%;
    animation: none;
  }
}

/* ---------- Without JavaScript ---------- */

/* Last in the file, so these win over the layout rules above. */

@media (scripting: none) {
  /* main.js never colours the fixed navigation without JavaScript, and its
     white text would run over the light chapters: give it the dark of the
     chapter bar. */
  .mf-page #main-nav {
    background: var(--color-surface-dark);
  }

  /* Loops get their poster from js/moving-types-facade-story.js; without it
     the same picture stands behind the video as a still. The native
     controls would cover it with an empty grey panel. */
  .mf-page video[data-poster] {
    background: var(--poster) center / cover no-repeat;
  }

  .mf-page video[data-poster]::-webkit-media-controls {
    display: none !important;
  }

  /* The canvases stay empty without the script: their resting state as a
     still. The demo controls would do nothing. */
  .mf-g01__canvas {
    background: url("/assets/moving-types-facade/g01-still.jpg") left center / cover no-repeat;
  }

  .mf-g03__canvas {
    background: url("/assets/moving-types-facade/g03-still.png") left center / cover no-repeat;
  }

  .mf-g01__controls {
    display: none;
  }
}
