/* ============================================================================
   500x — THE ROW · four statues, then the headline
   ----------------------------------------------------------------------------
   The middle of the homepage: the marble hall the opening shot walks into,
   four statues standing in it, and the headline that flies out of it.

   With motion, assets/js/hall-row.js moves the figures and the headline into
   the film's own pin and draws them over the film's canvas — the hall they
   stand in is the frame the film came to rest on, not a second picture of it.
   The authored backdrop stays behind in #row, which is then hidden. Without
   JavaScript, or with reduced motion, that same markup *is* the page: the hall,
   then the four figures with their names, then the headline. Nothing here is
   generated at runtime, so nothing is lost when the script does not run.

   Depth is CSS perspective. `.rw-figures` and `.rw-headbox` each give their own
   children a 1400 px perspective (tools/row_data.py PERSPECTIVE, and the same
   number in hall-row.js), so a figure's `translateZ` is a real move down the
   hall: it shrinks, and it slides toward the vanishing point, which is set to
   where the hall's own arches converge.
   ========================================================================== */

@property --lit {
  syntax: '<number>';
  inherits: true;
  initial-value: 0;
}

:root {
  --rw-persp: 1400px;
  /* The hall's horizon -- where the floor's lines converge, and where the three
     tiny figures at the far end of the corridor stand. A figure moving back in z
     moves toward this point, so its feet rise along the floor and never above the
     horizon, which is the one thing that would make it float. */
  --rw-vanish: 50% 76%;
  --rw-stone: #6d5c46;
  --rw-serif: 'Cinzel', 'Trajan Pro', Georgia, serif;
}

/* ---------------------------------------------------------------- in the pin */
/* Once mounted, #row is an empty shell: its children live in the pin. */
#row.is-row { display: none; }

/* Over the film's canvas (z 1), its poster (2), its lights (3) and its dust (4),
   and under the engine's grain and vignette (6) so the whole shot is graded as
   one picture rather than a layer pasted on another. */
.mv-pin .rw-stage {
  position: absolute;
  inset: 0;
  z-index: 5;
  overflow: hidden;
  pointer-events: none;
  will-change: opacity;
}

/* ---- the row ------------------------------------------------------------ */
.mv-pin .rw-figures {
  position: absolute;
  inset: 0;
  z-index: 1;
  margin: 0;
  padding: 0;
  list-style: none;
  perspective: var(--rw-persp);
  perspective-origin: var(--rw-vanish);
  will-change: transform;
  /* hall-row.js reads this once per resize to decide whether to pan the camera. */
  --rw-pan-on: 0;
  --rw-unit: 1vh;
}

.mv-pin .rw-fig {
  position: absolute;
  left: var(--rw-left);
  bottom: calc(var(--b) * 1%);
  margin: 0;
  opacity: 0;
  transform: translate3d(-50%, -16px, -780px);
  transform-origin: 50% 100%;
  will-change: transform, opacity;
  --rw-left: calc(var(--x) * 1%);
}
.mv-pin .rw-fig img {
  display: block;
  width: auto;
  max-width: none;
  height: calc(var(--h) * var(--rw-unit));
}

/* The contact shadow belongs to the floor, not to the figure: an ellipse under
   the plinth, thrown to the right because the hall's daylight comes from the
   left. Soft stops rather than a blur filter — a filter inside an element whose
   transform changes every frame is a re-raster every frame. */
.mv-pin .rw-fig::after {
  content: '';
  position: absolute;
  left: 56%;
  bottom: 0;
  z-index: -1;
  width: 148%;
  height: calc(var(--h) * var(--rw-unit) * 0.10);
  transform: translate(-50%, 46%);
  background: radial-gradient(closest-side ellipse at 50% 50%,
              rgba(52, 40, 26, 0.40), rgba(52, 40, 26, 0.17) 46%, rgba(52, 40, 26, 0) 74%);
}
/* And the polished floor gives a little of the figure back. */
.mv-pin .rw-fig::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 100%;
  z-index: -2;
  width: 62%;
  height: calc(var(--h) * var(--rw-unit) * 0.22);
  transform: translateX(-50%);
  background: linear-gradient(rgba(236, 226, 208, 0.30), rgba(236, 226, 208, 0));
  opacity: 0.55;
}

.mv-pin .rw-name {
  position: absolute;
  left: 50%;
  top: calc(100% + 0.5vh);
  transform: translateX(-50%);
  margin: 0;
  opacity: 0;
  white-space: nowrap;
  font-family: var(--rw-serif);
  font-weight: 700;
  font-size: clamp(15px, 1.35vw, 25px);
  letter-spacing: 0.26em;
  text-transform: uppercase;
  /* Incised into the floor slab: dark ink, a lit lower edge and a dark upper one, over a
     soft bloom of the hall's own light — which is what lifts a small word off a marble
     floor that is already full of veining and reflections. */
  color: #3b2e1d;
  text-shadow:
    0 0 10px rgba(255, 251, 240, 0.95),
    0 0 22px rgba(255, 248, 232, 0.85),
    0 0 42px rgba(255, 246, 226, 0.6),
    0 1px 0 rgba(255, 253, 246, 0.9),
    0 -1px 0 rgba(36, 25, 12, 0.5);
  will-change: opacity;
}

/* ---- the headline ------------------------------------------------------- */
.mv-pin .rw-headbox {
  position: absolute;
  inset: 0;
  z-index: 3;
  perspective: var(--rw-persp);
  pointer-events: none;
}
.mv-pin .rw-head {
  position: absolute;
  left: 50%;
  top: 50%;
  width: min(84vw, 1120px);
  margin: 0;
  opacity: 0;
  text-align: center;
  transform: translate3d(-50%, -50%, -2450px);
  /* the six pieces move in z of their own, against the same perspective the head does */
  transform-style: preserve-3d;
  will-change: transform, opacity;
}

/* The headline is a picture of carved stone (tools/build_headline.py): a marble
   lintel with a moulded edge and the words cut into its face with the same
   chisel the film uses. Styled text could only ever be *like* stone -- a
   gradient inside the glyphs and shadows around them -- because a letter is
   engraved only if there is stone for it to be cut into. The h2 still carries
   the words; in the pin they are the plate's caption, kept for readers and
   crawlers and taken out of the picture.

   It is also what makes the flight free: one baked image is rastered once and
   composited at every scale, where a stack of text-shadows was re-rastered at
   each new scale as the stone came forward. */
.mv-pin .rw-title { margin: 0; }
.mv-pin .rw-title picture,
.mv-pin .rw-plate {
  display: block;
  width: 100%;
  height: auto;
  max-width: none;
}

/* ---- the six pieces the lintel comes apart into -------------------------- */
/* Placed by the fractions tools/build_headline.py measured when it cut them, so laid down they
   are the plate again and nothing gives away that it is in pieces. The centring is done with
   `left`/`top` rather than a translate, because hall-row.js owns `transform` on these -- it
   carries each piece's own spread and depth, and a centring translate here would be overwritten
   by the first frame it draws. */
.mv-pin .rw-piece {
  display: block;
  position: absolute;
  left: calc((var(--u) - var(--pw) / 2) * 100%);
  top: calc((var(--v) - var(--ph) / 2) * 100%);
  width: calc(var(--pw) * 100%);
  height: calc(var(--ph) * 100%);
  z-index: var(--pz);
  will-change: transform, opacity;
}
.mv-pin .rw-piece picture,
.mv-pin .rw-piece img {
  display: block;
  width: 100%;
  height: 100%;
}
/* Each cut is chipped on one side only, so the chipped piece has to sit over the straight one:
   underneath, the neighbour's clean edge covers the break and the slab comes apart along
   machined lines. `--pz` is that order, written with the pieces. */
@media (orientation: portrait) {
  .mv-pin .rw-piece {
    left: calc((var(--pu) - var(--ppw) / 2) * 100%);
    top: calc((var(--pv) - var(--pph) / 2) * 100%);
    width: calc(var(--ppw) * 100%);
    height: calc(var(--pph) * 100%);
  }
}
.mv-pin .rw-title .rw-line {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* The far end of the hall is in shade. The lintel carries that shade with it and
   sheds it as it comes forward, which is the light moving across the stone --
   and it is an opacity on one small box, so it costs the compositor and nothing
   else. --lit is driven by hall-row.js on .rw-head and inherits here.

   Masked by the plate's own alpha, not inset by a guessed percentage: the plate
   carries a transparent margin for its cast shadow, and a plain rectangle of
   shade over that margin read as a dark card behind the stone. */
.mv-pin .rw-head::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: calc(0.48 * (1 - var(--lit)));
  background: linear-gradient(118deg,
    rgba(28, 21, 12, 0.30) 0%, rgba(24, 18, 10, 0.48) 46%, rgba(18, 13, 7, 0.68) 100%);
  -webkit-mask-image: url('/assets/hall/headline-plate.webp');
  mask-image: url('/assets/hall/headline-plate.webp');
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

/* The authored page's headline, and the fallback if the plate never loads. */
.rw-title {
  margin: 0;
  font-family: var(--rw-serif);
  font-weight: 700;
  font-size: clamp(24px, 4.3vw, 62px);
  line-height: 1.16;
  letter-spacing: 0.055em;
  text-transform: uppercase;
  color: #5b4a34;
}
.rw-title .rw-line { display: block; }

/* ------------------------------------------- the film's chrome over pale stone */
/* film.css draws the rail, the skip link and the progress bar in white, for a
   film that is almost black. This hall is almost white, and white-on-marble is
   unreadable. hall-row.js puts `rw-lit` on <body> while the row is the movement
   on screen, and takes it off again at both ends. */
body.rw-lit .film-rail a { color: rgba(58, 46, 32, 0.66); }
body.rw-lit .film-rail a[aria-current="true"] { color: #2c2216; }
body.rw-lit .film-rail .dot { background: rgba(58, 46, 32, 0.34); }
body.rw-lit .film-rail a[aria-current="true"] .dot { background: #2c2216; }
body.rw-lit .film-skip {
  color: rgba(52, 41, 27, 0.82);
  border-color: rgba(52, 41, 27, 0.26);
  background: rgba(250, 245, 234, 0.62);
}
body.rw-lit .film-skip:hover { color: #241b10; border-color: rgba(52, 41, 27, 0.55); }
body.rw-lit .film-progress { background: #3f3222; }

/* ------------------------------------------------ a narrow screen: pan the row */
/* Four statues will not stand side by side at 390 px, and stacking them into a
   column throws away the depth that is the whole point. So the row stays a row,
   three viewports wide, and the camera pans along it: one or two figures are in
   frame at a time, at full size, and the names keep their own type size.
   hall-row.js reads --rw-pan-on to know it should pan. */
@media (max-aspect-ratio: 1 / 1), (max-width: 860px) {
  :root { --rw-vanish: 50% 74%; }
  .mv-pin .rw-figures {
    --rw-pan-on: 1;
    --rw-unit: 1vh;
    right: auto;
    width: 310vw;
  }
  .mv-pin .rw-fig {
    --rw-left: calc(var(--xp) * 1vw);
    bottom: calc((var(--b) + 5) * 1%);
  }
  .mv-pin .rw-name { font-size: 15px; letter-spacing: 0.2em; top: calc(100% + 0.8vh); }
  .mv-pin .rw-head { width: 88vw; }
  .mv-pin .rw-head::after {
    -webkit-mask-image: url('/assets/hall/headline-plate-p.webp');
    mask-image: url('/assets/hall/headline-plate-p.webp');
  }
  .rw-title { font-size: clamp(21px, 6.6vw, 40px); line-height: 1.2; }
}

/* ------------------------------------------- no JavaScript, or reduced motion */
/* The authored page, in order: the hall, the four figures with their names,
   then the headline. */
@media (prefers-reduced-motion: reduce) {
  #row .rw-back img { max-height: 62vh; object-fit: cover; }
}
#row {
  display: block;
  background: #efe7d8;
  color: #4a3c2b;
  padding-bottom: 96px;
}
#row .rw-back { display: block; margin: 0; }
#row .rw-back img,
#row .rw-back picture { display: block; width: 100%; height: auto; }
#row .rw-figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 44px 28px;
  margin: 0;
  padding: 72px 6vw 0;
  list-style: none;
}
#row .rw-fig { margin: 0; text-align: center; opacity: 1; transform: none; }
#row .rw-fig::before,
#row .rw-fig::after { display: none; }
#row .rw-fig img { display: block; width: auto; max-width: 100%; height: 42vh; margin: 0 auto; }
#row .rw-name {
  margin: 20px 0 0;
  font-family: var(--rw-serif);
  font-weight: 700;
  font-size: 20px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #5b4a34;
}
#row .rw-head { margin: 0; padding: 88px 6vw 0; text-align: center; }
#row .rw-head .rw-title { font-size: clamp(26px, 3.6vw, 56px); }
/* The six cut pieces are never part of the authored page. Without JavaScript, or with reduced
   motion, the lintel is one whole plate and these do not exist -- the selector above would
   otherwise catch them too and stack six slabs down the page. hall-row.js shows them only once
   it has moved the headline into the film's pin. */
#row .rw-piece,
.rw-piece { display: none; }
/* The lintel as a picture, with the words still under it as the heading -- the
   same shape the film's own headline takes on the static page. */
#row .rw-title > picture,
#row .rw-plate {
  display: block;
  width: 100%;
  max-width: 1120px;
  height: auto;
  margin: 0 auto 30px;
}
