Kez/kez-chat/web/DESIGN.md
Jason Tudisco 60ff82b4a2 design(kez-chat/web): redesign foundation — tactical-terminal theme + tokens
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>
2026-05-27 21:45:21 -06:00

9.2 KiB
Raw Permalink Blame History

KEZ Design System

Source of truth for the kez-chat redesign (redesign-kez-theme branch). Goal: take the chat app out of the prototype phase into a real, WhatsApp/Discord-caliber messenger with an iconic KEZ identity.

Who we're designing for

Hackers, infosec people, privacy absolutists, anti-surveillance / sovereignty folks, Meshtastic & off-grid comms operators, journalists/activists in hostile environments — the Signal / Briar / Tails / Mullvad / Monero crowd. They trust verifiability over promises, have a finely-tuned bullshit detector, and bounce instantly from anything that smells like VC surveillance-ware.

Positioning: KEZ is the sovereign identity layer + encrypted comms for people who assume the network is hostile.

Aesthetic direction

Muted tactical terminal — restraint, not neon cosplay. Mullvad's calm authority. Monospace as identity. The first 3 seconds should feel like opening an operational tool, not a brochure. Hard-ish edges, visible structure, a single cold accent. No gradients-blobs, no mascots, no "delightful."

Hard DO-NOTs

  • No rounded-blob/gradient SaaS look, no mascots, no illustrations of laughing people.
  • No "military-grade / bank-level" marketing adjectives. Show, don't boast.
  • No surveillance tells: no third-party analytics, no social login, no email-required signup.
  • No stock photography.

Color palette (dark-first; light theme = v2, out of scope)

Tailwind v4 @theme tokens, in src/app.css.

Token Hex Use
--color-bg #0B0C0E app background (neutral near-black)
--color-surface #16181C cards, conversation list, sidebars
--color-elevated #1E2127 modals, menus, input wells
--color-border #2A2E35 hairlines, dividers
--color-text #E8EAED primary text (neutral off-white)
--color-text-secondary #9BA3AD secondary
--color-text-muted #5C636D timestamps, meta
--color-text-disabled #3A4049 disabled
--color-accent #28C8E8 the KEZ color — electric cyan
--color-accent-dim #1B9DBC hover/pressed, accent borders
--color-accent-contrast #04131A text on accent fills
--color-verified #4ADE80 proof verified (distinct from accent)
--color-danger #FF5C6C destructive, failed
--color-warning #FFB13D needs-attention
--color-bubble-recv #1B1F25 received message bubble fill

Accent is used surgically: send bubbles, focus rings, active nav, the wordmark cursor, links, live/streaming indicators. Greys carry the weight. Verified green is for proofs only — never as a general accent, so a verification badge never camouflages into accent UI.

Typography

  • UI/body: Inter--font-sans: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif
  • Monospace: JetBrains Mono--font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace. Used for keys, hashes, handles, the wordmark.

Loaded via Google Fonts.

Role Size / weight / line-height Notes
Wordmark 22px / 700 / 1.1 mono -0.02em, + cyan block cursor
Section header 12px / 600 / 1.3 sans uppercase, +0.08em, secondary color
Body / message 15px / 450 / 1.45 sans
Conversation name 15px / 600 / 1.3 sans
Timestamp/meta 12px / 500 / 1.2 muted
Mono key display 13px / 500 / 1.5 mono +0.01em

Spacing / radius / shadow

  • Spacing (4px base): 4, 8, 12, 16, 20, 24, 32, 48.
  • Radius — tactical, mid-soft: --radius-sm: 4px (chips/badges), --radius-md: 8px (inputs/buttons), --radius-lg: 12px (bubbles/cards), --radius-xl: 16px (modals). Fully-round reads consumer-soft; sharp reads unfinished; 812 says "engineered."
  • Shadows = terminal glow, not ambient drop shadows. Surfaces use 1px solid --color-border hairlines. Modals: 0 8px 24px -8px rgba(0,0,0,0.6). Accent focus/glow: 0 0 0 1px #28C8E833, 0 0 16px -2px #28C8E866.

Signature components

  • Message bubbles — radius lg, padding 8px 12px, max-width ~78%.
    • Sent: --color-accent fill, --color-accent-contrast text, border-bottom-right-radius: 4px tail.
    • Received: --color-bubble-recv fill, --color-text, 1px solid --color-border, border-bottom-left-radius: 4px.
  • Conversation row — 64px tall, 40px avatar (radius-md), name 600, preview secondary, time muted. Active = left 2px accent bar + elevated bg. Unread = accent dot + name 700.
  • Buttons — height 40px, radius-md, 600. Primary: accent fill / contrast text / dim hover / 0.98 active / glow focus. Secondary: transparent, 1px solid border, hover elevated bg + accent-dim border.
  • Inputs — elevated bg, 1px solid border, radius-md, focus → accent border + 0 0 0 3px #28C8E822 ring. Key inputs use mono.
  • Handle/identity chip — inline mono, radius-sm, 2px 8px, bg #28C8E814, 1px solid #28C8E833, accent text; leading @/0x muted.
  • Verified proof badgeradius-sm, bg #4ADE8014, border #4ADE8040, --color-verified text, mono 11/600, leading ✓.
  • Avatars — deterministic identicon generated from the ed25519 key, so every KEZ has a stable face. Eliminates the biggest "prototype" tell.

Motion

Fast (120200ms), cubic-bezier(0.2,0.8,0.2,1), on state change only, respect prefers-reduced-motion.

  • Received message: slide-up 6px + fade.
  • Sent message: spring scale .96→1 + brief accent-glow pulse decaying ~600ms.
  • Thread push/back slide on mobile.
  • Tasteful terminal flourish: a single cyan block-cursor blink on the empty compose field + after the wordmark. No content scanlines.

Wordmark / icon

  • Wordmark: kez lowercase, JetBrains Mono 700, -0.02em, primary text, followed by a blinking cyan block cursor . The cursor is the brand mark.
  • Icon: evolve the amber key → cyan. Recolor public/kez-icon.svg stroke #fbbf24#28C8E8 on #0B0C0E; reshape so the key reads as a key-meets-cursor glyph. Drop the literal 🔑 emoji everywhere. Regenerate PWA icon set. Manifest theme_color + background_color#0B0C0E.

Information architecture (the big structural change)

Land logged-in users on Chats, not a Dashboard. The "dashboard" as a destination is killed; its contents redistribute.

Navigation — 4 destinations

Destination Purpose
Chats conversation list + threads (the home)
Contacts known KEZs + verification status + start-new-chat
Identity your KEZ + claims/proofs (the superpower surface)
Settings security, backup, notifications, account, about
  • Mobile (PWA): fixed bottom tab bar, 4 tabs, unread badge on Chats. Thread view pushes full-screen with a back chevron.
  • Desktop: slim left icon rail (4 destinations) + secondary list column + main content pane. Replaces the current top nav bar entirely.

Feature → new home

Existing New home
Landing/Create/Restore/Unlock unauthenticated flow (pre-nav), restyled
Messages (list+thread+compose, SSE, emoji, unread, notifications) Chats (default surface)
Start chat by handle Contacts → New chat (preview card before opening)
Claims list Identity → My proofs (grouped verified/failed/pending)
AddClaim Identity → Add proof
Identity display (handle@server, ed25519 key, registry) Identity header card (avatar, copyable KEZ, fingerprint, QR)
Seed/key backup Settings → Security → Recovery phrase (re-auth gated)
Biometric/passkey Settings → Security → App lock
Notifications perm + test Settings → Notifications
Build SHA / source link Settings → About

New-conversation flow (the KEZ moment)

  • FAB on Chats (mobile) / "New chat" in Contacts column (desktop) → "Enter a KEZ" (handle@server, paste/QR) → lookuppreview card: avatar, handle, key fingerprint, and inline verified proofs (✓ github:you, ✓ dns:yourdomain) → "Message". Verification is always one tap from a thread via the contact-detail header. You see who someone is before you trust them.

Polish signals to ship

  1. Identicon avatars everywhere (from ed25519 key).
  2. Message status ticks (sent / SSE-delivered) + day separators.
  3. Real empty + skeleton-loading states.
  4. Verification shield badge system (green verified / neutral none / amber failed), consistent across Chats, Contacts, Identity.
  5. Native push/back + send transitions; smooth auto-scroll (already shipped).

Implementation phases

  1. Foundationapp.css Tailwind v4 @theme tokens, Google Fonts, recolor icon + regenerate PWA assets, manifest colors.
  2. Shell + nav — bottom tab bar / left rail, router lands on /chats, wordmark component.
  3. Chats — restyle list + thread + bubbles, identicon avatars, empty/skeleton states. Keep SSE/emoji/notifications/auto-scroll.
  4. Identity — identity card + proofs (migrate Claims/AddClaim).
  5. Settings — Account / Security / Notifications / About (migrate Dashboard remainder).
  6. Contacts — list + new-chat preview card with proofs.
  7. Auth flow restyle — Landing/Create/Restore/Unlock to the new theme.

All existing functionality is preserved; only its placement and presentation change.