feat(machine): operator branding — local-file source (issue #47 V1)

Read /var/lib/bitspire/branding/{logo.png,branding.json} on startup and
apply across the renderer. branding.json may set title, theme (one of
the 6 built-ins or "custom"), and a custom_colors map (with optional
.dark overlay) — unset CSS vars fall back to gruvbox.

Wiring:
- electron/main.ts:loadBranding() reads + validates the JSON and
  base64-encodes logo.png; surfaced via the existing get-config IPC
- composables/useBranding.ts holds reactive logoUrl/title refs and a
  single setBranding() setter — the seam where #48's Nostr-event
  source will eventually overlay the local-file source
- composables/useTheme.ts:applyBrandingTheme() handles built-in theme
  swap and injects a <style#branding-custom-theme> block for custom
- IdleView binds :src/title; App.vue calls setBranding() before the
  maintenance screen renders so "Under Service" wears operator branding

Provisioning: new deploy/nixos/provision-branding.sh rsyncs a local dir
to /var/lib/bitspire/branding/ via sudo-on-the-far-side and restarts
bitspire.service. The existing provision-atm.sh stays focused on .env.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Padreug 2026-05-25 08:03:32 +02:00
commit c3353c409b
10 changed files with 268 additions and 3 deletions

View file

@ -119,6 +119,8 @@ in
systemd.tmpfiles.rules = [
"d ${cfg.dataDir} 0750 bitspire bitspire -"
"d ${cfg.dataDir}/logs 0750 bitspire bitspire -"
# Operator branding override target (issue #47); empty by default
"d ${cfg.dataDir}/branding 0755 bitspire bitspire -"
];
# Environment file for ATM configuration