@nous-research/ui 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/ui/components/icons/discord.d.ts +3 -0
- package/dist/ui/components/icons/discord.d.ts.map +1 -0
- package/dist/ui/components/icons/discord.js +6 -0
- package/dist/ui/components/icons/discord.js.map +1 -0
- package/dist/ui/components/icons/github.d.ts +3 -0
- package/dist/ui/components/icons/github.d.ts.map +1 -0
- package/dist/ui/components/icons/github.js +6 -0
- package/dist/ui/components/icons/github.js.map +1 -0
- package/dist/ui/components/icons/index.d.ts +2 -0
- package/dist/ui/components/icons/index.d.ts.map +1 -1
- package/dist/ui/components/icons/index.js +2 -0
- package/dist/ui/components/icons/index.js.map +1 -1
- package/dist/ui/components/overlays/blend-modes.d.ts +2 -0
- package/dist/ui/components/overlays/blend-modes.d.ts.map +1 -0
- package/dist/ui/components/overlays/blend-modes.js +14 -0
- package/dist/ui/components/overlays/blend-modes.js.map +1 -0
- package/dist/ui/components/overlays/glitch.js +1 -1
- package/dist/ui/components/overlays/glitch.js.map +1 -1
- package/dist/ui/components/overlays/greys.js +1 -1
- package/dist/ui/components/overlays/greys.js.map +1 -1
- package/dist/ui/components/overlays/index.d.ts +9 -53
- package/dist/ui/components/overlays/index.d.ts.map +1 -1
- package/dist/ui/components/overlays/index.js +9 -135
- package/dist/ui/components/overlays/index.js.map +1 -1
- package/dist/ui/components/overlays/lens-layers.d.ts +15 -0
- package/dist/ui/components/overlays/lens-layers.d.ts.map +1 -0
- package/dist/ui/components/overlays/lens-layers.js +68 -0
- package/dist/ui/components/overlays/lens-layers.js.map +1 -0
- package/dist/ui/components/overlays/lens.d.ts +45 -0
- package/dist/ui/components/overlays/lens.d.ts.map +1 -0
- package/dist/ui/components/overlays/lens.js +65 -0
- package/dist/ui/components/overlays/lens.js.map +1 -0
- package/dist/ui/components/overlays/noise.js +1 -1
- package/dist/ui/components/overlays/noise.js.map +1 -1
- package/dist/ui/components/overlays/vignette.js +1 -1
- package/dist/ui/components/overlays/vignette.js.map +1 -1
- package/dist/ui/components/socials.d.ts +21 -0
- package/dist/ui/components/socials.d.ts.map +1 -0
- package/dist/ui/components/socials.js +9 -0
- package/dist/ui/components/socials.js.map +1 -0
- package/dist/ui/footer.d.ts +18 -3
- package/dist/ui/footer.d.ts.map +1 -1
- package/dist/ui/footer.js +13 -3
- package/dist/ui/footer.js.map +1 -1
- package/dist/ui/header.d.ts +39 -3
- package/dist/ui/header.d.ts.map +1 -1
- package/dist/ui/header.js +58 -5
- package/dist/ui/header.js.map +1 -1
- package/package.json +3 -1
|
@@ -1,145 +1,19 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { atom } from 'nanostores';
|
|
4
|
-
import { useEffect } from 'react';
|
|
5
|
-
import { setControlValue, useSmoothControls } from '../../../hooks/use-smooth-controls';
|
|
6
|
-
import { colorMix } from '../../../utils/color';
|
|
7
|
-
import fillerBg from '../../../assets/filler-bg0.jpg';
|
|
8
3
|
import { Glitch } from './glitch';
|
|
9
4
|
import { Greys } from './greys';
|
|
5
|
+
import { Lens } from './lens-layers';
|
|
10
6
|
import { Noise } from './noise';
|
|
11
7
|
import { Vignette } from './vignette';
|
|
8
|
+
export { BLEND_MODES } from './blend-modes';
|
|
9
|
+
export { Glitch } from './glitch';
|
|
10
|
+
export { Greys } from './greys';
|
|
11
|
+
export { Lens } from './lens-layers';
|
|
12
|
+
export { Noise } from './noise';
|
|
13
|
+
export { Vignette } from './vignette';
|
|
14
|
+
export { $lightMode, applyLens, lens0, lens5i, LENS_0, LENS_5I, LENSES, toggleLens } from './lens';
|
|
12
15
|
const LAYER = 'pointer-events-none fixed inset-0';
|
|
13
|
-
export const BLEND_MODES = [
|
|
14
|
-
'overlay',
|
|
15
|
-
'multiply',
|
|
16
|
-
'screen',
|
|
17
|
-
'difference',
|
|
18
|
-
'exclusion',
|
|
19
|
-
'color-dodge',
|
|
20
|
-
'color-burn',
|
|
21
|
-
'hard-light',
|
|
22
|
-
'soft-light',
|
|
23
|
-
'darken',
|
|
24
|
-
'lighten'
|
|
25
|
-
];
|
|
26
|
-
export const LENS_0 = {
|
|
27
|
-
Globe: { innerColor: '#170d02', innerOpacity: 0.1, outerColor: '#FFAC02' },
|
|
28
|
-
Lens: {
|
|
29
|
-
bgBlend: 'difference',
|
|
30
|
-
bgColor: '#041C1C',
|
|
31
|
-
bgOpacity: 1,
|
|
32
|
-
fgColor: '#FFFFFF',
|
|
33
|
-
fgOpacity: 0,
|
|
34
|
-
fillerOpacity: 0.033,
|
|
35
|
-
mgColor: '#ffe6cb',
|
|
36
|
-
mgOpacity: 1
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
export const LENS_5I = {
|
|
40
|
-
Globe: { innerColor: '#170d02', innerOpacity: 0.3, outerColor: '#FFAC02' },
|
|
41
|
-
Lens: {
|
|
42
|
-
bgBlend: 'multiply',
|
|
43
|
-
bgColor: '#170d02',
|
|
44
|
-
bgOpacity: 1,
|
|
45
|
-
fgColor: '#FFFFFF',
|
|
46
|
-
fgOpacity: 1,
|
|
47
|
-
fillerOpacity: 0.06,
|
|
48
|
-
mgColor: '#FFAC02',
|
|
49
|
-
mgOpacity: 1
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
export const lens0 = (l, g) => ({
|
|
53
|
-
Globe: { ...LENS_0.Globe, ...g },
|
|
54
|
-
Lens: { ...LENS_0.Lens, ...l }
|
|
55
|
-
});
|
|
56
|
-
// The Hermes light-mode look is produced by a fullscreen opaque-white
|
|
57
|
-
// `mix-blend-mode: difference` foreground layer that inverts everything.
|
|
58
|
-
// Colored lenses that want a "white + accent" look MUST be built from
|
|
59
|
-
// LENS_5I, not LENS_0 — otherwise `bgBlend: 'difference'` + an opaque
|
|
60
|
-
// colored bg + active fg inversion land halfway between dark and light
|
|
61
|
-
// mode and produce a muddy warm wash instead of a clean inversion.
|
|
62
|
-
export const lens5i = (l, g) => ({
|
|
63
|
-
Globe: { ...LENS_5I.Globe, ...g },
|
|
64
|
-
Lens: { ...LENS_5I.Lens, ...l }
|
|
65
|
-
});
|
|
66
|
-
// Accent colors are the *pre-inversion* source; after the difference FG
|
|
67
|
-
// layer they read as their visual complement. e.g. `#FFAC02` (orange)
|
|
68
|
-
// renders as blue #0053FD on screen — that's the default LENS_5I accent.
|
|
69
|
-
export const LENSES = [
|
|
70
|
-
['0', LENS_0],
|
|
71
|
-
['1', lens0({ bgColor: '#0A1F1F' })],
|
|
72
|
-
['2', lens0({ bgColor: '#0E0313', mgColor: '#e6cbff' })],
|
|
73
|
-
['3', lens5i({ mgColor: '#FFAC02' })],
|
|
74
|
-
['4', lens5i({ bgColor: '#0E0313', mgColor: '#FF5500' })],
|
|
75
|
-
['5', lens0({ bgColor: '#1540B1', bgOpacity: 0.7 })],
|
|
76
|
-
['5i', LENS_5I],
|
|
77
|
-
['6', lens5i({ bgColor: '#170D02', mgColor: '#00E5FF' })]
|
|
78
|
-
];
|
|
79
|
-
export const applyLens = (preset, animate = false) => Object.entries(preset).forEach(([g, v]) => Object.entries(v).forEach(([k, val]) => setControlValue(g, k, val, { animate })));
|
|
80
|
-
export const $lightMode = atom(true);
|
|
81
|
-
export const toggleLens = () => {
|
|
82
|
-
const isLight = $lightMode.get();
|
|
83
|
-
const next = isLight ? LENS_0 : LENS_5I;
|
|
84
|
-
$lightMode.set(!isLight);
|
|
85
|
-
applyLens(next, true);
|
|
86
|
-
};
|
|
87
16
|
export function Overlays({ dark, initial }) {
|
|
88
|
-
|
|
89
|
-
// the *exact* lens preset the user selected, avoiding a one-cycle lag
|
|
90
|
-
// where useSmoothControls emits old colors for the first paint (and, on
|
|
91
|
-
// Storybook's fast iframe reload, sometimes never catches up because
|
|
92
|
-
// useControls' ready-gate swallows the instant color writes).
|
|
93
|
-
const base = initial?.Lens ?? (dark ? LENS_0.Lens : LENS_5I.Lens);
|
|
94
|
-
const lens = useSmoothControls('Lens', {
|
|
95
|
-
bgBlend: { options: BLEND_MODES, value: base.bgBlend },
|
|
96
|
-
bgColor: { value: base.bgColor },
|
|
97
|
-
bgOpacity: { max: 1, min: 0, step: 0.01, value: base.bgOpacity },
|
|
98
|
-
fgBlend: { options: BLEND_MODES, value: 'difference' },
|
|
99
|
-
fgColor: { value: base.fgColor },
|
|
100
|
-
fgOpacity: { max: 1, min: 0, step: 0.01, value: base.fgOpacity },
|
|
101
|
-
fillerBlend: { options: BLEND_MODES, value: 'difference' },
|
|
102
|
-
fillerOpacity: { max: 1, min: 0, step: 0.01, value: base.fillerOpacity },
|
|
103
|
-
mgColor: { value: base.mgColor },
|
|
104
|
-
mgOpacity: { max: 1, min: 0, step: 0.01, value: base.mgOpacity }
|
|
105
|
-
}, { collapsed: false });
|
|
106
|
-
useEffect(() => {
|
|
107
|
-
$lightMode.set(!dark);
|
|
108
|
-
}, [dark]);
|
|
109
|
-
useEffect(() => {
|
|
110
|
-
const s = document.documentElement.style;
|
|
111
|
-
for (const [name, color, alpha] of [
|
|
112
|
-
['foreground', lens.fgColor, lens.fgOpacity],
|
|
113
|
-
['midground', lens.mgColor, lens.mgOpacity],
|
|
114
|
-
['background', lens.bgColor, lens.bgOpacity]
|
|
115
|
-
]) {
|
|
116
|
-
s.setProperty(`--${name}`, colorMix(color, alpha));
|
|
117
|
-
s.setProperty(`--${name}-base`, color);
|
|
118
|
-
s.setProperty(`--${name}-alpha`, `${alpha}`);
|
|
119
|
-
}
|
|
120
|
-
}, [lens]);
|
|
121
|
-
useEffect(() => {
|
|
122
|
-
const handle = (e) => e.key === 'x' && toggleLens();
|
|
123
|
-
window.addEventListener('keydown', handle);
|
|
124
|
-
return () => window.removeEventListener('keydown', handle);
|
|
125
|
-
}, []);
|
|
126
|
-
// NOTE: z-index is inlined because Tailwind's JIT sometimes doesn't emit
|
|
127
|
-
// these non-default utilities (e.g. in Storybook's isolated content
|
|
128
|
-
// scan), which silently collapses the overlay stack to DOM order and
|
|
129
|
-
// breaks the mix-blend-mode inversion — producing a muddy warm wash
|
|
130
|
-
// instead of the intended clean black/white inversion.
|
|
131
|
-
return (_jsxs(_Fragment, { children: [_jsx(Noise, { className: LAYER, style: { zIndex: 101 } }), _jsx("div", { className: LAYER, style: {
|
|
132
|
-
backgroundColor: colorMix(lens.fgColor, lens.fgOpacity),
|
|
133
|
-
mixBlendMode: lens.fgBlend,
|
|
134
|
-
zIndex: 100
|
|
135
|
-
} }), _jsx(Vignette, { className: LAYER, style: { zIndex: 99 } }), _jsx(Greys, { className: LAYER, style: { zIndex: 200 } }), _jsx(Glitch, { className: LAYER, style: { zIndex: 201 } }), _jsx("div", { className: LAYER, style: {
|
|
136
|
-
mixBlendMode: lens.fillerBlend,
|
|
137
|
-
opacity: lens.fillerOpacity,
|
|
138
|
-
zIndex: 2
|
|
139
|
-
}, children: _jsx("img", { alt: "", className: "h-[150dvh] w-auto min-w-dvw object-cover object-top-left invert", fetchPriority: "low", src: fillerBg.src }) }), _jsx("div", { className: LAYER, style: {
|
|
140
|
-
backgroundColor: colorMix(lens.bgColor, lens.bgOpacity),
|
|
141
|
-
mixBlendMode: lens.bgBlend,
|
|
142
|
-
zIndex: 1
|
|
143
|
-
} })] }));
|
|
17
|
+
return (_jsxs(_Fragment, { children: [_jsx(Lens, { dark: dark, initial: initial }), _jsx(Noise, { className: LAYER, style: { zIndex: 101 } }), _jsx(Vignette, { className: LAYER, style: { zIndex: 99 } }), _jsx(Greys, { className: LAYER, style: { zIndex: 200 } }), _jsx(Glitch, { className: LAYER, style: { zIndex: 201 } })] }));
|
|
144
18
|
}
|
|
145
19
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/ui/components/overlays/index.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client'\n\nimport { atom } from 'nanostores'\nimport { useEffect } from 'react'\n\nimport {\n getControlAtom,\n setControlValue,\n useSmoothControls\n} from '../../../hooks/use-smooth-controls'\nimport { colorMix } from '../../../utils/color'\n\nimport fillerBg from '../../../assets/filler-bg0.jpg'\n\nimport { Glitch } from './glitch'\nimport { Greys } from './greys'\nimport { Noise } from './noise'\nimport { Vignette } from './vignette'\n\nconst LAYER = 'pointer-events-none fixed inset-0'\n\nexport const BLEND_MODES = [\n 'overlay',\n 'multiply',\n 'screen',\n 'difference',\n 'exclusion',\n 'color-dodge',\n 'color-burn',\n 'hard-light',\n 'soft-light',\n 'darken',\n 'lighten'\n] as unknown as React.CSSProperties['mixBlendMode'][]\n\nexport const LENS_0 = {\n Globe: { innerColor: '#170d02', innerOpacity: 0.1, outerColor: '#FFAC02' },\n Lens: {\n bgBlend: 'difference',\n bgColor: '#041C1C',\n bgOpacity: 1,\n fgColor: '#FFFFFF',\n fgOpacity: 0,\n fillerOpacity: 0.033,\n mgColor: '#ffe6cb',\n mgOpacity: 1\n }\n}\n\nexport const LENS_5I = {\n Globe: { innerColor: '#170d02', innerOpacity: 0.3, outerColor: '#FFAC02' },\n Lens: {\n bgBlend: 'multiply',\n bgColor: '#170d02',\n bgOpacity: 1,\n fgColor: '#FFFFFF',\n fgOpacity: 1,\n fillerOpacity: 0.06,\n mgColor: '#FFAC02',\n mgOpacity: 1\n }\n}\n\nexport const lens0 = (\n l?: Partial<typeof LENS_0.Lens>,\n g?: Partial<typeof LENS_0.Globe>\n): LensPreset => ({\n Globe: { ...LENS_0.Globe, ...g },\n Lens: { ...LENS_0.Lens, ...l }\n})\n\n// The Hermes light-mode look is produced by a fullscreen opaque-white\n// `mix-blend-mode: difference` foreground layer that inverts everything.\n// Colored lenses that want a \"white + accent\" look MUST be built from\n// LENS_5I, not LENS_0 — otherwise `bgBlend: 'difference'` + an opaque\n// colored bg + active fg inversion land halfway between dark and light\n// mode and produce a muddy warm wash instead of a clean inversion.\nexport const lens5i = (\n l?: Partial<typeof LENS_5I.Lens>,\n g?: Partial<typeof LENS_5I.Globe>\n): LensPreset => ({\n Globe: { ...LENS_5I.Globe, ...g },\n Lens: { ...LENS_5I.Lens, ...l }\n})\n\n// Accent colors are the *pre-inversion* source; after the difference FG\n// layer they read as their visual complement. e.g. `#FFAC02` (orange)\n// renders as blue #0053FD on screen — that's the default LENS_5I accent.\nexport const LENSES: [string, LensPreset][] = [\n ['0', LENS_0],\n ['1', lens0({ bgColor: '#0A1F1F' })],\n ['2', lens0({ bgColor: '#0E0313', mgColor: '#e6cbff' })],\n ['3', lens5i({ mgColor: '#FFAC02' })],\n ['4', lens5i({ bgColor: '#0E0313', mgColor: '#FF5500' })],\n ['5', lens0({ bgColor: '#1540B1', bgOpacity: 0.7 })],\n ['5i', LENS_5I],\n ['6', lens5i({ bgColor: '#170D02', mgColor: '#00E5FF' })]\n]\n\nexport const applyLens = (preset: LensPreset, animate = false) =>\n Object.entries(preset).forEach(([g, v]) =>\n Object.entries(v).forEach(([k, val]) =>\n setControlValue(g, k, val, { animate })\n )\n )\n\nexport const $lightMode = atom(true)\n\nexport const toggleLens = () => {\n const isLight = $lightMode.get()\n const next = isLight ? LENS_0 : LENS_5I\n\n $lightMode.set(!isLight)\n applyLens(next, true)\n}\n\nexport function Overlays({ dark, initial }: OverlaysProps) {\n // `initial` lets the host (e.g. Storybook) seed the Leva/atom state with\n // the *exact* lens preset the user selected, avoiding a one-cycle lag\n // where useSmoothControls emits old colors for the first paint (and, on\n // Storybook's fast iframe reload, sometimes never catches up because\n // useControls' ready-gate swallows the instant color writes).\n const base = initial?.Lens ?? (dark ? LENS_0.Lens : LENS_5I.Lens)\n\n const lens = useSmoothControls(\n 'Lens',\n {\n bgBlend: { options: BLEND_MODES, value: base.bgBlend as 'multiply' },\n bgColor: { value: base.bgColor },\n bgOpacity: { max: 1, min: 0, step: 0.01, value: base.bgOpacity },\n fgBlend: { options: BLEND_MODES, value: 'difference' as const },\n fgColor: { value: base.fgColor },\n fgOpacity: { max: 1, min: 0, step: 0.01, value: base.fgOpacity },\n fillerBlend: { options: BLEND_MODES, value: 'difference' as const },\n fillerOpacity: { max: 1, min: 0, step: 0.01, value: base.fillerOpacity },\n mgColor: { value: base.mgColor },\n mgOpacity: { max: 1, min: 0, step: 0.01, value: base.mgOpacity }\n },\n { collapsed: false }\n )\n\n useEffect(() => {\n $lightMode.set(!dark)\n }, [dark])\n\n useEffect(() => {\n const s = document.documentElement.style\n\n for (const [name, color, alpha] of [\n ['foreground', lens.fgColor, lens.fgOpacity],\n ['midground', lens.mgColor, lens.mgOpacity],\n ['background', lens.bgColor, lens.bgOpacity]\n ] as [string, string, number][]) {\n s.setProperty(`--${name}`, colorMix(color, alpha))\n s.setProperty(`--${name}-base`, color)\n s.setProperty(`--${name}-alpha`, `${alpha}`)\n }\n }, [lens])\n\n useEffect(() => {\n const handle = (e: KeyboardEvent) => e.key === 'x' && toggleLens()\n window.addEventListener('keydown', handle)\n return () => window.removeEventListener('keydown', handle)\n }, [])\n\n // NOTE: z-index is inlined because Tailwind's JIT sometimes doesn't emit\n // these non-default utilities (e.g. in Storybook's isolated content\n // scan), which silently collapses the overlay stack to DOM order and\n // breaks the mix-blend-mode inversion — producing a muddy warm wash\n // instead of the intended clean black/white inversion.\n return (\n <>\n <Noise className={LAYER} style={{ zIndex: 101 }} />\n\n <div\n className={LAYER}\n style={{\n backgroundColor: colorMix(lens.fgColor, lens.fgOpacity),\n mixBlendMode: lens.fgBlend,\n zIndex: 100\n }}\n />\n\n <Vignette className={LAYER} style={{ zIndex: 99 }} />\n <Greys className={LAYER} style={{ zIndex: 200 }} />\n <Glitch className={LAYER} style={{ zIndex: 201 }} />\n\n <div\n className={LAYER}\n style={{\n mixBlendMode: lens.fillerBlend,\n opacity: lens.fillerOpacity,\n zIndex: 2\n }}\n >\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n alt=\"\"\n className=\"h-[150dvh] w-auto min-w-dvw object-cover object-top-left invert\"\n fetchPriority=\"low\"\n src={fillerBg.src}\n />\n </div>\n\n <div\n className={LAYER}\n style={{\n backgroundColor: colorMix(lens.bgColor, lens.bgOpacity),\n mixBlendMode: lens.bgBlend,\n zIndex: 1\n }}\n />\n </>\n )\n}\n\nexport interface LensPreset {\n Globe: typeof LENS_0.Globe\n Lens: typeof LENS_0.Lens\n}\n\ninterface OverlaysProps {\n dark?: boolean\n /**\n * Exact preset to seed the internal Leva controls with. When omitted the\n * component falls back to `LENS_0` / `LENS_5I` based on `dark`. Pass the\n * actual preset from a host (e.g. Storybook toolbar) to guarantee the\n * first-paint colors match the selected lens without needing a followup\n * `applyLens` that can be lost in useSmoothControls' startup window.\n */\n initial?: LensPreset\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/ui/components/overlays/index.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAIrC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACrC,OAAO,EACL,UAAU,EACV,SAAS,EACT,KAAK,EACL,MAAM,EACN,MAAM,EACN,OAAO,EACP,MAAM,EACN,UAAU,EACX,MAAM,QAAQ,CAAA;AAGf,MAAM,KAAK,GAAG,mCAAmC,CAAA;AAEjD,MAAM,UAAU,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAiB;IACvD,OAAO,CACL,8BACE,KAAC,IAAI,IAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,GAAI,EAEtC,KAAC,KAAK,IAAC,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,GAAI,EACnD,KAAC,QAAQ,IAAC,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,GAAI,EACrD,KAAC,KAAK,IAAC,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,GAAI,EACnD,KAAC,MAAM,IAAC,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,GAAI,IACnD,CACJ,CAAA;AACH,CAAC","sourcesContent":["'use client'\n\nimport { Glitch } from './glitch'\nimport { Greys } from './greys'\nimport { Lens } from './lens-layers'\nimport { Noise } from './noise'\nimport { Vignette } from './vignette'\n\nimport type { LensPreset } from './lens'\n\nexport { BLEND_MODES } from './blend-modes'\nexport { Glitch } from './glitch'\nexport { Greys } from './greys'\nexport { Lens } from './lens-layers'\nexport { Noise } from './noise'\nexport { Vignette } from './vignette'\nexport {\n $lightMode,\n applyLens,\n lens0,\n lens5i,\n LENS_0,\n LENS_5I,\n LENSES,\n toggleLens\n} from './lens'\nexport type { LensPreset } from './lens'\n\nconst LAYER = 'pointer-events-none fixed inset-0'\n\nexport function Overlays({ dark, initial }: OverlaysProps) {\n return (\n <>\n <Lens dark={dark} initial={initial} />\n\n <Noise className={LAYER} style={{ zIndex: 101 }} />\n <Vignette className={LAYER} style={{ zIndex: 99 }} />\n <Greys className={LAYER} style={{ zIndex: 200 }} />\n <Glitch className={LAYER} style={{ zIndex: 201 }} />\n </>\n )\n}\n\ninterface OverlaysProps {\n dark?: boolean\n initial?: LensPreset\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type LensPreset } from './lens';
|
|
2
|
+
export declare function Lens({ dark, initial }: LensProps): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
interface LensProps {
|
|
4
|
+
dark?: boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Exact preset to seed the internal Leva controls with. When omitted the
|
|
7
|
+
* component falls back to `LENS_0` / `LENS_5I` based on `dark`. Pass the
|
|
8
|
+
* actual preset from a host (e.g. Storybook toolbar) to guarantee the
|
|
9
|
+
* first-paint colors match the selected lens without needing a followup
|
|
10
|
+
* `applyLens` that can be lost in useSmoothControls' startup window.
|
|
11
|
+
*/
|
|
12
|
+
initial?: LensPreset;
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=lens-layers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lens-layers.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/overlays/lens-layers.tsx"],"names":[],"mappings":"AAUA,OAAO,EAA+B,KAAK,UAAU,EAAc,MAAM,QAAQ,CAAA;AAIjF,wBAAgB,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,SAAS,2CA4FhD;AAED,UAAU,SAAS;IACjB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,UAAU,CAAA;CACrB"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect } from 'react';
|
|
4
|
+
import { useSmoothControls } from '../../../hooks/use-smooth-controls';
|
|
5
|
+
import { colorMix } from '../../../utils/color';
|
|
6
|
+
import fillerBg from '../../../assets/filler-bg0.jpg';
|
|
7
|
+
import { BLEND_MODES } from './blend-modes';
|
|
8
|
+
import { $lightMode, LENS_0, LENS_5I, toggleLens } from './lens';
|
|
9
|
+
const LAYER = 'pointer-events-none fixed inset-0';
|
|
10
|
+
export function Lens({ dark, initial }) {
|
|
11
|
+
// `initial` lets the host (e.g. Storybook) seed the Leva/atom state with
|
|
12
|
+
// the *exact* lens preset the user selected, avoiding a one-cycle lag
|
|
13
|
+
// where useSmoothControls emits old colors for the first paint (and, on
|
|
14
|
+
// Storybook's fast iframe reload, sometimes never catches up because
|
|
15
|
+
// useControls' ready-gate swallows the instant color writes).
|
|
16
|
+
const base = initial?.Lens ?? (dark ? LENS_0.Lens : LENS_5I.Lens);
|
|
17
|
+
const lens = useSmoothControls('Lens', {
|
|
18
|
+
bgBlend: { options: BLEND_MODES, value: base.bgBlend },
|
|
19
|
+
bgColor: { value: base.bgColor },
|
|
20
|
+
bgOpacity: { max: 1, min: 0, step: 0.01, value: base.bgOpacity },
|
|
21
|
+
fgBlend: { options: BLEND_MODES, value: 'difference' },
|
|
22
|
+
fgColor: { value: base.fgColor },
|
|
23
|
+
fgOpacity: { max: 1, min: 0, step: 0.01, value: base.fgOpacity },
|
|
24
|
+
fillerBlend: { options: BLEND_MODES, value: 'difference' },
|
|
25
|
+
fillerOpacity: { max: 1, min: 0, step: 0.01, value: base.fillerOpacity },
|
|
26
|
+
mgColor: { value: base.mgColor },
|
|
27
|
+
mgOpacity: { max: 1, min: 0, step: 0.01, value: base.mgOpacity }
|
|
28
|
+
}, { collapsed: false });
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
$lightMode.set(!dark);
|
|
31
|
+
}, [dark]);
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
const s = document.documentElement.style;
|
|
34
|
+
for (const [name, color, alpha] of [
|
|
35
|
+
['foreground', lens.fgColor, lens.fgOpacity],
|
|
36
|
+
['midground', lens.mgColor, lens.mgOpacity],
|
|
37
|
+
['background', lens.bgColor, lens.bgOpacity]
|
|
38
|
+
]) {
|
|
39
|
+
s.setProperty(`--${name}`, colorMix(color, alpha));
|
|
40
|
+
s.setProperty(`--${name}-base`, color);
|
|
41
|
+
s.setProperty(`--${name}-alpha`, `${alpha}`);
|
|
42
|
+
}
|
|
43
|
+
}, [lens]);
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
const handle = (e) => e.key === 'x' && toggleLens();
|
|
46
|
+
window.addEventListener('keydown', handle);
|
|
47
|
+
return () => window.removeEventListener('keydown', handle);
|
|
48
|
+
}, []);
|
|
49
|
+
// NOTE: z-index is inlined because Tailwind's JIT sometimes doesn't emit
|
|
50
|
+
// these non-default utilities (e.g. in Storybook's isolated content
|
|
51
|
+
// scan), which silently collapses the overlay stack to DOM order and
|
|
52
|
+
// breaks the mix-blend-mode inversion — producing a muddy warm wash
|
|
53
|
+
// instead of the intended clean black/white inversion.
|
|
54
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: LAYER, style: {
|
|
55
|
+
backgroundColor: colorMix(lens.fgColor, lens.fgOpacity),
|
|
56
|
+
mixBlendMode: lens.fgBlend,
|
|
57
|
+
zIndex: 100
|
|
58
|
+
} }), _jsx("div", { className: LAYER, style: {
|
|
59
|
+
mixBlendMode: lens.fillerBlend,
|
|
60
|
+
opacity: lens.fillerOpacity,
|
|
61
|
+
zIndex: 2
|
|
62
|
+
}, children: _jsx("img", { alt: "", className: "h-[150dvh] w-auto min-w-dvw object-cover object-top-left invert", fetchPriority: "low", src: fillerBg.src }) }), _jsx("div", { className: LAYER, style: {
|
|
63
|
+
backgroundColor: colorMix(lens.bgColor, lens.bgOpacity),
|
|
64
|
+
mixBlendMode: lens.bgBlend,
|
|
65
|
+
zIndex: 1
|
|
66
|
+
} })] }));
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=lens-layers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lens-layers.js","sourceRoot":"","sources":["../../../../src/ui/components/overlays/lens-layers.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client'\n\nimport { useEffect } from 'react'\n\nimport { useSmoothControls } from '../../../hooks/use-smooth-controls'\nimport { colorMix } from '../../../utils/color'\n\nimport fillerBg from '../../../assets/filler-bg0.jpg'\n\nimport { BLEND_MODES } from './blend-modes'\nimport { $lightMode, LENS_0, LENS_5I, type LensPreset, toggleLens } from './lens'\n\nconst LAYER = 'pointer-events-none fixed inset-0'\n\nexport function Lens({ dark, initial }: LensProps) {\n // `initial` lets the host (e.g. Storybook) seed the Leva/atom state with\n // the *exact* lens preset the user selected, avoiding a one-cycle lag\n // where useSmoothControls emits old colors for the first paint (and, on\n // Storybook's fast iframe reload, sometimes never catches up because\n // useControls' ready-gate swallows the instant color writes).\n const base = initial?.Lens ?? (dark ? LENS_0.Lens : LENS_5I.Lens)\n\n const lens = useSmoothControls(\n 'Lens',\n {\n bgBlend: { options: BLEND_MODES, value: base.bgBlend as 'multiply' },\n bgColor: { value: base.bgColor },\n bgOpacity: { max: 1, min: 0, step: 0.01, value: base.bgOpacity },\n fgBlend: { options: BLEND_MODES, value: 'difference' as const },\n fgColor: { value: base.fgColor },\n fgOpacity: { max: 1, min: 0, step: 0.01, value: base.fgOpacity },\n fillerBlend: { options: BLEND_MODES, value: 'difference' as const },\n fillerOpacity: { max: 1, min: 0, step: 0.01, value: base.fillerOpacity },\n mgColor: { value: base.mgColor },\n mgOpacity: { max: 1, min: 0, step: 0.01, value: base.mgOpacity }\n },\n { collapsed: false }\n )\n\n useEffect(() => {\n $lightMode.set(!dark)\n }, [dark])\n\n useEffect(() => {\n const s = document.documentElement.style\n\n for (const [name, color, alpha] of [\n ['foreground', lens.fgColor, lens.fgOpacity],\n ['midground', lens.mgColor, lens.mgOpacity],\n ['background', lens.bgColor, lens.bgOpacity]\n ] as [string, string, number][]) {\n s.setProperty(`--${name}`, colorMix(color, alpha))\n s.setProperty(`--${name}-base`, color)\n s.setProperty(`--${name}-alpha`, `${alpha}`)\n }\n }, [lens])\n\n useEffect(() => {\n const handle = (e: KeyboardEvent) => e.key === 'x' && toggleLens()\n window.addEventListener('keydown', handle)\n return () => window.removeEventListener('keydown', handle)\n }, [])\n\n // NOTE: z-index is inlined because Tailwind's JIT sometimes doesn't emit\n // these non-default utilities (e.g. in Storybook's isolated content\n // scan), which silently collapses the overlay stack to DOM order and\n // breaks the mix-blend-mode inversion — producing a muddy warm wash\n // instead of the intended clean black/white inversion.\n return (\n <>\n <div\n className={LAYER}\n style={{\n backgroundColor: colorMix(lens.fgColor, lens.fgOpacity),\n mixBlendMode: lens.fgBlend,\n zIndex: 100\n }}\n />\n\n <div\n className={LAYER}\n style={{\n mixBlendMode: lens.fillerBlend,\n opacity: lens.fillerOpacity,\n zIndex: 2\n }}\n >\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n alt=\"\"\n className=\"h-[150dvh] w-auto min-w-dvw object-cover object-top-left invert\"\n fetchPriority=\"low\"\n src={fillerBg.src}\n />\n </div>\n\n <div\n className={LAYER}\n style={{\n backgroundColor: colorMix(lens.bgColor, lens.bgOpacity),\n mixBlendMode: lens.bgBlend,\n zIndex: 1\n }}\n />\n </>\n )\n}\n\ninterface LensProps {\n dark?: boolean\n /**\n * Exact preset to seed the internal Leva controls with. When omitted the\n * component falls back to `LENS_0` / `LENS_5I` based on `dark`. Pass the\n * actual preset from a host (e.g. Storybook toolbar) to guarantee the\n * first-paint colors match the selected lens without needing a followup\n * `applyLens` that can be lost in useSmoothControls' startup window.\n */\n initial?: LensPreset\n}\n"]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export declare const LENS_0: {
|
|
2
|
+
Globe: {
|
|
3
|
+
innerColor: string;
|
|
4
|
+
innerOpacity: number;
|
|
5
|
+
outerColor: string;
|
|
6
|
+
};
|
|
7
|
+
Lens: {
|
|
8
|
+
bgBlend: string;
|
|
9
|
+
bgColor: string;
|
|
10
|
+
bgOpacity: number;
|
|
11
|
+
fgColor: string;
|
|
12
|
+
fgOpacity: number;
|
|
13
|
+
fillerOpacity: number;
|
|
14
|
+
mgColor: string;
|
|
15
|
+
mgOpacity: number;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
export declare const LENS_5I: {
|
|
19
|
+
Globe: {
|
|
20
|
+
innerColor: string;
|
|
21
|
+
innerOpacity: number;
|
|
22
|
+
outerColor: string;
|
|
23
|
+
};
|
|
24
|
+
Lens: {
|
|
25
|
+
bgBlend: string;
|
|
26
|
+
bgColor: string;
|
|
27
|
+
bgOpacity: number;
|
|
28
|
+
fgColor: string;
|
|
29
|
+
fgOpacity: number;
|
|
30
|
+
fillerOpacity: number;
|
|
31
|
+
mgColor: string;
|
|
32
|
+
mgOpacity: number;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
export declare const lens0: (l?: Partial<typeof LENS_0.Lens>, g?: Partial<typeof LENS_0.Globe>) => LensPreset;
|
|
36
|
+
export declare const lens5i: (l?: Partial<typeof LENS_5I.Lens>, g?: Partial<typeof LENS_5I.Globe>) => LensPreset;
|
|
37
|
+
export declare const LENSES: [string, LensPreset][];
|
|
38
|
+
export declare const applyLens: (preset: LensPreset, animate?: boolean) => void;
|
|
39
|
+
export declare const $lightMode: import("nanostores").PreinitializedWritableAtom<boolean> & object;
|
|
40
|
+
export declare const toggleLens: () => void;
|
|
41
|
+
export interface LensPreset {
|
|
42
|
+
Globe: typeof LENS_0.Globe;
|
|
43
|
+
Lens: typeof LENS_0.Lens;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=lens.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lens.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/overlays/lens.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;CAYlB,CAAA;AAED,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;CAYnB,CAAA;AAED,eAAO,MAAM,KAAK,GAChB,IAAI,OAAO,CAAC,OAAO,MAAM,CAAC,IAAI,CAAC,EAC/B,IAAI,OAAO,CAAC,OAAO,MAAM,CAAC,KAAK,CAAC,KAC/B,UAGD,CAAA;AAQF,eAAO,MAAM,MAAM,GACjB,IAAI,OAAO,CAAC,OAAO,OAAO,CAAC,IAAI,CAAC,EAChC,IAAI,OAAO,CAAC,OAAO,OAAO,CAAC,KAAK,CAAC,KAChC,UAGD,CAAA;AAKF,eAAO,MAAM,MAAM,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,EASxC,CAAA;AAED,eAAO,MAAM,SAAS,GAAI,QAAQ,UAAU,EAAE,iBAAe,SAK1D,CAAA;AAEH,eAAO,MAAM,UAAU,mEAAa,CAAA;AAEpC,eAAO,MAAM,UAAU,YAMtB,CAAA;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,OAAO,MAAM,CAAC,KAAK,CAAA;IAC1B,IAAI,EAAE,OAAO,MAAM,CAAC,IAAI,CAAA;CACzB"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { atom } from 'nanostores';
|
|
3
|
+
import { setControlValue } from '../../../hooks/use-smooth-controls';
|
|
4
|
+
export const LENS_0 = {
|
|
5
|
+
Globe: { innerColor: '#170d02', innerOpacity: 0.1, outerColor: '#FFAC02' },
|
|
6
|
+
Lens: {
|
|
7
|
+
bgBlend: 'difference',
|
|
8
|
+
bgColor: '#041C1C',
|
|
9
|
+
bgOpacity: 1,
|
|
10
|
+
fgColor: '#FFFFFF',
|
|
11
|
+
fgOpacity: 0,
|
|
12
|
+
fillerOpacity: 0.033,
|
|
13
|
+
mgColor: '#ffe6cb',
|
|
14
|
+
mgOpacity: 1
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
export const LENS_5I = {
|
|
18
|
+
Globe: { innerColor: '#170d02', innerOpacity: 0.3, outerColor: '#FFAC02' },
|
|
19
|
+
Lens: {
|
|
20
|
+
bgBlend: 'multiply',
|
|
21
|
+
bgColor: '#170d02',
|
|
22
|
+
bgOpacity: 1,
|
|
23
|
+
fgColor: '#FFFFFF',
|
|
24
|
+
fgOpacity: 1,
|
|
25
|
+
fillerOpacity: 0.06,
|
|
26
|
+
mgColor: '#FFAC02',
|
|
27
|
+
mgOpacity: 1
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
export const lens0 = (l, g) => ({
|
|
31
|
+
Globe: { ...LENS_0.Globe, ...g },
|
|
32
|
+
Lens: { ...LENS_0.Lens, ...l }
|
|
33
|
+
});
|
|
34
|
+
// The Hermes light-mode look is produced by a fullscreen opaque-white
|
|
35
|
+
// `mix-blend-mode: difference` foreground layer that inverts everything.
|
|
36
|
+
// Colored lenses that want a "white + accent" look MUST be built from
|
|
37
|
+
// LENS_5I, not LENS_0 — otherwise `bgBlend: 'difference'` + an opaque
|
|
38
|
+
// colored bg + active fg inversion land halfway between dark and light
|
|
39
|
+
// mode and produce a muddy warm wash instead of a clean inversion.
|
|
40
|
+
export const lens5i = (l, g) => ({
|
|
41
|
+
Globe: { ...LENS_5I.Globe, ...g },
|
|
42
|
+
Lens: { ...LENS_5I.Lens, ...l }
|
|
43
|
+
});
|
|
44
|
+
// Accent colors are the *pre-inversion* source; after the difference FG
|
|
45
|
+
// layer they read as their visual complement. e.g. `#FFAC02` (orange)
|
|
46
|
+
// renders as blue #0053FD on screen — that's the default LENS_5I accent.
|
|
47
|
+
export const LENSES = [
|
|
48
|
+
['0', LENS_0],
|
|
49
|
+
['1', lens0({ bgColor: '#0A1F1F' })],
|
|
50
|
+
['2', lens0({ bgColor: '#0E0313', mgColor: '#e6cbff' })],
|
|
51
|
+
['3', lens5i({ mgColor: '#FFAC02' })],
|
|
52
|
+
['4', lens5i({ bgColor: '#0E0313', mgColor: '#FF5500' })],
|
|
53
|
+
['5', lens0({ bgColor: '#1540B1', bgOpacity: 0.7 })],
|
|
54
|
+
['5i', LENS_5I],
|
|
55
|
+
['6', lens5i({ bgColor: '#170D02', mgColor: '#00E5FF' })]
|
|
56
|
+
];
|
|
57
|
+
export const applyLens = (preset, animate = false) => Object.entries(preset).forEach(([g, v]) => Object.entries(v).forEach(([k, val]) => setControlValue(g, k, val, { animate })));
|
|
58
|
+
export const $lightMode = atom(true);
|
|
59
|
+
export const toggleLens = () => {
|
|
60
|
+
const isLight = $lightMode.get();
|
|
61
|
+
const next = isLight ? LENS_0 : LENS_5I;
|
|
62
|
+
$lightMode.set(!isLight);
|
|
63
|
+
applyLens(next, true);
|
|
64
|
+
};
|
|
65
|
+
//# sourceMappingURL=lens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lens.js","sourceRoot":"","sources":["../../../../src/ui/components/overlays/lens.ts"],"names":[],"mappings":"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","sourcesContent":["'use client'\n\nimport { atom } from 'nanostores'\n\nimport { setControlValue } from '../../../hooks/use-smooth-controls'\n\nexport const LENS_0 = {\n Globe: { innerColor: '#170d02', innerOpacity: 0.1, outerColor: '#FFAC02' },\n Lens: {\n bgBlend: 'difference',\n bgColor: '#041C1C',\n bgOpacity: 1,\n fgColor: '#FFFFFF',\n fgOpacity: 0,\n fillerOpacity: 0.033,\n mgColor: '#ffe6cb',\n mgOpacity: 1\n }\n}\n\nexport const LENS_5I = {\n Globe: { innerColor: '#170d02', innerOpacity: 0.3, outerColor: '#FFAC02' },\n Lens: {\n bgBlend: 'multiply',\n bgColor: '#170d02',\n bgOpacity: 1,\n fgColor: '#FFFFFF',\n fgOpacity: 1,\n fillerOpacity: 0.06,\n mgColor: '#FFAC02',\n mgOpacity: 1\n }\n}\n\nexport const lens0 = (\n l?: Partial<typeof LENS_0.Lens>,\n g?: Partial<typeof LENS_0.Globe>\n): LensPreset => ({\n Globe: { ...LENS_0.Globe, ...g },\n Lens: { ...LENS_0.Lens, ...l }\n})\n\n// The Hermes light-mode look is produced by a fullscreen opaque-white\n// `mix-blend-mode: difference` foreground layer that inverts everything.\n// Colored lenses that want a \"white + accent\" look MUST be built from\n// LENS_5I, not LENS_0 — otherwise `bgBlend: 'difference'` + an opaque\n// colored bg + active fg inversion land halfway between dark and light\n// mode and produce a muddy warm wash instead of a clean inversion.\nexport const lens5i = (\n l?: Partial<typeof LENS_5I.Lens>,\n g?: Partial<typeof LENS_5I.Globe>\n): LensPreset => ({\n Globe: { ...LENS_5I.Globe, ...g },\n Lens: { ...LENS_5I.Lens, ...l }\n})\n\n// Accent colors are the *pre-inversion* source; after the difference FG\n// layer they read as their visual complement. e.g. `#FFAC02` (orange)\n// renders as blue #0053FD on screen — that's the default LENS_5I accent.\nexport const LENSES: [string, LensPreset][] = [\n ['0', LENS_0],\n ['1', lens0({ bgColor: '#0A1F1F' })],\n ['2', lens0({ bgColor: '#0E0313', mgColor: '#e6cbff' })],\n ['3', lens5i({ mgColor: '#FFAC02' })],\n ['4', lens5i({ bgColor: '#0E0313', mgColor: '#FF5500' })],\n ['5', lens0({ bgColor: '#1540B1', bgOpacity: 0.7 })],\n ['5i', LENS_5I],\n ['6', lens5i({ bgColor: '#170D02', mgColor: '#00E5FF' })]\n]\n\nexport const applyLens = (preset: LensPreset, animate = false) =>\n Object.entries(preset).forEach(([g, v]) =>\n Object.entries(v).forEach(([k, val]) =>\n setControlValue(g, k, val, { animate })\n )\n )\n\nexport const $lightMode = atom(true)\n\nexport const toggleLens = () => {\n const isLight = $lightMode.get()\n const next = isLight ? LENS_0 : LENS_5I\n\n $lightMode.set(!isLight)\n applyLens(next, true)\n}\n\nexport interface LensPreset {\n Globe: typeof LENS_0.Globe\n Lens: typeof LENS_0.Lens\n}\n"]}
|
|
@@ -5,7 +5,7 @@ import * as THREE from 'three';
|
|
|
5
5
|
import { useGpuTier } from '../../../hooks/use-gpu-tier';
|
|
6
6
|
import { useSmoothControls } from '../../../hooks/use-smooth-controls';
|
|
7
7
|
import { cn, hexToVec3 } from '../../../utils';
|
|
8
|
-
import { BLEND_MODES } from '
|
|
8
|
+
import { BLEND_MODES } from './blend-modes';
|
|
9
9
|
const vert = /*glsl*/ `
|
|
10
10
|
varying vec2 vUv;
|
|
11
11
|
void main() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"noise.js","sourceRoot":"","sources":["../../../../src/ui/components/overlays/noise.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AACzC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAA;AACtE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE9C,OAAO,EAAE,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"noise.js","sourceRoot":"","sources":["../../../../src/ui/components/overlays/noise.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client'\n\nimport { useEffect, useRef } from 'react'\nimport * as THREE from 'three'\n\nimport { useGpuTier } from '../../../hooks/use-gpu-tier'\nimport { useSmoothControls } from '../../../hooks/use-smooth-controls'\nimport { cn, hexToVec3 } from '../../../utils'\n\nimport { BLEND_MODES } from './blend-modes'\n\nconst vert = /*glsl*/ `\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n`\n\nconst frag = /*glsl*/ `\n uniform vec2 uRes;\n uniform float uDpr, uSize, uDensity, uOpacity;\n uniform vec3 uColor;\n varying vec2 vUv;\n\n float hash(vec2 p) {\n vec3 p3 = fract(vec3(p.xyx) * 0.1031);\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n }\n\n void main() {\n float n = hash(floor(vUv * uRes / (uSize * uDpr)));\n gl_FragColor = vec4(uColor, step(1.0 - uDensity, n)) * uOpacity;\n }\n`\n\nexport function Noise({ className, style }: NoiseProps) {\n const gpuTier = useGpuTier()\n\n const c = useSmoothControls(\n 'Effects/Noise',\n {\n blend: { options: BLEND_MODES, value: 'color-dodge' as const },\n color: { value: '#eaeaea' },\n density: { max: 1, min: 0, step: 0.01, value: 0.11 },\n enabled: { value: true },\n opacity: { max: 1, min: 0, step: 0.01, value: 0.55 },\n size: { max: 10, min: 0.1, step: 0.1, value: 1 }\n },\n { collapsed: true }\n )\n\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const cRef = useRef(c)\n cRef.current = c\n\n const enabled = c.enabled && gpuTier > 0\n\n useEffect(() => {\n if (!canvasRef.current || !enabled) {\n return\n }\n\n const renderer = new THREE.WebGLRenderer({\n alpha: true,\n canvas: canvasRef.current,\n premultipliedAlpha: false\n })\n\n renderer.setClearColor(0x000000, 0)\n\n const scene = new THREE.Scene()\n const camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1)\n const geo = new THREE.PlaneGeometry(2, 2)\n\n const mat = new THREE.ShaderMaterial({\n fragmentShader: frag,\n transparent: true,\n uniforms: {\n uColor: { value: hexToVec3(c.color) },\n uDensity: { value: c.density },\n uDpr: { value: 1 },\n uOpacity: { value: c.opacity },\n uRes: { value: new THREE.Vector2() },\n uSize: { value: c.size }\n },\n vertexShader: vert\n })\n\n scene.add(new THREE.Mesh(geo, mat))\n\n const resize = () => {\n renderer.setSize(innerWidth, innerHeight)\n renderer.setPixelRatio(devicePixelRatio)\n mat.uniforms.uRes.value.set(\n innerWidth * devicePixelRatio,\n innerHeight * devicePixelRatio\n )\n mat.uniforms.uDpr.value = devicePixelRatio\n }\n\n resize()\n window.addEventListener('resize', resize)\n\n let raf: number\n const interval = gpuTier === 1 ? 100 : 0\n\n const loop = () => {\n raf = interval\n ? (setTimeout(loop, interval) as unknown as number)\n : requestAnimationFrame(loop)\n\n const v = cRef.current\n mat.uniforms.uSize.value = v.size\n mat.uniforms.uDensity.value = v.density\n mat.uniforms.uColor.value = hexToVec3(v.color)\n mat.uniforms.uOpacity.value = v.opacity\n renderer.render(scene, camera)\n }\n\n loop()\n\n return () => {\n window.removeEventListener('resize', resize)\n\n if (interval) {\n clearTimeout(raf)\n } else {\n cancelAnimationFrame(raf)\n }\n\n mat.dispose()\n geo.dispose()\n renderer.dispose()\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [enabled, gpuTier])\n\n if (!enabled) {\n return null\n }\n\n return (\n <canvas\n className={cn('h-full w-full', className)}\n ref={canvasRef}\n style={{ mixBlendMode: c.blend, ...style }}\n />\n )\n}\n\ninterface NoiseProps {\n className?: string\n style?: React.CSSProperties\n}\n"]}
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { useSmoothControls } from '../../../hooks/use-smooth-controls';
|
|
4
4
|
import { cn } from '../../../utils';
|
|
5
5
|
import { hexToRgb } from '../../../utils/color';
|
|
6
|
-
import { BLEND_MODES } from '
|
|
6
|
+
import { BLEND_MODES } from './blend-modes';
|
|
7
7
|
export function Vignette({ className, style }) {
|
|
8
8
|
const c = useSmoothControls('Effects/Vignette', {
|
|
9
9
|
blend: { options: BLEND_MODES, value: 'lighten' },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vignette.js","sourceRoot":"","sources":["../../../../src/ui/components/overlays/vignette.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAA;AACtE,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAA;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAE/C,OAAO,EAAE,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"vignette.js","sourceRoot":"","sources":["../../../../src/ui/components/overlays/vignette.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAA;AACtE,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAA;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAE/C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAE3C,MAAM,UAAU,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAiB;IAC1D,MAAM,CAAC,GAAG,iBAAiB,CACzB,kBAAkB,EAClB;QACE,KAAK,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,SAAkB,EAAE;QAC1D,UAAU,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE;QACpD,WAAW,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE;QACrD,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE;QAC3B,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;QACxB,OAAO,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;QACpD,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE;QAC9C,OAAO,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;QACpD,QAAQ,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE;KACnD,EACD,EAAE,SAAS,EAAE,IAAI,EAAE,CACpB,CAAA;IAED,IAAI,CAAC,CAAC,CAAC,OAAO;QAAE,OAAO,IAAI,CAAA;IAE3B,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;IAC7B,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,EAAE,CAAA;IAErB,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,EAAE,CAC/C,CAAC,GAAG,CAAC;QACL,8BAA8B,CAAC,KAAK,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,CAAA;IAEzF,MAAM,EAAE,GAAG;QACT,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;QACrB,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC;QACxB,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,UAAU,CAAC;QAC1B,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,WAAW,CAAC;KAC9B,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAEjB,IAAI,CAAC,EAAE,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IAE3B,OAAO,CACL,cACE,SAAS,EAAE,EAAE,CAAC,eAAe,EAAE,SAAS,CAAC,EACzC,KAAK,EAAE;YACL,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;YACzB,YAAY,EAAE,CAAC,CAAC,KAAK;YACrB,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,GAAG,KAAK;SACT,GACD,CACH,CAAA;AACH,CAAC","sourcesContent":["'use client'\n\nimport { useSmoothControls } from '../../../hooks/use-smooth-controls'\nimport { cn } from '../../../utils'\nimport { hexToRgb } from '../../../utils/color'\n\nimport { BLEND_MODES } from './blend-modes'\n\nexport function Vignette({ className, style }: VignetteProps) {\n const c = useSmoothControls(\n 'Effects/Vignette',\n {\n blend: { options: BLEND_MODES, value: 'lighten' as const },\n bottomLeft: { max: 1, min: 0, step: 0.01, value: 0 },\n bottomRight: { max: 1, min: 0, step: 0.01, value: 0 },\n color: { value: '#ffbd38' },\n enabled: { value: true },\n opacity: { max: 1, min: 0, step: 0.01, value: 0.22 },\n size: { max: 1, min: 0, step: 0.01, value: 1 },\n topLeft: { max: 1, min: 0, step: 0.01, value: 0.35 },\n topRight: { max: 1, min: 0, step: 0.01, value: 0 }\n },\n { collapsed: true }\n )\n\n if (!c.enabled) return null\n\n const rgb = hexToRgb(c.color)\n const s = c.size * 60\n\n const grad = (x: number, y: number, i: number) =>\n i > 0 &&\n `radial-gradient(ellipse at ${x}% ${y}%, rgba(${rgb},0) ${s}%, rgba(${rgb},${i}) 100%)`\n\n const bg = [\n grad(0, 0, c.topLeft),\n grad(100, 0, c.topRight),\n grad(0, 100, c.bottomLeft),\n grad(100, 100, c.bottomRight)\n ].filter(Boolean)\n\n if (!bg.length) return null\n\n return (\n <div\n className={cn('h-full w-full', className)}\n style={{\n background: bg.join(', '),\n mixBlendMode: c.blend,\n opacity: c.opacity,\n ...style\n }}\n />\n )\n}\n\ninterface VignetteProps {\n className?: string\n style?: React.CSSProperties\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare function Socials({ className, items, onNavigate, ...rest }: SocialsProps): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export interface SocialLink {
|
|
3
|
+
external?: boolean;
|
|
4
|
+
href: string;
|
|
5
|
+
icon: React.ComponentType<{
|
|
6
|
+
className?: string;
|
|
7
|
+
}>;
|
|
8
|
+
label: string;
|
|
9
|
+
onClick?: React.MouseEventHandler;
|
|
10
|
+
}
|
|
11
|
+
interface SocialsProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
12
|
+
items: SocialLink[];
|
|
13
|
+
/**
|
|
14
|
+
* Called *in addition* to each link's `onClick` after a click — useful in
|
|
15
|
+
* mobile drawer / dialog contexts where clicking a link should also close
|
|
16
|
+
* the surrounding overlay.
|
|
17
|
+
*/
|
|
18
|
+
onNavigate?: () => void;
|
|
19
|
+
}
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=socials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"socials.d.ts","sourceRoot":"","sources":["../../../src/ui/components/socials.tsx"],"names":[],"mappings":"AAEA,wBAAgB,OAAO,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,IAAI,EAAE,EAAE,YAAY,2CAqB9E;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACjD,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAA;CAClC;AAED,UAAU,YAAa,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACjE,KAAK,EAAE,UAAU,EAAE,CAAA;IACnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;CACxB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from '../../utils';
|
|
3
|
+
export function Socials({ className, items, onNavigate, ...rest }) {
|
|
4
|
+
return (_jsx("div", { className: cn('flex items-center gap-3', className), ...rest, children: items.map(({ external = true, href, icon: Icon, label, onClick }) => (_jsx("a", { className: "opacity-60 transition-opacity hover:opacity-100", href: href, onClick: e => {
|
|
5
|
+
onClick?.(e);
|
|
6
|
+
onNavigate?.();
|
|
7
|
+
}, rel: external ? 'noopener noreferrer' : undefined, target: external ? '_blank' : undefined, title: label, children: _jsx(Icon, {}) }, label))) }));
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=socials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"socials.js","sourceRoot":"","sources":["../../../src/ui/components/socials.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAA;AAEhC,MAAM,UAAU,OAAO,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,IAAI,EAAgB;IAC7E,OAAO,CACL,cAAK,SAAS,EAAE,EAAE,CAAC,yBAAyB,EAAE,SAAS,CAAC,KAAM,IAAI,YAC/D,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CACpE,YACE,SAAS,EAAC,iDAAiD,EAC3D,IAAI,EAAE,IAAI,EAEV,OAAO,EAAE,CAAC,CAAC,EAAE;gBACX,OAAO,EAAE,CAAC,CAAC,CAAC,CAAA;gBACZ,UAAU,EAAE,EAAE,CAAA;YAChB,CAAC,EACD,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,SAAS,EACjD,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EACvC,KAAK,EAAE,KAAK,YAEZ,KAAC,IAAI,KAAG,IATH,KAAK,CAUR,CACL,CAAC,GACE,CACP,CAAA;AACH,CAAC","sourcesContent":["import { cn } from '../../utils'\n\nexport function Socials({ className, items, onNavigate, ...rest }: SocialsProps) {\n return (\n <div className={cn('flex items-center gap-3', className)} {...rest}>\n {items.map(({ external = true, href, icon: Icon, label, onClick }) => (\n <a\n className=\"opacity-60 transition-opacity hover:opacity-100\"\n href={href}\n key={label}\n onClick={e => {\n onClick?.(e)\n onNavigate?.()\n }}\n rel={external ? 'noopener noreferrer' : undefined}\n target={external ? '_blank' : undefined}\n title={label}\n >\n <Icon />\n </a>\n ))}\n </div>\n )\n}\n\nexport interface SocialLink {\n external?: boolean\n href: string\n icon: React.ComponentType<{ className?: string }>\n label: string\n onClick?: React.MouseEventHandler\n}\n\ninterface SocialsProps extends React.HTMLAttributes<HTMLDivElement> {\n items: SocialLink[]\n /**\n * Called *in addition* to each link's `onClick` after a click — useful in\n * mobile drawer / dialog contexts where clicking a link should also close\n * the surrounding overlay.\n */\n onNavigate?: () => void\n}\n"]}
|
package/dist/ui/footer.d.ts
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { type SocialLink } from './components/socials';
|
|
2
|
+
export declare function Footer({ className, groups, LinkComponent, socials, socialsLabel, style, themeLabel, themeToggle }: FooterProps): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
export interface FooterGroup {
|
|
4
|
+
label: string;
|
|
5
|
+
links: (FooterLink | string)[];
|
|
6
|
+
}
|
|
7
|
+
export interface FooterLink {
|
|
8
|
+
href: string;
|
|
9
|
+
label: string;
|
|
10
|
+
}
|
|
11
|
+
export interface FooterProps {
|
|
12
|
+
className?: string;
|
|
13
|
+
groups?: FooterGroup[];
|
|
3
14
|
LinkComponent?: React.ElementType;
|
|
15
|
+
socials?: SocialLink[];
|
|
16
|
+
socialsLabel?: string;
|
|
17
|
+
style?: React.CSSProperties;
|
|
18
|
+
themeLabel?: string;
|
|
19
|
+
themeToggle?: boolean;
|
|
4
20
|
}
|
|
5
|
-
export {};
|
|
6
21
|
//# sourceMappingURL=footer.d.ts.map
|
package/dist/ui/footer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../src/ui/footer.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../src/ui/footer.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAW,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAW/D,wBAAgB,MAAM,CAAC,EACrB,SAAS,EACT,MAAuB,EACvB,aAAmB,EACnB,OAAO,EACP,YAAwB,EACxB,KAAK,EACL,UAAoB,EACpB,WAAmB,EACpB,EAAE,WAAW,2CA+Db;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,CAAC,UAAU,GAAG,MAAM,CAAC,EAAE,CAAA;CAC/B;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,WAAW,EAAE,CAAA;IACtB,aAAa,CAAC,EAAE,KAAK,CAAC,WAAW,CAAA;IACjC,OAAO,CAAC,EAAE,UAAU,EAAE,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAA;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB"}
|