# 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_