@timbal-ai/timbal-react 1.3.0 → 1.5.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 (53) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +28 -4
  3. package/dist/app.cjs +3610 -1489
  4. package/dist/app.d.cts +75 -30
  5. package/dist/app.d.ts +75 -30
  6. package/dist/app.esm.js +29 -7
  7. package/dist/{chart-artifact-Q5QgMtbj.d.ts → chart-artifact-2OTDTRwM.d.ts} +212 -41
  8. package/dist/{chart-artifact-WDEW9dHT.d.cts → chart-artifact-CS3qyGIY.d.cts} +212 -41
  9. package/dist/chat.cjs +264 -107
  10. package/dist/chat.d.cts +2 -2
  11. package/dist/chat.d.ts +2 -2
  12. package/dist/chat.esm.js +4 -3
  13. package/dist/chunk-5ECRZ5O7.esm.js +899 -0
  14. package/dist/{chunk-QU7ET55D.esm.js → chunk-AZL2WANO.esm.js} +320 -177
  15. package/dist/{chunk-OH23AX2V.esm.js → chunk-B4XAC4G7.esm.js} +430 -780
  16. package/dist/chunk-EDEKQYSU.esm.js +10 -0
  17. package/dist/{chunk-GQBYZRD7.esm.js → chunk-IGHBLJV3.esm.js} +38 -27
  18. package/dist/{chunk-OFWC4MIY.esm.js → chunk-JYDJRGDE.esm.js} +5 -3
  19. package/dist/{chunk-YCXN67SD.esm.js → chunk-SZDYIRMB.esm.js} +1639 -490
  20. package/dist/chunk-TZI3ID3C.esm.js +232 -0
  21. package/dist/{chunk-THBA27QY.esm.js → chunk-WMKPT5BV.esm.js} +242 -123
  22. package/dist/{chunk-VXMM2HX7.esm.js → chunk-ZNYAETFD.esm.js} +1 -1
  23. package/dist/{circular-progress-Ci8L-Hfa.d.cts → circular-progress-CDsJwIPF.d.cts} +19 -77
  24. package/dist/{circular-progress-Ci8L-Hfa.d.ts → circular-progress-CDsJwIPF.d.ts} +19 -77
  25. package/dist/index.cjs +5564 -3612
  26. package/dist/index.d.cts +7 -6
  27. package/dist/index.d.ts +7 -6
  28. package/dist/index.esm.js +45 -33
  29. package/dist/kanban-U5xNe9py.d.cts +212 -0
  30. package/dist/kanban-U5xNe9py.d.ts +212 -0
  31. package/dist/{layout-BTJyU8wd.d.ts → layout-B8r6Jbat.d.ts} +1 -1
  32. package/dist/{layout-C2G-FcER.d.cts → layout-Cu7Ijn04.d.cts} +1 -1
  33. package/dist/site.cjs +358 -0
  34. package/dist/site.d.cts +184 -0
  35. package/dist/site.d.ts +184 -0
  36. package/dist/site.esm.js +322 -0
  37. package/dist/studio.cjs +702 -343
  38. package/dist/studio.d.cts +1 -1
  39. package/dist/studio.d.ts +1 -1
  40. package/dist/studio.esm.js +7 -5
  41. package/dist/styles.css +56 -0
  42. package/dist/{timbal-v2-button-CNfdwGq4.d.cts → timbal-v2-button-B7vPs7gg.d.cts} +2 -2
  43. package/dist/{timbal-v2-button-CNfdwGq4.d.ts → timbal-v2-button-B7vPs7gg.d.ts} +2 -2
  44. package/dist/ui.cjs +1504 -659
  45. package/dist/ui.d.cts +11 -4
  46. package/dist/ui.d.ts +11 -4
  47. package/dist/ui.esm.js +35 -26
  48. package/dist/{welcome-DXqsGTwH.d.ts → welcome-DduQAC4K.d.ts} +4 -0
  49. package/dist/{welcome-BFGRoNfK.d.cts → welcome-NXZlcihe.d.cts} +4 -0
  50. package/package.json +9 -1
  51. package/dist/button-BoyX5pM_.d.cts +0 -18
  52. package/dist/button-BoyX5pM_.d.ts +0 -18
  53. package/dist/chunk-UCGVL7ZY.esm.js +0 -52
@@ -0,0 +1,184 @@
1
+ import * as React from 'react';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+
4
+ /** Entrance styles. `mask-up` clips the child and slides it in from below. */
5
+ type RevealVariant = "fade" | "fade-up" | "fade-down" | "fade-left" | "fade-right" | "blur" | "scale" | "mask-up";
6
+ interface RevealProps extends React.ComponentPropsWithoutRef<"div"> {
7
+ /** Entrance style. Default `fade-up`. */
8
+ variant?: RevealVariant;
9
+ /** Seconds before the animation starts. */
10
+ delay?: number;
11
+ /** Animation duration in seconds. Default {@link DURATION.base}. */
12
+ duration?: number;
13
+ /** Slide distance in px for the directional + mask variants. Default 28. */
14
+ distance?: number;
15
+ /**
16
+ * Fraction of the element that must be visible before it animates (0–1), or
17
+ * `"some"` / `"all"`. Default 0.3.
18
+ */
19
+ amount?: number | "some" | "all";
20
+ /** Replay every time the element re-enters the viewport. Default `false`. */
21
+ repeat?: boolean;
22
+ /** Render as a different intrinsic element (e.g. `"section"`, `"li"`). */
23
+ as?: keyof React.JSX.IntrinsicElements;
24
+ children?: React.ReactNode;
25
+ }
26
+ /**
27
+ * Reveal a block when it scrolls into view. Honours `prefers-reduced-motion`
28
+ * (renders immediately, no transform) and SSR (no layout shift — the element
29
+ * occupies its space from first paint).
30
+ *
31
+ * ```tsx
32
+ * <Reveal variant="fade-up" delay={0.1}>
33
+ * <h2>Built for the long run</h2>
34
+ * </Reveal>
35
+ * ```
36
+ */
37
+ declare const Reveal: React.ForwardRefExoticComponent<RevealProps & React.RefAttributes<HTMLDivElement>>;
38
+
39
+ interface TextRevealProps extends Omit<React.ComponentPropsWithoutRef<"span">, "children"> {
40
+ /** The text to reveal. Plain string only (split into tokens internally). */
41
+ children: string;
42
+ /** Split granularity. `words` (default) animates word-by-word; `lines` splits on `\n`. */
43
+ splitBy?: "words" | "lines";
44
+ /** Seconds between each token's entrance. Default 0.06. */
45
+ stagger?: number;
46
+ /** Seconds before the first token animates. Default 0. */
47
+ delay?: number;
48
+ /** Per-token duration in seconds. Default {@link DURATION.base}. */
49
+ duration?: number;
50
+ /** Replay every time it re-enters the viewport. Default `false`. */
51
+ repeat?: boolean;
52
+ /** Visibility fraction before animating (0–1). Default 0.4. */
53
+ amount?: number;
54
+ /** Render the wrapper as a block-level heading element instead of an inline span. */
55
+ as?: "span" | "h1" | "h2" | "h3" | "h4" | "p";
56
+ }
57
+ /**
58
+ * Reveal text token-by-token with a masked slide-up — the signature
59
+ * editorial/luxury headline entrance. Each word (or line) rides up out of an
60
+ * `overflow-hidden` clip on a stagger. Collapses to static text under
61
+ * `prefers-reduced-motion`.
62
+ *
63
+ * ```tsx
64
+ * <TextReveal as="h1" className="text-6xl font-semibold" stagger={0.08}>
65
+ * Every step forward
66
+ * </TextReveal>
67
+ * ```
68
+ */
69
+ declare function TextReveal({ children, splitBy, stagger, delay, duration, repeat, amount, as, className, ...rest }: TextRevealProps): react_jsx_runtime.JSX.Element;
70
+
71
+ interface ParallaxProps extends React.ComponentPropsWithoutRef<"div"> {
72
+ /**
73
+ * Parallax strength. Positive values drift the element *slower* than scroll
74
+ * (it lags behind); negative values push it ahead. Roughly the fraction of
75
+ * the element's travel to offset. Sensible range -0.6…0.6. Default 0.2.
76
+ */
77
+ speed?: number;
78
+ /** Axis to translate along. Default `"y"`. */
79
+ axis?: "x" | "y";
80
+ /** Smooth the motion with a spring (avoids jitter on fast scroll). Default `true`. */
81
+ smooth?: boolean;
82
+ children?: React.ReactNode;
83
+ }
84
+ /**
85
+ * Translate a layer relative to scroll for depth. Drives off the element's own
86
+ * position in the viewport (no global scroll listener), so multiple parallax
87
+ * layers compose cheaply. No-op under `prefers-reduced-motion`.
88
+ *
89
+ * ```tsx
90
+ * <Parallax speed={0.3}>
91
+ * <img src={hero} alt="" className="h-full w-full object-cover" />
92
+ * </Parallax>
93
+ * ```
94
+ */
95
+ declare const Parallax: React.ForwardRefExoticComponent<ParallaxProps & React.RefAttributes<HTMLDivElement>>;
96
+
97
+ interface MarqueeProps extends React.ComponentPropsWithoutRef<"div"> {
98
+ /** Scroll speed in px/second. Default 60. */
99
+ speed?: number;
100
+ /** Travel direction. Default `"left"`. */
101
+ direction?: "left" | "right";
102
+ /** Pause while hovered. Default `true`. */
103
+ pauseOnHover?: boolean;
104
+ /** Gap between the repeated content groups (any CSS length). Default `"3rem"`. */
105
+ gap?: string;
106
+ children?: React.ReactNode;
107
+ }
108
+ /**
109
+ * Seamless infinite marquee. Duplicates its children and advances a single
110
+ * motion value per frame, wrapping at the content width so there is no visible
111
+ * seam. Frame-rate independent (uses elapsed delta). Renders a static,
112
+ * horizontally-scrollable row under `prefers-reduced-motion`.
113
+ *
114
+ * ```tsx
115
+ * <Marquee speed={40} className="py-6">
116
+ * {logos.map((l) => <img key={l.id} src={l.src} alt={l.name} className="h-8" />)}
117
+ * </Marquee>
118
+ * ```
119
+ */
120
+ declare const Marquee: React.ForwardRefExoticComponent<MarqueeProps & React.RefAttributes<HTMLDivElement>>;
121
+
122
+ /**
123
+ * Shared motion tokens for the expressive `/site` layer.
124
+ *
125
+ * These are deliberately *opinionated but restrained* — the defaults produce
126
+ * the kind of confident, weighted motion seen on award-tier marketing sites
127
+ * (slow-out cubic-bezier, ~0.7–1s durations) rather than the snappy 150ms
128
+ * micro-interactions the app kit favours. Override per-component when a brief
129
+ * calls for it.
130
+ */
131
+ /** Cubic-bezier easings as `[x1, y1, x2, y2]` tuples (motion's `ease` format). */
132
+ declare const EASE: {
133
+ /** Strong slow-out — the workhorse for entrances and reveals. */
134
+ readonly out: readonly [0.16, 1, 0.3, 1];
135
+ /** Symmetric in-out for loops and continuous motion. */
136
+ readonly inOut: readonly [0.65, 0, 0.35, 1];
137
+ /** Gentle in-out, good for parallax / large translations. */
138
+ readonly soft: readonly [0.4, 0, 0.2, 1];
139
+ };
140
+ /** Default durations (seconds) for the expressive layer. */
141
+ declare const DURATION: {
142
+ readonly fast: 0.4;
143
+ readonly base: 0.7;
144
+ readonly slow: 1.1;
145
+ };
146
+ /** Spring presets for pointer-driven motion (Magnetic, etc.). */
147
+ declare const SPRING: {
148
+ /** Tight, responsive follow. */
149
+ readonly snappy: {
150
+ readonly stiffness: 350;
151
+ readonly damping: 30;
152
+ readonly mass: 0.4;
153
+ };
154
+ /** Looser, more elastic follow. */
155
+ readonly smooth: {
156
+ readonly stiffness: 150;
157
+ readonly damping: 20;
158
+ readonly mass: 0.6;
159
+ };
160
+ };
161
+
162
+ interface MagneticProps extends React.ComponentPropsWithoutRef<"div"> {
163
+ /** How far the element follows the pointer, as a fraction of the cursor offset. Default 0.35. */
164
+ strength?: number;
165
+ /** Max travel in px in any direction (clamps `strength` on large elements). Default 24. */
166
+ max?: number;
167
+ /** Spring feel. Default `"snappy"`. */
168
+ spring?: keyof typeof SPRING;
169
+ children?: React.ReactNode;
170
+ }
171
+ /**
172
+ * Make a child element drift toward the cursor while hovered, springing back
173
+ * on leave — the classic "magnetic" CTA / nav affordance. Wrap a single
174
+ * interactive child (button, link). No-op under `prefers-reduced-motion`.
175
+ *
176
+ * ```tsx
177
+ * <Magnetic strength={0.4}>
178
+ * <Button>Shop the drop</Button>
179
+ * </Magnetic>
180
+ * ```
181
+ */
182
+ declare const Magnetic: React.ForwardRefExoticComponent<MagneticProps & React.RefAttributes<HTMLDivElement>>;
183
+
184
+ export { DURATION, EASE, Magnetic, type MagneticProps, Marquee, type MarqueeProps, Parallax, type ParallaxProps, Reveal, type RevealProps, type RevealVariant, SPRING, TextReveal, type TextRevealProps };
package/dist/site.d.ts ADDED
@@ -0,0 +1,184 @@
1
+ import * as React from 'react';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+
4
+ /** Entrance styles. `mask-up` clips the child and slides it in from below. */
5
+ type RevealVariant = "fade" | "fade-up" | "fade-down" | "fade-left" | "fade-right" | "blur" | "scale" | "mask-up";
6
+ interface RevealProps extends React.ComponentPropsWithoutRef<"div"> {
7
+ /** Entrance style. Default `fade-up`. */
8
+ variant?: RevealVariant;
9
+ /** Seconds before the animation starts. */
10
+ delay?: number;
11
+ /** Animation duration in seconds. Default {@link DURATION.base}. */
12
+ duration?: number;
13
+ /** Slide distance in px for the directional + mask variants. Default 28. */
14
+ distance?: number;
15
+ /**
16
+ * Fraction of the element that must be visible before it animates (0–1), or
17
+ * `"some"` / `"all"`. Default 0.3.
18
+ */
19
+ amount?: number | "some" | "all";
20
+ /** Replay every time the element re-enters the viewport. Default `false`. */
21
+ repeat?: boolean;
22
+ /** Render as a different intrinsic element (e.g. `"section"`, `"li"`). */
23
+ as?: keyof React.JSX.IntrinsicElements;
24
+ children?: React.ReactNode;
25
+ }
26
+ /**
27
+ * Reveal a block when it scrolls into view. Honours `prefers-reduced-motion`
28
+ * (renders immediately, no transform) and SSR (no layout shift — the element
29
+ * occupies its space from first paint).
30
+ *
31
+ * ```tsx
32
+ * <Reveal variant="fade-up" delay={0.1}>
33
+ * <h2>Built for the long run</h2>
34
+ * </Reveal>
35
+ * ```
36
+ */
37
+ declare const Reveal: React.ForwardRefExoticComponent<RevealProps & React.RefAttributes<HTMLDivElement>>;
38
+
39
+ interface TextRevealProps extends Omit<React.ComponentPropsWithoutRef<"span">, "children"> {
40
+ /** The text to reveal. Plain string only (split into tokens internally). */
41
+ children: string;
42
+ /** Split granularity. `words` (default) animates word-by-word; `lines` splits on `\n`. */
43
+ splitBy?: "words" | "lines";
44
+ /** Seconds between each token's entrance. Default 0.06. */
45
+ stagger?: number;
46
+ /** Seconds before the first token animates. Default 0. */
47
+ delay?: number;
48
+ /** Per-token duration in seconds. Default {@link DURATION.base}. */
49
+ duration?: number;
50
+ /** Replay every time it re-enters the viewport. Default `false`. */
51
+ repeat?: boolean;
52
+ /** Visibility fraction before animating (0–1). Default 0.4. */
53
+ amount?: number;
54
+ /** Render the wrapper as a block-level heading element instead of an inline span. */
55
+ as?: "span" | "h1" | "h2" | "h3" | "h4" | "p";
56
+ }
57
+ /**
58
+ * Reveal text token-by-token with a masked slide-up — the signature
59
+ * editorial/luxury headline entrance. Each word (or line) rides up out of an
60
+ * `overflow-hidden` clip on a stagger. Collapses to static text under
61
+ * `prefers-reduced-motion`.
62
+ *
63
+ * ```tsx
64
+ * <TextReveal as="h1" className="text-6xl font-semibold" stagger={0.08}>
65
+ * Every step forward
66
+ * </TextReveal>
67
+ * ```
68
+ */
69
+ declare function TextReveal({ children, splitBy, stagger, delay, duration, repeat, amount, as, className, ...rest }: TextRevealProps): react_jsx_runtime.JSX.Element;
70
+
71
+ interface ParallaxProps extends React.ComponentPropsWithoutRef<"div"> {
72
+ /**
73
+ * Parallax strength. Positive values drift the element *slower* than scroll
74
+ * (it lags behind); negative values push it ahead. Roughly the fraction of
75
+ * the element's travel to offset. Sensible range -0.6…0.6. Default 0.2.
76
+ */
77
+ speed?: number;
78
+ /** Axis to translate along. Default `"y"`. */
79
+ axis?: "x" | "y";
80
+ /** Smooth the motion with a spring (avoids jitter on fast scroll). Default `true`. */
81
+ smooth?: boolean;
82
+ children?: React.ReactNode;
83
+ }
84
+ /**
85
+ * Translate a layer relative to scroll for depth. Drives off the element's own
86
+ * position in the viewport (no global scroll listener), so multiple parallax
87
+ * layers compose cheaply. No-op under `prefers-reduced-motion`.
88
+ *
89
+ * ```tsx
90
+ * <Parallax speed={0.3}>
91
+ * <img src={hero} alt="" className="h-full w-full object-cover" />
92
+ * </Parallax>
93
+ * ```
94
+ */
95
+ declare const Parallax: React.ForwardRefExoticComponent<ParallaxProps & React.RefAttributes<HTMLDivElement>>;
96
+
97
+ interface MarqueeProps extends React.ComponentPropsWithoutRef<"div"> {
98
+ /** Scroll speed in px/second. Default 60. */
99
+ speed?: number;
100
+ /** Travel direction. Default `"left"`. */
101
+ direction?: "left" | "right";
102
+ /** Pause while hovered. Default `true`. */
103
+ pauseOnHover?: boolean;
104
+ /** Gap between the repeated content groups (any CSS length). Default `"3rem"`. */
105
+ gap?: string;
106
+ children?: React.ReactNode;
107
+ }
108
+ /**
109
+ * Seamless infinite marquee. Duplicates its children and advances a single
110
+ * motion value per frame, wrapping at the content width so there is no visible
111
+ * seam. Frame-rate independent (uses elapsed delta). Renders a static,
112
+ * horizontally-scrollable row under `prefers-reduced-motion`.
113
+ *
114
+ * ```tsx
115
+ * <Marquee speed={40} className="py-6">
116
+ * {logos.map((l) => <img key={l.id} src={l.src} alt={l.name} className="h-8" />)}
117
+ * </Marquee>
118
+ * ```
119
+ */
120
+ declare const Marquee: React.ForwardRefExoticComponent<MarqueeProps & React.RefAttributes<HTMLDivElement>>;
121
+
122
+ /**
123
+ * Shared motion tokens for the expressive `/site` layer.
124
+ *
125
+ * These are deliberately *opinionated but restrained* — the defaults produce
126
+ * the kind of confident, weighted motion seen on award-tier marketing sites
127
+ * (slow-out cubic-bezier, ~0.7–1s durations) rather than the snappy 150ms
128
+ * micro-interactions the app kit favours. Override per-component when a brief
129
+ * calls for it.
130
+ */
131
+ /** Cubic-bezier easings as `[x1, y1, x2, y2]` tuples (motion's `ease` format). */
132
+ declare const EASE: {
133
+ /** Strong slow-out — the workhorse for entrances and reveals. */
134
+ readonly out: readonly [0.16, 1, 0.3, 1];
135
+ /** Symmetric in-out for loops and continuous motion. */
136
+ readonly inOut: readonly [0.65, 0, 0.35, 1];
137
+ /** Gentle in-out, good for parallax / large translations. */
138
+ readonly soft: readonly [0.4, 0, 0.2, 1];
139
+ };
140
+ /** Default durations (seconds) for the expressive layer. */
141
+ declare const DURATION: {
142
+ readonly fast: 0.4;
143
+ readonly base: 0.7;
144
+ readonly slow: 1.1;
145
+ };
146
+ /** Spring presets for pointer-driven motion (Magnetic, etc.). */
147
+ declare const SPRING: {
148
+ /** Tight, responsive follow. */
149
+ readonly snappy: {
150
+ readonly stiffness: 350;
151
+ readonly damping: 30;
152
+ readonly mass: 0.4;
153
+ };
154
+ /** Looser, more elastic follow. */
155
+ readonly smooth: {
156
+ readonly stiffness: 150;
157
+ readonly damping: 20;
158
+ readonly mass: 0.6;
159
+ };
160
+ };
161
+
162
+ interface MagneticProps extends React.ComponentPropsWithoutRef<"div"> {
163
+ /** How far the element follows the pointer, as a fraction of the cursor offset. Default 0.35. */
164
+ strength?: number;
165
+ /** Max travel in px in any direction (clamps `strength` on large elements). Default 24. */
166
+ max?: number;
167
+ /** Spring feel. Default `"snappy"`. */
168
+ spring?: keyof typeof SPRING;
169
+ children?: React.ReactNode;
170
+ }
171
+ /**
172
+ * Make a child element drift toward the cursor while hovered, springing back
173
+ * on leave — the classic "magnetic" CTA / nav affordance. Wrap a single
174
+ * interactive child (button, link). No-op under `prefers-reduced-motion`.
175
+ *
176
+ * ```tsx
177
+ * <Magnetic strength={0.4}>
178
+ * <Button>Shop the drop</Button>
179
+ * </Magnetic>
180
+ * ```
181
+ */
182
+ declare const Magnetic: React.ForwardRefExoticComponent<MagneticProps & React.RefAttributes<HTMLDivElement>>;
183
+
184
+ export { DURATION, EASE, Magnetic, type MagneticProps, Marquee, type MarqueeProps, Parallax, type ParallaxProps, Reveal, type RevealProps, type RevealVariant, SPRING, TextReveal, type TextRevealProps };
@@ -0,0 +1,322 @@
1
+ import {
2
+ cn
3
+ } from "./chunk-EDEKQYSU.esm.js";
4
+
5
+ // src/site/Reveal.tsx
6
+ import * as React from "react";
7
+ import { motion, useReducedMotion } from "motion/react";
8
+
9
+ // src/site/easing.ts
10
+ var EASE = {
11
+ /** Strong slow-out — the workhorse for entrances and reveals. */
12
+ out: [0.16, 1, 0.3, 1],
13
+ /** Symmetric in-out for loops and continuous motion. */
14
+ inOut: [0.65, 0, 0.35, 1],
15
+ /** Gentle in-out, good for parallax / large translations. */
16
+ soft: [0.4, 0, 0.2, 1]
17
+ };
18
+ var DURATION = {
19
+ fast: 0.4,
20
+ base: 0.7,
21
+ slow: 1.1
22
+ };
23
+ var SPRING = {
24
+ /** Tight, responsive follow. */
25
+ snappy: { stiffness: 350, damping: 30, mass: 0.4 },
26
+ /** Looser, more elastic follow. */
27
+ smooth: { stiffness: 150, damping: 20, mass: 0.6 }
28
+ };
29
+
30
+ // src/site/Reveal.tsx
31
+ import { jsx } from "react/jsx-runtime";
32
+ function hidden(variant, distance) {
33
+ switch (variant) {
34
+ case "fade":
35
+ return { opacity: 0 };
36
+ case "fade-up":
37
+ return { opacity: 0, y: distance };
38
+ case "fade-down":
39
+ return { opacity: 0, y: -distance };
40
+ case "fade-left":
41
+ return { opacity: 0, x: distance };
42
+ case "fade-right":
43
+ return { opacity: 0, x: -distance };
44
+ case "blur":
45
+ return { opacity: 0, filter: "blur(12px)" };
46
+ case "scale":
47
+ return { opacity: 0, scale: 0.94 };
48
+ case "mask-up":
49
+ return { y: "110%" };
50
+ }
51
+ }
52
+ function shown(variant) {
53
+ if (variant === "mask-up") return { y: "0%" };
54
+ if (variant === "blur") return { opacity: 1, filter: "blur(0px)" };
55
+ if (variant === "scale") return { opacity: 1, scale: 1 };
56
+ return { opacity: 1, x: 0, y: 0 };
57
+ }
58
+ var Reveal = React.forwardRef(function Reveal2({
59
+ variant = "fade-up",
60
+ delay = 0,
61
+ duration = DURATION.base,
62
+ distance = 28,
63
+ amount = 0.3,
64
+ repeat = false,
65
+ as = "div",
66
+ className,
67
+ children,
68
+ ...rest
69
+ }, ref) {
70
+ const reduce = useReducedMotion();
71
+ const isMask = variant === "mask-up";
72
+ if (reduce) {
73
+ const Tag = as;
74
+ return /* @__PURE__ */ jsx(Tag, { ref, className: cn(isMask && "overflow-hidden", className), ...rest, children });
75
+ }
76
+ const variants = {
77
+ hidden: hidden(variant, distance),
78
+ shown: shown(variant)
79
+ };
80
+ const MotionTag = motion[as] ?? motion.div;
81
+ const inner = /* @__PURE__ */ jsx(
82
+ MotionTag,
83
+ {
84
+ ref,
85
+ className,
86
+ variants,
87
+ initial: "hidden",
88
+ whileInView: "shown",
89
+ viewport: { once: !repeat, amount },
90
+ transition: { duration, delay, ease: EASE.out },
91
+ ...rest,
92
+ children
93
+ }
94
+ );
95
+ if (isMask) {
96
+ return /* @__PURE__ */ jsx("span", { className: "block overflow-hidden", children: inner });
97
+ }
98
+ return inner;
99
+ });
100
+
101
+ // src/site/TextReveal.tsx
102
+ import * as React2 from "react";
103
+ import { motion as motion2, useReducedMotion as useReducedMotion2 } from "motion/react";
104
+ import { jsx as jsx2 } from "react/jsx-runtime";
105
+ var tokenVariants = {
106
+ hidden: { y: "115%" },
107
+ shown: { y: "0%" }
108
+ };
109
+ function TextReveal({
110
+ children,
111
+ splitBy = "words",
112
+ stagger = 0.06,
113
+ delay = 0,
114
+ duration = DURATION.base,
115
+ repeat = false,
116
+ amount = 0.4,
117
+ as = "span",
118
+ className,
119
+ ...rest
120
+ }) {
121
+ const reduce = useReducedMotion2();
122
+ const Tag = as;
123
+ const tokens = React2.useMemo(() => {
124
+ if (splitBy === "lines") return children.split("\n");
125
+ return children.split(/(\s+)/).filter((t) => t.length > 0);
126
+ }, [children, splitBy]);
127
+ if (reduce) {
128
+ return /* @__PURE__ */ jsx2(Tag, { className, ...rest, children });
129
+ }
130
+ const containerVariants = {
131
+ hidden: {},
132
+ shown: { transition: { staggerChildren: stagger, delayChildren: delay } }
133
+ };
134
+ return /* @__PURE__ */ jsx2(
135
+ motion2.span,
136
+ {
137
+ variants: containerVariants,
138
+ initial: "hidden",
139
+ whileInView: "shown",
140
+ viewport: { once: !repeat, amount },
141
+ className: cn(as === "span" ? "inline" : "block", className),
142
+ ...rest,
143
+ children: /* @__PURE__ */ jsx2(Tag, { className: as === "span" ? "inline" : "block", children: tokens.map(
144
+ (token, i) => /^\s+$/.test(token) && splitBy === "words" ? /* @__PURE__ */ jsx2("span", { children: " " }, i) : /* @__PURE__ */ jsx2(
145
+ "span",
146
+ {
147
+ className: cn(
148
+ "overflow-hidden",
149
+ splitBy === "lines" ? "block" : "inline-block align-bottom"
150
+ ),
151
+ children: /* @__PURE__ */ jsx2(
152
+ motion2.span,
153
+ {
154
+ className: "inline-block",
155
+ variants: tokenVariants,
156
+ transition: { duration, ease: EASE.out },
157
+ children: token
158
+ }
159
+ )
160
+ },
161
+ i
162
+ )
163
+ ) })
164
+ }
165
+ );
166
+ }
167
+
168
+ // src/site/Parallax.tsx
169
+ import * as React3 from "react";
170
+ import {
171
+ motion as motion3,
172
+ useReducedMotion as useReducedMotion3,
173
+ useScroll,
174
+ useSpring,
175
+ useTransform
176
+ } from "motion/react";
177
+ import { jsx as jsx3 } from "react/jsx-runtime";
178
+ var Parallax = React3.forwardRef(function Parallax2({ speed = 0.2, axis = "y", smooth = true, className, children, style, ...rest }, forwardedRef) {
179
+ const reduce = useReducedMotion3();
180
+ const innerRef = React3.useRef(null);
181
+ React3.useImperativeHandle(forwardedRef, () => innerRef.current);
182
+ const { scrollYProgress } = useScroll({
183
+ target: innerRef,
184
+ offset: ["start end", "end start"]
185
+ });
186
+ const range = 100 * speed;
187
+ const raw = useTransform(scrollYProgress, [0, 1], [range, -range]);
188
+ const smoothed = useSpring(raw, { stiffness: 120, damping: 30, mass: 0.4 });
189
+ const value = smooth ? smoothed : raw;
190
+ if (reduce) {
191
+ return /* @__PURE__ */ jsx3("div", { ref: innerRef, className, style, ...rest, children });
192
+ }
193
+ return /* @__PURE__ */ jsx3(
194
+ motion3.div,
195
+ {
196
+ ref: innerRef,
197
+ className: cn("will-change-transform", className),
198
+ style: { ...style, [axis]: value },
199
+ ...rest,
200
+ children
201
+ }
202
+ );
203
+ });
204
+
205
+ // src/site/Marquee.tsx
206
+ import * as React4 from "react";
207
+ import {
208
+ motion as motion4,
209
+ useAnimationFrame,
210
+ useMotionValue,
211
+ useReducedMotion as useReducedMotion4
212
+ } from "motion/react";
213
+ import { jsx as jsx4, jsxs } from "react/jsx-runtime";
214
+ var Marquee = React4.forwardRef(function Marquee2({ speed = 60, direction = "left", pauseOnHover = true, gap = "3rem", className, children, ...rest }, ref) {
215
+ const reduce = useReducedMotion4();
216
+ const x = useMotionValue(0);
217
+ const setWidthRef = React4.useRef(0);
218
+ const groupRef = React4.useRef(null);
219
+ const [paused, setPaused] = React4.useState(false);
220
+ React4.useEffect(() => {
221
+ const el = groupRef.current;
222
+ if (!el) return;
223
+ const measure = () => {
224
+ const gapPx = parseFloat(getComputedStyle(el.parentElement).columnGap || "0") || 0;
225
+ setWidthRef.current = el.offsetWidth + gapPx;
226
+ };
227
+ measure();
228
+ const ro = new ResizeObserver(measure);
229
+ ro.observe(el);
230
+ return () => ro.disconnect();
231
+ }, []);
232
+ useAnimationFrame((_, delta) => {
233
+ if (reduce || paused || setWidthRef.current === 0) return;
234
+ const dir = direction === "left" ? -1 : 1;
235
+ const moveBy = speed * delta / 1e3;
236
+ let next = x.get() + dir * moveBy;
237
+ const w = setWidthRef.current;
238
+ if (next <= -w) next += w;
239
+ else if (next >= w) next -= w;
240
+ x.set(next);
241
+ });
242
+ if (reduce) {
243
+ return /* @__PURE__ */ jsx4(
244
+ "div",
245
+ {
246
+ ref,
247
+ className: cn("flex w-full items-center overflow-x-auto", className),
248
+ style: { columnGap: gap },
249
+ ...rest,
250
+ children
251
+ }
252
+ );
253
+ }
254
+ return /* @__PURE__ */ jsx4(
255
+ "div",
256
+ {
257
+ ref,
258
+ className: cn("w-full overflow-hidden", className),
259
+ onMouseEnter: pauseOnHover ? () => setPaused(true) : void 0,
260
+ onMouseLeave: pauseOnHover ? () => setPaused(false) : void 0,
261
+ ...rest,
262
+ children: /* @__PURE__ */ jsxs(motion4.div, { className: "flex w-max flex-nowrap items-center", style: { x, columnGap: gap }, children: [
263
+ /* @__PURE__ */ jsx4("div", { ref: groupRef, className: "flex flex-nowrap items-center", style: { columnGap: gap }, children }),
264
+ /* @__PURE__ */ jsx4("div", { className: "flex flex-nowrap items-center", style: { columnGap: gap }, "aria-hidden": true, children })
265
+ ] })
266
+ }
267
+ );
268
+ });
269
+
270
+ // src/site/Magnetic.tsx
271
+ import * as React5 from "react";
272
+ import { motion as motion5, useMotionValue as useMotionValue2, useReducedMotion as useReducedMotion5, useSpring as useSpring2 } from "motion/react";
273
+ import { jsx as jsx5 } from "react/jsx-runtime";
274
+ var Magnetic = React5.forwardRef(function Magnetic2({ strength = 0.35, max = 24, spring = "snappy", className, children, ...rest }, forwardedRef) {
275
+ const reduce = useReducedMotion5();
276
+ const innerRef = React5.useRef(null);
277
+ React5.useImperativeHandle(forwardedRef, () => innerRef.current);
278
+ const mvx = useMotionValue2(0);
279
+ const mvy = useMotionValue2(0);
280
+ const x = useSpring2(mvx, SPRING[spring]);
281
+ const y = useSpring2(mvy, SPRING[spring]);
282
+ const clamp = (v) => Math.max(-max, Math.min(max, v));
283
+ function handleMove(e) {
284
+ if (reduce) return;
285
+ const el = innerRef.current;
286
+ if (!el) return;
287
+ const rect = el.getBoundingClientRect();
288
+ const cx = rect.left + rect.width / 2;
289
+ const cy = rect.top + rect.height / 2;
290
+ mvx.set(clamp((e.clientX - cx) * strength));
291
+ mvy.set(clamp((e.clientY - cy) * strength));
292
+ }
293
+ function reset() {
294
+ mvx.set(0);
295
+ mvy.set(0);
296
+ }
297
+ if (reduce) {
298
+ return /* @__PURE__ */ jsx5("div", { ref: innerRef, className: cn("inline-block", className), ...rest, children });
299
+ }
300
+ return /* @__PURE__ */ jsx5(
301
+ motion5.div,
302
+ {
303
+ ref: innerRef,
304
+ className: cn("inline-block", className),
305
+ style: { x, y },
306
+ onMouseMove: handleMove,
307
+ onMouseLeave: reset,
308
+ ...rest,
309
+ children
310
+ }
311
+ );
312
+ });
313
+ export {
314
+ DURATION,
315
+ EASE,
316
+ Magnetic,
317
+ Marquee,
318
+ Parallax,
319
+ Reveal,
320
+ SPRING,
321
+ TextReveal
322
+ };