@walrosproject/ui 0.4.6 → 0.5.1
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 +26 -2
- package/dist/index.js +292 -32
- 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;
|
|
@@ -62,6 +62,28 @@ type WalrosThemeGlitchProps = {
|
|
|
62
62
|
};
|
|
63
63
|
declare function WalrosThemeGlitch({ active, zIndex, className, style, }: WalrosThemeGlitchProps): react.JSX.Element;
|
|
64
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
|
+
|
|
65
87
|
type WalrosTheme = "light" | "dark";
|
|
66
88
|
type WalrosThemeMode = "body" | "viewport";
|
|
67
89
|
type WalrosThemeShakeTarget = HTMLElement | RefObject<HTMLElement | null> | null | undefined;
|
|
@@ -107,5 +129,7 @@ declare const walrosLogoChromeUrl: string;
|
|
|
107
129
|
declare const walrosWordmarkLightUrl: string;
|
|
108
130
|
declare const walrosWordmarkDarkUrl: string;
|
|
109
131
|
declare const walrosThemeGlitchSoundUrl: string;
|
|
132
|
+
declare const walrosSeasonalPumpkinUrl: string;
|
|
133
|
+
declare const walrosSeasonalHeartArrowUrl: string;
|
|
110
134
|
|
|
111
|
-
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
|
@@ -362,21 +362,21 @@ var walrosHandCursor = "data:image/x-icon;base64,AAACAAEAICAAAAYAAQCoEAAAFgAAACg
|
|
|
362
362
|
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
363
363
|
var DESKTOP_CURSOR_QUERY = "(min-width: 1024px) and (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference)";
|
|
364
364
|
var CURSOR_STYLES = `
|
|
365
|
-
.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;
|
|
365
|
+
.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; }
|
|
366
366
|
.directional-cursor.is-visible { opacity: 1; }
|
|
367
367
|
.directional-cursor-shape { width: 20px; height: 22px; transform-origin: center center; will-change: transform; }
|
|
368
368
|
.directional-cursor svg { display: block; width: 20px; height: 22px; }
|
|
369
|
+
.directional-cursor-hand { display: none; position: absolute; top: 0; left: 0; width: 32px; height: 32px; transform: translate(-8px, -2px); image-rendering: auto; }
|
|
370
|
+
.directional-cursor.is-hand .directional-cursor-shape { display: none; }
|
|
371
|
+
.directional-cursor.is-hand .directional-cursor-hand { display: block; }
|
|
369
372
|
@media (min-width: 1024px) and (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
|
|
370
373
|
html.has-directional-cursor, html.has-directional-cursor * { cursor: none !important; }
|
|
371
374
|
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"])),
|
|
372
375
|
html.has-directional-cursor [contenteditable="true"] * { cursor: text !important; }
|
|
373
|
-
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"]) {
|
|
374
|
-
cursor: url("${walrosHandCursor}") 8 2, pointer !important;
|
|
375
|
-
}
|
|
376
376
|
}
|
|
377
377
|
`;
|
|
378
378
|
var 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"])';
|
|
379
|
-
var INTERACTIVE_SELECTOR = 'a, button, select, summary, [role="button"], [role="link"], [aria-haspopup="true"], input[type="checkbox"], input[type="radio"], input[type="range"]';
|
|
379
|
+
var INTERACTIVE_SELECTOR = 'a, button, select, summary, label, [role="button"], [role="link"], [role="menuitem"], [role="option"], [role="tab"], [aria-haspopup="true"], [data-cursor-hand], input[type="checkbox"], input[type="radio"], input[type="range"]';
|
|
380
380
|
function DirectionalCursor() {
|
|
381
381
|
const positionLayer = useRef2(null);
|
|
382
382
|
const directionLayer = useRef2(null);
|
|
@@ -401,6 +401,13 @@ function DirectionalCursor() {
|
|
|
401
401
|
let targetScale = 1;
|
|
402
402
|
let lastX = currentX;
|
|
403
403
|
let lastY = 0;
|
|
404
|
+
const updateCursorMode = (eventTarget) => {
|
|
405
|
+
const target = eventTarget instanceof Element ? eventTarget : null;
|
|
406
|
+
const textEntry = target?.closest(TEXT_ENTRY_SELECTOR);
|
|
407
|
+
const interactive = target?.closest(INTERACTIVE_SELECTOR);
|
|
408
|
+
position.classList.toggle("is-visible", !textEntry);
|
|
409
|
+
position.classList.toggle("is-hand", Boolean(interactive && !textEntry));
|
|
410
|
+
};
|
|
404
411
|
const render = () => {
|
|
405
412
|
currentX += (targetX - currentX) * 0.4;
|
|
406
413
|
currentY += (targetY - currentY) * 0.4;
|
|
@@ -424,10 +431,7 @@ function DirectionalCursor() {
|
|
|
424
431
|
const distance = Math.hypot(deltaX, deltaY);
|
|
425
432
|
targetX = event.clientX;
|
|
426
433
|
targetY = event.clientY;
|
|
427
|
-
|
|
428
|
-
const textEntry = target?.closest(TEXT_ENTRY_SELECTOR);
|
|
429
|
-
const interactive = target?.closest(INTERACTIVE_SELECTOR);
|
|
430
|
-
position.classList.toggle("is-visible", !textEntry && !interactive);
|
|
434
|
+
updateCursorMode(event.target);
|
|
431
435
|
if (distance > 1.25) {
|
|
432
436
|
const rawAngle = Math.atan2(deltaY, deltaX) * (180 / Math.PI) + 90;
|
|
433
437
|
const normalizedAngle = (rawAngle % 360 + 360) % 360;
|
|
@@ -453,18 +457,24 @@ function DirectionalCursor() {
|
|
|
453
457
|
latestEvent = event;
|
|
454
458
|
if (!moveFrame) moveFrame = window.requestAnimationFrame(processMove);
|
|
455
459
|
};
|
|
460
|
+
const handleMouseOver = (event) => {
|
|
461
|
+
updateCursorMode(event.target);
|
|
462
|
+
};
|
|
456
463
|
const activate = () => {
|
|
457
464
|
if (active) return;
|
|
458
465
|
active = true;
|
|
459
466
|
document.documentElement.classList.add("has-directional-cursor");
|
|
460
467
|
window.addEventListener("mousemove", handleMouseMove, { passive: true });
|
|
468
|
+
window.addEventListener("mouseover", handleMouseOver, { passive: true });
|
|
461
469
|
};
|
|
462
470
|
const deactivate = () => {
|
|
463
471
|
if (!active) return;
|
|
464
472
|
active = false;
|
|
465
473
|
document.documentElement.classList.remove("has-directional-cursor");
|
|
466
474
|
position.classList.remove("is-visible");
|
|
475
|
+
position.classList.remove("is-hand");
|
|
467
476
|
window.removeEventListener("mousemove", handleMouseMove);
|
|
477
|
+
window.removeEventListener("mouseover", handleMouseOver);
|
|
468
478
|
window.cancelAnimationFrame(frame);
|
|
469
479
|
window.cancelAnimationFrame(moveFrame);
|
|
470
480
|
window.clearTimeout(scaleTimer);
|
|
@@ -484,22 +494,25 @@ function DirectionalCursor() {
|
|
|
484
494
|
}, []);
|
|
485
495
|
return /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
486
496
|
/* @__PURE__ */ jsx5("style", { children: CURSOR_STYLES }),
|
|
487
|
-
/* @__PURE__ */
|
|
488
|
-
/* @__PURE__ */
|
|
489
|
-
/* @__PURE__ */
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
/* @__PURE__ */ jsx5("
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
497
|
+
/* @__PURE__ */ jsxs3("div", { ref: positionLayer, className: "directional-cursor", "aria-hidden": "true", children: [
|
|
498
|
+
/* @__PURE__ */ jsx5("div", { ref: directionLayer, className: "directional-cursor-shape", children: /* @__PURE__ */ jsxs3("svg", { width: "50", height: "54", viewBox: "0 0 50 54", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
499
|
+
/* @__PURE__ */ jsxs3("g", { filter: "url(#walros-cursor-shadow)", children: [
|
|
500
|
+
/* @__PURE__ */ jsx5("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" }),
|
|
501
|
+
/* @__PURE__ */ jsx5("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" })
|
|
502
|
+
] }),
|
|
503
|
+
/* @__PURE__ */ jsx5("defs", { children: /* @__PURE__ */ jsxs3("filter", { id: "walros-cursor-shadow", x: "0.602397", y: "0.952444", width: "49.0584", height: "52.428", filterUnits: "userSpaceOnUse", colorInterpolationFilters: "sRGB", children: [
|
|
504
|
+
/* @__PURE__ */ jsx5("feFlood", { floodOpacity: "0", result: "BackgroundImageFix" }),
|
|
505
|
+
/* @__PURE__ */ jsx5("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" }),
|
|
506
|
+
/* @__PURE__ */ jsx5("feOffset", { dy: "2.25825" }),
|
|
507
|
+
/* @__PURE__ */ jsx5("feGaussianBlur", { stdDeviation: "2.25825" }),
|
|
508
|
+
/* @__PURE__ */ jsx5("feComposite", { in2: "hardAlpha", operator: "out" }),
|
|
509
|
+
/* @__PURE__ */ jsx5("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" }),
|
|
510
|
+
/* @__PURE__ */ jsx5("feBlend", { mode: "normal", in2: "BackgroundImageFix", result: "effect1_dropShadow" }),
|
|
511
|
+
/* @__PURE__ */ jsx5("feBlend", { mode: "normal", in: "SourceGraphic", in2: "effect1_dropShadow", result: "shape" })
|
|
512
|
+
] }) })
|
|
513
|
+
] }) }),
|
|
514
|
+
/* @__PURE__ */ jsx5("img", { className: "directional-cursor-hand", src: walrosHandCursor, alt: "" })
|
|
515
|
+
] })
|
|
503
516
|
] });
|
|
504
517
|
}
|
|
505
518
|
|
|
@@ -524,6 +537,14 @@ var walrosThemeGlitchSoundUrl = new URL(
|
|
|
524
537
|
"./assets/walros-theme-glitch.mp3",
|
|
525
538
|
import.meta.url
|
|
526
539
|
).href;
|
|
540
|
+
var walrosSeasonalPumpkinUrl = new URL(
|
|
541
|
+
"./assets/walros-seasonal-pumpkin.svg",
|
|
542
|
+
import.meta.url
|
|
543
|
+
).href;
|
|
544
|
+
var walrosSeasonalHeartArrowUrl = new URL(
|
|
545
|
+
"./assets/walros-seasonal-heart-arrow.svg",
|
|
546
|
+
import.meta.url
|
|
547
|
+
).href;
|
|
527
548
|
|
|
528
549
|
// src/components/WalrosLogo.tsx
|
|
529
550
|
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
@@ -563,12 +584,247 @@ function WalrosWordmark({
|
|
|
563
584
|
);
|
|
564
585
|
}
|
|
565
586
|
|
|
587
|
+
// src/components/WalrosSeasonalBackground.tsx
|
|
588
|
+
import { useEffect as useEffect2, useMemo, useState as useState4 } from "react";
|
|
589
|
+
import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
590
|
+
var PARTICLES = [
|
|
591
|
+
[2, 6, 0, 28, -18, 0.84],
|
|
592
|
+
[10, 25, 2.2, 31, 16, 0.72],
|
|
593
|
+
[18, 58, 4.6, 29, -14, 0.8],
|
|
594
|
+
[26, 12, 6.9, 33, 20, 0.75],
|
|
595
|
+
[34, 42, 9.3, 27, -16, 0.86],
|
|
596
|
+
[42, 79, 11.8, 32, 18, 0.72],
|
|
597
|
+
[50, 3, 14.1, 30, -20, 0.82],
|
|
598
|
+
[58, 28, 16.7, 34, 15, 0.7],
|
|
599
|
+
[66, 63, 19.2, 28, -18, 0.84],
|
|
600
|
+
[74, 16, 21.5, 31, 16, 0.74],
|
|
601
|
+
[82, 48, 24.1, 29, -14, 0.8],
|
|
602
|
+
[90, 84, 26.8, 33, 20, 0.7],
|
|
603
|
+
[97, 36, 29.4, 27, -16, 0.86],
|
|
604
|
+
[13, 91, 31.8, 32, 18, 0.73],
|
|
605
|
+
[54, 94, 34.3, 30, -20, 0.8],
|
|
606
|
+
[88, 68, 37.1, 34, 15, 0.7],
|
|
607
|
+
[6, 23, 3.8, 35, -15, 0.8],
|
|
608
|
+
[21, 71, 7.1, 30, 18, 0.8],
|
|
609
|
+
[39, 32, 10.6, 33, -18, 0.8],
|
|
610
|
+
[47, 87, 13.2, 29, 16, 0.8],
|
|
611
|
+
[61, 53, 16.8, 35, -16, 0.8],
|
|
612
|
+
[73, 9, 20.3, 30, 18, 0.8],
|
|
613
|
+
[84, 76, 23.9, 33, -18, 0.8],
|
|
614
|
+
[95, 57, 27.5, 29, 16, 0.8]
|
|
615
|
+
];
|
|
616
|
+
var STYLES = `
|
|
617
|
+
.walros-seasonal-background {
|
|
618
|
+
position: relative;
|
|
619
|
+
isolation: isolate;
|
|
620
|
+
min-height: 100dvh;
|
|
621
|
+
}
|
|
622
|
+
.walros-seasonal-background__decorations {
|
|
623
|
+
position: absolute;
|
|
624
|
+
inset: 0;
|
|
625
|
+
z-index: 0;
|
|
626
|
+
overflow: hidden;
|
|
627
|
+
pointer-events: none;
|
|
628
|
+
contain: layout paint;
|
|
629
|
+
}
|
|
630
|
+
.walros-seasonal-background__content {
|
|
631
|
+
position: relative;
|
|
632
|
+
z-index: 1;
|
|
633
|
+
}
|
|
634
|
+
.walros-seasonal-background__particle {
|
|
635
|
+
position: absolute;
|
|
636
|
+
top: var(--walros-seasonal-top);
|
|
637
|
+
left: 0;
|
|
638
|
+
display: block;
|
|
639
|
+
width: clamp(24px, 2.45vw, 44px);
|
|
640
|
+
height: clamp(24px, 2.45vw, 44px);
|
|
641
|
+
color: var(--walros-seasonal-color);
|
|
642
|
+
/* Important prevents external theme styles or animations from making
|
|
643
|
+
individual decorations fade at different moments. */
|
|
644
|
+
opacity: var(--walros-seasonal-opacity) !important;
|
|
645
|
+
filter: drop-shadow(0 2px 5px rgb(0 0 0 / .12));
|
|
646
|
+
animation: walros-seasonal-drift var(--walros-seasonal-duration) linear var(--walros-seasonal-delay) infinite;
|
|
647
|
+
will-change: transform;
|
|
648
|
+
}
|
|
649
|
+
.walros-seasonal-background__particle svg {
|
|
650
|
+
display: block;
|
|
651
|
+
width: 100%;
|
|
652
|
+
height: 100%;
|
|
653
|
+
overflow: visible;
|
|
654
|
+
}
|
|
655
|
+
@keyframes walros-seasonal-drift {
|
|
656
|
+
0% { transform: translate3d(-12vw, 0, 0) rotate(-12deg); }
|
|
657
|
+
50% { transform: translate3d(50vw, var(--walros-seasonal-sway), 0) rotate(180deg); }
|
|
658
|
+
100% { transform: translate3d(112vw, 0, 0) rotate(372deg); }
|
|
659
|
+
}
|
|
660
|
+
@media (prefers-reduced-motion: reduce) {
|
|
661
|
+
.walros-seasonal-background__particle {
|
|
662
|
+
animation: none;
|
|
663
|
+
opacity: var(--walros-seasonal-opacity);
|
|
664
|
+
transform: translate3d(0, 0, 0);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
`;
|
|
668
|
+
function classNames(...values) {
|
|
669
|
+
return values.filter(Boolean).join(" ");
|
|
670
|
+
}
|
|
671
|
+
function installStyles() {
|
|
672
|
+
if (typeof document === "undefined" || document.getElementById("walros-seasonal-background-styles")) return;
|
|
673
|
+
const style = document.createElement("style");
|
|
674
|
+
style.id = "walros-seasonal-background-styles";
|
|
675
|
+
style.textContent = STYLES;
|
|
676
|
+
document.head.appendChild(style);
|
|
677
|
+
}
|
|
678
|
+
function getDateParts(date, timeZone) {
|
|
679
|
+
const parts = new Intl.DateTimeFormat("en-GB", {
|
|
680
|
+
timeZone,
|
|
681
|
+
day: "2-digit",
|
|
682
|
+
month: "2-digit",
|
|
683
|
+
year: "numeric"
|
|
684
|
+
}).formatToParts(date);
|
|
685
|
+
const value = (type) => Number(parts.find((part) => part.type === type)?.value);
|
|
686
|
+
return { day: value("day"), month: value("month"), year: value("year") };
|
|
687
|
+
}
|
|
688
|
+
function getUtcOffsetMilliseconds(date, timeZone) {
|
|
689
|
+
const parts = new Intl.DateTimeFormat("en-GB", {
|
|
690
|
+
timeZone,
|
|
691
|
+
timeZoneName: "longOffset"
|
|
692
|
+
}).formatToParts(date);
|
|
693
|
+
const offset = parts.find((part) => part.type === "timeZoneName")?.value ?? "GMT";
|
|
694
|
+
const match = offset.match(/^GMT([+-])(\d{2}):(\d{2})$/);
|
|
695
|
+
if (!match) return 0;
|
|
696
|
+
const minutes = Number(match[2]) * 60 + Number(match[3]);
|
|
697
|
+
return (match[1] === "+" ? 1 : -1) * minutes * 6e4;
|
|
698
|
+
}
|
|
699
|
+
function millisecondsUntilNextMidnight(timeZone) {
|
|
700
|
+
const now = /* @__PURE__ */ new Date();
|
|
701
|
+
const { year, month, day } = getDateParts(now, timeZone);
|
|
702
|
+
const localNextMidnight = Date.UTC(year, month - 1, day + 1, 0, 0, 1);
|
|
703
|
+
let nextMidnight = localNextMidnight - getUtcOffsetMilliseconds(new Date(localNextMidnight), timeZone);
|
|
704
|
+
nextMidnight = localNextMidnight - getUtcOffsetMilliseconds(new Date(nextMidnight), timeZone);
|
|
705
|
+
return Math.max(1e3, nextMidnight - now.getTime());
|
|
706
|
+
}
|
|
707
|
+
function getWalrosSeason(date = /* @__PURE__ */ new Date(), timeZone = "Europe/Madrid") {
|
|
708
|
+
const { day, month } = getDateParts(date, timeZone);
|
|
709
|
+
if (month === 9 && day >= 30 || month === 10) return "halloween";
|
|
710
|
+
if (month === 11 && day >= 30 || month === 12 || month === 1 && day <= 10) return "winter";
|
|
711
|
+
if (month === 2 && day === 14) return "valentine";
|
|
712
|
+
return null;
|
|
713
|
+
}
|
|
714
|
+
function useAutomaticSeason(timeZone) {
|
|
715
|
+
const [now, setNow] = useState4(() => /* @__PURE__ */ new Date());
|
|
716
|
+
useEffect2(() => {
|
|
717
|
+
let timer = 0;
|
|
718
|
+
const refreshAtNextMidnight = () => {
|
|
719
|
+
timer = window.setTimeout(() => {
|
|
720
|
+
setNow(/* @__PURE__ */ new Date());
|
|
721
|
+
refreshAtNextMidnight();
|
|
722
|
+
}, millisecondsUntilNextMidnight(timeZone));
|
|
723
|
+
};
|
|
724
|
+
refreshAtNextMidnight();
|
|
725
|
+
return () => window.clearTimeout(timer);
|
|
726
|
+
}, [timeZone]);
|
|
727
|
+
return getWalrosSeason(now, timeZone);
|
|
728
|
+
}
|
|
729
|
+
function SnowIcon() {
|
|
730
|
+
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: [
|
|
731
|
+
/* @__PURE__ */ jsx8("path", { d: "M16 3v26M4.7 9.5l22.6 13M4.7 22.5l22.6-13" }),
|
|
732
|
+
/* @__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" })
|
|
733
|
+
] }) });
|
|
734
|
+
}
|
|
735
|
+
function PumpkinIcon() {
|
|
736
|
+
return /* @__PURE__ */ jsxs4("svg", { viewBox: "0 0 160 160", fill: "none", "aria-hidden": "true", children: [
|
|
737
|
+
/* @__PURE__ */ jsxs4("defs", { children: [
|
|
738
|
+
/* @__PURE__ */ jsxs4("linearGradient", { id: "walros-seasonal-pumpkin", x1: "28", y1: "44", x2: "133", y2: "132", gradientUnits: "userSpaceOnUse", children: [
|
|
739
|
+
/* @__PURE__ */ jsx8("stop", { stopColor: "#FF9F17" }),
|
|
740
|
+
/* @__PURE__ */ jsx8("stop", { offset: "1", stopColor: "#F06408" })
|
|
741
|
+
] }),
|
|
742
|
+
/* @__PURE__ */ jsxs4("linearGradient", { id: "walros-seasonal-stem", x1: "83", y1: "15", x2: "105", y2: "55", gradientUnits: "userSpaceOnUse", children: [
|
|
743
|
+
/* @__PURE__ */ jsx8("stop", { stopColor: "#45933D" }),
|
|
744
|
+
/* @__PURE__ */ jsx8("stop", { offset: "1", stopColor: "#1D642C" })
|
|
745
|
+
] })
|
|
746
|
+
] }),
|
|
747
|
+
/* @__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)" }),
|
|
748
|
+
/* @__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)" }),
|
|
749
|
+
/* @__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" }),
|
|
750
|
+
/* @__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" }),
|
|
751
|
+
/* @__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" })
|
|
752
|
+
] });
|
|
753
|
+
}
|
|
754
|
+
function HeartArrowIcon() {
|
|
755
|
+
return /* @__PURE__ */ jsxs4("svg", { viewBox: "0 0 160 160", fill: "none", "aria-hidden": "true", children: [
|
|
756
|
+
/* @__PURE__ */ jsxs4("defs", { children: [
|
|
757
|
+
/* @__PURE__ */ jsxs4("linearGradient", { id: "walros-seasonal-heart", x1: "40", y1: "51", x2: "123", y2: "129", gradientUnits: "userSpaceOnUse", children: [
|
|
758
|
+
/* @__PURE__ */ jsx8("stop", { stopColor: "#FF5457" }),
|
|
759
|
+
/* @__PURE__ */ jsx8("stop", { offset: "1", stopColor: "#D41E32" })
|
|
760
|
+
] }),
|
|
761
|
+
/* @__PURE__ */ jsxs4("linearGradient", { id: "walros-seasonal-gold", x1: "24", y1: "24", x2: "135", y2: "133", gradientUnits: "userSpaceOnUse", children: [
|
|
762
|
+
/* @__PURE__ */ jsx8("stop", { stopColor: "#FFE958" }),
|
|
763
|
+
/* @__PURE__ */ jsx8("stop", { offset: "1", stopColor: "#F3AE19" })
|
|
764
|
+
] })
|
|
765
|
+
] }),
|
|
766
|
+
/* @__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" }),
|
|
767
|
+
/* @__PURE__ */ jsx8("path", { d: "M76 44c-13-9-28-2-33 12", stroke: "#FF9A90", strokeWidth: "6", strokeLinecap: "round", opacity: ".45" }),
|
|
768
|
+
/* @__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" }),
|
|
769
|
+
/* @__PURE__ */ jsx8("path", { d: "m31 53 96 72", stroke: "#F5B415", strokeWidth: "13", strokeLinecap: "round" }),
|
|
770
|
+
/* @__PURE__ */ jsx8("path", { d: "M72 89c0-16 11-24 24-22", stroke: "#AE1830", strokeWidth: "9", strokeLinecap: "round" })
|
|
771
|
+
] });
|
|
772
|
+
}
|
|
773
|
+
function Decoration({ season }) {
|
|
774
|
+
if (season === "halloween") return /* @__PURE__ */ jsx8(PumpkinIcon, {});
|
|
775
|
+
if (season === "winter") return /* @__PURE__ */ jsx8(SnowIcon, {});
|
|
776
|
+
return /* @__PURE__ */ jsx8(HeartArrowIcon, {});
|
|
777
|
+
}
|
|
778
|
+
function getSeasonColor(season) {
|
|
779
|
+
if (season === "halloween") return "transparent";
|
|
780
|
+
if (season === "winter") return "#78B7E8";
|
|
781
|
+
return "transparent";
|
|
782
|
+
}
|
|
783
|
+
function WalrosSeasonalBackground({
|
|
784
|
+
children,
|
|
785
|
+
season = "auto",
|
|
786
|
+
timeZone = "Europe/Madrid",
|
|
787
|
+
density = 20,
|
|
788
|
+
enabled = true,
|
|
789
|
+
className,
|
|
790
|
+
contentClassName,
|
|
791
|
+
style
|
|
792
|
+
}) {
|
|
793
|
+
useEffect2(() => installStyles(), []);
|
|
794
|
+
const automaticSeason = useAutomaticSeason(timeZone);
|
|
795
|
+
const activeSeason = season === "auto" ? automaticSeason : season === "none" ? null : season;
|
|
796
|
+
const particleCount = Math.max(1, Math.min(PARTICLES.length, Math.round(density)));
|
|
797
|
+
const particles = useMemo(() => PARTICLES.slice(0, particleCount), [particleCount]);
|
|
798
|
+
return /* @__PURE__ */ jsxs4("div", { className: classNames("walros-seasonal-background", className), style, children: [
|
|
799
|
+
enabled && activeSeason && /* @__PURE__ */ jsx8("div", { className: "walros-seasonal-background__decorations", "aria-hidden": "true", children: particles.map(([, top, , duration, sway], index) => {
|
|
800
|
+
const elapsed = index / particleCount * duration;
|
|
801
|
+
return /* @__PURE__ */ jsx8(
|
|
802
|
+
"span",
|
|
803
|
+
{
|
|
804
|
+
className: "walros-seasonal-background__particle",
|
|
805
|
+
style: {
|
|
806
|
+
"--walros-seasonal-top": `${top}%`,
|
|
807
|
+
"--walros-seasonal-delay": `-${elapsed}s`,
|
|
808
|
+
"--walros-seasonal-duration": `${duration}s`,
|
|
809
|
+
"--walros-seasonal-sway": `${sway}px`,
|
|
810
|
+
"--walros-seasonal-opacity": ".52",
|
|
811
|
+
"--walros-seasonal-color": getSeasonColor(activeSeason)
|
|
812
|
+
},
|
|
813
|
+
children: /* @__PURE__ */ jsx8(Decoration, { season: activeSeason })
|
|
814
|
+
},
|
|
815
|
+
`${activeSeason}-${index}`
|
|
816
|
+
);
|
|
817
|
+
}) }),
|
|
818
|
+
/* @__PURE__ */ jsx8("div", { className: classNames("walros-seasonal-background__content", contentClassName), children })
|
|
819
|
+
] });
|
|
820
|
+
}
|
|
821
|
+
|
|
566
822
|
// src/hooks/useWalrosTheme.ts
|
|
567
823
|
import {
|
|
568
824
|
useCallback,
|
|
569
|
-
useEffect as
|
|
825
|
+
useEffect as useEffect3,
|
|
570
826
|
useRef as useRef3,
|
|
571
|
-
useState as
|
|
827
|
+
useState as useState5
|
|
572
828
|
} from "react";
|
|
573
829
|
var GLITCH_BASE_CLASS = "walros-theme-glitch-page";
|
|
574
830
|
var GLITCH_BODY_CLASS = "walros-theme-glitch-page--body";
|
|
@@ -615,11 +871,11 @@ function useWalrosTheme({
|
|
|
615
871
|
lockScroll,
|
|
616
872
|
onAfterUnlock
|
|
617
873
|
} = {}) {
|
|
618
|
-
const [theme, setThemeState] =
|
|
874
|
+
const [theme, setThemeState] = useState5(
|
|
619
875
|
() => readInitialTheme(storageKey, defaultTheme, useSystemPreference)
|
|
620
876
|
);
|
|
621
|
-
const [mounted, setMounted] =
|
|
622
|
-
const [glitching, setGlitching] =
|
|
877
|
+
const [mounted, setMounted] = useState5(false);
|
|
878
|
+
const [glitching, setGlitching] = useState5(false);
|
|
623
879
|
const themeRef = useRef3(theme);
|
|
624
880
|
const glitchingRef = useRef3(false);
|
|
625
881
|
const swapTimerRef = useRef3(null);
|
|
@@ -674,7 +930,7 @@ function useWalrosTheme({
|
|
|
674
930
|
},
|
|
675
931
|
[storageKey]
|
|
676
932
|
);
|
|
677
|
-
|
|
933
|
+
useEffect3(() => {
|
|
678
934
|
const initialTheme = readInitialTheme(
|
|
679
935
|
storageKey,
|
|
680
936
|
defaultTheme,
|
|
@@ -809,7 +1065,7 @@ function useWalrosTheme({
|
|
|
809
1065
|
finishGlitch();
|
|
810
1066
|
}, effectiveDuration);
|
|
811
1067
|
}, [finishGlitch, lockViewport, persistTheme, playThemeSound, swapDelay, totalDuration]);
|
|
812
|
-
|
|
1068
|
+
useEffect3(() => {
|
|
813
1069
|
return () => {
|
|
814
1070
|
clearTimers();
|
|
815
1071
|
removeShakeClasses();
|
|
@@ -834,12 +1090,16 @@ export {
|
|
|
834
1090
|
Walros3DPortalTransition,
|
|
835
1091
|
WalrosLogo,
|
|
836
1092
|
WalrosPortalTransition,
|
|
1093
|
+
WalrosSeasonalBackground,
|
|
837
1094
|
WalrosThemeGlitch,
|
|
838
1095
|
WalrosThemeTransition,
|
|
839
1096
|
WalrosWordmark,
|
|
1097
|
+
getWalrosSeason,
|
|
840
1098
|
useWalrosTheme,
|
|
841
1099
|
walrosLogoChromeUrl,
|
|
842
1100
|
walrosPortalSilhouetteUrl,
|
|
1101
|
+
walrosSeasonalHeartArrowUrl,
|
|
1102
|
+
walrosSeasonalPumpkinUrl,
|
|
843
1103
|
walrosThemeGlitchSoundUrl,
|
|
844
1104
|
walrosWordmarkDarkUrl,
|
|
845
1105
|
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\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","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?.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","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; }\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.directional-cursor-hand { display: none; position: absolute; top: 0; left: 0; width: 32px; height: 32px; transform: translate(-8px, -2px); image-rendering: auto; }\n.directional-cursor.is-hand .directional-cursor-shape { display: none; }\n.directional-cursor.is-hand .directional-cursor-hand { display: block; }\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}\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, label, [role=\"button\"], [role=\"link\"], [role=\"menuitem\"], [role=\"option\"], [role=\"tab\"], [aria-haspopup=\"true\"], [data-cursor-hand], 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;\n let targetScale = 1;\n let lastX = currentX;\n let lastY = 0;\n\n const updateCursorMode = (eventTarget: EventTarget | null) => {\n const target = eventTarget instanceof Element ? eventTarget : null;\n const textEntry = target?.closest(TEXT_ENTRY_SELECTOR);\n const interactive = target?.closest(INTERACTIVE_SELECTOR);\n\n // Text inputs deliberately preserve the native I-beam. Every other\n // state stays inside this overlay, so an OS pointer never flashes next\n // to the WalrOS cursor while entering a control.\n position.classList.toggle(\"is-visible\", !textEntry);\n position.classList.toggle(\"is-hand\", Boolean(interactive && !textEntry));\n };\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 updateCursorMode(event.target);\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) => {\n latestEvent = event;\n if (!moveFrame) moveFrame = window.requestAnimationFrame(processMove);\n };\n\n const handleMouseOver = (event: MouseEvent) => {\n updateCursorMode(event.target);\n };\n\r\n const activate = () => {\r\n if (active) return;\r\n active = true;\n document.documentElement.classList.add(\"has-directional-cursor\");\n window.addEventListener(\"mousemove\", handleMouseMove, { passive: true });\n window.addEventListener(\"mouseover\", handleMouseOver, { passive: true });\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\");\n position.classList.remove(\"is-hand\");\n window.removeEventListener(\"mousemove\", handleMouseMove);\n window.removeEventListener(\"mouseover\", handleMouseOver);\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\">\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>\n </div>\n <img className=\"directional-cursor-hand\" src={walrosHandCursor} alt=\"\" />\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"]}
|