feat(dependencies): add Lottie animation libraries and refactor NotFoundPage
- Added `@lottiefiles/dotlottie-react` and `lottie-react` dependencies for enhanced animation capabilities. - Refactored the NotFoundPage component to utilize a dedicated NotFoundContent component, improving code organization and readability. - Updated package.json and pnpm-lock.yaml to reflect new dependencies and their versions.
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Brand-aligned Lottie tinting (Tailwind theme tokens → normalized RGBA).
|
||||
* Primary: #5750F1 — slightly lifted in dark mode for contrast on `dark` bg.
|
||||
*/
|
||||
|
||||
export type LottieThemeMode = "light" | "dark";
|
||||
|
||||
/** #5750F1 */
|
||||
const PRIMARY_LIGHT = [87 / 255, 80 / 255, 241 / 255, 1] as const;
|
||||
/** Brighter violet for fills on #111928 */
|
||||
const PRIMARY_ON_DARK = [125 / 255, 118 / 255, 252 / 255, 1] as const;
|
||||
|
||||
function deepClone<T>(value: T): T {
|
||||
return JSON.parse(JSON.stringify(value)) as T;
|
||||
}
|
||||
|
||||
function colorsMatch(a: unknown, b: readonly number[]): boolean {
|
||||
if (!Array.isArray(a) || a.length !== 4) return false;
|
||||
return a.every(
|
||||
(v, i) => typeof v === "number" && Math.abs(v - b[i]!) < 0.0001,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace exact RGBA quadruples anywhere in the JSON tree (Lottie uses nested `c.k`).
|
||||
*/
|
||||
function replaceRgbaEverywhere(
|
||||
node: unknown,
|
||||
from: readonly number[],
|
||||
to: readonly number[],
|
||||
): unknown {
|
||||
if (node === null || typeof node !== "object") {
|
||||
return node;
|
||||
}
|
||||
if (Array.isArray(node)) {
|
||||
if (colorsMatch(node, from)) {
|
||||
return [...to];
|
||||
}
|
||||
return node.map((item) => replaceRgbaEverywhere(item, from, to));
|
||||
}
|
||||
const out: Record<string, unknown> = {};
|
||||
for (const [k, v] of Object.entries(node)) {
|
||||
out[k] = replaceRgbaEverywhere(v, from, to);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/** Pure black fills/strokes → brand primary (loading spinner dots, etc.). */
|
||||
export function applyLoadingLottieTheme<T extends object>(
|
||||
data: T,
|
||||
mode: LottieThemeMode,
|
||||
): T {
|
||||
const clone = deepClone(data);
|
||||
const to = mode === "dark" ? PRIMARY_ON_DARK : PRIMARY_LIGHT;
|
||||
return replaceRgbaEverywhere(clone, [0, 0, 0, 1], to) as T;
|
||||
}
|
||||
|
||||
/**
|
||||
* Full illustrations (e.g. 404): clone only until we add palette maps per asset.
|
||||
*/
|
||||
export function applyIllustrationLottieTheme<T extends object>(
|
||||
data: T,
|
||||
_mode: LottieThemeMode,
|
||||
): T {
|
||||
return deepClone(data);
|
||||
}
|
||||
Reference in New Issue
Block a user