/* ==========================================================================
   CRIT — transitions.
   One movement system: darkness compresses, the mark becomes a portal, the new
   room opens from the same point. Shared timing, shared lighting, shared grain.
   ========================================================================== */

/* The iris that swallows the entrance and hands over to the archive. */
.portal-veil {
  position: fixed;
  inset: 0;
  z-index: var(--z-transition);
  background: var(--void);
  clip-path: circle(150% at 50% 48%);
  pointer-events: none;
  visibility: hidden;
}

.portal-veil[data-active='1'] { visibility: visible; }
.portal-veil[data-closing='1'] { animation: portalClose 760ms var(--ease-in-out-quart) forwards; }
.portal-veil[data-opening='1'] { animation: portalOpen 880ms var(--ease-out-expo) forwards; }

@keyframes portalClose {
  from { clip-path: circle(150% at 50% 48%); }
  to   { clip-path: circle(3% at 50% 48%); }
}

@keyframes portalOpen {
  from { clip-path: circle(3% at 50% 48%); }
  to   { clip-path: circle(150% at 50% 48%); }
}

/* --------------------------------------------------------------- switching
   Profile to profile: the old room retracts (scale + dim + blur), the new room
   arrives from behind it. Never a full page load, always the same universe. */

.scene {
  transition:
    opacity 520ms var(--ease-out-expo),
    transform 620ms var(--ease-out-expo),
    filter 520ms var(--ease-out-expo);
}

.scene[data-state='leaving'] {
  opacity: 0;
  transform: scale(1.018);
  filter: blur(9px);
}

.scene[data-state='arriving'] {
  opacity: 0;
  transform: scale(0.988);
  filter: blur(7px);
}

.scene[data-state='settled'] {
  opacity: 1;
  transform: none;
  filter: none;
}

/* The environment layer crossfades more slowly than the type — that lag is
   what makes a room feel like it has walls. */
.pf-env {
  transition: opacity 780ms var(--ease-out-expo), transform 900ms var(--ease-out-expo);
}

.pf-env[data-state='leaving'] { opacity: 0; transform: scale(1.03); }
.pf-env[data-state='arriving'] { opacity: 0; transform: scale(0.99); }

/* ------------------------------------------------------------ shared element
   The fragment the visitor hovered becomes the room they walk into. */
.shared-fragment {
  position: fixed;
  z-index: var(--z-preview);
  pointer-events: none;
  overflow: hidden;
  will-change: transform, opacity, clip-path;
  background: linear-gradient(168deg, #0e0e12 0%, #060607 70%);
}

.shared-fragment img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* This is the person's own photograph on its way into the room, so it carries
     the room's grade and the person's colour. It used to open in grayscale(1)
     and desaturate mid-flight. */
  filter: contrast(1.05) brightness(0.92);
}

/* -------------------------------------------------------------- micro state
   Ambient statuses — tiny, quiet, part of the world rather than notifications. */

.status {
  position: fixed;
  left: 50%;
  bottom: clamp(1.2rem, 4vh, 2.4rem);
  z-index: var(--z-ui);
  transform: translate3d(-50%, 8px, 0);
  padding: 0.5rem 0.9rem;
  background: rgba(10, 10, 12, 0.86);
  backdrop-filter: blur(10px);
  border: 1px solid var(--line);
  font-family: var(--font-meta);
  font-size: 0.74rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--fg-soft);
  opacity: 0;
  pointer-events: none;
  transition: opacity 300ms var(--ease-out-expo), transform 300ms var(--ease-out-expo);
}

.status[data-on='1'] { opacity: 1; transform: translate3d(-50%, 0, 0); }