User story / Problem statement
The default template styling (Telegraf font, yellow connect button, flat card layout, light-first theme) doesn't reflect the COPS brand identity. The UI needs a cohesive dark-first design with proper typography, visual hierarchy, and layout balance — aligned with the confidential/crypto nature of the product.
Proposed solution
Theme system
- Dark-first palette inspired by Catppuccin (deep navy base, blue primary accents, green for success states)
- Light theme as secondary option with coordinated colors
data-theme attribute-based switching via next-themes
- Theme toggle in the header
Typography
- Body: Inter (via
next/font/google, variable --font-inter)
- Monospace: JetBrains Mono (variable
--font-jetbrains) for addresses, amounts, hashes
- Removed external Telegraf font dependency (was loaded via fontshare CDN)
Logo & assets
- SVG logo with dark/light variants (
/logo-dark.svg, /logo-light.svg)
- SVG favicon (
/favicon.svg) replacing the PNG
CopsLogo component with theme-aware switching
CopsIconMark component for compact usage
Layout improvements
- Header: pill-style role switcher (Employer/Employee) replacing plain nav links, logo + theme toggle
- Employee page: 2-column balanced grid (Identity + USDC left, Salary + cUSDC right)
- Employer page: 2-column grid for Fund/Run sections, owner-gating with read-only warning for non-owners
- Home page: hero section with gradient glow, feature badges (Ethereum Secured, FHE Encryption, USDC Stablecoin)
Component polish
EncryptedAmount: pill-style with lock icons (open/closed), glow-green/glow-blue effects, "No access" state for ACL denials
StatusText: bordered card-style with variant icons instead of plain text
CryptoAmount: tabular-nums, separated symbol styling
Balance: simplified inline display
RainbowKitCustomConnectButton: rounded primary button replacing yellow hardcoded style
Hook refactor (decryption)
useEmployeeSalary: replaced useFHEDecrypt wrapper with direct FhevmDecryptionSignature.loadOrSign + instance.userDecrypt calls; accepts employeeId per-call instead of at hook creation; added 120s timeout, ACL denial detection, structured error messages
useEmployeeBalance: same refactor pattern; removed chainId param dependency
CSS
- Removed duplicate
@custom-variant dark rule
- Removed global
p { margin: 1rem 0 } reset
- Added utility classes:
.glow-blue, .glow-green, .encrypted-dots, .hero-glow
- Cards use
border border-base-300/50 consistently
- Buttons: removed default shadow, added hover glow on primary
Acceptance criteria
Technical notes
ThemeProvider from next-themes configured with attribute="data-theme" for DaisyUI compatibility
CopsLogo uses useTheme() + mounted guard to avoid hydration mismatch
- Decryption hooks now call
FhevmDecryptionSignature.loadOrSign directly — the useFHEDecrypt wrapper added unnecessary indirection for single-handle decrypt flows
LockOpen SVG uses Heroicons mini lock-open path; LockClosed uses the closed variant
Files changed
app/layout.tsx — fonts, ThemeProvider config
app/page.tsx — hero section with feature badges
app/employee/page.tsx — balanced 2-column layout
app/employer/page.tsx — owner gating, layout grid
components/Header.tsx — pill nav, logo, theme toggle
components/helper/Balance.tsx — simplified display
components/helper/RainbowKitCustomConnectButton/index.tsx — primary button style
components/ui/CopsLogo.tsx — new theme-aware logo
components/ui/ThemeToggle.tsx — new dark/light toggle
components/ui/CryptoAmount.tsx — tabular-nums, symbol styling
components/ui/EncryptedAmount.tsx — lock icons, denied state, glow effects
components/ui/StatusText.tsx — card-style with icons
components/ui/index.ts — barrel exports
hooks/cops/useEmployeeSalary.ts — direct decrypt, timeout, error handling
hooks/cops/useEmployeeBalance.ts — direct decrypt, simplified params
styles/globals.css — theme colors, glow utilities, font stacks
utils/helper/getMetadata.ts — SVG favicon
public/logo-dark.svg, public/logo-light.svg, public/favicon.svg — new assets
User story / Problem statement
The default template styling (Telegraf font, yellow connect button, flat card layout, light-first theme) doesn't reflect the COPS brand identity. The UI needs a cohesive dark-first design with proper typography, visual hierarchy, and layout balance — aligned with the confidential/crypto nature of the product.
Proposed solution
Theme system
data-themeattribute-based switching vianext-themesTypography
next/font/google, variable--font-inter)--font-jetbrains) for addresses, amounts, hashesLogo & assets
/logo-dark.svg,/logo-light.svg)/favicon.svg) replacing the PNGCopsLogocomponent with theme-aware switchingCopsIconMarkcomponent for compact usageLayout improvements
Component polish
EncryptedAmount: pill-style with lock icons (open/closed),glow-green/glow-blueeffects, "No access" state for ACL denialsStatusText: bordered card-style with variant icons instead of plain textCryptoAmount: tabular-nums, separated symbol stylingBalance: simplified inline displayRainbowKitCustomConnectButton: rounded primary button replacing yellow hardcoded styleHook refactor (decryption)
useEmployeeSalary: replaceduseFHEDecryptwrapper with directFhevmDecryptionSignature.loadOrSign+instance.userDecryptcalls; acceptsemployeeIdper-call instead of at hook creation; added 120s timeout, ACL denial detection, structured error messagesuseEmployeeBalance: same refactor pattern; removedchainIdparam dependencyCSS
@custom-variant darkrulep { margin: 1rem 0 }reset.glow-blue,.glow-green,.encrypted-dots,.hero-glowborder border-base-300/50consistentlyAcceptance criteria
next/font(no external CDN)EncryptedAmountshows distinct lock-open / lock-closed iconsbg-[#FFD208],text-gray-900) remainpnpm lintpasses with 0 warningspnpm check-typespasses (no new type errors)abortRefunused refs, cleaned imports)Technical notes
ThemeProviderfromnext-themesconfigured withattribute="data-theme"for DaisyUI compatibilityCopsLogousesuseTheme()+ mounted guard to avoid hydration mismatchFhevmDecryptionSignature.loadOrSigndirectly — theuseFHEDecryptwrapper added unnecessary indirection for single-handle decrypt flowsLockOpenSVG uses Heroicons mini lock-open path;LockCloseduses the closed variantFiles changed
app/layout.tsx— fonts, ThemeProvider configapp/page.tsx— hero section with feature badgesapp/employee/page.tsx— balanced 2-column layoutapp/employer/page.tsx— owner gating, layout gridcomponents/Header.tsx— pill nav, logo, theme togglecomponents/helper/Balance.tsx— simplified displaycomponents/helper/RainbowKitCustomConnectButton/index.tsx— primary button stylecomponents/ui/CopsLogo.tsx— new theme-aware logocomponents/ui/ThemeToggle.tsx— new dark/light togglecomponents/ui/CryptoAmount.tsx— tabular-nums, symbol stylingcomponents/ui/EncryptedAmount.tsx— lock icons, denied state, glow effectscomponents/ui/StatusText.tsx— card-style with iconscomponents/ui/index.ts— barrel exportshooks/cops/useEmployeeSalary.ts— direct decrypt, timeout, error handlinghooks/cops/useEmployeeBalance.ts— direct decrypt, simplified paramsstyles/globals.css— theme colors, glow utilities, font stacksutils/helper/getMetadata.ts— SVG faviconpublic/logo-dark.svg,public/logo-light.svg,public/favicon.svg— new assets