/* GENERATED by build-web.js — edit board.css / common.js instead. */
:root {
  --paper:#fbfbf9; --ink:#1c1a16; --gray:#524e45;
  --red:#a8402f; --blue:#365f9e; --green:#41703f; --faint:#cbc2a9;
}
/* ---- the wall (board.css) ---- */
/* =====================================================================
   board.css — THE WALL. The style layer for web/index.html, the landing
   page: every edition pinned to one surface you fly a camera over.

   Consumed exactly the way web.css is: build-web.js reads this file and
   writes it into web/board.css behind a generated `:root` block carrying
   common.js's COLORS. So the ink here is the deck's ink — paper, ink,
   gray, red, faint all arrive as custom properties and are NEVER
   re-typed as hex. Only the two board-surface colours below are new,
   because the board is the one thing in the series that is not paper.

   UNITS. Everything inside #world is in WORLD pixels — the same
   1080-wide artboard the deck and the sheets are measured in. The camera
   scales it, so a "world px" is whatever the current zoom says it is.
   The chrome outside #world (#hud, #back) is in screen px and does not
   scale, because it belongs to the viewer, not to the wall.

   THE ROLL (round 37). A sheet's world rect is the LIVE PAGE'S FULL
   HEIGHT — for Nº1 that is 11640px against 1080px of width, roughly a
   1:10.8 ribbon. A wall of 1:10.8 ribbons cannot be framed: fitting four
   of them on screen puts each one at ~40px wide. So a sheet has two
   lengths and one geometry:

       .sheet   the world rect. Full height, always. The camera reads
                only this, so flying never has to re-measure anything.
       .paper   the visible length. `--head` (one deck page, 1350px) at
                wall zoom; `--h` (the whole page) once the sheet opens.

   The paper is clipped, never re-laid-out — the mounted iframe keeps a
   fixed `--h` height the entire time, so the live page's viewport (and
   therefore its own layout) never changes underneath the reader. What
   animates is the clip. The sheet un-rolls down the wall.
   ===================================================================== */

:root {
  /* the board surface — a shade darker than the sheets, so paper reads as
     paper sitting ON something. That difference is where the depth is. */
  --board: #e8e3d8;
  --board-deep: #ddd6c7;

  /* one deck page. The wall's unit of composition: a sheet at rest is
     exactly this tall, which is why the wall still looks like a wall. */
  --head: 1350px;
}

@font-face { font-family:'Caveat'; font-weight:700; src:url('assets/caveat-700.woff2') format('woff2'); font-display:swap; }
@font-face { font-family:'Kalam'; font-weight:700; src:url('assets/kalam-700.woff2') format('woff2'); font-display:swap; }
@font-face { font-family:'Shantell Sans'; font-weight:400 600; src:url('assets/shantellsans-var.woff2') format('woff2'); font-display:swap; }

* { box-sizing: border-box; margin: 0; padding: 0; }

html, body {
  height: 100%;
  overflow: hidden;              /* the camera scrolls, not the document */
  background: var(--board);
  color: var(--ink);
  font-family: 'Shantell Sans', 'Patrick Hand', cursive, sans-serif;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior: none;
}

/* ---- the surface ---------------------------------------------------- */

#viewport {
  position: fixed;
  inset: 0;
  cursor: grab;
  touch-action: none;            /* we own the gestures */
  background:
    radial-gradient(ellipse 120% 90% at 50% 40%,
      var(--board) 0%, var(--board-deep) 100%);
}
#viewport.grabbing { cursor: grabbing; }

#world {
  position: absolute;
  top: 0; left: 0;
  transform-origin: 0 0;
  will-change: transform;
}

/* the whole board tilts a couple of degrees toward the pointer — depth
   without a WebGL dependency. board.js suppresses the tilt once a sheet is
   filling the screen and adds .flat, which drops the 3D context entirely:
   a mounted iframe inside a perspective ancestor rasterises soft. */
#stage { perspective: 2400px; perspective-origin: 50% 45%; }
#stage.flat { perspective: none; }

/* ---- a sheet: the world rect ---------------------------------------- */
/* pointer-events live on .paper and .caption, not here. The rect is full
   height even at wall zoom, so without this a rolled-up sheet's invisible
   tail would swallow every click on the row beneath it. */

.sheet {
  position: absolute;
  left: var(--x); top: var(--y);
  width: var(--w); height: var(--h);
  pointer-events: none;
  z-index: 1;
  /* the hand that pinned it up was not a plotter. Straightens on open —
     a 0.7deg lean is charming across 1350px and silly across 11640. */
  transform: rotate(var(--tilt));
  transform-origin: 50% 0;
  transition: transform 420ms cubic-bezier(.22, .61, .36, 1);
}
.sheet.is-open { z-index: 6; transform: rotate(0deg); }

/* ---- a sheet: the visible paper ------------------------------------- */

.paper {
  position: absolute;
  left: 0; top: 0;
  width: 100%;
  height: var(--head);
  overflow: hidden;
  pointer-events: auto;
  background: var(--paper);
  /* one light source, upper-left, on every sheet. The shadow is the single
     most expensive-looking lever here — keep it soft, keep it identical. */
  box-shadow:
    0 2px 4px rgba(40, 34, 22, 0.06),
    0 12px 28px rgba(40, 34, 22, 0.10),
    0 40px 80px rgba(40, 34, 22, 0.10);
  transition: height 420ms cubic-bezier(.22, .61, .36, 1),
              box-shadow 240ms ease;
}
.sheet.is-open .paper {
  height: var(--h);
  box-shadow:
    0 3px 6px rgba(40, 34, 22, 0.07),
    0 18px 40px rgba(40, 34, 22, 0.13),
    0 60px 120px rgba(40, 34, 22, 0.13);
}

.paper::after {                  /* paper edge — a hair of warmth at the rim */
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  box-shadow: inset 0 0 0 1px rgba(28, 26, 22, 0.06);
}

/* far-zoom representation: a photograph of the live page's first 1350px,
   so the swap below is a dissolve between the same picture and not a cut
   between two different ones. */
.plate {
  position: absolute;
  left: 0; top: 0;
  width: 100%; height: var(--head);
  object-fit: cover;
  object-position: top center;
  display: block;
  transition: opacity 260ms ease;
}

/* near-zoom representation: the real page, mounted only for the sheet you
   opened. Height is pinned to the full world rect and never changes, so the
   iframe's viewport — and the page's own responsive layout inside it — is
   fixed for the whole visit. That is what makes the declared height in the
   markup a constant instead of a guess. */
.live {
  position: absolute;
  left: 0; top: 0;
  width: 100%; height: var(--h);
  border: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity 260ms ease;
}
.sheet.is-open.is-loaded .live { opacity: 1; pointer-events: auto; }
.sheet.is-open.is-loaded .plate { opacity: 0; }

/* unshipped editions — penciled in, not empty */
.sheet.is-planned .paper {
  background:
    repeating-linear-gradient(
      -45deg,
      rgba(203, 194, 169, 0.18) 0 2px,
      transparent 2px 22px),
    var(--paper);
  box-shadow: 0 2px 6px rgba(40, 34, 22, 0.05);
}

.stamp {
  position: absolute;
  left: 0; right: 0;
  top: 46%;
  text-align: center;
  font-family: 'Caveat', cursive;
  color: var(--faint);
  font-size: 92px;
  line-height: 1.1;
  user-select: none;
}
.stamp small {
  display: block;
  font-family: 'Kalam', cursive;
  font-size: 26px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--faint);
  margin-top: 18px;
}

/* the tape holding each sheet to the wall. It is a child of .sheet, not of
   .paper: the paper clips (that is how the roll works) and the tape hangs
   22px over the top edge, so inside the paper it would be sheared in half.
   z-index puts it over the plate, which is a later sibling subtree. */
.tape {
  position: absolute;
  z-index: 3;
  width: 190px; height: 46px;
  background: rgba(255, 248, 220, 0.62);
  box-shadow: 0 1px 3px rgba(40, 34, 22, 0.14);
  top: -22px; left: 50%;
  transform: translateX(-50%) rotate(-1.6deg);
  pointer-events: none;
}
.tape::before, .tape::after {   /* torn ends */
  content: '';
  position: absolute;
  top: 0; bottom: 0; width: 8px;
  background: inherit;
}
.tape::before { left: -6px;  clip-path: polygon(100% 0, 0 22%, 100% 44%, 0 68%, 100% 88%, 60% 100%, 100% 100%); }
.tape::after  { right: -6px; clip-path: polygon(0 0, 100% 22%, 0 44%, 100% 68%, 0 88%, 40% 100%, 0 100%); }

/* ---- caption under each sheet ---------------------------------------- */
/* Pinned to the HEAD, not to the rect: it belongs to the wall composition,
   and it gets out of the way the moment the sheet unrolls over it. */

.caption {
  position: absolute;
  left: 0; right: 0;
  top: var(--head);
  padding-top: 34px;
  text-align: center;
  pointer-events: auto;
  user-select: none;
  transition: opacity 240ms ease;
}
/* only a SHIPPED sheet unrolls over its own caption. A penciled one has
   nothing to unroll, and its caption is the only thing on it worth reading. */
.sheet.is-shipped.is-open .caption { opacity: 0; pointer-events: none; }

.caption a { text-decoration: none; color: inherit; display: block; }
.caption .no {
  font-family: 'Kalam', cursive;
  font-size: 30px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--gray);
}
.caption .name {
  font-family: 'Caveat', cursive;
  font-size: 86px;
  line-height: 1;
  margin-top: 6px;
}
.caption .status {
  font-family: 'Shantell Sans', cursive;
  font-size: 28px;
  color: var(--gray);
  margin-top: 10px;
}
.caption a:hover .name, .caption a:focus-visible .name { color: var(--red); }

/* ---- chrome (screen px — it belongs to the viewer, not the wall) ------ */

#hud {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
  padding: 18px 20px calc(18px + env(safe-area-inset-bottom));
  font-family: 'Kalam', cursive;
  font-size: 15px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gray);
  pointer-events: none;
  z-index: 20;
  transition: opacity 200ms ease;
}
#hud .key {
  border: 1px solid rgba(82, 78, 69, 0.35);
  border-radius: 3px;
  padding: 2px 7px;
  margin-right: 5px;
}
#hud.dim { opacity: 0; }

#back {
  position: fixed;
  top: 20px; left: 20px;
  z-index: 21;
  font-family: 'Kalam', cursive;
  font-size: 15px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gray);
  background: rgba(251, 251, 249, 0.9);
  border: 1px solid rgba(82, 78, 69, 0.25);
  border-radius: 4px;
  padding: 9px 14px;
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transition: opacity 180ms ease;
}
#back.show { opacity: 1; pointer-events: auto; }

/* the series word, top-right. Small: the wall itself is the headline. */
#brand {
  position: fixed;
  top: 20px; right: 22px;
  z-index: 20;
  text-align: right;
  pointer-events: none;
  transition: opacity 200ms ease;
}
#brand .word { font-family: 'Caveat', cursive; font-size: 34px; line-height: 1; }
#brand .tagline {
  font-family: 'Kalam', cursive;
  font-size: 12px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--gray); margin-top: 3px;
}
#brand.dim { opacity: 0; }

/* ---- no JS ----------------------------------------------------------- */
/* board.js drops .nojs off <html> on its first line. Without it the camera
   never runs, so the wall is meaningless — fall back to the plain list of
   links that is in the markup anyway (and is what a crawler reads). */

#fallback { display: none; }
.nojs #viewport, .nojs #hud, .nojs #back, .nojs #brand { display: none; }
.nojs, .nojs body { overflow: auto; height: auto; }
.nojs #fallback {
  display: block;
  max-width: 34rem;
  margin: 0 auto;
  padding: 3rem 1.5rem;
}
.nojs #fallback .word { font-family: 'Caveat', cursive; font-size: 3rem; line-height: 1; }
.nojs #fallback .tagline {
  font-family: 'Kalam', cursive; font-size: .8rem;
  letter-spacing: .14em; text-transform: uppercase; color: var(--gray);
  margin: .4rem 0 2rem;
}
.nojs #fallback li { list-style: none; margin: 0 0 1.4rem; }
.nojs #fallback .no {
  font-family: 'Kalam', cursive; font-size: .8rem;
  letter-spacing: .24em; text-transform: uppercase; color: var(--gray);
}
.nojs #fallback .name { font-family: 'Caveat', cursive; font-size: 2.2rem; line-height: 1; }
.nojs #fallback a { color: inherit; }

@media (prefers-reduced-motion: reduce) {
  #world, .sheet, .paper, .plate, .live, .caption { transition: none !important; }
}
