/* ==========================================================================
   CRIT — cursor, hover preview, and the shared chrome.
   Desktop only. On touch the native interaction carries the whole experience.
   ========================================================================== */

@media (hover: hover) and (pointer: fine) {
  html.crit-has-cursor,
  html.crit-has-cursor * {
    cursor: none !important;
  }
}

.cursor {
  position: fixed;
  top: 0;
  left: 0;
  z-index: var(--z-cursor);
  pointer-events: none;
  opacity: 0;
  transition: opacity 320ms var(--ease-out-expo);
  mix-blend-mode: difference;
}

.cursor[data-on='1'] { opacity: 1; }

/* On a CPU compositor a live `difference` blend re-reads the backdrop beneath
   the cursor on every frame the pointer moves. The palette is near-black, so
   difference(white, dark) is indistinguishable from source-over, but dropping
   the blend removes a per-frame backdrop read — measured at ~10% of the pointer
   frame on a software compositor. */
[data-render='software'] .cursor {
  mix-blend-mode: normal;
}

/* --------------------------------------------------------------- reticle
   CRIT's cursor is a targeting reticle, not a dot: a weightless ring around a
   zero-lag pin, with four hairline ticks and one lit lead tick. The reticle
   rotates to the direction of travel, so the pointer always reads as aimed
   somewhere — the one gesture on the site that is unmistakably ours. */

/* The pin is the true pointer position, with no smoothing at all. */
.cursor__dot {
  position: absolute;
  top: 0;
  left: 0;
  width: 4px;
  height: 4px;
  margin: -2px 0 0 -2px;
  border-radius: 50%;
  background: var(--white);
  box-shadow: 0 0 9px rgba(255, 255, 255, 0.5);
  transition: transform 180ms var(--ease-out-expo), opacity 180ms linear;
}

/* The ring carries a little inertia — that is what makes it feel like an
   object with weight rather than a decoration. */
.cursor__ring {
  position: absolute;
  top: 0;
  left: 0;
  width: 30px;
  height: 30px;
  margin: -15px 0 0 -15px;
  border: 1px solid rgba(255, 255, 255, 0.42);
  border-radius: 50%;
  transition:
    width 340ms var(--ease-out-expo),
    height 340ms var(--ease-out-expo),
    margin 340ms var(--ease-out-expo),
    border-radius 340ms var(--ease-out-expo),
    border-color 340ms var(--ease-out-expo),
    background-color 340ms var(--ease-out-expo),
    opacity 340ms linear;
}

/* Rotated by the engine to the pointer's heading. */
.cursor__reticle {
  position: absolute;
  inset: 0;
  transform: rotate(0deg);
  transition: transform 140ms linear;
  will-change: transform;
}

.cursor__tick {
  position: absolute;
  background: rgba(255, 255, 255, 0.72);
}

/* North / south ticks. */
.cursor__tick[data-dir='n'],
.cursor__tick[data-dir='s'] {
  left: 50%;
  width: 1px;
  height: 5px;
  margin-left: -0.5px;
}

/* East / west ticks. */
.cursor__tick[data-dir='e'],
.cursor__tick[data-dir='w'] {
  top: 50%;
  width: 5px;
  height: 1px;
  margin-top: -0.5px;
}

.cursor__tick[data-dir='n'] { top: 2px; }
.cursor__tick[data-dir='s'] { bottom: 2px; }
.cursor__tick[data-dir='e'] { right: 2px; }
.cursor__tick[data-dir='w'] { left: 2px; }

/* The lead tick is longer and lit — it points where the pointer is going. */
.cursor__tick--lead {
  top: -4px !important;
  left: 50% !important;
  width: 1px !important;
  height: 8px !important;
  margin: 0 0 0 -0.5px !important;
  background: var(--accent, rgba(196, 214, 255, 0.95));
  box-shadow: 0 0 8px rgba(170, 196, 255, 0.75);
  border-radius: 1px;
}

.cursor__label {
  position: absolute;
  top: 0;
  left: 0;
  font-family: var(--font-meta);
  font-size: 0.68rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--white);
  text-shadow: 0 0 12px rgba(190, 202, 226, 0.34);
  white-space: nowrap;
  opacity: 0;
  transform: translate3d(0, -50%, 0);
  transition: opacity 240ms var(--ease-out-expo);
}

.cursor[data-state='person'] .cursor__ring {
  width: 62px;
  height: 62px;
  margin: -31px 0 0 -31px;
  border-color: rgba(255, 255, 255, 0.85);
  background: rgba(255, 255, 255, 0.045);
}

.cursor[data-state='person'] .cursor__dot { transform: scale(0.35); }
.cursor[data-state='person'] .cursor__label { opacity: 1; }

.cursor[data-state='media'] .cursor__ring {
  width: 48px;
  height: 48px;
  margin: -24px 0 0 -24px;
  border-radius: 9px;
  border-color: rgba(255, 255, 255, 0.7);
}

.cursor[data-state='link'] .cursor__ring {
  width: 36px;
  height: 36px;
  margin: -18px 0 0 -18px;
  border-color: rgba(255, 255, 255, 0.36);
}

.cursor[data-state='link'] .cursor__dot { opacity: 0; }

.cursor[data-state='back'] .cursor__ring {
  width: 46px;
  height: 46px;
  margin: -23px 0 0 -23px;
  border-color: rgba(255, 255, 255, 0.6);
}

.cursor[data-state='back'] .cursor__label { opacity: 1; }

.cursor[data-state='quiet'] .cursor__ring { opacity: 0; }
.cursor[data-state='quiet'] .cursor__dot { opacity: 0.35; }

.cursor[data-state='accent'] .cursor__ring { border-color: var(--accent, rgba(255, 255, 255, 0.6)); }

/* Pressed: the reticle closes a touch — a physical click, not a colour change. */
.cursor[data-down='1'] .cursor__ring { border-color: rgba(255, 255, 255, 0.95); }
.cursor[data-down='1'] .cursor__tick--lead { box-shadow: 0 0 14px rgba(180, 202, 255, 0.95); }

/* --------------------------------------------------------- hover preview */

/* Not a tooltip. A fragment of the person's world surfacing next to the
   pointer, with its own inertia, depth and crop. */
.preview {
  position: fixed;
  top: 0;
  left: 0;
  z-index: var(--z-preview);
  width: var(--preview-w, 30vmin);
  height: calc(var(--preview-w, 30vmin) * 1.34);
  pointer-events: none;
  opacity: 0;
  transform: translate3d(-50%, -50%, 0) scale(0.82);
  transform-origin: center center;
  transition: opacity 240ms var(--ease-out-expo);
  will-change: transform, opacity;
  perspective: 900px;
}

.preview[data-on='1'] { opacity: 1; }

.preview__frame {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: linear-gradient(168deg, #101014 0%, #070708 62%, #0b0b0e 100%);
  box-shadow:
    0 34px 80px -28px rgba(0, 0, 0, 0.92),
    0 0 0 1px rgba(255, 255, 255, 0.07);
  transform: rotate(var(--tilt, 0deg));
  transform-style: preserve-3d;
}

/* The frame edge is softened so the fragment feels like it is emerging from
   the dark rather than sitting on top of it. */
.preview__frame::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(120% 100% at 50% 40%, transparent 46%, rgba(5, 5, 6, 0.72) 100%);
  pointer-events: none;
}

.preview__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* The person's own photograph, at cursor size. It was the same picture as the
     portrait and was still printed in grayscale(1), so the room and the fragment
     that flies into it disagreed about whether the site was in colour. */
  filter: contrast(1.06) brightness(0.94);
  transform: scale(1.06);
}

/* A blurred copy behind the frame reads as light bleeding off the fragment. */
.preview__glow {
  position: absolute;
  inset: -12%;
  z-index: -1;
  background: rgba(180, 190, 210, 0.1);
  filter: blur(34px);
  border-radius: 2px;
}

.preview__meta {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1.65rem;
  display: flex;
  justify-content: space-between;
  gap: 0.7rem;
  font-family: var(--font-meta);
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--fg-soft);
  text-shadow: 0 0 14px rgba(178, 192, 220, 0.22);
  opacity: 0;
  transition: opacity 320ms var(--ease-out-expo) 120ms;
}

.preview[data-on='1'] .preview__meta { opacity: 1; }

/* When there is no uploaded portrait yet, the frame carries the index
   instead — the interaction never dies, the archive just stays abstract. */
.preview[data-fallback='1'] .preview__frame {
  display: grid;
  place-items: center;
  background:
    radial-gradient(120% 90% at 30% 20%, rgba(150, 158, 176, 0.14) 0%, transparent 60%),
    linear-gradient(200deg, #0e0e12 0%, #060607 70%);
}

.preview[data-fallback='1'] .preview__img { display: none; }

.preview__plate {
  position: absolute;
  inset: 0;
  opacity: 0.5;
  mix-blend-mode: luminosity;
}

.preview[data-fallback='1'] .preview__plate { opacity: 0.9; }

.preview__glyph {
  position: relative;
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 74, 'wght' 600;
  font-size: clamp(1.6rem, 3.4vmin, 3rem);
  letter-spacing: -0.03em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.16);
  -webkit-text-stroke: 1px rgba(255, 255, 255, 0.24);
}

.preview[data-fallback='1'] .preview__glyph { display: block; }

/* --------------------------------------------------------------- footer */

.archive__foot {
  padding-top: clamp(0.6rem, 2vh, 1.2rem);
  align-items: flex-end;
}

.footer-mark {
  display: flex;
  align-items: baseline;
  gap: 0.7rem;
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 78, 'wght' 560;
  font-size: clamp(0.78rem, 1.05vw, 0.95rem);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--fg-soft);
}

.footer-mark em {
  font-style: normal;
  color: var(--fg-faint);
}

.archive__foot .rule {
  width: clamp(80px, 16vw, 260px);
  margin-bottom: 0.5rem;
}