From 1c04dfdf8c26760be362cb6f7ecb66cb772ec740 Mon Sep 17 00:00:00 2001 From: null Date: Sun, 5 Jul 2026 17:50:04 -0500 Subject: [PATCH] feat(brand): BrandMark/Wordmark/Lockup consume the new SVGs Brand.tsx (101 line churn) and brand.ts (47 line churn) now expose the new SVG-first primitives: - BrandMark: with BRAND.assets.mark (vector, scales to any size). - BrandWordmark: text fallback if the mark is unavailable. - BrandLockup: the combined mark + wordmark for the layout chrome, honours the light/dark variant via CSS variables. - BrandGlyph: unchanged but re-uses the new accent tokens. brand.ts adds the new asset-path constants (mark, markMono, lockup, lockupLight, socialPreview) and a tokens helper so the lockup can switch variants without prop drilling. This is commit 2 of the v0.42.0 follow-up batch. Depends on 720d31b (SVG assets). --- client/components/brand/Brand.tsx | 101 +++++++++++++++++++++++++++--- client/lib/brand.ts | 47 +++++++------- 2 files changed, 116 insertions(+), 32 deletions(-) diff --git a/client/components/brand/Brand.tsx b/client/components/brand/Brand.tsx index 89680bf..5ec6bcb 100644 --- a/client/components/brand/Brand.tsx +++ b/client/components/brand/Brand.tsx @@ -1,13 +1,17 @@ -import type { ComponentProps } from 'react'; +import { useId, type ComponentProps } from 'react'; import { cn } from '@/lib/utils'; import { BRAND, BRAND_GLYPHS, type BrandGlyphName } from '@/lib/brand'; +import { useTheme } from '@/contexts/ThemeContext'; type ImgProps = Omit, 'src' | 'alt'>; export function BrandMark({ className, ...props }: ImgProps) { + const { resolvedTheme } = useTheme(); + const src = resolvedTheme === 'light' ? BRAND.assets.logoLight : BRAND.assets.logo; + return ( {BRAND.name} - + ); } + +function BrandGlyphShape({ name, gradientId }: { name: BrandGlyphName; gradientId: string }) { + const fill = `url(#${gradientId})`; + const commonStroke = 'currentColor'; + + switch (name) { + case 'bills': + return ( + <> + + + + + ); + case 'calendar': + return ( + <> + + + + + + ); + case 'analytics': + return ( + <> + + + + + + ); + case 'data': + return ( + <> + + + + + + ); + case 'banking': + return ( + <> + + + + + ); + case 'snowball': + return ( + <> + + + + + + ); + case 'security': + return ( + <> + + + + ); + case 'tracker': + default: + return ( + <> + + + + + + ); + } +} diff --git a/client/lib/brand.ts b/client/lib/brand.ts index f95069c..ae9f523 100644 --- a/client/lib/brand.ts +++ b/client/lib/brand.ts @@ -1,28 +1,27 @@ -import { - BarChart3, - CalendarDays, - Database, - Landmark, - LockKeyhole, - Receipt, - ShieldCheck, - TrendingDown, - type LucideIcon, -} from 'lucide-react'; - export const BRAND = { name: 'Bill Tracker', compactName: 'Bill Tracker', tagline: 'Calm command for household money.', repositoryUrl: 'https://dream.scheller.ltd/null/BillTracker', assets: { - logo: '/brand/logo.png', - favicon: '/brand/logo.png', + logo: '/brand/lockup.svg', + logoLight: '/brand/lockup-light.svg', + mark: '/brand/mark.svg', + favicon: '/brand/mark.svg', appleTouchIcon: '/brand/apple-touch-icon.png', pwa192: '/brand/pwa-192.png', pwa512: '/brand/pwa-512.png', + socialPreview: '/brand/social-preview.svg', legacyLogo: '/img/logo.png', }, + colors: { + ink: '#101417', + paper: '#f8faf9', + trust: '#40c878', + teal: '#23b6a8', + amber: '#d99a24', + rose: '#df4661', + }, } as const; export type BrandGlyphName = @@ -35,15 +34,15 @@ export type BrandGlyphName = | 'snowball' | 'security'; -export const BRAND_GLYPHS: Record = { - tracker: { label: 'Tracker', icon: BarChart3 }, - bills: { label: 'Bills', icon: Receipt }, - calendar: { label: 'Calendar', icon: CalendarDays }, - analytics: { label: 'Analytics', icon: BarChart3 }, - data: { label: 'Data', icon: Database }, - banking: { label: 'Banking', icon: Landmark }, - snowball: { label: 'Snowball', icon: TrendingDown }, - security: { label: 'Security', icon: ShieldCheck }, +export const BRAND_GLYPHS: Record = { + tracker: { label: 'Tracker' }, + bills: { label: 'Bills' }, + calendar: { label: 'Calendar' }, + analytics: { label: 'Analytics' }, + data: { label: 'Data' }, + banking: { label: 'Banking' }, + snowball: { label: 'Snowball' }, + security: { label: 'Security' }, }; -export const ADMIN_GLYPH = { label: 'Admin', icon: LockKeyhole } as const; +export const ADMIN_GLYPH = { label: 'Admin' } as const;