/* massens.com — tribute splash
   Dark cyber-futuristic. No words. Everything hints, nothing announces.
   Scene look is driven by two things the engine sets:
     - a treatment class on each photo layer (t-signal / t-noir / t-ember / t-matrix)
     - the --accent custom property on <body>
*/

:root {
  --bg: #05070a;
  --accent: #4be1ff;
  --fade: 2400ms; /* keep in sync with FADE_MS in scripts/variants.js */
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: var(--bg);
}

/* ---------- photo layers ---------- */

.layer {
  position: fixed;
  inset: -6%;
  background-size: cover;
  background-position: 70% 35%; /* keep the face in frame on both photos */
  opacity: 0;
  transform: scale(1.02);
  transition: opacity var(--fade) ease;
  will-change: opacity, transform;
  z-index: 0;
}

.layer.visible {
  opacity: 1;
  animation: kenburns 46s ease-in-out infinite alternate;
}

@keyframes kenburns {
  from { transform: scale(1.02) translate3d(0, 0, 0); }
  to   { transform: scale(1.10) translate3d(-1.4%, -1.2%, 0); }
}

/* blend step: Mario ghosted over the current uploaded image */
.layer.blended {
  background-blend-mode: screen;
}

/* per-scene photo treatments */
.layer.t-signal { filter: grayscale(0.55) brightness(0.50) contrast(1.18) saturate(1.05); }
.layer.t-noir   { filter: grayscale(1)    brightness(0.68) contrast(1.22); }
.layer.t-ember  { filter: sepia(0.45) hue-rotate(285deg) saturate(1.55) brightness(0.48) contrast(1.15); }
.layer.t-matrix { filter: grayscale(0.85) sepia(0.55) hue-rotate(72deg) saturate(1.35) brightness(0.64) contrast(1.18); }

/* ---------- atmosphere ---------- */

/* accent-colored wash that retints with each scene */
.tint {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(ellipse at 50% 118%, color-mix(in srgb, var(--accent) 16%, transparent), transparent 55%),
    radial-gradient(ellipse at 50% -25%, color-mix(in srgb, var(--accent) 8%, transparent), transparent 50%),
    linear-gradient(180deg, rgba(3, 5, 8, 0.55), rgba(3, 5, 8, 0.15) 40%, rgba(3, 5, 8, 0.72));
  transition: background 1600ms ease;
}

/* receding perspective grid along the bottom */
.grid-floor {
  position: fixed;
  left: -25%;
  right: -25%;
  bottom: -2%;
  height: 34vh;
  z-index: 1;
  pointer-events: none;
  transform: perspective(420px) rotateX(62deg);
  transform-origin: bottom center;
  background-image:
    linear-gradient(color-mix(in srgb, var(--accent) 26%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--accent) 26%, transparent) 1px, transparent 1px);
  background-size: 42px 42px;
  animation: grid-drift 5.5s linear infinite;
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 55%);
          mask-image: linear-gradient(180deg, transparent, #000 55%);
  opacity: 0.5;
}

@keyframes grid-drift {
  from { background-position: 0 0; }
  to   { background-position: 0 42px; }
}

/* matrix-style ANSI rain — columns spawned by variants.js, animated purely in CSS */
.rain {
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  overflow: hidden;
}

.rain span {
  position: absolute;
  top: 0;
  font-family: 'Consolas', 'Courier New', monospace;
  font-weight: 700;
  white-space: pre;
  line-height: 1.05;
  color: var(--accent);
  text-shadow: 0 0 8px color-mix(in srgb, var(--accent) 75%, transparent);
  opacity: 0.75;
  transform: translateY(-100%);
  animation: rain-fall linear forwards;
  will-change: transform;
  /* tail fades out above the falling head */
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 55%);
          mask-image: linear-gradient(180deg, transparent 0%, #000 55%);
}

@keyframes rain-fall {
  to { transform: translateY(100vh); }
}

.scanlines {
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: repeating-linear-gradient(
    180deg,
    rgba(0, 0, 0, 0.22) 0px,
    rgba(0, 0, 0, 0.22) 1px,
    transparent 1px,
    transparent 3px
  );
  opacity: 0.55;
}

.grain {
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
  opacity: 0.07;
  mix-blend-mode: overlay;
}

.vignette {
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: radial-gradient(ellipse at 50% 46%, transparent 42%, rgba(0, 0, 0, 0.78) 100%);
}

/* ---------- center core ---------- */

.core {
  position: fixed;
  inset: 0;
  z-index: 3;
  display: grid;
  place-items: center;
  grid-template-rows: 1fr auto auto auto 1fr;
  pointer-events: none;
}

.core::before { content: ''; } /* top spacer */
.core::after  { content: ''; } /* bottom spacer */

.mm {
  font-family: 'Arial Black', 'Impact', sans-serif;
  font-size: clamp(4rem, 16vw, 11rem);
  font-weight: 900;
  line-height: 0.85;
  letter-spacing: -0.07em;
  color: #eef6fa;
  text-shadow:
    0 0 14px color-mix(in srgb, var(--accent) 65%, transparent),
    0 0 46px color-mix(in srgb, var(--accent) 40%, transparent),
    0 0 110px color-mix(in srgb, var(--accent) 25%, transparent);
  transition: text-shadow 1600ms ease;
  user-select: none;
}

/* ZAP — MM takes a hit: pop, jump, RGB split. JS toggles .zap briefly */
.mm.zap {
  animation: zap 640ms steps(1, end) 1;
}

@keyframes zap {
  0%  { transform: translate(0, 0) scale(1); }
  6%  { transform: translate(-8px, 5px) scale(1.08) skewX(-3deg);
        text-shadow: -6px 0 0 rgba(0, 255, 255, 0.85), 6px 0 0 rgba(255, 0, 90, 0.85),
                     0 0 30px color-mix(in srgb, var(--accent) 90%, transparent); }
  14% { transform: translate(6px, -4px) scale(0.94) skewX(2deg);
        text-shadow: 5px 0 0 rgba(0, 255, 255, 0.7), -5px 0 0 rgba(255, 0, 90, 0.7),
                     0 0 60px color-mix(in srgb, var(--accent) 90%, transparent); }
  22% { transform: translate(-4px, -7px) scale(1.12);
        text-shadow: -3px 0 0 rgba(0, 255, 255, 0.8), 3px 0 0 rgba(255, 0, 90, 0.8),
                     0 0 90px var(--accent); }
  32% { transform: translate(3px, 2px) scale(0.98) skewX(-1deg); }
  44% { transform: translate(-1px, -2px) scale(1.03); }
  58% { transform: translate(0, 1px) scale(1); }
  100% { transform: translate(0, 0) scale(1); }
}

/* screen flicker that rides along with the zap */
.zap-flash {
  position: fixed;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background: radial-gradient(circle at 50% 42%, color-mix(in srgb, var(--accent) 14%, transparent), transparent 60%);
  animation: zap-flash 640ms steps(1, end) 1 forwards;
}

@keyframes zap-flash {
  0%   { opacity: 0; }
  6%   { opacity: 1; }
  12%  { opacity: 0; }
  20%  { opacity: 0.85; }
  30%  { opacity: 0.15; }
  38%  { opacity: 0.5; }
  50%  { opacity: 0; }
  100% { opacity: 0; }
}

/* click shockwave */
.wave {
  position: fixed;
  width: 120px;
  height: 120px;
  border-radius: 50%;
  border: 2px solid var(--accent);
  box-shadow:
    0 0 18px color-mix(in srgb, var(--accent) 60%, transparent),
    inset 0 0 12px color-mix(in srgb, var(--accent) 40%, transparent);
  pointer-events: none;
  z-index: 4;
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.04);
  animation: wave-out 850ms cubic-bezier(0.2, 0.6, 0.3, 1) forwards;
}

@keyframes wave-out {
  0%   { opacity: 0.9; transform: translate(-50%, -50%) scale(0.04); }
  100% { opacity: 0;   transform: translate(-50%, -50%) scale(9); }
}

/* rising ember motes — constant, very quiet */
.mote {
  position: fixed;
  bottom: -6px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 6px color-mix(in srgb, var(--accent) 70%, transparent);
  pointer-events: none;
  z-index: 1;
  opacity: 0;
  animation: mote-rise linear infinite;
}

@keyframes mote-rise {
  0%   { transform: translateY(0) translateX(0);       opacity: 0; }
  8%   { opacity: 0.45; }
  60%  { transform: translateY(-60vh) translateX(2vw); opacity: 0.3; }
  100% { transform: translateY(-108vh) translateX(-1vw); opacity: 0; }
}

/* horizontal scanline sweep, now and again */
.sweep {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  height: 2px;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--accent) 65%, transparent) 50%, transparent);
  box-shadow: 0 0 12px color-mix(in srgb, var(--accent) 50%, transparent);
  animation: sweep-down 1.6s linear forwards;
}

@keyframes sweep-down {
  from { transform: translateY(-3px);  opacity: 0.6; }
  to   { transform: translateY(100vh); opacity: 0.2; }
}

/* occasional subtle glitch slice — JS toggles .glitch briefly */
.mm.glitch {
  animation: glitch 340ms steps(2, end) 1;
}

@keyframes glitch {
  0%   { transform: translate(0, 0);      clip-path: inset(0 0 0 0); }
  20%  { transform: translate(-3px, 1px); clip-path: inset(12% 0 58% 0); }
  40%  { transform: translate(3px, -1px); clip-path: inset(55% 0 18% 0); }
  60%  { transform: translate(-2px, 0);   clip-path: inset(30% 0 40% 0); }
  80%  { transform: translate(2px, 1px);  clip-path: inset(70% 0 6% 0); }
  100% { transform: translate(0, 0);      clip-path: inset(0 0 0 0); }
}

/* charging ring — fills, holds a breath, resets. Something is loading. */
.ring {
  width: clamp(64px, 11vw, 104px);
  margin-top: clamp(1.2rem, 3vh, 2.2rem);
  transform: rotate(-90deg);
  overflow: visible;
}

.ring-track,
.ring-charge {
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
}

.ring-track {
  stroke: color-mix(in srgb, var(--accent) 18%, transparent);
}

.ring-charge {
  stroke: var(--accent);
  stroke-dasharray: 326.7; /* 2 * pi * 52 */
  stroke-dashoffset: 326.7;
  filter: drop-shadow(0 0 6px color-mix(in srgb, var(--accent) 80%, transparent));
  animation: charge 9s cubic-bezier(0.4, 0, 0.3, 1) infinite;
  transition: stroke 1600ms ease;
}

@keyframes charge {
  0%   { stroke-dashoffset: 326.7; opacity: 0.9; }
  74%  { stroke-dashoffset: 0;     opacity: 1; }
  86%  { stroke-dashoffset: 0;     opacity: 0.35; }
  92%  { stroke-dashoffset: 0;     opacity: 1; }
  100% { stroke-dashoffset: 326.7; opacity: 0.9; }
}

/* blinking terminal cursor — someone is at the keyboard */
.cursor {
  width: 0.85rem;
  height: 1.35rem;
  margin-top: clamp(1rem, 2.6vh, 1.8rem);
  background: var(--accent);
  box-shadow: 0 0 10px color-mix(in srgb, var(--accent) 80%, transparent);
  animation: blink 1.25s steps(1, end) infinite;
  transition: background-color 1600ms ease;
}

@keyframes blink {
  0%, 55% { opacity: 1; }
  56%, 100% { opacity: 0; }
}

/* ---------- drop zone feedback (wordless) ---------- */

.drop-frame {
  position: fixed;
  inset: 14px;
  z-index: 4;
  pointer-events: none;
  border: 1px dashed color-mix(in srgb, var(--accent) 70%, transparent);
  border-radius: 14px;
  opacity: 0;
  transform: scale(1.015);
  transition: opacity 220ms ease, transform 220ms ease, border-color 220ms ease;
}

body[data-drop="over"] .drop-frame {
  opacity: 1;
  transform: scale(1);
  box-shadow: inset 0 0 60px color-mix(in srgb, var(--accent) 12%, transparent);
}

body[data-drop="busy"] .drop-frame {
  opacity: 1;
  transform: scale(1);
  animation: drop-pulse 900ms ease-in-out infinite;
}

body[data-drop="done"] .drop-frame {
  opacity: 1;
  border-style: solid;
}

body[data-drop="error"] .drop-frame {
  opacity: 1;
  border-color: rgba(255, 80, 80, 0.8);
}

@keyframes drop-pulse {
  0%, 100% { box-shadow: inset 0 0 30px color-mix(in srgb, var(--accent) 8%, transparent); }
  50%      { box-shadow: inset 0 0 90px color-mix(in srgb, var(--accent) 22%, transparent); }
}

/* ---------- accessibility / power ---------- */

@media (prefers-reduced-motion: reduce) {
  .layer.visible { animation: none; transform: scale(1.04); }
  .grid-floor { animation: none; }
  .mm.glitch { animation: none; }
  .ring-charge { animation: none; stroke-dashoffset: 82; }
  .cursor { animation: none; opacity: 1; }
}

@media (max-width: 600px) {
  .layer { background-position: 72% 30%; }
  .grid-floor { background-size: 30px 30px; }
}
