/* Gallery tunnel (8 Oct 2026): CSS 3D corridor of her work. Loaded by /assets/js/tunnel.js.
   Segments fly from deep in the dark to just past the viewer; panels fade in like fog lifting. */
.tunnel { position: relative; height: clamp(280px, 50vh, 520px); overflow: clip; perspective: 520px; perspective-origin: 50% 50%;
  background: radial-gradient(60% 60% at 50% 50%, #1c130e, #0d0805 75%); border-radius: inherit; isolation: isolate; }
.tunnel::after { content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 2;
  background: radial-gradient(42% 42% at 50% 50%, rgb(13 8 5 / .95), transparent 70%), radial-gradient(120% 120% at 50% 50%, transparent 55%, rgb(13 8 5 / .7)); }
.tn-world { position: absolute; inset: 0; transform-style: preserve-3d; }
.tn-seg { position: absolute; left: 50%; top: 50%; width: 0; height: 0; transform-style: preserve-3d;
  --dur: calc(var(--tn-n) * 0.75s); --delay: calc(var(--i) * var(--dur) / var(--tn-n) * -1);
  transform: translateZ(calc(var(--tn-d) * (var(--i) - var(--tn-n) + 1.5)));
  animation: tn-fly var(--dur) linear var(--delay) infinite paused; }
.tunnel.tn-play .tn-seg, .tunnel.tn-play .tn-cell { animation-play-state: running; }
@keyframes tn-fly { from { transform: translateZ(calc(var(--tn-d) * (1.5 - var(--tn-n)))); } to { transform: translateZ(calc(var(--tn-d) * 1.5)); } }
.tn-cell { position: absolute; left: 0; top: 0; transform-style: preserve-3d;
  outline: 1px dashed rgb(210 165 120 / .22); outline-offset: -1px;       /* the corridor's saddle-stitched seams */
  animation: tn-fog calc(var(--tn-n) * 0.75s) linear calc(var(--i) * var(--tn-n) * 0.75s / var(--tn-n) * -1) infinite paused; }
/* 10 Oct: panels also fade out before they reach the viewer. At full opacity to the end, the nearest panels
   crossed the camera plane (drawn huge for a frame) and then vanished at once when the segment looped back:
   a flash about every 1.5 s, worst on wide screens where the segment depth outgrows the 520px perspective. */
@keyframes tn-fog { 0% { opacity: 0; } 35% { opacity: .35; } 70% { opacity: 1; } 84% { opacity: 1; } 92% { opacity: 0; } 100% { opacity: 0; } }
.tn-panel { position: absolute; inset: 3%; border-radius: 6px; overflow: hidden; box-shadow: 0 0 0 1px rgb(0 0 0 / .35), 0 8px 18px rgb(0 0 0 / .4); }
.tn-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tn-slab { background-image: url("/img/leather-light.webp"); background-size: 260px; background-blend-mode: multiply; box-shadow: inset 2px 2px 0 rgb(255 240 220 / .25), inset -3px -3px 6px rgb(0 0 0 / .35); }
.tn-slab::before { content: ""; position: absolute; inset: 7px; border: 1.5px dashed rgb(255 236 214 / .35); border-radius: 4px; }
.tn-natural { background-color: #d2a578; } .tn-saddle { background-color: #8a4d26; } .tn-rust { background-color: #a4532c; }
.tn-teal { background-color: #1f9e9a; } .tn-espresso { background-color: #3a2416; }
.tunnel.tn-still .tn-seg, .tunnel.tn-still .tn-cell { animation: none; }
.tunnel.tn-still .tn-cell { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .tn-seg, .tn-cell { animation: none !important; } }

/* The opening still (8 Oct 2026): three of her photos, fanned, until the corridor is built and its first photos
   decoded (tunnel.js adds .tn-built), so the panel never opens as an empty dark box. */
.tn-poster { position: absolute; inset: 0; z-index: 3; display: flex; align-items: center; justify-content: center; gap: 3%;
  pointer-events: none; transition: opacity .7s ease; }
.tn-poster img { width: min(24%, 210px); height: auto; aspect-ratio: 4 / 5; object-fit: cover; border-radius: 8px;
  box-shadow: 0 0 0 1px rgb(0 0 0 / .35), 0 14px 28px rgb(0 0 0 / .55); }
.tn-poster img:nth-child(1) { transform: rotate(-4deg) translateY(4%); }
.tn-poster img:nth-child(3) { transform: rotate(4deg) translateY(4%); }
.tunnel.tn-built .tn-poster { opacity: 0; }
@media (prefers-reduced-motion: reduce) { .tn-poster { transition: none; } }
