/* ======================================================================
   The little world
   ====================================================================== */
/* sunlight: nearby flowers lean a few degrees toward the cursor (set by script as --sun) */
.hero-flowers .bloom, .about-bloom, .title-bloom, .sc-bloom, .footer-flowers svg, .hello-flower, .w-dandelion { transform: rotate(var(--sun, 0deg)); transition: transform 1.1s cubic-bezier(0.25, 0.8, 0.3, 1); }
.title-bloom { transition: transform 1.1s cubic-bezier(0.25, 0.8, 0.3, 1), scale 0.9s var(--spring) 0.2s, opacity 0.6s ease 0.2s; }
.g-art, .h-art { transform: rotate(var(--sun, 0deg)); }
.g-art { transition: max-width 0.5s var(--glide), transform 0.9s cubic-bezier(0.25, 0.8, 0.3, 1), opacity 0.4s ease; }
.h-art { transition: max-width 0.5s var(--glide), transform 0.9s cubic-bezier(0.25, 0.8, 0.3, 1), opacity 0.4s ease; }
.g-cat:hover .g-art, .g-cat:focus-visible .g-art { transform: translateY(-4px) rotate(calc(var(--sun, 0deg) - 1.5deg)); }
.h-spec:hover .h-art, .h-spec:focus-visible .h-art { transform: translateY(-5px) rotate(calc(var(--sun, 0deg) - 2deg)) scale(1.04); }
/* the corner sunflower turns its face toward the light, slowly */
.to-top .sf-sway { rotate: var(--face, 0deg); transition: rotate 1.6s cubic-bezier(0.25, 0.8, 0.3, 1); }

/* small things a visitor can pick up or touch */
.w-seed { position: absolute; z-index: 105; width: 18px; height: 24px; margin: -12px 0 0 -9px; cursor: grab; touch-action: none; -webkit-tap-highlight-color: transparent;  }
.w-seed::after { content: ''; position: absolute; inset: -14px; border-radius: 50%; }   /* a forgiving grab area */
.w-seed svg { width: 100%; height: 100%; overflow: visible; filter: drop-shadow(0 2px 2px rgba(110, 80, 50, 0.25)); }
.w-seed.held { cursor: grabbing; animation: none; scale: 1.2; }
.w-seed.wiggle { animation: seedWiggle 0.5s ease; }
.w-seed.eaten { transition: scale 0.4s ease, opacity 0.4s ease; scale: 0; opacity: 0; }
.w-seed.gone { transition: transform 0.9s ease-in, opacity 0.9s ease; transform: translate(40px, -30px) rotate(160deg); opacity: 0; }
@keyframes seedIn { from { scale: 0; rotate: -60deg; } }
@keyframes seedGlint { 0%, 85%, 100% { filter: none; } 92% { filter: drop-shadow(0 0 5px rgba(255, 236, 160, 0.95)); } }
@keyframes seedWiggle { 25% { rotate: -14deg; } 75% { rotate: 12deg; } }
.w-spark { position: absolute; z-index: 106; width: 6px; height: 6px; margin: -3px 0 0 -3px; border-radius: 50%; background: #f6d36b; box-shadow: 0 0 6px rgba(246, 211, 107, 0.9); pointer-events: none; }
.guide-bird.curious .gb-body { animation-duration: 1.2s !important; }
.guide-bird.fed .gb-flip, .w-bird.fed .c-body { animation: happyHop 0.45s ease 2; }
@keyframes happyHop { 50% { transform: translateY(-5px); } }
.w-petal { z-index: 104; width: 10px; height: 13px; margin: -6px 0 0 -5px; border-radius: 60% 60% 50% 50% / 70% 70% 30% 30%; background: #f9c6d6; box-shadow: inset 2px 2px 0 rgba(255, 255, 255, 0.5); pointer-events: none; animation: petalTumble 1.6s ease-in-out infinite alternate; }
@keyframes petalTumble { from { rotate: -30deg; scale: 1 0.8; } to { rotate: 40deg; scale: 0.8 1; } }
.w-carried { position: absolute; left: 30px; top: 14px; width: 10px; height: 13px; pointer-events: none; }
.w-carried.is-petal { border-radius: 60% 60% 50% 50% / 70% 70% 30% 30%; background: #f9c6d6; }
.w-carried.is-seed svg { width: 10px; height: 13px; display: block; }
.w-bird { pointer-events: none; }

/* the nest at the corner of the contact photo: it gains a piece now and then, only while out of sight */
.w-nest { position: absolute; z-index: 6; right: -14px; top: -30px; width: 74px; height: 43px; pointer-events: none; }
.w-nest svg { width: 100%; height: 100%; overflow: visible; }
.w-nest g { opacity: 0; }
.w-nest[data-stage="1"] .n1, .w-nest[data-stage="2"] :is(.n1, .n2), .w-nest[data-stage="3"] :is(.n1, .n2, .n3), .w-nest[data-stage="4"] :is(.n1, .n2, .n3, .n4), .w-nest[data-stage="5"] g { opacity: 1; }

/* the caterpillar's twig, below the About photo */
.w-story { position: absolute; z-index: 3; left: -34px; bottom: -22px; width: 120px; height: 50px; pointer-events: none; }
.w-story svg { display: block; width: 100%; height: 100%; overflow: visible; }
.ws-cat { position: absolute; left: 12px; top: 4px; width: 30px; height: 13px; animation: wsCrawl 34s ease-in-out infinite; }
.ws-cat svg { width: 100%; height: 100%; }
.ws-segs { transform-box: fill-box; transform-origin: 100% 50%; animation: inchSegs 1.6s ease-in-out infinite; }
/* (renamed from a second "inch": the duplicate name overrode the vine caterpillar's small squash and made it slide back and forth) */
@keyframes wsCrawl { 0%, 8% { transform: translateX(0); } 40%, 48% { transform: translateX(44px) translateY(1px); } 52% { transform: translateX(44px) scaleX(-1); } 90%, 100% { transform: translateX(0) scaleX(-1); } }
@keyframes inchSegs { 50% { transform: scaleX(0.82); } }
.ws-chrysalis { position: absolute; left: 64px; top: 20px; width: 13px; height: 25px; transform-origin: 50% 0; opacity: 0; animation: hang 6s ease-in-out infinite alternate; }
.ws-chrysalis svg { width: 100%; height: 100%; }
@keyframes hang { from { rotate: -4deg; } to { rotate: 4deg; } }
.w-story:not([data-stage="0"]) .ws-cat { display: none; }
.w-story[data-stage="1"] .ws-chrysalis { opacity: 1; }
@media (max-width: 700px) { .w-story { left: -10px; bottom: -26px; width: 96px; height: 40px; } }

/* the dandelion and its drifting seeds */
.w-dandelion { position: absolute; z-index: 2; width: 44px; height: 84px; cursor: pointer; transform-origin: 50% 100%; -webkit-tap-highlight-color: transparent; }
.w-dandelion[hidden] { display: none; }
.w-dandelion svg { width: 100%; height: 100%; overflow: visible; }
.w-dandelion.blown .wd-puff { opacity: 0; transition: opacity 0.3s; }
.w-dandelion.nod { animation: nod 0.7s ease; }
@keyframes nod { 30% { rotate: -6deg; } 70% { rotate: 4deg; } }
.w-fluff { position: fixed; left: 0; top: 0; z-index: 96;    pointer-events: none;  }
.w-sprout { position: absolute; bottom: 6px; z-index: 1; width: 24px; height: 40px; margin-left: -12px; pointer-events: none; transform-origin: 50% 100%; animation: sproutUp 1.6s var(--spring), breeze 6.5s ease-in-out 1.6s infinite alternate; }
.w-sprout svg { width: 100%; height: 100%; overflow: visible; }
@keyframes sproutUp { from { scale: 0.2 0; } }

/* the rain cloud: a short, local shower; flowers bow, then lift; sometimes a faint rainbow */
.w-cloud { position: absolute; z-index: 7; width: 110px; height: 62px; cursor: pointer; opacity: 0; translate: -40px 0; transition: opacity 1.2s ease, translate 1.6s ease; -webkit-tap-highlight-color: transparent; }
.w-cloud.on { opacity: 1; translate: 0 0; animation: cloudBob 5s ease-in-out infinite alternate; }
.w-cloud.away { opacity: 0; translate: 60px -10px; }
.w-cloud svg { width: 100%; height: 100%; overflow: visible; }
.w-cloud .cl-body { fill: #fff; stroke: #bcd0ea; stroke-width: 2; stroke-linejoin: round; transition: fill 0.6s, stroke 0.6s; }
.w-cloud.raining .cl-body { fill: #dfe9f7; stroke: #92afd6; }
.w-cloud .cl-still { display: none; }
@keyframes cloudBob { to { transform: translateY(-5px); } }
.w-rain { position: absolute; left: 10%; right: 10%; top: 52px; pointer-events: none; overflow: hidden; }
.w-rain i { position: absolute; top: -12px; width: 2px; height: 10px; border-radius: 2px; background: rgba(140, 196, 230, 0.75); animation: dropAll var(--s, 0.85s) linear var(--d, 0s) infinite; }
.w-rain.stop i { animation-iteration-count: 1; }
@keyframes dropAll { from { top: -12px; } to { top: 100%; opacity: 0.3; } }
.w-rained .g-art, .w-rained .h-art { animation: rainBow 6.5s ease-in-out; }
@keyframes rainBow { 15%, 85% { transform: rotate(5deg) translateY(3px) scale(0.98); } }
.w-refreshed .g-art, .w-refreshed .h-art { animation: lift 1.4s var(--spring); }
@keyframes lift { 40% { transform: translateY(-5px) scale(1.03); } }
.w-rainbow { position: absolute; z-index: 0; pointer-events: none; border-radius: 999px 999px 0 0; opacity: 0; animation: rainbowFade 10s ease-in-out forwards;
    background: radial-gradient(circle at 50% 100%, transparent 52%, rgba(200, 160, 230, 0.5) 53%, rgba(140, 190, 240, 0.5) 57%, rgba(150, 210, 160, 0.5) 61%, rgba(250, 225, 120, 0.5) 65%, rgba(250, 170, 130, 0.5) 69%, rgba(240, 140, 160, 0.45) 73%, transparent 74%); }
@keyframes rainbowFade { 0% { opacity: 0; } 25%, 70% { opacity: 0.35; } 100% { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
    .to-top .sf-sway, .hero-flowers .bloom, .about-bloom, .title-bloom, .sc-bloom, .footer-flowers svg, .g-art, .h-art { transition: none; }
    .ws-cat, .ws-segs, .ws-chrysalis, .w-seed, .w-cloud.on, .w-sprout, .w-petal { animation: none !important; }
}
.w-dandelion.small { width: 32px; height: 61px; }


/* the secret envelope (js/easter-eggs/envelope.js): dropped by a bird, drifts down; the flap hinges open, a folded letter slides out and unfolds onto pink graph paper.
   data-state = closed | opening | open | closing. Layers, back to front: body, open flap, hearts, letter, front panels, closed flap, seal, tap target.
   The wrapper's left/top place it (dragging); its transform is only the resting tilt / the drop-in, so the opening timeline (on the layers) never fights it. */
.env-carry { position: absolute; left: 27px; top: 13px; width: 22px; pointer-events: none; }
.env-carry svg { display: block; width: 100%; height: auto; overflow: visible; }
.w-envelope { position: absolute; z-index: 105; width: 64px; height: 60px; margin: -32px 0 0 -30px; transform: rotate(-3deg); pointer-events: none; transition: scale 0.25s ease; }
.w-envelope.settling { transition: scale 0.25s ease, left 0.3s ease, top 0.3s ease; }
.w-envelope[data-state="closed"]:hover { scale: 1.08; }
.w-envelope.is-dragging { scale: 1.07; }
.w-envelope > svg { position: absolute; display: block; overflow: visible; pointer-events: none; }
.w-envelope .env-back { inset: 0; width: 100%; height: 100%; z-index: 0; filter: drop-shadow(0 3px 3px rgba(90, 67, 102, 0.2)); transition: filter 0.2s ease; }
.w-envelope.is-dragging .env-back { filter: drop-shadow(0 9px 8px rgba(90, 67, 102, 0.3)); }
.w-envelope .env-flap-open { left: 0; top: 2px; width: 64px; height: 21px; z-index: 1; opacity: 0; transform-origin: 50% 100%; }
.w-envelope .env-front { inset: 0; width: 100%; height: 100%; z-index: 4; }
.w-envelope .env-flap { left: 0; top: 23px; width: 64px; height: 24px; z-index: 5; transform-origin: 50% 0; }
.w-envelope .env-seal { inset: 0; width: 100%; height: 100%; z-index: 6; transform-origin: 50% 62%; }
.env-hit { position: absolute; z-index: 7; left: 0; right: 0; top: 20px; bottom: 0; padding: 0; border: 0; background: none; cursor: grab; pointer-events: auto; touch-action: none; user-select: none; -webkit-user-select: none; -webkit-tap-highlight-color: transparent; }
.env-hit::after { content: ''; position: absolute; inset: -12px; }   /* a forgiving grab / tap area while closed */
.w-envelope.is-dragging .env-hit { cursor: grabbing; }
.w-envelope:not([data-state="closed"]) .env-hit { cursor: pointer; touch-action: manipulation; }
.w-envelope:not([data-state="closed"]) .env-hit::after { display: none; }
.env-hit:focus-visible { outline: 2px dashed #c2457e; outline-offset: 6px; border-radius: 8px; }
.w-envelope.drifting { animation: envDrift 3.4s cubic-bezier(0.45, 0.05, 0.5, 1) both; }
.w-envelope.drifting .env-hit { pointer-events: none; }
.w-envelope.fade-in { animation: envRise 1s ease both; }
@keyframes envDrift {
    0%   { transform: translate(var(--dx), var(--dy)) rotate(-18deg); }
    28%  { transform: translate(calc(var(--dx) * 0.55 + 18px), calc(var(--dy) * 0.66)) rotate(13deg); }
    56%  { transform: translate(calc(var(--dx) * 0.25 - 15px), calc(var(--dy) * 0.33)) rotate(-10deg); }
    80%  { transform: translate(calc(var(--dx) * 0.06 + 7px), calc(var(--dy) * 0.07)) rotate(5deg); }
    100% { transform: translate(0, 0) rotate(-3deg); }
}
@keyframes envRise { from { opacity: 0; translate: 0 12px; } to { opacity: 1; translate: 0 0; } }

/* temporary opening light and particles: all sit behind the readable letter */
.env-magic { position: absolute; inset: 0; z-index: 1; overflow: visible; pointer-events: none; }
.env-magic[hidden] { display: none; }
.env-glow { position: absolute; left: 50%; top: -74px; width: 260px; height: 190px; border-radius: 50%; opacity: 0; pointer-events: none;
    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%);
    filter: blur(10px); transform: translateX(-50%); }
.env-ring { position: absolute; left: 50%; top: -30px; width: 238px; height: 172px; box-sizing: border-box; border: 2px solid rgba(255, 237, 177, .75); border-radius: 50%; opacity: 0; pointer-events: none;
    box-shadow: 0 0 14px rgba(255, 221, 145, .55), inset 0 0 18px rgba(242, 195, 224, .28); filter: blur(.4px); }
.env-ray { --ray-angle: 0deg; position: absolute; left: 50%; top: -130px; width: 20px; height: 155px; opacity: 0; pointer-events: none; transform-origin: 50% 100%;
    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%; }
.env-ray.r1 { --ray-angle: -48deg; } .env-ray.r2 { --ray-angle: -24deg; height: 170px; top: -145px; }
.env-ray.r3 { --ray-angle: 25deg; height: 164px; top: -139px; } .env-ray.r4 { --ray-angle: 49deg; }
.env-hearts { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.env-heart { position: absolute; left: 22px; top: 9px; width: 22px; height: 21px; opacity: 0; pointer-events: none; filter: drop-shadow(0 2px 4px rgba(163, 104, 137, .28)) drop-shadow(0 0 5px rgba(255, 237, 205, .42)); }
.env-heart svg { display: block; width: 100%; height: 100%; }
.env-spark { width: 10px; height: 10px; left: 27px; top: 13px; filter: drop-shadow(0 0 3px rgba(255, 226, 151, .45)); }

/* the letter box clips only what would hang below the envelope; everything above and beside it is free */
.env-letter-box { position: absolute; inset: 0; z-index: 3; pointer-events: none; clip-path: inset(-600px -240px 4px -240px); }
/* the letter: one 190 x 152 sheet of four panels. Its resting look is the OPEN look; the opening timeline drives every fold */
.env-letter { position: absolute; left: calc(50% + var(--nx, 0px) - 95px); bottom: 20px; width: 190px; height: 152px; max-width: calc(100vw - 16px); transform-origin: 50% 100%; translate: 0 -16px; rotate: -0.6deg; opacity: 0; pointer-events: none;
    font-family: var(--font-hand); font-size: 1.1rem; line-height: 1.22; color: #5a4366; text-align: center; cursor: pointer; touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
.w-envelope[data-state="closed"] .env-letter { visibility: hidden; }
.w-envelope[data-state="open"] .env-letter { opacity: 1; pointer-events: auto; }
/* once open, nothing clips the sheet: near the top of the page it is pushed down past the pocket, and the box's bottom clip would cut it off */
.w-envelope[data-state="open"] .env-letter-box { clip-path: none; }
.env-sheet { position: absolute; inset: 0; transform-origin: 50% 100%; filter: drop-shadow(0 6px 8px rgba(90, 67, 102, 0.17)) drop-shadow(0 1px 1.5px rgba(90, 67, 102, 0.14)); }
.env-row { position: absolute; left: 0; width: 100%; height: 50%; }
.env-row.t { top: 0; transform-origin: 50% 100%; }
.env-row.b { bottom: 0; }
/* light blush graph paper: a faint pink + lavender square grid, 19px, drawn with gradients (95 x 76 panels hold 5 x 4 whole squares, so it runs across the folds) */
.env-panel { position: absolute; top: 0; width: 50%; height: 100%; box-sizing: border-box; background-color: #fff0f5;
    background-image: linear-gradient(rgba(236, 160, 196, 0.26) 1px, transparent 1px), linear-gradient(90deg, rgba(180, 160, 226, 0.28) 1px, transparent 1px); background-size: 19px 19px;
    border: 1px solid rgba(214, 170, 196, 0.5); }
/* no border along the inner (fold) edges: they would draw heavy cross lines over the open letter */
.env-panel.tl, .env-panel.bl { border-right: 0; } .env-panel.tr, .env-panel.br { border-left: 0; } .env-panel.tl, .env-panel.tr { border-bottom: 0; } .env-panel.bl, .env-panel.br { border-top: 0; }
.env-panel.tr, .env-panel.br { left: 50%; }
.env-panel.tl, .env-panel.bl { left: 0; transform-origin: 100% 50%; }
.env-panel.tl { border-radius: 8px 0 0 0; } .env-panel.tr { border-radius: 0 9px 0 0; } .env-panel.bl { border-radius: 0 0 0 9px; } .env-panel.br { border-radius: 0 0 8px 0; }
.env-panel .shade, .env-row > .shade { position: absolute; inset: 0; opacity: 0; pointer-events: none; background: linear-gradient(160deg, rgba(120, 85, 125, 0.28), rgba(120, 85, 125, 0.06)); border-radius: inherit; }
.env-row > .shade { left: 50%; width: 50%; border-radius: 0 9px 0 0; }   /* only over the folded stack, not the empty half the left panel left behind */
.env-paper-shimmer { position: absolute; inset: 0; z-index: 1; border-radius: 9px; opacity: 0; pointer-events: none; background: linear-gradient(112deg, transparent 34%, rgba(255,255,255,.76) 45%, rgba(255,239,184,.42) 51%, rgba(225,207,250,.32) 57%, transparent 68%); background-size: 260% 100%; background-position: 135% 0; }
.env-text { position: absolute; inset: 0; z-index: 2; display: flex; overflow: hidden; }
.env-copy { margin: auto 0; width: 100%; padding: 10px 14px; box-sizing: border-box; }
.env-copy span { display: block; }
.env-copy span + span { margin-top: 7px; }
.env-copy .env-hello { white-space: nowrap; font-size: 1.3rem; font-weight: 600; color: #c2457e; }
.env-copy-heart { display: inline-block; margin-left: 2px; color: #d96b93; font-size: 1.25em; line-height: .8; font-weight: 700; filter: drop-shadow(0 1px 2px rgba(194,69,126,.18)); }
/* resting states (the timeline overrides these while it plays): closed = flap down, seal on; open = flap up, seal gone */
.w-envelope[data-state="open"] .env-flap, .w-envelope[data-state="open"] .env-seal { opacity: 0; }
.w-envelope[data-state="open"] .env-flap-open { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
    .w-envelope.drifting, .w-envelope.fade-in { animation: envFade 0.8s ease both; }
    .w-envelope, .w-envelope.settling, .env-back { transition: none; }
    .env-letter { transition: opacity 0.3s ease; }
    .env-hearts { display: none; }
    .env-magic .env-ray, .env-magic .env-ring, .env-paper-shimmer { display: none; }
    .env-magic.is-still .env-glow { opacity: .24; transform: translate(-50%, -2px) scale(.95); }
}
@keyframes envFade { from { opacity: 0; } to { opacity: 1; } }

/* ---- snails (js/animals/snails.js) ---- */
.snail { position: absolute; z-index: 3; width: 42px; height: 31px; cursor: pointer; touch-action: manipulation; -webkit-tap-highlight-color: transparent; --sh1: #f4b9a8; --sh2: #d98b7b; --bd: #f0e0cc; --pt: #f6a9c4; --sn-in: .45s; }
.snail[hidden] { display: none; }
.snail::after { content: ''; position: absolute; inset: -10px; }   /* a forgiving tap area */
.snail:focus-visible { outline: 2.5px solid var(--focus); outline-offset: 4px; border-radius: 8px; }
.sn-flip { display: block; width: 100%; height: 100%; }
.snail.is-left .sn-flip { transform: scaleX(-1); }
.snail svg { display: block; width: 100%; height: 100%; overflow: visible; filter: drop-shadow(0 1px 1px rgba(110, 80, 50, .25)); }
.sn-foot { fill: var(--bd); }
.sn-stalk { fill: none; stroke: var(--bd); stroke-width: 1.6; stroke-linecap: round; }
.sn-eye { fill: #5a4366; }
.sn-shell { fill: var(--sh1); stroke: var(--sh2); stroke-width: .8; }
.sn-spiral { fill: none; stroke: var(--sh2); stroke-width: 1.3; stroke-linecap: round; }
.sn-hi { fill: #fff; opacity: .45; }
.sn-dec { display: none; fill: var(--sh2); opacity: .8; }
.sn-petal { display: none; fill: var(--pt); stroke: rgba(255, 255, 255, .6); stroke-width: .4; }
.snail.is-deco .sn-dec, .snail.has-petal .sn-petal { display: block; }
.snail.is-wet .sn-hi { opacity: .8; }
.sn-body { transform-origin: 20px 26px; transition: transform var(--sn-in) ease-in-out, opacity var(--sn-in) ease-in-out; }
.snail.is-hidden .sn-body { transform: translateX(4px) scale(.15, .4); opacity: 0; }
.snail.is-peek .sn-body { transform: translateX(8px) scale(.6, .9); }
.snail.is-peek .sn-eyes { transform: translateY(2px); }
@media (prefers-reduced-motion: no-preference) {
    .snail.is-crawl .sn-body { animation: snStretch 1.7s ease-in-out infinite; }
    .snail:not(.is-hidden):not(.is-peek):not(.is-crawl) .sn-eyes { transform-origin: 38px 17px; animation: snLook 7s ease-in-out infinite; }
    .snail.is-new svg { animation: snNew 1.3s ease; }
    .sn-trail { animation: snTrail 3.6s ease-out forwards; }
    .sn-spark { animation: snSpark 2.4s ease-out forwards; }
    .sn-flour { animation: snFlour 6s ease-in-out forwards; }
}
@media (prefers-reduced-motion: reduce) { .sn-body { transition: none; } }
.sn-trail { position: absolute; z-index: 2; width: 10px; height: 3px; opacity: 0; border-radius: 50%; pointer-events: none; background: radial-gradient(ellipse, rgba(255, 255, 255, .95), rgba(190, 215, 240, .6) 55%, transparent 78%); transform: rotate(var(--r, 0deg)); opacity: 0; }
.sn-rain { width: 12px; height: 4px; background: radial-gradient(ellipse, hsla(var(--hue, 300), 90%, 86%, .95), hsla(calc(var(--hue, 300) + 60), 85%, 80%, .55) 58%, transparent 80%); box-shadow: 0 0 7px hsla(var(--hue, 300), 95%, 82%, .6); }
.sn-spark { position: absolute; z-index: 2; width: 7px; height: 7px; pointer-events: none; opacity: 0; clip-path: polygon(50% 0, 60% 40%, 100% 50%, 60% 60%, 50% 100%, 40% 60%, 0 50%, 40% 40%); }
.sn-flour { position: absolute; z-index: 2; width: 16px; height: 16px; pointer-events: none; opacity: 0; }
.sn-flour svg { display: block; width: 100%; height: 100%; overflow: visible; }
@keyframes snStretch { 0%, 100% { transform: scaleX(1); } 50% { transform: scaleX(1.07); } }
@keyframes snLook { 0%, 40%, 100% { transform: rotate(0); } 55% { transform: rotate(-5deg); } 75% { transform: rotate(4deg); } }
@keyframes snNew { 0%, 100% { filter: drop-shadow(0 1px 1px rgba(110, 80, 50, .25)); } 40% { filter: drop-shadow(0 0 6px rgba(255, 230, 150, .95)) brightness(1.15); } }
@keyframes snTrail { 0% { opacity: 0; scale: .6; } 12% { opacity: .85; scale: 1; } 100% { opacity: 0; scale: 1.25; } }
@keyframes snSpark { 0% { opacity: 0; scale: .2; } 20% { opacity: 1; scale: 1; } 100% { opacity: 0; scale: .4; rotate: 50deg; } }
@keyframes snFlour { 0% { opacity: 0; scale: .3; } 15% { opacity: .9; scale: 1; } 70% { opacity: .8; } 100% { opacity: 0; scale: 1.1; } }
@media (max-width: 699px) { .snail { width: 35px; height: 26px; } }
/* speech bubble (a child of .snail, so it never flips with the body); tail follows the snail when the bubble is nudged inside the screen */
.sn-say { position: absolute; left: 50%; bottom: calc(100% + 7px); z-index: 30; width: max-content; max-width: min(150px, 46vw); padding: 5px 11px 6px; border-radius: 15px 15px 15px 8px; background: var(--bb, rgba(255, 250, 242, .9)); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); color: var(--bt, #5a4366); border: 1.5px solid var(--bbd, rgba(155, 127, 207, .45)); box-shadow: 0 3px 9px rgba(110, 80, 50, .16), inset 0 1px 0 rgba(255, 255, 255, .55); font-family: var(--font-body); font-weight: 600; font-size: 12px; line-height: 1.3; text-align: center; pointer-events: none; transform: translateX(calc(-50% + var(--dx, 0px))); animation: snSay .25s ease-out; }
.sn-say::after { content: ''; position: absolute; top: 100%; left: calc(50% - var(--dx, 0px)); width: 7px; height: 7px; background: var(--bb, #fffaf2); border: solid var(--bbd, rgba(155, 127, 207, .45)); border-width: 0 1.5px 1.5px 0; border-radius: 0 0 3px 0; transform: translate(-50%, -4px) rotate(45deg); }
.sn-say.is-below { bottom: auto; top: calc(100% + 6px); }
.sn-say.is-below::after { top: auto; bottom: 100%; border-width: 1.5px 0 0 1.5px; border-radius: 3px 0 0 0; transform: translate(-50%, 4px) rotate(45deg); }
@keyframes snSay { from { opacity: 0; } to { opacity: 1; } }
@media (max-width: 699px) { .sn-say { font-size: 11px; padding: 3px 8px; max-width: min(130px, 44vw); } }
@media (prefers-reduced-motion: reduce) { .sn-say { animation: none; } }

/* ---- insects that come out from under a tapped decorative leaf (js/animals/insects.js): they never take taps; they just crawl away ---- */
.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; }
.insect.is-in { opacity: 1; }
.insect.is-out { opacity: 0; transition-duration: .5s; }
.insect.is-under { z-index: 0; }   /* beneath the leaf (z-index 1) while it slips out */
.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 */
.insect .in-flip, .insect .in-body { display: block; width: 100%; height: 100%; }
.insect.is-left .in-flip { transform: scaleX(-1); }
.insect svg { display: block; width: 100%; height: 100%; overflow: visible; filter: drop-shadow(0 1px 1px rgba(110, 80, 50, .28)); }
.insect.is-crawl .in-body { animation: inCrawl .3s ease-in-out infinite alternate; }
.insect.in-caterpillar.is-crawl .in-body { transform-origin: 50% 100%; animation: inInch .9s ease-in-out infinite; }
@keyframes inCrawl { from { transform: translateY(0); } to { transform: translateY(-.6px) scale(1.04, .98); } }
@keyframes inInch { 0%, 100% { transform: scaleX(1); } 50% { transform: scale(.82, 1.14); } }

/* ---------------------------------------------------------------------
   The bird nest beside the DeviantArt button (js/animals/nest.js).
   Placed by script; each click advances it: eggs appear, crack, hatch; chicks bob, blink,
   peep and open their beaks when fed. Transforms and opacity only.
   --------------------------------------------------------------------- */
.social-links { position: relative; }
.about-hello { position: relative; }
.bn { --g: 0.5; position: absolute; z-index: 3; width: 100px; height: 75px; cursor: pointer; border-radius: 12px; outline: none; -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
.bn:focus-visible { outline: 3px solid var(--focus, #c2457e); outline-offset: 3px; }
.bn svg { display: block; width: 100%; height: 100%; overflow: visible; filter: drop-shadow(0 2px 2px rgba(110, 80, 50, 0.2)); }
.bn-adults { display: none; }
.bn.has-adults .bn-adults { display: inline; }
.vine-bird.nflap .c-wing, .bn.flutter .c-wing { animation: wingFlap 0.13s ease-in-out infinite alternate; }
.bn-slot .bn-shell, .bn-slot .bn-baby, .bn-slot .bn-egg, .bn-slot .bn-crack { display: none; }
.bn-slot[data-st="0"] .bn-egg, .bn-slot[data-st="1"] .bn-egg, .bn-slot[data-st="1"] .bn-crack { display: inline; }
.bn-slot[data-st="2"] .bn-shell, .bn-slot[data-st="2"] .bn-baby { display: inline; }
.bn-eggbody, .bn-baby, .bn-head, .bn-mouth, .bn-eye { transform-box: fill-box; }
.bn-eggbody { transform-origin: 50% 100%; }
.bn-baby { transform-origin: 50% 100%; animation: bnBob 3.4s ease-in-out var(--d, 0s) infinite alternate; }
.bn-eye { transform-origin: 50% 50%; animation: bnBlink 5.5s ease-in-out var(--d, 0s) infinite; }
/* chick personalities (kept subtle): 1 eager, 2 calm, 3 sleepy; the feeding rules below still win */
.bn-c0 .bn-baby { animation: bnBobEager 2.2s ease-in-out var(--d, 0s) infinite alternate; }
.bn-c0 .bn-mouth { animation-duration: 6s; }
.bn-c1 .bn-baby { animation: bnBobCalm 4.6s ease-in-out var(--d, 0s) infinite alternate; }
.bn-c1 .bn-eye { animation-duration: 3.6s; }
.bn-c1 .bn-mouth { transition-delay: 0.12s; }
.bn-c2 .bn-mouth { transition-delay: 0.24s; }
.bn-c2 .bn-head { animation: bnNod 12s ease-in-out var(--d, 0s) infinite; }
.bn.near .bn-c2 .bn-head, .bn-c2 .bn-baby.gape .bn-head { animation: none; }
.bn-head { transform-origin: 50% 90%; transition: rotate 0.25s ease, translate 0.25s ease; }
.bn-mouth { opacity: 0; scale: 0.4; transform-origin: 50% 0; transition: opacity 0.2s ease, scale 0.25s ease; animation: bnPeep 9s ease-in-out calc(var(--d, 0s) - 3s) infinite; }
.bn-beak { transition: opacity 0.2s ease; }
.bn.near .bn-baby, .bn-baby.gape { animation: bnBob 0.55s ease-in-out infinite alternate; }
.bn.near .bn-mouth, .bn-baby.gape .bn-mouth { opacity: 1; scale: 1; animation: none; }
.bn.near .bn-beak, .bn-baby.gape .bn-beak { opacity: 0; }
.bn.near .bn-head, .bn-baby.gape .bn-head { rotate: -5deg; translate: 0 -0.8px; }
.bn-baby.hop { animation: bnHop 0.45s ease 2; }
.bn-slot.wig .bn-eggbody { animation: bnWig 0.75s ease-in-out; }
.bn-slot.shake .bn-eggbody { animation: bnShake 0.65s ease-in-out forwards; }
.bn-slot.fresh .bn-eggbody { animation: bnLay 0.8s cubic-bezier(0.34, 1.56, 0.64, 1); }
.bn-slot[data-st="1"] .bn-eggbody { animation: bnTremble 6s ease-in-out var(--d, 0s) infinite; }
.bn-slot[data-st="1"].shake .bn-eggbody { animation: bnShake 0.65s ease-in-out forwards; }
.bn-slot.born .bn-baby { animation: bnPop 0.8s cubic-bezier(0.34, 1.56, 0.64, 1), bnBob 3.4s ease-in-out var(--d, 0s) infinite alternate; }
.bn[data-grow="1"] { --g: 0.72; }
.bn[data-grow="2"] { --g: 0.95; }
.bn[data-grow="3"] { --g: 1.18; }
.bn-baby { scale: var(--g); transition: scale 1.2s ease; }
.vine-bird.bn-parent svg { width: 43px; height: 35px; }
/* 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 */
.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; }
.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 */
@keyframes bnWorm { to { rotate: 22deg; scale: 1.1 0.8; } }
/* 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 */
.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; }
.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; }
.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; }
.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; }
@keyframes bnBob { to { translate: 0 -1.2px; } }
@keyframes bnBlink { 0%, 93%, 100% { scale: 1; } 96% { scale: 1 0.1; } }
@keyframes bnPeep { 0%, 90%, 100% { opacity: 0; scale: 0.4; } 93%, 97% { opacity: 1; scale: 0.9; } }
@keyframes bnBobEager { to { translate: 0 -2px; } }
@keyframes bnBobCalm { to { translate: 0 -0.5px; } }
@keyframes bnNod { 0%, 72%, 100% { rotate: 0deg; translate: 0 0; } 78%, 84% { rotate: 14deg; translate: 0.6px 1.8px; } 90% { rotate: -4deg; translate: 0 -1px; } 95% { rotate: 0deg; translate: 0 0; } }
@keyframes bnHop { 50% { translate: 0 -2.4px; } }
@keyframes bnPop { from { scale: 0.1; opacity: 0; } 60% { scale: calc(var(--g) * 1.15); opacity: 1; } to { scale: var(--g); } }
@keyframes bnWig { 15% { rotate: -13deg; } 35% { rotate: 12deg; } 55% { rotate: -9deg; } 75% { rotate: 7deg; } 100% { rotate: 0deg; } }
@keyframes bnShake { 10% { rotate: -14deg; } 25% { rotate: 14deg; } 40% { rotate: -12deg; } 55% { rotate: 12deg; } 70% { rotate: -8deg; scale: 1.08; } 100% { rotate: 0deg; scale: 1.12; opacity: 0; } }
@keyframes bnLay { from { scale: 0; translate: 0 -8px; } to { scale: 1; translate: 0 0; } }
@keyframes bnTremble { 0%, 88%, 100% { rotate: 0deg; } 90% { rotate: -3deg; } 94% { rotate: 3deg; } 97% { rotate: -2deg; } }
/* phones: ~30% smaller than before (80x60) and above the photo/flower decorations; the hello row is lifted so the About nest layers over the photo */
@media (max-width: 700px) { .bn { width: 80px; height: 60px; z-index: 20; } .about-hello { z-index: 20; } }
@media (prefers-reduced-motion: reduce) { .bn, .bn * { animation: none !important; transition: none !important; } }
/* phones: the pink About bloom moves to the photo's top-left corner (the nest perches on the top-right) */
@media (max-width: 700px) { .about-bloom.ab1 { right: auto; left: -26px; } }
