feat(web): implement complete workspace with themes, tabs, sidebar, and mobile

Transform CalcText from a single-document calculator into a full workspace
application with multi-document support, theming, and responsive mobile experience.

- Theme system: 5 presets (Light, Dark, Matrix, Midnight, Warm) + accent colors
- Document model with localStorage persistence and auto-save
- Tab bar with keyboard shortcuts (Ctrl+N/W/Tab/1-9), rename, close
- Sidebar with search, recent, favorites, folders, templates, drag-and-drop
- 5 templates: Budget, Invoice, Unit Converter, Trip Planner, Loan Calculator
- Status bar with cursor position, engine status, dedication to Igor Cassel
- Results panel: type-specific colors, click-to-copy, error hints
- Format toolbar: H, B, I, //, color labels with live preview toggle
- Syntax highlighting using theme CSS variables
- Error hover tooltips
- Mobile: bottom results tray, sidebar drawer, touch targets, safe areas
- Docker multi-stage build (Rust WASM + Vite + Nginx)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-18 09:12:05 -04:00
parent 806e2f1ec6
commit 0d38bd3108
78 changed files with 8175 additions and 421 deletions

View File

@@ -0,0 +1,44 @@
# Product Brief: CalcText
> The strategic foundation — why this product exists, who it serves, and what success looks like.
**Created:** 2026-03-17
**Phase:** 1 — Product Brief
**Agent:** Saga (Analyst)
---
## What Belongs Here
The Product Brief answers five strategic questions:
1. **Why** does this product exist? (Vision & business goals)
2. **Who** is it for? (Target users and their context)
3. **What** does it need to do? (Core capabilities)
4. **How** will we know it works? (Success metrics)
5. **What** are the constraints? (Platform requirements, tech stack)
Everything downstream — trigger maps, scenarios, page specs, design system — traces back to decisions made here. This is the North Star.
---
## For Agents
**Workflow:** `_bmad/wds/workflows/1-project-brief/workflow.md`
**Agent trigger:** `PB` (Saga)
**Templates:** `_bmad/wds/workflows/1-project-brief/templates/`
---
## Documents
_This section will be updated as documents are created during Phase 1._
| # | Document | Status |
|---|----------|--------|
| 01 | Project Brief (Simplified) | Complete |
| 02 | Brownfield Analysis | Complete |
---
_Created using Whiteport Design Studio (WDS) methodology_

View File

@@ -0,0 +1,205 @@
# CalcText Web — Brownfield Analysis
**Date:** 2026-03-17
**Agent:** Freya (WDS Designer)
**Scope:** calcpad-web current state + cross-platform patterns from macOS
---
## 1. Current Architecture
| Layer | Tech | Status |
|-------|------|--------|
| Framework | React 19 + TypeScript | Solid |
| Editor | CodeMirror 6 (custom language, extensions) | Solid |
| Engine | Rust WASM in Web Worker (JS fallback for dev) | Solid |
| Build | Vite 7, ES2022 target, code splitting | Solid |
| PWA | vite-plugin-pwa, service worker, manifest | Solid |
| Styling | CSS custom properties, no framework | Flexible — ready for theme system |
---
## 2. Current Layout
```
┌─────────────────────────────────────────┐
│ Header (logo + subtitle + status dot) │ 52px
├─────────────────────────────────────────┤
│ Align Toolbar (editor + results) │ 28px
├───────────────────────┬─┬───────────────┤
│ │ │ │
│ Editor (flex: 3) │D│ Results │
│ CodeMirror 6 │i│ Panel │
│ 15px mono, 24px line │v│ (flex: 1) │
│ │ │ │
└───────────────────────┴─┴───────────────┘
```
**Mobile (< 640px):** Results panel, toolbar, divider, subtitle — all hidden. Editor only.
---
## 3. CSS Design Tokens (Current)
### Colors
| Token | Light | Dark |
|-------|-------|------|
| --text | #6b6375 | #9ca3af |
| --text-h | #08060d | #f3f4f6 |
| --bg | #fff | #16171d |
| --bg-secondary | #f8f9fa | #1a1b23 |
| --border | #e5e4e7 | #2e303a |
| --code-bg | #f4f3ec | #1f2028 |
| --accent | #6366f1 | #818cf8 |
| --accent-bg | rgba(99,102,241,0.1) | rgba(129,140,248,0.15) |
| --accent-border | rgba(99,102,241,0.5) | rgba(129,140,248,0.5) |
| --warning | #f59e0b | (same) |
| --success | #10b981 | (same) |
| --error | #e53e3e | (same) |
### Typography
| Context | Font | Size | Weight | Line Height |
|---------|------|------|--------|-------------|
| Body | system-ui | 16px | 400 | 1.5 |
| Editor/Results | ui-monospace | 15px | 400/600 | 1.6 (24px) |
| Header title | system-ui | 20px | — | — |
| Header subtitle | system-ui | 13px | — | — |
| Status | system-ui | 12px | — | — |
| Toolbar labels | system-ui | 11px | — | — |
| Buttons | system-ui | 14px | 500 | — |
### Spacing
| Context | Value |
|---------|-------|
| Header padding | 12px 24px |
| Editor line padding | 0 16px |
| Editor content padding | 12px 0 |
| Results line padding | 0 16px |
| Results content padding | 12px 0 |
| Toolbar height | 28px |
| Toolbar padding | 0 12px |
| Button gaps | 4px |
| Divider width | 5px (9px hit area) |
### Breakpoints
| Width | Behavior |
|-------|----------|
| > 640px | Full two-column layout |
| <= 640px | Single column, results/toolbar/divider hidden |
| <= 480px | Install prompt stacks vertically |
### Z-Index
| Element | Value |
|---------|-------|
| Install prompt | 100 |
| (everything else) | Default stacking |
### Animations
| Element | Type | Duration |
|---------|------|----------|
| Divider hover | Transition | 0.15s |
| Toolbar buttons | Transition | 0.1s |
| Install button | Transition | 0.2s |
| Status dot (loading) | Pulse keyframe | 1.5s |
| Offline icon | Pulse keyframe | 2s |
---
## 4. Component Inventory
| Component | Location | Props | Purpose |
|-----------|----------|-------|---------|
| App | App.tsx | — | Shell, state, layout |
| CalcEditor | editor/CalcEditor.tsx | initialDoc, onDocChange, results, debounceMs, onViewReady | CodeMirror wrapper |
| ResultsPanel | components/ResultsPanel.tsx | results, align, style | Right-side results display |
| AlignToolbar | components/AlignToolbar.tsx | editorAlign, resultsAlign, onChange handlers | Text alignment controls |
| OfflineBanner | components/OfflineBanner.tsx | isOnline | Offline status |
| InstallPrompt | components/InstallPrompt.tsx | promptEvent, isInstalled, onInstall, onDismiss | PWA install |
### Editor Extensions
| Extension | File | Purpose |
|-----------|------|---------|
| calcpadLanguage | calcpad-language.ts | Syntax highlighting (keywords, functions, operators, currencies) |
| errorDisplayExtension | error-display.ts | Wavy underlines + gutter markers for errors |
| stripedLinesExtension | inline-results.ts | Even-line zebra striping |
| calcpadEditorTheme | CalcEditor.tsx | Base theme (font, padding, colors) |
### Hooks
| Hook | File | State |
|------|------|-------|
| useEngine | engine/useEngine.ts | ready, results, error, evalSheet() |
| useOnlineStatus | hooks/useOnlineStatus.ts | isOnline |
| useInstallPrompt | hooks/useInstallPrompt.ts | promptEvent, isInstalled, handlers |
---
## 5. Accessibility Audit
| Feature | Status | Notes |
|---------|--------|-------|
| Semantic HTML | Partial | Header, main present. Missing nav, regions |
| ARIA roles | Partial | OfflineBanner (status), InstallPrompt (complementary) |
| Focus indicators | Missing | No custom :focus-visible styles |
| Keyboard nav | Default | CodeMirror defaults only, toolbar not keyboard-navigable |
| Screen reader | Partial | Results panel has no aria-live for updates |
| Color contrast | OK | Meets AA for most combinations |
| Font scaling | Missing | Fixed 15px, ignores system preferences |
| Reduced motion | Missing | No prefers-reduced-motion media query |
---
## 6. Cross-Platform Comparison (macOS vs Web)
| Aspect | macOS | Web | Recommendation |
|--------|-------|-----|----------------|
| Spacing | Compact (8px) | Spacious (12-16px) | Tighten to match native feel |
| Results weight | Regular, secondary color | Bold 600, accent color | Reduce to secondary — results are too loud |
| Font scaling | System Dynamic Type | Fixed 15px | Respect system preferences |
| Min dimensions | 800x600 window | No minimum | Set min-width guidance |
| Text substitutions | All disabled | Browser default | Disable smart quotes/dashes |
| Stripe pattern | Synced, 4% opacity | Synced, 2.5-3.5% opacity | Already close |
| Error display | Editor only | Editor only | Already matched |
| Scroll sync | Binding-driven | Event-driven (passive) | Both work well |
---
## 7. What's Missing for Workspace Vision
| Feature | Exists? | Effort | Priority |
|---------|---------|--------|----------|
| Theme engine (multi-theme) | No (only system dark/light) | Medium | P0 |
| Theme switcher UI | No | Low | P0 |
| Document model (multi-doc) | No (single string in state) | Medium | P0 |
| Tab bar | No | Medium | P0 |
| File sidebar | No | Medium | P1 |
| localStorage persistence | No | Low | P0 |
| Folder organization | No | Medium | P1 |
| Templates library | No | Low | P2 |
| Dark mode toggle (manual) | No (system preference only) | Low | P0 |
| Mobile results view | No (hidden on mobile) | Medium | P1 |
| Keyboard shortcuts panel | No | Low | P2 |
| Status bar | No | Low | P1 |
---
## 8. Strengths to Preserve
1. **Engine isolation** — Web Worker keeps UI responsive
2. **PWA foundation** — Offline-ready, installable
3. **CSS custom properties** — Perfect base for theme system
4. **CodeMirror extensibility** — Custom language, errors, striping
5. **Scroll sync** — Reliable cross-pane synchronization
6. **Light/dark adaptation** — prefers-color-scheme already works
7. **Code splitting** — React and CodeMirror in separate chunks
---
_Created using Whiteport Design Studio (WDS) methodology_

View File

@@ -0,0 +1,94 @@
# CalcText — Simplified Product Brief
**Date:** 2026-03-17
**Type:** Brownfield — Workspace Evolution
**Brief Level:** Simplified
---
## Project Scope
CalcText is a cross-platform notepad calculator (Web, macOS, Windows) powered by a shared Rust calculation engine with 200+ unit conversions, 180+ fiat currencies, 50+ crypto, date/time math, and 50+ built-in functions.
The web app is evolving from a single-document, two-column calculator into a **full workspace application** with:
- **Multi-theme system** — Light, Dark, Matrix, and custom user-defined themes
- **Tabbed documents** — Multiple calctext files open simultaneously
- **File sidebar** — Left panel with folder organization, recent files, favorites, templates
- **localStorage persistence** — Documents survive page reloads without backend
- **Elevated results panel** — Richer, subtler result display
**Platform strategy:** Web-first design. Once established, replicate the UX patterns to macOS (SwiftUI) and Windows (iced/Rust). The design must be portable — avoid web-only paradigms that don't translate to native.
---
## Challenge & Opportunity
CalcText has a powerful engine trapped in a basic single-document UI. The current web app is functional but doesn't reflect the depth of what the engine can do, and doesn't invite users to stay.
**The opportunity:** No competitor (Soulver, Numi, Numbr, PCalc) offers a true multi-document workspace with theming and file organization for calculations. CalcText can own this gap — becoming the app users open daily and live in, not just visit for a quick calculation.
**The gap:** Current UI is a text editor with results. The vision is a professional workspace where calculations are organized, styled, and persistent.
---
## Design Goals
### Functional
- Multi-theme engine with preset themes and custom theme support
- Tab bar for multi-document management
- Collapsible file sidebar with tree view, folders, and templates
- Document model with create, rename, delete, organize
- localStorage persistence for all documents and preferences
### Experience
- Professional workspace feel — "VS Code/Notion for numbers"
- Complete experience shipped as one coherent product, not incremental phases
- Matrix theme as a brand differentiator and personality statement
- Intuitive for first-time users, powerful for daily users
### Business
- Web-first design that establishes reusable UX patterns
- Cross-platform portable design language
- Foundation for future premium features (cloud sync, accounts, collaboration)
---
## Constraints
### Technical (locked in)
- React 19 + CodeMirror 6 + Vite 7
- Rust WASM engine running in Web Worker
- Custom CSS with CSS custom properties (no Tailwind, no shadcn)
- PWA architecture (service worker, manifest, offline support)
### Deferred (out of scope this phase)
- User accounts and authentication
- Cloud save and sync (Supabase planned)
- Collaborative real-time editing (CRDT)
- Shareable URL links
- Embeddable widget
### Cross-platform
- Design patterns must translate to SwiftUI (macOS) and iced (Windows)
- Avoid web-only interactions that don't port to native
- Shared engine means consistent calculation behavior across platforms
### Timeline & Budget
- Flexible — no hard deadline
- Stakes: enterprise/high — quality over speed
---
## Current State Reference
See `01-brownfield-analysis.md` for complete codebase scan including:
- All CSS custom properties and values
- Component inventory and props
- Responsive breakpoints and behavior
- Accessibility audit
- Cross-platform comparison (macOS vs Web)
---
_Created using Whiteport Design Studio (WDS) methodology_