Phase 0 of the redesign (see DESIGN.md). Establishes the visual
foundation; route restyling + IA reorg follow in subsequent commits.
Design direction (decided with a 3-agent design-team debate):
• Audience: hackers, privacy absolutists, anti-surveillance, Meshtastic
/ off-grid, journalists in hostile environments.
• Aesthetic: "muted tactical terminal" — Mullvad-calm restraint, not
neon cyberpunk cosplay. Monospace as identity. Hard-ish edges.
• Signature color: electric cyan #28C8E8 on neutral near-black #0B0C0E
(chosen over signal-amber and phosphor-green — ages better, reads
"serious infrastructure" without shouting). Verified-green reserved
for proofs only.
Changes:
• app.css: full Tailwind v4 @theme token set — elevation ramp, text
tiers, accent + dim + contrast, semantic colors, Inter + JetBrains
Mono via Google Fonts, tactical radius scale, accent glow, dark
color-scheme, cyan text-selection, thin dark scrollbars, and the
kez-cursor blink keyframe (respects prefers-reduced-motion).
• Wordmark.svelte: `kez▌` mono wordmark with blinking cyan block
cursor — the cursor is the brand mark.
• Avatar.svelte: deterministic 5×5 symmetric identicon from the
ed25519 key, cyan-arc hue. Every KEZ gets a stable face.
• kez-icon.svg: amber key → cyan key-meets-cursor glyph; regenerated
the full PWA icon set + apple-touch-icon from it.
• manifest + index.html theme/background color → #0B0C0E.
• DESIGN.md: the full system + IA plan as source of truth.
Note: existing route components still use light-theme utility classes
and will look inconsistent until restyled in the next phases — that
work lands next (shell/nav → Chats → Identity → Settings → Contacts).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Now installable on iOS (Safari → Share → Add to Home Screen) and
Android/desktop Chrome (install prompt or Settings → Install app).
Launches in standalone mode with a dark theme color matching the
lock-icon palette.
Stack:
• vite-plugin-pwa with workbox in generateSW mode, registerType
'autoUpdate' — new SW activates on next page load, no upgrade prompt
(chat needs to stay fresh).
• @vite-pwa/assets-generator for icon variants from a single SVG.
Source kez-icon.svg = dark squircle (#111827) + amber key glyph,
drawn inside the 80% maskable safe zone.
Caching:
• Precaches the SPA shell (~635 KB inc. the zstd WASM, well under
the 5 MB per-file cap).
• runtimeCaching 'NetworkOnly' for /v1/* — never cache authenticated
chat data; every poll must hit the network.
• navigateFallback to index.html so /messages, /claims, /dashboard
survive a refresh while offline. The /v1/, /internal/, /.well-known/
paths are explicitly denylisted from this fallback.
Meta tags (index.html):
• <link rel="manifest"> + theme-color for Android Chrome.
• apple-touch-icon-180x180 + apple-mobile-web-app-* meta for iOS,
including status-bar-style=black-translucent so the dark header
flows into the notch area in standalone.
• viewport-fit=cover so safe-area-inset works on notched devices.
Generated artifacts committed under web/public/:
kez-icon.svg, pwa-{64,192,512}.png, maskable-icon-512x512.png,
apple-touch-icon-180x180.png, favicon.ico.
Verified live: /manifest.webmanifest serves application/manifest+json,
/sw.js serves text/javascript, all icons return 200.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>