Interactive Feature Prototypes
Interactive Feature Prototypes
The Interactive Feature Prototypes are the static HTML/CSS mockup suite that defines the visual language, layout, and kinetic interaction behavior of the Secure Mesh messaging platform. They act as the single source of truth for UI/UX porting into the production Next.js web app (streaming-frontend) and the Expo mobile app (streaming), including the Obsidian Precision design-token system.
Purpose and Scope
This page documents the interactive prototype layer of the Secure Mesh repository: the prototype folders and design specifications that define how every screen looks and behaves before production code is written. It covers:
- The prototype catalog and its mapping to production routes.
- The Obsidian Precision design system (colors, typography, spacing, radii, elevation, motion).
- The interactive-state contract (hover, press, focus, spring physics) that production components must honor.
- The porting workflow from static mockup to
globals.cssand route components.
Related capabilities are intentionally left to their own pages: the Rust backend (streaming-backend), the shared realtime client (@securemesh/realtime-core), the Next.js frontend (streaming-frontend), and the Expo mobile app (streaming). This page only covers the prototype/design-source layer that drives their UI.
Overview
Secure Mesh is an end-to-end encrypted, real-time multimedia messaging and audio/video calling application (Signal Protocol X3DH + Double Ratchet, gRPC-Web realtime, Redis pattern-subscription signaling). Before any production component is built, the team authors static, interactive HTML/CSS prototypes that lock down the user experience.
This prototype-first workflow means the mockups are not throwaway design artifacts — they are the porting contract for every page. Each prototype maps to a route group in the Next.js App Router (and, via the same design tokens, to the Expo screens). The design language itself is codified in a YAML-front-matter design spec that doubles as a machine-readable token source (colors, typography, rounded, spacing blocks) plus a human-readable brand/interaction guide.
Three principles make these prototypes distinctive:
- Obsidian Foundations — deep, void-like dark surfaces (
#12131abackground family) that maximize contrast and make the single emerald accent (#4edea3) carry brand presence. - Glassmorphic Depth — translucent panels with heavy backdrop blur (12–20px) and hairline
1pxborder highlights that simulate light catching a glass edge. - Kinetic Feedback — a “physical” interaction model: buttons scale down to
0.97on press, panels slide with momentum-based spring physics, and all hover states stay subtle (opacity 0.8 or slight background tint).
The prototypes also enforce engineering constraints on the final implementation, most notably strict single-responsibility module decomposition applied across backend, web, and mobile code, which forces the ported components to be split into focused modules.
Architecture
The prototype layer sits at the top of the UI stack. Design tokens and interaction specs flow down into both production clients, while the backend (gRPC/Redis/PostgreSQL) is invisible to the prototype layer — prototypes only define presentation and interaction, not data flow.
Component Roles
| Prototype | Role | Production Destination |
|---|---|---|
| Auth flows | Sign-up and login screens, form states, error surfaces | (auth)/signup and (auth)/login routes |
| Chats | Conversation list and message thread UI, bubbles, composer, toasts | (app)/chats route |
| Groups | Group management and group-chat surfaces | (app)/groups route |
| Status | Status/story ring surfaces and timeline | (app)/status route |
| Calls | Call UI — in-call controls, call history, CallKit-style surfaces | (app)/calls route |
| Design spec | Design tokens + interaction spec (the “design API”) | app/globals.css, all components |
This mapping is the authoritative porting directive. The design spec’s own YAML front matter is the machine-readable token source that becomes globals.css on web and the Reanimated motion system on mobile.
The Obsidian Precision Design System
The design language is defined in a hybrid design-spec document: a YAML front-matter block holding machine-readable design tokens, followed by a human-readable brand, component, and interaction guide. This makes the same file usable both as documentation and as the extraction source for globals.css.
Brand Philosophy
The system is centered on “uncompromising craft engineering and Apple-like physical directness,” aimed at users who value speed, privacy, and aesthetic rigor. Its four pillars:
- Obsidian Foundations — deep, void-like dark backgrounds that maximize contrast.
- Glassmorphic Depth — translucent layers with heavy backdrop blurs (
12pxto20px) and hairline border highlights mimicking light catching a glass edge. - Kinetic Feedback — a “physical” interface where every interaction has weight: buttons scale on press, panels slide with momentum-based spring physics.
- Precision Detailing — zero-width gutters, monospaced numeric scales for timers, and intentional whitespace.
Color Tokens
The palette is monochromatic and structural, punctuated by a single high-energy emerald accent. The token names follow Material Design 3 conventions (surface roles, containers, fixed variants), which eases porting to component libraries:
| Token group | Example tokens | Role |
|---|---|---|
| Surfaces | surface #12131a, surface-container-lowest #0c0e14, surface-container #1e1f26, surface-bright #383940 |
Layered dark canvas — hierarchy by elevation, not color |
| On-surface | on-surface #e2e1eb, on-surface-variant #bbcabf |
Text/metadata contrast on surfaces |
| Primary (Precision Emerald) | primary #4edea3, primary-container #10b981, on-primary #003824 |
Affirmative actions, active states, brand presence |
| Secondary (Electric Blue) | secondary #aac7ff, secondary-container #3e90ff |
System links, secondary interactive triggers, information-dense highlights |
| Error | error #ffb4ab, error-container #93000a, on-error #690005 |
Destructive actions and error surfaces |
| Outline | outline #86948a, outline-variant #3c4a42 |
Hairline borders and dividers |
The emerald accent must “feel vibrant against the dark canvas”; blue is deliberately reserved so it never competes with primary actions. Neutral zinc/obsidian tones define hierarchy through elevation rather than color.
Typography Tokens
Inter is the sole typeface — a neutral, utilitarian foundation that scales from small metadata to large display titles. The token set covers display, headline, body, label, and numeric-stat styles:
| Token | Size | Weight | Line height | Letter spacing | Use |
|---|---|---|---|---|---|
display-lg |
40px | 700 | 44px | -0.02em | Hero/display titles |
headline-md |
24px | 600 | 32px | -0.015em | Section headlines (desktop) |
headline-md-mobile |
20px | 600 | 28px | -0.01em | Section headlines (mobile, scaled down) |
body-base |
15px | 400 | 22px | 0 | Message text, body copy |
body-bold |
15px | 600 | 22px | 0 | Emphasis within body copy |
label-caps |
12px | 600 | 16px | 0.05em | Uppercase labels, metadata |
stat-numeric |
32px | 700 | 38px | -0.02em | Timers, counters (tabular-nums) |
Two rules matter for implementation: timers, unread counts, and timestamps must use tabular-nums to prevent layout shift during live updates, and hierarchy is expressed with weight (600 vs 400) and color (pure white vs muted zinc) rather than size alone.
Spacing, Radii, and Elevation
- Spacing follows a strict 4px baseline rhythm:
xs4px,sm8px,md16px,lg24px,xl32px, with a 16px gutter and 16px/32px mobile/desktop margins. All margins, gaps, and paddings must be multiples of 4px; use 24px for major section separation and 8px for related element grouping (e.g., a message bubble and its timestamp). - Radii are a “pebble/hardware” shape language:
sm4px, default 8px for inputs and buttons,md12px,lg16px for cards and message bubbles,xl24px, andfull(9999px) exclusively for primary action buttons and the navigation dock. Message bubbles use asymmetric corners — the tail-side corner has a smaller radius (≈4px) to indicate message direction. - Elevation is tonal layering plus glassmorphism rather than drop shadows: Level 0 root is obsidian black
#0a0a0a; Level 1 panels are charcoal glass#121215; Level 2 active cards/popovers arergba(24, 24, 27, 0.8)withbackdrop-filter: blur(16px). Every elevated surface carries a1pxtop-border highlight (rgba(255, 255, 255, 0.1)) simulating a light source from above; only the highest-level modals get a soft ambient shadow (24px blur, 0.3 opacity, background-tinted).
These rules are part of the design spec.
Component Recipes
The spec prescribes exact recipes for core components:
- Primary buttons — pill-shaped (
rounded-full), emerald fill, white text; active state transitions withscale(0.97). - Secondary glass buttons — dark translucent fill, hairline border, backdrop blur.
- Message bubbles — sent: emerald fill with white text; received: dark glass fill with hairline border and muted zinc metadata.
- Floating navigation dock — pill-shaped bar fixed at bottom center, dark glass with
12pxblur, with a spring-animated sliding highlight behind the active icon. - Input fields — frameless
rgba(255, 255, 255, 0.04)background,1pxhairline border that glows emerald on focus. - Toasts (Sonner-style) — stacked at the bottom, entering with slide-up and scale-in from
0.95.
The Interactive-State Contract
The single most important requirement for porting is the interaction contract, because it defines feel, not just look:
All hover states should be subtle (opacity 0.8 or slight background tint). All “press” states must trigger a scale down to
0.97to feel physical.
The mobile stack maps this contract onto react-native-reanimated 4.5.1 + react-native-worklets, with all animations running on the UI thread via runOnUI / scheduleOnUI:
| Prototype interaction | Production implementation (web) | Production implementation (mobile) |
|---|---|---|
| Hover → opacity 0.8 / tint | CSS :hover transitions in globals.css |
Not applicable (touch); replaced by pressed state |
Press → scale(0.97) |
CSS :active { transform: scale(0.97) } |
Reanimated scale(0.97) kinetic press on buttons |
| Message bubble entry | CSS spring-like keyframes | Spring slide-up + fade (UI thread) |
| TabBar sliding indicator | CSS transitions | Momentum spring slide indicator |
| Status ring | CSS emerald pulse | Emerald pulse repeat (UI thread) |
| Toast enter | Slide-up + scale-in from 0.95 | Reanimated slide-up + scale-in |
Because the prototypes are static HTML/CSS, they express kinetic behavior through CSS transforms and transitions; the Expo port elevates the same spec to UI-thread Reanimated worklets so interaction stays at 60/120fps even during heavy E2EE and Realm I/O.
Core Flow: From Prototype to Production UI
The porting pipeline is the heart of this capability. It is a one-way, extract-then-adapt flow: tokens and behavior are extracted from the static mockups, codified into globals.css and design constants, then consumed by route components on both clients. The single-responsibility decomposition applies at the component-authoring stage, forcing each extracted piece into focused modules.
Step-by-Step Walkthrough
- Authoring — Designers produce the interactive HTML/CSS mockups, one per feature surface, plus the design-token spec.
- Token extraction — The YAML front matter of the design spec (colors, typography, rounded, spacing) is ported to
app/globals.cssas CSS custom properties, preserving names like--color-primary,--radius-lg,--space-md. - Component authoring — Route components are written against the tokens. Composite screens (e.g., the chat surface) are split into single-responsibility modules that consume the token layer.
- Behavior mapping — The interactive-state contract is translated per platform: CSS
:hover/:activetransforms on web; Reanimated UI-thread worklets (runOnUI/scheduleOnUI) on mobile. - Verification loop — Ported screens are visually compared to the mockups; any deviation (wrong radius, missing press scale, wrong blur depth) routes back to component authoring.
Sequence: Porting the Chat Surface
Usage Examples
The following excerpts are the actual source artifacts that drive the prototype layer.
1. Design token front matter (machine-readable spec)
The YAML header of the design spec is the token source for both clients — colors are Material-3-style roles, typography is a named scale, and rounded/spacing define the 4px-rhythm geometry:
colors:
surface: '#12131a'
surface-container-lowest: '#0c0e14'
surface-container: '#1e1f26'
primary: '#4edea3'
on-primary: '#003824'
primary-container: '#10b981'
secondary: '#aac7ff'
secondary-container: '#3e90ff'
error: '#ffb4ab'
error-container: '#93000a'
outline: '#86948a'
surface-tint: '#4edea3'
typography:
display-lg:
fontFamily: Inter
fontSize: 40px
fontWeight: '700'
lineHeight: 44px
letterSpacing: -0.02em
stat-numeric:
fontFamily: Inter
fontSize: 32px
fontWeight: '700'
lineHeight: 38px
letterSpacing: -0.02em
rounded:
sm: 0.25rem
DEFAULT: 0.5rem
lg: 1rem
full: 9999px
spacing:
unit: 4px
sm: 8px
md: 16px
lg: 24px
xl: 32px
2. Interactive-state and component recipes (behavior spec)
The prose section of the same file is the normative behavior contract — note the explicit press-scale and hover rules that production must replicate:
- **Buttons:**
- **Primary:** Pill-shaped, Emerald fill, white text. Active state: `scale(0.97)` transition.
- **Secondary Glass:** Dark translucent fill, hairline border, blur.
- **Message Bubbles:**
- **Sent:** Emerald fill with white text.
- **Received:** Dark glass fill with hairline border and muted zinc metadata.
- **Floating Navigation Dock:** A pill-shaped bar fixed at the bottom center. Dark glass background, `12px` blur, with a sliding background highlight that moves behind active icons using a spring animation.
- **Toasts (Sonner-style):** Stacked at the bottom, entering with a slide-up and scale-in (`from 0.95`).
- **Interactive States:** All hover states should be subtle (opacity 0.8 or slight background tint). All "press" states must trigger a scale down to `0.97` to feel physical.
3. Prototype-to-route porting directive
The porting directive declares the exact mapping of each feature surface to its App Router destination — this is the authoritative porting contract:
> **UI/UX porting directive**:
> - `(auth)/signup` & `login`
> - `(app)/chats`
> - `(app)/groups`
> - `(app)/status`
> - `(app)/calls`
> - Core design tokens -> `globals.css`
The same directive also binds the mobile implementation to the interaction contract — all animations run on the UI thread via runOnUI / scheduleOnUI, with message-bubble spring entry, a momentum TabBar slide indicator, scale(0.97) kinetic press, and an emerald pulse StatusRing.
Design Token Schema Reference
The YAML front matter of the design spec is effectively the configuration interface of the prototype layer. Any porting tool or globals.css generator consumes this schema:
| Field | Type | Values / Default | Description |
|---|---|---|---|
name |
string | Obsidian Precision |
Design language identifier |
colors.surface |
hex | #12131a |
Base panel surface |
colors.surface-container-lowest |
hex | #0c0e14 |
Deepest layer (root elevation) |
colors.surface-container |
hex | #1e1f26 |
Standard elevated surface |
colors.surface-container-high / highest |
hex | #282a31 / #33343c |
Hover/pressed elevation steps |
colors.on-surface |
hex | #e2e1eb |
Primary text on surfaces |
colors.primary |
hex | #4edea3 |
Precision Emerald — affirmative actions, active states |
colors.primary-container |
hex | #10b981 |
Emerald fill for sent bubbles, filled controls |
colors.secondary |
hex | #aac7ff |
Electric Blue — links, secondary triggers |
colors.error / error-container |
hex | #ffb4ab / #93000a |
Error text / error fill |
colors.outline |
hex | #86948a |
Hairline borders, dividers |
typography.<token>.fontSize |
px | 12–40px | Named type scale (see Typography Tokens table) |
typography.<token>.fontWeight |
int | 400–700 | Weight-based hierarchy |
rounded.DEFAULT |
rem | 0.5rem |
Standard control radius (8px) |
rounded.full |
rem | 9999px |
Pills — primary buttons, nav dock only |
spacing.unit |
px | 4px |
Baseline rhythm; all spacing is a multiple of 4px |
spacing.gutter |
px | 16px |
Page gutter |
Prototype Porting Contract (API of the mapping layer)
There is no runtime API in this layer — the “interface” is the route-mapping contract between mockups and production routes:
| Prototype | Output (route) | Notes |
|---|---|---|
| Auth flows | (auth)/signup, (auth)/login |
Form states, error surfaces, validation UI |
| Chats | (app)/chats |
Bubbles, composer, dock, toasts |
| Groups | (app)/groups |
Group list + thread |
| Status | (app)/status |
StatusRing, timeline |
| Calls | (app)/calls |
In-call controls, history |
| Design spec | app/globals.css |
CSS custom properties |
Failure Modes, Edge Cases & Concurrency
Because the prototype layer is static by design, its risks are about divergence and porting fidelity, not runtime crashes:
- Token drift between spec and implementation. If
globals.cssis hand-edited instead of generated from the YAML front matter, colors/radii silently diverge from the design spec. The design treats the spec as the single source of truth; edits should land in the YAML first. - Asymmetric bubble corners on RTL. The bubble spec (tail-side corner ≈4px) is direction-sensitive; porting must handle mirrored layouts or the visual direction cue breaks.
- Layout shift from timers. The
tabular-numsrequirement for timers, unread counts, and timestamps exists specifically to prevent reflow when digits change every second — a common edge-case failure in chat/call UIs if ignored. - Backdrop-blur overdraw. Glassmorphism (
blur(12–20px)) on many simultaneous panels is GPU-expensive; the elevation rules (Level 2 only for active cards/popovers) cap how much blur exists on screen at once. The mobile port must run these on the UI thread to avoid JS-thread jank. - Press-state scaling conflicts.
scale(0.97)on press can fight with spring slide animations if applied to the same transform property; the contract expects the scale to be composed with the entry spring rather than replacing it. - Concurrency in porting. Multiple developers porting different mockups share the same token layer; the single-responsibility decomposition and token-first approach reduce merge conflicts by keeping presentation modules independent, but token renames still ripple across all route components.
- Mobile hover parity. Hover states (opacity 0.8 / tint) have no touch equivalent; the mobile port deliberately maps them to pressed states, so web-only hover styling must not carry functional meaning.
Performance & Operational Notes
- UI-thread animation guarantee (mobile). All prototype-specified motion (bubble entry springs, TabBar momentum slide, kinetic press, StatusRing pulse) executes via
react-native-reanimatedworklets on the UI thread, so interactions stay smooth while E2EE crypto and Realm I/O run on other threads. - Web motion cost. CSS
backdrop-filterand transform animations are compositor-friendly, but blur layers are the main rendering cost; the elevation spec’s “blur only on active Level-2 surfaces” rule is the operational guardrail. - Module decomposition. The single-responsibility decomposition is enforced at authoring time; it keeps ported components focused and makes visual diffing against mockups tractable.
- Static deliverable, no runtime ops. The prototypes have no servers, no persistence, and no concurrency at runtime — operational concerns are limited to the build/porting pipeline and to the production clients that consume the tokens.
Extension Points
- New feature surfaces. Add a new prototype surface and extend the porting directive with its
->route mapping; the pipeline and token layer require no other changes. - Token additions. New color roles, type styles, or radii are added to the YAML front matter first; consumers regenerate
globals.cssand the mobile theme constants from it. - Alternative design languages. The token schema is reusable — a second design language can be defined with the same front-matter structure and swapped in at the token-extraction step without touching route components.
- Component library adoption. The token names follow Material 3 conventions (
surface-container,primary-container, fixed variants), which maps cleanly onto@shadcn/reactand@base-ui/reacttheming used by the web client.