/* One physical monitor crosses the hero/process boundary. The two invisible
   anchors provide responsive geometry while the same media node stays mounted. */
.portal-placeholder {
  visibility: hidden !important;
  pointer-events: none !important;
  transform: none !important;
}
.has-shared-portrait #story-machine {
  visibility: hidden;
  transform: none !important;
}
.js .portal-monitor.is-shared {
  position: fixed;
  z-index: 8;
  right: auto;
  bottom: auto;
  margin: 0;
  opacity: 1;
  display: flex;
  flex-direction: column;
  transition: none;
  pointer-events: none;
  will-change: transform;
}
.js .portal-monitor.is-shared .monitor-screen {
  flex: 1 1 auto;
  min-height: 0;
  height: auto;
  aspect-ratio: auto;
  /* The guest page inside scales with the screen. */
  container-type: size;
}
.is-shared .monitor-top,
.is-shared .monitor-bottom {
  flex: 0 0 auto;
}

/* ---- One card, three shapes: monitor (story), phone (Keep), frame (themes).
   Written by continuity.js: --frame (phone bezel, 0..1), --phone (guest page
   layout; unwinds in the handoff), --guest (page details), --chrome (monitor
   bars), --bezel (px), --worlds-morph (handoff into the gallery). ---- */
.js .portal-monitor.is-shared {
  --pad0: 12px;
  padding: calc(
    (var(--pad0) + (var(--bezel, 10px) - var(--pad0)) * var(--frame, 0)) *
      (1 - var(--worlds-morph, 0))
  );
  border-width: calc((1 - var(--worlds-morph, 0)) * 1px);
  background: color-mix(in srgb, #151515 calc(var(--ink, 0) * 100%), #e8e8e5);
  border-color: color-mix(
    in srgb,
    #151515 calc(var(--ink, 0) * 100%),
    #59595960
  );
}
/* Without color-mix() the bezel keeps the paper card colour (still a phone by
   its shape, notch and guest page). */
@supports not (color: color-mix(in srgb, red 50%, blue)) {
  .js .portal-monitor.is-shared {
    background: #e8e8e5;
    border-color: #59595960;
  }
}
.is-shared .monitor-top,
.is-shared .monitor-bottom {
  --bar-a: 5px;
  --bar-b: 12px;
  max-height: calc(var(--chrome, 1) * 35px);
  opacity: var(--chrome, 1);
  overflow: hidden;
}
.is-shared .monitor-top {
  padding-top: calc(var(--chrome, 1) * var(--bar-a));
  padding-bottom: calc(var(--chrome, 1) * var(--bar-b));
}
.is-shared .monitor-bottom {
  padding-top: calc(var(--chrome, 1) * var(--bar-b));
  padding-bottom: calc(var(--chrome, 1) * (var(--bar-a) - 1px));
}
@media (max-width: 760px) {
  .js .portal-monitor.is-shared {
    --pad0: 9px;
  }
  .is-shared .monitor-top,
  .is-shared .monitor-bottom {
    --bar-b: 9px;
  }
}
@media (max-height: 600px) and (min-width: 600px) {
  .is-shared .monitor-top,
  .is-shared .monitor-bottom {
    --bar-a: 3px;
    --bar-b: 7px;
  }
}
/* The media slides into the guest page's video box (3:4, like the real
   microsite video) as the phone forms. */
.is-shared .monitor-screen > :is(img, video),
.chapter-still .still-phone-media {
  top: calc(var(--phone, 0) * 16%);
  left: calc(var(--phone, 0) * 6%);
  width: calc(100% - var(--phone, 0) * 12%);
  height: calc(100% - var(--phone, 0) * 45.8%);
  border-radius: calc(var(--phone, 0) * 4.5%) / calc(var(--phone, 0) * 3.4%);
}
.is-shared .monitor-scan,
.is-shared .monitor-reticle {
  opacity: calc(0.4 * (1 - var(--phone, 0)));
}
/* Capture is the original photo, in its natural colour. */
.capture-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ---- The mini guest page (mirrors the real microsite: event logo, the film,
   Download video / Download photo). Decorative; the chapter copy carries the
   meaning. Positions are shares of the 9:19.5 screen. ---- */
.guest-page {
  position: absolute;
  inset: 0;
  visibility: hidden;
  background:
    radial-gradient(70% 34% at 100% 0%, #ffb34a1f, transparent 72%),
    radial-gradient(70% 34% at 0% 100%, #57a9ff1c, transparent 72%), #f2f2ef;
  color: #151515;
}
.guest-page > * {
  position: absolute;
  opacity: var(--guest, 0);
}
.guest-notch {
  top: 1.5%;
  left: 35%;
  width: 30%;
  height: 3.1%;
  border-radius: 999px;
  background: #151515;
}
.guest-logo {
  top: 7.6%;
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 2.2cqw;
  font:
    600 max(8px, 7.4cqw) / 1 "Space Grotesk",
    var(--font-display);
  letter-spacing: -0.075em;
  white-space: nowrap;
}
.guest-logo svg {
  width: 6.6cqw;
  height: 6.6cqw;
}
.guest-logo b {
  font-weight: 500;
  color: #585858;
}
.guest-button {
  left: 6%;
  right: 6%;
  height: 6%;
  display: grid;
  place-items: center;
  border-radius: 2.6cqw;
  background: #151515;
  color: #f2f2ef;
  font: 600 max(8px, 4.3cqw) / 1 var(--font-body);
  white-space: nowrap;
}
.guest-logo + .guest-button {
  top: 73.4%;
}
.guest-button + .guest-button {
  top: 81.4%;
}
.guest-home {
  bottom: 1.4%;
  left: 33%;
  width: 34%;
  height: 0.75%;
  border-radius: 999px;
  background: #151515;
}

/* ---- Keep: the QR tile beside the phone ---- */
/* It overlaps the bezel only, never the guest page's buttons. */
.is-shared .delivery-card {
  left: calc(100% - var(--bezel, 10px) - 6px);
  right: auto;
  bottom: 3%;
}
.is-shared #story-pixels {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.is-shared .capture-guides,
.is-shared .story-scan,
.is-shared .story-play {
  opacity: 0;
}
.has-shared-portrait .journey {
  border-top-color: transparent;
}
.has-shared-portrait .journey-header,
.has-shared-portrait .journey-copy,
.has-shared-portrait .journey-rail {
  opacity: var(--arrival, 0);
  transform: translateY(var(--arrival-shift, 24px));
}
/* Decorations leave with the chapter copy (no orphans during the handoff). */
.has-shared-portrait .journey-halo,
.has-shared-portrait .journey-cross {
  opacity: calc(var(--arrival, 0) * var(--exit-opacity, 1));
}
/* The keepsake label belongs above the shared monitor, without lifting the
   whole journey section above the header or the page's navigation. */
.has-shared-portrait .delivery-card {
  z-index: 10;
}
/* Semantic headings keep a stable accessible name. Only decorative ink changes. */
.cipher-word {
  display: inline-block;
  white-space: nowrap;
}
.cipher-cell {
  position: relative;
  display: inline-block;
}
.cipher-measure {
  visibility: hidden;
  white-space: pre;
}
.cipher-ink {
  position: absolute;
  inset: 0;
  white-space: pre;
}
.portal-heading h1 > .hero-word {
  display: inline-block;
  position: relative;
  white-space: nowrap;
}
.portal-heading h1 > .hero-word:not(.hero-word--outline) {
  font-size: 1em;
  letter-spacing: inherit;
  color: var(--ivory);
  -webkit-text-stroke: 0;
}
#hero-title {
  pointer-events: auto;
}
.hero-word:before,
.hero-word:after {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  opacity: 0;
  pointer-events: none;
  -webkit-text-stroke: 0;
}
.hero-word:before {
  color: #ff8080;
}
.hero-word:after {
  color: #8199ff;
}
.js #hero-title.is-glitching .hero-word:before {
  animation: signal-coral 0.52s steps(1, end) both;
}
.js #hero-title.is-glitching .hero-word:after {
  animation: signal-blue 0.52s steps(1, end) both;
}
@keyframes signal-coral {
  0%,
  100% {
    opacity: 0;
    transform: none;
    clip-path: inset(0 0 100%);
  }
  12% {
    opacity: 0.8;
    transform: translate(-5px, 0);
    clip-path: inset(18% 0 60%);
  }
  36% {
    opacity: 0.65;
    transform: translate(4px, 1px);
    clip-path: inset(62% 0 21%);
  }
  58% {
    opacity: 0.7;
    transform: translate(-3px, 0);
    clip-path: inset(37% 0 48%);
  }
  80% {
    opacity: 0;
  }
}
@keyframes signal-blue {
  0%,
  100% {
    opacity: 0;
    transform: none;
    clip-path: inset(0 0 100%);
  }
  17% {
    opacity: 0.75;
    transform: translate(5px, 0);
    clip-path: inset(53% 0 28%);
  }
  42% {
    opacity: 0.7;
    transform: translate(-4px, -1px);
    clip-path: inset(20% 0 68%);
  }
  66% {
    opacity: 0.65;
    transform: translate(3px, 0);
    clip-path: inset(74% 0 12%);
  }
  84% {
    opacity: 0;
  }
}
.motion-paused .hero-word:before,
.motion-paused .hero-word:after {
  animation: none !important;
  opacity: 0 !important;
}
@media (prefers-reduced-motion: reduce) {
  .hero-word:before,
  .hero-word:after {
    animation: none !important;
    opacity: 0 !important;
  }
}

.has-shared-portrait .portal-bottom,
.has-shared-portrait .portal-coordinate,
.has-shared-portrait .portal-orbit {
  opacity: var(--departure, 1);
}
.has-shared-portrait .portal.is-departing .portal-bottom {
  visibility: hidden;
}
.cipher-ink[data-noise] {
  overflow: hidden;
}

/* ---- Hero -> process: the night dissolves into paper (driven by --exit) ---- */
.pixel-horizon {
  position: absolute;
  z-index: 3;
  left: 0;
  right: 0;
  top: calc(var(--horizon-h, 400px) * -0.6);
  width: 100%;
  height: var(--horizon-h, 400px);
  max-width: none;
  opacity: 0;
  pointer-events: none;
}
.origin-hero {
  --exit: 0;
  --parallax: 0.35;
  --dim: 0.6;
}
@media (prefers-reduced-motion: no-preference) {
  html:not(.motion-paused) .origin-copy {
    translate: 0 calc(var(--exit) * var(--parallax) * -40vh);
    opacity: calc(1 - var(--exit) * 1.45);
  }
  html:not(.motion-paused) .origin-visual {
    scale: calc(1 - var(--exit) * 0.06 * var(--dim));
  }
  /* A dark veil instead of filter: brightness() (no extra render surface
     over the WebGL canvas). */
  html:not(.motion-paused) .origin-visual::after {
    content: "";
    position: absolute;
    z-index: 9;
    inset: 0;
    background: #04070f;
    opacity: calc(var(--exit) * 0.6 * var(--dim));
    pointer-events: none;
  }
  html:not(.motion-paused) .origin-footer {
    opacity: calc(1 - var(--exit) * 3.3);
  }
}
[tabindex="-1"]:focus {
  outline: none;
}

/* ---- Chapter headlines: line-masked swaps ---- */
.journey-chapter h3 .line {
  display: block;
  overflow: clip;
  padding: 0.02em 0.06em 0.1em;
  margin: -0.02em -0.06em -0.1em;
}
.journey-chapter h3 .line > span {
  display: block;
  will-change: transform;
}

/* ---- Pixel seams between the lower sections ---- */
.pixel-seam {
  position: relative;
  z-index: 1;
  height: 24px;
  margin: 0 var(--gutter, 0);
  pointer-events: none;
}
.pixel-seam canvas {
  display: block;
  width: 100%;
  height: 24px;
}

/* ---- Reveal on enter (JS adds .is-in; no-JS and reduced motion stay visible) ---- */
@media (prefers-reduced-motion: no-preference) {
  .js:not(.motion-paused) [data-reveal] {
    opacity: 0;
    transform: translateY(var(--reveal-d, 28px));
    transition:
      opacity 0.7s cubic-bezier(0.2, 0.7, 0.2, 1)
        calc(var(--i, 0) * var(--reveal-s, 0.09)),
      transform 0.9s cubic-bezier(0.2, 0.7, 0.2, 1)
        calc(var(--i, 0) * var(--reveal-s, 0.09)),
      clip-path 0.9s cubic-bezier(0.2, 0.7, 0.2, 1)
        calc(var(--i, 0) * var(--reveal-s, 0.09));
  }
  .js:not(.motion-paused) [data-reveal].is-in {
    opacity: 1;
    transform: none;
  }
  .js:not(.motion-paused) [data-reveal] h2 {
    clip-path: inset(0 0 100% 0);
    transition: clip-path 0.9s cubic-bezier(0.2, 0.7, 0.2, 1) 0.1s;
  }
  .js:not(.motion-paused) [data-reveal].is-in h2 {
    clip-path: inset(-10% -5% -10% -5%);
  }
}

/* ---- Browser chrome follows the page once the paper takes over ---- */
html.on-paper {
  scrollbar-color: #b5b5b0 #f2f2ef;
  color-scheme: light;
}
