Add complete brand asset pack

This commit is contained in:
null 2026-07-06 12:54:29 -05:00
parent 40dfd6e3c1
commit b25be070ed
24 changed files with 208 additions and 26 deletions

View File

@ -1,7 +1,7 @@
# Bill Tracker # Bill Tracker
<p align="center"> <p align="center">
<img src="client/public/brand/social-preview.svg" alt="Bill Tracker — Calm command for household money"> <img src="client/public/brand/social-preview.png" alt="Bill Tracker — Calm command for household money">
</p> </p>
Bill Tracker is a private, self-hosted bill planning app for households and Bill Tracker is a private, self-hosted bill planning app for households and

View File

@ -6,12 +6,19 @@ export const BRAND = {
assets: { assets: {
logo: '/brand/lockup.svg', logo: '/brand/lockup.svg',
logoLight: '/brand/lockup-light.svg', logoLight: '/brand/lockup-light.svg',
logoPng: '/brand/logo.png',
mark: '/brand/mark.svg', mark: '/brand/mark.svg',
favicon: '/brand/mark.svg', markPng: '/brand/mark.png',
monoMark: '/brand/mark-mono.svg',
favicon: '/brand/favicon.svg',
faviconIco: '/brand/favicon.ico',
appleTouchIcon: '/brand/apple-touch-icon.png', appleTouchIcon: '/brand/apple-touch-icon.png',
pwa192: '/brand/pwa-192.png', pwa192: '/brand/pwa-192.png',
pwa512: '/brand/pwa-512.png', pwa512: '/brand/pwa-512.png',
pwaMaskable512: '/brand/pwa-maskable-512.png',
socialPreview: '/brand/social-preview.svg', socialPreview: '/brand/social-preview.svg',
socialPreviewPng: '/brand/social-preview.png',
emptyState: '/brand/empty-state.svg',
legacyLogo: '/img/logo.png', legacyLogo: '/img/logo.png',
}, },
colors: { colors: {
@ -34,15 +41,15 @@ export type BrandGlyphName =
| 'snowball' | 'snowball'
| 'security'; | 'security';
export const BRAND_GLYPHS: Record<BrandGlyphName, { label: string }> = { export const BRAND_GLYPHS: Record<BrandGlyphName, { label: string; asset: string }> = {
tracker: { label: 'Tracker' }, tracker: { label: 'Tracker', asset: '/brand/glyphs/tracker.svg' },
bills: { label: 'Bills' }, bills: { label: 'Bills', asset: '/brand/glyphs/bills.svg' },
calendar: { label: 'Calendar' }, calendar: { label: 'Calendar', asset: '/brand/glyphs/calendar.svg' },
analytics: { label: 'Analytics' }, analytics: { label: 'Analytics', asset: '/brand/glyphs/analytics.svg' },
data: { label: 'Data' }, data: { label: 'Data', asset: '/brand/glyphs/data-banking.svg' },
banking: { label: 'Banking' }, banking: { label: 'Banking', asset: '/brand/glyphs/data-banking.svg' },
snowball: { label: 'Snowball' }, snowball: { label: 'Snowball', asset: '/brand/glyphs/snowball-payoff.svg' },
security: { label: 'Security' }, security: { label: 'Security', asset: '/brand/glyphs/admin-security.svg' },
}; };
export const ADMIN_GLYPH = { label: 'Admin' } as const; export const ADMIN_GLYPH = { label: 'Admin' } as const;

View File

@ -58,7 +58,7 @@ export const RELEASE_NOTES: ReleaseNotes = {
}, },
], ],
image: { image: {
src: '/brand/social-preview.svg', src: '/brand/social-preview.png',
alt: 'Bill Tracker brand preview', alt: 'Bill Tracker brand preview',
}, },
}; };

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,31 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 360" role="img" aria-labelledby="title desc">
<title id="title">Bill Tracker empty-state illustration</title>
<desc id="desc">Quiet ledger cards, a checkmark chart, and calm status dots.</desc>
<defs>
<radialGradient id="glow" cx="50%" cy="35%" r="60%">
<stop offset="0" stop-color="#40c878" stop-opacity="0.18"/>
<stop offset="1" stop-color="#40c878" stop-opacity="0"/>
</radialGradient>
<linearGradient id="trust" x1="242" x2="392" y1="246" y2="96" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#1e9f93"/>
<stop offset="0.58" stop-color="#40c878"/>
<stop offset="1" stop-color="#96e6a1"/>
</linearGradient>
</defs>
<rect width="640" height="360" rx="38" fill="#101417"/>
<rect width="640" height="360" rx="38" fill="url(#glow)"/>
<rect x="126" y="74" width="388" height="212" rx="30" fill="#172025" stroke="#314047"/>
<rect x="158" y="108" width="122" height="18" rx="9" fill="#314047"/>
<rect x="158" y="144" width="84" height="14" rx="7" fill="#26343a"/>
<rect x="158" y="174" width="128" height="14" rx="7" fill="#26343a"/>
<rect x="158" y="204" width="102" height="14" rx="7" fill="#26343a"/>
<circle cx="438" cy="118" r="9" fill="#40c878"/>
<circle cx="438" cy="156" r="9" fill="#d99a24"/>
<circle cx="438" cy="194" r="9" fill="#23b6a8"/>
<rect x="318" y="183" width="22" height="52" rx="7" fill="url(#trust)" opacity="0.82"/>
<rect x="352" y="153" width="22" height="82" rx="7" fill="url(#trust)" opacity="0.92"/>
<rect x="386" y="122" width="22" height="113" rx="7" fill="url(#trust)"/>
<path d="m319 132 29 29 82-64" fill="none" stroke="#96e6a1" stroke-linecap="round" stroke-linejoin="round" stroke-width="12"/>
<path d="m319 132 29 29 82-64" fill="none" stroke="#40c878" stroke-linecap="round" stroke-linejoin="round" stroke-width="6"/>
<path d="M118 296h404" stroke="#26343a" stroke-width="4" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

View File

@ -0,0 +1,21 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" role="img" aria-labelledby="title desc">
<title id="title">Bill Tracker favicon</title>
<desc id="desc">A compact green checkmark and bar chart mark.</desc>
<defs>
<linearGradient id="trust" x1="48" x2="206" y1="210" y2="50" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#1e9f93"/>
<stop offset="0.58" stop-color="#40c878"/>
<stop offset="1" stop-color="#96e6a1"/>
</linearGradient>
<linearGradient id="ink" x1="34" x2="222" y1="34" y2="222" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#172025"/>
<stop offset="1" stop-color="#0f1417"/>
</linearGradient>
</defs>
<rect width="256" height="256" rx="58" fill="url(#ink)"/>
<rect x="61" y="123" width="28" height="59" rx="8" fill="url(#trust)" opacity="0.86"/>
<rect x="101" y="95" width="28" height="87" rx="8" fill="url(#trust)" opacity="0.94"/>
<rect x="141" y="69" width="28" height="113" rx="8" fill="url(#trust)"/>
<path d="M62 80.5 97.5 116 190 45" fill="none" stroke="#96e6a1" stroke-linecap="round" stroke-linejoin="round" stroke-width="18"/>
<path d="M62 80.5 97.5 116 190 45" fill="none" stroke="#40c878" stroke-linecap="round" stroke-linejoin="round" stroke-width="10"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96" role="img" aria-labelledby="title desc">
<title id="title">Admin and security glyph</title>
<desc id="desc">A shield with a confirmation check for secure administration.</desc>
<rect width="96" height="96" rx="22" fill="#101417"/>
<path d="M48 15 73 25v19c0 17-10 29-25 37-15-8-25-20-25-37V25l25-10Z" fill="none" stroke="#40c878" stroke-width="6" stroke-linejoin="round"/>
<path d="m35 48 9 9 19-25" fill="none" stroke="#96e6a1" stroke-width="8" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="70" cy="70" r="8" fill="#23b6a8"/>
</svg>

After

Width:  |  Height:  |  Size: 621 B

View File

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96" role="img" aria-labelledby="title desc">
<title id="title">Analytics glyph</title>
<desc id="desc">A calm trend line with two data points.</desc>
<rect width="96" height="96" rx="22" fill="#101417"/>
<path d="M20 72h56" stroke="#314047" stroke-width="6" stroke-linecap="round"/>
<path d="M22 63 38 46l14 10 24-34" fill="none" stroke="#40c878" stroke-width="8" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="38" cy="46" r="7" fill="#96e6a1"/>
<circle cx="76" cy="22" r="7" fill="#23b6a8"/>
<path d="M22 63 38 46l14 10" fill="none" stroke="#96e6a1" stroke-width="3" stroke-linecap="round" opacity="0.75"/>
</svg>

After

Width:  |  Height:  |  Size: 701 B

View File

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96" role="img" aria-labelledby="title desc">
<title id="title">Bills glyph</title>
<desc id="desc">A receipt with ledger lines and a checkmark.</desc>
<rect width="96" height="96" rx="22" fill="#101417"/>
<path d="M27 17h42v62l-8-6-7 6-7-6-7 6-7-6-6 5V17Z" fill="none" stroke="#40c878" stroke-width="6" stroke-linejoin="round"/>
<path d="M36 34h20M36 46h16M36 58h12" stroke="#96e6a1" stroke-width="5" stroke-linecap="round" opacity="0.78"/>
<path d="m52 56 7 7 16-22" fill="none" stroke="#23b6a8" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 638 B

View File

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96" role="img" aria-labelledby="title desc">
<title id="title">Calendar glyph</title>
<desc id="desc">A calendar page with one quiet payment check.</desc>
<rect width="96" height="96" rx="22" fill="#101417"/>
<rect x="20" y="23" width="56" height="53" rx="10" fill="none" stroke="#40c878" stroke-width="6"/>
<path d="M31 16v15M65 16v15M22 38h52" stroke="#96e6a1" stroke-width="6" stroke-linecap="round"/>
<rect x="31" y="48" width="13" height="13" rx="4" fill="#23b6a8" opacity="0.82"/>
<path d="m49 60 7 7 17-24" fill="none" stroke="#40c878" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 686 B

View File

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96" role="img" aria-labelledby="title desc">
<title id="title">Data and banking glyph</title>
<desc id="desc">A banking column connected to a data store.</desc>
<rect width="96" height="96" rx="22" fill="#101417"/>
<path d="M17 35 42 21l25 14H17Z" fill="none" stroke="#40c878" stroke-width="6" stroke-linejoin="round"/>
<path d="M25 39v25M42 39v25M59 39v25M20 71h45" stroke="#96e6a1" stroke-width="6" stroke-linecap="round"/>
<ellipse cx="68" cy="49" rx="12" ry="5" fill="none" stroke="#23b6a8" stroke-width="5"/>
<path d="M56 49v14c0 3 5 6 12 6s12-3 12-6V49" fill="none" stroke="#23b6a8" stroke-width="5"/>
<path d="M56 57c0 3 5 6 12 6s12-3 12-6" stroke="#23b6a8" stroke-width="5" opacity="0.7"/>
</svg>

After

Width:  |  Height:  |  Size: 777 B

View File

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96" role="img" aria-labelledby="title desc">
<title id="title">Snowball and payoff glyph</title>
<desc id="desc">Two growing payoff circles following an upward path.</desc>
<rect width="96" height="96" rx="22" fill="#101417"/>
<circle cx="33" cy="36" r="11" fill="none" stroke="#96e6a1" stroke-width="6" opacity="0.82"/>
<circle cx="58" cy="57" r="18" fill="none" stroke="#40c878" stroke-width="6"/>
<path d="M20 74c19-3 41-19 57-53" fill="none" stroke="#23b6a8" stroke-width="8" stroke-linecap="round"/>
<path d="M61 22h16v16" fill="none" stroke="#96e6a1" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 700 B

View File

@ -0,0 +1,17 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96" role="img" aria-labelledby="title desc">
<title id="title">Tracker glyph</title>
<desc id="desc">Three rising bars with a checkmark for bill tracking.</desc>
<defs>
<linearGradient id="g" x1="20" x2="76" y1="76" y2="18" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#1e9f93"/>
<stop offset="0.62" stop-color="#40c878"/>
<stop offset="1" stop-color="#96e6a1"/>
</linearGradient>
</defs>
<rect width="96" height="96" rx="22" fill="#101417"/>
<rect x="22" y="50" width="10" height="25" rx="4" fill="url(#g)" opacity="0.78"/>
<rect x="40" y="38" width="10" height="37" rx="4" fill="url(#g)" opacity="0.9"/>
<rect x="58" y="26" width="10" height="49" rx="4" fill="url(#g)"/>
<path d="m21 30 14 14 40-30" fill="none" stroke="#96e6a1" stroke-linecap="round" stroke-linejoin="round" stroke-width="8"/>
<path d="m21 30 14 14 40-30" fill="none" stroke="#40c878" stroke-linecap="round" stroke-linejoin="round" stroke-width="4"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -0,0 +1,26 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" role="img" aria-labelledby="title desc">
<title id="title">Bill Tracker maskable PWA icon</title>
<desc id="desc">A padded Bill Tracker mark for maskable app icon surfaces.</desc>
<defs>
<linearGradient id="trust" x1="142" x2="370" y1="378" y2="134" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#1e9f93"/>
<stop offset="0.58" stop-color="#40c878"/>
<stop offset="1" stop-color="#96e6a1"/>
</linearGradient>
<radialGradient id="glow" cx="44%" cy="34%" r="62%">
<stop offset="0" stop-color="#40c878" stop-opacity="0.18"/>
<stop offset="1" stop-color="#40c878" stop-opacity="0"/>
</radialGradient>
<linearGradient id="ink" x1="0" x2="512" y1="0" y2="512" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#172025"/>
<stop offset="1" stop-color="#0f1417"/>
</linearGradient>
</defs>
<rect width="512" height="512" fill="url(#ink)"/>
<rect width="512" height="512" fill="url(#glow)"/>
<rect x="118" y="256" width="44" height="92" rx="13" fill="url(#trust)" opacity="0.86"/>
<rect x="192" y="203" width="44" height="145" rx="13" fill="url(#trust)" opacity="0.94"/>
<rect x="266" y="152" width="44" height="196" rx="13" fill="url(#trust)"/>
<path d="m120 174 62 62 180-138" fill="none" stroke="#96e6a1" stroke-linecap="round" stroke-linejoin="round" stroke-width="34"/>
<path d="m120 174 62 62 180-138" fill="none" stroke="#40c878" stroke-linecap="round" stroke-linejoin="round" stroke-width="18"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

View File

@ -49,10 +49,15 @@ Primary source files live in `client/public/brand/`.
- `lockup.svg` - primary logo for dark surfaces. - `lockup.svg` - primary logo for dark surfaces.
- `lockup-light.svg` - primary logo for light surfaces. - `lockup-light.svg` - primary logo for light surfaces.
- `logo.png` - raster export of the primary logo for docs and non-SVG contexts.
- `mark.svg` - compact app mark and favicon. - `mark.svg` - compact app mark and favicon.
- `mark.png` - raster export of the compact app mark.
- `mark-mono.svg` - single-color mark for constrained contexts. - `mark-mono.svg` - single-color mark for constrained contexts.
- `social-preview.svg` - Open Graph, README, release, or marketplace preview. - `favicon.svg`, `favicon.ico` - browser tab and legacy favicon surfaces.
- `pwa-192.png`, `pwa-512.png`, `apple-touch-icon.png` - install surfaces. - `social-preview.svg`, `social-preview.png` - Open Graph, README, release, or marketplace preview.
- `empty-state.svg` - reusable empty-state illustration style.
- `pwa-192.png`, `pwa-512.png`, `pwa-maskable.svg`, `pwa-maskable-512.png`, `apple-touch-icon.png` - install surfaces.
- `glyphs/*.svg` - standalone product glyph source files.
Rules: Rules:
@ -65,14 +70,15 @@ Rules:
Bill Tracker has a small proprietary product glyph set for page identity only: Bill Tracker has a small proprietary product glyph set for page identity only:
- Tracker | Product area | Asset |
- Bills | --- | --- |
- Calendar | Tracker | `client/public/brand/glyphs/tracker.svg` |
- Analytics | Bills | `client/public/brand/glyphs/bills.svg` |
- Data | Calendar | `client/public/brand/glyphs/calendar.svg` |
- Banking | Analytics | `client/public/brand/glyphs/analytics.svg` |
- Snowball | Data / Banking | `client/public/brand/glyphs/data-banking.svg` |
- Security/Admin | Snowball / Payoff | `client/public/brand/glyphs/snowball-payoff.svg` |
| Admin / Security | `client/public/brand/glyphs/admin-security.svg` |
Rules: Rules:

View File

@ -3,17 +3,21 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/svg+xml" href="/brand/mark.svg"> <link rel="icon" type="image/svg+xml" href="/brand/favicon.svg">
<link rel="alternate icon" href="/brand/favicon.ico">
<link rel="apple-touch-icon" href="/brand/apple-touch-icon.png"> <link rel="apple-touch-icon" href="/brand/apple-touch-icon.png">
<meta name="theme-color" content="#101417"> <meta name="theme-color" content="#101417">
<meta name="description" content="Calm command for household money."> <meta name="description" content="Calm command for household money.">
<meta property="og:title" content="Bill Tracker"> <meta property="og:title" content="Bill Tracker">
<meta property="og:description" content="Calm command for household money."> <meta property="og:description" content="Calm command for household money.">
<meta property="og:image" content="/brand/social-preview.svg"> <meta property="og:image" content="/brand/social-preview.png">
<meta property="og:image:type" content="image/png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image"> <meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Bill Tracker"> <meta name="twitter:title" content="Bill Tracker">
<meta name="twitter:description" content="Calm command for household money."> <meta name="twitter:description" content="Calm command for household money.">
<meta name="twitter:image" content="/brand/social-preview.svg"> <meta name="twitter:image" content="/brand/social-preview.png">
<meta name="mobile-web-app-capable" content="yes"> <meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">

View File

@ -23,13 +23,28 @@ export default defineConfig({
VitePWA({ VitePWA({
registerType: 'autoUpdate', registerType: 'autoUpdate',
includeAssets: [ includeAssets: [
'brand/favicon.svg',
'brand/favicon.ico',
'brand/mark.svg', 'brand/mark.svg',
'brand/mark.png',
'brand/mark-mono.svg', 'brand/mark-mono.svg',
'brand/lockup.svg', 'brand/lockup.svg',
'brand/lockup-light.svg', 'brand/lockup-light.svg',
'brand/logo.png',
'brand/empty-state.svg',
'brand/social-preview.svg', 'brand/social-preview.svg',
'brand/social-preview.png',
'brand/pwa-maskable.svg',
'brand/glyphs/tracker.svg',
'brand/glyphs/bills.svg',
'brand/glyphs/calendar.svg',
'brand/glyphs/analytics.svg',
'brand/glyphs/data-banking.svg',
'brand/glyphs/snowball-payoff.svg',
'brand/glyphs/admin-security.svg',
'brand/pwa-192.png', 'brand/pwa-192.png',
'brand/pwa-512.png', 'brand/pwa-512.png',
'brand/pwa-maskable-512.png',
], ],
manifest: { manifest: {
name: 'Bill Tracker', name: 'Bill Tracker',
@ -41,7 +56,8 @@ export default defineConfig({
start_url: '/', start_url: '/',
icons: [ icons: [
{ src: '/brand/pwa-192.png', sizes: '192x192', type: 'image/png' }, { src: '/brand/pwa-192.png', sizes: '192x192', type: 'image/png' },
{ src: '/brand/pwa-512.png', sizes: '512x512', type: 'image/png', purpose: 'any maskable' }, { src: '/brand/pwa-512.png', sizes: '512x512', type: 'image/png', purpose: 'any' },
{ src: '/brand/pwa-maskable-512.png', sizes: '512x512', type: 'image/png', purpose: 'maskable' },
], ],
}, },
workbox: { workbox: {