@autumnsgrove/groveengine 0.7.0 → 0.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/OnboardingChecklist.svelte +2 -2
- package/dist/components/WispButton.svelte +83 -0
- package/dist/components/WispButton.svelte.d.ts +49 -0
- package/dist/components/WispPanel.svelte +1093 -0
- package/dist/components/WispPanel.svelte.d.ts +49 -0
- package/dist/components/custom/TableOfContents.svelte +12 -1
- package/dist/components/quota/UpgradePrompt.svelte +1 -0
- package/dist/config/wisp.d.ts +145 -0
- package/dist/config/wisp.js +175 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/server/inference-client.d.ts +139 -0
- package/dist/server/inference-client.js +294 -0
- package/dist/ui/components/content/RoadmapPreview.svelte +91 -0
- package/dist/ui/components/content/RoadmapPreview.svelte.d.ts +36 -0
- package/dist/ui/components/content/index.d.ts +1 -0
- package/dist/ui/components/content/index.js +1 -0
- package/dist/ui/components/nature/Logo.svelte +260 -0
- package/dist/ui/components/nature/Logo.svelte.d.ts +14 -0
- package/dist/ui/components/nature/botanical/Acorn.svelte +48 -0
- package/dist/ui/components/nature/botanical/Acorn.svelte.d.ts +8 -0
- package/dist/ui/components/nature/botanical/Berry.svelte +67 -0
- package/dist/ui/components/nature/botanical/Berry.svelte.d.ts +8 -0
- package/dist/ui/components/nature/botanical/DandelionPuff.svelte +98 -0
- package/dist/ui/components/nature/botanical/DandelionPuff.svelte.d.ts +8 -0
- package/dist/ui/components/nature/botanical/FallingLeavesLayer.svelte +170 -0
- package/dist/ui/components/nature/botanical/FallingLeavesLayer.svelte.d.ts +35 -0
- package/dist/ui/components/nature/botanical/FallingPetalsLayer.svelte +174 -0
- package/dist/ui/components/nature/botanical/FallingPetalsLayer.svelte.d.ts +25 -0
- package/dist/ui/components/nature/botanical/Leaf.svelte +77 -0
- package/dist/ui/components/nature/botanical/Leaf.svelte.d.ts +10 -0
- package/dist/ui/components/nature/botanical/LeafFalling.svelte +186 -0
- package/dist/ui/components/nature/botanical/LeafFalling.svelte.d.ts +22 -0
- package/dist/ui/components/nature/botanical/PetalFalling.svelte +266 -0
- package/dist/ui/components/nature/botanical/PetalFalling.svelte.d.ts +25 -0
- package/dist/ui/components/nature/botanical/PineCone.svelte +61 -0
- package/dist/ui/components/nature/botanical/PineCone.svelte.d.ts +7 -0
- package/dist/ui/components/nature/botanical/Vine.svelte +102 -0
- package/dist/ui/components/nature/botanical/Vine.svelte.d.ts +11 -0
- package/dist/ui/components/nature/botanical/index.d.ts +10 -0
- package/dist/ui/components/nature/botanical/index.js +11 -0
- package/dist/ui/components/nature/creatures/Bee.svelte +78 -0
- package/dist/ui/components/nature/creatures/Bee.svelte.d.ts +9 -0
- package/dist/ui/components/nature/creatures/Bird.svelte +94 -0
- package/dist/ui/components/nature/creatures/Bird.svelte.d.ts +11 -0
- package/dist/ui/components/nature/creatures/BirdFlying.svelte +83 -0
- package/dist/ui/components/nature/creatures/BirdFlying.svelte.d.ts +9 -0
- package/dist/ui/components/nature/creatures/Bluebird.svelte +95 -0
- package/dist/ui/components/nature/creatures/Bluebird.svelte.d.ts +12 -0
- package/dist/ui/components/nature/creatures/Butterfly.svelte +87 -0
- package/dist/ui/components/nature/creatures/Butterfly.svelte.d.ts +9 -0
- package/dist/ui/components/nature/creatures/Cardinal.svelte +95 -0
- package/dist/ui/components/nature/creatures/Cardinal.svelte.d.ts +12 -0
- package/dist/ui/components/nature/creatures/Chickadee.svelte +97 -0
- package/dist/ui/components/nature/creatures/Chickadee.svelte.d.ts +12 -0
- package/dist/ui/components/nature/creatures/Deer.svelte +95 -0
- package/dist/ui/components/nature/creatures/Deer.svelte.d.ts +9 -0
- package/dist/ui/components/nature/creatures/Firefly.svelte +111 -0
- package/dist/ui/components/nature/creatures/Firefly.svelte.d.ts +10 -0
- package/dist/ui/components/nature/creatures/Owl.svelte +91 -0
- package/dist/ui/components/nature/creatures/Owl.svelte.d.ts +9 -0
- package/dist/ui/components/nature/creatures/Rabbit.svelte +90 -0
- package/dist/ui/components/nature/creatures/Rabbit.svelte.d.ts +9 -0
- package/dist/ui/components/nature/creatures/Robin.svelte +98 -0
- package/dist/ui/components/nature/creatures/Robin.svelte.d.ts +12 -0
- package/dist/ui/components/nature/creatures/Squirrel.svelte +97 -0
- package/dist/ui/components/nature/creatures/Squirrel.svelte.d.ts +9 -0
- package/dist/ui/components/nature/creatures/index.d.ts +13 -0
- package/dist/ui/components/nature/creatures/index.js +14 -0
- package/dist/ui/components/nature/ground/Bush.svelte +57 -0
- package/dist/ui/components/nature/ground/Bush.svelte.d.ts +10 -0
- package/dist/ui/components/nature/ground/Crocus.svelte +83 -0
- package/dist/ui/components/nature/ground/Crocus.svelte.d.ts +12 -0
- package/dist/ui/components/nature/ground/Daffodil.svelte +75 -0
- package/dist/ui/components/nature/ground/Daffodil.svelte.d.ts +11 -0
- package/dist/ui/components/nature/ground/Fern.svelte +72 -0
- package/dist/ui/components/nature/ground/Fern.svelte.d.ts +10 -0
- package/dist/ui/components/nature/ground/FlowerWild.svelte +60 -0
- package/dist/ui/components/nature/ground/FlowerWild.svelte.d.ts +10 -0
- package/dist/ui/components/nature/ground/GrassTuft.svelte +49 -0
- package/dist/ui/components/nature/ground/GrassTuft.svelte.d.ts +10 -0
- package/dist/ui/components/nature/ground/Log.svelte +42 -0
- package/dist/ui/components/nature/ground/Log.svelte.d.ts +7 -0
- package/dist/ui/components/nature/ground/Mushroom.svelte +48 -0
- package/dist/ui/components/nature/ground/Mushroom.svelte.d.ts +9 -0
- package/dist/ui/components/nature/ground/MushroomCluster.svelte +41 -0
- package/dist/ui/components/nature/ground/MushroomCluster.svelte.d.ts +8 -0
- package/dist/ui/components/nature/ground/Rock.svelte +59 -0
- package/dist/ui/components/nature/ground/Rock.svelte.d.ts +8 -0
- package/dist/ui/components/nature/ground/Stump.svelte +44 -0
- package/dist/ui/components/nature/ground/Stump.svelte.d.ts +8 -0
- package/dist/ui/components/nature/ground/Tulip.svelte +79 -0
- package/dist/ui/components/nature/ground/Tulip.svelte.d.ts +11 -0
- package/dist/ui/components/nature/ground/index.d.ts +12 -0
- package/dist/ui/components/nature/ground/index.js +13 -0
- package/dist/ui/components/nature/index.d.ts +28 -0
- package/dist/ui/components/nature/index.js +38 -0
- package/dist/ui/components/nature/palette.d.ts +602 -0
- package/dist/ui/components/nature/palette.js +472 -0
- package/dist/ui/components/nature/sky/Cloud.svelte +122 -0
- package/dist/ui/components/nature/sky/Cloud.svelte.d.ts +11 -0
- package/dist/ui/components/nature/sky/CloudWispy.svelte +79 -0
- package/dist/ui/components/nature/sky/CloudWispy.svelte.d.ts +9 -0
- package/dist/ui/components/nature/sky/Moon.svelte +60 -0
- package/dist/ui/components/nature/sky/Moon.svelte.d.ts +9 -0
- package/dist/ui/components/nature/sky/Rainbow.svelte +101 -0
- package/dist/ui/components/nature/sky/Rainbow.svelte.d.ts +8 -0
- package/dist/ui/components/nature/sky/Star.svelte +84 -0
- package/dist/ui/components/nature/sky/Star.svelte.d.ts +10 -0
- package/dist/ui/components/nature/sky/StarCluster.svelte +85 -0
- package/dist/ui/components/nature/sky/StarCluster.svelte.d.ts +9 -0
- package/dist/ui/components/nature/sky/StarShooting.svelte +90 -0
- package/dist/ui/components/nature/sky/StarShooting.svelte.d.ts +9 -0
- package/dist/ui/components/nature/sky/Sun.svelte +70 -0
- package/dist/ui/components/nature/sky/Sun.svelte.d.ts +9 -0
- package/dist/ui/components/nature/sky/index.d.ts +8 -0
- package/dist/ui/components/nature/sky/index.js +9 -0
- package/dist/ui/components/nature/structural/Birdhouse.svelte +53 -0
- package/dist/ui/components/nature/structural/Birdhouse.svelte.d.ts +8 -0
- package/dist/ui/components/nature/structural/Bridge.svelte +65 -0
- package/dist/ui/components/nature/structural/Bridge.svelte.d.ts +7 -0
- package/dist/ui/components/nature/structural/FencePost.svelte +54 -0
- package/dist/ui/components/nature/structural/FencePost.svelte.d.ts +8 -0
- package/dist/ui/components/nature/structural/GardenGate.svelte +70 -0
- package/dist/ui/components/nature/structural/GardenGate.svelte.d.ts +8 -0
- package/dist/ui/components/nature/structural/Lantern.svelte +113 -0
- package/dist/ui/components/nature/structural/Lantern.svelte.d.ts +10 -0
- package/dist/ui/components/nature/structural/Lattice.svelte +89 -0
- package/dist/ui/components/nature/structural/Lattice.svelte.d.ts +8 -0
- package/dist/ui/components/nature/structural/LatticeWithVine.svelte +89 -0
- package/dist/ui/components/nature/structural/LatticeWithVine.svelte.d.ts +11 -0
- package/dist/ui/components/nature/structural/StonePath.svelte +48 -0
- package/dist/ui/components/nature/structural/StonePath.svelte.d.ts +7 -0
- package/dist/ui/components/nature/structural/index.d.ts +8 -0
- package/dist/ui/components/nature/structural/index.js +9 -0
- package/dist/ui/components/nature/trees/TreeAspen.svelte +163 -0
- package/dist/ui/components/nature/trees/TreeAspen.svelte.d.ts +11 -0
- package/dist/ui/components/nature/trees/TreeBirch.svelte +186 -0
- package/dist/ui/components/nature/trees/TreeBirch.svelte.d.ts +11 -0
- package/dist/ui/components/nature/trees/TreeCherry.svelte +108 -0
- package/dist/ui/components/nature/trees/TreeCherry.svelte.d.ts +11 -0
- package/dist/ui/components/nature/trees/TreePine.svelte +79 -0
- package/dist/ui/components/nature/trees/TreePine.svelte.d.ts +11 -0
- package/dist/ui/components/nature/trees/index.d.ts +4 -0
- package/dist/ui/components/nature/trees/index.js +5 -0
- package/dist/ui/components/nature/water/LilyPad.svelte +99 -0
- package/dist/ui/components/nature/water/LilyPad.svelte.d.ts +10 -0
- package/dist/ui/components/nature/water/Pond.svelte +104 -0
- package/dist/ui/components/nature/water/Pond.svelte.d.ts +8 -0
- package/dist/ui/components/nature/water/Reeds.svelte +85 -0
- package/dist/ui/components/nature/water/Reeds.svelte.d.ts +11 -0
- package/dist/ui/components/nature/water/Stream.svelte +98 -0
- package/dist/ui/components/nature/water/Stream.svelte.d.ts +8 -0
- package/dist/ui/components/nature/water/index.d.ts +4 -0
- package/dist/ui/components/nature/water/index.js +5 -0
- package/dist/ui/components/nature/weather/SnowfallLayer.svelte +175 -0
- package/dist/ui/components/nature/weather/SnowfallLayer.svelte.d.ts +25 -0
- package/dist/ui/components/nature/weather/Snowflake.svelte +99 -0
- package/dist/ui/components/nature/weather/Snowflake.svelte.d.ts +11 -0
- package/dist/ui/components/nature/weather/SnowflakeFalling.svelte +162 -0
- package/dist/ui/components/nature/weather/SnowflakeFalling.svelte.d.ts +23 -0
- package/dist/ui/components/nature/weather/index.d.ts +3 -0
- package/dist/ui/components/nature/weather/index.js +4 -0
- package/dist/ui/components/primitives/textarea/textarea.svelte +1 -1
- package/dist/ui/components/typography/Alagard.svelte +17 -0
- package/dist/ui/components/typography/Alagard.svelte.d.ts +10 -0
- package/dist/ui/components/typography/Atkinson.svelte +17 -0
- package/dist/ui/components/typography/Atkinson.svelte.d.ts +10 -0
- package/dist/ui/components/typography/BodoniModa.svelte +17 -0
- package/dist/ui/components/typography/BodoniModa.svelte.d.ts +10 -0
- package/dist/ui/components/typography/Calistoga.svelte +17 -0
- package/dist/ui/components/typography/Calistoga.svelte.d.ts +10 -0
- package/dist/ui/components/typography/Caveat.svelte +17 -0
- package/dist/ui/components/typography/Caveat.svelte.d.ts +10 -0
- package/dist/ui/components/typography/Cormorant.svelte +17 -0
- package/dist/ui/components/typography/Cormorant.svelte.d.ts +10 -0
- package/dist/ui/components/typography/Cozette.svelte +17 -0
- package/dist/ui/components/typography/Cozette.svelte.d.ts +10 -0
- package/dist/ui/components/typography/EBGaramond.svelte +17 -0
- package/dist/ui/components/typography/EBGaramond.svelte.d.ts +10 -0
- package/dist/ui/components/typography/FontProvider.svelte +98 -0
- package/dist/ui/components/typography/FontProvider.svelte.d.ts +17 -0
- package/dist/ui/components/typography/Fraunces.svelte +17 -0
- package/dist/ui/components/typography/Fraunces.svelte.d.ts +10 -0
- package/dist/ui/components/typography/IBMPlexMono.svelte +17 -0
- package/dist/ui/components/typography/IBMPlexMono.svelte.d.ts +10 -0
- package/dist/ui/components/typography/InstrumentSans.svelte +17 -0
- package/dist/ui/components/typography/InstrumentSans.svelte.d.ts +10 -0
- package/dist/ui/components/typography/Lexend.svelte +17 -0
- package/dist/ui/components/typography/Lexend.svelte.d.ts +10 -0
- package/dist/ui/components/typography/Lora.svelte +17 -0
- package/dist/ui/components/typography/Lora.svelte.d.ts +10 -0
- package/dist/ui/components/typography/Luciole.svelte +17 -0
- package/dist/ui/components/typography/Luciole.svelte.d.ts +10 -0
- package/dist/ui/components/typography/Manrope.svelte +17 -0
- package/dist/ui/components/typography/Manrope.svelte.d.ts +10 -0
- package/dist/ui/components/typography/Merriweather.svelte +17 -0
- package/dist/ui/components/typography/Merriweather.svelte.d.ts +10 -0
- package/dist/ui/components/typography/Nunito.svelte +17 -0
- package/dist/ui/components/typography/Nunito.svelte.d.ts +10 -0
- package/dist/ui/components/typography/OpenDyslexic.svelte +17 -0
- package/dist/ui/components/typography/OpenDyslexic.svelte.d.ts +10 -0
- package/dist/ui/components/typography/PlusJakartaSans.svelte +17 -0
- package/dist/ui/components/typography/PlusJakartaSans.svelte.d.ts +10 -0
- package/dist/ui/components/typography/Quicksand.svelte +17 -0
- package/dist/ui/components/typography/Quicksand.svelte.d.ts +10 -0
- package/dist/ui/components/typography/README.md +153 -0
- package/dist/ui/components/typography/index.d.ts +23 -0
- package/dist/ui/components/typography/index.js +42 -0
- package/dist/ui/components/ui/GlassCarousel.svelte +446 -0
- package/dist/ui/components/ui/GlassCarousel.svelte.d.ts +57 -0
- package/dist/ui/components/ui/GlassConfirmDialog.svelte +2 -1
- package/dist/ui/components/ui/GlassLogo.svelte +423 -0
- package/dist/ui/components/ui/GlassLogo.svelte.d.ts +23 -0
- package/dist/ui/components/ui/GlassNavbar.svelte +120 -0
- package/dist/ui/components/ui/GlassNavbar.svelte.d.ts +42 -0
- package/dist/ui/components/ui/GlassOverlay.svelte +1 -1
- package/dist/ui/components/ui/Logo.svelte +47 -52
- package/dist/ui/components/ui/Logo.svelte.d.ts +4 -3
- package/dist/ui/components/ui/index.d.ts +3 -0
- package/dist/ui/components/ui/index.js +3 -0
- package/dist/ui/index.d.ts +1 -0
- package/dist/ui/index.js +2 -0
- package/dist/ui/styles/grove.css +15 -1
- package/dist/ui/vineyard/index.d.ts +9 -0
- package/dist/ui/vineyard/index.js +8 -0
- package/dist/utils/csrf.js +5 -2
- package/dist/utils/readability.d.ts +89 -0
- package/dist/utils/readability.js +204 -0
- package/package.json +27 -1
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Grove — A place to Be
|
|
3
|
+
Copyright (c) 2025 Autumn Brown
|
|
4
|
+
Licensed under AGPL-3.0
|
|
5
|
+
-->
|
|
6
|
+
<script lang="ts">
|
|
7
|
+
import { bark, accents } from '../palette';
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
class?: string;
|
|
11
|
+
style?: string;
|
|
12
|
+
bodyColor?: string;
|
|
13
|
+
breastColor?: string;
|
|
14
|
+
beakColor?: string;
|
|
15
|
+
animate?: boolean;
|
|
16
|
+
facing?: 'left' | 'right';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let {
|
|
20
|
+
class: className = 'w-6 h-6',
|
|
21
|
+
style,
|
|
22
|
+
bodyColor,
|
|
23
|
+
breastColor,
|
|
24
|
+
beakColor,
|
|
25
|
+
animate = true,
|
|
26
|
+
facing = 'right'
|
|
27
|
+
}: Props = $props();
|
|
28
|
+
|
|
29
|
+
// American Robin colors - from palette
|
|
30
|
+
const body = $derived(bodyColor ?? accents.bird.robinBody);
|
|
31
|
+
const wing = $derived(accents.bird.robinWing);
|
|
32
|
+
const wingDark = $derived(accents.bird.robinWingDark);
|
|
33
|
+
const breast = $derived(breastColor ?? accents.bird.robinBreast);
|
|
34
|
+
const breastLight = $derived(accents.bird.robinBreastLight);
|
|
35
|
+
const beak = $derived(beakColor ?? accents.bird.robinBeak);
|
|
36
|
+
const legColor = $derived(bark.darkBark);
|
|
37
|
+
|
|
38
|
+
const scaleX = $derived(facing === 'left' ? -1 : 1);
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<!-- American Robin - herald of spring! -->
|
|
42
|
+
<svg
|
|
43
|
+
class="{className} {animate ? 'hop' : ''}"
|
|
44
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
45
|
+
viewBox="0 0 50 60"
|
|
46
|
+
style="transform: scaleX({scaleX}); {style ?? ''}"
|
|
47
|
+
>
|
|
48
|
+
<!-- Tail feathers - dark gray-brown -->
|
|
49
|
+
<path fill={body} d="M5 32 Q2 38 4 46 Q10 44 14 38 Q15 34 11 31 Q7 30 5 32" />
|
|
50
|
+
<path fill={wing} d="M6 34 Q4 40 5 44 Q9 42 11 38" opacity="0.5" />
|
|
51
|
+
|
|
52
|
+
<!-- Body - dark gray-brown upper -->
|
|
53
|
+
<ellipse fill={body} cx="22" cy="30" rx="14" ry="11" />
|
|
54
|
+
|
|
55
|
+
<!-- Wing - slightly darker with feather details -->
|
|
56
|
+
<path fill={wing} d="M9 26 Q5 32 8 40 Q15 38 19 32 Q17 25 9 26" />
|
|
57
|
+
<path fill={wingDark} d="M11 30 Q9 34 11 38 Q14 36 15 33 Q13 30 11 30" opacity="0.5" />
|
|
58
|
+
|
|
59
|
+
<!-- Breast - iconic orange-red -->
|
|
60
|
+
<ellipse fill={breast} cx="30" cy="34" rx="9" ry="10" />
|
|
61
|
+
<!-- Breast highlight -->
|
|
62
|
+
<ellipse fill={breastLight} cx="32" cy="32" rx="5" ry="6" opacity="0.4" />
|
|
63
|
+
|
|
64
|
+
<!-- Head - dark gray -->
|
|
65
|
+
<circle fill={body} cx="36" cy="18" r="9" />
|
|
66
|
+
|
|
67
|
+
<!-- White eye ring - Robin's distinctive feature -->
|
|
68
|
+
<circle fill="white" cx="40" cy="17" r="4" opacity="0.3" />
|
|
69
|
+
|
|
70
|
+
<!-- Eye -->
|
|
71
|
+
<circle fill="#1a1a1a" cx="40" cy="17" r="2.5" />
|
|
72
|
+
<!-- Eye highlight -->
|
|
73
|
+
<circle fill="white" cx="41" cy="16" r="0.8" />
|
|
74
|
+
|
|
75
|
+
<!-- Beak - yellow-orange, pointed -->
|
|
76
|
+
<path fill={beak} d="M44 18 L52 19 L44 22 Q43 20 44 18" />
|
|
77
|
+
<!-- Beak detail -->
|
|
78
|
+
<path fill="#d97706" d="M45 19 Q48 19 50 19.5" stroke="#b45309" stroke-width="0.3" />
|
|
79
|
+
|
|
80
|
+
<!-- Legs - dark -->
|
|
81
|
+
<g fill="none" stroke={legColor} stroke-width="1.5">
|
|
82
|
+
<path d="M22 41 L22 52 M20 50 L24 50" />
|
|
83
|
+
<path d="M28 41 L28 52 M26 50 L30 50" />
|
|
84
|
+
</g>
|
|
85
|
+
</svg>
|
|
86
|
+
|
|
87
|
+
<style>
|
|
88
|
+
@keyframes hop {
|
|
89
|
+
0%, 100% { transform: translateY(0); }
|
|
90
|
+
25% { transform: translateY(-3px); }
|
|
91
|
+
50% { transform: translateY(0); }
|
|
92
|
+
75% { transform: translateY(-2px); }
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.hop {
|
|
96
|
+
animation: hop 1.8s ease-in-out infinite;
|
|
97
|
+
}
|
|
98
|
+
</style>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
class?: string;
|
|
3
|
+
style?: string;
|
|
4
|
+
bodyColor?: string;
|
|
5
|
+
breastColor?: string;
|
|
6
|
+
beakColor?: string;
|
|
7
|
+
animate?: boolean;
|
|
8
|
+
facing?: 'left' | 'right';
|
|
9
|
+
}
|
|
10
|
+
declare const Robin: import("svelte").Component<Props, {}, "">;
|
|
11
|
+
type Robin = ReturnType<typeof Robin>;
|
|
12
|
+
export default Robin;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Grove — A place to Be
|
|
3
|
+
Copyright (c) 2025 Autumn Brown
|
|
4
|
+
Licensed under AGPL-3.0
|
|
5
|
+
-->
|
|
6
|
+
<script lang="ts">
|
|
7
|
+
import { bark, earth } from '../palette';
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
class?: string;
|
|
11
|
+
furColor?: string;
|
|
12
|
+
animate?: boolean;
|
|
13
|
+
facing?: 'left' | 'right';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let {
|
|
17
|
+
class: className = 'w-8 h-8',
|
|
18
|
+
furColor,
|
|
19
|
+
animate = true,
|
|
20
|
+
facing = 'right'
|
|
21
|
+
}: Props = $props();
|
|
22
|
+
|
|
23
|
+
const fur = $derived(furColor ?? bark.warmBark);
|
|
24
|
+
const lightFur = $derived(earth.sand);
|
|
25
|
+
const scaleX = $derived(facing === 'left' ? -1 : 1);
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<!-- Sitting squirrel -->
|
|
29
|
+
<svg
|
|
30
|
+
class={className}
|
|
31
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
32
|
+
viewBox="0 0 60 70"
|
|
33
|
+
style="transform: scaleX({scaleX})"
|
|
34
|
+
>
|
|
35
|
+
<!-- Tail (fluffy!) -->
|
|
36
|
+
<g class={animate ? 'tail-flick' : ''}>
|
|
37
|
+
<path
|
|
38
|
+
fill={fur}
|
|
39
|
+
d="M5 35 Q0 20 10 10 Q20 5 25 15 Q28 25 20 35 Q15 40 10 38 Q5 40 5 35"
|
|
40
|
+
/>
|
|
41
|
+
<path
|
|
42
|
+
fill={lightFur}
|
|
43
|
+
d="M10 30 Q8 22 15 15 Q20 12 22 18 Q23 24 18 30"
|
|
44
|
+
opacity="0.5"
|
|
45
|
+
/>
|
|
46
|
+
</g>
|
|
47
|
+
|
|
48
|
+
<!-- Back leg -->
|
|
49
|
+
<ellipse fill={fur} cx="25" cy="58" rx="10" ry="8" />
|
|
50
|
+
|
|
51
|
+
<!-- Body -->
|
|
52
|
+
<ellipse fill={fur} cx="32" cy="45" rx="14" ry="16" />
|
|
53
|
+
|
|
54
|
+
<!-- Belly -->
|
|
55
|
+
<ellipse fill={lightFur} cx="35" cy="48" rx="8" ry="10" />
|
|
56
|
+
|
|
57
|
+
<!-- Front paws (holding something) -->
|
|
58
|
+
<ellipse fill={fur} cx="42" cy="52" rx="4" ry="6" />
|
|
59
|
+
<ellipse fill={fur} cx="48" cy="50" rx="4" ry="5" />
|
|
60
|
+
|
|
61
|
+
<!-- Head -->
|
|
62
|
+
<circle fill={fur} cx="48" cy="32" r="12" />
|
|
63
|
+
|
|
64
|
+
<!-- Cheek -->
|
|
65
|
+
<ellipse fill={lightFur} cx="52" cy="36" rx="6" ry="5" />
|
|
66
|
+
|
|
67
|
+
<!-- Ears -->
|
|
68
|
+
<ellipse fill={fur} cx="42" cy="20" rx="4" ry="6" />
|
|
69
|
+
<ellipse fill={lightFur} cx="42" cy="20" rx="2" ry="4" />
|
|
70
|
+
<ellipse fill={fur} cx="52" cy="18" rx="4" ry="6" />
|
|
71
|
+
<ellipse fill={lightFur} cx="52" cy="18" rx="2" ry="4" />
|
|
72
|
+
|
|
73
|
+
<!-- Eye -->
|
|
74
|
+
<circle fill="#1a1a1a" cx="52" cy="30" r="3" />
|
|
75
|
+
<circle fill="white" cx="53" cy="29" r="1" />
|
|
76
|
+
|
|
77
|
+
<!-- Nose -->
|
|
78
|
+
<circle fill="#1a1a1a" cx="58" cy="34" r="2" />
|
|
79
|
+
|
|
80
|
+
<!-- Acorn (optional detail) -->
|
|
81
|
+
<ellipse fill={bark.bark} cx="45" cy="56" rx="3" ry="4" />
|
|
82
|
+
<path fill={bark.darkBark} d="M42 53 Q45 51 48 53 L48 54 Q45 52 42 54 Z" />
|
|
83
|
+
</svg>
|
|
84
|
+
|
|
85
|
+
<style>
|
|
86
|
+
@keyframes tail-flick {
|
|
87
|
+
0%, 80%, 100% { transform: rotate(0deg); }
|
|
88
|
+
85% { transform: rotate(5deg); }
|
|
89
|
+
90% { transform: rotate(-3deg); }
|
|
90
|
+
95% { transform: rotate(2deg); }
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.tail-flick {
|
|
94
|
+
transform-origin: bottom right;
|
|
95
|
+
animation: tail-flick 3s ease-in-out infinite;
|
|
96
|
+
}
|
|
97
|
+
</style>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { default as Bee } from './Bee.svelte';
|
|
2
|
+
export { default as Bird } from './Bird.svelte';
|
|
3
|
+
export { default as BirdFlying } from './BirdFlying.svelte';
|
|
4
|
+
export { default as Bluebird } from './Bluebird.svelte';
|
|
5
|
+
export { default as Butterfly } from './Butterfly.svelte';
|
|
6
|
+
export { default as Cardinal } from './Cardinal.svelte';
|
|
7
|
+
export { default as Chickadee } from './Chickadee.svelte';
|
|
8
|
+
export { default as Deer } from './Deer.svelte';
|
|
9
|
+
export { default as Firefly } from './Firefly.svelte';
|
|
10
|
+
export { default as Owl } from './Owl.svelte';
|
|
11
|
+
export { default as Rabbit } from './Rabbit.svelte';
|
|
12
|
+
export { default as Robin } from './Robin.svelte';
|
|
13
|
+
export { default as Squirrel } from './Squirrel.svelte';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Creature components - animals and insects that bring the forest to life
|
|
2
|
+
export { default as Bee } from './Bee.svelte';
|
|
3
|
+
export { default as Bird } from './Bird.svelte';
|
|
4
|
+
export { default as BirdFlying } from './BirdFlying.svelte';
|
|
5
|
+
export { default as Bluebird } from './Bluebird.svelte';
|
|
6
|
+
export { default as Butterfly } from './Butterfly.svelte';
|
|
7
|
+
export { default as Cardinal } from './Cardinal.svelte';
|
|
8
|
+
export { default as Chickadee } from './Chickadee.svelte';
|
|
9
|
+
export { default as Deer } from './Deer.svelte';
|
|
10
|
+
export { default as Firefly } from './Firefly.svelte';
|
|
11
|
+
export { default as Owl } from './Owl.svelte';
|
|
12
|
+
export { default as Rabbit } from './Rabbit.svelte';
|
|
13
|
+
export { default as Robin } from './Robin.svelte';
|
|
14
|
+
export { default as Squirrel } from './Squirrel.svelte';
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Grove — A place to Be
|
|
3
|
+
Copyright (c) 2025 Autumn Brown
|
|
4
|
+
Licensed under AGPL-3.0
|
|
5
|
+
-->
|
|
6
|
+
<script lang="ts">
|
|
7
|
+
import type { Season } from '../palette';
|
|
8
|
+
import { greens, autumn, bark } from '../palette';
|
|
9
|
+
|
|
10
|
+
interface Props {
|
|
11
|
+
class?: string;
|
|
12
|
+
color?: string;
|
|
13
|
+
season?: Season;
|
|
14
|
+
animate?: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let {
|
|
18
|
+
class: className = 'w-8 h-8',
|
|
19
|
+
color,
|
|
20
|
+
season = 'summer',
|
|
21
|
+
animate = false
|
|
22
|
+
}: Props = $props();
|
|
23
|
+
|
|
24
|
+
// Bushes turn warm colors in autumn
|
|
25
|
+
const defaultColor = $derived(season === 'autumn' ? autumn.amber : greens.grove);
|
|
26
|
+
const foliageColor = $derived(color ?? defaultColor);
|
|
27
|
+
const shadowColor = $derived(season === 'autumn' ? autumn.rust : greens.deepGreen);
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<!-- Round bush/shrub -->
|
|
31
|
+
<svg class="{className} {animate ? 'sway' : ''}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 60">
|
|
32
|
+
<!-- Base shadow/depth -->
|
|
33
|
+
<ellipse fill={shadowColor} cx="40" cy="45" rx="35" ry="15" opacity="0.5" />
|
|
34
|
+
|
|
35
|
+
<!-- Main foliage clusters -->
|
|
36
|
+
<ellipse fill={foliageColor} cx="40" cy="35" rx="32" ry="25" />
|
|
37
|
+
<ellipse fill={foliageColor} cx="22" cy="40" rx="20" ry="18" />
|
|
38
|
+
<ellipse fill={foliageColor} cx="58" cy="40" rx="20" ry="18" />
|
|
39
|
+
<ellipse fill={foliageColor} cx="40" cy="22" rx="22" ry="16" />
|
|
40
|
+
<ellipse fill={foliageColor} cx="28" cy="28" rx="15" ry="12" />
|
|
41
|
+
<ellipse fill={foliageColor} cx="52" cy="28" rx="15" ry="12" />
|
|
42
|
+
|
|
43
|
+
<!-- Ground hint -->
|
|
44
|
+
<ellipse fill={bark.bark} cx="40" cy="55" rx="15" ry="4" opacity="0.3" />
|
|
45
|
+
</svg>
|
|
46
|
+
|
|
47
|
+
<style>
|
|
48
|
+
@keyframes sway {
|
|
49
|
+
0%, 100% { transform: rotate(0deg); }
|
|
50
|
+
50% { transform: rotate(0.5deg); }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.sway {
|
|
54
|
+
transform-origin: center bottom;
|
|
55
|
+
animation: sway 4s ease-in-out infinite;
|
|
56
|
+
}
|
|
57
|
+
</style>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Season } from '../palette';
|
|
2
|
+
interface Props {
|
|
3
|
+
class?: string;
|
|
4
|
+
color?: string;
|
|
5
|
+
season?: Season;
|
|
6
|
+
animate?: boolean;
|
|
7
|
+
}
|
|
8
|
+
declare const Bush: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type Bush = ReturnType<typeof Bush>;
|
|
10
|
+
export default Bush;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Grove — A place to Be
|
|
3
|
+
Copyright (c) 2025 Autumn Brown
|
|
4
|
+
Licensed under AGPL-3.0
|
|
5
|
+
-->
|
|
6
|
+
<script lang="ts">
|
|
7
|
+
import { greens, wildflowers } from '../palette';
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
class?: string;
|
|
11
|
+
style?: string;
|
|
12
|
+
petalColor?: string;
|
|
13
|
+
centerColor?: string;
|
|
14
|
+
stemColor?: string;
|
|
15
|
+
variant?: 'purple' | 'yellow' | 'white';
|
|
16
|
+
animate?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let {
|
|
20
|
+
class: className = 'w-4 h-6',
|
|
21
|
+
style,
|
|
22
|
+
petalColor,
|
|
23
|
+
centerColor,
|
|
24
|
+
stemColor,
|
|
25
|
+
variant = 'purple',
|
|
26
|
+
animate = true
|
|
27
|
+
}: Props = $props();
|
|
28
|
+
|
|
29
|
+
// Crocus color variants - early spring bloomers
|
|
30
|
+
const variantColors = {
|
|
31
|
+
purple: wildflowers.crocus,
|
|
32
|
+
yellow: wildflowers.buttercup,
|
|
33
|
+
white: '#fafafa'
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const petals = $derived(petalColor ?? variantColors[variant]);
|
|
37
|
+
const center = $derived(centerColor ?? '#f97316'); // Orange stamen
|
|
38
|
+
const stem = $derived(stemColor ?? greens.deepGreen);
|
|
39
|
+
|
|
40
|
+
// Slightly different shade for depth
|
|
41
|
+
const petalDark = $derived(variant === 'purple' ? '#7c3aed' :
|
|
42
|
+
variant === 'yellow' ? '#eab308' :
|
|
43
|
+
'#e5e5e5');
|
|
44
|
+
</script>
|
|
45
|
+
|
|
46
|
+
<!-- Crocus - first flowers of spring, often peeking through snow -->
|
|
47
|
+
<svg class="{className} {animate ? 'emerge' : ''}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 60" style={style}>
|
|
48
|
+
<!-- Stem - short, crocus blooms close to ground -->
|
|
49
|
+
<path fill="none" stroke={stem} stroke-width="2" d="M20 60 Q19 50 20 42" />
|
|
50
|
+
|
|
51
|
+
<!-- Grass-like leaves -->
|
|
52
|
+
<path fill={stem} d="M20 58 Q14 50 12 55 Q16 48 20 52" />
|
|
53
|
+
<path fill={stem} d="M20 55 Q26 47 28 52 Q24 45 20 50" />
|
|
54
|
+
<path fill={stem} d="M18 52 Q10 40 8 45 Q14 38 18 45" />
|
|
55
|
+
<path fill={stem} d="M22 52 Q30 40 32 45 Q26 38 22 45" />
|
|
56
|
+
|
|
57
|
+
<!-- Crocus bloom - goblet-shaped with pointed petals -->
|
|
58
|
+
<!-- Outer petals -->
|
|
59
|
+
<path fill={petals} d="M10 40 Q8 28 14 15 Q20 8 20 8 Q12 20 10 40" />
|
|
60
|
+
<path fill={petals} d="M30 40 Q32 28 26 15 Q20 8 20 8 Q28 20 30 40" />
|
|
61
|
+
<path fill={petals} d="M15 42 Q10 30 18 12 Q20 8 20 8 Q15 18 15 42" />
|
|
62
|
+
<path fill={petals} d="M25 42 Q30 30 22 12 Q20 8 20 8 Q25 18 25 42" />
|
|
63
|
+
|
|
64
|
+
<!-- Inner petals (darker) -->
|
|
65
|
+
<path fill={petalDark} d="M17 38 Q15 28 19 16 Q20 12 20 12 Q18 22 17 38" opacity="0.6" />
|
|
66
|
+
<path fill={petalDark} d="M23 38 Q25 28 21 16 Q20 12 20 12 Q22 22 23 38" opacity="0.6" />
|
|
67
|
+
|
|
68
|
+
<!-- Center/stamen - distinctive orange -->
|
|
69
|
+
<ellipse fill={center} cx="20" cy="35" rx="3" ry="4" />
|
|
70
|
+
<path fill="#ea580c" d="M19 32 L20 25 L21 32" opacity="0.8" />
|
|
71
|
+
</svg>
|
|
72
|
+
|
|
73
|
+
<style>
|
|
74
|
+
@keyframes emerge {
|
|
75
|
+
0%, 100% { transform: translateY(0) scale(1); }
|
|
76
|
+
50% { transform: translateY(-1px) scale(1.02); }
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.emerge {
|
|
80
|
+
transform-origin: center bottom;
|
|
81
|
+
animation: emerge 4s ease-in-out infinite;
|
|
82
|
+
}
|
|
83
|
+
</style>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
class?: string;
|
|
3
|
+
style?: string;
|
|
4
|
+
petalColor?: string;
|
|
5
|
+
centerColor?: string;
|
|
6
|
+
stemColor?: string;
|
|
7
|
+
variant?: 'purple' | 'yellow' | 'white';
|
|
8
|
+
animate?: boolean;
|
|
9
|
+
}
|
|
10
|
+
declare const Crocus: import("svelte").Component<Props, {}, "">;
|
|
11
|
+
type Crocus = ReturnType<typeof Crocus>;
|
|
12
|
+
export default Crocus;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Grove — A place to Be
|
|
3
|
+
Copyright (c) 2025 Autumn Brown
|
|
4
|
+
Licensed under AGPL-3.0
|
|
5
|
+
-->
|
|
6
|
+
<script lang="ts">
|
|
7
|
+
import { greens, wildflowers } from '../palette';
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
class?: string;
|
|
11
|
+
style?: string;
|
|
12
|
+
petalColor?: string;
|
|
13
|
+
trumpetColor?: string;
|
|
14
|
+
stemColor?: string;
|
|
15
|
+
animate?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let {
|
|
19
|
+
class: className = 'w-5 h-8',
|
|
20
|
+
style,
|
|
21
|
+
petalColor,
|
|
22
|
+
trumpetColor,
|
|
23
|
+
stemColor,
|
|
24
|
+
animate = true
|
|
25
|
+
}: Props = $props();
|
|
26
|
+
|
|
27
|
+
const petals = $derived(petalColor ?? wildflowers.daffodil); // Pale yellow petals
|
|
28
|
+
const trumpet = $derived(trumpetColor ?? wildflowers.buttercup); // Deeper yellow/orange trumpet
|
|
29
|
+
const stem = $derived(stemColor ?? greens.deepGreen);
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<!-- Daffodil - classic spring herald -->
|
|
33
|
+
<svg class="{className} {animate ? 'nod' : ''}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 80" style={style}>
|
|
34
|
+
<!-- Stem - curved like real daffodils -->
|
|
35
|
+
<path fill="none" stroke={stem} stroke-width="2.5" d="M25 80 Q23 65 25 50 Q28 42 32 38" />
|
|
36
|
+
|
|
37
|
+
<!-- Long strap-like leaves -->
|
|
38
|
+
<path fill={stem} d="M25 78 Q15 65 10 70 Q18 60 25 68" />
|
|
39
|
+
<path fill={stem} d="M25 72 Q35 58 40 63 Q32 52 25 62" />
|
|
40
|
+
<path fill={stem} d="M23 65 Q10 50 5 58 Q15 45 23 55" />
|
|
41
|
+
|
|
42
|
+
<!-- Flower faces slightly to the side (characteristic daffodil pose) -->
|
|
43
|
+
<g transform="rotate(-15 32 28)">
|
|
44
|
+
<!-- Back petals (6 petals in star pattern) -->
|
|
45
|
+
<ellipse fill={petals} cx="32" cy="18" rx="5" ry="12" />
|
|
46
|
+
<ellipse fill={petals} cx="32" cy="18" rx="5" ry="12" transform="rotate(60 32 28)" />
|
|
47
|
+
<ellipse fill={petals} cx="32" cy="18" rx="5" ry="12" transform="rotate(120 32 28)" />
|
|
48
|
+
<ellipse fill={petals} cx="32" cy="38" rx="5" ry="12" />
|
|
49
|
+
<ellipse fill={petals} cx="32" cy="38" rx="5" ry="12" transform="rotate(60 32 28)" />
|
|
50
|
+
<ellipse fill={petals} cx="32" cy="38" rx="5" ry="12" transform="rotate(120 32 28)" />
|
|
51
|
+
|
|
52
|
+
<!-- Central trumpet/corona - the distinctive feature -->
|
|
53
|
+
<ellipse fill={trumpet} cx="32" cy="28" rx="7" ry="8" />
|
|
54
|
+
<!-- Trumpet rim - ruffled edge effect -->
|
|
55
|
+
<ellipse fill="none" stroke={trumpet} stroke-width="2" cx="32" cy="24" rx="6" ry="4" opacity="0.8" />
|
|
56
|
+
<!-- Inner trumpet shadow -->
|
|
57
|
+
<ellipse fill="#d97706" cx="32" cy="28" rx="4" ry="5" opacity="0.5" />
|
|
58
|
+
|
|
59
|
+
<!-- Stamen in center -->
|
|
60
|
+
<circle fill="#f97316" cx="32" cy="30" r="2" />
|
|
61
|
+
</g>
|
|
62
|
+
</svg>
|
|
63
|
+
|
|
64
|
+
<style>
|
|
65
|
+
@keyframes nod {
|
|
66
|
+
0%, 100% { transform: rotate(0deg); }
|
|
67
|
+
25% { transform: rotate(2deg); }
|
|
68
|
+
75% { transform: rotate(-1deg); }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.nod {
|
|
72
|
+
transform-origin: center bottom;
|
|
73
|
+
animation: nod 3.5s ease-in-out infinite;
|
|
74
|
+
}
|
|
75
|
+
</style>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
class?: string;
|
|
3
|
+
style?: string;
|
|
4
|
+
petalColor?: string;
|
|
5
|
+
trumpetColor?: string;
|
|
6
|
+
stemColor?: string;
|
|
7
|
+
animate?: boolean;
|
|
8
|
+
}
|
|
9
|
+
declare const Daffodil: import("svelte").Component<Props, {}, "">;
|
|
10
|
+
type Daffodil = ReturnType<typeof Daffodil>;
|
|
11
|
+
export default Daffodil;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Grove — A place to Be
|
|
3
|
+
Copyright (c) 2025 Autumn Brown
|
|
4
|
+
Licensed under AGPL-3.0
|
|
5
|
+
-->
|
|
6
|
+
<script lang="ts">
|
|
7
|
+
import type { Season } from '../palette';
|
|
8
|
+
import { greens, autumn } from '../palette';
|
|
9
|
+
|
|
10
|
+
interface Props {
|
|
11
|
+
class?: string;
|
|
12
|
+
color?: string;
|
|
13
|
+
season?: Season;
|
|
14
|
+
animate?: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let {
|
|
18
|
+
class: className = 'w-6 h-6',
|
|
19
|
+
color,
|
|
20
|
+
season = 'summer',
|
|
21
|
+
animate = true
|
|
22
|
+
}: Props = $props();
|
|
23
|
+
|
|
24
|
+
// Ferns turn golden/brown in autumn
|
|
25
|
+
const defaultColor = $derived(season === 'autumn' ? autumn.gold : greens.deepGreen);
|
|
26
|
+
const frondColor = $derived(color ?? defaultColor);
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<!-- Curled fern frond -->
|
|
30
|
+
<svg class="{className} {animate ? 'sway' : ''}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 70">
|
|
31
|
+
<!-- Main stem -->
|
|
32
|
+
<path
|
|
33
|
+
fill="none"
|
|
34
|
+
stroke={frondColor}
|
|
35
|
+
stroke-width="2"
|
|
36
|
+
d="M25 70 Q24 50 26 35 Q28 20 35 8"
|
|
37
|
+
/>
|
|
38
|
+
|
|
39
|
+
<!-- Left leaflets -->
|
|
40
|
+
<path fill={frondColor} d="M24 60 Q15 55 10 58 Q18 52 24 55" />
|
|
41
|
+
<path fill={frondColor} d="M24 50 Q12 44 6 48 Q16 40 24 45" />
|
|
42
|
+
<path fill={frondColor} d="M25 40 Q14 32 8 36 Q17 28 25 34" />
|
|
43
|
+
<path fill={frondColor} d="M27 30 Q18 22 14 26 Q21 18 27 24" />
|
|
44
|
+
<path fill={frondColor} d="M30 22 Q24 15 22 18 Q27 12 32 16" />
|
|
45
|
+
|
|
46
|
+
<!-- Right leaflets -->
|
|
47
|
+
<path fill={frondColor} d="M26 60 Q35 55 40 58 Q32 52 26 55" />
|
|
48
|
+
<path fill={frondColor} d="M26 50 Q38 44 44 48 Q34 40 26 45" />
|
|
49
|
+
<path fill={frondColor} d="M27 40 Q38 32 44 36 Q35 28 27 34" />
|
|
50
|
+
<path fill={frondColor} d="M29 30 Q38 22 42 26 Q35 18 29 24" />
|
|
51
|
+
<path fill={frondColor} d="M33 22 Q38 16 40 18 Q36 12 32 16" />
|
|
52
|
+
|
|
53
|
+
<!-- Curled tip -->
|
|
54
|
+
<path
|
|
55
|
+
fill="none"
|
|
56
|
+
stroke={frondColor}
|
|
57
|
+
stroke-width="1.5"
|
|
58
|
+
d="M35 8 Q42 4 44 8 Q44 12 40 12"
|
|
59
|
+
/>
|
|
60
|
+
</svg>
|
|
61
|
+
|
|
62
|
+
<style>
|
|
63
|
+
@keyframes sway {
|
|
64
|
+
0%, 100% { transform: rotate(0deg); }
|
|
65
|
+
50% { transform: rotate(2deg); }
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.sway {
|
|
69
|
+
transform-origin: center bottom;
|
|
70
|
+
animation: sway 3s ease-in-out infinite;
|
|
71
|
+
}
|
|
72
|
+
</style>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Season } from '../palette';
|
|
2
|
+
interface Props {
|
|
3
|
+
class?: string;
|
|
4
|
+
color?: string;
|
|
5
|
+
season?: Season;
|
|
6
|
+
animate?: boolean;
|
|
7
|
+
}
|
|
8
|
+
declare const Fern: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type Fern = ReturnType<typeof Fern>;
|
|
10
|
+
export default Fern;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Grove — A place to Be
|
|
3
|
+
Copyright (c) 2025 Autumn Brown
|
|
4
|
+
Licensed under AGPL-3.0
|
|
5
|
+
-->
|
|
6
|
+
<script lang="ts">
|
|
7
|
+
import { accents, greens } from '../palette';
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
class?: string;
|
|
11
|
+
petalColor?: string;
|
|
12
|
+
centerColor?: string;
|
|
13
|
+
stemColor?: string;
|
|
14
|
+
animate?: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let {
|
|
18
|
+
class: className = 'w-4 h-6',
|
|
19
|
+
petalColor,
|
|
20
|
+
centerColor,
|
|
21
|
+
stemColor,
|
|
22
|
+
animate = true
|
|
23
|
+
}: Props = $props();
|
|
24
|
+
|
|
25
|
+
const petals = $derived(petalColor ?? accents.flower.purple);
|
|
26
|
+
const center = $derived(centerColor ?? accents.flower.yellow);
|
|
27
|
+
const stem = $derived(stemColor ?? greens.deepGreen);
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<!-- Simple 5-petal wildflower -->
|
|
31
|
+
<svg class="{className} {animate ? 'sway' : ''}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 60">
|
|
32
|
+
<!-- Stem -->
|
|
33
|
+
<path fill="none" stroke={stem} stroke-width="2" d="M20 60 Q18 45 20 30" />
|
|
34
|
+
|
|
35
|
+
<!-- Leaves -->
|
|
36
|
+
<path fill={stem} d="M20 50 Q12 45 8 48 Q14 42 20 45" />
|
|
37
|
+
<path fill={stem} d="M20 42 Q28 37 32 40 Q26 34 20 38" />
|
|
38
|
+
|
|
39
|
+
<!-- Petals -->
|
|
40
|
+
<ellipse fill={petals} cx="20" cy="12" rx="6" ry="10" />
|
|
41
|
+
<ellipse fill={petals} cx="10" cy="20" rx="6" ry="10" transform="rotate(-72 10 20)" />
|
|
42
|
+
<ellipse fill={petals} cx="30" cy="20" rx="6" ry="10" transform="rotate(72 30 20)" />
|
|
43
|
+
<ellipse fill={petals} cx="13" cy="28" rx="6" ry="10" transform="rotate(-144 13 28)" />
|
|
44
|
+
<ellipse fill={petals} cx="27" cy="28" rx="6" ry="10" transform="rotate(144 27 28)" />
|
|
45
|
+
|
|
46
|
+
<!-- Center -->
|
|
47
|
+
<circle fill={center} cx="20" cy="22" r="5" />
|
|
48
|
+
</svg>
|
|
49
|
+
|
|
50
|
+
<style>
|
|
51
|
+
@keyframes sway {
|
|
52
|
+
0%, 100% { transform: rotate(0deg); }
|
|
53
|
+
50% { transform: rotate(3deg); }
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.sway {
|
|
57
|
+
transform-origin: center bottom;
|
|
58
|
+
animation: sway 2.8s ease-in-out infinite;
|
|
59
|
+
}
|
|
60
|
+
</style>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
class?: string;
|
|
3
|
+
petalColor?: string;
|
|
4
|
+
centerColor?: string;
|
|
5
|
+
stemColor?: string;
|
|
6
|
+
animate?: boolean;
|
|
7
|
+
}
|
|
8
|
+
declare const FlowerWild: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type FlowerWild = ReturnType<typeof FlowerWild>;
|
|
10
|
+
export default FlowerWild;
|