@nous-research/ui 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"use-smooth-controls.d.ts","sourceRoot":"","sources":["../../src/hooks/use-smooth-controls.ts"],"names":[],"mappings":"AAGA,OAAO,EAAe,WAAW,EAAE,MAAM,MAAM,CAAA;AAC/C,OAAO,EAAQ,KAAK,YAAY,EAAE,MAAM,YAAY,CAAA;AAqBpD,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC7D,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,CAAC,EACd,OAAO,CAAC,EAAE,wBAAwB,EAClC,YAAY,CAAC,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,MAEpC,CAAC;WAAoC,MAAM,CAAC;iBAmOzD;AAED,eAAO,MAAM,cAAc,GAAI,CAAC,GAAG,GAAG,EACpC,OAAO,MAAM,EACb,KAAK,MAAM,KACV,SAAS,GAAG,YAAY,CAAC,CAAC,CACqC,CAAA;AAElE,eAAO,MAAM,eAAe,GAAI,CAAC,GAAG,GAAG,EACrC,OAAO,MAAM,EACb,KAAK,MAAM,EACX,OAAO,CAAC,EACR,UAAU;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,SAwBnD,CAAA;AAED,KAAK,wBAAwB,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;IACxB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB,CAAA"}
1
+ {"version":3,"file":"use-smooth-controls.d.ts","sourceRoot":"","sources":["../../src/hooks/use-smooth-controls.ts"],"names":[],"mappings":"AAGA,OAAO,EAAe,WAAW,EAAE,MAAM,MAAM,CAAA;AAC/C,OAAO,EAAQ,KAAK,YAAY,EAAE,MAAM,YAAY,CAAA;AAqBpD,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC7D,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,CAAC,EACd,OAAO,CAAC,EAAE,wBAAwB,EAClC,YAAY,CAAC,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,MAEpC,CAAC;WAAoC,MAAM,CAAC;iBAoPzD;AAED,eAAO,MAAM,cAAc,GAAI,CAAC,GAAG,GAAG,EACpC,OAAO,MAAM,EACb,KAAK,MAAM,KACV,SAAS,GAAG,YAAY,CAAC,CAAC,CACqC,CAAA;AAElE,eAAO,MAAM,eAAe,GAAI,CAAC,GAAG,GAAG,EACrC,OAAO,MAAM,EACb,KAAK,MAAM,EACX,OAAO,CAAC,EACR,UAAU;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,SAwBnD,CAAA;AAED,KAAK,wBAAwB,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;IACxB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB,CAAA"}
@@ -15,11 +15,18 @@ const randNum = (v) => typeof v === 'object' && ('min' in v || 'max' in v)
15
15
  export function useSmoothControls(label, initialArgs, options, dependencies) {
16
16
  const entries = useMemo(() => Object.entries(initialArgs ?? {}), [initialArgs]);
17
17
  const values = useMemo(() => entries.filter(([, v]) => !/button|folder/i.test(v?.type)), [entries]);
18
+ // Tracks whether this component instance has mounted yet. When a remount
19
+ // happens (e.g. Storybook changing a `key` prop to force a lens reset), we
20
+ // want the module-scoped atoms to be reseeded from the new `initialArgs` so
21
+ // the first paint reflects the newly-selected preset — not leftover values
22
+ // from the previous mount.
23
+ const mountedRef = useRef(false);
18
24
  const atoms = useMemo(() => {
19
25
  const map = atomRegistry.get(label) ?? new Map();
20
26
  if (!atomRegistry.has(label)) {
21
27
  atomRegistry.set(label, map);
22
28
  }
29
+ const freshMount = !mountedRef.current;
23
30
  entries.forEach(([k, v]) => {
24
31
  if (v?.schema) {
25
32
  Object.keys(v.schema).forEach(sk => {
@@ -27,14 +34,23 @@ export function useSmoothControls(label, initialArgs, options, dependencies) {
27
34
  if (!map.has(key)) {
28
35
  map.set(key, atom(val(v.schema[sk])));
29
36
  }
37
+ else if (freshMount) {
38
+ map.get(key).set(val(v.schema[sk]));
39
+ }
30
40
  });
31
41
  }
32
42
  else if (!map.has(k)) {
33
43
  map.set(k, atom(val(v)));
34
44
  }
45
+ else if (freshMount) {
46
+ map.get(k).set(val(v));
47
+ }
35
48
  });
36
49
  return map;
37
50
  }, [label, entries]);
51
+ useEffect(() => {
52
+ mountedRef.current = true;
53
+ }, []);
38
54
  const hydrate = useCallback(() => Object.fromEntries(entries.flatMap(([k, v]) => v?.schema
39
55
  ? Object.entries(v.schema).map(([k0, v0]) => [
40
56
  k0,
@@ -1 +1 @@
1
- {"version":3,"file":"use-smooth-controls.js","sourceRoot":"","sources":["../../src/hooks/use-smooth-controls.ts"],"names":[],"mappings":"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","sourcesContent":["'use client'\n\nimport gsap from 'gsap'\nimport { buttonGroup, useControls } from 'leva'\nimport { atom, type WritableAtom } from 'nanostores'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\n\nconst atomRegistry = new Map<string, Map<string, WritableAtom<any>>>()\n\nconst val = (v: any) =>\n v && typeof v === 'object' && 'value' in v ? v.value : v\n\nconst isHex = (v: any) =>\n /color/i.test(v?.type) || /^#[0-9a-f]{3,8}$/i.test(val(v))\n\nconst randHex = () =>\n `#${Math.floor(Math.random() * 0xffffff)\n .toString(16)\n .padStart(6, '0')}`\n\nconst randNum = (v: any) =>\n typeof v === 'object' && ('min' in v || 'max' in v)\n ? gsap.utils.random(v.min ?? 0, v.max ?? 1, v.step ?? 0.01)\n : gsap.utils.random(0, 1)\n\nexport function useSmoothControls<T extends Record<string, any>>(\n label: string,\n initialArgs: T,\n options?: UseSmoothControlsOptions,\n dependencies?: Parameters<typeof useControls>[3]\n) {\n type R = { [K in keyof T]: T[K] extends { value: infer V } ? V : never }\n\n const entries = useMemo(\n () => Object.entries(initialArgs ?? {}),\n [initialArgs]\n )\n\n const values = useMemo(\n () => entries.filter(([, v]) => !/button|folder/i.test(v?.type)),\n [entries]\n )\n\n const atoms = useMemo(() => {\n const map = atomRegistry.get(label) ?? new Map<string, WritableAtom<any>>()\n\n if (!atomRegistry.has(label)) {\n atomRegistry.set(label, map)\n }\n\n entries.forEach(([k, v]) => {\n if (v?.schema) {\n Object.keys(v.schema).forEach(sk => {\n const key = `${k}.${sk}`\n\n if (!map.has(key)) {\n map.set(key, atom(val(v.schema[sk])))\n }\n })\n } else if (!map.has(k)) {\n map.set(k, atom(val(v)))\n }\n })\n\n return map\n }, [label, entries])\n\n const hydrate = useCallback(\n () =>\n Object.fromEntries(\n entries.flatMap(([k, v]) =>\n v?.schema\n ? Object.entries(v.schema).map(([k0, v0]: [string, any]) => [\n k0,\n atoms.get(`${k}.${k0}`)?.get() ?? val(v0)\n ])\n : [[k, atoms.get(k)?.get() ?? val(v)]]\n )\n ) as R,\n [entries, atoms]\n )\n\n const [args, update] = useState<R>(hydrate)\n const setRef = useRef<((values: Partial<R>) => void) | null>(null)\n const atomVals = useRef<Record<string, any>>({})\n const fromAtom = useRef(false)\n const fromControl = useRef<Set<string>>(new Set())\n\n useEffect(() => {\n if (Object.keys(args).length !== Object.keys(initialArgs).length) {\n update(hydrate)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [initialArgs, args])\n\n useEffect(() => {\n if (!setRef.current) {\n return\n }\n\n const unsubs: Array<() => void> = []\n let ready = false\n const initTimeout = setTimeout(() => (ready = true), 100)\n\n const subscribe = (fullKey: string, updateFn: (v: any) => void) => {\n const a = atoms.get(fullKey)\n\n if (!a) {\n return\n }\n\n unsubs.push(\n a.subscribe(v => {\n const prev = atomVals.current[fullKey]\n atomVals.current[fullKey] = v\n\n if (\n setRef.current &&\n ready &&\n prev !== v &&\n !fromControl.current.has(fullKey)\n ) {\n fromAtom.current = true\n\n try {\n updateFn(v)\n } catch {\n //\n }\n\n setTimeout(() => (fromAtom.current = false), 0)\n }\n })\n )\n\n atomVals.current[fullKey] = a.get()\n }\n\n entries.forEach(([k, v]) => {\n if (v?.schema) {\n Object.keys(v.schema).forEach(sk => {\n subscribe(`${k}.${sk}`, v => {\n try {\n setRef.current!({\n [k]: { ...((args[k] as any) ?? {}), [sk]: v }\n } as Partial<R>)\n } catch {\n //\n }\n\n update(st => ({\n ...st,\n [k]: { ...((st[k] as any) ?? {}), [sk]: v }\n }))\n })\n })\n } else {\n subscribe(k, v => {\n try {\n setRef.current!({ [k]: v } as Partial<R>)\n } catch {\n //\n }\n\n update(st => ({ ...st, [k]: v }))\n })\n }\n })\n\n return () => {\n clearTimeout(initTimeout)\n unsubs.forEach(fn => fn())\n }\n }, [label, entries, atoms, args])\n\n const onChange =\n (k: string, orig?: (e: any, k0?: string) => void) =>\n (e: any, k0?: string) => {\n if (fromAtom.current) {\n return orig?.(e, k0)\n }\n\n const key = k0?.split('.')?.pop() ?? k\n const fullKey = k0 ?? k\n const a = atoms.get(fullKey)\n\n fromControl.current.add(fullKey)\n\n const sync = (v: any) => {\n update(st => ({ ...st, [key]: v }))\n a?.set(v)\n orig?.(v, k0)\n }\n\n if (typeof e === 'number' && args[key] !== e) {\n gsap.to(args, {\n duration: options?.duration ?? 0.35,\n ease: 'circ.out',\n [key]: e,\n onComplete: () => void fromControl.current.delete(fullKey),\n onUpdate: () => {\n fromControl.current.add(fullKey)\n sync(args[key])\n setTimeout(() => fromControl.current.delete(fullKey), 0)\n }\n })\n } else {\n sync(e)\n setTimeout(() => fromControl.current.delete(fullKey), 0)\n }\n }\n\n const [, set] = useControls(\n label,\n () => ({\n ...Object.fromEntries(\n entries.map(([k, v]) =>\n v?.schema\n ? [\n k,\n {\n ...v,\n schema: Object.fromEntries(\n Object.entries(v.schema).map(([sk, sv]: [string, any]) => [\n sk,\n { ...sv!, onChange: onChange(k, sv?.onChange) }\n ])\n )\n }\n ]\n : [k, { ...v, onChange: onChange(k, v?.onChange) }]\n )\n ),\n\n ' ': buttonGroup({\n flatten: () =>\n void set(Object.fromEntries(values.map(([k]) => [k, 0]))),\n randomize: () => {\n set(\n Object.fromEntries(\n values.map(([k, v]) => [k, isHex(v) ? randHex() : randNum(v)])\n )\n )\n options?.onRandomize?.()\n },\n reset: () => {\n set(Object.fromEntries(values.map(([k, v]) => [k, val(v)])))\n options?.onReset?.()\n }\n })\n }),\n { collapsed: true, ...options },\n dependencies ?? []\n )\n\n setRef.current = set\n\n return args\n}\n\nexport const getControlAtom = <T = any>(\n label: string,\n key: string\n): undefined | WritableAtom<T> =>\n atomRegistry.get(label)?.get(key) as undefined | WritableAtom<T>\n\nexport const setControlValue = <T = any>(\n label: string,\n key: string,\n value: T,\n options?: { animate?: boolean; duration?: number }\n) => {\n const a = getControlAtom<T>(label, key)\n\n if (!a) {\n return\n }\n\n if (\n options?.animate &&\n typeof value === 'number' &&\n typeof a.get() === 'number'\n ) {\n const t = { v: a.get() }\n\n gsap.to(t, {\n duration: options.duration ?? 0.35,\n ease: 'circ.out',\n onUpdate: () => a.set(t.v),\n v: value\n })\n } else {\n a.set(value)\n }\n}\n\ntype UseSmoothControlsOptions = Parameters<typeof useControls>[2] & {\n duration?: number\n onRandomize?: () => void\n onReset?: () => void\n}\n"]}
1
+ {"version":3,"file":"use-smooth-controls.js","sourceRoot":"","sources":["../../src/hooks/use-smooth-controls.ts"],"names":[],"mappings":"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","sourcesContent":["'use client'\n\nimport gsap from 'gsap'\nimport { buttonGroup, useControls } from 'leva'\nimport { atom, type WritableAtom } from 'nanostores'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\n\nconst atomRegistry = new Map<string, Map<string, WritableAtom<any>>>()\n\nconst val = (v: any) =>\n v && typeof v === 'object' && 'value' in v ? v.value : v\n\nconst isHex = (v: any) =>\n /color/i.test(v?.type) || /^#[0-9a-f]{3,8}$/i.test(val(v))\n\nconst randHex = () =>\n `#${Math.floor(Math.random() * 0xffffff)\n .toString(16)\n .padStart(6, '0')}`\n\nconst randNum = (v: any) =>\n typeof v === 'object' && ('min' in v || 'max' in v)\n ? gsap.utils.random(v.min ?? 0, v.max ?? 1, v.step ?? 0.01)\n : gsap.utils.random(0, 1)\n\nexport function useSmoothControls<T extends Record<string, any>>(\n label: string,\n initialArgs: T,\n options?: UseSmoothControlsOptions,\n dependencies?: Parameters<typeof useControls>[3]\n) {\n type R = { [K in keyof T]: T[K] extends { value: infer V } ? V : never }\n\n const entries = useMemo(\n () => Object.entries(initialArgs ?? {}),\n [initialArgs]\n )\n\n const values = useMemo(\n () => entries.filter(([, v]) => !/button|folder/i.test(v?.type)),\n [entries]\n )\n\n // Tracks whether this component instance has mounted yet. When a remount\n // happens (e.g. Storybook changing a `key` prop to force a lens reset), we\n // want the module-scoped atoms to be reseeded from the new `initialArgs` so\n // the first paint reflects the newly-selected preset — not leftover values\n // from the previous mount.\n const mountedRef = useRef(false)\n\n const atoms = useMemo(() => {\n const map = atomRegistry.get(label) ?? new Map<string, WritableAtom<any>>()\n\n if (!atomRegistry.has(label)) {\n atomRegistry.set(label, map)\n }\n\n const freshMount = !mountedRef.current\n\n entries.forEach(([k, v]) => {\n if (v?.schema) {\n Object.keys(v.schema).forEach(sk => {\n const key = `${k}.${sk}`\n\n if (!map.has(key)) {\n map.set(key, atom(val(v.schema[sk])))\n } else if (freshMount) {\n map.get(key)!.set(val(v.schema[sk]))\n }\n })\n } else if (!map.has(k)) {\n map.set(k, atom(val(v)))\n } else if (freshMount) {\n map.get(k)!.set(val(v))\n }\n })\n\n return map\n }, [label, entries])\n\n useEffect(() => {\n mountedRef.current = true\n }, [])\n\n const hydrate = useCallback(\n () =>\n Object.fromEntries(\n entries.flatMap(([k, v]) =>\n v?.schema\n ? Object.entries(v.schema).map(([k0, v0]: [string, any]) => [\n k0,\n atoms.get(`${k}.${k0}`)?.get() ?? val(v0)\n ])\n : [[k, atoms.get(k)?.get() ?? val(v)]]\n )\n ) as R,\n [entries, atoms]\n )\n\n const [args, update] = useState<R>(hydrate)\n const setRef = useRef<((values: Partial<R>) => void) | null>(null)\n const atomVals = useRef<Record<string, any>>({})\n const fromAtom = useRef(false)\n const fromControl = useRef<Set<string>>(new Set())\n\n useEffect(() => {\n if (Object.keys(args).length !== Object.keys(initialArgs).length) {\n update(hydrate)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [initialArgs, args])\n\n useEffect(() => {\n if (!setRef.current) {\n return\n }\n\n const unsubs: Array<() => void> = []\n let ready = false\n const initTimeout = setTimeout(() => (ready = true), 100)\n\n const subscribe = (fullKey: string, updateFn: (v: any) => void) => {\n const a = atoms.get(fullKey)\n\n if (!a) {\n return\n }\n\n unsubs.push(\n a.subscribe(v => {\n const prev = atomVals.current[fullKey]\n atomVals.current[fullKey] = v\n\n if (\n setRef.current &&\n ready &&\n prev !== v &&\n !fromControl.current.has(fullKey)\n ) {\n fromAtom.current = true\n\n try {\n updateFn(v)\n } catch {\n //\n }\n\n setTimeout(() => (fromAtom.current = false), 0)\n }\n })\n )\n\n atomVals.current[fullKey] = a.get()\n }\n\n entries.forEach(([k, v]) => {\n if (v?.schema) {\n Object.keys(v.schema).forEach(sk => {\n subscribe(`${k}.${sk}`, v => {\n try {\n setRef.current!({\n [k]: { ...((args[k] as any) ?? {}), [sk]: v }\n } as Partial<R>)\n } catch {\n //\n }\n\n update(st => ({\n ...st,\n [k]: { ...((st[k] as any) ?? {}), [sk]: v }\n }))\n })\n })\n } else {\n subscribe(k, v => {\n try {\n setRef.current!({ [k]: v } as Partial<R>)\n } catch {\n //\n }\n\n update(st => ({ ...st, [k]: v }))\n })\n }\n })\n\n return () => {\n clearTimeout(initTimeout)\n unsubs.forEach(fn => fn())\n }\n }, [label, entries, atoms, args])\n\n const onChange =\n (k: string, orig?: (e: any, k0?: string) => void) =>\n (e: any, k0?: string) => {\n if (fromAtom.current) {\n return orig?.(e, k0)\n }\n\n const key = k0?.split('.')?.pop() ?? k\n const fullKey = k0 ?? k\n const a = atoms.get(fullKey)\n\n fromControl.current.add(fullKey)\n\n const sync = (v: any) => {\n update(st => ({ ...st, [key]: v }))\n a?.set(v)\n orig?.(v, k0)\n }\n\n if (typeof e === 'number' && args[key] !== e) {\n gsap.to(args, {\n duration: options?.duration ?? 0.35,\n ease: 'circ.out',\n [key]: e,\n onComplete: () => void fromControl.current.delete(fullKey),\n onUpdate: () => {\n fromControl.current.add(fullKey)\n sync(args[key])\n setTimeout(() => fromControl.current.delete(fullKey), 0)\n }\n })\n } else {\n sync(e)\n setTimeout(() => fromControl.current.delete(fullKey), 0)\n }\n }\n\n const [, set] = useControls(\n label,\n () => ({\n ...Object.fromEntries(\n entries.map(([k, v]) =>\n v?.schema\n ? [\n k,\n {\n ...v,\n schema: Object.fromEntries(\n Object.entries(v.schema).map(([sk, sv]: [string, any]) => [\n sk,\n { ...sv!, onChange: onChange(k, sv?.onChange) }\n ])\n )\n }\n ]\n : [k, { ...v, onChange: onChange(k, v?.onChange) }]\n )\n ),\n\n ' ': buttonGroup({\n flatten: () =>\n void set(Object.fromEntries(values.map(([k]) => [k, 0]))),\n randomize: () => {\n set(\n Object.fromEntries(\n values.map(([k, v]) => [k, isHex(v) ? randHex() : randNum(v)])\n )\n )\n options?.onRandomize?.()\n },\n reset: () => {\n set(Object.fromEntries(values.map(([k, v]) => [k, val(v)])))\n options?.onReset?.()\n }\n })\n }),\n { collapsed: true, ...options },\n dependencies ?? []\n )\n\n setRef.current = set\n\n return args\n}\n\nexport const getControlAtom = <T = any>(\n label: string,\n key: string\n): undefined | WritableAtom<T> =>\n atomRegistry.get(label)?.get(key) as undefined | WritableAtom<T>\n\nexport const setControlValue = <T = any>(\n label: string,\n key: string,\n value: T,\n options?: { animate?: boolean; duration?: number }\n) => {\n const a = getControlAtom<T>(label, key)\n\n if (!a) {\n return\n }\n\n if (\n options?.animate &&\n typeof value === 'number' &&\n typeof a.get() === 'number'\n ) {\n const t = { v: a.get() }\n\n gsap.to(t, {\n duration: options.duration ?? 0.35,\n ease: 'circ.out',\n onUpdate: () => a.set(t.v),\n v: value\n })\n } else {\n a.set(value)\n }\n}\n\ntype UseSmoothControlsOptions = Parameters<typeof useControls>[2] & {\n duration?: number\n onRandomize?: () => void\n onReset?: () => void\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -15,8 +15,11 @@ export { Cell, Grid } from './ui/components/grid';
15
15
  export { HoverBg } from './ui/components/hover-bg';
16
16
  export * as Icons from './ui/components/icons';
17
17
  export { ImageDistortion } from './ui/components/image-distortion';
18
+ export type { AutoPlayPattern } from './ui/components/image-distortion';
18
19
  export { LevaClient } from './ui/components/leva-client';
19
20
  export { Modal } from './ui/components/modal';
21
+ export { Poster } from './ui/components/poster';
22
+ export type { PosterAspect, PosterProps, PosterVariant } from './ui/components/poster';
20
23
  export { applyLens, LENSES, LENS_0, LENS_5I, toggleLens, $lightMode } from './ui/components/overlays';
21
24
  export { Overlays } from './ui/components/overlays';
22
25
  export type { LensPreset } from './ui/components/overlays';
@@ -28,6 +31,8 @@ export { Stats } from './ui/components/stats';
28
31
  export { TerminalDemo } from './ui/components/terminal-demo';
29
32
  export type { TerminalDemoStep } from './ui/components/terminal-demo';
30
33
  export { ThemeToggle } from './ui/components/theme-toggle';
34
+ export { TierCard } from './ui/components/tier-card';
35
+ export type { TierCardPrice, TierCardProps } from './ui/components/tier-card';
31
36
  export { TV } from './ui/components/tv';
32
37
  export { Watchlist } from './ui/components/watchlist';
33
38
  export { Typography } from './ui/components/typography';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AAChF,OAAO,EAAE,aAAa,EAAE,QAAQ,IAAI,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAChF,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAA;AACjE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AACnF,YAAY,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAChE,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAA;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAClD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAC5D,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAA;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAClD,OAAO,KAAK,KAAK,MAAM,uBAAuB,CAAA;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAA;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAC7C,OAAO,EACL,SAAS,EACT,MAAM,EACN,MAAM,EACN,OAAO,EACP,UAAU,EACV,UAAU,EACX,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACnD,YAAY,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAA;AACtE,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAC5D,YAAY,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAC1D,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAA;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAErD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AACvD,YAAY,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AACjE,OAAO,EAAE,EAAE,EAAE,MAAM,+BAA+B,CAAA;AAClD,OAAO,EAAE,EAAE,EAAE,MAAM,+BAA+B,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAA;AAC1D,OAAO,EAAE,KAAK,EAAE,MAAM,kCAAkC,CAAA;AAExD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,OAAO,EACL,SAAS,EACT,SAAS,EACT,qBAAqB,EACrB,mBAAmB,EACnB,aAAa,EACd,MAAM,SAAS,CAAA;AAEhB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACnF,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAChE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAExE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACxD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,eAAe,EAChB,MAAM,6BAA6B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -16,6 +16,7 @@ export * as Icons from './ui/components/icons';
16
16
  export { ImageDistortion } from './ui/components/image-distortion';
17
17
  export { LevaClient } from './ui/components/leva-client';
18
18
  export { Modal } from './ui/components/modal';
19
+ export { Poster } from './ui/components/poster';
19
20
  export { applyLens, LENSES, LENS_0, LENS_5I, toggleLens, $lightMode } from './ui/components/overlays';
20
21
  export { Overlays } from './ui/components/overlays';
21
22
  export { Progress } from './ui/components/progress';
@@ -25,6 +26,7 @@ export { SelectionSwitcher } from './ui/components/selection-switcher';
25
26
  export { Stats } from './ui/components/stats';
26
27
  export { TerminalDemo } from './ui/components/terminal-demo';
27
28
  export { ThemeToggle } from './ui/components/theme-toggle';
29
+ export { TierCard } from './ui/components/tier-card';
28
30
  export { TV } from './ui/components/tv';
29
31
  export { Watchlist } from './ui/components/watchlist';
30
32
  export { Typography } from './ui/components/typography';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["export { AnimatedCount, useAnimatedCount } from './ui/components/animated-count'\nexport { AsciiSkeleton, Scramble as AsciiScramble } from './ui/components/ascii'\nexport { Badge } from './ui/components/badge'\nexport { NouseGirlBadge } from './ui/components/badges/nous-girl'\nexport { BlendMode, useBlendMode, withBlendMode } from './ui/components/blend-mode'\nexport type { BlendModeProps } from './ui/components/blend-mode'\nexport { Blink } from './ui/components/blink'\nexport { Button } from './ui/components/button'\nexport { CommandBlock, CopyButton } from './ui/components/command-block'\nexport { Cursor } from './ui/components/cursor'\nexport { DropdownMenu } from './ui/components/dropdown-menu'\nexport { FitText } from './ui/components/fit-text'\nexport { BarChart, LineChart } from './ui/components/graphs'\nexport { Cell, Grid } from './ui/components/grid'\nexport { HoverBg } from './ui/components/hover-bg'\nexport * as Icons from './ui/components/icons'\nexport { ImageDistortion } from './ui/components/image-distortion'\nexport { LevaClient } from './ui/components/leva-client'\nexport { Modal } from './ui/components/modal'\nexport {\n applyLens,\n LENSES,\n LENS_0,\n LENS_5I,\n toggleLens,\n $lightMode\n} from './ui/components/overlays'\nexport { Overlays } from './ui/components/overlays'\nexport type { LensPreset } from './ui/components/overlays'\nexport { Progress } from './ui/components/progress'\nexport { SceneCanvas } from './ui/components/scene-canvas'\nexport { Scramble } from './ui/components/scramble'\nexport { SelectionSwitcher } from './ui/components/selection-switcher'\nexport { Stats } from './ui/components/stats'\nexport { TerminalDemo } from './ui/components/terminal-demo'\nexport type { TerminalDemoStep } from './ui/components/terminal-demo'\nexport { ThemeToggle } from './ui/components/theme-toggle'\nexport { TV } from './ui/components/tv'\nexport { Watchlist } from './ui/components/watchlist'\n\nexport { Typography } from './ui/components/typography'\nexport type { TypographyProps } from './ui/components/typography'\nexport { H1 } from './ui/components/typography/h1'\nexport { H2 } from './ui/components/typography/h2'\nexport { Legend } from './ui/components/typography/legend'\nexport { Small } from './ui/components/typography/small'\n\nexport { BasicPage } from './ui/basic-page'\nexport { Header } from './ui/header'\nexport { Footer } from './ui/footer'\nexport { LayoutWrapper } from './ui/layout-wrapper'\n\nexport {\n FONT_SANS,\n FONT_MONO,\n FONT_RULES_COMPRESSED,\n FONT_RULES_EXPANDED,\n FONT_MONDWEST\n} from './fonts'\n\nexport { cn, clamp, smoothstep, hexToVec3, truncate, stripWpStyles } from './utils'\nexport { polyRef } from './utils'\nexport type { PolyComponent, PolyProps, PolyRef } from './utils'\nexport { hexToRgb, rgbToHex, colorDodge, colorMix } from './utils/color'\n\nexport { useCappedFrame } from './hooks/use-capped-frame'\nexport { useCssVarDims } from './hooks/use-css-var-dims'\nexport { $gpuTier, useGpuTier } from './hooks/use-gpu-tier'\nexport {\n useSmoothControls,\n getControlAtom,\n setControlValue\n} from './hooks/use-smooth-controls'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["export { AnimatedCount, useAnimatedCount } from './ui/components/animated-count'\nexport { AsciiSkeleton, Scramble as AsciiScramble } from './ui/components/ascii'\nexport { Badge } from './ui/components/badge'\nexport { NouseGirlBadge } from './ui/components/badges/nous-girl'\nexport { BlendMode, useBlendMode, withBlendMode } from './ui/components/blend-mode'\nexport type { BlendModeProps } from './ui/components/blend-mode'\nexport { Blink } from './ui/components/blink'\nexport { Button } from './ui/components/button'\nexport { CommandBlock, CopyButton } from './ui/components/command-block'\nexport { Cursor } from './ui/components/cursor'\nexport { DropdownMenu } from './ui/components/dropdown-menu'\nexport { FitText } from './ui/components/fit-text'\nexport { BarChart, LineChart } from './ui/components/graphs'\nexport { Cell, Grid } from './ui/components/grid'\nexport { HoverBg } from './ui/components/hover-bg'\nexport * as Icons from './ui/components/icons'\nexport { ImageDistortion } from './ui/components/image-distortion'\nexport type { AutoPlayPattern } from './ui/components/image-distortion'\nexport { LevaClient } from './ui/components/leva-client'\nexport { Modal } from './ui/components/modal'\nexport { Poster } from './ui/components/poster'\nexport type {\n PosterAspect,\n PosterProps,\n PosterVariant\n} from './ui/components/poster'\nexport {\n applyLens,\n LENSES,\n LENS_0,\n LENS_5I,\n toggleLens,\n $lightMode\n} from './ui/components/overlays'\nexport { Overlays } from './ui/components/overlays'\nexport type { LensPreset } from './ui/components/overlays'\nexport { Progress } from './ui/components/progress'\nexport { SceneCanvas } from './ui/components/scene-canvas'\nexport { Scramble } from './ui/components/scramble'\nexport { SelectionSwitcher } from './ui/components/selection-switcher'\nexport { Stats } from './ui/components/stats'\nexport { TerminalDemo } from './ui/components/terminal-demo'\nexport type { TerminalDemoStep } from './ui/components/terminal-demo'\nexport { ThemeToggle } from './ui/components/theme-toggle'\nexport { TierCard } from './ui/components/tier-card'\nexport type { TierCardPrice, TierCardProps } from './ui/components/tier-card'\nexport { TV } from './ui/components/tv'\nexport { Watchlist } from './ui/components/watchlist'\n\nexport { Typography } from './ui/components/typography'\nexport type { TypographyProps } from './ui/components/typography'\nexport { H1 } from './ui/components/typography/h1'\nexport { H2 } from './ui/components/typography/h2'\nexport { Legend } from './ui/components/typography/legend'\nexport { Small } from './ui/components/typography/small'\n\nexport { BasicPage } from './ui/basic-page'\nexport { Header } from './ui/header'\nexport { Footer } from './ui/footer'\nexport { LayoutWrapper } from './ui/layout-wrapper'\n\nexport {\n FONT_SANS,\n FONT_MONO,\n FONT_RULES_COMPRESSED,\n FONT_RULES_EXPANDED,\n FONT_MONDWEST\n} from './fonts'\n\nexport { cn, clamp, smoothstep, hexToVec3, truncate, stripWpStyles } from './utils'\nexport { polyRef } from './utils'\nexport type { PolyComponent, PolyProps, PolyRef } from './utils'\nexport { hexToRgb, rgbToHex, colorDodge, colorMix } from './utils/color'\n\nexport { useCappedFrame } from './hooks/use-capped-frame'\nexport { useCssVarDims } from './hooks/use-css-var-dims'\nexport { $gpuTier, useGpuTier } from './hooks/use-gpu-tier'\nexport {\n useSmoothControls,\n getControlAtom,\n setControlValue\n} from './hooks/use-smooth-controls'\n"]}
@@ -61,7 +61,8 @@
61
61
  }
62
62
 
63
63
  .gc {
64
- @apply min-w-0 border-r border-inherit p-4;
64
+ min-width: 0;
65
+ @apply border-r border-inherit p-4;
65
66
 
66
67
  &:has(> .gc) {
67
68
  @apply p-0;
@@ -1,6 +1,13 @@
1
- export declare function ImageDistortion({ active, className, fallbackClassName, src, style, tint, tintStrength }: ImageDistortionProps): import("react/jsx-runtime").JSX.Element;
1
+ export declare function ImageDistortion({ active, autoPlay, className, fallbackClassName, src, style, tint, tintStrength }: ImageDistortionProps): import("react/jsx-runtime").JSX.Element;
2
+ export type AutoPlayPattern = 'aggressive' | 'gentle' | 'slash';
2
3
  interface ImageDistortionProps {
3
4
  active?: boolean;
5
+ /**
6
+ * Drive the distortion with a choreographed motion pattern instead of
7
+ * waiting for a real pointer. Useful for posters, social clips, and any
8
+ * context where the image needs to feel alive on its own.
9
+ */
10
+ autoPlay?: AutoPlayPattern;
4
11
  className?: string;
5
12
  fallbackClassName?: string;
6
13
  src: string;
@@ -1 +1 @@
1
- {"version":3,"file":"image-distortion.d.ts","sourceRoot":"","sources":["../../../src/ui/components/image-distortion.tsx"],"names":[],"mappings":"AAoGA,wBAAgB,eAAe,CAAC,EAC9B,MAAa,EACb,SAAS,EACT,iBAAiB,EACjB,GAAG,EACH,KAAK,EACL,IAAI,EACJ,YAAY,EACb,EAAE,oBAAoB,2CA4QtB;AAED,UAAU,oBAAoB;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAA;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;CACpD"}
1
+ {"version":3,"file":"image-distortion.d.ts","sourceRoot":"","sources":["../../../src/ui/components/image-distortion.tsx"],"names":[],"mappings":"AAmJA,wBAAgB,eAAe,CAAC,EAC9B,MAAa,EACb,QAAQ,EACR,SAAS,EACT,iBAAiB,EACjB,GAAG,EACH,KAAK,EACL,IAAI,EACJ,YAAY,EACb,EAAE,oBAAoB,2CAkStB;AAED,MAAM,MAAM,eAAe,GAAG,YAAY,GAAG,QAAQ,GAAG,OAAO,CAAA;AAE/D,UAAU,oBAAoB;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAA;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;CACpD"}
@@ -93,7 +93,45 @@ void main(){
93
93
 
94
94
  gl_FragColor=vec4(col,1.0);
95
95
  }`;
96
- export function ImageDistortion({ active = true, className, fallbackClassName, src, style, tint, tintStrength }) {
96
+ /**
97
+ * Choreographed motion patterns used when `autoPlay` is set. Each pattern
98
+ * returns a synthetic pointer position in [0,1] and a hover intensity in
99
+ * [0,1] for the current time (seconds). They drive the shader without
100
+ * requiring a real pointer, which is what lets us record the distortion
101
+ * as a GIF / screenshot / poster.
102
+ */
103
+ const AUTOPLAY_PATTERNS = {
104
+ aggressive: t => {
105
+ const cycle = 1.4;
106
+ const phase = (t % cycle) / cycle;
107
+ const stab = Math.exp(-((phase - 0.15) ** 2) * 260);
108
+ const angle = Math.floor(t / cycle) * 1.37;
109
+ const mx = 0.5 + Math.cos(angle) * 0.42 * (stab + 0.15);
110
+ const my = 0.5 + Math.sin(angle) * 0.38 * (stab + 0.15);
111
+ return { hover: 0.55 + stab * 0.45, mx, my };
112
+ },
113
+ gentle: t => ({
114
+ hover: 0.45 + Math.sin(t * 0.9) * 0.1,
115
+ mx: 0.5 + Math.sin(t * 0.5) * 0.28,
116
+ my: 0.5 + Math.cos(t * 0.37) * 0.22
117
+ }),
118
+ slash: t => {
119
+ // Long breath -> sword slash -> recoil twitch, repeating.
120
+ const cycle = 3.6;
121
+ const phase = (t % cycle) / cycle;
122
+ const slash = Math.exp(-((phase - 0.28) ** 2) * 180);
123
+ const micro = Math.exp(-((phase - 0.7) ** 2) * 340);
124
+ const driftX = 0.5 + Math.sin(t * 0.7) * 0.16;
125
+ const driftY = 0.55 + Math.cos(t * 0.5) * 0.14;
126
+ // Slash trajectory: bottom-left up into the giant's chest (top-right).
127
+ const slashX = -0.15 + phase * 1.55;
128
+ const slashY = 0.95 - phase * 1.35;
129
+ const mx = driftX * (1 - slash) + slashX * slash;
130
+ const my = driftY * (1 - slash) + slashY * slash;
131
+ return { hover: 0.5 + slash * 0.5 + micro * 0.35, mx, my };
132
+ }
133
+ };
134
+ export function ImageDistortion({ active = true, autoPlay, className, fallbackClassName, src, style, tint, tintStrength }) {
97
135
  const canvasRef = useRef(null);
98
136
  const tier = useGpuTier();
99
137
  const [loaded, setLoaded] = useState(false);
@@ -101,6 +139,8 @@ export function ImageDistortion({ active = true, className, fallbackClassName, s
101
139
  activeRef.current = active;
102
140
  const tintStrengthRef = useRef(tintStrength);
103
141
  tintStrengthRef.current = tintStrength;
142
+ const autoPlayRef = useRef(autoPlay);
143
+ autoPlayRef.current = autoPlay;
104
144
  const state = useRef({
105
145
  bandTargets: new Float32Array(NUM_BANDS),
106
146
  bands: new Float32Array(NUM_BANDS),
@@ -194,9 +234,14 @@ export function ImageDistortion({ active = true, className, fallbackClassName, s
194
234
  const onLeave = () => {
195
235
  state.current.hoverTarget = 0;
196
236
  };
197
- c.addEventListener('pointermove', onMove);
198
- c.addEventListener('pointerenter', onEnter);
199
- c.addEventListener('pointerleave', onLeave);
237
+ // When autoPlay drives the distortion we want the poster to look
238
+ // alive regardless of whether a pointer is near the canvas, so we
239
+ // skip the real pointer listeners entirely.
240
+ if (!autoPlayRef.current) {
241
+ c.addEventListener('pointermove', onMove);
242
+ c.addEventListener('pointerenter', onEnter);
243
+ c.addEventListener('pointerleave', onLeave);
244
+ }
200
245
  const bandEaseRates = new Float32Array(NUM_BANDS);
201
246
  for (let i = 0; i < NUM_BANDS; i++) {
202
247
  bandEaseRates[i] = 0.02 + Math.random() * 0.06;
@@ -212,6 +257,15 @@ export function ImageDistortion({ active = true, className, fallbackClassName, s
212
257
  const loop = () => {
213
258
  raf = requestAnimationFrame(loop);
214
259
  const s = state.current;
260
+ const pattern = autoPlayRef.current
261
+ ? AUTOPLAY_PATTERNS[autoPlayRef.current]
262
+ : null;
263
+ if (pattern) {
264
+ const driven = pattern((performance.now() - t0) / 1e3);
265
+ s.mx = driven.mx;
266
+ s.my = driven.my;
267
+ s.hoverTarget = driven.hover;
268
+ }
215
269
  const dvx = s.mx - s.prevMx;
216
270
  const dvy = s.my - s.prevMy;
217
271
  s.vx += (dvx * 8 - s.vx) * 0.1;
@@ -263,6 +317,10 @@ export function ImageDistortion({ active = true, className, fallbackClassName, s
263
317
  gl.deleteProgram(prog);
264
318
  setLoaded(false);
265
319
  };
320
+ // autoPlay is intentionally omitted so toggling it at runtime doesn't
321
+ // tear down the shader pipeline. The ref-driven loop reads the live
322
+ // value each frame, so listener attach/detach is handled once on mount.
323
+ // eslint-disable-next-line react-hooks/exhaustive-deps
266
324
  }, [src, tier, tint]);
267
325
  if (tier === 0) {
268
326
  return (
@@ -1 +1 @@
1
- {"version":3,"file":"image-distortion.js","sourceRoot":"","sources":["../../../src/ui/components/image-distortion.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client'\n\nimport { useEffect, useRef, useState } from 'react'\n\nimport { useGpuTier } from '../../hooks/use-gpu-tier'\nimport { cn, hexToRgb } from '../../utils'\n\nconst NUM_BANDS = 12\n\nconst VERT = `attribute vec2 a;varying vec2 vUv;void main(){vUv=vec2(a.x*.5+.5,.5-a.y*.5);gl_Position=vec4(a,0,1);}`\n\nconst FRAG = `precision highp float;\nuniform float t;\nuniform vec2 r,imgSize,vel;\nuniform sampler2D tex;\nuniform float bands[${NUM_BANDS}];\nuniform vec3 tint;\nuniform float tintStrength;\nvarying vec2 vUv;\n\nfloat h(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}\n\n// cover-style UV: crops the image to fill the canvas, centered\nvec2 coverUV(vec2 uv){\n float canvasAspect=r.x/r.y;\n float imgAspect=imgSize.x/imgSize.y;\n vec2 scale=canvasAspect>imgAspect\n ?vec2(1.0,imgAspect/canvasAspect)\n :vec2(canvasAspect/imgAspect,1.0);\n return(uv-0.5)*scale+0.5;\n}\n\nvoid main(){\n vec2 uv=coverUV(vUv);\n float scanY=floor(vUv.y*r.y);\n\n float bandF=vUv.y*${NUM_BANDS}.0;\n int bandIdx=int(floor(bandF));\n float bandFrac=fract(bandF);\n\n float strength=0.0;\n for(int i=0;i<${NUM_BANDS};i++){\n if(i==bandIdx) strength=bands[i];\n }\n\n float neighborStr=0.0;\n int neighborIdx=bandFrac>.5?bandIdx+1:bandIdx-1;\n for(int i=0;i<${NUM_BANDS};i++){\n if(i==neighborIdx) neighborStr=bands[i];\n }\n float edgeBlend=abs(bandFrac-.5)*2.0;\n edgeBlend*=edgeBlend;\n strength=mix(strength,neighborStr,edgeBlend*.3);\n\n float speed=length(vel);\n float dirBlend=smoothstep(0.0,0.02,speed);\n vec2 dir=speed>.0001?vel/speed:vec2(0);\n dir*=dirBlend;\n\n float rowSeed=h(vec2(scanY,floor(t*3.)+float(bandIdx)*7.));\n float rowVar=mix(.4,1.0,rowSeed);\n\n float ySmooth=vUv.y*6.0+t*0.7;\n float yNoise=mix(h(vec2(floor(ySmooth),13.)),h(vec2(floor(ySmooth)+1.0,13.)),smoothstep(0.0,1.0,fract(ySmooth)));\n float colVar=mix(.4,1.0,yNoise);\n\n float tearShiftX=dir.x*strength*rowVar*0.15;\n float tearShiftY=dir.y*strength*colVar*0.10;\n\n float bandSeed=h(vec2(float(bandIdx),42.));\n tearShiftX+=strength*(.5-bandSeed)*0.05;\n\n float yJitter=mix(h(vec2(floor(ySmooth),73.)),h(vec2(floor(ySmooth)+1.0,73.)),smoothstep(0.0,1.0,fract(ySmooth)));\n tearShiftY+=strength*(.5-yJitter)*0.035;\n\n uv.x+=tearShiftX;\n uv.y+=tearShiftY;\n\n float sortGate=step(.5,strength)*step(.4,rowSeed);\n uv.x+=dir.x*sortGate*strength*0.03;\n uv.y+=dir.y*sortGate*strength*0.02;\n\n float caX=abs(tearShiftX)*2.5+sortGate*strength*0.01;\n float caY=abs(tearShiftY)*2.5+sortGate*strength*0.01;\n float cr=texture2D(tex,vec2(uv.x+caX,uv.y+caY)).r;\n float cg=texture2D(tex,uv).g;\n float cb=texture2D(tex,vec2(uv.x-caX,uv.y-caY)).b;\n\n vec3 col=vec3(cr,cg,cb);\n\n col*=.97+.03*sin(vUv.y*r.y*3.14159);\n\n float bandEdge=smoothstep(.02,.0,min(bandFrac,1.0-bandFrac));\n col+=vec3(bandEdge*strength*.1);\n\n col=mix(col,col*tint,tintStrength);\n\n gl_FragColor=vec4(col,1.0);\n}`\n\nexport function ImageDistortion({\n active = true,\n className,\n fallbackClassName,\n src,\n style,\n tint,\n tintStrength\n}: ImageDistortionProps) {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const tier = useGpuTier()\n const [loaded, setLoaded] = useState(false)\n\n const activeRef = useRef(active)\n activeRef.current = active\n const tintStrengthRef = useRef(tintStrength)\n tintStrengthRef.current = tintStrength\n\n const state = useRef({\n bandTargets: new Float32Array(NUM_BANDS),\n bands: new Float32Array(NUM_BANDS),\n hoverTarget: 0,\n imgH: 1,\n imgW: 1,\n mx: 0.5,\n my: 0.5,\n prevMx: 0.5,\n prevMy: 0.5,\n vx: 0,\n vy: 0\n })\n\n useEffect(() => {\n if (tier === 0) {\n return\n }\n\n const c = canvasRef.current\n\n if (!c) {\n return\n }\n\n const gl = c.getContext('webgl')\n\n if (!gl) {\n return\n }\n\n const compile = (type: number, source: string) => {\n const s = gl.createShader(type)!\n gl.shaderSource(s, source)\n gl.compileShader(s)\n\n return s\n }\n\n const prog = gl.createProgram()!\n gl.attachShader(prog, compile(gl.VERTEX_SHADER, VERT))\n gl.attachShader(prog, compile(gl.FRAGMENT_SHADER, FRAG))\n gl.linkProgram(prog)\n gl.useProgram(prog)\n\n gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer())\n gl.bufferData(\n gl.ARRAY_BUFFER,\n new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n gl.STATIC_DRAW\n )\n\n const a = gl.getAttribLocation(prog, 'a')\n gl.enableVertexAttribArray(a)\n gl.vertexAttribPointer(a, 2, gl.FLOAT, false, 0, 0)\n\n const uT = gl.getUniformLocation(prog, 't')\n const uR = gl.getUniformLocation(prog, 'r')\n const uImgSize = gl.getUniformLocation(prog, 'imgSize')\n const uVel = gl.getUniformLocation(prog, 'vel')\n const uTex = gl.getUniformLocation(prog, 'tex')\n const uTint = gl.getUniformLocation(prog, 'tint')\n const uTintStrength = gl.getUniformLocation(prog, 'tintStrength')\n const uBands: (null | WebGLUniformLocation)[] = []\n\n for (let i = 0; i < NUM_BANDS; i++) {\n uBands.push(gl.getUniformLocation(prog, `bands[${i}]`))\n }\n\n const texture = gl.createTexture()!\n gl.bindTexture(gl.TEXTURE_2D, texture)\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)\n gl.texImage2D(\n gl.TEXTURE_2D,\n 0,\n gl.RGBA,\n 1,\n 1,\n 0,\n gl.RGBA,\n gl.UNSIGNED_BYTE,\n new Uint8Array([0, 0, 0, 255])\n )\n\n const img = new Image()\n img.crossOrigin = 'anonymous'\n\n img.onload = () => {\n state.current.imgW = img.naturalWidth\n state.current.imgH = img.naturalHeight\n gl.bindTexture(gl.TEXTURE_2D, texture)\n gl.texImage2D(\n gl.TEXTURE_2D,\n 0,\n gl.RGBA,\n gl.RGBA,\n gl.UNSIGNED_BYTE,\n img\n )\n setLoaded(true)\n }\n\n img.src = src\n\n gl.activeTexture(gl.TEXTURE0)\n gl.bindTexture(gl.TEXTURE_2D, texture)\n gl.uniform1i(uTex, 0)\n\n const resize = () => {\n const rect = c.getBoundingClientRect()\n const dpr = Math.min(devicePixelRatio, 2)\n c.width = rect.width * dpr\n c.height = rect.height * dpr\n gl.viewport(0, 0, c.width, c.height)\n }\n\n resize()\n const ro = new ResizeObserver(resize)\n ro.observe(c)\n\n const onMove = (e: PointerEvent) => {\n const rect = c.getBoundingClientRect()\n state.current.mx = (e.clientX - rect.left) / rect.width\n state.current.my = (e.clientY - rect.top) / rect.height\n }\n\n const onEnter = () => {\n state.current.hoverTarget = 1\n }\n\n const onLeave = () => {\n state.current.hoverTarget = 0\n }\n\n c.addEventListener('pointermove', onMove)\n c.addEventListener('pointerenter', onEnter)\n c.addEventListener('pointerleave', onLeave)\n\n const bandEaseRates = new Float32Array(NUM_BANDS)\n\n for (let i = 0; i < NUM_BANDS; i++) {\n bandEaseRates[i] = 0.02 + Math.random() * 0.06\n }\n\n const tintVec: readonly [number, number, number] = tint\n ? (() => {\n const [tr, tg, tb] = hexToRgb(tint)\n\n return [tr / 255, tg / 255, tb / 255] as const\n })()\n : ([1, 1, 1] as const)\n\n const t0 = performance.now()\n let raf = 0\n\n const loop = () => {\n raf = requestAnimationFrame(loop)\n const s = state.current\n\n const dvx = s.mx - s.prevMx\n const dvy = s.my - s.prevMy\n s.vx += (dvx * 8 - s.vx) * 0.1\n s.vy += (dvy * 8 - s.vy) * 0.1\n s.prevMx = s.mx\n s.prevMy = s.my\n\n const speed = Math.sqrt(s.vx * s.vx + s.vy * s.vy)\n\n for (let i = 0; i < NUM_BANDS; i++) {\n const bandCenter = (i + 0.5) / NUM_BANDS\n const dist = Math.abs(s.my - bandCenter)\n const proximity = Math.max(0, 1 - dist / 0.3)\n const activation =\n s.hoverTarget * proximity * (0.4 + Math.min(speed, 1) * 0.6)\n s.bandTargets[i] = activation\n }\n\n for (let i = 0; i < NUM_BANDS; i++) {\n const rate = bandEaseRates[i]!\n const current = s.bands[i] ?? 0\n const target = s.bandTargets[i] ?? 0\n s.bands[i] = current + (target - current) * rate\n\n if (s.bands[i]! < 0.001) {\n s.bands[i] = 0\n }\n }\n\n gl.uniform1f(uT, (performance.now() - t0) / 1e3)\n gl.uniform2f(uR, c.width, c.height)\n gl.uniform2f(uImgSize, s.imgW, s.imgH)\n gl.uniform2f(uVel, s.vx, s.vy)\n gl.uniform3f(uTint, tintVec[0], tintVec[1], tintVec[2])\n\n const ts = tintStrengthRef.current\n const defaultStrength = tint ? 0.35 : 0\n const defaultInactive = tint ? 0.15 : 0\n gl.uniform1f(\n uTintStrength,\n activeRef.current\n ? (ts?.active ?? defaultStrength)\n : (ts?.inactive ?? defaultInactive)\n )\n\n for (let i = 0; i < NUM_BANDS; i++) {\n gl.uniform1f(uBands[i]!, s.bands[i]!)\n }\n\n gl.bindTexture(gl.TEXTURE_2D, texture)\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4)\n }\n\n raf = requestAnimationFrame(loop)\n\n return () => {\n cancelAnimationFrame(raf)\n ro.disconnect()\n c.removeEventListener('pointermove', onMove)\n c.removeEventListener('pointerenter', onEnter)\n c.removeEventListener('pointerleave', onLeave)\n gl.deleteTexture(texture)\n gl.deleteProgram(prog)\n setLoaded(false)\n }\n }, [src, tier, tint])\n\n if (tier === 0) {\n return (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n alt=\"\"\n className={cn(\n 'absolute inset-0 h-full w-full object-cover',\n fallbackClassName ?? className\n )}\n src={src}\n style={{ mixBlendMode: 'overlay', ...style }}\n />\n )\n }\n\n return (\n <canvas\n className={cn(\n 'absolute inset-0 h-full w-full transition-opacity duration-500',\n className\n )}\n ref={canvasRef}\n style={{\n mixBlendMode: 'overlay',\n opacity: loaded ? 1 : 0,\n ...style\n }}\n />\n )\n}\n\ninterface ImageDistortionProps {\n active?: boolean\n className?: string\n fallbackClassName?: string\n src: string\n style?: React.CSSProperties\n tint?: string\n tintStrength?: { active: number; inactive: number }\n}\n"]}
1
+ {"version":3,"file":"image-distortion.js","sourceRoot":"","sources":["../../../src/ui/components/image-distortion.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client'\n\nimport { useEffect, useRef, useState } from 'react'\n\nimport { useGpuTier } from '../../hooks/use-gpu-tier'\nimport { cn, hexToRgb } from '../../utils'\n\nconst NUM_BANDS = 12\n\nconst VERT = `attribute vec2 a;varying vec2 vUv;void main(){vUv=vec2(a.x*.5+.5,.5-a.y*.5);gl_Position=vec4(a,0,1);}`\n\nconst FRAG = `precision highp float;\nuniform float t;\nuniform vec2 r,imgSize,vel;\nuniform sampler2D tex;\nuniform float bands[${NUM_BANDS}];\nuniform vec3 tint;\nuniform float tintStrength;\nvarying vec2 vUv;\n\nfloat h(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}\n\n// cover-style UV: crops the image to fill the canvas, centered\nvec2 coverUV(vec2 uv){\n float canvasAspect=r.x/r.y;\n float imgAspect=imgSize.x/imgSize.y;\n vec2 scale=canvasAspect>imgAspect\n ?vec2(1.0,imgAspect/canvasAspect)\n :vec2(canvasAspect/imgAspect,1.0);\n return(uv-0.5)*scale+0.5;\n}\n\nvoid main(){\n vec2 uv=coverUV(vUv);\n float scanY=floor(vUv.y*r.y);\n\n float bandF=vUv.y*${NUM_BANDS}.0;\n int bandIdx=int(floor(bandF));\n float bandFrac=fract(bandF);\n\n float strength=0.0;\n for(int i=0;i<${NUM_BANDS};i++){\n if(i==bandIdx) strength=bands[i];\n }\n\n float neighborStr=0.0;\n int neighborIdx=bandFrac>.5?bandIdx+1:bandIdx-1;\n for(int i=0;i<${NUM_BANDS};i++){\n if(i==neighborIdx) neighborStr=bands[i];\n }\n float edgeBlend=abs(bandFrac-.5)*2.0;\n edgeBlend*=edgeBlend;\n strength=mix(strength,neighborStr,edgeBlend*.3);\n\n float speed=length(vel);\n float dirBlend=smoothstep(0.0,0.02,speed);\n vec2 dir=speed>.0001?vel/speed:vec2(0);\n dir*=dirBlend;\n\n float rowSeed=h(vec2(scanY,floor(t*3.)+float(bandIdx)*7.));\n float rowVar=mix(.4,1.0,rowSeed);\n\n float ySmooth=vUv.y*6.0+t*0.7;\n float yNoise=mix(h(vec2(floor(ySmooth),13.)),h(vec2(floor(ySmooth)+1.0,13.)),smoothstep(0.0,1.0,fract(ySmooth)));\n float colVar=mix(.4,1.0,yNoise);\n\n float tearShiftX=dir.x*strength*rowVar*0.15;\n float tearShiftY=dir.y*strength*colVar*0.10;\n\n float bandSeed=h(vec2(float(bandIdx),42.));\n tearShiftX+=strength*(.5-bandSeed)*0.05;\n\n float yJitter=mix(h(vec2(floor(ySmooth),73.)),h(vec2(floor(ySmooth)+1.0,73.)),smoothstep(0.0,1.0,fract(ySmooth)));\n tearShiftY+=strength*(.5-yJitter)*0.035;\n\n uv.x+=tearShiftX;\n uv.y+=tearShiftY;\n\n float sortGate=step(.5,strength)*step(.4,rowSeed);\n uv.x+=dir.x*sortGate*strength*0.03;\n uv.y+=dir.y*sortGate*strength*0.02;\n\n float caX=abs(tearShiftX)*2.5+sortGate*strength*0.01;\n float caY=abs(tearShiftY)*2.5+sortGate*strength*0.01;\n float cr=texture2D(tex,vec2(uv.x+caX,uv.y+caY)).r;\n float cg=texture2D(tex,uv).g;\n float cb=texture2D(tex,vec2(uv.x-caX,uv.y-caY)).b;\n\n vec3 col=vec3(cr,cg,cb);\n\n col*=.97+.03*sin(vUv.y*r.y*3.14159);\n\n float bandEdge=smoothstep(.02,.0,min(bandFrac,1.0-bandFrac));\n col+=vec3(bandEdge*strength*.1);\n\n col=mix(col,col*tint,tintStrength);\n\n gl_FragColor=vec4(col,1.0);\n}`\n\n/**\n * Choreographed motion patterns used when `autoPlay` is set. Each pattern\n * returns a synthetic pointer position in [0,1] and a hover intensity in\n * [0,1] for the current time (seconds). They drive the shader without\n * requiring a real pointer, which is what lets us record the distortion\n * as a GIF / screenshot / poster.\n */\nconst AUTOPLAY_PATTERNS: Record<\n AutoPlayPattern,\n (t: number) => { hover: number; mx: number; my: number }\n> = {\n aggressive: t => {\n const cycle = 1.4\n const phase = (t % cycle) / cycle\n const stab = Math.exp(-((phase - 0.15) ** 2) * 260)\n const angle = Math.floor(t / cycle) * 1.37\n const mx = 0.5 + Math.cos(angle) * 0.42 * (stab + 0.15)\n const my = 0.5 + Math.sin(angle) * 0.38 * (stab + 0.15)\n\n return { hover: 0.55 + stab * 0.45, mx, my }\n },\n gentle: t => ({\n hover: 0.45 + Math.sin(t * 0.9) * 0.1,\n mx: 0.5 + Math.sin(t * 0.5) * 0.28,\n my: 0.5 + Math.cos(t * 0.37) * 0.22\n }),\n slash: t => {\n // Long breath -> sword slash -> recoil twitch, repeating.\n const cycle = 3.6\n const phase = (t % cycle) / cycle\n const slash = Math.exp(-((phase - 0.28) ** 2) * 180)\n const micro = Math.exp(-((phase - 0.7) ** 2) * 340)\n\n const driftX = 0.5 + Math.sin(t * 0.7) * 0.16\n const driftY = 0.55 + Math.cos(t * 0.5) * 0.14\n\n // Slash trajectory: bottom-left up into the giant's chest (top-right).\n const slashX = -0.15 + phase * 1.55\n const slashY = 0.95 - phase * 1.35\n\n const mx = driftX * (1 - slash) + slashX * slash\n const my = driftY * (1 - slash) + slashY * slash\n\n return { hover: 0.5 + slash * 0.5 + micro * 0.35, mx, my }\n }\n}\n\nexport function ImageDistortion({\n active = true,\n autoPlay,\n className,\n fallbackClassName,\n src,\n style,\n tint,\n tintStrength\n}: ImageDistortionProps) {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const tier = useGpuTier()\n const [loaded, setLoaded] = useState(false)\n\n const activeRef = useRef(active)\n activeRef.current = active\n const tintStrengthRef = useRef(tintStrength)\n tintStrengthRef.current = tintStrength\n const autoPlayRef = useRef(autoPlay)\n autoPlayRef.current = autoPlay\n\n const state = useRef({\n bandTargets: new Float32Array(NUM_BANDS),\n bands: new Float32Array(NUM_BANDS),\n hoverTarget: 0,\n imgH: 1,\n imgW: 1,\n mx: 0.5,\n my: 0.5,\n prevMx: 0.5,\n prevMy: 0.5,\n vx: 0,\n vy: 0\n })\n\n useEffect(() => {\n if (tier === 0) {\n return\n }\n\n const c = canvasRef.current\n\n if (!c) {\n return\n }\n\n const gl = c.getContext('webgl')\n\n if (!gl) {\n return\n }\n\n const compile = (type: number, source: string) => {\n const s = gl.createShader(type)!\n gl.shaderSource(s, source)\n gl.compileShader(s)\n\n return s\n }\n\n const prog = gl.createProgram()!\n gl.attachShader(prog, compile(gl.VERTEX_SHADER, VERT))\n gl.attachShader(prog, compile(gl.FRAGMENT_SHADER, FRAG))\n gl.linkProgram(prog)\n gl.useProgram(prog)\n\n gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer())\n gl.bufferData(\n gl.ARRAY_BUFFER,\n new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n gl.STATIC_DRAW\n )\n\n const a = gl.getAttribLocation(prog, 'a')\n gl.enableVertexAttribArray(a)\n gl.vertexAttribPointer(a, 2, gl.FLOAT, false, 0, 0)\n\n const uT = gl.getUniformLocation(prog, 't')\n const uR = gl.getUniformLocation(prog, 'r')\n const uImgSize = gl.getUniformLocation(prog, 'imgSize')\n const uVel = gl.getUniformLocation(prog, 'vel')\n const uTex = gl.getUniformLocation(prog, 'tex')\n const uTint = gl.getUniformLocation(prog, 'tint')\n const uTintStrength = gl.getUniformLocation(prog, 'tintStrength')\n const uBands: (null | WebGLUniformLocation)[] = []\n\n for (let i = 0; i < NUM_BANDS; i++) {\n uBands.push(gl.getUniformLocation(prog, `bands[${i}]`))\n }\n\n const texture = gl.createTexture()!\n gl.bindTexture(gl.TEXTURE_2D, texture)\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)\n gl.texImage2D(\n gl.TEXTURE_2D,\n 0,\n gl.RGBA,\n 1,\n 1,\n 0,\n gl.RGBA,\n gl.UNSIGNED_BYTE,\n new Uint8Array([0, 0, 0, 255])\n )\n\n const img = new Image()\n img.crossOrigin = 'anonymous'\n\n img.onload = () => {\n state.current.imgW = img.naturalWidth\n state.current.imgH = img.naturalHeight\n gl.bindTexture(gl.TEXTURE_2D, texture)\n gl.texImage2D(\n gl.TEXTURE_2D,\n 0,\n gl.RGBA,\n gl.RGBA,\n gl.UNSIGNED_BYTE,\n img\n )\n setLoaded(true)\n }\n\n img.src = src\n\n gl.activeTexture(gl.TEXTURE0)\n gl.bindTexture(gl.TEXTURE_2D, texture)\n gl.uniform1i(uTex, 0)\n\n const resize = () => {\n const rect = c.getBoundingClientRect()\n const dpr = Math.min(devicePixelRatio, 2)\n c.width = rect.width * dpr\n c.height = rect.height * dpr\n gl.viewport(0, 0, c.width, c.height)\n }\n\n resize()\n const ro = new ResizeObserver(resize)\n ro.observe(c)\n\n const onMove = (e: PointerEvent) => {\n const rect = c.getBoundingClientRect()\n state.current.mx = (e.clientX - rect.left) / rect.width\n state.current.my = (e.clientY - rect.top) / rect.height\n }\n\n const onEnter = () => {\n state.current.hoverTarget = 1\n }\n\n const onLeave = () => {\n state.current.hoverTarget = 0\n }\n\n // When autoPlay drives the distortion we want the poster to look\n // alive regardless of whether a pointer is near the canvas, so we\n // skip the real pointer listeners entirely.\n if (!autoPlayRef.current) {\n c.addEventListener('pointermove', onMove)\n c.addEventListener('pointerenter', onEnter)\n c.addEventListener('pointerleave', onLeave)\n }\n\n const bandEaseRates = new Float32Array(NUM_BANDS)\n\n for (let i = 0; i < NUM_BANDS; i++) {\n bandEaseRates[i] = 0.02 + Math.random() * 0.06\n }\n\n const tintVec: readonly [number, number, number] = tint\n ? (() => {\n const [tr, tg, tb] = hexToRgb(tint)\n\n return [tr / 255, tg / 255, tb / 255] as const\n })()\n : ([1, 1, 1] as const)\n\n const t0 = performance.now()\n let raf = 0\n\n const loop = () => {\n raf = requestAnimationFrame(loop)\n const s = state.current\n\n const pattern = autoPlayRef.current\n ? AUTOPLAY_PATTERNS[autoPlayRef.current]\n : null\n\n if (pattern) {\n const driven = pattern((performance.now() - t0) / 1e3)\n s.mx = driven.mx\n s.my = driven.my\n s.hoverTarget = driven.hover\n }\n\n const dvx = s.mx - s.prevMx\n const dvy = s.my - s.prevMy\n s.vx += (dvx * 8 - s.vx) * 0.1\n s.vy += (dvy * 8 - s.vy) * 0.1\n s.prevMx = s.mx\n s.prevMy = s.my\n\n const speed = Math.sqrt(s.vx * s.vx + s.vy * s.vy)\n\n for (let i = 0; i < NUM_BANDS; i++) {\n const bandCenter = (i + 0.5) / NUM_BANDS\n const dist = Math.abs(s.my - bandCenter)\n const proximity = Math.max(0, 1 - dist / 0.3)\n const activation =\n s.hoverTarget * proximity * (0.4 + Math.min(speed, 1) * 0.6)\n s.bandTargets[i] = activation\n }\n\n for (let i = 0; i < NUM_BANDS; i++) {\n const rate = bandEaseRates[i]!\n const current = s.bands[i] ?? 0\n const target = s.bandTargets[i] ?? 0\n s.bands[i] = current + (target - current) * rate\n\n if (s.bands[i]! < 0.001) {\n s.bands[i] = 0\n }\n }\n\n gl.uniform1f(uT, (performance.now() - t0) / 1e3)\n gl.uniform2f(uR, c.width, c.height)\n gl.uniform2f(uImgSize, s.imgW, s.imgH)\n gl.uniform2f(uVel, s.vx, s.vy)\n gl.uniform3f(uTint, tintVec[0], tintVec[1], tintVec[2])\n\n const ts = tintStrengthRef.current\n const defaultStrength = tint ? 0.35 : 0\n const defaultInactive = tint ? 0.15 : 0\n gl.uniform1f(\n uTintStrength,\n activeRef.current\n ? (ts?.active ?? defaultStrength)\n : (ts?.inactive ?? defaultInactive)\n )\n\n for (let i = 0; i < NUM_BANDS; i++) {\n gl.uniform1f(uBands[i]!, s.bands[i]!)\n }\n\n gl.bindTexture(gl.TEXTURE_2D, texture)\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4)\n }\n\n raf = requestAnimationFrame(loop)\n\n return () => {\n cancelAnimationFrame(raf)\n ro.disconnect()\n c.removeEventListener('pointermove', onMove)\n c.removeEventListener('pointerenter', onEnter)\n c.removeEventListener('pointerleave', onLeave)\n gl.deleteTexture(texture)\n gl.deleteProgram(prog)\n setLoaded(false)\n }\n // autoPlay is intentionally omitted so toggling it at runtime doesn't\n // tear down the shader pipeline. The ref-driven loop reads the live\n // value each frame, so listener attach/detach is handled once on mount.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [src, tier, tint])\n\n if (tier === 0) {\n return (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n alt=\"\"\n className={cn(\n 'absolute inset-0 h-full w-full object-cover',\n fallbackClassName ?? className\n )}\n src={src}\n style={{ mixBlendMode: 'overlay', ...style }}\n />\n )\n }\n\n return (\n <canvas\n className={cn(\n 'absolute inset-0 h-full w-full transition-opacity duration-500',\n className\n )}\n ref={canvasRef}\n style={{\n mixBlendMode: 'overlay',\n opacity: loaded ? 1 : 0,\n ...style\n }}\n />\n )\n}\n\nexport type AutoPlayPattern = 'aggressive' | 'gentle' | 'slash'\n\ninterface ImageDistortionProps {\n active?: boolean\n /**\n * Drive the distortion with a choreographed motion pattern instead of\n * waiting for a real pointer. Useful for posters, social clips, and any\n * context where the image needs to feel alive on its own.\n */\n autoPlay?: AutoPlayPattern\n className?: string\n fallbackClassName?: string\n src: string\n style?: React.CSSProperties\n tint?: string\n tintStrength?: { active: number; inactive: number }\n}\n"]}
@@ -34,12 +34,26 @@ export declare const LENS_5I: {
34
34
  };
35
35
  };
36
36
  export declare const lens0: (l?: Partial<typeof LENS_0.Lens>, g?: Partial<typeof LENS_0.Globe>) => LensPreset;
37
+ export declare const lens5i: (l?: Partial<typeof LENS_5I.Lens>, g?: Partial<typeof LENS_5I.Globe>) => LensPreset;
37
38
  export declare const LENSES: [string, LensPreset][];
38
39
  export declare const applyLens: (preset: LensPreset, animate?: boolean) => void;
39
40
  export declare const $lightMode: import("nanostores").PreinitializedWritableAtom<boolean> & object;
40
41
  export declare const toggleLens: () => void;
41
- export declare function Overlays({ dark }: {
42
+ export declare function Overlays({ dark, initial }: OverlaysProps): import("react/jsx-runtime").JSX.Element;
43
+ export interface LensPreset {
44
+ Globe: typeof LENS_0.Globe;
45
+ Lens: typeof LENS_0.Lens;
46
+ }
47
+ interface OverlaysProps {
42
48
  dark?: boolean;
43
- }): import("react/jsx-runtime").JSX.Element;
44
- export type LensPreset = Record<string, Record<string, unknown>>;
49
+ /**
50
+ * Exact preset to seed the internal Leva controls with. When omitted the
51
+ * component falls back to `LENS_0` / `LENS_5I` based on `dark`. Pass the
52
+ * actual preset from a host (e.g. Storybook toolbar) to guarantee the
53
+ * first-paint colors match the selected lens without needing a followup
54
+ * `applyLens` that can be lost in useSmoothControls' startup window.
55
+ */
56
+ initial?: LensPreset;
57
+ }
58
+ export {};
45
59
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/overlays/index.tsx"],"names":[],"mappings":"AAqBA,eAAO,MAAM,WAAW,EAYR,KAAK,CAAC,aAAa,CAAC,cAAc,CAAC,EAAE,CAAA;AAErD,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;AAEF,eAAO,MAAM,MAAM,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,EAiBxC,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,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,2CAmFpD;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/overlays/index.tsx"],"names":[],"mappings":"AAqBA,eAAO,MAAM,WAAW,EAYR,KAAK,CAAC,aAAa,CAAC,cAAc,CAAC,EAAE,CAAA;AAErD,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,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,aAAa,2CAkGxD;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,OAAO,MAAM,CAAC,KAAK,CAAA;IAC1B,IAAI,EAAE,OAAO,MAAM,CAAC,IAAI,CAAA;CACzB;AAED,UAAU,aAAa;IACrB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,UAAU,CAAA;CACrB"}
@@ -53,23 +53,28 @@ export const lens0 = (l, g) => ({
53
53
  Globe: { ...LENS_0.Globe, ...g },
54
54
  Lens: { ...LENS_0.Lens, ...l }
55
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.
56
69
  export const LENSES = [
57
70
  ['0', LENS_0],
58
- ['1', lens0({ bgColor: '#041C1C', fgOpacity: 1 })],
59
- ['2', lens0({ bgColor: '#0E0313', fgOpacity: 1 })],
60
- ['3', lens0({ bgColor: '#003EB4', fgColor: '#001289', fgOpacity: 1 })],
61
- ['4', lens0({ bgColor: '#0E39AA', fgColor: '#001289', fgOpacity: 1 })],
71
+ ['1', lens0({ bgColor: '#0A1F1F' })],
72
+ ['2', lens0({ bgColor: '#0E0313', mgColor: '#e6cbff' })],
73
+ ['3', lens5i({ mgColor: '#FFAC02' })],
74
+ ['4', lens5i({ bgColor: '#0E0313', mgColor: '#FF5500' })],
62
75
  ['5', lens0({ bgColor: '#1540B1', bgOpacity: 0.7 })],
63
76
  ['5i', LENS_5I],
64
- [
65
- '6',
66
- lens0({
67
- bgColor: '#0e39aa',
68
- fgColor: '#001289',
69
- fgOpacity: 1,
70
- mgColor: '#ffffff'
71
- })
72
- ],
77
+ ['6', lens5i({ bgColor: '#170D02', mgColor: '#00E5FF' })]
73
78
  ];
74
79
  export const applyLens = (preset, animate = false) => Object.entries(preset).forEach(([g, v]) => Object.entries(v).forEach(([k, val]) => setControlValue(g, k, val, { animate })));
75
80
  export const $lightMode = atom(true);
@@ -79,23 +84,27 @@ export const toggleLens = () => {
79
84
  $lightMode.set(!isLight);
80
85
  applyLens(next, true);
81
86
  };
82
- export function Overlays({ dark }) {
83
- const init = dark ? LENS_0.Lens : LENS_5I.Lens;
87
+ export function Overlays({ dark, initial }) {
88
+ // `initial` lets the host (e.g. Storybook) seed the Leva/atom state with
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);
84
94
  const lens = useSmoothControls('Lens', {
85
- bgBlend: { options: BLEND_MODES, value: init.bgBlend },
86
- bgColor: { value: init.bgColor },
87
- bgOpacity: { max: 1, min: 0, step: 0.01, value: init.bgOpacity },
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 },
88
98
  fgBlend: { options: BLEND_MODES, value: 'difference' },
89
- fgColor: { value: init.fgColor },
90
- fgOpacity: { max: 1, min: 0, step: 0.01, value: init.fgOpacity },
99
+ fgColor: { value: base.fgColor },
100
+ fgOpacity: { max: 1, min: 0, step: 0.01, value: base.fgOpacity },
91
101
  fillerBlend: { options: BLEND_MODES, value: 'difference' },
92
- fillerOpacity: { max: 1, min: 0, step: 0.01, value: init.fillerOpacity },
93
- mgColor: { value: init.mgColor },
94
- mgOpacity: { max: 1, min: 0, step: 0.01, value: init.mgOpacity }
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 }
95
105
  }, { collapsed: false });
96
106
  useEffect(() => {
97
107
  $lightMode.set(!dark);
98
- applyLens(dark ? LENS_0 : LENS_5I);
99
108
  }, [dark]);
100
109
  useEffect(() => {
101
110
  const s = document.documentElement.style;
@@ -114,12 +123,23 @@ export function Overlays({ dark }) {
114
123
  window.addEventListener('keydown', handle);
115
124
  return () => window.removeEventListener('keydown', handle);
116
125
  }, []);
117
- return (_jsxs(_Fragment, { children: [_jsx(Noise, { className: `${LAYER} z-101` }), _jsx("div", { className: `${LAYER} z-100`, style: {
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: {
118
132
  backgroundColor: colorMix(lens.fgColor, lens.fgOpacity),
119
- mixBlendMode: lens.fgBlend
120
- } }), _jsx(Vignette, { className: `${LAYER} z-99` }), _jsx(Greys, { className: `${LAYER} z-200` }), _jsx(Glitch, { className: `${LAYER} z-201` }), _jsx("div", { className: `${LAYER} z-2`, style: { mixBlendMode: lens.fillerBlend, opacity: lens.fillerOpacity }, 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} z-1`, style: {
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: {
121
140
  backgroundColor: colorMix(lens.bgColor, lens.bgOpacity),
122
- mixBlendMode: lens.bgBlend
141
+ mixBlendMode: lens.bgBlend,
142
+ zIndex: 1
123
143
  } })] }));
124
144
  }
125
145
  //# 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\nexport const LENSES: [string, LensPreset][] = [\n ['0', LENS_0],\n ['1', lens0({ bgColor: '#041C1C', fgOpacity: 1 })],\n ['2', lens0({ bgColor: '#0E0313', fgOpacity: 1 })],\n ['3', lens0({ bgColor: '#003EB4', fgColor: '#001289', fgOpacity: 1 })],\n ['4', lens0({ bgColor: '#0E39AA', fgColor: '#001289', fgOpacity: 1 })],\n ['5', lens0({ bgColor: '#1540B1', bgOpacity: 0.7 })],\n ['5i', LENS_5I],\n [\n '6',\n lens0({\n bgColor: '#0e39aa',\n fgColor: '#001289',\n fgOpacity: 1,\n mgColor: '#ffffff'\n })\n ],\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 }: { dark?: boolean }) {\n const init = dark ? LENS_0.Lens : LENS_5I.Lens\n\n const lens = useSmoothControls(\n 'Lens',\n {\n bgBlend: { options: BLEND_MODES, value: init.bgBlend as 'multiply' },\n bgColor: { value: init.bgColor },\n bgOpacity: { max: 1, min: 0, step: 0.01, value: init.bgOpacity },\n fgBlend: { options: BLEND_MODES, value: 'difference' as const },\n fgColor: { value: init.fgColor },\n fgOpacity: { max: 1, min: 0, step: 0.01, value: init.fgOpacity },\n fillerBlend: { options: BLEND_MODES, value: 'difference' as const },\n fillerOpacity: { max: 1, min: 0, step: 0.01, value: init.fillerOpacity },\n mgColor: { value: init.mgColor },\n mgOpacity: { max: 1, min: 0, step: 0.01, value: init.mgOpacity }\n },\n { collapsed: false }\n )\n\n useEffect(() => {\n $lightMode.set(!dark)\n applyLens(dark ? LENS_0 : LENS_5I)\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 return (\n <>\n <Noise className={`${LAYER} z-101`} />\n\n <div\n className={`${LAYER} z-100`}\n style={{\n backgroundColor: colorMix(lens.fgColor, lens.fgOpacity),\n mixBlendMode: lens.fgBlend\n }}\n />\n\n <Vignette className={`${LAYER} z-99`} />\n <Greys className={`${LAYER} z-200`} />\n <Glitch className={`${LAYER} z-201`} />\n\n <div\n className={`${LAYER} z-2`}\n style={{ mixBlendMode: lens.fillerBlend, opacity: lens.fillerOpacity }}\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} z-1`}\n style={{\n backgroundColor: colorMix(lens.bgColor, lens.bgOpacity),\n mixBlendMode: lens.bgBlend\n }}\n />\n </>\n )\n}\n\nexport type LensPreset = Record<string, Record<string, unknown>>\n"]}
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"]}
@@ -0,0 +1,63 @@
1
+ import type { AutoPlayPattern } from './image-distortion';
2
+ /**
3
+ * Social-ready glitchy card built around the haptic-distortion image
4
+ * component. The poster runs the sword-guy distortion on an auto-animated
5
+ * slash pattern so it can be screen-recorded as a GIF without a human
6
+ * moving a cursor.
7
+ *
8
+ * Two variants, matching actual use cases:
9
+ * - `'vibe'` (default): full-bleed distorted image with just registration
10
+ * marks and a tiny "Hermes Agent" mark in the corner — mirrors the
11
+ * overlay on the Hermes agent website.
12
+ * - `'dispatch'`: broadcast-card layout with sidebar copy, numbered tags,
13
+ * and chrome — for when the poster needs to carry information.
14
+ */
15
+ export declare function Poster({ aspect, autoPlay, body, border, channel, children, className, cornerMarks, eyebrow, headline, layout, scale, seal, signature, src, tags, tint, tintStrength, variant, ...rest }: PosterProps): import("react/jsx-runtime").JSX.Element;
16
+ export type PosterAspect = 'landscape' | 'portrait' | 'square' | 'story' | 'wide';
17
+ export type PosterVariant = 'dispatch' | 'vibe';
18
+ export interface PosterProps {
19
+ /** Output aspect ratio. Picks sensible defaults for common social formats. */
20
+ aspect?: PosterAspect;
21
+ /** Distortion choreography pattern. Default: `'slash'`. */
22
+ autoPlay?: AutoPlayPattern;
23
+ /** (`dispatch` only) Descriptive copy under the headline. */
24
+ body?: React.ReactNode;
25
+ /** Show the thin outer frame around the poster. Default `true`. */
26
+ border?: boolean;
27
+ /** Tiny broadcast-station label. Optional in `vibe`; shown in header in `dispatch`. */
28
+ channel?: React.ReactNode;
29
+ /** (`dispatch` only) Override the sidebar content (takes precedence over headline/body). */
30
+ children?: React.ReactNode;
31
+ className?: string;
32
+ /** Show the small `+` die-line registration marks in the image corners. Default `true`. */
33
+ cornerMarks?: boolean;
34
+ /** (`dispatch` only) Small tagline above the headline. */
35
+ eyebrow?: React.ReactNode;
36
+ /** (`dispatch` only) Big expanded-typography headline. Pass an array of strings to stack lines. */
37
+ headline?: string[] | string;
38
+ /** (`dispatch` only) Force stacked vs split layout. Default inferred from `aspect`. */
39
+ layout?: 'split' | 'stacked';
40
+ /** Render scale. 1 = full canvas (1080px+ base width). */
41
+ scale?: number;
42
+ /** (`dispatch` only) Small legal / signature line at the bottom-right. */
43
+ seal?: React.ReactNode;
44
+ /**
45
+ * Signature mark. In `vibe` this is the small "Hermes Agent" overlay in the
46
+ * bottom-right. In `dispatch` this is the URL / CTA in the footer.
47
+ */
48
+ signature?: React.ReactNode;
49
+ /** Override the poster image. Defaults to the Hermes "filler-bg0" asset. */
50
+ src?: string;
51
+ /** (`dispatch` only) Ranked list of features / pricing tiers rendered as a numbered sidebar list. */
52
+ tags?: string[];
53
+ /** Shader tint overlay. Great for tier-colored variants. */
54
+ tint?: string;
55
+ /** Active / inactive tint strength — defaults match `ImageDistortion`. */
56
+ tintStrength?: {
57
+ active: number;
58
+ inactive: number;
59
+ };
60
+ /** Layout variant. `'vibe'` (default) is full-bleed image; `'dispatch'` is the broadcast-card with sidebar copy. */
61
+ variant?: PosterVariant;
62
+ }
63
+ //# sourceMappingURL=poster.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poster.d.ts","sourceRoot":"","sources":["../../../src/ui/components/poster.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAoEzD;;;;;;;;;;;;GAYG;AACH,wBAAgB,MAAM,CAAC,EACrB,MAAiB,EACjB,QAAkB,EAClB,IAAI,EACJ,MAAa,EACb,OAAO,EACP,QAAQ,EACR,SAAS,EACT,WAAkB,EAClB,OAAO,EACP,QAAkD,EAClD,MAAM,EACN,KAAS,EACT,IAAmB,EACnB,SAAS,EACT,GAAiB,EACjB,IAAI,EACJ,IAAI,EACJ,YAAY,EACZ,OAAgB,EAChB,GAAG,IAAI,EACR,EAAE,WAAW,2CAyKb;AA6ED,MAAM,MAAM,YAAY,GACpB,WAAW,GACX,UAAU,GACV,QAAQ,GACR,OAAO,GACP,MAAM,CAAA;AAEV,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,MAAM,CAAA;AAE/C,MAAM,WAAW,WAAW;IAC1B,8EAA8E;IAC9E,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,eAAe,CAAA;IAC1B,6DAA6D;IAC7D,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACtB,mEAAmE;IACnE,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,uFAAuF;IACvF,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,4FAA4F;IAC5F,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,2FAA2F;IAC3F,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,mGAAmG;IACnG,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IAC5B,uFAAuF;IACvF,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC5B,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,0EAA0E;IAC1E,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACtB;;;OAGG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC3B,4EAA4E;IAC5E,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,qGAAqG;IACrG,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,0EAA0E;IAC1E,YAAY,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;IACnD,oHAAoH;IACpH,OAAO,CAAC,EAAE,aAAa,CAAA;CACxB"}
@@ -0,0 +1,102 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useEffect, useState } from 'react';
4
+ import fillerBg from '../../assets/filler-bg0.jpg';
5
+ import { cn } from '../../utils';
6
+ import { Blink } from './blink';
7
+ import { ImageDistortion } from './image-distortion';
8
+ import { Typography } from './typography';
9
+ import { Small } from './typography/small';
10
+ const ASPECT_CONFIG = {
11
+ landscape: { defaultLayout: 'split', height: 1080, width: 1920 },
12
+ portrait: { defaultLayout: 'split', height: 1350, width: 1080 },
13
+ square: { defaultLayout: 'split', height: 1080, width: 1080 },
14
+ story: { defaultLayout: 'stacked', height: 1920, width: 1080 },
15
+ wide: { defaultLayout: 'split', height: 900, width: 1600 }
16
+ };
17
+ const DEFAULT_SRC = fillerBg.src ?? fillerBg;
18
+ function useUtcClock() {
19
+ const [now, setNow] = useState(null);
20
+ useEffect(() => {
21
+ setNow(new Date());
22
+ const id = setInterval(() => setNow(new Date()), 1000);
23
+ return () => clearInterval(id);
24
+ }, []);
25
+ return now ? now.toISOString().slice(11, 19) : '--:--:--';
26
+ }
27
+ function CornerMark({ className }) {
28
+ return (_jsxs("span", { "aria-hidden": true, className: cn('pointer-events-none absolute block size-4 opacity-50', className), children: [_jsx("span", { className: "absolute top-1/2 left-0 h-px w-full -translate-y-1/2 bg-current" }), _jsx("span", { className: "absolute top-0 left-1/2 h-full w-px -translate-x-1/2 bg-current" })] }));
29
+ }
30
+ function ChannelDot() {
31
+ return (_jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "bg-midground size-1.5 animate-pulse rounded-full" }), _jsx(Small, { className: "opacity-70", children: "REC" })] }));
32
+ }
33
+ function ScanlineOverlay() {
34
+ return (_jsx("div", { "aria-hidden": true, className: "pointer-events-none absolute inset-0 opacity-20 mix-blend-overlay", style: {
35
+ backgroundImage: 'repeating-linear-gradient(0deg, transparent 0, transparent 2px, rgba(255,255,255,0.08) 2px, rgba(255,255,255,0.08) 3px)'
36
+ } }));
37
+ }
38
+ /**
39
+ * Social-ready glitchy card built around the haptic-distortion image
40
+ * component. The poster runs the sword-guy distortion on an auto-animated
41
+ * slash pattern so it can be screen-recorded as a GIF without a human
42
+ * moving a cursor.
43
+ *
44
+ * Two variants, matching actual use cases:
45
+ * - `'vibe'` (default): full-bleed distorted image with just registration
46
+ * marks and a tiny "Hermes Agent" mark in the corner — mirrors the
47
+ * overlay on the Hermes agent website.
48
+ * - `'dispatch'`: broadcast-card layout with sidebar copy, numbered tags,
49
+ * and chrome — for when the poster needs to carry information.
50
+ */
51
+ export function Poster({ aspect = 'square', autoPlay = 'slash', body, border = true, channel, children, className, cornerMarks = true, eyebrow, headline = ['An Agent', 'That Grows', 'With You.'], layout, scale = 1, seal = 'MIT · 2026', signature, src = DEFAULT_SRC, tags, tint, tintStrength, variant = 'vibe', ...rest }) {
52
+ const config = ASPECT_CONFIG[aspect];
53
+ const resolvedLayout = layout ?? config.defaultLayout;
54
+ // Use aspect-ratio + max-width/height so the poster fluidly fits any parent
55
+ // (storybook iframe, a tweet preview, an embed) without getting clipped,
56
+ // but caps at the intended export width for screen-recording. `maxHeight`
57
+ // uses an absolute `dvh`-based value rather than `%` because `%` inside a
58
+ // flex container can cause the browser to clamp height without re-running
59
+ // aspect-ratio on width, producing a subtly wrong shape. An absolute cap
60
+ // leaves aspect-ratio fully in charge: once the height binds, width is
61
+ // re-derived correctly. `calc(100dvh - 8rem)` = viewport minus a typical
62
+ // host's vertical padding (e.g. Storybook's `p-8` = 4rem on each side),
63
+ // so the poster + padding fit within the viewport without ever producing
64
+ // scrollbars. Container queries tie all internal typography to the
65
+ // actual rendered width so headline/metadata scales along with the canvas.
66
+ const outerProps = {
67
+ // `text-midground` (not `text-foreground`) is the readable on-canvas
68
+ // color across every lens. `--foreground` is really the lens's inversion
69
+ // layer color: on dark lenses it has `fgOpacity: 0` and resolves to
70
+ // fully-transparent via `color-mix`, which would make text invisible.
71
+ // `--midground` always has opacity 1 and picks up each lens's accent.
72
+ className: cn('text-midground relative overflow-hidden font-sans', border && 'border border-current/25', className),
73
+ style: {
74
+ aspectRatio: `${config.width} / ${config.height}`,
75
+ background: 'var(--background)',
76
+ containerType: 'inline-size',
77
+ fontSize: `${(16 / config.width) * 100}cqi`,
78
+ maxHeight: 'calc(100dvh - 8rem)',
79
+ maxWidth: '100%',
80
+ width: `${config.width * scale}px`
81
+ },
82
+ ...rest
83
+ };
84
+ if (variant === 'vibe') {
85
+ return (_jsx("div", { ...outerProps, children: _jsx(VibeContent, { autoPlay: autoPlay, channel: channel, cornerMarks: cornerMarks, signature: signature, src: src, tint: tint, tintStrength: tintStrength }) }));
86
+ }
87
+ const headlineLines = Array.isArray(headline) ? headline : [headline];
88
+ return (_jsxs("div", { ...outerProps, className: cn('flex flex-col', outerProps.className), children: [_jsx(DispatchHeader, { channel: channel }), _jsxs("div", { className: cn('relative min-h-0 min-w-0 flex-1', resolvedLayout === 'split'
89
+ ? 'grid grid-cols-[3fr_2fr]'
90
+ : 'grid grid-rows-[3fr_2fr]'), children: [_jsxs("div", { className: cn('relative overflow-hidden border-current/20', resolvedLayout === 'split' ? 'border-r' : 'border-b'), style: { backgroundColor: 'var(--background)' }, children: [_jsx(ImageDistortion, { autoPlay: autoPlay, src: src, tint: tint, tintStrength: tintStrength }), cornerMarks && (_jsxs(_Fragment, { children: [_jsx(CornerMark, { className: "top-3 left-3" }), _jsx(CornerMark, { className: "top-3 right-3" }), _jsx(CornerMark, { className: "bottom-3 left-3" }), _jsx(CornerMark, { className: "right-3 bottom-3" })] })), _jsx(ScanlineOverlay, {}), _jsx(Small, { className: "absolute bottom-4 left-4 z-1 opacity-80", children: "Hermes Agent" })] }), _jsxs("aside", { className: "relative flex min-w-0 flex-col justify-between gap-8 p-8", children: [_jsxs("div", { className: "flex flex-col gap-5", children: [eyebrow && (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "bg-midground/80 h-px flex-1" }), _jsx(Small, { className: "opacity-80", children: eyebrow })] })), children ?? (_jsxs(_Fragment, { children: [_jsx(Typography, { as: "h1", className: "text-[2.75em] leading-[0.95] font-bold tracking-[-0.01em]", expanded: true, children: headlineLines.map((line, i) => (_jsx("span", { className: "block", children: line }, `${line}-${i}`))) }), body && (_jsx("p", { className: "text-[1.0625em] leading-[1.5] tracking-normal normal-case opacity-60", children: body }))] }))] }), tags && tags.length > 0 && (_jsx("ul", { className: "flex flex-col gap-2 border-t border-current/15 pt-4", children: tags.map((tag, i) => (_jsxs("li", { className: "flex items-baseline justify-between gap-3", children: [_jsx(Small, { className: "font-courier opacity-40", children: String(i + 1).padStart(3, '0') }), _jsx(Small, { className: "opacity-80", children: tag }), _jsx("span", { className: "mx-1 h-px flex-1 translate-y-[-3px] border-b border-dotted border-current/25" }), _jsxs(Small, { className: "font-courier opacity-40", children: [String(i + 1).padStart(2, '0'), "/", String(tags.length).padStart(2, '0')] })] }, `${tag}-${i}`))) }))] })] }), _jsxs("footer", { className: "flex items-center justify-between gap-4 border-t border-current/20 px-6 py-3", children: [_jsxs(Small, { className: "opacity-70", children: [signature, _jsx(Blink, {})] }), _jsx(Small, { className: "font-courier opacity-40", children: seal })] })] }));
91
+ }
92
+ function DispatchHeader({ channel }) {
93
+ const clock = useUtcClock();
94
+ return (_jsxs("header", { className: "flex items-center justify-between gap-4 border-b border-current/20 px-6 py-3", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { className: "bg-midground size-2 rounded-sm opacity-70" }), _jsx(Small, { className: "opacity-70", children: channel })] }), _jsxs("div", { className: "flex items-center gap-4", children: [_jsx(ChannelDot, {}), _jsxs(Small, { className: "font-courier opacity-50", children: [clock, " UTC"] })] })] }));
95
+ }
96
+ function VibeContent({ autoPlay, channel, cornerMarks, signature, src, tint, tintStrength }) {
97
+ // Absolute-inset-0 guarantees this fills the poster even when the outer
98
+ // container uses aspect-ratio-derived height in a browser that doesn't
99
+ // propagate that as a definite height for percentage-based children.
100
+ return (_jsxs("div", { className: "absolute inset-0", children: [_jsx(ImageDistortion, { autoPlay: autoPlay, src: src, tint: tint, tintStrength: tintStrength }), cornerMarks && (_jsxs(_Fragment, { children: [_jsx(CornerMark, { className: "top-5 left-5" }), _jsx(CornerMark, { className: "top-5 right-5" }), _jsx(CornerMark, { className: "bottom-5 left-5" }), _jsx(CornerMark, { className: "right-5 bottom-5" })] })), _jsx(ScanlineOverlay, {}), channel && (_jsx(Small, { className: "absolute top-5 left-10 z-1 text-[0.75em] opacity-70", children: channel })), _jsx(Small, { className: "absolute right-10 bottom-5 z-1 text-[0.75em] opacity-80", children: signature })] }));
101
+ }
102
+ //# sourceMappingURL=poster.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poster.js","sourceRoot":"","sources":["../../../src/ui/components/poster.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client'\n\nimport { useEffect, useState } from 'react'\n\nimport fillerBg from '../../assets/filler-bg0.jpg'\nimport { cn } from '../../utils'\n\nimport { Blink } from './blink'\nimport { ImageDistortion } from './image-distortion'\nimport { Typography } from './typography'\nimport { Small } from './typography/small'\n\nimport type { AutoPlayPattern } from './image-distortion'\n\nconst ASPECT_CONFIG: Record<\n PosterAspect,\n { defaultLayout: 'split' | 'stacked'; height: number; width: number }\n> = {\n landscape: { defaultLayout: 'split', height: 1080, width: 1920 },\n portrait: { defaultLayout: 'split', height: 1350, width: 1080 },\n square: { defaultLayout: 'split', height: 1080, width: 1080 },\n story: { defaultLayout: 'stacked', height: 1920, width: 1080 },\n wide: { defaultLayout: 'split', height: 900, width: 1600 }\n}\n\nconst DEFAULT_SRC =\n (fillerBg as { src?: string }).src ?? (fillerBg as unknown as string)\n\nfunction useUtcClock() {\n const [now, setNow] = useState<Date | null>(null)\n\n useEffect(() => {\n setNow(new Date())\n const id = setInterval(() => setNow(new Date()), 1000)\n\n return () => clearInterval(id)\n }, [])\n\n return now ? now.toISOString().slice(11, 19) : '--:--:--'\n}\n\nfunction CornerMark({ className }: { className?: string }) {\n return (\n <span\n aria-hidden\n className={cn(\n 'pointer-events-none absolute block size-4 opacity-50',\n className\n )}\n >\n <span className=\"absolute top-1/2 left-0 h-px w-full -translate-y-1/2 bg-current\" />\n\n <span className=\"absolute top-0 left-1/2 h-full w-px -translate-x-1/2 bg-current\" />\n </span>\n )\n}\n\nfunction ChannelDot() {\n return (\n <span className=\"flex items-center gap-1.5\">\n <span className=\"bg-midground size-1.5 animate-pulse rounded-full\" />\n\n <Small className=\"opacity-70\">REC</Small>\n </span>\n )\n}\n\nfunction ScanlineOverlay() {\n return (\n <div\n aria-hidden\n className=\"pointer-events-none absolute inset-0 opacity-20 mix-blend-overlay\"\n style={{\n backgroundImage:\n 'repeating-linear-gradient(0deg, transparent 0, transparent 2px, rgba(255,255,255,0.08) 2px, rgba(255,255,255,0.08) 3px)'\n }}\n />\n )\n}\n\n/**\n * Social-ready glitchy card built around the haptic-distortion image\n * component. The poster runs the sword-guy distortion on an auto-animated\n * slash pattern so it can be screen-recorded as a GIF without a human\n * moving a cursor.\n *\n * Two variants, matching actual use cases:\n * - `'vibe'` (default): full-bleed distorted image with just registration\n * marks and a tiny \"Hermes Agent\" mark in the corner — mirrors the\n * overlay on the Hermes agent website.\n * - `'dispatch'`: broadcast-card layout with sidebar copy, numbered tags,\n * and chrome — for when the poster needs to carry information.\n */\nexport function Poster({\n aspect = 'square',\n autoPlay = 'slash',\n body,\n border = true,\n channel,\n children,\n className,\n cornerMarks = true,\n eyebrow,\n headline = ['An Agent', 'That Grows', 'With You.'],\n layout,\n scale = 1,\n seal = 'MIT · 2026',\n signature,\n src = DEFAULT_SRC,\n tags,\n tint,\n tintStrength,\n variant = 'vibe',\n ...rest\n}: PosterProps) {\n const config = ASPECT_CONFIG[aspect]\n const resolvedLayout = layout ?? config.defaultLayout\n\n // Use aspect-ratio + max-width/height so the poster fluidly fits any parent\n // (storybook iframe, a tweet preview, an embed) without getting clipped,\n // but caps at the intended export width for screen-recording. `maxHeight`\n // uses an absolute `dvh`-based value rather than `%` because `%` inside a\n // flex container can cause the browser to clamp height without re-running\n // aspect-ratio on width, producing a subtly wrong shape. An absolute cap\n // leaves aspect-ratio fully in charge: once the height binds, width is\n // re-derived correctly. `calc(100dvh - 8rem)` = viewport minus a typical\n // host's vertical padding (e.g. Storybook's `p-8` = 4rem on each side),\n // so the poster + padding fit within the viewport without ever producing\n // scrollbars. Container queries tie all internal typography to the\n // actual rendered width so headline/metadata scales along with the canvas.\n const outerProps = {\n // `text-midground` (not `text-foreground`) is the readable on-canvas\n // color across every lens. `--foreground` is really the lens's inversion\n // layer color: on dark lenses it has `fgOpacity: 0` and resolves to\n // fully-transparent via `color-mix`, which would make text invisible.\n // `--midground` always has opacity 1 and picks up each lens's accent.\n className: cn(\n 'text-midground relative overflow-hidden font-sans',\n border && 'border border-current/25',\n className\n ),\n style: {\n aspectRatio: `${config.width} / ${config.height}`,\n background: 'var(--background)',\n containerType: 'inline-size' as const,\n fontSize: `${(16 / config.width) * 100}cqi`,\n maxHeight: 'calc(100dvh - 8rem)',\n maxWidth: '100%',\n width: `${config.width * scale}px`\n },\n ...rest\n }\n\n if (variant === 'vibe') {\n return (\n <div {...outerProps}>\n <VibeContent\n autoPlay={autoPlay}\n channel={channel}\n cornerMarks={cornerMarks}\n signature={signature}\n src={src}\n tint={tint}\n tintStrength={tintStrength}\n />\n </div>\n )\n }\n\n const headlineLines = Array.isArray(headline) ? headline : [headline]\n\n return (\n <div {...outerProps} className={cn('flex flex-col', outerProps.className)}>\n <DispatchHeader channel={channel} />\n\n <div\n className={cn(\n 'relative min-h-0 min-w-0 flex-1',\n resolvedLayout === 'split'\n ? 'grid grid-cols-[3fr_2fr]'\n : 'grid grid-rows-[3fr_2fr]'\n )}\n >\n <div\n className={cn(\n 'relative overflow-hidden border-current/20',\n resolvedLayout === 'split' ? 'border-r' : 'border-b'\n )}\n style={{ backgroundColor: 'var(--background)' }}\n >\n <ImageDistortion\n autoPlay={autoPlay}\n src={src}\n tint={tint}\n tintStrength={tintStrength}\n />\n\n {cornerMarks && (\n <>\n <CornerMark className=\"top-3 left-3\" />\n <CornerMark className=\"top-3 right-3\" />\n <CornerMark className=\"bottom-3 left-3\" />\n <CornerMark className=\"right-3 bottom-3\" />\n </>\n )}\n\n <ScanlineOverlay />\n\n <Small className=\"absolute bottom-4 left-4 z-1 opacity-80\">\n Hermes Agent\n </Small>\n </div>\n\n <aside className=\"relative flex min-w-0 flex-col justify-between gap-8 p-8\">\n <div className=\"flex flex-col gap-5\">\n {eyebrow && (\n <div className=\"flex items-center gap-2\">\n <span className=\"bg-midground/80 h-px flex-1\" />\n\n <Small className=\"opacity-80\">{eyebrow}</Small>\n </div>\n )}\n\n {children ?? (\n <>\n <Typography\n as=\"h1\"\n className=\"text-[2.75em] leading-[0.95] font-bold tracking-[-0.01em]\"\n expanded\n >\n {headlineLines.map((line, i) => (\n <span className=\"block\" key={`${line}-${i}`}>\n {line}\n </span>\n ))}\n </Typography>\n\n {body && (\n <p className=\"text-[1.0625em] leading-[1.5] tracking-normal normal-case opacity-60\">\n {body}\n </p>\n )}\n </>\n )}\n </div>\n\n {tags && tags.length > 0 && (\n <ul className=\"flex flex-col gap-2 border-t border-current/15 pt-4\">\n {tags.map((tag, i) => (\n <li\n className=\"flex items-baseline justify-between gap-3\"\n key={`${tag}-${i}`}\n >\n <Small className=\"font-courier opacity-40\">\n {String(i + 1).padStart(3, '0')}\n </Small>\n\n <Small className=\"opacity-80\">{tag}</Small>\n\n <span className=\"mx-1 h-px flex-1 translate-y-[-3px] border-b border-dotted border-current/25\" />\n\n <Small className=\"font-courier opacity-40\">\n {String(i + 1).padStart(2, '0')}/\n {String(tags.length).padStart(2, '0')}\n </Small>\n </li>\n ))}\n </ul>\n )}\n </aside>\n </div>\n\n <footer className=\"flex items-center justify-between gap-4 border-t border-current/20 px-6 py-3\">\n <Small className=\"opacity-70\">\n {signature}\n\n <Blink />\n </Small>\n\n <Small className=\"font-courier opacity-40\">{seal}</Small>\n </footer>\n </div>\n )\n}\n\nfunction DispatchHeader({ channel }: { channel: React.ReactNode }) {\n const clock = useUtcClock()\n\n return (\n <header className=\"flex items-center justify-between gap-4 border-b border-current/20 px-6 py-3\">\n <div className=\"flex items-center gap-3\">\n <span className=\"bg-midground size-2 rounded-sm opacity-70\" />\n\n <Small className=\"opacity-70\">{channel}</Small>\n </div>\n\n <div className=\"flex items-center gap-4\">\n <ChannelDot />\n\n <Small className=\"font-courier opacity-50\">{clock} UTC</Small>\n </div>\n </header>\n )\n}\n\ninterface VibeContentProps {\n autoPlay: AutoPlayPattern\n channel: React.ReactNode\n cornerMarks: boolean\n signature: React.ReactNode\n src: string\n tint?: string\n tintStrength?: { active: number; inactive: number }\n}\n\nfunction VibeContent({\n autoPlay,\n channel,\n cornerMarks,\n signature,\n src,\n tint,\n tintStrength\n}: VibeContentProps) {\n // Absolute-inset-0 guarantees this fills the poster even when the outer\n // container uses aspect-ratio-derived height in a browser that doesn't\n // propagate that as a definite height for percentage-based children.\n return (\n <div className=\"absolute inset-0\">\n <ImageDistortion\n autoPlay={autoPlay}\n src={src}\n tint={tint}\n tintStrength={tintStrength}\n />\n\n {cornerMarks && (\n <>\n <CornerMark className=\"top-5 left-5\" />\n <CornerMark className=\"top-5 right-5\" />\n <CornerMark className=\"bottom-5 left-5\" />\n <CornerMark className=\"right-5 bottom-5\" />\n </>\n )}\n\n <ScanlineOverlay />\n\n {channel && (\n <Small className=\"absolute top-5 left-10 z-1 text-[0.75em] opacity-70\">\n {channel}\n </Small>\n )}\n\n <Small className=\"absolute right-10 bottom-5 z-1 text-[0.75em] opacity-80\">\n {signature}\n </Small>\n </div>\n )\n}\n\nexport type PosterAspect =\n | 'landscape'\n | 'portrait'\n | 'square'\n | 'story'\n | 'wide'\n\nexport type PosterVariant = 'dispatch' | 'vibe'\n\nexport interface PosterProps {\n /** Output aspect ratio. Picks sensible defaults for common social formats. */\n aspect?: PosterAspect\n /** Distortion choreography pattern. Default: `'slash'`. */\n autoPlay?: AutoPlayPattern\n /** (`dispatch` only) Descriptive copy under the headline. */\n body?: React.ReactNode\n /** Show the thin outer frame around the poster. Default `true`. */\n border?: boolean\n /** Tiny broadcast-station label. Optional in `vibe`; shown in header in `dispatch`. */\n channel?: React.ReactNode\n /** (`dispatch` only) Override the sidebar content (takes precedence over headline/body). */\n children?: React.ReactNode\n className?: string\n /** Show the small `+` die-line registration marks in the image corners. Default `true`. */\n cornerMarks?: boolean\n /** (`dispatch` only) Small tagline above the headline. */\n eyebrow?: React.ReactNode\n /** (`dispatch` only) Big expanded-typography headline. Pass an array of strings to stack lines. */\n headline?: string[] | string\n /** (`dispatch` only) Force stacked vs split layout. Default inferred from `aspect`. */\n layout?: 'split' | 'stacked'\n /** Render scale. 1 = full canvas (1080px+ base width). */\n scale?: number\n /** (`dispatch` only) Small legal / signature line at the bottom-right. */\n seal?: React.ReactNode\n /**\n * Signature mark. In `vibe` this is the small \"Hermes Agent\" overlay in the\n * bottom-right. In `dispatch` this is the URL / CTA in the footer.\n */\n signature?: React.ReactNode\n /** Override the poster image. Defaults to the Hermes \"filler-bg0\" asset. */\n src?: string\n /** (`dispatch` only) Ranked list of features / pricing tiers rendered as a numbered sidebar list. */\n tags?: string[]\n /** Shader tint overlay. Great for tier-colored variants. */\n tint?: string\n /** Active / inactive tint strength — defaults match `ImageDistortion`. */\n tintStrength?: { active: number; inactive: number }\n /** Layout variant. `'vibe'` (default) is full-bleed image; `'dispatch'` is the broadcast-card with sidebar copy. */\n variant?: PosterVariant\n}\n"]}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Selectable tier / pricing card. Full-bleed distorted image background,
3
+ * readable overlay text, and an animated `.arc-border` shimmer on the
4
+ * selected state. Fully presentational — the consumer owns the data
5
+ * (tier schema, price formatting, tier imagery / tints).
6
+ *
7
+ * Visual states:
8
+ * - `selected`: brightens the distortion, activates `.arc-border`, and
9
+ * composites the headline / price with `mix-blend-mode: plus-lighter`
10
+ * so the text lifts off the image regardless of tint.
11
+ * - `isCurrent`: subtle midground-tinted border hint (suppressed when
12
+ * `selected` wins).
13
+ * - `overlay`: optional top-layer color blended with `mix-blend-mode:
14
+ * color` — used for the "highest tier" red treatment on top of any
15
+ * base tint.
16
+ */
17
+ export declare function TierCard({ badge, bullets, className, image, isCurrent, onSelect, overlay, price, selected, tint, tintStrength, title }: TierCardProps): import("react/jsx-runtime").JSX.Element;
18
+ export interface TierCardPrice {
19
+ /** Headline price, e.g. `"$20"` or `"Free"`. */
20
+ primary: string;
21
+ /** Small suffix rendered after `primary`, e.g. `"/mo"` or `"first payment"`. */
22
+ primarySuffix?: string;
23
+ /** Optional struck-through comparison price rendered above `primary`, e.g. `"$30"`. */
24
+ secondary?: string;
25
+ /** Small suffix rendered after `secondary`. */
26
+ secondarySuffix?: string;
27
+ }
28
+ export interface TierCardProps {
29
+ /** Small annotation after the title, e.g. `"(current)"`. */
30
+ badge?: React.ReactNode;
31
+ /** Feature list rendered under the price. */
32
+ bullets: React.ReactNode[];
33
+ className?: string;
34
+ /** Background image URL. */
35
+ image: string;
36
+ /** Applies the "current plan" border hint when not `selected`. */
37
+ isCurrent?: boolean;
38
+ onSelect?: () => void;
39
+ /** Color blended with `mix-blend-mode: color` over the image (used for the highest-tier red treatment). */
40
+ overlay?: string;
41
+ price: TierCardPrice;
42
+ /** Applies selected chrome (arc-border shimmer, active distortion, plus-lighter text blend). */
43
+ selected?: boolean;
44
+ /** Shader tint passed through to `ImageDistortion`. */
45
+ tint?: string;
46
+ /** Active / inactive tint strength passed through to `ImageDistortion`. */
47
+ tintStrength?: {
48
+ active: number;
49
+ inactive: number;
50
+ };
51
+ /** Tier name / headline. */
52
+ title: React.ReactNode;
53
+ }
54
+ //# sourceMappingURL=tier-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tier-card.d.ts","sourceRoot":"","sources":["../../../src/ui/components/tier-card.tsx"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,OAAO,EACP,SAAS,EACT,KAAK,EACL,SAAiB,EACjB,QAAQ,EACR,OAAO,EACP,KAAK,EACL,QAAgB,EAChB,IAAI,EACJ,YAAY,EACZ,KAAK,EACN,EAAE,aAAa,2CAsHf;AAED,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAA;IACf,gFAAgF;IAChF,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,+CAA+C;IAC/C,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACvB,6CAA6C;IAC7C,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,kEAAkE;IAClE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,2GAA2G;IAC3G,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,aAAa,CAAA;IACpB,gGAAgG;IAChG,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,2EAA2E;IAC3E,YAAY,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;IACnD,4BAA4B;IAC5B,KAAK,EAAE,KAAK,CAAC,SAAS,CAAA;CACvB"}
@@ -0,0 +1,26 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { cn } from '../../utils';
4
+ import { ImageDistortion } from './image-distortion';
5
+ import { Typography } from './typography';
6
+ import { Small } from './typography/small';
7
+ /**
8
+ * Selectable tier / pricing card. Full-bleed distorted image background,
9
+ * readable overlay text, and an animated `.arc-border` shimmer on the
10
+ * selected state. Fully presentational — the consumer owns the data
11
+ * (tier schema, price formatting, tier imagery / tints).
12
+ *
13
+ * Visual states:
14
+ * - `selected`: brightens the distortion, activates `.arc-border`, and
15
+ * composites the headline / price with `mix-blend-mode: plus-lighter`
16
+ * so the text lifts off the image regardless of tint.
17
+ * - `isCurrent`: subtle midground-tinted border hint (suppressed when
18
+ * `selected` wins).
19
+ * - `overlay`: optional top-layer color blended with `mix-blend-mode:
20
+ * color` — used for the "highest tier" red treatment on top of any
21
+ * base tint.
22
+ */
23
+ export function TierCard({ badge, bullets, className, image, isCurrent = false, onSelect, overlay, price, selected = false, tint, tintStrength, title }) {
24
+ return (_jsxs("button", { className: cn('group relative flex w-full cursor-pointer flex-col border border-current/20', 'text-left transition-colors duration-300', selected && 'border-midground/60', isCurrent && !selected && 'border-midground/30', className), onClick: onSelect, type: "button", children: [_jsx("span", { "aria-hidden": true, className: cn('arc-border transition-opacity duration-200', selected ? 'opacity-100' : 'opacity-0 group-hover:opacity-100') }), _jsxs("div", { className: "relative aspect-[3/4] min-h-0 w-full flex-1 overflow-hidden", style: { backgroundColor: 'var(--background)' }, children: [_jsx(ImageDistortion, { active: selected, src: image, tint: tint, tintStrength: tintStrength }), overlay && (_jsx("div", { className: "pointer-events-none absolute inset-0", style: { backgroundColor: overlay, mixBlendMode: 'color' } })), _jsxs("div", { className: "pointer-events-none absolute inset-0 z-[1] flex flex-col justify-between p-3", children: [_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsxs(Small, { className: cn('block drop-shadow-[0_1px_2px_rgba(0,0,0,0.5)]', 'transition-colors', selected && 'text-midground'), style: selected ? { mixBlendMode: 'plus-lighter' } : undefined, children: [title, badge && _jsx("span", { className: "ml-1 opacity-50", children: badge })] }), price.secondary ? (_jsxs(_Fragment, { children: [_jsxs(Typography, { className: "block text-sm line-through opacity-50 drop-shadow-[0_1px_3px_rgba(0,0,0,0.6)]", expanded: true, style: { mixBlendMode: 'plus-lighter' }, children: [price.secondary, price.secondarySuffix && (_jsx("span", { className: "text-[0.625rem]", children: price.secondarySuffix }))] }), _jsxs(Typography, { className: "block text-lg font-bold drop-shadow-[0_1px_3px_rgba(0,0,0,0.6)]", expanded: true, style: { mixBlendMode: 'plus-lighter' }, children: [price.primary, price.primarySuffix && (_jsxs("span", { className: "text-[0.625rem] opacity-60", children: [' ', price.primarySuffix] }))] })] })) : (_jsxs(Typography, { className: "block text-lg font-bold drop-shadow-[0_1px_3px_rgba(0,0,0,0.6)]", expanded: true, style: { mixBlendMode: 'plus-lighter' }, children: [price.primary, price.primarySuffix && (_jsx("span", { className: "text-[0.625rem] opacity-60", children: price.primarySuffix }))] }))] }), bullets.length > 0 && (_jsx("ul", { className: "flex flex-col gap-1", children: bullets.map((bullet, i) => (_jsxs("li", { className: cn('font-courier text-[0.6875rem] leading-tight tracking-wider uppercase', 'drop-shadow-[0_1px_2px_rgba(0,0,0,0.5)]', 'opacity-70'), children: ["\u00B7 ", bullet] }, typeof bullet === 'string' ? bullet : i))) }))] })] })] }));
25
+ }
26
+ //# sourceMappingURL=tier-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tier-card.js","sourceRoot":"","sources":["../../../src/ui/components/tier-card.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client'\n\nimport { cn } from '../../utils'\n\nimport { ImageDistortion } from './image-distortion'\nimport { Typography } from './typography'\nimport { Small } from './typography/small'\n\n/**\n * Selectable tier / pricing card. Full-bleed distorted image background,\n * readable overlay text, and an animated `.arc-border` shimmer on the\n * selected state. Fully presentational — the consumer owns the data\n * (tier schema, price formatting, tier imagery / tints).\n *\n * Visual states:\n * - `selected`: brightens the distortion, activates `.arc-border`, and\n * composites the headline / price with `mix-blend-mode: plus-lighter`\n * so the text lifts off the image regardless of tint.\n * - `isCurrent`: subtle midground-tinted border hint (suppressed when\n * `selected` wins).\n * - `overlay`: optional top-layer color blended with `mix-blend-mode:\n * color` — used for the \"highest tier\" red treatment on top of any\n * base tint.\n */\nexport function TierCard({\n badge,\n bullets,\n className,\n image,\n isCurrent = false,\n onSelect,\n overlay,\n price,\n selected = false,\n tint,\n tintStrength,\n title\n}: TierCardProps) {\n return (\n <button\n className={cn(\n 'group relative flex w-full cursor-pointer flex-col border border-current/20',\n 'text-left transition-colors duration-300',\n selected && 'border-midground/60',\n isCurrent && !selected && 'border-midground/30',\n className\n )}\n onClick={onSelect}\n type=\"button\"\n >\n <span\n aria-hidden\n className={cn(\n 'arc-border transition-opacity duration-200',\n selected ? 'opacity-100' : 'opacity-0 group-hover:opacity-100'\n )}\n />\n\n <div\n className=\"relative aspect-[3/4] min-h-0 w-full flex-1 overflow-hidden\"\n style={{ backgroundColor: 'var(--background)' }}\n >\n <ImageDistortion\n active={selected}\n src={image}\n tint={tint}\n tintStrength={tintStrength}\n />\n\n {overlay && (\n <div\n className=\"pointer-events-none absolute inset-0\"\n style={{ backgroundColor: overlay, mixBlendMode: 'color' }}\n />\n )}\n\n <div className=\"pointer-events-none absolute inset-0 z-[1] flex flex-col justify-between p-3\">\n <div className=\"flex flex-col gap-0.5\">\n <Small\n className={cn(\n 'block drop-shadow-[0_1px_2px_rgba(0,0,0,0.5)]',\n 'transition-colors',\n selected && 'text-midground'\n )}\n style={selected ? { mixBlendMode: 'plus-lighter' } : undefined}\n >\n {title}\n {badge && <span className=\"ml-1 opacity-50\">{badge}</span>}\n </Small>\n\n {price.secondary ? (\n <>\n <Typography\n className=\"block text-sm line-through opacity-50 drop-shadow-[0_1px_3px_rgba(0,0,0,0.6)]\"\n expanded\n style={{ mixBlendMode: 'plus-lighter' }}\n >\n {price.secondary}\n {price.secondarySuffix && (\n <span className=\"text-[0.625rem]\">\n {price.secondarySuffix}\n </span>\n )}\n </Typography>\n\n <Typography\n className=\"block text-lg font-bold drop-shadow-[0_1px_3px_rgba(0,0,0,0.6)]\"\n expanded\n style={{ mixBlendMode: 'plus-lighter' }}\n >\n {price.primary}\n {price.primarySuffix && (\n <span className=\"text-[0.625rem] opacity-60\">\n {' '}\n {price.primarySuffix}\n </span>\n )}\n </Typography>\n </>\n ) : (\n <Typography\n className=\"block text-lg font-bold drop-shadow-[0_1px_3px_rgba(0,0,0,0.6)]\"\n expanded\n style={{ mixBlendMode: 'plus-lighter' }}\n >\n {price.primary}\n {price.primarySuffix && (\n <span className=\"text-[0.625rem] opacity-60\">\n {price.primarySuffix}\n </span>\n )}\n </Typography>\n )}\n </div>\n\n {bullets.length > 0 && (\n <ul className=\"flex flex-col gap-1\">\n {bullets.map((bullet, i) => (\n <li\n className={cn(\n 'font-courier text-[0.6875rem] leading-tight tracking-wider uppercase',\n 'drop-shadow-[0_1px_2px_rgba(0,0,0,0.5)]',\n 'opacity-70'\n )}\n key={typeof bullet === 'string' ? bullet : i}\n >\n · {bullet}\n </li>\n ))}\n </ul>\n )}\n </div>\n </div>\n </button>\n )\n}\n\nexport interface TierCardPrice {\n /** Headline price, e.g. `\"$20\"` or `\"Free\"`. */\n primary: string\n /** Small suffix rendered after `primary`, e.g. `\"/mo\"` or `\"first payment\"`. */\n primarySuffix?: string\n /** Optional struck-through comparison price rendered above `primary`, e.g. `\"$30\"`. */\n secondary?: string\n /** Small suffix rendered after `secondary`. */\n secondarySuffix?: string\n}\n\nexport interface TierCardProps {\n /** Small annotation after the title, e.g. `\"(current)\"`. */\n badge?: React.ReactNode\n /** Feature list rendered under the price. */\n bullets: React.ReactNode[]\n className?: string\n /** Background image URL. */\n image: string\n /** Applies the \"current plan\" border hint when not `selected`. */\n isCurrent?: boolean\n onSelect?: () => void\n /** Color blended with `mix-blend-mode: color` over the image (used for the highest-tier red treatment). */\n overlay?: string\n price: TierCardPrice\n /** Applies selected chrome (arc-border shimmer, active distortion, plus-lighter text blend). */\n selected?: boolean\n /** Shader tint passed through to `ImageDistortion`. */\n tint?: string\n /** Active / inactive tint strength passed through to `ImageDistortion`. */\n tintStrength?: { active: number; inactive: number }\n /** Tier name / headline. */\n title: React.ReactNode\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nous-research/ui",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "sideEffects": [