/* ==========================================================================
   NINE VIEWS — Kiriko
   Overlay-cut glass. A kise colour is laid over each photograph; the panels and
   the place names are the cut, and the photograph comes back to full strength
   inside them. Corners are chamfered, never rounded: a cut edge is a facet.
   ========================================================================== */

:root {
  /* Leaded-crystal base. Everything else is mixed against it. */
  --ground: #070A0E;
  --ink: #EDF1F6;
  --ink-dim: #A9B4C2;

  /* Each view overrides --kise inline; this is what the standing chrome falls back to. */
  --kise: #1B4A8C;

  /* How much of its own colour the photograph gives up to the overlay. Overlay glass
     colours what is behind it; it does not replace it. Every view sets its own value:
     where the kise hue already agrees with the frame (the blue and the snow) it can
     sit high, and where it fights the frame (the warm coasts, Kyoto's autumn) it has
     to come down or the photograph goes monochrome and stops being a photograph. */
  --tint: 0.34;

  /* The light a cut face catches, top edge to bottom. Slight by design — the contrast
     that makes a name legible should come from the tint the surrounding sheet still
     carries, not from bleaching the letterforms into lit type. */
  --wash-top: rgba(255, 255, 255, 0.17);
  --wash-bottom: rgba(255, 255, 255, 0.04);

  /* The fully ground facet — the brightest a cut face goes, where the wheel took the
     overlay away completely. It is the whole chromatic system's other end: every
     coloured surface here is a mix between this and the live kise, and the percentage
     is literally how far the wheel went. Used bare only where a face is fully clear:
     the rail item you are standing in, and a caption credit under the cursor. */
  --facet-lit: #FFFFFF;

  /* The sheet reads heavier than the ground it lies on, so it is its own value rather
     than an alpha of --ground. Kept as components so the plate gradient can vary only
     the thickness: rgb(var(--sheet-black) / 0.80). */
  --sheet-black: 4 6 10;

  /* Small type over arbitrary photography needs its own ground. These are the two
     weights that do it — captions sit inside the sheet, the wordmark on top of it. */
  --shadow-caption: 0 1px 12px rgb(0 0 0 / 0.7);
  --shadow-mark: 0 1px 14px rgb(0 0 0 / 0.85);

  --gutter: clamp(1.15rem, 4.2vw, 4.25rem);
  --chamfer: clamp(9px, 1.5vw, 20px);
  --measure: 44ch;

  /* One easing token for the whole build. */
  --ease: cubic-bezier(0.16, 1, 0.3, 1);

  color-scheme: dark;

  /* The colophon publishes its own timeline so the standing chrome can retire
     against it; the rail and the mark belong to the sheet, not to the ground. */
  timeline-scope: --end;
}

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

/* Nothing on these two may take a transform, filter or containment: the plates are
   fixed to the viewport and either would trap them in a new containing block. */
html { background: var(--ground); }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: 'Archivo', ui-sans-serif, system-ui, sans-serif;
  font-variation-settings: 'wdth' 96;
  font-weight: 400;
  font-size: clamp(0.95rem, 0.34vw + 0.88rem, 1.08rem);
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

.ja {
  font-family: 'Zen Kaku Gothic New', ui-sans-serif, sans-serif;
  font-weight: 400;
  letter-spacing: 0.22em;
}

/* --------------------------------------------------------------------------
   Focus and skip
   -------------------------------------------------------------------------- */

:focus-visible {
  outline: 2px solid color-mix(in oklab, var(--facet-lit) 72%, var(--kise));
  outline-offset: 3px;
}

.skip {
  position: fixed;
  top: 0.6rem;
  left: 0.6rem;
  z-index: 90;
  padding: 0.75em 1.2em;
  background: var(--ground);
  color: var(--ink);
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  transform: translateY(-180%);
  transition: transform 0.22s var(--ease);
}
.skip:focus-visible { transform: none; }

/* --------------------------------------------------------------------------
   The plates — the world rewritten from above.
   Each view's photograph is fixed to the viewport and descends into place as its
   section arrives, so a new view lands over the last one instead of cutting.
   -------------------------------------------------------------------------- */

.view {
  position: relative;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: clamp(4.5rem, 11vh, 8rem) var(--gutter) clamp(1.1rem, 3vh, 2rem);
  view-timeline-name: --v;
  view-timeline-axis: block;
}

.view__plate {
  position: fixed;
  inset: 0;
  z-index: 0;
  display: block;
  /* Colour before pixels: the overlay is on screen while the photograph loads. */
  background: color-mix(in oklab, var(--kise) 38%, var(--ground));
  opacity: 0;
}

/* With neither scroll timelines nor JavaScript, one photograph still stands behind
   the whole piece rather than nine of them stacked. */
.view--open .view__plate { opacity: 1; }

.view__plate img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--focus, 50% 50%);
  /* Part of the overlay, not a filter applied for its own sake: the sheet is dark
     glass, so it costs the photograph light as well as colour. */
  filter: brightness(0.72) contrast(1.06) saturate(0.94);
}

/* The kise layer — colour laid across the whole sheet, then the weight of the
   sheet itself: leaded glass is heaviest where it is thickest, so the field goes
   down towards black at top and bottom and keeps its light through the middle.
   This is also what holds the captions and the mark at contrast over any frame. */
.view__plate::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgb(var(--sheet-black) / 0.80) 0%,
    rgb(var(--sheet-black) / 0.18) 28%,
    rgb(var(--sheet-black) / 0.20) 54%,
    rgb(var(--sheet-black) / 0.66) 84%,
    rgb(var(--sheet-black) / 0.94) 100%
  );
}

/* A second pass in `color` blend does the actual tinting; the layer above does the
   weight. Kept apart because one blend mode cannot do both jobs well. */
.view__plate::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  background: var(--kise);
  mix-blend-mode: color;
  opacity: var(--tint);
}

/* The plate descends into place, holds for its whole screen, then is struck once the
   next one has fully covered it. Striking it matters: nine full-viewport plates each
   carrying a blended colour layer would otherwise all stay live and composited by the
   time you reach the ninth view. */
@keyframes plate-descend {
  0%   { opacity: 0; visibility: hidden; transform: translate3d(0, -12%, 0) scale(1.07); }
  1%   { opacity: 0; visibility: visible; transform: translate3d(0, -12%, 0) scale(1.07); }
  46%  { opacity: 1; visibility: visible; transform: none; }
  90%  { opacity: 1; visibility: visible; transform: none; }
  100% { opacity: 0; visibility: hidden; transform: none; }
}

@supports (animation-timeline: view()) {
  .view__plate {
    animation: plate-descend linear both;
    animation-timeline: --v;
    animation-range: cover 0% cover 100%;
  }
}

/* Fallback driver where a browser has no scroll timelines. Same two states. */
.no-tl .view__plate {
  transform: translate3d(0, -12%, 0) scale(1.07);
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
}
.no-tl .view__plate.is-on { opacity: 1; transform: none; }

/* --------------------------------------------------------------------------
   The cut — place names ground through the overlay to the clear photograph
   -------------------------------------------------------------------------- */

/* A name that breaks across lines breaks into elements, not <br>. Accessible-name
   computation concatenates text nodes and contributes nothing for a <br>, so
   "Nine<br>Views" was announced as one word. */
.cut__line { display: block; }

.cut {
  position: relative;
  z-index: 1;
  margin: 0;
  max-width: 15ch;
  font-size: clamp(2.6rem, 11vw, 8.75rem);
  font-variation-settings: 'wdth' 118;
  font-weight: 250;
  line-height: 0.88;
  letter-spacing: -0.032em;
  text-wrap: balance;
  color: var(--ink);
}

@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .cut {
    /* Registered with the fixed plate: same cover geometry, same focal point, so the
       letterforms show the photograph exactly where it already is. */
    /* A clear facet catches a little more light than the sheet around it. This wash
       is deliberately slight: the contrast that makes the cut legible is meant to
       come from the tint the surrounding sheet still carries, not from bleaching the
       letterforms until they read as lit type instead of as glass. */
    background-image:
      linear-gradient(180deg, var(--wash-top), var(--wash-bottom)),
      image-set(var(--cut-a) type('image/avif'), var(--cut-w) type('image/webp'));
    background-size: auto, cover;
    background-position: 0 0, var(--focus, 50% 50%);
    background-attachment: scroll, fixed;
    background-repeat: repeat, no-repeat;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    /* Clear glass: inside the cut the sheet's colour and weight are gone, so the
       photograph comes back brighter and more saturated than the field around it.
       That step is what makes the letterform read as ground away rather than
       tinted — it is the whole mechanic, so it is stated firmly. */
    /* The facet: a hairline catching light along the cut face, then the weight of
       the sheet underneath it. */
    /* The facet edge is a bright line, not a light source. Held down deliberately:
       over a featureless fill — open sky, still water — a strong stroke and a light
       drop-shadow stop reading as a ground edge and start reading as neon. */
    -webkit-text-stroke: 1px color-mix(in oklab, var(--facet-lit) 34%, var(--kise));
    filter:
      saturate(1.2) brightness(1.1) contrast(1.06)
      drop-shadow(0 1px 0 color-mix(in oklab, var(--facet-lit) 12%, var(--kise)))
      drop-shadow(0 18px 38px rgba(0, 0, 0, 0.66));
  }
}

/* Not a place name. This view has no place, and the heading has to read as a
   statement about the record rather than as another name in the series — so it drops
   a step, loses the display width, and keeps the sentence case it was written in. */
.cut--absent {
  max-width: 20ch;
  /* The floor clears 24px with room to spare. At 1.55rem it landed on 24.8px — the exact
     line where WCAG stops treating text as large and the required contrast steps from
     3:1 to 4.5:1, which this variant's deliberately reduced wash cannot meet. */
  font-size: clamp(1.7rem, 4.2vw, 3.1rem);
  font-variation-settings: 'wdth' 96;
  font-weight: 300;
  line-height: 1.04;
  letter-spacing: -0.018em;
  /* An absence must not be the loudest thing on the page. It sits a step under the
     place names in scale and in light, or it starts announcing itself as the subject. */
  --wash-top: rgba(255, 255, 255, 0.07);
  --wash-bottom: rgba(255, 255, 255, 0.02);
  opacity: 0.8;
}

.cut--title {
  max-width: 9ch;
  font-size: clamp(3.2rem, 13.5vw, 11rem);
  font-variation-settings: 'wdth' 112;
  font-weight: 220;
  letter-spacing: -0.042em;
  margin-bottom: clamp(1.25rem, 3vh, 2.25rem);
}

/* Pacing: the name changes corner as you descend, so nine screens do not land
   identically. The caption never moves — it is the one fixed line of the piece, and
   the photograph keeps whichever half of the frame the name has left alone. */
.view:nth-of-type(even) { justify-content: flex-start; }
.view:nth-of-type(even) .cut { align-self: flex-end; text-align: right; }
.view:nth-of-type(even) .caption { margin-top: auto; }

/* --------------------------------------------------------------------------
   Panels — cut faces. Chamfered, bevelled, never rounded.
   -------------------------------------------------------------------------- */

.panel {
  position: relative;
  z-index: 1;
  padding: 1px; /* the bevel is the parent showing through at the edge */
  clip-path: polygon(
    var(--chamfer) 0, 100% 0,
    100% calc(100% - var(--chamfer)), calc(100% - var(--chamfer)) 100%,
    0 100%, 0 var(--chamfer)
  );
  /* Two lit facets and two dark ones, the way a ground edge catches a light source
     from one side only. The chamfers are where the bevel is widest and brightest. */
  background: linear-gradient(
    142deg,
    color-mix(in oklab, var(--facet-lit) 92%, var(--kise)) 0%,
    color-mix(in oklab, var(--facet-lit) 34%, var(--kise)) 14%,
    color-mix(in oklab, var(--kise) 62%, rgba(6, 9, 14, 0.9)) 46%,
    color-mix(in oklab, var(--kise) 70%, rgba(6, 9, 14, 0.9)) 70%,
    color-mix(in oklab, var(--facet-lit) 58%, var(--kise)) 100%
  );
}

.panel__in {
  clip-path: inherit;
  padding: clamp(1.15rem, 2.4vw, 2rem) clamp(1.25rem, 2.6vw, 2.25rem);
  /* Kagome — the woven-basket lattice, one of the ground patterns a Kiriko wheel
     actually cuts. Three sets of parallel grooves at 60° to each other, held at the
     threshold of visibility so it reads as worked glass under raking light rather
     than as a texture laid on top. This is the cut field; it never crosses a
     photograph, only the faces that have been ground flat. */
  background-image:
    repeating-linear-gradient(60deg, transparent 0 13px, color-mix(in oklab, var(--facet-lit) 9%, transparent) 13px 14px),
    repeating-linear-gradient(-60deg, transparent 0 13px, color-mix(in oklab, var(--facet-lit) 9%, transparent) 13px 14px),
    repeating-linear-gradient(0deg, transparent 0 13px, color-mix(in oklab, var(--facet-lit) 6%, transparent) 13px 14px);
  background-color: color-mix(in oklab, var(--kise) 18%, rgba(6, 9, 14, 0.44));
  backdrop-filter: blur(30px) saturate(1.5) brightness(0.8);
  -webkit-backdrop-filter: blur(30px) saturate(1.5) brightness(0.8);
}

/* The opening reads land-first: the glass panel floats up in the empty sky, and the
   title is cut into the ground below it, where the photograph has something to show
   through the letterforms. */
.panel--open {
  order: -1;
  max-width: 34rem;
  margin-bottom: clamp(2.5rem, 9vh, 6.5rem);
}

.lede {
  margin: 0;
  font-size: clamp(1.02rem, 0.5vw + 0.92rem, 1.2rem);
  line-height: 1.5;
  text-wrap: pretty;
}

.note {
  margin: 0.9em 0 0;
  max-width: var(--measure);
  color: var(--ink-dim);
  font-size: 0.86em;
  line-height: 1.55;
  text-wrap: pretty;
}

/* --------------------------------------------------------------------------
   Captions — place, region, photographer. The only copy inside a view.
   -------------------------------------------------------------------------- */

.caption {
  position: relative;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.55em 1.5em;
  margin: clamp(1.25rem, 3.5vh, 2.5rem) 0 0;
  font-size: clamp(0.76rem, 0.28vw + 0.7rem, 0.86rem);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.caption__place {
  font-variation-settings: 'wdth' 88;
  font-weight: 500;
  color: var(--ink);
  text-shadow: var(--shadow-caption);
}
.caption__place .ja { text-transform: none; letter-spacing: 0.2em; }
.view--open .caption__place .ja { margin-left: 0.7em; }

.caption__region {
  color: var(--ink-dim);
  text-shadow: var(--shadow-caption);
}
.caption__region--none {
  font-style: italic;
  letter-spacing: 0.08em;
  text-transform: none;
}

.caption__by {
  color: color-mix(in oklab, var(--facet-lit) 80%, var(--kise));
  text-decoration: none;
  border-bottom: 1px solid color-mix(in oklab, var(--facet-lit) 34%, var(--kise));
  padding-bottom: 0.15em;
  text-shadow: var(--shadow-caption);
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease);
}
.caption__by:hover { color: var(--facet-lit); border-bottom-color: var(--facet-lit); }

/* --------------------------------------------------------------------------
   Standing chrome
   -------------------------------------------------------------------------- */

.mark {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 8;
  padding: clamp(1rem, 2.5vh, 1.75rem) var(--gutter);
}

.mark__link {
  color: var(--ink);
  /* The label role, fixed at its documented size rather than fluid: at the low end the
     fluid version fell to 11.5px, which is under the floor this piece sets for standing
     chrome a recruiter has to read on a phone. */
  font-size: 0.78rem;
  font-variation-settings: 'wdth' 84;
  font-weight: 500;
  letter-spacing: 0.34em;
  text-decoration: none;
  text-shadow: var(--shadow-mark);
}

.rail {
  position: fixed;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  z-index: 8;
  /* Small type over arbitrary photography cannot hold contrast on its own, so the
     rail sits on its own chamfered dark face rather than floating on the frame. */
  padding: clamp(0.9rem, 1.6vw, 1.35rem) clamp(0.95rem, 1.8vw, 1.5rem);
  clip-path: polygon(
    var(--chamfer) 0, 100% 0, 100% 100%, 0 100%, 0 var(--chamfer)
  );
  background: rgb(var(--sheet-black) / 0.62);
  backdrop-filter: blur(18px) saturate(1.3);
  -webkit-backdrop-filter: blur(18px) saturate(1.3);
}

.rail__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.68em;
  text-align: right;
}

.rail__list a {
  display: block;
  color: var(--ink-dim);
  font-size: 0.78rem;
  font-variation-settings: 'wdth' 80;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  transition: color 0.3s var(--ease);
}
.rail__list a:hover { color: var(--ink); }
.rail__list li.is-here a {
  color: var(--facet-lit);
  /* the lit facet marks where you are */
  text-shadow: 0 0 16px color-mix(in oklab, var(--facet-lit) 60%, var(--kise));
}

/* Below the rail's comfortable width it becomes a column of cut marks rather than
   disappearing — the phone is this audience's first device and it should not be the
   one left without an index. */
@media (max-width: 62rem) {
  /* The marks take a lane of their own; nothing in a view runs under them. */
  .view { padding-right: calc(var(--gutter) + 2.6rem); }
  .rail { padding: 0.75rem 0.5rem; }
  /* 24px targets on a 28px pitch. The mark stays 0.7rem — the cut square is the right
     size for the world; it is the finger that needed room, so the target grew around it
     rather than the mark growing with it. */
  .rail__list { gap: 4px; }
  .rail__list a {
    position: relative;
    width: 24px;
    height: 24px;
    overflow: hidden;
    text-indent: 3rem;
    white-space: nowrap;
  }
  .rail__list a::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 0.7rem;
    height: 0.7rem;
    margin: -0.35rem 0 0 -0.35rem;
    background: color-mix(in oklab, var(--ink) 34%, transparent);
    clip-path: polygon(35% 0, 100% 0, 100% 65%, 65% 100%, 0 100%, 0 35%);
    transition: background-color 0.3s var(--ease);
  }
  .rail__list li.is-here a::before {
    background: var(--facet-lit);
    box-shadow: 0 0 12px color-mix(in oklab, var(--facet-lit) 70%, var(--kise));
  }
}

/* Standing chrome belongs to the sheet. When the colophon arrives the sheet has
   ended, so the rail and the mark go with it rather than sitting on top of type. */
@keyframes chrome-retire {
  from { opacity: 1; visibility: visible; }
  to   { opacity: 0; visibility: hidden; }
}

@supports (animation-timeline: view()) {
  .rail, .mark {
    animation: chrome-retire linear both;
    animation-timeline: --end;
    animation-range: entry 0% entry 32%;
  }
}

.no-tl .rail, .no-tl .mark { transition: opacity 0.4s var(--ease), visibility 0.4s; }
.no-tl.at-end .rail, .no-tl.at-end .mark { opacity: 0; visibility: hidden; }

/* --------------------------------------------------------------------------
   Colophon — the sheet ends and the ground shows
   -------------------------------------------------------------------------- */

.colophon {
  position: relative;
  z-index: 2; /* covers the last fixed plate */
  view-timeline-name: --end;
  view-timeline-axis: block;
  background: var(--ground);
  border-top: 1px solid color-mix(in oklab, var(--ink) 16%, transparent);
  padding: clamp(3.5rem, 11vh, 7.5rem) var(--gutter) clamp(3rem, 8vh, 5rem);
}

.colophon__grid {
  display: grid;
  gap: clamp(2.5rem, 5vw, 4rem);
  max-width: 82rem;
  margin: 0 auto;
}

@media (min-width: 54rem) {
  .colophon__grid { grid-template-columns: 1.2fr 1fr 0.9fr; }
}

/* The facet grammar carries through to the close. Without this the built world stops
   one section before the page does, and the colophon reads as a different site. */
.colophon__block h2 {
  position: relative;
  margin: 0 0 1.3em;
  padding-bottom: 0.75em;
  border-bottom: 1px solid color-mix(in oklab, var(--ink) 16%, transparent);
  color: color-mix(in oklab, var(--facet-lit) 72%, var(--kise));
  font-size: 0.78rem;
  font-variation-settings: 'wdth' 86;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

.colophon__block p {
  margin: 0 0 1em;
  max-width: var(--measure);
  color: var(--ink-dim);
  text-wrap: pretty;
}
.colophon__block p:last-child { margin-bottom: 0; }

.colophon__by {
  color: var(--ink);
  font-size: clamp(1.3rem, 2vw, 1.6rem);
  font-variation-settings: 'wdth' 104;
  font-weight: 450;
  letter-spacing: -0.02em;
  margin-bottom: 0.15em;
}

.colophon__studio {
  font-size: 0.78rem;
  font-variation-settings: 'wdth' 84;
  letter-spacing: 0.3em;
  margin-bottom: 1.7em;
}

.credits, .links { list-style: none; margin: 0; padding: 0; }

.credits li {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3em 1em;
  justify-content: space-between;
  padding: 0.62em 0;
  border-bottom: 1px solid color-mix(in oklab, var(--ink) 10%, transparent);
  font-size: 0.84rem;
}
.credits li span { color: var(--ink-dim); }

/* Each section heading's rule ends on a cut rather than a square stop. */
.colophon__block h2::after {
  content: '';
  position: absolute;
  right: 0;
  bottom: -1px;
  width: 0.62rem;
  height: 0.62rem;
  background: color-mix(in oklab, var(--facet-lit) 58%, var(--kise));
  clip-path: polygon(100% 0, 100% 100%, 0 100%);
}

.links { display: grid; gap: 0.6em; margin-bottom: 1.7em; }

.links a, .credits a {
  color: var(--ink);
  text-decoration-color: color-mix(in oklab, var(--ink) 40%, transparent);
  text-underline-offset: 0.24em;
  text-decoration-thickness: 1px;
  transition: text-decoration-color 0.25s var(--ease);
}
.links a:hover, .credits a:hover { text-decoration-color: color-mix(in oklab, var(--facet-lit) 82%, var(--kise)); }

/* --------------------------------------------------------------------------
   Narrow screens
   -------------------------------------------------------------------------- */

@media (max-width: 40rem) {
  .cut { max-width: none; }
  .view:nth-of-type(even) .cut { align-self: stretch; text-align: left; }
  .caption { gap: 0.45em 1.15em; }

  /* A phone crop of a landscape frame is mostly sky unless it is told otherwise;
     the opening in particular needs the town under the mountain, not the air above it. */
  .view--open { --focus: 56% 58%; }
  .cut--title { font-size: clamp(3.4rem, 17vw, 6rem); }

  /* A name is physically smaller here, so the same wash gives it less body, and with
     the facet edge held down the fill has to carry the letterform on its own or the
     name hollows out into an outline. */
  .cut { --wash-top: rgba(255, 255, 255, 0.44); --wash-bottom: rgba(255, 255, 255, 0.18); }
  .cut--absent { --wash-top: rgba(255, 255, 255, 0.14); --wash-bottom: rgba(255, 255, 255, 0.05); }
}

/* `background-attachment: fixed` is ignored on iOS, where the cut falls back to a
   photographic fill framed to the letterforms instead of to the viewport. That is a
   graceful degradation on one engine, so it is not turned off for every narrow
   screen — Android and a narrowed desktop window keep the registered cut. */

/* --------------------------------------------------------------------------
   Reduced motion — the sheet steps instead of descending. Nothing is hidden.
   -------------------------------------------------------------------------- */

@keyframes plate-step {
  0%   { opacity: 0; visibility: hidden; }
  1%   { opacity: 0; visibility: visible; }
  30%, 92% { opacity: 1; visibility: visible; }
  100% { opacity: 0; visibility: hidden; }
}

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

@media (prefers-reduced-motion: reduce) {
  @supports (animation-timeline: view()) {
    .view__plate { animation-name: plate-step; }
  }
  .no-tl .view__plate { transform: none; transition: opacity 0.001s; }
  .no-tl .view__plate.is-on { transform: none; }
  .skip, .caption__by, .rail__list a, .rail__list a::before, .links a, .credits a { transition: none; }
}
