/*
 * stage.css — the pinned 16:9 stage.
 *
 * The collage is laid out once, at 1920x1080, and never re-laid-out: a single
 * scale on .canvas maps that box onto whatever viewport is showing it, so the
 * composition is proportionally identical to the source PDFs everywhere.
 *
 * The background is Background.pdf — a square sheet of paper, drawn full-bleed
 * and `cover`, so it crops to whatever shape the viewport is. It covers the
 * viewport behind the stage and bleeds into the letterbox. There is nothing
 * below the pin any more to match it to: the page is one screen, and the
 * furniture that used to live under it is drawn over this sheet instead.
 *
 * --ground is the flat color behind the paper, set to the paper's own mean so
 * that anything showing through — overscroll, a failed image load, the moment
 * before it decodes — is the same color rather than a flash of white. It is
 * the sRGB color Preview shows for Background.pdf, not the numbers a raw
 * rasterize happens to produce; see tools/build-assets.py on color
 * management, and `npm run ground`, which checks it against Preview.
 * --paper-veil is 1 because the supplied sheet is already the color and the
 * texture that is wanted; drop it below 1 and the ground shows through in
 * proportion. `npm run ground` re-measures both and checks the live page.
 */

:root {
  --ground: #eab46b;
  --paper-veil: 1;
  --ink: #2a2723;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font: 400 clamp(1rem, 0.9rem + 0.4vw, 1.15rem)/1.6 ui-serif, Georgia, "Times New Roman", serif;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* --- the pinned stage ---------------------------------------------------- */

.pin-track { position: relative; }

.pin {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
}

/* The flat ground, and the paper scan over it. Two layers rather than one so
   the texture can carry an opacity of its own — and so the very slow drift on
   .paper moves the grain without moving the color. */
.ground {
  position: absolute;
  inset: 0;
  background: var(--ground);
}

.paper {
  position: absolute;
  inset: 0;
  opacity: var(--paper-veil);
  background: center / cover no-repeat;
  background-image: image-set(url("../img/paper.webp?v=591dca34") type("image/webp"),
                              url("../img/paper.jpg?v=591dca34") type("image/jpeg"));
  will-change: transform;
}

.canvas {
  /* Clip to the 16:9 design box, not to the viewport. Elements waiting to
     rise, or already swept out, sit outside 1920x1080; on any viewport that
     is not exactly 16:9 they would otherwise be visible in the letterbox. */
  overflow: hidden;
  position: absolute;
  left: 50%;
  top: 50%;
  width: 1920px;
  height: 1080px;
  margin: -540px 0 0 -960px;
  transform: scale(var(--k, 1));
  transform-origin: 50% 50%;
}

.shell { opacity: 0; transition: opacity 420ms ease; }
.shell.is-ready { opacity: 1; }

/* --- collage elements ---------------------------------------------------- */

/* .el carries translation and the idle drift; .fit carries scale and clip.
   Keeping them apart lets the drift rotate about an element's own center
   while the layout transform stays a clean, interpolable pair of numbers. */
.el {
  position: absolute;
  inset: 0;
  pointer-events: none;
  will-change: transform;
}

.fit {
  position: absolute;
  left: 0;
  top: 0;
  transform-origin: 0 0;
  will-change: transform, clip-path;
}

.fit picture,
.fit img {
  display: block;
  width: 100%;
  height: 100%;
  user-select: none;
  -webkit-user-drag: none;
}

/* --- the three buttons --------------------------------------------------- */

/* .el is stage-sized, so a button must stay transparent to the pointer and
   let its .fit box - the paper itself - take the clicks. Otherwise whichever
   button paints last swallows every click on the page. */
.el--button {
  pointer-events: none;
  cursor: pointer;
  display: block;
  text-decoration: none;
}

.el--button .fit {
  pointer-events: auto;
  transition: filter 180ms ease;
}

.el--button:hover .fit { filter: brightness(1.05) drop-shadow(0 6px 14px rgb(0 0 0 / 0.18)); }
.el--button:active .fit { filter: brightness(0.98); }

.el--button:focus-visible { outline: none; }
.el--button:focus-visible .fit {
  outline: 4px solid var(--ink);
  outline-offset: 10px;
}

/* --- the page furniture ---------------------------------------------------

   .after used to be the section BELOW the pin — a second screen you scrolled to
   once the collage had finished. It is inside .pin now and arrives over the top
   of frame 7, so its layout is no longer this file's business: it is page
   furniture, and site.css owns it. See "the landing page" there.

   What follows from that here: the document is exactly as tall as .pin-track,
   because nothing is stacked underneath it any more. --------------------------- */

/* --- accessibility ------------------------------------------------------- */

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  left: 1rem; top: -4rem;
  z-index: 10;
  padding: 0.6rem 1rem;
  background: #fff;
  color: var(--ink);
  border-radius: 2px;
  transition: top 160ms ease;
}
.skip-link:focus { top: 1rem; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .paper { will-change: auto; }
  .shell { transition: none; }
}
