/* ==========================================================================
   Ambient motion layer — wireframe sphere, drifting spores, parallax,
   idle "breathing" on the scene, and entrance stagger for the content.
   Purely additive: delete this file + ambient.js and the page is unchanged.
   ========================================================================== */

/* ---------- Holographic wireframe sphere ---------- */

.sphere-wrap {
  position: absolute;
  top: 30%;
  left: 50%;
  width: clamp(320px, 42vw, 640px);
  aspect-ratio: 1;
  z-index: 3; /* above .scene / .hex, below .content (10) */
  pointer-events: none;
  opacity: 0.5;
  mix-blend-mode: screen;
  transform: translate(-50%, -50%);
  /* Faded edges so the rings dissolve instead of ending on a hard circle */
  -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 42%, transparent 74%);
  mask-image: radial-gradient(circle at 50% 50%, #000 42%, transparent 74%);
}

.sphere {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  transform: rotateX(-14deg);
  animation: sphere-spin 42s linear infinite;
}

.sphere-ring {
  position: absolute;
  inset: 0;
  border: 1px solid rgba(56, 186, 179, 0.5);
  border-radius: 50%;
}

/* Meridians: 8 circles fanned around the vertical axis */
.sphere-ring.m1 { transform: rotateY(0deg); }
.sphere-ring.m2 { transform: rotateY(22.5deg); }
.sphere-ring.m3 { transform: rotateY(45deg); }
.sphere-ring.m4 { transform: rotateY(67.5deg); }
.sphere-ring.m5 { transform: rotateY(90deg); }
.sphere-ring.m6 { transform: rotateY(112.5deg); }
.sphere-ring.m7 { transform: rotateY(135deg); }
.sphere-ring.m8 { transform: rotateY(157.5deg); }

/* Latitudes: flattened circles stacked up the axis. Each is scaled to the
   radius of the sphere at its height (cos of the latitude angle). */
.sphere-ring.lat {
  border-color: rgba(80, 210, 255, 0.28);
}
.sphere-ring.l1 { transform: rotateX(90deg) translateZ(38%)  scale(0.60); }
.sphere-ring.l2 { transform: rotateX(90deg) translateZ(20%)  scale(0.87); }
.sphere-ring.l3 { transform: rotateX(90deg) translateZ(0)    scale(1); }
.sphere-ring.l4 { transform: rotateX(90deg) translateZ(-20%) scale(0.87); }
.sphere-ring.l5 { transform: rotateX(90deg) translateZ(-38%) scale(0.60); }

/* Core bloom sitting inside the cage */
.sphere-core {
  position: absolute;
  inset: 18%;
  border-radius: 50%;
  background: radial-gradient(
    circle at 42% 38%,
    rgba(120, 235, 255, 0.34),
    rgba(56, 186, 179, 0.14) 46%,
    transparent 70%
  );
  animation: sphere-breathe 7s ease-in-out infinite;
}

@keyframes sphere-spin {
  to { transform: rotateX(-14deg) rotateY(360deg); }
}

@keyframes sphere-breathe {
  0%, 100% { opacity: 0.55; transform: scale(1); }
  50%      { opacity: 1;    transform: scale(1.07); }
}

/* ---------- Drifting spores ---------- */

.spores {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  overflow: hidden;
}

.spore {
  position: absolute;
  bottom: -6vh;
  width: var(--size, 3px);
  height: var(--size, 3px);
  border-radius: 50%;
  background: rgba(140, 240, 255, 0.7);
  box-shadow: 0 0 6px 1px rgba(56, 186, 179, 0.45);
  opacity: 0;
  animation: spore-rise var(--dur, 18s) linear var(--delay, 0s) infinite;
}

.spores.paused .spore {
  animation-play-state: paused;
}

@keyframes spore-rise {
  0%   { opacity: 0; transform: translate(0, 0) scale(0.6); }
  12%  { opacity: var(--peak, 0.7); }
  80%  { opacity: var(--peak, 0.7); }
  100% { opacity: 0; transform: translate(var(--drift, 40px), -112vh) scale(1); }
}

/* ---------- Idle life in the existing scene ---------- */

.dodo {
  animation: bob 5.5s ease-in-out infinite;
}

.trex {
  animation: bob 8s ease-in-out -2s infinite;
}

@keyframes bob {
  0%, 100% { translate: 0 0; }
  50%      { translate: 0 -0.55vw; }
}

.water-glow {
  animation: water-pulse 6s ease-in-out infinite;
}

@keyframes water-pulse {
  0%, 100% { opacity: 0.78; filter: blur(0px); }
  50%      { opacity: 1;    filter: blur(2px); }
}

.dodo-glow {
  animation: water-pulse 6s ease-in-out -3s infinite;
}

/* ---------- Hex lattice: light travels through the pattern ----------
   The hex art becomes a MASK instead of an image, so what we paint behind it
   only shows up on the lattice lines. A wide diagonal band of light is then
   swept across that mask — reading as a charge running through the grid
   rather than the whole cluster dimming in and out. */

.hex-left,
.hex-right {
  background-image: none;
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

.hex-left {
  opacity: 0.85;
  -webkit-mask-image: url("assets/hex-pattern-strong.png");
  mask-image: url("assets/hex-pattern-strong.png");
  background:
    /* travelling charge */
    linear-gradient(
      118deg,
      transparent 30%,
      rgba(56, 186, 179, 0.5) 42%,
      rgba(150, 245, 255, 0.95) 50%,
      rgba(56, 186, 179, 0.5) 58%,
      transparent 70%
    ),
    /* always-on resting tint so the lattice never disappears */
    linear-gradient(rgba(56, 186, 179, 0.16), rgba(56, 186, 179, 0.16));
  background-size: 320% 320%, 100% 100%;
  background-repeat: no-repeat;
  animation: hex-sweep 9s ease-in-out infinite;
}

.hex-right {
  opacity: 0.7;
  -webkit-mask-image: url("assets/hex-right.svg");
  mask-image: url("assets/hex-right.svg");
  background:
    linear-gradient(
      62deg,
      transparent 30%,
      rgba(56, 186, 179, 0.45) 42%,
      rgba(150, 245, 255, 0.9) 50%,
      rgba(56, 186, 179, 0.45) 58%,
      transparent 70%
    ),
    linear-gradient(rgba(56, 186, 179, 0.13), rgba(56, 186, 179, 0.13));
  background-size: 320% 320%, 100% 100%;
  background-repeat: no-repeat;
  /* Offset + slightly different period so the two sides never sync up */
  animation: hex-sweep 11.5s ease-in-out -4s infinite;
}

@keyframes hex-sweep {
  /* Long dwell at each end so the sweep feels like an occasional pulse
     instead of a metronome. */
  0%,  8%   { background-position: 120% 120%, 0 0; }
  46%, 58%  { background-position: -20% -20%, 0 0; }
  100%      { background-position: 120% 120%, 0 0; }
}

/* Logo gets a slow float + a glow that swells with the sphere */
.logo {
  animation: logo-float 9s ease-in-out infinite;
}

/* The entries page uses the logo as a small header link — a floating nav
   element reads as broken rather than alive, so it stays put. */
.logo-sm {
  animation: none;
}

.logo-link {
  transition: transform 0.2s cubic-bezier(0.2, 0.9, 0.2, 1), filter 0.2s ease;
  display: inline-block;
}

.logo-link:hover {
  transform: translateY(-1px);
  filter: brightness(1.1) drop-shadow(0 0 16px rgba(56, 186, 179, 0.4));
}

@keyframes logo-float {
  0%, 100% { translate: 0 0;     filter: drop-shadow(0 0 40px rgba(56, 186, 179, 0.25)); }
  50%      { translate: 0 -6px;  filter: drop-shadow(0 0 56px rgba(56, 186, 179, 0.45)); }
}

/* ---------- Giveaway panels: make them read as live feeds ----------
   Same language as the hex lattice — a slow travelling sweep — so the
   panels feel like part of one system rather than a separate effect. */

/* ---------- Panel shape: no square corners anywhere ----------
   Follows the reference frame's grammar — every corner bevelled (at four
   different scales so it never reads as a rounded rect), plus notches biting
   into the left and bottom edges. Written in px via calc() rather than %, so
   the bevels keep their 45° angle at any panel size instead of shearing. */

.give-panel {
  --c-tl: 15px; /* top-left    — largest, matches the reference */
  --c-tr: 6px;  /* top-right   — barely clipped */
  --c-br: 17px; /* bottom-right— the big diagonal */
  --c-bl: 7px;  /* bottom-left */
  --notch: 6px; /* depth of the edge bites */

  clip-path: polygon(
    /* top-left bevel */
    0 var(--c-tl),
    var(--c-tl) 0,
    /* top edge → top-right bevel */
    calc(100% - var(--c-tr)) 0,
    100% var(--c-tr),
    /* right edge → bottom-right bevel */
    100% calc(100% - var(--c-br)),
    calc(100% - var(--c-br)) 100%,
    /* bottom edge: a tab notched upward, right of centre */
    calc(60% + 13px) 100%,
    calc(60% + 7px) calc(100% - var(--notch)),
    calc(40% - 7px) calc(100% - var(--notch)),
    calc(40% - 13px) 100%,
    /* bottom-left bevel */
    var(--c-bl) 100%,
    0 calc(100% - var(--c-bl)),
    /* left edge: middle section stepped inward */
    0 72%,
    var(--notch) calc(72% - var(--notch)),
    var(--notch) calc(28% + var(--notch)),
    0 28%
  );

  /* Light direction on the 1px edge. The darkest stop stays at the original
     --panel-border (#1a4247) — going darker made the stroke fade out
     everywhere except the top-left corner. */
  background: linear-gradient(150deg, #276769 0%, #1e4b50 55%, #1a4247 100%);
}

/* Interior fill — bottom-weighted teal, matching the reference gradient
   (#07ABB4 at 10% up top, 25% at the base) over the dark panel colour,
   plus the reference's wide inner glow. */
.give-panel::before {
  background:
    /* Fine grain, generated inline so there's no extra asset to ship.
       Kept at ~6% like the reference — plus-lighter ADDS light, so anything
       heavier stops reading as texture and just greys the panel out.
       numOctaves='1' keeps the grain even; higher values clump into
       visible blotches at this size. */
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.95' numOctaves='1' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='0.06'/%3E%3C/svg%3E"),
    linear-gradient(
      180deg,
      rgba(7, 171, 180, 0.03) 0%,
      rgba(7, 171, 180, 0.05) 50%,
      rgba(7, 171, 180, 0.11) 100%
    ),
    #051920;
  background-size: 120px 120px, auto, auto;
  /* Desaturated turbulence + plus-lighter reads as texture; leaving the
     noise coloured would speckle the panel with stray RGB dots. */
  background-blend-mode: plus-lighter, normal, normal;
  /* The reference's 50px blur was drawn for a 224px-tall frame; these panels
     are ~110px, so at 50px the glow covered the whole surface and washed it
     out. Scaled to keep the same proportion of the panel. */
  box-shadow: inset 0 0 24px rgba(114, 233, 227, 0.06);
}

/* No travelling sheen on these panels. They sit directly beneath the form,
   and any repeating movement there competes with the CTA — the hex lattice
   at the edges of the frame carries the page's motion instead. */

/* Give the content clearance from the new left-edge notch */
.countdown-panel,
.winners-panel {
  padding-left: 20px;
  padding-right: 18px;
}

/* The prize sits static — styles.css already gives it a teal text-shadow,
   which is enough to make it the brightest thing in the panel. */

/* "Recent winners" gets a live indicator */
.winners-panel .give-label {
  display: flex;
  align-items: center;
  gap: 7px;
}

.winners-panel .give-label::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #38bab3;
  flex-shrink: 0;
  animation: live-dot 2.2s ease-in-out infinite;
}

@keyframes live-dot {
  0%, 100% { opacity: 0.5; box-shadow: 0 0 0 0 rgba(56, 186, 179, 0); }
  50%      { opacity: 1;   box-shadow: 0 0 6px 1px rgba(56, 186, 179, 0.3); }
}

/* The winners' own dots stay static — one live indicator per panel is the
   signal; five pulsing dots is just noise. */
.winners li:first-child .w-dot {
  animation: none;
}

.winners li:first-child .w-amt {
  text-shadow: none;
}

/* Winner rows land one after another instead of appearing as a block */
.winners li {
  animation: winner-in 0.5s cubic-bezier(0.2, 0.9, 0.2, 1) both;
}

.winners li:nth-child(1) { animation-delay: 0.05s; }
.winners li:nth-child(2) { animation-delay: 0.13s; }
.winners li:nth-child(3) { animation-delay: 0.21s; }
.winners li:nth-child(4) { animation-delay: 0.29s; }
.winners li:nth-child(5) { animation-delay: 0.37s; }

@keyframes winner-in {
  from { opacity: 0; transform: translateX(-8px); }
  to   { opacity: 1; transform: translateX(0); }
}

/* Most recent winner is the one worth looking at */
.winners li:first-child .w-dot {
  animation: live-dot 2.2s ease-in-out infinite;
}

.winners li:first-child .w-amt {
  text-shadow: 0 0 12px rgba(56, 186, 179, 0.55);
}

.winners li {
  transition: transform 0.18s ease;
}

.winners li:hover {
  transform: translateX(2px);
}

/* ---------- Entrance stagger ---------- */

.reveal {
  opacity: 0;
  translate: 0 14px;
  filter: blur(6px);
}

.js-ready .reveal {
  opacity: 1;
  translate: 0 0;
  filter: blur(0);
  transition:
    opacity 0.8s ease,
    translate 0.8s cubic-bezier(0.2, 0.9, 0.2, 1),
    filter 0.8s ease;
  transition-delay: var(--reveal-delay, 0s);
}

/* ---------- Interaction polish ---------- */

.btn-shape {
  transition: transform 0.18s cubic-bezier(0.2, 0.9, 0.2, 1), filter 0.18s ease;
}

.btn-shape:hover {
  transform: translateY(-1px);
  filter: brightness(1.12) drop-shadow(0 0 14px rgba(56, 186, 179, 0.45));
}

.btn-shape:active {
  transform: translateY(1px);
}

.socials a {
  transition: transform 0.18s cubic-bezier(0.2, 0.9, 0.2, 1), color 0.18s ease;
}

.socials a:hover {
  transform: translateY(-2px) scale(1.1);
}

/* ---------- Reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  .sphere,
  .sphere-core,
  .spore,
  .dodo,
  .trex,
  .water-glow,
  .dodo-glow,
  .hex-left,
  .hex-right,
  .logo,
  .winners-panel .give-label::before,
  .winners li,
  .winners li:first-child .w-dot {
    animation: none !important;
  }

  .spores {
    display: none;
  }

  .reveal {
    opacity: 1;
    translate: none;
    filter: none;
  }
}
