@autumnsgrove/groveengine 0.7.0 → 0.8.0

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.
Files changed (160) hide show
  1. package/dist/ui/components/content/RoadmapPreview.svelte +91 -0
  2. package/dist/ui/components/content/RoadmapPreview.svelte.d.ts +36 -0
  3. package/dist/ui/components/content/index.d.ts +1 -0
  4. package/dist/ui/components/content/index.js +1 -0
  5. package/dist/ui/components/nature/Logo.svelte +224 -0
  6. package/dist/ui/components/nature/Logo.svelte.d.ts +14 -0
  7. package/dist/ui/components/nature/botanical/Acorn.svelte +48 -0
  8. package/dist/ui/components/nature/botanical/Acorn.svelte.d.ts +8 -0
  9. package/dist/ui/components/nature/botanical/Berry.svelte +67 -0
  10. package/dist/ui/components/nature/botanical/Berry.svelte.d.ts +8 -0
  11. package/dist/ui/components/nature/botanical/DandelionPuff.svelte +98 -0
  12. package/dist/ui/components/nature/botanical/DandelionPuff.svelte.d.ts +8 -0
  13. package/dist/ui/components/nature/botanical/FallingLeavesLayer.svelte +170 -0
  14. package/dist/ui/components/nature/botanical/FallingLeavesLayer.svelte.d.ts +35 -0
  15. package/dist/ui/components/nature/botanical/FallingPetalsLayer.svelte +174 -0
  16. package/dist/ui/components/nature/botanical/FallingPetalsLayer.svelte.d.ts +25 -0
  17. package/dist/ui/components/nature/botanical/Leaf.svelte +77 -0
  18. package/dist/ui/components/nature/botanical/Leaf.svelte.d.ts +10 -0
  19. package/dist/ui/components/nature/botanical/LeafFalling.svelte +186 -0
  20. package/dist/ui/components/nature/botanical/LeafFalling.svelte.d.ts +22 -0
  21. package/dist/ui/components/nature/botanical/PetalFalling.svelte +266 -0
  22. package/dist/ui/components/nature/botanical/PetalFalling.svelte.d.ts +25 -0
  23. package/dist/ui/components/nature/botanical/PineCone.svelte +61 -0
  24. package/dist/ui/components/nature/botanical/PineCone.svelte.d.ts +7 -0
  25. package/dist/ui/components/nature/botanical/Vine.svelte +102 -0
  26. package/dist/ui/components/nature/botanical/Vine.svelte.d.ts +11 -0
  27. package/dist/ui/components/nature/botanical/index.d.ts +10 -0
  28. package/dist/ui/components/nature/botanical/index.js +11 -0
  29. package/dist/ui/components/nature/creatures/Bee.svelte +78 -0
  30. package/dist/ui/components/nature/creatures/Bee.svelte.d.ts +9 -0
  31. package/dist/ui/components/nature/creatures/Bird.svelte +94 -0
  32. package/dist/ui/components/nature/creatures/Bird.svelte.d.ts +11 -0
  33. package/dist/ui/components/nature/creatures/BirdFlying.svelte +83 -0
  34. package/dist/ui/components/nature/creatures/BirdFlying.svelte.d.ts +9 -0
  35. package/dist/ui/components/nature/creatures/Bluebird.svelte +95 -0
  36. package/dist/ui/components/nature/creatures/Bluebird.svelte.d.ts +12 -0
  37. package/dist/ui/components/nature/creatures/Butterfly.svelte +87 -0
  38. package/dist/ui/components/nature/creatures/Butterfly.svelte.d.ts +9 -0
  39. package/dist/ui/components/nature/creatures/Cardinal.svelte +95 -0
  40. package/dist/ui/components/nature/creatures/Cardinal.svelte.d.ts +12 -0
  41. package/dist/ui/components/nature/creatures/Chickadee.svelte +97 -0
  42. package/dist/ui/components/nature/creatures/Chickadee.svelte.d.ts +12 -0
  43. package/dist/ui/components/nature/creatures/Deer.svelte +95 -0
  44. package/dist/ui/components/nature/creatures/Deer.svelte.d.ts +9 -0
  45. package/dist/ui/components/nature/creatures/Firefly.svelte +111 -0
  46. package/dist/ui/components/nature/creatures/Firefly.svelte.d.ts +10 -0
  47. package/dist/ui/components/nature/creatures/Owl.svelte +91 -0
  48. package/dist/ui/components/nature/creatures/Owl.svelte.d.ts +9 -0
  49. package/dist/ui/components/nature/creatures/Rabbit.svelte +90 -0
  50. package/dist/ui/components/nature/creatures/Rabbit.svelte.d.ts +9 -0
  51. package/dist/ui/components/nature/creatures/Robin.svelte +98 -0
  52. package/dist/ui/components/nature/creatures/Robin.svelte.d.ts +12 -0
  53. package/dist/ui/components/nature/creatures/Squirrel.svelte +97 -0
  54. package/dist/ui/components/nature/creatures/Squirrel.svelte.d.ts +9 -0
  55. package/dist/ui/components/nature/creatures/index.d.ts +13 -0
  56. package/dist/ui/components/nature/creatures/index.js +14 -0
  57. package/dist/ui/components/nature/ground/Bush.svelte +57 -0
  58. package/dist/ui/components/nature/ground/Bush.svelte.d.ts +10 -0
  59. package/dist/ui/components/nature/ground/Crocus.svelte +83 -0
  60. package/dist/ui/components/nature/ground/Crocus.svelte.d.ts +12 -0
  61. package/dist/ui/components/nature/ground/Daffodil.svelte +75 -0
  62. package/dist/ui/components/nature/ground/Daffodil.svelte.d.ts +11 -0
  63. package/dist/ui/components/nature/ground/Fern.svelte +72 -0
  64. package/dist/ui/components/nature/ground/Fern.svelte.d.ts +10 -0
  65. package/dist/ui/components/nature/ground/FlowerWild.svelte +60 -0
  66. package/dist/ui/components/nature/ground/FlowerWild.svelte.d.ts +10 -0
  67. package/dist/ui/components/nature/ground/GrassTuft.svelte +49 -0
  68. package/dist/ui/components/nature/ground/GrassTuft.svelte.d.ts +10 -0
  69. package/dist/ui/components/nature/ground/Log.svelte +42 -0
  70. package/dist/ui/components/nature/ground/Log.svelte.d.ts +7 -0
  71. package/dist/ui/components/nature/ground/Mushroom.svelte +48 -0
  72. package/dist/ui/components/nature/ground/Mushroom.svelte.d.ts +9 -0
  73. package/dist/ui/components/nature/ground/MushroomCluster.svelte +41 -0
  74. package/dist/ui/components/nature/ground/MushroomCluster.svelte.d.ts +8 -0
  75. package/dist/ui/components/nature/ground/Rock.svelte +59 -0
  76. package/dist/ui/components/nature/ground/Rock.svelte.d.ts +8 -0
  77. package/dist/ui/components/nature/ground/Stump.svelte +44 -0
  78. package/dist/ui/components/nature/ground/Stump.svelte.d.ts +8 -0
  79. package/dist/ui/components/nature/ground/Tulip.svelte +79 -0
  80. package/dist/ui/components/nature/ground/Tulip.svelte.d.ts +11 -0
  81. package/dist/ui/components/nature/ground/index.d.ts +12 -0
  82. package/dist/ui/components/nature/ground/index.js +13 -0
  83. package/dist/ui/components/nature/index.d.ts +28 -0
  84. package/dist/ui/components/nature/index.js +38 -0
  85. package/dist/ui/components/nature/palette.d.ts +491 -0
  86. package/dist/ui/components/nature/palette.js +384 -0
  87. package/dist/ui/components/nature/sky/Cloud.svelte +122 -0
  88. package/dist/ui/components/nature/sky/Cloud.svelte.d.ts +11 -0
  89. package/dist/ui/components/nature/sky/CloudWispy.svelte +79 -0
  90. package/dist/ui/components/nature/sky/CloudWispy.svelte.d.ts +9 -0
  91. package/dist/ui/components/nature/sky/Moon.svelte +60 -0
  92. package/dist/ui/components/nature/sky/Moon.svelte.d.ts +9 -0
  93. package/dist/ui/components/nature/sky/Rainbow.svelte +101 -0
  94. package/dist/ui/components/nature/sky/Rainbow.svelte.d.ts +8 -0
  95. package/dist/ui/components/nature/sky/Star.svelte +84 -0
  96. package/dist/ui/components/nature/sky/Star.svelte.d.ts +10 -0
  97. package/dist/ui/components/nature/sky/StarCluster.svelte +85 -0
  98. package/dist/ui/components/nature/sky/StarCluster.svelte.d.ts +9 -0
  99. package/dist/ui/components/nature/sky/StarShooting.svelte +90 -0
  100. package/dist/ui/components/nature/sky/StarShooting.svelte.d.ts +9 -0
  101. package/dist/ui/components/nature/sky/Sun.svelte +70 -0
  102. package/dist/ui/components/nature/sky/Sun.svelte.d.ts +9 -0
  103. package/dist/ui/components/nature/sky/index.d.ts +8 -0
  104. package/dist/ui/components/nature/sky/index.js +9 -0
  105. package/dist/ui/components/nature/structural/Birdhouse.svelte +53 -0
  106. package/dist/ui/components/nature/structural/Birdhouse.svelte.d.ts +8 -0
  107. package/dist/ui/components/nature/structural/Bridge.svelte +65 -0
  108. package/dist/ui/components/nature/structural/Bridge.svelte.d.ts +7 -0
  109. package/dist/ui/components/nature/structural/FencePost.svelte +54 -0
  110. package/dist/ui/components/nature/structural/FencePost.svelte.d.ts +8 -0
  111. package/dist/ui/components/nature/structural/GardenGate.svelte +70 -0
  112. package/dist/ui/components/nature/structural/GardenGate.svelte.d.ts +8 -0
  113. package/dist/ui/components/nature/structural/Lantern.svelte +113 -0
  114. package/dist/ui/components/nature/structural/Lantern.svelte.d.ts +10 -0
  115. package/dist/ui/components/nature/structural/Lattice.svelte +89 -0
  116. package/dist/ui/components/nature/structural/Lattice.svelte.d.ts +8 -0
  117. package/dist/ui/components/nature/structural/LatticeWithVine.svelte +89 -0
  118. package/dist/ui/components/nature/structural/LatticeWithVine.svelte.d.ts +11 -0
  119. package/dist/ui/components/nature/structural/StonePath.svelte +48 -0
  120. package/dist/ui/components/nature/structural/StonePath.svelte.d.ts +7 -0
  121. package/dist/ui/components/nature/structural/index.d.ts +8 -0
  122. package/dist/ui/components/nature/structural/index.js +9 -0
  123. package/dist/ui/components/nature/trees/TreeAspen.svelte +163 -0
  124. package/dist/ui/components/nature/trees/TreeAspen.svelte.d.ts +11 -0
  125. package/dist/ui/components/nature/trees/TreeBirch.svelte +186 -0
  126. package/dist/ui/components/nature/trees/TreeBirch.svelte.d.ts +11 -0
  127. package/dist/ui/components/nature/trees/TreeCherry.svelte +108 -0
  128. package/dist/ui/components/nature/trees/TreeCherry.svelte.d.ts +11 -0
  129. package/dist/ui/components/nature/trees/TreePine.svelte +79 -0
  130. package/dist/ui/components/nature/trees/TreePine.svelte.d.ts +11 -0
  131. package/dist/ui/components/nature/trees/index.d.ts +4 -0
  132. package/dist/ui/components/nature/trees/index.js +5 -0
  133. package/dist/ui/components/nature/water/LilyPad.svelte +99 -0
  134. package/dist/ui/components/nature/water/LilyPad.svelte.d.ts +10 -0
  135. package/dist/ui/components/nature/water/Pond.svelte +104 -0
  136. package/dist/ui/components/nature/water/Pond.svelte.d.ts +8 -0
  137. package/dist/ui/components/nature/water/Reeds.svelte +85 -0
  138. package/dist/ui/components/nature/water/Reeds.svelte.d.ts +11 -0
  139. package/dist/ui/components/nature/water/Stream.svelte +98 -0
  140. package/dist/ui/components/nature/water/Stream.svelte.d.ts +8 -0
  141. package/dist/ui/components/nature/water/index.d.ts +4 -0
  142. package/dist/ui/components/nature/water/index.js +5 -0
  143. package/dist/ui/components/nature/weather/SnowfallLayer.svelte +175 -0
  144. package/dist/ui/components/nature/weather/SnowfallLayer.svelte.d.ts +25 -0
  145. package/dist/ui/components/nature/weather/Snowflake.svelte +99 -0
  146. package/dist/ui/components/nature/weather/Snowflake.svelte.d.ts +11 -0
  147. package/dist/ui/components/nature/weather/SnowflakeFalling.svelte +162 -0
  148. package/dist/ui/components/nature/weather/SnowflakeFalling.svelte.d.ts +23 -0
  149. package/dist/ui/components/nature/weather/index.d.ts +3 -0
  150. package/dist/ui/components/nature/weather/index.js +4 -0
  151. package/dist/ui/components/ui/GlassLogo.svelte +422 -0
  152. package/dist/ui/components/ui/GlassLogo.svelte.d.ts +23 -0
  153. package/dist/ui/components/ui/GlassNavbar.svelte +120 -0
  154. package/dist/ui/components/ui/GlassNavbar.svelte.d.ts +42 -0
  155. package/dist/ui/components/ui/Logo.svelte +47 -52
  156. package/dist/ui/components/ui/Logo.svelte.d.ts +4 -3
  157. package/dist/ui/components/ui/index.d.ts +2 -0
  158. package/dist/ui/components/ui/index.js +2 -0
  159. package/dist/ui/styles/grove.css +15 -1
  160. package/package.json +11 -1
@@ -0,0 +1,99 @@
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 { winter } from '../palette';
8
+
9
+ type SnowflakeVariant = 'crystal' | 'simple' | 'star' | 'delicate' | 'dot';
10
+
11
+ interface Props {
12
+ class?: string;
13
+ color?: string;
14
+ variant?: SnowflakeVariant;
15
+ /** Opacity for depth effect */
16
+ opacity?: number;
17
+ }
18
+
19
+ let {
20
+ class: className = 'w-4 h-4',
21
+ color = winter.snow,
22
+ variant = 'crystal',
23
+ opacity = 1
24
+ }: Props = $props();
25
+ </script>
26
+
27
+ <!-- Snowflake - various crystalline shapes -->
28
+ <svg
29
+ class={className}
30
+ xmlns="http://www.w3.org/2000/svg"
31
+ viewBox="0 0 40 40"
32
+ style="opacity: {opacity};"
33
+ >
34
+ {#if variant === 'crystal'}
35
+ <!-- Classic 6-pointed crystal snowflake -->
36
+ <g fill="none" stroke={color} stroke-width="1.5" stroke-linecap="round">
37
+ <!-- Main axes -->
38
+ <line x1="20" y1="4" x2="20" y2="36" />
39
+ <line x1="6" y1="12" x2="34" y2="28" />
40
+ <line x1="6" y1="28" x2="34" y2="12" />
41
+ <!-- Branch details on vertical axis -->
42
+ <line x1="20" y1="8" x2="16" y2="12" />
43
+ <line x1="20" y1="8" x2="24" y2="12" />
44
+ <line x1="20" y1="32" x2="16" y2="28" />
45
+ <line x1="20" y1="32" x2="24" y2="28" />
46
+ <!-- Branch details on diagonal axes -->
47
+ <line x1="10" y1="14" x2="12" y2="10" />
48
+ <line x1="10" y1="14" x2="8" y2="18" />
49
+ <line x1="30" y1="26" x2="28" y2="30" />
50
+ <line x1="30" y1="26" x2="32" y2="22" />
51
+ <line x1="10" y1="26" x2="12" y2="30" />
52
+ <line x1="10" y1="26" x2="8" y2="22" />
53
+ <line x1="30" y1="14" x2="28" y2="10" />
54
+ <line x1="30" y1="14" x2="32" y2="18" />
55
+ </g>
56
+ <!-- Center crystal -->
57
+ <circle fill={color} cx="20" cy="20" r="2" />
58
+ {:else if variant === 'simple'}
59
+ <!-- Simple 6-pointed star snowflake -->
60
+ <g fill="none" stroke={color} stroke-width="2" stroke-linecap="round">
61
+ <line x1="20" y1="5" x2="20" y2="35" />
62
+ <line x1="7" y1="12.5" x2="33" y2="27.5" />
63
+ <line x1="7" y1="27.5" x2="33" y2="12.5" />
64
+ </g>
65
+ <circle fill={color} cx="20" cy="20" r="3" />
66
+ {:else if variant === 'star'}
67
+ <!-- Decorative star snowflake with filled points -->
68
+ <polygon
69
+ fill={color}
70
+ points="20,2 22,15 35,12 25,20 35,28 22,25 20,38 18,25 5,28 15,20 5,12 18,15"
71
+ />
72
+ <circle fill={color} cx="20" cy="20" r="4" opacity="0.8" />
73
+ {:else if variant === 'delicate'}
74
+ <!-- Delicate branching snowflake -->
75
+ <g fill="none" stroke={color} stroke-width="1" stroke-linecap="round">
76
+ <!-- Main spokes -->
77
+ <line x1="20" y1="4" x2="20" y2="36" />
78
+ <line x1="6" y1="12" x2="34" y2="28" />
79
+ <line x1="6" y1="28" x2="34" y2="12" />
80
+ <!-- Delicate inner branches -->
81
+ <line x1="20" y1="10" x2="14" y2="13" />
82
+ <line x1="20" y1="10" x2="26" y2="13" />
83
+ <line x1="20" y1="30" x2="14" y2="27" />
84
+ <line x1="20" y1="30" x2="26" y2="27" />
85
+ <!-- Tiny end crystals -->
86
+ <circle cx="20" cy="4" r="1.5" fill={color} />
87
+ <circle cx="20" cy="36" r="1.5" fill={color} />
88
+ <circle cx="6" cy="12" r="1.5" fill={color} />
89
+ <circle cx="34" cy="28" r="1.5" fill={color} />
90
+ <circle cx="6" cy="28" r="1.5" fill={color} />
91
+ <circle cx="34" cy="12" r="1.5" fill={color} />
92
+ </g>
93
+ <circle fill={color} cx="20" cy="20" r="2.5" />
94
+ {:else if variant === 'dot'}
95
+ <!-- Simple snow dot/orb (for distant flakes) -->
96
+ <circle fill={color} cx="20" cy="20" r="8" />
97
+ <circle fill="white" cx="17" cy="17" r="2" opacity="0.6" />
98
+ {/if}
99
+ </svg>
@@ -0,0 +1,11 @@
1
+ type SnowflakeVariant = 'crystal' | 'simple' | 'star' | 'delicate' | 'dot';
2
+ interface Props {
3
+ class?: string;
4
+ color?: string;
5
+ variant?: SnowflakeVariant;
6
+ /** Opacity for depth effect */
7
+ opacity?: number;
8
+ }
9
+ declare const Snowflake: import("svelte").Component<Props, {}, "">;
10
+ type Snowflake = ReturnType<typeof Snowflake>;
11
+ export default Snowflake;
@@ -0,0 +1,162 @@
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 { winter } from '../palette';
8
+ import Snowflake from './Snowflake.svelte';
9
+ import { browser } from '$app/environment';
10
+
11
+ type SnowflakeVariant = 'crystal' | 'simple' | 'star' | 'delicate' | 'dot';
12
+
13
+ interface Props {
14
+ class?: string;
15
+ color?: string;
16
+ variant?: SnowflakeVariant;
17
+ /** Fall animation duration in seconds */
18
+ duration?: number;
19
+ /** Animation delay in seconds */
20
+ delay?: number;
21
+ /** Horizontal drift amount in vw units */
22
+ drift?: number;
23
+ /** Vertical fall distance in vh units */
24
+ fallDistance?: number;
25
+ /** Enable falling animation */
26
+ animate?: boolean;
27
+ /** Random seed for rotation variation */
28
+ seed?: number;
29
+ /** Opacity for depth effect */
30
+ opacity?: number;
31
+ }
32
+
33
+ let {
34
+ class: className = 'w-4 h-4',
35
+ color = winter.snow,
36
+ variant = 'crystal',
37
+ duration = 12,
38
+ delay = 0,
39
+ drift = 0,
40
+ fallDistance = 100,
41
+ animate = true,
42
+ seed = 0,
43
+ opacity = 1
44
+ }: Props = $props();
45
+
46
+ // Deterministic rotation based on seed - gentle swaying for snow
47
+ const initialRotation = $derived((seed * 37) % 360);
48
+ const rotationDirection = $derived(seed % 2 === 0 ? 1 : -1);
49
+ const rotationAmount = $derived(180 + (seed % 180)); // 180-360 degrees total rotation - gentler than petals
50
+
51
+ // Gentle horizontal sway - snow drifts more subtly than petals
52
+ const swayAmplitude = $derived(40 + (seed % 60)); // 40-100px horizontal sway - lighter than petals
53
+ const swayFrequency = $derived(1 + (seed % 3)); // 1-3 complete waves during fall - fewer than petals
54
+
55
+ // Unique animation name to prevent conflicts
56
+ const animId = $derived(`snow-${seed}`);
57
+
58
+ // Inject dynamic keyframes at runtime
59
+ $effect(() => {
60
+ if (!browser || !animate) return;
61
+
62
+ const styleId = `snow-style-${seed}`;
63
+ // Check if already injected
64
+ if (document.getElementById(styleId)) return;
65
+
66
+ const style = document.createElement('style');
67
+ style.id = styleId;
68
+ // Create gentle drifting motion with sine wave horizontal movement
69
+ // Snowflakes are lighter and more delicate than petals
70
+ style.textContent = `
71
+ @keyframes ${animId}-fall {
72
+ 0% {
73
+ transform: translateY(0) translateX(0) rotate(${initialRotation}deg);
74
+ opacity: 0;
75
+ }
76
+ 5% {
77
+ opacity: ${opacity};
78
+ }
79
+ 12.5% {
80
+ transform: translateY(${fallDistance * 0.125}vh) translateX(${Math.sin(Math.PI * 0.25 * swayFrequency) * swayAmplitude + drift * 0.125}px) rotate(${initialRotation + rotationAmount * rotationDirection * 0.125}deg);
81
+ }
82
+ 25% {
83
+ transform: translateY(${fallDistance * 0.25}vh) translateX(${Math.sin(Math.PI * 0.5 * swayFrequency) * swayAmplitude + drift * 0.25}px) rotate(${initialRotation + rotationAmount * rotationDirection * 0.25}deg);
84
+ }
85
+ 37.5% {
86
+ transform: translateY(${fallDistance * 0.375}vh) translateX(${Math.sin(Math.PI * 0.75 * swayFrequency) * swayAmplitude + drift * 0.375}px) rotate(${initialRotation + rotationAmount * rotationDirection * 0.375}deg);
87
+ }
88
+ 50% {
89
+ transform: translateY(${fallDistance * 0.5}vh) translateX(${Math.sin(Math.PI * swayFrequency) * swayAmplitude + drift * 0.5}px) rotate(${initialRotation + rotationAmount * rotationDirection * 0.5}deg);
90
+ }
91
+ 62.5% {
92
+ transform: translateY(${fallDistance * 0.625}vh) translateX(${Math.sin(Math.PI * 1.25 * swayFrequency) * swayAmplitude + drift * 0.625}px) rotate(${initialRotation + rotationAmount * rotationDirection * 0.625}deg);
93
+ }
94
+ 75% {
95
+ transform: translateY(${fallDistance * 0.75}vh) translateX(${Math.sin(Math.PI * 1.5 * swayFrequency) * swayAmplitude + drift * 0.75}px) rotate(${initialRotation + rotationAmount * rotationDirection * 0.75}deg);
96
+ }
97
+ 87.5% {
98
+ transform: translateY(${fallDistance * 0.875}vh) translateX(${Math.sin(Math.PI * 1.75 * swayFrequency) * swayAmplitude + drift * 0.875}px) rotate(${initialRotation + rotationAmount * rotationDirection * 0.875}deg);
99
+ }
100
+ 95% {
101
+ opacity: ${opacity};
102
+ }
103
+ 100% {
104
+ transform: translateY(${fallDistance}vh) translateX(${Math.sin(Math.PI * 2 * swayFrequency) * swayAmplitude + drift}px) rotate(${initialRotation + rotationAmount * rotationDirection}deg);
105
+ opacity: 0;
106
+ }
107
+ }
108
+ @keyframes ${animId}-flutter {
109
+ 0%, 100% {
110
+ transform: rotateX(0deg) rotateY(0deg) scale(1);
111
+ }
112
+ 20% {
113
+ transform: rotateX(20deg) rotateY(25deg) scale(0.95);
114
+ }
115
+ 40% {
116
+ transform: rotateX(-15deg) rotateY(-20deg) scale(1.05);
117
+ }
118
+ 60% {
119
+ transform: rotateX(25deg) rotateY(20deg) scale(0.92);
120
+ }
121
+ 80% {
122
+ transform: rotateX(-20deg) rotateY(-25deg) scale(1.03);
123
+ }
124
+ }
125
+ `;
126
+ document.head.appendChild(style);
127
+
128
+ return () => {
129
+ // Cleanup on component destroy
130
+ const el = document.getElementById(styleId);
131
+ if (el) el.remove();
132
+ };
133
+ });
134
+ </script>
135
+
136
+ <!-- Snowflake - delicate and drifting -->
137
+ <!-- Wrapper div for fall animation (translateY/X/rotate), inner div for flutter (3D rotations) -->
138
+ <div
139
+ class="snowflake-wrapper"
140
+ style="{animate ? `animation: ${animId}-fall ${duration}s linear ${delay}s infinite;` : `opacity: ${opacity};`}"
141
+ >
142
+ <div
143
+ class="snowflake-flutter"
144
+ style="{animate ? `animation: ${animId}-flutter ${duration / 3}s ease-in-out ${delay}s infinite;` : ''}"
145
+ >
146
+ <Snowflake class={className} {color} {variant} opacity={1} />
147
+ </div>
148
+ </div>
149
+
150
+ <style>
151
+ /* Dynamic keyframes are injected via $effect */
152
+ .snowflake-wrapper {
153
+ display: inline-block;
154
+ will-change: transform, opacity;
155
+ }
156
+
157
+ .snowflake-flutter {
158
+ display: inline-block;
159
+ transform-style: preserve-3d;
160
+ will-change: transform;
161
+ }
162
+ </style>
@@ -0,0 +1,23 @@
1
+ type SnowflakeVariant = 'crystal' | 'simple' | 'star' | 'delicate' | 'dot';
2
+ interface Props {
3
+ class?: string;
4
+ color?: string;
5
+ variant?: SnowflakeVariant;
6
+ /** Fall animation duration in seconds */
7
+ duration?: number;
8
+ /** Animation delay in seconds */
9
+ delay?: number;
10
+ /** Horizontal drift amount in vw units */
11
+ drift?: number;
12
+ /** Vertical fall distance in vh units */
13
+ fallDistance?: number;
14
+ /** Enable falling animation */
15
+ animate?: boolean;
16
+ /** Random seed for rotation variation */
17
+ seed?: number;
18
+ /** Opacity for depth effect */
19
+ opacity?: number;
20
+ }
21
+ declare const SnowflakeFalling: import("svelte").Component<Props, {}, "">;
22
+ type SnowflakeFalling = ReturnType<typeof SnowflakeFalling>;
23
+ export default SnowflakeFalling;
@@ -0,0 +1,3 @@
1
+ export { default as SnowfallLayer } from './SnowfallLayer.svelte';
2
+ export { default as Snowflake } from './Snowflake.svelte';
3
+ export { default as SnowflakeFalling } from './SnowflakeFalling.svelte';
@@ -0,0 +1,4 @@
1
+ // Weather components - seasonal weather effects
2
+ export { default as SnowfallLayer } from './SnowfallLayer.svelte';
3
+ export { default as Snowflake } from './Snowflake.svelte';
4
+ export { default as SnowflakeFalling } from './SnowflakeFalling.svelte';