Skip to content

vmedium/continua-design-prototype

Repository files navigation

Continua — Interactive App Simulator

A fully functional, cross-platform app simulator built with vanilla HTML, CSS, and JavaScript. Designed as a prototyping and demonstration tool for the Continua Social AI platform, supporting guided scenario walkthroughs, dark mode, and responsive desktop/mobile layouts.


What This Is

Continua is a high-fidelity interactive prototype that behaves like a real app. Users can navigate between screens, send messages, create group chats, and interact with AI agent conversations — all rendered client-side with no backend.

The app has 3 tabs (Home, Messages, Settings) and 19 detail screens including agent chat, group chat, world chat, direct messages, call UIs, and settings sub-screens. The Home tab shows dynamic action cards — weather, flight itinerary, calendar events, email summary, and news — that appear based on the active scenario.

On top of the fully functional app, a Lesson System provides guided scenario walkthroughs (onboarding, agent setup, group chat creation) with step-by-step tracking, auto-execution, and replay-based navigation.

experiments/trefoil-demo.html is a standalone exploration tool: an SVG-based emotion state visualizer with arousal, valence, dominance, and intensity sliders. It's separate from the main app.


Architecture

The system is organized into three layers:

┌─────────────────────────────────┐
│  Lesson Layer                   │  LessonRunner, step list UI,
│  (guided walkthroughs)          │  completion detection, replay
├─────────────────────────────────┤
│  Flow Engine                    │  FLOWS registry, FlowEngine,
│  (conversation scripts)         │  declarative step definitions
├─────────────────────────────────┤
│  App Core                       │  Navigation, APP_STATE, UI
│  (always functional)            │  components, screen management
└─────────────────────────────────┘

App Core — The app works like a real messaging app at all times. Navigation (switchTab, openScreen, closeScreen), state management (APP_STATE), and all UI components function independently of lessons or flows.

Flow Engine — Conversations are declarative definitions in a FLOWS registry. Each flow specifies an init state and a series of steps with onResponse handlers. FlowEngine.start(), .handleInput(), .reset(), and .jumpToStep() manage the lifecycle. Adding a new conversation flow means adding one entry to FLOWS.

Lesson System — A LESSONS registry defines guided scenarios with labeled steps. Each step has an execute() function (for auto-play) and a detect() function (for completion polling). LessonRunner manages the active lesson, renders a step list in the debug panel, and supports click-to-jump replay navigation.


File Structure

├── index.html                    Main application (HTML + inline JS, all screens)
├── styles.css                    App component styles (references token CSS vars)
├── package.json                  npm scripts: build:tokens, build:icons, add-icon
├── style-dictionary.config.js    Token build config (Style Dictionary 4)
├── assets/                       SVG/PNG icons and avatars (brand marks, avatars, ic_* icons)
├── design-system/
│   ├── tokens/                   DTCG token source files — edit these
│   │   ├── primitive.color.json
│   │   ├── semantic.color.json
│   │   ├── semantic.color.dark.json
│   │   ├── semantic.typography.json
│   │   ├── semantic.spacing.json
│   │   ├── semantic.radius.json
│   │   ├── semantic.motion.json
│   │   ├── component.json
│   │   └── component.dark.json
│   ├── tokens.css                GENERATED — do not edit
│   ├── tokens-dark.css           GENERATED — do not edit
│   ├── REFERENCE.md              GENERATED — auto token reference for LLM context
│   ├── BRAND.md                  Hand-authored brand voice & design principles
│   ├── components.html           Living component library (inspection + audit)
│   └── archive/                  Legacy pre-token-system files
├── scripts/
│   ├── inline-icons.js           Build step: replaces icon spans with inline SVGs
│   ├── add-icon.js               Helper: normalises a new SVG and prints ICON_MAP entry
│   └── svg-inject.js             Runtime SVG injector (legacy, not currently wired)
└── experiments/
    ├── trefoil-demo.html         Emotion state visualization (arousal/valence/dominance)
    └── character-creator.html   Character/persona creator tool

Key Features

Responsive Layout

  • Mobile: 390×844px phone frame with native iOS chrome (status bar, home indicator, tab bar)
  • Desktop: 800px content model, full-width frosted header, centered navigation, modal sign-in
  • Instant transitions on desktop, slide animations on mobile
  • Toggle between layouts via the debug panel

Design Token System

All colors, spacing, radii, typography, and motion values are CSS custom properties from a W3C DTCG–compliant token system compiled by Style Dictionary. No hardcoded values in component styles.

Three-tier hierarchy:

Tier Purpose Files
Tier 1 — Primitives Raw palette values, never used directly in components primitive.color.json
Tier 2 — Semantic Intent-based tokens (text, bg, border, brand, state) semantic.*.json
Tier 3 — Component Per-component tokens with dark mode overrides component.json, component.dark.json

CSS variable conventions:

Prefix Example Purpose
--color-text-* --color-text-primary Text hierarchy
--color-brand-* --color-brand-primary Brand purple
--color-bg-* --color-bg-surface Surface hierarchy
--color-border-* --color-border-default Border colors
--component-* --component-bubble-user-background Per-component tokens

Build:

npm run build:tokens   # token JSON → tokens.css + tokens-dark.css + REFERENCE.md
npm run build:icons    # icon spans → inline SVGs in index.html and components.html
npm run build          # both, in order

Dark Mode

Dark mode token overrides are defined in semantic.color.dark.json and component.dark.json. The build generates tokens-dark.css which applies all overrides under body.dark-mode. No manual body.dark-mode blocks in styles.css — all dark mode values live in token files.

Toggle in the debug panel; persisted to localStorage.

Icon System

All icons are inline SVGs injected at build time by scripts/inline-icons.js. The SVG files in /assets/ use fill="var(--fill-0, #fallback)" — a CSS variable system that responds to the design token cascade automatically, including dark mode.

Icon CSS variables:

Variable Light Dark Purpose
--fill-0 var(--tone-purple-10) dark indigo var(--tone-purple-80) light purple Icon primary color
--fill-1 var(--tone-purple-60) accent purple var(--tone-purple-60) Icon accent (send arrow, agent bubble)

Context overrides:

  • .action-check-24 { --fill-0: #fff; } — white checkmark on colored button
  • .flight-widget { --fill-0: var(--widget-flight-text); } — blue flight icons

Adding a new icon:

  1. Export SVG from Figma → drop in /assets/
  2. npm run add-icon assets/ic-my-icon.svg — normalises fill colors, prints ICON_MAP entry
  3. Add the printed entry to scripts/inline-icons.js
  4. npm run build:icons

Hover System

Scoping rule: All hover effects are double-scoped: @media (hover: hover) AND .layout-desktop. Hover states never appear on the mobile prototype.

Asymmetric timing: Hover fades in at 100ms, fades out at 50ms. The base state transition governs exit; the :hover state transition governs entry.

.action-card { transition: filter 0.05s ease, background 0.05s ease; }
.layout-desktop .action-card:hover { transition: filter 0.1s ease, background 0.1s ease; }

Scenarios & Lessons

Four built-in scenarios accessible from the debug panel:

# Scenario What it covers
1 Login Sign-in modal dismissal
2 Agent Setup Open agent chat, name agent, set permissions
3 Group Chat Create chat, add people, submit, open conversation
4 Next Day Browse home cards, check messages

LessonRunner architecture notes:

  • Race condition pattern: _startDetection runs a requestAnimationFrame loop polling step.detect(). executeCurrentStep also polls detect() via a setTimeout chain. Fix: always cancelAnimationFrame(self._rafId) before executing a step manually, and restart RAF only after execution completes.

  • _onStepClick behavior: Clicking any step always calls executeCurrentStep() (the current pending step). Do not call goToStep or _replayTo from click handlers — replay from step 0 causes intermediate execute() calls to fire visible side effects.

  • Step execute() should be side-effect-free for replay: Steps that open overlays must not do so during _replayTo. The group chat step selects contacts via togglePerson() without calling togglePeoplePicker().

Component Library

design-system/components.html is a living inspection and audit library showing every UI component with:

  • All states (default, hover, active, disabled, error, loading)
  • Token inspector — click any component to see which tokens it uses
  • Mobile (390px, 33% width) and desktop (67% width) previews side by side, both flexible
  • Token audit (components using unregistered values)

Dev Tools

The debug panel (gear icon, bottom-right) provides:

  • Scenario launcher — Start any lesson with one click
  • Step list — Interactive checklist with completion tracking
  • Layout toggle — Switch between phone and desktop views
  • Theme toggle — Light/dark mode
  • Hierarchy tree — DOM structure inspector
  • Layout debug — Colored overlay showing component boundaries with hover inspection
  • Reset — Full state reset

Layout debug hover tool:

  • Hover over any element inside the phone frame to see: component name, color tokens by property category (bg, text, border), and current app state (dark mode, desktop, scenario, tab, screen).
  • Double-click copies a structured plain-text report to clipboard — identity, state, tokens, layout, typography — ready to paste into an agent conversation.

Dark mode layout debug: The overlay uses high-contrast colors distinct from the dark mode palette so region boundaries are legible regardless of theme.


Technical Notes

  • Dependencies: Style Dictionary (dev dep, token build only). App itself has zero runtime dependencies.
  • Local preview: Serve with Live Server or any static server. Open index.html. Run npm run build if token or icon files changed.
  • GitHub Pages: Deployed from the master branch root.
  • State management: APP_STATE tracks scenario, flow phase, and dynamic content. resetScenarioState() performs full DOM + JS cleanup on scenario switch.
  • Desktop overrides: CSS organized by component section (/* ── Desktop: Site Header ── */) for maintainability.
  • Agent naming: Agent names are never hardcoded in component markup. Always rendered from APP_STATE via [data-agent-name] attributes.

Development Workflow

This project is built with Cursor and Claude Code. Custom Claude Code skills live in .claude/. The workflow:

  1. Describe changes in the agent chat (Cursor or Claude Code)
  2. Review diffs in the editor
  3. npm run build before committing if token or icon files changed
  4. Commit and push — GitHub Pages deploys automatically from master

Branch naming: design-system/* for token/system work, feature/* for component work.


Repository

github.com/vmedium/ContinuaPrototype

Releases

No releases published

Packages

 
 
 

Contributors