/* PhotonForgeAI intro (v4.6). Loaded as its own versioned file so the intro never
   depends on a cached copy of the shared page stylesheet. intro.js checks the
   sentinel below and skips the intro cleanly if this exact file did not apply. */
:root { --pf-tx-css: 46; }

/* Intro overlay and hologram-interface reveal (v3) */
.pf-tx-field {
  position: fixed;
  z-index: 10000;
  /* Match the intro clip's true black so the 3:4 video box is not a visible rectangle. */
  background: #000000;
  display: flex;
  align-items: center;
  justify-content: center;
  /* v4.6: fully opaque (v4.5 used 0.996, which let the page show through at
     up to 2-3/255). The box overhangs the viewport by 4px on every side and
     its black is clipped to the content box, which is exactly the viewport:
     every on-screen pixel is pure #000, but the off-screen 4px rim is clear,
     so Chrome does not mark the layer "contents opaque" and keeps drawing the
     page underneath (no occlusion culling). With a plain opaque cover the
     page's quads and filter passes were culled for the whole intro and their
     first draw at the reveal cost a 105-140 ms frame in testing. */
  inset: -4px;
  padding: 4px;
  background-clip: content-box;
  opacity: 1;
  will-change: opacity;
}
@media (max-width: 699px) {
  .pf-tx-field { align-items: flex-end; }
}
.pf-tx-clip {
  position: relative;
  width: min(100vw, calc(100dvh * 3 / 4));
  height: min(100dvh, calc(100vw * 4 / 3));
  max-width: 100vw;
  max-height: 100dvh;
  overflow: hidden;
  flex-shrink: 0;
}
.pf-tx-film {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center center;
  background: transparent;
  /* Softly dissolve the clip's bottom edge into the page black so the
     3:4 video box never shows a hard crop line across her legs. */
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 88%, transparent 100%);
          mask-image: linear-gradient(to bottom, #000 0%, #000 88%, transparent 100%);
  -webkit-mask-size: 100% 100%;
          mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
}
.pf-tx-film::-webkit-media-controls,
.pf-tx-film::-webkit-media-controls-enclosure {
  display: none !important;
}
/* Intro figure is the clean graded video: no flicker, dip, tint wash, or scanlines. */
.pf-tx-clip .holo-dip,
.pf-tx-clip .holo-tint,
.pf-tx-clip .holo-glow,
.pf-tx-clip .holo-scan { display: none !important; }
.pf-tx-pass {
  position: absolute;
  right: calc(1.25rem + 4px);
  bottom: calc(1.25rem + 4px);
  margin: 0;
  padding: 0.5rem 0.85rem;
  border: 0;
  background: transparent;
  color: #7F95A3;
  font-family: Inter, "Segoe UI Variable", "Segoe UI", system-ui, sans-serif;
  font-size: 0.9rem;
  letter-spacing: 0.04em;
  line-height: 1.2;
  cursor: pointer;
  z-index: 2;
}
.pf-tx-pass:hover { color: var(--signal); }
.pf-tx-pass:focus {
  outline: 2px solid #00C8D8;
  outline-offset: 3px;
}

/* Projector: hand cutout (above the HUD so fingers stay in front), plus the
   palm glow and light spill. z-index sits above the hologram panel (10001). */
.pf-tx-proj {
  position: fixed;
  inset: 0;
  z-index: 10002;
  pointer-events: none;
  visibility: hidden;
}
.pf-tx-proj.is-on { visibility: visible; }
.pf-tx-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.pf-tx-hand {
  /* Fades near-black pixels out of the hand cutout (v4.2 did this per frame
     in JS with getImageData; same formula, no GPU readback). */
  filter: url(#pf-tx-knock);
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  opacity: 0;
  pointer-events: none;
  will-change: opacity;
}
.pf-tx-orb { display: none !important;
  position: absolute;
  left: 0;
  top: 0;
  width: 150px;
  height: 150px;
  border-radius: 50%;
  transform: translate(-50%, -50%) scale(0.55);
  background: radial-gradient(
    circle,
    rgba(0, 200, 216, 0.7) 0%,
    rgba(0, 200, 216, 0.28) 28%,
    rgba(224, 134, 26, 0.08) 48%,
    transparent 70%
  );
  filter: blur(0.4px);
  opacity: 0;
  will-change: transform, opacity;
}
.pf-tx-spill { display: none !important;
  position: absolute;
  left: 0;
  top: 0;
  width: 200px;
  height: 130px;
  border-radius: 50%;
  transform: translate(-50%, -40%) scale(0.7);
  background: radial-gradient(
    ellipse,
    rgba(0, 200, 216, 0.4) 0%,
    rgba(0, 200, 216, 0.14) 42%,
    transparent 72%
  );
  opacity: 0;
  will-change: transform, opacity;
}

/* Hold one-shot / boot page animations until the intro finishes.
   Looping decorations also start fresh at reveal. No-JS undoes this in intro-noscript.css. */
html.pf-tx-hold .site-root * {
  animation-play-state: paused !important;
}

/* v4.5 hologram panel: a separate fixed layer holding a pre-rendered
   snapshot of the hero plus the cyan frame and brackets. The real page is
   never moved, scaled, transformed or given will-change. The panel is a
   compositor layer for its whole life (transform/opacity only). */
.pf-tx-panel {
  /* Overrides the [hidden] attribute: without this exact file the panel and
     its snapshot never render in the page. */
  display: block;
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: 10001;
  pointer-events: none;
  overflow: hidden;
  background: #000000;
  transform-origin: 0 0;
  transform: translate(0px, 0px) scale(1, 1);
  opacity: 0;
  visibility: hidden;
  will-change: transform, opacity;
  contain: strict;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.pf-tx-panel.is-on { visibility: visible; }
.pf-tx-panel picture { display: block; }
.pf-tx-snap {
  display: block;
  width: 100%;
  height: auto;
  -webkit-user-select: none;
  user-select: none;
}
/* Desktop: the page column is centred and identical at every width >= 752px,
   so the 1920-wide snapshot is shown 1:1, centred, top-aligned. */
@media (min-width: 752px) {
  .pf-tx-snap {
    height: 100%;
    object-fit: none;
    object-position: 50% 0;
  }
}
.holo-chrome {
  display: none;
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 3;
}
.holo-chrome.is-on { display: block; }
/* Bloom chrome is a thin cyan frame and corner brackets only.
   No tint, scanlines, travelling band, or RGB-split jitter. */
.holo-chrome-tint,
.holo-chrome-scan,
.holo-chrome-band { display: none !important; }
.holo-chrome-frame {
  position: absolute;
  inset: 0;
  border: 1px solid rgba(0, 200, 216, 0.7);
  box-sizing: border-box;
}
.holo-br {
  position: absolute;
  width: 16px;
  height: 16px;
  border-color: #00C8D8;
  border-style: solid;
  opacity: 0.75;
  box-sizing: border-box;
}
.holo-br--tl { top: 5px; left: 5px; border-width: 1px 0 0 1px; }
.holo-br--tr { top: 5px; right: 5px; border-width: 1px 1px 0 0; }
.holo-br--bl { bottom: 5px; left: 5px; border-width: 0 0 1px 1px; }
.holo-br--br { bottom: 5px; right: 5px; border-width: 0 1px 1px 0; }
.holo-chrome.is-jitter { animation: none; }

/* v4.4: the intro never toggles overflow or the scrollbar. The page keeps a
   permanent scrollbar (styles.css) and its full height during the intro, and
   intro.js blocks wheel/touch/key scrolling instead. So nothing about the
   page's width, height or scrollbar changes at the handoff. */
html.pf-tx-hold { overscroll-behavior: none; }
@media (prefers-reduced-motion: reduce) {
  .pf-tx-field, .pf-tx-proj, .pf-tx-panel, .holo-chrome { display: none !important; }
  .pf-tx-clip .holo-scan, .holo-chrome-band { animation: none; display: none; }
}
