/* Wall of Blocks — "pixel-grid CSS-3D block" (a mempool.space-style pixel block
   viz, restyled with Hartii's own branding) — framework-free, shared with the
   hartiibiome explorer (apps/biome/public/explorer/wall3d/ keeps a byte-identical
   copy). CSS drives all continuous idle motion; the canvas fill-in sweep is a
   short one-shot handled in wallBlock3d.js. Loaded only from the lazy /wall route
   chunk — never import this from anything reachable by the main bundle. */

.w3d-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ---------- Hero slab (block detail page) ---------- */

.w3d-slab-scene {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  max-width: 100%;
  padding: 32px 12px 56px;
  perspective: 1100px;
  isolation: isolate;
  opacity: 1;
  transform: rotateX(var(--w3d-pointer-tilt-x, 0deg)) rotateY(var(--w3d-pointer-tilt-y, 0deg));
  transition: transform 180ms cubic-bezier(.2,.75,.2,1);
}

.w3d-slab-stage {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  max-width: 100%;
  overflow: visible;
  transform-style: preserve-3d;
}

.w3d-tile-stage {
  position: relative;
  width: 100%;
  height: 100%;
  max-width: 100%;
  overflow: visible;
  perspective: 650px;
  transform-style: preserve-3d;
  transition: transform 180ms cubic-bezier(.2,.75,.2,1), filter 180ms ease;
}
.w3d-tile-stage.w3d-pointer-active {
  transform: rotateX(var(--w3d-pointer-tilt-x, 0deg)) rotateY(var(--w3d-pointer-tilt-y, 0deg));
  filter: brightness(1.08);
}

.w3d-fx-video {
  position: absolute;
  inset: -7% -4%;
  width: 108%;
  height: 114%;
  object-fit: cover;
  border-radius: 18px;
  pointer-events: none;
  user-select: none;
}
.w3d-fx-field {
  z-index: -2;
  opacity: .24;
  mix-blend-mode: screen;
  filter: saturate(1.15) contrast(1.05);
}
.w3d-fx-forge {
  z-index: 6;
  opacity: 0;
  mix-blend-mode: screen;
  filter: saturate(1.3) brightness(1.25);
}
.w3d-fx-forge.is-playing { animation: w3dForgeVideoFlash 1.25s ease-out both; }
@keyframes w3dForgeVideoFlash {
  0% { opacity: 0; transform: scale(.82); }
  18% { opacity: .64; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.08); }
}

.w3d-slab-scene.w3d-forge-in {
  animation: w3dSceneForgeIn 0.8s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
@keyframes w3dSceneForgeIn {
  0% { opacity: 0; filter: blur(10px) brightness(2.2); }
  55% { opacity: 1; filter: blur(2px) brightness(1.6); }
  100% { opacity: 1; filter: blur(0) brightness(1); }
}

.w3d-slab-glow {
  position: absolute;
  inset: -22% -8%;
  border-radius: 50%;
  background: radial-gradient(circle, var(--w3d-color) 0%, transparent 68%);
  opacity: 0.28;
  filter: blur(54px);
  z-index: -1;
  pointer-events: none;
}

.w3d-slab-shadow {
  position: absolute;
  bottom: 16px;
  left: 50%;
  width: 58%;
  height: 20px;
  background: radial-gradient(ellipse, rgba(0, 0, 0, 0.6) 0%, transparent 72%);
  filter: blur(5px);
  transform: translateX(-50%);
  animation: w3dShadowDrift var(--w3d-dur, 9s) ease-in-out infinite;
}

.w3d-slab {
  position: relative;
  width: min(88vw, 420px, 100%);
  max-width: 100%;
  aspect-ratio: 1;
  transform-style: preserve-3d;
  --w3d-thickness: 26px;
  animation-duration: var(--w3d-dur, 9s);
  will-change: transform;
}

/* ---------- Grid tile (Wall.jsx grid) ---------- */

.w3d-tile {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transform: rotateY(var(--w3d-tilt-y, 0deg)) rotateX(var(--w3d-tilt-x, 0deg));
  transition: transform 160ms ease, box-shadow 160ms ease;
  animation: w3dTileForge 0.45s cubic-bezier(0.2, 0.8, 0.2, 1) both;
  --w3d-thickness: 7px;
  will-change: transform;
}

/* ---------- Shared 3D shell: edges (thickness), faces, canvas front ---------- */

.w3d-slab-edge {
  position: absolute;
  background: linear-gradient(var(--w3d-edge-angle, 180deg), rgba(255, 255, 255, 0.2), rgba(0, 0, 0, 0.55));
  background-color: var(--w3d-accent, var(--w3d-color));
  background-blend-mode: multiply;
}
/* Thickness = four full-size layers stacked BEHIND the front face (extrusion), not four rotated
   side faces: rotated sides were projected in front of the grid by perspective and covered the
   message's top/left. Layers behind the front can never overlap it; they peek out as the slab turns. */
.w3d-slab-edge-top, .w3d-slab-edge-right, .w3d-slab-edge-bottom, .w3d-slab-edge-left { inset: 0; border-radius: inherit; }
.w3d-slab-edge-top { transform: translateZ(calc(var(--w3d-thickness) * 0.25)); --w3d-edge-angle: 135deg; }
.w3d-slab-edge-right { transform: translateZ(0); --w3d-edge-angle: 135deg; filter: brightness(0.85); }
.w3d-slab-edge-bottom { transform: translateZ(calc(var(--w3d-thickness) * -0.25)); --w3d-edge-angle: 135deg; filter: brightness(0.7); }
.w3d-slab-edge-left { transform: translateZ(calc(var(--w3d-thickness) * -0.5)); --w3d-edge-angle: 135deg; filter: brightness(0.55); }

.w3d-tile-edge {
  position: absolute;
  inset: 0;
  border-radius: 4px;
  transform: translateZ(calc(var(--w3d-thickness) * -1)) scale(0.92);
  background: var(--w3d-accent, var(--w3d-color));
  filter: brightness(0.6);
}

.w3d-slab-face {
  position: absolute;
  inset: 0;
  border-radius: 6px;
  overflow: hidden;
  background: #0c0f14;
}
.w3d-slab-front {
  transform: translateZ(calc(var(--w3d-thickness) / 2));
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.12), inset 0 -16px 26px -14px rgba(0, 0, 0, 0.55);
}
.w3d-slab-back {
  transform: translateZ(calc(var(--w3d-thickness) / -2)) rotateY(180deg);
  background: var(--w3d-accent, var(--w3d-color));
  filter: brightness(0.45) saturate(0.85);
}

.w3d-tile-face {
  position: absolute;
  inset: 0;
  border-radius: 4px;
  overflow: hidden;
  background: #0c0f14;
  transform: translateZ(calc(var(--w3d-thickness) / 2));
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.14), inset 0 -6px 10px -4px rgba(0, 0, 0, 0.55);
}

.w3d-grid-canvas {
  display: block;
  width: 100%;
  height: 100%;
}
.w3d-grid-life {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(115deg, transparent 38%, color-mix(in srgb, var(--w3d-accent, var(--w3d-color)) 24%, transparent) 50%, transparent 62%),
    repeating-linear-gradient(135deg, transparent 0 13px, rgba(255,255,255,.035) 13px 14px, transparent 14px 28px);
  background-size: 240% 100%, 100% 100%;
  mix-blend-mode: screen;
  opacity: .52;
  animation: w3dGridLife 5.8s linear infinite;
}
@keyframes w3dGridLife {
  from { background-position: -120% 0, 0 0; opacity: .34; }
  50% { opacity: .58; }
  to { background-position: 120% 0, 28px -28px; opacity: .34; }
}

/* One-shot arrival wipe: covers the (already fully-painted) canvas at mount,
   then recedes top-to-bottom — a "cells filling in" read without depending on
   canvas redraw timing for correctness. Pure CSS/GPU-composited, so it can
   never leave the grid itself half-drawn even on a throttled main thread. */
.w3d-grid-reveal {
  position: absolute;
  inset: 0;
  background: #0c0f14;
  clip-path: inset(0 0 0 0);
  animation: w3dGridReveal 0.7s cubic-bezier(0.3, 0.7, 0.2, 1) both;
  animation-delay: 0.05s;
  pointer-events: none;
}
@keyframes w3dGridReveal {
  from { clip-path: inset(0 0 0 0); }
  to { clip-path: inset(100% 0 0 0); }
}

/* Raking specular sweep over the canvas — reads as a light catching the pixel
   grid as the block drifts/spins. */
.w3d-slab-sweep {
  position: absolute;
  inset: -20%;
  background: linear-gradient(115deg, transparent 40%, rgba(255, 255, 255, 0.22) 50%, transparent 60%);
  background-size: 220% 220%;
  mix-blend-mode: overlay;
  animation: w3dSweep calc(var(--w3d-dur, 9s) * 0.7) linear infinite;
  pointer-events: none;
}
@keyframes w3dSweep {
  from { background-position: -40% -40%; }
  to { background-position: 140% 140%; }
}

/* ---------- Idle animation variants (driven by the on-chain `animation` meta) ---------- */

@keyframes w3dDrift {
  0%, 100% { transform: rotateY(-11deg) rotateX(4deg); }
  50% { transform: rotateY(11deg) rotateX(4deg); }
}
@keyframes w3dTileDrift {
  0%, 100% { transform: rotateY(calc(var(--w3d-tilt-y, 0deg) - 9deg)) rotateX(var(--w3d-tilt-x, 0deg)); }
  50% { transform: rotateY(calc(var(--w3d-tilt-y, 0deg) + 9deg)) rotateX(var(--w3d-tilt-x, 0deg)); }
}
@keyframes w3dFloat {
  0%, 100% { transform: translateY(0) rotateY(-6deg) rotateX(4deg); }
  50% { transform: translateY(-16px) rotateY(6deg) rotateX(2deg); }
}
@keyframes w3dTileFloat {
  0%, 100% { transform: translateY(0) rotateY(var(--w3d-tilt-y, 0deg)) rotateX(var(--w3d-tilt-x, 0deg)); }
  50% { transform: translateY(-6px) rotateY(var(--w3d-tilt-y, 0deg)) rotateX(var(--w3d-tilt-x, 0deg)); }
}
@keyframes w3dSpin {
  from { transform: rotateY(0deg) rotateX(6deg); }
  to { transform: rotateY(360deg) rotateX(6deg); }
}
@keyframes w3dGlitch {
  0%, 90%, 100% { transform: rotateY(-8deg) rotateX(4deg) translate(0, 0); filter: none; }
  91% { transform: rotateY(-8deg) rotateX(4deg) translate(2px, -1px); filter: drop-shadow(2px 0 0 #ff2d55) drop-shadow(-2px 0 0 #00e5ff); }
  92% { transform: rotateY(-8deg) rotateX(4deg) translate(-3px, 1px); filter: drop-shadow(-2px 0 0 #a78bfa) drop-shadow(2px 0 0 #7CFF6B); }
  93% { transform: rotateY(-8deg) rotateX(4deg) translate(1px, 0); filter: none; }
}
@keyframes w3dPulseGlow {
  0%, 100% { box-shadow: 0 0 0 0 transparent; }
  50% { box-shadow: 0 0 calc(18px + var(--w3d-glow, 0) * 34px) calc(2px + var(--w3d-glow, 0) * 8px) var(--w3d-accent, var(--w3d-color)); }
}

.w3d-slab.w3d-anim-drift { animation-name: w3dDrift; animation-timing-function: ease-in-out; animation-iteration-count: infinite; }
.w3d-slab.w3d-anim-float { animation-name: w3dFloat; animation-timing-function: ease-in-out; animation-iteration-count: infinite; }
.w3d-slab.w3d-anim-spin { animation-name: w3dSpin; animation-timing-function: linear; animation-iteration-count: infinite; }
.w3d-slab.w3d-anim-pulse { animation-name: w3dDrift; animation-timing-function: ease-in-out; animation-iteration-count: infinite; animation-duration: calc(var(--w3d-dur, 9s) * 1.7); }
.w3d-slab.w3d-anim-pulse .w3d-slab-front { animation: w3dPulseGlow calc(var(--w3d-dur, 9s) * 0.4) ease-in-out infinite; }
.w3d-slab.w3d-anim-glitch { animation-name: w3dGlitch; animation-timing-function: steps(1); animation-iteration-count: infinite; }
.w3d-slab.w3d-anim-none { animation: none; transform: rotateY(-8deg) rotateX(4deg); }

.w3d-tile.w3d-anim-drift { animation: w3dTileForge 0.45s cubic-bezier(0.2, 0.8, 0.2, 1) both, w3dTileDrift var(--w3d-dur, 11s) ease-in-out infinite; }
.w3d-tile.w3d-anim-float { animation: w3dTileForge 0.45s cubic-bezier(0.2, 0.8, 0.2, 1) both, w3dTileFloat var(--w3d-dur, 10s) ease-in-out infinite; }
.w3d-tile.w3d-anim-spin { animation: w3dTileForge 0.45s cubic-bezier(0.2, 0.8, 0.2, 1) both, w3dSpin var(--w3d-dur, 12s) linear infinite; }
.w3d-tile.w3d-anim-pulse { animation: w3dTileForge 0.45s cubic-bezier(0.2, 0.8, 0.2, 1) both, w3dTileDrift calc(var(--w3d-dur, 11s) * 1.7) ease-in-out infinite; }
.w3d-tile.w3d-anim-pulse .w3d-tile-face { animation: w3dPulseGlow calc(var(--w3d-dur, 11s) * 0.4) ease-in-out infinite; }
.w3d-tile.w3d-anim-glitch { animation: w3dTileForge 0.45s cubic-bezier(0.2, 0.8, 0.2, 1) both, w3dGlitch var(--w3d-dur, 11s) steps(1) infinite; }
.w3d-tile.w3d-anim-none { animation: w3dTileForge 0.45s cubic-bezier(0.2, 0.8, 0.2, 1) both; }

@keyframes w3dShadowDrift {
  0%, 100% { opacity: 0.5; transform: translateX(-50%) scaleX(1); }
  50% { opacity: 0.32; transform: translateX(-50%) scaleX(0.82); }
}

@keyframes w3dTileForge {
  from { opacity: 0; transform: rotateY(var(--w3d-tilt-y, 0deg)) rotateX(var(--w3d-tilt-x, 0deg)) scale(0.7) translateZ(-30px); filter: brightness(1.8); }
  to { opacity: 1; transform: rotateY(var(--w3d-tilt-y, 0deg)) rotateX(var(--w3d-tilt-x, 0deg)) scale(1) translateZ(0); filter: brightness(1); }
}

/* New-arrival tiles get a short glow pulse — animated on the face (a separate
   element/property from .w3d-tile's own transform animation) so it never
   fights the meta-driven idle-motion animation-name above. */
.w3d-tile.is-new .w3d-tile-face { animation: w3dTileGlowPulse 1.4s ease-out both; }
@keyframes w3dTileGlowPulse {
  0% { box-shadow: 0 0 0 0 var(--w3d-color); }
  40% { box-shadow: 0 0 18px 4px var(--w3d-color); }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* ---------- Material variants (tint the slab/edges/faces) ---------- */

.w3d-material-metal .w3d-slab-edge,
.w3d-material-metal .w3d-tile-edge {
  background-image: repeating-linear-gradient(100deg, rgba(255, 255, 255, 0.28) 0 2px, rgba(0, 0, 0, 0.3) 2px 4px);
}
.w3d-material-metal .w3d-slab-front,
.w3d-material-metal .w3d-tile-face {
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.3), inset 0 -16px 26px -14px rgba(0, 0, 0, 0.6);
}
.w3d-material-metal .w3d-slab-sweep { background: linear-gradient(115deg, transparent 30%, rgba(255, 255, 255, 0.5) 50%, transparent 70%); mix-blend-mode: screen; }
.w3d-material-metal .w3d-slab-front::after,
.w3d-material-metal .w3d-tile-face::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(100deg, transparent 0 11px, rgba(255,255,255,.11) 12px, transparent 14px 24px);
  mix-blend-mode: screen;
  opacity: .42;
  animation: w3dMetalBrush 4.8s linear infinite;
}
@keyframes w3dMetalBrush { from { background-position: -32px 0; } to { background-position: 32px 0; } }

.w3d-material-glass .w3d-slab-face,
.w3d-material-glass .w3d-tile-face {
  background: rgba(12, 15, 20, 0.55);
  backdrop-filter: blur(3px);
}
.w3d-material-glass .w3d-slab-front,
.w3d-material-glass .w3d-tile-face {
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, 0.4), inset 0 -10px 18px -10px rgba(0, 0, 0, 0.35);
}
.w3d-material-glass .w3d-slab-edge,
.w3d-material-glass .w3d-tile-edge { opacity: 0.65; }
.w3d-material-glass .w3d-slab-front::after,
.w3d-material-glass .w3d-tile-face::after {
  content: '';
  position: absolute;
  inset: -20%;
  pointer-events: none;
  background: linear-gradient(120deg, transparent 36%, rgba(255,255,255,.22) 48%, transparent 60%);
  animation: w3dGlassRefraction 5.6s ease-in-out infinite;
}
@keyframes w3dGlassRefraction { from { transform: translateX(-26%) rotate(8deg); } 50%, to { transform: translateX(26%) rotate(8deg); } }

/* No `filter` on .w3d-slab/.w3d-tile: a filter flattens `transform-style: preserve-3d`, which
   collapses the side faces onto the front and clips the grid. The glow lives on the faces. */
.w3d-material-neon .w3d-slab-front,
.w3d-material-neon .w3d-tile-face {
  box-shadow: inset 0 0 0 1.5px var(--w3d-accent, var(--w3d-color)), 0 0 22px 2px var(--w3d-accent, var(--w3d-color));
}
.w3d-material-neon .w3d-slab-front::after,
.w3d-material-neon .w3d-tile-face::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(circle at 22% 30%, var(--w3d-accent, var(--w3d-color)), transparent 38%);
  mix-blend-mode: screen;
  opacity: .16;
  animation: w3dNeonFlicker 3.8s steps(3, end) infinite;
}
@keyframes w3dNeonFlicker { 0%, 14%, 100% { opacity: .1; } 15% { opacity: .32; } 16% { opacity: .12; } 62% { opacity: .22; } 63% { opacity: .08; } }
.w3d-material-neon .w3d-slab-edge,
.w3d-material-neon .w3d-tile-edge { background-color: var(--w3d-accent, var(--w3d-color)); background-image: none; filter: brightness(0.9); }

.w3d-material-gold .w3d-slab-edge,
.w3d-material-gold .w3d-tile-edge {
  background-image: linear-gradient(120deg, #fff3c4 0%, #d4af37 30%, #8a6a13 55%, #f9e28c 75%, #b8860b 100%);
  background-color: transparent;
}
.w3d-material-gold .w3d-slab-front,
.w3d-material-gold .w3d-tile-face {
  box-shadow: inset 0 0 0 1.5px #f3d675, inset 0 -16px 26px -14px rgba(60, 40, 0, 0.6);
}
.w3d-material-gold .w3d-slab-sweep { background: linear-gradient(115deg, transparent 30%, rgba(255, 236, 170, 0.55) 50%, transparent 70%); }
.w3d-material-gold .w3d-slab-front::after,
.w3d-material-gold .w3d-tile-face::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(112deg, transparent 37%, rgba(255,242,178,.38) 49%, transparent 58%);
  background-size: 220% 100%;
  animation: w3dGoldGlint 4.2s ease-in-out infinite;
}
@keyframes w3dGoldGlint { from { background-position: -100% 0; } to { background-position: 100% 0; } }

/* stone (default) needs no overrides — the base edge/face rules already read as
   a matte, slightly grainy slab via the inset shadows above. */

/* ---------- Hover lift — fine-pointer devices only ---------- */
@media (hover: hover) and (pointer: fine) {
  .w3d-tile { cursor: pointer; }
  button:hover .w3d-tile-stage,
  a:hover .w3d-tile-stage {
    transform: scale(1.12) translateZ(10px);
    filter: drop-shadow(0 10px 8px rgba(0, 0, 0, .45));
    z-index: 2;
  }
}

/* ---------- Reduced motion: static but dimensional ---------- */
@media (prefers-reduced-motion: reduce) {
  .w3d-slab, .w3d-slab-sweep, .w3d-slab-shadow, .w3d-tile, .w3d-grid-life { animation: none !important; }
  .w3d-slab-scene.w3d-forge-in { animation: none !important; opacity: 1; }
  .w3d-grid-reveal { display: none; }
}
.w3d-no-motion, .w3d-no-motion .w3d-slab-sweep, .w3d-no-motion .w3d-slab-shadow, .w3d-no-motion .w3d-slab-front {
  animation: none !important;
}
.w3d-offscreen, .w3d-offscreen *, .w3d-offscreen *::before, .w3d-offscreen *::after {
  animation-play-state: paused !important;
}
.w3d-slab.w3d-no-motion { transform: rotateY(-8deg) rotateX(4deg); }
.w3d-tile.w3d-no-motion { animation: none !important; }

.w3d-material-stone .w3d-slab-front::before,
.w3d-material-stone .w3d-tile-face::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image: radial-gradient(circle, rgba(226,236,226,.32) 0 1px, transparent 1.5px);
  background-size: 37px 29px;
  opacity: .18;
  will-change: transform, opacity;
  animation: w3dStoneDust 6.8s ease-in-out infinite;
}
@keyframes w3dStoneDust {
  from { transform: translate3d(0, 0, 0); opacity: .12; }
  50% { opacity: .22; }
  to { transform: translate3d(8px, -6px, 0); opacity: .12; }
}

/* Framework-free profile/miner badge surface (pixelBadge.js). */
.pixel-badge {
  position: relative;
  display: block;
  width: 240px;
  height: 72px;
  overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--pixel-badge-color, #7c3aed) 58%, transparent);
  border-radius: 9px;
  background: #080a12;
  box-shadow: 0 0 20px color-mix(in srgb, var(--pixel-badge-color, #7c3aed) 22%, transparent);
}
.pixel-badge-canvas { display: block; width: 100%; height: 100%; image-rendering: pixelated; }
