@walrosproject/ui 0.4.5 → 0.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.
- package/README.md +24 -0
- package/dist/assets/walros-seasonal-heart-arrow.svg +17 -0
- package/dist/assets/walros-seasonal-pumpkin.svg +17 -0
- package/dist/index.d.ts +28 -3
- package/dist/index.js +288 -88
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -73,6 +73,30 @@ const theme = useWalrosTheme({
|
|
|
73
73
|
<DirectionalCursor />
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
+
## Decoración estacional
|
|
77
|
+
|
|
78
|
+
`WalrosSeasonalBackground` envuelve la interfaz y coloca sus decoraciones SVG en una capa de fondo: nunca se superponen al contenido, no ocupan espacio, no capturan interacción y respetan `prefers-reduced-motion`. El calendario automático se resuelve en `Europe/Madrid` y se actualiza al siguiente cambio de día.
|
|
79
|
+
|
|
80
|
+
- Halloween: desde el 30 de septiembre a las 00:00 hasta el 1 de noviembre a las 00:00.
|
|
81
|
+
- Navidad: desde el 30 de noviembre a las 00:00 hasta el 11 de enero a las 00:00.
|
|
82
|
+
- San Valentín: desde el 14 de febrero a las 00:00 hasta el 15 de febrero a las 00:00.
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
import { WalrosSeasonalBackground } from "@walrosproject/ui";
|
|
86
|
+
|
|
87
|
+
export function App() {
|
|
88
|
+
return (
|
|
89
|
+
<WalrosSeasonalBackground density={20} style={{ background: "var(--page-background)" }}>
|
|
90
|
+
<YourApp />
|
|
91
|
+
</WalrosSeasonalBackground>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Para que todos los SVG conserven exactamente la misma presencia, aplica el fondo general de la página al wrapper (mediante `style` o su clase) y deja transparente el contenedor principal. Los fondos opacos de tarjetas y secciones seguirán ocultando correctamente las decoraciones que pasen por detrás.
|
|
97
|
+
|
|
98
|
+
Para previsualizar una temporada sin esperar a la fecha, utiliza `season="halloween"`, `season="winter"` o `season="valentine"`. `season="none"` desactiva la capa. Una vez integrado y desplegado, las campañas se activan cada año sin actualizar los repositorios.
|
|
99
|
+
|
|
76
100
|
## Otros recursos
|
|
77
101
|
|
|
78
102
|
El paquete conserva `WalrosLogo`, `WalrosWordmark` y sus URLs de imagen. Todos los componentes funcionan con React 18 y 19. El portal y el glitch respetan `prefers-reduced-motion`.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 160 160" fill="none">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="heart" x1="40" y1="51" x2="123" y2="129" gradientUnits="userSpaceOnUse">
|
|
4
|
+
<stop stop-color="#FF5457"/>
|
|
5
|
+
<stop offset="1" stop-color="#D41E32"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
<linearGradient id="gold" x1="24" y1="24" x2="135" y2="133" gradientUnits="userSpaceOnUse">
|
|
8
|
+
<stop stop-color="#FFE958"/>
|
|
9
|
+
<stop offset="1" stop-color="#F3AE19"/>
|
|
10
|
+
</linearGradient>
|
|
11
|
+
</defs>
|
|
12
|
+
<path d="M80 137S28 107 28 64c0-20 14-34 33-34 10 0 16 5 19 12 3-7 9-12 19-12 19 0 33 14 33 34 0 43-52 73-52 73Z" fill="url(#heart)" stroke="#C92735" stroke-width="7" stroke-linejoin="round"/>
|
|
13
|
+
<path d="M76 44c-13-9-28-2-33 12" stroke="#FF9A90" stroke-width="6" stroke-linecap="round" opacity=".45"/>
|
|
14
|
+
<path d="m18 43 37-16-16 37-21-21ZM142 117l-37 16 16-37 21 21Z" fill="url(#gold)" stroke="#D8A91C" stroke-width="5" stroke-linejoin="round"/>
|
|
15
|
+
<path d="m31 53 96 72" stroke="#F5B415" stroke-width="13" stroke-linecap="round"/>
|
|
16
|
+
<path d="M72 89c0-16 11-24 24-22" stroke="#AE1830" stroke-width="9" stroke-linecap="round"/>
|
|
17
|
+
</svg>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 160 160" fill="none">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="pumpkin" x1="28" y1="44" x2="133" y2="132" gradientUnits="userSpaceOnUse">
|
|
4
|
+
<stop stop-color="#FF9F17"/>
|
|
5
|
+
<stop offset="1" stop-color="#F06408"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
<linearGradient id="stem" x1="83" y1="15" x2="105" y2="55" gradientUnits="userSpaceOnUse">
|
|
8
|
+
<stop stop-color="#45933D"/>
|
|
9
|
+
<stop offset="1" stop-color="#1D642C"/>
|
|
10
|
+
</linearGradient>
|
|
11
|
+
</defs>
|
|
12
|
+
<path d="M88 45c-2-14 3-26 14-34 11 7 17 17 16 31-1 8-5 13-12 15-8 3-15-2-18-12Z" fill="url(#stem)"/>
|
|
13
|
+
<path d="M80 36c-36 0-61 22-61 57 0 34 24 53 61 53s61-19 61-53c0-35-25-57-61-57Z" fill="url(#pumpkin)"/>
|
|
14
|
+
<path d="M80 38c-18 14-23 75 0 106M51 44c-17 22-17 64 0 94M109 44c17 22 17 64 0 94" stroke="#FFBE3C" stroke-width="5" stroke-linecap="round" opacity=".6"/>
|
|
15
|
+
<path d="m47 82 16-20c2-3 6-3 8 1l8 24c1 4-3 7-7 6l-22-4c-4-1-5-4-3-7ZM113 82 97 62c-2-3-6-3-8 1l-8 24c-1 4 3 7 7 6l22-4c4-1 5-4 3-7ZM78 91l-10 12c-3 3-1 8 4 8h17c5 0 7-5 4-8L83 91c-1-2-4-2-5 0Z" fill="#3A260F"/>
|
|
16
|
+
<path d="M45 112c-2-5 4-8 8-5l10 7 10-7c2-2 5-2 7 0l10 7 10-7c4-3 10 0 8 5l-9 28c-1 4-5 5-8 3l-11-8-11 8c-3 2-7 1-8-3l-16-28Z" fill="#3A260F"/>
|
|
17
|
+
</svg>
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { ImgHTMLAttributes, CSSProperties, RefObject } from 'react';
|
|
2
|
+
import { ImgHTMLAttributes, CSSProperties, ReactNode, RefObject } from 'react';
|
|
3
3
|
|
|
4
4
|
type PortalOrigin = {
|
|
5
5
|
centerX: number;
|
|
@@ -15,7 +15,8 @@ type Walros3DPortalTransitionProps = {
|
|
|
15
15
|
zIndex?: number;
|
|
16
16
|
lockScroll?: boolean;
|
|
17
17
|
};
|
|
18
|
-
|
|
18
|
+
/** The stable portal used by ui 0.3.4: a centred silhouette that only scales. */
|
|
19
|
+
declare function Walros3DPortalTransition({ onComplete, duration, backgroundColor, zIndex, lockScroll, }: Walros3DPortalTransitionProps): react.JSX.Element | null;
|
|
19
20
|
|
|
20
21
|
type WalrosPortalTransitionProps = {
|
|
21
22
|
duration?: number;
|
|
@@ -61,6 +62,28 @@ type WalrosThemeGlitchProps = {
|
|
|
61
62
|
};
|
|
62
63
|
declare function WalrosThemeGlitch({ active, zIndex, className, style, }: WalrosThemeGlitchProps): react.JSX.Element;
|
|
63
64
|
|
|
65
|
+
type WalrosSeason = "auto" | "none" | "halloween" | "winter" | "valentine";
|
|
66
|
+
type WalrosSeasonalBackgroundProps = {
|
|
67
|
+
children: ReactNode;
|
|
68
|
+
/** Uses the seasonal calendar when set to auto. */
|
|
69
|
+
season?: WalrosSeason;
|
|
70
|
+
/** Time zone used by automatic mode. Defaults to Europe/Madrid. */
|
|
71
|
+
timeZone?: string;
|
|
72
|
+
/** Number of decorations distributed throughout the page. Defaults to 20. */
|
|
73
|
+
density?: number;
|
|
74
|
+
enabled?: boolean;
|
|
75
|
+
className?: string;
|
|
76
|
+
contentClassName?: string;
|
|
77
|
+
style?: CSSProperties;
|
|
78
|
+
};
|
|
79
|
+
type ActiveSeason = Exclude<WalrosSeason, "auto" | "none">;
|
|
80
|
+
/**
|
|
81
|
+
* Returns the campaign active on a date in the selected time zone.
|
|
82
|
+
* Each interval includes its start at 00:00 and excludes its stated end at 00:00.
|
|
83
|
+
*/
|
|
84
|
+
declare function getWalrosSeason(date?: Date, timeZone?: string): ActiveSeason | null;
|
|
85
|
+
declare function WalrosSeasonalBackground({ children, season, timeZone, density, enabled, className, contentClassName, style, }: WalrosSeasonalBackgroundProps): react.JSX.Element;
|
|
86
|
+
|
|
64
87
|
type WalrosTheme = "light" | "dark";
|
|
65
88
|
type WalrosThemeMode = "body" | "viewport";
|
|
66
89
|
type WalrosThemeShakeTarget = HTMLElement | RefObject<HTMLElement | null> | null | undefined;
|
|
@@ -106,5 +129,7 @@ declare const walrosLogoChromeUrl: string;
|
|
|
106
129
|
declare const walrosWordmarkLightUrl: string;
|
|
107
130
|
declare const walrosWordmarkDarkUrl: string;
|
|
108
131
|
declare const walrosThemeGlitchSoundUrl: string;
|
|
132
|
+
declare const walrosSeasonalPumpkinUrl: string;
|
|
133
|
+
declare const walrosSeasonalHeartArrowUrl: string;
|
|
109
134
|
|
|
110
|
-
export { DirectionalCursor, type PortalOrigin, type UseWalrosThemeOptions, type UseWalrosThemeResult, Walros3DPortalTransition, type Walros3DPortalTransitionProps, WalrosLogo, type WalrosLogoProps, WalrosPortalTransition, type WalrosPortalTransitionProps, type WalrosTheme, WalrosThemeGlitch, type WalrosThemeGlitchProps, type WalrosThemeMode, type WalrosThemeShakeTarget, WalrosThemeTransition, type WalrosThemeTransitionProps, WalrosWordmark, type WalrosWordmarkProps, useWalrosTheme, walrosLogoChromeUrl, walrosPortalSilhouetteUrl, walrosThemeGlitchSoundUrl, walrosWordmarkDarkUrl, walrosWordmarkLightUrl };
|
|
135
|
+
export { DirectionalCursor, type PortalOrigin, type UseWalrosThemeOptions, type UseWalrosThemeResult, Walros3DPortalTransition, type Walros3DPortalTransitionProps, WalrosLogo, type WalrosLogoProps, WalrosPortalTransition, type WalrosPortalTransitionProps, type WalrosSeason, WalrosSeasonalBackground, type WalrosSeasonalBackgroundProps, type WalrosTheme, WalrosThemeGlitch, type WalrosThemeGlitchProps, type WalrosThemeMode, type WalrosThemeShakeTarget, WalrosThemeTransition, type WalrosThemeTransitionProps, WalrosWordmark, type WalrosWordmarkProps, getWalrosSeason, useWalrosTheme, walrosLogoChromeUrl, walrosPortalSilhouetteUrl, walrosSeasonalHeartArrowUrl, walrosSeasonalPumpkinUrl, walrosThemeGlitchSoundUrl, walrosWordmarkDarkUrl, walrosWordmarkLightUrl };
|
package/dist/index.js
CHANGED
|
@@ -15,15 +15,11 @@ var walrosPortalPaths = [
|
|
|
15
15
|
|
|
16
16
|
// src/components/Walros3DPortalTransition.tsx
|
|
17
17
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
18
|
+
var SILHOUETTE_VIEWBOX = 1254;
|
|
18
19
|
var FOCUS_X = 626;
|
|
19
20
|
var FOCUS_Y = 333;
|
|
20
|
-
var VISIBLE_LEFT = 244;
|
|
21
|
-
var VISIBLE_RIGHT = 1010;
|
|
22
|
-
var VISIBLE_TOP = 115;
|
|
23
|
-
var VISIBLE_BOTTOM = 1128;
|
|
24
21
|
var PORTAL_RADIUS = 190;
|
|
25
22
|
function Walros3DPortalTransition({
|
|
26
|
-
origin,
|
|
27
23
|
onComplete,
|
|
28
24
|
duration = 900,
|
|
29
25
|
backgroundColor = "#000",
|
|
@@ -36,100 +32,52 @@ function Walros3DPortalTransition({
|
|
|
36
32
|
height: typeof window === "undefined" ? 0 : window.innerHeight
|
|
37
33
|
}));
|
|
38
34
|
const overlay = useRef(null);
|
|
39
|
-
const
|
|
35
|
+
const maskScale = useRef(null);
|
|
40
36
|
const completeRef = useRef(onComplete);
|
|
41
37
|
completeRef.current = onComplete;
|
|
42
|
-
const maskId = `walros-
|
|
38
|
+
const maskId = `walros-portal-mask-${useId().replace(/:/g, "_")}`;
|
|
43
39
|
useLayoutEffect(() => {
|
|
44
|
-
if (!visible || viewport.width <= 0 || viewport.height <= 0 || !overlay.current || !
|
|
40
|
+
if (!visible || viewport.width <= 0 || viewport.height <= 0 || !overlay.current || !maskScale.current) return;
|
|
45
41
|
const previousOverflow = document.body.style.overflow;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
const visualCenterX = (VISIBLE_LEFT + VISIBLE_RIGHT) / 2;
|
|
54
|
-
const visualCenterY = (VISIBLE_TOP + VISIBLE_BOTTOM) / 2;
|
|
55
|
-
const initialScale = Math.min(origin.width / visibleWidth, origin.height / visibleHeight) * 0.985;
|
|
56
|
-
const initialX = origin.centerX - (visualCenterX - FOCUS_X) * initialScale;
|
|
57
|
-
const initialY = origin.centerY - (visualCenterY - FOCUS_Y) * initialScale;
|
|
58
|
-
const diagonal = Math.hypot(viewport.width, viewport.height) / 2;
|
|
59
|
-
const finalScale = Math.max(
|
|
60
|
-
(diagonal + 80) / PORTAL_RADIUS * 1.15,
|
|
61
|
-
(viewport.height / 2 + 80) / (429 - FOCUS_Y) * 1.05
|
|
62
|
-
);
|
|
63
|
-
const targetX = viewport.width / 2 - (visualCenterX - FOCUS_X) * finalScale;
|
|
64
|
-
const targetY = viewport.height / 2 - (visualCenterY - FOCUS_Y) * finalScale;
|
|
42
|
+
if (lockScroll) document.body.style.overflow = "hidden";
|
|
43
|
+
const initialPixels2 = Math.min(180, Math.max(120, viewport.width * 0.12));
|
|
44
|
+
const initialScale2 = initialPixels2 / SILHOUETTE_VIEWBOX;
|
|
45
|
+
const finalScale = (Math.hypot(viewport.width, viewport.height) / 2 + 80) / PORTAL_RADIUS * 1.15;
|
|
46
|
+
const visualCenter2 = SILHOUETTE_VIEWBOX / 2;
|
|
47
|
+
const portalCenterX2 = viewport.width / 2 - (visualCenter2 - FOCUS_X) * initialScale2;
|
|
48
|
+
const portalCenterY2 = viewport.height / 2 - (visualCenter2 - FOCUS_Y) * initialScale2;
|
|
65
49
|
const total = duration / 1e3;
|
|
66
|
-
gsap.set(
|
|
67
|
-
x: initialX,
|
|
68
|
-
y: initialY,
|
|
69
|
-
scale: initialScale,
|
|
70
|
-
svgOrigin: "0 0"
|
|
71
|
-
});
|
|
50
|
+
gsap.set(maskScale.current, { scale: initialScale2, svgOrigin: "0 0" });
|
|
72
51
|
gsap.set(overlay.current, { opacity: 1 });
|
|
73
52
|
const finish = () => {
|
|
74
|
-
if (lockScroll)
|
|
75
|
-
document.body.style.overflow = previousOverflow;
|
|
76
|
-
document.documentElement.style.scrollbarGutter = previousScrollbarGutter;
|
|
77
|
-
}
|
|
53
|
+
if (lockScroll) document.body.style.overflow = previousOverflow;
|
|
78
54
|
setVisible(false);
|
|
79
55
|
completeRef.current?.();
|
|
80
56
|
};
|
|
81
|
-
const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
82
57
|
const timeline = gsap.timeline({ onComplete: finish });
|
|
83
|
-
if (
|
|
58
|
+
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
|
|
84
59
|
timeline.to(overlay.current, { opacity: 0, duration: 0.15, ease: "power1.out" });
|
|
85
60
|
} else {
|
|
86
|
-
timeline.to(
|
|
87
|
-
x: targetX,
|
|
88
|
-
y: targetY,
|
|
89
|
-
scale: finalScale,
|
|
90
|
-
duration: total,
|
|
91
|
-
ease: "power2.in"
|
|
92
|
-
});
|
|
93
|
-
timeline.to(overlay.current, {
|
|
94
|
-
opacity: 0,
|
|
95
|
-
duration: total * 0.1,
|
|
96
|
-
ease: "power2.out"
|
|
97
|
-
}, total * 0.9);
|
|
61
|
+
timeline.to(maskScale.current, { scale: initialScale2 * 1.4, duration: total * 0.15, ease: "power2.out" }, 0).to(maskScale.current, { scale: finalScale, duration: total * 0.85, ease: "power2.in" }, total * 0.15).to(overlay.current, { opacity: 0, duration: total * 0.1, ease: "power2.out" }, total * 0.9);
|
|
98
62
|
}
|
|
99
63
|
return () => {
|
|
100
64
|
timeline.kill();
|
|
101
|
-
if (lockScroll)
|
|
102
|
-
document.body.style.overflow = previousOverflow;
|
|
103
|
-
document.documentElement.style.scrollbarGutter = previousScrollbarGutter;
|
|
104
|
-
}
|
|
65
|
+
if (lockScroll) document.body.style.overflow = previousOverflow;
|
|
105
66
|
};
|
|
106
|
-
}, [duration, lockScroll,
|
|
67
|
+
}, [duration, lockScroll, viewport, visible]);
|
|
107
68
|
if (!visible) return null;
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
zIndex,
|
|
121
|
-
backgroundColor: viewport.width > 0 && viewport.height > 0 ? "transparent" : backgroundColor
|
|
122
|
-
},
|
|
123
|
-
"aria-hidden": "true",
|
|
124
|
-
children: /* @__PURE__ */ jsxs("svg", { width: "100%", height: "100%", viewBox: `0 0 ${viewport.width} ${viewport.height}`, preserveAspectRatio: "none", style: { display: "block" }, children: [
|
|
125
|
-
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("mask", { id: maskId, maskUnits: "userSpaceOnUse", x: "0", y: "0", width: viewport.width, height: viewport.height, children: [
|
|
126
|
-
/* @__PURE__ */ jsx("rect", { width: viewport.width, height: viewport.height, fill: "white" }),
|
|
127
|
-
/* @__PURE__ */ jsx("g", { ref: portal, children: /* @__PURE__ */ jsx("g", { transform: `translate(${-FOCUS_X} ${-FOCUS_Y})`, fill: "black", children: walrosPortalPaths.map((path, index) => /* @__PURE__ */ jsx("path", { d: path }, index)) }) })
|
|
128
|
-
] }) }),
|
|
129
|
-
/* @__PURE__ */ jsx("rect", { width: viewport.width, height: viewport.height, fill: backgroundColor, mask: `url(#${maskId})` })
|
|
130
|
-
] })
|
|
131
|
-
}
|
|
132
|
-
);
|
|
69
|
+
const initialPixels = Math.min(180, Math.max(120, viewport.width * 0.12));
|
|
70
|
+
const initialScale = initialPixels / SILHOUETTE_VIEWBOX;
|
|
71
|
+
const visualCenter = SILHOUETTE_VIEWBOX / 2;
|
|
72
|
+
const portalCenterX = viewport.width / 2 - (visualCenter - FOCUS_X) * initialScale;
|
|
73
|
+
const portalCenterY = viewport.height / 2 - (visualCenter - FOCUS_Y) * initialScale;
|
|
74
|
+
return /* @__PURE__ */ jsx("div", { ref: overlay, className: "walros-3d-portal", "aria-hidden": "true", style: { position: "fixed", inset: 0, width: "100vw", height: "100dvh", overflow: "hidden", pointerEvents: "none", zIndex, backgroundColor: viewport.width > 0 ? "transparent" : backgroundColor }, children: /* @__PURE__ */ jsxs("svg", { width: "100%", height: "100%", viewBox: `0 0 ${viewport.width} ${viewport.height}`, preserveAspectRatio: "none", style: { display: "block" }, children: [
|
|
75
|
+
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("mask", { id: maskId, maskUnits: "userSpaceOnUse", x: "0", y: "0", width: viewport.width, height: viewport.height, children: [
|
|
76
|
+
/* @__PURE__ */ jsx("rect", { width: viewport.width, height: viewport.height, fill: "white" }),
|
|
77
|
+
/* @__PURE__ */ jsx("g", { transform: `translate(${portalCenterX} ${portalCenterY})`, children: /* @__PURE__ */ jsx("g", { ref: maskScale, transform: `scale(${initialScale})`, children: /* @__PURE__ */ jsx("g", { transform: `translate(${-FOCUS_X} ${-FOCUS_Y})`, fill: "black", children: walrosPortalPaths.map((path, index) => /* @__PURE__ */ jsx("path", { d: path }, index)) }) }) })
|
|
78
|
+
] }) }),
|
|
79
|
+
/* @__PURE__ */ jsx("rect", { width: viewport.width, height: viewport.height, fill: backgroundColor, mask: `url(#${maskId})` })
|
|
80
|
+
] }) });
|
|
133
81
|
}
|
|
134
82
|
|
|
135
83
|
// src/components/useOverlayHost.ts
|
|
@@ -576,6 +524,14 @@ var walrosThemeGlitchSoundUrl = new URL(
|
|
|
576
524
|
"./assets/walros-theme-glitch.mp3",
|
|
577
525
|
import.meta.url
|
|
578
526
|
).href;
|
|
527
|
+
var walrosSeasonalPumpkinUrl = new URL(
|
|
528
|
+
"./assets/walros-seasonal-pumpkin.svg",
|
|
529
|
+
import.meta.url
|
|
530
|
+
).href;
|
|
531
|
+
var walrosSeasonalHeartArrowUrl = new URL(
|
|
532
|
+
"./assets/walros-seasonal-heart-arrow.svg",
|
|
533
|
+
import.meta.url
|
|
534
|
+
).href;
|
|
579
535
|
|
|
580
536
|
// src/components/WalrosLogo.tsx
|
|
581
537
|
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
@@ -615,12 +571,247 @@ function WalrosWordmark({
|
|
|
615
571
|
);
|
|
616
572
|
}
|
|
617
573
|
|
|
574
|
+
// src/components/WalrosSeasonalBackground.tsx
|
|
575
|
+
import { useEffect as useEffect2, useMemo, useState as useState4 } from "react";
|
|
576
|
+
import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
577
|
+
var PARTICLES = [
|
|
578
|
+
[2, 6, 0, 28, -18, 0.84],
|
|
579
|
+
[10, 25, 2.2, 31, 16, 0.72],
|
|
580
|
+
[18, 58, 4.6, 29, -14, 0.8],
|
|
581
|
+
[26, 12, 6.9, 33, 20, 0.75],
|
|
582
|
+
[34, 42, 9.3, 27, -16, 0.86],
|
|
583
|
+
[42, 79, 11.8, 32, 18, 0.72],
|
|
584
|
+
[50, 3, 14.1, 30, -20, 0.82],
|
|
585
|
+
[58, 28, 16.7, 34, 15, 0.7],
|
|
586
|
+
[66, 63, 19.2, 28, -18, 0.84],
|
|
587
|
+
[74, 16, 21.5, 31, 16, 0.74],
|
|
588
|
+
[82, 48, 24.1, 29, -14, 0.8],
|
|
589
|
+
[90, 84, 26.8, 33, 20, 0.7],
|
|
590
|
+
[97, 36, 29.4, 27, -16, 0.86],
|
|
591
|
+
[13, 91, 31.8, 32, 18, 0.73],
|
|
592
|
+
[54, 94, 34.3, 30, -20, 0.8],
|
|
593
|
+
[88, 68, 37.1, 34, 15, 0.7],
|
|
594
|
+
[6, 23, 3.8, 35, -15, 0.8],
|
|
595
|
+
[21, 71, 7.1, 30, 18, 0.8],
|
|
596
|
+
[39, 32, 10.6, 33, -18, 0.8],
|
|
597
|
+
[47, 87, 13.2, 29, 16, 0.8],
|
|
598
|
+
[61, 53, 16.8, 35, -16, 0.8],
|
|
599
|
+
[73, 9, 20.3, 30, 18, 0.8],
|
|
600
|
+
[84, 76, 23.9, 33, -18, 0.8],
|
|
601
|
+
[95, 57, 27.5, 29, 16, 0.8]
|
|
602
|
+
];
|
|
603
|
+
var STYLES = `
|
|
604
|
+
.walros-seasonal-background {
|
|
605
|
+
position: relative;
|
|
606
|
+
isolation: isolate;
|
|
607
|
+
min-height: 100dvh;
|
|
608
|
+
}
|
|
609
|
+
.walros-seasonal-background__decorations {
|
|
610
|
+
position: absolute;
|
|
611
|
+
inset: 0;
|
|
612
|
+
z-index: 0;
|
|
613
|
+
overflow: hidden;
|
|
614
|
+
pointer-events: none;
|
|
615
|
+
contain: layout paint;
|
|
616
|
+
}
|
|
617
|
+
.walros-seasonal-background__content {
|
|
618
|
+
position: relative;
|
|
619
|
+
z-index: 1;
|
|
620
|
+
}
|
|
621
|
+
.walros-seasonal-background__particle {
|
|
622
|
+
position: absolute;
|
|
623
|
+
top: var(--walros-seasonal-top);
|
|
624
|
+
left: 0;
|
|
625
|
+
display: block;
|
|
626
|
+
width: clamp(24px, 2.45vw, 44px);
|
|
627
|
+
height: clamp(24px, 2.45vw, 44px);
|
|
628
|
+
color: var(--walros-seasonal-color);
|
|
629
|
+
/* Important prevents external theme styles or animations from making
|
|
630
|
+
individual decorations fade at different moments. */
|
|
631
|
+
opacity: var(--walros-seasonal-opacity) !important;
|
|
632
|
+
filter: drop-shadow(0 2px 5px rgb(0 0 0 / .12));
|
|
633
|
+
animation: walros-seasonal-drift var(--walros-seasonal-duration) linear var(--walros-seasonal-delay) infinite;
|
|
634
|
+
will-change: transform;
|
|
635
|
+
}
|
|
636
|
+
.walros-seasonal-background__particle svg {
|
|
637
|
+
display: block;
|
|
638
|
+
width: 100%;
|
|
639
|
+
height: 100%;
|
|
640
|
+
overflow: visible;
|
|
641
|
+
}
|
|
642
|
+
@keyframes walros-seasonal-drift {
|
|
643
|
+
0% { transform: translate3d(-12vw, 0, 0) rotate(-12deg); }
|
|
644
|
+
50% { transform: translate3d(50vw, var(--walros-seasonal-sway), 0) rotate(180deg); }
|
|
645
|
+
100% { transform: translate3d(112vw, 0, 0) rotate(372deg); }
|
|
646
|
+
}
|
|
647
|
+
@media (prefers-reduced-motion: reduce) {
|
|
648
|
+
.walros-seasonal-background__particle {
|
|
649
|
+
animation: none;
|
|
650
|
+
opacity: var(--walros-seasonal-opacity);
|
|
651
|
+
transform: translate3d(0, 0, 0);
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
`;
|
|
655
|
+
function classNames(...values) {
|
|
656
|
+
return values.filter(Boolean).join(" ");
|
|
657
|
+
}
|
|
658
|
+
function installStyles() {
|
|
659
|
+
if (typeof document === "undefined" || document.getElementById("walros-seasonal-background-styles")) return;
|
|
660
|
+
const style = document.createElement("style");
|
|
661
|
+
style.id = "walros-seasonal-background-styles";
|
|
662
|
+
style.textContent = STYLES;
|
|
663
|
+
document.head.appendChild(style);
|
|
664
|
+
}
|
|
665
|
+
function getDateParts(date, timeZone) {
|
|
666
|
+
const parts = new Intl.DateTimeFormat("en-GB", {
|
|
667
|
+
timeZone,
|
|
668
|
+
day: "2-digit",
|
|
669
|
+
month: "2-digit",
|
|
670
|
+
year: "numeric"
|
|
671
|
+
}).formatToParts(date);
|
|
672
|
+
const value = (type) => Number(parts.find((part) => part.type === type)?.value);
|
|
673
|
+
return { day: value("day"), month: value("month"), year: value("year") };
|
|
674
|
+
}
|
|
675
|
+
function getUtcOffsetMilliseconds(date, timeZone) {
|
|
676
|
+
const parts = new Intl.DateTimeFormat("en-GB", {
|
|
677
|
+
timeZone,
|
|
678
|
+
timeZoneName: "longOffset"
|
|
679
|
+
}).formatToParts(date);
|
|
680
|
+
const offset = parts.find((part) => part.type === "timeZoneName")?.value ?? "GMT";
|
|
681
|
+
const match = offset.match(/^GMT([+-])(\d{2}):(\d{2})$/);
|
|
682
|
+
if (!match) return 0;
|
|
683
|
+
const minutes = Number(match[2]) * 60 + Number(match[3]);
|
|
684
|
+
return (match[1] === "+" ? 1 : -1) * minutes * 6e4;
|
|
685
|
+
}
|
|
686
|
+
function millisecondsUntilNextMidnight(timeZone) {
|
|
687
|
+
const now = /* @__PURE__ */ new Date();
|
|
688
|
+
const { year, month, day } = getDateParts(now, timeZone);
|
|
689
|
+
const localNextMidnight = Date.UTC(year, month - 1, day + 1, 0, 0, 1);
|
|
690
|
+
let nextMidnight = localNextMidnight - getUtcOffsetMilliseconds(new Date(localNextMidnight), timeZone);
|
|
691
|
+
nextMidnight = localNextMidnight - getUtcOffsetMilliseconds(new Date(nextMidnight), timeZone);
|
|
692
|
+
return Math.max(1e3, nextMidnight - now.getTime());
|
|
693
|
+
}
|
|
694
|
+
function getWalrosSeason(date = /* @__PURE__ */ new Date(), timeZone = "Europe/Madrid") {
|
|
695
|
+
const { day, month } = getDateParts(date, timeZone);
|
|
696
|
+
if (month === 9 && day >= 30 || month === 10) return "halloween";
|
|
697
|
+
if (month === 11 && day >= 30 || month === 12 || month === 1 && day <= 10) return "winter";
|
|
698
|
+
if (month === 2 && day === 14) return "valentine";
|
|
699
|
+
return null;
|
|
700
|
+
}
|
|
701
|
+
function useAutomaticSeason(timeZone) {
|
|
702
|
+
const [now, setNow] = useState4(() => /* @__PURE__ */ new Date());
|
|
703
|
+
useEffect2(() => {
|
|
704
|
+
let timer = 0;
|
|
705
|
+
const refreshAtNextMidnight = () => {
|
|
706
|
+
timer = window.setTimeout(() => {
|
|
707
|
+
setNow(/* @__PURE__ */ new Date());
|
|
708
|
+
refreshAtNextMidnight();
|
|
709
|
+
}, millisecondsUntilNextMidnight(timeZone));
|
|
710
|
+
};
|
|
711
|
+
refreshAtNextMidnight();
|
|
712
|
+
return () => window.clearTimeout(timer);
|
|
713
|
+
}, [timeZone]);
|
|
714
|
+
return getWalrosSeason(now, timeZone);
|
|
715
|
+
}
|
|
716
|
+
function SnowIcon() {
|
|
717
|
+
return /* @__PURE__ */ jsx8("svg", { viewBox: "0 0 32 32", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsxs4("g", { stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
718
|
+
/* @__PURE__ */ jsx8("path", { d: "M16 3v26M4.7 9.5l22.6 13M4.7 22.5l22.6-13" }),
|
|
719
|
+
/* @__PURE__ */ jsx8("path", { d: "m16 3-3 4M16 3l3 4M16 29l-3-4M16 29l3-4M4.7 9.5l4.9.5M4.7 9.5l2 4.5M27.3 22.5l-4.9-.5M27.3 22.5l-2-4.5M4.7 22.5l4.9-.5M4.7 22.5l2-4.5M27.3 9.5l-4.9.5M27.3 9.5l-2 4.5" })
|
|
720
|
+
] }) });
|
|
721
|
+
}
|
|
722
|
+
function PumpkinIcon() {
|
|
723
|
+
return /* @__PURE__ */ jsxs4("svg", { viewBox: "0 0 160 160", fill: "none", "aria-hidden": "true", children: [
|
|
724
|
+
/* @__PURE__ */ jsxs4("defs", { children: [
|
|
725
|
+
/* @__PURE__ */ jsxs4("linearGradient", { id: "walros-seasonal-pumpkin", x1: "28", y1: "44", x2: "133", y2: "132", gradientUnits: "userSpaceOnUse", children: [
|
|
726
|
+
/* @__PURE__ */ jsx8("stop", { stopColor: "#FF9F17" }),
|
|
727
|
+
/* @__PURE__ */ jsx8("stop", { offset: "1", stopColor: "#F06408" })
|
|
728
|
+
] }),
|
|
729
|
+
/* @__PURE__ */ jsxs4("linearGradient", { id: "walros-seasonal-stem", x1: "83", y1: "15", x2: "105", y2: "55", gradientUnits: "userSpaceOnUse", children: [
|
|
730
|
+
/* @__PURE__ */ jsx8("stop", { stopColor: "#45933D" }),
|
|
731
|
+
/* @__PURE__ */ jsx8("stop", { offset: "1", stopColor: "#1D642C" })
|
|
732
|
+
] })
|
|
733
|
+
] }),
|
|
734
|
+
/* @__PURE__ */ jsx8("path", { d: "M88 45c-2-14 3-26 14-34 11 7 17 17 16 31-1 8-5 13-12 15-8 3-15-2-18-12Z", fill: "url(#walros-seasonal-stem)" }),
|
|
735
|
+
/* @__PURE__ */ jsx8("path", { d: "M80 36c-36 0-61 22-61 57 0 34 24 53 61 53s61-19 61-53c0-35-25-57-61-57Z", fill: "url(#walros-seasonal-pumpkin)" }),
|
|
736
|
+
/* @__PURE__ */ jsx8("path", { d: "M80 38c-18 14-23 75 0 106M51 44c-17 22-17 64 0 94M109 44c17 22 17 64 0 94", stroke: "#FFBE3C", strokeWidth: "5", strokeLinecap: "round", opacity: ".6" }),
|
|
737
|
+
/* @__PURE__ */ jsx8("path", { d: "m47 82 16-20c2-3 6-3 8 1l8 24c1 4-3 7-7 6l-22-4c-4-1-5-4-3-7ZM113 82 97 62c-2-3-6-3-8 1l-8 24c-1 4 3 7 7 6l22-4c4-1 5-4 3-7ZM78 91l-10 12c-3 3-1 8 4 8h17c5 0 7-5 4-8L83 91c-1-2-4-2-5 0Z", fill: "#3A260F" }),
|
|
738
|
+
/* @__PURE__ */ jsx8("path", { d: "M45 112c-2-5 4-8 8-5l10 7 10-7c2-2 5-2 7 0l10 7 10-7c4-3 10 0 8 5l-9 28c-1 4-5 5-8 3l-11-8-11 8c-3 2-7 1-8-3l-16-28Z", fill: "#3A260F" })
|
|
739
|
+
] });
|
|
740
|
+
}
|
|
741
|
+
function HeartArrowIcon() {
|
|
742
|
+
return /* @__PURE__ */ jsxs4("svg", { viewBox: "0 0 160 160", fill: "none", "aria-hidden": "true", children: [
|
|
743
|
+
/* @__PURE__ */ jsxs4("defs", { children: [
|
|
744
|
+
/* @__PURE__ */ jsxs4("linearGradient", { id: "walros-seasonal-heart", x1: "40", y1: "51", x2: "123", y2: "129", gradientUnits: "userSpaceOnUse", children: [
|
|
745
|
+
/* @__PURE__ */ jsx8("stop", { stopColor: "#FF5457" }),
|
|
746
|
+
/* @__PURE__ */ jsx8("stop", { offset: "1", stopColor: "#D41E32" })
|
|
747
|
+
] }),
|
|
748
|
+
/* @__PURE__ */ jsxs4("linearGradient", { id: "walros-seasonal-gold", x1: "24", y1: "24", x2: "135", y2: "133", gradientUnits: "userSpaceOnUse", children: [
|
|
749
|
+
/* @__PURE__ */ jsx8("stop", { stopColor: "#FFE958" }),
|
|
750
|
+
/* @__PURE__ */ jsx8("stop", { offset: "1", stopColor: "#F3AE19" })
|
|
751
|
+
] })
|
|
752
|
+
] }),
|
|
753
|
+
/* @__PURE__ */ jsx8("path", { d: "M80 137S28 107 28 64c0-20 14-34 33-34 10 0 16 5 19 12 3-7 9-12 19-12 19 0 33 14 33 34 0 43-52 73-52 73Z", fill: "url(#walros-seasonal-heart)", stroke: "#C92735", strokeWidth: "7", strokeLinejoin: "round" }),
|
|
754
|
+
/* @__PURE__ */ jsx8("path", { d: "M76 44c-13-9-28-2-33 12", stroke: "#FF9A90", strokeWidth: "6", strokeLinecap: "round", opacity: ".45" }),
|
|
755
|
+
/* @__PURE__ */ jsx8("path", { d: "m18 43 37-16-16 37-21-21ZM142 117l-37 16 16-37 21 21Z", fill: "url(#walros-seasonal-gold)", stroke: "#D8A91C", strokeWidth: "5", strokeLinejoin: "round" }),
|
|
756
|
+
/* @__PURE__ */ jsx8("path", { d: "m31 53 96 72", stroke: "#F5B415", strokeWidth: "13", strokeLinecap: "round" }),
|
|
757
|
+
/* @__PURE__ */ jsx8("path", { d: "M72 89c0-16 11-24 24-22", stroke: "#AE1830", strokeWidth: "9", strokeLinecap: "round" })
|
|
758
|
+
] });
|
|
759
|
+
}
|
|
760
|
+
function Decoration({ season }) {
|
|
761
|
+
if (season === "halloween") return /* @__PURE__ */ jsx8(PumpkinIcon, {});
|
|
762
|
+
if (season === "winter") return /* @__PURE__ */ jsx8(SnowIcon, {});
|
|
763
|
+
return /* @__PURE__ */ jsx8(HeartArrowIcon, {});
|
|
764
|
+
}
|
|
765
|
+
function getSeasonColor(season) {
|
|
766
|
+
if (season === "halloween") return "transparent";
|
|
767
|
+
if (season === "winter") return "#78B7E8";
|
|
768
|
+
return "transparent";
|
|
769
|
+
}
|
|
770
|
+
function WalrosSeasonalBackground({
|
|
771
|
+
children,
|
|
772
|
+
season = "auto",
|
|
773
|
+
timeZone = "Europe/Madrid",
|
|
774
|
+
density = 20,
|
|
775
|
+
enabled = true,
|
|
776
|
+
className,
|
|
777
|
+
contentClassName,
|
|
778
|
+
style
|
|
779
|
+
}) {
|
|
780
|
+
useEffect2(() => installStyles(), []);
|
|
781
|
+
const automaticSeason = useAutomaticSeason(timeZone);
|
|
782
|
+
const activeSeason = season === "auto" ? automaticSeason : season === "none" ? null : season;
|
|
783
|
+
const particleCount = Math.max(1, Math.min(PARTICLES.length, Math.round(density)));
|
|
784
|
+
const particles = useMemo(() => PARTICLES.slice(0, particleCount), [particleCount]);
|
|
785
|
+
return /* @__PURE__ */ jsxs4("div", { className: classNames("walros-seasonal-background", className), style, children: [
|
|
786
|
+
enabled && activeSeason && /* @__PURE__ */ jsx8("div", { className: "walros-seasonal-background__decorations", "aria-hidden": "true", children: particles.map(([, top, , duration, sway], index) => {
|
|
787
|
+
const elapsed = index / particleCount * duration;
|
|
788
|
+
return /* @__PURE__ */ jsx8(
|
|
789
|
+
"span",
|
|
790
|
+
{
|
|
791
|
+
className: "walros-seasonal-background__particle",
|
|
792
|
+
style: {
|
|
793
|
+
"--walros-seasonal-top": `${top}%`,
|
|
794
|
+
"--walros-seasonal-delay": `-${elapsed}s`,
|
|
795
|
+
"--walros-seasonal-duration": `${duration}s`,
|
|
796
|
+
"--walros-seasonal-sway": `${sway}px`,
|
|
797
|
+
"--walros-seasonal-opacity": ".52",
|
|
798
|
+
"--walros-seasonal-color": getSeasonColor(activeSeason)
|
|
799
|
+
},
|
|
800
|
+
children: /* @__PURE__ */ jsx8(Decoration, { season: activeSeason })
|
|
801
|
+
},
|
|
802
|
+
`${activeSeason}-${index}`
|
|
803
|
+
);
|
|
804
|
+
}) }),
|
|
805
|
+
/* @__PURE__ */ jsx8("div", { className: classNames("walros-seasonal-background__content", contentClassName), children })
|
|
806
|
+
] });
|
|
807
|
+
}
|
|
808
|
+
|
|
618
809
|
// src/hooks/useWalrosTheme.ts
|
|
619
810
|
import {
|
|
620
811
|
useCallback,
|
|
621
|
-
useEffect as
|
|
812
|
+
useEffect as useEffect3,
|
|
622
813
|
useRef as useRef3,
|
|
623
|
-
useState as
|
|
814
|
+
useState as useState5
|
|
624
815
|
} from "react";
|
|
625
816
|
var GLITCH_BASE_CLASS = "walros-theme-glitch-page";
|
|
626
817
|
var GLITCH_BODY_CLASS = "walros-theme-glitch-page--body";
|
|
@@ -667,11 +858,11 @@ function useWalrosTheme({
|
|
|
667
858
|
lockScroll,
|
|
668
859
|
onAfterUnlock
|
|
669
860
|
} = {}) {
|
|
670
|
-
const [theme, setThemeState] =
|
|
861
|
+
const [theme, setThemeState] = useState5(
|
|
671
862
|
() => readInitialTheme(storageKey, defaultTheme, useSystemPreference)
|
|
672
863
|
);
|
|
673
|
-
const [mounted, setMounted] =
|
|
674
|
-
const [glitching, setGlitching] =
|
|
864
|
+
const [mounted, setMounted] = useState5(false);
|
|
865
|
+
const [glitching, setGlitching] = useState5(false);
|
|
675
866
|
const themeRef = useRef3(theme);
|
|
676
867
|
const glitchingRef = useRef3(false);
|
|
677
868
|
const swapTimerRef = useRef3(null);
|
|
@@ -699,8 +890,12 @@ function useWalrosTheme({
|
|
|
699
890
|
try {
|
|
700
891
|
if (!soundRef.current || soundRef.current.src !== new URL(soundUrlRef.current, document.baseURI).href) {
|
|
701
892
|
soundRef.current?.pause();
|
|
893
|
+
soundRef.current?.remove();
|
|
702
894
|
soundRef.current = new Audio(soundUrlRef.current);
|
|
703
895
|
soundRef.current.preload = "auto";
|
|
896
|
+
soundRef.current.setAttribute("aria-hidden", "true");
|
|
897
|
+
soundRef.current.style.display = "none";
|
|
898
|
+
document.body.appendChild(soundRef.current);
|
|
704
899
|
}
|
|
705
900
|
const audio = soundRef.current;
|
|
706
901
|
audio.volume = Math.max(0, Math.min(1, soundVolumeRef.current));
|
|
@@ -722,7 +917,7 @@ function useWalrosTheme({
|
|
|
722
917
|
},
|
|
723
918
|
[storageKey]
|
|
724
919
|
);
|
|
725
|
-
|
|
920
|
+
useEffect3(() => {
|
|
726
921
|
const initialTheme = readInitialTheme(
|
|
727
922
|
storageKey,
|
|
728
923
|
defaultTheme,
|
|
@@ -857,12 +1052,13 @@ function useWalrosTheme({
|
|
|
857
1052
|
finishGlitch();
|
|
858
1053
|
}, effectiveDuration);
|
|
859
1054
|
}, [finishGlitch, lockViewport, persistTheme, playThemeSound, swapDelay, totalDuration]);
|
|
860
|
-
|
|
1055
|
+
useEffect3(() => {
|
|
861
1056
|
return () => {
|
|
862
1057
|
clearTimers();
|
|
863
1058
|
removeShakeClasses();
|
|
864
1059
|
unlockViewport(false);
|
|
865
1060
|
soundRef.current?.pause();
|
|
1061
|
+
soundRef.current?.remove();
|
|
866
1062
|
if (soundRef.current) soundRef.current.currentTime = 0;
|
|
867
1063
|
soundRef.current = null;
|
|
868
1064
|
};
|
|
@@ -881,12 +1077,16 @@ export {
|
|
|
881
1077
|
Walros3DPortalTransition,
|
|
882
1078
|
WalrosLogo,
|
|
883
1079
|
WalrosPortalTransition,
|
|
1080
|
+
WalrosSeasonalBackground,
|
|
884
1081
|
WalrosThemeGlitch,
|
|
885
1082
|
WalrosThemeTransition,
|
|
886
1083
|
WalrosWordmark,
|
|
1084
|
+
getWalrosSeason,
|
|
887
1085
|
useWalrosTheme,
|
|
888
1086
|
walrosLogoChromeUrl,
|
|
889
1087
|
walrosPortalSilhouetteUrl,
|
|
1088
|
+
walrosSeasonalHeartArrowUrl,
|
|
1089
|
+
walrosSeasonalPumpkinUrl,
|
|
890
1090
|
walrosThemeGlitchSoundUrl,
|
|
891
1091
|
walrosWordmarkDarkUrl,
|
|
892
1092
|
walrosWordmarkLightUrl
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/WalrosPortalTransition.tsx","../src/components/Walros3DPortalTransition.tsx","../src/portalSilhouette.ts","../src/components/useOverlayHost.ts","../src/components/WalrosThemeTransition.tsx","../src/components/WalrosThemeGlitch.tsx","../src/components/DirectionalCursor.tsx","../src/handCursor.ts","../src/assets.ts","../src/components/WalrosLogo.tsx","../src/components/WalrosWordmark.tsx","../src/hooks/useWalrosTheme.ts"],"sourcesContent":["import { useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { Walros3DPortalTransition, type PortalOrigin } from \"./Walros3DPortalTransition\";\nimport { useOverlayHost } from \"./useOverlayHost\";\n\nexport type WalrosPortalTransitionProps = {\n duration?: number;\n onComplete?: () => void;\n backgroundColor?: string;\n enabled?: boolean;\n storageMode?: \"always\" | \"session\" | \"once\";\n storageKey?: string;\n zIndex?: number;\n /** Projected bounds of an existing 3D logo, as on walros.org. */\n origin?: PortalOrigin;\n};\n\nfunction defaultOrigin(): PortalOrigin {\n if (typeof window === \"undefined\") return { centerX: 0, centerY: 0, width: 70, height: 90 };\n return {\n centerX: window.innerWidth / 2,\n centerY: window.innerHeight * .45,\n width: 70,\n height: 90,\n };\n}\n\nfunction getStorage(mode: \"session\" | \"once\"): Storage | null {\n if (typeof window === \"undefined\") return null;\n try {\n return mode === \"session\" ? window.sessionStorage : window.localStorage;\n } catch {\n return null;\n }\n}\n\nfunction shouldRun(enabled: boolean, mode: \"always\" | \"session\" | \"once\", key: string) {\n if (!enabled) return false;\n if (mode === \"always\") return true;\n try {\n return getStorage(mode)?.getItem(key) == null;\n } catch {\n return true;\n }\n}\n\n/** 900 ms entrance: the walrus silhouette reveals the page from the centre. */\nexport function WalrosPortalTransition({\n duration = 900,\n onComplete,\n backgroundColor = \"#000\",\n enabled = true,\n storageMode = \"always\",\n storageKey = \"walros-portal-seen\",\n zIndex = 10000,\n origin,\n}: WalrosPortalTransitionProps) {\n const [run] = useState(() => shouldRun(enabled, storageMode, storageKey));\n const [complete, setComplete] = useState(false);\n const [initialOrigin] = useState(() => origin ?? defaultOrigin());\n const host = useOverlayHost(zIndex);\n\n if (!host || !enabled || !run || complete) return null;\n\n return createPortal(\n <Walros3DPortalTransition\n origin={initialOrigin}\n duration={duration}\n backgroundColor={backgroundColor}\n zIndex={1}\n lockScroll\n onComplete={() => {\n if (storageMode !== \"always\") {\n try { getStorage(storageMode)?.setItem(storageKey, \"1\"); } catch { /* Storage is optional. */ }\n }\n setComplete(true);\n onComplete?.();\n }}\n />,\n host,\n );\n}\n\nexport default WalrosPortalTransition;\n","import { useId, useLayoutEffect, useRef, useState } from \"react\";\nimport gsap from \"gsap\";\nimport { walrosPortalPaths } from \"../portalSilhouette\";\n\r\nexport type PortalOrigin = {\r\n centerX: number;\r\n centerY: number;\r\n width: number;\r\n height: number;\r\n};\r\n\r\nexport type Walros3DPortalTransitionProps = {\n origin: PortalOrigin;\n onComplete?: () => void;\n duration?: number;\n backgroundColor?: string;\n zIndex?: number;\n lockScroll?: boolean;\n};\n\r\nconst FOCUS_X = 626;\r\nconst FOCUS_Y = 333;\r\nconst VISIBLE_LEFT = 244;\r\nconst VISIBLE_RIGHT = 1010;\r\nconst VISIBLE_TOP = 115;\r\nconst VISIBLE_BOTTOM = 1128;\r\nconst PORTAL_RADIUS = 190;\r\n\r\nexport function Walros3DPortalTransition({\n origin,\n onComplete,\n duration = 900,\n backgroundColor = \"#000\",\n zIndex = 10001,\n lockScroll = true,\n}: Walros3DPortalTransitionProps) {\n const [visible, setVisible] = useState(true);\n // Keep one coordinate system for the entire 900 ms animation. Locking the\n // page can trigger a resize when its scrollbar disappears; restarting the\n // GSAP timeline on that resize would leave the entrance stuck on black.\n const [viewport] = useState(() => ({\n width: typeof window === \"undefined\" ? 0 : window.innerWidth,\n height: typeof window === \"undefined\" ? 0 : window.innerHeight,\n }));\n const overlay = useRef<HTMLDivElement>(null);\n const portal = useRef<SVGGElement>(null);\n const completeRef = useRef(onComplete);\n completeRef.current = onComplete;\n const maskId = `walros-3d-portal-${useId().replace(/:/g, \"_\")}`;\n\r\n useLayoutEffect(() => {\n if (!visible || viewport.width <= 0 || viewport.height <= 0 || !overlay.current || !portal.current) return;\n const previousOverflow = document.body.style.overflow;\n const previousScrollbarGutter = document.documentElement.style.scrollbarGutter;\n if (lockScroll) {\n document.documentElement.style.scrollbarGutter = \"stable\";\n document.body.style.overflow = \"hidden\";\n }\n\r\n const visibleWidth = VISIBLE_RIGHT - VISIBLE_LEFT;\n const visibleHeight = VISIBLE_BOTTOM - VISIBLE_TOP;\n const visualCenterX = (VISIBLE_LEFT + VISIBLE_RIGHT) / 2;\n const visualCenterY = (VISIBLE_TOP + VISIBLE_BOTTOM) / 2;\n // Let the black mask overlap the projected GLB by roughly one pixel. This\n // removes the pale halo without visibly cropping the chrome silhouette.\n const initialScale = Math.min(origin.width / visibleWidth, origin.height / visibleHeight) * .985;\n // Match the small silhouette to the supplied 3D logo bounds, then move\n // its muzzle on a straight path into the viewport centre as it grows.\n const initialX = origin.centerX - (visualCenterX - FOCUS_X) * initialScale;\n const initialY = origin.centerY - (visualCenterY - FOCUS_Y) * initialScale;\n const diagonal = Math.hypot(viewport.width, viewport.height) / 2;\n const finalScale = Math.max(\n ((diagonal + 80) / PORTAL_RADIUS) * 1.15,\n ((viewport.height / 2 + 80) / (429 - FOCUS_Y)) * 1.05,\n );\n // Scale is applied around the SVG origin (0, 0). Compensate for the\n // silhouette's visual centre so that it travels in a straight line and\n // remains centred instead of drifting towards the lower-right corner.\n const targetX = viewport.width / 2 - (visualCenterX - FOCUS_X) * finalScale;\n const targetY = viewport.height / 2 - (visualCenterY - FOCUS_Y) * finalScale;\n const total = duration / 1000;\r\n\r\n gsap.set(portal.current, {\n x: initialX,\n y: initialY,\n scale: initialScale,\n svgOrigin: \"0 0\",\n });\n gsap.set(overlay.current, { opacity: 1 });\n\r\n const finish = () => {\n if (lockScroll) {\n document.body.style.overflow = previousOverflow;\n document.documentElement.style.scrollbarGutter = previousScrollbarGutter;\n }\n setVisible(false);\n completeRef.current?.();\n };\r\n const reducedMotion = window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\r\n const timeline = gsap.timeline({ onComplete: finish });\r\n if (reducedMotion) {\r\n timeline.to(overlay.current, { opacity: 0, duration: 0.15, ease: \"power1.out\" });\n } else {\n timeline\n .to(portal.current, {\n x: targetX,\n y: targetY,\n scale: finalScale,\n duration: total,\n ease: \"power2.in\",\n });\n timeline\n .to(overlay.current, {\n opacity: 0,\r\n duration: total * 0.1,\r\n ease: \"power2.out\",\r\n }, total * 0.9);\r\n }\r\n\r\n return () => {\n timeline.kill();\n if (lockScroll) {\n document.body.style.overflow = previousOverflow;\n document.documentElement.style.scrollbarGutter = previousScrollbarGutter;\n }\n };\n }, [duration, lockScroll, origin, viewport, visible]);\n\n if (!visible) return null;\n\r\n return (\r\n <div\r\n ref={overlay}\r\n className=\"walros-3d-portal\"\n style={{\n position: \"fixed\",\n inset: 0,\n width: \"100vw\",\n height: \"100dvh\",\n overflow: \"hidden\",\n pointerEvents: \"none\",\n zIndex,\n backgroundColor: viewport.width > 0 && viewport.height > 0 ? \"transparent\" : backgroundColor,\n }}\n aria-hidden=\"true\"\r\n >\r\n <svg width=\"100%\" height=\"100%\" viewBox={`0 0 ${viewport.width} ${viewport.height}`} preserveAspectRatio=\"none\" style={{ display: \"block\" }}>\n <defs>\r\n <mask id={maskId} maskUnits=\"userSpaceOnUse\" x=\"0\" y=\"0\" width={viewport.width} height={viewport.height}>\r\n <rect width={viewport.width} height={viewport.height} fill=\"white\" />\r\n <g ref={portal}>\r\n <g transform={`translate(${-FOCUS_X} ${-FOCUS_Y})`} fill=\"black\">\r\n {walrosPortalPaths.map((path, index) => <path d={path} key={index} />)}\n </g>\r\n </g>\r\n </mask>\r\n </defs>\n <rect width={viewport.width} height={viewport.height} fill={backgroundColor} mask={`url(#${maskId})`} />\n </svg>\r\n </div>\r\n );\r\n}\r\n","/* Exact silhouette used by the walros.org portal mask. */\r\nexport const walrosPortalPaths = [\r\n \"M 244.00 354.00 C 240.50 377.67, 240.17 413.67, 242.00 434.00 C 243.83 454.33, 249.50 464.50, 255.00 476.00 C 260.50 487.50, 268.50 496.00, 275.00 503.00 C 281.50 510.00, 287.17 513.67, 294.00 518.00 C 300.83 522.33, 306.00 525.67, 316.00 529.00 C 326.00 532.33, 336.33 536.67, 354.00 538.00 C 371.67 539.33, 397.83 540.83, 422.00 537.00 C 446.17 533.17, 474.17 525.33, 499.00 515.00 C 523.83 504.67, 550.00 489.33, 571.00 475.00 C 592.00 460.67, 615.00 436.50, 625.00 429.00 C 635.00 421.50, 623.67 424.00, 631.00 430.00 C 638.33 436.00, 656.67 454.83, 669.00 465.00 C 681.33 475.17, 690.00 482.17, 705.00 491.00 C 720.00 499.83, 743.67 511.50, 759.00 518.00 C 774.33 524.50, 784.00 526.83, 797.00 530.00 C 810.00 533.17, 820.00 535.83, 837.00 537.00 C 854.00 538.17, 881.17 539.00, 899.00 537.00 C 916.83 535.00, 932.00 530.00, 944.00 525.00 C 956.00 520.00, 962.00 516.17, 971.00 507.00 C 980.00 497.83, 991.67 482.83, 998.00 470.00 C 1004.33 457.17, 1007.17 446.33, 1009.00 430.00 C 1010.83 413.67, 1010.83 390.50, 1009.00 372.00 C 1007.17 353.50, 1003.83 337.17, 998.00 319.00 C 992.17 300.83, 983.67 280.17, 974.00 263.00 C 964.33 245.83, 952.00 229.67, 940.00 216.00 C 928.00 202.33, 917.17 192.00, 902.00 181.00 C 886.83 170.00, 866.50 158.17, 849.00 150.00 C 831.50 141.83, 816.67 137.00, 797.00 132.00 C 777.33 127.00, 756.67 122.83, 731.00 120.00 C 705.33 117.17, 673.67 115.33, 643.00 115.00 C 612.33 114.67, 575.67 115.67, 547.00 118.00 C 518.33 120.33, 496.17 123.00, 471.00 129.00 C 445.83 135.00, 418.33 143.50, 396.00 154.00 C 373.67 164.50, 353.50 178.50, 337.00 192.00 C 320.50 205.50, 309.33 218.33, 297.00 235.00 C 284.67 251.67, 271.83 272.17, 263.00 292.00 C 254.17 311.83, 247.50 330.33, 244.00 354.00 Z\",\r\n \"M 289.00 536.00 C 283.17 535.50, 284.83 533.00, 284.00 544.00 C 283.17 555.00, 282.67 578.67, 284.00 602.00 C 285.33 625.33, 287.00 651.83, 292.00 684.00 C 297.00 716.17, 306.33 763.50, 314.00 795.00 C 321.67 826.50, 328.67 847.17, 338.00 873.00 C 347.33 898.83, 357.00 923.67, 370.00 950.00 C 383.00 976.33, 399.67 1006.00, 416.00 1031.00 C 432.33 1056.00, 455.33 1084.50, 468.00 1100.00 C 480.67 1115.50, 486.17 1119.33, 492.00 1124.00 C 497.83 1128.67, 500.67 1127.67, 503.00 1128.00 C 505.33 1128.33, 505.50 1127.50, 506.00 1126.00 C 506.50 1124.50, 510.33 1132.00, 506.00 1119.00 C 501.67 1106.00, 488.17 1073.83, 480.00 1048.00 C 471.83 1022.17, 462.67 987.67, 457.00 964.00 C 451.33 940.33, 449.17 927.33, 446.00 906.00 C 442.83 884.67, 439.50 865.00, 438.00 836.00 C 436.50 807.00, 436.50 758.33, 437.00 732.00 C 437.50 705.67, 439.00 696.33, 441.00 678.00 C 443.00 659.67, 444.83 644.00, 449.00 622.00 C 453.17 600.00, 464.50 559.00, 466.00 546.00 C 467.50 533.00, 468.67 542.50, 458.00 544.00 C 447.33 545.50, 418.33 553.17, 402.00 555.00 C 385.67 556.83, 373.83 556.33, 360.00 555.00 C 346.17 553.67, 330.83 550.17, 319.00 547.00 C 307.17 543.83, 294.83 536.50, 289.00 536.00 Z\",\r\n \"M 961.00 537.00 C 948.50 539.17, 907.83 552.00, 889.00 555.00 C 870.17 558.00, 864.17 557.00, 848.00 555.00 C 831.83 553.00, 802.83 545.00, 792.00 543.00 C 781.17 541.00, 784.83 542.50, 783.00 543.00 C 781.17 543.50, 778.67 533.83, 781.00 546.00 C 783.33 558.17, 792.67 592.33, 797.00 616.00 C 801.33 639.67, 804.83 668.83, 807.00 688.00 C 809.17 707.17, 809.67 709.00, 810.00 731.00 C 810.33 753.00, 810.50 792.83, 809.00 820.00 C 807.50 847.17, 804.50 870.50, 801.00 894.00 C 797.50 917.50, 794.00 936.17, 788.00 961.00 C 782.00 985.83, 773.50 1016.67, 765.00 1043.00 C 756.50 1069.33, 741.33 1104.83, 737.00 1119.00 C 732.67 1133.17, 736.67 1127.17, 739.00 1128.00 C 741.33 1128.83, 745.83 1127.83, 751.00 1124.00 C 756.17 1120.17, 757.33 1120.50, 770.00 1105.00 C 782.67 1089.50, 811.33 1053.50, 827.00 1031.00 C 842.67 1008.50, 851.17 995.00, 864.00 970.00 C 876.83 945.00, 892.83 910.00, 904.00 881.00 C 915.17 852.00, 923.00 826.67, 931.00 796.00 C 939.00 765.33, 946.67 728.67, 952.00 697.00 C 957.33 665.33, 961.00 631.83, 963.00 606.00 C 965.00 580.17, 964.33 553.50, 964.00 542.00 C 963.67 530.50, 973.50 534.83, 961.00 537.00 Z\",\r\n] as const;\r\n","import { useLayoutEffect, useState } from \"react\";\n\n/** Keep fixed overlays outside an animated body, which would otherwise\n * become their containing block and displace the portal during the glitch. */\nexport function useOverlayHost(zIndex: number) {\n const [host] = useState<HTMLDivElement | null>(() =>\n typeof document === \"undefined\" ? null : document.createElement(\"div\"),\n );\n\n useLayoutEffect(() => {\n if (!host) return;\n host.dataset.walrosOverlayRoot = \"\";\n host.style.position = \"fixed\";\n host.style.inset = \"0\";\n host.style.pointerEvents = \"none\";\n document.documentElement.appendChild(host);\n return () => host.remove();\n }, [host]);\n\n useLayoutEffect(() => {\n if (host) host.style.zIndex = String(zIndex);\n }, [host, zIndex]);\n\n return host;\n}\n","import { createPortal } from \"react-dom\";\nimport { WalrosThemeGlitch } from \"./WalrosThemeGlitch\";\nimport { useOverlayHost } from \"./useOverlayHost\";\n\nexport type WalrosThemeTransitionProps = {\n /** Pass the `glitching` value returned by `useWalrosTheme`. */\n active: boolean;\n /** @deprecated The theme change has no portal; retained for source compatibility. */\n portalDuration?: number;\n /** @deprecated The theme change has no logo; retained for source compatibility. */\n logoUrl?: string;\n zIndex?: number;\n};\n\n/** The walros.org theme effect is a shake and glitch, without an intro logo. */\nexport function WalrosThemeTransition({\n active,\n zIndex = 10000,\n}: WalrosThemeTransitionProps) {\n const host = useOverlayHost(zIndex);\n if (!host) return null;\n\n return createPortal(\n <WalrosThemeGlitch active={active} zIndex={1} />,\n host,\n );\n}\n","import type { CSSProperties } from \"react\";\n\nexport type WalrosThemeGlitchProps = {\n active: boolean;\n zIndex?: number;\n className?: string;\n style?: CSSProperties;\n};\n\nconst GLITCH_STYLES = `\n.walros-theme-glitch-root {\n position: fixed;\n inset: 0;\n z-index: 9998;\n pointer-events: none;\n overflow: hidden;\n visibility: hidden;\n}\n.walros-theme-glitch-root.is-active {\n visibility: visible;\n}\n.walros-theme-glitch-root::before,\n.walros-theme-glitch-root::after {\n content: \"\";\n position: absolute;\n inset: 0;\n}\n.walros-theme-glitch-root::before {\n background: rgba(0, 0, 0, .82);\n mix-blend-mode: normal;\n animation: walros-glitch-flash 1500ms steps(1, end) both;\n}\n.walros-theme-glitch-root::after {\n background: repeating-linear-gradient(0deg, transparent 0 3px, rgba(255,255,255,.09) 3px 4px);\n animation: walros-glitch-scan 90ms steps(2, end) 16 both;\n}\n.walros-theme-glitch-band {\n position: absolute;\n left: -12%;\n width: 124%;\n opacity: 0;\n}\n.walros-theme-glitch-band:nth-child(1) { top: 12%; height: 4%; background: #eaf6ff; animation: walros-glitch-band-a 1500ms steps(1, end) both; }\n.walros-theme-glitch-band:nth-child(2) { top: 36%; height: 11%; background: #020407; animation: walros-glitch-band-b 1500ms steps(1, end) both; }\n.walros-theme-glitch-band:nth-child(3) { top: 62%; height: 2%; background: #7faddb; animation: walros-glitch-band-c 1500ms steps(1, end) both; }\n.walros-theme-glitch-band:nth-child(4) { top: 79%; height: 8%; background: #f4f6f5; animation: walros-glitch-band-d 1500ms steps(1, end) both; }\n\n@keyframes walros-glitch-scan {\n 0% { transform: translateY(-2px); opacity: .25; }\n 50% { transform: translateY(2px); opacity: .08; }\n 100% { transform: translateY(0); opacity: .2; }\n}\n@keyframes walros-glitch-flash {\n 0%, 17%, 22%, 34%, 39%, 54%, 59%, 73%, 78%, 100% { opacity: 0; }\n 18%, 21% { opacity: .18; }\n 35%, 38% { opacity: .48; }\n 55%, 58% { opacity: .82; }\n 74%, 77% { opacity: .22; }\n}\n@keyframes walros-glitch-band-a {\n 0%, 8%, 18%, 42%, 51%, 73%, 82%, 100% { opacity: 0; transform: translateX(0); }\n 9%, 17% { opacity: .55; transform: translateX(-7%); }\n 43%, 50% { opacity: .82; transform: translateX(10%); }\n 74%, 81% { opacity: .32; transform: translateX(-4%); }\n}\n@keyframes walros-glitch-band-b {\n 0%, 20%, 27%, 46%, 55%, 64%, 71%, 100% { opacity: 0; transform: translateX(0); }\n 21%, 26% { opacity: .72; transform: translateX(9%); }\n 47%, 54% { opacity: .9; transform: translateX(-6%); }\n 65%, 70% { opacity: .5; transform: translateX(4%); }\n}\n@keyframes walros-glitch-band-c {\n 0%, 13%, 23%, 39%, 48%, 67%, 76%, 100% { opacity: 0; transform: translateX(0); }\n 14%, 22% { opacity: .9; transform: translateX(5%); }\n 40%, 47% { opacity: .65; transform: translateX(-11%); }\n 68%, 75% { opacity: .75; transform: translateX(8%); }\n}\n@keyframes walros-glitch-band-d {\n 0%, 29%, 38%, 57%, 65%, 85%, 93%, 100% { opacity: 0; transform: translateX(0); }\n 30%, 37% { opacity: .42; transform: translateX(-8%); }\n 58%, 64% { opacity: .7; transform: translateX(7%); }\n 86%, 92% { opacity: .25; transform: translateX(-3%); }\n}\n\n.walros-theme-glitch-lock {\n overscroll-behavior: none;\n}\n\n.walros-theme-glitch-page {\n will-change: transform, filter;\n}\n\n/* Comportamiento original de WalrOS Forum para páginas normales. */\n.walros-theme-glitch-page--body {\n animation: walros-glitch-page-body 1500ms steps(1, end) both;\n}\n\n@keyframes walros-glitch-page-body {\n 0%, 6%, 18%, 31%, 49%, 68%, 82%, 100% { transform: translate3d(0,0,0) scale(1); filter: none; }\n 7% { transform: translate3d(-18px,4px,0) scale(1.012); filter: contrast(1.5) saturate(.45); }\n 19% { transform: translate3d(26px,-7px,0) scale(1.02) skewX(-1.2deg); filter: contrast(1.9) saturate(1.6); }\n 32% { transform: translate3d(-9px,11px,0) scale(1.03); filter: invert(.12) contrast(2); }\n 50%, 57% { transform: translate3d(34px,-3px,0) scale(1.025); filter: grayscale(1) contrast(2.3); }\n 69% { transform: translate3d(-24px,5px,0) scale(1.016); filter: contrast(1.7) saturate(.2); }\n 83% { transform: translate3d(8px,-2px,0) scale(1.006); filter: contrast(1.35); }\n}\n\n/*\n * Modo seguro para parallax/sticky/ScrollTrigger.\n * El shake se aplica a una capa estable del viewport, nunca al scroll real.\n * El pequeño overscan evita descubrir bordes al desplazar la escena.\n */\n.walros-theme-glitch-page--viewport {\n transform-origin: 50% var(--walros-glitch-origin-y, 50%);\n animation: walros-glitch-page-viewport 1500ms steps(1, end) both;\n}\n\n@keyframes walros-glitch-page-viewport {\n 0%, 6%, 18%, 31%, 49%, 68%, 82%, 100% { transform: translate3d(0,0,0) scale(1.012); filter: none; }\n 7% { transform: translate3d(-18px,4px,0) scale(1.012); filter: contrast(1.5) saturate(.45); }\n 19% { transform: translate3d(26px,-7px,0) scale(1.02) skewX(-1.2deg); filter: contrast(1.9) saturate(1.6); }\n 32% { transform: translate3d(-9px,11px,0) scale(1.03); filter: invert(.12) contrast(2); }\n 50%, 57% { transform: translate3d(34px,-3px,0) scale(1.025); filter: grayscale(1) contrast(2.3); }\n 69% { transform: translate3d(-24px,5px,0) scale(1.016); filter: contrast(1.7) saturate(.2); }\n 83% { transform: translate3d(8px,-2px,0) scale(1.006); filter: contrast(1.35); }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .walros-theme-glitch-root::before,\n .walros-theme-glitch-root::after {\n animation: walros-glitch-reduced 150ms ease-out forwards;\n }\n\n .walros-theme-glitch-band {\n animation: none !important;\n }\n\n .walros-theme-glitch-page--body,\n .walros-theme-glitch-page--viewport {\n animation: none;\n }\n\n @keyframes walros-glitch-reduced {\n from { opacity: 0.35; }\n to { opacity: 0; }\n }\n}\n`;\n\nexport function WalrosThemeGlitch({\n active,\n zIndex = 9998,\n className,\n style,\n}: WalrosThemeGlitchProps) {\n return (\n <>\n <style>{GLITCH_STYLES}</style>\n {active ? (\n <div\n className={[\"walros-theme-glitch-root\", \"is-active\", className]\n .filter(Boolean)\n .join(\" \")}\n style={{ zIndex, ...style }}\n aria-hidden=\"true\"\n >\n <span className=\"walros-theme-glitch-band\" />\n <span className=\"walros-theme-glitch-band\" />\n <span className=\"walros-theme-glitch-band\" />\n <span className=\"walros-theme-glitch-band\" />\n </div>\n ) : null}\n </>\n );\n}\n\nexport default WalrosThemeGlitch;\n","import { useEffect, useRef } from \"react\";\nimport { walrosHandCursor } from \"../handCursor\";\n\r\nconst DESKTOP_CURSOR_QUERY = \"(min-width: 1024px) and (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference)\";\n\nconst CURSOR_STYLES = `\n.directional-cursor { position: fixed; top: 0; left: 0; z-index: 9999; width: 20px; height: 22px; opacity: 0; pointer-events: none; contain: layout style; will-change: transform; transition: opacity 100ms linear; }\n.directional-cursor.is-visible { opacity: 1; }\n.directional-cursor-shape { width: 20px; height: 22px; transform-origin: center center; will-change: transform; }\n.directional-cursor svg { display: block; width: 20px; height: 22px; }\n@media (min-width: 1024px) and (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {\n html.has-directional-cursor, html.has-directional-cursor * { cursor: none !important; }\n html.has-directional-cursor :is(textarea, [contenteditable=\"true\"], input:not([type]), input:is([type=\"text\"], [type=\"search\"], [type=\"email\"], [type=\"password\"], [type=\"url\"], [type=\"tel\"], [type=\"number\"])),\n html.has-directional-cursor [contenteditable=\"true\"] * { cursor: text !important; }\n html.has-directional-cursor :is(a, button, select, summary, [role=\"button\"], [role=\"link\"], [aria-haspopup=\"true\"], input[type=\"checkbox\"], input[type=\"radio\"], input[type=\"range\"]) {\n cursor: url(\"${walrosHandCursor}\") 8 2, pointer !important;\n }\n}\n`;\n\nconst TEXT_ENTRY_SELECTOR = 'textarea, [contenteditable=\"true\"], input:not([type]), input:is([type=\"text\"], [type=\"search\"], [type=\"email\"], [type=\"password\"], [type=\"url\"], [type=\"tel\"], [type=\"number\"])';\nconst INTERACTIVE_SELECTOR = 'a, button, select, summary, [role=\"button\"], [role=\"link\"], [aria-haspopup=\"true\"], input[type=\"checkbox\"], input[type=\"radio\"], input[type=\"range\"]';\n\r\nexport function DirectionalCursor() {\r\n const positionLayer = useRef<HTMLDivElement>(null);\r\n const directionLayer = useRef<HTMLDivElement>(null);\r\n\r\n useEffect(() => {\r\n const position = positionLayer.current;\r\n const direction = directionLayer.current;\r\n if (!position || !direction) return;\r\n\r\n const media = window.matchMedia(DESKTOP_CURSOR_QUERY);\r\n let active = false;\r\n let frame = 0;\r\n let moveFrame = 0;\r\n let scaleTimer = 0;\r\n let latestEvent: MouseEvent | null = null;\r\n let currentX = window.innerWidth / 2;\r\n let currentY = -60;\r\n let targetX = currentX;\r\n let targetY = currentY;\r\n let currentAngle = 0;\r\n let targetAngle = 0;\r\n let hasAngle = false;\r\n let currentScale = 1;\r\n let targetScale = 1;\r\n let lastX = currentX;\r\n let lastY = 0;\r\n\r\n const render = () => {\r\n currentX += (targetX - currentX) * 0.4;\r\n currentY += (targetY - currentY) * 0.4;\r\n const angleDelta = ((targetAngle - currentAngle + 540) % 360) - 180;\r\n currentAngle += angleDelta * 0.24;\r\n currentScale += (targetScale - currentScale) * 0.24;\r\n\r\n position.style.transform = `translate3d(${currentX}px, ${currentY}px, 0)`;\r\n direction.style.transform = `translate(-50%, -50%) rotate(${currentAngle}deg) scale(${currentScale})`;\r\n\r\n const unsettled = Math.abs(targetX - currentX) > 0.08\r\n || Math.abs(targetY - currentY) > 0.08\r\n || Math.abs(angleDelta) > 0.08\r\n || Math.abs(targetScale - currentScale) > 0.002;\r\n frame = unsettled ? window.requestAnimationFrame(render) : 0;\r\n };\r\n\r\n const requestRender = () => {\r\n if (!frame) frame = window.requestAnimationFrame(render);\r\n };\r\n\r\n const processMove = () => {\r\n moveFrame = 0;\r\n const event = latestEvent;\r\n if (!event) return;\r\n const deltaX = event.clientX - lastX;\r\n const deltaY = event.clientY - lastY;\r\n const distance = Math.hypot(deltaX, deltaY);\r\n targetX = event.clientX;\r\n targetY = event.clientY;\r\n // Text editing keeps the native I-beam; everything clickable uses only\n // the WalrOS cursor, never a second OS hand or arrow.\n const target = event.target instanceof Element ? event.target : null;\n const textEntry = target?.closest(TEXT_ENTRY_SELECTOR);\n const interactive = target?.closest(INTERACTIVE_SELECTOR);\n // Interactive controls use the supplied .cur hand. Hide the directional\n // cursor there so two pointers are never shown at once.\n position.classList.toggle(\"is-visible\", !textEntry && !interactive);\n\r\n if (distance > 1.25) {\r\n const rawAngle = Math.atan2(deltaY, deltaX) * (180 / Math.PI) + 90;\r\n const normalizedAngle = (rawAngle % 360 + 360) % 360;\r\n if (!hasAngle) {\r\n targetAngle = normalizedAngle;\r\n currentAngle = normalizedAngle;\r\n hasAngle = true;\r\n } else {\r\n targetAngle = normalizedAngle;\r\n }\r\n\r\n targetScale = 0.92;\r\n window.clearTimeout(scaleTimer);\r\n scaleTimer = window.setTimeout(() => {\r\n targetScale = 1;\r\n requestRender();\r\n }, 130);\r\n }\r\n\r\n lastX = event.clientX;\r\n lastY = event.clientY;\r\n requestRender();\r\n };\r\n\r\n const handleMouseMove = (event: MouseEvent) => {\r\n latestEvent = event;\r\n if (!moveFrame) moveFrame = window.requestAnimationFrame(processMove);\r\n };\r\n\r\n const activate = () => {\r\n if (active) return;\r\n active = true;\r\n document.documentElement.classList.add(\"has-directional-cursor\");\r\n window.addEventListener(\"mousemove\", handleMouseMove, { passive: true });\r\n };\r\n\r\n const deactivate = () => {\r\n if (!active) return;\r\n active = false;\r\n document.documentElement.classList.remove(\"has-directional-cursor\");\r\n position.classList.remove(\"is-visible\");\r\n window.removeEventListener(\"mousemove\", handleMouseMove);\r\n window.cancelAnimationFrame(frame);\r\n window.cancelAnimationFrame(moveFrame);\r\n window.clearTimeout(scaleTimer);\r\n frame = 0;\r\n moveFrame = 0;\r\n };\r\n\r\n const sync = () => {\r\n if (media.matches) activate();\r\n else deactivate();\r\n };\r\n media.addEventListener(\"change\", sync);\r\n sync();\r\n\r\n return () => {\r\n media.removeEventListener(\"change\", sync);\r\n deactivate();\r\n };\r\n }, []);\r\n\r\n return (\n <><style>{CURSOR_STYLES}</style><div ref={positionLayer} className=\"directional-cursor\" aria-hidden=\"true\">\n <div ref={directionLayer} className=\"directional-cursor-shape\">\r\n <svg width=\"50\" height=\"54\" viewBox=\"0 0 50 54\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <g filter=\"url(#walros-cursor-shadow)\">\r\n <path d=\"M42.6817 41.1495L27.5103 6.79925C26.7269 5.02557 24.2082 5.02558 23.3927 6.79925L7.59814 41.1495C6.75833 42.9759 8.52712 44.8902 10.4125 44.1954L24.3757 39.0496C24.8829 38.8627 25.4385 38.8627 25.9422 39.0496L39.8121 44.1954C41.6849 44.8902 43.4884 42.9759 42.6817 41.1495Z\" fill=\"black\" />\r\n <path d=\"M43.7146 40.6933L28.5431 6.34306C27.3556 3.65428 23.5772 3.69516 22.3668 6.32755L6.57226 40.6778C5.3134 43.4156 7.97238 46.298 10.803 45.2549L24.7662 40.109C25.0221 40.0147 25.2999 40.0156 25.5494 40.1082L39.4193 45.254C42.2261 46.2953 44.9254 43.4347 43.7146 40.6933Z\" stroke=\"white\" strokeWidth=\"2.25825\" />\r\n </g>\r\n <defs>\r\n <filter id=\"walros-cursor-shadow\" x=\"0.602397\" y=\"0.952444\" width=\"49.0584\" height=\"52.428\" filterUnits=\"userSpaceOnUse\" colorInterpolationFilters=\"sRGB\">\r\n <feFlood floodOpacity=\"0\" result=\"BackgroundImageFix\" />\r\n <feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\" />\r\n <feOffset dy=\"2.25825\" />\r\n <feGaussianBlur stdDeviation=\"2.25825\" />\r\n <feComposite in2=\"hardAlpha\" operator=\"out\" />\r\n <feColorMatrix type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.08 0\" />\r\n <feBlend mode=\"normal\" in2=\"BackgroundImageFix\" result=\"effect1_dropShadow\" />\r\n <feBlend mode=\"normal\" in=\"SourceGraphic\" in2=\"effect1_dropShadow\" result=\"shape\" />\r\n </filter>\r\n </defs>\r\n </svg>\r\n </div>\r\n </div></>\n );\n}\n","// Embedded so consumers receive the exact .cur without copying a package asset.\nexport const walrosHandCursor = \"data:image/x-icon;base64,AAACAAEAICAAAAYAAQCoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAgBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAMAAAADAAAAAwAAAAMAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAwAAAAYAAAAJAAAACwAAAAwAAAAMAAAACwAAAAkAAAAGAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAUAAAAKAAAADwAAABQAAAAYAAAAGgAAABoAAAAYAAAAFAAAAA8AAAAKAAAABQAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAADAAAABQAAAAcAAAAJAAAACkAAAAsAAAALAAAACkAAAAkAAAAHAAAABQAAAAMAAAABgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABgAAAAwAAAAW1tbWTvf397n+/v7v//////////r8/Pzj8/PztsDAwFcAAAArAAAAIAAAABUAAAALAAAABQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAYAAAANAAAAF+fn52v9/f35oqKi/01NTf8xMTH/Ozs7/1paWv+rq6v//v7++uDg4IMAAAAtAAAAIAAAABMAAAAJAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAADQAAABfj4+Nm/f39+mJiYv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP9UVFT/+/v7/dnZ2XcAAAAqAAAAGwAAAA4AAAAFAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAwAAAAW5OTkZf39/fpiYmL/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP9vb2///v7+8paWlkIAAAAiAAAAEwAAAAgAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAAFeTk5GT9/f36YmJi/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wICAv/Ly8v/6+vrnAAAACgAAAAXAAAACgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDn5+di/f39+mJiYv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/3Jycv/5+fnUAAAAKwAAABoAAAAMAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7u7uWP7+/vliYmL/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/RkZG//7+/vEAAAAtAAAAGwAAAA0AAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD////heXl5/wAAAP8AAAD/Dw8P/1NTU/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP9AQED/////+AAAAC4AAAAcAAAADQAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////dDQ0P/AAAA/w8PD//IyMj/iIiI/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/0BAQP/////4AAAALgAAABwAAAANAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/f39ptbW1v91dXX/z8/P//////+IiIj/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/QEBA//////gAAAAsAAAAGwAAAA0AAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADNzc0O/Pz8jv39/cb39/eb+vr6woiIiP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP9AQED/////+AAAACkAAAAYAAAACwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAEAAAACQAAABL5+fmyiIiI/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/0ZGRv/////zAAAAIwAAABQAAAAJAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAADPr6+rCIiIj/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/p6en//n5+cEAAAAbAAAADwAAAAYAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAL+/v7sIiIiP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8CAgL/JiYm/52dnf/////y1NTUQAAAABEAAAAJAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAv7+/uwiIiI/wAAAP8AAAD/Kioq/2JiYv+SkpL/wsLC//Pz8////////Pz8y9zc3D4AAAAPAAAACQAAAAQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAACvv7+6+IiIj/AAAA/wAAAP/Hx8f//Pz85/X19bXv7++J5eXlVr+/vyIAAAAOAAAACgAAAAYAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAK+/v7r4iIiP8AAAD/AAAA/8fHx//j4+OHAAAAKAAAABoAAAAPAAAACAAAAAUAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAj8/PyuiIiI/wAAAP8AAAD/x8fH/+bm5oMAAAAgAAAAEgAAAAgAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABvz8/KuNjY3/AAAA/wAAAP/Nzc3/6urqewAAABgAAAANAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE+vr6cOXl5f9LS0v/aGho//7+/v3V1dVCAAAAEQAAAAgAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKdnZ0I/Pz8lv////T////m8/PzagAAAA8AAAAJAAAABAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////////////////4B///4AH//8AA//+AAH//AAA//gAAP/wAAB/8AAAf/AAAH/wAAB/8AAAf/AAAH/wAAB/8AAAf/AAAH/wAAB//AAAf/wAAP/8AAD//AAB//wAB//8AD///AB///4Af//+AH//8=\";\n","export const walrosPortalSilhouetteUrl = new URL(\n \"./assets/walros-portal-silhouette.svg\",\n import.meta.url,\n).href;\n\nexport const walrosLogoChromeUrl = new URL(\n \"./assets/walros-logo-chrome.png\",\n import.meta.url,\n).href;\n\nexport const walrosWordmarkLightUrl = new URL(\n \"./assets/walros-wordmark-light.png\",\n import.meta.url,\n).href;\n\nexport const walrosWordmarkDarkUrl = new URL(\n \"./assets/walros-wordmark-dark.png\",\n import.meta.url,\n).href;\n\nexport const walrosThemeGlitchSoundUrl = new URL(\n \"./assets/walros-theme-glitch.mp3\",\n import.meta.url,\n).href;\n","import type { ImgHTMLAttributes } from \"react\";\nimport { walrosLogoChromeUrl } from \"../assets\";\n\nexport type WalrosLogoProps = Omit<\n ImgHTMLAttributes<HTMLImageElement>,\n \"src\"\n>;\n\nexport function WalrosLogo({\n alt = \"WalrOS\",\n draggable = false,\n ...props\n}: WalrosLogoProps) {\n return (\n <img\n src={walrosLogoChromeUrl}\n alt={alt}\n draggable={draggable}\n {...props}\n />\n );\n}\n\nexport default WalrosLogo;\n","import type { ImgHTMLAttributes } from \"react\";\nimport {\n walrosWordmarkDarkUrl,\n walrosWordmarkLightUrl,\n} from \"../assets\";\n\nexport type WalrosWordmarkProps = Omit<\n ImgHTMLAttributes<HTMLImageElement>,\n \"src\"\n> & {\n variant?: \"light\" | \"dark\";\n};\n\nexport function WalrosWordmark({\n variant = \"light\",\n alt = \"WalrOS\",\n draggable = false,\n ...props\n}: WalrosWordmarkProps) {\n const src =\n variant === \"dark\"\n ? walrosWordmarkDarkUrl\n : walrosWordmarkLightUrl;\n\n return (\n <img\n src={src}\n alt={alt}\n draggable={draggable}\n {...props}\n />\n );\n}\n\nexport default WalrosWordmark;\n","import {\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport type { RefObject } from \"react\";\nimport { walrosThemeGlitchSoundUrl } from \"../assets\";\n\nexport type WalrosTheme = \"light\" | \"dark\";\nexport type WalrosThemeMode = \"body\" | \"viewport\";\n\nexport type WalrosThemeShakeTarget =\n | HTMLElement\n | RefObject<HTMLElement | null>\n | null\n | undefined;\n\nexport type UseWalrosThemeOptions = {\n storageKey?: string;\n defaultTheme?: WalrosTheme;\n useSystemPreference?: boolean;\n swapDelay?: number;\n totalDuration?: number;\n /** Set to false to disable audio, or provide a custom sound URL. */\n soundUrl?: string | false;\n /** Playback volume from 0 to 1. Defaults to the WalrOS site mix. */\n soundVolume?: number;\n applyTheme?: (theme: WalrosTheme) => void;\n\n /**\n * `body` reproduce el comportamiento original de WalrOS Forum.\n * `viewport` bloquea el scroll y sacude solo los elementos indicados,\n * recomendado para parallax, sticky y GSAP ScrollTrigger.\n */\n mode?: WalrosThemeMode;\n\n /** Elementos que recibirán el shake cuando mode=\"viewport\". */\n shakeTargets?: readonly WalrosThemeShakeTarget[];\n\n /**\n * En modo viewport se activa por defecto. Mantiene scrollX/scrollY estables\n * con requestAnimationFrame sin usar position: fixed en el body.\n */\n lockScroll?: boolean;\n\n /** Se ejecuta después de restaurar el scroll; útil para ScrollTrigger.update(). */\n onAfterUnlock?: () => void;\n};\n\nexport type UseWalrosThemeResult = {\n theme: WalrosTheme;\n isDark: boolean;\n mounted: boolean;\n glitching: boolean;\n toggleTheme: () => void;\n setTheme: (theme: WalrosTheme) => void;\n};\n\ntype ViewportLockState = {\n scrollX: number;\n scrollY: number;\n rafId: number;\n active: boolean;\n bodyOverflow: string;\n htmlOverflow: string;\n htmlOverscrollBehavior: string;\n};\n\nconst GLITCH_BASE_CLASS = \"walros-theme-glitch-page\";\nconst GLITCH_BODY_CLASS = \"walros-theme-glitch-page--body\";\nconst GLITCH_VIEWPORT_CLASS = \"walros-theme-glitch-page--viewport\";\nconst GLITCH_LOCK_CLASS = \"walros-theme-glitch-lock\";\n\nfunction defaultApplyTheme(theme: WalrosTheme) {\n if (typeof document === \"undefined\") return;\n\n const root = document.documentElement;\n root.classList.toggle(\"dark\", theme === \"dark\");\n root.style.colorScheme = theme;\n}\n\nfunction readInitialTheme(\n storageKey: string,\n defaultTheme: WalrosTheme,\n useSystemPreference: boolean,\n): WalrosTheme {\n if (typeof window === \"undefined\") return defaultTheme;\n\n try {\n const stored = window.localStorage.getItem(storageKey);\n if (stored === \"light\" || stored === \"dark\") return stored;\n } catch {\n // localStorage puede estar bloqueado en modo privado.\n }\n\n if (\n useSystemPreference &&\n window.matchMedia?.(\"(prefers-color-scheme: dark)\").matches\n ) {\n return \"dark\";\n }\n\n return defaultTheme;\n}\n\nfunction resolveShakeTargets(\n targets: readonly WalrosThemeShakeTarget[],\n): HTMLElement[] {\n const resolved = new Set<HTMLElement>();\n\n for (const target of targets) {\n if (!target) continue;\n\n const element =\n typeof target === \"object\" && \"current\" in target\n ? target.current\n : target;\n\n if (element) resolved.add(element);\n }\n\n return [...resolved];\n}\n\nexport function useWalrosTheme({\n storageKey = \"walros-theme\",\n defaultTheme = \"light\",\n useSystemPreference = false,\n swapDelay = 610,\n totalDuration = 1500,\n soundUrl = walrosThemeGlitchSoundUrl,\n soundVolume = 0.52,\n applyTheme = defaultApplyTheme,\n mode = \"body\",\n shakeTargets = [],\n lockScroll,\n onAfterUnlock,\n}: UseWalrosThemeOptions = {}): UseWalrosThemeResult {\n const [theme, setThemeState] = useState<WalrosTheme>(() =>\n readInitialTheme(storageKey, defaultTheme, useSystemPreference),\n );\n const [mounted, setMounted] = useState(false);\n const [glitching, setGlitching] = useState(false);\n\n const themeRef = useRef(theme);\n const glitchingRef = useRef(false);\n const swapTimerRef = useRef<number | null>(null);\n const cleanupTimerRef = useRef<number | null>(null);\n const applyThemeRef = useRef(applyTheme);\n const modeRef = useRef(mode);\n const shakeTargetsRef = useRef(shakeTargets);\n const lockScrollRef = useRef(lockScroll);\n const onAfterUnlockRef = useRef(onAfterUnlock);\n const activeTargetsRef = useRef<HTMLElement[]>([]);\n const viewportLockRef = useRef<ViewportLockState | null>(null);\n const soundRef = useRef<HTMLAudioElement | null>(null);\n const soundUrlRef = useRef(soundUrl);\n const soundVolumeRef = useRef(soundVolume);\n\n themeRef.current = theme;\n applyThemeRef.current = applyTheme;\n modeRef.current = mode;\n shakeTargetsRef.current = shakeTargets;\n lockScrollRef.current = lockScroll;\n onAfterUnlockRef.current = onAfterUnlock;\n soundUrlRef.current = soundUrl;\n soundVolumeRef.current = soundVolume;\n\n const playThemeSound = useCallback(() => {\n if (typeof window === \"undefined\" || !soundUrlRef.current) return;\n\n try {\n if (!soundRef.current || soundRef.current.src !== new URL(soundUrlRef.current, document.baseURI).href) {\n soundRef.current?.pause();\n soundRef.current = new Audio(soundUrlRef.current);\n soundRef.current.preload = \"auto\";\n }\n const audio = soundRef.current;\n audio.volume = Math.max(0, Math.min(1, soundVolumeRef.current));\n audio.currentTime = 0;\n void audio.play().catch(() => {\n // Browsers may block sound; the theme animation still continues.\n });\n } catch {\n // Audio support is optional and must not block the theme change.\n }\n }, []);\n\n const persistTheme = useCallback(\n (nextTheme: WalrosTheme) => {\n applyThemeRef.current(nextTheme);\n setThemeState(nextTheme);\n themeRef.current = nextTheme;\n\n try {\n window.localStorage.setItem(storageKey, nextTheme);\n } catch {\n // El cambio debe funcionar aunque localStorage falle.\n }\n },\n [storageKey],\n );\n\n useEffect(() => {\n const initialTheme = readInitialTheme(\n storageKey,\n defaultTheme,\n useSystemPreference,\n );\n\n themeRef.current = initialTheme;\n setThemeState(initialTheme);\n applyThemeRef.current(initialTheme);\n setMounted(true);\n }, [defaultTheme, storageKey, useSystemPreference]);\n\n const clearTimers = useCallback(() => {\n if (swapTimerRef.current !== null) {\n window.clearTimeout(swapTimerRef.current);\n swapTimerRef.current = null;\n }\n\n if (cleanupTimerRef.current !== null) {\n window.clearTimeout(cleanupTimerRef.current);\n cleanupTimerRef.current = null;\n }\n }, []);\n\n const lockViewport = useCallback(() => {\n if (\n typeof window === \"undefined\" ||\n typeof document === \"undefined\" ||\n viewportLockRef.current\n ) {\n return;\n }\n\n const body = document.body;\n const html = document.documentElement;\n const lockState: ViewportLockState = {\n scrollX: window.scrollX,\n scrollY: window.scrollY,\n rafId: 0,\n active: true,\n bodyOverflow: body.style.overflow,\n htmlOverflow: html.style.overflow,\n htmlOverscrollBehavior: html.style.overscrollBehavior,\n };\n\n viewportLockRef.current = lockState;\n\n const keepScrollStable = () => {\n if (!lockState.active) return;\n window.scrollTo(lockState.scrollX, lockState.scrollY);\n lockState.rafId = window.requestAnimationFrame(keepScrollStable);\n };\n\n html.classList.add(GLITCH_LOCK_CLASS);\n html.style.overflow = \"hidden\";\n html.style.overscrollBehavior = \"none\";\n body.style.overflow = \"hidden\";\n lockState.rafId = window.requestAnimationFrame(keepScrollStable);\n }, []);\n\n const unlockViewport = useCallback((runCallback: boolean) => {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n return;\n }\n\n const lockState = viewportLockRef.current;\n if (!lockState) return;\n\n lockState.active = false;\n window.cancelAnimationFrame(lockState.rafId);\n\n const body = document.body;\n const html = document.documentElement;\n body.style.overflow = lockState.bodyOverflow;\n html.style.overflow = lockState.htmlOverflow;\n html.style.overscrollBehavior = lockState.htmlOverscrollBehavior;\n html.classList.remove(GLITCH_LOCK_CLASS);\n\n viewportLockRef.current = null;\n window.scrollTo(lockState.scrollX, lockState.scrollY);\n\n if (runCallback) {\n window.requestAnimationFrame(() => {\n onAfterUnlockRef.current?.();\n });\n }\n }, []);\n\n const removeShakeClasses = useCallback(() => {\n for (const target of activeTargetsRef.current) {\n target.classList.remove(\n GLITCH_BASE_CLASS,\n GLITCH_BODY_CLASS,\n GLITCH_VIEWPORT_CLASS,\n );\n target.style.removeProperty(\"--walros-glitch-origin-y\");\n }\n\n activeTargetsRef.current = [];\n }, []);\n\n const finishGlitch = useCallback(() => {\n if (soundRef.current) {\n soundRef.current.pause();\n soundRef.current.currentTime = 0;\n }\n removeShakeClasses();\n unlockViewport(true);\n glitchingRef.current = false;\n setGlitching(false);\n }, [removeShakeClasses, unlockViewport]);\n\n const setTheme = useCallback(\n (nextTheme: WalrosTheme) => {\n if (glitchingRef.current) return;\n persistTheme(nextTheme);\n },\n [persistTheme],\n );\n\n const toggleTheme = useCallback(() => {\n if (\n typeof window === \"undefined\" ||\n typeof document === \"undefined\" ||\n glitchingRef.current\n ) {\n return;\n }\n\n playThemeSound();\n\n const currentMode = modeRef.current;\n const shouldLockScroll =\n lockScrollRef.current ?? currentMode === \"viewport\";\n\n if (currentMode === \"viewport\" && shouldLockScroll) {\n lockViewport();\n }\n\n const targets =\n currentMode === \"body\"\n ? [document.body]\n : resolveShakeTargets(shakeTargetsRef.current);\n\n const modeClass =\n currentMode === \"body\"\n ? GLITCH_BODY_CLASS\n : GLITCH_VIEWPORT_CLASS;\n\n for (const target of targets) {\n target.style.setProperty(\n \"--walros-glitch-origin-y\",\n currentMode === \"body\"\n ? `${window.scrollY + window.innerHeight / 2}px`\n : \"50%\",\n );\n target.classList.add(GLITCH_BASE_CLASS, modeClass);\n }\n\n activeTargetsRef.current = targets;\n glitchingRef.current = true;\n setGlitching(true);\n\n const reducedMotion = window.matchMedia?.(\n \"(prefers-reduced-motion: reduce)\",\n ).matches;\n\n const nextTheme: WalrosTheme =\n themeRef.current === \"dark\" ? \"light\" : \"dark\";\n\n const effectiveSwapDelay = reducedMotion\n ? 75\n : Math.max(0, swapDelay);\n const effectiveDuration = reducedMotion\n ? 150\n : Math.max(effectiveSwapDelay, totalDuration);\n\n swapTimerRef.current = window.setTimeout(() => {\n persistTheme(nextTheme);\n swapTimerRef.current = null;\n }, effectiveSwapDelay);\n\n cleanupTimerRef.current = window.setTimeout(() => {\n cleanupTimerRef.current = null;\n finishGlitch();\n }, effectiveDuration);\n }, [finishGlitch, lockViewport, persistTheme, playThemeSound, swapDelay, totalDuration]);\n\n useEffect(() => {\n return () => {\n clearTimers();\n removeShakeClasses();\n unlockViewport(false);\n soundRef.current?.pause();\n if (soundRef.current) soundRef.current.currentTime = 0;\n soundRef.current = null;\n };\n }, [clearTimers, removeShakeClasses, unlockViewport]);\n\n return {\n theme,\n isDark: theme === \"dark\",\n mounted,\n glitching,\n toggleTheme,\n setTheme,\n };\n}\n\nexport default useWalrosTheme;\n"],"mappings":"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","names":["useState","useLayoutEffect","useState","jsx","useState","createPortal","jsx","jsxs","jsx","createPortal","useRef","Fragment","jsx","jsxs","useRef","jsx","jsx","useEffect","useRef","useState","useState","useRef","useEffect"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/WalrosPortalTransition.tsx","../src/components/Walros3DPortalTransition.tsx","../src/portalSilhouette.ts","../src/components/useOverlayHost.ts","../src/components/WalrosThemeTransition.tsx","../src/components/WalrosThemeGlitch.tsx","../src/components/DirectionalCursor.tsx","../src/handCursor.ts","../src/assets.ts","../src/components/WalrosLogo.tsx","../src/components/WalrosWordmark.tsx","../src/components/WalrosSeasonalBackground.tsx","../src/hooks/useWalrosTheme.ts"],"sourcesContent":["import { useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { Walros3DPortalTransition, type PortalOrigin } from \"./Walros3DPortalTransition\";\nimport { useOverlayHost } from \"./useOverlayHost\";\n\nexport type WalrosPortalTransitionProps = {\n duration?: number;\n onComplete?: () => void;\n backgroundColor?: string;\n enabled?: boolean;\n storageMode?: \"always\" | \"session\" | \"once\";\n storageKey?: string;\n zIndex?: number;\n /** Projected bounds of an existing 3D logo, as on walros.org. */\n origin?: PortalOrigin;\n};\n\nfunction defaultOrigin(): PortalOrigin {\n if (typeof window === \"undefined\") return { centerX: 0, centerY: 0, width: 70, height: 90 };\n return {\n centerX: window.innerWidth / 2,\n centerY: window.innerHeight * .45,\n width: 70,\n height: 90,\n };\n}\n\nfunction getStorage(mode: \"session\" | \"once\"): Storage | null {\n if (typeof window === \"undefined\") return null;\n try {\n return mode === \"session\" ? window.sessionStorage : window.localStorage;\n } catch {\n return null;\n }\n}\n\nfunction shouldRun(enabled: boolean, mode: \"always\" | \"session\" | \"once\", key: string) {\n if (!enabled) return false;\n if (mode === \"always\") return true;\n try {\n return getStorage(mode)?.getItem(key) == null;\n } catch {\n return true;\n }\n}\n\n/** 900 ms entrance: the walrus silhouette reveals the page from the centre. */\nexport function WalrosPortalTransition({\n duration = 900,\n onComplete,\n backgroundColor = \"#000\",\n enabled = true,\n storageMode = \"always\",\n storageKey = \"walros-portal-seen\",\n zIndex = 10000,\n origin,\n}: WalrosPortalTransitionProps) {\n const [run] = useState(() => shouldRun(enabled, storageMode, storageKey));\n const [complete, setComplete] = useState(false);\n const [initialOrigin] = useState(() => origin ?? defaultOrigin());\n const host = useOverlayHost(zIndex);\n\n if (!host || !enabled || !run || complete) return null;\n\n return createPortal(\n <Walros3DPortalTransition\n origin={initialOrigin}\n duration={duration}\n backgroundColor={backgroundColor}\n zIndex={1}\n lockScroll\n onComplete={() => {\n if (storageMode !== \"always\") {\n try { getStorage(storageMode)?.setItem(storageKey, \"1\"); } catch { /* Storage is optional. */ }\n }\n setComplete(true);\n onComplete?.();\n }}\n />,\n host,\n );\n}\n\nexport default WalrosPortalTransition;\n","import { useId, useLayoutEffect, useRef, useState } from \"react\";\nimport gsap from \"gsap\";\nimport { walrosPortalPaths } from \"../portalSilhouette\";\n\nexport type PortalOrigin = { centerX: number; centerY: number; width: number; height: number };\n\nexport type Walros3DPortalTransitionProps = {\n origin: PortalOrigin;\n onComplete?: () => void;\n duration?: number;\n backgroundColor?: string;\n zIndex?: number;\n lockScroll?: boolean;\n};\n\nconst SILHOUETTE_VIEWBOX = 1254;\nconst FOCUS_X = 626;\nconst FOCUS_Y = 333;\nconst PORTAL_RADIUS = 190;\n\n/** The stable portal used by ui 0.3.4: a centred silhouette that only scales. */\nexport function Walros3DPortalTransition({\n onComplete,\n duration = 900,\n backgroundColor = \"#000\",\n zIndex = 10001,\n lockScroll = true,\n}: Walros3DPortalTransitionProps) {\n const [visible, setVisible] = useState(true);\n const [viewport] = useState(() => ({\n width: typeof window === \"undefined\" ? 0 : window.innerWidth,\n height: typeof window === \"undefined\" ? 0 : window.innerHeight,\n }));\n const overlay = useRef<HTMLDivElement>(null);\n const maskScale = useRef<SVGGElement>(null);\n const completeRef = useRef(onComplete);\n completeRef.current = onComplete;\n const maskId = `walros-portal-mask-${useId().replace(/:/g, \"_\")}`;\n\n useLayoutEffect(() => {\n if (!visible || viewport.width <= 0 || viewport.height <= 0 || !overlay.current || !maskScale.current) return;\n const previousOverflow = document.body.style.overflow;\n if (lockScroll) document.body.style.overflow = \"hidden\";\n\n const initialPixels = Math.min(180, Math.max(120, viewport.width * 0.12));\n const initialScale = initialPixels / SILHOUETTE_VIEWBOX;\n const finalScale = (Math.hypot(viewport.width, viewport.height) / 2 + 80) / PORTAL_RADIUS * 1.15;\n const visualCenter = SILHOUETTE_VIEWBOX / 2;\n const portalCenterX = viewport.width / 2 - (visualCenter - FOCUS_X) * initialScale;\n const portalCenterY = viewport.height / 2 - (visualCenter - FOCUS_Y) * initialScale;\n const total = duration / 1000;\n\n gsap.set(maskScale.current, { scale: initialScale, svgOrigin: \"0 0\" });\n gsap.set(overlay.current, { opacity: 1 });\n const finish = () => {\n if (lockScroll) document.body.style.overflow = previousOverflow;\n setVisible(false);\n completeRef.current?.();\n };\n const timeline = gsap.timeline({ onComplete: finish });\n if (window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches) {\n timeline.to(overlay.current, { opacity: 0, duration: 0.15, ease: \"power1.out\" });\n } else {\n timeline\n .to(maskScale.current, { scale: initialScale * 1.4, duration: total * 0.15, ease: \"power2.out\" }, 0)\n .to(maskScale.current, { scale: finalScale, duration: total * 0.85, ease: \"power2.in\" }, total * 0.15)\n .to(overlay.current, { opacity: 0, duration: total * 0.1, ease: \"power2.out\" }, total * 0.9);\n }\n return () => {\n timeline.kill();\n if (lockScroll) document.body.style.overflow = previousOverflow;\n };\n }, [duration, lockScroll, viewport, visible]);\n\n if (!visible) return null;\n const initialPixels = Math.min(180, Math.max(120, viewport.width * 0.12));\n const initialScale = initialPixels / SILHOUETTE_VIEWBOX;\n const visualCenter = SILHOUETTE_VIEWBOX / 2;\n const portalCenterX = viewport.width / 2 - (visualCenter - FOCUS_X) * initialScale;\n const portalCenterY = viewport.height / 2 - (visualCenter - FOCUS_Y) * initialScale;\n\n return <div ref={overlay} className=\"walros-3d-portal\" aria-hidden=\"true\" style={{ position: \"fixed\", inset: 0, width: \"100vw\", height: \"100dvh\", overflow: \"hidden\", pointerEvents: \"none\", zIndex, backgroundColor: viewport.width > 0 ? \"transparent\" : backgroundColor }}>\n <svg width=\"100%\" height=\"100%\" viewBox={`0 0 ${viewport.width} ${viewport.height}`} preserveAspectRatio=\"none\" style={{ display: \"block\"}}>\n <defs><mask id={maskId} maskUnits=\"userSpaceOnUse\" x=\"0\" y=\"0\" width={viewport.width} height={viewport.height}>\n <rect width={viewport.width} height={viewport.height} fill=\"white\" />\n <g transform={`translate(${portalCenterX} ${portalCenterY})`}>\n <g ref={maskScale} transform={`scale(${initialScale})`}>\n <g transform={`translate(${-FOCUS_X} ${-FOCUS_Y})`} fill=\"black\">\n {walrosPortalPaths.map((path, index) => <path d={path} key={index} />)}\n </g>\n </g>\n </g>\n </mask></defs>\n <rect width={viewport.width} height={viewport.height} fill={backgroundColor} mask={`url(#${maskId})`} />\n </svg>\n </div>;\n}\n","/* Exact silhouette used by the walros.org portal mask. */\r\nexport const walrosPortalPaths = [\r\n \"M 244.00 354.00 C 240.50 377.67, 240.17 413.67, 242.00 434.00 C 243.83 454.33, 249.50 464.50, 255.00 476.00 C 260.50 487.50, 268.50 496.00, 275.00 503.00 C 281.50 510.00, 287.17 513.67, 294.00 518.00 C 300.83 522.33, 306.00 525.67, 316.00 529.00 C 326.00 532.33, 336.33 536.67, 354.00 538.00 C 371.67 539.33, 397.83 540.83, 422.00 537.00 C 446.17 533.17, 474.17 525.33, 499.00 515.00 C 523.83 504.67, 550.00 489.33, 571.00 475.00 C 592.00 460.67, 615.00 436.50, 625.00 429.00 C 635.00 421.50, 623.67 424.00, 631.00 430.00 C 638.33 436.00, 656.67 454.83, 669.00 465.00 C 681.33 475.17, 690.00 482.17, 705.00 491.00 C 720.00 499.83, 743.67 511.50, 759.00 518.00 C 774.33 524.50, 784.00 526.83, 797.00 530.00 C 810.00 533.17, 820.00 535.83, 837.00 537.00 C 854.00 538.17, 881.17 539.00, 899.00 537.00 C 916.83 535.00, 932.00 530.00, 944.00 525.00 C 956.00 520.00, 962.00 516.17, 971.00 507.00 C 980.00 497.83, 991.67 482.83, 998.00 470.00 C 1004.33 457.17, 1007.17 446.33, 1009.00 430.00 C 1010.83 413.67, 1010.83 390.50, 1009.00 372.00 C 1007.17 353.50, 1003.83 337.17, 998.00 319.00 C 992.17 300.83, 983.67 280.17, 974.00 263.00 C 964.33 245.83, 952.00 229.67, 940.00 216.00 C 928.00 202.33, 917.17 192.00, 902.00 181.00 C 886.83 170.00, 866.50 158.17, 849.00 150.00 C 831.50 141.83, 816.67 137.00, 797.00 132.00 C 777.33 127.00, 756.67 122.83, 731.00 120.00 C 705.33 117.17, 673.67 115.33, 643.00 115.00 C 612.33 114.67, 575.67 115.67, 547.00 118.00 C 518.33 120.33, 496.17 123.00, 471.00 129.00 C 445.83 135.00, 418.33 143.50, 396.00 154.00 C 373.67 164.50, 353.50 178.50, 337.00 192.00 C 320.50 205.50, 309.33 218.33, 297.00 235.00 C 284.67 251.67, 271.83 272.17, 263.00 292.00 C 254.17 311.83, 247.50 330.33, 244.00 354.00 Z\",\r\n \"M 289.00 536.00 C 283.17 535.50, 284.83 533.00, 284.00 544.00 C 283.17 555.00, 282.67 578.67, 284.00 602.00 C 285.33 625.33, 287.00 651.83, 292.00 684.00 C 297.00 716.17, 306.33 763.50, 314.00 795.00 C 321.67 826.50, 328.67 847.17, 338.00 873.00 C 347.33 898.83, 357.00 923.67, 370.00 950.00 C 383.00 976.33, 399.67 1006.00, 416.00 1031.00 C 432.33 1056.00, 455.33 1084.50, 468.00 1100.00 C 480.67 1115.50, 486.17 1119.33, 492.00 1124.00 C 497.83 1128.67, 500.67 1127.67, 503.00 1128.00 C 505.33 1128.33, 505.50 1127.50, 506.00 1126.00 C 506.50 1124.50, 510.33 1132.00, 506.00 1119.00 C 501.67 1106.00, 488.17 1073.83, 480.00 1048.00 C 471.83 1022.17, 462.67 987.67, 457.00 964.00 C 451.33 940.33, 449.17 927.33, 446.00 906.00 C 442.83 884.67, 439.50 865.00, 438.00 836.00 C 436.50 807.00, 436.50 758.33, 437.00 732.00 C 437.50 705.67, 439.00 696.33, 441.00 678.00 C 443.00 659.67, 444.83 644.00, 449.00 622.00 C 453.17 600.00, 464.50 559.00, 466.00 546.00 C 467.50 533.00, 468.67 542.50, 458.00 544.00 C 447.33 545.50, 418.33 553.17, 402.00 555.00 C 385.67 556.83, 373.83 556.33, 360.00 555.00 C 346.17 553.67, 330.83 550.17, 319.00 547.00 C 307.17 543.83, 294.83 536.50, 289.00 536.00 Z\",\r\n \"M 961.00 537.00 C 948.50 539.17, 907.83 552.00, 889.00 555.00 C 870.17 558.00, 864.17 557.00, 848.00 555.00 C 831.83 553.00, 802.83 545.00, 792.00 543.00 C 781.17 541.00, 784.83 542.50, 783.00 543.00 C 781.17 543.50, 778.67 533.83, 781.00 546.00 C 783.33 558.17, 792.67 592.33, 797.00 616.00 C 801.33 639.67, 804.83 668.83, 807.00 688.00 C 809.17 707.17, 809.67 709.00, 810.00 731.00 C 810.33 753.00, 810.50 792.83, 809.00 820.00 C 807.50 847.17, 804.50 870.50, 801.00 894.00 C 797.50 917.50, 794.00 936.17, 788.00 961.00 C 782.00 985.83, 773.50 1016.67, 765.00 1043.00 C 756.50 1069.33, 741.33 1104.83, 737.00 1119.00 C 732.67 1133.17, 736.67 1127.17, 739.00 1128.00 C 741.33 1128.83, 745.83 1127.83, 751.00 1124.00 C 756.17 1120.17, 757.33 1120.50, 770.00 1105.00 C 782.67 1089.50, 811.33 1053.50, 827.00 1031.00 C 842.67 1008.50, 851.17 995.00, 864.00 970.00 C 876.83 945.00, 892.83 910.00, 904.00 881.00 C 915.17 852.00, 923.00 826.67, 931.00 796.00 C 939.00 765.33, 946.67 728.67, 952.00 697.00 C 957.33 665.33, 961.00 631.83, 963.00 606.00 C 965.00 580.17, 964.33 553.50, 964.00 542.00 C 963.67 530.50, 973.50 534.83, 961.00 537.00 Z\",\r\n] as const;\r\n","import { useLayoutEffect, useState } from \"react\";\n\n/** Keep fixed overlays outside an animated body, which would otherwise\n * become their containing block and displace the portal during the glitch. */\nexport function useOverlayHost(zIndex: number) {\n const [host] = useState<HTMLDivElement | null>(() =>\n typeof document === \"undefined\" ? null : document.createElement(\"div\"),\n );\n\n useLayoutEffect(() => {\n if (!host) return;\n host.dataset.walrosOverlayRoot = \"\";\n host.style.position = \"fixed\";\n host.style.inset = \"0\";\n host.style.pointerEvents = \"none\";\n document.documentElement.appendChild(host);\n return () => host.remove();\n }, [host]);\n\n useLayoutEffect(() => {\n if (host) host.style.zIndex = String(zIndex);\n }, [host, zIndex]);\n\n return host;\n}\n","import { createPortal } from \"react-dom\";\nimport { WalrosThemeGlitch } from \"./WalrosThemeGlitch\";\nimport { useOverlayHost } from \"./useOverlayHost\";\n\nexport type WalrosThemeTransitionProps = {\n /** Pass the `glitching` value returned by `useWalrosTheme`. */\n active: boolean;\n /** @deprecated The theme change has no portal; retained for source compatibility. */\n portalDuration?: number;\n /** @deprecated The theme change has no logo; retained for source compatibility. */\n logoUrl?: string;\n zIndex?: number;\n};\n\n/** The walros.org theme effect is a shake and glitch, without an intro logo. */\nexport function WalrosThemeTransition({\n active,\n zIndex = 10000,\n}: WalrosThemeTransitionProps) {\n const host = useOverlayHost(zIndex);\n if (!host) return null;\n\n return createPortal(\n <WalrosThemeGlitch active={active} zIndex={1} />,\n host,\n );\n}\n","import type { CSSProperties } from \"react\";\n\nexport type WalrosThemeGlitchProps = {\n active: boolean;\n zIndex?: number;\n className?: string;\n style?: CSSProperties;\n};\n\nconst GLITCH_STYLES = `\n.walros-theme-glitch-root {\n position: fixed;\n inset: 0;\n z-index: 9998;\n pointer-events: none;\n overflow: hidden;\n visibility: hidden;\n}\n.walros-theme-glitch-root.is-active {\n visibility: visible;\n}\n.walros-theme-glitch-root::before,\n.walros-theme-glitch-root::after {\n content: \"\";\n position: absolute;\n inset: 0;\n}\n.walros-theme-glitch-root::before {\n background: rgba(0, 0, 0, .82);\n mix-blend-mode: normal;\n animation: walros-glitch-flash 1500ms steps(1, end) both;\n}\n.walros-theme-glitch-root::after {\n background: repeating-linear-gradient(0deg, transparent 0 3px, rgba(255,255,255,.09) 3px 4px);\n animation: walros-glitch-scan 90ms steps(2, end) 16 both;\n}\n.walros-theme-glitch-band {\n position: absolute;\n left: -12%;\n width: 124%;\n opacity: 0;\n}\n.walros-theme-glitch-band:nth-child(1) { top: 12%; height: 4%; background: #eaf6ff; animation: walros-glitch-band-a 1500ms steps(1, end) both; }\n.walros-theme-glitch-band:nth-child(2) { top: 36%; height: 11%; background: #020407; animation: walros-glitch-band-b 1500ms steps(1, end) both; }\n.walros-theme-glitch-band:nth-child(3) { top: 62%; height: 2%; background: #7faddb; animation: walros-glitch-band-c 1500ms steps(1, end) both; }\n.walros-theme-glitch-band:nth-child(4) { top: 79%; height: 8%; background: #f4f6f5; animation: walros-glitch-band-d 1500ms steps(1, end) both; }\n\n@keyframes walros-glitch-scan {\n 0% { transform: translateY(-2px); opacity: .25; }\n 50% { transform: translateY(2px); opacity: .08; }\n 100% { transform: translateY(0); opacity: .2; }\n}\n@keyframes walros-glitch-flash {\n 0%, 17%, 22%, 34%, 39%, 54%, 59%, 73%, 78%, 100% { opacity: 0; }\n 18%, 21% { opacity: .18; }\n 35%, 38% { opacity: .48; }\n 55%, 58% { opacity: .82; }\n 74%, 77% { opacity: .22; }\n}\n@keyframes walros-glitch-band-a {\n 0%, 8%, 18%, 42%, 51%, 73%, 82%, 100% { opacity: 0; transform: translateX(0); }\n 9%, 17% { opacity: .55; transform: translateX(-7%); }\n 43%, 50% { opacity: .82; transform: translateX(10%); }\n 74%, 81% { opacity: .32; transform: translateX(-4%); }\n}\n@keyframes walros-glitch-band-b {\n 0%, 20%, 27%, 46%, 55%, 64%, 71%, 100% { opacity: 0; transform: translateX(0); }\n 21%, 26% { opacity: .72; transform: translateX(9%); }\n 47%, 54% { opacity: .9; transform: translateX(-6%); }\n 65%, 70% { opacity: .5; transform: translateX(4%); }\n}\n@keyframes walros-glitch-band-c {\n 0%, 13%, 23%, 39%, 48%, 67%, 76%, 100% { opacity: 0; transform: translateX(0); }\n 14%, 22% { opacity: .9; transform: translateX(5%); }\n 40%, 47% { opacity: .65; transform: translateX(-11%); }\n 68%, 75% { opacity: .75; transform: translateX(8%); }\n}\n@keyframes walros-glitch-band-d {\n 0%, 29%, 38%, 57%, 65%, 85%, 93%, 100% { opacity: 0; transform: translateX(0); }\n 30%, 37% { opacity: .42; transform: translateX(-8%); }\n 58%, 64% { opacity: .7; transform: translateX(7%); }\n 86%, 92% { opacity: .25; transform: translateX(-3%); }\n}\n\n.walros-theme-glitch-lock {\n overscroll-behavior: none;\n}\n\n.walros-theme-glitch-page {\n will-change: transform, filter;\n}\n\n/* Comportamiento original de WalrOS Forum para páginas normales. */\n.walros-theme-glitch-page--body {\n animation: walros-glitch-page-body 1500ms steps(1, end) both;\n}\n\n@keyframes walros-glitch-page-body {\n 0%, 6%, 18%, 31%, 49%, 68%, 82%, 100% { transform: translate3d(0,0,0) scale(1); filter: none; }\n 7% { transform: translate3d(-18px,4px,0) scale(1.012); filter: contrast(1.5) saturate(.45); }\n 19% { transform: translate3d(26px,-7px,0) scale(1.02) skewX(-1.2deg); filter: contrast(1.9) saturate(1.6); }\n 32% { transform: translate3d(-9px,11px,0) scale(1.03); filter: invert(.12) contrast(2); }\n 50%, 57% { transform: translate3d(34px,-3px,0) scale(1.025); filter: grayscale(1) contrast(2.3); }\n 69% { transform: translate3d(-24px,5px,0) scale(1.016); filter: contrast(1.7) saturate(.2); }\n 83% { transform: translate3d(8px,-2px,0) scale(1.006); filter: contrast(1.35); }\n}\n\n/*\n * Modo seguro para parallax/sticky/ScrollTrigger.\n * El shake se aplica a una capa estable del viewport, nunca al scroll real.\n * El pequeño overscan evita descubrir bordes al desplazar la escena.\n */\n.walros-theme-glitch-page--viewport {\n transform-origin: 50% var(--walros-glitch-origin-y, 50%);\n animation: walros-glitch-page-viewport 1500ms steps(1, end) both;\n}\n\n@keyframes walros-glitch-page-viewport {\n 0%, 6%, 18%, 31%, 49%, 68%, 82%, 100% { transform: translate3d(0,0,0) scale(1.012); filter: none; }\n 7% { transform: translate3d(-18px,4px,0) scale(1.012); filter: contrast(1.5) saturate(.45); }\n 19% { transform: translate3d(26px,-7px,0) scale(1.02) skewX(-1.2deg); filter: contrast(1.9) saturate(1.6); }\n 32% { transform: translate3d(-9px,11px,0) scale(1.03); filter: invert(.12) contrast(2); }\n 50%, 57% { transform: translate3d(34px,-3px,0) scale(1.025); filter: grayscale(1) contrast(2.3); }\n 69% { transform: translate3d(-24px,5px,0) scale(1.016); filter: contrast(1.7) saturate(.2); }\n 83% { transform: translate3d(8px,-2px,0) scale(1.006); filter: contrast(1.35); }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .walros-theme-glitch-root::before,\n .walros-theme-glitch-root::after {\n animation: walros-glitch-reduced 150ms ease-out forwards;\n }\n\n .walros-theme-glitch-band {\n animation: none !important;\n }\n\n .walros-theme-glitch-page--body,\n .walros-theme-glitch-page--viewport {\n animation: none;\n }\n\n @keyframes walros-glitch-reduced {\n from { opacity: 0.35; }\n to { opacity: 0; }\n }\n}\n`;\n\nexport function WalrosThemeGlitch({\n active,\n zIndex = 9998,\n className,\n style,\n}: WalrosThemeGlitchProps) {\n return (\n <>\n <style>{GLITCH_STYLES}</style>\n {active ? (\n <div\n className={[\"walros-theme-glitch-root\", \"is-active\", className]\n .filter(Boolean)\n .join(\" \")}\n style={{ zIndex, ...style }}\n aria-hidden=\"true\"\n >\n <span className=\"walros-theme-glitch-band\" />\n <span className=\"walros-theme-glitch-band\" />\n <span className=\"walros-theme-glitch-band\" />\n <span className=\"walros-theme-glitch-band\" />\n </div>\n ) : null}\n </>\n );\n}\n\nexport default WalrosThemeGlitch;\n","import { useEffect, useRef } from \"react\";\nimport { walrosHandCursor } from \"../handCursor\";\n\r\nconst DESKTOP_CURSOR_QUERY = \"(min-width: 1024px) and (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference)\";\n\nconst CURSOR_STYLES = `\n.directional-cursor { position: fixed; top: 0; left: 0; z-index: 9999; width: 20px; height: 22px; opacity: 0; pointer-events: none; contain: layout style; will-change: transform; transition: opacity 100ms linear; }\n.directional-cursor.is-visible { opacity: 1; }\n.directional-cursor-shape { width: 20px; height: 22px; transform-origin: center center; will-change: transform; }\n.directional-cursor svg { display: block; width: 20px; height: 22px; }\n@media (min-width: 1024px) and (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {\n html.has-directional-cursor, html.has-directional-cursor * { cursor: none !important; }\n html.has-directional-cursor :is(textarea, [contenteditable=\"true\"], input:not([type]), input:is([type=\"text\"], [type=\"search\"], [type=\"email\"], [type=\"password\"], [type=\"url\"], [type=\"tel\"], [type=\"number\"])),\n html.has-directional-cursor [contenteditable=\"true\"] * { cursor: text !important; }\n html.has-directional-cursor :is(a, button, select, summary, [role=\"button\"], [role=\"link\"], [aria-haspopup=\"true\"], input[type=\"checkbox\"], input[type=\"radio\"], input[type=\"range\"]) {\n cursor: url(\"${walrosHandCursor}\") 8 2, pointer !important;\n }\n}\n`;\n\nconst TEXT_ENTRY_SELECTOR = 'textarea, [contenteditable=\"true\"], input:not([type]), input:is([type=\"text\"], [type=\"search\"], [type=\"email\"], [type=\"password\"], [type=\"url\"], [type=\"tel\"], [type=\"number\"])';\nconst INTERACTIVE_SELECTOR = 'a, button, select, summary, [role=\"button\"], [role=\"link\"], [aria-haspopup=\"true\"], input[type=\"checkbox\"], input[type=\"radio\"], input[type=\"range\"]';\n\r\nexport function DirectionalCursor() {\r\n const positionLayer = useRef<HTMLDivElement>(null);\r\n const directionLayer = useRef<HTMLDivElement>(null);\r\n\r\n useEffect(() => {\r\n const position = positionLayer.current;\r\n const direction = directionLayer.current;\r\n if (!position || !direction) return;\r\n\r\n const media = window.matchMedia(DESKTOP_CURSOR_QUERY);\r\n let active = false;\r\n let frame = 0;\r\n let moveFrame = 0;\r\n let scaleTimer = 0;\r\n let latestEvent: MouseEvent | null = null;\r\n let currentX = window.innerWidth / 2;\r\n let currentY = -60;\r\n let targetX = currentX;\r\n let targetY = currentY;\r\n let currentAngle = 0;\r\n let targetAngle = 0;\r\n let hasAngle = false;\r\n let currentScale = 1;\r\n let targetScale = 1;\r\n let lastX = currentX;\r\n let lastY = 0;\r\n\r\n const render = () => {\r\n currentX += (targetX - currentX) * 0.4;\r\n currentY += (targetY - currentY) * 0.4;\r\n const angleDelta = ((targetAngle - currentAngle + 540) % 360) - 180;\r\n currentAngle += angleDelta * 0.24;\r\n currentScale += (targetScale - currentScale) * 0.24;\r\n\r\n position.style.transform = `translate3d(${currentX}px, ${currentY}px, 0)`;\r\n direction.style.transform = `translate(-50%, -50%) rotate(${currentAngle}deg) scale(${currentScale})`;\r\n\r\n const unsettled = Math.abs(targetX - currentX) > 0.08\r\n || Math.abs(targetY - currentY) > 0.08\r\n || Math.abs(angleDelta) > 0.08\r\n || Math.abs(targetScale - currentScale) > 0.002;\r\n frame = unsettled ? window.requestAnimationFrame(render) : 0;\r\n };\r\n\r\n const requestRender = () => {\r\n if (!frame) frame = window.requestAnimationFrame(render);\r\n };\r\n\r\n const processMove = () => {\r\n moveFrame = 0;\r\n const event = latestEvent;\r\n if (!event) return;\r\n const deltaX = event.clientX - lastX;\r\n const deltaY = event.clientY - lastY;\r\n const distance = Math.hypot(deltaX, deltaY);\r\n targetX = event.clientX;\r\n targetY = event.clientY;\r\n // Text editing keeps the native I-beam; everything clickable uses only\n // the WalrOS cursor, never a second OS hand or arrow.\n const target = event.target instanceof Element ? event.target : null;\n const textEntry = target?.closest(TEXT_ENTRY_SELECTOR);\n const interactive = target?.closest(INTERACTIVE_SELECTOR);\n // Interactive controls use the supplied .cur hand. Hide the directional\n // cursor there so two pointers are never shown at once.\n position.classList.toggle(\"is-visible\", !textEntry && !interactive);\n\r\n if (distance > 1.25) {\r\n const rawAngle = Math.atan2(deltaY, deltaX) * (180 / Math.PI) + 90;\r\n const normalizedAngle = (rawAngle % 360 + 360) % 360;\r\n if (!hasAngle) {\r\n targetAngle = normalizedAngle;\r\n currentAngle = normalizedAngle;\r\n hasAngle = true;\r\n } else {\r\n targetAngle = normalizedAngle;\r\n }\r\n\r\n targetScale = 0.92;\r\n window.clearTimeout(scaleTimer);\r\n scaleTimer = window.setTimeout(() => {\r\n targetScale = 1;\r\n requestRender();\r\n }, 130);\r\n }\r\n\r\n lastX = event.clientX;\r\n lastY = event.clientY;\r\n requestRender();\r\n };\r\n\r\n const handleMouseMove = (event: MouseEvent) => {\r\n latestEvent = event;\r\n if (!moveFrame) moveFrame = window.requestAnimationFrame(processMove);\r\n };\r\n\r\n const activate = () => {\r\n if (active) return;\r\n active = true;\r\n document.documentElement.classList.add(\"has-directional-cursor\");\r\n window.addEventListener(\"mousemove\", handleMouseMove, { passive: true });\r\n };\r\n\r\n const deactivate = () => {\r\n if (!active) return;\r\n active = false;\r\n document.documentElement.classList.remove(\"has-directional-cursor\");\r\n position.classList.remove(\"is-visible\");\r\n window.removeEventListener(\"mousemove\", handleMouseMove);\r\n window.cancelAnimationFrame(frame);\r\n window.cancelAnimationFrame(moveFrame);\r\n window.clearTimeout(scaleTimer);\r\n frame = 0;\r\n moveFrame = 0;\r\n };\r\n\r\n const sync = () => {\r\n if (media.matches) activate();\r\n else deactivate();\r\n };\r\n media.addEventListener(\"change\", sync);\r\n sync();\r\n\r\n return () => {\r\n media.removeEventListener(\"change\", sync);\r\n deactivate();\r\n };\r\n }, []);\r\n\r\n return (\n <><style>{CURSOR_STYLES}</style><div ref={positionLayer} className=\"directional-cursor\" aria-hidden=\"true\">\n <div ref={directionLayer} className=\"directional-cursor-shape\">\r\n <svg width=\"50\" height=\"54\" viewBox=\"0 0 50 54\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <g filter=\"url(#walros-cursor-shadow)\">\r\n <path d=\"M42.6817 41.1495L27.5103 6.79925C26.7269 5.02557 24.2082 5.02558 23.3927 6.79925L7.59814 41.1495C6.75833 42.9759 8.52712 44.8902 10.4125 44.1954L24.3757 39.0496C24.8829 38.8627 25.4385 38.8627 25.9422 39.0496L39.8121 44.1954C41.6849 44.8902 43.4884 42.9759 42.6817 41.1495Z\" fill=\"black\" />\r\n <path d=\"M43.7146 40.6933L28.5431 6.34306C27.3556 3.65428 23.5772 3.69516 22.3668 6.32755L6.57226 40.6778C5.3134 43.4156 7.97238 46.298 10.803 45.2549L24.7662 40.109C25.0221 40.0147 25.2999 40.0156 25.5494 40.1082L39.4193 45.254C42.2261 46.2953 44.9254 43.4347 43.7146 40.6933Z\" stroke=\"white\" strokeWidth=\"2.25825\" />\r\n </g>\r\n <defs>\r\n <filter id=\"walros-cursor-shadow\" x=\"0.602397\" y=\"0.952444\" width=\"49.0584\" height=\"52.428\" filterUnits=\"userSpaceOnUse\" colorInterpolationFilters=\"sRGB\">\r\n <feFlood floodOpacity=\"0\" result=\"BackgroundImageFix\" />\r\n <feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\" />\r\n <feOffset dy=\"2.25825\" />\r\n <feGaussianBlur stdDeviation=\"2.25825\" />\r\n <feComposite in2=\"hardAlpha\" operator=\"out\" />\r\n <feColorMatrix type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.08 0\" />\r\n <feBlend mode=\"normal\" in2=\"BackgroundImageFix\" result=\"effect1_dropShadow\" />\r\n <feBlend mode=\"normal\" in=\"SourceGraphic\" in2=\"effect1_dropShadow\" result=\"shape\" />\r\n </filter>\r\n </defs>\r\n </svg>\r\n </div>\r\n </div></>\n );\n}\n","// Embedded so consumers receive the exact .cur without copying a package asset.\nexport const walrosHandCursor = \"data:image/x-icon;base64,AAACAAEAICAAAAYAAQCoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAgBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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\";\n","export const walrosPortalSilhouetteUrl = new URL(\n \"./assets/walros-portal-silhouette.svg\",\n import.meta.url,\n).href;\n\nexport const walrosLogoChromeUrl = new URL(\n \"./assets/walros-logo-chrome.png\",\n import.meta.url,\n).href;\n\nexport const walrosWordmarkLightUrl = new URL(\n \"./assets/walros-wordmark-light.png\",\n import.meta.url,\n).href;\n\nexport const walrosWordmarkDarkUrl = new URL(\n \"./assets/walros-wordmark-dark.png\",\n import.meta.url,\n).href;\n\nexport const walrosThemeGlitchSoundUrl = new URL(\n \"./assets/walros-theme-glitch.mp3\",\n import.meta.url,\n).href;\n\nexport const walrosSeasonalPumpkinUrl = new URL(\n \"./assets/walros-seasonal-pumpkin.svg\",\n import.meta.url,\n).href;\n\nexport const walrosSeasonalHeartArrowUrl = new URL(\n \"./assets/walros-seasonal-heart-arrow.svg\",\n import.meta.url,\n).href;\n","import type { ImgHTMLAttributes } from \"react\";\nimport { walrosLogoChromeUrl } from \"../assets\";\n\nexport type WalrosLogoProps = Omit<\n ImgHTMLAttributes<HTMLImageElement>,\n \"src\"\n>;\n\nexport function WalrosLogo({\n alt = \"WalrOS\",\n draggable = false,\n ...props\n}: WalrosLogoProps) {\n return (\n <img\n src={walrosLogoChromeUrl}\n alt={alt}\n draggable={draggable}\n {...props}\n />\n );\n}\n\nexport default WalrosLogo;\n","import type { ImgHTMLAttributes } from \"react\";\nimport {\n walrosWordmarkDarkUrl,\n walrosWordmarkLightUrl,\n} from \"../assets\";\n\nexport type WalrosWordmarkProps = Omit<\n ImgHTMLAttributes<HTMLImageElement>,\n \"src\"\n> & {\n variant?: \"light\" | \"dark\";\n};\n\nexport function WalrosWordmark({\n variant = \"light\",\n alt = \"WalrOS\",\n draggable = false,\n ...props\n}: WalrosWordmarkProps) {\n const src =\n variant === \"dark\"\n ? walrosWordmarkDarkUrl\n : walrosWordmarkLightUrl;\n\n return (\n <img\n src={src}\n alt={alt}\n draggable={draggable}\n {...props}\n />\n );\n}\n\nexport default WalrosWordmark;\n","import { useEffect, useMemo, useState } from \"react\";\nimport type { CSSProperties, ReactNode } from \"react\";\n\nexport type WalrosSeason = \"auto\" | \"none\" | \"halloween\" | \"winter\" | \"valentine\";\n\nexport type WalrosSeasonalBackgroundProps = {\n children: ReactNode;\n /** Uses the seasonal calendar when set to auto. */\n season?: WalrosSeason;\n /** Time zone used by automatic mode. Defaults to Europe/Madrid. */\n timeZone?: string;\n /** Number of decorations distributed throughout the page. Defaults to 20. */\n density?: number;\n enabled?: boolean;\n className?: string;\n contentClassName?: string;\n style?: CSSProperties;\n};\n\ntype ActiveSeason = Exclude<WalrosSeason, \"auto\" | \"none\">;\n\nconst PARTICLES = [\n [2, 6, 0, 28, -18, 0.84], [10, 25, 2.2, 31, 16, 0.72],\n [18, 58, 4.6, 29, -14, 0.8], [26, 12, 6.9, 33, 20, 0.75],\n [34, 42, 9.3, 27, -16, 0.86], [42, 79, 11.8, 32, 18, 0.72],\n [50, 3, 14.1, 30, -20, 0.82], [58, 28, 16.7, 34, 15, 0.7],\n [66, 63, 19.2, 28, -18, 0.84], [74, 16, 21.5, 31, 16, 0.74],\n [82, 48, 24.1, 29, -14, 0.8], [90, 84, 26.8, 33, 20, 0.7],\n [97, 36, 29.4, 27, -16, 0.86], [13, 91, 31.8, 32, 18, 0.73],\n [54, 94, 34.3, 30, -20, 0.8], [88, 68, 37.1, 34, 15, 0.7],\n [6, 23, 3.8, 35, -15, 0.8], [21, 71, 7.1, 30, 18, 0.8],\n [39, 32, 10.6, 33, -18, 0.8], [47, 87, 13.2, 29, 16, 0.8],\n [61, 53, 16.8, 35, -16, 0.8], [73, 9, 20.3, 30, 18, 0.8],\n [84, 76, 23.9, 33, -18, 0.8], [95, 57, 27.5, 29, 16, 0.8],\n] as const;\n\nconst STYLES = `\n.walros-seasonal-background {\n position: relative;\n isolation: isolate;\n min-height: 100dvh;\n}\n.walros-seasonal-background__decorations {\n position: absolute;\n inset: 0;\n z-index: 0;\n overflow: hidden;\n pointer-events: none;\n contain: layout paint;\n}\n.walros-seasonal-background__content {\n position: relative;\n z-index: 1;\n}\n.walros-seasonal-background__particle {\n position: absolute;\n top: var(--walros-seasonal-top);\n left: 0;\n display: block;\n width: clamp(24px, 2.45vw, 44px);\n height: clamp(24px, 2.45vw, 44px);\n color: var(--walros-seasonal-color);\n /* Important prevents external theme styles or animations from making\n individual decorations fade at different moments. */\n opacity: var(--walros-seasonal-opacity) !important;\n filter: drop-shadow(0 2px 5px rgb(0 0 0 / .12));\n animation: walros-seasonal-drift var(--walros-seasonal-duration) linear var(--walros-seasonal-delay) infinite;\n will-change: transform;\n}\n.walros-seasonal-background__particle svg {\n display: block;\n width: 100%;\n height: 100%;\n overflow: visible;\n}\n@keyframes walros-seasonal-drift {\n 0% { transform: translate3d(-12vw, 0, 0) rotate(-12deg); }\n 50% { transform: translate3d(50vw, var(--walros-seasonal-sway), 0) rotate(180deg); }\n 100% { transform: translate3d(112vw, 0, 0) rotate(372deg); }\n}\n@media (prefers-reduced-motion: reduce) {\n .walros-seasonal-background__particle {\n animation: none;\n opacity: var(--walros-seasonal-opacity);\n transform: translate3d(0, 0, 0);\n }\n}\n`;\n\nfunction classNames(...values: Array<string | undefined>) {\n return values.filter(Boolean).join(\" \");\n}\n\nfunction installStyles() {\n if (typeof document === \"undefined\" || document.getElementById(\"walros-seasonal-background-styles\")) return;\n const style = document.createElement(\"style\");\n style.id = \"walros-seasonal-background-styles\";\n style.textContent = STYLES;\n document.head.appendChild(style);\n}\n\nfunction getDateParts(date: Date, timeZone: string) {\n const parts = new Intl.DateTimeFormat(\"en-GB\", {\n timeZone,\n day: \"2-digit\",\n month: \"2-digit\",\n year: \"numeric\",\n }).formatToParts(date);\n const value = (type: Intl.DateTimeFormatPartTypes) => Number(parts.find((part) => part.type === type)?.value);\n return { day: value(\"day\"), month: value(\"month\"), year: value(\"year\") };\n}\n\nfunction getUtcOffsetMilliseconds(date: Date, timeZone: string) {\n const parts = new Intl.DateTimeFormat(\"en-GB\", {\n timeZone,\n timeZoneName: \"longOffset\",\n }).formatToParts(date);\n const offset = parts.find((part) => part.type === \"timeZoneName\")?.value ?? \"GMT\";\n const match = offset.match(/^GMT([+-])(\\d{2}):(\\d{2})$/);\n if (!match) return 0;\n const minutes = Number(match[2]) * 60 + Number(match[3]);\n return (match[1] === \"+\" ? 1 : -1) * minutes * 60_000;\n}\n\nfunction millisecondsUntilNextMidnight(timeZone: string) {\n const now = new Date();\n const { year, month, day } = getDateParts(now, timeZone);\n const localNextMidnight = Date.UTC(year, month - 1, day + 1, 0, 0, 1);\n let nextMidnight = localNextMidnight - getUtcOffsetMilliseconds(new Date(localNextMidnight), timeZone);\n nextMidnight = localNextMidnight - getUtcOffsetMilliseconds(new Date(nextMidnight), timeZone);\n return Math.max(1_000, nextMidnight - now.getTime());\n}\n\n/**\n * Returns the campaign active on a date in the selected time zone.\n * Each interval includes its start at 00:00 and excludes its stated end at 00:00.\n */\nexport function getWalrosSeason(date = new Date(), timeZone = \"Europe/Madrid\"): ActiveSeason | null {\n const { day, month } = getDateParts(date, timeZone);\n // 30 Sep 00:00 <= date < 1 Nov 00:00\n if ((month === 9 && day >= 30) || month === 10) return \"halloween\";\n // 30 Nov 00:00 <= date < 11 Jan 00:00\n if ((month === 11 && day >= 30) || month === 12 || (month === 1 && day <= 10)) return \"winter\";\n // 14 Feb 00:00 <= date < 15 Feb 00:00\n if (month === 2 && day === 14) return \"valentine\";\n return null;\n}\n\nfunction useAutomaticSeason(timeZone: string) {\n const [now, setNow] = useState(() => new Date());\n useEffect(() => {\n let timer = 0;\n const refreshAtNextMidnight = () => {\n timer = window.setTimeout(() => {\n setNow(new Date());\n refreshAtNextMidnight();\n }, millisecondsUntilNextMidnight(timeZone));\n };\n refreshAtNextMidnight();\n return () => window.clearTimeout(timer);\n }, [timeZone]);\n\n return getWalrosSeason(now, timeZone);\n}\n\nfunction SnowIcon() {\n return <svg viewBox=\"0 0 32 32\" fill=\"none\" aria-hidden=\"true\"><g stroke=\"currentColor\" strokeWidth=\"2.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"M16 3v26M4.7 9.5l22.6 13M4.7 22.5l22.6-13\"/><path d=\"m16 3-3 4M16 3l3 4M16 29l-3-4M16 29l3-4M4.7 9.5l4.9.5M4.7 9.5l2 4.5M27.3 22.5l-4.9-.5M27.3 22.5l-2-4.5M4.7 22.5l4.9-.5M4.7 22.5l2-4.5M27.3 9.5l-4.9.5M27.3 9.5l-2 4.5\"/></g></svg>;\n}\n\nfunction PumpkinIcon() {\n return <svg viewBox=\"0 0 160 160\" fill=\"none\" aria-hidden=\"true\"><defs><linearGradient id=\"walros-seasonal-pumpkin\" x1=\"28\" y1=\"44\" x2=\"133\" y2=\"132\" gradientUnits=\"userSpaceOnUse\"><stop stopColor=\"#FF9F17\"/><stop offset=\"1\" stopColor=\"#F06408\"/></linearGradient><linearGradient id=\"walros-seasonal-stem\" x1=\"83\" y1=\"15\" x2=\"105\" y2=\"55\" gradientUnits=\"userSpaceOnUse\"><stop stopColor=\"#45933D\"/><stop offset=\"1\" stopColor=\"#1D642C\"/></linearGradient></defs><path d=\"M88 45c-2-14 3-26 14-34 11 7 17 17 16 31-1 8-5 13-12 15-8 3-15-2-18-12Z\" fill=\"url(#walros-seasonal-stem)\"/><path d=\"M80 36c-36 0-61 22-61 57 0 34 24 53 61 53s61-19 61-53c0-35-25-57-61-57Z\" fill=\"url(#walros-seasonal-pumpkin)\"/><path d=\"M80 38c-18 14-23 75 0 106M51 44c-17 22-17 64 0 94M109 44c17 22 17 64 0 94\" stroke=\"#FFBE3C\" strokeWidth=\"5\" strokeLinecap=\"round\" opacity=\".6\"/><path d=\"m47 82 16-20c2-3 6-3 8 1l8 24c1 4-3 7-7 6l-22-4c-4-1-5-4-3-7ZM113 82 97 62c-2-3-6-3-8 1l-8 24c-1 4 3 7 7 6l22-4c4-1 5-4 3-7ZM78 91l-10 12c-3 3-1 8 4 8h17c5 0 7-5 4-8L83 91c-1-2-4-2-5 0Z\" fill=\"#3A260F\"/><path d=\"M45 112c-2-5 4-8 8-5l10 7 10-7c2-2 5-2 7 0l10 7 10-7c4-3 10 0 8 5l-9 28c-1 4-5 5-8 3l-11-8-11 8c-3 2-7 1-8-3l-16-28Z\" fill=\"#3A260F\"/></svg>;\n}\n\nfunction HeartArrowIcon() {\n return <svg viewBox=\"0 0 160 160\" fill=\"none\" aria-hidden=\"true\"><defs><linearGradient id=\"walros-seasonal-heart\" x1=\"40\" y1=\"51\" x2=\"123\" y2=\"129\" gradientUnits=\"userSpaceOnUse\"><stop stopColor=\"#FF5457\"/><stop offset=\"1\" stopColor=\"#D41E32\"/></linearGradient><linearGradient id=\"walros-seasonal-gold\" x1=\"24\" y1=\"24\" x2=\"135\" y2=\"133\" gradientUnits=\"userSpaceOnUse\"><stop stopColor=\"#FFE958\"/><stop offset=\"1\" stopColor=\"#F3AE19\"/></linearGradient></defs><path d=\"M80 137S28 107 28 64c0-20 14-34 33-34 10 0 16 5 19 12 3-7 9-12 19-12 19 0 33 14 33 34 0 43-52 73-52 73Z\" fill=\"url(#walros-seasonal-heart)\" stroke=\"#C92735\" strokeWidth=\"7\" strokeLinejoin=\"round\"/><path d=\"M76 44c-13-9-28-2-33 12\" stroke=\"#FF9A90\" strokeWidth=\"6\" strokeLinecap=\"round\" opacity=\".45\"/><path d=\"m18 43 37-16-16 37-21-21ZM142 117l-37 16 16-37 21 21Z\" fill=\"url(#walros-seasonal-gold)\" stroke=\"#D8A91C\" strokeWidth=\"5\" strokeLinejoin=\"round\"/><path d=\"m31 53 96 72\" stroke=\"#F5B415\" strokeWidth=\"13\" strokeLinecap=\"round\"/><path d=\"M72 89c0-16 11-24 24-22\" stroke=\"#AE1830\" strokeWidth=\"9\" strokeLinecap=\"round\"/></svg>;\n}\n\nfunction Decoration({ season }: { season: ActiveSeason }) {\n if (season === \"halloween\") return <PumpkinIcon />;\n if (season === \"winter\") return <SnowIcon />;\n return <HeartArrowIcon />;\n}\n\nfunction getSeasonColor(season: ActiveSeason) {\n if (season === \"halloween\") return \"transparent\";\n if (season === \"winter\") return \"#78B7E8\";\n return \"transparent\";\n}\n\nexport function WalrosSeasonalBackground({\n children,\n season = \"auto\",\n timeZone = \"Europe/Madrid\",\n density = 20,\n enabled = true,\n className,\n contentClassName,\n style,\n}: WalrosSeasonalBackgroundProps) {\n useEffect(() => installStyles(), []);\n\n const automaticSeason = useAutomaticSeason(timeZone);\n const activeSeason = season === \"auto\" ? automaticSeason : season === \"none\" ? null : season;\n const particleCount = Math.max(1, Math.min(PARTICLES.length, Math.round(density)));\n const particles = useMemo(() => PARTICLES.slice(0, particleCount), [particleCount]);\n\n return (\n <div className={classNames(\"walros-seasonal-background\", className)} style={style}>\n {enabled && activeSeason && (\n <div className=\"walros-seasonal-background__decorations\" aria-hidden=\"true\">\n {particles.map(([, top, , duration, sway], index) => {\n // Each decoration starts at a different point in its trip, so the\n // page stays evenly populated instead of collecting at one edge.\n const elapsed = (index / particleCount) * duration;\n return <span\n className=\"walros-seasonal-background__particle\"\n key={`${activeSeason}-${index}`}\n style={{\n \"--walros-seasonal-top\": `${top}%`,\n \"--walros-seasonal-delay\": `-${elapsed}s`,\n \"--walros-seasonal-duration\": `${duration}s`,\n \"--walros-seasonal-sway\": `${sway}px`,\n \"--walros-seasonal-opacity\": \".52\",\n \"--walros-seasonal-color\": getSeasonColor(activeSeason),\n } as CSSProperties}\n >\n <Decoration season={activeSeason} />\n </span>;\n })}\n </div>\n )}\n <div className={classNames(\"walros-seasonal-background__content\", contentClassName)}>{children}</div>\n </div>\n );\n}\n","import {\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport type { RefObject } from \"react\";\nimport { walrosThemeGlitchSoundUrl } from \"../assets\";\n\nexport type WalrosTheme = \"light\" | \"dark\";\nexport type WalrosThemeMode = \"body\" | \"viewport\";\n\nexport type WalrosThemeShakeTarget =\n | HTMLElement\n | RefObject<HTMLElement | null>\n | null\n | undefined;\n\nexport type UseWalrosThemeOptions = {\n storageKey?: string;\n defaultTheme?: WalrosTheme;\n useSystemPreference?: boolean;\n swapDelay?: number;\n totalDuration?: number;\n /** Set to false to disable audio, or provide a custom sound URL. */\n soundUrl?: string | false;\n /** Playback volume from 0 to 1. Defaults to the WalrOS site mix. */\n soundVolume?: number;\n applyTheme?: (theme: WalrosTheme) => void;\n\n /**\n * `body` reproduce el comportamiento original de WalrOS Forum.\n * `viewport` bloquea el scroll y sacude solo los elementos indicados,\n * recomendado para parallax, sticky y GSAP ScrollTrigger.\n */\n mode?: WalrosThemeMode;\n\n /** Elementos que recibirán el shake cuando mode=\"viewport\". */\n shakeTargets?: readonly WalrosThemeShakeTarget[];\n\n /**\n * En modo viewport se activa por defecto. Mantiene scrollX/scrollY estables\n * con requestAnimationFrame sin usar position: fixed en el body.\n */\n lockScroll?: boolean;\n\n /** Se ejecuta después de restaurar el scroll; útil para ScrollTrigger.update(). */\n onAfterUnlock?: () => void;\n};\n\nexport type UseWalrosThemeResult = {\n theme: WalrosTheme;\n isDark: boolean;\n mounted: boolean;\n glitching: boolean;\n toggleTheme: () => void;\n setTheme: (theme: WalrosTheme) => void;\n};\n\ntype ViewportLockState = {\n scrollX: number;\n scrollY: number;\n rafId: number;\n active: boolean;\n bodyOverflow: string;\n htmlOverflow: string;\n htmlOverscrollBehavior: string;\n};\n\nconst GLITCH_BASE_CLASS = \"walros-theme-glitch-page\";\nconst GLITCH_BODY_CLASS = \"walros-theme-glitch-page--body\";\nconst GLITCH_VIEWPORT_CLASS = \"walros-theme-glitch-page--viewport\";\nconst GLITCH_LOCK_CLASS = \"walros-theme-glitch-lock\";\n\nfunction defaultApplyTheme(theme: WalrosTheme) {\n if (typeof document === \"undefined\") return;\n\n const root = document.documentElement;\n root.classList.toggle(\"dark\", theme === \"dark\");\n root.style.colorScheme = theme;\n}\n\nfunction readInitialTheme(\n storageKey: string,\n defaultTheme: WalrosTheme,\n useSystemPreference: boolean,\n): WalrosTheme {\n if (typeof window === \"undefined\") return defaultTheme;\n\n try {\n const stored = window.localStorage.getItem(storageKey);\n if (stored === \"light\" || stored === \"dark\") return stored;\n } catch {\n // localStorage puede estar bloqueado en modo privado.\n }\n\n if (\n useSystemPreference &&\n window.matchMedia?.(\"(prefers-color-scheme: dark)\").matches\n ) {\n return \"dark\";\n }\n\n return defaultTheme;\n}\n\nfunction resolveShakeTargets(\n targets: readonly WalrosThemeShakeTarget[],\n): HTMLElement[] {\n const resolved = new Set<HTMLElement>();\n\n for (const target of targets) {\n if (!target) continue;\n\n const element =\n typeof target === \"object\" && \"current\" in target\n ? target.current\n : target;\n\n if (element) resolved.add(element);\n }\n\n return [...resolved];\n}\n\nexport function useWalrosTheme({\n storageKey = \"walros-theme\",\n defaultTheme = \"light\",\n useSystemPreference = false,\n swapDelay = 610,\n totalDuration = 1500,\n soundUrl = walrosThemeGlitchSoundUrl,\n soundVolume = 0.52,\n applyTheme = defaultApplyTheme,\n mode = \"body\",\n shakeTargets = [],\n lockScroll,\n onAfterUnlock,\n}: UseWalrosThemeOptions = {}): UseWalrosThemeResult {\n const [theme, setThemeState] = useState<WalrosTheme>(() =>\n readInitialTheme(storageKey, defaultTheme, useSystemPreference),\n );\n const [mounted, setMounted] = useState(false);\n const [glitching, setGlitching] = useState(false);\n\n const themeRef = useRef(theme);\n const glitchingRef = useRef(false);\n const swapTimerRef = useRef<number | null>(null);\n const cleanupTimerRef = useRef<number | null>(null);\n const applyThemeRef = useRef(applyTheme);\n const modeRef = useRef(mode);\n const shakeTargetsRef = useRef(shakeTargets);\n const lockScrollRef = useRef(lockScroll);\n const onAfterUnlockRef = useRef(onAfterUnlock);\n const activeTargetsRef = useRef<HTMLElement[]>([]);\n const viewportLockRef = useRef<ViewportLockState | null>(null);\n const soundRef = useRef<HTMLAudioElement | null>(null);\n const soundUrlRef = useRef(soundUrl);\n const soundVolumeRef = useRef(soundVolume);\n\n themeRef.current = theme;\n applyThemeRef.current = applyTheme;\n modeRef.current = mode;\n shakeTargetsRef.current = shakeTargets;\n lockScrollRef.current = lockScroll;\n onAfterUnlockRef.current = onAfterUnlock;\n soundUrlRef.current = soundUrl;\n soundVolumeRef.current = soundVolume;\n\n const playThemeSound = useCallback(() => {\n if (typeof window === \"undefined\" || !soundUrlRef.current) return;\n\n try {\n if (!soundRef.current || soundRef.current.src !== new URL(soundUrlRef.current, document.baseURI).href) {\n soundRef.current?.pause();\n soundRef.current?.remove();\n soundRef.current = new Audio(soundUrlRef.current);\n soundRef.current.preload = \"auto\";\n soundRef.current.setAttribute(\"aria-hidden\", \"true\");\n soundRef.current.style.display = \"none\";\n document.body.appendChild(soundRef.current);\n }\n const audio = soundRef.current;\n audio.volume = Math.max(0, Math.min(1, soundVolumeRef.current));\n audio.currentTime = 0;\n void audio.play().catch(() => {\n // Browsers may block sound; the theme animation still continues.\n });\n } catch {\n // Audio support is optional and must not block the theme change.\n }\n }, []);\n\n const persistTheme = useCallback(\n (nextTheme: WalrosTheme) => {\n applyThemeRef.current(nextTheme);\n setThemeState(nextTheme);\n themeRef.current = nextTheme;\n\n try {\n window.localStorage.setItem(storageKey, nextTheme);\n } catch {\n // El cambio debe funcionar aunque localStorage falle.\n }\n },\n [storageKey],\n );\n\n useEffect(() => {\n const initialTheme = readInitialTheme(\n storageKey,\n defaultTheme,\n useSystemPreference,\n );\n\n themeRef.current = initialTheme;\n setThemeState(initialTheme);\n applyThemeRef.current(initialTheme);\n setMounted(true);\n }, [defaultTheme, storageKey, useSystemPreference]);\n\n const clearTimers = useCallback(() => {\n if (swapTimerRef.current !== null) {\n window.clearTimeout(swapTimerRef.current);\n swapTimerRef.current = null;\n }\n\n if (cleanupTimerRef.current !== null) {\n window.clearTimeout(cleanupTimerRef.current);\n cleanupTimerRef.current = null;\n }\n }, []);\n\n const lockViewport = useCallback(() => {\n if (\n typeof window === \"undefined\" ||\n typeof document === \"undefined\" ||\n viewportLockRef.current\n ) {\n return;\n }\n\n const body = document.body;\n const html = document.documentElement;\n const lockState: ViewportLockState = {\n scrollX: window.scrollX,\n scrollY: window.scrollY,\n rafId: 0,\n active: true,\n bodyOverflow: body.style.overflow,\n htmlOverflow: html.style.overflow,\n htmlOverscrollBehavior: html.style.overscrollBehavior,\n };\n\n viewportLockRef.current = lockState;\n\n const keepScrollStable = () => {\n if (!lockState.active) return;\n window.scrollTo(lockState.scrollX, lockState.scrollY);\n lockState.rafId = window.requestAnimationFrame(keepScrollStable);\n };\n\n html.classList.add(GLITCH_LOCK_CLASS);\n html.style.overflow = \"hidden\";\n html.style.overscrollBehavior = \"none\";\n body.style.overflow = \"hidden\";\n lockState.rafId = window.requestAnimationFrame(keepScrollStable);\n }, []);\n\n const unlockViewport = useCallback((runCallback: boolean) => {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n return;\n }\n\n const lockState = viewportLockRef.current;\n if (!lockState) return;\n\n lockState.active = false;\n window.cancelAnimationFrame(lockState.rafId);\n\n const body = document.body;\n const html = document.documentElement;\n body.style.overflow = lockState.bodyOverflow;\n html.style.overflow = lockState.htmlOverflow;\n html.style.overscrollBehavior = lockState.htmlOverscrollBehavior;\n html.classList.remove(GLITCH_LOCK_CLASS);\n\n viewportLockRef.current = null;\n window.scrollTo(lockState.scrollX, lockState.scrollY);\n\n if (runCallback) {\n window.requestAnimationFrame(() => {\n onAfterUnlockRef.current?.();\n });\n }\n }, []);\n\n const removeShakeClasses = useCallback(() => {\n for (const target of activeTargetsRef.current) {\n target.classList.remove(\n GLITCH_BASE_CLASS,\n GLITCH_BODY_CLASS,\n GLITCH_VIEWPORT_CLASS,\n );\n target.style.removeProperty(\"--walros-glitch-origin-y\");\n }\n\n activeTargetsRef.current = [];\n }, []);\n\n const finishGlitch = useCallback(() => {\n if (soundRef.current) {\n soundRef.current.pause();\n soundRef.current.currentTime = 0;\n }\n removeShakeClasses();\n unlockViewport(true);\n glitchingRef.current = false;\n setGlitching(false);\n }, [removeShakeClasses, unlockViewport]);\n\n const setTheme = useCallback(\n (nextTheme: WalrosTheme) => {\n if (glitchingRef.current) return;\n persistTheme(nextTheme);\n },\n [persistTheme],\n );\n\n const toggleTheme = useCallback(() => {\n if (\n typeof window === \"undefined\" ||\n typeof document === \"undefined\" ||\n glitchingRef.current\n ) {\n return;\n }\n\n playThemeSound();\n\n const currentMode = modeRef.current;\n const shouldLockScroll =\n lockScrollRef.current ?? currentMode === \"viewport\";\n\n if (currentMode === \"viewport\" && shouldLockScroll) {\n lockViewport();\n }\n\n const targets =\n currentMode === \"body\"\n ? [document.body]\n : resolveShakeTargets(shakeTargetsRef.current);\n\n const modeClass =\n currentMode === \"body\"\n ? GLITCH_BODY_CLASS\n : GLITCH_VIEWPORT_CLASS;\n\n for (const target of targets) {\n target.style.setProperty(\n \"--walros-glitch-origin-y\",\n currentMode === \"body\"\n ? `${window.scrollY + window.innerHeight / 2}px`\n : \"50%\",\n );\n target.classList.add(GLITCH_BASE_CLASS, modeClass);\n }\n\n activeTargetsRef.current = targets;\n glitchingRef.current = true;\n setGlitching(true);\n\n const reducedMotion = window.matchMedia?.(\n \"(prefers-reduced-motion: reduce)\",\n ).matches;\n\n const nextTheme: WalrosTheme =\n themeRef.current === \"dark\" ? \"light\" : \"dark\";\n\n const effectiveSwapDelay = reducedMotion\n ? 75\n : Math.max(0, swapDelay);\n const effectiveDuration = reducedMotion\n ? 150\n : Math.max(effectiveSwapDelay, totalDuration);\n\n swapTimerRef.current = window.setTimeout(() => {\n persistTheme(nextTheme);\n swapTimerRef.current = null;\n }, effectiveSwapDelay);\n\n cleanupTimerRef.current = window.setTimeout(() => {\n cleanupTimerRef.current = null;\n finishGlitch();\n }, effectiveDuration);\n }, [finishGlitch, lockViewport, persistTheme, playThemeSound, swapDelay, totalDuration]);\n\n useEffect(() => {\n return () => {\n clearTimers();\n removeShakeClasses();\n unlockViewport(false);\n soundRef.current?.pause();\n soundRef.current?.remove();\n if (soundRef.current) soundRef.current.currentTime = 0;\n soundRef.current = null;\n };\n }, [clearTimers, removeShakeClasses, unlockViewport]);\n\n return {\n theme,\n isDark: theme === \"dark\",\n mounted,\n glitching,\n toggleTheme,\n setTheme,\n };\n}\n\nexport default useWalrosTheme;\n"],"mappings":"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","names":["useState","initialPixels","initialScale","visualCenter","portalCenterX","portalCenterY","useLayoutEffect","useState","jsx","useState","createPortal","jsx","jsxs","jsx","createPortal","useRef","Fragment","jsx","jsxs","useRef","jsx","jsx","useEffect","useState","jsx","jsxs","useEffect","useRef","useState","useState","useRef","useEffect"]}
|