/* Seasons Smash — a scene that sits still while the canvas on top of it goes
   wild. Everything here is CSS/SVG so there are no image assets to ship.

   All four seasons share one skeleton and differ only in these custom
   properties, so adding a fifth would mean one [data-season] block. */

*, *::before, *::after { box-sizing: border-box; }

/* ---------------------------------------------------------------- themes */

[data-season="summer"] {
  --sky: linear-gradient(#1f8fe0 0%, #4fb4f2 30%, #8fd8fb 62%, #ffe1a8 88%, #ffd08a 100%);
  --sun-core: radial-gradient(circle at 38% 34%, #fffdf0 0%, #ffe66b 45%, #ffb43d 100%);
  --sun-glow: rgba(255, 214, 92, .85);
  --sun-glow-far: rgba(255, 190, 60, .45);
  --sun-ray: rgba(255, 236, 150, .55);
  --cloud: #fff;
  --bird: rgba(255, 255, 255, .9);
  --mid: linear-gradient(#5fd8e8 0%, #1fb6d8 35%, #0b8fbf 100%);
  --band-far: rgba(255, 255, 255, .28);
  --band-mid: rgba(255, 255, 255, .38);
  --band-near: rgba(224, 250, 255, .75);
  --glint: rgba(255, 255, 255, .62);
  --shore: rgba(255, 255, 255, .95);
  --ground: linear-gradient(#f6dfa8 0%, #e8c684 55%, #d9b06a 100%);
  --ground-lip: #ffeec4;
  --grain-a: rgba(160, 120, 60, .25);
  --grain-b: rgba(255, 255, 255, .4);
  --trunk: #8a5a33;
  --leaf: #2fa14a;
  --leaf-alt: #268940;
  --fruit: #5c3a1e;
  --ambient-glyph: "";
  --accent: #e4572e;
  --accent-2: #ffd166;
  --ink: #06405f;
  --ink-soft: #17627f;
}

[data-season="spring"] {
  --sky: linear-gradient(#3f9ee6 0%, #6fbdf2 28%, #a9dbf9 58%, #d8f0e6 84%, #eaf7d9 100%);
  --sun-core: radial-gradient(circle at 38% 34%, #fffef2 0%, #fff3a8 48%, #ffd76b 100%);
  --sun-glow: rgba(255, 240, 150, .8);
  --sun-glow-far: rgba(255, 225, 120, .4);
  --sun-ray: rgba(255, 246, 190, .5);
  --cloud: #fff;
  --bird: rgba(255, 255, 255, .95);
  --mid: linear-gradient(#a5dd82 0%, #74c159 40%, #4f9e3c 100%);
  --band-far: rgba(255, 255, 255, .3);
  --band-mid: rgba(196, 232, 160, .75);
  --band-near: rgba(150, 209, 118, .9);
  --glint: rgba(255, 255, 255, .5);
  --shore: rgba(255, 255, 255, .8);
  --ground: linear-gradient(#a8dd85 0%, #79c25c 55%, #5aa544 100%);
  --ground-lip: #cdf0ad;
  --grain-a: rgba(60, 120, 40, .22);
  --grain-b: rgba(255, 255, 255, .35);
  --trunk: #8a6a4a;
  --leaf: #ffc0d9;
  --leaf-alt: #ffa8c9;
  --fruit: #fff6fa;
  --ambient-glyph: "🌸";
  --accent: #e8578f;
  --accent-2: #ffd166;
  --ink: #2c5c2f;
  --ink-soft: #4a7d4a;
}

[data-season="fall"] {
  --sky: linear-gradient(#3d7ea6 0%, #6ba5c4 26%, #a8c7d4 52%, #f2c98b 82%, #eda866 100%);
  --sun-core: radial-gradient(circle at 38% 34%, #fff6de 0%, #ffd98a 46%, #f0a94f 100%);
  --sun-glow: rgba(255, 190, 120, .72);
  --sun-glow-far: rgba(230, 150, 80, .4);
  --sun-ray: rgba(255, 214, 160, .45);
  --cloud: #f3e7d8;
  --bird: rgba(90, 60, 40, .75);
  --mid: linear-gradient(#c8752f 0%, #a55a24 42%, #7a3d18 100%);
  --band-far: rgba(255, 200, 130, .3);
  --band-mid: rgba(196, 108, 46, .6);
  --band-near: rgba(150, 74, 32, .85);
  --glint: rgba(255, 214, 150, .45);
  --shore: rgba(240, 200, 150, .7);
  --ground: linear-gradient(#e8b06a 0%, #cf8a45 55%, #a9662f 100%);
  --ground-lip: #f6d3a0;
  --grain-a: rgba(120, 60, 20, .28);
  --grain-b: rgba(255, 220, 170, .4);
  --trunk: #7a5133;
  --leaf: #d9622b;
  --leaf-alt: #e8862f;
  --fruit: #c0442a;
  --ambient-glyph: "🍁";
  --accent: #c8471c;
  --accent-2: #f0a94f;
  --ink: #5a3212;
  --ink-soft: #8a5a2a;
}

[data-season="winter"] {
  --sky: linear-gradient(#5f83bd 0%, #8aabd6 28%, #b8cfe9 56%, #dbe9f7 82%, #eef5fc 100%);
  --sun-core: radial-gradient(circle at 38% 34%, #ffffff 0%, #eaf4ff 50%, #cfe2f7 100%);
  --sun-glow: rgba(220, 238, 255, .8);
  --sun-glow-far: rgba(190, 215, 245, .4);
  --sun-ray: rgba(235, 245, 255, .4);
  --cloud: #eef4fb;
  --bird: rgba(70, 90, 120, .7);
  --mid: linear-gradient(#f4f9ff 0%, #dbe8f7 45%, #b9cfe8 100%);
  --band-far: rgba(255, 255, 255, .7);
  --band-mid: rgba(234, 243, 255, .9);
  --band-near: rgba(214, 231, 249, .95);
  --glint: rgba(255, 255, 255, .75);
  --shore: rgba(255, 255, 255, .95);
  --ground: linear-gradient(#ffffff 0%, #eaf2fb 55%, #d3e2f2 100%);
  --ground-lip: #ffffff;
  --grain-a: rgba(150, 180, 210, .3);
  --grain-b: rgba(255, 255, 255, .6);
  --trunk: #5a3f2b;
  --leaf: #2f6b45;
  --leaf-alt: #275c3b;
  --fruit: #ffffff;
  --ambient-glyph: "❄️";
  --accent: #3b7fc4;
  --accent-2: #a5d8ff;
  --ink: #1e3f63;
  --ink-soft: #3d6a94;
}

/* ------------------------------------------------------------------- base */

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: #38b6ff;
  font-family: "Baloo 2", "Comic Sans MS", "Trebuchet MS", system-ui, sans-serif;
  /* Toddlers drag. Nothing should select, scroll, or bounce. */
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  overscroll-behavior: none;
  touch-action: none;
  cursor: default;
}

/* ------------------------------------------------------------------ scene */

.scene { position: fixed; inset: 0; overflow: hidden; }

.sky {
  position: absolute;
  inset: 0 0 38% 0;
  background: var(--sky);
}

/* --- sun --- */
.sun {
  position: absolute;
  top: 7vh; right: 12vw;
  width: 18vmin; height: 18vmin;
  display: grid; place-items: center;
}
.sun-core {
  position: absolute;
  width: 100%; height: 100%;
  border-radius: 50%;
  background: var(--sun-core);
  box-shadow: 0 0 6vmin var(--sun-glow), 0 0 16vmin var(--sun-glow-far);
  will-change: transform;
  animation: pulse 5s ease-in-out infinite;
}
.sun-rays {
  position: absolute;
  width: 300%; height: 300%;
  border-radius: 50%;
  background: repeating-conic-gradient(
    var(--sun-ray) 0deg 5deg,
    rgba(255, 255, 255, 0) 5deg 18deg);
  -webkit-mask-image: radial-gradient(circle, #000 18%, transparent 62%);
  mask-image: radial-gradient(circle, #000 18%, transparent 62%);
  /* Promoted so the conic gradient and its mask rasterise once, then the
     compositor just spins the layer. */
  will-change: transform;
  animation: spin 70s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes pulse { 50% { transform: scale(1.05); } }

/* --- clouds --- */
.clouds { position: absolute; inset: 0 0 auto 0; height: 46%; }
.cloud { position: absolute; left: 0; width: 26vmin; height: 7vmin; will-change: translate; }
.cloud i {
  position: absolute;
  bottom: 0;
  background: var(--cloud);
  border-radius: 50%;
  filter: blur(.2vmin);
  opacity: .93;
}
.cloud i:nth-child(1) { left: 0;   width: 55%; height: 100%; }
.cloud i:nth-child(2) { left: 26%; width: 60%; height: 150%; }
.cloud i:nth-child(3) { left: 58%; width: 45%; height: 92%; }
.c1 { top: 8%;  animation: drift 64s linear infinite; }
.c2 { top: 24%; transform: scale(.7); opacity: .85; animation: drift 92s linear infinite -30s; }
.c3 { top: 3%;  transform: scale(1.3); opacity: .7;  animation: drift 120s linear infinite -70s; }
/* `translate`, not `left`: animating `left` relayouts the whole scene every
   frame. Using the standalone translate property rather than a transform
   leaves `transform` free for the per-cloud scale and the birds' wing flap. */
@keyframes drift {
  from { translate: -30vmin 0; }
  to   { translate: 105vw 0; }
}

/* --- birds --- */
.birds { position: absolute; inset: 0 0 auto 0; height: 40%; }
.bird {
  position: absolute;
  width: 7vmin;
  fill: none;
  stroke: var(--bird);
  stroke-width: 1.4;
  stroke-linecap: round;
}
.b1 { top: 22%; left: 0; animation: drift 48s linear infinite -6s, flap 1.1s ease-in-out infinite; }
.b2 { top: 30%; left: 0; width: 5vmin; animation: drift 61s linear infinite -24s, flap 1.4s ease-in-out infinite; }
@keyframes flap { 50% { transform: scaleY(.55); } }

/* --- midground: sea, hills, snowfield, meadow --- */
.midground { position: absolute; left: 0; right: 0; top: 46%; bottom: 22%; }
.midground-body { position: absolute; inset: 0; background: var(--mid); }

/* Glints: long thin highlights, not dots. The gradients fade out softly
   enough on their own that no blur filter is needed — and a filter on a layer
   that animates is re-applied every frame, which isn't worth it here. */
.glints {
  position: absolute; inset: 0;
  background-image:
    radial-gradient(ellipse 3.5vmin .4vmin at 30% 50%, var(--glint), transparent 78%),
    radial-gradient(ellipse 2.2vmin .35vmin at 70% 50%, var(--glint), transparent 78%);
  background-size: 17vmin 7vmin, 11vmin 4.5vmin;
  opacity: .5;
  will-change: translate, opacity;
  animation: shimmer 7s ease-in-out infinite alternate;
}
/* Sliding the layer rather than its background-position: the same drift, but
   composited instead of repainting the whole midground each frame. */
@keyframes shimmer {
  from { translate: 0 0;            opacity: .32; }
  to   { translate: 2.5vmin .6vmin; opacity: .6; }
}

/* Two screens wide; a 50% slide lands on an identical crest. */
.band {
  position: absolute;
  left: 0;
  width: 200%;
  height: 9vmin;
  will-change: transform;
}
.b-far  { bottom: 34%; fill: var(--band-far);  animation: roll 13s linear infinite; }
.b-mid  { bottom: 14%; fill: var(--band-mid);  animation: roll 9s linear infinite reverse; }
.b-near { bottom: -3%; fill: var(--band-near); animation: roll 7s linear infinite; }
@keyframes roll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
/* On land the bands are hills, not water: they shouldn't scroll sideways. */
[data-season="spring"] .band,
[data-season="fall"] .band,
[data-season="winter"] .band { animation: none; width: 100%; }
[data-season="spring"] .glints,
[data-season="fall"] .glints { opacity: .25; }

/* --- shore line + ground --- */
.shore {
  position: absolute;
  left: 0; right: 0;
  top: 76%;
  height: 5vmin;
  background: radial-gradient(ellipse at 50% 0%, var(--shore) 0%, transparent 76%);
  will-change: transform;
  animation: lap 7s ease-in-out infinite alternate;
}
@keyframes lap { to { transform: translateY(1.6vmin) scaleX(1.04); } }
[data-season="fall"] .shore,
[data-season="winter"] .shore,
[data-season="spring"] .shore { animation: none; }

.ground {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 22%;
  background:
    radial-gradient(ellipse 60% 100% at 50% 0%, var(--ground-lip) 0%, transparent 60%),
    var(--ground);
}
.ground::after { /* grain / texture */
  content: "";
  position: absolute; inset: 0;
  background-image:
    radial-gradient(circle, var(--grain-a) 40%, transparent 41%),
    radial-gradient(circle, var(--grain-b) 40%, transparent 41%);
  background-size: 1.1vmin 1.1vmin, 1.7vmin 1.7vmin;
  opacity: .4;
}

/* --- props --- */
.props { position: absolute; inset: 0; display: none; }
[data-season="spring"] .props-spring,
[data-season="summer"] .props-summer,
[data-season="fall"]   .props-fall,
[data-season="winter"] .props-winter { display: block; }
.props i {
  position: absolute;
  font-style: normal;
  font-size: 5vmin;
  filter: drop-shadow(0 .4vmin .4vmin rgba(90, 70, 40, .3));
}
.p1 { left: 14%; top: 42%; transform: rotate(-16deg); }
.p2 { left: 72%; top: 26%; font-size: 4vmin; transform: rotate(12deg); }
.p3 { left: 47%; top: 58%; font-size: 6vmin; animation: scuttle 9s ease-in-out infinite alternate; }
.p4 { right: 9%; top: 46%; font-size: 7vmin; }
@keyframes scuttle { to { transform: translateX(14vw) scaleX(-1); } }

/* --- trees --- */
.tree {
  position: absolute;
  left: 2vw; bottom: 0;
  height: 62vh;
  transform-origin: 50% 100%;
  display: none;
  will-change: transform;
  animation: sway 7s ease-in-out infinite alternate;
  filter: drop-shadow(0 1vmin 1vmin rgba(0, 0, 0, .18));
}
[data-season="spring"] .tree-spring,
[data-season="summer"] .tree-summer,
[data-season="fall"]   .tree-fall,
[data-season="winter"] .tree-winter { display: block; }
.tree .trunk  { fill: var(--trunk); }
.tree .leaves { fill: var(--leaf); }
.tree .leaves > *:nth-child(even) { fill: var(--leaf-alt); }
.tree .fruit  { fill: var(--fruit); }
.tree .snow   { fill: rgba(255, 255, 255, .92); }
@keyframes sway { to { transform: rotate(2.2deg); } }
/* An evergreen under snow doesn't sway like a palm. */
[data-season="winter"] .tree { animation-duration: 12s; }

/* --- falling leaves / snow / blossom --- */
.ambient { position: absolute; inset: 0; overflow: hidden; }
[data-season="summer"] .ambient { display: none; }
.ambient i {
  position: absolute;
  top: 0; left: var(--x);
  font-style: normal;
  font-size: 3.4vmin;
  opacity: 0;
  animation: descend var(--d) linear var(--delay) infinite;
}
.ambient i::before { content: var(--ambient-glyph); }
@keyframes descend {
  0%   { transform: translate3d(0, -12vh, 0) rotate(0deg); opacity: 0; }
  8%   { opacity: .95; }
  92%  { opacity: .95; }
  100% { transform: translate3d(7vw, 108vh, 0) rotate(420deg); opacity: 0; }
}

/* ------------------------------------------------------------------ canvas */

#fx {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 5;
  pointer-events: none;
}

/* ------------------------------------------------------------------- gate */

#gate {
  position: fixed;
  inset: 0;
  z-index: 20;
  display: grid;
  place-items: center;
  /* A plain tint rather than backdrop-filter: blurring the whole viewport is
     expensive, and this is the first thing a slow machine has to paint. */
  background: rgba(4, 40, 65, .5);
  padding: 4vmin;
}
#gate.gone { display: none; }

.gate-card {
  position: relative;
  max-width: min(92vw, 700px);
  padding: 5vmin 6vmin;
  border-radius: 4vmin;
  text-align: center;
  color: var(--ink);
  background: linear-gradient(#fffdf6, #fff5e4);
  box-shadow: 0 2vmin 6vmin rgba(0, 30, 60, .45), inset 0 0 0 .6vmin var(--accent-2);
}
.gate-card h1 {
  margin: 0;
  font-size: clamp(26px, 5.6vmin, 52px);
  letter-spacing: .5px;
  text-wrap: balance;
  color: var(--accent);
  text-shadow: 0 .5vmin 0 var(--accent-2);
}
.ico-l::before { content: var(--ambient-glyph, "🏖️"); }
.ico-r::before { content: var(--ambient-glyph, "🌊"); }
[data-season="summer"] .ico-l::before { content: "🏖️"; }
[data-season="summer"] .ico-r::before { content: "🌊"; }
.gate-card h1 span { display: inline-block; animation: bob 2.4s ease-in-out infinite; }
.gate-card h1 span:last-child { animation-delay: .6s; }
@keyframes bob { 50% { transform: translateY(-.9vmin) rotate(-6deg); } }

.tag { margin: 1.6vmin 0 3.6vmin; font-size: clamp(15px, 2.6vmin, 24px); color: var(--ink-soft); }

#play {
  font: inherit;
  font-size: clamp(20px, 4.4vmin, 40px);
  font-weight: 700;
  color: #fff;
  padding: 2.2vmin 7vmin;
  border: none;
  border-radius: 99px;
  background: linear-gradient(color-mix(in srgb, var(--accent) 82%, #fff),
                              var(--accent));
  box-shadow: 0 1.2vmin 0 color-mix(in srgb, var(--accent) 70%, #000),
              0 2vmin 3vmin rgba(0, 0, 0, .25);
  cursor: pointer;
  transition: transform .08s ease, box-shadow .08s ease;
}
#play:hover { transform: translateY(-.3vmin); }
#play:active {
  transform: translateY(1.1vmin);
  box-shadow: 0 .2vmin 0 color-mix(in srgb, var(--accent) 70%, #000);
}

/* --------------------------------------------------------- season picker */

.seasons {
  display: flex;
  justify-content: center;
  gap: 1.4vmin;
  flex-wrap: wrap;
  margin: 4vmin 0 0;
}
.season-btn {
  font: inherit;
  font-size: clamp(11px, 1.9vmin, 16px);
  font-weight: 700;
  color: var(--ink-soft);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .4vmin;
  padding: 1.4vmin 2.4vmin;
  min-width: 17vmin;
  border: none;
  border-radius: 2.2vmin;
  background: rgba(0, 0, 0, .05);
  box-shadow: inset 0 0 0 .3vmin transparent;
  cursor: pointer;
  transition: background .15s ease, box-shadow .15s ease, transform .1s ease;
}
.season-btn b { font-size: clamp(18px, 3.4vmin, 30px); line-height: 1; }
.season-btn:hover { background: rgba(0, 0, 0, .09); transform: translateY(-.3vmin); }
.season-btn.on {
  color: var(--accent);
  background: #fff;
  box-shadow: inset 0 0 0 .4vmin var(--accent-2), 0 .6vmin 1.2vmin rgba(0, 0, 0, .12);
}

.notes {
  margin: 3.4vmin 0 0;
  padding: 0;
  list-style: none;
  font-size: clamp(12px, 2vmin, 17px);
  line-height: 1.75;
  color: var(--ink-soft);
}

/* ------------------------------------------------------ more games badge */

/* Top-right of the start screen. It sits inside #gate, so it disappears the
   moment play begins — a live link on screen during play would be an escape
   hatch for exactly the person this app is built to contain. */
#more-games {
  position: fixed;
  top: 2.5vmin; right: 2.5vmin;
  z-index: 22;
  display: flex;
  align-items: center;
  gap: 1.2vmin;
  padding: 1.1vmin 2.4vmin;
  border-radius: 99px;
  text-decoration: none;
  font-weight: 800;
  font-size: clamp(12px, 1.9vmin, 17px);
  color: #06405f;
  background: linear-gradient(#fff6d8, #ffd166);
  border: .45vmin solid #06405f;
  box-shadow: 0 .8vmin 0 rgba(6, 64, 95, .35), 0 1.4vmin 3vmin rgba(0, 30, 60, .3);
  animation: nudge 3.4s ease-in-out infinite;
  transition: transform .1s ease, box-shadow .1s ease;
}
#more-games:hover { transform: translateY(-.4vmin); box-shadow: 0 1.2vmin 0 rgba(6,64,95,.35), 0 2vmin 3.4vmin rgba(0,30,60,.34); }
#more-games:active { transform: translateY(.5vmin); box-shadow: 0 .2vmin 0 rgba(6,64,95,.35); }
.mg-ico { font-size: clamp(16px, 2.6vmin, 24px); line-height: 1; }
/* Wiggles every few seconds so a passing grown-up notices it. */
@keyframes nudge {
  0%, 88%, 100% { transform: rotate(0deg); }
  91% { transform: rotate(-3deg) scale(1.04); }
  95% { transform: rotate(3deg) scale(1.04); }
}
@media (max-width: 560px) {
  .mg-txt { display: none; }        /* just the controller on small screens */
  #more-games { padding: 1.4vmin 1.8vmin; }
}

/* Moved to the left so it doesn't collide with the badge. */
.mute {
  position: fixed;
  top: 2.5vmin; left: 2.5vmin;
  width: 8vmin; height: 8vmin;
  max-width: 54px; max-height: 54px;
  font-size: clamp(18px, 3.6vmin, 26px);
  line-height: 1;
  border: none;
  border-radius: 50%;
  background: #ffe9b0;
  box-shadow: inset 0 0 0 .4vmin var(--accent-2);
  cursor: pointer;
}
.mute.off { filter: grayscale(1); opacity: .6; }

/* -------------------------------------------------------------- exit hint */

#exit-hint {
  position: fixed;
  left: 50%; bottom: 1.6vmin;
  transform: translateX(-50%);
  z-index: 15;
  padding: .8vmin 2.4vmin;
  border-radius: 99px;
  font-size: clamp(10px, 1.7vmin, 14px);
  color: rgba(255, 255, 255, .8);
  background: rgba(0, 40, 70, .3);
  opacity: 0;
  transition: opacity .5s ease;
  pointer-events: none;
}
#exit-hint.show { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .sun-rays, .sun-core, .cloud, .bird, .band, .shore, .p3, .tree, .glints,
  .ambient i, .gate-card h1 span { animation: none !important; }
  .ambient i { opacity: .9; }
}
