feat(branding): brand kit architecture (Phase 1) #96
No reviewers
Labels
No labels
app:activities
app:chat
app:events
app:forum
app:libra
app:market
app:restaurant
app:tasks
app:wallet
app:webapp
bug
enhancement
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
aiolabs/webapp!96
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/brand-kit"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #95 (Phase 1) — establishes the white-label brand kit in the webapp tree. Phase 2 (NixOS hosts migrate to
BRAND_DIR) tracked in aiolabs/server-deploy#8.What changed
A
branding/<dep>/directory now drives PWA icons, manifest fields, and the in-app<img>logo across the hub and all 8 standalones. The committedbranding/default/is aiolabs's brand. Downstream deployers pointBRAND_DIRat their own variant and get a fully rebranded build without forking.branding/default/—logo.png(seeded fromsrc/assets/logo.png) +brand.jsonwith{ name, shortName }. SVG slot reserved; defaults ship PNG-only until a vector source lands.pwa-assets.config.ts+@vite-pwa/assets-generator— derive the full PWA icon set from a single source. Resolution order:branding/<dep>/icons/<app>/logo.{svg,png}→branding/<dep>/logo.{svg,png}→ error.vite-branding.ts— shared resolver. ExportsBRAND_DIR, the typedbrandobject, a@brandimport alias,brandManifestName()helper, andbrandAssetsPlugin()(auto-runs the generator on every build/dev start via Vite'sbuildStart).scripts/generate-pwa-assets.mjs— wraps the CLI and cleans up the staged source so the 1024px brand source doesn't leak intodist/icons/.@/assets/logo.pngto@brand/logo.png(Login.vue,LoginDemo.vue,AppSidebar.vue,MobileDrawer.vue)./icons/<name>paths (the seven hand-craftedpublic/*.png|.ico|.svgbinaries are deleted;public/icons/is gitignored).brand.themeColor/backgroundColoras optional chrome overrides with??fallbacks to existing per-app accents. Events takes its fullmanifest.name/short_namefrom brand.branding/README.md+ a Brand Kit section inCLAUDE.mddocument the contract.Strict, no compat shims
Per CLAUDE.md's pre-public-launch policy,
VITE_APP_NAMEno longer overrides. Hosts that currently set it (cfaun → "Bouge") must declareBRAND_DIRpointing at a per-hostbranding/directory before their nextwebappflake input bump. That migration is aiolabs/server-deploy#8.Between landing this PR and Phase 2:
aio-demo(trackswebapp-demo→dev) immediately ships as "AIO Hub" / "AIO" branded — acceptable for staging vet.webappflake.lock bump.Deferred to follow-up
flake.nixexposinglib.mkWebapp— has real complexity (pnpm + sharp/libvips under nix sandbox). Filed as a separate issue.Commit layout
9 narrow commits, one concern each (scaffold → install generator → @brand alias → cleanup wrapper → manifest wiring → drop compat shim → icon path migration → auto-gen plugin → docs).
Test plan
pnpm installclean (sharp peer dep warning is expected — generator uses sharp via CLI, not through vite-plugin-pwa)pnpm buildproducesdist/index.htmlwith<title>AIO Hub</title>and 6 icons indist/icons/pnpm build:eventsproduces a manifest withname: "AIO", theme#1f2937pnpm build:walletkeepsname: "Wallet — Lightning"+ theme#eab308accent (verifying per-app fallbacks)BRAND_DIR=branding/<fixture> pnpm build:eventsswaps logo + manifest name end-to-endpnpm build:demosucceeds across all 9 builds, each emits its owndist-<app>/icons/set🤖 Generated with Claude Code
Adds pwa-assets.config.ts that reads $BRAND_DIR (default ./branding/default) and $BRAND_APP (optional per-standalone override), resolves logo.svg/logo.png with documented fallback order, and emits the existing icon set (favicon.ico, icon-{192,512}.png, icon-maskable-{192,512}.png, apple-touch-icon.png) into public/icons/. Generator outputs alongside its source, so the config stages the brand source into public/icons/.brand-source.{svg,png}; gitignoring public/icons/ covers both staged source and generated icons in one line. Adds pnpm script `generate-pwa-assets`. Vite configs / HTML <link> href updates come in follow-up commits; this commit alone produces the icon set under public/icons/ but doesn't yet replace the committed public/*.png binaries. Part of aiolabs/webapp#95 (brand kit architecture). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>vite-branding.ts now loads brand.json into a typed `brand` object and exports a `brandManifestName()` helper. Schema: { name (required), shortName?, themeColor?, backgroundColor? } Default brand.json drops themeColor/backgroundColor — they're optional overrides; per-app accents (wallet yellow, chat green, …) keep working via `?? '<existing>'` fallbacks in each standalone's vite config. events: manifest.name/short_name driven by brand. VITE_APP_NAME env override stays (Phase 2 server-deploy migration still in flight) and, when set, overrides both name and short_name to preserve pre-#95 behavior. cfaun's VITE_APP_NAME=Bouge keeps working unchanged. hub (vite.config.ts): brand.name flows into %VITE_APP_NAME% Hub title. 7 other standalones (wallet, chat, market, forum, tasks, restaurant, libra): only theme_color/background_color get brand overrides. Their manifest.name/short_name stay hardcoded so multi-PWA home-screen labels remain differentiated ("Wallet", "Chat", …) rather than all collapsing to the brand short_name. Verified default build: events manifest name=AIO; wallet keeps "Wallet — Lightning" + #eab308 accent. Verified VITE_APP_NAME=Sortir override: events name+short_name=Sortir. Part of aiolabs/webapp#95. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>PWA icons now ship from public/icons/ (generated by @vite-pwa/assets-generator, gitignored). The seven hand-crafted binaries at public/ root come out of the tree. Changes: - 7 deleted: public/{favicon.ico, apple-touch-icon.png, mask-icon.svg, icon-{192,512}.png, icon-maskable-{192,512}.png} - 9 HTML: <link rel="icon"|"apple-touch-icon"> hrefs prefixed with /icons/. mask-icon link dropped (PNG source → no sharp SVG; modern browsers prefer favicon.svg anyway, which we can revisit when an SVG brand source lands). - 8 vite configs: includeAssets[] + manifest.icons[].src prefixed with icons/. Vite rewrites /icons/foo → <base>/icons/foo when base is set (so /events/icons/favicon.ico under /events/ deploys). Build is now dependent on `pnpm generate-pwa-assets` running first (or whatever invokes the generator — Phase 2 NixOS builds wire this into buildNpmPackage). Standalone dev runs the generator on first boot or whenever BRAND_DIR changes. Part of aiolabs/webapp#95. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>9b38c00938to3388b481a73388b481a7to1516320c061516320c06tobe427f1821