Skip to content

Commit fcb7b84

Browse files
letter
1 parent c223ff9 commit fcb7b84

7 files changed

Lines changed: 232 additions & 71 deletions

File tree

‎css/08-garden-game-v7-v8.css‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,3 +260,20 @@
260260
.reveal.visible .social-link, .reveal.visible .fact { animation: chipIn 0.6s cubic-bezier(0.34, 1.6, 0.64, 1) backwards; animation-delay: calc(0.5s + var(--ci, 0) * 120ms); }
261261
@media (prefers-reduced-motion: reduce) { .hero-tag, .social-link, .fact { animation: none !important; } .g-sway { transform: none; } }
262262

263+
264+
/* rain cloud click cycle: soft flash, plants perk up, lingering dew, a pale rainbow that fades away */
265+
.g-cloud.g-flash { animation: gCloudGlow 1.1s ease-out; }
266+
.g-cloud.g-flash .cl-body { animation: gCloudDim 1.1s ease-out; }
267+
@keyframes gCloudGlow { 0%, 100% { filter: drop-shadow(0 4px 6px rgba(120, 140, 170, 0.16)); } 35% { filter: drop-shadow(0 0 16px rgba(255, 246, 214, 0.95)); } }
268+
@keyframes gCloudDim { 35% { fill: #cdd7ea; stroke: #8fa8cf; } }
269+
.g-plant.g-perk .g-life { animation: gPerk 2.6s ease-in-out; }
270+
.g-plant.g-perk .g-head { transform-box: fill-box; transform-origin: 50% 60%; animation: gOpen 2.6s ease-in-out; }
271+
@keyframes gPerk { 0%, 100% { transform: none; } 35% { transform: translateY(-4px) scale(1.05, 1.09); } }
272+
@keyframes gOpen { 0%, 100% { transform: scale(1); } 35%, 60% { transform: scale(1.14); } }
273+
.g-dew { width: 5px; height: 6px; margin: -3px 0 0 -2.5px; border-radius: 50% 50% 50% 50% / 40% 40% 60% 60%; background: radial-gradient(circle at 35% 30%, #fff 0 22%, rgba(190, 228, 246, 0.85) 45%, rgba(130, 186, 224, 0.5)); box-shadow: 0 1px 2px rgba(110, 160, 200, 0.3); opacity: 0; animation: gDew 6.2s ease-in-out forwards; }
274+
@keyframes gDew { 0% { opacity: 0; transform: scale(0.4); } 12% { opacity: 1; transform: scale(1); } 70% { opacity: 0.9; } 100% { opacity: 0; transform: translateY(5px) scale(0.8); } }
275+
.g-rainbow { position: absolute; bottom: 24px; z-index: 0; pointer-events: none; opacity: 0; filter: blur(2.5px); animation: gRainbow 7.6s ease-in-out forwards;
276+
background: radial-gradient(ellipse 50% 100% at 50% 100%, transparent 0 56%, rgba(247, 156, 175, 0.5) 59%, rgba(250, 190, 150, 0.5) 62%, rgba(252, 232, 150, 0.5) 65%, rgba(190, 226, 170, 0.5) 68%, rgba(160, 204, 238, 0.5) 71%, rgba(196, 174, 232, 0.5) 74%, transparent 78%);
277+
-webkit-mask-image: linear-gradient(transparent 0, #000 35%); mask-image: linear-gradient(transparent 0, #000 35%); }
278+
@keyframes gRainbow { 0% { opacity: 0; } 25%, 65% { opacity: 0.85; } 100% { opacity: 0; } }
279+
@media (prefers-reduced-motion: reduce) { .g-cloud.g-flash, .g-cloud.g-flash .cl-body, .g-plant.g-perk .g-life, .g-plant.g-perk .g-head { animation: none; } .g-rainbow { animation-duration: 7.6s; filter: none; } }

‎css/11-little-world.css‎

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,20 @@
130130
}
131131
@keyframes envRise { from { opacity: 0; translate: 0 12px; } to { opacity: 1; translate: 0 0; } }
132132

133-
/* hearts: behind the letter, above the pocket; the timeline in JS moves and fades them */
133+
/* temporary opening light and particles: all sit behind the readable letter */
134+
.env-magic { position: absolute; inset: 0; z-index: 1; overflow: visible; pointer-events: none; }
135+
.env-magic[hidden] { display: none; }
136+
.env-glow { position: absolute; left: 50%; top: -74px; width: 260px; height: 190px; border-radius: 50%; opacity: 0; pointer-events: none;
137+
background: radial-gradient(ellipse at 50% 66%, rgba(255, 250, 207, .98) 0%, rgba(255, 220, 151, .62) 28%, rgba(247, 194, 224, .25) 54%, rgba(205, 188, 241, 0) 78%);
138+
filter: blur(10px); transform: translateX(-50%); }
139+
.env-ray { --ray-angle: 0deg; position: absolute; left: 50%; top: -130px; width: 20px; height: 155px; opacity: 0; pointer-events: none; transform-origin: 50% 100%;
140+
background: linear-gradient(to top, rgba(255, 248, 208, .58), rgba(255, 226, 174, .2) 58%, transparent); filter: blur(5px); border-radius: 50% 50% 20% 20%; }
141+
.env-ray.r1 { --ray-angle: -48deg; } .env-ray.r2 { --ray-angle: -24deg; height: 170px; top: -145px; }
142+
.env-ray.r3 { --ray-angle: 25deg; height: 164px; top: -139px; } .env-ray.r4 { --ray-angle: 49deg; }
134143
.env-hearts { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
135-
.env-heart { position: absolute; left: 26px; top: 12px; width: 12px; height: 11px; opacity: 0; pointer-events: none; }
144+
.env-heart { position: absolute; left: 24px; top: 11px; width: 18px; height: 17px; opacity: 0; pointer-events: none; filter: drop-shadow(0 2px 3px rgba(163, 104, 137, .18)); }
136145
.env-heart svg { display: block; width: 100%; height: 100%; }
137-
.env-spark { width: 10px; height: 10px; left: 27px; top: 13px; }
146+
.env-spark { width: 10px; height: 10px; left: 27px; top: 13px; filter: drop-shadow(0 0 3px rgba(255, 226, 151, .45)); }
138147

139148
/* the letter box clips only what would hang below the envelope; everything above and beside it is free */
140149
.env-letter-box { position: absolute; inset: 0; z-index: 3; pointer-events: none; clip-path: inset(-600px -240px 4px -240px); }
@@ -177,5 +186,7 @@
177186
.w-envelope, .w-envelope.settling, .env-back { transition: none; }
178187
.env-letter { transition: opacity 0.3s ease; }
179188
.env-hearts { display: none; }
189+
.env-magic .env-ray { display: none; }
190+
.env-magic.is-still .env-glow { opacity: .24; transform: translate(-50%, -2px) scale(.95); }
180191
}
181192
@keyframes envFade { from { opacity: 0; } to { opacity: 1; } }

‎index.html‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
<link rel="stylesheet" href="css/05-fx-titles-gallery-cursor.css?v=2">
1717
<link rel="stylesheet" href="css/06-backgrounds-rainbow-gallery.css?v=2">
1818
<link rel="stylesheet" href="css/07-living-background-v4-v6.css?v=2">
19-
<link rel="stylesheet" href="css/08-garden-game-v7-v8.css?v=3">
19+
<link rel="stylesheet" href="css/08-garden-game-v7-v8.css?v=4">
2020
<link rel="stylesheet" href="css/09-v9-refinements.css?v=2">
2121
<link rel="stylesheet" href="css/10-botanical.css?v=3">
22-
<link rel="stylesheet" href="css/11-little-world.css?v=12">
22+
<link rel="stylesheet" href="css/11-little-world.css?v=13">
2323
<link rel="stylesheet" href="css/12-polish-pass.css?v=2">
2424
<link rel="stylesheet" href="css/13-ecosystem.css?v=2">
2525
<link rel="stylesheet" href="css/14-side-vines-plants.css?v=3">
@@ -721,7 +721,7 @@ <h2 class="contact-title">Let's <em>Connect</em></h2>
721721
<script src="js/core/utils.js?v=1" defer></script>
722722
<script src="js/core/scheduler.js?v=2" defer></script>
723723
<script src="js/core/state.js?v=1" defer></script>
724-
<script src="js/core/particles.js?v=1" defer></script>
724+
<script src="js/core/particles.js?v=2" defer></script>
725725
<script src="js/core/safe-zones.js?v=1" defer></script>
726726
<script src="js/core/world.js?v=1" defer></script>
727727
<script src="js/gallery/artworks.js?v=1" defer></script>
@@ -739,12 +739,12 @@ <h2 class="contact-title">Let's <em>Connect</em></h2>
739739
<script src="js/animals/art.js?v=2" defer></script>
740740
<script src="js/plants/plants.js?v=2" defer></script>
741741
<script src="js/plants/vine-sprigs.js?v=4" defer></script>
742-
<script src="js/environment/weather.js?v=3" defer></script>
742+
<script src="js/environment/weather.js?v=4" defer></script>
743743
<script src="js/garden/species.js?v=1" defer></script>
744744
<script src="js/garden/hud.js?v=1" defer></script>
745745
<script src="js/garden/critters.js?v=1" defer></script>
746746
<script src="js/animals/deer.js?v=2" defer></script>
747-
<script src="js/garden/garden.js?v=1" defer></script>
747+
<script src="js/garden/garden.js?v=2" defer></script>
748748
<script src="js/animals/animals.js?v=1" defer></script>
749749
<script src="js/animals/guide-bird.js?v=1" defer></script>
750750
<script src="js/animals/birds.js?v=4" defer></script>
@@ -757,7 +757,7 @@ <h2 class="contact-title">Let's <em>Connect</em></h2>
757757
<script src="js/botanical/stage.js?v=2" defer></script>
758758
<script src="js/botanical/links.js?v=1" defer></script>
759759
<script src="js/easter-eggs/easter-eggs.js?v=1" defer></script>
760-
<script src="js/easter-eggs/envelope.js?v=21" defer></script>
760+
<script src="js/easter-eggs/envelope.js?v=24" defer></script>
761761
<script src="js/environment/breeze.js?v=2" defer></script>
762762
<script src="js/animals/caterpillar.js?v=2" defer></script>
763763
<script src="js/plants/dandelions.js?v=2" defer></script>

‎js/core/particles.js‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@ MB.define('core.particles', [], function () {
1111
let live = 0; const MAX = innerWidth < 700 ? 28 : 48;
1212
return {
1313
room: n => Math.max(0, Math.min(n, MAX - live)),
14-
/* el is removed (and its slot returned) when its animation ends, or after ms at the latest */
14+
/* Removes el and returns its slot on finish/timeout; the returned function also cleans up immediately. */
1515
track(el, anim, ms) {
1616
live++; let done = false;
17-
const end = () => { if (done) return; done = true; live--; el.remove(); };
18-
if (anim) anim.onfinish = end; setTimeout(end, ms || 4000);
17+
const end = () => { if (done) return; done = true; clearTimeout(timer); live--; el.remove(); };
18+
const timer = setTimeout(end, ms || 4000);
19+
if (anim) anim.onfinish = end;
20+
return end;
1921
},
2022
/* for particles moved by a script loop instead of an animation */
2123
claim: n => { const k = Math.max(0, Math.min(n, MAX - live)); live += k; return k; },

0 commit comments

Comments
 (0)