/* The hero: a jungle clearing with the arcade's whole cast passing through it.

   Every creature is three nested elements so the transforms never fight:
     .cr      horizontal travel across the scene
     .cr__b   vertical motion — bob, hop arc, sway
     .cr__g   the creature itself — flap, squash, tilt, facing
   Each layer owns exactly one transform, which keeps all of it on the
   compositor and off the main thread. Timing comes in as custom properties so
   no two creatures share a rhythm. */

.hero {
  position: relative;
  overflow: hidden;
  min-height: clamp(460px, 58vh, 640px);
  display: grid;
  place-items: center;
  isolation: isolate;
  background: linear-gradient(180deg, #BFE9FF 0%, #DFF3E6 46%, #E9F8D6 76%, #CFEFAF 100%);
}
:root[data-theme="dark"] .hero,
:root:not([data-theme="light"]) .hero {
  background: linear-gradient(180deg, #0C2C4A 0%, #103A46 44%, #123A2C 78%, #0E3323 100%);
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .hero {
    background: linear-gradient(180deg, #BFE9FF 0%, #DFF3E6 46%, #E9F8D6 76%, #CFEFAF 100%);
  }
}

/* Sun and haze */
.hero__sky {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(circle 190px at 84% 14%, rgba(255,240,170,.95), rgba(255,225,120,.35) 42%, transparent 70%),
    radial-gradient(ellipse 130% 60% at 50% 0%, rgba(255,255,255,.5), transparent 62%);
}
:root[data-theme="dark"] .hero__sky,
:root:not([data-theme="light"]) .hero__sky {
  background:
    radial-gradient(circle 150px at 84% 14%, rgba(200,230,255,.5), transparent 68%),
    radial-gradient(ellipse 130% 60% at 50% 0%, rgba(120,190,255,.16), transparent 62%);
}

/* Distant tree line */
.hero__far {
  position: absolute; left: 0; right: 0; bottom: 0; height: 62%; z-index: 1;
  pointer-events: none; opacity: .5;
  background: repeat-x bottom / 620px 100%
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='620' height='300' viewBox='0 0 620 300'%3E%3Cg fill='%232F8A00' opacity='0.55'%3E%3Cellipse cx='70' cy='150' rx='96' ry='84'/%3E%3Cellipse cx='210' cy='186' rx='118' ry='96'/%3E%3Cellipse cx='360' cy='158' rx='104' ry='88'/%3E%3Cellipse cx='520' cy='192' rx='126' ry='100'/%3E%3C/g%3E%3Cg fill='%231F6B00' opacity='0.5'%3E%3Crect x='60' y='196' width='20' height='104' rx='8'/%3E%3Crect x='200' y='226' width='22' height='74' rx='8'/%3E%3Crect x='350' y='204' width='20' height='96' rx='8'/%3E%3Crect x='510' y='232' width='24' height='68' rx='8'/%3E%3C/g%3E%3C/svg%3E");
}

/* Jungle floor. Sits BEHIND the cast (z-index 2) so the ground-dwellers walk
   on top of it rather than being sliced in half by it. */
.hero__ground {
  position: absolute; left: 0; right: 0; bottom: 0; height: 74px; z-index: 2;
  pointer-events: none;
  background: linear-gradient(180deg, #6BAF3A 0%, #4C8A28 46%, #3A6B1E 100%);
  border-top: 4px solid var(--stroke);
}
:root[data-theme="dark"] .hero__ground,
:root:not([data-theme="light"]) .hero__ground {
  background: linear-gradient(180deg, #2C5C22 0%, #1E4418 50%, #143010 100%);
}

/* Hanging vines the swingers use */
.hero__vines { position: absolute; inset: 0; z-index: 3; pointer-events: none; }
.vine-rope {
  position: absolute; top: -8px; width: 8px;
  background: linear-gradient(180deg, #2F8A00, #1F6B00);
  border-radius: 0 0 var(--r-pill) var(--r-pill);
  border: 2px solid var(--stroke); border-top: 0;
}

/* Layers the cast lives in */
.hero__cast   { position: absolute; inset: 0; z-index: 3; pointer-events: none; }
.hero__front  { position: absolute; inset: 0; z-index: 6; pointer-events: none; }

.hero__content {
  position: relative; z-index: 5;
  display: flex; flex-direction: column; align-items: center;
  /* Clearance so the hoppers and walkers along the floor pass BELOW the badge
     row instead of through it. */
  padding: var(--s5) var(--s4) calc(74px + var(--s8));
  gap: var(--s4);
  text-align: center;
}

/* ---------- a creature ---------- */

.cr {
  position: absolute;
  top: var(--y, 40%);
  left: 0;
  will-change: transform;
  animation: crTravel var(--dur, 26s) linear infinite;
  animation-delay: var(--delay, 0s);
}
.cr--rtl { animation-name: crTravelBack; }

.cr__b {
  will-change: transform;
  animation: var(--bob, crBob) var(--bobDur, 2.4s) ease-in-out infinite;
  animation-delay: var(--delay, 0s);
}
.cr__g {
  display: block;
  font-size: var(--size, 46px);
  line-height: 1;
  filter: drop-shadow(0 4px 5px rgba(10,39,84,.28));
  will-change: transform;
  animation: var(--gest, crTilt) var(--gestDur, 1.6s) ease-in-out infinite alternate;
  animation-delay: var(--delay, 0s);
}

@keyframes crTravel     { from { transform: translateX(-16vw); } to { transform: translateX(116vw); } }
@keyframes crTravelBack { from { transform: translateX(116vw); } to { transform: translateX(-16vw); } }

/* vertical behaviours */
@keyframes crBob   { 0%,100% { transform: translateY(0); }      50% { transform: translateY(-16px); } }
@keyframes crGlide { 0%,100% { transform: translateY(0); }      50% { transform: translateY(-34px); } }
@keyframes crHop   {
  0%   { transform: translateY(0)     scaleY(.86) scaleX(1.12); }
  12%  { transform: translateY(-52px) scaleY(1.14) scaleX(.9); }
  30%  { transform: translateY(-62px) scaleY(1); }
  48%  { transform: translateY(0)     scaleY(.82) scaleX(1.16); }
  62%  { transform: translateY(0)     scaleY(1); }
  100% { transform: translateY(0)     scaleY(.86) scaleX(1.12); }
}
@keyframes crCrawl { 0%,100% { transform: translateY(0) scaleX(1); } 50% { transform: translateY(-3px) scaleX(.9); } }
@keyframes crFlat  { 0%,100% { transform: translateY(0); } }

/* gestures */
@keyframes crTilt  { from { transform: rotate(-7deg); }  to { transform: rotate(7deg); } }
@keyframes crFlap  { from { transform: scaleY(.82) rotate(-6deg); } to { transform: scaleY(1.1) rotate(6deg); } }
@keyframes crWig   { from { transform: rotate(-14deg); } to { transform: rotate(14deg); } }
@keyframes crSpin  { from { transform: rotate(0deg); }   to { transform: rotate(360deg); } }

/* Facing rides the standalone `scale` property on the middle wrapper, so it
   composes with the gesture animation instead of being overwritten by it.
   Artwork faces LEFT, so only right-bound creatures are mirrored. */
.cr--mirror .cr__b { scale: -1 1; }

/* ---------- swinging on a vine ---------- */

.swinger {
  position: absolute; top: 0; z-index: 3;
  transform-origin: 50% 0;
  animation: swingArc var(--dur, 3.6s) ease-in-out infinite alternate;
  animation-delay: var(--delay, 0s);
  pointer-events: none;
}
.swinger__rope {
  width: 8px; height: var(--rope, 130px); margin: 0 auto;
  background: linear-gradient(180deg, #2F8A00, #1F6B00);
  border: 2px solid var(--stroke); border-top: 0;
  border-radius: 0 0 4px 4px;
}
.swinger__g { font-size: var(--size, 50px); line-height: 1; filter: drop-shadow(0 5px 6px rgba(10,39,84,.3)); }
@keyframes swingArc { from { transform: rotate(-22deg); } to { transform: rotate(22deg); } }

/* ---------- hanging (sloth) ---------- */
.hanger {
  position: absolute; z-index: 3; pointer-events: none;
  transform-origin: 50% 10%;
  animation: hangSway var(--dur, 5.2s) ease-in-out infinite alternate;
  animation-delay: var(--delay, 0s);
  font-size: var(--size, 46px); line-height: 1;
  filter: drop-shadow(0 5px 6px rgba(10,39,84,.28));
}
@keyframes hangSway { from { transform: rotate(-9deg); } to { transform: rotate(9deg); } }

/* ---------- rocket fly-by ---------- */
.rocketby {
  position: absolute; z-index: 6; pointer-events: none;
  font-size: var(--size, 40px); line-height: 1;
  animation: rocketPath var(--dur, 15s) ease-in infinite;
  animation-delay: var(--delay, 0s);
}
@keyframes rocketPath {
  0%       { transform: translate(-14vw, 34vh) rotate(-38deg); opacity: 0; }
  6%       { opacity: 1; }
  46%      { opacity: 1; }
  60%,100% { transform: translate(112vw, -22vh) rotate(-38deg); opacity: 0; }
}

/* ---------- bubbles rising through the water band ---------- */
.hbub {
  position: absolute; z-index: 3; pointer-events: none;
  width: var(--size, 12px); height: var(--size, 12px);
  border-radius: 50%;
  background: radial-gradient(circle at 32% 28%, rgba(255,255,255,.95), rgba(255,255,255,.25) 58%, transparent);
  border: 1.5px solid rgba(255,255,255,.55);
  animation: hbubRise var(--dur, 7s) linear infinite;
  animation-delay: var(--delay, 0s);
}
@keyframes hbubRise {
  from { transform: translateY(0) translateX(0); opacity: 0; }
  10%  { opacity: .9; }
  90%  { opacity: .7; }
  to   { transform: translateY(-190px) translateX(22px); opacity: 0; }
}

/* Fewer creatures, smaller, on a phone. */
@media (max-width: 720px) {
  .hero { min-height: clamp(380px, 50vh, 460px); }
  .hero__content { padding-bottom: calc(74px + var(--s6)); }
  .cr, .swinger, .hanger, .rocketby { --size: 46px; }
  .cr--optional, .swinger--optional, .hanger--optional { display: none; }
}

/* Motion is the point of this section, but it is never worth a headache. */
@media (prefers-reduced-motion: reduce) {
  .cr, .cr__b, .cr__g, .swinger, .hanger, .rocketby, .hbub { animation: none !important; }
  .cr { transform: translateX(var(--restX, 40vw)); }
  .hbub { opacity: .5; }
}


/* ---------- hero copy ---------- */

/* The hero is deliberately busy, so the one line of text in it has to fight
   for itself: full-strength ink, a heavier weight, and a soft plate behind it. */
.hero .masthead__tag {
  margin: 0;
  max-width: 30ch;
  font-size: clamp(1.0625rem, 2.2vw, 1.375rem);
  font-weight: 800;
  line-height: 1.35;
  color: var(--ink);
  background: color-mix(in srgb, var(--surface) 82%, transparent);
  border: var(--bd) solid var(--stroke);
  border-radius: var(--r-pill);
  padding: var(--s3) var(--s5);
  box-shadow: 0 4px 0 var(--stroke);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

/* ============================================================
   Canopy — a real row of leaves on a branch, moving in the wind.

   Built from individual elements rather than a repeating background image,
   because a background cannot sway. Each leaf carries its own rhythm, and the
   gust is delayed by index so it travels across the screen like actual wind
   rather than every leaf twitching in unison.

   Three nested elements again, one transform each:
     .leaf      the resting tilt and position
     .leaf__s   the constant breeze
     .leaf__g   the gust that rolls through
   ============================================================ */

.canopy {
  position: relative;
  height: 78px;
  overflow: hidden;
  z-index: 8;
  background: transparent;
}

.canopy__branch {
  position: absolute; top: 0; left: 0; right: 0; height: 12px;
  background: linear-gradient(180deg, #2F8A00, #1F6B00);
  border-bottom: 3px solid var(--stroke);
}

.leaf {
  position: absolute;
  top: 8px;
  width: var(--w, 26px);
  height: var(--h, 46px);
  margin-left: calc(var(--w, 26px) / -2);
  transform-origin: 50% 0;
  transform: rotate(var(--tilt, 0deg));
}
.leaf__s {
  display: block; width: 100%; height: 100%;
  transform-origin: 50% 0;
  animation: leafBreeze var(--dur, 3.4s) ease-in-out infinite alternate;
  animation-delay: var(--delay, 0s);
}
.leaf__g {
  display: block; width: 100%; height: 100%;
  transform-origin: 50% 0;
  animation: leafGust 9s ease-in-out infinite;
  animation-delay: var(--gust, 0s);
}
.leaf svg { width: 100%; height: 100%; display: block; overflow: visible; }

@keyframes leafBreeze {
  from { transform: rotate(-5deg) scaleY(.99); }
  to   { transform: rotate(5deg)  scaleY(1.01); }
}

/* A gust: mostly still, then a shove and a couple of decaying bounces back. */
@keyframes leafGust {
  0%, 62%  { transform: rotate(0deg); }
  68%      { transform: rotate(26deg) scaleY(.93); }
  74%      { transform: rotate(-9deg); }
  79%      { transform: rotate(15deg); }
  84%      { transform: rotate(-5deg); }
  89%      { transform: rotate(6deg); }
  95%, 100%{ transform: rotate(0deg); }
}

/* Leaves torn loose and blown across the page. */
.canopy__drift {
  position: absolute; top: 0; left: 0; right: 0; height: 100%;
  pointer-events: none; overflow: visible;
}
.driftleaf {
  position: absolute;
  font-size: var(--size, 20px); line-height: 1;
  animation: driftAcross var(--dur, 14s) linear infinite;
  animation-delay: var(--delay, 0s);
  will-change: transform;
}
.driftleaf__t {
  display: block;
  animation: driftTumble var(--tum, 2.2s) linear infinite;
}
@keyframes driftAcross {
  from { transform: translate(-8vw, 0); opacity: 0; }
  6%   { opacity: 1; }
  92%  { opacity: 1; }
  to   { transform: translate(108vw, 46px); opacity: 0; }
}
@keyframes driftTumble {
  from { transform: rotate(0deg) translateY(0); }
  50%  { transform: rotate(180deg) translateY(14px); }
  to   { transform: rotate(360deg) translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .leaf__s, .leaf__g, .driftleaf, .driftleaf__t { animation: none; }
  .canopy__drift { display: none; }
}
