/* =============================================================================
   PIBITOS MEDIA — scene.css
   The edit-bay push-in intro. Loaded only by /scene/ for now.

   Nothing in this file is required for the page to be correct. The overlay is
   built by scene.js and only after it has decided the visitor is eligible, so
   with no JS, reduced motion, or a narrow viewport the markup below never
   renders and the page is simply the page.

   Layers are positioned in viewport coordinates by JS on load and on resize --
   those are layout writes, and they happen twice, never per frame. Everything
   the scroll drives is transform and opacity only.
   ============================================================================= */

.scene {
  position: fixed;
  inset: 0;
  z-index: 400;
  overflow: hidden;
  /* Literal first. If --ink ever fails to resolve -- scene.css arriving before
     style.css from cache, say -- var() alone collapses to transparent and the
     browser canvas shows through as white. */
  background: #0F0F0E;
  background: var(--ink, #0F0F0E);
  contain: layout paint;    /* the intro can never reflow the page beneath it */
}

/* Each layer is absolutely placed by JS. transform-origin is set to the screen's
   centre so the push converges on the monitor rather than on the viewport, which
   is what makes it read as a camera move instead of a zoom. */
.scene__layer,
.scene__screen {
  position: absolute;
  transform-origin: 0 0;
  will-change: transform;
  backface-visibility: hidden;
  /* style.css:190 sets `img, svg, video { max-width: 100% }` as a reset, and
     max-width clamps a box no matter what `width` says -- including an inline
     one. It held the room layer to the viewport's 1920 when the cover fit needs
     2122, leaving a 101px strip of bare canvas down the right-hand edge. */
  max-width: none;
  max-height: none;
}

.scene__fondo   { z-index: 1; object-fit: cover; }
.scene__screen  { z-index: 2; overflow: hidden; background: #050505; }

/* objetos ships as JPEG colour + a separate 8-bit mask rather than one RGBA PNG:
   at 2560px that is 360kb instead of 2774kb, and the mask stays lossless so the
   cut-out edges do not fringe. */
.scene__objetos {
  z-index: 3;
  background-size: 100% 100%;
  background-repeat: no-repeat;
  -webkit-mask-size: 100% 100%;
          mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
}

.scene__screen video,
.scene__screen img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* The monitor is curved and slightly off-axis. The rotation is tiny on purpose:
   enough to seat the screen inside the bezel, small enough that it reads as flat
   by the time the element has grown to fill the viewport. */
.scene__screen {
  transform-style: preserve-3d;
}

.scene__skip,
.scene__sound {
  position: fixed;
  z-index: 401;
  bottom: var(--pad-x, 1.25rem);
  padding: .55rem 1rem;
  border: 1px solid var(--ink-line-strong, #6B6860);
  border-radius: 999px;
  background: rgb(15 15 14 / .72);
  backdrop-filter: blur(10px);
  color: var(--bone, #F5F0E0);
  font: inherit;
  font-size: .8125rem;
  cursor: pointer;
}
.scene__skip { right: var(--pad-x, 1.25rem); }

/* Sits immediately left of Skip so the two read as one control pair. Its width
   is fixed rather than content-sized: the label swaps between Mute and Unmute,
   and a button that changes size under the cursor is a button you misclick. */
.scene__sound {
  right: calc(var(--pad-x, 1.25rem) + 6.5rem);
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  width: 6rem;
  justify-content: center;
}
.scene__sound svg { width: 15px; height: 15px; flex: 0 0 auto; }
.scene__sound .off { display: none; }
.scene__sound[aria-pressed="true"] .on  { display: none; }
.scene__sound[aria-pressed="true"] .off { display: block; }

.scene__skip:hover,
.scene__sound:hover { border-color: var(--amber, #EFA01E); }

/* cursor.js hides the native pointer (`cursor: none`) and draws its own at
   z-index 200 -- underneath this overlay at 400, which left the intro with no
   visible pointer at all and nothing to aim at Mute or Skip with. Lift it over
   the scene while the intro owns the screen. */
.scene-running .cursor { z-index: 402; }

/* Told in the page's own language: a timecode counting the intro out. */
.scene__tc {
  position: fixed;
  z-index: 401;
  left: var(--pad-x, 1.25rem);
  bottom: var(--pad-x, 1.25rem);
  margin: 0;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: .8125rem;
  letter-spacing: .04em;
  color: var(--amber, #EFA01E);
}

/* The lock.

   `overflow: hidden` on the root alone was not enough: a scroll offset could
   still be set on the document while the intro ran, and whatever was sitting
   there at the handoff became the half-scrolled page this rewrite exists to
   fix. Preventing scroll is a losing game -- so remove the scroll instead.

   With the body fixed to the viewport there is no overflow left to scroll:
   scrollHeight collapses to clientHeight and scrollY cannot be anything but 0,
   whatever generates the gesture. `main` is inert and hidden under the overlay,
   so the reflow this causes is never visible; it unwinds at release. */
.scene-running {
  overflow: hidden;
  scrollbar-gutter: stable;
}
.scene-running body {
  position: fixed;
  inset: 0;
  width: 100%;
  overflow: hidden;
}

/* The prompt. Centred by the grid rather than by a transform, so transform is
   left free for the motion. */
.scene__hint {
  position: fixed;
  inset: 0;
  z-index: 401;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 1.1rem;
  margin: 0;
  pointer-events: none;
  text-align: center;

  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: .8125rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--bone, #F5F0E0);
  text-shadow: 0 2px 18px rgb(0 0 0 / .85);

  opacity: 0;
  transform: translateY(12px);
  transition: opacity 1.15s ease, transform 1.15s cubic-bezier(.16, 1, .3, 1);
}
.scene__hint.is-in  { opacity: 1; transform: none; }
/* Leaves faster than it arrived: it has done its job the moment they scroll. */
.scene__hint.is-out {
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity .4s ease, transform .4s ease;
}

.scene__hint svg {
  width: 20px;
  height: 25px;
  color: var(--amber, #EFA01E);
}
.scene__hint.is-in svg { animation: hint-drift 2.1s cubic-bezier(.45, 0, .55, 1) infinite; }

/* Down, and unhurried -- the gesture the words are asking for. */
@keyframes hint-drift {
  0%, 100% { transform: translateY(-3px); opacity: .75; }
  50%      { transform: translateY(5px);  opacity: 1; }
}

/* Held back until the handoff so the swoosh is the first thing the real page
   does, not something that already ran behind the overlay. */
.scene-armed .loader { display: none; }

@media (prefers-reduced-motion: reduce) {
  .scene, .scene__skip, .scene__sound, .scene__tc, .scene__hint { display: none !important; }
}
