/* Pure Shit — the dump. Live physics scene, not a scripted sequence.
   Positions are written by js/dump.js each frame via transform only. */

/* .dump is the anchor, not the scene: it reserves the space the pile rests
   in and tells the engine where the floor goes. It draws nothing itself. */
.dump {
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  /* Tall enough for the pile plus air above it, and no taller. --dump-min is
     the estimated settled height, written by js/dump.js from the posters
     themselves, so the pit tracks the pile rather than the window: a taller
     screen used to grow the pit while the pile stayed the same size, stranding
     the heap under half a screen of nothing. The 1.18 is the margin the
     estimate needs in practice — at --dump-min exactly, half the reloads had
     the pile bursting out of the top, which reads as a wall, and the fall is
     random so the slack is the point. min(62vh, 30rem) is the floor for the
     no-JS case, where --dump-min falls back to its own default.

     No viewport term sits in this max() any more. It used to, as
     `112vh - --dump-top`, and it was doing damage at both ends: --dump-top is
     most of the page, so the term came out hundreds of pixels NEGATIVE at every
     screen size and catalogue size tested — the min() then handed that back and
     capped a 500-title pit at 480px instead of the ~8000px the pile needs. And
     because it moved with vh, a mobile browser retracting its toolbar (+64px of
     vh) grew it by ~70px, which is exactly the 71px swing measured in this
     element's height as the toolbar came and went, dropping the settled pile a
     little further on every scroll. */
     The 30rem floor is a fixed length, not a share of the viewport. It only
     ever applies before the script has written --dump-min (or with JS off,
     where the fallback grid is showing anyway), and a viewport share there
     would put a unit that can move back into this property for no benefit. */
  height: max(30rem, calc(var(--dump-min, 30rem) * 1.18));
  /* Cancel the section's bottom padding: the pile rests on the page edge. */
  margin-bottom: calc(-1 * var(--tier-pad-b));
  touch-action: pan-y;
}

/* On a phone the tiers above eat most of the viewport, leaving the pit barely
   400px tall — the pile then fills it to the brim and reads as a wall rather
   than a heap. Let it run a little past the bottom of the screen so the heap
   has room to spread; the floor follows the element, so nothing else needs to
   change.
   --dump-min alone decides the height here, and the viewport term that used to
   sit beside it in a max() is gone. It never won: at every catalogue size from
   10 to 500 titles, on every phone geometry, `110vh - --dump-top` came out
   hundreds of pixels negative, because --dump-top is most of the page. What it
   did do was move. A mobile browser retracting its toolbar grows vh by ~64px,
   which grew that term by ~70px (1.10 x 64) — and the measured height of this
   element swung 757<->828 in lockstep with the toolbar, 71px, dragging the
   floor and the whole settled pile down with it on every scroll. A term that
   cannot win but can oscillate is pure liability.

   --dump-min's estimate is generous for the big phone posters: at full
   --dump-min a ~600px pile sat under ~350px of nothing. 0.738 trims it back to
   the pile plus the margin the random fall still needs. Little room is left
   below that: the tightest reloads settle ~10px under the top edge, so shaving
   further starts pushing the pile out of the frame. */
@media (max-width: 639px) {
  .dump {
    height: calc(var(--dump-min, 30rem) * 0.738);
  }
}

/* Phone laid on its side: the screen is short, not narrow, so a pit measured
   in vh collapses to a couple of hundred pixels and the pile bursts out of the
   top. Give it a floor in rem that the viewport height can't undercut. */
@media (max-height: 519px) {
  .dump {
    height: max(var(--dump-min, 26rem), 30rem);
  }
}

/* The bodies live here: a layer anchored to the page, not to the window, so
   the pile scrolls with its section and never shifts while you scroll. It
   spans the document from the top down to the floor, which lets anything the
   cursor flings upward travel far up the page instead of being clipped just
   above the heap.
   Sits behind the page content (z-index 0 against the nav's 50) and takes no
   pointer events, so text stays readable and clickable throughout. */
.dump__layer {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

/* Every falling body is absolutely placed at the origin; the engine
   writes translate()+rotate() into --x/--y/--r. */
.debris {
  position: absolute;
  top: 0;
  left: 0;
  /* The transform is written whole by js/dump.js each frame, as one inline
     declaration rather than three custom properties it would then be resolved
     from — a third of the writes and no variable resolution, which is the part
     of the frame that scales with the body count. Nothing to declare here:
     a body with no transform yet has not been placed, and js/dump.js writes
     one before the element is ever appended. */
  will-change: transform;
  user-select: none;
  -webkit-user-drag: none;
}

.debris--poster {
  border: 1px solid rgba(216, 171, 94, 0.14);
  background: #17120c;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.55);
}

.debris--poster img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Dulled: this is the reject pile. */
  filter: brightness(0.82) saturate(0.75);
  pointer-events: none;
}

/* Litter carries the wax red of rejection: this is the reject pile, so the
   colour belongs here. It keeps the seal red rather than the lighter ink the
   "La Fossa" heading takes — these are drawings, not type, so they are read by
   shape and carry no contrast minimum, and the darker red is what puts the
   pile a step behind the heading instead of competing with it. Held back a
   further 15%, the same value on every piece, since a random one per piece is
   what made the red read as muddy before. No brightness filter: on this
   near-black ground it would dull the red instead of just softening it. */
.debris--litter {
  color: var(--wax-seal-red);
  opacity: 0.85;
}

.debris--litter svg { width: 100%; height: 100%; display: block; }

/* Fallback: no JS. Show the rejects as a plain, still grid so the section
   still has content.

   There is no prefers-reduced-motion rule here on purpose — see js/dump.js:
   browsers that report `reduce` for every user were hiding the scene from
   everyone, and the pile is this section's content rather than decoration.
   docs/adr/0004-dump-ignores-reduced-motion.md has the reasoning. */
.dump__fallback { display: none; }

.dump--static .dump { display: none; }
.dump--static .dump__fallback { display: grid; }

.dump__fallback {
  grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr));
  gap: 1rem;
}

.dump__fallback .poster img { filter: brightness(0.82) saturate(0.75); }

