Skip to content

Commit dea1370

Browse files
intro animation, fixing bird nest feeding, critters under leaf
1 parent 05735bc commit dea1370

12 files changed

Lines changed: 405 additions & 119 deletions

‎ARCHITECTURE.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ separate, later phase (never mixed into structural moves).
2626
| a creature (new or existing) | `animals/animals.js` + that creature's file + `core/scheduler.js` + `css/animals.css` |
2727
| deer | `animals/deer.js` + garden host API in `garden/garden.js` |
2828
| page snails (tap, peek, crawl, trail) | `animals/snails.js` (+ `weather.onRain` hook) |
29-
| tapping a decorative leaf (ladybug, caterpillar, bee, beetle come out and move on) | `animals/insects.js` (+ `.insect` rules in `css/11-little-world.css`) |
29+
| tapping a decorative leaf (ladybug, caterpillar, beetle come out and crawl away) | `animals/insects.js` (+ `.insect` rules in `css/11-little-world.css`) |
3030
| birds / nest / seed feeding | `animals/birds.js` (guide bird: `animals/guide-bird.js`) |
3131
| the bird family by the DeviantArt button (eggs, chicks) | `animals/nest.js` (uses `birds.visitingBird`, `birds.seed.onDrop`) |
3232
| weather, rain, sun, wind | `environment/weather.js` or `breeze.js` + `css/environment.css` |
@@ -36,6 +36,7 @@ separate, later phase (never mixed into structural moves).
3636
| footer garden game | `garden/*` + `css/garden.css` |
3737
| Experience / Skills / bouquet | `botanical/*` + `css/botanical.css` |
3838
| gallery / lightbox | `gallery/*` + `css/gallery.css` |
39+
| opening intro animation (transparent canvas over the live page: golden ignition → screen-wide burst → pastel sparkle + petal rainfall, every page load) | `site/intro.js` + `css/15-intro.css` + the gate script in `index.html` `<head>` |
3940
| nav, hero, scrolling effects | `navigation/`, `site/hero.js`, `effects/*` |
4041
| Easter egg | `easter-eggs/easter-eggs.js` (secret bird-delivered envelope: `easter-eggs/envelope.js`) |
4142
| persistence, random timing, cursor tracking, "is this spot free?" | `core/state.js`, `core/scheduler.js`, `core/pointer.js`, `core/safe-zones.js` |
@@ -242,7 +243,7 @@ bouquet and ribbon, ways-in links, "seed of curiosity". Not: the footer garden,
242243
- `guide-bird.js`: the red banner bird (own spot-finding, scroll re-check, bubble). Independent logic, own file.
243244
- `vine-caterpillar.js`: crawls along vine paths (own physics/rAF/eating). `caterpillar.js`: the story twig caterpillar → chrysalis → butterfly life cycle.
244245
- `snails.js`: a few tappable snails resting in open margins (hide/peek/emerge, crawl to a nearby plant with a fading dew trail); reacts to rain through `weather.onRain`.
245-
- `insects.js`: tap a decorative leaf (`.sc-leaf`) and a ladybug (most often), caterpillar, bee or beetle comes out, crawls round the leaf and moves to another decorative leaf/bloom/posy; tap it to hop again. One module for every leaf; reads decor/creature geometry, never mutates it.
246+
- `insects.js`: tap a standalone decorative leaf (`.sc-leaf` plus the two hero leaves `.hero-flowers .bloom.f5/.f8`) and a ladybug, caterpillar or beetle (in rotation) comes out from under it and crawls away along its own randomized, curved route until it is off screen, then is removed (routes avoid content, flower clusters, vines and other critters; blocked = fade out). One module for every leaf; reads decor/creature geometry, never mutates it.
246247
- `butterflies.js`: drifting butterfly, vine butterflies, visitor butterfly/bee, tiny touch-butterfly. `deer.js`: the garden deer.
247248

248249
**environment/** `weather.js`: rain clouds (garden and page), sun toggle, rainbow after rain. `breeze.js`: cursor-driven forces on plants

‎CLAUDE.md‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ It must work from `file://` (double-click), a local server (`python3 -m http.ser
88
- **`ARCHITECTURE.md`** before any structural or feature work. Its routing table says which files to read for a given request.
99
- **`MIGRATION_PLAN.md`** is historical/reference only. Read it only for requests about unfinished migration work (code may still live in `js/legacy/*` / `ecosystem.js` / `style.css`; ARCHITECTURE §0 maps where). Do not mix feature work into a migration step.
1010

11+
## Testing / Verification
12+
For normal website edits:
13+
14+
- Do not run the full test suite, browser automation, headless browsers, or extensive verification unless I explicitly request it.
15+
- Do not set up Playwright, Puppeteer, Selenium, or any new testing harness just to verify a change.
16+
- After an edit, perform only a quick syntax/basic sanity check if needed.
17+
- Do not let testing or verification block completion of the requested edit.
18+
- If an existing test or command hangs, stop it and continue rather than troubleshooting the test environment.
19+
- Only perform extensive testing when I explicitly ask for it.
20+
1121
## Background features
1222
Before adding or modifying background decorations, plants, creatures, ambient effects, or draggable objects, read `BACKGROUND_RULES.md` and the relevant ownership guidance in `ARCHITECTURE.md`.
1323
These are global rules. Apply them to every background feature unless I explicitly override them.

‎css/02-spring-theme.css‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ h1, h2, h3, h4, .section-title{ font-variation-settings: 'SOFT' 100; letter-spac
3737
.bloom.f6 { width: 38px; height: 38px; top: 12%; right: 6%; animation-delay: 1.4s, -14s; animation-duration: 1.4s, 34s; }
3838
.bloom.f7 { width: 52px; height: 52px; bottom: 9%; left: 40%; animation-delay: 1.6s, -8s; }
3939
.bloom.f8 { width: 30px; height: 30px; bottom: 19%; right: 9.5%; animation: bloomIn 1.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards 1.2s, leafSway 6s ease-in-out infinite -2s; }
40+
.bloom.f9 { width: 32px; height: 32px; top: 14%; left: 24%; animation: bloomIn 1.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards 1.5s, leafSway 5.5s ease-in-out infinite -1s; }
41+
@media (max-width: 1099px) { .bloom.f9 { display: none; } } /* tablet and phone: the hero text runs under it */
4042
@keyframes bloomIn { from { opacity: 0; scale: 0.2; } to { opacity: 1; scale: 1; } }
4143
@keyframes spinSlow { to { rotate: 360deg; } }
4244
@keyframes leafSway { 0%, 100% { rotate: -12deg; } 50% { rotate: 14deg; } }

‎css/10-botanical.css‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ main > section, footer { overflow: visible; }
469469
.to-top { width: 38px !important; height: 63px !important; right: calc(2px + var(--safe-r)) !important; bottom: calc(6px + var(--safe-b)) !important; }
470470
.to-top::after { content: ''; position: absolute; inset: -6px -2px -6px -8px; }
471471
footer { padding-bottom: calc(100px + var(--safe-b)) !important; }
472-
.bloom.f1, .bloom.f5 { display: none; }
472+
.bloom.f1, .bloom.f5, .bloom.f9 { display: none; }
473473
}
474474

475475
/* ---------------------------------------------------------------------

‎css/11-little-world.css‎

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -243,25 +243,19 @@
243243
@media (max-width: 699px) { .sn-say { font-size: 11px; padding: 3px 8px; max-width: min(130px, 44vw); } }
244244
@media (prefers-reduced-motion: reduce) { .sn-say { animation: none; } }
245245

246-
/* ---- insects that come out from under a tapped decorative leaf (js/animals/insects.js) ---- */
246+
/* ---- insects that come out from under a tapped decorative leaf (js/animals/insects.js): they never take taps; they just crawl away ---- */
247247
.insect { position: absolute; left: 0; top: 0; z-index: 2; pointer-events: none; opacity: 0; transition: opacity .35s ease; will-change: transform; touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
248248
.insect.is-in { opacity: 1; }
249249
.insect.is-out { opacity: 0; transition-duration: .5s; }
250250
.insect.is-under { z-index: 0; } /* beneath the leaf (z-index 1) while it slips out */
251-
.insect.is-landed { pointer-events: auto; cursor: pointer; }
252-
.insect.is-landed::after { content: ''; position: absolute; inset: -8px; } /* a forgiving tap area */
251+
.hero-flowers .insect.is-under { z-index: -1; } /* the hero leaves sit in .hero-flowers' own stacking context, where the critter comes after them in the page order */
253252
.insect .in-flip, .insect .in-body { display: block; width: 100%; height: 100%; }
254253
.insect.is-left .in-flip { transform: scaleX(-1); }
255254
.insect svg { display: block; width: 100%; height: 100%; overflow: visible; filter: drop-shadow(0 1px 1px rgba(110, 80, 50, .28)); }
256-
.insect.is-fly svg { filter: drop-shadow(0 4px 3px rgba(90, 67, 102, .2)); }
257-
.insect.is-fly .in-body { animation: inFly .22s ease-in-out infinite alternate; }
258255
.insect.is-crawl .in-body { animation: inCrawl .3s ease-in-out infinite alternate; }
259256
.insect.in-caterpillar.is-crawl .in-body { transform-origin: 50% 100%; animation: inInch .9s ease-in-out infinite; }
260-
.insect.is-wiggle .in-body { animation: inWiggle .5s ease; }
261-
@keyframes inFly { from { transform: translateY(-1px) scale(1.06, .94); } to { transform: translateY(1px) scale(.94, 1.06); } }
262257
@keyframes inCrawl { from { transform: translateY(0); } to { transform: translateY(-.6px) scale(1.04, .98); } }
263258
@keyframes inInch { 0%, 100% { transform: scaleX(1); } 50% { transform: scale(.82, 1.14); } }
264-
@keyframes inWiggle { 20% { transform: rotate(-14deg); } 50% { transform: rotate(12deg); } 80% { transform: rotate(-6deg); } }
265259

266260
/* ---------------------------------------------------------------------
267261
The bird nest beside the DeviantArt button (js/animals/nest.js).
@@ -311,9 +305,15 @@
311305
.bn[data-grow="3"] { --g: 1.18; }
312306
.bn-baby { scale: var(--g); transition: scale 1.2s ease; }
313307
.vine-bird.bn-parent svg { width: 43px; height: 35px; }
314-
.bn-worm { position: absolute; left: 32px; top: 11px; width: 17px; height: 7px; border-radius: 3px; background: #e0868f; box-shadow: inset 0 -1px 0 rgba(150, 70, 90, 0.35); pointer-events: none; animation: bnWorm 0.5s ease-in-out infinite alternate; }
315-
.bn-worm.fly { position: fixed; left: 0; top: 0; z-index: 7; width: 20px; height: 8px; }
308+
/* a small wriggly pink worm: a wavy body with a lighter band (clitellum) and a dot eye, drawn as an inline SVG so it stays readable at ~17px */
309+
.bn-worm { position: absolute; left: 31px; top: 8px; width: 18px; height: 11px; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 11'%3E%3Cpath d='M1.5 7.5 Q4 1.5 7 5.5 T12.5 5.5 T16 3.5' fill='none' stroke='%23c4636f' stroke-width='3.6' stroke-linecap='round'/%3E%3Cpath d='M1.5 7.5 Q4 1.5 7 5.5 T12.5 5.5 T16 3.5' fill='none' stroke='%23ec9aa3' stroke-width='2.2' stroke-linecap='round'/%3E%3Cpath d='M10.2 3.2 L10.2 7.6' stroke='%23c4636f' stroke-width='1.1'/%3E%3Ccircle cx='16' cy='3.2' r='0.6' fill='%23402'/%3E%3C/svg%3E") center / 100% 100% no-repeat; pointer-events: none; animation: bnWorm 0.5s ease-in-out infinite alternate; }
310+
.bn-worm.fly { position: fixed; left: 0; top: 0; z-index: 7; width: 20px; height: 12px; animation: none; } /* no bnWorm here: its rotate/scale are applied outside the translate and would swing/squash the flight path */
316311
@keyframes bnWorm { to { rotate: 22deg; scale: 1.1 0.8; } }
312+
/* the 2nd and 3rd feedings bring a berry and a seed instead of the worm (data-food set in nest.js); they sit still instead of wriggling */
313+
.bn-worm:not(.fly)[data-food=berry] { left: 35px; top: 10px; width: 9px; height: 9px; border-radius: 50%; background: radial-gradient(circle at 32% 30%, #ff9fb0 0 14%, transparent 16%), radial-gradient(circle at 50% 55%, #d6334f, #8e1d3c); box-shadow: 0 -2px 0 -1px #5a9a4a; animation: bnBob 0.5s ease-in-out infinite alternate; }
314+
.bn-worm:not(.fly)[data-food=seed] { left: 35px; top: 11px; width: 10px; height: 6px; border-radius: 60% 40% 60% 40% / 70% 70% 40% 40%; background: linear-gradient(100deg, #d9b26a 0 55%, #a97c3a 55% 62%, #d9b26a 62%); box-shadow: inset 0 -1px 0 rgba(90, 60, 20, 0.4); rotate: -18deg; animation: none; }
315+
.bn-worm.fly[data-food=berry] { width: 10px; height: 10px; border-radius: 50%; background: radial-gradient(circle at 32% 30%, #ff9fb0 0 14%, transparent 16%), radial-gradient(circle at 50% 55%, #d6334f, #8e1d3c); box-shadow: 0 -2px 0 -1px #5a9a4a; animation: none; }
316+
.bn-worm.fly[data-food=seed] { width: 11px; height: 7px; border-radius: 60% 40% 60% 40% / 70% 70% 40% 40%; background: linear-gradient(100deg, #d9b26a 0 55%, #a97c3a 55% 62%, #d9b26a 62%); box-shadow: inset 0 -1px 0 rgba(90, 60, 20, 0.4); animation: none; }
317317
@keyframes bnBob { to { translate: 0 -1.2px; } }
318318
@keyframes bnBlink { 0%, 93%, 100% { scale: 1; } 96% { scale: 1 0.1; } }
319319
@keyframes bnPeep { 0%, 90%, 100% { opacity: 0; scale: 0.4; } 93%, 97% { opacity: 1; scale: 0.9; } }

‎css/12-polish-pass.css‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ html body .rb-host:hover .rb-vis .rb-ch, html body .rb-host:focus-visible .rb-vi
3232
.fl-spin { animation: flSpin var(--spd, 40s) linear var(--sdl, 0s) infinite, flFloat var(--fl, 6s) ease-in-out var(--fdl, 0s) infinite; }
3333
.fl-spin.fl-rev { animation-name: flSpinRev, flFloat; }
3434
.hero-flowers .bloom.fl-spin { animation: bloomIn 1.4s cubic-bezier(0.34, 1.56, 0.64, 1) var(--bdl, 0.4s) forwards, flSpin var(--spd, 40s) linear var(--sdl, 0s) infinite, flFloat var(--fl, 6s) ease-in-out var(--fdl, 0s) infinite; }
35-
.hero-flowers .bloom.f5, .hero-flowers .bloom.f8 { animation: bloomIn 1.4s cubic-bezier(0.34, 1.56, 0.64, 1) 0.9s forwards, leafSway 5s ease-in-out infinite; }
35+
.hero-flowers .bloom.f5, .hero-flowers .bloom.f8, .hero-flowers .bloom.f9 { animation: bloomIn 1.4s cubic-bezier(0.34, 1.56, 0.64, 1) 0.9s forwards, leafSway 5s ease-in-out infinite; }
3636
.hero-flowers .bloom.f8 { animation-delay: 1.2s, -2s; animation-duration: 1.4s, 6s; }
37+
.hero-flowers .bloom.f9 { animation-delay: 1.5s, -1s; animation-duration: 1.4s, 5.5s; }
3738
.title-bloom.fl-spin { animation: flSpin var(--spd, 24s) linear var(--sdl, 0s) infinite; }
3839
.section-head:hover .title-bloom.fl-spin { animation-duration: var(--spd, 24s); }
3940
.reveal.visible .hello-flower.fl-spin { animation: popBloom 0.8s var(--spring) 1.8s forwards, flSpin var(--spd, 12s) linear 2.6s infinite !important; }

‎css/15-intro.css‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/* =====================================================
2+
INTRO: transparent full-screen particle overlay (gradient backdrop, spinning golden sparkle → explosion → pastel sparkle + petal rainfall)
3+
Owner: js/site/intro.js (builds the canvas, draws the particles, removes everything at the end).
4+
No cover/background: the live page shows through. The overlay never catches pointer events.
5+
===================================================== */
6+
7+
.intro { position: fixed; inset: 0; z-index: 99999; overflow: hidden; pointer-events: none; background: none; }
8+
.intro .in-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; pointer-events: none; }
9+
/* soft translucent gradient overlay on top of the site (max opacity set in intro.js); opacity is driven from intro.js (fades in, then out to reveal the site) */
10+
.intro .in-bg { position: absolute; inset: 0; opacity: 0; pointer-events: none;
11+
background: radial-gradient(circle at 50% 45%, #ffe8a0 0%, #ffc2dd 30%, #c9b0ff 62%, #9cc8ff 100%); }

‎index.html‎

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,29 @@
99
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
1010
<link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Caveat:wght@500;600&family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;1,9..40,400&family=Fraunces:ital,opsz,wght,SOFT@0,9..144,300..600,50;1,9..144,300..600,100&display=swap" rel="stylesheet">
1111
<link href="https://fonts.googleapis.com/css2?family=Caveat:wght@500;600&family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;1,9..40,400&family=Fraunces:ital,opsz,wght,SOFT@0,9..144,300..600,50;1,9..144,300..600,100&display=swap" rel="stylesheet">
12+
<script>
13+
/* Intro gate (see js/site/intro.js). Plays on every page load; no persistent flag. Dev: ?nointro skips. */
14+
(function () { try {
15+
if (/[?&]nointro\b/.test(location.search)) return;
16+
document.documentElement.classList.add("intro-on");
17+
setTimeout(function () { document.documentElement.classList.remove("intro-on"); }, 6000); /* failsafe: never leave the cover up */
18+
} catch (e) {} })();
19+
</script>
1220
<link rel="stylesheet" href="css/01-base.css?v=7">
13-
<link rel="stylesheet" href="css/02-spring-theme.css?v=2">
21+
<link rel="stylesheet" href="css/02-spring-theme.css?v=4">
1422
<link rel="stylesheet" href="css/03-flower-fx.css?v=2">
1523
<link rel="stylesheet" href="css/04-hero.css?v=2">
1624
<link rel="stylesheet" href="css/05-fx-titles-gallery-cursor.css?v=2">
1725
<link rel="stylesheet" href="css/06-backgrounds-rainbow-gallery.css?v=2">
1826
<link rel="stylesheet" href="css/07-living-background-v4-v6.css?v=2">
1927
<link rel="stylesheet" href="css/08-garden-game-v7-v8.css?v=9">
2028
<link rel="stylesheet" href="css/09-v9-refinements.css?v=3">
21-
<link rel="stylesheet" href="css/10-botanical.css?v=3">
22-
<link rel="stylesheet" href="css/11-little-world.css?v=30">
23-
<link rel="stylesheet" href="css/12-polish-pass.css?v=2">
29+
<link rel="stylesheet" href="css/10-botanical.css?v=4">
30+
<link rel="stylesheet" href="css/11-little-world.css?v=31">
31+
<link rel="stylesheet" href="css/12-polish-pass.css?v=3">
2432
<link rel="stylesheet" href="css/13-ecosystem.css?v=2">
2533
<link rel="stylesheet" href="css/14-side-vines-plants.css?v=4">
34+
<link rel="stylesheet" href="css/15-intro.css?v=16">
2635
</head>
2736
<body>
2837
<svg width="0" height="0" style="position:absolute" aria-hidden="true">
@@ -79,6 +88,7 @@
7988
<svg class="bloom f6" style="color:var(--yellow);--center:#d99a12"><use href="#fl-forsythia"/></svg>
8089
<svg class="bloom f7" style="color:var(--pink-soft);--center:var(--pink)"><use href="#fl-bloom"/></svg>
8190
<svg class="bloom f8" style="color:var(--green)"><use href="#fl-leaf"/></svg>
91+
<svg class="bloom f9" style="color:var(--green)"><use href="#fl-leaf"/></svg>
8292
</div>
8393
<div class="hero-glow" aria-hidden="true"></div>
8494
<div class="hero-inner">
@@ -764,8 +774,9 @@ <h2 class="contact-title">Let's <em>Connect</em></h2>
764774
<script src="js/plants/flowers.js?v=4" defer></script>
765775
<script src="js/world/world.js?v=1" defer></script>
766776
<script src="js/animals/snails.js?v=6" defer></script>
767-
<script src="js/animals/insects.js?v=2" defer></script>
777+
<script src="js/animals/insects.js?v=11" defer></script>
768778
<script src="js/animals/nest.js?v=16" defer></script>
769-
<script src="js/main.js?v=8" defer></script>
779+
<script src="js/site/intro.js?v=21" defer></script>
780+
<script src="js/main.js?v=9" defer></script>
770781
</body>
771782
</html>

0 commit comments

Comments
 (0)