/* ══════════════════════════════════════
   Optical-zoom page transitions
   Shared by index.html and every case-study page (see js/transitions.js).

   Leaving:  JS builds a .zoom-layer, grows the clicked card's thumbnail from
             its own rect to full-screen, and pushes the old page toward the
             camera (scale + fade) about the card's centre.
   Arriving: the destination paints a .zoom-cover that already shows the same
             image full-screen (so the hand-off is seamless), then this file's
             keyframes let it drift on toward the viewer and dissolve.
   The arrival half is pure CSS on purpose — it must not depend on JS having
   loaded before first paint. The <head> script only sets the html class.
══════════════════════════════════════ */

.zoom-layer {
  position: fixed; inset: 0; z-index: 700;
  pointer-events: auto;          /* swallow a second click while flying */
  overflow: hidden;
}
.zoom-dim { position: absolute; inset: 0; background: #04060b; opacity: 0; }
.zoom-frame {
  position: fixed;
  overflow: hidden;
  background: var(--bg-2, #0b111d);
  border-radius: var(--radius-md, 18px);
  box-shadow: 0 0 0 1px rgba(160,225,255,.5), 0 0 60px 6px rgba(0,163,224,.55);
}
.zoom-frame img { width: 100%; height: 100%; object-fit: cover; display: block; }
.zoom-frame::after {              /* glass sheen that sweeps as it lands */
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(135deg, rgba(255,255,255,.28), rgba(255,255,255,0) 40%, rgba(0,163,224,.18));
}

/* Old page while it is being "pushed through": composited, so no reflow. */
.zoom-leaving { will-change: transform, opacity; }

/* ── Arrival on a case-study page ── */
.zoom-cover {
  position: fixed; inset: 0; z-index: 700;
  background: #04060b;
  pointer-events: none;
  display: none;
}
.zoom-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
html.zoom-arrive .zoom-cover {
  display: block;
  animation: zoom-cover-out 1.15s cubic-bezier(.5, 0, .15, 1) .12s both;
}
@keyframes zoom-cover-out {
  0%   { opacity: 1; transform: scale(1);    filter: blur(0); }
  35%  { opacity: 1; }
  100% { opacity: 0; transform: scale(1.35); filter: blur(14px); visibility: hidden; }
}

/* ── Arrival back on the index: fade up from the dark the case study left.
   Opacity only, on purpose: any transform on <main> during arrival skews the
   rects the browser uses for #hash scrolling (scrollIntoView reads the
   transformed box), so About/Work landed 130-260px off. ── */
html.zoom-return main.page,
html.zoom-return footer {
  animation: zoom-settle .9s var(--ease, cubic-bezier(.16,1,.3,1)) both;
}
@keyframes zoom-settle { from { opacity: 0; } to { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  html.zoom-arrive .zoom-cover { display: none; animation: none; }
  html.zoom-return main.page, html.zoom-return footer { animation: none; }
}
