/* Panel entry reveals, image blur-reveal, attract loop motion, touch feedback. */

[data-reveal] {
  opacity: 0;
  transition:
    opacity 620ms var(--ease-out),
    transform 720ms var(--ease-out),
    filter 720ms var(--ease-out);
  transition-delay: var(--rd, 0ms);
  will-change: opacity, transform;
}
[data-reveal="up"]    { transform: translateY(38px); }
[data-reveal="down"]  { transform: translateY(-30px); }
[data-reveal="left"]  { transform: translateX(-46px); }
[data-reveal="right"] { transform: translateX(46px); }
[data-reveal="scale"] { transform: scale(0.955); }
[data-reveal="wipe"]  { clip-path: inset(0 100% 0 0); transition: clip-path 900ms var(--ease-out), opacity 400ms linear; }
[data-reveal].is-in { opacity: 1; transform: none; clip-path: inset(0 0 0 0); }

.blur-reveal { filter: blur(8px); opacity: 0.6; transition: filter 1100ms var(--ease-out), opacity 900ms var(--ease-out); }
.blur-reveal.is-in { filter: blur(0); opacity: 1; }

/* Attract loop: slow drift on both halves, out of phase. */
.kenburns { animation: drift 26s var(--ease-in-out) infinite alternate; transform-origin: 50% 45%; }
.kenburns--b { animation-duration: 32s; animation-delay: -9s; transform-origin: 42% 55%; }
@keyframes drift {
  from { transform: scale(1.04) translate3d(0, 0, 0); }
  to   { transform: scale(1.15) translate3d(-2.2%, -1.6%, 0); }
}

/* Light travelling down the seam between the two worlds. */
/* Light travelling down the seam, as a dash walking along the line. */
.seam__glow { animation: seamsweep 8.5s var(--ease-in-out) infinite; }
@keyframes seamsweep {
  from { stroke-dashoffset: 260; }
  to   { stroke-dashoffset: -1120; }
}

.touchcue__dot { animation: breathe 2.4s var(--ease-in-out) infinite; }
@keyframes breathe {
  0%, 100% { transform: scale(1); opacity: 1; }
  50%      { transform: scale(0.55); opacity: 0.45; }
}

.touchcue { animation: nudge 5s var(--ease-in-out) infinite; }
@keyframes nudge {
  0%, 86%, 100% { transform: translateX(0); }
  91%           { transform: translateX(9px); }
  95%           { transform: translateX(0); }
}

/* Attract stagger on load - driven by --rd set in markup order. */
.attract [data-reveal] { transition-duration: 900ms; }

/* Touch ripple - the only feedback a fingertip gets. */
.ripple {
  position: fixed;
  z-index: 999;
  width: 16px; height: 16px;
  margin: -8px 0 0 -8px;
  border-radius: 50%;
  border: 2px solid var(--accent-lift);
  pointer-events: none;
  animation: ripple 560ms var(--ease-out) forwards;
}
@keyframes ripple {
  from { transform: scale(1); opacity: 0.8; }
  to   { transform: scale(7); opacity: 0; }
}

/* Lazy image shimmer until decode completes. */
img[loading="lazy"]:not(.is-loaded) {
  background: linear-gradient(100deg, var(--bg-2) 8%, var(--bg-3) 20%, var(--bg-2) 34%);
  background-size: 260% 100%;
  animation: shimmer 1.5s linear infinite;
}
@keyframes shimmer {
  from { background-position: 130% 0; }
  to   { background-position: -30% 0; }
}

/* Idle warning veil before the kiosk resets itself. */
.idleveil {
  position: absolute; inset: 0; z-index: 900;
  display: none;
  place-items: center;
  background: rgba(4,6,10,0.9);
  text-align: center;
}
.idleveil.is-on { display: grid; animation: fadein 320ms var(--ease-out); }
.idleveil__t { font-family: var(--sign); font-weight: 800; font-size: 78px; text-transform: uppercase; color: #f0f3f7; line-height: 0.92; }
.idleveil__d { font-family: var(--data); font-size: 21px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--accent-lift); margin-top: 26px; }
.idleveil__n { font-family: var(--sign); font-weight: 800; font-size: 120px; color: var(--accent-lift); line-height: 1; margin-top: 12px; }
@keyframes fadein { from { opacity: 0; } to { opacity: 1; } }

@view-transition { navigation: auto; }
::view-transition-old(root) { animation: 220ms var(--ease-in-out) both vt-out; }
::view-transition-new(root) { animation: 420ms var(--ease-out) both vt-in; }
@keyframes vt-out { to { opacity: 0; } }
@keyframes vt-in { from { opacity: 0; } to { opacity: 1; } }
