/* =============================================================================
   RAIL - the three workstations on one horizontal rail.

   Felix, 22/09/2026: each workstation is an object you go INTO and come back
   OUT of by the same way, and between two workstations the view SLIDES
   sideways, the current object leaving to the left while the next one arrives
   from the right with its own cartouche.

   So `#computer`, `#camera` and `#workbench` stop being three blocks stacked
   down the page: js/rail.js moves them into one `.rail-track`, side by side,
   inside a single pinned `.rail`. One master timeline drives the track and
   replays the scenes the existing modules already build.

   WHAT LIVES HERE. Only the shell: the pinned box, the track, the panels, and
   the handful of overrides the workstation sections need once they are 100vw
   boxes instead of page sections. Nothing of the drawings, the terminal or the
   corridor is redrawn: css/stations.css, css/terminal.css and css/tunnel.css
   keep every rule they had.

   WHEN IT DOES NOT RUN. `html.rail` is only set by js/rail.js on a desktop
   sized viewport with GSAP and motion allowed. Without it not one rule of this
   file applies and the page is exactly the stacked page it was.
   ============================================================================= */

/* -----------------------------------------------------------------------------
   1. The pinned box
   ----------------------------------------------------------------------------- */

/* THE BAND OF PAPER AT THE TOP OF THE SCREEN.

   Measured, 22/09 evening: with Lenis the page is scrolled from a rAF callback
   and Chrome presents the scrolled content one frame before it re-places what
   is anchored to the viewport. EVERY viewport anchored box lags, not only the
   pin: a plain `position: fixed` marker injected next to the rail lags by
   exactly the same amount (0 px at rest, 17 px at 120 px per frame, 53 px at
   600). Neither `pinType: transform` nor promoting the layer changes anything,
   because both the fixed box and the pin transform are written on the main
   thread. What shows in the lag is not the rail and not the panel (a red
   background on either of them does not tint the band) but the page canvas,
   which is paper.

   So the canvas is painted the colour of whatever the rail is showing:
   js/rail.js writes `--rail-back` from the panel on screen (its own background
   while the corridor is ink, the mix of the iris while the paper turns to
   ink). The lag is still there, one frame of it, but it is now ink on ink and
   nothing can be seen. */
html.rail body {
  background-color: var(--rail-back, var(--paper));
}

html.rail .rail {
  position: relative;
  width: 100%;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  /* The panels are paper; the seam between two of them must never show a
     strip of the page background. */
  background: var(--paper);
  /* The track is the only thing that moves: nothing inside may paint
     outside this box. */
  contain: paint;
}

/* The track is a frame of reference, not a layer. It used to be a 300vw flex
   row carrying one transform and a `will-change`, which is a composited
   texture three viewports wide, alive from the first paint of the page to the
   last (measured at 1990x1040: 5970 x 1040, 6.2 Mpx, never released). The
   three panels are stacked on the same box instead and each carries its own
   offset, so the only thing that can be rasterised is the one or two panels
   actually in frame. */
html.rail .rail-track {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

html.rail .rail-panel {
  position: absolute;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100%;
  margin: 0;
  padding: 0;
  border-top: 0;
  overflow: hidden;
  contain: layout paint;
  background: var(--paper);
  transform: translate3d(0, 0, 0);
}

/* A panel that is not on screen is not painted, not composited and not laid
   out. The class is written by the master when a step changes, never on every
   frame. */
html.rail .rail-panel.is-away {
  content-visibility: auto;
  contain-intrinsic-size: 100vw 100svh;
  visibility: hidden;
}

/* Promoted only while the view is actually sliding. */
html.rail .rail.is-travelling .rail-panel { will-change: transform; }

/* -----------------------------------------------------------------------------
   2. The workstation section, once it is a panel

   css/stations.css sizes `.poste-header.is-scene` at one screen and gives it
   its own paper; inside the rail the panel already IS that screen, so the
   header only has to fill it. The top margin that compensated the sticky
   topbar has nothing left to compensate: the panel starts at the top of the
   viewport by construction.
   ----------------------------------------------------------------------------- */

html.rail .poste.rail-panel {
  display: block;
  margin-top: 0;
  padding: 0;
  scroll-margin-top: 0;
}

/* The section's own decorative wash would sit behind the panel and drift. */
html.rail .poste.rail-panel::before { display: none; }

html.rail .rail-panel > .poste-header.is-scene {
  position: absolute;
  inset: 0;
  width: 100%;
  min-height: 0;
  height: 100%;
  margin: 0;
  /* The padding of css/stations.css is kept, minus the topbar allowance. */
  --stn-pad-top: clamp(0.75rem, 2.6vh, 2.25rem);
}

/* -----------------------------------------------------------------------------
   2b. What is entered THROUGH the drawing

   The session and the corridor are no longer blocks further down the page:
   they are a layer over the drawing of the panel they belong to, shown by the
   push that goes into it. Until that push starts they must paint nothing, and
   the only thing that shows them is the inline opacity js/terminal.js writes on
   `.term-scene` and the aperture js/tunnel.js writes on `--tun-clip`.
   ----------------------------------------------------------------------------- */

html.rail .rail-panel > .term.term--scene {
  position: absolute;
  inset: 0;
  z-index: 2;
  height: 100%;
  min-height: 0;
  margin: 0;
}

/* The ink guard of css/terminal.css exists to stop a hairline of paper showing
   at the seams while the block rises through the page. Nothing rises here, and
   a full screen of ink under the drawing is exactly what must not paint. */
html.rail .rail-panel > .term.term--scene::before { display: none; }

/* Hidden until the push into the laptop screen starts writing its own opacity
   (js/terminal.js, section 6c). `visibility` and not only `opacity`: a layer
   left at opacity 0 is still composited, and this one is a full viewport of
   ink plus the whole session block (measured: two layers of 2.1 and 1.3 Mpx
   alive through the whole of station 01). `visibility` keeps the layout, so
   js/terminal.js can still measure its own lines. */
html.rail .rail-panel > .term.term--scene > .term-scene { opacity: 0; }
html.rail .rail-panel > .term.term--scene:not(.is-open) > .term-scene { visibility: hidden; }

/* Same for the corridor: outside its own steps it paints nothing at all. */
html.rail .rail-panel > .tun.is-live:not(.is-open) .tun-scene { visibility: hidden; }

html.rail .rail-panel > .tun {
  position: absolute;
  inset: 0;
  z-index: 2;
  /* `.poste > *` caps the page content column at --maxw; the corridor is the
     whole panel. */
  max-width: none;
  width: 100%;
  margin: 0;
  padding: 0;
}

html.rail .rail-panel > .tun.is-live .tun-scene {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin-inline: 0;
  /* The paper of css/tunnel.css is what the corridor swallows on its way in.
     In the rail the panel below IS that paper, with the camera drawn on it, so
     a second sheet laid over it would simply hide the drawing: what shows
     through the iris is the ink layer, which is clipped, and nothing else. */
  background: transparent;
}

/* -----------------------------------------------------------------------------
   3. What came out of the rail

   The blocks that followed each workstation in the flow (the sober grid of
   the gallery, the workbench nomenclature) are moved out by js/rail.js and
   laid out after the rail, in that order. Both are hidden when their scene
   runs (below, and css/factory.css), so the factory hands over straight to
   the contact section. They keep every rule they had; they only need the
   page gutter the `.poste` around them used to give.
   ----------------------------------------------------------------------------- */

html.rail .rail-after {
  position: relative;
  display: block;
}

html.rail .rail-out {
  position: relative;
  padding: clamp(2.5rem, 7vh, 5rem) 0 clamp(2.5rem, 7vh, 5rem);
  border-top: 1px solid var(--line);
}

html.rail .rail-out:first-child { border-top: 0; }

/* The page content column `.poste > *` used to give these blocks. Only the
   direct children, so a block that breaks out on purpose (the sober gallery
   grid) keeps doing it. */
html.rail .rail-out > * {
  max-width: var(--maxw);
  margin-left: auto;
  margin-right: auto;
  padding-left: clamp(1.25rem, 4vw, 3rem);
  padding-right: clamp(1.25rem, 4vw, 3rem);
}

/* The three project files are written against the ink of the session: out of
   the session they need to carry their own. Same ink, same gutters, so the
   listing reads as the one the shell printed. */
html.rail .rail-out > .term-files {
  box-sizing: border-box;
  padding-top: clamp(1.5rem, 4vh, 2.75rem);
  padding-bottom: clamp(1.5rem, 4vh, 2.75rem);
  background: var(--term-ink);
  border-radius: 6px;
  /* The session set this on the block it pinned; out of it the listing has to
     carry the shell's own face, or the file rows read as body copy. */
  font-family: var(--font-mono);
  font-size: clamp(0.8rem, 0.45rem + 0.5vw, 1rem);
  line-height: 1.9;
}

/* The sober gallery grid is the fallback the corridor replaces: out of `.tun`
   the rule of css/tunnel.css that hides it no longer reaches it, so the same
   condition is written here. `html.tun-fx` is set by js/tunnel.js only when
   the corridor really runs, so a machine that gets the grid instead still gets
   it, after the rail. */
html.rail.tun-fx .rail-out[data-out="index"] .tun-flat { display: none; }
/* ...and the block that held only that grid goes with it, rather than an
   empty band between two rules. */
html.rail.tun-fx .rail-out[data-out="index"]:has(> .tun-flat:only-child) { display: none; }

/* The accent of the workstation the block belongs to, so a block still reads
   as part of its station. */
html.rail .rail-out[data-out="fiches"] { --poste-accent: var(--blue-deep); }
html.rail .rail-out[data-out="camera"],
html.rail .rail-out[data-out="index"] { --poste-accent: var(--brass); }
html.rail .rail-out[data-out="nomen"] { --poste-accent: var(--atelier); }

/* -----------------------------------------------------------------------------
   4. The travelling

   Nothing moves during a slide except `.rail-track`. The arriving sheet is
   held at its finished linework, very pale, until the slide is over: the class
   is toggled by js/rail.js at the two ends of the move, so no style change can
   land inside the scrub.
   ----------------------------------------------------------------------------- */

html.rail .rail.is-travelling .rail-panel {
  /* No drawing traces while the view is moving sideways. */
  pointer-events: none;
}
