From d541afd74516e4aa7a386b8bb6e564f6b546fb5e Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Wed, 1 Oct 2025 12:54:13 +0000 Subject: [PATCH] Refactor: Improve Novu Inbox theming --- index.html | 5 ++ src/hooks/useNovuTheme.ts | 110 +++++++++++++++++++++++++++----------- tailwind.config.ts | 4 ++ 3 files changed, 87 insertions(+), 32 deletions(-) diff --git a/index.html b/index.html index c9ddd12d..c8e0f607 100644 --- a/index.html +++ b/index.html @@ -16,6 +16,11 @@ + + + + + diff --git a/src/hooks/useNovuTheme.ts b/src/hooks/useNovuTheme.ts index dfe2313b..98cc45e2 100644 --- a/src/hooks/useNovuTheme.ts +++ b/src/hooks/useNovuTheme.ts @@ -5,13 +5,9 @@ export function useNovuTheme() { const { theme } = useTheme(); const appearance = useMemo(() => { - // Get computed styles to access CSS variables - const root = document.documentElement; - const style = getComputedStyle(root); - return { variables: { - // Colors + // Colors - using semantic tokens colorBackground: `hsl(var(--background))`, colorForeground: `hsl(var(--foreground))`, colorPrimary: `hsl(var(--primary))`, @@ -29,16 +25,20 @@ export function useNovuTheme() { colorBorder: `hsl(var(--border))`, // Border radius - borderRadius: `var(--radius)`, + borderRadius: `calc(var(--radius) + 2px)`, - // Font - fontFamily: style.getPropertyValue('font-family') || 'inherit', + // Typography + fontFamily: 'Inter, system-ui, -apple-system, sans-serif', fontSize: '14px', + fontWeightRegular: '400', + fontWeightMedium: '500', + fontWeightBold: '600', + lineHeight: '1.5', }, elements: { bellContainer: { - width: '40px', - height: '40px', + width: '36px', + height: '36px', }, bell: { width: '20px', @@ -47,84 +47,130 @@ export function useNovuTheme() { }, bellDot: { backgroundColor: `hsl(var(--primary))`, + width: '8px', + height: '8px', + boxShadow: `0 0 8px hsl(var(--primary) / 0.5)`, }, popover: { + width: '400px', + maxWidth: '90vw', + maxHeight: '600px', boxShadow: `var(--shadow-card)`, border: `1px solid hsl(var(--border))`, borderRadius: `calc(var(--radius) + 4px)`, + backgroundColor: `hsl(var(--background))`, + overflow: 'hidden', + }, + notificationList: { + maxHeight: '480px', + overflowY: 'auto', }, notificationItem: { + padding: '16px', + borderBottom: `1px solid hsl(var(--border) / 0.5)`, transition: 'var(--transition-smooth)', - '&:hover': { - backgroundColor: `hsl(var(--muted) / 0.5)`, - }, + cursor: 'pointer', }, notificationItemRead: { - opacity: '0.7', + opacity: '0.65', + backgroundColor: `hsl(var(--muted) / 0.2)`, }, notificationItemUnread: { - backgroundColor: `hsl(var(--muted) / 0.3)`, - borderLeft: `3px solid hsl(var(--primary))`, + backgroundColor: `hsl(var(--muted) / 0.4)`, + borderLeft: `4px solid hsl(var(--primary))`, + fontWeight: '500', }, notificationDot: { backgroundColor: `hsl(var(--primary))`, - width: '8px', - height: '8px', + width: '10px', + height: '10px', + borderRadius: '50%', + boxShadow: `0 0 6px hsl(var(--primary) / 0.6)`, }, notificationTitle: { - fontWeight: '500', + fontSize: '15px', + fontWeight: '600', + lineHeight: '1.4', color: `hsl(var(--foreground))`, + marginBottom: '4px', }, notificationDescription: { + fontSize: '14px', + lineHeight: '1.5', color: `hsl(var(--muted-foreground))`, + marginBottom: '8px', }, notificationTimestamp: { fontSize: '12px', color: `hsl(var(--muted-foreground))`, + fontWeight: '400', }, notificationPrimaryAction: { backgroundColor: `hsl(var(--primary))`, color: `hsl(var(--primary-foreground))`, borderRadius: `var(--radius)`, - padding: '8px 16px', + padding: '10px 20px', + fontSize: '14px', + fontWeight: '500', + border: 'none', transition: 'var(--transition-smooth)', - '&:hover': { - opacity: '0.9', - }, + cursor: 'pointer', }, notificationSecondaryAction: { backgroundColor: `hsl(var(--secondary))`, color: `hsl(var(--secondary-foreground))`, borderRadius: `var(--radius)`, - padding: '8px 16px', + padding: '10px 20px', + fontSize: '14px', + fontWeight: '500', + border: 'none', transition: 'var(--transition-smooth)', - '&:hover': { - backgroundColor: `hsl(var(--secondary) / 0.8)`, - }, + cursor: 'pointer', }, loader: { color: `hsl(var(--primary))`, + width: '32px', + height: '32px', }, emptyNotifications: { color: `hsl(var(--muted-foreground))`, textAlign: 'center', - padding: '32px 16px', + padding: '48px 24px', + fontSize: '15px', + lineHeight: '1.6', }, header: { borderBottom: `1px solid hsl(var(--border))`, - padding: '16px', + padding: '16px 20px', + backgroundColor: `hsl(var(--muted) / 0.3)`, }, headerTitle: { - fontSize: '16px', + fontSize: '17px', fontWeight: '600', color: `hsl(var(--foreground))`, + letterSpacing: '-0.01em', + }, + headerMarkAllAsReadButton: { + fontSize: '13px', + color: `hsl(var(--primary))`, + fontWeight: '500', + cursor: 'pointer', + transition: 'var(--transition-smooth)', }, footer: { borderTop: `1px solid hsl(var(--border))`, - padding: '12px 16px', + padding: '12px 20px', + backgroundColor: `hsl(var(--muted) / 0.3)`, + }, + footerViewAllButton: { + fontSize: '14px', + color: `hsl(var(--primary))`, + fontWeight: '500', + cursor: 'pointer', + transition: 'var(--transition-smooth)', }, }, - }; + } as const; }, [theme]); return appearance; diff --git a/tailwind.config.ts b/tailwind.config.ts index a1edb691..13053976 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -13,6 +13,10 @@ export default { }, }, extend: { + fontFamily: { + sans: ["Inter", "system-ui", "-apple-system", "sans-serif"], + inter: ["Inter", "system-ui", "-apple-system", "sans-serif"], + }, colors: { border: "hsl(var(--border))", input: "hsl(var(--input))",