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
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
- Engine isolation — Web Worker keeps UI responsive
- PWA foundation — Offline-ready, installable
- CSS custom properties — Perfect base for theme system
- CodeMirror extensibility — Custom language, errors, striping
- Scroll sync — Reliable cross-pane synchronization
- Light/dark adaptation — prefers-color-scheme already works
- Code splitting — React and CodeMirror in separate chunks
Created using Whiteport Design Studio (WDS) methodology